#
tokens: 48284/50000 3/1633 files (page 99/186)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 99 of 186. Use http://codebase.md/xmlui-org/xmlui/mockApiDef.js?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .changeset
│   └── config.json
├── .eslintrc.cjs
├── .github
│   ├── build-checklist.png
│   ├── ISSUE_TEMPLATE
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   └── workflows
│       ├── deploy-blog-optimized.yml
│       ├── deploy-blog-swa.yml
│       ├── deploy-blog.yml
│       ├── deploy-docs-optimized.yml
│       ├── deploy-docs.yml
│       ├── prepare-versions.yml
│       ├── release-packages.yml
│       ├── run-all-tests.yml
│       └── run-smoke-tests.yml
├── .gitignore
├── .prettierrc.js
├── .vscode
│   ├── launch.json
│   └── settings.json
├── blog
│   ├── .gitignore
│   ├── .gitkeep
│   ├── CHANGELOG.md
│   ├── extensions.ts
│   ├── index.html
│   ├── index.ts
│   ├── package.json
│   ├── public
│   │   ├── blog
│   │   │   ├── images
│   │   │   │   ├── an-advanced-codefence.gif
│   │   │   │   ├── an-advanced-codefence.mp4
│   │   │   │   ├── blog-page-component.png
│   │   │   │   ├── blog-scrabble.png
│   │   │   │   ├── codefence-runner.png
│   │   │   │   ├── integrated-blog-search.png
│   │   │   │   ├── lorem-ipsum.png
│   │   │   │   ├── playground-checkbox-source.png
│   │   │   │   ├── playground.png
│   │   │   │   ├── use-xmlui-mcp-to-find-a-howto.png
│   │   │   │   └── xmlui-demo-gallery.png
│   │   │   ├── introducing-xmlui.md
│   │   │   ├── lorem-ipsum.md
│   │   │   ├── newest-post.md
│   │   │   ├── older-post.md
│   │   │   ├── xmlui-playground.md
│   │   │   └── xmlui-powered-blog.md
│   │   ├── mockServiceWorker.js
│   │   ├── resources
│   │   │   ├── favicon.ico
│   │   │   ├── files
│   │   │   │   └── for-download
│   │   │   │       └── xmlui
│   │   │   │           └── xmlui-standalone.umd.js
│   │   │   ├── github.svg
│   │   │   ├── llms.txt
│   │   │   ├── logo-dark.svg
│   │   │   ├── logo.svg
│   │   │   ├── pg-popout.svg
│   │   │   ├── rss.svg
│   │   │   └── xmlui-logo.svg
│   │   ├── serve.json
│   │   ├── staticwebapp.config.json
│   │   └── web.config
│   ├── scripts
│   │   ├── download-latest-xmlui.js
│   │   ├── generate-rss.js
│   │   ├── get-releases.js
│   │   └── utils.js
│   ├── src
│   │   ├── components
│   │   │   ├── BlogOverview.xmlui
│   │   │   ├── BlogPage.xmlui
│   │   │   └── PageNotFound.xmlui
│   │   ├── config.ts
│   │   ├── Main.xmlui
│   │   └── themes
│   │       └── blog-theme.ts
│   └── tsconfig.json
├── CONTRIBUTING.md
├── docs
│   ├── .gitignore
│   ├── CHANGELOG.md
│   ├── ComponentRefLinks.txt
│   ├── content
│   │   ├── _meta.json
│   │   ├── components
│   │   │   ├── _meta.json
│   │   │   ├── _overview.md
│   │   │   ├── APICall.md
│   │   │   ├── App.md
│   │   │   ├── AppHeader.md
│   │   │   ├── AppState.md
│   │   │   ├── AutoComplete.md
│   │   │   ├── Avatar.md
│   │   │   ├── Backdrop.md
│   │   │   ├── Badge.md
│   │   │   ├── BarChart.md
│   │   │   ├── Bookmark.md
│   │   │   ├── Breakout.md
│   │   │   ├── Button.md
│   │   │   ├── Card.md
│   │   │   ├── Carousel.md
│   │   │   ├── ChangeListener.md
│   │   │   ├── Checkbox.md
│   │   │   ├── CHStack.md
│   │   │   ├── ColorPicker.md
│   │   │   ├── Column.md
│   │   │   ├── ContentSeparator.md
│   │   │   ├── CVStack.md
│   │   │   ├── DataSource.md
│   │   │   ├── DateInput.md
│   │   │   ├── DatePicker.md
│   │   │   ├── DonutChart.md
│   │   │   ├── DropdownMenu.md
│   │   │   ├── EmojiSelector.md
│   │   │   ├── ExpandableItem.md
│   │   │   ├── FileInput.md
│   │   │   ├── FileUploadDropZone.md
│   │   │   ├── FlowLayout.md
│   │   │   ├── Footer.md
│   │   │   ├── Form.md
│   │   │   ├── FormItem.md
│   │   │   ├── FormSection.md
│   │   │   ├── Fragment.md
│   │   │   ├── H1.md
│   │   │   ├── H2.md
│   │   │   ├── H3.md
│   │   │   ├── H4.md
│   │   │   ├── H5.md
│   │   │   ├── H6.md
│   │   │   ├── Heading.md
│   │   │   ├── HSplitter.md
│   │   │   ├── HStack.md
│   │   │   ├── Icon.md
│   │   │   ├── IFrame.md
│   │   │   ├── Image.md
│   │   │   ├── Items.md
│   │   │   ├── LabelList.md
│   │   │   ├── Legend.md
│   │   │   ├── LineChart.md
│   │   │   ├── Link.md
│   │   │   ├── List.md
│   │   │   ├── Logo.md
│   │   │   ├── Markdown.md
│   │   │   ├── MenuItem.md
│   │   │   ├── MenuSeparator.md
│   │   │   ├── ModalDialog.md
│   │   │   ├── NavGroup.md
│   │   │   ├── NavLink.md
│   │   │   ├── NavPanel.md
│   │   │   ├── NoResult.md
│   │   │   ├── NumberBox.md
│   │   │   ├── Option.md
│   │   │   ├── Page.md
│   │   │   ├── PageMetaTitle.md
│   │   │   ├── Pages.md
│   │   │   ├── Pagination.md
│   │   │   ├── PasswordInput.md
│   │   │   ├── PieChart.md
│   │   │   ├── ProgressBar.md
│   │   │   ├── Queue.md
│   │   │   ├── RadioGroup.md
│   │   │   ├── RealTimeAdapter.md
│   │   │   ├── Redirect.md
│   │   │   ├── Select.md
│   │   │   ├── Slider.md
│   │   │   ├── Slot.md
│   │   │   ├── SpaceFiller.md
│   │   │   ├── Spinner.md
│   │   │   ├── Splitter.md
│   │   │   ├── Stack.md
│   │   │   ├── StickyBox.md
│   │   │   ├── SubMenuItem.md
│   │   │   ├── Switch.md
│   │   │   ├── TabItem.md
│   │   │   ├── Table.md
│   │   │   ├── TableOfContents.md
│   │   │   ├── Tabs.md
│   │   │   ├── Text.md
│   │   │   ├── TextArea.md
│   │   │   ├── TextBox.md
│   │   │   ├── Theme.md
│   │   │   ├── TimeInput.md
│   │   │   ├── Timer.md
│   │   │   ├── ToneChangerButton.md
│   │   │   ├── ToneSwitch.md
│   │   │   ├── Tooltip.md
│   │   │   ├── Tree.md
│   │   │   ├── VSplitter.md
│   │   │   ├── VStack.md
│   │   │   ├── xmlui-animations
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   ├── Animation.md
│   │   │   │   ├── FadeAnimation.md
│   │   │   │   ├── FadeInAnimation.md
│   │   │   │   ├── FadeOutAnimation.md
│   │   │   │   ├── ScaleAnimation.md
│   │   │   │   └── SlideInAnimation.md
│   │   │   ├── xmlui-pdf
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   └── Pdf.md
│   │   │   ├── xmlui-spreadsheet
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   └── Spreadsheet.md
│   │   │   └── xmlui-website-blocks
│   │   │       ├── _meta.json
│   │   │       ├── _overview.md
│   │   │       ├── Carousel.md
│   │   │       ├── HelloMd.md
│   │   │       ├── HeroSection.md
│   │   │       └── ScrollToTop.md
│   │   └── extensions
│   │       ├── _meta.json
│   │       ├── xmlui-animations
│   │       │   ├── _meta.json
│   │       │   ├── _overview.md
│   │       │   ├── Animation.md
│   │       │   ├── FadeAnimation.md
│   │       │   ├── FadeInAnimation.md
│   │       │   ├── FadeOutAnimation.md
│   │       │   ├── ScaleAnimation.md
│   │       │   └── SlideInAnimation.md
│   │       └── xmlui-website-blocks
│   │           ├── _meta.json
│   │           ├── _overview.md
│   │           ├── Carousel.md
│   │           ├── FancyButton.md
│   │           ├── HeroSection.md
│   │           └── ScrollToTop.md
│   ├── extensions.ts
│   ├── index.html
│   ├── index.ts
│   ├── package.json
│   ├── public
│   │   ├── feed.rss
│   │   ├── mockServiceWorker.js
│   │   ├── pages
│   │   │   ├── _meta.json
│   │   │   ├── app-structure.md
│   │   │   ├── build-editor-component.md
│   │   │   ├── build-hello-world-component.md
│   │   │   ├── components-intro.md
│   │   │   ├── context-variables.md
│   │   │   ├── forms.md
│   │   │   ├── globals.md
│   │   │   ├── glossary.md
│   │   │   ├── helper-tags.md
│   │   │   ├── hosted-deployment.md
│   │   │   ├── howto
│   │   │   │   ├── assign-a-complex-json-literal-to-a-component-variable.md
│   │   │   │   ├── chain-a-refetch.md
│   │   │   │   ├── control-cache-invalidation.md
│   │   │   │   ├── debounce-user-input-for-api-calls.md
│   │   │   │   ├── debounce-with-changelistener.md
│   │   │   │   ├── debug-a-component.md
│   │   │   │   ├── delay-a-datasource-until-another-datasource-is-ready.md
│   │   │   │   ├── delegate-a-method.md
│   │   │   │   ├── do-custom-form-validation.md
│   │   │   │   ├── expose-a-method-from-a-component.md
│   │   │   │   ├── filter-and-transform-data-from-an-api.md
│   │   │   │   ├── group-items-in-list-by-a-property.md
│   │   │   │   ├── handle-background-operations.md
│   │   │   │   ├── hide-an-element-until-its-datasource-is-ready.md
│   │   │   │   ├── make-a-set-of-equal-width-cards.md
│   │   │   │   ├── make-a-table-responsive.md
│   │   │   │   ├── make-navpanel-width-responsive.md
│   │   │   │   ├── modify-a-value-reported-in-a-column.md
│   │   │   │   ├── paginate-a-list.md
│   │   │   │   ├── pass-data-to-a-modal-dialog.md
│   │   │   │   ├── react-to-button-click-not-keystrokes.md
│   │   │   │   ├── set-the-initial-value-of-a-select-from-fetched-data.md
│   │   │   │   ├── share-a-modaldialog-across-components.md
│   │   │   │   ├── sync-selections-between-table-and-list-views.md
│   │   │   │   ├── update-ui-optimistically.md
│   │   │   │   ├── use-built-in-form-validation.md
│   │   │   │   └── use-the-same-modaldialog-to-add-or-edit.md
│   │   │   ├── howto.md
│   │   │   ├── intro.md
│   │   │   ├── layout.md
│   │   │   ├── markup.md
│   │   │   ├── mcp.md
│   │   │   ├── modal-dialogs.md
│   │   │   ├── news-and-reviews.md
│   │   │   ├── reactive-intro.md
│   │   │   ├── refactoring.md
│   │   │   ├── routing-and-links.md
│   │   │   ├── samples
│   │   │   │   ├── color-palette.xmlui
│   │   │   │   ├── color-values.xmlui
│   │   │   │   ├── shadow-sizes.xmlui
│   │   │   │   ├── spacing-sizes.xmlui
│   │   │   │   ├── swatch.xmlui
│   │   │   │   ├── theme-gallery-brief.xmlui
│   │   │   │   └── theme-gallery.xmlui
│   │   │   ├── scoping.md
│   │   │   ├── scripting.md
│   │   │   ├── styles-and-themes
│   │   │   │   ├── common-units.md
│   │   │   │   ├── layout-props.md
│   │   │   │   ├── theme-variable-defaults.md
│   │   │   │   ├── theme-variables.md
│   │   │   │   └── themes.md
│   │   │   ├── template-properties.md
│   │   │   ├── test.md
│   │   │   ├── tutorial-01.md
│   │   │   ├── tutorial-02.md
│   │   │   ├── tutorial-03.md
│   │   │   ├── tutorial-04.md
│   │   │   ├── tutorial-05.md
│   │   │   ├── tutorial-06.md
│   │   │   ├── tutorial-07.md
│   │   │   ├── tutorial-08.md
│   │   │   ├── tutorial-09.md
│   │   │   ├── tutorial-10.md
│   │   │   ├── tutorial-11.md
│   │   │   ├── tutorial-12.md
│   │   │   ├── universal-properties.md
│   │   │   ├── user-defined-components.md
│   │   │   ├── vscode.md
│   │   │   ├── working-with-markdown.md
│   │   │   ├── working-with-text.md
│   │   │   ├── xmlui-animations
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   ├── Animation.md
│   │   │   │   ├── FadeAnimation.md
│   │   │   │   ├── FadeInAnimation.md
│   │   │   │   ├── FadeOutAnimation.md
│   │   │   │   ├── ScaleAnimation.md
│   │   │   │   └── SlideInAnimation.md
│   │   │   ├── xmlui-charts
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   ├── BarChart.md
│   │   │   │   ├── DonutChart.md
│   │   │   │   ├── LabelList.md
│   │   │   │   ├── Legend.md
│   │   │   │   ├── LineChart.md
│   │   │   │   └── PieChart.md
│   │   │   ├── xmlui-pdf
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   └── Pdf.md
│   │   │   └── xmlui-spreadsheet
│   │   │       ├── _meta.json
│   │   │       ├── _overview.md
│   │   │       └── Spreadsheet.md
│   │   ├── resources
│   │   │   ├── devdocs
│   │   │   │   ├── debug-proxy-object-2.png
│   │   │   │   ├── debug-proxy-object.png
│   │   │   │   ├── table_editor_01.png
│   │   │   │   ├── table_editor_02.png
│   │   │   │   ├── table_editor_03.png
│   │   │   │   ├── table_editor_04.png
│   │   │   │   ├── table_editor_05.png
│   │   │   │   ├── table_editor_06.png
│   │   │   │   ├── table_editor_07.png
│   │   │   │   ├── table_editor_08.png
│   │   │   │   ├── table_editor_09.png
│   │   │   │   ├── table_editor_10.png
│   │   │   │   ├── table_editor_11.png
│   │   │   │   ├── table-editor-01.png
│   │   │   │   ├── table-editor-02.png
│   │   │   │   ├── table-editor-03.png
│   │   │   │   ├── table-editor-04.png
│   │   │   │   ├── table-editor-06.png
│   │   │   │   ├── table-editor-07.png
│   │   │   │   ├── table-editor-08.png
│   │   │   │   ├── table-editor-09.png
│   │   │   │   └── xmlui-rendering-of-tiptap-markdown.png
│   │   │   ├── favicon.ico
│   │   │   ├── files
│   │   │   │   ├── clients.json
│   │   │   │   ├── daily-revenue.json
│   │   │   │   ├── dashboard-stats.json
│   │   │   │   ├── demo.xmlui
│   │   │   │   ├── demo.xmlui.xs
│   │   │   │   ├── downloads
│   │   │   │   │   └── downloads.json
│   │   │   │   ├── for-download
│   │   │   │   │   ├── index-with-api.html
│   │   │   │   │   ├── index.html
│   │   │   │   │   ├── mockApi.js
│   │   │   │   │   ├── start-darwin.sh
│   │   │   │   │   ├── start-linux.sh
│   │   │   │   │   ├── start.bat
│   │   │   │   │   └── xmlui
│   │   │   │   │       └── xmlui-standalone.umd.js
│   │   │   │   ├── getting-started
│   │   │   │   │   ├── cl-tutorial-final.zip
│   │   │   │   │   ├── cl-tutorial.zip
│   │   │   │   │   ├── cl-tutorial2.zip
│   │   │   │   │   ├── cl-tutorial3.zip
│   │   │   │   │   ├── cl-tutorial4.zip
│   │   │   │   │   ├── cl-tutorial5.zip
│   │   │   │   │   ├── cl-tutorial6.zip
│   │   │   │   │   ├── getting-started.zip
│   │   │   │   │   ├── hello-xmlui.zip
│   │   │   │   │   ├── xmlui-empty.zip
│   │   │   │   │   └── xmlui-starter.zip
│   │   │   │   ├── howto
│   │   │   │   │   └── component-icons
│   │   │   │   │       └── up-arrow.svg
│   │   │   │   ├── invoices.json
│   │   │   │   ├── monthly-status.json
│   │   │   │   ├── news-and-reviews.json
│   │   │   │   ├── products.json
│   │   │   │   ├── releases.json
│   │   │   │   ├── tutorials
│   │   │   │   │   ├── datasource
│   │   │   │   │   │   └── api.ts
│   │   │   │   │   └── p2do
│   │   │   │   │       ├── api.ts
│   │   │   │   │       └── todo-logo.svg
│   │   │   │   └── xmlui.json
│   │   │   ├── github.svg
│   │   │   ├── images
│   │   │   │   ├── apiaction-tutorial
│   │   │   │   │   ├── add-success.png
│   │   │   │   │   ├── apiaction-param.png
│   │   │   │   │   ├── change-completed.png
│   │   │   │   │   ├── change-in-progress.png
│   │   │   │   │   ├── confirm-delete.png
│   │   │   │   │   ├── data-error.png
│   │   │   │   │   ├── data-progress.png
│   │   │   │   │   ├── data-success.png
│   │   │   │   │   ├── display-1.png
│   │   │   │   │   ├── item-deleted.png
│   │   │   │   │   ├── item-updated.png
│   │   │   │   │   ├── missing-api-key.png
│   │   │   │   │   ├── new-item-added.png
│   │   │   │   │   └── test-message.png
│   │   │   │   ├── chat-api
│   │   │   │   │   └── domain-model.svg
│   │   │   │   ├── components
│   │   │   │   │   ├── image
│   │   │   │   │   │   └── breakfast.jpg
│   │   │   │   │   ├── markdown
│   │   │   │   │   │   └── colors.png
│   │   │   │   │   └── modal
│   │   │   │   │       ├── deep_link_dialog_1.jpg
│   │   │   │   │       └── deep_link_dialog_2.jpg
│   │   │   │   ├── create-apps
│   │   │   │   │   ├── collapsed-vertical.png
│   │   │   │   │   ├── using-forms-warning-dialog.png
│   │   │   │   │   └── using-forms.png
│   │   │   │   ├── datasource-tutorial
│   │   │   │   │   ├── data-with-header.png
│   │   │   │   │   ├── filtered-data.png
│   │   │   │   │   ├── filtered-items.png
│   │   │   │   │   ├── initial-page-items.png
│   │   │   │   │   ├── list-items.png
│   │   │   │   │   ├── next-page-items.png
│   │   │   │   │   ├── no-data.png
│   │   │   │   │   ├── pagination-1.jpg
│   │   │   │   │   ├── pagination-1.png
│   │   │   │   │   ├── polling-1.png
│   │   │   │   │   ├── refetch-data.png
│   │   │   │   │   ├── slow-loading.png
│   │   │   │   │   ├── test-message.png
│   │   │   │   │   ├── Thumbs.db
│   │   │   │   │   ├── unconventional-data.png
│   │   │   │   │   └── unfiltered-items.png
│   │   │   │   ├── flower.jpg
│   │   │   │   ├── get-started
│   │   │   │   │   ├── add-new-contact.png
│   │   │   │   │   ├── app-modified.png
│   │   │   │   │   ├── app-start.png
│   │   │   │   │   ├── app-with-boxes.png
│   │   │   │   │   ├── app-with-toast.png
│   │   │   │   │   ├── boilerplate-structure.png
│   │   │   │   │   ├── cl-initial.png
│   │   │   │   │   ├── cl-start.png
│   │   │   │   │   ├── contact-counts.png
│   │   │   │   │   ├── contact-dialog-title.png
│   │   │   │   │   ├── contact-dialog.png
│   │   │   │   │   ├── contact-menus.png
│   │   │   │   │   ├── contact-predicates.png
│   │   │   │   │   ├── context-menu.png
│   │   │   │   │   ├── dashboard-numbers.png
│   │   │   │   │   ├── default-contact-list.png
│   │   │   │   │   ├── delete-contact.png
│   │   │   │   │   ├── delete-task.png
│   │   │   │   │   ├── detailed-template.png
│   │   │   │   │   ├── edit-contact-details.png
│   │   │   │   │   ├── edited-contact-saved.png
│   │   │   │   │   ├── empty-sections.png
│   │   │   │   │   ├── filter-completed.png
│   │   │   │   │   ├── fullwidth-desktop.png
│   │   │   │   │   ├── fullwidth-mobile.png
│   │   │   │   │   ├── initial-table.png
│   │   │   │   │   ├── items-and-badges.png
│   │   │   │   │   ├── loading-message.png
│   │   │   │   │   ├── new-contact-button.png
│   │   │   │   │   ├── new-contact-saved.png
│   │   │   │   │   ├── no-empty-sections.png
│   │   │   │   │   ├── personal-todo-initial.png
│   │   │   │   │   ├── piechart.png
│   │   │   │   │   ├── review-today.png
│   │   │   │   │   ├── rudimentary-dashboard.png
│   │   │   │   │   ├── section-collapsed.png
│   │   │   │   │   ├── sectioned-items.png
│   │   │   │   │   ├── sections-ordered.png
│   │   │   │   │   ├── spacex-list-with-links.png
│   │   │   │   │   ├── spacex-list.png
│   │   │   │   │   ├── start-personal-todo-1.png
│   │   │   │   │   ├── submit-new-contact.png
│   │   │   │   │   ├── submit-new-task.png
│   │   │   │   │   ├── syntax-highlighting.png
│   │   │   │   │   ├── table-with-badge.png
│   │   │   │   │   ├── template-with-card.png
│   │   │   │   │   ├── test-emulated-api.png
│   │   │   │   │   ├── Thumbs.db
│   │   │   │   │   ├── todo-logo.png
│   │   │   │   │   └── xmlui-tools.png
│   │   │   │   ├── HelloApp.png
│   │   │   │   ├── HelloApp2.png
│   │   │   │   ├── logos
│   │   │   │   │   ├── xmlui1.svg
│   │   │   │   │   ├── xmlui2.svg
│   │   │   │   │   ├── xmlui3.svg
│   │   │   │   │   ├── xmlui4.svg
│   │   │   │   │   ├── xmlui5.svg
│   │   │   │   │   ├── xmlui6.svg
│   │   │   │   │   └── xmlui7.svg
│   │   │   │   ├── pdf
│   │   │   │   │   └── dummy-pdf.jpg
│   │   │   │   ├── rendering-engine
│   │   │   │   │   ├── AppEngine-flow.svg
│   │   │   │   │   ├── Component.svg
│   │   │   │   │   ├── CompoundComponent.svg
│   │   │   │   │   ├── RootComponent.svg
│   │   │   │   │   └── tree-with-containers.svg
│   │   │   │   ├── reviewers-guide
│   │   │   │   │   ├── AppEngine-flow.svg
│   │   │   │   │   └── incbutton-in-action.png
│   │   │   │   ├── tools
│   │   │   │   │   └── boilerplate-structure.png
│   │   │   │   ├── try.svg
│   │   │   │   ├── tutorial
│   │   │   │   │   ├── app-chat-history.png
│   │   │   │   │   ├── app-content-placeholder.png
│   │   │   │   │   ├── app-header-and-content.png
│   │   │   │   │   ├── app-links-channel-selected.png
│   │   │   │   │   ├── app-links-click.png
│   │   │   │   │   ├── app-navigation.png
│   │   │   │   │   ├── finished-ex01.png
│   │   │   │   │   ├── finished-ex02.png
│   │   │   │   │   ├── hello.png
│   │   │   │   │   ├── splash-screen-advanced.png
│   │   │   │   │   ├── splash-screen-after-click.png
│   │   │   │   │   ├── splash-screen-centered.png
│   │   │   │   │   ├── splash-screen-events.png
│   │   │   │   │   ├── splash-screen-expression.png
│   │   │   │   │   ├── splash-screen-reuse-after.png
│   │   │   │   │   ├── splash-screen-reuse-before.png
│   │   │   │   │   └── splash-screen.png
│   │   │   │   └── tutorial-01.png
│   │   │   ├── llms.txt
│   │   │   ├── logo-dark.svg
│   │   │   ├── logo.svg
│   │   │   ├── pg-popout.svg
│   │   │   └── xmlui-logo.svg
│   │   ├── serve.json
│   │   └── web.config
│   ├── scripts
│   │   ├── download-latest-xmlui.js
│   │   ├── generate-rss.js
│   │   ├── get-releases.js
│   │   └── utils.js
│   ├── src
│   │   ├── components
│   │   │   ├── BlogOverview.xmlui
│   │   │   ├── BlogPage.xmlui
│   │   │   ├── Boxes.xmlui
│   │   │   ├── Breadcrumb.xmlui
│   │   │   ├── ChangeLog.xmlui
│   │   │   ├── ColorPalette.xmlui
│   │   │   ├── DocumentLinks.xmlui
│   │   │   ├── DocumentPage.xmlui
│   │   │   ├── DocumentPageNoTOC.xmlui
│   │   │   ├── Icons.xmlui
│   │   │   ├── IncButton.xmlui
│   │   │   ├── IncButton2.xmlui
│   │   │   ├── NameValue.xmlui
│   │   │   ├── PageNotFound.xmlui
│   │   │   ├── PaletteItem.xmlui
│   │   │   ├── Palettes.xmlui
│   │   │   ├── SectionHeader.xmlui
│   │   │   ├── TBD.xmlui
│   │   │   ├── Test.xmlui
│   │   │   ├── ThemesIntro.xmlui
│   │   │   ├── ThousandThemes.xmlui
│   │   │   ├── TubeStops.xmlui
│   │   │   ├── TubeStops.xmlui.xs
│   │   │   └── TwoColumnCode.xmlui
│   │   ├── config.ts
│   │   ├── Main.xmlui
│   │   └── themes
│   │       ├── docs-theme.ts
│   │       ├── earthtone.ts
│   │       ├── xmlui-gray-on-default.ts
│   │       ├── xmlui-green-on-default.ts
│   │       └── xmlui-orange-on-default.ts
│   └── tsconfig.json
├── LICENSE
├── package-lock.json
├── package.json
├── packages
│   ├── tsconfig.json
│   ├── xmlui-animations
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── Animation.tsx
│   │       ├── AnimationNative.tsx
│   │       ├── FadeAnimation.tsx
│   │       ├── FadeInAnimation.tsx
│   │       ├── FadeOutAnimation.tsx
│   │       ├── index.tsx
│   │       ├── ScaleAnimation.tsx
│   │       └── SlideInAnimation.tsx
│   ├── xmlui-devtools
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   ├── src
│   │   │   ├── devtools
│   │   │   │   ├── DevTools.tsx
│   │   │   │   ├── DevToolsNative.module.scss
│   │   │   │   ├── DevToolsNative.tsx
│   │   │   │   ├── ModalDialog.module.scss
│   │   │   │   ├── ModalDialog.tsx
│   │   │   │   ├── ModalVisibilityContext.tsx
│   │   │   │   ├── Tooltip.module.scss
│   │   │   │   ├── Tooltip.tsx
│   │   │   │   └── utils.ts
│   │   │   ├── editor
│   │   │   │   └── Editor.tsx
│   │   │   └── index.tsx
│   │   └── vite.config-overrides.ts
│   ├── xmlui-hello-world
│   │   ├── .gitignore
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── HelloWorld.module.scss
│   │       ├── HelloWorld.tsx
│   │       ├── HelloWorldNative.tsx
│   │       └── index.tsx
│   ├── xmlui-os-frames
│   │   ├── .gitignore
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── index.tsx
│   │       ├── IPhoneFrame.module.scss
│   │       ├── IPhoneFrame.tsx
│   │       ├── MacOSAppFrame.module.scss
│   │       ├── MacOSAppFrame.tsx
│   │       ├── WindowsAppFrame.module.scss
│   │       └── WindowsAppFrame.tsx
│   ├── xmlui-pdf
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   ├── components
│   │   │   │   └── Pdf.xmlui
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── index.tsx
│   │       ├── LazyPdfNative.tsx
│   │       ├── Pdf.module.scss
│   │       └── Pdf.tsx
│   ├── xmlui-playground
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── hooks
│   │       │   ├── usePlayground.ts
│   │       │   └── useToast.ts
│   │       ├── index.tsx
│   │       ├── playground
│   │       │   ├── Box.module.scss
│   │       │   ├── Box.tsx
│   │       │   ├── CodeSelector.tsx
│   │       │   ├── ConfirmationDialog.module.scss
│   │       │   ├── ConfirmationDialog.tsx
│   │       │   ├── Editor.tsx
│   │       │   ├── Header.module.scss
│   │       │   ├── Header.tsx
│   │       │   ├── Playground.tsx
│   │       │   ├── PlaygroundContent.module.scss
│   │       │   ├── PlaygroundContent.tsx
│   │       │   ├── PlaygroundNative.module.scss
│   │       │   ├── PlaygroundNative.tsx
│   │       │   ├── Preview.module.scss
│   │       │   ├── Preview.tsx
│   │       │   ├── Select.module.scss
│   │       │   ├── StandalonePlayground.tsx
│   │       │   ├── StandalonePlaygroundNative.module.scss
│   │       │   ├── StandalonePlaygroundNative.tsx
│   │       │   ├── ThemeSwitcher.module.scss
│   │       │   ├── ThemeSwitcher.tsx
│   │       │   ├── ToneSwitcher.tsx
│   │       │   ├── Tooltip.module.scss
│   │       │   ├── Tooltip.tsx
│   │       │   └── utils.ts
│   │       ├── providers
│   │       │   ├── Toast.module.scss
│   │       │   └── ToastProvider.tsx
│   │       ├── state
│   │       │   └── store.ts
│   │       ├── themes
│   │       │   └── theme.ts
│   │       └── utils
│   │           └── helpers.ts
│   ├── xmlui-search
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── index.tsx
│   │       ├── Search.module.scss
│   │       └── Search.tsx
│   ├── xmlui-spreadsheet
│   │   ├── .gitignore
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── index.tsx
│   │       ├── Spreadsheet.tsx
│   │       └── SpreadsheetNative.tsx
│   └── xmlui-website-blocks
│       ├── .gitignore
│       ├── CHANGELOG.md
│       ├── demo
│       │   ├── components
│       │   │   ├── HeroBackgroundBreakoutPage.xmlui
│       │   │   ├── HeroBackgroundsPage.xmlui
│       │   │   ├── HeroContentsPage.xmlui
│       │   │   ├── HeroTextAlignPage.xmlui
│       │   │   ├── HeroTextPage.xmlui
│       │   │   └── HeroTonesPage.xmlui
│       │   ├── Main.xmlui
│       │   └── themes
│       │       └── default.ts
│       ├── index.html
│       ├── index.ts
│       ├── meta
│       │   └── componentsMetadata.ts
│       ├── package.json
│       ├── public
│       │   └── resources
│       │       ├── building.jpg
│       │       └── xmlui-logo.svg
│       └── src
│           ├── Carousel
│           │   ├── Carousel.module.scss
│           │   ├── Carousel.tsx
│           │   ├── CarouselContext.tsx
│           │   └── CarouselNative.tsx
│           ├── FancyButton
│           │   ├── FancyButton.module.scss
│           │   ├── FancyButton.tsx
│           │   └── FancyButton.xmlui
│           ├── Hello
│           │   ├── Hello.tsx
│           │   ├── Hello.xmlui
│           │   └── Hello.xmlui.xs
│           ├── HeroSection
│           │   ├── HeroSection.module.scss
│           │   ├── HeroSection.spec.ts
│           │   ├── HeroSection.tsx
│           │   └── HeroSectionNative.tsx
│           ├── index.tsx
│           ├── ScrollToTop
│           │   ├── ScrollToTop.module.scss
│           │   ├── ScrollToTop.tsx
│           │   └── ScrollToTopNative.tsx
│           └── vite-env.d.ts
├── playwright.config.ts
├── README.md
├── tools
│   ├── codefence
│   │   └── xmlui-code-fence-docs.md
│   ├── create-app
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── create-app.ts
│   │   ├── helpers
│   │   │   ├── copy.ts
│   │   │   ├── get-pkg-manager.ts
│   │   │   ├── git.ts
│   │   │   ├── install.ts
│   │   │   ├── is-folder-empty.ts
│   │   │   ├── is-writeable.ts
│   │   │   ├── make-dir.ts
│   │   │   └── validate-pkg.ts
│   │   ├── index.ts
│   │   ├── package.json
│   │   ├── templates
│   │   │   ├── default
│   │   │   │   └── ts
│   │   │   │       ├── gitignore
│   │   │   │       ├── index.html
│   │   │   │       ├── index.ts
│   │   │   │       ├── public
│   │   │   │       │   ├── mockServiceWorker.js
│   │   │   │       │   ├── resources
│   │   │   │       │   │   ├── favicon.ico
│   │   │   │       │   │   └── xmlui-logo.svg
│   │   │   │       │   └── serve.json
│   │   │   │       └── src
│   │   │   │           ├── components
│   │   │   │           │   ├── ApiAware.xmlui
│   │   │   │           │   ├── Home.xmlui
│   │   │   │           │   ├── IncButton.xmlui
│   │   │   │           │   └── PagePanel.xmlui
│   │   │   │           ├── config.ts
│   │   │   │           └── Main.xmlui
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   └── tsconfig.json
│   ├── create-xmlui-hello-world
│   │   ├── index.js
│   │   └── package.json
│   └── vscode
│       ├── .gitignore
│       ├── .vscode
│       │   ├── launch.json
│       │   └── tasks.json
│       ├── .vscodeignore
│       ├── build.sh
│       ├── CHANGELOG.md
│       ├── esbuild.js
│       ├── eslint.config.mjs
│       ├── formatter-docs.md
│       ├── generate-test-sample.sh
│       ├── LICENSE.md
│       ├── package-lock.json
│       ├── package.json
│       ├── README.md
│       ├── resources
│       │   ├── xmlui-logo.png
│       │   └── xmlui-markup-syntax-highlighting.png
│       ├── src
│       │   ├── extension.ts
│       │   └── server.ts
│       ├── syntaxes
│       │   └── xmlui.tmLanguage.json
│       ├── test-samples
│       │   └── sample.xmlui
│       ├── tsconfig.json
│       └── tsconfig.tsbuildinfo
├── turbo.json
└── xmlui
    ├── .gitignore
    ├── bin
    │   ├── bootstrap.cjs
    │   ├── bootstrap.js
    │   ├── build-lib.ts
    │   ├── build.ts
    │   ├── index.ts
    │   ├── preview.ts
    │   ├── start.ts
    │   ├── vite-xmlui-plugin.ts
    │   └── viteConfig.ts
    ├── CHANGELOG.md
    ├── conventions
    │   ├── component-qa-checklist.md
    │   ├── copilot-conventions.md
    │   ├── create-xmlui-components.md
    │   ├── mermaid.md
    │   ├── testing-conventions.md
    │   └── xmlui-in-a-nutshell.md
    ├── dev-docs
    │   ├── accessibility.md
    │   ├── build-system.md
    │   ├── build-xmlui.md
    │   ├── component-behaviors.md
    │   ├── component-metadata.md
    │   ├── components-with-options.md
    │   ├── containers.md
    │   ├── data-operations.md
    │   ├── glossary.md
    │   ├── index.md
    │   ├── next
    │   │   ├── component-dev-guide.md
    │   │   ├── configuration-management-enhancement-summary.md
    │   │   ├── documentation-scripts-refactoring-complete-summary.md
    │   │   ├── documentation-scripts-refactoring-plan.md
    │   │   ├── duplicate-pattern-extraction-summary.md
    │   │   ├── error-handling-standardization-summary.md
    │   │   ├── generating-component-reference.md
    │   │   ├── index.md
    │   │   ├── logging-consistency-implementation-summary.md
    │   │   ├── project-build.md
    │   │   ├── project-structure.md
    │   │   ├── theme-context.md
    │   │   ├── tiptap-design-considerations.md
    │   │   ├── working-with-code.md
    │   │   ├── xmlui-runtime-architecture
    │   │   └── xmlui-wcag-accessibility-report.md
    │   ├── react-fundamentals.md
    │   ├── release-method.md
    │   ├── standalone-app.md
    │   ├── theme-variables-refactoring.md
    │   ├── ud-components.md
    │   └── xmlui-repo.md
    ├── package.json
    ├── scripts
    │   ├── coverage-only.js
    │   ├── e2e-test-summary.js
    │   ├── extract-component-metadata.js
    │   ├── generate-docs
    │   │   ├── build-downloads-map.mjs
    │   │   ├── build-pages-map.mjs
    │   │   ├── components-config.json
    │   │   ├── configuration-management.mjs
    │   │   ├── constants.mjs
    │   │   ├── create-theme-files.mjs
    │   │   ├── DocsGenerator.mjs
    │   │   ├── error-handling.mjs
    │   │   ├── extensions-config.json
    │   │   ├── folders.mjs
    │   │   ├── generate-summary-files.mjs
    │   │   ├── get-docs.mjs
    │   │   ├── input-handler.mjs
    │   │   ├── logger.mjs
    │   │   ├── logging-standards.mjs
    │   │   ├── MetadataProcessor.mjs
    │   │   ├── pattern-utilities.mjs
    │   │   └── utils.mjs
    │   ├── generate-metadata-markdown.js
    │   ├── get-langserver-metadata.js
    │   ├── inline-links.mjs
    │   └── README-e2e-summary.md
    ├── src
    │   ├── abstractions
    │   │   ├── _conventions.md
    │   │   ├── ActionDefs.ts
    │   │   ├── AppContextDefs.ts
    │   │   ├── ComponentDefs.ts
    │   │   ├── ContainerDefs.ts
    │   │   ├── ExtensionDefs.ts
    │   │   ├── FunctionDefs.ts
    │   │   ├── RendererDefs.ts
    │   │   ├── scripting
    │   │   │   ├── BlockScope.ts
    │   │   │   ├── Compilation.ts
    │   │   │   ├── LogicalThread.ts
    │   │   │   ├── LoopScope.ts
    │   │   │   ├── modules.ts
    │   │   │   ├── ScriptParserError.ts
    │   │   │   ├── Token.ts
    │   │   │   ├── TryScope.ts
    │   │   │   └── TryScopeExp.ts
    │   │   └── ThemingDefs.ts
    │   ├── components
    │   │   ├── _conventions.md
    │   │   ├── abstractions.ts
    │   │   ├── Accordion
    │   │   │   ├── Accordion.md
    │   │   │   ├── Accordion.module.scss
    │   │   │   ├── Accordion.spec.ts
    │   │   │   ├── Accordion.tsx
    │   │   │   ├── AccordionContext.tsx
    │   │   │   ├── AccordionItem.tsx
    │   │   │   ├── AccordionItemNative.tsx
    │   │   │   └── AccordionNative.tsx
    │   │   ├── Animation
    │   │   │   └── AnimationNative.tsx
    │   │   ├── APICall
    │   │   │   ├── APICall.md
    │   │   │   ├── APICall.spec.ts
    │   │   │   ├── APICall.tsx
    │   │   │   └── APICallNative.tsx
    │   │   ├── App
    │   │   │   ├── App.md
    │   │   │   ├── App.module.scss
    │   │   │   ├── App.spec.ts
    │   │   │   ├── App.tsx
    │   │   │   ├── AppLayoutContext.ts
    │   │   │   ├── AppNative.tsx
    │   │   │   ├── AppStateContext.ts
    │   │   │   ├── doc-resources
    │   │   │   │   ├── condensed-sticky.xmlui
    │   │   │   │   ├── condensed.xmlui
    │   │   │   │   ├── horizontal-sticky.xmlui
    │   │   │   │   ├── horizontal.xmlui
    │   │   │   │   ├── vertical-full-header.xmlui
    │   │   │   │   ├── vertical-sticky.xmlui
    │   │   │   │   └── vertical.xmlui
    │   │   │   ├── IndexerContext.ts
    │   │   │   ├── LinkInfoContext.ts
    │   │   │   ├── SearchContext.tsx
    │   │   │   ├── Sheet.module.scss
    │   │   │   └── Sheet.tsx
    │   │   ├── AppHeader
    │   │   │   ├── AppHeader.md
    │   │   │   ├── AppHeader.module.scss
    │   │   │   ├── AppHeader.spec.ts
    │   │   │   ├── AppHeader.tsx
    │   │   │   └── AppHeaderNative.tsx
    │   │   ├── AppState
    │   │   │   ├── AppState.md
    │   │   │   ├── AppState.spec.ts
    │   │   │   ├── AppState.tsx
    │   │   │   └── AppStateNative.tsx
    │   │   ├── AutoComplete
    │   │   │   ├── AutoComplete.md
    │   │   │   ├── AutoComplete.module.scss
    │   │   │   ├── AutoComplete.spec.ts
    │   │   │   ├── AutoComplete.tsx
    │   │   │   ├── AutoCompleteContext.tsx
    │   │   │   └── AutoCompleteNative.tsx
    │   │   ├── Avatar
    │   │   │   ├── Avatar.md
    │   │   │   ├── Avatar.module.scss
    │   │   │   ├── Avatar.spec.ts
    │   │   │   ├── Avatar.tsx
    │   │   │   └── AvatarNative.tsx
    │   │   ├── Backdrop
    │   │   │   ├── Backdrop.md
    │   │   │   ├── Backdrop.module.scss
    │   │   │   ├── Backdrop.spec.ts
    │   │   │   ├── Backdrop.tsx
    │   │   │   └── BackdropNative.tsx
    │   │   ├── Badge
    │   │   │   ├── Badge.md
    │   │   │   ├── Badge.module.scss
    │   │   │   ├── Badge.spec.ts
    │   │   │   ├── Badge.tsx
    │   │   │   └── BadgeNative.tsx
    │   │   ├── Bookmark
    │   │   │   ├── Bookmark.md
    │   │   │   ├── Bookmark.module.scss
    │   │   │   ├── Bookmark.spec.ts
    │   │   │   ├── Bookmark.tsx
    │   │   │   └── BookmarkNative.tsx
    │   │   ├── Breakout
    │   │   │   ├── Breakout.module.scss
    │   │   │   ├── Breakout.spec.ts
    │   │   │   ├── Breakout.tsx
    │   │   │   └── BreakoutNative.tsx
    │   │   ├── Button
    │   │   │   ├── Button-style.spec.ts
    │   │   │   ├── Button.md
    │   │   │   ├── Button.module.scss
    │   │   │   ├── Button.spec.ts
    │   │   │   ├── Button.tsx
    │   │   │   └── ButtonNative.tsx
    │   │   ├── Card
    │   │   │   ├── Card.md
    │   │   │   ├── Card.module.scss
    │   │   │   ├── Card.spec.ts
    │   │   │   ├── Card.tsx
    │   │   │   └── CardNative.tsx
    │   │   ├── Carousel
    │   │   │   ├── Carousel.md
    │   │   │   ├── Carousel.module.scss
    │   │   │   ├── Carousel.spec.ts
    │   │   │   ├── Carousel.tsx
    │   │   │   ├── CarouselContext.tsx
    │   │   │   ├── CarouselItem.tsx
    │   │   │   ├── CarouselItemNative.tsx
    │   │   │   └── CarouselNative.tsx
    │   │   ├── ChangeListener
    │   │   │   ├── ChangeListener.md
    │   │   │   ├── ChangeListener.spec.ts
    │   │   │   ├── ChangeListener.tsx
    │   │   │   └── ChangeListenerNative.tsx
    │   │   ├── chart-color-schemes.ts
    │   │   ├── Charts
    │   │   │   ├── AreaChart
    │   │   │   │   ├── AreaChart.md
    │   │   │   │   ├── AreaChart.spec.ts
    │   │   │   │   ├── AreaChart.tsx
    │   │   │   │   └── AreaChartNative.tsx
    │   │   │   ├── BarChart
    │   │   │   │   ├── BarChart.md
    │   │   │   │   ├── BarChart.module.scss
    │   │   │   │   ├── BarChart.spec.ts
    │   │   │   │   ├── BarChart.tsx
    │   │   │   │   └── BarChartNative.tsx
    │   │   │   ├── DonutChart
    │   │   │   │   ├── DonutChart.spec.ts
    │   │   │   │   └── DonutChart.tsx
    │   │   │   ├── LabelList
    │   │   │   │   ├── LabelList.module.scss
    │   │   │   │   ├── LabelList.spec.ts
    │   │   │   │   ├── LabelList.tsx
    │   │   │   │   └── LabelListNative.tsx
    │   │   │   ├── Legend
    │   │   │   │   ├── Legend.spec.ts
    │   │   │   │   ├── Legend.tsx
    │   │   │   │   └── LegendNative.tsx
    │   │   │   ├── LineChart
    │   │   │   │   ├── LineChart.md
    │   │   │   │   ├── LineChart.module.scss
    │   │   │   │   ├── LineChart.spec.ts
    │   │   │   │   ├── LineChart.tsx
    │   │   │   │   └── LineChartNative.tsx
    │   │   │   ├── PieChart
    │   │   │   │   ├── PieChart.md
    │   │   │   │   ├── PieChart.spec.ts
    │   │   │   │   ├── PieChart.tsx
    │   │   │   │   ├── PieChartNative.module.scss
    │   │   │   │   └── PieChartNative.tsx
    │   │   │   ├── RadarChart
    │   │   │   │   ├── RadarChart.md
    │   │   │   │   ├── RadarChart.spec.ts
    │   │   │   │   ├── RadarChart.tsx
    │   │   │   │   └── RadarChartNative.tsx
    │   │   │   ├── Tooltip
    │   │   │   │   ├── TooltipContent.module.scss
    │   │   │   │   ├── TooltipContent.spec.ts
    │   │   │   │   └── TooltipContent.tsx
    │   │   │   └── utils
    │   │   │       ├── abstractions.ts
    │   │   │       └── ChartProvider.tsx
    │   │   ├── Checkbox
    │   │   │   ├── Checkbox.md
    │   │   │   ├── Checkbox.spec.ts
    │   │   │   └── Checkbox.tsx
    │   │   ├── CodeBlock
    │   │   │   ├── CodeBlock.module.scss
    │   │   │   ├── CodeBlock.spec.ts
    │   │   │   ├── CodeBlock.tsx
    │   │   │   ├── CodeBlockNative.tsx
    │   │   │   └── highlight-code.ts
    │   │   ├── collectedComponentMetadata.ts
    │   │   ├── ColorPicker
    │   │   │   ├── ColorPicker.md
    │   │   │   ├── ColorPicker.module.scss
    │   │   │   ├── ColorPicker.spec.ts
    │   │   │   ├── ColorPicker.tsx
    │   │   │   └── ColorPickerNative.tsx
    │   │   ├── Column
    │   │   │   ├── Column.md
    │   │   │   ├── Column.tsx
    │   │   │   ├── ColumnNative.tsx
    │   │   │   ├── doc-resources
    │   │   │   │   └── list-component-data.js
    │   │   │   └── TableContext.tsx
    │   │   ├── component-utils.ts
    │   │   ├── ComponentProvider.tsx
    │   │   ├── ComponentRegistryContext.tsx
    │   │   ├── container-helpers.tsx
    │   │   ├── ContentSeparator
    │   │   │   ├── ContentSeparator.md
    │   │   │   ├── ContentSeparator.module.scss
    │   │   │   ├── ContentSeparator.spec.ts
    │   │   │   ├── ContentSeparator.tsx
    │   │   │   └── ContentSeparatorNative.tsx
    │   │   ├── DataSource
    │   │   │   ├── DataSource.md
    │   │   │   └── DataSource.tsx
    │   │   ├── DateInput
    │   │   │   ├── DateInput.md
    │   │   │   ├── DateInput.module.scss
    │   │   │   ├── DateInput.spec.ts
    │   │   │   ├── DateInput.tsx
    │   │   │   └── DateInputNative.tsx
    │   │   ├── DatePicker
    │   │   │   ├── DatePicker.md
    │   │   │   ├── DatePicker.module.scss
    │   │   │   ├── DatePicker.spec.ts
    │   │   │   ├── DatePicker.tsx
    │   │   │   └── DatePickerNative.tsx
    │   │   ├── DropdownMenu
    │   │   │   ├── DropdownMenu.md
    │   │   │   ├── DropdownMenu.module.scss
    │   │   │   ├── DropdownMenu.spec.ts
    │   │   │   ├── DropdownMenu.tsx
    │   │   │   ├── DropdownMenuNative.tsx
    │   │   │   ├── MenuItem.md
    │   │   │   └── SubMenuItem.md
    │   │   ├── EmojiSelector
    │   │   │   ├── EmojiSelector.md
    │   │   │   ├── EmojiSelector.spec.ts
    │   │   │   ├── EmojiSelector.tsx
    │   │   │   └── EmojiSelectorNative.tsx
    │   │   ├── ExpandableItem
    │   │   │   ├── ExpandableItem.module.scss
    │   │   │   ├── ExpandableItem.spec.ts
    │   │   │   ├── ExpandableItem.tsx
    │   │   │   └── ExpandableItemNative.tsx
    │   │   ├── FileInput
    │   │   │   ├── FileInput.md
    │   │   │   ├── FileInput.module.scss
    │   │   │   ├── FileInput.spec.ts
    │   │   │   ├── FileInput.tsx
    │   │   │   └── FileInputNative.tsx
    │   │   ├── FileUploadDropZone
    │   │   │   ├── FileUploadDropZone.md
    │   │   │   ├── FileUploadDropZone.module.scss
    │   │   │   ├── FileUploadDropZone.spec.ts
    │   │   │   ├── FileUploadDropZone.tsx
    │   │   │   └── FileUploadDropZoneNative.tsx
    │   │   ├── FlowLayout
    │   │   │   ├── FlowLayout.md
    │   │   │   ├── FlowLayout.module.scss
    │   │   │   ├── FlowLayout.spec.ts
    │   │   │   ├── FlowLayout.spec.ts-snapshots
    │   │   │   │   └── Edge-cases-boxShadow-is-not-clipped-1-non-smoke-darwin.png
    │   │   │   ├── FlowLayout.tsx
    │   │   │   └── FlowLayoutNative.tsx
    │   │   ├── Footer
    │   │   │   ├── Footer.md
    │   │   │   ├── Footer.module.scss
    │   │   │   ├── Footer.spec.ts
    │   │   │   ├── Footer.tsx
    │   │   │   └── FooterNative.tsx
    │   │   ├── Form
    │   │   │   ├── Form.md
    │   │   │   ├── Form.module.scss
    │   │   │   ├── Form.spec.ts
    │   │   │   ├── Form.tsx
    │   │   │   ├── formActions.ts
    │   │   │   ├── FormContext.ts
    │   │   │   └── FormNative.tsx
    │   │   ├── FormItem
    │   │   │   ├── FormItem.md
    │   │   │   ├── FormItem.module.scss
    │   │   │   ├── FormItem.spec.ts
    │   │   │   ├── FormItem.tsx
    │   │   │   ├── FormItemNative.tsx
    │   │   │   ├── HelperText.module.scss
    │   │   │   ├── HelperText.tsx
    │   │   │   ├── ItemWithLabel.tsx
    │   │   │   └── Validations.ts
    │   │   ├── FormSection
    │   │   │   ├── FormSection.md
    │   │   │   ├── FormSection.ts
    │   │   │   └── FormSection.xmlui
    │   │   ├── Fragment
    │   │   │   ├── Fragment.spec.ts
    │   │   │   └── Fragment.tsx
    │   │   ├── Heading
    │   │   │   ├── abstractions.ts
    │   │   │   ├── H1.md
    │   │   │   ├── H1.spec.ts
    │   │   │   ├── H2.md
    │   │   │   ├── H2.spec.ts
    │   │   │   ├── H3.md
    │   │   │   ├── H3.spec.ts
    │   │   │   ├── H4.md
    │   │   │   ├── H4.spec.ts
    │   │   │   ├── H5.md
    │   │   │   ├── H5.spec.ts
    │   │   │   ├── H6.md
    │   │   │   ├── H6.spec.ts
    │   │   │   ├── Heading.md
    │   │   │   ├── Heading.module.scss
    │   │   │   ├── Heading.spec.ts
    │   │   │   ├── Heading.tsx
    │   │   │   └── HeadingNative.tsx
    │   │   ├── HoverCard
    │   │   │   ├── HoverCard.tsx
    │   │   │   └── HovercardNative.tsx
    │   │   ├── HtmlTags
    │   │   │   ├── HtmlTags.module.scss
    │   │   │   ├── HtmlTags.spec.ts
    │   │   │   └── HtmlTags.tsx
    │   │   ├── Icon
    │   │   │   ├── AdmonitionDanger.tsx
    │   │   │   ├── AdmonitionInfo.tsx
    │   │   │   ├── AdmonitionNote.tsx
    │   │   │   ├── AdmonitionTip.tsx
    │   │   │   ├── AdmonitionWarning.tsx
    │   │   │   ├── ApiIcon.tsx
    │   │   │   ├── ArrowDropDown.module.scss
    │   │   │   ├── ArrowDropDown.tsx
    │   │   │   ├── ArrowDropUp.module.scss
    │   │   │   ├── ArrowDropUp.tsx
    │   │   │   ├── ArrowLeft.module.scss
    │   │   │   ├── ArrowLeft.tsx
    │   │   │   ├── ArrowRight.module.scss
    │   │   │   ├── ArrowRight.tsx
    │   │   │   ├── Attach.tsx
    │   │   │   ├── Binding.module.scss
    │   │   │   ├── Binding.tsx
    │   │   │   ├── BoardIcon.tsx
    │   │   │   ├── BoxIcon.tsx
    │   │   │   ├── CheckIcon.tsx
    │   │   │   ├── ChevronDownIcon.tsx
    │   │   │   ├── ChevronLeft.tsx
    │   │   │   ├── ChevronRight.tsx
    │   │   │   ├── ChevronUpIcon.tsx
    │   │   │   ├── CodeFileIcon.tsx
    │   │   │   ├── CodeSandbox.tsx
    │   │   │   ├── CompactListIcon.tsx
    │   │   │   ├── ContentCopyIcon.tsx
    │   │   │   ├── DarkToLightIcon.tsx
    │   │   │   ├── DatabaseIcon.module.scss
    │   │   │   ├── DatabaseIcon.tsx
    │   │   │   ├── DocFileIcon.tsx
    │   │   │   ├── DocIcon.tsx
    │   │   │   ├── DotMenuHorizontalIcon.tsx
    │   │   │   ├── DotMenuIcon.tsx
    │   │   │   ├── EmailIcon.tsx
    │   │   │   ├── EmptyFolderIcon.tsx
    │   │   │   ├── ErrorIcon.tsx
    │   │   │   ├── ExpressionIcon.tsx
    │   │   │   ├── FillPlusCricleIcon.tsx
    │   │   │   ├── FilterIcon.tsx
    │   │   │   ├── FolderIcon.tsx
    │   │   │   ├── GlobeIcon.tsx
    │   │   │   ├── HomeIcon.tsx
    │   │   │   ├── HyperLinkIcon.tsx
    │   │   │   ├── Icon.md
    │   │   │   ├── Icon.module.scss
    │   │   │   ├── Icon.spec.ts
    │   │   │   ├── Icon.tsx
    │   │   │   ├── IconNative.tsx
    │   │   │   ├── ImageFileIcon.tsx
    │   │   │   ├── Inspect.tsx
    │   │   │   ├── LightToDark.tsx
    │   │   │   ├── LinkIcon.tsx
    │   │   │   ├── ListIcon.tsx
    │   │   │   ├── LooseListIcon.tsx
    │   │   │   ├── MoonIcon.tsx
    │   │   │   ├── MoreOptionsIcon.tsx
    │   │   │   ├── NoSortIcon.tsx
    │   │   │   ├── PDFIcon.tsx
    │   │   │   ├── PenIcon.tsx
    │   │   │   ├── PhoneIcon.tsx
    │   │   │   ├── PhotoIcon.tsx
    │   │   │   ├── PlusIcon.tsx
    │   │   │   ├── SearchIcon.tsx
    │   │   │   ├── ShareIcon.tsx
    │   │   │   ├── SortAscendingIcon.tsx
    │   │   │   ├── SortDescendingIcon.tsx
    │   │   │   ├── StarsIcon.tsx
    │   │   │   ├── SunIcon.tsx
    │   │   │   ├── svg
    │   │   │   │   ├── admonition_danger.svg
    │   │   │   │   ├── admonition_info.svg
    │   │   │   │   ├── admonition_note.svg
    │   │   │   │   ├── admonition_tip.svg
    │   │   │   │   ├── admonition_warning.svg
    │   │   │   │   ├── api.svg
    │   │   │   │   ├── arrow-dropdown.svg
    │   │   │   │   ├── arrow-left.svg
    │   │   │   │   ├── arrow-right.svg
    │   │   │   │   ├── arrow-up.svg
    │   │   │   │   ├── attach.svg
    │   │   │   │   ├── binding.svg
    │   │   │   │   ├── box.svg
    │   │   │   │   ├── bulb.svg
    │   │   │   │   ├── code-file.svg
    │   │   │   │   ├── code-sandbox.svg
    │   │   │   │   ├── dark_to_light.svg
    │   │   │   │   ├── database.svg
    │   │   │   │   ├── doc.svg
    │   │   │   │   ├── empty-folder.svg
    │   │   │   │   ├── expression.svg
    │   │   │   │   ├── eye-closed.svg
    │   │   │   │   ├── eye-dark.svg
    │   │   │   │   ├── eye.svg
    │   │   │   │   ├── file-text.svg
    │   │   │   │   ├── filter.svg
    │   │   │   │   ├── folder.svg
    │   │   │   │   ├── img.svg
    │   │   │   │   ├── inspect.svg
    │   │   │   │   ├── light_to_dark.svg
    │   │   │   │   ├── moon.svg
    │   │   │   │   ├── pdf.svg
    │   │   │   │   ├── photo.svg
    │   │   │   │   ├── share.svg
    │   │   │   │   ├── stars.svg
    │   │   │   │   ├── sun.svg
    │   │   │   │   ├── trending-down.svg
    │   │   │   │   ├── trending-level.svg
    │   │   │   │   ├── trending-up.svg
    │   │   │   │   ├── txt.svg
    │   │   │   │   ├── unknown-file.svg
    │   │   │   │   ├── unlink.svg
    │   │   │   │   └── xls.svg
    │   │   │   ├── TableDeleteColumnIcon.tsx
    │   │   │   ├── TableDeleteRowIcon.tsx
    │   │   │   ├── TableInsertColumnIcon.tsx
    │   │   │   ├── TableInsertRowIcon.tsx
    │   │   │   ├── TrashIcon.tsx
    │   │   │   ├── TrendingDownIcon.tsx
    │   │   │   ├── TrendingLevelIcon.tsx
    │   │   │   ├── TrendingUpIcon.tsx
    │   │   │   ├── TxtIcon.tsx
    │   │   │   ├── UnknownFileIcon.tsx
    │   │   │   ├── UnlinkIcon.tsx
    │   │   │   ├── UserIcon.tsx
    │   │   │   ├── WarningIcon.tsx
    │   │   │   └── XlsIcon.tsx
    │   │   ├── IconProvider.tsx
    │   │   ├── IconRegistryContext.tsx
    │   │   ├── IFrame
    │   │   │   ├── IFrame.md
    │   │   │   ├── IFrame.module.scss
    │   │   │   ├── IFrame.spec.ts
    │   │   │   ├── IFrame.tsx
    │   │   │   └── IFrameNative.tsx
    │   │   ├── Image
    │   │   │   ├── Image.md
    │   │   │   ├── Image.module.scss
    │   │   │   ├── Image.spec.ts
    │   │   │   ├── Image.tsx
    │   │   │   └── ImageNative.tsx
    │   │   ├── Input
    │   │   │   ├── index.ts
    │   │   │   ├── InputAdornment.module.scss
    │   │   │   ├── InputAdornment.tsx
    │   │   │   ├── InputDivider.module.scss
    │   │   │   ├── InputDivider.tsx
    │   │   │   ├── InputLabel.module.scss
    │   │   │   ├── InputLabel.tsx
    │   │   │   ├── PartialInput.module.scss
    │   │   │   └── PartialInput.tsx
    │   │   ├── InspectButton
    │   │   │   ├── InspectButton.module.scss
    │   │   │   └── InspectButton.tsx
    │   │   ├── Items
    │   │   │   ├── Items.md
    │   │   │   ├── Items.spec.ts
    │   │   │   ├── Items.tsx
    │   │   │   └── ItemsNative.tsx
    │   │   ├── Link
    │   │   │   ├── Link.md
    │   │   │   ├── Link.module.scss
    │   │   │   ├── Link.spec.ts
    │   │   │   ├── Link.tsx
    │   │   │   └── LinkNative.tsx
    │   │   ├── List
    │   │   │   ├── doc-resources
    │   │   │   │   └── list-component-data.js
    │   │   │   ├── List.md
    │   │   │   ├── List.module.scss
    │   │   │   ├── List.spec.ts
    │   │   │   ├── List.tsx
    │   │   │   └── ListNative.tsx
    │   │   ├── Logo
    │   │   │   ├── doc-resources
    │   │   │   │   └── xmlui-logo.svg
    │   │   │   ├── Logo.md
    │   │   │   ├── Logo.tsx
    │   │   │   └── LogoNative.tsx
    │   │   ├── Markdown
    │   │   │   ├── CodeText.module.scss
    │   │   │   ├── CodeText.tsx
    │   │   │   ├── Markdown.md
    │   │   │   ├── Markdown.module.scss
    │   │   │   ├── Markdown.spec.ts
    │   │   │   ├── Markdown.tsx
    │   │   │   ├── MarkdownNative.tsx
    │   │   │   ├── parse-binding-expr.ts
    │   │   │   └── utils.ts
    │   │   ├── metadata-helpers.ts
    │   │   ├── ModalDialog
    │   │   │   ├── ConfirmationModalContextProvider.tsx
    │   │   │   ├── Dialog.module.scss
    │   │   │   ├── Dialog.tsx
    │   │   │   ├── ModalDialog.md
    │   │   │   ├── ModalDialog.module.scss
    │   │   │   ├── ModalDialog.spec.ts
    │   │   │   ├── ModalDialog.tsx
    │   │   │   ├── ModalDialogNative.tsx
    │   │   │   └── ModalVisibilityContext.tsx
    │   │   ├── NavGroup
    │   │   │   ├── NavGroup.md
    │   │   │   ├── NavGroup.module.scss
    │   │   │   ├── NavGroup.spec.ts
    │   │   │   ├── NavGroup.tsx
    │   │   │   ├── NavGroupContext.ts
    │   │   │   └── NavGroupNative.tsx
    │   │   ├── NavLink
    │   │   │   ├── NavLink.md
    │   │   │   ├── NavLink.module.scss
    │   │   │   ├── NavLink.spec.ts
    │   │   │   ├── NavLink.tsx
    │   │   │   └── NavLinkNative.tsx
    │   │   ├── NavPanel
    │   │   │   ├── NavPanel.md
    │   │   │   ├── NavPanel.module.scss
    │   │   │   ├── NavPanel.spec.ts
    │   │   │   ├── NavPanel.tsx
    │   │   │   └── NavPanelNative.tsx
    │   │   ├── NestedApp
    │   │   │   ├── AppWithCodeView.module.scss
    │   │   │   ├── AppWithCodeView.tsx
    │   │   │   ├── AppWithCodeViewNative.tsx
    │   │   │   ├── defaultProps.tsx
    │   │   │   ├── logo.svg
    │   │   │   ├── NestedApp.module.scss
    │   │   │   ├── NestedApp.tsx
    │   │   │   ├── NestedAppNative.tsx
    │   │   │   ├── Tooltip.module.scss
    │   │   │   ├── Tooltip.tsx
    │   │   │   └── utils.ts
    │   │   ├── NoResult
    │   │   │   ├── NoResult.md
    │   │   │   ├── NoResult.module.scss
    │   │   │   ├── NoResult.spec.ts
    │   │   │   ├── NoResult.tsx
    │   │   │   └── NoResultNative.tsx
    │   │   ├── NumberBox
    │   │   │   ├── numberbox-abstractions.ts
    │   │   │   ├── NumberBox.md
    │   │   │   ├── NumberBox.module.scss
    │   │   │   ├── NumberBox.spec.ts
    │   │   │   ├── NumberBox.tsx
    │   │   │   └── NumberBoxNative.tsx
    │   │   ├── Option
    │   │   │   ├── Option.md
    │   │   │   ├── Option.spec.ts
    │   │   │   ├── Option.tsx
    │   │   │   ├── OptionNative.tsx
    │   │   │   └── OptionTypeProvider.tsx
    │   │   ├── PageMetaTitle
    │   │   │   ├── PageMetaTilteNative.tsx
    │   │   │   ├── PageMetaTitle.md
    │   │   │   ├── PageMetaTitle.spec.ts
    │   │   │   └── PageMetaTitle.tsx
    │   │   ├── Pages
    │   │   │   ├── Page.md
    │   │   │   ├── Pages.md
    │   │   │   ├── Pages.module.scss
    │   │   │   ├── Pages.tsx
    │   │   │   └── PagesNative.tsx
    │   │   ├── Pagination
    │   │   │   ├── Pagination.md
    │   │   │   ├── Pagination.module.scss
    │   │   │   ├── Pagination.spec.ts
    │   │   │   ├── Pagination.tsx
    │   │   │   └── PaginationNative.tsx
    │   │   ├── PositionedContainer
    │   │   │   ├── PositionedContainer.module.scss
    │   │   │   ├── PositionedContainer.tsx
    │   │   │   └── PositionedContainerNative.tsx
    │   │   ├── ProfileMenu
    │   │   │   ├── ProfileMenu.module.scss
    │   │   │   └── ProfileMenu.tsx
    │   │   ├── ProgressBar
    │   │   │   ├── ProgressBar.md
    │   │   │   ├── ProgressBar.module.scss
    │   │   │   ├── ProgressBar.spec.ts
    │   │   │   ├── ProgressBar.tsx
    │   │   │   └── ProgressBarNative.tsx
    │   │   ├── Queue
    │   │   │   ├── Queue.md
    │   │   │   ├── Queue.spec.ts
    │   │   │   ├── Queue.tsx
    │   │   │   ├── queueActions.ts
    │   │   │   └── QueueNative.tsx
    │   │   ├── RadioGroup
    │   │   │   ├── RadioGroup.md
    │   │   │   ├── RadioGroup.module.scss
    │   │   │   ├── RadioGroup.spec.ts
    │   │   │   ├── RadioGroup.tsx
    │   │   │   ├── RadioGroupNative.tsx
    │   │   │   ├── RadioItem.tsx
    │   │   │   └── RadioItemNative.tsx
    │   │   ├── RealTimeAdapter
    │   │   │   ├── RealTimeAdapter.tsx
    │   │   │   └── RealTimeAdapterNative.tsx
    │   │   ├── Redirect
    │   │   │   ├── Redirect.md
    │   │   │   ├── Redirect.spec.ts
    │   │   │   └── Redirect.tsx
    │   │   ├── ResponsiveBar
    │   │   │   ├── README.md
    │   │   │   ├── ResponsiveBar.md
    │   │   │   ├── ResponsiveBar.module.scss
    │   │   │   ├── ResponsiveBar.spec.ts
    │   │   │   ├── ResponsiveBar.tsx
    │   │   │   └── ResponsiveBarNative.tsx
    │   │   ├── Select
    │   │   │   ├── HiddenOption.tsx
    │   │   │   ├── OptionContext.ts
    │   │   │   ├── Select.md
    │   │   │   ├── Select.module.scss
    │   │   │   ├── Select.spec.ts
    │   │   │   ├── Select.tsx
    │   │   │   ├── SelectContext.tsx
    │   │   │   └── SelectNative.tsx
    │   │   ├── SelectionStore
    │   │   │   ├── SelectionStore.md
    │   │   │   ├── SelectionStore.tsx
    │   │   │   └── SelectionStoreNative.tsx
    │   │   ├── Slider
    │   │   │   ├── Slider.md
    │   │   │   ├── Slider.module.scss
    │   │   │   ├── Slider.spec.ts
    │   │   │   ├── Slider.tsx
    │   │   │   └── SliderNative.tsx
    │   │   ├── Slot
    │   │   │   ├── Slot.md
    │   │   │   ├── Slot.spec.ts
    │   │   │   └── Slot.ts
    │   │   ├── SlotItem.tsx
    │   │   ├── SpaceFiller
    │   │   │   ├── SpaceFiller.md
    │   │   │   ├── SpaceFiller.module.scss
    │   │   │   ├── SpaceFiller.spec.ts
    │   │   │   ├── SpaceFiller.tsx
    │   │   │   └── SpaceFillerNative.tsx
    │   │   ├── Spinner
    │   │   │   ├── Spinner.md
    │   │   │   ├── Spinner.module.scss
    │   │   │   ├── Spinner.spec.ts
    │   │   │   ├── Spinner.tsx
    │   │   │   └── SpinnerNative.tsx
    │   │   ├── Splitter
    │   │   │   ├── HSplitter.md
    │   │   │   ├── HSplitter.spec.ts
    │   │   │   ├── Splitter.md
    │   │   │   ├── Splitter.module.scss
    │   │   │   ├── Splitter.spec.ts
    │   │   │   ├── Splitter.tsx
    │   │   │   ├── SplitterNative.tsx
    │   │   │   ├── utils.ts
    │   │   │   ├── VSplitter.md
    │   │   │   └── VSplitter.spec.ts
    │   │   ├── Stack
    │   │   │   ├── CHStack.md
    │   │   │   ├── CHStack.spec.ts
    │   │   │   ├── CVStack.md
    │   │   │   ├── CVStack.spec.ts
    │   │   │   ├── HStack.md
    │   │   │   ├── HStack.spec.ts
    │   │   │   ├── Stack.md
    │   │   │   ├── Stack.module.scss
    │   │   │   ├── Stack.spec.ts
    │   │   │   ├── Stack.tsx
    │   │   │   ├── StackNative.tsx
    │   │   │   ├── VStack.md
    │   │   │   └── VStack.spec.ts
    │   │   ├── StickyBox
    │   │   │   ├── StickyBox.md
    │   │   │   ├── StickyBox.module.scss
    │   │   │   ├── StickyBox.tsx
    │   │   │   └── StickyBoxNative.tsx
    │   │   ├── Switch
    │   │   │   ├── Switch.md
    │   │   │   ├── Switch.spec.ts
    │   │   │   └── Switch.tsx
    │   │   ├── Table
    │   │   │   ├── doc-resources
    │   │   │   │   └── list-component-data.js
    │   │   │   ├── react-table-config.d.ts
    │   │   │   ├── Table.md
    │   │   │   ├── Table.module.scss
    │   │   │   ├── Table.spec.ts
    │   │   │   ├── Table.tsx
    │   │   │   ├── TableNative.tsx
    │   │   │   └── useRowSelection.tsx
    │   │   ├── TableOfContents
    │   │   │   ├── TableOfContents.module.scss
    │   │   │   ├── TableOfContents.spec.ts
    │   │   │   ├── TableOfContents.tsx
    │   │   │   └── TableOfContentsNative.tsx
    │   │   ├── Tabs
    │   │   │   ├── TabContext.tsx
    │   │   │   ├── TabItem.md
    │   │   │   ├── TabItem.tsx
    │   │   │   ├── TabItemNative.tsx
    │   │   │   ├── Tabs.md
    │   │   │   ├── Tabs.module.scss
    │   │   │   ├── Tabs.spec.ts
    │   │   │   ├── Tabs.tsx
    │   │   │   └── TabsNative.tsx
    │   │   ├── Text
    │   │   │   ├── Text.md
    │   │   │   ├── Text.module.scss
    │   │   │   ├── Text.spec.ts
    │   │   │   ├── Text.tsx
    │   │   │   └── TextNative.tsx
    │   │   ├── TextArea
    │   │   │   ├── TextArea.md
    │   │   │   ├── TextArea.module.scss
    │   │   │   ├── TextArea.spec.ts
    │   │   │   ├── TextArea.tsx
    │   │   │   ├── TextAreaNative.tsx
    │   │   │   ├── TextAreaResizable.tsx
    │   │   │   └── useComposedRef.ts
    │   │   ├── TextBox
    │   │   │   ├── TextBox.md
    │   │   │   ├── TextBox.module.scss
    │   │   │   ├── TextBox.spec.ts
    │   │   │   ├── TextBox.tsx
    │   │   │   └── TextBoxNative.tsx
    │   │   ├── Theme
    │   │   │   ├── NotificationToast.tsx
    │   │   │   ├── Theme.md
    │   │   │   ├── Theme.module.scss
    │   │   │   ├── Theme.spec.ts
    │   │   │   ├── Theme.tsx
    │   │   │   └── ThemeNative.tsx
    │   │   ├── TimeInput
    │   │   │   ├── TimeInput.md
    │   │   │   ├── TimeInput.module.scss
    │   │   │   ├── TimeInput.spec.ts
    │   │   │   ├── TimeInput.tsx
    │   │   │   ├── TimeInputNative.tsx
    │   │   │   └── utils.ts
    │   │   ├── Timer
    │   │   │   ├── Timer.md
    │   │   │   ├── Timer.spec.ts
    │   │   │   ├── Timer.tsx
    │   │   │   └── TimerNative.tsx
    │   │   ├── Toggle
    │   │   │   ├── Toggle.module.scss
    │   │   │   └── Toggle.tsx
    │   │   ├── ToneChangerButton
    │   │   │   ├── ToneChangerButton.md
    │   │   │   ├── ToneChangerButton.spec.ts
    │   │   │   └── ToneChangerButton.tsx
    │   │   ├── ToneSwitch
    │   │   │   ├── ToneSwitch.md
    │   │   │   ├── ToneSwitch.module.scss
    │   │   │   ├── ToneSwitch.spec.ts
    │   │   │   ├── ToneSwitch.tsx
    │   │   │   └── ToneSwitchNative.tsx
    │   │   ├── Tooltip
    │   │   │   ├── Tooltip.md
    │   │   │   ├── Tooltip.module.scss
    │   │   │   ├── Tooltip.spec.ts
    │   │   │   ├── Tooltip.tsx
    │   │   │   └── TooltipNative.tsx
    │   │   ├── Tree
    │   │   │   ├── testData.ts
    │   │   │   ├── Tree-dynamic.spec.ts
    │   │   │   ├── Tree-icons.spec.ts
    │   │   │   ├── Tree.md
    │   │   │   ├── Tree.spec.ts
    │   │   │   ├── TreeComponent.module.scss
    │   │   │   ├── TreeComponent.tsx
    │   │   │   └── TreeNative.tsx
    │   │   ├── TreeDisplay
    │   │   │   ├── TreeDisplay.md
    │   │   │   ├── TreeDisplay.module.scss
    │   │   │   ├── TreeDisplay.tsx
    │   │   │   └── TreeDisplayNative.tsx
    │   │   ├── ValidationSummary
    │   │   │   ├── ValidationSummary.module.scss
    │   │   │   └── ValidationSummary.tsx
    │   │   └── VisuallyHidden.tsx
    │   ├── components-core
    │   │   ├── abstractions
    │   │   │   ├── ComponentRenderer.ts
    │   │   │   ├── LoaderRenderer.ts
    │   │   │   ├── standalone.ts
    │   │   │   └── treeAbstractions.ts
    │   │   ├── action
    │   │   │   ├── actions.ts
    │   │   │   ├── APICall.tsx
    │   │   │   ├── FileDownloadAction.tsx
    │   │   │   ├── FileUploadAction.tsx
    │   │   │   ├── NavigateAction.tsx
    │   │   │   └── TimedAction.tsx
    │   │   ├── ApiBoundComponent.tsx
    │   │   ├── appContext
    │   │   │   ├── date-functions.ts
    │   │   │   ├── math-function.ts
    │   │   │   └── misc-utils.ts
    │   │   ├── AppContext.tsx
    │   │   ├── behaviors
    │   │   │   ├── Behavior.tsx
    │   │   │   └── CoreBehaviors.tsx
    │   │   ├── component-hooks.ts
    │   │   ├── ComponentDecorator.tsx
    │   │   ├── ComponentViewer.tsx
    │   │   ├── CompoundComponent.tsx
    │   │   ├── constants.ts
    │   │   ├── DebugViewProvider.tsx
    │   │   ├── descriptorHelper.ts
    │   │   ├── devtools
    │   │   │   ├── InspectorDialog.module.scss
    │   │   │   ├── InspectorDialog.tsx
    │   │   │   └── InspectorDialogVisibilityContext.tsx
    │   │   ├── EngineError.ts
    │   │   ├── event-handlers.ts
    │   │   ├── InspectorButton.module.scss
    │   │   ├── InspectorContext.tsx
    │   │   ├── interception
    │   │   │   ├── abstractions.ts
    │   │   │   ├── ApiInterceptor.ts
    │   │   │   ├── ApiInterceptorProvider.tsx
    │   │   │   ├── apiInterceptorWorker.ts
    │   │   │   ├── Backend.ts
    │   │   │   ├── Errors.ts
    │   │   │   ├── IndexedDb.ts
    │   │   │   ├── initMock.ts
    │   │   │   ├── InMemoryDb.ts
    │   │   │   ├── ReadonlyCollection.ts
    │   │   │   └── useApiInterceptorContext.tsx
    │   │   ├── loader
    │   │   │   ├── ApiLoader.tsx
    │   │   │   ├── DataLoader.tsx
    │   │   │   ├── ExternalDataLoader.tsx
    │   │   │   ├── Loader.tsx
    │   │   │   ├── MockLoaderRenderer.tsx
    │   │   │   └── PageableLoader.tsx
    │   │   ├── LoaderComponent.tsx
    │   │   ├── markup-check.ts
    │   │   ├── parts.ts
    │   │   ├── renderers.ts
    │   │   ├── rendering
    │   │   │   ├── AppContent.tsx
    │   │   │   ├── AppRoot.tsx
    │   │   │   ├── AppWrapper.tsx
    │   │   │   ├── buildProxy.ts
    │   │   │   ├── collectFnVarDeps.ts
    │   │   │   ├── ComponentAdapter.tsx
    │   │   │   ├── ComponentWrapper.tsx
    │   │   │   ├── Container.tsx
    │   │   │   ├── containers.ts
    │   │   │   ├── ContainerWrapper.tsx
    │   │   │   ├── ErrorBoundary.module.scss
    │   │   │   ├── ErrorBoundary.tsx
    │   │   │   ├── InvalidComponent.module.scss
    │   │   │   ├── InvalidComponent.tsx
    │   │   │   ├── nodeUtils.ts
    │   │   │   ├── reducer.ts
    │   │   │   ├── renderChild.tsx
    │   │   │   ├── StandaloneComponent.tsx
    │   │   │   ├── StateContainer.tsx
    │   │   │   ├── UnknownComponent.module.scss
    │   │   │   ├── UnknownComponent.tsx
    │   │   │   └── valueExtractor.ts
    │   │   ├── reportEngineError.ts
    │   │   ├── RestApiProxy.ts
    │   │   ├── script-runner
    │   │   │   ├── asyncProxy.ts
    │   │   │   ├── AttributeValueParser.ts
    │   │   │   ├── bannedFunctions.ts
    │   │   │   ├── BindingTreeEvaluationContext.ts
    │   │   │   ├── eval-tree-async.ts
    │   │   │   ├── eval-tree-common.ts
    │   │   │   ├── eval-tree-sync.ts
    │   │   │   ├── ParameterParser.ts
    │   │   │   ├── process-statement-async.ts
    │   │   │   ├── process-statement-common.ts
    │   │   │   ├── process-statement-sync.ts
    │   │   │   ├── ScriptingSourceTree.ts
    │   │   │   ├── simplify-expression.ts
    │   │   │   ├── statement-queue.ts
    │   │   │   └── visitors.ts
    │   │   ├── StandaloneApp.tsx
    │   │   ├── StandaloneExtensionManager.ts
    │   │   ├── TableOfContentsContext.tsx
    │   │   ├── theming
    │   │   │   ├── _themes.scss
    │   │   │   ├── component-layout-resolver.ts
    │   │   │   ├── extendThemeUtils.ts
    │   │   │   ├── hvar.ts
    │   │   │   ├── layout-resolver.ts
    │   │   │   ├── parse-layout-props.ts
    │   │   │   ├── StyleContext.tsx
    │   │   │   ├── StyleRegistry.ts
    │   │   │   ├── ThemeContext.tsx
    │   │   │   ├── ThemeProvider.tsx
    │   │   │   ├── themes
    │   │   │   │   ├── base-utils.ts
    │   │   │   │   ├── palette.ts
    │   │   │   │   ├── root.ts
    │   │   │   │   ├── solid.ts
    │   │   │   │   ├── theme-colors.ts
    │   │   │   │   └── xmlui.ts
    │   │   │   ├── themeVars.module.scss
    │   │   │   ├── themeVars.ts
    │   │   │   ├── transformThemeVars.ts
    │   │   │   └── utils.ts
    │   │   ├── utils
    │   │   │   ├── actionUtils.ts
    │   │   │   ├── audio-utils.ts
    │   │   │   ├── base64-utils.ts
    │   │   │   ├── compound-utils.ts
    │   │   │   ├── css-utils.ts
    │   │   │   ├── DataLoaderQueryKeyGenerator.ts
    │   │   │   ├── date-utils.ts
    │   │   │   ├── extractParam.ts
    │   │   │   ├── hooks.tsx
    │   │   │   ├── LruCache.ts
    │   │   │   ├── mergeProps.ts
    │   │   │   ├── misc.ts
    │   │   │   ├── request-params.ts
    │   │   │   ├── statementUtils.ts
    │   │   │   └── treeUtils.ts
    │   │   └── xmlui-parser.ts
    │   ├── index-standalone.ts
    │   ├── index.scss
    │   ├── index.ts
    │   ├── language-server
    │   │   ├── server-common.ts
    │   │   ├── server-web-worker.ts
    │   │   ├── server.ts
    │   │   ├── services
    │   │   │   ├── common
    │   │   │   │   ├── docs-generation.ts
    │   │   │   │   ├── lsp-utils.ts
    │   │   │   │   ├── metadata-utils.ts
    │   │   │   │   └── syntax-node-utilities.ts
    │   │   │   ├── completion.ts
    │   │   │   ├── diagnostic.ts
    │   │   │   ├── format.ts
    │   │   │   └── hover.ts
    │   │   └── xmlui-metadata-generated.js
    │   ├── logging
    │   │   ├── LoggerContext.tsx
    │   │   ├── LoggerInitializer.tsx
    │   │   ├── LoggerService.ts
    │   │   └── xmlui.ts
    │   ├── logo.svg
    │   ├── parsers
    │   │   ├── common
    │   │   │   ├── GenericToken.ts
    │   │   │   ├── InputStream.ts
    │   │   │   └── utils.ts
    │   │   ├── scripting
    │   │   │   ├── code-behind-collect.ts
    │   │   │   ├── Lexer.ts
    │   │   │   ├── modules.ts
    │   │   │   ├── Parser.ts
    │   │   │   ├── ParserError.ts
    │   │   │   ├── ScriptingNodeTypes.ts
    │   │   │   ├── TokenTrait.ts
    │   │   │   ├── TokenType.ts
    │   │   │   └── tree-visitor.ts
    │   │   ├── style-parser
    │   │   │   ├── errors.ts
    │   │   │   ├── source-tree.ts
    │   │   │   ├── StyleInputStream.ts
    │   │   │   ├── StyleLexer.ts
    │   │   │   ├── StyleParser.ts
    │   │   │   └── tokens.ts
    │   │   └── xmlui-parser
    │   │       ├── CharacterCodes.ts
    │   │       ├── diagnostics.ts
    │   │       ├── fileExtensions.ts
    │   │       ├── index.ts
    │   │       ├── lint.ts
    │   │       ├── parser.ts
    │   │       ├── ParserError.ts
    │   │       ├── scanner.ts
    │   │       ├── syntax-kind.ts
    │   │       ├── syntax-node.ts
    │   │       ├── transform.ts
    │   │       ├── utils.ts
    │   │       ├── xmlui-serializer.ts
    │   │       └── xmlui-tree.ts
    │   ├── react-app-env.d.ts
    │   ├── syntax
    │   │   ├── monaco
    │   │   │   ├── grammar.monacoLanguage.ts
    │   │   │   ├── index.ts
    │   │   │   ├── xmlui-dark.ts
    │   │   │   ├── xmlui-light.ts
    │   │   │   └── xmluiscript.monacoLanguage.ts
    │   │   └── textMate
    │   │       ├── index.ts
    │   │       ├── xmlui-dark.json
    │   │       ├── xmlui-light.json
    │   │       ├── xmlui.json
    │   │       └── xmlui.tmLanguage.json
    │   ├── testing
    │   │   ├── assertions.ts
    │   │   ├── component-test-helpers.ts
    │   │   ├── ComponentDrivers.ts
    │   │   ├── drivers
    │   │   │   ├── DateInputDriver.ts
    │   │   │   ├── index.ts
    │   │   │   ├── ModalDialogDriver.ts
    │   │   │   ├── NumberBoxDriver.ts
    │   │   │   ├── TextBoxDriver.ts
    │   │   │   ├── TimeInputDriver.ts
    │   │   │   ├── TimerDriver.ts
    │   │   │   └── TreeDriver.ts
    │   │   ├── fixtures.ts
    │   │   ├── index.ts
    │   │   ├── infrastructure
    │   │   │   ├── index.html
    │   │   │   ├── main.tsx
    │   │   │   ├── public
    │   │   │   │   ├── mockServiceWorker.js
    │   │   │   │   ├── resources
    │   │   │   │   │   ├── bell.svg
    │   │   │   │   │   ├── box.svg
    │   │   │   │   │   ├── doc.svg
    │   │   │   │   │   ├── eye.svg
    │   │   │   │   │   ├── flower-640x480.jpg
    │   │   │   │   │   ├── sun.svg
    │   │   │   │   │   ├── test-image-100x100.jpg
    │   │   │   │   │   └── txt.svg
    │   │   │   │   └── serve.json
    │   │   │   └── TestBed.tsx
    │   │   └── themed-app-test-helpers.ts
    │   └── vite-env.d.ts
    ├── tests
    │   ├── components
    │   │   ├── CodeBlock
    │   │   │   └── hightlight-code.test.ts
    │   │   ├── playground-pattern.test.ts
    │   │   └── Tree
    │   │       └── Tree-states.test.ts
    │   ├── components-core
    │   │   ├── abstractions
    │   │   │   └── treeAbstractions.test.ts
    │   │   ├── container
    │   │   │   └── buildProxy.test.ts
    │   │   ├── interception
    │   │   │   ├── orderBy.test.ts
    │   │   │   ├── ReadOnlyCollection.test.ts
    │   │   │   └── request-param-converter.test.ts
    │   │   ├── scripts-runner
    │   │   │   ├── AttributeValueParser.test.ts
    │   │   │   ├── eval-tree-arrow-async.test.ts
    │   │   │   ├── eval-tree-arrow.test.ts
    │   │   │   ├── eval-tree-func-decl-async.test.ts
    │   │   │   ├── eval-tree-func-decl.test.ts
    │   │   │   ├── eval-tree-pre-post.test.ts
    │   │   │   ├── eval-tree-regression.test.ts
    │   │   │   ├── eval-tree.test.ts
    │   │   │   ├── function-proxy.test.ts
    │   │   │   ├── parser-regression.test.ts
    │   │   │   ├── process-event.test.ts
    │   │   │   ├── process-function.test.ts
    │   │   │   ├── process-implicit-context.test.ts
    │   │   │   ├── process-statement-asgn.test.ts
    │   │   │   ├── process-statement-destruct.test.ts
    │   │   │   ├── process-statement-regs.test.ts
    │   │   │   ├── process-statement-sync.test.ts
    │   │   │   ├── process-statement.test.ts
    │   │   │   ├── process-switch-sync.test.ts
    │   │   │   ├── process-switch.test.ts
    │   │   │   ├── process-try-sync.test.ts
    │   │   │   ├── process-try.test.ts
    │   │   │   └── test-helpers.ts
    │   │   ├── test-metadata-handler.ts
    │   │   ├── theming
    │   │   │   ├── border-segments.test.ts
    │   │   │   ├── component-layout.resolver.test.ts
    │   │   │   ├── layout-property-parser.test.ts
    │   │   │   ├── layout-resolver.test.ts
    │   │   │   ├── layout-resolver2.test.ts
    │   │   │   ├── layout-vp-override.test.ts
    │   │   │   └── padding-segments.test.ts
    │   │   └── utils
    │   │       ├── date-utils.test.ts
    │   │       ├── format-human-elapsed-time.test.ts
    │   │       └── LruCache.test.ts
    │   ├── language-server
    │   │   ├── completion.test.ts
    │   │   ├── format.test.ts
    │   │   ├── hover.test.ts
    │   │   └── mockData.ts
    │   └── parsers
    │       ├── common
    │       │   └── input-stream.test.ts
    │       ├── markdown
    │       │   └── parse-binding-expression.test.ts
    │       ├── parameter-parser.test.ts
    │       ├── paremeter-parser.test.ts
    │       ├── scripting
    │       │   ├── eval-tree-arrow.test.ts
    │       │   ├── eval-tree-pre-post.test.ts
    │       │   ├── eval-tree.test.ts
    │       │   ├── function-proxy.test.ts
    │       │   ├── lexer-literals.test.ts
    │       │   ├── lexer-misc.test.ts
    │       │   ├── module-parse.test.ts
    │       │   ├── parser-arrow.test.ts
    │       │   ├── parser-assignments.test.ts
    │       │   ├── parser-binary.test.ts
    │       │   ├── parser-destructuring.test.ts
    │       │   ├── parser-errors.test.ts
    │       │   ├── parser-expressions.test.ts
    │       │   ├── parser-function.test.ts
    │       │   ├── parser-literals.test.ts
    │       │   ├── parser-primary.test.ts
    │       │   ├── parser-regex.test.ts
    │       │   ├── parser-statements.test.ts
    │       │   ├── parser-unary.test.ts
    │       │   ├── process-event.test.ts
    │       │   ├── process-implicit-context.test.ts
    │       │   ├── process-statement-asgn.test.ts
    │       │   ├── process-statement-destruct.test.ts
    │       │   ├── process-statement-regs.test.ts
    │       │   ├── process-statement-sync.test.ts
    │       │   ├── process-statement.test.ts
    │       │   ├── process-switch-sync.test.ts
    │       │   ├── process-switch.test.ts
    │       │   ├── process-try-sync.test.ts
    │       │   ├── process-try.test.ts
    │       │   ├── simplify-expression.test.ts
    │       │   ├── statement-hooks.test.ts
    │       │   └── test-helpers.ts
    │       ├── style-parser
    │       │   ├── generateHvarChain.test.ts
    │       │   ├── parseHVar.test.ts
    │       │   ├── parser.test.ts
    │       │   └── tokens.test.ts
    │       └── xmlui
    │           ├── lint.test.ts
    │           ├── parser.test.ts
    │           ├── scanner.test.ts
    │           ├── transform.attr.test.ts
    │           ├── transform.circular.test.ts
    │           ├── transform.element.test.ts
    │           ├── transform.errors.test.ts
    │           ├── transform.escape.test.ts
    │           ├── transform.regression.test.ts
    │           ├── transform.script.test.ts
    │           ├── transform.test.ts
    │           └── xmlui.ts
    ├── tests-e2e
    │   ├── api-bound-component-regression.spec.ts
    │   ├── api-call-as-extracted-component.spec.ts
    │   ├── assign-to-object-or-array-regression.spec.ts
    │   ├── binding-regression.spec.ts
    │   ├── children-as-template-context-vars.spec.ts
    │   ├── compound-component.spec.ts
    │   ├── context-vars-regression.spec.ts
    │   ├── data-bindings.spec.ts
    │   ├── datasource-and-api-usage-in-var.spec.ts
    │   ├── datasource-direct-binding.spec.ts
    │   ├── datasource-onLoaded-regression.spec.ts
    │   ├── modify-array-item-regression.spec.ts
    │   ├── namespaces.spec.ts
    │   ├── push-to-array-regression.spec.ts
    │   ├── screen-breakpoints.spec.ts
    │   ├── scripting.spec.ts
    │   ├── state-scope-in-pages.spec.ts
    │   └── state-var-scopes.spec.ts
    ├── tsconfig.bin.json
    ├── tsconfig.json
    ├── tsconfig.node.json
    ├── vite.config.ts
    └── vitest.config.ts
