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

# Directory Structure

```
├── .changeset
│   ├── config.json
│   └── cool-queens-look.md
├── .eslintrc.cjs
├── .github
│   ├── build-checklist.png
│   ├── ISSUE_TEMPLATE
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   └── workflows
│       ├── deploy-blog.yml
│       ├── deploy-docs-optimized.yml
│       ├── deploy-docs.yml
│       ├── prepare-versions.yml
│       ├── release-packages.yml
│       ├── run-all-tests.yml
│       └── run-smoke-tests.yml
├── .gitignore
├── .prettierrc.js
├── .vscode
│   ├── launch.json
│   └── settings.json
├── blog
│   ├── .gitignore
│   ├── .gitkeep
│   ├── CHANGELOG.md
│   ├── extensions.ts
│   ├── index.html
│   ├── index.ts
│   ├── package.json
│   ├── public
│   │   ├── blog
│   │   │   ├── images
│   │   │   │   ├── blog-page-component.png
│   │   │   │   ├── blog-scrabble.png
│   │   │   │   ├── integrated-blog-search.png
│   │   │   │   └── lorem-ipsum.png
│   │   │   ├── lorem-ipsum.md
│   │   │   ├── newest-post.md
│   │   │   ├── older-post.md
│   │   │   └── welcome-to-the-xmlui-blog.md
│   │   ├── mockServiceWorker.js
│   │   ├── netlify.toml
│   │   ├── resources
│   │   │   ├── favicon.ico
│   │   │   ├── files
│   │   │   │   └── for-download
│   │   │   │       └── xmlui
│   │   │   │           └── xmlui-standalone.umd.js
│   │   │   ├── github.svg
│   │   │   ├── 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
│   │   │   ├── Debug.xmlui
│   │   │   └── PageNotFound.xmlui
│   │   ├── config.ts
│   │   ├── Main.xmlui
│   │   ├── Main.xmlui.xs
│   │   └── themes
│   │       ├── docs-theme.ts
│   │       ├── earthtone.ts
│   │       ├── xmlui-gray-on-default.ts
│   │       ├── xmlui-green-on-default.ts
│   │       └── xmlui-orange-on-default.ts
│   └── tsconfig.json
├── CONTRIBUTING.md
├── docs
│   ├── .gitignore
│   ├── CHANGELOG.md
│   ├── ComponentRefLinks.txt
│   ├── content
│   │   ├── _meta.json
│   │   ├── components
│   │   │   ├── _meta.json
│   │   │   ├── _overview.md
│   │   │   ├── APICall.md
│   │   │   ├── App.md
│   │   │   ├── AppHeader.md
│   │   │   ├── AppState.md
│   │   │   ├── AutoComplete.md
│   │   │   ├── Avatar.md
│   │   │   ├── Backdrop.md
│   │   │   ├── Badge.md
│   │   │   ├── BarChart.md
│   │   │   ├── Bookmark.md
│   │   │   ├── Breakout.md
│   │   │   ├── Button.md
│   │   │   ├── Card.md
│   │   │   ├── Carousel.md
│   │   │   ├── ChangeListener.md
│   │   │   ├── Checkbox.md
│   │   │   ├── CHStack.md
│   │   │   ├── ColorPicker.md
│   │   │   ├── Column.md
│   │   │   ├── ContentSeparator.md
│   │   │   ├── CVStack.md
│   │   │   ├── DataSource.md
│   │   │   ├── DateInput.md
│   │   │   ├── DatePicker.md
│   │   │   ├── DonutChart.md
│   │   │   ├── DropdownMenu.md
│   │   │   ├── EmojiSelector.md
│   │   │   ├── ExpandableItem.md
│   │   │   ├── FileInput.md
│   │   │   ├── FileUploadDropZone.md
│   │   │   ├── FlowLayout.md
│   │   │   ├── Footer.md
│   │   │   ├── Form.md
│   │   │   ├── FormItem.md
│   │   │   ├── FormSection.md
│   │   │   ├── Fragment.md
│   │   │   ├── H1.md
│   │   │   ├── H2.md
│   │   │   ├── H3.md
│   │   │   ├── H4.md
│   │   │   ├── H5.md
│   │   │   ├── H6.md
│   │   │   ├── Heading.md
│   │   │   ├── HSplitter.md
│   │   │   ├── HStack.md
│   │   │   ├── Icon.md
│   │   │   ├── IFrame.md
│   │   │   ├── Image.md
│   │   │   ├── Items.md
│   │   │   ├── LabelList.md
│   │   │   ├── Legend.md
│   │   │   ├── LineChart.md
│   │   │   ├── Link.md
│   │   │   ├── List.md
│   │   │   ├── Logo.md
│   │   │   ├── Markdown.md
│   │   │   ├── MenuItem.md
│   │   │   ├── MenuSeparator.md
│   │   │   ├── ModalDialog.md
│   │   │   ├── NavGroup.md
│   │   │   ├── NavLink.md
│   │   │   ├── NavPanel.md
│   │   │   ├── NoResult.md
│   │   │   ├── NumberBox.md
│   │   │   ├── Option.md
│   │   │   ├── Page.md
│   │   │   ├── PageMetaTitle.md
│   │   │   ├── Pages.md
│   │   │   ├── Pagination.md
│   │   │   ├── PasswordInput.md
│   │   │   ├── PieChart.md
│   │   │   ├── ProgressBar.md
│   │   │   ├── Queue.md
│   │   │   ├── RadioGroup.md
│   │   │   ├── RealTimeAdapter.md
│   │   │   ├── Redirect.md
│   │   │   ├── Select.md
│   │   │   ├── Slider.md
│   │   │   ├── Slot.md
│   │   │   ├── SpaceFiller.md
│   │   │   ├── Spinner.md
│   │   │   ├── Splitter.md
│   │   │   ├── Stack.md
│   │   │   ├── StickyBox.md
│   │   │   ├── SubMenuItem.md
│   │   │   ├── Switch.md
│   │   │   ├── TabItem.md
│   │   │   ├── Table.md
│   │   │   ├── TableOfContents.md
│   │   │   ├── Tabs.md
│   │   │   ├── Text.md
│   │   │   ├── TextArea.md
│   │   │   ├── TextBox.md
│   │   │   ├── Theme.md
│   │   │   ├── TimeInput.md
│   │   │   ├── Timer.md
│   │   │   ├── ToneChangerButton.md
│   │   │   ├── ToneSwitch.md
│   │   │   ├── Tooltip.md
│   │   │   ├── Tree.md
│   │   │   ├── VSplitter.md
│   │   │   ├── VStack.md
│   │   │   ├── xmlui-animations
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   ├── Animation.md
│   │   │   │   ├── FadeAnimation.md
│   │   │   │   ├── FadeInAnimation.md
│   │   │   │   ├── FadeOutAnimation.md
│   │   │   │   ├── ScaleAnimation.md
│   │   │   │   └── SlideInAnimation.md
│   │   │   ├── xmlui-pdf
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   └── Pdf.md
│   │   │   ├── xmlui-spreadsheet
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   └── Spreadsheet.md
│   │   │   └── xmlui-website-blocks
│   │   │       ├── _meta.json
│   │   │       ├── _overview.md
│   │   │       ├── Carousel.md
│   │   │       ├── HelloMd.md
│   │   │       ├── HeroSection.md
│   │   │       └── ScrollToTop.md
│   │   └── extensions
│   │       ├── _meta.json
│   │       ├── xmlui-animations
│   │       │   ├── _meta.json
│   │       │   ├── _overview.md
│   │       │   ├── Animation.md
│   │       │   ├── FadeAnimation.md
│   │       │   ├── FadeInAnimation.md
│   │       │   ├── FadeOutAnimation.md
│   │       │   ├── ScaleAnimation.md
│   │       │   └── SlideInAnimation.md
│   │       └── xmlui-website-blocks
│   │           ├── _meta.json
│   │           ├── _overview.md
│   │           ├── Carousel.md
│   │           ├── 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
│   │   │   │   ├── 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
│   │   │   │   ├── 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
│   ├── 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
│   │   └── tsconfig.json
│   ├── 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
│   │   ├── tsconfig.json
│   │   └── 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
│   │   └── tsconfig.json
│   ├── 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
│   │   └── tsconfig.json
│   ├── 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
│   │   └── tsconfig.json
│   ├── xmlui-playground
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   ├── src
│   │   │   ├── hooks
│   │   │   │   ├── usePlayground.ts
│   │   │   │   └── useToast.ts
│   │   │   ├── index.tsx
│   │   │   ├── playground
│   │   │   │   ├── Box.module.scss
│   │   │   │   ├── Box.tsx
│   │   │   │   ├── CodeSelector.tsx
│   │   │   │   ├── ConfirmationDialog.module.scss
│   │   │   │   ├── ConfirmationDialog.tsx
│   │   │   │   ├── Editor.tsx
│   │   │   │   ├── Header.module.scss
│   │   │   │   ├── Header.tsx
│   │   │   │   ├── Playground.tsx
│   │   │   │   ├── PlaygroundContent.module.scss
│   │   │   │   ├── PlaygroundContent.tsx
│   │   │   │   ├── PlaygroundNative.module.scss
│   │   │   │   ├── PlaygroundNative.tsx
│   │   │   │   ├── Preview.module.scss
│   │   │   │   ├── Preview.tsx
│   │   │   │   ├── Select.module.scss
│   │   │   │   ├── StandalonePlayground.tsx
│   │   │   │   ├── StandalonePlaygroundNative.module.scss
│   │   │   │   ├── StandalonePlaygroundNative.tsx
│   │   │   │   ├── ThemeSwitcher.module.scss
│   │   │   │   ├── ThemeSwitcher.tsx
│   │   │   │   ├── ToneSwitcher.tsx
│   │   │   │   ├── Tooltip.module.scss
│   │   │   │   ├── Tooltip.tsx
│   │   │   │   └── utils.ts
│   │   │   ├── providers
│   │   │   │   ├── Toast.module.scss
│   │   │   │   └── ToastProvider.tsx
│   │   │   ├── state
│   │   │   │   └── store.ts
│   │   │   ├── themes
│   │   │   │   └── theme.ts
│   │   │   └── utils
│   │   │       └── helpers.ts
│   │   └── tsconfig.json
│   ├── 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
│   │   └── tsconfig.json
│   ├── xmlui-spreadsheet
│   │   ├── .gitignore
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   ├── src
│   │   │   ├── index.tsx
│   │   │   ├── Spreadsheet.tsx
│   │   │   └── SpreadsheetNative.tsx
│   │   └── tsconfig.json
│   └── 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.tsx
│       │   │   └── HeroSectionNative.tsx
│       │   ├── index.tsx
│       │   ├── ScrollToTop
│       │   │   ├── ScrollToTop.module.scss
│       │   │   ├── ScrollToTop.tsx
│       │   │   └── ScrollToTopNative.tsx
│       │   └── vite-env.d.ts
│       └── tsconfig.json
├── 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.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
    │   ├── containers.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
    │   ├── state-management.md
    │   └── xmlui-repo.md
    ├── package.json
    ├── playwright.config.ts
    ├── scripts
    │   ├── coverage-only.js
    │   ├── e2e-test-summary.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
    │   ├── get-langserver-metadata.mjs
    │   ├── 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.spec.ts
    │   │   │   │   ├── LabelList.tsx
    │   │   │   │   ├── LabelListNative.module.scss
    │   │   │   │   └── LabelListNative.tsx
    │   │   │   ├── Legend
    │   │   │   │   ├── Legend.spec.ts
    │   │   │   │   ├── Legend.tsx
    │   │   │   │   └── LegendNative.tsx
    │   │   │   ├── LineChart
    │   │   │   │   ├── LineChart.md
    │   │   │   │   ├── LineChart.module.scss
    │   │   │   │   ├── LineChart.spec.ts
    │   │   │   │   ├── LineChart.tsx
    │   │   │   │   └── LineChartNative.tsx
    │   │   │   ├── PieChart
    │   │   │   │   ├── PieChart.md
    │   │   │   │   ├── PieChart.spec.ts
    │   │   │   │   ├── PieChart.tsx
    │   │   │   │   ├── PieChartNative.module.scss
    │   │   │   │   └── PieChartNative.tsx
    │   │   │   ├── RadarChart
    │   │   │   │   ├── RadarChart.md
    │   │   │   │   ├── RadarChart.spec.ts
    │   │   │   │   ├── RadarChart.tsx
    │   │   │   │   └── RadarChartNative.tsx
    │   │   │   ├── Tooltip
    │   │   │   │   ├── TooltipContent.module.scss
    │   │   │   │   ├── TooltipContent.spec.ts
    │   │   │   │   └── TooltipContent.tsx
    │   │   │   └── utils
    │   │   │       ├── abstractions.ts
    │   │   │       └── ChartProvider.tsx
    │   │   ├── Checkbox
    │   │   │   ├── Checkbox.md
    │   │   │   ├── Checkbox.spec.ts
    │   │   │   └── Checkbox.tsx
    │   │   ├── CodeBlock
    │   │   │   ├── CodeBlock.module.scss
    │   │   │   ├── CodeBlock.spec.ts
    │   │   │   ├── CodeBlock.tsx
    │   │   │   ├── CodeBlockNative.tsx
    │   │   │   └── highlight-code.ts
    │   │   ├── collectedComponentMetadata.ts
    │   │   ├── ColorPicker
    │   │   │   ├── ColorPicker.md
    │   │   │   ├── ColorPicker.module.scss
    │   │   │   ├── ColorPicker.spec.ts
    │   │   │   ├── ColorPicker.tsx
    │   │   │   └── ColorPickerNative.tsx
    │   │   ├── Column
    │   │   │   ├── Column.md
    │   │   │   ├── Column.tsx
    │   │   │   ├── ColumnNative.tsx
    │   │   │   ├── doc-resources
    │   │   │   │   └── list-component-data.js
    │   │   │   └── TableContext.tsx
    │   │   ├── component-utils.ts
    │   │   ├── ComponentProvider.tsx
    │   │   ├── ComponentRegistryContext.tsx
    │   │   ├── container-helpers.tsx
    │   │   ├── ContentSeparator
    │   │   │   ├── ContentSeparator.md
    │   │   │   ├── ContentSeparator.module.scss
    │   │   │   ├── ContentSeparator.spec.ts
    │   │   │   ├── ContentSeparator.tsx
    │   │   │   └── ContentSeparatorNative.tsx
    │   │   ├── DataSource
    │   │   │   ├── DataSource.md
    │   │   │   └── DataSource.tsx
    │   │   ├── DateInput
    │   │   │   ├── DateInput.md
    │   │   │   ├── DateInput.module.scss
    │   │   │   ├── DateInput.spec.ts
    │   │   │   ├── DateInput.tsx
    │   │   │   └── DateInputNative.tsx
    │   │   ├── DatePicker
    │   │   │   ├── DatePicker.md
    │   │   │   ├── DatePicker.module.scss
    │   │   │   ├── DatePicker.spec.ts
    │   │   │   ├── DatePicker.tsx
    │   │   │   └── DatePickerNative.tsx
    │   │   ├── DropdownMenu
    │   │   │   ├── DropdownMenu.md
    │   │   │   ├── DropdownMenu.module.scss
    │   │   │   ├── DropdownMenu.spec.ts
    │   │   │   ├── DropdownMenu.tsx
    │   │   │   ├── DropdownMenuNative.tsx
    │   │   │   ├── MenuItem.md
    │   │   │   └── SubMenuItem.md
    │   │   ├── EmojiSelector
    │   │   │   ├── EmojiSelector.md
    │   │   │   ├── EmojiSelector.spec.ts
    │   │   │   ├── EmojiSelector.tsx
    │   │   │   └── EmojiSelectorNative.tsx
    │   │   ├── ExpandableItem
    │   │   │   ├── ExpandableItem.module.scss
    │   │   │   ├── ExpandableItem.spec.ts
    │   │   │   ├── ExpandableItem.tsx
    │   │   │   └── ExpandableItemNative.tsx
    │   │   ├── FileInput
    │   │   │   ├── FileInput.md
    │   │   │   ├── FileInput.module.scss
    │   │   │   ├── FileInput.spec.ts
    │   │   │   ├── FileInput.tsx
    │   │   │   └── FileInputNative.tsx
    │   │   ├── FileUploadDropZone
    │   │   │   ├── FileUploadDropZone.md
    │   │   │   ├── FileUploadDropZone.module.scss
    │   │   │   ├── FileUploadDropZone.spec.ts
    │   │   │   ├── FileUploadDropZone.tsx
    │   │   │   └── FileUploadDropZoneNative.tsx
    │   │   ├── FlowLayout
    │   │   │   ├── FlowLayout.md
    │   │   │   ├── FlowLayout.module.scss
    │   │   │   ├── FlowLayout.spec.ts
    │   │   │   ├── FlowLayout.spec.ts-snapshots
    │   │   │   │   └── Edge-cases-boxShadow-is-not-clipped-1-non-smoke-darwin.png
    │   │   │   ├── FlowLayout.tsx
    │   │   │   └── FlowLayoutNative.tsx
    │   │   ├── Footer
    │   │   │   ├── Footer.md
    │   │   │   ├── Footer.module.scss
    │   │   │   ├── Footer.spec.ts
    │   │   │   ├── Footer.tsx
    │   │   │   └── FooterNative.tsx
    │   │   ├── Form
    │   │   │   ├── Form.md
    │   │   │   ├── Form.module.scss
    │   │   │   ├── Form.spec.ts
    │   │   │   ├── Form.tsx
    │   │   │   ├── formActions.ts
    │   │   │   ├── FormContext.ts
    │   │   │   └── FormNative.tsx
    │   │   ├── FormItem
    │   │   │   ├── FormItem.md
    │   │   │   ├── FormItem.module.scss
    │   │   │   ├── FormItem.spec.ts
    │   │   │   ├── FormItem.tsx
    │   │   │   ├── FormItemNative.tsx
    │   │   │   ├── HelperText.module.scss
    │   │   │   ├── HelperText.tsx
    │   │   │   ├── ItemWithLabel.tsx
    │   │   │   └── Validations.ts
    │   │   ├── FormSection
    │   │   │   ├── FormSection.md
    │   │   │   ├── FormSection.ts
    │   │   │   └── FormSection.xmlui
    │   │   ├── Fragment
    │   │   │   ├── Fragment.spec.ts
    │   │   │   └── Fragment.tsx
    │   │   ├── Heading
    │   │   │   ├── abstractions.ts
    │   │   │   ├── H1.md
    │   │   │   ├── H1.spec.ts
    │   │   │   ├── H2.md
    │   │   │   ├── H2.spec.ts
    │   │   │   ├── H3.md
    │   │   │   ├── H3.spec.ts
    │   │   │   ├── H4.md
    │   │   │   ├── H4.spec.ts
    │   │   │   ├── H5.md
    │   │   │   ├── H5.spec.ts
    │   │   │   ├── H6.md
    │   │   │   ├── H6.spec.ts
    │   │   │   ├── Heading.md
    │   │   │   ├── Heading.module.scss
    │   │   │   ├── Heading.spec.ts
    │   │   │   ├── Heading.tsx
    │   │   │   └── HeadingNative.tsx
    │   │   ├── HoverCard
    │   │   │   ├── HoverCard.tsx
    │   │   │   └── HovercardNative.tsx
    │   │   ├── HtmlTags
    │   │   │   ├── HtmlTags.module.scss
    │   │   │   ├── HtmlTags.spec.ts
    │   │   │   └── HtmlTags.tsx
    │   │   ├── Icon
    │   │   │   ├── AdmonitionDanger.tsx
    │   │   │   ├── AdmonitionInfo.tsx
    │   │   │   ├── AdmonitionNote.tsx
    │   │   │   ├── AdmonitionTip.tsx
    │   │   │   ├── AdmonitionWarning.tsx
    │   │   │   ├── ApiIcon.tsx
    │   │   │   ├── ArrowDropDown.module.scss
    │   │   │   ├── ArrowDropDown.tsx
    │   │   │   ├── ArrowDropUp.module.scss
    │   │   │   ├── ArrowDropUp.tsx
    │   │   │   ├── ArrowLeft.module.scss
    │   │   │   ├── ArrowLeft.tsx
    │   │   │   ├── ArrowRight.module.scss
    │   │   │   ├── ArrowRight.tsx
    │   │   │   ├── Attach.tsx
    │   │   │   ├── Binding.module.scss
    │   │   │   ├── Binding.tsx
    │   │   │   ├── BoardIcon.tsx
    │   │   │   ├── BoxIcon.tsx
    │   │   │   ├── CheckIcon.tsx
    │   │   │   ├── ChevronDownIcon.tsx
    │   │   │   ├── ChevronLeft.tsx
    │   │   │   ├── ChevronRight.tsx
    │   │   │   ├── ChevronUpIcon.tsx
    │   │   │   ├── CodeFileIcon.tsx
    │   │   │   ├── CodeSandbox.tsx
    │   │   │   ├── CompactListIcon.tsx
    │   │   │   ├── ContentCopyIcon.tsx
    │   │   │   ├── DarkToLightIcon.tsx
    │   │   │   ├── DatabaseIcon.module.scss
    │   │   │   ├── DatabaseIcon.tsx
    │   │   │   ├── DocFileIcon.tsx
    │   │   │   ├── DocIcon.tsx
    │   │   │   ├── DotMenuHorizontalIcon.tsx
    │   │   │   ├── DotMenuIcon.tsx
    │   │   │   ├── EmailIcon.tsx
    │   │   │   ├── EmptyFolderIcon.tsx
    │   │   │   ├── ErrorIcon.tsx
    │   │   │   ├── ExpressionIcon.tsx
    │   │   │   ├── FillPlusCricleIcon.tsx
    │   │   │   ├── FilterIcon.tsx
    │   │   │   ├── FolderIcon.tsx
    │   │   │   ├── GlobeIcon.tsx
    │   │   │   ├── HomeIcon.tsx
    │   │   │   ├── HyperLinkIcon.tsx
    │   │   │   ├── Icon.md
    │   │   │   ├── Icon.module.scss
    │   │   │   ├── Icon.spec.ts
    │   │   │   ├── Icon.tsx
    │   │   │   ├── IconNative.tsx
    │   │   │   ├── ImageFileIcon.tsx
    │   │   │   ├── Inspect.tsx
    │   │   │   ├── LightToDark.tsx
    │   │   │   ├── LinkIcon.tsx
    │   │   │   ├── ListIcon.tsx
    │   │   │   ├── LooseListIcon.tsx
    │   │   │   ├── MoonIcon.tsx
    │   │   │   ├── MoreOptionsIcon.tsx
    │   │   │   ├── NoSortIcon.tsx
    │   │   │   ├── PDFIcon.tsx
    │   │   │   ├── PenIcon.tsx
    │   │   │   ├── PhoneIcon.tsx
    │   │   │   ├── PhotoIcon.tsx
    │   │   │   ├── PlusIcon.tsx
    │   │   │   ├── SearchIcon.tsx
    │   │   │   ├── ShareIcon.tsx
    │   │   │   ├── SortAscendingIcon.tsx
    │   │   │   ├── SortDescendingIcon.tsx
    │   │   │   ├── StarsIcon.tsx
    │   │   │   ├── SunIcon.tsx
    │   │   │   ├── svg
    │   │   │   │   ├── admonition_danger.svg
    │   │   │   │   ├── admonition_info.svg
    │   │   │   │   ├── admonition_note.svg
    │   │   │   │   ├── admonition_tip.svg
    │   │   │   │   ├── admonition_warning.svg
    │   │   │   │   ├── api.svg
    │   │   │   │   ├── arrow-dropdown.svg
    │   │   │   │   ├── arrow-left.svg
    │   │   │   │   ├── arrow-right.svg
    │   │   │   │   ├── arrow-up.svg
    │   │   │   │   ├── attach.svg
    │   │   │   │   ├── binding.svg
    │   │   │   │   ├── box.svg
    │   │   │   │   ├── bulb.svg
    │   │   │   │   ├── code-file.svg
    │   │   │   │   ├── code-sandbox.svg
    │   │   │   │   ├── dark_to_light.svg
    │   │   │   │   ├── database.svg
    │   │   │   │   ├── doc.svg
    │   │   │   │   ├── empty-folder.svg
    │   │   │   │   ├── expression.svg
    │   │   │   │   ├── eye-closed.svg
    │   │   │   │   ├── eye-dark.svg
    │   │   │   │   ├── eye.svg
    │   │   │   │   ├── file-text.svg
    │   │   │   │   ├── filter.svg
    │   │   │   │   ├── folder.svg
    │   │   │   │   ├── img.svg
    │   │   │   │   ├── inspect.svg
    │   │   │   │   ├── light_to_dark.svg
    │   │   │   │   ├── moon.svg
    │   │   │   │   ├── pdf.svg
    │   │   │   │   ├── photo.svg
    │   │   │   │   ├── share.svg
    │   │   │   │   ├── stars.svg
    │   │   │   │   ├── sun.svg
    │   │   │   │   ├── trending-down.svg
    │   │   │   │   ├── trending-level.svg
    │   │   │   │   ├── trending-up.svg
    │   │   │   │   ├── txt.svg
    │   │   │   │   ├── unknown-file.svg
    │   │   │   │   ├── unlink.svg
    │   │   │   │   └── xls.svg
    │   │   │   ├── TableDeleteColumnIcon.tsx
    │   │   │   ├── TableDeleteRowIcon.tsx
    │   │   │   ├── TableInsertColumnIcon.tsx
    │   │   │   ├── TableInsertRowIcon.tsx
    │   │   │   ├── TrashIcon.tsx
    │   │   │   ├── TrendingDownIcon.tsx
    │   │   │   ├── TrendingLevelIcon.tsx
    │   │   │   ├── TrendingUpIcon.tsx
    │   │   │   ├── TxtIcon.tsx
    │   │   │   ├── UnknownFileIcon.tsx
    │   │   │   ├── UnlinkIcon.tsx
    │   │   │   ├── UserIcon.tsx
    │   │   │   ├── WarningIcon.tsx
    │   │   │   └── XlsIcon.tsx
    │   │   ├── IconProvider.tsx
    │   │   ├── IconRegistryContext.tsx
    │   │   ├── IFrame
    │   │   │   ├── IFrame.md
    │   │   │   ├── IFrame.module.scss
    │   │   │   ├── IFrame.spec.ts
    │   │   │   ├── IFrame.tsx
    │   │   │   └── IFrameNative.tsx
    │   │   ├── Image
    │   │   │   ├── Image.md
    │   │   │   ├── Image.module.scss
    │   │   │   ├── Image.spec.ts
    │   │   │   ├── Image.tsx
    │   │   │   └── ImageNative.tsx
    │   │   ├── Input
    │   │   │   ├── index.ts
    │   │   │   ├── InputAdornment.module.scss
    │   │   │   ├── InputAdornment.tsx
    │   │   │   ├── InputDivider.module.scss
    │   │   │   ├── InputDivider.tsx
    │   │   │   ├── InputLabel.module.scss
    │   │   │   ├── InputLabel.tsx
    │   │   │   ├── PartialInput.module.scss
    │   │   │   └── PartialInput.tsx
    │   │   ├── InspectButton
    │   │   │   ├── InspectButton.module.scss
    │   │   │   └── InspectButton.tsx
    │   │   ├── Items
    │   │   │   ├── Items.md
    │   │   │   ├── Items.spec.ts
    │   │   │   ├── Items.tsx
    │   │   │   └── ItemsNative.tsx
    │   │   ├── Link
    │   │   │   ├── Link.md
    │   │   │   ├── Link.module.scss
    │   │   │   ├── Link.spec.ts
    │   │   │   ├── Link.tsx
    │   │   │   └── LinkNative.tsx
    │   │   ├── List
    │   │   │   ├── doc-resources
    │   │   │   │   └── list-component-data.js
    │   │   │   ├── List.md
    │   │   │   ├── List.module.scss
    │   │   │   ├── List.spec.ts
    │   │   │   ├── List.tsx
    │   │   │   └── ListNative.tsx
    │   │   ├── Logo
    │   │   │   ├── doc-resources
    │   │   │   │   └── xmlui-logo.svg
    │   │   │   ├── Logo.md
    │   │   │   ├── Logo.tsx
    │   │   │   └── LogoNative.tsx
    │   │   ├── Markdown
    │   │   │   ├── CodeText.module.scss
    │   │   │   ├── CodeText.tsx
    │   │   │   ├── Markdown.md
    │   │   │   ├── Markdown.module.scss
    │   │   │   ├── Markdown.spec.ts
    │   │   │   ├── Markdown.tsx
    │   │   │   ├── MarkdownNative.tsx
    │   │   │   ├── parse-binding-expr.ts
    │   │   │   └── utils.ts
    │   │   ├── metadata-helpers.ts
    │   │   ├── ModalDialog
    │   │   │   ├── ConfirmationModalContextProvider.tsx
    │   │   │   ├── Dialog.module.scss
    │   │   │   ├── Dialog.tsx
    │   │   │   ├── ModalDialog.md
    │   │   │   ├── ModalDialog.module.scss
    │   │   │   ├── ModalDialog.spec.ts
    │   │   │   ├── ModalDialog.tsx
    │   │   │   ├── ModalDialogNative.tsx
    │   │   │   └── ModalVisibilityContext.tsx
    │   │   ├── NavGroup
    │   │   │   ├── NavGroup.md
    │   │   │   ├── NavGroup.module.scss
    │   │   │   ├── NavGroup.spec.ts
    │   │   │   ├── NavGroup.tsx
    │   │   │   ├── NavGroupContext.ts
    │   │   │   └── NavGroupNative.tsx
    │   │   ├── NavLink
    │   │   │   ├── NavLink.md
    │   │   │   ├── NavLink.module.scss
    │   │   │   ├── NavLink.spec.ts
    │   │   │   ├── NavLink.tsx
    │   │   │   └── NavLinkNative.tsx
    │   │   ├── NavPanel
    │   │   │   ├── NavPanel.md
    │   │   │   ├── NavPanel.module.scss
    │   │   │   ├── NavPanel.spec.ts
    │   │   │   ├── NavPanel.tsx
    │   │   │   └── NavPanelNative.tsx
    │   │   ├── NestedApp
    │   │   │   ├── AppWithCodeView.module.scss
    │   │   │   ├── AppWithCodeView.tsx
    │   │   │   ├── AppWithCodeViewNative.tsx
    │   │   │   ├── defaultProps.tsx
    │   │   │   ├── logo.svg
    │   │   │   ├── NestedApp.module.scss
    │   │   │   ├── NestedApp.tsx
    │   │   │   ├── NestedAppNative.tsx
    │   │   │   ├── Tooltip.module.scss
    │   │   │   ├── Tooltip.tsx
    │   │   │   └── utils.ts
    │   │   ├── NoResult
    │   │   │   ├── NoResult.md
    │   │   │   ├── NoResult.module.scss
    │   │   │   ├── NoResult.spec.ts
    │   │   │   ├── NoResult.tsx
    │   │   │   └── NoResultNative.tsx
    │   │   ├── NumberBox
    │   │   │   ├── numberbox-abstractions.ts
    │   │   │   ├── NumberBox.md
    │   │   │   ├── NumberBox.module.scss
    │   │   │   ├── NumberBox.spec.ts
    │   │   │   ├── NumberBox.tsx
    │   │   │   └── NumberBoxNative.tsx
    │   │   ├── Option
    │   │   │   ├── Option.md
    │   │   │   ├── Option.spec.ts
    │   │   │   ├── Option.tsx
    │   │   │   ├── OptionNative.tsx
    │   │   │   └── OptionTypeProvider.tsx
    │   │   ├── PageMetaTitle
    │   │   │   ├── PageMetaTilteNative.tsx
    │   │   │   ├── PageMetaTitle.md
    │   │   │   ├── PageMetaTitle.spec.ts
    │   │   │   └── PageMetaTitle.tsx
    │   │   ├── Pages
    │   │   │   ├── Page.md
    │   │   │   ├── Pages.md
    │   │   │   ├── Pages.module.scss
    │   │   │   ├── Pages.tsx
    │   │   │   └── PagesNative.tsx
    │   │   ├── Pagination
    │   │   │   ├── Pagination.md
    │   │   │   ├── Pagination.module.scss
    │   │   │   ├── Pagination.spec.ts
    │   │   │   ├── Pagination.tsx
    │   │   │   └── PaginationNative.tsx
    │   │   ├── PositionedContainer
    │   │   │   ├── PositionedContainer.module.scss
    │   │   │   ├── PositionedContainer.tsx
    │   │   │   └── PositionedContainerNative.tsx
    │   │   ├── ProfileMenu
    │   │   │   ├── ProfileMenu.module.scss
    │   │   │   └── ProfileMenu.tsx
    │   │   ├── ProgressBar
    │   │   │   ├── ProgressBar.md
    │   │   │   ├── ProgressBar.module.scss
    │   │   │   ├── ProgressBar.spec.ts
    │   │   │   ├── ProgressBar.tsx
    │   │   │   └── ProgressBarNative.tsx
    │   │   ├── Queue
    │   │   │   ├── Queue.md
    │   │   │   ├── Queue.spec.ts
    │   │   │   ├── Queue.tsx
    │   │   │   ├── queueActions.ts
    │   │   │   └── QueueNative.tsx
    │   │   ├── RadioGroup
    │   │   │   ├── RadioGroup.md
    │   │   │   ├── RadioGroup.module.scss
    │   │   │   ├── RadioGroup.spec.ts
    │   │   │   ├── RadioGroup.tsx
    │   │   │   ├── RadioGroupNative.tsx
    │   │   │   ├── RadioItem.tsx
    │   │   │   └── RadioItemNative.tsx
    │   │   ├── RealTimeAdapter
    │   │   │   ├── RealTimeAdapter.tsx
    │   │   │   └── RealTimeAdapterNative.tsx
    │   │   ├── Redirect
    │   │   │   ├── Redirect.md
    │   │   │   ├── Redirect.spec.ts
    │   │   │   └── Redirect.tsx
    │   │   ├── ResponsiveBar
    │   │   │   ├── README.md
    │   │   │   ├── ResponsiveBar.md
    │   │   │   ├── ResponsiveBar.module.scss
    │   │   │   ├── ResponsiveBar.spec.ts
    │   │   │   ├── ResponsiveBar.tsx
    │   │   │   └── ResponsiveBarNative.tsx
    │   │   ├── Select
    │   │   │   ├── HiddenOption.tsx
    │   │   │   ├── MultiSelectOption.tsx
    │   │   │   ├── OptionContext.ts
    │   │   │   ├── Select.md
    │   │   │   ├── Select.module.scss
    │   │   │   ├── Select.spec.ts
    │   │   │   ├── Select.tsx
    │   │   │   ├── SelectContext.tsx
    │   │   │   ├── SelectNative.tsx
    │   │   │   ├── SelectOption.tsx
    │   │   │   └── SimpleSelect.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
    │   │   │   ├── 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.mjs
    │   ├── 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
    │   │   │   ├── ModalDialogDriver.ts
    │   │   │   ├── NumberBoxDriver.ts
    │   │   │   ├── TextBoxDriver.ts
    │   │   │   ├── TimeInputDriver.ts
    │   │   │   ├── TimerDriver.ts
    │   │   │   └── TreeDriver.ts
    │   │   ├── fixtures.ts
    │   │   ├── infrastructure
    │   │   │   ├── index.html
    │   │   │   ├── main.tsx
    │   │   │   ├── public
    │   │   │   │   ├── mockServiceWorker.js
    │   │   │   │   ├── resources
    │   │   │   │   │   ├── bell.svg
    │   │   │   │   │   ├── box.svg
    │   │   │   │   │   ├── doc.svg
    │   │   │   │   │   ├── eye.svg
    │   │   │   │   │   ├── flower-640x480.jpg
    │   │   │   │   │   ├── sun.svg
    │   │   │   │   │   ├── test-image-100x100.jpg
    │   │   │   │   │   └── txt.svg
    │   │   │   │   └── serve.json
    │   │   │   └── TestBed.tsx
    │   │   └── themed-app-test-helpers.ts
    │   └── vite-env.d.ts
    ├── tests
    │   ├── components
    │   │   ├── CodeBlock
    │   │   │   └── hightlight-code.test.ts
    │   │   ├── playground-pattern.test.ts
    │   │   └── Tree
    │   │       └── Tree-states.test.ts
    │   ├── components-core
    │   │   ├── abstractions
    │   │   │   └── treeAbstractions.test.ts
    │   │   ├── container
    │   │   │   └── buildProxy.test.ts
    │   │   ├── interception
    │   │   │   ├── orderBy.test.ts
    │   │   │   ├── ReadOnlyCollection.test.ts
    │   │   │   └── request-param-converter.test.ts
    │   │   ├── scripts-runner
    │   │   │   ├── AttributeValueParser.test.ts
    │   │   │   ├── eval-tree-arrow-async.test.ts
    │   │   │   ├── eval-tree-arrow.test.ts
    │   │   │   ├── eval-tree-func-decl-async.test.ts
    │   │   │   ├── eval-tree-func-decl.test.ts
    │   │   │   ├── eval-tree-pre-post.test.ts
    │   │   │   ├── eval-tree-regression.test.ts
    │   │   │   ├── eval-tree.test.ts
    │   │   │   ├── function-proxy.test.ts
    │   │   │   ├── parser-regression.test.ts
    │   │   │   ├── process-event.test.ts
    │   │   │   ├── process-function.test.ts
    │   │   │   ├── process-implicit-context.test.ts
    │   │   │   ├── process-statement-asgn.test.ts
    │   │   │   ├── process-statement-destruct.test.ts
    │   │   │   ├── process-statement-regs.test.ts
    │   │   │   ├── process-statement-sync.test.ts
    │   │   │   ├── process-statement.test.ts
    │   │   │   ├── process-switch-sync.test.ts
    │   │   │   ├── process-switch.test.ts
    │   │   │   ├── process-try-sync.test.ts
    │   │   │   ├── process-try.test.ts
    │   │   │   └── test-helpers.ts
    │   │   ├── test-metadata-handler.ts
    │   │   ├── theming
    │   │   │   ├── border-segments.test.ts
    │   │   │   ├── component-layout.resolver.test.ts
    │   │   │   ├── layout-property-parser.test.ts
    │   │   │   ├── layout-resolver.test.ts
    │   │   │   ├── layout-resolver2.test.ts
    │   │   │   ├── layout-vp-override.test.ts
    │   │   │   └── padding-segments.test.ts
    │   │   └── utils
    │   │       ├── date-utils.test.ts
    │   │       ├── format-human-elapsed-time.test.ts
    │   │       └── LruCache.test.ts
    │   ├── language-server
    │   │   ├── completion.test.ts
    │   │   ├── format.test.ts
    │   │   ├── hover.test.ts
    │   │   └── mockData.ts
    │   └── parsers
    │       ├── common
    │       │   └── input-stream.test.ts
    │       ├── markdown
    │       │   └── parse-binding-expression.test.ts
    │       ├── parameter-parser.test.ts
    │       ├── paremeter-parser.test.ts
    │       ├── scripting
    │       │   ├── eval-tree-arrow.test.ts
    │       │   ├── eval-tree-pre-post.test.ts
    │       │   ├── eval-tree.test.ts
    │       │   ├── function-proxy.test.ts
    │       │   ├── lexer-literals.test.ts
    │       │   ├── lexer-misc.test.ts
    │       │   ├── module-parse.test.ts
    │       │   ├── parser-arrow.test.ts
    │       │   ├── parser-assignments.test.ts
    │       │   ├── parser-binary.test.ts
    │       │   ├── parser-destructuring.test.ts
    │       │   ├── parser-errors.test.ts
    │       │   ├── parser-expressions.test.ts
    │       │   ├── parser-function.test.ts
    │       │   ├── parser-literals.test.ts
    │       │   ├── parser-primary.test.ts
    │       │   ├── parser-regex.test.ts
    │       │   ├── parser-statements.test.ts
    │       │   ├── parser-unary.test.ts
    │       │   ├── process-event.test.ts
    │       │   ├── process-implicit-context.test.ts
    │       │   ├── process-statement-asgn.test.ts
    │       │   ├── process-statement-destruct.test.ts
    │       │   ├── process-statement-regs.test.ts
    │       │   ├── process-statement-sync.test.ts
    │       │   ├── process-statement.test.ts
    │       │   ├── process-switch-sync.test.ts
    │       │   ├── process-switch.test.ts
    │       │   ├── process-try-sync.test.ts
    │       │   ├── process-try.test.ts
    │       │   ├── simplify-expression.test.ts
    │       │   ├── statement-hooks.test.ts
    │       │   └── test-helpers.ts
    │       ├── style-parser
    │       │   ├── generateHvarChain.test.ts
    │       │   ├── parseHVar.test.ts
    │       │   ├── parser.test.ts
    │       │   └── tokens.test.ts
    │       └── xmlui
    │           ├── lint.test.ts
    │           ├── parser.test.ts
    │           ├── scanner.test.ts
    │           ├── transform.attr.test.ts
    │           ├── transform.circular.test.ts
    │           ├── transform.element.test.ts
    │           ├── transform.errors.test.ts
    │           ├── transform.escape.test.ts
    │           ├── transform.regression.test.ts
    │           ├── transform.script.test.ts
    │           ├── transform.test.ts
    │           └── xmlui.ts
    ├── tests-e2e
    │   ├── api-bound-component-regression.spec.ts
    │   ├── api-call-as-extracted-component.spec.ts
    │   ├── assign-to-object-or-array-regression.spec.ts
    │   ├── binding-regression.spec.ts
    │   ├── children-as-template-context-vars.spec.ts
    │   ├── compound-component.spec.ts
    │   ├── context-vars-regression.spec.ts
    │   ├── data-bindings.spec.ts
    │   ├── datasource-and-api-usage-in-var.spec.ts
    │   ├── datasource-direct-binding.spec.ts
    │   ├── datasource-onLoaded-regression.spec.ts
    │   ├── modify-array-item-regression.spec.ts
    │   ├── namespaces.spec.ts
    │   ├── push-to-array-regression.spec.ts
    │   ├── screen-breakpoints.spec.ts
    │   ├── scripting.spec.ts
    │   ├── state-scope-in-pages.spec.ts
    │   └── state-var-scopes.spec.ts
    ├── tsconfig.bin.json
    ├── tsconfig.json
    ├── tsconfig.node.json
    ├── vite.config.ts
    └── vitest.config.ts
```

