#
tokens: 47533/50000 7/1634 files (page 46/145)
lines: off (toggle) GitHub
raw markdown copy
This is page 46 of 145. Use http://codebase.md/xmlui-org/xmlui/%7Bnode.props.src?lines=false&page={x} to view the full context.

# Directory Structure

```
├── .changeset
│   ├── config.json
│   └── tender-llamas-dress.md
├── .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-swa.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
│   │   │   ├── Choose.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
│   │           ├── HelloMd.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.module.scss
│   │       │   ├── 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.tsx
│   │       │   ├── StandalonePlayground.tsx
│   │       │   ├── StandalonePlaygroundNative.module.scss
│   │       │   ├── StandalonePlaygroundNative.tsx
│   │       │   ├── ThemeSwitcher.module.scss
│   │       │   ├── ThemeSwitcher.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
    │   │   ├── Choose
    │   │   │   ├── Choose.md
    │   │   │   ├── Choose.spec.ts
    │   │   │   └── Choose.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
    │   │   │   └── test-padding.xmlui
    │   │   ├── 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.json
    ├── tsdown.config.ts
    ├── vite.config.ts
    └── vitest.config.ts
```

# Files

--------------------------------------------------------------------------------
/xmlui/dev-docs/next/component-dev-guide.md:
--------------------------------------------------------------------------------

```markdown
# XMLUI Component Development Guide

## Component Architecture Overview

XMLUI components follow a specific architectural pattern that separates concerns between React implementation and XMLUI framework integration. Understanding this pattern is crucial for creating components that integrate properly with the XMLUI ecosystem.

## The Two-File Pattern

Every XMLUI component should be split into two files:

### 1. Native Component (`ComponentNameNative.tsx`)

This file contains the actual React component implementation:

```typescript
// ToneSwitchNative.tsx
import React from 'react';

export type ToneSwitchProps = {
  /**
   * Icon to display for light mode
   * @default "sun"
   */
  iconLight?: string;

  /**
   * Icon to display for dark mode
   * @default "moon"
   */
  iconDark?: string;
};

export function ToneSwitch({
  iconLight = "sun",
  iconDark = "moon"
}: ToneSwitchProps) {
  // React component implementation
  return <div>...</div>;
}
```

**Key characteristics:**
- Pure React component
- Exports TypeScript interface for props
- Uses standard React patterns and hooks
- Contains all component logic and rendering
- Can be used standalone outside XMLUI

### 2. XMLUI Renderer (`ComponentName.tsx`)

This file contains the XMLUI integration layer:

```typescript
// ToneSwitch.tsx
import { createComponentRenderer } from "../../components-core/renderers";
import { createMetadata } from "../metadata-helpers";
import { ToneSwitch, type ToneSwitchProps } from "./ToneSwitchNative";

const COMP = "ToneSwitch";

export const ToneSwitchMd = createMetadata({
  status: "stable",
  description: "`ToneSwitch` enables users to switch themes.",
  props: {
    iconLight: {
      type: "string",
      description: "Icon to display for light mode",
      defaultValue: "sun",
    },
    iconDark: {
      type: "string",
      description: "Icon to display for dark mode",
      defaultValue: "moon",
    },
  },
  // ... theme variables, etc.
});

export const toneSwitchComponentRenderer = createComponentRenderer(
  COMP,
  ToneSwitchMd,
  ({ node, extractValue }) => {
    return <ToneSwitch
      iconLight={extractValue(node.props.iconLight)}
      iconDark={extractValue(node.props.iconDark)}
    />;
  }
);
```

**Key characteristics:**
- Imports the native component
- Defines component metadata for documentation
- Creates the component renderer that bridges XMLUI and React
- Handles prop extraction from XMLUI markup

## Component Registration

### 1. Add to Component Metadata Registry

```typescript
// collectedComponentMetadata.ts
import { ToneSwitchMd } from "./ToneSwitch/ToneSwitch";

export const collectedComponentMetadata = {
  // ... other components
  ToneSwitch: ToneSwitchMd,
};
```

### 2. Register Component Renderer

```typescript
// ComponentProvider.tsx
import { toneSwitchComponentRenderer } from "./ToneSwitch/ToneSwitch";

// In ComponentRegistry constructor:
if (process.env.VITE_USED_COMPONENTS_ToneSwitch !== "false") {
  this.registerCoreComponent(toneSwitchComponentRenderer);
}
```

## Component Documentation Pattern

### Source Documentation (`ComponentName.md`)

Each component should have a corresponding `.md` file in its source directory (`src/components/ComponentName/ComponentName.md`) that contains template-based documentation. This source documentation uses special template markers that get processed during documentation generation.

#### Template Markers

XMLUI uses these optional template patterns for documentation generation:

- **`%-DESC-START` / `%-DESC-END`**: Main component description and examples
- **`%-PROP-START propName` / `%-PROP-END`**: Detailed property documentation
- **`%-EVENT-START eventName` / `%-EVENT-END`**: Event documentation
- **`%-API-START methodName` / `%-API-END`**: API method documentation

Use these to provide additional detail beyond what's automatically generated from the metadata.

The ToneSwitch example shows the minimal approach - just %-DESC-START/END for the main example, letting the props documentation be auto-generated from the metadata. You'd add %-PROP-START iconLight only if you wanted to elaborate on that specific prop with examples or additional context beyond "Icon to display for light mode".

#### Example Source Documentation

```markdown
%-DESC-START

xmlui-pg {4} copy display name="Example: using ToneSwitch"
<App>
  <AppHeader>
    <SpaceFiller />
    <ToneSwitch />
  </AppHeader>
  <Card
    title="Tone Switch"
    subtitle="Toggle the switch to change the tone."
  />
</App>

%-DESC-END
```

### Generated Documentation

When you run `npm run generate-all-docs` from `xmlui/xmlui`, the source documentation gets processed and generates the final documentation files in `docs/content/components/`.

The generated documentation includes:
- Component description from `%-DESC-START/END` blocks
- Properties section with details from metadata and `%-PROP-START/END` blocks
- Events section (if any events are defined)
- Exposed methods section (if any API methods are defined)
- Styling section with theme variables table

#### Generated Documentation Example

```markdown
# ToneSwitch [#toneswitch]

ToneSwitch enables the user to switch between light and dark modes using a switch control.

xmlui-pg {4} copy display name="Example: using ToneSwitch"
<App>
  <AppHeader>
    <SpaceFiller />
    <ToneSwitch />
  </AppHeader>
  <Card
    title="Tone Switch"
    subtitle="Toggle the switch to change the tone."
  />
</App>

## Properties [#properties]

### iconDark (default: "moon") [#icondark-default-moon]

Icon to display for dark mode

### iconLight (default: "sun") [#iconlight-default-sun]

Icon to display for light mode

## Events [#events]

This component does not have any events.

## Exposed Methods [#exposed-methods]

This component does not expose any methods.

## Styling [#styling]

### Theme Variables [#theme-variables]