```

# Files

--------------------------------------------------------------------------------
/xmlui/src/components/IFrame/IFrame.spec.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { expect, test } from "../../testing/fixtures";
  2 | 
  3 | // =============================================================================
  4 | // BASIC FUNCTIONALITY TESTS
  5 | // =============================================================================
  6 | 
  7 | test.describe("Basic Functionality", () => {
  8 |   test("component renders", async ({ initTestBed, page }) => {
  9 |     await initTestBed(`<IFrame testId="iframe" />`);
 10 |     await expect(page.getByTestId("iframe")).toBeVisible();
 11 |   });
 12 | 
 13 |   test("component renders with 'src' property", async ({ initTestBed, page }) => {
 14 |     await initTestBed(`<IFrame src="https://example.com" testId="iframe" />`);
 15 |     const iframe = page.getByTestId("iframe");
 16 |     await expect(iframe).toBeVisible();
 17 |     await expect(iframe).toHaveAttribute("src", "https://example.com");
 18 |   });
 19 | 
 20 |   test("component renders with 'srcdoc' property", async ({ initTestBed, page }) => {
 21 |     const htmlContent = "<h1>Test Content</h1><p>This is embedded HTML.</p>";
 22 |     await initTestBed(`<IFrame srcdoc="${htmlContent}" testId="iframe" />`);
 23 |     const iframe = page.getByTestId("iframe");
 24 |     await expect(iframe).toBeVisible();
 25 |     await expect(iframe).toHaveAttribute("srcdoc", htmlContent);
 26 |   });
 27 | 
 28 |   test.describe("allow property", () => {
 29 |     test("sets permissions policy", async ({ initTestBed, page }) => {
 30 |       const allowValue = "camera; microphone; geolocation";
 31 |       await initTestBed(`<IFrame allow="${allowValue}" testId="iframe" />`);
 32 |       const iframe = page.getByTestId("iframe");
 33 |       await expect(iframe).toHaveAttribute("allow", allowValue);
 34 |     });
 35 | 
 36 |     test("handles empty string", async ({ initTestBed, page }) => {
 37 |       await initTestBed(`<IFrame allow="" testId="iframe" />`);
 38 |       const iframe = page.getByTestId("iframe");
 39 |       await expect(iframe).toHaveAttribute("allow", "");
 40 |     });
 41 | 
 42 |     test("handles null gracefully", async ({ initTestBed, page }) => {
 43 |       await initTestBed(`<IFrame allow="{null}" testId="iframe" />`);
 44 |       const iframe = page.getByTestId("iframe");
 45 |       await expect(iframe).not.toHaveAttribute("allow");
 46 |     });
 47 | 
 48 |     test("handles undefined gracefully", async ({ initTestBed, page }) => {
 49 |       await initTestBed(`<IFrame allow="{undefined}" testId="iframe" />`);
 50 |       const iframe = page.getByTestId("iframe");
 51 |       await expect(iframe).not.toHaveAttribute("allow");
 52 |     });
 53 |   });
 54 | 
 55 |   test.describe("name property", () => {
 56 |     test("sets iframe name", async ({ initTestBed, page }) => {
 57 |       await initTestBed(`<IFrame name="myFrame" testId="iframe" />`);
 58 |       const iframe = page.getByTestId("iframe");
 59 |       await expect(iframe).toHaveAttribute("name", "myFrame");
 60 |     });
 61 | 
 62 |     test("handles empty string", async ({ initTestBed, page }) => {
 63 |       await initTestBed(`<IFrame name="" testId="iframe" />`);
 64 |       const iframe = page.getByTestId("iframe");
 65 |       await expect(iframe).toHaveAttribute("name", "");
 66 |     });
 67 | 
 68 |     test("handles null gracefully", async ({ initTestBed, page }) => {
 69 |       await initTestBed(`<IFrame name="{null}" testId="iframe" />`);
 70 |       const iframe = page.getByTestId("iframe");
 71 |       await expect(iframe).not.toHaveAttribute("name");
 72 |     });
 73 | 
 74 |     test("handles undefined gracefully", async ({ initTestBed, page }) => {
 75 |       await initTestBed(`<IFrame name="{undefined}" testId="iframe" />`);
 76 |       const iframe = page.getByTestId("iframe");
 77 |       await expect(iframe).not.toHaveAttribute("name");
 78 |     });
 79 | 
 80 |     test("handles unicode characters", async ({ initTestBed, page }) => {
 81 |       const unicodeName = "测试框架👨‍👩‍👧‍👦";
 82 |       await initTestBed(`<IFrame name="${unicodeName}" testId="iframe" />`);
 83 |       const iframe = page.getByTestId("iframe");
 84 |       await expect(iframe).toHaveAttribute("name", unicodeName);
 85 |     });
 86 |   });
 87 | 
 88 |   test.describe("referrerPolicy property", () => {
 89 |     [
 90 |       "no-referrer",
 91 |       "no-referrer-when-downgrade", 
 92 |       "origin",
 93 |       "origin-when-cross-origin",
 94 |       "same-origin",
 95 |       "strict-origin",
 96 |       "strict-origin-when-cross-origin",
 97 |       "unsafe-url"
 98 |     ].forEach(policy => {
 99 |       test(`sets referrerPolicy to '${policy}'`, async ({ initTestBed, page }) => {
100 |         await initTestBed(`<IFrame referrerPolicy="${policy}" testId="iframe" />`);
101 |         const iframe = page.getByTestId("iframe");
102 |         await expect(iframe).toHaveAttribute("referrerpolicy", policy);
103 |       });
104 |     });
105 | 
106 |     test("handles invalid value gracefully", async ({ initTestBed, page }) => {
107 |       await initTestBed(`<IFrame referrerPolicy="invalid-policy" testId="iframe" />`);
108 |       const iframe = page.getByTestId("iframe");
109 |       await expect(iframe).toHaveAttribute("referrerpolicy", "invalid-policy");
110 |     });
111 | 
112 |     test("handles null gracefully", async ({ initTestBed, page }) => {
113 |       await initTestBed(`<IFrame referrerPolicy="{null}" testId="iframe" />`);
114 |       const iframe = page.getByTestId("iframe");
115 |       await expect(iframe).not.toHaveAttribute("referrerpolicy");
116 |     });
117 |   });
118 | 
119 |   test.describe("sandbox property", () => {
120 |     test("sets sandbox restrictions", async ({ initTestBed, page }) => {
121 |       const sandboxValue = "allow-scripts allow-same-origin";
122 |       await initTestBed(`<IFrame sandbox="${sandboxValue}" testId="iframe" />`);
123 |       const iframe = page.getByTestId("iframe");
124 |       await expect(iframe).toHaveAttribute("sandbox", sandboxValue);
125 |     });
126 | 
127 |     test("handles empty string for strict sandboxing", async ({ initTestBed, page }) => {
128 |       await initTestBed(`<IFrame sandbox="" testId="iframe" />`);
129 |       const iframe = page.getByTestId("iframe");
130 |       await expect(iframe).toHaveAttribute("sandbox", "");
131 |     });
132 | 
133 |     test("handles single sandbox flag", async ({ initTestBed, page }) => {
134 |       await initTestBed(`<IFrame sandbox="allow-scripts" testId="iframe" />`);
135 |       const iframe = page.getByTestId("iframe");
136 |       await expect(iframe).toHaveAttribute("sandbox", "allow-scripts");
137 |     });
138 | 
139 |     test("handles null gracefully", async ({ initTestBed, page }) => {
140 |       await initTestBed(`<IFrame sandbox="{null}" testId="iframe" />`);
141 |       const iframe = page.getByTestId("iframe");
142 |       await expect(iframe).not.toHaveAttribute("sandbox");
143 |     });
144 |   });
145 | 
146 |   test.describe("event handlers", () => {
147 |     test("'load' event fires when content loads", async ({ initTestBed, page }) => {
148 |       const { testStateDriver } = await initTestBed(`
149 |         <IFrame 
150 |           srcdoc="<h1>Test</h1>" 
151 |           onLoad="testState = 'loaded'" 
152 |           testId="iframe" 
153 |         />
154 |       `);
155 |       
156 |       // Wait for the load event to fire
157 |       await expect.poll(testStateDriver.testState).toEqual("loaded");
158 |     });
159 | 
160 |     test("'load' event receives event object", async ({ initTestBed, page }) => {
161 |       const { testStateDriver } = await initTestBed(`
162 |         <IFrame 
163 |           srcdoc="<h1>Test</h1>" 
164 |           onLoad="event => testState = event.type" 
165 |           testId="iframe" 
166 |         />
167 |       `);
168 |       
169 |       await expect.poll(testStateDriver.testState).toEqual("load");
170 |     });
171 |   });
172 | 
173 |   test.describe("edge case combinations", () => {
174 |     test("handles both src and srcdoc (srcdoc should take precedence)", async ({ initTestBed, page }) => {
175 |       const htmlContent = "<h1>Srcdoc Content</h1>";
176 |       await initTestBed(`<IFrame src="https://example.com" srcdoc="${htmlContent}" testId="iframe" />`);
177 |       const iframe = page.getByTestId("iframe");
178 |       await expect(iframe).toHaveAttribute("src", "https://example.com");
179 |       await expect(iframe).toHaveAttribute("srcdoc", htmlContent);
180 |     });
181 | 
182 |     test("handles all security properties together", async ({ initTestBed, page }) => {
183 |       await initTestBed(`
184 |         <IFrame 
185 |           src="https://example.com"
186 |           sandbox="allow-scripts allow-same-origin"
187 |           allow="camera; microphone"
188 |           referrerPolicy="no-referrer"
189 |           testId="iframe" 
190 |         />
191 |       `);
192 |       const iframe = page.getByTestId("iframe");
193 |       await expect(iframe).toHaveAttribute("sandbox", "allow-scripts allow-same-origin");
194 |       await expect(iframe).toHaveAttribute("allow", "camera; microphone");
195 |       await expect(iframe).toHaveAttribute("referrerpolicy", "no-referrer");
196 |     });
197 | 
198 |     test("handles extremely long URL", async ({ initTestBed, page }) => {
199 |       const longUrl = "https://example.com/" + "a".repeat(2000);
200 |       await initTestBed(`<IFrame src="${longUrl}" testId="iframe" />`);
201 |       const iframe = page.getByTestId("iframe");
202 |       await expect(iframe).toHaveAttribute("src", longUrl);
203 |     });
204 | 
205 |     test("handles complex HTML in srcdoc with special characters", async ({ initTestBed, page }) => {
206 |       const complexHtml = "&lt;h1&gt;测试&lt;/h1&gt;&lt;p&gt;Special chars: &amp;lt;&amp;gt;&amp;amp;&lt;/p&gt;";
207 |       await initTestBed(`<IFrame srcdoc="${complexHtml}" testId="iframe" />`);
208 |       const iframe = page.getByTestId("iframe");
209 |       await expect(iframe).toBeVisible();
210 |       // HTML entities get decoded by the browser, so we expect the decoded version
211 |       await expect(iframe).toHaveAttribute("srcdoc", "<h1>测试</h1><p>Special chars: &lt;&gt;&amp;</p>");
212 |     });
213 |   });
214 | });
215 | 
216 | // =============================================================================
217 | // ACCESSIBILITY TESTS
218 | // =============================================================================
219 | 
220 | test.describe("Accessibility", () => {
221 |   test("has correct element type", async ({ initTestBed, page }) => {
222 |     await initTestBed(`<IFrame testId="iframe" />`);
223 |     // Note: iframe elements don't have an implicit role, they are identified by tag name
224 |     const iframe = page.getByTestId("iframe");
225 |     await expect(iframe).toBeVisible();
226 |     // Check that it's actually an iframe element
227 |     const tagName = await iframe.evaluate(el => el.tagName);
228 |     expect(tagName).toBe("IFRAME");
229 |   });
230 | 
231 |   test("maintains focus management", async ({ initTestBed, page }) => {
232 |     await initTestBed(`<IFrame testId="iframe" />`);
233 |     const iframe = page.getByTestId("iframe");
234 |     
235 |     // IFrame should be focusable by default
236 |     await iframe.focus();
237 |     await expect(iframe).toBeFocused();
238 |   });
239 | 
240 |   test("can be identified by name for accessibility tools", async ({ initTestBed, page }) => {
241 |     await initTestBed(`<IFrame name="mainContent" testId="iframe" />`);
242 |     const iframe = page.getByTestId("iframe");
243 |     await expect(iframe).toHaveAttribute("name", "mainContent");
244 |     // Name attribute can be used by accessibility tools to identify the frame
245 |   });
246 | 
247 |   test("supports sandbox for secure content embedding", async ({ initTestBed, page }) => {
248 |     await initTestBed(`<IFrame sandbox="allow-scripts" testId="iframe" />`);
249 |     const iframe = page.getByTestId("iframe");
250 |     await expect(iframe).toHaveAttribute("sandbox", "allow-scripts");
251 |     // Sandbox provides security restrictions which can help with accessibility concerns
252 |   });
253 | });
254 | 
255 | // =============================================================================
256 | // THEME VARIABLE TESTS
257 | // =============================================================================
258 | 
259 | test.describe("Theme Variables", () => {
260 |   test("applies 'width-IFrame' theme variable", async ({ initTestBed, page }) => {
261 |     await initTestBed(`<IFrame testId="iframe" />`, {
262 |       testThemeVars: { "width-IFrame": "500px" },
263 |     });
264 |     await expect(page.getByTestId("iframe")).toHaveCSS("width", "500px");
265 |   });
266 | 
267 |   test("applies 'height-IFrame' theme variable", async ({ initTestBed, page }) => {
268 |     await initTestBed(`<IFrame testId="iframe" />`, {
269 |       testThemeVars: { "height-IFrame": "400px" },
270 |     });
271 |     await expect(page.getByTestId("iframe")).toHaveCSS("height", "400px");
272 |   });
273 | 
274 |   test("applies 'borderRadius-IFrame' theme variable", async ({ initTestBed, page }) => {
275 |     await initTestBed(`<IFrame testId="iframe" />`, {
276 |       testThemeVars: { "borderRadius-IFrame": "10px" },
277 |     });
278 |     await expect(page.getByTestId("iframe")).toHaveCSS("border-radius", "10px");
279 |   });
280 | 
281 |   test("applies 'border-IFrame' theme variable", async ({ initTestBed, page }) => {
282 |     await initTestBed(`<IFrame testId="iframe" />`, {
283 |       testThemeVars: { "border-IFrame": "2px solid rgb(255, 0, 0)" },
284 |     });
285 |     await expect(page.getByTestId("iframe")).toHaveCSS("border", "2px solid rgb(255, 0, 0)");
286 |   });
287 | 
288 |   test("applies multiple theme variables together", async ({ initTestBed, page }) => {
289 |     await initTestBed(`<IFrame testId="iframe" />`, {
290 |       testThemeVars: { 
291 |         "width-IFrame": "600px",
292 |         "height-IFrame": "400px",
293 |         "borderRadius-IFrame": "8px",
294 |         "border-IFrame": "3px dashed rgb(0, 255, 0)"
295 |       },
296 |     });
297 |     const iframe = page.getByTestId("iframe");
298 |     await expect(iframe).toHaveCSS("width", "600px");
299 |     await expect(iframe).toHaveCSS("height", "400px");
300 |     await expect(iframe).toHaveCSS("border-radius", "8px");
301 |     await expect(iframe).toHaveCSS("border", "3px dashed rgb(0, 255, 0)");
302 |   });
303 | 
304 |   test("falls back to default theme variables", async ({ initTestBed, page }) => {
305 |     await initTestBed(`<IFrame testId="iframe" />`);
306 |     const iframe = page.getByTestId("iframe");
307 |     
308 |     // Default height should be 300px  
309 |     await expect(iframe).toHaveCSS("height", "300px");
310 |     // Should have some border (exact value depends on theme)
311 |     const borderStyle = await iframe.evaluate(el => getComputedStyle(el).border);
312 |     expect(borderStyle).toBeTruthy();
313 |     // Width might not be 100% in test environment but should have a computed value
314 |     const widthStyle = await iframe.evaluate(el => getComputedStyle(el).width);
315 |     expect(widthStyle).toBeTruthy();
316 |   });
317 | });
318 | 
319 | // =============================================================================
320 | // OTHER EDGE CASE TESTS
321 | // =============================================================================
322 | 
323 | test.describe("Other Edge Cases", () => {
324 |   test("handles no props gracefully", async ({ initTestBed, page }) => {
325 |     await initTestBed(`<IFrame testId="iframe" />`);
326 |     const iframe = page.getByTestId("iframe");
327 |     await expect(iframe).toBeVisible();
328 |     // Should not have src or srcdoc attributes
329 |     await expect(iframe).not.toHaveAttribute("src");
330 |     await expect(iframe).not.toHaveAttribute("srcdoc");
331 |   });
332 | 
333 |   test("handles invalid URL in src", async ({ initTestBed, page }) => {
334 |     await initTestBed(`<IFrame src="not-a-valid-url" testId="iframe" />`);
335 |     const iframe = page.getByTestId("iframe");
336 |     await expect(iframe).toBeVisible();
337 |     // The src attribute might be transformed by XMLUI's resource URL handling
338 |     const srcValue = await iframe.getAttribute("src");
339 |     expect(srcValue).toContain("not-a-valid-url");
340 |   });
341 | 
342 |   test("handles empty srcdoc", async ({ initTestBed, page }) => {
343 |     await initTestBed(`<IFrame srcdoc="" testId="iframe" />`);
344 |     const iframe = page.getByTestId("iframe");
345 |     await expect(iframe).toBeVisible();
346 |     await expect(iframe).toHaveAttribute("srcdoc", "");
347 |   });
348 | 
349 |   test("handles malformed HTML in srcdoc", async ({ initTestBed, page }) => {
350 |     const malformedHtml = "<div><p>Unclosed tags<span>More content";
351 |     await initTestBed(`<IFrame srcdoc="${malformedHtml}" testId="iframe" />`);
352 |     const iframe = page.getByTestId("iframe");
353 |     await expect(iframe).toBeVisible();
354 |     await expect(iframe).toHaveAttribute("srcdoc", malformedHtml);
355 |   });
356 | 
357 |   test("handles very long sandbox value", async ({ initTestBed, page }) => {
358 |     const longSandbox = Array(100).fill("allow-scripts").join(" ");
359 |     await initTestBed(`<IFrame sandbox="${longSandbox}" testId="iframe" />`);
360 |     const iframe = page.getByTestId("iframe");
361 |     await expect(iframe).toHaveAttribute("sandbox", longSandbox);
362 |   });
363 | 
364 |   test("maintains performance with multiple iframes", async ({ initTestBed, page }) => {
365 |     await initTestBed(`
366 |       <Fragment>
367 |         <IFrame srcdoc="<h1>Frame 1</h1>" testId="iframe1" />
368 |         <IFrame srcdoc="<h1>Frame 2</h1>" testId="iframe2" />
369 |         <IFrame srcdoc="<h1>Frame 3</h1>" testId="iframe3" />
370 |       </Fragment>
371 |     `);
372 |     
373 |     await expect(page.getByTestId("iframe1")).toBeVisible();
374 |     await expect(page.getByTestId("iframe2")).toBeVisible();
375 |     await expect(page.getByTestId("iframe3")).toBeVisible();
376 |   });
377 | 
378 |   test("handles data URLs in src", async ({ initTestBed, page }) => {
379 |     const dataUrl = "data:text/html,<h1>Data URL Content</h1>";
380 |     await initTestBed(`<IFrame src="${dataUrl}" testId="iframe" />`);
381 |     const iframe = page.getByTestId("iframe");
382 |     await expect(iframe).toBeVisible();
383 |     // The URL might be transformed by XMLUI's resource URL handling
384 |     const srcValue = await iframe.getAttribute("src");
385 |     expect(srcValue).toContain("data:text/html");
386 |   });
387 | 
388 |   test("handles blob URLs in src", async ({ initTestBed, page }) => {
389 |     // Blob URLs are typically generated by JavaScript, so we test with a mock
390 |     const blobUrl = "blob:https://example.com/12345678-1234-1234-1234-123456789abc";
391 |     await initTestBed(`<IFrame src="${blobUrl}" testId="iframe" />`);
392 |     const iframe = page.getByTestId("iframe");
393 |     await expect(iframe).toBeVisible();
394 |     // The URL might be transformed by XMLUI's resource URL handling
395 |     const srcValue = await iframe.getAttribute("src");
396 |     expect(srcValue).toContain("blob:https://example.com");
397 |   });
398 | });
399 | 
400 | // =============================================================================
401 | // API TESTS
402 | // =============================================================================
403 | 
404 | test.describe("APIs", () => {
405 |   test("postMessage sends message to iframe content window", async ({ initTestBed, page }) => {
406 |     const { testStateDriver } = await initTestBed(`
407 |       <Fragment>
408 |         <IFrame 
409 |           id="testIframe"
410 |           srcdoc="
411 |             <script>
412 |               window.addEventListener('message', (event) => {
413 |                 window.parent.postMessage({ received: event.data }, '*');
414 |               });
415 |             </script>
416 |             <h1>Test IFrame</h1>
417 |           "
418 |           testId="iframe" />
419 |         <Button 
420 |           onClick="
421 |             testIframe.postMessage({ type: 'test', message: 'Hello IFrame' }, '*');
422 |             testState = 'message-sent';
423 |           " 
424 |           label="Send Message" 
425 |           testId="sendButton" />
426 |       </Fragment>
427 |     `);
428 | 
429 |     await page.getByTestId("sendButton").click();
430 |     await expect.poll(testStateDriver.testState).toEqual("message-sent");
431 |   });
432 | 
433 |   test("postMessage with custom target origin", async ({ initTestBed, page }) => {
434 |     const { testStateDriver } = await initTestBed(`
435 |       <Fragment>
436 |         <IFrame 
437 |           id="testIframe"
438 |           srcdoc="<h1>Test IFrame</h1>"
439 |           testId="iframe" />
440 |         <Button 
441 |           onClick="
442 |             testIframe.postMessage('test-message', 'https://example.com');
443 |             testState = 'message-with-origin-sent';
444 |           " 
445 |           label="Send Message with Origin" 
446 |           testId="sendButton" />
447 |       </Fragment>
448 |     `);
449 | 
450 |     await page.getByTestId("sendButton").click();
451 |     await expect.poll(testStateDriver.testState).toEqual("message-with-origin-sent");
452 |   });
453 | 
454 |   test("getContentWindow returns content window object", async ({ initTestBed, page }) => {
455 |     const { testStateDriver } = await initTestBed(`
456 |       <Fragment>
457 |         <IFrame 
458 |           id="testIframe"
459 |           srcdoc="<h1>Test Content</h1>"
460 |           testId="iframe" />
461 |         <Button 
462 |           onClick="
463 |             const contentWindow = testIframe.getContentWindow();
464 |             testState = {
465 |               hasContentWindow: contentWindow !== null,
466 |               isWindow: contentWindow && typeof contentWindow.postMessage === 'function'
467 |             };
468 |           " 
469 |           label="Get Content Window" 
470 |           testId="getWindowButton" />
471 |       </Fragment>
472 |     `);
473 | 
474 |     await page.getByTestId("getWindowButton").click();
475 |     
476 |     const result = await testStateDriver.testState();
477 |     expect(result.hasContentWindow).toBe(true);
478 |     expect(result.isWindow).toBe(true);
479 |   });
480 | 
481 |   test("getContentWindow returns null when iframe not loaded", async ({ initTestBed, page }) => {
482 |     const { testStateDriver } = await initTestBed(`
483 |       <Fragment>
484 |         <IFrame 
485 |           id="testIframe"
486 |           src="about:blank"
487 |           testId="iframe" />
488 |         <Button 
489 |           onClick="
490 |             const contentWindow = testIframe.getContentWindow();
491 |             testState = { isNull: contentWindow === null };
492 |           " 
493 |           label="Get Content Window" 
494 |           testId="getWindowButton" />
495 |       </Fragment>
496 |     `);
497 | 
498 |     // Click immediately before iframe might be fully loaded
499 |     await page.getByTestId("getWindowButton").click();
500 |     
501 |     const result = await testStateDriver.testState();
502 |     // Content window should exist even for about:blank
503 |     expect(result.isNull).toBe(false);
504 |   });
505 | 
506 |   test("getContentDocument returns content document object", async ({ initTestBed, page }) => {
507 |     const { testStateDriver } = await initTestBed(`
508 |       <Fragment>
509 |         <IFrame 
510 |           id="testIframe"
511 |           srcdoc="<html><head><title>Test Document</title></head><body><h1>Test Content</h1></body></html>"
512 |           testId="iframe" />
513 |         <Button 
514 |           onClick="
515 |             const contentDoc = testIframe.getContentDocument();
516 |             testState = {
517 |               hasContentDocument: contentDoc !== null,
518 |               documentTitle: contentDoc ? contentDoc.title : null,
519 |               isDocument: contentDoc && typeof contentDoc.querySelector === 'function'
520 |             };
521 |           " 
522 |           label="Get Content Document" 
523 |           testId="getDocButton" />
524 |       </Fragment>
525 |     `);
526 | 
527 |     // Wait for iframe to load
528 |     await page.waitForTimeout(100);
529 |     await page.getByTestId("getDocButton").click();
530 |     
531 |     const result = await testStateDriver.testState();
532 |     expect(result.hasContentDocument).toBe(true);
533 |     expect(result.documentTitle).toBe("Test Document");
534 |     expect(result.isDocument).toBe(true);
535 |   });
536 | 
537 |   test("APIs work with same-origin srcdoc content", async ({ initTestBed, page }) => {
538 |     const { testStateDriver } = await initTestBed(`
539 |       <Fragment>
540 |         <IFrame 
541 |           id="testIframe"
542 |           srcdoc="
543 |             <html>
544 |               <head><title>API Test Document</title></head>
545 |               <body>
546 |                 <h1>API Test Content</h1>
547 |                 <script>
548 |                   window.addEventListener('message', (event) => \\{
549 |                     if (event.data.type === 'ping') \\{
550 |                       window.parent.postMessage(\\{ type: 'pong', data: event.data.data }, '*');
551 |                     }
552 |                   });
553 |                 </script>
554 |               </body>
555 |             </html>
556 |           "
557 |           testId="iframe" />
558 |         <Button 
559 |           onClick="
560 |             const contentWindow = testIframe.getContentWindow();
561 |             const contentDoc = testIframe.getContentDocument();
562 |             testIframe.postMessage({ type: 'ping', data: 'test-data' }, '*');
563 |             testState = {
564 |               hasWindow: contentWindow !== null,
565 |               hasDocument: contentDoc !== null,
566 |               documentTitle: contentDoc ? contentDoc.title : null,
567 |               messageSent: true
568 |             };
569 |           " 
570 |           label="Test All APIs" 
571 |           testId="testAllButton" />
572 |       </Fragment>
573 |     `);
574 | 
575 |     // Wait for iframe to load
576 |     await page.waitForTimeout(100);
577 |     await page.getByTestId("testAllButton").click();
578 |     
579 |     const result = await testStateDriver.testState();
580 |     expect(result.hasWindow).toBe(true);
581 |     expect(result.hasDocument).toBe(true);
582 |     expect(result.documentTitle).toBe("API Test Document");
583 |     expect(result.messageSent).toBe(true);
584 |   });
585 | });
586 | 
```