# Files

--------------------------------------------------------------------------------
/xmlui/src/components/DropdownMenu/DropdownMenu.md:
--------------------------------------------------------------------------------

```markdown
  1 | %-DESC-START
  2 | 
  3 | **Key features:**
  4 | - **Hierarchical organization**: Supports nested submenus for complex menu structures
  5 | - **Flexible triggers**: Customizable button trigger or use your own trigger component
  6 | - **Progressive disclosure**: Reveals options on demand
  7 | 
  8 | You can nest `MenuItem`, `MenuSeparator`, and `SubMenuItem` components into `DropdownMenu` to define a menu hierarchy. The component provides a trigger to display the menu items:
  9 | 
 10 | ```xmlui-pg copy display name="Example: Using DropdownMenu" height="240px"
 11 | ---app copy display
 12 | <App>
 13 |   <DropdownMenu label="DropdownMenu">
 14 |     <MenuItem>Item 1</MenuItem>
 15 |     <MenuItem>Item 2</MenuItem>
 16 |     <MenuSeparator />
 17 |     <SubMenuItem label="Submenu">
 18 |       <MenuItem>Submenu Item 1</MenuItem>
 19 |       <MenuItem>Submenu Item 2</MenuItem>
 20 |     </SubMenuItem>
 21 |   </DropdownMenu>
 22 | </App>
 23 | ---desc
 24 | Try this dropdown menu:
 25 | ```
 26 | 
 27 | %-DESC-END
 28 | 
 29 | %-PROP-START alignment
 30 | 
 31 | Available values are:
 32 | - `start`: Menu items are aligned to the start of the trigger component (default).
 33 | - `end`: Menu items are aligned to the end of the trigger component.
 34 | 
 35 | ```xmlui-pg copy display name="Example: alignment" height="240px"
 36 | <App>
 37 |   <HStack>
 38 |     <DropdownMenu label="Start-aligned menu (open it!)">
 39 |       <MenuItem>Item 1</MenuItem>
 40 |       <MenuItem>Item 2</MenuItem>
 41 |       <MenuItem>Item 3</MenuItem>
 42 |     </DropdownMenu>
 43 |     <DropdownMenu label="End-aligned menu (open it!)" alignment="end">
 44 |       <MenuItem>Item 1</MenuItem>
 45 |       <MenuItem>Item 2</MenuItem>
 46 |       <MenuItem>Item 3</MenuItem>
 47 |     </DropdownMenu>
 48 |   </HStack>
 49 | </App>
 50 | ```
 51 | 
 52 | %-PROP-END
 53 | 
 54 | %-PROP-START triggerTemplate
 55 | 
 56 | ```xmlui-pg copy {3-5} display name="Example: triggerTemplate" height="240px"
 57 | <App>
 58 |   <DropdownMenu label="(ignored)">
 59 |     <property name="triggerTemplate">
 60 |       <Button label="Custom trigger" icon="chevrondown" iconPosition="end"/>
 61 |     </property>
 62 |     <MenuItem>Item 1</MenuItem>
 63 |     <MenuItem>Item 2</MenuItem>
 64 |     <MenuItem>Item 3</MenuItem>
 65 |   </DropdownMenu>
 66 | </App>
 67 | ```
 68 | 
 69 | %-PROP-END
 70 | 
 71 | %-PROP-START enabled
 72 | 
 73 | ```xmlui-pg copy {4, 11} display name="Example: enabled" height="240px"
 74 | <App>
 75 |   <HStack>
 76 |     <DropdownMenu
 77 |       enabled="true"
 78 |       label="Enabled Dropdown">
 79 |       <MenuItem>Item 1</MenuItem>
 80 |       <MenuItem>Item 2</MenuItem>
 81 |       <MenuItem>Item 3</MenuItem>
 82 |     </DropdownMenu>
 83 |     <DropdownMenu
 84 |       enabled="false"
 85 |       label="Disabled Dropdown">
 86 |       <MenuItem>Item 1</MenuItem>
 87 |       <MenuItem>Item 2</MenuItem>
 88 |       <MenuItem>Item 3</MenuItem>
 89 |     </DropdownMenu>
 90 |   </HStack>
 91 | </App>
 92 | ```
 93 | 
 94 | %-PROP-END
 95 | 
 96 | %-EVENT-START willOpen
 97 | 
 98 | ```xmlui-pg copy {6} display name="Example: willOpen" height="240px"
 99 | <App>