| Variable | Default Value (Light) | Default Value (Dark) |
| --- | --- | --- |
| [backgroundColor](../styles-and-themes/common-units/#color)-ToneSwitch-dark | $color-primary-500 | $color-primary-500 |
| [backgroundColor](../styles-and-themes/common-units/#color)-ToneSwitch-light | $color-surface-200 | $color-surface-700 |
```

**Important distinction**: The source `.md` files in `src/components/` are templates that use special markers, while the generated files in `docs/content/components/` are the final documentation that gets published. Always edit the source files, not the generated ones.

## Component Metadata Best Practices

### Props Definition

```typescript
props: {
  propName: {
    type: "string" | "boolean" | "number",
    description: "Clear description of what this prop does",
    defaultValue: "default value if any",
    required?: true, // if prop is required
  },
}
```

### Theme Variables

```typescript
// Include if component has custom styling
themeVars: parseScssVar(styles.themeVars),
limitThemeVarsToComponent: true,
defaultThemeVars: {
  [`backgroundColor-${COMP}`]: "$color-surface-200",
  [`color-${COMP}`]: "$color-text-primary",

  // Dark mode variants
  dark: {
    [`backgroundColor-${COMP}`]: "$color-surface-700",
  }
}
```

## Component Renderer Patterns

### Basic Prop Extraction

```typescript
export const componentRenderer = createComponentRenderer(
  COMP,
  ComponentMd,
  ({ node, extractValue }) => {
    return <Component
      title={extractValue(node.props.title)}
      enabled={extractValue.asOptionalBoolean(node.props.enabled)}
      count={extractValue.asOptionalNumber(node.props.count)}
    />;
  }
);
```

### Common Extract Value Methods

- `extractValue(prop)` - Extract string value
- `extractValue.asOptionalString(prop)` - Extract optional string
- `extractValue.asOptionalBoolean(prop)` - Extract optional boolean
- `extractValue.asOptionalNumber(prop)` - Extract optional number

## Extending Existing Components

### Using inputRenderer Pattern

When extending components like Toggle, use the `inputRenderer` pattern:

```typescript
export function CustomSwitch({ icon }: CustomSwitchProps) {
  return (
    <Toggle
      variant="switch"
      inputRenderer={(contextVars) => (
        <div className="custom-switch">
          <Icon name={contextVars.$checked ? "on" : "off"} />
        </div>
      )}
    />
  );
}
```

**Context Variables Available:**
- `$checked` - Current boolean state
- `$setChecked` - Function to update state

## Theme Integration

### Using Theme Context

```typescript
import { useThemes, useTheme } from "../../components-core/theming/ThemeContext";

function ThemeAwareComponent() {
  // For reading/writing theme state
  const { activeThemeTone, setActiveThemeTone } = useThemes();

  // For accessing theme properties
  const theme = useTheme();

  return <div data-theme={activeThemeTone}>...</div>;
}
```

## File Structure

```
src/components/MyComponent/
├── MyComponent.tsx           # XMLUI renderer & metadata
├── MyComponentNative.tsx     # React implementation
├── MyComponent.module.scss   # Component styles
├── MyComponent.md           # Component documentation template
```

## Documentation Generation Workflow

1. **Create source documentation**: Write your component documentation in `src/components/ComponentName/ComponentName.md` using the template markers
2. **Generate documentation**: Run `npm run generate-all-docs` from `xmlui/xmlui`
3. **Review generated docs**: Check the generated files in `docs/content/components/` to ensure they look correct
4. **Iterate as needed**: Update source documentation and regenerate as needed

The documentation generation process:
- Extracts component metadata from your component renderer
- Processes template markers in source `.md` files
- Combines metadata with template content
- Generates final documentation with proper formatting, property tables, and theme variable documentation

## Common Pitfalls to Avoid

### 1. Don't Mix Concerns
- Keep React logic in Native component
- Keep XMLUI integration in renderer component
- Don't put XMLUI-specific code in Native component

### 2. Always Export Props Type
```typescript
// Good
export type MyComponentProps = { ... };
export function MyComponent(props: MyComponentProps) { ... }

// Bad
export function MyComponent({ title }: { title: string }) { ... }
```

### 3. Handle Prop Extraction Properly
```typescript
// Good - handles undefined props
iconLight={extractValue(node.props.iconLight)}

// Bad - assumes props exist
iconLight={node.props.iconLight}
```

### 4. Include Proper Default Values
```typescript
// Good - consistent defaults
export function Component({
  title = "Default Title"
}: ComponentProps) { ... }

// In metadata:
defaultValue: "Default Title"
```

### 5. Don't Edit Generated Documentation
```typescript
// Good - edit source template
// src/components/MyComponent/MyComponent.md

// Bad - editing generated files (gets overwritten)
// docs/content/components/MyComponent.md
```

## Testing Your Component

### 1. Test Native Component Standalone
```typescript
// Can be tested as regular React component
render(<ToneSwitch iconLight="custom" iconDark="custom" />);
```

### 2. Test XMLUI Integration
```xmlui
<ToneSwitch iconLight="brightness" iconDark="nightMode" />
```

### 3. Verify Documentation Generation
- Check that props appear in generated docs
- Verify default values are correct
- Ensure descriptions are helpful
- Test example code snippets

## Documentation Guidelines

### Component Description
- Start with backticks around component name
- Be concise but descriptive
- Focus on what the component does, not how

### Prop Descriptions
- Use clear, actionable language
- Mention default behavior
- Include examples when helpful
- Avoid implementation details

### Examples
- Show basic usage first
- Include common customization scenarios
- Use realistic prop values
- Use `xmlui-pg` blocks for interactive examples

### Template Marker Usage
- Use `%-DESC-START/END` for main description and primary examples
- Use `%-PROP-START propName/END` for detailed property documentation
- Use `%-EVENT-START eventName/END` for event documentation
- Use `%-API-START methodName/END` for API method documentation

## Summary Checklist

Before submitting a new XMLUI component:

- [ ] Split into Native and Renderer files
- [ ] Proper TypeScript interfaces exported
- [ ] Component registered in ComponentProvider
- [ ] Metadata added to collectedComponentMetadata
- [ ] Props properly documented with defaults
- [ ] Theme variables defined if needed
- [ ] Source documentation created with template markers
- [ ] Documentation generated and reviewed
- [ ] Examples include usage scenarios
- [ ] Component follows established patterns
- [ ] No XMLUI-specific code in Native component
- [ ] Proper prop extraction in renderer
- [ ] Generated documentation is accurate and helpful

```

--------------------------------------------------------------------------------
/xmlui/src/components-core/utils/hooks.tsx:
--------------------------------------------------------------------------------

```typescript
import type { MutableRefObject } from "react";
import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
import { isEqual } from "lodash-es";

import type { ComponentApi, ContainerState } from "../rendering/ContainerWrapper";
import type { ColorDef } from "./css-utils";

import { shallowCompare, useEvent } from "../utils/misc";
import { useTheme } from "../theming/ThemeContext";
import { EMPTY_OBJECT } from "../constants";
import Color from "color";

/**
 * This hook invokes a callback when the size of the specified DOM element changes.
 * @param element A DOM element to watch for size changes
 * @param callback The callback function to invoke on size changes
 */
export const useResizeObserver = (
  element: React.MutableRefObject<Element | undefined | null>,
  callback: ResizeObserverCallback,
) => {
  const current = element?.current;
  const observer = useRef<ResizeObserver>();

  useEffect(() => {
    // --- We are already observing old element
    if (observer?.current && current) {
      observer.current.unobserve(current);
    }
    observer.current = new ResizeObserver(callback);
    if (element && element.current && observer.current) {
      observer.current.observe(element.current);
    }
  }, [callback, current, element]);
};

/**
 * This hook gets the previous state of the specified value (props, variable used in a React
 * function).
 *
 * @see {@link https://blog.logrocket.com/accessing-previous-props-state-react-hooks/}
 */
export function usePrevious<T>(value: T): ReturnType<typeof useRef<T>>["current"] {
  const ref = useRef<T>();
  useEffect(() => {
    ref.current = value;
  }, [value]);
  return ref.current;
}

/**
 * This hook tests if the component is used within an iframe.
 * @returns True, if the component is used within an iframe; otherwise, false.
 */
export function useIsInIFrame() {
  return useMemo(() => {
    try {
      return window.self !== window.top;
    } catch (e) {
      return true;
    }
  }, []);
}

// --- Tests if the document has the focus
const hasFocus = () => typeof document !== "undefined" && document.hasFocus();

/**
 * This hook tests if the window has the focus.
 * @returns True, if the window has the focus; otherwise, false.
 */
export function useIsWindowFocused() {
  const [focused, setFocused] = useState(hasFocus); // Focus for first render

  useEffect(() => {
    setFocused(hasFocus()); // Focus for additional renders

    const onFocus = () => setFocused(true);
    const onBlur = () => setFocused(false);

    window.addEventListener("focus", onFocus);
    window.addEventListener("blur", onBlur);

    return () => {
      window.removeEventListener("focus", onFocus);
      window.removeEventListener("blur", onBlur);
    };
  }, []);

  return focused;
}

/**
 * This hook allows running media queries.
 * @param query Media query to run
 */
export function useMediaQuery(query: string) {
  const [matches, setMatches] = useState<boolean>(false);
  useEffect(() => {
    if (!window) {
      setMatches(false);
      return;
    }

    const matchMedia = window.matchMedia(query);
    // Triggered at the first client-side load and if query changes
    handleChange();

    matchMedia.addEventListener("change", handleChange);
    return () => {
      matchMedia.removeEventListener("change", handleChange);
    };

    function handleChange() {
      setMatches(matchMedia.matches);
    }
  }, [query]);

  return matches;
}

/**
 * This hook runs a callback function when a key is pressed in the document window.
 * @param onDocumentKeydown Callback function to run
 */
export function useDocumentKeydown(onDocumentKeydown: (event: KeyboardEvent) => void) {
  const onKeyDown = useEvent(onDocumentKeydown);
  useEffect(() => {
    document.addEventListener("keydown", onKeyDown);
    return () => {
      document.removeEventListener("keydown", onKeyDown);
    };
  }, [onKeyDown]);
}

/**
 * This hook runs a function when the corresponding component has been mounted.
 * @param onMount
 */
export function useOnMount(onMount: any) {
  const thizRef = useRef({ mountedFired: false });
  useEffect(() => {
    if (!thizRef.current.mountedFired) {
      thizRef.current.mountedFired = true;
      onMount?.();
    }
  }, [onMount]);
}

/**
 * This hook memoizes the specified value. It uses a shallow comparison with the previously
 * stored value when checking for changes. So, while a shallow comparison shows equality,
 * it returns with the memoized value.
 * @param value Value to memoize
 */
export function useShallowCompareMemoize<T extends Record<any, any> | undefined>(value: T) {
  const ref = React.useRef<T>(value);
  const signalRef = React.useRef<number>(0);

  if (!shallowCompare(value, ref.current)) {
    ref.current = value;
    signalRef.current++;
  }

  // eslint-disable-next-line react-hooks/exhaustive-deps
  return React.useMemo(() => ref.current, [signalRef.current]);
}

/**
 * This hook memoizes the specified value. When checking for changes, it uses a deep comparison
 * with the previously stored value. So, while a deep comparison shows equality, it returns with
 * the memoized value, even if value references differ.
 * @param value Value to memoize
 */
export function useDeepCompareMemoize<T extends Record<any, any> | undefined>(value: T) {
  const ref = React.useRef<T>(value);
  const signalRef = React.useRef<number>(0);

  if (!isEqual(value, ref.current)) {
    ref.current = value;
    signalRef.current += 1;
  }

  // eslint-disable-next-line react-hooks/exhaustive-deps
  return React.useMemo(() => ref.current, [signalRef.current]);
}

export function useColors(...colorNames: (string | ColorDef)[]) {
  const { getThemeVar } = useTheme();
  // const paramsRef = useRef(colorNames);
  // const { themeStyles } = useTheme();
  const colors = useMemo(() => {
    const ret: Record<string, string> = {};
    for (const color of colorNames) {
      if (typeof color === "string") {
        const col = getThemeVar(color);
        ret[color] = Color(col).toString();
      } else {
        const col = getThemeVar(color.name);
        ret[color.name] = Color(col).hex().toString();
      }
    }
    return ret;
  }, [colorNames, getThemeVar]);

  // useEffect(() => {
  //   setColors(getColors(...paramsRef.current));
  // }, [themeStyles]);

  return colors;
}

export function useReferenceTrackedApi(componentState: ContainerState) {
  return useShallowCompareMemoize(
    useMemo(() => {
      const ret: Record<string, ComponentApi> = {};
      if (Reflect.ownKeys(componentState).length === 0) {
        //skip containers with no registered apis
        return EMPTY_OBJECT;
      }
      for (const componentApiKey of Object.getOwnPropertySymbols(componentState)) {
        const value = componentState[componentApiKey];
        if (componentApiKey.description) {
          ret[componentApiKey.description] = value;
        }
      }
      return ret;
    }, [componentState]),
  );
}

/**
 * This hook uses either useLayoutEffect or useEffect based on the environment
 * (client-side or server-side).
 */
export const useIsomorphicLayoutEffect =
  typeof document !== "undefined" ? useLayoutEffect : useEffect;

// https://stackoverflow.com/a/49186677
function getScrollParent(element: HTMLElement) {
  let style = getComputedStyle(element);
  const excludeStaticParent = style.position === "absolute";
  const overflowRegex = /(auto|scroll)/;

  if (style.position === "fixed") {
    return document.body;
  }
  for (let parent = element; ; parent = parent.parentElement) {
    if (!parent) {
      return null;
    }
    style = getComputedStyle(parent);
    if (excludeStaticParent && style.position === "static") {
      continue;
    }
    if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) {
      return parent;
    }
  }

  return document.body;
}

export const useScrollParent = (element?: HTMLElement): HTMLElement => {
  const [scrollParent, setScrollParent] = useState<HTMLElement | null>(null);
  useIsomorphicLayoutEffect(() => {
    setScrollParent(element ? getScrollParent(element) : null);
  }, [element]);
  return scrollParent;
};

// because safari doesn't support scrollend event...
export const useScrollEventHandler = (
  element: HTMLElement | null | undefined,
  {
    onScrollStart,
    onScrollEnd,
  }: {
    onScrollStart?: () => void;
    onScrollEnd?: () => void;
  },
) => {
  const thisRef = useRef({ scrolling: false });
  useIsomorphicLayoutEffect(() => {
    let timer;
    let listener = () => {
      if (!thisRef.current.scrolling) {
        onScrollStart?.();
      }
      thisRef.current.scrolling = true;
      clearTimeout(timer);
      timer = setTimeout(() => {
        thisRef.current.scrolling = false;
        onScrollEnd?.();
      }, 50);
    };
    element?.addEventListener("scroll", listener);
    return () => {
      element?.removeEventListener("scroll", listener);
    };
  }, [element, onScrollEnd, onScrollStart]);
};

function realBackgroundColor(elem: HTMLElement) {
  let transparent = "rgba(0, 0, 0, 0)";
  let transparentIE11 = "transparent";
  if (!elem) return transparent;

  let bg = getComputedStyle(elem).backgroundColor;
  if (bg === transparent || bg === transparentIE11) {
    return realBackgroundColor(elem.parentElement);
  } else {
    return bg;
  }
}

export const useRealBackground = (element: HTMLElement) => {
  const { activeThemeTone, activeThemeId } = useTheme();
  const [counter, setCounter] = useState(0);
  useEffect(() => {
    return setCounter((prev) => prev + 1);
  }, [activeThemeTone, activeThemeId]);
  return useMemo(() => (element ? realBackgroundColor(element) : "transparent"), [element]);
};

// export const useIsInViewport = (ref, observerOptions) => {
//   const [entered, setEntered] = useState(false);
//   const observer = useRef(
//     new IntersectionObserver(
//       ([entry]) => setEntered(entry.isIntersecting),
//       observerOptions
//     )
//   );
//
//   useEffect(() => {
//     const element = ref.current;
//     const ob = observer.current;
//
//     // stop observing once the element has entered the viewport for the first time.
//     // if (entered) {
//     //   ob.disconnect();
//     //   return;
//     // }
//
//     if (element) ob.observe(element);
//
//     return () => ob.disconnect();
//   }, [entered, ref]);
//
//   return entered;
// };

export const useStartMargin = (
  hasOutsideScroll: boolean,
  parentRef: MutableRefObject<HTMLElement | null | undefined>,
  scrollRef: MutableRefObject<HTMLElement | null | undefined>,
) => {
  const [startMargin, setStartMargin] = useState<number>(0);

  const calculateStartMargin = useEvent(() => {
    if (!hasOutsideScroll) {
      return 0;
    }
    const precedingElement = parentRef.current;
    const scrollContainer = scrollRef.current;

    if (precedingElement && scrollContainer) {
      const precedingRect = precedingElement.getBoundingClientRect();
      const scrollContainerRect = scrollContainer.getBoundingClientRect();

      // It's important that scrollContainer is indeed the element whose scrollTop is relevant
      const scrollTopOfScrollContainer = scrollContainer.scrollTop;

      const calculatedMargin =
        precedingRect.top - scrollContainerRect.top + scrollTopOfScrollContainer;
      return calculatedMargin;
    }
    return 0;
  });

  useResizeObserver(scrollRef, () => {
    setStartMargin(calculateStartMargin());
  });

  return startMargin;
};

export function useHasExplicitHeight(parentRef: React.MutableRefObject<HTMLDivElement | null>) {
  const [hasHeight, setHasHeight] = useState(false);
  useLayoutEffect(() => {
    if (parentRef.current) {
      const computedStyles = window.getComputedStyle(parentRef.current);
      const hasMaxHeight = computedStyles.maxHeight !== "none";
      // Get the original computed height
      const originalHeight = window.getComputedStyle(parentRef.current).height;

      // Store original inline style to restore it later
      const originalInlineHeight = parentRef.current.style.height || "";

      // Temporarily set height to auto and get the new computed height
      parentRef.current.style.height = "auto";
      const autoHeight = window.getComputedStyle(parentRef.current).height;

      // Restore the original inline style immediately
      parentRef.current.style.height = originalInlineHeight;

      // If the original height is different from what the browser
      // calculates for 'auto', it means a height was explicitly set.
      // We also check if the inline style itself had a value.
      let hasHeight = originalHeight !== autoHeight || !!originalInlineHeight;

      const isFlex = computedStyles.display === "flex";
      setHasHeight(hasMaxHeight || hasHeight || isFlex);
    }
  }, [parentRef]);
  return hasHeight;
}

```

--------------------------------------------------------------------------------
/docs/public/resources/files/tutorials/datasource/api.ts:
--------------------------------------------------------------------------------

```typescript
import { ApiInterceptorDefinition } from "xmlui";

const mock: ApiInterceptorDefinition = {
  type: "db",
  config: {
    database: "xmluiDataManipuliationTutorial",
    version: 1
  },
  apiUrl: "/api",
  helpers: {
    Assertions: {
      getIfPresent: `(itemId) => {
        const found = $db.$shoppingItems.byId(itemId);
        if (!found) {
          throw Errors.NotFound404("Item id:" + itemId + " not found");
        }
        return found;
      }`
    },
  },
  auth: {
    defaultLoggedInUser: {
      id: 1
    }
  },
  schemaDescriptor: {
    tables: [
      {
        name: "shoppingItems",
        fields: {
          id: "bigint",
          name: "varchar(64)",
          quantity: "integer",
          unit: "varchar(64)",
          category: "varchar(64)",
          inPantry: "boolean",
        },
        pk: ["++id"],
      },
      {
        name: "polledItems",
        fields: {
          id: "bigint",
          name: "varchar(64)",
          quantity: "integer",
          unit: "varchar(64)",
          category: "varchar(64)",
          inPantry: "boolean",
        },
        pk: ["++id"],
      },
      {
        name: "recipes",
        fields: {
          id: "bigint",
          name: "varchar(64)",
        },
        pk: ["++id"],
      }
    ],
    dtos: {
      recipe: {
        id: "number",
        name: "string",
        ingredients: "{shoppingItems[]}",
      },
    },
  },
  initialData: {
    shoppingItems: [
      {
        id: 1,
        name: "Carrots",
        quantity: 100,
        unit: "grams",
        category: "vegetables",
        inPantry: true,
      },
      {
        id: 2,
        name: "Bananas",
        quantity: 6,
        unit: "pieces",
        category: "fruits",
        inPantry: false,
      },
      {
        id: 3,
        name: "Apples",
        quantity: 5,
        unit: "pieces",
        category: "fruits",
        inPantry: true,
      },
      {
        id: 4,
        name: "Spinach",
        quantity: 1,
        unit: "bunch",
        category: "vegetables",
        inPantry: true,
      },
      {
        id: 5,
        name: "Milk",
        quantity: 10,
        unit: "liter",
        category: "dairy",
        inPantry: false,
      },
      {
        id: 6,
        name: "Cheese",
        quantity: 200,
        unit: "grams",
        category: "dairy",
        inPantry: false,
      },
      {
        id: 7,
        name: "Tomatoes",
        quantity: 3,
        unit: "pieces",
        category: "vegetables",
        inPantry: false,
      },
      {
        id: 8,
        name: "Oranges",
        quantity: 4,
        unit: "pieces",
        category: "fruits",
        inPantry: true,
      },
      {
        id: 9,
        name: "Broccoli",
        quantity: 2,
        unit: "heads",
        category: "vegetables",
        inPantry: true,
      },
      {
        id: 10,
        name: "Eggs",
        quantity: 12,
        unit: "pieces",
        category: "dairy",
        inPantry: false,
      },
      {
        id: 11,
        name: "Potatoes",
        quantity: 1,
        unit: "kg",
        category: "vegetables",
        inPantry: true,
      },
      {
        id: 12,
        name: "Grapes",
        quantity: 500,
        unit: "grams",
        category: "fruits",
        inPantry: false,
      },
      {
        id: 13,
        name: "Chicken",
        quantity: 2,
        unit: "kg",
        category: "meat",
        inPantry: false,
      },
      {
        id: 14,
        name: "Bread",
        quantity: 1,
        unit: "loaf",
        category: "bakery",
        inPantry: true,
      },
      {
        id: 15,
        name: "Yogurt",
        quantity: 500,
        unit: "grams",
        category: "dairy",
        inPantry: true,
      },
      {
        id: 16,
        name: "Olive Oil",
        quantity: 1,
        unit: "liter",
        category: "cooking oils",
        inPantry: true,
      },
    ],
    polledItems: [],
    recipes: [
      {
        id: 1,
        name: "Salad",
        ingredients: [
          {
            id: 1,
            name: "Carrots",
            quantity: 100,
            unit: "grams",
            category: "vegetables",
            inPantry: true,
          },
          {
            id: 7,
            name: "Tomatoes",
            quantity: 3,
            unit: "pieces",
            category: "vegetables",
            inPantry: false,
          },
          {
            id: 9,
            name: "Broccoli",
            quantity: 2,
            unit: "heads",
            category: "vegetables",
            inPantry: true,
          },
        ]
      },
      {
        id: 2,
        name: "Orange Banana Smoothie",
        ingredients: [
          {
            id: 2,
            name: "Bananas",
            quantity: 6,
            unit: "pieces",
            category: "fruits",
            inPantry: false,
          },
          {
            id: 5,
            name: "Milk",
            quantity: 10,
            unit: "liter",
            category: "dairy",
            inPantry: false,
          },
          {
            id: 8,
            name: "Oranges",
            quantity: 4,
            unit: "pieces",
            category: "fruits",
            inPantry: true,
          },
        ]
      },
      {
        id: 3,
        name: "Carrot Soup",
        ingredients: [
          {
            id: 1,
            name: "Carrots",
            quantity: 100,
            unit: "grams",
            category: "vegetables",
            inPantry: true,
          },
          {
            id: 16,
            name: "Olive Oil",
            quantity: 1,
            unit: "liter",
            category: "cooking oils",
            inPantry: true,
          },
        ]
      },
    ],
  },
  operations: {
    login: {
      url: "/login",
      method: "post",
      queryParamTypes: {
        userId: "integer"
      },
      handler: "$authService.login({id: $queryParams.userId})"
    },

    loadMe: {
      url: "/users/me",
      method: "get",
      handler: "$db.$users.byId($loggedInUser.id)"
    },

    test: {
      url: "/test",
      method: "get",
      handler: "return { message: 'Hello from the Server!' }",
    },

    "shopping-list": {
      url: "/shopping-list",
      method: "get",
      responseShape: "shoppingItem[]",
      handler: `$db.$shoppingItems.toArray()`
    },

    "shopping-list-slow": {
      url: "/shopping-list-slow",
      method: "get",
      responseShape: "shoppingItem[]",
      handler: `
        delay(8000);
        return $db.$shoppingItems.toArray();`
    },

    "shopping-list-create": {
      url: "/shopping-list",
      method: "post",
      queryParamTypes: {
        highlight: "boolean",
      },
      responseShape: "shoppingItem?",
      handler: `{
        if ($queryParams.highlight) {
          $requestBody.name = $requestBody.name.toUpperCase() + "!!!";
        }
        return $db.$shoppingItems.insert($requestBody);
      }`
    },

    "shopping-list-create-query": {
      url: "/shopping-list-query",
      method: "post",
      queryParamTypes: {
        addIfInPantry: "boolean",
      },
      responseShape: "shoppingItem?",
      handler: `return $db.$shoppingItems.insert($requestBody);`
    },

    "shopping-list-delete": {
      url: "/shopping-list/:itemId",
      method: "delete",
      pathParamTypes: {
        itemId: "integer",
      },
      responseShape: "boolean",
      handler: `$db.$shoppingItems.native().where("id").equals($pathParams.itemId).delete();`
    },

    "shopping-list-update": {
      url: "/shopping-list/:itemId",
      method: "put",
      pathParamTypes: {
        itemId: "integer",
      },
      responseShape: "shoppingItem",
      handler: `
        const item = $db.$shoppingItems.byId($pathParams.itemId);
        $db.$shoppingItems.update({...item, ...$requestBody});`
    },

    "shopping-list-update-slow": {
      url: "/shopping-list-slow/:itemId",
      method: "put",
      pathParamTypes: {
        itemId: "integer",
      },
      responseShape: "shoppingItem",
      handler: `{
        delay(5000);
        if ($requestBody.name.toLowerCase() === "error") {
          throw Errors.HttpError(400, { message: "Error!" });
        }
        const item = $db.$shoppingItems.byId($pathParams.itemId);
        $db.$shoppingItems.update({...item, ...$requestBody});
      }`
    },

    "shopping-list-meta": {
      url: "/shopping-list-meta",
      method: "get",
      responseShape: "shoppingItem[]",
      handler: `
        const shoppingList = $db.$shoppingItems.toArray();
        return {
          items: shoppingList,
          meta: {
            totalItems: shoppingList.length,
          },
        };`
    },

    "shopping-list-query": {
      url: "/shopping-list-query",
      method: "get",
      responseShape: "shoppingItem[]",
      handler: `
        let items = $db.$shoppingItems.toArray();
        const { inPantry, limit } = $queryParams;

        items = inPantry !== undefined ? items.filter(item => item.inPantry): items;
        items = limit !== undefined ? items.slice(0, limit) : items;

        return items;`
    },

    "shopping-list-refetch": {
      url: "/shopping-list-refetch",
      method: "get",
      responseShape: "shoppingItem[]",
      handler: `        
        $db.$shoppingItems.insert({
          name: "Carrots",
          quantity: 100,
          unit: "grams",
          category: "vegetables",
          inPantry: true,
        })`
    },

    "shopping-list-headers": {
      url: "/shopping-list-headers",
      method: "get",
      responseShape: "shoppingItem[]",
      handler: `
        const token = $requestHeaders['x-api-key'];
        if (token) {
          console.log("Token #" + token + " accepted!");
          return $db.$shoppingItems.toArray();
        }
        throw Errors.HttpError(400, { message: "No API key provided in header!" });`,
    },

    "shopping-list-headers-post": {
      url: "/shopping-list-headers",
      method: "post",
      responseShape: "shoppingItem[]",
      handler: `
        const token = $requestHeaders['x-api-key'];
        if (token === "1111") {
          console.log("Token #" + token + " accepted!");
          return $db.$shoppingItems.insert($requestBody);
        }
        throw Errors.HttpError(400, { message: "No valid API key provided in header!" });`,
    },

    "shopping-list-polled": {
      url: "/shopping-list-polled",
      method: "get",
      responseShape: "shoppingItem[]",
      handler: `
        if ($db.$polledItems.native().count() >= 5) {
          $db.$polledItems.native().clear();
        }

        const groceriesLength = $db.$shoppingItems.native().count();
        const randomIdx = Math.floor(Math.random() * (groceriesLength + 1));

        const newItem = $db.$shoppingItems.byId(randomIdx);
        if (newItem) {
          newItem.id = undefined;
          $db.$polledItems.insert({
            ...newItem,
          });
        }
        
        return $db.$polledItems.toArray();`
    },

    "shopping-list-pagination": {
      url: "/shopping-list-pagination",
      method: "get",
      responseShape: "shoppingItems[]",
      handler: `
        const items = $db.$shoppingItems.toArray();
        const { size, nextPageParam } = $queryParams;
        const _size = parseInt(size);
        let startIndex = 0;
        let endIndex = items.length < _size ? items.length : _size;
        
        if (nextPageParam !== undefined) {
          const startId = parseInt(nextPageParam);
          const temp = items.findIndex(item => item.id === startId);
          if (temp === -1) {
            throw Errors.HttpError(404, "No such item");
          }

          startIndex = temp + 1;
          endIndex = startIndex + _size < items.length ? startIndex + _size : items.length;
        }

        return items.slice(startIndex, endIndex);`
    },

    "shopping-item-unconventional": {
      url: "/shopping-item-unconventional",
      method: "post",
      responseShape: "shoppingItem",
      handler: "Assertions.getIfPresent($requestBody.id)"
    },

    "shopping-item": {
      url: "/shopping-list/:itemId",
      method: "get",
      pathParamTypes: {
        itemId: "integer"
      },
      responseShape: "shoppingItem",
      handler: "Assertions.getIfPresent($pathParams.itemId)"
    },

    "shopping-item-recipes": {
      url: "/shopping-item-recipes/:itemId",
      method: "get",
      pathParamTypes: {
        itemId: "integer"
      },
      responseShape: "recipe[]",
      handler: `
        const item = Assertions.getIfPresent($pathParams.itemId);
        const recipes = $db.$recipes.toArray().filter(recipe => recipe.ingredients.find(ingredient => ingredient.name === item.name));
        return recipes;`
    }
  }
};

export default mock;

```

--------------------------------------------------------------------------------
/xmlui/src/components-core/markup-check.ts:
--------------------------------------------------------------------------------

```typescript
import type { ComponentDef, CompoundComponentDef } from "../abstractions/ComponentDefs";

import { parseParameterString } from "./script-runner/ParameterParser";
import { Parser } from "../parsers/scripting/Parser";
import { layoutOptionKeys } from "./descriptorHelper";
import { viewportSizeNames } from "../components/abstractions";

type IsValidFunction<T> = (propKey: string, propValue: T) => string | string[] | undefined | null;

// --- This interface reperesent an object that can handle component metadata.
// --- As the metadata format may change in the futue, this interface is used to
// --- abstract the metadata handling.
export interface MetadataHandler {
  componentRegistered: (componentName: string) => boolean;
  getComponentProps: (componentName: string) => PropDescriptorHash;
  getComponentEvents: (componentName: string) => Record<string, any>;
  acceptArbitraryProps: (componentName: string) => boolean;
  getComponentValidator: (componentName: string) => ComponentValidator | void;
}

export type PropDescriptor = {
  type?: string;
  availableValues?: any[];
  defaultValue?: any;
  isValid?: IsValidFunction<any>;
};

export type PropDescriptorHash = Record<string, PropDescriptor>;

export type ComponentValidator = (instance: ComponentDef, devMode?: boolean) => string | string[] | null;

type VisitResult = { cancel?: boolean; abort?: boolean };

/**
 * This function checks the XMLUI markup for potential issues. It retrieves
 * a list of errors and warnings.
 * @param rootDef Root component definition
 * @param components Components referenced in the XMLUI markup
 * @param devMode Indicates if the check is performed in development mode
 * @returns List of errors and warnings
 */
export function checkXmlUiMarkup(
  rootDef: ComponentDef | null,
  components: CompoundComponentDef[],
  metadataHandler: MetadataHandler,
  devMode?: boolean,
): MarkupCheckResult[] {
  const errorsCollected: MarkupCheckResult[] = [];

  // --- Initialize the check
  const continuation: VisitResult = {};
  const componentIdsCollected = new Set<string>();
  const compoundIdsCollected = new Set<string>();

  // --- Visit the root component
  if (rootDef) {
    visitComponent(rootDef, null, componentDefVisitor, continuation, metadataHandler);
  }

  // --- Visit the compound components
  if (!continuation.abort) {
    for (const component of components) {
      // --- Rule: Compound component name must be a valid JavaScript identifier
      if (!isValidIdentifier(component.name)) {
        reportError("M007", "Component", component.name);
      }
      // --- Rule: Compound component name cannot be 'Component'
      if (component.name === "Component") {
        reportError("M008", "Component", component.name);
      }

      // --- Rule: Compound component must not have the name of a registered component
      if (metadataHandler.componentRegistered(component.name)) {
        reportError("M009", "Component", component.name);
      }

      // --- Rule: Compound component name must be unique
      if (compoundIdsCollected.has(component.name)) {
        reportError("M010", "Component", component.name);
      } else {
        compoundIdsCollected.add(component.name);
      }

      // --- Reset component ID scope
      componentIdsCollected.clear();
      // --- Visit the compount component's definition
      visitComponent(component.component, null, componentDefVisitor, continuation, metadataHandler);
    }
  }

  // --- Done.
  return errorsCollected;

  // --- This visitor checks the rules for a particular component
  function componentDefVisitor(
    def: ComponentDef,
    parent: ComponentDef | null | undefined,
    before: boolean,
    continuation: VisitResult,
  ): void {
    // --- This is the visitor function to check a ComponentDef markup
    if (!before) {
      // --- Do not visit the component definition after its children have been visited
      return;
    }

    // --- Rule: Component name must be registered
    if (!metadataHandler.componentRegistered(def.type)) {
      reportError("M001", parent?.type ?? "Root", def.type);
      // continuation.cancel = true;
      return;
    }

    // --- Rule: an ID must be a valid JavaScript identifier
    if (def.uid) {
      if (!isValidIdentifier(def.uid)) {
        reportError("M002", def.type, def.type, def.uid);
      } else if (componentIdsCollected.has(def.uid)) {
        reportError("M003", def.type, def.uid);
      } else {
        componentIdsCollected.add(def.uid);
      }
    }

    // --- Check all props of the component
    const propDescriptors = metadataHandler.getComponentProps(def.type) ?? {};
    const currentProps = def.props ?? {};
    for (const propName of Object.keys(currentProps)) {
      const propDescriptor = propDescriptors[propName];

      // --- Rule: The property must be defined in the component descriptor or be a layout option
      // --- or the component must accept arbitrary properties
      if (propDescriptor) {
        // --- The property has a descriptor, so it is allowed.
        // --- Rule: The property value must be parseable
        const propValue = currentProps[propName];
        if (typeof propValue === "string") {
          try {
            parseParameterString(propValue);
          } catch (error) {
            reportError("M006", def.type, propName, (error as any).message);
          }
        }
      } else {
        // --- The property has no descriptor.
        const propParts = propName.split("-");

        // --- Check for a layout property
        const validProp =
          // --- Layout property
          (propParts.length === 1 && layoutOptionKeys.includes(propName)) ||
          // --- Layout property with viewport size
          (propParts.length === 2 &&
            layoutOptionKeys.includes(propParts[0]) &&
            viewportSizeNames.includes(propParts[1])) ||
          // --- Arbitrary property is allowed
          metadataHandler.acceptArbitraryProps(def.type);

        if (!validProp) {
          // --- The component does not accept arbitrary properties and
          // --- the property is not a layout option
          reportError("M005", def.type, def.type, propName);
        }
      }
    }

    // --- Check all events of the component
    const eventDescriptors = metadataHandler.getComponentEvents(def.type) ?? {};
    const currentEvents = def.events ?? {};
    for (const eventName of Object.keys(currentEvents)) {
      const eventDescriptor = eventDescriptors[eventName];

      // --- Rule: The event must be defined in the component descriptor
      if (eventDescriptor) {
        // --- The event has a descriptor, so it is allowed.
        const eventValue = currentEvents[eventName];
        if (typeof eventValue === "string") {
          // --- Rule: The event value must be parseable
          const parser = new Parser(eventValue);
          try {
            parser.parseStatements();
            if (parser.errors.length > 0) {
              reportError("M012", def.type, eventName, parser.errors[0].text);
            }
          } catch (error) {
            reportError("M012", def.type, eventName, (error as any).message);
          }
        }
      } else {
        reportError("M011", def.type, def.type, eventName);
      }
    }

    // --- Check the component validator
    const componentValidator = metadataHandler.getComponentValidator(def.type);
    if (componentValidator) {
      const validationErrors = componentValidator(def, devMode);
      if (validationErrors) {
        if (Array.isArray(validationErrors)) {
          for (const error of validationErrors) {
            reportError("M013", def.type, error);
          }
        } else {
          reportError("M013", def.type, validationErrors);
        }
      }
    }
  }

  /**
   * Checks if a string is a valid JavaScript identifier.
   * @param identifier The string to check.
   * @returns True if the string is a valid identifier, false otherwise.
   */
  function isValidIdentifier(identifier: string): boolean {
    const identifierRegex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
    return identifierRegex.test(identifier);
  }

  function reportError(code: ErrorCode, name: string, ...args: any) {
    _reportError(code, name, false, ...args);
  }

  function reportWarning(code: ErrorCode, name: string, ...args: any) {
    _reportError(code, name, true, ...args);
  }

  function _reportError(code: ErrorCode, name: string, isWarning: boolean, ...args: any) {
    let errorText: string = errorMessages[code] ?? "Unkonwn error";
    if (args) {
      args.forEach((a: string, idx: number) => (errorText = replace(errorText, `{${idx}}`, args[idx].toString())));
    }

    errorsCollected.push({ name, code, message: errorText, isWarning, args });

    function replace(input: string, placeholder: string, replacement: string): string {
      do {
        input = input.replace(placeholder, replacement);
      } while (input.includes(placeholder));
      return input;
    }
  }
}
// --- This function visits a component, its nested components and children
export function visitComponent(
    def: ComponentDef,
    parent: ComponentDef | null | undefined,
    visitor: (
        def: ComponentDef,
        parent: ComponentDef | null | undefined,
        before: boolean,
        continuation: VisitResult,
    ) => void,
    continuation: VisitResult = {},
    metadataHandler: MetadataHandler,
): void {
  // --- Visit the component (before)
  visitor(def, parent, true, continuation);
  if (continuation.abort || continuation.cancel) {
    // --- Stop the visit
    return;
  }

  // --- Visit the properties with "ComponentDef" value
  const propDescriptors = metadataHandler.getComponentProps(def.type) ?? {};
  const currentProps = def.props ?? {};
  for (const propName of Object.keys(currentProps)) {
    const propDescriptor = propDescriptors[propName];
    if (!propDescriptor) {
      // --- No descriptor for the property, skip it
      continue;
    }

    const propValue = currentProps[propName];
    if (propDescriptor.type === "ComponentDef" && propValue.type) {
      // --- This property holds a nested component, visit it
      visitComponent(propValue, def, visitor, continuation, metadataHandler);
      if (continuation.abort || continuation.cancel) {
        // --- Stop the visit
        return;
      }
    }
  }


  // --- Visit events with nested components
  const eventDescriptors = metadataHandler.getComponentEvents(def.type) ?? {};
  const currentEvents = def.events ?? {};
  for (const eventName of Object.keys(currentEvents)) {
    const eventDescriptor = eventDescriptors[eventName];
    if (!eventDescriptor) {
      // --- No descriptor for the events, skip it
      continue;
    }

    const eventValue = currentEvents[eventName];
    if (typeof eventValue === "object" && eventValue.type) {
      // --- This event holds a nested component, visit it
      visitComponent(eventValue, def, visitor, continuation, metadataHandler);
      if (continuation.abort) {
        // --- Stop visiting this component
        return;
      }
      if (continuation.cancel) {
        // --- Skip the remaining items
        break;
      }
    }
  }

  // --- Visit the component children
  if (def.children) {
    for (const child of def.children) {
      visitComponent(child, def, visitor, continuation, metadataHandler);
      if (continuation.abort) {
        // --- Stop visiting this component
        return;
      }
      if (continuation.cancel) {
        // --- Skip the remaining items
        break;
      }
    }
  }

  // --- Visit the component (after)
  visitor(def, undefined, false, continuation);
}


export type MarkupCheckResult = {
  name: string;
  code: ErrorCode;
  message: string;
  isWarning?: boolean;
  args?: Array<any>
};

// --- Available error codes
type ErrorCode =
  | "M001"
  | "M002"
  | "M003"
  | "M004"
  | "M005"
  | "M006"
  | "M007"
  | "M008"
  | "M009"
  | "M010"
  | "M011"
  | "M012"
  | "M013";

// --- Error message type description
type ErrorText = Record<string, string>;

// --- The error messages of error codes
const errorMessages: ErrorText = {
  M001: "The component '{0}' is not registered",
  M002: "The '{0}' element has an invalid id: '{1}'",
  M003: "Invalid component identifier: '{0}'",
  M004: "Duplicated component identifier: '{0}'",
  M005: "The '{0}' element has an invalid property: '{1}'",
  M006: "Parsing property value of '{0}' failed: {1}",
  M007: "The name of a reusable component is invalid: '{0}'",
  M008: "The name of a reusable component must not be '{0}', as it is a reserved name",
  M009: "A reusable component cannot have the name of a registered component: '{0}'",
  M010: "Duplicated reusable component name: '{0}'",
  M011: "The '{0}' element has an invalid event: '{1}'",
  M012: "Parsing event value of '{0}' failed: {1}",
  M013: "Component validation failed: '{0}'",
};

```

--------------------------------------------------------------------------------
/xmlui/src/components/Toggle/Toggle.module.scss:
--------------------------------------------------------------------------------

```scss
@use "../../components-core/theming/themes" as t;

// --- This code snippet is required to collect the theme variables used in this module
$themeVars: ();
@function createThemeVar($componentVariable) {
  $themeVars: t.appendThemeVar($themeVars, $componentVariable) !global;
  @return t.getThemeVar($themeVars, $componentVariable);
}

// Variables for Checkbox - default variant
$borderRadius-Checkbox--default: createThemeVar("Input:borderRadius-Checkbox--default");
$borderColor-Checkbox--default: createThemeVar("Input:borderColor-Checkbox--default");
$backgroundColor-Checkbox--default: createThemeVar("Input:backgroundColor-Checkbox--default");
$outlineWidth-Checkbox--default--focus: createThemeVar("Input:outlineWidth-Checkbox--default--focus");
$outlineColor-Checkbox--default--focus: createThemeVar("Input:outlineColor-Checkbox--default--focus");
$outlineStyle-Checkbox--default--focus: createThemeVar("Input:outlineStyle-Checkbox--default--focus");
$outlineOffset-Checkbox--default--focus: createThemeVar("Input:outlineOffset-Checkbox--default--focus");

// Variables for Checkbox - error variant
$borderRadius-Checkbox--error: createThemeVar("Input:borderRadius-Checkbox--error");
$borderColor-Checkbox--error: createThemeVar("Input:borderColor-Checkbox--error");
$backgroundColor-Checkbox--error: createThemeVar("Input:backgroundColor-Checkbox--error");
$outlineWidth-Checkbox--error--focus: createThemeVar("Input:outlineWidth-Checkbox--error--focus");
$outlineColor-Checkbox--error--focus: createThemeVar("Input:outlineColor-Checkbox--error--focus");
$outlineStyle-Checkbox--error--focus: createThemeVar("Input:outlineStyle-Checkbox--error--focus");
$outlineOffset-Checkbox--error--focus: createThemeVar("Input:outlineOffset-Checkbox--error--focus");

// Variables for Checkbox - warning variant
$borderRadius-Checkbox--warning: createThemeVar("Input:borderRadius-Checkbox--warning");
$borderColor-Checkbox--warning: createThemeVar("Input:borderColor-Checkbox--warning");
$backgroundColor-Checkbox--warning: createThemeVar("Input:backgroundColor-Checkbox--warning");
$outlineWidth-Checkbox--warning--focus: createThemeVar("Input:outlineWidth-Checkbox--warning--focus");
$outlineColor-Checkbox--warning--focus: createThemeVar("Input:outlineColor-Checkbox--warning--focus");
$outlineStyle-Checkbox--warning--focus: createThemeVar("Input:outlineStyle-Checkbox--warning--focus");
$outlineOffset-Checkbox--warning--focus: createThemeVar("Input:outlineOffset-Checkbox--warning--focus");

// Variables for Checkbox - success variant
$borderRadius-Checkbox--success: createThemeVar("Input:borderRadius-Checkbox--success");
$borderColor-Checkbox--success: createThemeVar("Input:borderColor-Checkbox--success");
$backgroundColor-Checkbox--success: createThemeVar("Input:backgroundColor-Checkbox--success");
$outlineWidth-Checkbox--success--focus: createThemeVar("Input:outlineWidth-Checkbox--success--focus");
$outlineColor-Checkbox--success--focus: createThemeVar("Input:outlineColor-Checkbox--success--focus");
$outlineStyle-Checkbox--success--focus: createThemeVar("Input:outlineStyle-Checkbox--success--focus");
$outlineOffset-Checkbox--success--focus: createThemeVar("Input:outlineOffset-Checkbox--success--focus");

// Variables for Checkbox - hover and disabled states
$borderColor-Checkbox--default--hover: createThemeVar("Input:borderColor-Checkbox--default--hover");
$backgroundColor-Checkbox--disabled: createThemeVar("Input:backgroundColor-Checkbox--disabled");
$borderColor-Checkbox--disabled: createThemeVar("Input:borderColor-Checkbox--disabled");

// Variables for Checkbox - checked states
$borderColor-checked-Checkbox: createThemeVar("Input:borderColor-checked-Checkbox");
$backgroundColor-checked-Checkbox: createThemeVar("Input:backgroundColor-checked-Checkbox");
$borderColor-checked-Checkbox--error: createThemeVar("Input:borderColor-checked-Checkbox--error");
$backgroundColor-checked-Checkbox--error: createThemeVar("Input:backgroundColor-checked-Checkbox--error");
$borderColor-checked-Checkbox--warning: createThemeVar("Input:borderColor-checked-Checkbox--warning");
$backgroundColor-checked-Checkbox--warning: createThemeVar("Input:backgroundColor-checked-Checkbox--warning");
$borderColor-checked-Checkbox--success: createThemeVar("Input:borderColor-checked-Checkbox--success");
$backgroundColor-checked-Checkbox--success: createThemeVar("Input:backgroundColor-checked-Checkbox--success");

// Variables for Checkbox indicator
$backgroundColor-indicator-Checkbox: createThemeVar("backgroundColor-indicator-Checkbox");

// Variables for Switch - hover and disabled states
$borderColor-Switch--default--hover: createThemeVar("Input:borderColor-Switch--default--hover");
$backgroundColor-Switch--disabled: createThemeVar("Input:backgroundColor-Switch--disabled");
$borderColor-Switch--disabled: createThemeVar("Input:borderColor-Switch--disabled");

// Variables for Switch - checked states
$borderColor-checked-Switch: createThemeVar("Input:borderColor-checked-Switch");
$backgroundColor-checked-Switch: createThemeVar("Input:backgroundColor-checked-Switch");
$borderColor-checked-Switch--error: createThemeVar("Input:borderColor-checked-Switch--error");
$backgroundColor-checked-Switch--error: createThemeVar("Input:backgroundColor-checked-Switch--error");
$borderColor-checked-Switch--warning: createThemeVar("Input:borderColor-checked-Switch--warning");
$backgroundColor-checked-Switch--warning: createThemeVar("Input:backgroundColor-checked-Switch--warning");
$borderColor-checked-Switch--success: createThemeVar("Input:borderColor-checked-Switch--success");
$backgroundColor-checked-Switch--success: createThemeVar("Input:backgroundColor-checked-Switch--success");

// Variables for Switch
$backgroundColor-Switch: createThemeVar("Input:backgroundColor-Switch");
$borderColor-Switch: createThemeVar("Input:borderColor-Switch");
$backgroundColor-indicator-Switch: createThemeVar("backgroundColor-indicator-Switch");
$backgroundColor-checked-Switch: createThemeVar("backgroundColor-checked-Switch");
$backgroundColor-indicator-checked-Switch: createThemeVar("backgroundColor-indicator-checked-Switch");
$backgroundColor-Switch-indicator--disabled: createThemeVar("backgroundColor-Switch-indicator--disabled");
$outlineWidth-Switch--focus: createThemeVar("Input:outlineWidth-Switch--focus");
$outlineColor-Switch--focus: createThemeVar("Input:outlineColor-Switch--focus");
$outlineStyle-Switch--focus: createThemeVar("Input:outlineStyle-Switch--focus");
$outlineOffset-Switch--focus: createThemeVar("Input:outlineOffset-Switch--focus");

// Variables for Switch - validation variants
$borderColor-Switch--error: createThemeVar("Input:borderColor-Switch--error");
$borderColor-Switch--warning: createThemeVar("Input:borderColor-Switch--warning");
$borderColor-Switch--success: createThemeVar("Input:borderColor-Switch--success");

// --- CSS properties of a particular Checkbox variant
@mixin checkboxVariant($variantName) {
  border-radius: createThemeVar("Input:borderRadius-Checkbox--#{$variantName}");
  border-color: createThemeVar("Input:borderColor-Checkbox--#{$variantName}");
  background-color: createThemeVar("Input:backgroundColor-Checkbox--#{$variantName}");

  &:focus-visible {
    outline-width: createThemeVar("Input:outlineWidth-Checkbox--#{$variantName}--focus");
    outline-color: createThemeVar("Input:outlineColor-Checkbox--#{$variantName}--focus");
    outline-style: createThemeVar("Input:outlineStyle-Checkbox--#{$variantName}--focus");
    outline-offset: createThemeVar("Input:outlineOffset-Checkbox--#{$variantName}--focus");
  }
}

@mixin hoverAndDisabledState($componentName) {
  &:not([readonly]):not(:disabled):hover {
    border-color: createThemeVar("Input:borderColor-#{$componentName}--default--hover");
  }

  &:disabled {
    cursor: not-allowed;
    background-color: createThemeVar("Input:backgroundColor-#{$componentName}--disabled");
    border-color: createThemeVar("Input:borderColor-#{$componentName}--disabled");
  }
}

@mixin checkedState($componentName) {
  &:checked {
    border-color: createThemeVar("Input:borderColor-checked-#{$componentName}");
    background-color: createThemeVar("Input:backgroundColor-checked-#{$componentName}");
  }

  &:checked:disabled {
    background-color: createThemeVar("Input:backgroundColor-#{$componentName}--disabled");
    border-color: createThemeVar("Input:borderColor-#{$componentName}--disabled");
  }

  &:checked.error {
    border-color: createThemeVar("Input:borderColor-checked-#{$componentName}--error");
    background-color: createThemeVar("Input:backgroundColor-checked-#{$componentName}--error");
  }

  &:checked.warning {
    border-color: createThemeVar("Input:borderColor-checked-#{$componentName}--warning");
    background-color: createThemeVar("Input:backgroundColor-checked-#{$componentName}--warning");
  }

  &:checked.valid {
    border-color: createThemeVar("Input:borderColor-checked-#{$componentName}--success");
    background-color: createThemeVar("Input:backgroundColor-checked-#{$componentName}--success");
  }
}

@layer components {
  .resetAppearance {
    /* Add if not using autoprefixer */
    -webkit-appearance: none;
    appearance: none;
    /* Not removed via appearance */
    margin: 0;
  }

  .label {
    width: 100%;
  }

  .inputContainer {
    z-index: -1;
    position: relative;
    opacity: 0;
    width: 0;
    height: 0;
  }

  // --------------- Checkbox ---------------

  .checkbox {
    display: grid;
    place-content: center;
    min-width: 1em;
    min-height: 1em;
    width: 1em;
    height: 1em;
    border: 2px solid transparent;

    &:not([readonly]) {
      cursor: pointer;
    }

    @include checkboxVariant("default");
    @include hoverAndDisabledState("Checkbox");

    .forceHover {
      border-color: $borderColor-Checkbox--default--hover;
      // Don't override background-color - let the existing background rules apply
    }

    &.error {
      @include checkboxVariant("error");
    }

    &.warning {
      @include checkboxVariant("warning");
    }

    &.valid {
      @include checkboxVariant("success");
    }

    &::before {
      content: "";
      width: 0.5em;
      height: 0.5em;
      transform: scale(0);
      transition: 0.1s transform ease-out;
      box-shadow: inset 1em 1em $backgroundColor-indicator-Checkbox;
      transform-origin: center;
      clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
    }

    &:checked::before {
      transform: scale(1);
    }

    @include checkedState("Checkbox");

    &:indeterminate {
      background-color: $backgroundColor-checked-Checkbox;
      border-color: $borderColor-checked-Checkbox;

      &[readonly] {
        pointer-events: none;
      }
    }
    &:indeterminate:disabled {
      background-color: $backgroundColor-Checkbox--disabled;
      border-color: $borderColor-Checkbox--disabled;
    }
    &:indeterminate::before {
      clip-path: circle(30% at 50% 50%);
      transform: scale(1);
    }
  }

  // --------------- Switch ---------------

  .switch {
    --thumb-size: 1rem;
    --thumb-position: 0%;
    --track-size: calc(var(--thumb-size) * 3);
    --padding-size: 4px;

    &:not([readonly]) {
      cursor: pointer;
    }
    flex-shrink: 0;
    display: grid;
    align-items: center;
    grid: [track] 1fr / [track] 1fr;
    background-color: $backgroundColor-Switch;

    width: var(--track-size);
    min-height: var(--thumb-size);

    padding: var(--padding-size);
    border: 1px solid $borderColor-Switch;
    border-radius: 1rem;

    &::before {
      content: "";
      grid-area: track;
      height: var(--thumb-size);
      width: var(--thumb-size);
      background: $backgroundColor-indicator-Switch;
      border-radius: 50%;

      transform: translateX(var(--thumb-position));
      transition: 0.3s transform;
    }

    &:checked {
      background: $backgroundColor-checked-Switch;

      &::before {
        background: $backgroundColor-indicator-checked-Switch;
        --thumb-position: calc(
          var(--track-size) - var(--thumb-size) - 2 * var(--padding-size) - 2px
        );
      }
    }

    @include hoverAndDisabledState("Switch");
    @include checkedState("Switch");

    .forceHover {
      border-color: $borderColor-Switch--default--hover;
      // Don't override background-color - let the existing background rules apply
    }

    &:focus-visible {
      outline-width: $outlineWidth-Switch--focus;
      outline-color: $outlineColor-Switch--focus;
      outline-style: $outlineStyle-Switch--focus;
      outline-offset: $outlineOffset-Switch--focus;
    }

    &:disabled {
      &::before {
        background-color: $backgroundColor-Switch-indicator--disabled;
      }
    }

    &.error {
      border-color: $borderColor-Switch--error;
    }

    &.warning {
      border-color: $borderColor-Switch--warning;
    }

    &.valid {
      border-color: $borderColor-Switch--success;
    }
  }
}

// --- We export the theme variables to add them to the component renderer
:export {
  themeVars: t.json-stringify($themeVars);
}

```

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

```typescript
import { test, expect } from "../../testing/fixtures";

// =============================================================================
// BASIC FUNCTIONALITY TESTS
// =============================================================================

test("initializes with default props", async ({ initTestBed, page }) => {
  await initTestBed(`
    <Fragment>
      <AppState id="appState" />
      <Text testId="stateValue">|{JSON.stringify(appState.value)}|</Text>
    </Fragment>
  `);

  // AppState should initialize with default bucket and display the correct value
  await expect(page.getByTestId("stateValue")).toBeVisible();
  await expect(page.getByTestId("stateValue")).toHaveText("||");
});

test("initializes with initial state value", async ({ initTestBed, page }) => {
  await initTestBed(`
    <Fragment>
      <AppState id="appState" initialValue="{{ mode: true }}"/>
      <Text testId="stateValue">|{appState.value.mode}|</Text>
    </Fragment>
  `);

  // AppState should initialize with default bucket and display the correct value
  await expect(page.getByTestId("stateValue")).toBeVisible();
  await expect(page.getByTestId("stateValue")).toHaveText("|true|");
});

test("initializes with multiple initial state value", async ({ initTestBed, page }) => {
  await initTestBed(`
    <Fragment>
      <AppState id="appState" initialValue="{{ mode: true }}"/>
      <AppState id="appState2" initialValue="{{ otherMode: 123 }}"/>
      <Text testId="stateValue">|{appState.value.mode}|{appState2.value.otherMode}|</Text>
    </Fragment>
  `);

  // AppState should initialize with default bucket and display the correct value
  await expect(page.getByTestId("stateValue")).toBeVisible();
  await expect(page.getByTestId("stateValue")).toHaveText("|true|123|");
});

test("initializes with provided bucket name and no initial value", async ({
  initTestBed,
  page,
}) => {
  await initTestBed(`
    <Fragment>
      <AppState id="appState" bucket="settings" />
      <Text testId="stateValue">|{JSON.stringify(appState.value)}|</Text>
    </Fragment>
  `);

  // AppState should initialize with default bucket and display the correct value
  await expect(page.getByTestId("stateValue")).toBeVisible();
  await expect(page.getByTestId("stateValue")).toHaveText("||");
});

test("initializes with bucket name and initial state value", async ({ initTestBed, page }) => {
  await initTestBed(`
    <Fragment>
      <AppState id="appState" bucket="settings" initialValue="{{ mode: true }}"/>
      <Text testId="stateValue">|{appState.value.mode}|</Text>
    </Fragment>
  `);

  // AppState should initialize with default bucket and display the correct value
  await expect(page.getByTestId("stateValue")).toBeVisible();
  await expect(page.getByTestId("stateValue")).toHaveText("|true|");
});

test("initializes with bucket name and multiple initial state value", async ({
  initTestBed,
  page,
}) => {
  await initTestBed(`
    <Fragment>
      <AppState id="appState" bucket="settings" initialValue="{{ mode: true }}"/>
      <AppState id="appState2" bucket="settings" initialValue="{{ otherMode: 123 }}"/>
      <Text testId="stateValue">|{appState.value.mode}|{appState.value.otherMode}|</Text>
    </Fragment>
  `);

  // AppState should initialize with default bucket and display the correct value
  await expect(page.getByTestId("stateValue")).toBeVisible();
  await expect(page.getByTestId("stateValue")).toHaveText("|true|123|");
});

test("updates state using the update API", async ({ initTestBed, page }) => {
  await initTestBed(`
    <Fragment>
      <AppState id="appState" initialValue="{{ counter: 0 }}" />
      <Button testId="updateBtn" onClick="appState.update({ counter: appState.value.counter + 1 })">
        Increment
      </Button>
      <Text testId="stateValue">{JSON.stringify(appState.value)}</Text>
    </Fragment>
  `);

  // Check initial state
  await expect(page.getByTestId("stateValue")).toHaveText('{"counter":0}');

  // Update state by clicking button
  await page.getByTestId("updateBtn").click();

  // Check updated state
  await expect(page.getByTestId("stateValue")).toHaveText('{"counter":1}');
});

test("updates state using the update API (using backet name)", async ({ initTestBed, page }) => {
  await initTestBed(`
    <Fragment>
      <AppState id="appState" bucket="settings" initialValue="{{ counter: 0 }}" />
      <Button testId="updateBtn" onClick="appState.update({ counter: appState.value.counter + 1 })">
        Increment
      </Button>
      <Text testId="stateValue">{JSON.stringify(appState.value)}</Text>
    </Fragment>
  `);

  // Check initial state
  await expect(page.getByTestId("stateValue")).toHaveText('{"counter":0}');

  // Update state by clicking button
  await page.getByTestId("updateBtn").click();

  // Check updated state
  await expect(page.getByTestId("stateValue")).toHaveText('{"counter":1}');
});

// =============================================================================
// STATE SHARING TESTS
// =============================================================================

test("shares state between multiple instances with the default bucket", async ({
  initTestBed,
  page,
}) => {
  await initTestBed(`
    <Fragment>
      <AppState id="appState1" initialValue="{{ counter: 0 }}" />
      <AppState id="appState2" />
      <Button testId="updateBtn" onClick="appState1.update({ counter: appState1.value.counter + 1 })">
        Increment
      </Button>
      <Text testId="stateValue1">{JSON.stringify(appState1.value)}</Text>
      <Text testId="stateValue2">{JSON.stringify(appState2.value)}</Text>
    </Fragment>
  `);

  // Check initial state in both instances
  await expect(page.getByTestId("stateValue1")).toHaveText('{"counter":0}');
  await expect(page.getByTestId("stateValue2")).toHaveText('{"counter":0}');

  // Update state through first instance
  await page.getByTestId("updateBtn").click();

  // Both instances should reflect the change
  await expect(page.getByTestId("stateValue1")).toHaveText('{"counter":1}');
  await expect(page.getByTestId("stateValue2")).toHaveText('{"counter":1}');
});

test("shares state between multiple instances with a specific bucket", async ({
  initTestBed,
  page,
}) => {
  await initTestBed(`
    <Fragment>
      <AppState id="appState1" initialValue="{{ counter: 0 }}" bucket="bucket1" />
      <AppState id="appState2" bucket="bucket1" />
      <Button testId="updateBtn" onClick="appState1.update({ counter: appState1.value.counter + 1 })">
        Increment
      </Button>
      <Text testId="stateValue1">{JSON.stringify(appState1.value)}</Text>
      <Text testId="stateValue2">{JSON.stringify(appState2.value)}</Text>
    </Fragment>
  `);

  // Check initial state in both instances
  await expect(page.getByTestId("stateValue1")).toHaveText('{"counter":0}');
  await expect(page.getByTestId("stateValue2")).toHaveText('{"counter":0}');

  // Update state through first instance
  await page.getByTestId("updateBtn").click();

  // Both instances should reflect the change
  await expect(page.getByTestId("stateValue1")).toHaveText('{"counter":1}');
  await expect(page.getByTestId("stateValue2")).toHaveText('{"counter":1}');
});

test("maintains separate states for different buckets", async ({ initTestBed, page }) => {
  await initTestBed(`
    <Fragment>
      <AppState id="appState1" initialValue="{{ counter: 0 }}" bucket="bucket1" />
      <AppState id="appState2" initialValue="{{ counter: 0 }}" bucket="bucket2" />
      <Button testId="updateBtn" onClick="appState1.update({ counter: appState1.value.counter + 1 })">
        Increment
      </Button>
      <Text testId="stateValue1">{JSON.stringify(appState1.value)}</Text>
      <Text testId="stateValue2">{JSON.stringify(appState2.value)}</Text>
    </Fragment>
  `);

  // Check initial state in both instances
  await expect(page.getByTestId("stateValue1")).toHaveText('{"counter":0}');
  await expect(page.getByTestId("stateValue2")).toHaveText('{"counter":0}');

  // Update state through first instance
  await page.getByTestId("updateBtn").click();

  // Only the first instance should reflect the change
  await expect(page.getByTestId("stateValue1")).toHaveText('{"counter":1}');
  await expect(page.getByTestId("stateValue2")).toHaveText('{"counter":0}');
});

// =============================================================================
// EDGE CASE TESTS
// =============================================================================

test("handles undefined initialValue gracefully", async ({ initTestBed, page }) => {
  await initTestBed(`
    <Fragment>
      <AppState ref="appState" initialValue="{undefined}" />
      <Text testId="stateValue">|{JSON.stringify(appState.value)}|</Text>
    </Fragment>
  `);

  // Should not throw error with undefined initialValue
  await expect(page.getByTestId("stateValue")).toBeVisible();
  await expect(page.getByTestId("stateValue")).toHaveText("||");
});

test("handles complex nested state updates correctly", async ({ initTestBed, page }) => {
  await initTestBed(`
    <Fragment>
      <AppState
        id="appState"
        initialValue="{{ user: { name: 'John', profile: { age: 30, roles: ['admin'] } } }}"
      />
      <Button testId="updateBtn" 
        onClick="appState.update({ 
          user: { ...appState.value.user, 
          profile: { ...appState.value.user.profile, age: 31 } } 
        })">
        Update Age
      </Button>
      <Text testId="stateValue">{JSON.stringify(appState.value)}</Text>
    </Fragment>
  `);

  // Check initial state
  await expect(page.getByTestId("stateValue")).toContainText('"age":30');

  // Update nested property
  await page.getByTestId("updateBtn").click();

  // Check updated nested property
  await expect(page.getByTestId("stateValue")).toContainText('"age":31');
  // Check other properties remain unchanged
  await expect(page.getByTestId("stateValue")).toContainText('"name":"John"');
  await expect(page.getByTestId("stateValue")).toContainText('"roles":["admin"]');
});

// =============================================================================
// PERFORMANCE TESTS
// =============================================================================

test("handles multiple rapid state updates efficiently", async ({ initTestBed, page }) => {
  await initTestBed(`
    <Fragment var.clickCount="{0}">
      <AppState id="appState" initialValue="{{ counter: 0 }}" />
      <Button 
        testId="updateBtn" 
        onClick="appState.update({ counter: appState.value.counter + 1 }); clickCount = clickCount + 1;">
        Increment
      </Button>
      <Text testId="stateValue">{JSON.stringify(appState.value)}</Text>
      <Text testId="clickCount">{clickCount}</Text>
    </Fragment>
  `);

  // Perform multiple rapid clicks
  for (let i = 0; i < 5; i++) {
    await page.getByTestId("updateBtn").click();
  }

  // Verify click count
  await expect(page.getByTestId("clickCount")).toHaveText("5");

  // Verify state was updated correctly
  await expect(page.getByTestId("stateValue")).toContainText('{"counter":5}');
});

// =============================================================================
// INTEGRATION TESTS
// =============================================================================

test("integrates with other components that consume app state", async ({ initTestBed, page }) => {
  // TODO: review these Copilot-created tests
  await initTestBed(`
    <Fragment>
      <AppState id="appState" initialValue="{{ theme: 'light', fontSize: 14 }}" />
      <Fragment var.currentTheme="initial">
        <Button testId="themeBtn" onClick="currentTheme = appState.value.theme">
          Get Theme
        </Button>
        <Text testId="themeValue">{currentTheme}</Text>
      </Fragment>
    </Fragment>
  `);

  // Get the theme value by clicking button
  await page.getByTestId("themeBtn").click();

  // Check that the value was correctly retrieved from AppState
  await expect(page.getByTestId("themeValue")).toHaveText("light");
});

test("works correctly when wrapped in conditional rendering", async ({ initTestBed, page }) => {
  // TODO: review these Copilot-created tests
  await initTestBed(`
    <Fragment var.showState="{false}">
      <Fragment when="{showState}">
        <Text>AppState is visible</Text>
        <AppState id="appState" initialValue="{{ visible: true }}" />
      </Fragment>
      <Button testId="toggleBtn" onClick="showState = !showState">Toggle AppState</Button>
      <Text testId="visibilityStatus">{appState.value.visible ? 'Visible' : 'Hidden'}</Text>
    </Fragment>
  `);

  // Initially the AppState component should be rendered
  await expect(page.getByTestId("visibilityStatus")).toHaveText("Hidden");

  // Toggle the component's visibility
  await page.getByTestId("toggleBtn").click();
  await expect(page.getByTestId("visibilityStatus")).toHaveText("Visible");

  // Toggle it back: The AppState component is hidden, but the state is still remain
  // there. It should work this way.
  await page.getByTestId("toggleBtn").click();
  await expect(page.getByTestId("visibilityStatus")).toHaveText("Visible");
});

```