--------------------------------------------------------------------------------
/xmlui/src/parsers/scripting/tree-visitor.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import {
  2 |   type Statement,
  3 |   type Expression,
  4 |   T_BLOCK_STATEMENT,
  5 |   T_EMPTY_STATEMENT,
  6 |   T_EXPRESSION_STATEMENT,
  7 |   T_ARROW_EXPRESSION_STATEMENT,
  8 |   T_LET_STATEMENT,
  9 |   T_CONST_STATEMENT,
 10 |   T_VAR_STATEMENT,
 11 |   T_IF_STATEMENT,
 12 |   T_RETURN_STATEMENT,
 13 |   T_BREAK_STATEMENT,
 14 |   T_CONTINUE_STATEMENT,
 15 |   T_WHILE_STATEMENT,
 16 |   T_DO_WHILE_STATEMENT,
 17 |   T_FOR_STATEMENT,
 18 |   T_FOR_IN_STATEMENT,
 19 |   T_FOR_OF_STATEMENT,
 20 |   T_THROW_STATEMENT,
 21 |   T_TRY_STATEMENT,
 22 |   T_SWITCH_STATEMENT,
 23 |   T_FUNCTION_DECLARATION,
 24 |   T_UNARY_EXPRESSION,
 25 |   T_BINARY_EXPRESSION,
 26 |   T_SEQUENCE_EXPRESSION,
 27 |   T_CONDITIONAL_EXPRESSION,
 28 |   T_FUNCTION_INVOCATION_EXPRESSION,
 29 |   T_MEMBER_ACCESS_EXPRESSION,
 30 |   T_CALCULATED_MEMBER_ACCESS_EXPRESSION,
 31 |   T_IDENTIFIER,
 32 |   T_LITERAL,
 33 |   T_ARRAY_LITERAL,
 34 |   T_OBJECT_LITERAL,
 35 |   T_SPREAD_EXPRESSION,
 36 |   T_ASSIGNMENT_EXPRESSION,
 37 |   T_NO_ARG_EXPRESSION,
 38 |   T_ARROW_EXPRESSION,
 39 |   T_PREFIX_OP_EXPRESSION,
 40 |   T_POSTFIX_OP_EXPRESSION,
 41 |   T_VAR_DECLARATION,
 42 |   T_DESTRUCTURE,
 43 |   T_OBJECT_DESTRUCTURE,
 44 |   T_ARRAY_DESTRUCTURE,
 45 |   T_REACTIVE_VAR_DECLARATION,
 46 |   T_TEMPLATE_LITERAL_EXPRESSION,
 47 |   T_SWITCH_CASE,
 48 | } from "../../components-core/script-runner/ScriptingSourceTree";
 49 | 
 50 | const unreachable = (_x: never) => {};
 51 | 
 52 | type VisitSubject = Statement | Expression;
 53 | 
 54 | /* Visitors take this type as argument and return it
 55 |  * `data` is the output that the caller of visitNode will be interested in
 56 |  *[key: string] is a hack from the type system's perspective, but useful.
 57 |  * If visitor X calls visitor Y, X can use the working state of Y if it is defined inside these keys and not in global vars*/
 58 | export type VisitorState<TState = any> = {
 59 |   data: TState;
 60 |   cancel: boolean;
 61 |   skipChildren: boolean;
 62 |   [key: string]: any;
 63 | };
 64 | 
 65 | /* This visitor is called usually twice on every statement when give to a `visitNode` function
 66 |  * before = true when entering a statement and before = false when exiting it.
 67 |  * If the stmt is a leaf node (break, continue),it will be called once with before = true */
 68 | type StmtVisitor<TState = any> = (
 69 |   before: boolean,
 70 |   visited: Statement,
 71 |   state: VisitorState<TState>,
 72 |   parent?: VisitSubject,
 73 |   tag?: string,
 74 | ) => VisitorState<TState>;
 75 | 
 76 | /* This visitor is called usually twice on every expression when give to a `visitNode` function
 77 |  * before = true when entering an expr and before = false when exiting it.
 78 |  * If the expr is a leaf node (literal, identifier, ...),it will be called once with before = true */
 79 | type ExprVisitor<TState = any> = (
 80 |   before: boolean,
 81 |   visited: Expression,
 82 |   state: VisitorState<TState>,
 83 |   parent?: VisitSubject,
 84 |   tag?: string,
 85 | ) => VisitorState<TState>;
 86 | 
 87 | /*Walk through the ast, executing visitors on the nodes
 88 |  *
 89 |  * @param subject the root of the tree to start the walk from
 90 |  * @param state the initial state that will be passed through to the visitors
 91 |  * @param stmtVisior will be called on every statement. If undefined, statements will be ignored
 92 |  * @param exprVisitor will be called on every expression. If undefined, exoressiones will be ignored
 93 |  */
 94 | export function visitNode<TState = any>(
 95 |   subject: VisitSubject | Statement[],
 96 |   state: VisitorState<TState>,
 97 |   stmtVisitor?: StmtVisitor<TState>,
 98 |   exprVisitor?: ExprVisitor<TState>,
 99 |   parent?: VisitSubject,
100 |   tag?: string,
101 | ): VisitorState<TState> {
102 |   // --- Stop visiting if cancelled
103 |   if (state.cancel) {
104 |     return state;
105 |   }
106 | 
107 |   // --- By default visit all children down the hierarchy
108 |   state.skipChildren = false;
109 | 
110 |   if (Array.isArray(subject)) {
111 |     for (const statement of subject) {
112 |       state = visitNode(statement, state, stmtVisitor, exprVisitor, parent, tag);
113 |     }
114 |     return state;
115 |   }
116 | 
117 |   switch (subject.type) {
118 |     case T_BLOCK_STATEMENT: {
119 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
120 |       if (state.cancel) return state;
121 |       if (!state.skipChildren) {
122 |         for (const statement of subject.stmts) {
123 |           state = visitNode(statement, state, stmtVisitor, exprVisitor, subject, "statements");
124 |           if (state.cancel) return state;
125 |         }
126 |       }
127 |       state = stmtVisitor?.(false, subject, state, parent, tag) || state;
128 |       return state;
129 |     }
130 | 
131 |     case T_EMPTY_STATEMENT: {
132 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
133 |       return state;
134 |     }
135 | 
136 |     case T_EXPRESSION_STATEMENT: {
137 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
138 |       if (state.cancel) return state;
139 |       if (!state.skipChildren) {
140 |         state = visitNode(subject.expr, state, stmtVisitor, exprVisitor, subject, "expression");
141 |         if (state.cancel) return state;
142 |       }
143 |       state = stmtVisitor?.(false, subject, state, parent, tag) || state;
144 |       return state;
145 |     }
146 | 
147 |     case T_ARROW_EXPRESSION_STATEMENT: {
148 |       //--- Cannot reach that
149 |       return state;
150 |     }
151 | 
152 |     case T_LET_STATEMENT: {
153 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
154 |       if (state.cancel) return state;
155 |       if (!state.skipChildren) {
156 |         for (const declaration of subject.decls) {
157 |           state = visitNode(declaration, state, stmtVisitor, exprVisitor, subject, "declarations");
158 |           if (state.cancel) return state;
159 |         }
160 |       }
161 |       state = stmtVisitor?.(false, subject, state, parent, tag) || state;
162 |       return state;
163 |     }
164 | 
165 |     case T_CONST_STATEMENT: {
166 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
167 |       if (state.cancel) return state;
168 |       if (!state.skipChildren) {
169 |         for (const declaration of subject.decls) {
170 |           state = visitNode(declaration, state, stmtVisitor, exprVisitor, subject, "declarations");
171 |           if (state.cancel) return state;
172 |         }
173 |       }
174 |       state = stmtVisitor?.(false, subject, state, parent, tag) || state;
175 |       return state;
176 |     }
177 | 
178 |     case T_VAR_STATEMENT: {
179 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
180 |       if (state.cancel) return state;
181 |       if (!state.skipChildren) {
182 |         for (const declaration of subject.decls) {
183 |           state = visitNode(declaration, state, stmtVisitor, exprVisitor, subject, "declarations");
184 |           if (state.cancel) return state;
185 |         }
186 |       }
187 |       state = stmtVisitor?.(false, subject, state, parent, tag) || state;
188 |       return state;
189 |     }
190 | 
191 |     case T_IF_STATEMENT: {
192 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
193 |       if (state.cancel) return state;
194 |       if (!state.skipChildren) {
195 |         state = visitNode(subject.cond, state, stmtVisitor, exprVisitor, subject, "condition");
196 |         if (state.cancel) return state;
197 |         if (subject.thenB) {
198 |           state = visitNode(subject.thenB, state, stmtVisitor, exprVisitor, subject, "thenBranch");
199 |         }
200 |         if (state.cancel) return state;
201 |         if (subject.elseB) {
202 |           state = visitNode(subject.elseB, state, stmtVisitor, exprVisitor, subject, "elseBranch");
203 |         }
204 |         if (state.cancel) return state;
205 |       }
206 |       state = stmtVisitor?.(false, subject, state, parent, tag) || state;
207 | 
208 |       return state;
209 |     }
210 | 
211 |     case T_RETURN_STATEMENT: {
212 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
213 |       if (state.cancel) return state;
214 |       if (!state.skipChildren) {
215 |         if (subject.expr) {
216 |           state = visitNode(subject.expr, state, stmtVisitor, exprVisitor, subject, "expression");
217 |         }
218 |         if (state.cancel) return state;
219 |       }
220 |       state = stmtVisitor?.(false, subject, state, parent, tag) || state;
221 |       return state;
222 |     }
223 | 
224 |     case T_BREAK_STATEMENT: {
225 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
226 |       return state;
227 |     }
228 | 
229 |     case T_CONTINUE_STATEMENT: {
230 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
231 |       return state;
232 |     }
233 | 
234 |     case T_WHILE_STATEMENT: {
235 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
236 |       if (state.cancel) return state;
237 |       if (!state.skipChildren) {
238 |         state = visitNode(subject.cond, state, stmtVisitor, exprVisitor, subject, "condition");
239 |         if (state.cancel) return state;
240 |         state = visitNode(subject.body, state, stmtVisitor, exprVisitor, subject, "body");
241 |         if (state.cancel) return state;
242 |       }
243 |       state = stmtVisitor?.(false, subject, state, parent, tag) || state;
244 |       return state;
245 |     }
246 | 
247 |     case T_DO_WHILE_STATEMENT: {
248 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
249 |       if (state.cancel) return state;
250 |       if (!state.skipChildren) {
251 |         state = visitNode(subject.body, state, stmtVisitor, exprVisitor, subject, "body");
252 |         if (state.cancel) return state;
253 |         state = visitNode(subject.cond, state, stmtVisitor, exprVisitor, subject, "condition");
254 |         if (state.cancel) return state;
255 |       }
256 |       state = stmtVisitor?.(false, subject, state, parent, tag) || state;
257 |       return state;
258 |     }
259 | 
260 |     case T_FOR_STATEMENT: {
261 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
262 |       if (state.cancel) return state;
263 |       if (!state.skipChildren) {
264 |         if (subject.init) {
265 |           state = visitNode(subject.init, state, stmtVisitor, exprVisitor, subject, "init");
266 |         }
267 |         if (state.cancel) return state;
268 |         if (subject.cond) {
269 |           state = visitNode(subject.cond, state, stmtVisitor, exprVisitor, subject, "condition");
270 |         }
271 |         if (state.cancel) return state;
272 |         if (subject.upd) {
273 |           state = visitNode(subject.upd, state, stmtVisitor, exprVisitor, subject, "update");
274 |         }
275 |         if (state.cancel) return state;
276 |         state = visitNode(subject.body, state, stmtVisitor, exprVisitor, subject, "body");
277 |         if (state.cancel) return state;
278 |       }
279 |       state = stmtVisitor?.(false, subject, state, parent, tag) || state;
280 |       return state;
281 |     }
282 | 
283 |     case T_FOR_IN_STATEMENT: {
284 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
285 |       if (state.cancel) return state;
286 |       if (!state.skipChildren) {
287 |         state = visitNode(subject.expr, state, stmtVisitor, exprVisitor, subject, "expression");
288 |         if (state.cancel) return state;
289 |         state = visitNode(subject.body, state, stmtVisitor, exprVisitor, subject, "body");
290 |         if (state.cancel) return state;
291 |       }
292 |       state = stmtVisitor?.(false, subject, state, parent, tag) || state;
293 |       return state;
294 |     }
295 | 
296 |     case T_FOR_OF_STATEMENT: {
297 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
298 |       if (state.cancel) return state;
299 |       if (!state.skipChildren) {
300 |         state = visitNode(subject.expr, state, stmtVisitor, exprVisitor, subject, "expression");
301 |         if (state.cancel) return state;
302 |         state = visitNode(subject.body, state, stmtVisitor, exprVisitor, subject, "body");
303 |         if (state.cancel) return state;
304 |       }
305 |       state = stmtVisitor?.(false, subject, state, parent, tag) || state;
306 |       return state;
307 |     }
308 | 
309 |     case T_THROW_STATEMENT: {
310 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
311 |       if (state.cancel) return state;
312 |       if (!state.skipChildren) {
313 |         state = visitNode(subject.expr, state, stmtVisitor, exprVisitor, subject, "expression");
314 |         if (state.cancel) return state;
315 |       }
316 |       state = stmtVisitor?.(false, subject, state, parent, tag) || state;
317 |       return state;
318 |     }
319 |     case T_TRY_STATEMENT: {
320 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
321 |       if (state.cancel) return state;
322 |       if (!state.skipChildren) {
323 |         if (subject.tryB) {
324 |           state = visitNode(subject.tryB, state, stmtVisitor, exprVisitor, subject, "tryBlock");
325 |         }
326 |         if (state.cancel) return state;
327 |         if (subject.catchB) {
328 |           state = visitNode(subject.catchB, state, stmtVisitor, exprVisitor, subject, "catchBlock");
329 |         }
330 |         if (state.cancel) return state;
331 |         if (subject.finallyB) {
332 |           state = visitNode(
333 |             subject.finallyB,
334 |             state,
335 |             stmtVisitor,
336 |             exprVisitor,
337 |             subject,
338 |             "finallyBlock",
339 |           );
340 |         }
341 |         if (state.cancel) return state;
342 |       }
343 |       state = stmtVisitor?.(false, subject, state, parent, tag) || state;
344 |       return state;
345 |     }
346 |     case T_SWITCH_STATEMENT: {
347 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
348 |       if (state.cancel) return state;
349 |       if (!state.skipChildren) {
350 |         state = visitNode(subject.expr, state, stmtVisitor, exprVisitor, subject, "expression");
351 |         if (state.cancel) return state;
352 |         for (const switchCase of subject.cases) {
353 |           if (switchCase.caseE)
354 |             state = visitNode(
355 |               switchCase.caseE,
356 |               state,
357 |               stmtVisitor,
358 |               exprVisitor,
359 |               subject,
360 |               "caseExpression",
361 |             );
362 |           if (state.cancel) return state;
363 |           if (switchCase.stmts === undefined) continue;
364 |           for (const statement of switchCase.stmts) {
365 |             state = visitNode(
366 |               statement,
367 |               state,
368 |               stmtVisitor,
369 |               exprVisitor,
370 |               subject,
371 |               "switchStatement",
372 |             );
373 |             if (state.cancel) return state;
374 |           }
375 |         }
376 |       }
377 |       state = stmtVisitor?.(false, subject, state, parent, tag) || state;
378 |       return state;
379 |     }
380 | 
381 |     case T_FUNCTION_DECLARATION: {
382 |       state = stmtVisitor?.(true, subject, state, parent, tag) || state;
383 |       if (state.cancel) return state;
384 |       if (!state.skipChildren) {
385 |         for (const expr of subject.args) {
386 |           state = visitNode(expr, state, stmtVisitor, exprVisitor, subject, "arg");
387 |           if (state.cancel) return state;
388 |         }
389 |         state = visitNode(subject.stmt, state, stmtVisitor, exprVisitor, subject, "statement");
390 |         if (state.cancel) return state;
391 |       }
392 |       state = stmtVisitor?.(false, subject, state, parent, tag) || state;
393 |       return state;
394 |     }
395 | 
396 |     // ================= Expressions =================
397 |     case T_UNARY_EXPRESSION: {
398 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
399 |       if (state.cancel) return state;
400 |       if (!state.skipChildren) {
401 |         state = visitNode(subject.expr, state, stmtVisitor, exprVisitor, subject, "operand");
402 |         if (state.cancel) return state;
403 |       }
404 |       state = exprVisitor?.(false, subject, state, parent, tag) || state;
405 |       return state;
406 |     }
407 | 
408 |     case T_BINARY_EXPRESSION: {
409 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
410 |       if (state.cancel) return state;
411 |       if (!state.skipChildren) {
412 |         state = visitNode(subject.left, state, stmtVisitor, exprVisitor, subject, "left");
413 |         if (state.cancel) return state;
414 |         state = visitNode(subject.right, state, stmtVisitor, exprVisitor, subject, "right");
415 |         if (state.cancel) return state;
416 |       }
417 |       state = exprVisitor?.(false, subject, state, parent, tag) || state;
418 |       return state;
419 |     }
420 | 
421 |     case T_SEQUENCE_EXPRESSION: {
422 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
423 |       if (state.cancel) return state;
424 |       if (!state.skipChildren) {
425 |         for (const expr of subject.exprs) {
426 |           state = visitNode(expr, state, stmtVisitor, exprVisitor, subject, "expression");
427 |           if (state.cancel) return state;
428 |         }
429 |       }
430 |       state = exprVisitor?.(false, subject, state, parent, tag) || state;
431 |       return state;
432 |     }
433 | 
434 |     case T_CONDITIONAL_EXPRESSION: {
435 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
436 |       if (state.cancel) return state;
437 |       if (!state.skipChildren) {
438 |         state = visitNode(subject.cond, state, stmtVisitor, exprVisitor, subject, "condition");
439 |         if (state.cancel) return state;
440 |         state = visitNode(subject.thenE, state, stmtVisitor, exprVisitor, subject, "consequent");
441 |         if (state.cancel) return state;
442 |         state = visitNode(subject.elseE, state, stmtVisitor, exprVisitor, subject, "alternate");
443 |         if (state.cancel) return state;
444 |       }
445 |       state = exprVisitor?.(false, subject, state, parent, tag) || state;
446 |       return state;
447 |     }
448 | 
449 |     case T_FUNCTION_INVOCATION_EXPRESSION: {
450 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
451 |       if (state.cancel) return state;
452 |       if (!state.skipChildren) {
453 |         for (const arg of subject.arguments) {
454 |           state = visitNode(arg, state, stmtVisitor, exprVisitor, subject, "argument");
455 |           if (state.cancel) return state;
456 |         }
457 |         state = visitNode(subject.obj, state, stmtVisitor, exprVisitor, subject, "object");
458 |         if (state.cancel) return state;
459 |       }
460 |       state = exprVisitor?.(false, subject, state, parent, tag) || state;
461 |       return state;
462 |     }
463 | 
464 |     case T_MEMBER_ACCESS_EXPRESSION: {
465 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
466 |       if (state.cancel) return state;
467 |       if (!state.skipChildren) {
468 |         state = visitNode(subject.obj, state, stmtVisitor, exprVisitor, subject, "object");
469 |         if (state.cancel) return state;
470 |       }
471 |       state = exprVisitor?.(false, subject, state, parent, tag) || state;
472 |       return state;
473 |     }
474 | 
475 |     case T_CALCULATED_MEMBER_ACCESS_EXPRESSION: {
476 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
477 |       if (state.cancel) return state;
478 |       if (!state.skipChildren) {
479 |         state = visitNode(subject.obj, state, stmtVisitor, exprVisitor, subject, "object");
480 |         if (state.cancel) return state;
481 |         state = visitNode(subject.member, state, stmtVisitor, exprVisitor, subject, "member");
482 |         if (state.cancel) return state;
483 |       }
484 |       state = exprVisitor?.(false, subject, state, parent, tag) || state;
485 |       return state;
486 |     }
487 | 
488 |     case T_IDENTIFIER: {
489 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
490 |       return state;
491 |     }
492 | 
493 |     case T_LITERAL: {
494 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
495 |       return state;
496 |     }
497 | 
498 |     case T_ARRAY_LITERAL: {
499 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
500 |       if (state.cancel) return state;
501 |       if (!state.skipChildren) {
502 |         for (const item of subject.items) {
503 |           state = visitNode(item, state, stmtVisitor, exprVisitor, subject, "item");
504 |           if (state.cancel) return state;
505 |         }
506 |       }
507 |       state = exprVisitor?.(false, subject, state, parent, tag) || state;
508 |       return state;
509 |     }
510 | 
511 |     case T_OBJECT_LITERAL: {
512 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
513 |       if (state.cancel) return state;
514 |       if (!state.skipChildren) {
515 |         for (const prop of subject.props) {
516 |           if (Array.isArray(prop)) {
517 |             const [key, value]: [Expression, Expression] = prop;
518 |             state = visitNode(key, state, stmtVisitor, exprVisitor, subject, "propKey");
519 |             if (state.cancel) return state;
520 |             state = visitNode(value, state, stmtVisitor, exprVisitor, subject, "propValue");
521 |             if (state.cancel) return state;
522 |           } else {
523 |             //SpreadExpression branch
524 |             state = visitNode(prop, state, stmtVisitor, exprVisitor, subject, "prop");
525 |             if (state.cancel) return state;
526 |           }
527 |         }
528 |       }
529 |       state = exprVisitor?.(false, subject, state, parent, tag) || state;
530 |       return state;
531 |     }
532 | 
533 |     case T_SPREAD_EXPRESSION: {
534 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
535 |       if (state.cancel) return state;
536 |       if (!state.skipChildren) {
537 |         state = visitNode(subject.expr, state, stmtVisitor, exprVisitor, subject, "operand");
538 |         if (state.cancel) return state;
539 |       }
540 |       state = exprVisitor?.(false, subject, state, parent, tag) || state;
541 |       return state;
542 |     }
543 | 
544 |     case T_ASSIGNMENT_EXPRESSION: {
545 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
546 |       if (state.cancel) return state;
547 |       if (!state.skipChildren) {
548 |         state = visitNode(subject.expr, state, stmtVisitor, exprVisitor, subject, "operand");
549 |         if (state.cancel) return state;
550 |         state = visitNode(subject.leftValue, state, stmtVisitor, exprVisitor, subject, "leftValue");
551 |         if (state.cancel) return state;
552 |       }
553 |       state = exprVisitor?.(false, subject, state, parent, tag) || state;
554 |       return state;
555 |     }
556 | 
557 |     case T_NO_ARG_EXPRESSION: {
558 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
559 |       return state;
560 |     }
561 | 
562 |     case T_ARROW_EXPRESSION: {
563 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
564 |       if (state.cancel) return state;
565 |       if (!state.skipChildren) {
566 |         for (const expr of subject.args) {
567 |           state = visitNode(expr, state, stmtVisitor, exprVisitor, subject, "arg");
568 |           if (state.cancel) return state;
569 |         }
570 |         state = visitNode(subject.statement, state, stmtVisitor, exprVisitor, subject, "statement");
571 |         if (state.cancel) return state;
572 |       }
573 |       state = exprVisitor?.(false, subject, state, parent, tag) || state;
574 |       return state;
575 |     }
576 | 
577 |     case T_PREFIX_OP_EXPRESSION:
578 |     case T_POSTFIX_OP_EXPRESSION: {
579 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
580 |       if (state.cancel) return state;
581 |       if (!state.skipChildren) {
582 |         state = visitNode(subject.expr, state, stmtVisitor, exprVisitor, subject, "operand");
583 |         if (state.cancel) return state;
584 |       }
585 |       state = exprVisitor?.(false, subject, state, parent, tag) || state;
586 |       return state;
587 |     }
588 | 
589 |     case T_VAR_DECLARATION: {
590 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
591 |       if (state.cancel) return state;
592 |       if (!state.skipChildren) {
593 |         if (subject.aDestr !== undefined) {
594 |           for (const expr of subject.aDestr) {
595 |             state = visitNode(expr, state, stmtVisitor, exprVisitor, subject);
596 |             if (state.cancel) return state;
597 |           }
598 |         }
599 | 
600 |         if (subject.oDestr !== undefined) {
601 |           for (const expr of subject.oDestr) {
602 |             state = visitNode(expr, state, stmtVisitor, exprVisitor, subject);
603 |             if (state.cancel) return state;
604 |           }
605 |         }
606 | 
607 |         if (subject.expr) {
608 |           state = visitNode(subject.expr, state, stmtVisitor, exprVisitor, subject, "expression");
609 |         }
610 |         if (state.cancel) return state;
611 |       }
612 |       state = exprVisitor?.(false, subject, state, parent, tag) || state;
613 |       return state;
614 |     }
615 | 
616 |     case T_DESTRUCTURE:
617 |     case T_OBJECT_DESTRUCTURE:
618 |     case T_ARRAY_DESTRUCTURE: {
619 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
620 |       if (state.cancel) return state;
621 |       if (!state.skipChildren) {
622 |         if (subject.aDestr !== undefined) {
623 |           for (const expr of subject.aDestr) {
624 |             state = visitNode(expr, state, stmtVisitor, exprVisitor, subject);
625 |             if (state.cancel) return state;
626 |           }
627 |         }
628 | 
629 |         if (subject.oDestr !== undefined) {
630 |           for (const expr of subject.oDestr) {
631 |             state = visitNode(expr, state, stmtVisitor, exprVisitor, subject);
632 |             if (state.cancel) return state;
633 |           }
634 |         }
635 |       }
636 |       state = exprVisitor?.(false, subject, state, parent, tag) || state;
637 |       return state;
638 |     }
639 | 
640 |     case T_REACTIVE_VAR_DECLARATION: {
641 |       state = exprVisitor?.(true, subject, state, parent, tag) || state;
642 |       if (state.cancel) return state;
643 |       if (!state.skipChildren) {
644 |         if (subject.expr) {
645 |           state = visitNode(subject.expr, state, stmtVisitor, exprVisitor, subject, "expression");
646 |         }
647 |         if (state.cancel) return state;
648 |       }
649 |       state = exprVisitor?.(false, subject, state, parent, tag) || state;
650 |       return state;
651 |     }
652 | 
653 |     case T_TEMPLATE_LITERAL_EXPRESSION:
654 |       // TODO: Implement this
655 |       return state;
656 | 
657 |     case T_SWITCH_CASE:
658 |       return state;
659 | 
660 |     default:
661 |       unreachable(subject);
662 |       return state;
663 |   }
664 | }
665 | 
```

--------------------------------------------------------------------------------
/blog/public/resources/llms.txt:
--------------------------------------------------------------------------------

```
  1 | # XMLUI Framework
  2 | 
  3 | XMLUI is a declarative framework for building user interfaces with XML markup and flexible theming. XMLUI enables developers to create sophisticated web applications with little or no knowledge of JavaScript, CSS, or React.
  4 | 
  5 | ## Core Philosophy
  6 | 
  7 | XMLUI apps are:
  8 | - **Easy to create** - Build on the web platform with minimal programming knowledge
  9 | - **Beautiful by default** - Enjoy themes that look great out of the box and are easy to modify
 10 | - **Connected** - Read and write APIs with little or no scripting
 11 | - **Modular** - Use a comprehensive suite of 90+ components that you can extend
 12 | - **Easy to deploy** - Just drop a handful of files onto a static webserver
 13 | 
 14 | ### Key Features
 15 | - **Reactive data binding** with automatic UI updates (like spreadsheets)
 16 | - **90+ built-in components** covering all application needs
 17 | - **Virtualized performance** for large datasets (List, Table components)
 18 | - **Template properties** for extensive component customization (25+ templates)
 19 | - **Helper tags** (`<variable>`, `<property>`, `<event>`) for clean markup organization
 20 | - **Comprehensive theming** system with 7 built-in theme variants
 21 | - **Real-time data sources** and seamless API integration
 22 | - **Built-in routing** and navigation management
 23 | - **No CSS required** for most styling needs
 24 | 
 25 | ### Basic Syntax
 26 | ```xml
 27 | <App>
 28 |   <variable name="count" value="{0}" />
 29 |   <Button onClick="count++" label="Count: {count}" />
 30 |   <Text>{count}</Text>
 31 | </App>
 32 | ```
 33 | 
 34 | ## Application Structure
 35 | 
 36 | ### File Structure
 37 | ```
 38 | app/
 39 | ├── index.html           # Entry point with XMLUI script reference
 40 | ├── Main.xmlui          # Root App component
 41 | ├── config.json         # App configuration (optional)
 42 | ├── components/         # User-defined components
 43 | │   ├── Dashboard.xmlui
 44 | │   └── UserCard.xmlui
 45 | ├── resources/          # Static assets (images, icons)
 46 | ├── themes/            # Custom theme definitions
 47 | └── xmlui/             # XMLUI framework files
 48 |     └── 0.9.23.js
 49 | ```
 50 | 
 51 | ### Main.xmlui Structure
 52 | ```xml
 53 | <App name="My Application" layout="vertical-sticky">
 54 |   <AppHeader>
 55 |     <property name="logoTemplate">
 56 |       <Heading level="h3" value="My App" />
 57 |     </property>
 58 |   </AppHeader>
 59 | 
 60 |   <NavPanel>
 61 |     <NavLink label="Home" to="/" icon="home" />
 62 |     <NavGroup label="Management">
 63 |       <NavLink label="Users" to="/users" />
 64 |       <NavLink label="Settings" to="/settings" />
 65 |     </NavGroup>
 66 |   </NavPanel>
 67 | 
 68 |   <Pages fallbackPath="/">
 69 |     <Page url="/">
 70 |       <Dashboard />
 71 |     </Page>
 72 |     <Page url="/users">
 73 |       <UserList />
 74 |     </Page>
 75 |   </Pages>
 76 | 
 77 |   <Footer>© 2024 My Company</Footer>
 78 | </App>
 79 | ```
 80 | 
 81 | ## Component Categories
 82 | 
 83 | ### Application Structure (7 components)
 84 | - **App** - Root container with 7 layout templates:
 85 |   - `horizontal` / `horizontal-sticky` - Stacked header, nav, content, footer
 86 |   - `vertical` / `vertical-sticky` / `vertical-full-header` - Left sidebar navigation
 87 |   - `condensed` / `condensed-sticky` - Combined header/nav bar (default)
 88 | - **AppHeader** - Top navigation with logo, title, profile areas
 89 | - **NavPanel** - Navigation container supporting hierarchical menus
 90 | - **Pages/Page** - Declarative routing with URL patterns and `$routeParams`
 91 | - **Footer** - Application footer area
 92 | - **Theme** - Styling contexts without CSS
 93 | - **PageMetaTitle** - Dynamic browser tab titles
 94 | 
 95 | ### Layout Components (15+ components)
 96 | **Primary Containers:**
 97 | - **Stack/VStack/HStack** - Fundamental layout with orientation, alignment, gaps
 98 | - **CHStack/CVStack** - Centered horizontal/vertical stacks
 99 | - **FlowLayout** - Horizontal layout with automatic wrapping and responsive sizing