100 |   <variable name="counter" value="{0}" />
101 |   <Text value="Number of times the dropdown was opened: {counter}" />
102 |   <DropdownMenu
103 |     label="Dropdown"
104 |     onWillOpen="counter += 1">
105 |     <MenuItem>Item 1</MenuItem>
106 |     <MenuItem>Item 2</MenuItem>
107 |     <MenuItem>Item 3</MenuItem>
108 |   </DropdownMenu>
109 | </App>
110 | ```
111 | 
112 | %-EVENT-END
113 | 
114 | %-API-START close
115 | 
116 | ```xmlui-pg copy {4} display name="Example: close" height="240px"
117 | <App>
118 |   <DropdownMenu id="emojiDropdown" label="Emoji Dropdown">
119 |     <EmojiSelector
120 |       onSelect="(reaction) => { emojiDropdown.close(); }"
121 |       autoFocus="true"
122 |     />
123 |   </DropdownMenu>
124 | </App>
125 | ```
126 | 
127 | %-API-END
128 | 
129 | %-API-START open
130 | 
131 | ```xmlui-pg copy {2} display name="Example: open" height="300px"
132 | <App>
133 |   <Button onClick="emojiDropdown.open()">Open the Dropdown</Button>
134 |   <DropdownMenu id="emojiDropdown" label="Emoji Dropdown">
135 |     <EmojiSelector
136 |       onSelect="(reaction) => { emojiDropdown.close(); }"
137 |       autoFocus="true"
138 |     />
139 |   </DropdownMenu>
140 | </App>
141 | ```
142 | 
143 | %-API-END
144 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/RealTimeAdapter/RealTimeAdapterNative.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import { useEffect } from "react";
  2 | 
  3 | import type { AppContextObject } from "../../abstractions/AppContextDefs";
  4 | import RestApiProxy from "../../components-core/RestApiProxy";
  5 | import { delay } from "../../components-core/utils/misc";
  6 | import { useAppContext } from "../../components-core/AppContext";
  7 | 
  8 | export const defaultProps = {
  9 |   url: "",
 10 | };
 11 | 
 12 | type Props = {
 13 |   url: any;
 14 |   onEvent?: (...args: any[]) => void;
 15 | };
 16 | 
 17 | type RealtimeEventHandler = (events: Array<RealTimeEvent>) => void;
 18 | 
 19 | class PollClient {
 20 |   handlers: Array<RealtimeEventHandler> = [];
 21 |   lastEventId: any;
 22 |   tries: number = 0;
 23 |   polling: boolean = false;
 24 |   abortController: AbortController = new AbortController();
 25 | 
 26 |   constructor(
 27 |     public url: string,
 28 |     public appContext: AppContextObject,
 29 |   ) {}
 30 | 
 31 |   refreshAppContext(appContext: AppContextObject) {
 32 |     this.appContext = appContext;
 33 |   }
 34 | 
 35 |   private async poll(abortSignal: AbortSignal) {
 36 |     if (!this.polling || abortSignal.aborted) {
 37 |       return;
 38 |     }
 39 |     try {
 40 |       const response = await new RestApiProxy(this.appContext).execute({
 41 |         abortSignal,
 42 |         operation: {
 43 |           url: this.url,
 44 |           method: "get",
 45 |           headers: {
 46 |             "Cache-Control": "no-cache, no-store",
 47 |           },
 48 |           queryParams: {
 49 |             lastEventId: this.lastEventId,
 50 |           },
 51 |         },
 52 |         resolveBindingExpressions: true,
 53 |       });
 54 |       this.eventArrived(response);
 55 |       await this.poll(abortSignal);
 56 |     } catch (e) {
 57 |       if (this.tries < 100) {
 58 |         this.tries++;
 59 |         await delay(this.tries * 100); //TODO we should do some exponential fallback here
 60 |         await this.poll(abortSignal);
 61 |       } else {
 62 |         this.stopPoll();
 63 |       }
 64 |     }
 65 |   }
 66 | 
 67 |   private startPoll() {
 68 |     if (this.polling) {
 69 |       return;
 70 |     }
 71 |     this.polling = true;
 72 |     this.tries = 0;
 73 |     this.abortController = new AbortController();
 74 |     // console.log("poll client: start polling", this.handlers);
 75 |     void this.poll(this.abortController.signal);
 76 |   }
 77 | 
 78 |   private stopPoll() {
 79 |     this.polling = false;
 80 |     this.abortController.abort();
 81 |     // console.log("poll client: stop polling");
 82 |   }
 83 | 
 84 |   private eventArrived(response: any) {
 85 |     if (!response) {
 86 |       return;
 87 |     }
 88 |     let events = [response];
 89 |     if (Array.isArray(response)) {
 90 |       events = response;
 91 |     }
 92 |     this.lastEventId = events[events.length - 1].id;
 93 |     this.handlers.forEach((handler) => {
 94 |       handler(events);
 95 |     });
 96 |   }
 97 | 
 98 |   subscribe(handler: RealtimeEventHandler) {
 99 |     // console.log("subscribe", handler);
100 |     this.handlers.push(handler);
101 |     this.startPoll();
102 |   }
103 | 
104 |   unsubscribe(handler: RealtimeEventHandler) {
105 |     // console.log("unsubscribe", handler);
106 |     this.handlers = this.handlers.filter((existingHandler) => handler !== existingHandler);
107 |     if (!this.handlers.length) {
108 |       this.stopPoll();
109 |     }
110 |   }
111 | }
112 | 
113 | interface RealTimeEvent {}
114 | 
115 | const clients: Record<string, PollClient> = {};
116 | 
117 | function createOrGetPollClient(url: string, appContext: AppContextObject) {
118 |   if (!clients[url]) {
119 |     clients[url] = new PollClient(url, appContext);
120 |   }
121 |   clients[url].refreshAppContext(appContext);
122 |   return clients[url];
123 | }
124 | 
125 | export function RealTimeAdapter({ url, onEvent }: Props) {
126 |   const appContext = useAppContext();
127 | 
128 |   useEffect(() => {
129 |     const pollClient = createOrGetPollClient(url, appContext);
130 | 
131 |     const handler: RealtimeEventHandler = (events) => {
132 |       events.forEach((event) => {
133 |         onEvent?.(event);
134 |       });
135 |     };
136 | 
137 |     pollClient.subscribe(handler);
138 | 
139 |     return () => {
140 |       pollClient.unsubscribe(handler);
141 |     };
142 |   }, [appContext, onEvent, url]);
143 | 
144 |   return null;
145 | }
146 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/Icon/svg/admonition_info.svg:
--------------------------------------------------------------------------------

```
 1 | <svg width="37" height="36" viewBox="0 0 37 36" fill="none" xmlns="http://www.w3.org/2000/svg">
 2 | <path d="M19.6797 30.6797H16.7538C16.4842 30.6797 16.2661 30.8978 16.2661 31.1673V31.655C16.2661 32.7308 17.141 33.6056 18.2168 33.6056C19.2925 33.6056 20.1674 32.7308 20.1674 31.655V31.1673C20.1674 30.8978 19.9493 30.6797 19.6797 30.6797Z" fill="#868491"/>
 3 | <path d="M18.2163 30.6797H16.7538C16.4842 30.6797 16.2661 30.8978 16.2661 31.1673V31.655C16.2661 32.7307 17.1407 33.6053 18.2163 33.6056V30.6797Z" fill="#9A9A9A"/>
 4 | <path d="M25.8957 5.43603C23.6164 3.29393 20.631 2.22101 17.4998 2.41742C11.7935 2.7725 7.18363 7.53242 7.00551 13.2541C6.87409 17.4935 9.10093 21.3967 12.8174 23.4411C13.7413 23.9497 14.3152 24.9265 14.3152 25.9908V29.704C14.3152 30.7798 15.19 31.6547 16.2658 31.6547H20.1671C21.2429 31.6547 22.1177 30.7798 22.1177 29.704V25.9908C22.1177 24.9274 22.6959 23.9483 23.6274 23.4349C27.2082 21.4595 29.4326 17.6954 29.4326 13.6112C29.4326 10.5281 28.1435 7.54833 25.8957 5.43603Z" fill="#FFD93C"/>
 5 | <path d="M18.2172 22.9604C23.3799 22.9604 27.5651 18.7752 27.5651 13.6125C27.5651 8.44982 23.3799 4.26465 18.2172 4.26465C13.0546 4.26465 8.86938 8.44982 8.86938 13.6125C8.86938 18.7752 13.0546 22.9604 18.2172 22.9604Z" fill="#FFE980"/>
 6 | <path d="M19.922 16.5376C19.2738 16.5376 18.9424 16.1594 18.701 15.8837C18.4881 15.6408 18.4033 15.5622 18.2133 15.5622C18.0242 15.5622 17.94 15.6408 17.728 15.8832C17.5004 16.1437 17.156 16.5376 16.5079 16.5376C15.8602 16.5376 15.5159 16.1437 15.2883 15.8832C15.0763 15.6408 14.9921 15.5622 14.803 15.5622C14.5334 15.5622 14.3153 15.3441 14.3153 15.0746C14.3153 14.805 14.5334 14.5869 14.803 14.5869C15.4506 14.5869 15.7949 14.9808 16.0226 15.2412C16.2346 15.4837 16.3188 15.5622 16.5079 15.5622C16.697 15.5622 16.7817 15.4837 16.9937 15.2412C17.2213 14.9808 17.5656 14.5869 18.2133 14.5869C18.8615 14.5869 19.1929 14.965 19.4343 15.2408C19.6472 15.4837 19.732 15.5622 19.922 15.5622C20.1115 15.5622 20.1963 15.4837 20.4092 15.2412C20.6373 14.9808 20.9816 14.5869 21.6302 14.5869C21.8998 14.5869 22.1179 14.805 22.1179 15.0746C22.1179 15.3441 21.8998 15.5622 21.6302 15.5622C21.4402 15.5622 21.3554 15.6408 21.1425 15.8837C20.9144 16.1442 20.5702 16.5376 19.922 16.5376Z" fill="#FFF7CE"/>
 7 | <path d="M16.7533 25.8024C16.529 25.8024 16.3271 25.6466 16.277 25.4185L13.8387 14.2023C13.7815 13.939 13.9488 13.6794 14.2116 13.6218C14.4764 13.5637 14.7345 13.7319 14.7921 13.9947L17.2304 25.2109C17.2876 25.4742 17.1204 25.7338 16.8575 25.7914C16.8224 25.7991 16.7875 25.8024 16.7533 25.8024Z" fill="#FFF7CE"/>
 8 | <path d="M19.6802 25.8022C19.6458 25.8022 19.6111 25.7989 19.5759 25.7913C19.313 25.7337 19.1458 25.4741 19.203 25.2108L21.6413 13.9946C21.6989 13.7317 21.9561 13.564 22.2218 13.6217C22.4847 13.6793 22.6518 13.9389 22.5947 14.2022L20.1564 25.4184C20.1064 25.6466 19.9045 25.8022 19.6802 25.8022Z" fill="#FFF7CE"/>
 9 | <path d="M14.2314 25.3164C14.2833 25.5354 14.3152 25.761 14.3152 25.9922V29.7053C14.3152 30.7811 15.1901 31.656 16.2658 31.656H20.1671C21.2429 31.656 22.1178 30.7811 22.1178 29.7053V25.9922C22.1178 25.7612 22.1499 25.5355 22.2021 25.3164H14.2314Z" fill="#B4B6BC"/>