--------------------------------------------------------------------------------
/xmlui/src/components-core/script-runner/ScriptingSourceTree.ts:
--------------------------------------------------------------------------------

```typescript
import type { GenericToken } from "../../parsers/common/GenericToken";
import type { TokenType } from "../../parsers/scripting/TokenType";
import type { ScriptParserErrorMessage } from "../../abstractions/scripting/ScriptParserError";

// --- All binding expression tree node types
type ScriptNode = Statement | Expression;

type ScriptingToken = GenericToken<TokenType>;

// The root type of all source tree nodes
export interface ScripNodeBase {
  // Node type discriminator
  type: ScriptNode["type"];

  // The unique id of the node
  nodeId: number;

  // The start token of the node
  startToken?: ScriptingToken;

  // The end token of the node
  endToken?: ScriptingToken;
}

// Import the actual implementation constants from outside the abstractions folder
import * as NodeTypes from "../../parsers/scripting/ScriptingNodeTypes";

// Re-export the constants so they can be used both as types and values
export const {
  // Statement node type values
  T_BLOCK_STATEMENT,
  T_EMPTY_STATEMENT,
  T_EXPRESSION_STATEMENT,
  T_ARROW_EXPRESSION_STATEMENT,
  T_LET_STATEMENT,
  T_CONST_STATEMENT,
  T_VAR_STATEMENT,
  T_IF_STATEMENT,
  T_RETURN_STATEMENT,
  T_BREAK_STATEMENT,
  T_CONTINUE_STATEMENT,
  T_WHILE_STATEMENT,
  T_DO_WHILE_STATEMENT,
  T_FOR_STATEMENT,
  T_FOR_IN_STATEMENT,
  T_FOR_OF_STATEMENT,
  T_THROW_STATEMENT,
  T_TRY_STATEMENT,
  T_SWITCH_STATEMENT,
  T_FUNCTION_DECLARATION,
  
  // Expression node type values
  T_UNARY_EXPRESSION,
  T_BINARY_EXPRESSION,
  T_SEQUENCE_EXPRESSION,
  T_CONDITIONAL_EXPRESSION,
  T_FUNCTION_INVOCATION_EXPRESSION,
  T_MEMBER_ACCESS_EXPRESSION,
  T_CALCULATED_MEMBER_ACCESS_EXPRESSION,
  T_IDENTIFIER,
  T_TEMPLATE_LITERAL_EXPRESSION,
  T_LITERAL,
  T_ARRAY_LITERAL,
  T_OBJECT_LITERAL,
  T_SPREAD_EXPRESSION,
  T_ASSIGNMENT_EXPRESSION,
  T_NO_ARG_EXPRESSION,
  T_ARROW_EXPRESSION,
  T_PREFIX_OP_EXPRESSION,
  T_POSTFIX_OP_EXPRESSION,
  T_REACTIVE_VAR_DECLARATION,
  
  // Other node type values
  T_VAR_DECLARATION,
  T_DESTRUCTURE,
  T_ARRAY_DESTRUCTURE,
  T_OBJECT_DESTRUCTURE,
  T_SWITCH_CASE
} = NodeTypes;

// --- Statement node types
type BLOCK_STATEMENT = typeof T_BLOCK_STATEMENT;
type EMPTY_STATEMENT = typeof T_EMPTY_STATEMENT;
type EXPRESSION_STATEMENT = typeof T_EXPRESSION_STATEMENT;
type ARROW_EXPRESSION_STATEMENT = typeof T_ARROW_EXPRESSION_STATEMENT;
type LET_STATEMENT = typeof T_LET_STATEMENT;
type CONST_STATEMENT = typeof T_CONST_STATEMENT;
type VAR_STATEMENT = typeof T_VAR_STATEMENT;
type IF_STATEMENT = typeof T_IF_STATEMENT;
type RETURN_STATEMENT = typeof T_RETURN_STATEMENT;
type BREAK_STATEMENT = typeof T_BREAK_STATEMENT;
type CONTINUE_STATEMENT = typeof T_CONTINUE_STATEMENT;
type WHILE_STATEMENT = typeof T_WHILE_STATEMENT;
type DO_WHILE_STATEMENT = typeof T_DO_WHILE_STATEMENT;
type FOR_STATEMENT = typeof T_FOR_STATEMENT;
type FOR_IN_STATEMENT = typeof T_FOR_IN_STATEMENT;
type FOR_OF_STATEMENT = typeof T_FOR_OF_STATEMENT;
type THROW_STATEMENT = typeof T_THROW_STATEMENT;
type TRY_STATEMENT = typeof T_TRY_STATEMENT;
type SWITCH_STATEMENT = typeof T_SWITCH_STATEMENT;
type FUNCTION_DECLARATION = typeof T_FUNCTION_DECLARATION;

// --- Expression node types
type UNARY_EXPRESSION = typeof T_UNARY_EXPRESSION;
type BINARY_EXPRESSION = typeof T_BINARY_EXPRESSION;
type SEQUENCE_EXPRESSION = typeof T_SEQUENCE_EXPRESSION;
type CONDITIONAL_EXPRESSION = typeof T_CONDITIONAL_EXPRESSION;
type FUNCTION_INVOCATION_EXPRESSION = typeof T_FUNCTION_INVOCATION_EXPRESSION;
type MEMBER_ACCESS_EXPRESSION = typeof T_MEMBER_ACCESS_EXPRESSION;
type CALCULATED_MEMBER_ACCESS_EXPRESSION = typeof T_CALCULATED_MEMBER_ACCESS_EXPRESSION;
type IDENTIFIER = typeof T_IDENTIFIER;
type TEMPLATE_LITERAL_EXPRESSION = typeof T_TEMPLATE_LITERAL_EXPRESSION;
type LITERAL = typeof T_LITERAL;
type ARRAY_LITERAL = typeof T_ARRAY_LITERAL;
type OBJECT_LITERAL = typeof T_OBJECT_LITERAL;
type SPREAD_EXPRESSION = typeof T_SPREAD_EXPRESSION;
type ASSIGNMENT_EXPRESSION = typeof T_ASSIGNMENT_EXPRESSION;
type NO_ARG_EXPRESSION = typeof T_NO_ARG_EXPRESSION;
type ARROW_EXPRESSION = typeof T_ARROW_EXPRESSION;
type PREFIX_OP_EXPRESSION = typeof T_PREFIX_OP_EXPRESSION;
type POSTFIX_OP_EXPRESSION = typeof T_POSTFIX_OP_EXPRESSION;
type REACTIVE_VAR_DECLARATION = typeof T_REACTIVE_VAR_DECLARATION;

// --- Other node types
type VAR_DECLARATION = typeof T_VAR_DECLARATION;
type DESTRUCTURE = typeof T_DESTRUCTURE;
type ARRAY_DESTRUCTURE = typeof T_ARRAY_DESTRUCTURE;
type OBJECT_DESTRUCTURE = typeof T_OBJECT_DESTRUCTURE;
type SWITCH_CASE = typeof T_SWITCH_CASE;

// =====================================================================================================================
// Statements

export type Statement =
  | BlockStatement
  | EmptyStatement
  | ExpressionStatement
  | ArrowExpressionStatement
  | LetStatement
  | ConstStatement
  | VarStatement
  | IfStatement
  | ReturnStatement
  | BreakStatement
  | ContinueStatement
  | WhileStatement
  | DoWhileStatement
  | ForStatement
  | ForInStatement
  | ForOfStatement
  | ThrowStatement
  | TryStatement
  | SwitchStatement
  | FunctionDeclaration;

export type LoopStatement = WhileStatement | DoWhileStatement;

export interface EmptyStatement extends ScripNodeBase {
  type: EMPTY_STATEMENT;
}

export interface ExpressionStatement extends ScripNodeBase {
  type: EXPRESSION_STATEMENT;
  expr: Expression;
}

export interface ArrowExpressionStatement extends ScripNodeBase {
  type: ARROW_EXPRESSION_STATEMENT;
  expr: ArrowExpression;
}

export interface VarDeclaration extends ExpressionBase {
  type: VAR_DECLARATION;
  id?: string;
  aDestr?: ArrayDestructure[];
  oDestr?: ObjectDestructure[];
  expr?: Expression;
}

export interface DestructureBase extends ExpressionBase {
  id?: string;
  aDestr?: ArrayDestructure[];
  oDestr?: ObjectDestructure[];
}

export interface Destructure extends DestructureBase {
  type: DESTRUCTURE;
  aDestr?: ArrayDestructure[];
  oDestr?: ObjectDestructure[];
}

export interface ArrayDestructure extends DestructureBase {
  type: ARRAY_DESTRUCTURE;
}

export interface ObjectDestructure extends DestructureBase {
  type: OBJECT_DESTRUCTURE;
  id: string;
  alias?: string;
}

export interface LetStatement extends ScripNodeBase {
  type: LET_STATEMENT;
  decls: VarDeclaration[];
}

export interface ConstStatement extends ScripNodeBase {
  type: CONST_STATEMENT;
  decls: VarDeclaration[];
}

export interface VarStatement extends ScripNodeBase {
  type: VAR_STATEMENT;
  decls: ReactiveVarDeclaration[];
}

export interface ReactiveVarDeclaration extends ExpressionBase {
  type: REACTIVE_VAR_DECLARATION;
  id: Identifier;
  expr: Expression;
}

export interface BlockStatement extends ScripNodeBase {
  type: BLOCK_STATEMENT;
  stmts: Statement[];
}

export interface IfStatement extends ScripNodeBase {
  type: IF_STATEMENT;
  cond: Expression;
  thenB: Statement;
  elseB?: Statement;
}

export interface ReturnStatement extends ScripNodeBase {
  type: RETURN_STATEMENT;
  expr?: Expression;
}

export interface WhileStatement extends ScripNodeBase {
  type: WHILE_STATEMENT;
  cond: Expression;
  body: Statement;
}

export interface DoWhileStatement extends ScripNodeBase {
  type: DO_WHILE_STATEMENT;
  cond: Expression;
  body: Statement;
}

export interface BreakStatement extends ScripNodeBase {
  type: BREAK_STATEMENT;
}

export interface ContinueStatement extends ScripNodeBase {
  type: CONTINUE_STATEMENT;
}

export interface ThrowStatement extends ScripNodeBase {
  type: THROW_STATEMENT;
  expr: Expression;
}

export interface TryStatement extends ScripNodeBase {
  type: TRY_STATEMENT;
  tryB: BlockStatement;
  catchB?: BlockStatement;
  catchV?: Identifier;
  finallyB?: BlockStatement;
}

export interface ForStatement extends ScripNodeBase {
  type: FOR_STATEMENT;
  init?: ExpressionStatement | LetStatement;
  cond?: Expression;
  upd?: Expression;
  body: Statement;
}

export type ForVarBinding = "let" | "const" | "none";
export interface ForInStatement extends ScripNodeBase {
  type: FOR_IN_STATEMENT;
  varB: ForVarBinding;
  id: Identifier;
  expr: Expression;
  body: Statement;
}

export interface ForOfStatement extends ScripNodeBase {
  type: FOR_OF_STATEMENT;
  varB: ForVarBinding;
  id: Identifier;
  expr: Expression;
  body: Statement;
}

export interface SwitchStatement extends ScripNodeBase {
  type: SWITCH_STATEMENT;
  expr: Expression;
  cases: SwitchCase[];
}

export interface SwitchCase extends ExpressionBase {
  type: SWITCH_CASE;
  caseE?: Expression;
  stmts?: Statement[];
}

export interface FunctionDeclaration extends ScripNodeBase {
  type: FUNCTION_DECLARATION;
  id: Identifier;
  args: Expression[];
  stmt: BlockStatement;
}

// =====================================================================================================================
// Expressions

// All syntax nodes that represent an expression
export type Expression =
  | UnaryExpression
  | BinaryExpression
  | SequenceExpression
  | ConditionalExpression
  | FunctionInvocationExpression
  | MemberAccessExpression
  | CalculatedMemberAccessExpression
  | Identifier
  | TemplateLiteralExpression
  | Literal
  | ArrayLiteral
  | ObjectLiteral
  | SpreadExpression
  | AssignmentExpression
  | NoArgExpression
  | ArrowExpression
  | PrefixOpExpression
  | PostfixOpExpression
  | ReactiveVarDeclaration
  | VarDeclaration
  | Destructure
  | ObjectDestructure
  | ArrayDestructure
  | SwitchCase;

// Common base node for all expression syntax nodes
export interface ExpressionBase extends ScripNodeBase {
  // Is this expression parenthesized?
  parenthesized?: number;
}

export type UnaryOpSymbols = "+" | "-" | "~" | "!" | "typeof" | "delete";

export type BinaryOpSymbols =
  | "**"
  | "*"
  | "/"
  | "%"
  | "+"
  | "-"
  | "<<"
  | ">>"
  | ">>>"
  | "<"
  | "<="
  | ">"
  | ">="
  | "=="
  | "==="
  | "!="
  | "!=="
  | "&"
  | "|"
  | "^"
  | "&&"
  | "||"
  | "??"
  | "in";

export type AssignmentSymbols =
  | "="
  | "+="
  | "-="
  | "**="
  | "*="
  | "/="
  | "%="
  | "<<="
  | ">>="
  | ">>>="
  | "&="
  | "^="
  | "|="
  | "&&="
  | "||="
  | "??=";

export type PrefixOpSymbol = "++" | "--";

export interface UnaryExpression extends ExpressionBase {
  type: UNARY_EXPRESSION;
  op: UnaryOpSymbols;
  expr: Expression;
}

export interface BinaryExpression extends ExpressionBase {
  type: BINARY_EXPRESSION;
  op: BinaryOpSymbols;
  left: Expression;
  right: Expression;
}

export interface SequenceExpression extends ExpressionBase {
  type: SEQUENCE_EXPRESSION;
  exprs: Expression[];
  loose?: boolean;
}

export interface ConditionalExpression extends ExpressionBase {
  type: CONDITIONAL_EXPRESSION;
  cond: Expression;
  thenE: Expression;
  elseE: Expression;
}

export interface FunctionInvocationExpression extends ExpressionBase {
  type: FUNCTION_INVOCATION_EXPRESSION;
  obj: Expression;
  arguments: Expression[];
}

export interface MemberAccessExpression extends ExpressionBase {
  type: MEMBER_ACCESS_EXPRESSION;
  obj: Expression;
  member: string;
  opt?: boolean;
}

export interface CalculatedMemberAccessExpression extends ExpressionBase {
  type: CALCULATED_MEMBER_ACCESS_EXPRESSION;
  obj: Expression;
  member: Expression;
}

export interface Identifier extends ExpressionBase {
  type: IDENTIFIER;
  name: string;
  isGlobal?: boolean;
}

export interface Literal extends ExpressionBase {
  type: LITERAL;
  value: any;
}

export interface TemplateLiteralExpression extends ExpressionBase {
  type: TEMPLATE_LITERAL_EXPRESSION;
  segments: (Literal | Expression)[];
}

export interface ArrayLiteral extends ExpressionBase {
  type: ARRAY_LITERAL;
  items: Expression[];
  loose?: boolean;
}

export interface ObjectLiteral extends ExpressionBase {
  type: OBJECT_LITERAL;
  props: (SpreadExpression | [Expression, Expression])[];
}

export interface SpreadExpression extends ExpressionBase {
  type: SPREAD_EXPRESSION;
  expr: Expression;
}

export interface AssignmentExpression extends ExpressionBase {
  type: ASSIGNMENT_EXPRESSION;
  leftValue: Expression;
  op: AssignmentSymbols;
  expr: Expression;
}

export interface NoArgExpression extends ExpressionBase {
  type: NO_ARG_EXPRESSION;
}

export interface ArrowExpression extends ExpressionBase {
  type: ARROW_EXPRESSION;
  name?: string;
  args: Expression[];
  statement: Statement;
}

export interface PrefixOpExpression extends ExpressionBase {
  type: PREFIX_OP_EXPRESSION;
  op: PrefixOpSymbol;
  expr: Expression;
}

export interface PostfixOpExpression extends ExpressionBase {
  type: POSTFIX_OP_EXPRESSION;
  op: PrefixOpSymbol;
  expr: Expression;
}

/**
 * Represents a parsed and resolved module
 */
export type ScriptModule = {
  type: "ScriptModule";
  name: string;
  parent?: ScriptModule | null;
  functions: Record<string, FunctionDeclaration>;
  statements: Statement[];
  sources: Map<Statement, string>;
};

/**
 * Represents a module error
 */
export type ModuleErrors = Record<string, ScriptParserErrorMessage[]>;

export type CollectedDeclarations = {
  vars: Record<string, CodeDeclaration>;
  functions: Record<string, CodeDeclaration>;
  moduleErrors?: ModuleErrors;
};

export type CodeDeclaration = {
  source?: string;
  tree: Expression;
  [x: string]: unknown;
};

```
Page 46/145FirstPrevNextLast