100 | - **Grid** - Grid-based layouts
101 | - **Splitter/HSplitter/VSplitter** - Resizable divided containers
102 | 
103 | **Content Organization:**
104 | - **Card** - Content boundaries with padding, borders, shadows
105 | - **Backdrop** - Semi-transparent overlays with optional content
106 | - **ContentSeparator** - Visual dividers (horizontal/vertical lines)
107 | - **StickyBox** - Fixed positioning (top/bottom)
108 | - **Breakout** - Full-width sections ignoring parent constraints
109 | - **SpaceFiller** - Flexible space allocation and line breaks
110 | 
111 | ### Form Components (15+ components)
112 | **Form Structure:**
113 | - **Form** - Data binding, validation, submission with `$data` context
114 | - **FormItem** - Field wrapper with validation, labeling, `$value` context
115 | - **FormSection** - Field grouping with FlowLayout
116 | 
117 | **Input Controls:**
118 | - **TextBox/TextArea/PasswordInput** - Text input with validation support
119 | - **NumberBox** - Numeric input with spinners and formatting
120 | - **DatePicker** - Calendar-based date selection
121 | - **FileInput/FileUploadDropZone** - File selection and drag-drop upload
122 | 
123 | **Selection Controls:**
124 | - **Select/AutoComplete** - Dropdown selection with search and custom templates
125 | - **RadioGroup** - Mutually exclusive selection
126 | - **Checkbox/Switch** - Boolean controls
127 | - **Slider** - Numeric range selection with single/dual thumbs
128 | 
129 | **Specialized:**
130 | - **ColorPicker** - RGB/HSL/HEX color selection
131 | - **EmojiSelector** - System emoji browser
132 | - **Option** - Data structure for selection components
133 | 
134 | ### Data Display (12+ components)
135 | **High-Performance Lists:**
136 | - **List** - Virtualized, groupable, sortable lists for thousands of items
137 |   - Context: `$item`, `$itemIndex`, `$isFirst`, `$isLast`, `$group`
138 |   - Features: grouping, sorting, pagination, empty state handling
139 | - **Items** - Lightweight iteration without virtualization
140 | - **Table** - Structured data with Column components and sorting
141 | 
142 | **Typography:**
143 | - **Text** - Styled text with variants (abbr, cite, code, deleted, inserted, keyboard)
144 | - **Heading/H1-H6** - Semantic headings with anchor generation
145 | - **Link** - Navigation with internal/external URL support
146 | - **Markdown** - Rich text formatting with markdown syntax
147 | 
148 | **Media & Status:**
149 | - **Image** - Responsive images with aspect ratio control
150 | - **Icon** - Scalable vector icons from built-in registry
151 | - **Avatar** - Circular profile images with fallback initials
152 | - **Logo** - Application branding with light/dark variants
153 | - **Badge** - Status indicators and tags with color mapping
154 | - **ProgressBar** - Task completion visualization
155 | - **Spinner** - Indeterminate loading states
156 | - **NoResult** - Empty state displays
157 | 
158 | **Content Organization:**
159 | - **Tabs/TabItem** - Switchable content panels
160 | - **ExpandableItem** - Collapsible sections (like HTML details)
161 | - **TableOfContents** - Auto-generated navigation from headings
162 | 
163 | ### Interactive Components (8+ components)
164 | **Menus:**
165 | - **DropdownMenu** - Space-efficient action menus with trigger templates
166 | - **MenuItem/SubMenuItem** - Menu items with icons, actions, nested submenus
167 | - **MenuSeparator** - Visual menu grouping
168 | 
169 | **Dialogs:**
170 | - **ModalDialog** - Overlay dialogs with parameters and programmatic control
171 | 
172 | **Navigation:**
173 | - **NavLink** - Smart navigation with active state detection
174 | - **NavGroup** - Collapsible hierarchical menu containers
175 | 
176 | **Utilities:**
177 | - **Bookmark** - Scroll targets for navigation
178 | - **ToneChangerButton** - Light/dark mode toggle
179 | 
180 | ### Data Management (6+ components)
181 | **API Integration:**
182 | - **DataSource** - Automatic data fetching with reactive URL binding
183 | - **APICall** - Manual CRUD operations with success/error handling
184 | - **RealTimeAdapter** - WebSocket/SSE integration
185 | 
186 | **State Management:**
187 | - **AppState** - Global state persistence across navigation
188 | - **ChangeListener** - Reactive value monitoring and side effects
189 | 
190 | **Background Processing:**
191 | - **Queue** - FIFO task processing with UI progress feedback
192 | 
193 | ### Chart Components (5 components)
194 | - **BarChart** - Horizontal/vertical bars, grouped/stacked layouts
195 | - **LineChart** - Connected points for trends and time series data
196 | - **PieChart/DonutChart** - Proportional circular visualizations
197 | - **Legend** - Standalone chart legends with custom positioning
198 | 
199 | ### Utility Components (5+ components)
200 | - **Fragment** - Conditional rendering and component grouping
201 | - **Redirect** - Internal navigation redirects with conditions
202 | - **Column** - Table column definitions with sorting and custom content
203 | - **LabelList** - Custom chart labeling
204 | 
205 | ### Extension Packages
206 | **XMLUI Animations (Experimental):**
207 | - **FadeAnimation/FadeInAnimation/FadeOutAnimation** - Opacity transitions
208 | - **ScaleAnimation** - Size transformations
209 | - **SlideInAnimation** - Directional entry animations
210 | 
211 | ## XML Markup Fundamentals
212 | 
213 | ### Properties
214 | Properties can be literal strings or JavaScript expressions in curly braces:
215 | ```xml
216 | <!-- Literal -->
217 | <Text value="Hello World" />
218 | 
219 | <!-- Expression -->
220 | <Text value="Result: {6 * 7}" />
221 | 
222 | <!-- JSON Array -->
223 | <Items data="{['Apple', 'Banana', 'Cherry']}">
224 |   <Text>{$item}</Text>
225 | </Items>
226 | 
227 | <!-- JSON Object -->
228 | <Form data='{{ name: "John", age: 30 }}'>
229 |   <FormItem bindTo="name" />
230 |   <FormItem bindTo="age" />
231 | </Form>
232 | ```
233 | 
234 | ### Variables
235 | Components can declare reactive variables using two syntaxes:
236 | ```xml
237 | <!-- Attribute syntax -->
238 | <App var.count="{0}" var.message="Hello">
239 |   <Text>{message}: {count}</Text>
240 | </App>
241 | 
242 | <!-- Helper tag syntax -->
243 | <App>
244 |   <variable name="count" value="{0}" />
245 |   <variable name="message" value="Hello" />
246 |   <Text>{message}: {count}</Text>
247 | </App>
248 | ```
249 | 
250 | ### Reactive Variables
251 | Variables automatically update dependent expressions:
252 | ```xml
253 | <App var.count="{0}" var.doubleCount="{count * 2}">
254 |   <Button onClick="count++" label="Increment" />
255 |   <Text>Count: {count}</Text>
256 |   <Text>Double: {doubleCount}</Text> <!-- Updates automatically -->
257 | </App>
258 | ```
259 | 
260 | ### Event Handlers
261 | Events can be declared as attributes or using helper tags:
262 | ```xml
263 | <!-- Attribute syntax -->
264 | <Button onClick="count++" label="Click me" />
265 | 
266 | <!-- Helper tag syntax (required for component handlers) -->
267 | <Button label="Save">
268 |   <event name="click">
269 |     <APICall url="/api/save" method="POST" body="{formData}" />
270 |   </event>
271 | </Button>
272 | ```
273 | 
274 | ## Helper Tags
275 | 
276 | ### `<variable>` - State Management
277 | Alternative to `var.` attribute syntax:
278 | ```xml
279 | <variable name="user" value='{{ name: "John", role: "admin" }}' />
280 | <variable name="isLoading" value="{false}" />
281 | <variable name="items" value="{[]}" />
282 | ```
283 | 
284 | ### `<property>` - Template Content
285 | For template properties containing markup:
286 | ```xml
287 | <List data="{users}">
288 |   <property name="itemTemplate">
289 |     <Card>
290 |       <HStack gap="$space-2">
291 |         <Avatar src="{$item.avatar}" />
292 |         <VStack>
293 |           <Text variant="strong">{$item.name}</Text>
294 |           <Text color="muted">{$item.email}</Text>
295 |         </VStack>
296 |       </HStack>
297 |     </Card>
298 |   </property>
299 | 
300 |   <property name="emptyListTemplate">
301 |     <VStack horizontalAlignment="center" padding="$space-8">
302 |       <Icon name="user-x" size="xl" color="muted" />
303 |       <Text color="muted">No users found</Text>
304 |     </VStack>
305 |   </property>
306 | </List>
307 | ```
308 | 
309 | ### `<event>` - Action Handlers
310 | For complex event handling with components:
311 | ```xml
312 | <Button label="Process Data">
313 |   <event name="click">
314 |     <APICall
315 |       url="/api/process"
316 |       method="POST"
317 |       body="{selectedItems}"
318 |       onSuccess="toast('Processing complete!'); data.refresh()"
319 |       onError="toast('Failed to process', 'error')" />
320 |   </event>
321 | </Button>
322 | ```
323 | 
324 | ## Template Properties System
325 | 
326 | 25+ template properties for extensive customization:
327 | 
328 | ### Application Templates (5)
329 | ```xml
330 | <App>
331 |   <property name="logoTemplate">
332 |     <HStack gap="$space-1">
333 |       <Icon name="star" color="primary" />
334 |       <Heading level="h3" value="My App" />
335 |     </HStack>
336 |   </property>
337 | </App>
338 | 
339 | <AppHeader>
340 |   <property name="profileMenuTemplate">
341 |     <DropdownMenu>
342 |       <MenuItem label="Profile" icon="user" />
343 |       <MenuItem label="Settings" icon="settings" />
344 |       <MenuSeparator />
345 |       <MenuItem label="Logout" icon="logout" />
346 |     </DropdownMenu>
347 |   </property>
348 | </AppHeader>
349 | ```
350 | 
351 | ### Form Templates (3)
352 | ```xml
353 | <Form>
354 |   <property name="buttonRowTemplate">
355 |     <HStack gap="$space-2" horizontalAlignment="end">
356 |       <Button type="button" label="Cancel" variant="outlined" />
357 |       <Button type="submit" label="Save" variant="solid" />
358 |     </HStack>
359 |   </property>
360 | </Form>
361 | 
362 | <FormItem field="category">
363 |   <property name="inputTemplate">
364 |     <Select>
365 |       <Option value="work" label="Work" />
366 |       <Option value="personal" label="Personal" />
367 |     </Select>
368 |   </property>
369 | </FormItem>
370 | ```
371 | 
372 | ### Data Display Templates (8)
373 | ```xml
374 | <List data="{products}" groupBy="category">
375 |   <property name="groupHeaderTemplate">
376 |     <HStack justifyContent="space-between" padding="$space-2">
377 |       <Text variant="subtitle">{$group.key}</Text>
378 |       <Badge value="{$group.items.length}" />
379 |     </HStack>
380 |   </property>
381 | 
382 |   <property name="itemTemplate">
383 |     <Card>
384 |       <Text variant="strong">{$item.name}</Text>
385 |       <Text>${$item.price}</Text>
386 |     </Card>
387 |   </property>
388 | 
389 |   <property name="emptyListTemplate">
390 |     <Text color="muted">No products available</Text>
391 |   </property>
392 | </List>
393 | ```
394 | 
395 | ## Context Variables
396 | 
397 | Special variables automatically provided by XMLUI within specific scopes:
398 | 
399 | ### Form Context
400 | - **`$data`** - Complete form data object (inside `<Form>`)
401 | - **`$value`** - Current field value (inside `<FormItem>`)
402 | - **`$validationResult`** - Field validation status
403 | - **`$setValue`** - Function to programmatically set field values
404 | 
405 | ```xml
406 | <Form data='{{ name: "", email: "" }}'>
407 |   <FormItem bindTo="name">
408 |     <Text>Current value: {$value}</Text>
409 |     <TextBox placeholder="Enter name" />
410 |   </FormItem>
411 | 
412 |   <Text>Form data: {JSON.stringify($data)}</Text>
413 | </Form>
414 | ```
415 | 
416 | ### Data Iteration Context
417 | - **`$item`** - Current item in data iterations
418 | - **`$itemIndex`** - Zero-based index of current item
419 | - **`$isFirst/$isLast`** - Boolean position indicators
420 | 
421 | ```xml
422 | <Items data="{products}">
423 |   <HStack gap="$space-2">
424 |     <Badge value="{$itemIndex + 1}" />
425 |     <Text>{$item.name}</Text>
426 |     {$isFirst && <Badge value="First" />}
427 |     {$isLast && <Badge value="Last" />}
428 |   </HStack>
429 | </Items>
430 | ```
431 | 
432 | ### Grouping Context (List with groupBy)
433 | - **`$group`** - Group information object
434 |   - `$group.key` - Group identifier
435 |   - `$group.items` - Items in this group
436 |   - `$group.id` - Unique group ID
437 | 
438 | ```xml
439 | <List data="{orders}" groupBy="status">
440 |   <property name="groupHeaderTemplate">
441 |     <HStack justifyContent="space-between">
442 |       <Text variant="strong">{$group.key} Orders</Text>
443 |       <Badge value="{$group.items.length}" />
444 |     </HStack>
445 |   </property>
446 | </List>
447 | ```
448 | 
449 | ### Navigation Context
450 | - **`$routeParams`** - URL parameters from route patterns
451 | 
452 | ```xml
453 | <Pages>
454 |   <Page url="/user/:userId">
455 |     <Text>Viewing user: {$routeParams.userId}</Text>
456 |   </Page>
457 | </Pages>
458 | ```
459 | 
460 | ### Component Context
461 | - **`$props`** - Properties passed to user-defined components
462 | - **`var.myVar`** - Scoped variables declared in markup
463 | - **`componentId`** - Reference to components with `id` attributes
464 | 
465 | ## Reactive Data Binding
466 | 
467 | XMLUI's reactive system automatically updates UI when data changes:
468 | 
469 | ### Basic Reactivity
470 | ```xml
471 | <App>
472 |   <!-- User selection drives other components -->
473 |   <Select id="category" initialValue="electronics">
474 |     <Option value="electronics" label="Electronics" />
475 |     <Option value="clothing" label="Clothing" />
476 |   </Select>
477 | 
478 |   <!-- DataSource reacts to selection changes -->
479 |   <DataSource
480 |     id="products"
481 |     url="/api/products?category={category.value}"
482 |     resultSelector="data" />
483 | 
484 |   <!-- Multiple components use the same data -->
485 |   <Text>Found {products.value?.length || 0} products</Text>
486 |   <List data="{products.value}">
487 |     <property name="itemTemplate">
488 |       <Card title="{$item.name}" subtitle="${$item.price}" />
489 |     </property>
490 |   </List>
491 | </App>
492 | ```
493 | 
494 | ### Advanced Data Flow with Forms
495 | ```xml
496 | <App>
497 |   <!-- Form drives API calls -->
498 |   <Form id="searchForm" data='{{ query: "", minPrice: 0 }}'>
499 |     <FormItem bindTo="query" label="Search">
500 |       <TextBox placeholder="Product name..." />
501 |     </FormItem>
502 |     <FormItem bindTo="minPrice" label="Min Price">
503 |       <NumberBox />
504 |     </FormItem>
505 |   </Form>
506 | 
507 |   <!-- DataSource reacts to form changes -->
508 |   <DataSource
509 |     id="results"
510 |     url="/api/search?q={searchForm.data.query}&minPrice={searchForm.data.minPrice}"
511 |     resultSelector="products" />
512 | 
513 |   <!-- UI updates automatically -->
514 |   <List data="{results.value}" loading="{results.loading}">
515 |     <property name="itemTemplate">
516 |       <Card title="{$item.name}" subtitle="${$item.price}" />
517 |     </property>
518 |     <property name="emptyListTemplate">
519 |       <Text>No products match your criteria</Text>
520 |     </property>
521 |   </List>
522 | </App>
523 | ```
524 | 
525 | ## Layout System
526 | 
527 | ### Fundamental Containers
528 | 
529 | **Stack Variants:**
530 | - **VStack** - Vertical layout (each child on new row)
531 | - **HStack** - Horizontal layout (children in same row)
532 | - **CHStack/CVStack** - Centered horizontal/vertical stacks
533 | - **Stack** - Configurable orientation with `orientation` property
534 | 
535 | **Flow Layout:**
536 | - **FlowLayout** - Horizontal with wrapping, percentage-aware sizing
537 | 
538 | ### Layout Properties
539 | - **Alignment**: `horizontalAlignment`, `verticalAlignment` (start, center, end)
540 | - **Spacing**: `gap`, `padding` (use theme variables like `$space-2`, `$gap-loose`)
541 | - **Sizing**: `width`, `height`, `minWidth`, `maxWidth` etc.
542 | 
543 | ### Dimension Units
544 | - **No value** - Container determines size based on content
545 | - **Fixed units** - px, rem, em (container respects exact size)
546 | - **Percentage** - % of parent container (50%, 100%)
547 | - **Star sizing** - * weights for distributing remaining space (*, 2*, 3*)
548 | 
549 | ### Layout Examples
550 | ```xml
551 | <!-- Responsive card grid -->
552 | <FlowLayout>
553 |   <Card width="300px">Content 1</Card>
554 |   <Card width="300px">Content 2</Card>
555 |   <Card width="300px">Content 3</Card>
556 | </FlowLayout>
557 | 
558 | <!-- Dashboard layout with star sizing -->
559 | <HStack height="100vh">
560 |   <!-- Sidebar takes fixed width -->
561 |   <VStack width="250px" backgroundColor="$color-surface">
562 |     <Navigation />
563 |   </VStack>
564 | 
565 |   <!-- Main content takes remaining space -->
566 |   <VStack width="*" padding="$space-4">
567 |     <!-- Header takes content height -->
568 |     <Header />
569 | 
570 |     <!-- Content area takes remaining height -->
571 |     <VStack height="*">
572 |       <MainContent />
573 |     </VStack>
574 |   </VStack>
575 | </HStack>
576 | 
577 | <!-- Centered dialog -->
578 | <CVStack height="100vh" width="100vw">
579 |   <Card width="400px" padding="$space-6">
580 |     <ModalContent />
581 |   </Card>
582 | </CVStack>
583 | ```
584 | 
585 | ## Theming System
586 | 
587 | ### Built-in Themes
588 | 7 theme variants available:
589 | - **xmlui** (default blue)
590 | - **xmlui-green**
591 | - **xmlui-gray**
592 | - **xmlui-orange**
593 | - **xmlui-purple**
594 | - **xmlui-cyan**
595 | - **xmlui-red**
596 | 
597 | Each theme supports light and dark tones.
598 | 
599 | ### Theme Usage
600 | ```xml
601 | <!-- Global theme -->
602 | <Theme themeId="xmlui-green" tone="dark">
603 |   <App>...</App>
604 | </Theme>
605 | 
606 | <!-- Scoped theme overrides -->
607 | <Theme
608 |   backgroundColor-Button="red"
609 |   borderRadius-Button="8px"
610 |   color-text-Button="white">
611 |   <Button label="Danger Action" />
612 | </Theme>
613 | ```
614 | 
615 | ### Theme Variables
616 | **Colors:**
617 | ```css
618 | --color-primary, --color-secondary, --color-accent
619 | --color-background, --color-surface, --color-overlay
620 | --color-text, --color-muted, --color-inverse
621 | --color-success, --color-warn, --color-danger, --color-info
622 | ```
623 | 
624 | **Spacing:**
625 | ```css
626 | --space-xs, --space-sm, --space-normal, --space-lg, --space-xl
627 | --space-2, --space-4, --space-8, --space-16, --space-32, --space-64
628 | --gap-tight, --gap-normal, --gap-loose
629 | ```
630 | 
631 | **Typography:**
632 | ```css
633 | --font-size-xs, --font-size-sm, --font-size-normal, --font-size-lg
634 | --font-weight-normal, --font-weight-medium, --font-weight-bold
635 | --line-height-normal, --line-height-relaxed
636 | ```
637 | 
638 | ## User-Defined Components
639 | 
640 | ### Component Definition
641 | ```xml
642 | <!-- components/UserCard.xmlui -->
643 | <Component name="UserCard">
644 |   <Card>
645 |     <HStack gap="$space-2">
646 |       <Avatar src="{$props.user.avatar}" name="{$props.user.name}" />
647 |       <VStack>
648 |         <Text variant="strong">{$props.user.name}</Text>
649 |         <Text color="muted">{$props.user.email}</Text>
650 |         <Text>{$props.user.role ?? 'User'}</Text>
651 |       </VStack>
652 |     </HStack>
653 |   </Card>
654 | </Component>
655 | ```
656 | 
657 | ### Component Usage
658 | ```xml
659 | <App>
660 |   <UserCard user='{{ name: "John Doe", email: "[email protected]", role: "Admin" }}' />
661 | </App>
662 | ```
663 | 
664 | ### Component with Methods and Events
665 | ```xml
666 | <Component
667 |   name="Counter"
668 |   var.count="{$props.initialValue ?? 0}"
669 |   method.reset="() => count = 0"
670 |   method.setValue="(value) => count = value">
671 | 
672 |   <HStack gap="$space-2">
673 |     <Button onClick="count--" label="-" />
674 |     <Text>{count}</Text>
675 |     <Button onClick="count++" label="+" />
676 |     <Button onClick="emitEvent('valueChanged', count)" label="Notify" />
677 |   </HStack>
678 | </Component>
679 | 
680 | <!-- Usage -->
681 | <Counter
682 |   id="myCounter"
683 |   initialValue="{10}"
684 |   onValueChanged="(value) => toast('Count changed to: ' + value)" />
685 | <Button onClick="myCounter.reset()" label="Reset Counter" />
686 | ```
687 | 
688 | ### Slots for Content Injection
689 | ```xml
690 | <Component name="Dialog">
691 |   <Card padding="$space-6">
692 |     <VStack gap="$space-4">
693 |       <!-- Named slot with context -->
694 |       <Slot name="headerTemplate" title="{$props.title}">
695 |         <Heading level="h2">{$props.title}</Heading>
696 |       </Slot>
697 | 
698 |       <!-- Default slot for main content -->
699 |       <Slot>
700 |         <Text>Default content when no children provided</Text>
701 |       </Slot>
702 | 
703 |       <!-- Named slot for actions -->
704 |       <Slot name="actionsTemplate">
705 |         <Button label="OK" />
706 |       </Slot>
707 |     </VStack>
708 |   </Card>
709 | </Component>
710 | 
711 | <!-- Usage -->
712 | <Dialog title="Confirm Action">
713 |   <property name="headerTemplate">
714 |     <HStack gap="$space-2">
715 |       <Icon name="alert-triangle" color="warn" />
716 |       <Text variant="strong">{$title}</Text>
717 |     </HStack>
718 |   </property>
719 | 
720 |   <Text>Are you sure you want to delete this item?</Text>
721 | 
722 |   <property name="actionsTemplate">
723 |     <HStack gap="$space-2">
724 |       <Button label="Cancel" variant="outlined" />
725 |       <Button label="Delete" variant="solid" themeColor="danger" />
726 |     </HStack>
727 |   </property>
728 | </Dialog>
729 | ```
730 | 
731 | ## Performance Features
732 | 
733 | ### Virtualization
734 | - **List** - Automatically virtualizes large datasets (thousands of items)
735 | - **Table** - Virtual scrolling for massive data tables
736 | - Zero configuration required
737 | 
738 | ### Efficient Updates
739 | - Smart reactivity only updates dependent components
740 | - Batched DOM updates
741 | - Minimal re-rendering
742 | 
743 | ### Loading States
744 | ```xml
745 | <DataSource id="users" url="/api/users" />
746 | <List data="{users.value}" loading="{users.loading}">
747 |   <property name="itemTemplate">
748 |     <UserCard user="{$item}" />
749 |   </property>
750 |   <property name="emptyListTemplate">
751 |     <VStack horizontalAlignment="center" padding="$space-8">
752 |       <Spinner />
753 |       <Text>Loading users...</Text>
754 |     </VStack>
755 |   </property>
756 | </List>
757 | ```
758 | 
759 | ## Deployment
760 | 
761 | ### Static Hosting
762 | XMLUI apps are static files that can be deployed anywhere:
763 | - **Development**: `python -m http.server` or `npx http-server`
764 | - **Production**: Any static host (Netlify, AWS S3, GitHub Pages)
765 | 
766 | ### Minimal Deployment
767 | ```
768 | app/
769 | ├── index.html
770 | ├── Main.xmlui
771 | └── xmlui/
772 |     └── 0.9.23.js
773 | ```
774 | 
775 | The framework automatically loads components from the `components/` folder and handles routing without server configuration.
776 | 
777 | ## Best Practices
778 | 
779 | ### Application Architecture
780 | 1. **Start with App component** defining layout and navigation structure
781 | 2. **Use Pages for routing** with meaningful URL patterns
782 | 3. **Organize components** in logical folders by feature
783 | 4. **Leverage template properties** instead of custom CSS for customization
784 | 
785 | ### Data Management
786 | 1. **Use DataSource for reads**, APICall for writes
787 | 2. **Implement loading states** and error handling
788 | 3. **Utilize reactive binding** for automatic UI updates
789 | 4. **Structure forms** with proper validation and field binding
790 | 
791 | ### Performance
792 | 1. **Choose List over Items** for large datasets (1000+ items)
793 | 2. **Use virtualization** features for tables and lists
794 | 3. **Implement pagination** for very large datasets
795 | 4. **Optimize data fetching** with proper caching
796 | 
797 | ### Code Organization
798 | 1. **Break down complex UIs** into reusable components
799 | 2. **Use meaningful component and variable names**
800 | 3. **Organize navigation** hierarchically with NavGroup
801 | 4. **Handle empty states** and error conditions gracefully
802 | 
803 | XMLUI enables rapid development of professional web applications through declarative markup, comprehensive theming, and automatic reactive updates. The framework handles modern web complexity while maintaining simplicity for developers of all skill levels.
804 | 
```
Page 99/186FirstPrevNextLast