10 | <path d="M18.2162 25.3164H14.2314C14.2833 25.5354 14.3152 25.761 14.3152 25.9922V29.7053C14.3152 30.7811 15.1901 31.656 16.2658 31.656H18.2162V25.3164Z" fill="#B4B6BC"/>
11 | <path d="M22.1175 26.7773H18.2162V27.7527H22.1175V26.7773Z" fill="#9A9A9A"/>
12 | <path d="M22.1177 28.7285H18.2164V29.7038H22.1177V28.7285Z" fill="#9A9A9A"/>
13 | <path d="M18.2162 26.7773H14.3149V27.7527H18.2162V26.7773Z" fill="#9A9A9A"/>
14 | <path d="M18.2162 28.7285H14.3149V29.7038H18.2162V28.7285Z" fill="#9A9A9A"/>
15 | </svg>
16 | 
```

--------------------------------------------------------------------------------
/docs/public/pages/howto/chain-a-refetch.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Chain a DataSource refetch from an APICall.execute
  2 | 
  3 | `APICall.execute` returns a Promise, you can call `.then` to do something else.
  4 | 
  5 | ```xmlui-pg copy display {54} name="Click the Like button"
  6 | ---comp display
  7 | <Component name="SocialButton">
  8 |   <Button
  9 |     borderRadius="50%"
 10 |     icon="{$props.icon}"
 11 |     variant="outlined"
 12 |     themeColor="{$props.themeColor || 'secondary'}"
 13 |     size="xs"
 14 |     onClick="{emitEvent('click')}" />
 15 | </Component>
 16 | ---app display
 17 | <App>
 18 |   <APICall
 19 |     id="favoritePost"
 20 |     method="post"
 21 |     url="/api/posts/{$param}/favorite" />
 22 |   <APICall
 23 |     id="unfavoritePost"
 24 |     method="post"
 25 |     url="/api/posts/{$param}/unfavorite" />
 26 |   <DataSource
 27 |     id="timelineData"
 28 |     url="/api/timeline"
 29 |     method="GET" />
 30 |   <VStack gap="$space-4" padding="$space-4">
 31 |     <Text variant="h3">Social Media Timeline</Text>
 32 |     <Items data="{timelineData}">
 33 |       <Card padding="$space-3" marginBottom="$space-2">
 34 |         <VStack gap="$space-2">
 35 |           <Text variant="h6">{$item.author}</Text>
 36 |           <Text>{$item.content}</Text>
 37 |           <HStack gap="$space-4" verticalAlignment="center">
 38 |             <HStack gap="$space-1" verticalAlignment="center">
 39 |               <SocialButton icon="reply" />
 40 |               <Text variant="caption">{$item.replies_count}</Text>
 41 |             </HStack>
 42 |             <HStack gap="$space-1" verticalAlignment="center">
 43 |               <SocialButton icon="trending-up" />
 44 |               <Text variant="caption">{$item.reblogs_count}</Text>
 45 |             </HStack>
 46 |             <HStack gap="$space-1" verticalAlignment="center">
 47 |               <SocialButton
 48 |                 icon="like"
 49 |                 themeColor="{$item.favourited ? 'attention' : 'secondary'}">
 50 |                 <event name="click">
 51 |                   if ($item.favourited) {
 52 |                     // execute returns a Promise
 53 |                     unfavoritePost.execute($item.id).then(() => timelineData.refetch());
 54 |                   } else {
 55 |                     favoritePost.execute($item.id).then(() => timelineData.refetch());
 56 |                   }
 57 |                 </event>
 58 |               </SocialButton>
 59 |               <Text variant="caption">{$item.favourites_count}</Text>
 60 |             </HStack>
 61 |           </HStack>
 62 |         </VStack>
 63 |       </Card>
 64 |     </Items>
 65 |   </VStack>
 66 | </App>
 67 | ---api
 68 | {
 69 |   "apiUrl": "/api",
 70 |   "initialize": "$state.posts = [
 71 |     {
 72 |       id: '1',
 73 |       content: 'This is a great post about XMLUI!',
 74 |       author: 'John Developer',
 75 |       favourited: false,
 76 |       favourites_count: 5,
 77 |       replies_count: 2,
 78 |       reblogs_count: 1
 79 |     },
 80 |     {
 81 |       id: '2',
 82 |       content: 'Learning how to chain API calls is so useful.',
 83 |       author: 'Jane Designer',
 84 |       favourited: true,
 85 |       favourites_count: 12,
 86 |       replies_count: 4,
 87 |       reblogs_count: 3
 88 |     }
 89 |   ]",
 90 |   "operations": {
 91 |     "get-timeline": {
 92 |       "url": "/timeline",
 93 |       "method": "get",
 94 |       "handler": "return $state.posts"
 95 |     },
 96 |     "favorite-post": {
 97 |       "url": "/posts/:id/favorite",
 98 |       "method": "post",
 99 |       "pathParamTypes": {
100 |         "id": "string"
101 |       },
102 |       "handler": "
103 |         const post = $state.posts.find(p => p.id === $pathParams.id);
104 |         if (post) {
105 |           post.favourited = true;
106 |           post.favourites_count += 1;
107 |         }
108 |       "
109 |     },
110 |     "unfavorite-post": {
111 |       "url": "/posts/:id/unfavorite",
112 |       "method": "post",
113 |       "pathParamTypes": {
114 |         "id": "string"
115 |       },
116 |       "handler": "
117 |         const post = $state.posts.find(p => p.id === $pathParams.id);
118 |         if (post) {
119 |           post.favourited = false;
120 |           post.favourites_count -= 1;
121 |         }
122 |       "
123 |     }
124 |   }
125 | }
126 | ```
127 | 
```

--------------------------------------------------------------------------------
/xmlui/tests/components-core/scripts-runner/eval-tree-arrow.test.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { describe, expect, it } from "vitest";
  2 | 
  3 | import { evalBindingExpression } from "../../../src/components-core/script-runner/eval-tree-sync";
  4 | import {createEvalContext} from "./test-helpers";
  5 | 
  6 | describe("Evaluate arrow expressions (exp)", () => {
  7 |   it("Arrow #1", () => {
  8 |     // --- Arrange
  9 |     const source = "(x => 2 * x)(4)";
 10 |     const context = createEvalContext({});
 11 | 
 12 |     // --- Act
 13 |     const value = evalBindingExpression(source, context);
 14 | 
 15 |     // --- Arrange
 16 |     expect(value).equal(8);
 17 |   });
 18 | 
 19 |   it("Arrow #2", () => {
 20 |     // --- Arrange
 21 |     const source = "((x, y) => x + y)(1, 2)";
 22 |     const context = createEvalContext({});
 23 | 
 24 |     // --- Act
 25 |     const value = evalBindingExpression(source, context);
 26 | 
 27 |     // --- Arrange
 28 |     expect(value).equal(3);
 29 |   });
 30 | 
 31 |   it("Arrow #3", () => {
 32 |     // --- Arrange
 33 |     const source = "((x, y) => { return x + y })(1, 2)";
 34 |     const context = createEvalContext({});
 35 | 
 36 |     // --- Act
 37 |     const value = evalBindingExpression(source, context);
 38 | 
 39 |     // --- Arrange
 40 |     expect(value).equal(3);
 41 |   });
 42 | 
 43 |   it("Arrow #4", () => {
 44 |     // --- Arrange
 45 |     const source = "(x => (++x.h))(count)";
 46 |     const context = createEvalContext({
 47 |       localContext: {
 48 |         count: { h: 3 }
 49 |       }
 50 |     });
 51 | 
 52 |     // --- Act
 53 |     const value = evalBindingExpression(source, context);
 54 | 
 55 |     // --- Arrange
 56 |     expect(value).equal(4);
 57 |   });
 58 | 
 59 |   it("Arrow #5", () => {
 60 |     // --- Arrange
 61 |     const source = "(x => x += 2)(count)";
 62 |     const context = createEvalContext({
 63 |       localContext: {
 64 |         count: 3
 65 |       }
 66 |     });
 67 | 
 68 |     // --- Act
 69 |     const value = evalBindingExpression(source, context);
 70 | 
 71 |     // --- Arrange
 72 |     expect(value).equal(5);
 73 |   });
 74 | 
 75 |   it("Arrow #6", () => {
 76 |     // --- Arrange
 77 |     const source = "(x => x += 2)(count + 4)";
 78 |     const context = createEvalContext({
 79 |       localContext: {
 80 |         count: 3
 81 |       }
 82 |     });
 83 | 
 84 |     // --- Act
 85 |     const value = evalBindingExpression(source, context);
 86 | 
 87 |     // --- Arrange
 88 |     expect(value).equal(9);
 89 |   });
 90 | 
 91 |   it("Arrow #7", () => {
 92 |     // --- Arrange
 93 |     const source = "[1,2,3,4,5].filter(x => x % 2 === 0)[1]";
 94 |     const context = createEvalContext({
 95 |       localContext: {
 96 |         count: 3
 97 |       }
 98 |     });
 99 | 
100 |     // --- Act
101 |     const value = evalBindingExpression(source, context);
102 | 
103 |     // --- Arrange
104 |     expect(value).equal(4);
105 |   });
106 | 
107 |   it("Arrow #8", () => {
108 |     // --- Arrange
109 |     const source = "containsArray.array.filter(item => item % 2 === 0)[1]";
110 |     const context = createEvalContext({
111 |       localContext: {
112 |         containsArray: {
113 |           array: [5, 4, 3, 2, 1]
114 |         }
115 |       }
116 |     });
117 | 
118 |     // --- Act
119 |     const value = evalBindingExpression(source, context);
120 | 
121 |     // --- Arrange
122 |     expect(value).equal(2);
123 |   });
124 | 
125 |   it("Arrow #9", () => {
126 |     // --- Arrange
127 |     const source = "array.reduce((acc, item) => acc + item, 0)";
128 |     const context = createEvalContext({
129 |       localContext: {
130 |         array: [5, 4, 3, 2, 1]
131 |       }
132 |     });
133 | 
134 |     // --- Act
135 |     const value = evalBindingExpression(source, context);
136 | 
137 |     // --- Arrange
138 |     expect(value).equal(15);
139 |   });
140 | 
141 |   it("Arrow with rest #1", () => {
142 |     // --- Arrange
143 |     const source = "((...a) => a[0] + a[1])(1, 2)";
144 |     const context = createEvalContext({});
145 | 
146 |     // --- Act
147 |     const value = evalBindingExpression(source, context);
148 | 
149 |     // --- Arrange
150 |     expect(value).equal(3);
151 |   });
152 | 
153 |   it("Arrow with rest #2", () => {
154 |     // --- Arrange
155 |     const source = "((x, ...a) => x + a[0] + a[1])(1, 2, 3)";
156 |     const context = createEvalContext({});
157 | 
158 |     // --- Act
159 |     const value = evalBindingExpression(source, context);
160 | 
161 |     // --- Arrange
162 |     expect(value).equal(6);
163 |   });
164 | });
165 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/Markdown/Markdown.md:
--------------------------------------------------------------------------------

```markdown
  1 | %-DESC-START
  2 | 
  3 | **Key features:**
  4 | - **Rich formatting**: Support for headings, bold, italic, lists, links, images, blockquotes, and code blocks
  5 | - **Dynamic content**: Use &#64;{} binding expressions to inject variables and function results
  6 | - **File loading**: Load markdown content from external files using the `data` property
  7 | 
  8 | ## Acquiring content
  9 | 
 10 | You can specify Markdown content in these ways.
 11 | 
 12 | ### The content property
 13 | 
 14 | Render Markdown content that you calculate or get from other components.
 15 | 
 16 | ### The data property
 17 | 
 18 | Render Markdown content from an URL.
 19 | 
 20 | ### Nested text
 21 | 
 22 | Render Markdown content that you place directly in a Markdown component.
 23 | 
 24 | ## Whitespace and special characters
 25 | 
 26 | Whitespace is significant in Markdown, for example headers using the `#` syntax must begin in column 1.
 27 | 
 28 | These special XML characters are significant too.
 29 | 
 30 | ```
 31 | < (less than) - Must be escaped as &lt;
 32 | > (greater than) - Must be escaped as &gt;
 33 | & (ampersand) - Must be escaped as &amp;
 34 | " (double quote) - Must be escaped as &quot; in attributes
 35 | ' (single quote/apostrophe) - Must be escaped as &apos; in attributes
 36 | ```
 37 | 
 38 | You can use a CDATA section to avoid having to escape these characters individually.
 39 | 
 40 | ```
 41 | <Markdown>
 42 |   <![CDATA[
 43 |   ]]>
 44 | </Markdown>
 45 | ```
 46 | 
 47 | Or, as we have done in this page, you can use a code fence (a block delimited by triple backtics) to preserve them.
 48 | 
 49 | ## Supported elements
 50 | 
 51 | The `Markdown` component supports these basic elements.
 52 | 
 53 | - Heading
 54 | - Bold
 55 | - Italic
 56 | - Strikethrough
 57 | - Blockquote
 58 | - Ordered List
 59 | - Unordered List
 60 | - Code
 61 | - Horizontal Rule
 62 | - Link
 63 | - Image
 64 | - Table
 65 | 
 66 | See [this markdown guide](https://www.markdownguide.org/cheat-sheet/).
 67 | 
 68 | ## Binding Expressions
 69 | 
 70 | Our `Markdown` component is capable of evaluating binding expressions just as other XMLUI components.
 71 | Use the &#64;{} syntax to wrap expressions that need to be evaluated.
 72 | 
 73 | Objects, functions and arrays will be stringified if you place them in `Markdown`.
 74 | 
 75 | Function calls are executed and their return values inlined as strings into markdown.
 76 | 
 77 | ```xmlui-pg copy {5-9} name="Example: binding expressions syntax"
 78 | <App>
 79 |   <variable name="x" value="{() => { return 'testing' }}" />
 80 |   <Markdown>
 81 |     <![CDATA[
 82 | Empty elements are removed: @{}
 83 | 
 84 | Nested objects and functions are handled: @{ { a: 1, b: () => {} } }
 85 | 
 86 | Function calls are executed: @{x()}
 87 |     ]]>
 88 |   </Markdown>
 89 | </App>
 90 | ```
 91 | 
 92 | %-DESC-END
 93 | 
 94 | %-STYLE-START
 95 | The component itself cannot be styled, but the components that render the final text have customizable style variables.
 96 | 
 97 | [`Text`](/components/Text#styling)
 98 | [`Heading`](/components/Heading#styling)
 99 | [`Link`](/components/Link#styling)
100 | [`Image`](/components/Image#styling)
101 | [`Checkbox`](/components/Checkbox#styling)
102 | 
103 | 
104 | %-STYLE-END
105 | 
106 | %-PROP-START content
107 | 
108 | Use this property when the text you provide is not static but a result of calculations (you assemble the text or get it from other components).
109 | 
110 | 
111 | %-PROP-END
112 | 
113 | %-PROP-START removeIndents
114 | 
115 | ```xmlui-pg copy display name="Example: removeIndents property"
116 | <App layout="horizontal-sticky" padding="1rem">
117 |   <Markdown removeIndents="true">
118 |     <![CDATA[
119 |       # My Adventure in Markdown Land
120 | 
121 |       ## The Beginning
122 | 
123 |       In the bustling city of Markdownville, I embarked on a journey to
124 |       discover the secrets of Markdown. My adventure started in the heart
125 |       of the city, where the first rule of Markdown was inscribed in stone.
126 |     ]]>
127 |   </Markdown>
128 | </App>
129 | ```
130 | 
131 | %-PROP-END
132 | 
133 | %-PROP-START showHeadingAnchors
134 | 
135 | If this property is not set, the engine checks if `showHeadingAnchors` flag is turned on in the global configuration (in the `appGlobals` configuration object) and displays the heading anchor accordingly.
136 | 
137 | %-PROP-END
```

--------------------------------------------------------------------------------
/docs/content/components/FileUploadDropZone.md:
--------------------------------------------------------------------------------

```markdown
 1 | # FileUploadDropZone [#fileuploaddropzone]
 2 | 
 3 | `FileUploadDropZone` enables users to upload files by dragging and dropping files from their local file system onto a designated area within the UI.
 4 | 
 5 | ## Using `FileUploadDropZone` [#using-fileuploaddropzone]
 6 | 
 7 | The component provides a surface on which you can drag files or paste files from the clipboard. The following example demonstrates how to use the component.
 8 | 
 9 | ```xmlui-pg copy display name="Example: using FileUploadDropZone" height="200px"
10 | ---app copy display
11 | <App>
12 |   <H3>The cyan area below is a FileUploadDropZone</H3>
13 |   <FileUploadDropZone backgroundColor="cyan" height="100px"
14 |     onUpload="
15 |       (files) => {
16 |         console.log(files); 
17 |         files.map(file => toast('file ' + file.path + ' uploaded'))}" />
18 | </App>
19 | ---desc
20 | You can try it by dragging one or more files to the cyan surface. When you drop the file(s), the app triggers the `upload` event and displays a dialog for each file.
21 | 
22 | You can also paste files from the clipboard: click the drop zone (cyan area) and then use the keyboard shortcut set on your OS.
23 | ```
24 | 
25 | ## Properties [#properties]
26 | 
27 | ### `acceptedFileTypes` [#acceptedfiletypes]
28 | 
29 | Accepted file MIME types, separated by commas. For example: 'image/*,application/pdf'.
30 | 
31 | ### `allowPaste` (default: true) [#allowpaste-default-true]
32 | 
33 | This property indicates if the drop zone accepts files pasted from the clipboard (`true`) or only dragged files (`false`).
34 | 
35 | This property indicates if the drop zone accepts files pasted from the clipboard (`true`) or only dragged files (`false`).
36 | 
37 | The following example sets this property to `false` and, thus, it turns off pasting files:
38 | 
39 | ```xmlui-pg copy display name="Example: allowPaste" height="200px"
40 | ---app copy display
41 | <App>
42 |   <H3>You cannot paste files from the clipboard</H3>
43 |   <FileUploadDropZone backgroundColor="cyan" height="100px"
44 |     allowPaste="false"
45 |     onUpload="(files) => files.map(file => toast('file ' + file.path + ' uploaded'))" />
46 | </App>
47 | ---desc
48 | Try it! When you copy a file to a clipboard, you cannot paste it with the keyboard shortcut of your OS.
49 | ```
50 | 
51 | ### `enabled` (default: true) [#enabled-default-true]
52 | 
53 | If set to `false`, the drop zone will be disabled and users will not be able to upload files.
54 | 
55 | ### `maxFiles` [#maxfiles]
56 | 
57 | The maximum number of files that can be selected.
58 | 
59 | ### `text` (default: "Drop files here") [#text-default-drop-files-here]
60 | 
61 | With this property, you can change the default text to display when files are dragged over the drop zone.
62 | 
63 | ## Events [#events]
64 | 
65 | ### `upload` [#upload]
66 | 
67 | This component accepts files for upload but does not perform the actual operation. It fires the `upload` event and passes the list files to upload in the method's argument. You can use the passed file information to implement the upload (according to the protocol your backend supports).
68 | 
69 | Each item passed in the event argument is an instance of [File](https://developer.mozilla.org/en-US/docs/Web/API/File).
70 | 
71 | ## Exposed Methods [#exposed-methods]
72 | 
73 | This component does not expose any methods.
74 | 
75 | ## Styling [#styling]
76 | 
77 | ### Theme Variables [#theme-variables]
78 | 
79 | | Variable | Default Value (Light) | Default Value (Dark) |
80 | | --- | --- | --- |
81 | | [backgroundColor](../styles-and-themes/common-units/#color)-dropping-FileUploadDropZone | $backgroundColor--selected | $backgroundColor--selected |
82 | | [backgroundColor](../styles-and-themes/common-units/#color)-FileUploadDropZone | $backgroundColor | $backgroundColor |
83 | | [opacity](../styles-and-themes/common-units/#opacity)-dropping-FileUploadDropZone | 0.5 | 0.5 |
84 | | [textColor](../styles-and-themes/common-units/#color)-FileUploadDropZone | $textColor | $textColor |
85 | 
```

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

```typescript
  1 | import type { LogicalThread } from "../../abstractions/scripting/LogicalThread";
  2 | import type { ActionExecutionContext } from "../../abstractions/ActionDefs";
  3 | import type { ArrowExpression, Statement } from "./ScriptingSourceTree";
  4 | import type { BlockScope } from "../../abstractions/scripting/BlockScope";
  5 | 
  6 | /**
  7 |  * A function that resolves a module name to the text of the module
  8 |  */
  9 | export type ModuleResolver = (sourceModule: string, moduleName: string) => string | null;
 10 | 
 11 | // This type represents the context in which binding expressions and statements should be evaluated
 12 | export type BindingTreeEvaluationContext = {
 13 |   // --- Container scope
 14 |   localContext?: any;
 15 | 
 16 |   // --- Function to obtain the current working copy of the local context
 17 |   getLocalContext?: () => any;
 18 | 
 19 |   // --- Application context scope
 20 |   appContext?: any;
 21 | 
 22 |   // --- The main execution thread;
 23 |   mainThread?: LogicalThread;
 24 | 
 25 |   // --- The cancellation token to signal the cancellation of an operation
 26 |   cancellationToken?: CancellationToken;
 27 | 
 28 |   // --- Execution timeout in milliseconds
 29 |   timeout?: number;
 30 | 
 31 |   // --- Evaluation options
 32 |   options?: EvalTreeOptions;
 33 | 
 34 |   // --- Start time of the synchronous statement processing
 35 |   startTick?: number;
 36 | 
 37 |   // --- The values of event arguments to process in an ArrowExpressionStatement
 38 |   eventArgs?: any[];
 39 | 
 40 |   // --- Cached closure contexts for arrow expressions
 41 |   closureContexts?: Map<ArrowExpression, BlockScope[]>
 42 | 
 43 |   // --- Use this context wrapper with function that support implicit context
 44 |   implicitContextGetter?: ImplicitContextGetter;
 45 | 
 46 |   // --- Function to call on updating a localContext property (directly or indirectly)
 47 |   onUpdateHook?: (updateFn: () => any) => Promise<any>;
 48 | 
 49 |   // --- Call this method when a non-local variable is accessed
 50 |   onWillAccess?: (scope: any, index: string | number) => void | Promise<void>;
 51 | 
 52 |   // --- Call this method when a non-local variable is updated
 53 |   onWillUpdate?: (scope: any, index: string | number, updateType: UpdateType) => void | Promise<void>;
 54 | 
 55 |   // --- Call this method after a non-local variable has been updated
 56 |   onDidUpdate?: (scope: any, index: string | number, updateType: UpdateType) => void | Promise<void>;
 57 | 
 58 |   // --- Sign that a particular statement has started
 59 |   onStatementStarted?(evalContext: BindingTreeEvaluationContext, stmt: Statement): void | Promise<void>;
 60 | 
 61 |   // --- Sign that a particular statement has completed
 62 |   onStatementCompleted?(evalContext: BindingTreeEvaluationContext, stmt: Statement): void | Promise<void>;
 63 | };
 64 | 
 65 | // --- The type of non-local variable update
 66 | type UpdateType = "assignment" | "pre-post" | "function-call";
 67 | 
 68 | /**
 69 |  * A token that signals the cancellation of an operation
 70 |  */
 71 | class CancellationToken {
 72 |   private _cancelled = false;
 73 | 
 74 |   public get cancelled (): boolean {
 75 |     return this._cancelled;
 76 |   }
 77 | 
 78 |   public cancel (): void {
 79 |     this._cancelled = true;
 80 |   }
 81 | }
 82 | 
 83 | // Evaluation options to use with binding tree evaluation
 84 | export type EvalTreeOptions = {
 85 |   defaultToOptionalMemberAccess?: boolean;
 86 | };
 87 | 
 88 | // This function gets an object to pass as an implicit context when invoking a function on "objectWithFunction"
 89 | type ImplicitContextGetter = (objectWithFunction: any) => ActionExecutionContext;
 90 | 
 91 | /**
 92 |  * Creates an evaluation context with the given parts
 93 |  * @param parts Parts of the evaluation context
 94 |  * @returns New evaluation context
 95 |  */
 96 | export function createEvalContext (parts: Partial<BindingTreeEvaluationContext>): BindingTreeEvaluationContext {
 97 |   return {
 98 |     ...{
 99 |       mainThread: {
100 |         childThreads: [],
101 |         blocks: [{ vars: {} }],
102 |         loops: [],
103 |         breakLabelValue: -1
104 |       },
105 |       localContext: {}
106 |     },
107 |     ...parts
108 |   };
109 | }
110 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/AppState/AppState.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import { createComponentRenderer } from "../../components-core/renderers";
 2 | import { createMetadata, d } from "../metadata-helpers";
 3 | import { AppState, defaultProps } from "./AppStateNative";
 4 | 
 5 | const COMP = "AppState";
 6 | 
 7 | export const AppStateMd = createMetadata({
 8 |   status: "stable",
 9 |   description:
10 |     "`AppState` is an invisible component that provides global state management " +
11 |     "across your entire application. Unlike component variables that are scoped " +
12 |     "locally, AppState allows any component to access and update shared state " +
13 |     "without prop drilling.",
14 |   events: {
15 |     didUpdate: d(
16 |       "This event is fired when the AppState value is updated. The event provides " +
17 |         "the new state value as its parameter.",
18 |     ),
19 |   },
20 |   props: {
21 |     bucket: {
22 |       description:
23 |         `This property is the identifier of the bucket to which the \`${COMP}\` instance is bound. ` +
24 |         `Multiple \`${COMP}\` instances with the same bucket will share the same state object: any ` +
25 |         `of them updating the state will cause the other instances to view the new, updated state.`,
26 |       valueType: "string",
27 |       defaultValue: defaultProps.bucket,
28 |     },
29 |     initialValue: {
30 |       description:
31 |         `This property contains the initial state value. Though you can use multiple \`${COMP}\`` +
32 |         `component instances for the same bucket with their \`initialValue\` set, it may result ` +
33 |         `in faulty app logic. When xmlui instantiates an \`${COMP}\` with an explicit initial ` +
34 |         `value, that value is immediately merged with the existing state. ` +
35 |         `The issue may come from the behavior that \`initialValue\` is set (merged) only when a component mounts. ` +
36 |         `By default, the bucket's initial state is undefined.`,
37 |     },
38 |   },
39 |   apis: {
40 |     update: {
41 |       signature: "update(newState: Record<string, any>)",
42 |       description:
43 |         "This method updates the application state object bound to the `AppState` instance.",
44 |       parameters: {
45 |         newState: "An object that specifies the new state value.",
46 |       },
47 |     },
48 |     appendToList: {
49 |       signature: "appendToList(key: string, id: any)",
50 |       description:
51 |         "This method appends an item to an array in the application state object bound to the" +
52 |         " `AppState` instance.",
53 |       parameters: {
54 |         key: "The key of the array in the state object.",
55 |         id: "The item to append to the array.",
56 |       },
57 |     },
58 |     removeFromList: {
59 |       signature: "removeFromList(key: string, id: any)",
60 |       description:
61 |         "This method removes an item from an array in the application state object bound to the" +
62 |         " `AppState` instance.",
63 |       parameters: {
64 |         key: "The key of the array in the state object.",
65 |         id: "The item to remove from the array.",
66 |       },
67 |     },
68 |     listIncludes: {
69 |       signature: "listIncludes(key: string, id: any)",
70 |       description:
71 |         "This method checks if an array in the application state object contains a specific item.",
72 |       parameters: {
73 |         key: "The key of the array in the state object.",
74 |         id: "The item to check for in the array.",
75 |       },
76 |     },
77 |   },
78 |   nonVisual: true,
79 | });
80 | 
81 | export const appStateComponentRenderer = createComponentRenderer(
82 |   COMP,
83 |   AppStateMd,
84 |   ({ node, extractValue, updateState, registerComponentApi, lookupEventHandler }) => {
85 |     return (
86 |       <AppState
87 |         bucket={extractValue(node.props.bucket)}
88 |         initialValue={extractValue(node.props.initialValue)}
89 |         updateState={updateState}
90 |         registerComponentApi={registerComponentApi}
91 |         onDidUpdate={lookupEventHandler("didUpdate")}
92 |       />
93 |     );
94 |   },
95 | );
96 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/Form/Form.md:
--------------------------------------------------------------------------------

```markdown
  1 | %-DESC-START
  2 | 
  3 | **Key features:**
  4 | - **Automatic data binding**: Form controls automatically sync with form data using `bindTo` properties
  5 | - **Built-in validation**: Validates individual fields and overall form state before submission
  6 | - **Context sharing**: Provides `$data` and other context values accessible to all nested components
  7 | - **Submission handling**: Manages form submission workflow and prevents invalid submissions
  8 | 
  9 | See [this guide](/forms) for details.
 10 | 
 11 | %-DESC-END
 12 | 
 13 | %-CONTEXT_VAR-START $data
 14 | 
 15 | The following sample demonstrates enabling a field according to another's current value.
 16 | 
 17 | ```xmlui-pg copy {5} display name="Example: referencing field values"
 18 | <App>
 19 |   <Form
 20 |     data="{{ isEnabled: true, name: 'Joe' }}" paddingHorizontal="1rem">
 21 |     <FormItem label="Enable name" bindTo="isEnabled" type="switch" />
 22 |     <FormItem enabled="{$data.isEnabled}" label="Name" bindTo="name" />
 23 |   </Form>
 24 | </App>
 25 | ```
 26 | 
 27 | %-CONTEXT_VAR-END
 28 | 
 29 | %-PROP-START buttonRowTemplate
 30 | 
 31 | The following example demonstrates using it:
 32 | 
 33 | ```xmlui-pg copy display name="Example: buttonRowTemplate"
 34 | ---app copy display {10-19}
 35 | <App>
 36 |   <Form id="searchForm" padding="0.5rem"
 37 |     data="{{ search: 'Seattle', caseSensitive: false }}"
 38 |     onSubmit="() => {isSearching = true; delay(1000); isSearching = false; }"
 39 |     saveLabel="Search"
 40 |     var.isSearching="{false}">
 41 |       <Text>Please specify the name to include in the search:</Text>
 42 |       <FormItem bindTo="search" width="280px" />
 43 |       <FormItem type="checkbox" label="Case sensitive?" bindTo="caseSensitive" />
 44 |       <property name="buttonRowTemplate">
 45 |         <HStack gap="0.5rem" borderTop="1px solid #ddd" paddingVertical="1rem">
 46 |           <Button label="Test Search Server" type="button"
 47 |             themeColor="secondary" variant="outlined"
 48 |             onClick="toast('Search server is ok.')"/>
 49 |           <SpaceFiller/>
 50 |           <Button type="submit" enabled="{!isSearching}" icon="search"
 51 |             label="{isSearching ? 'Searching...' : 'Search'}"/>
 52 |         </HStack>
 53 |       </property>
 54 |   </Form>
 55 | </App>  
 56 | ---desc
 57 | This example mimics a one-second search and turns off the submit button during the operation. Also, it adds a Test Search Server button:
 58 | ```
 59 | 
 60 | %-PROP-END
 61 | 
 62 | %-EVENT-START submit
 63 | 
 64 | ```xmlui-pg copy {4} display name="Example: submit"
 65 | <App>
 66 |   <Form padding="0.5rem"
 67 |     data="{{ name: 'Joe', age: 43 }}"
 68 |     onSubmit="(toSave) => toast(JSON.stringify(toSave))">
 69 |     <FlowLayout columnGap="12px" paddingBottom="6px">
 70 |       <FormItem bindTo="name" label="Customer name" width="50%" />
 71 |       <FormItem bindTo="age" label="Age" type="integer" width="50%"
 72 |         zeroOrPositive="true" />
 73 |     </FlowLayout>
 74 |   </Form>
 75 | </App>  
 76 | ```
 77 | 
 78 | %-EVENT-END
 79 | 
 80 | %-API-START update
 81 | 
 82 | This method updates the form data with the change passed in its parameter. The parameter is a hash object, and this method updates the Form's properties accordingly. 
 83 | 
 84 | ```xmlui-pg copy display name="Example: update"
 85 | <App>
 86 |   <Form id="myForm" padding="0.5rem"
 87 |     data="{{ name: 'Joe', age: 43, $update: 123 }}"
 88 |     onSubmit="(toSave) => toast(JSON.stringify(toSave))">
 89 |     <FlowLayout columnGap="12px" paddingBottom="6px">
 90 |       <FormItem bindTo="name" label="Customer name" width="50%" />
 91 |       <FormItem bindTo="age" label="Age" type="integer" width="50%"
 92 |         zeroOrPositive="true" />
 93 |     </FlowLayout>
 94 |     <Button onClick="() => $data.update({age: $data.age + 1})" >
 95 |       Increment age (1)
 96 |     </Button>
 97 |     <Button onClick="() => myForm.update({age: $data.age + 1})" >
 98 |       Increment age (2)
 99 |     </Button>
100 |     <Button onClick="() => myForm.update({name: $data.name + '!', age: $data.age + 1})" >
101 |       Update name and age
102 |     </Button>
103 |   </Form>
104 | </App>  
105 | ```
106 | 
107 | %-API-END
108 | 
```

--------------------------------------------------------------------------------
/xmlui/scripts/generate-docs/create-theme-files.mjs:
--------------------------------------------------------------------------------

```
  1 | import { join, dirname } from "path";
  2 | import { existsSync, mkdirSync } from "fs";
  3 | import { fileURLToPath } from "url";
  4 | import { collectedThemes, collectedComponentMetadata } from "../../dist/metadata/xmlui-metadata.mjs";
  5 | import { ERROR_HANDLING, ERROR_MESSAGES } from "./constants.mjs";
  6 | import { handleFatalError, validateDependencies } from "./error-handling.mjs";
  7 | import { createScopedLogger } from "./logging-standards.mjs";
  8 | import { pathResolver } from "./configuration-management.mjs";
  9 | import { 
 10 |   processComponentThemeVars, 
 11 |   iterateObjectEntries,
 12 |   writeFileWithLogging 
 13 | } from "./pattern-utilities.mjs";
 14 | 
 15 | const OUTPUT_DIR = pathResolver.getOutputPaths().themes;
 16 | const logger = createScopedLogger("ThemeGenerator");
 17 | 
 18 | /**
 19 |  * Counts the number of theme variables, excluding those that start with "---"
 20 |  * @param {Object} themeVars - The theme variables object
 21 |  * @returns {number} - The count of non-separator theme variables
 22 |  */
 23 | function countThemeVars(themeVars) {
 24 |   if (!themeVars || typeof themeVars !== 'object') {
 25 |     return 0;
 26 |   }
 27 |   
 28 |   return Object.keys(themeVars).filter(key => !key.startsWith("---")).length;
 29 | }
 30 | 
 31 | async function generateThemeFiles() {
 32 |   logger.operationStart("theme file generation");
 33 |   
 34 |   try {
 35 |     // --- Create the output folder
 36 |     if (!existsSync(OUTPUT_DIR)) {
 37 |       mkdirSync(OUTPUT_DIR, { recursive: true });
 38 |     }
 39 | 
 40 |     // Validate required dependencies
 41 |     validateDependencies({
 42 |       THEME_INFO: collectedThemes,
 43 |       COMPONENT_METADATA: collectedComponentMetadata
 44 |     });
 45 | 
 46 |     const rootTheme = collectedThemes.root;
 47 | 
 48 |     // Extract theme variable information from components using utility
 49 |     const themeVarsData = processComponentThemeVars(collectedComponentMetadata, logger);
 50 | 
 51 |     // Write theme files with error handling
 52 |     let totalThemeVars = 0;
 53 |     let exportedThemeCount = 0;
 54 |     
 55 |     await iterateObjectEntries(collectedThemes, async (themeName, themeData) => {
 56 |       // Skip the abstract root theme
 57 |       if (themeName === "root") return;
 58 | 
 59 |       // Prepare the complete theme vars object
 60 |       const completeThemeVars = {
 61 |         "--- App-bound root theme variables": "",
 62 |         ...rootTheme.themeVars,
 63 |         "--- App-bound theme-specific variables": "",
 64 |         ...themeData.themeVars,
 65 |         "--- Component-bound theme variables": "",
 66 |         ...themeVarsData.base,
 67 |         light: { ...themeData.themeVars.light, ...themeVarsData.light },
 68 |         dark: { ...themeData.themeVars.dark, ...themeVarsData.dark },
 69 |       };
 70 | 
 71 |       // Count theme vars (excluding separators)
 72 |       const themeVarCount = countThemeVars(completeThemeVars);
 73 |       totalThemeVars += themeVarCount;
 74 |       exportedThemeCount++;
 75 |       
 76 |       const themePath = join(OUTPUT_DIR, `${themeName}.json`);
 77 |       const themeContent = JSON.stringify(
 78 |         {
 79 |           ...themeData,
 80 |           themeVars: completeThemeVars,
 81 |         },
 82 |         null,
 83 |         2,
 84 |       );
 85 | 
 86 |       await writeFileWithLogging(themePath, themeContent, logger);
 87 |       
 88 |       logger.info(`Theme '${themeName}' exported with ${themeVarCount} theme variables`);
 89 |     }, { async: true });
 90 |     
 91 |     // Display summary of all exported themes
 92 |     if (exportedThemeCount > 0) {
 93 |       logger.info(`\n=== Theme Export Summary ===`);
 94 |       logger.info(`Exported ${exportedThemeCount} theme files with a total of ${totalThemeVars} theme variables`);
 95 |       logger.info(`Average of ${Math.round(totalThemeVars / exportedThemeCount)} theme variables per theme file`);
 96 |     }
 97 | 
 98 |     logger.operationComplete("theme file generation");
 99 |     
100 |   } catch (error) {
101 |     handleFatalError(error, ERROR_HANDLING.EXIT_CODES.GENERAL_ERROR, "theme file generation");
102 |   }
103 | }
104 | 
105 | // Execute the main function
106 | generateThemeFiles();
```

--------------------------------------------------------------------------------
/xmlui/src/components/Charts/LineChart/LineChart.md:
--------------------------------------------------------------------------------

```markdown
  1 | %-DESC-START
  2 | 
  3 | The LineChart component accommodates the size of its parent unless you set it explicitly:
  4 | 
  5 | ```xmlui-pg copy display height="300px" name="Example: dimension determined by the parent" /Card height="240px" width="75%"/
  6 | <Card height="240px" width="75%">
  7 |   <LineChart
  8 |     data="{[
  9 |         { 'sprint': 'Sprint 1', 'A': 44 },
 10 |         { 'sprint': 'Sprint 2', 'A': 32 },
 11 |         { 'sprint': 'Sprint 3', 'A': 48 },
 12 |         { 'sprint': 'Sprint 4', 'A': 72 }
 13 |        ]}"
 14 |     yKeys="{['A']}"
 15 |     xKey="sprint"
 16 |   />
 17 | </Card>
 18 | ```
 19 | 
 20 | ```xmlui-pg copy display height="300px" name="Example: dimension overwritten by LineChart" /height="240px"/ /height="200px"/
 21 | <Card height="240px">
 22 |   <LineChart
 23 |     height="200px"
 24 |     data="{[
 25 |         { 'sprint': 'Sprint 1', 'A': 44 },
 26 |         { 'sprint': 'Sprint 2', 'A': 32 },
 27 |         { 'sprint': 'Sprint 3', 'A': 48 },
 28 |         { 'sprint': 'Sprint 4', 'A': 72 }
 29 |        ]}"
 30 |     yKeys="{['A']}"
 31 |     xKey="sprint"
 32 |   />
 33 | </Card>
 34 | ```
 35 | 
 36 | 
 37 | **Key features:**
 38 | - **Flexible orientation**: Choose horizontal or vertical bar layouts
 39 | - **Multiple data series**: Display several metrics on the same chart with different colored bars
 40 | - **Stacked vs grouped**: Stack bars on top of each other or place them side by side
 41 | - **Custom formatting**: Use `tickFormatter` to format axis labels and [`LabelList`](/components/LabelList) for data labels
 42 | 
 43 | %-DESC-END
 44 | 
 45 | %-PROP-START tickFormatterY
 46 | 
 47 | ```xmlui-pg copy display height="320px" name="Example: tickFormatterY" /tickFormatterY/
 48 | <App>
 49 |   <LineChart
 50 |     height="240px"
 51 |     data="{[
 52 |         { 'sprint': 'Sprint 1', 'A': 44 },
 53 |         { 'sprint': 'Sprint 2', 'A': 32 },
 54 |         { 'sprint': 'Sprint 3', 'A': 48 },
 55 |         { 'sprint': 'Sprint 4', 'A': 72 }
 56 |        ]}"
 57 |     yKeys="{['A']}"
 58 |     xKey="sprint"
 59 |     tickFormatterY="{(value) => '$' + value}"
 60 |   />
 61 | </App>
 62 | ```
 63 | 
 64 | %-PROP-END
 65 | 
 66 | 
 67 | %-PROP-START tickFormatterX
 68 | 
 69 | ```xmlui-pg copy display height="320px" name="Example: tickFormatterX" /tickFormatterX/
 70 | <App>
 71 |   <LineChart
 72 |     height="240px"
 73 |     data="{[
 74 |         { 'sprint': 'Sprint 1', 'A': 44 },
 75 |         { 'sprint': 'Sprint 2', 'A': 32 },
 76 |         { 'sprint': 'Sprint 3', 'A': 48 },
 77 |         { 'sprint': 'Sprint 4', 'A': 72 }
 78 |        ]}"
 79 |     yKeys="{['A']}"
 80 |     xKey="sprint"
 81 |     tickFormatterX="{(value) => '(' + value + ')'}"
 82 |   />
 83 | </App>
 84 | ```
 85 | 
 86 | %-PROP-END
 87 | 
 88 | %-PROP-START tooltipTemplate
 89 | 
 90 | ```xmlui-pg copy display height="320px" name="Example: tooltipTemplate" /tooltipTemplate/
 91 | <App>
 92 |   <LineChart
 93 |     height="240px"
 94 |     data="{[
 95 |         { 'sprint': 'Sprint 1', 'A': 44, 'B': 28 },
 96 |         { 'sprint': 'Sprint 2', 'A': 32, 'B': 41 },
 97 |         { 'sprint': 'Sprint 3', 'A': 48, 'B': 35 },
 98 |         { 'sprint': 'Sprint 4', 'A': 72, 'B': 58 }
 99 |        ]}"
100 |     yKeys="{['A', 'B']}"
101 |     xKey="sprint"
102 |   >
103 |       <property name="tooltipTemplate">
104 |         <VStack backgroundColor='white' padding="$space-2">
105 |           <Text fontWeight='bold'>{$tooltip.label}</Text>
106 |           <Items data="{$tooltip.payload}">
107 |             <HStack gap="$space-2" verticalAlignment="center">
108 |               <Stack
109 |                 width="8px"
110 |                 height="8px"
111 |                 backgroundColor="{$item.color}" />
112 |               <Text>{$item.label}: {$item.value}</Text>
113 |             </HStack>
114 |           </Items>
115 |         </VStack>
116 |       </property>
117 |   </LineChart>
118 | </App>
119 | ```
120 | 
121 | The `tooltipTemplate` prop allows you to customize the appearance and content of chart tooltips. The template receives a `$tooltip` context variable containing:
122 | 
123 | - `$tooltip.label`: The label for the data point (typically the yKey value)
124 | - `$tooltip.payload`: An object containing all data values for the hovered point
125 | - `$tooltip.active`: Boolean indicating if the tooltip is currently active
126 | 
127 | %-PROP-END
128 | 
```

--------------------------------------------------------------------------------
/docs/content/components/Image.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Image [#image]
  2 | 
  3 | `Image` displays pictures from URLs or local sources with built-in responsive sizing, aspect ratio control, and accessibility features. It handles different image formats and provides options for lazy loading and click interactions.
  4 | 
  5 | ## Properties [#properties]
  6 | 
  7 | ### `alt` [#alt]
  8 | 
  9 | This optional property specifies an alternate text for the image.
 10 | 
 11 | This is useful in two cases:
 12 | 1. Accessibility: screen readers read the prop value to users so they know what the image is about.
 13 | 2. The text is also displayed when the image can't be loaded for some reason (network errors, content blocking, etc.).
 14 | 
 15 | ```xmlui-pg copy display name="Example: alt"
 16 | <App>
 17 |   <Image 
 18 |     src="cantFindIt.jpg" 
 19 |     alt="This image depicts a wonderful scene not for human eyes" />
 20 | </App>
 21 | ```
 22 | 
 23 | ### `aspectRatio` [#aspectratio]
 24 | 
 25 | This property sets a preferred aspect ratio for the image, which will be used in calculating auto sizes and other layout functions. If this value is not used, the original aspect ratio is kept. The value can be a number of a string (such as "16/9").
 26 | 
 27 | ```xmlui-pg copy display name="Example: aspectRatio"
 28 | <App>
 29 |   <Image 
 30 |     src="/resources/images/components/image/breakfast.jpg" 
 31 |     aspectRatio="200 / 150" />
 32 | </App>
 33 | ```
 34 | 
 35 | ### `data` [#data]
 36 | 
 37 | This property contains the binary data that represents the image.
 38 | 
 39 | ### `fit` (default: "contain") [#fit-default-contain]
 40 | 
 41 | This property sets how the image content should be resized to fit its container.
 42 | 
 43 | | Name      | Value |
 44 | | --------- | ----- |
 45 | | `contain` | The replaced content is scaled to maintain its aspect ratio while fitting within the image's container. The entire image is made to fill the container. |
 46 | | `cover`   | The image is sized to maintain its aspect ratio while filling the element's entire content box. If the image's aspect ratio does not match the aspect ratio of its container, then the image will be clipped to fit. |
 47 | 
 48 | ```xmlui-pg copy display name="Example: fit" {5,9}
 49 | <App>
 50 |   <HStack padding="1rem" height="280px" gap="1rem">
 51 |     <Image 
 52 |       src="/resources/images/components/image/breakfast.jpg" 
 53 |       fit="contain" 
 54 |       width="240px" />
 55 |     <Image 
 56 |       src="/resources/images/components/image/breakfast.jpg" 
 57 |       fit="cover" 
 58 |       width="240px" />
 59 |   </HStack>
 60 | </App>
 61 | ```
 62 | 
 63 | ### `inline` (default: false) [#inline-default-false]
 64 | 
 65 | When set to true, the image will be displayed as an inline element instead of a block element.
 66 | 
 67 | ### `lazyLoad` (default: false) [#lazyload-default-false]
 68 | 
 69 | Lazy loading instructs the browser to load the image only when it is imminently needed (e.g. user scrolls to it).
 70 | 
 71 | Lazy loading instructs the browser to load the image only when it is imminently needed (e.g. user scrolls to it).
 72 | The default value is eager (\`false\`).
 73 | 
 74 | ### `src` [#src]
 75 | 
 76 | This property is used to indicate the source (path) of the image to display. When not defined, no image is displayed.
 77 | 
 78 | ## Events [#events]
 79 | 
 80 | ### `click` [#click]
 81 | 
 82 | This event is triggered when the Image is clicked.
 83 | 
 84 | This event is triggered when the image is clicked.
 85 | 
 86 | ```xmlui-pg copy {6} display name="Example: click"
 87 | <App>
 88 |   <Stack height="280px" width="400px">
 89 |     <Image
 90 |       src="/resources/images/components/image/breakfast.jpg"
 91 |       fit="cover"
 92 |       onClick="toast('Image clicked')"
 93 |     />
 94 |   </Stack>
 95 | </App>
 96 | ```
 97 | 
 98 | ## Exposed Methods [#exposed-methods]
 99 | 
100 | This component does not expose any methods.
101 | 
102 | ## Styling [#styling]
103 | 
104 | ### Theme Variables [#theme-variables]
105 | 
106 | | Variable | Default Value (Light) | Default Value (Dark) |
107 | | --- | --- | --- |
108 | | [borderColor](../styles-and-themes/common-units/#color)-Image | *none* | *none* |
109 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-Image | *none* | *none* |
110 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/NumberBox/numberbox-abstractions.ts:
--------------------------------------------------------------------------------

```typescript
  1 | export const NUMBERBOX_MAX_VALUE = 999999999999999;
  2 | export const DECIMAL_SEPARATOR = ".";
  3 | export const EXPONENTIAL_SEPARATOR = "e";
  4 | export const INT_REGEXP = /^-?\d+$/;
  5 | export const FLOAT_REGEXP = /^-?\d+(\.\d+)?([eE][+-]?\d+)?$/;
  6 | export const DEFAULT_STEP = 1;
  7 | 
  8 | export type empty = null | undefined;
  9 | 
 10 | export function isEmptyLike(value: string | number | empty): value is empty {
 11 |   return typeof value === "undefined" || value === null || value === "";
 12 | }
 13 | 
 14 | export function mapToRepresentation(value: string | number | empty) {
 15 |   if (typeof value === "string") return value;
 16 |   if (typeof value === "number") return value.toString();
 17 |   return "";
 18 | }
 19 | 
 20 | export function isOutOfBounds(value: number, min: number, max: number) {
 21 |   return value < min || value > max;
 22 | }
 23 | 
 24 | export function clamp(value: number, min: number, max: number) {
 25 |   let clamped = value;
 26 |   if (value < min) clamped = min;
 27 |   if (value > max) clamped = max;
 28 |   return clamped;
 29 | }
 30 | 
 31 | export function toUsableNumber(value: string | number | empty, isInteger = false): number | empty {
 32 |   const isUsable = isInteger ? isUsableInteger : isUsableFloat;
 33 |   if (!isUsable(value)) return null;
 34 | 
 35 |   if (typeof value === "string") {
 36 |     value = isInteger ? Number.parseInt(value) : +value;
 37 |   }
 38 | 
 39 |   return value;
 40 | }
 41 | 
 42 | /**
 43 |  * Check whether the input value is a usable number for operations.
 44 |  * Passes if it's of type number or a non-empty string that evaluates to a number.
 45 |  */
 46 | export function isUsableFloat(value: string | number | empty) {
 47 |   if (typeof value === "string" && value.length > 0) {
 48 |     return !Number.isNaN(+value) && naiveFloatBounding(value);
 49 |   }
 50 |   return typeof value === "number";
 51 | }
 52 | 
 53 | // TEMP
 54 | // Rounding and arithmetic with large floats is a hassle if loss of precision is apparent.
 55 | // Just bound the incoming floating point value to the max value available.
 56 | // This is an edge case but makes it so that we stay consistent and can do arithmetic with the spinner box.
 57 | function naiveFloatBounding(value: string) {
 58 |   const integerPart = value.split(".")[0];
 59 |   return Math.abs(Number.parseInt(integerPart)) <= NUMBERBOX_MAX_VALUE;
 60 | }
 61 | 
 62 | /**
 63 |  * Check whether the input value is a usable integer for operations.
 64 |  * Passes if it's of type number and is an integer
 65 |  * or a non-empty string that evaluates to an integer.
 66 |  */
 67 | export function isUsableInteger(value: string | number | empty) {
 68 |   if (
 69 |     typeof value === "string" &&
 70 |     value.length > 0 &&
 71 |     ![EXPONENTIAL_SEPARATOR, DECIMAL_SEPARATOR].some((item) => value.includes(item))
 72 |   ) {
 73 |     return Number.isSafeInteger(+value);
 74 |   } else if (typeof value === "number") {
 75 |     return Number.isSafeInteger(value);
 76 |   }
 77 |   return false;
 78 | }
 79 | 
 80 | // TODO:
 81 | 
 82 | class NumberFormatter2 {
 83 |   private formatter: Intl.NumberFormat;
 84 |   private model: {
 85 |     value: number;
 86 |     formatted: string;
 87 |     stripped: string;
 88 | 
 89 |     group: string;
 90 |     decimal: string;
 91 |     sign: string;
 92 |     //exponent: string;
 93 |   }
 94 |   locale: string;
 95 |   options?: Intl.NumberFormatOptions;
 96 | 
 97 |   constructor(locale: string, options?: Intl.NumberFormatOptions) {
 98 |     this.locale = locale;
 99 |     this.options = options;
100 |     this.formatter = new Intl.NumberFormat(locale, options);
101 |   }
102 | 
103 |   set input(value: string | number | empty) {
104 | 
105 |   }
106 | 
107 |   private buildModel() {
108 |     const parts = this.formatter.formatToParts(1234.5);
109 |     this.model.group = parts.find((p) => p.type === "group")?.value || "";
110 |     this.model.decimal = parts.find((p) => p.type === "decimal")?.value || "";
111 |   }
112 | 
113 |   parse(value: string): number {
114 |     return 0;
115 |   }
116 | 
117 |   format(value: number): string {
118 |     return this.formatter.format(value);
119 |   }
120 | 
121 |   /**
122 |    * Strip all non-numeric characters but keep the type of string
123 |    * @param value 
124 |    */
125 |   sanitize(value: string): string {
126 |     return "";
127 |   }
128 | }
129 | 
```

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

```scss
  1 | @use "../../components-core/theming/themes" as t;
  2 | 
  3 | // --- This code snippet is required to collect the theme variables used in this module
  4 | $component: "ModalDialog";
  5 | $themeVars: ();
  6 | @function createThemeVar($componentVariable) {
  7 |   $themeVars: t.appendThemeVar($themeVars, $componentVariable) !global;
  8 |   @return t.getThemeVar($themeVars, $componentVariable);
  9 | }
 10 | 
 11 | // --- Theme vars for paddings
 12 | $themeVars: t.composePaddingVars($themeVars, $component);
 13 | $themeVars: t.composePaddingVars($themeVars, "overlay-#{$component}");
 14 | $padding-ModalDialog: createThemeVar("padding-#{$component}");
 15 | $backgroundColor-ModalDialog: createThemeVar("Dialog:backgroundColor-#{$component}");
 16 | $backgroundColor-overlay-ModalDialog: createThemeVar("Dialog:backgroundColor-overlay-#{$component}");
 17 | $borderRadius-ModalDialog: createThemeVar("Dialog:borderRadius-#{$component}");
 18 | $fontFamily-ModalDialog: createThemeVar("Dialog:fontFamily-#{$component}");
 19 | $textColor-ModalDialog: createThemeVar("Dialog:textColor-#{$component}");
 20 | $minWidth-ModalDialog: createThemeVar("Dialog:minWidth-#{$component}");
 21 | $maxWidth-ModalDialog: createThemeVar("Dialog:maxWidth-#{$component}");
 22 | $marginBottom-title-ModalDialog: createThemeVar("Dialog:marginBottom-title-#{$component}");
 23 | 
 24 | @layer components {
 25 |   .overlay {
 26 |     position: absolute;
 27 |     display: grid;
 28 |     place-items: center;
 29 |     overflow-y: auto;
 30 |     inset: 0;
 31 |     padding: t.$space-4;
 32 |   }
 33 | 
 34 |   .fullScreen {
 35 |     padding: 0;
 36 |     width: 100%;
 37 |     height: 100%;
 38 |     display: block;
 39 |     .content {
 40 |       overflow: auto;
 41 |       width: 100%;
 42 |       height: 100%;
 43 |       max-width: 100%;
 44 |       max-height: 100%;
 45 |       padding: 0;
 46 |       border-radius: 0;
 47 |     }
 48 |   }
 49 | 
 50 |   .overlayBg {
 51 |     background-color: $backgroundColor-overlay-ModalDialog;
 52 |     inset: 0;
 53 |     animation: overlayShow 150ms cubic-bezier(0.16, 1, 0.3, 1);
 54 |     position: fixed;
 55 | 
 56 |     &.nested {
 57 |       position: absolute;
 58 |       top: 0;
 59 |       display: flex;
 60 |       align-items: center;
 61 |       justify-content: center;
 62 |       height: 100%;
 63 |       overflow: hidden;
 64 |     }
 65 |   }
 66 | 
 67 |   .content {
 68 |     background-color: $backgroundColor-ModalDialog;
 69 |     border-radius: $borderRadius-ModalDialog;
 70 |     font-family: $fontFamily-ModalDialog;
 71 |     color: $textColor-ModalDialog;
 72 |     @include t.paddingVars($themeVars, $component);
 73 |     box-shadow: t.$boxShadow-spread;
 74 |     transform: translate(0);
 75 |     width: 90vw;
 76 |     max-height: 100%;
 77 |     max-width: $maxWidth-ModalDialog;
 78 |     min-width: $minWidth-ModalDialog;
 79 |     isolation: isolate;
 80 |     position: relative;
 81 |     display: flex;
 82 |     flex-direction: column;
 83 |     gap: t.$space-4;
 84 |   }
 85 | 
 86 |   .contentAnimation {
 87 |     animation: contentShow 150ms cubic-bezier(0.16, 1, 0.3, 1);
 88 |   }
 89 | 
 90 |   .content:focus {
 91 |     outline: none;
 92 |   }
 93 | 
 94 |   .dialogTitle {
 95 |     flex: 1;
 96 |     margin-bottom: $marginBottom-title-ModalDialog;
 97 |     font-size: t.$fontSize-2xl;
 98 |   }
 99 | 
100 |   .innerContent {
101 |     display: flex;
102 |     flex-direction: column;
103 |     min-height: 0;
104 |     gap: var(--stack-gap-default);
105 |     flex: 1;
106 |   }
107 | 
108 |   @keyframes overlayShow {
109 |     from {
110 |       opacity: 0;
111 |     }
112 |     to {
113 |       opacity: 1;
114 |     }
115 |   }
116 | 
117 |   @keyframes contentShow {
118 |     from {
119 |       opacity: 0;
120 |       transform: translateY(2%) scale(0.96);
121 |     }
122 |     to {
123 |       opacity: 1;
124 |       transform: translateY(0) scale(1);
125 |     }
126 |   }
127 | 
128 |   .closeButton {
129 |     position: absolute;
130 |     right: 0.5rem;
131 |     top: 0.4rem;
132 |   }
133 | 
134 |   @media (max-width: 70em) {
135 |     .dialog, .content {
136 |       max-width: 90%;
137 |     }
138 |   }
139 | 
140 |   @media (max-width: 50em) {
141 |     .dialog, .content {
142 |       width: 100%;
143 |       max-width: calc(100% - #{t.$space-6});
144 |       min-width: 0 !important;
145 |     }
146 |   }
147 | }
148 | 
149 | // --- We export the theme variables to add them to the component renderer
150 | :export {
151 |   themeVars: t.json-stringify($themeVars);
152 | }
153 | 
```

--------------------------------------------------------------------------------
/xmlui/tests-e2e/data-bindings.spec.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import type { ApiInterceptorDefinition } from "../src";
  2 | import { expect, test } from "../src/testing/fixtures";
  3 | 
  4 | const CustomComponent = [
  5 |   `
  6 |   <Component name="CustomComponent">
  7 |     <Text testId="dataValue">{$props.data}</Text>
  8 |   </Component>
  9 | `,
 10 | ];
 11 | const apiInterceptor: ApiInterceptorDefinition = {
 12 |   operations: {
 13 |     "load-api-data": {
 14 |       url: "/api/data",
 15 |       method: "get",
 16 |       handler: `() => { return 'STRING_DATA_FROM_API'; }`,
 17 |     },
 18 |   },
 19 | };
 20 | 
 21 | test("raw_data binds as data", async ({ page, initTestBed }) => {
 22 |   await initTestBed(`<CustomComponent raw_data="RUNNING"/>`, {
 23 |     components: CustomComponent,
 24 |   });
 25 |   await expect(page.getByTestId("dataValue")).toHaveText("RUNNING");
 26 | });
 27 | 
 28 | test("inline datasource as data", async ({ page, initTestBed }) => {
 29 |   await initTestBed(
 30 |     `
 31 |       <CustomComponent>
 32 |         <property name="data">
 33 |           <DataSource url="/api/data"/>
 34 |         </property>
 35 |       </CustomComponent>
 36 |     `,
 37 |     {
 38 |       components: CustomComponent,
 39 |       apiInterceptor: apiInterceptor,
 40 |     },
 41 |   );
 42 |   await expect(page.getByTestId("dataValue")).toHaveText("STRING_DATA_FROM_API");
 43 | });
 44 | 
 45 | test("datasource reference as data", async ({ page, initTestBed }) => {
 46 |   await initTestBed(
 47 |     `
 48 |       <Fragment>
 49 |         <DataSource url="/api/data" id="someDataSource"/>
 50 |         <CustomComponent data="{someDataSource}"/>
 51 |       </Fragment>
 52 |     `,
 53 |     {
 54 |       components: CustomComponent,
 55 |       apiInterceptor: apiInterceptor,
 56 |     },
 57 |   );
 58 |   await expect(page.getByTestId("dataValue")).toHaveText("STRING_DATA_FROM_API");
 59 | });
 60 | 
 61 | test("datasource reference as any property", async ({ page, initTestBed }) => {
 62 |   await initTestBed(
 63 |     `
 64 |       <Fragment>
 65 |         <DataSource url="/api/data" id="someDataSource"/>
 66 |         <Text testId="dataValue" value="{someDataSource}"/>
 67 |       </Fragment>
 68 |     `,
 69 |     {
 70 |       components: CustomComponent,
 71 |       apiInterceptor: apiInterceptor,
 72 |     },
 73 |   );
 74 |   await expect(page.getByTestId("dataValue")).toHaveText("STRING_DATA_FROM_API");
 75 | });
 76 | 
 77 | test("datasource reference outside of implicit container", async ({ page, initTestBed }) => {
 78 |   await initTestBed(
 79 |     `
 80 |       <Fragment>
 81 |         <DataSource url="/api/data" id="someDataSource"/>
 82 |         <Stack backgroundColor="lightgreen" var.something="something that makes it an implicit container">
 83 |           <CustomComponent data="{someDataSource}"/>
 84 |         </Stack>
 85 |       </Fragment>
 86 |     `,
 87 |     {
 88 |       components: CustomComponent,
 89 |       apiInterceptor: apiInterceptor,
 90 |     },
 91 |   );
 92 |   await expect(page.getByTestId("dataValue")).toHaveText("STRING_DATA_FROM_API");
 93 | });
 94 | 
 95 | test("datasource value as data", async ({ page, initTestBed }) => {
 96 |   await initTestBed(
 97 |     `
 98 |       <Fragment>
 99 |         <DataSource url="/api/data" id="someDataSource"/>
100 |         <CustomComponent data="{someDataSource.value}"/>
101 |       </Fragment>
102 |     `,
103 |     {
104 |       components: CustomComponent,
105 |       apiInterceptor: apiInterceptor,
106 |     },
107 |   );
108 |   await expect(page.getByTestId("dataValue")).toHaveText("STRING_DATA_FROM_API");
109 | });
110 | 
111 | test("data url", async ({ page, initTestBed }) => {
112 |   await initTestBed(`<CustomComponent data="/api/data"/>`, {
113 |     components: CustomComponent,
114 |     apiInterceptor: apiInterceptor,
115 |   });
116 |   await expect(page.getByTestId("dataValue")).toHaveText("STRING_DATA_FROM_API");
117 | });
118 | 
119 | test("data url from binding expression", async ({ page, initTestBed }) => {
120 |   await initTestBed(
121 |     `
122 |       <Fragment>
123 |         <script>
124 |           var dataUrl = "/api/data";
125 |         </script>
126 |         <CustomComponent data="{dataUrl}"/>
127 |       </Fragment>
128 |     `,
129 |     {
130 |       components: CustomComponent,
131 |       apiInterceptor: apiInterceptor,
132 |     },
133 |   );
134 |   await expect(page.getByTestId("dataValue")).toHaveText("STRING_DATA_FROM_API");
135 | });
136 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components-core/ComponentDecorator.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import type React from "react";
  2 | import {
  3 |   cloneElement,
  4 |   forwardRef,
  5 |   useCallback,
  6 |   useLayoutEffect,
  7 |   useRef,
  8 |   useState,
  9 | } from "react";
 10 | import { composeRefs } from "@radix-ui/react-compose-refs";
 11 | import { useShallowCompareMemoize } from "./utils/hooks";
 12 | 
 13 | // --- Describes the properties of the decorator component
 14 | interface DecoratorProps {
 15 |   // --- Attribute name and value pairs to add to the component's DOM node
 16 |   attr: Record<string, any>;
 17 | 
 18 |   // --- If true, only the ref'd child will have the attributes added
 19 |   allowOnlyRefdChild?: boolean;
 20 | 
 21 |   // --- Callback function to be called when the target component is mounted
 22 |   onTargetMounted?: () => void;
 23 | 
 24 |   // --- The component to decorate
 25 |   children: React.ReactElement;
 26 | }
 27 | 
 28 | const HIDDEN_STYLE: React.CSSProperties = { position: "absolute", width: 0, display: "none" };
 29 | 
 30 | /**
 31 |  * This component decorates the DOM element of a component with a set of
 32 |  * attributes. We use this feature to assign helper attributes to the app's
 33 |  * xmlui component nodes for testing, debugging, and other development-related
 34 |  * purposes.
 35 |  */
 36 | const ComponentDecorator = forwardRef((props: DecoratorProps, forwardedRef) => {
 37 |   // the concept:
 38 |   //   we want to add attributes to the component's DOM node even if that component doesn't handle refs
 39 |   //   to find the actual dom node, we use either the ref passed to the component, or the ref of the previous or next sibling
 40 |   //   with those sibling refs we can find the actual dom node (via nextElementSibling)
 41 |   //   we are making sure that the next and previous elements are not the same, to avoid adding attributes to the wrong element
 42 |   const prevSiblingRef = useRef(null);
 43 |   const nextSiblingRef = useRef(null);
 44 |   const { onTargetMounted } = props;
 45 | 
 46 |   const foundNode = useRef(null);
 47 |   const itemRef = useRef<HTMLElement | null>(null);
 48 |   const [handlesItemRefs, setHandlesItemRefs] = useState(false);
 49 |   const itemRefCallback = useCallback(
 50 |     (node: any) => {
 51 |       itemRef.current = node;
 52 |       if (node !== null) {
 53 |         onTargetMounted?.();
 54 |       }
 55 |       setHandlesItemRefs(true);
 56 |     },
 57 |     [onTargetMounted],
 58 |   );
 59 |   const [_, setForceRender] = useState(0);
 60 | 
 61 |   const shallowAttrs = useShallowCompareMemoize(props.attr);
 62 |   const shouldRenderHelperSpan = !props.allowOnlyRefdChild && !handlesItemRefs;
 63 | 
 64 |   // --- When the component mounts, we add the attributes to the component's DOM node
 65 |   useLayoutEffect(() => {
 66 |     let node;
 67 |     if (handlesItemRefs) {
 68 |       node = itemRef.current;
 69 |     } else {
 70 |       if (shouldRenderHelperSpan) {
 71 |         if (foundNode.current) {
 72 |           node = foundNode.current;
 73 |         } else {
 74 |           node =
 75 |             (prevSiblingRef.current.nextElementSibling === nextSiblingRef.current
 76 |               ? null
 77 |               : prevSiblingRef.current.nextElementSibling) || null;
 78 |           foundNode.current = node;
 79 |           setForceRender((prev) => prev++);
 80 |         }
 81 |       }
 82 |     }
 83 |     if (node) {
 84 |       Object.entries(shallowAttrs).forEach(([key, value]) => {
 85 |         if (value !== undefined) {
 86 |           node.setAttribute?.(key, value);
 87 |         } else {
 88 |           node.removeAttribute?.(key);
 89 |         }
 90 |       });
 91 |     }
 92 |   }, [shouldRenderHelperSpan, shallowAttrs, handlesItemRefs]);
 93 | 
 94 |   return (
 95 |     <>
 96 |       {!foundNode.current && shouldRenderHelperSpan && (
 97 |         <span style={HIDDEN_STYLE} ref={prevSiblingRef} />
 98 |       )}
 99 |       {cloneElement(props.children, {
100 |         ref: forwardedRef ? composeRefs(itemRefCallback, forwardedRef) : itemRefCallback,
101 |       })}
102 |       {!foundNode.current && shouldRenderHelperSpan && (
103 |         <span style={HIDDEN_STYLE} ref={nextSiblingRef} />
104 |       )}
105 |     </>
106 |   );
107 | });
108 | ComponentDecorator.displayName = "ComponentDecorator";
109 | 
110 | export default ComponentDecorator;
111 | 
```
Page 20/181FirstPrevNextLast