#
tokens: 49540/50000 23/1627 files (page 16/182)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 16 of 182. Use http://codebase.md/xmlui-org/xmlui/xmlui-standalone.umd.js?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .changeset
│   └── config.json
├── .eslintrc.cjs
├── .github
│   ├── build-checklist.png
│   ├── ISSUE_TEMPLATE
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   └── workflows
│       ├── deploy-blog.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
│   ├── layout-changes.md
│   ├── 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
│   │   ├── 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
│   │   │   ├── Headlines.xmlui
│   │   │   └── PageNotFound.xmlui
│   │   ├── config.ts
│   │   ├── Main.xmlui
│   │   └── themes
│   │       └── blog-theme.ts
│   └── tsconfig.json
├── CONTRIBUTING.md
├── docs
│   ├── .gitignore
│   ├── CHANGELOG.md
│   ├── ComponentRefLinks.txt
│   ├── content
│   │   ├── _meta.json
│   │   ├── components
│   │   │   ├── _meta.json
│   │   │   ├── _overview.md
│   │   │   ├── APICall.md
│   │   │   ├── App.md
│   │   │   ├── AppHeader.md
│   │   │   ├── AppState.md
│   │   │   ├── AutoComplete.md
│   │   │   ├── Avatar.md
│   │   │   ├── Backdrop.md
│   │   │   ├── Badge.md
│   │   │   ├── BarChart.md
│   │   │   ├── Bookmark.md
│   │   │   ├── Breakout.md
│   │   │   ├── Button.md
│   │   │   ├── Card.md
│   │   │   ├── Carousel.md
│   │   │   ├── ChangeListener.md
│   │   │   ├── Checkbox.md
│   │   │   ├── CHStack.md
│   │   │   ├── ColorPicker.md
│   │   │   ├── Column.md
│   │   │   ├── ContentSeparator.md
│   │   │   ├── CVStack.md
│   │   │   ├── DataSource.md
│   │   │   ├── DateInput.md
│   │   │   ├── DatePicker.md
│   │   │   ├── DonutChart.md
│   │   │   ├── DropdownMenu.md
│   │   │   ├── EmojiSelector.md
│   │   │   ├── ExpandableItem.md
│   │   │   ├── FileInput.md
│   │   │   ├── FileUploadDropZone.md
│   │   │   ├── FlowLayout.md
│   │   │   ├── Footer.md
│   │   │   ├── Form.md
│   │   │   ├── FormItem.md
│   │   │   ├── FormSection.md
│   │   │   ├── Fragment.md
│   │   │   ├── H1.md
│   │   │   ├── H2.md
│   │   │   ├── H3.md
│   │   │   ├── H4.md
│   │   │   ├── H5.md
│   │   │   ├── H6.md
│   │   │   ├── Heading.md
│   │   │   ├── HSplitter.md
│   │   │   ├── HStack.md
│   │   │   ├── Icon.md
│   │   │   ├── IFrame.md
│   │   │   ├── Image.md
│   │   │   ├── Items.md
│   │   │   ├── LabelList.md
│   │   │   ├── Legend.md
│   │   │   ├── LineChart.md
│   │   │   ├── Link.md
│   │   │   ├── List.md
│   │   │   ├── Logo.md
│   │   │   ├── Markdown.md
│   │   │   ├── MenuItem.md
│   │   │   ├── MenuSeparator.md
│   │   │   ├── ModalDialog.md
│   │   │   ├── NavGroup.md
│   │   │   ├── NavLink.md
│   │   │   ├── NavPanel.md
│   │   │   ├── NoResult.md
│   │   │   ├── NumberBox.md
│   │   │   ├── Option.md
│   │   │   ├── Page.md
│   │   │   ├── PageMetaTitle.md
│   │   │   ├── Pages.md
│   │   │   ├── Pagination.md
│   │   │   ├── PasswordInput.md
│   │   │   ├── PieChart.md
│   │   │   ├── ProgressBar.md
│   │   │   ├── Queue.md
│   │   │   ├── RadioGroup.md
│   │   │   ├── RealTimeAdapter.md
│   │   │   ├── Redirect.md
│   │   │   ├── Select.md
│   │   │   ├── Slider.md
│   │   │   ├── Slot.md
│   │   │   ├── SpaceFiller.md
│   │   │   ├── Spinner.md
│   │   │   ├── Splitter.md
│   │   │   ├── Stack.md
│   │   │   ├── StickyBox.md
│   │   │   ├── SubMenuItem.md
│   │   │   ├── Switch.md
│   │   │   ├── TabItem.md
│   │   │   ├── Table.md
│   │   │   ├── TableOfContents.md
│   │   │   ├── Tabs.md
│   │   │   ├── Text.md
│   │   │   ├── TextArea.md
│   │   │   ├── TextBox.md
│   │   │   ├── Theme.md
│   │   │   ├── TimeInput.md
│   │   │   ├── Timer.md
│   │   │   ├── ToneChangerButton.md
│   │   │   ├── ToneSwitch.md
│   │   │   ├── Tooltip.md
│   │   │   ├── Tree.md
│   │   │   ├── VSplitter.md
│   │   │   ├── VStack.md
│   │   │   ├── xmlui-animations
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   ├── Animation.md
│   │   │   │   ├── FadeAnimation.md
│   │   │   │   ├── FadeInAnimation.md
│   │   │   │   ├── FadeOutAnimation.md
│   │   │   │   ├── ScaleAnimation.md
│   │   │   │   └── SlideInAnimation.md
│   │   │   ├── xmlui-pdf
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   └── Pdf.md
│   │   │   ├── xmlui-spreadsheet
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   └── Spreadsheet.md
│   │   │   └── xmlui-website-blocks
│   │   │       ├── _meta.json
│   │   │       ├── _overview.md
│   │   │       ├── Carousel.md
│   │   │       ├── HelloMd.md
│   │   │       ├── HeroSection.md
│   │   │       └── ScrollToTop.md
│   │   └── extensions
│   │       ├── _meta.json
│   │       ├── xmlui-animations
│   │       │   ├── _meta.json
│   │       │   ├── _overview.md
│   │       │   ├── Animation.md
│   │       │   ├── FadeAnimation.md
│   │       │   ├── FadeInAnimation.md
│   │       │   ├── FadeOutAnimation.md
│   │       │   ├── ScaleAnimation.md
│   │       │   └── SlideInAnimation.md
│   │       └── xmlui-website-blocks
│   │           ├── _meta.json
│   │           ├── _overview.md
│   │           ├── Carousel.md
│   │           ├── 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
│   │   │   │   ├── make-navpanel-width-responsive.md
│   │   │   │   ├── modify-a-value-reported-in-a-column.md
│   │   │   │   ├── paginate-a-list.md
│   │   │   │   ├── pass-data-to-a-modal-dialog.md
│   │   │   │   ├── react-to-button-click-not-keystrokes.md
│   │   │   │   ├── set-the-initial-value-of-a-select-from-fetched-data.md
│   │   │   │   ├── share-a-modaldialog-across-components.md
│   │   │   │   ├── sync-selections-between-table-and-list-views.md
│   │   │   │   ├── update-ui-optimistically.md
│   │   │   │   ├── use-built-in-form-validation.md
│   │   │   │   └── use-the-same-modaldialog-to-add-or-edit.md
│   │   │   ├── howto.md
│   │   │   ├── intro.md
│   │   │   ├── layout.md
│   │   │   ├── markup.md
│   │   │   ├── mcp.md
│   │   │   ├── modal-dialogs.md
│   │   │   ├── news-and-reviews.md
│   │   │   ├── reactive-intro.md
│   │   │   ├── refactoring.md
│   │   │   ├── routing-and-links.md
│   │   │   ├── samples
│   │   │   │   ├── color-palette.xmlui
│   │   │   │   ├── color-values.xmlui
│   │   │   │   ├── shadow-sizes.xmlui
│   │   │   │   ├── spacing-sizes.xmlui
│   │   │   │   ├── swatch.xmlui
│   │   │   │   ├── theme-gallery-brief.xmlui
│   │   │   │   └── theme-gallery.xmlui
│   │   │   ├── scoping.md
│   │   │   ├── scripting.md
│   │   │   ├── styles-and-themes
│   │   │   │   ├── common-units.md
│   │   │   │   ├── layout-props.md
│   │   │   │   ├── theme-variable-defaults.md
│   │   │   │   ├── theme-variables.md
│   │   │   │   └── themes.md
│   │   │   ├── template-properties.md
│   │   │   ├── test.md
│   │   │   ├── tutorial-01.md
│   │   │   ├── tutorial-02.md
│   │   │   ├── tutorial-03.md
│   │   │   ├── tutorial-04.md
│   │   │   ├── tutorial-05.md
│   │   │   ├── tutorial-06.md
│   │   │   ├── tutorial-07.md
│   │   │   ├── tutorial-08.md
│   │   │   ├── tutorial-09.md
│   │   │   ├── tutorial-10.md
│   │   │   ├── tutorial-11.md
│   │   │   ├── tutorial-12.md
│   │   │   ├── universal-properties.md
│   │   │   ├── user-defined-components.md
│   │   │   ├── vscode.md
│   │   │   ├── working-with-markdown.md
│   │   │   ├── working-with-text.md
│   │   │   ├── xmlui-animations
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   ├── Animation.md
│   │   │   │   ├── FadeAnimation.md
│   │   │   │   ├── FadeInAnimation.md
│   │   │   │   ├── FadeOutAnimation.md
│   │   │   │   ├── ScaleAnimation.md
│   │   │   │   └── SlideInAnimation.md
│   │   │   ├── xmlui-charts
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   ├── BarChart.md
│   │   │   │   ├── DonutChart.md
│   │   │   │   ├── LabelList.md
│   │   │   │   ├── Legend.md
│   │   │   │   ├── LineChart.md
│   │   │   │   └── PieChart.md
│   │   │   ├── xmlui-pdf
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   └── Pdf.md
│   │   │   └── xmlui-spreadsheet
│   │   │       ├── _meta.json
│   │   │       ├── _overview.md
│   │   │       └── Spreadsheet.md
│   │   ├── resources
│   │   │   ├── devdocs
│   │   │   │   ├── debug-proxy-object-2.png
│   │   │   │   ├── debug-proxy-object.png
│   │   │   │   ├── table_editor_01.png
│   │   │   │   ├── table_editor_02.png
│   │   │   │   ├── table_editor_03.png
│   │   │   │   ├── table_editor_04.png
│   │   │   │   ├── table_editor_05.png
│   │   │   │   ├── table_editor_06.png
│   │   │   │   ├── table_editor_07.png
│   │   │   │   ├── table_editor_08.png
│   │   │   │   ├── table_editor_09.png
│   │   │   │   ├── table_editor_10.png
│   │   │   │   ├── table_editor_11.png
│   │   │   │   ├── table-editor-01.png
│   │   │   │   ├── table-editor-02.png
│   │   │   │   ├── table-editor-03.png
│   │   │   │   ├── table-editor-04.png
│   │   │   │   ├── table-editor-06.png
│   │   │   │   ├── table-editor-07.png
│   │   │   │   ├── table-editor-08.png
│   │   │   │   ├── table-editor-09.png
│   │   │   │   └── xmlui-rendering-of-tiptap-markdown.png
│   │   │   ├── favicon.ico
│   │   │   ├── files
│   │   │   │   ├── clients.json
│   │   │   │   ├── daily-revenue.json
│   │   │   │   ├── dashboard-stats.json
│   │   │   │   ├── demo.xmlui
│   │   │   │   ├── demo.xmlui.xs
│   │   │   │   ├── downloads
│   │   │   │   │   └── downloads.json
│   │   │   │   ├── for-download
│   │   │   │   │   ├── index-with-api.html
│   │   │   │   │   ├── index.html
│   │   │   │   │   ├── mockApi.js
│   │   │   │   │   ├── start-darwin.sh
│   │   │   │   │   ├── start-linux.sh
│   │   │   │   │   ├── start.bat
│   │   │   │   │   └── xmlui
│   │   │   │   │       └── xmlui-standalone.umd.js
│   │   │   │   ├── getting-started
│   │   │   │   │   ├── cl-tutorial-final.zip
│   │   │   │   │   ├── cl-tutorial.zip
│   │   │   │   │   ├── cl-tutorial2.zip
│   │   │   │   │   ├── cl-tutorial3.zip
│   │   │   │   │   ├── cl-tutorial4.zip
│   │   │   │   │   ├── cl-tutorial5.zip
│   │   │   │   │   ├── cl-tutorial6.zip
│   │   │   │   │   ├── getting-started.zip
│   │   │   │   │   ├── hello-xmlui.zip
│   │   │   │   │   ├── xmlui-empty.zip
│   │   │   │   │   └── xmlui-starter.zip
│   │   │   │   ├── howto
│   │   │   │   │   └── component-icons
│   │   │   │   │       └── up-arrow.svg
│   │   │   │   ├── invoices.json
│   │   │   │   ├── monthly-status.json
│   │   │   │   ├── news-and-reviews.json
│   │   │   │   ├── products.json
│   │   │   │   ├── releases.json
│   │   │   │   ├── tutorials
│   │   │   │   │   ├── datasource
│   │   │   │   │   │   └── api.ts
│   │   │   │   │   └── p2do
│   │   │   │   │       ├── api.ts
│   │   │   │   │       └── todo-logo.svg
│   │   │   │   └── xmlui.json
│   │   │   ├── github.svg
│   │   │   ├── images
│   │   │   │   ├── apiaction-tutorial
│   │   │   │   │   ├── add-success.png
│   │   │   │   │   ├── apiaction-param.png
│   │   │   │   │   ├── change-completed.png
│   │   │   │   │   ├── change-in-progress.png
│   │   │   │   │   ├── confirm-delete.png
│   │   │   │   │   ├── data-error.png
│   │   │   │   │   ├── data-progress.png
│   │   │   │   │   ├── data-success.png
│   │   │   │   │   ├── display-1.png
│   │   │   │   │   ├── item-deleted.png
│   │   │   │   │   ├── item-updated.png
│   │   │   │   │   ├── missing-api-key.png
│   │   │   │   │   ├── new-item-added.png
│   │   │   │   │   └── test-message.png
│   │   │   │   ├── chat-api
│   │   │   │   │   └── domain-model.svg
│   │   │   │   ├── components
│   │   │   │   │   ├── image
│   │   │   │   │   │   └── breakfast.jpg
│   │   │   │   │   ├── markdown
│   │   │   │   │   │   └── colors.png
│   │   │   │   │   └── modal
│   │   │   │   │       ├── deep_link_dialog_1.jpg
│   │   │   │   │       └── deep_link_dialog_2.jpg
│   │   │   │   ├── create-apps
│   │   │   │   │   ├── collapsed-vertical.png
│   │   │   │   │   ├── using-forms-warning-dialog.png
│   │   │   │   │   └── using-forms.png
│   │   │   │   ├── datasource-tutorial
│   │   │   │   │   ├── data-with-header.png
│   │   │   │   │   ├── filtered-data.png
│   │   │   │   │   ├── filtered-items.png
│   │   │   │   │   ├── initial-page-items.png
│   │   │   │   │   ├── list-items.png
│   │   │   │   │   ├── next-page-items.png
│   │   │   │   │   ├── no-data.png
│   │   │   │   │   ├── pagination-1.jpg
│   │   │   │   │   ├── pagination-1.png
│   │   │   │   │   ├── polling-1.png
│   │   │   │   │   ├── refetch-data.png
│   │   │   │   │   ├── slow-loading.png
│   │   │   │   │   ├── test-message.png
│   │   │   │   │   ├── Thumbs.db
│   │   │   │   │   ├── unconventional-data.png
│   │   │   │   │   └── unfiltered-items.png
│   │   │   │   ├── flower.jpg
│   │   │   │   ├── get-started
│   │   │   │   │   ├── add-new-contact.png
│   │   │   │   │   ├── app-modified.png
│   │   │   │   │   ├── app-start.png
│   │   │   │   │   ├── app-with-boxes.png
│   │   │   │   │   ├── app-with-toast.png
│   │   │   │   │   ├── boilerplate-structure.png
│   │   │   │   │   ├── cl-initial.png
│   │   │   │   │   ├── cl-start.png
│   │   │   │   │   ├── contact-counts.png
│   │   │   │   │   ├── contact-dialog-title.png
│   │   │   │   │   ├── contact-dialog.png
│   │   │   │   │   ├── contact-menus.png
│   │   │   │   │   ├── contact-predicates.png
│   │   │   │   │   ├── context-menu.png
│   │   │   │   │   ├── dashboard-numbers.png
│   │   │   │   │   ├── default-contact-list.png
│   │   │   │   │   ├── delete-contact.png
│   │   │   │   │   ├── delete-task.png
│   │   │   │   │   ├── detailed-template.png
│   │   │   │   │   ├── edit-contact-details.png
│   │   │   │   │   ├── edited-contact-saved.png
│   │   │   │   │   ├── empty-sections.png
│   │   │   │   │   ├── filter-completed.png
│   │   │   │   │   ├── fullwidth-desktop.png
│   │   │   │   │   ├── fullwidth-mobile.png
│   │   │   │   │   ├── initial-table.png
│   │   │   │   │   ├── items-and-badges.png
│   │   │   │   │   ├── loading-message.png
│   │   │   │   │   ├── new-contact-button.png
│   │   │   │   │   ├── new-contact-saved.png
│   │   │   │   │   ├── no-empty-sections.png
│   │   │   │   │   ├── personal-todo-initial.png
│   │   │   │   │   ├── piechart.png
│   │   │   │   │   ├── review-today.png
│   │   │   │   │   ├── rudimentary-dashboard.png
│   │   │   │   │   ├── section-collapsed.png
│   │   │   │   │   ├── sectioned-items.png
│   │   │   │   │   ├── sections-ordered.png
│   │   │   │   │   ├── spacex-list-with-links.png
│   │   │   │   │   ├── spacex-list.png
│   │   │   │   │   ├── start-personal-todo-1.png
│   │   │   │   │   ├── submit-new-contact.png
│   │   │   │   │   ├── submit-new-task.png
│   │   │   │   │   ├── syntax-highlighting.png
│   │   │   │   │   ├── table-with-badge.png
│   │   │   │   │   ├── template-with-card.png
│   │   │   │   │   ├── test-emulated-api.png
│   │   │   │   │   ├── Thumbs.db
│   │   │   │   │   ├── todo-logo.png
│   │   │   │   │   └── xmlui-tools.png
│   │   │   │   ├── HelloApp.png
│   │   │   │   ├── HelloApp2.png
│   │   │   │   ├── logos
│   │   │   │   │   ├── xmlui1.svg
│   │   │   │   │   ├── xmlui2.svg
│   │   │   │   │   ├── xmlui3.svg
│   │   │   │   │   ├── xmlui4.svg
│   │   │   │   │   ├── xmlui5.svg
│   │   │   │   │   ├── xmlui6.svg
│   │   │   │   │   └── xmlui7.svg
│   │   │   │   ├── pdf
│   │   │   │   │   └── dummy-pdf.jpg
│   │   │   │   ├── rendering-engine
│   │   │   │   │   ├── AppEngine-flow.svg
│   │   │   │   │   ├── Component.svg
│   │   │   │   │   ├── CompoundComponent.svg
│   │   │   │   │   ├── RootComponent.svg
│   │   │   │   │   └── tree-with-containers.svg
│   │   │   │   ├── reviewers-guide
│   │   │   │   │   ├── AppEngine-flow.svg
│   │   │   │   │   └── incbutton-in-action.png
│   │   │   │   ├── tools
│   │   │   │   │   └── boilerplate-structure.png
│   │   │   │   ├── try.svg
│   │   │   │   ├── tutorial
│   │   │   │   │   ├── app-chat-history.png
│   │   │   │   │   ├── app-content-placeholder.png
│   │   │   │   │   ├── app-header-and-content.png
│   │   │   │   │   ├── app-links-channel-selected.png
│   │   │   │   │   ├── app-links-click.png
│   │   │   │   │   ├── app-navigation.png
│   │   │   │   │   ├── finished-ex01.png
│   │   │   │   │   ├── finished-ex02.png
│   │   │   │   │   ├── hello.png
│   │   │   │   │   ├── splash-screen-advanced.png
│   │   │   │   │   ├── splash-screen-after-click.png
│   │   │   │   │   ├── splash-screen-centered.png
│   │   │   │   │   ├── splash-screen-events.png
│   │   │   │   │   ├── splash-screen-expression.png
│   │   │   │   │   ├── splash-screen-reuse-after.png
│   │   │   │   │   ├── splash-screen-reuse-before.png
│   │   │   │   │   └── splash-screen.png
│   │   │   │   └── tutorial-01.png
│   │   │   ├── llms.txt
│   │   │   ├── logo-dark.svg
│   │   │   ├── logo.svg
│   │   │   ├── pg-popout.svg
│   │   │   └── xmlui-logo.svg
│   │   ├── serve.json
│   │   └── web.config
│   ├── scripts
│   │   ├── download-latest-xmlui.js
│   │   ├── generate-rss.js
│   │   ├── get-releases.js
│   │   └── utils.js
│   ├── src
│   │   ├── components
│   │   │   ├── BlogOverview.xmlui
│   │   │   ├── BlogPage.xmlui
│   │   │   ├── Boxes.xmlui
│   │   │   ├── Breadcrumb.xmlui
│   │   │   ├── ChangeLog.xmlui
│   │   │   ├── ColorPalette.xmlui
│   │   │   ├── DocumentLinks.xmlui
│   │   │   ├── DocumentPage.xmlui
│   │   │   ├── DocumentPageNoTOC.xmlui
│   │   │   ├── Icons.xmlui
│   │   │   ├── IncButton.xmlui
│   │   │   ├── IncButton2.xmlui
│   │   │   ├── NameValue.xmlui
│   │   │   ├── PageNotFound.xmlui
│   │   │   ├── PaletteItem.xmlui
│   │   │   ├── Palettes.xmlui
│   │   │   ├── SectionHeader.xmlui
│   │   │   ├── TBD.xmlui
│   │   │   ├── Test.xmlui
│   │   │   ├── ThemesIntro.xmlui
│   │   │   ├── ThousandThemes.xmlui
│   │   │   ├── TubeStops.xmlui
│   │   │   ├── TubeStops.xmlui.xs
│   │   │   └── TwoColumnCode.xmlui
│   │   ├── config.ts
│   │   ├── Main.xmlui
│   │   └── themes
│   │       ├── docs-theme.ts
│   │       ├── earthtone.ts
│   │       ├── xmlui-gray-on-default.ts
│   │       ├── xmlui-green-on-default.ts
│   │       └── xmlui-orange-on-default.ts
│   └── tsconfig.json
├── LICENSE
├── package-lock.json
├── package.json
├── packages
│   ├── 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
    │   ├── ud-components.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
    │   │   │   ├── base64-utils.ts
    │   │   │   ├── compound-utils.ts
    │   │   │   ├── css-utils.ts
    │   │   │   ├── DataLoaderQueryKeyGenerator.ts
    │   │   │   ├── date-utils.ts
    │   │   │   ├── extractParam.ts
    │   │   │   ├── hooks.tsx
    │   │   │   ├── LruCache.ts
    │   │   │   ├── mergeProps.ts
    │   │   │   ├── misc.ts
    │   │   │   ├── request-params.ts
    │   │   │   ├── statementUtils.ts
    │   │   │   └── treeUtils.ts
    │   │   └── xmlui-parser.ts
    │   ├── index-standalone.ts
    │   ├── index.scss
    │   ├── index.ts
    │   ├── language-server
    │   │   ├── server-common.ts
    │   │   ├── server-web-worker.ts
    │   │   ├── server.ts
    │   │   ├── services
    │   │   │   ├── common
    │   │   │   │   ├── docs-generation.ts
    │   │   │   │   ├── lsp-utils.ts
    │   │   │   │   ├── metadata-utils.ts
    │   │   │   │   └── syntax-node-utilities.ts
    │   │   │   ├── completion.ts
    │   │   │   ├── diagnostic.ts
    │   │   │   ├── format.ts
    │   │   │   └── hover.ts
    │   │   └── xmlui-metadata-generated.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/Heading/H6.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { test, expect } from "../../testing/fixtures";
 2 | 
 3 | // =============================================================================
 4 | // BASIC FUNCTIONALITY TESTS
 5 | // =============================================================================
 6 | 
 7 | test.describe("Basic Functionality", () => {
 8 |   test("renders as h6 level heading", async ({ initTestBed, createHeadingDriver }) => {
 9 |     await initTestBed(`<H6 testId="h6">Test Heading</H6>`);
10 | 
11 |     const driver = await createHeadingDriver("h6");
12 |     
13 |     await expect(driver.component).toBeVisible();
14 |     await expect(driver.component).toContainText("Test Heading");
15 |     await expect(driver.component).toHaveRole("heading");
16 |     
17 |     // Verify it renders as h6 HTML element
18 |     const tagName = await driver.getComponentTagName();
19 |     expect(tagName.toLowerCase()).toBe("h6");
20 |   });
21 | 
22 |   test("renders with value property", async ({ initTestBed, createHeadingDriver }) => {
23 |     await initTestBed(`<H6 testId="h6" value="Value Property Text" />`);
24 | 
25 |     const driver = await createHeadingDriver("h6");
26 |     
27 |     await expect(driver.component).toBeVisible();
28 |     await expect(driver.component).toContainText("Value Property Text");
29 |     await expect(driver.component).toHaveRole("heading");
30 |     
31 |     // Verify it renders as h6 HTML element
32 |     const tagName = await driver.getComponentTagName();
33 |     expect(tagName.toLowerCase()).toBe("h6");
34 |   });
35 | 
36 |   test("is equivalent to Heading with level='h6'", async ({ initTestBed, createHeadingDriver }) => {
37 |     await initTestBed(`
38 |       <Fragment>
39 |         <Heading testId="heading" level="h6">Heading Content</Heading>
40 |         <H6 testId="h6">H6 Content</H6>
41 |       </Fragment>
42 |     `);
43 | 
44 |     const headingDriver = await createHeadingDriver("heading");
45 |     const h6Driver = await createHeadingDriver("h6");
46 |     
47 |     // Both should render as h6 elements
48 |     const headingTagName = await headingDriver.getComponentTagName();
49 |     const h6TagName = await h6Driver.getComponentTagName();
50 |     
51 |     expect(headingTagName.toLowerCase()).toBe("h6");
52 |     expect(h6TagName.toLowerCase()).toBe("h6");
53 |     expect(headingTagName).toEqual(h6TagName);
54 |     
55 |     // Both should have heading role
56 |     await expect(headingDriver.component).toHaveRole("heading");
57 |     await expect(h6Driver.component).toHaveRole("heading");
58 |   });
59 | 
60 |   test("ignores level property when provided", async ({ initTestBed, createHeadingDriver }) => {
61 |     await initTestBed(`<H6 testId="h6" level="h1">Should be H6</H6>`);
62 | 
63 |     const driver = await createHeadingDriver("h6");
64 |     
65 |     await expect(driver.component).toBeVisible();
66 |     await expect(driver.component).toContainText("Should be H6");
67 |     await expect(driver.component).toHaveRole("heading");
68 |     
69 |     // Should always be h6 despite level="h1" prop (this is the expected behavior)
70 |     const tagName = await driver.getComponentTagName();
71 |     expect(tagName.toLowerCase()).toBe("h6");
72 |   });
73 | });
74 | 
```

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

```typescript
 1 | import { InspectorDialog } from "./devtools/InspectorDialog";
 2 | import AppWithCodeViewNative from "../components/NestedApp/AppWithCodeViewNative";
 3 | import React, { useMemo } from "react";
 4 | import { useDevTools } from "./InspectorContext";
 5 | import { Tooltip } from "../components/NestedApp/Tooltip";
 6 | import styles from "../components/NestedApp/NestedApp.module.scss";
 7 | import { AiOutlineClose } from "react-icons/ai";
 8 | import { useAppContext } from "./AppContext";
 9 | 
10 | export const ComponentViewer = () => {
11 |   const { mockApi, setIsOpen, isOpen, inspectedNode, clickPosition, projectCompilation, sources } =
12 |     useDevTools();
13 | 
14 |   const { appGlobals } = useAppContext();
15 | 
16 |   const components = useMemo<string[]>(() => {
17 |     if (!projectCompilation) {
18 |       return [];
19 |     }
20 |     return projectCompilation.components.map((component) => {
21 |       return component.markupSource;
22 |     });
23 |   }, [projectCompilation]);
24 | 
25 |   const value = useMemo(() => {
26 |     const compSrc = inspectedNode?.debug?.source;
27 | 
28 |     if (!compSrc) {
29 |       return "";
30 |     }
31 |     if (!sources) {
32 |       return "";
33 |     }
34 |     const { start, end, fileId } = compSrc;
35 |     const slicedSrc = sources[fileId].slice(start, end);
36 | 
37 |     let dropEmptyLines = true;
38 |     const prunedLines: Array<string> = [];
39 |     let trimBeginCount: number | undefined = undefined;
40 |     slicedSrc.split("\n").forEach((line) => {
41 |       if (line.trim() === "" && dropEmptyLines) {
42 |         //drop empty lines from the beginning
43 |         return;
44 |       } else {
45 |         dropEmptyLines = false;
46 |         prunedLines.push(line);
47 |         const startingWhiteSpaces = line.search(/\S|$/);
48 |         if (
49 |           line.trim() !== "" &&
50 |           (trimBeginCount === undefined || startingWhiteSpaces < trimBeginCount)
51 |         ) {
52 |           trimBeginCount = startingWhiteSpaces;
53 |         }
54 |       }
55 |     });
56 |     return prunedLines
57 |       .map((line) => line.slice(trimBeginCount).replace(/inspect="true"/g, ""))
58 |       .join("\n");
59 |   }, [inspectedNode, sources]);
60 | 
61 |   return process.env.VITE_USER_COMPONENTS_Inspect !== "false" &&
62 |     isOpen &&
63 |     inspectedNode !== null ? (
64 |     <InspectorDialog isOpen={isOpen} setIsOpen={setIsOpen} clickPosition={clickPosition}>
65 |       <AppWithCodeViewNative
66 |         height={"500px"}
67 |         allowPlaygroundPopup
68 |         initiallyShowCode={appGlobals?.initiallyShowCode ?? true}
69 |         splitView={true}
70 |         controlsWidth={"120px"}
71 |         closeButton={
72 |           <Tooltip
73 |             trigger={
74 |               <button
75 |                 className={styles.headerButton}
76 |                 onClick={() => {
77 |                   setIsOpen(false);
78 |                 }}
79 |               >
80 |                 <AiOutlineClose />
81 |               </button>
82 |             }
83 |             label="Close"
84 |           />
85 |         }
86 |         markdown={`\`\`\`xmlui
87 | ${value}
88 | \`\`\``}
89 |         api={mockApi}
90 |         app={value}
91 |         components={components}
92 |       />
93 |     </InspectorDialog>
94 |   ) : null;
95 | };
96 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components-core/devtools/InspectorDialog.module.scss:
--------------------------------------------------------------------------------

```scss
  1 | @use "xmlui/themes.scss" 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 | 
 25 | .overlay {
 26 |   position: fixed;
 27 |   overflow-y: auto;
 28 |   display: flex;
 29 |   align-items: center;
 30 |   justify-content: center;
 31 |   inset: 0;
 32 |   background-color: $backgroundColor-overlay-ModalDialog;
 33 |   padding: t.$space-4;
 34 | }
 35 | 
 36 | .overlayBg {
 37 |   background-color: $backgroundColor-overlay-ModalDialog;
 38 |   position: fixed;
 39 |   inset: 0;
 40 | }
 41 | 
 42 | .contentWrapper {
 43 |   display: flex;
 44 |   justify-content: center;
 45 |   align-items: center;
 46 |   width: 100%;
 47 |   height: 100%;
 48 | }
 49 | 
 50 | .content {
 51 |   border-radius: $borderRadius-ModalDialog;
 52 |   font-family: $fontFamily-ModalDialog;
 53 |   color: $textColor-ModalDialog;
 54 |   width: 90vw;
 55 |   max-width: 960px;
 56 |   min-width: 240px;
 57 |   isolation: isolate;
 58 |   position: relative;
 59 |   display: flex;
 60 |   flex-direction: column;
 61 |   max-height: 80vh;
 62 |   overflow-y: auto;
 63 | }
 64 | 
 65 | .content:focus {
 66 |   outline: none;
 67 | }
 68 | 
 69 | .dialogTitle {
 70 |   flex: 1;
 71 |   margin-bottom: $marginBottom-title-ModalDialog;
 72 |   font-size: t.$fontSize-2xl;
 73 | }
 74 | 
 75 | .innerContent {
 76 |   display: flex;
 77 |   flex-direction: column;
 78 |   min-height: 0;
 79 |   gap: var(--stack-gap-default);
 80 |   flex: 1;
 81 | }
 82 | 
 83 | .closeButton {
 84 |   position: absolute;
 85 |   right: 0.5rem;
 86 |   top: 0.4rem;
 87 | }
 88 | 
 89 | .actions {
 90 |   display: inline-flex;
 91 |   align-items: center;
 92 |   justify-content: flex-end;
 93 | }
 94 | 
 95 | .header {
 96 |   padding: t.$space-2;
 97 |   justify-content: space-between;
 98 |   display: flex;
 99 |   flex-direction: row;
100 |   border-bottom: 1px solid t.$borderColor;
101 | }
102 | 
103 | @media (max-width: 70em) {
104 |   .dialog, .content {
105 |     max-width: 90%;
106 |   }
107 | }
108 | 
109 | @media (max-width: 50em) {
110 |   .dialog, .content {
111 |     width: 100%;
112 |     max-width: calc(100% - #{t.$space-6});
113 |     min-width: 0 !important;
114 |   }
115 | }
116 | 
117 | // --- We export the theme variables to add them to the component renderer
118 | :export {
119 |   themeVars: t.json-stringify($themeVars);
120 | }
121 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components-core/action/FileDownloadAction.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import type { ComponentDef } from "../../abstractions/ComponentDefs";
 2 | import type { ActionExecutionContext } from "../../abstractions/ActionDefs";
 3 | import type { ApiActionOptions, DownloadOperationDef } from "../RestApiProxy";
 4 | import RestApiProxy from "../RestApiProxy";
 5 | 
 6 | import { createAction } from "./actions";
 7 | 
 8 | export interface DownloadActionComponent extends ComponentDef {
 9 |   props: DownloadOperationDef;
10 | }
11 | 
12 | async function download(
13 |   { state, appContext }: ActionExecutionContext,
14 |   {
15 |     params,
16 |     url,
17 |     queryParams,
18 |     method,
19 |     rawBody,
20 |     body,
21 |     fileName,
22 |     headers,
23 |   }: {
24 |     params: any;
25 |   } & DownloadOperationDef,
26 |   { resolveBindingExpressions }: ApiActionOptions = {}
27 | ) {
28 |   const context = { ...params, ...state };
29 |   const operation: DownloadOperationDef = {
30 |     url,
31 |     queryParams,
32 |     method,
33 |     rawBody,
34 |     body,
35 |     fileName,
36 |     headers,
37 |   };
38 | 
39 |   const api = new RestApiProxy(appContext);
40 |   const _url = api.resolveUrl({ operation, params: context, resolveBindingExpressions });
41 | 
42 |   if (
43 |     (operation.method && (operation.method as string).toLowerCase() !== "get") ||
44 |     Object.keys(appContext.appGlobals?.headers || {}).length !== 0 || //if we have any headers for the api, we can't use the iframe trick
45 |     appContext.apiInterceptorContext.isMocked(_url) //if we mock this url, the mock can't work in an iframe, so we must fall back to download it with the restApiProxy
46 |   ) {
47 |     const file: File = await api.execute({
48 |       operation,
49 |       params: context,
50 |       parseOptions: {
51 |         asFile: true,
52 |       },
53 |       resolveBindingExpressions,
54 |     });
55 |     downloadWithAnchor(file);
56 |   } else {
57 |     downloadInIframe(_url);
58 |   }
59 | }
60 | 
61 | //we use a hidden iframe trick here,
62 | // we set the iframe source as the download url, this way the browser will ask to download the file, and show a progress bar
63 | // (we could use an anchor tag with a download attribute, but in this case we can't show progress )
64 | // we can use it if we don't have to add extra headers to the request in order to download a file (pre-signed urls, or public urls)
65 | function downloadInIframe(fileUrl: string) {
66 |   const iframe = document.createElement("iframe");
67 |   iframe.style.display = "none";
68 |   iframe.hidden = true;
69 |   iframe.name = fileUrl;
70 |   iframe.id = `download-iframe_${fileUrl}`;
71 |   iframe.src = fileUrl;
72 |   document.body.appendChild(iframe);
73 |   setTimeout(() => {
74 |     iframe.remove();
75 |   }, 20000);
76 | }
77 | 
78 | // we can use it if we do have to add extra headers to the request in order to download a file (urls require authentication)
79 | function downloadWithAnchor(file: File) {
80 |   const url = window.URL.createObjectURL(file);
81 |   const a = document.createElement("a");
82 |   a.style.display = "none";
83 |   a.href = url;
84 |   // the filename you want
85 |   a.download = file.name;
86 |   document.body.appendChild(a);
87 |   a.click();
88 |   window.URL.revokeObjectURL(url);
89 | }
90 | 
91 | export const downloadAction = createAction("download", download);
92 | 
```

--------------------------------------------------------------------------------
/xmlui/scripts/inline-links.mjs:
--------------------------------------------------------------------------------

```
 1 | import * as fs from "fs";
 2 | import * as path from "path";
 3 | 
 4 | const includedFileExtensions = [".mdx", ".md"];
 5 | 
 6 | // Read the file contents
 7 | const fileContent = fs.readFileSync("../docs/meta/pages.js", "utf-8");
 8 | 
 9 | // Match lines like: export const NAME = "value";
10 | const regex = /export const (\w+)\s*=\s*["'`](.*?)["'`];/g;
11 | 
12 | const constants = {};
13 | let match;
14 | while ((match = regex.exec(fileContent)) !== null) {
15 |   const [, key, value] = match;
16 |   constants[key] = value;
17 | }
18 | 
19 | inlineLinks("../docs/pages");
20 | 
21 | function inlineLinks(pagesFolder) {
22 |   traverseDirectory({ name: "", path: pagesFolder }, (item, _) => {
23 |     /**
24 |      * name: the folder's/file's name (eg. "hello-app-engine")
25 |      * path: the path to the root of the given folder from the project root (eg. "src/apps/1_basic/samples/hello-app-engine")
26 |      * parent: parent node
27 |      * children: children file/folder names
28 |      */
29 |     if (fs.statSync(item.path).isDirectory()) {
30 |       // Node is a folder
31 |     } else {
32 |       // Node is a file
33 |       if (includedFileExtensions.includes(path.extname(item.name))) {
34 |         console.log(item.name);
35 |         const mdxContent = fs.readFileSync(item.path, "utf-8");
36 |         
37 |         const regex = /<SmartLink\s+href=\{([^}]+)\}>/g;
38 |         const newMdxContent = mdxContent.replace(regex, (_, hrefExpr) => {
39 |           return `<SmartLink href="${constants[hrefExpr] || ''}">`;
40 |         });
41 | 
42 |         fs.writeFileSync(item.path, newMdxContent);
43 |       }
44 |     }
45 |   });
46 | }
47 | 
48 | /**
49 |  * Recursive function that traverses a given folder and applies an optional function on
50 |  * each of the folders/files found inside.
51 |  */
52 | export function traverseDirectory(node, visitor, level = 0) {
53 |   level++;
54 |   const dirContents = fs.readdirSync(node.path);
55 |   if (!node.children) node.children = dirContents;
56 |   for (const itemName of dirContents) {
57 |     const itemPath = [winPathToPosix(node.path), itemName].join(path.posix.sep);
58 |     const itemIsDir = fs.statSync(itemPath).isDirectory();
59 |     const childNode = {
60 |       name: itemName,
61 |       path: itemPath,
62 |       parent: node,
63 |     };
64 |     visitor && visitor(childNode, level);
65 |     if (itemIsDir) {
66 |       traverseDirectory(childNode, visitor, level);
67 |     }
68 |   }
69 | }
70 | 
71 | /**
72 |  * Multi-liner (commented and compatible with really old javascript versions)
73 |  * Source: https://stackoverflow.com/a/62732509
74 |  */
75 | export function winPathToPosix(windowsPath) {
76 |   // handle the edge-case of Window's long file names
77 |   // See: https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#short-vs-long-names
78 |   windowsPath = windowsPath.replace(/^\\\\\?\\/, "");
79 | 
80 |   // convert the separators, valid since both \ and / can't be in a windows filename
81 |   windowsPath = windowsPath.replace(/\\/g, "/");
82 | 
83 |   // compress any // or /// to be just /, which is a safe oper under POSIX
84 |   // and prevents accidental errors caused by manually doing path1+path2
85 |   windowsPath = windowsPath.replace(/\/\/+/g, "/");
86 | 
87 |   return windowsPath;
88 | }
89 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/Stack/VStack.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { test, expect } from "../../testing/fixtures";
 2 | 
 3 | // =============================================================================
 4 | // BASIC FUNCTIONALITY TESTS
 5 | // =============================================================================
 6 | 
 7 | test.describe("Basic Functionality", () => {
 8 |   test("renders items vertically", async ({ initTestBed, page }) => {
 9 |     await initTestBed(`
10 |       <VStack testId="vstack">
11 |         <Stack testId="item1" height="32px" width="32px" backgroundColor="red" />
12 |         <Stack testId="item2" height="32px" width="32px" backgroundColor="blue" />
13 |         <Stack testId="item3" height="32px" width="32px" backgroundColor="green" />
14 |       </VStack>
15 |     `);
16 | 
17 |     const vstack = page.getByTestId("vstack");
18 |     const item1 = page.getByTestId("item1");
19 |     const item2 = page.getByTestId("item2");
20 |     const item3 = page.getByTestId("item3");
21 | 
22 |     await expect(vstack).toBeVisible();
23 |     await expect(item1).toBeVisible();
24 |     await expect(item2).toBeVisible();
25 |     await expect(item3).toBeVisible();
26 | 
27 |     // Get bounding boxes to verify vertical layout
28 |     const item1Box = await item1.boundingBox();
29 |     const item2Box = await item2.boundingBox();
30 |     const item3Box = await item3.boundingBox();
31 | 
32 |     // Verify items are stacked vertically (item2 should be below item1, item3 below item2)
33 |     expect(item2Box!.y).toBeGreaterThan(item1Box!.y + item1Box!.height - 1); // -1 for floating point tolerance
34 |     expect(item3Box!.y).toBeGreaterThan(item2Box!.y + item2Box!.height - 1); // -1 for floating point tolerance
35 | 
36 |     // Verify items are horizontally aligned (should start at roughly the same x position)
37 |     expect(Math.abs(item1Box!.x - item2Box!.x)).toBeLessThan(1);
38 |     expect(Math.abs(item2Box!.x - item3Box!.x)).toBeLessThan(1);
39 |   });
40 | 
41 |   test("renders empty VStack", async ({ initTestBed, page }) => {
42 |     await initTestBed(`<VStack testId="vstack"></VStack>`);
43 |     
44 |     const vstack = page.getByTestId("vstack");
45 |     await expect(vstack).toBeAttached();
46 |     await expect(vstack).toBeEmpty();
47 |   });
48 | 
49 |   test("ignores orientation property", async ({ initTestBed, page }) => {
50 |     await initTestBed(`
51 |       <VStack testId="vstack" orientation="horizontal">
52 |         <Stack testId="item1" height="32px" width="32px" backgroundColor="red" />
53 |         <Stack testId="item2" height="32px" width="32px" backgroundColor="blue" />
54 |       </VStack>
55 |     `);
56 | 
57 |     const item1 = page.getByTestId("item1");
58 |     const item2 = page.getByTestId("item2");
59 | 
60 |     await expect(item1).toBeVisible();
61 |     await expect(item2).toBeVisible();
62 | 
63 |     // Get bounding boxes to verify still renders vertically despite orientation="horizontal"
64 |     const item1Box = await item1.boundingBox();
65 |     const item2Box = await item2.boundingBox();
66 | 
67 |     // Verify items are still stacked vertically (orientation prop should be ignored)
68 |     expect(item2Box!.y).toBeGreaterThan(item1Box!.y + item1Box!.height - 1);
69 |   });
70 | });
71 | 
```

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

```typescript
 1 | import { createComponentRenderer } from "../../components-core/renderers";
 2 | import { MemoizedItem } from "../container-helpers";
 3 | import { createMetadata, d } from "../metadata-helpers";
 4 | import { OptionNative, defaultProps } from "./OptionNative";
 5 | 
 6 | const COMP = "Option";
 7 | 
 8 | export const OptionMd = createMetadata({
 9 |   status: "stable",
10 |   description:
11 |     "`Option` defines selectable items for choice-based components, providing both " +
12 |     "the underlying value and display text for selection interfaces. It serves as " +
13 |     "a non-visual data structure that describes individual choices within " +
14 |     "[Select](/components/Select), [AutoComplete](/components/AutoComplete), " +
15 |     "and other selection components.",
16 |   props: {
17 |     label: d(
18 |       `This property defines the text to display for the option. If \`label\` is not defined, ` +
19 |       `\`Option\` will use the \`value\` as the label.`,
20 |     ),
21 |     value: d(
22 |       "This property defines the value of the option. If `value` is not defined, " +
23 |       "`Option` will use the `label` as the value. If neither is defined, " +
24 |       "the option is not displayed.",
25 |     ),
26 |     enabled: {
27 |       description: "This boolean property indicates whether the option is enabled or disabled.",
28 |       valueType: "boolean",
29 |       defaultValue: defaultProps.enabled,
30 |     },
31 |     keywords: d(
32 |       "An array of keywords that can be used for searching and filtering the option. " +
33 |       "These keywords are not displayed but help users find the option through search.",
34 |     ),
35 |   },
36 | });
37 | 
38 | export const optionComponentRenderer = createComponentRenderer(
39 |   COMP,
40 |   OptionMd,
41 |   ({ node, extractValue, className, renderChild, layoutContext }) => {
42 |     const label = extractValue.asOptionalString(node.props.label);
43 |     let value = extractValue(node.props.value);
44 |     if (label === undefined && value === undefined) {
45 |       return null;
46 |     }
47 | 
48 |     const hasTextNodeChild = node.children?.length === 1 && (node.children[0].type === "TextNode" || node.children[0].type === "TextNodeCData");
49 |     const textNodeChild = hasTextNodeChild ? renderChild(node.children) as string : undefined;
50 | 
51 |     return (
52 |       <OptionNative
53 |         label={label || textNodeChild}
54 |         value={value !== undefined && value !== "" ? value : label}
55 |         enabled={extractValue.asOptionalBoolean(node.props.enabled)}
56 |         keywords={extractValue.asOptionalStringArray(node.props.keywords)}
57 |         className={className}
58 |         optionRenderer={
59 |           node.children?.length > 0
60 |             ? !hasTextNodeChild ? (contextVars) => (
61 |               <MemoizedItem
62 |                 node={node.children}
63 |                 renderChild={renderChild}
64 |                 contextVars={contextVars}
65 |                 layoutContext={layoutContext}
66 |               />
67 |             ) : undefined
68 |             : undefined
69 |         }
70 |       >
71 |         {!hasTextNodeChild && renderChild(node.children)}
72 |       </OptionNative>
73 |     );
74 |   },
75 | );
76 | 
```

--------------------------------------------------------------------------------
/docs/public/pages/howto/paginate-a-list.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Paginate a List
 2 | 
 3 | XMLUI provides a `Pagination` component that can be used to display visual controls for the pagination feature, no matter whether it is handled inside or outside of a layout component requiring that feature.
 4 | 
 5 | The [`Table`](./table) component provides out-of-the-box support for pagination,
 6 | so you can access pagination options via the following properties: `isPaginated`, `pageSize`, `pageSizeOptions`, `paginationControlsLocation`.
 7 | 
 8 | ```xmlui noHeader copy
 9 | <Table
10 |   data="/api/endpoint"
11 |   isPaginated
12 |   pageSize="10"
13 |   pageSizeOptions="{[5, 10, 20, 30]}"
14 |   paginationControlsLocation="both"
15 | >
16 |     ...
17 | </Table>
18 | ```
19 | 
20 | Other components, such as the `List`, can be hooked up with pagination using a `DataSource` combined with the `Pagination` component. This pattern works as a more generic solution where either the component does not have pagination implemented in the component itself, or you wish to use custom pagination logic.
21 | 
22 | In this case the `DataSource` component does the heavy lifting by querying the page index, the previous and next page IDs. This can be done using variables and query parameters.
23 | 
24 | ```xmlui-pg
25 | ---app display
26 | <App var.pageSize="{5}" var.currentPage="{0}" var.before="{0}" var.after="{pageSize-1}">
27 |   <DataSource id="pagination_ds" url="/api/pagination_items" queryParams="{{ from: before, to: after }}" />
28 |   <Pagination
29 |     itemCount="20"
30 |     pageSize="{pageSize}"
31 |     pageIndex="{currentPage}"
32 |     onPageDidChange="(page, size, total) => {
33 |       currentPage = page;
34 |       before = page * size;
35 |       after = before + size - 1;
36 |     }"
37 |   />
38 |   <List data="{pagination_ds}" />
39 | </App>
40 | ---api
41 | {
42 |   "apiUrl": "/api",
43 |   "initialize": "$state.pagination_items = [{ id: 1, name: 'Laptop Pro', price: 1299 },{ id: 2, name: 'Wireless Mouse', price: 29 },{ id: 3, name: 'Mechanical Keyboard', price: 149 },{ id: 4, name: '4K Monitor', price: 399 },{ id: 5, name: 'USB-C Hub', price: 79 },{ id: 6, name: 'Bluetooth Headphones', price: 199 },{ id: 7, name: 'Webcam HD', price: 89 },{ id: 8, name: 'Standing Desk', price: 299 },{ id: 9, name: 'Ergonomic Chair', price: 249 },{ id: 10, name: 'Desk Lamp', price: 45 },{ id: 11, name: 'Cable Organizer', price: 15 },{ id: 12, name: 'Mouse Pad', price: 12 },{ id: 13, name: 'Laptop Stand', price: 35 },{ id: 14, name: 'External SSD', price: 129 },{ id: 15, name: 'Wireless Charger', price: 59 },{ id: 16, name: 'Smart Speaker', price: 99 },{ id: 17, name: 'Fitness Tracker', price: 199 },{ id: 18, name: 'Tablet Pro', price: 799 },{ id: 19, name: 'Gaming Mouse', price: 89 },{ id: 20, name: 'Noise Cancelling Headphones', price: 349 }]",
44 |   "operations": {
45 |     "get-pagination-items": {
46 |       "url": "/pagination_items",
47 |       "method": "get",
48 |       "queryParams": {
49 |         "from": "integer",
50 |         "to": "integer"
51 |       },
52 |       "handler": "$state.pagination_items.slice(Number($queryParams.from), Number($queryParams.to) + 1);"
53 |     }
54 |   }
55 | }
56 | ```
57 | 
```

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

```markdown
  1 | # FormSection [#formsection]
  2 | 
  3 | `FormSection` groups elements within a `Form`. Child components are placed in a [FlowLayout](/components/FlowLayout).
  4 | 
  5 | ## Properties [#properties]
  6 | 
  7 | ### `columnGap` (default: "3rem") [#columngap-default-3rem]
  8 | 
  9 | The gap between columns of items within the section.
 10 | 
 11 | ```xmlui-pg copy display name="Example: columnGap"
 12 | <Form padding="1rem">
 13 |   <FormSection columnGap="1rem">
 14 |     <FormItem width="50%" label="Name" bindTo="" />
 15 |     <FormItem width="50%" label="Occupation" bindTo="" />
 16 |   </FormSection>
 17 | </Form>
 18 | ```
 19 | 
 20 | ### `heading` [#heading]
 21 | 
 22 | The heading text to be displayed at the top of the form section.
 23 | 
 24 | ```xmlui-pg copy display name="Example: heading"
 25 | <Form padding="1rem">
 26 |   <FormSection heading="Basic Heading">
 27 |     <FormItem label="Input Field" bindTo="" />
 28 |   </FormSection>
 29 | </Form>
 30 | ```
 31 | 
 32 | ### `headingLevel` (default: "h3") [#headinglevel-default-h3]
 33 | 
 34 | The semantic and visual level of the heading.
 35 | 
 36 | Available values: `h1`, `h2`, `h3` **(default)**, `h4`, `h5`, `h6`
 37 | 
 38 | ```xmlui-pg copy display name="Example: headingLevel"
 39 | <Form padding="1rem">
 40 |   <FormSection heading="Basic Heading" headingLevel="h1">
 41 |     <FormItem label="Input Field" bindTo="" />
 42 |   </FormSection>
 43 | </Form>
 44 | ```
 45 | 
 46 | ### `headingWeight` (default: "bold") [#headingweight-default-bold]
 47 | 
 48 | The font weight of the heading.
 49 | 
 50 | The default weight is `bold`.
 51 | 
 52 | ```xmlui-pg copy display name="Example: headingWeight"
 53 | <Form padding="1rem">
 54 |   <FormSection heading="Basic Heading" headingWeight="normal">
 55 |     <FormItem label="Input Field" bindTo="" />
 56 |   </FormSection>
 57 | </Form>
 58 | ```
 59 | 
 60 | ### `info` [#info]
 61 | 
 62 | Informational text displayed below the heading.
 63 | 
 64 | ```xmlui-pg copy display name="Example: info"
 65 | <Form padding="1rem">
 66 |   <FormSection info="This is some information about a particular section.">
 67 |     <FormItem label="Input Field" bindTo="" />
 68 |   </FormSection>
 69 | </Form>
 70 | ```
 71 | 
 72 | ### `infoFontSize` (default: "0.8rem") [#infofontsize-default-0-8rem]
 73 | 
 74 | The font size of the informational text.
 75 | 
 76 | ```xmlui-pg copy {4} display name="Example: infoFontSize"
 77 | <Form padding="1rem">
 78 |   <FormSection
 79 |     info="This is some information about a particular section."
 80 |     infoFontSize="18px"
 81 |   >
 82 |     <FormItem label="Input Field" bindTo="" />
 83 |   </FormSection>
 84 | </Form>
 85 | ```
 86 | 
 87 | ### `paddingTop` (default: "$space-normal") [#paddingtop-default-space-normal]
 88 | 
 89 | The top padding of the FlowLayout where the section's children are placed.
 90 | 
 91 | ### `rowGap` (default: "$space-normal") [#rowgap-default-space-normal]
 92 | 
 93 | The gap between rows of items within the section.
 94 | 
 95 | ```xmlui-pg copy display name="Example: rowGap"
 96 | <Form padding="1rem">
 97 |   <FormSection rowGap="2rem">
 98 |     <FormItem label="Name" bindTo="" />
 99 |     <FormItem label="Occupation" bindTo="" />
100 |   </FormSection>
101 | </Form>
102 | ```
103 | 
104 | ## Events [#events]
105 | 
106 | This component does not have any events.
107 | 
108 | ## Exposed Methods [#exposed-methods]
109 | 
110 | This component does not expose any methods.
111 | 
112 | ## Styling [#styling]
113 | 
114 | This component does not have any styles.
115 | 
```

--------------------------------------------------------------------------------
/packages/xmlui-devtools/src/devtools/ModalDialog.module.scss:
--------------------------------------------------------------------------------

```scss
  1 | @use "xmlui/themes.scss" 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 | 
 25 | .overlay {
 26 |   position: fixed;
 27 |   overflow-y: auto;
 28 |   display: flex;
 29 |   align-items: center;
 30 |   justify-content: center;
 31 |   inset: 0;
 32 |   padding: t.$space-4;
 33 | }
 34 | 
 35 | .overlayBg {
 36 |   background-color: $backgroundColor-overlay-ModalDialog;
 37 |   position: fixed;
 38 |   inset: 0;
 39 | }
 40 | 
 41 | .contentWrapper {
 42 |   display: flex;
 43 |   justify-content: center;
 44 |   align-items: center;
 45 |   width: 100%;
 46 |   height: 100%;
 47 | }
 48 | 
 49 | .content {
 50 |   background-color: $backgroundColor-ModalDialog;
 51 |   border-radius: $borderRadius-ModalDialog;
 52 |   font-family: $fontFamily-ModalDialog;
 53 |   color: $textColor-ModalDialog;
 54 |   box-shadow: t.$boxShadow-spread;
 55 |   width: 90vw;
 56 |   max-width: 960px;
 57 |   min-width: 240px;
 58 |   isolation: isolate;
 59 |   position: relative;
 60 |   display: flex;
 61 |   flex-direction: column;
 62 |   max-height: 80vh;
 63 |   overflow-y: auto;
 64 | }
 65 | 
 66 | .content:focus {
 67 |   outline: none;
 68 | }
 69 | 
 70 | .dialogTitle {
 71 |   flex: 1;
 72 |   margin-bottom: $marginBottom-title-ModalDialog;
 73 |   font-size: t.$fontSize-2xl;
 74 | }
 75 | 
 76 | .innerContent {
 77 |   display: flex;
 78 |   flex-direction: column;
 79 |   min-height: 0;
 80 |   gap: var(--stack-gap-default);
 81 |   flex: 1;
 82 | }
 83 | 
 84 | .closeButton {
 85 |   position: absolute;
 86 |   right: 0.5rem;
 87 |   top: 0.4rem;
 88 | }
 89 | 
 90 | .actions {
 91 |   display: inline-flex;
 92 |   align-items: center;
 93 |   justify-content: flex-end;
 94 | }
 95 | 
 96 | .header {
 97 |   padding: t.$space-2;
 98 |   justify-content: space-between;
 99 |   display: flex;
100 |   flex-direction: row;
101 |   border-bottom: 1px solid t.$borderColor;
102 | }
103 | 
104 | @media (max-width: 70em) {
105 |   .dialog, .content {
106 |     max-width: 90%;
107 |   }
108 | }
109 | 
110 | @media (max-width: 50em) {
111 |   .dialog, .content {
112 |     width: 100%;
113 |     max-width: calc(100% - #{t.$space-6});
114 |     min-width: 0 !important;
115 |   }
116 | }
117 | 
118 | // --- We export the theme variables to add them to the component renderer
119 | :export {
120 |   themeVars: t.json-stringify($themeVars);
121 | }
122 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/Stack/HStack.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { test, expect } from "../../testing/fixtures";
 2 | 
 3 | // =============================================================================
 4 | // BASIC FUNCTIONALITY TESTS
 5 | // =============================================================================
 6 | 
 7 | test.describe("Basic Functionality", () => {
 8 |   test("renders items horizontally", async ({ initTestBed, page }) => {
 9 |     await initTestBed(`
10 |       <HStack testId="hstack">
11 |         <Stack testId="item1" height="32px" width="32px" backgroundColor="red" />
12 |         <Stack testId="item2" height="32px" width="32px" backgroundColor="blue" />
13 |         <Stack testId="item3" height="32px" width="32px" backgroundColor="green" />
14 |       </HStack>
15 |     `);
16 | 
17 |     const hstack = page.getByTestId("hstack");
18 |     const item1 = page.getByTestId("item1");
19 |     const item2 = page.getByTestId("item2");
20 |     const item3 = page.getByTestId("item3");
21 | 
22 |     await expect(hstack).toBeVisible();
23 |     await expect(item1).toBeVisible();
24 |     await expect(item2).toBeVisible();
25 |     await expect(item3).toBeVisible();
26 | 
27 |     // Get bounding boxes to verify horizontal layout
28 |     const item1Box = await item1.boundingBox();
29 |     const item2Box = await item2.boundingBox();
30 |     const item3Box = await item3.boundingBox();
31 | 
32 |     // Verify items are stacked horizontally (item2 should be to the right of item1, item3 to the right of item2)
33 |     expect(item2Box!.x).toBeGreaterThan(item1Box!.x + item1Box!.width - 1); // -1 for floating point tolerance
34 |     expect(item3Box!.x).toBeGreaterThan(item2Box!.x + item2Box!.width - 1); // -1 for floating point tolerance
35 | 
36 |     // Verify items are vertically aligned (should start at roughly the same y position)
37 |     expect(Math.abs(item1Box!.y - item2Box!.y)).toBeLessThan(1);
38 |     expect(Math.abs(item2Box!.y - item3Box!.y)).toBeLessThan(1);
39 |   });
40 | 
41 |   test("renders empty HStack", async ({ initTestBed, page }) => {
42 |     await initTestBed(`<HStack testId="hstack"></HStack>`);
43 |     
44 |     const hstack = page.getByTestId("hstack");
45 |     await expect(hstack).toBeAttached();
46 |     await expect(hstack).toBeEmpty();
47 |   });
48 | 
49 |   test("ignores orientation property", async ({ initTestBed, page }) => {
50 |     await initTestBed(`
51 |       <HStack testId="hstack" orientation="vertical">
52 |         <Stack testId="item1" height="32px" width="32px" backgroundColor="red" />
53 |         <Stack testId="item2" height="32px" width="32px" backgroundColor="blue" />
54 |       </HStack>
55 |     `);
56 | 
57 |     const item1 = page.getByTestId("item1");
58 |     const item2 = page.getByTestId("item2");
59 | 
60 |     await expect(item1).toBeVisible();
61 |     await expect(item2).toBeVisible();
62 | 
63 |     // Get bounding boxes to verify still renders horizontally despite orientation="vertical"
64 |     const item1Box = await item1.boundingBox();
65 |     const item2Box = await item2.boundingBox();
66 | 
67 |     // Verify items are still stacked horizontally (orientation prop should be ignored)
68 |     expect(item2Box!.x).toBeGreaterThan(item1Box!.x + item1Box!.width - 1);
69 |   });
70 | });
71 | 
```

--------------------------------------------------------------------------------
/xmlui/bin/vite-xmlui-plugin.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { dataToEsm } from "@rollup/pluginutils";
 2 | import type { Plugin } from "vite";
 3 | import {
 4 |   collectCodeBehindFromSource,
 5 |   removeCodeBehindTokensFromTree,
 6 | } from "../src/parsers/scripting/code-behind-collect";
 7 | import {
 8 |   codeBehindFileExtension,
 9 |   componentFileExtension,
10 |   moduleFileExtension,
11 | } from "../src/parsers/xmlui-parser/fileExtensions";
12 | import { Parser } from "../src/parsers/scripting/Parser";
13 | import * as fs from "fs";
14 | import * as path from "path";
15 | import { errReportComponent, xmlUiMarkupToComponent } from "../src/components-core/xmlui-parser";
16 | 
17 | export type PluginOptions = {
18 |   // --- Add plugin options here.
19 | };
20 | 
21 | const xmluiExtension = new RegExp(`.${componentFileExtension}$`);
22 | const xmluiScriptExtension = new RegExp(`.${codeBehindFileExtension}$`);
23 | const moduleScriptExtension = new RegExp(`.${moduleFileExtension}$`);
24 | 
25 | /**
26 |  * Transform XMLUI files to JS objects.
27 |  */
28 | export default function viteXmluiPlugin(pluginOptions: PluginOptions = {}): Plugin {
29 |   let itemIndex = 0;
30 |   return {
31 |     name: "vite:transform-xmlui",
32 | 
33 |     async transform(code: string, id: string, options) {
34 |       const moduleNameResolver = (moduleName: string) => {
35 |         return path.resolve(path.dirname(id), moduleName);
36 |       };
37 | 
38 |       if (xmluiExtension.test(id)) {
39 |         const fileId = "" + itemIndex++;
40 |         let { component, errors, erroneousCompoundComponentName } = xmlUiMarkupToComponent(
41 |           code,
42 |           fileId,
43 |         );
44 |         if (errors.length > 0) {
45 |           component = errReportComponent(errors, id, erroneousCompoundComponentName);
46 |         }
47 |         const file = {
48 |           component,
49 |           src: code,
50 |           file: fileId,
51 |         };
52 | 
53 |         return {
54 |           code: dataToEsm(file),
55 |           map: { mappings: "" },
56 |         };
57 |       }
58 | 
59 |       const hasXmluiScriptExtension = xmluiScriptExtension.test(id);
60 |       const hasModuleScriptExtension = moduleScriptExtension.test(id);
61 |       if (hasXmluiScriptExtension || hasModuleScriptExtension) {
62 |         // --- We parse the module file to catch parsing errors
63 | 
64 |         const parser = new Parser(code);
65 |         parser.parseStatements();
66 |         const moduleName = hasXmluiScriptExtension
67 |           ? id.substring(0, id.length - (codeBehindFileExtension.length + 1))
68 |           : id.substring(0, id.length - (moduleFileExtension.length + 1));
69 | 
70 |         const codeBehind = collectCodeBehindFromSource(moduleNameResolver(moduleName), code);
71 |         removeCodeBehindTokensFromTree(codeBehind);
72 | 
73 |         // TODO: Add error handling.
74 |         // Check, if codeBehind.moduleErrors is not empty (Record<string, ModuleErrors[]>); each module
75 |         // should be checked for errors and warnings. If there are errors, throw an error.
76 | 
77 |         return {
78 |           code: dataToEsm({...codeBehind, src: code}),
79 |           map: { mappings: "" },
80 |         };
81 |       }
82 |       return null;
83 |     },
84 |     // async generateBundle(opts, bundle, isWrite){
85 |     //   console.log('generate bundle', opts);
86 |     // }
87 |   };
88 | }
89 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components-core/loader/ApiLoader.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import { useCallback } from "react";
  2 | 
  3 | import type {
  4 |   LoaderErrorFn,
  5 |   LoaderInProgressChangedFn,
  6 |   LoaderLoadedFn,
  7 | } from "../abstractions/LoaderRenderer";
  8 | import type { ComponentDef } from "../../abstractions/ComponentDefs";
  9 | import type { ContainerState } from "../rendering/ContainerWrapper";
 10 | import { removeNullProperties } from "../utils/misc";
 11 | import { extractParam } from "../utils/extractParam";
 12 | import { createLoaderRenderer } from "../renderers";
 13 | import { useAppContext } from "../AppContext";
 14 | import { Loader } from "./Loader";
 15 | import { createMetadata, d } from "../../components/metadata-helpers";
 16 | 
 17 | /**
 18 |  * Properties of the API loader component
 19 |  */
 20 | type ApiLoaderProps = {
 21 |   loader: ApiLoaderDef;
 22 |   loaderInProgressChanged: LoaderInProgressChangedFn;
 23 |   loaderIsRefetchingChanged: LoaderInProgressChangedFn;
 24 |   loaderLoaded: LoaderLoadedFn;
 25 |   loaderError: LoaderErrorFn;
 26 |   state: ContainerState;
 27 |   doNotRemoveNulls?: boolean;
 28 |   structuralSharing?: boolean;
 29 | };
 30 | 
 31 | /**
 32 |  * Represents a non-displayed React component, which handles the specified API loader
 33 |  */
 34 | function ApiLoader({
 35 |   loader,
 36 |   loaderInProgressChanged,
 37 |   loaderIsRefetchingChanged,
 38 |   loaderLoaded,
 39 |   loaderError,
 40 |   state,
 41 |   doNotRemoveNulls,
 42 |   structuralSharing = true,
 43 | }: ApiLoaderProps) {
 44 |   const appContext = useAppContext();
 45 | 
 46 |   const url = extractParam(state, loader.props.url, appContext);
 47 |   const loadable = !!url;
 48 | 
 49 |   const doLoad = useCallback(async () => {
 50 |     if (!loadable) {
 51 |       return;
 52 |     }
 53 |     const response = await fetch(url);
 54 |     if (loader.props.raw) {
 55 |       return await response.text();
 56 |     }
 57 |     const responseObj = await response.json();
 58 |     if (!doNotRemoveNulls) {
 59 |       removeNullProperties(responseObj);
 60 |     }
 61 |     return responseObj;
 62 |   }, [doNotRemoveNulls, loadable, loader.props.raw, url]);
 63 | 
 64 |   return (
 65 |     <Loader
 66 |       state={state}
 67 |       loader={loader}
 68 |       loaderInProgressChanged={loaderInProgressChanged}
 69 |       loaderIsRefetchingChanged={loaderIsRefetchingChanged}
 70 |       loaderLoaded={loaderLoaded}
 71 |       loaderError={loaderError}
 72 |       loaderFn={doLoad}
 73 |       structuralSharing={structuralSharing}
 74 |     />
 75 |   );
 76 | }
 77 | 
 78 | const ApiLoaderMd = createMetadata({
 79 |   status: "stable",
 80 |   description: `Represents a loader that calls an API through an HTTP/HTTPS GET request`,
 81 |   props: {
 82 |     url: d("URL segment to use in the GET request"),
 83 |     raw: d("If true, the loader returns the raw text response instead of parsing it as JSON"),
 84 |   },
 85 | });
 86 | 
 87 | type ApiLoaderDef = ComponentDef<typeof ApiLoaderMd>;
 88 | 
 89 | export const apiLoaderRenderer = createLoaderRenderer(
 90 |   "ApiLoader",
 91 |   ({ loader, state, loaderInProgressChanged, loaderIsRefetchingChanged, loaderLoaded, loaderError }) => {
 92 |     return (
 93 |       <ApiLoader
 94 |         loader={loader}
 95 |         state={state}
 96 |         loaderInProgressChanged={loaderInProgressChanged}
 97 |         loaderIsRefetchingChanged={loaderIsRefetchingChanged}
 98 |         loaderLoaded={loaderLoaded}
 99 |         loaderError={loaderError}
100 |       />
101 |     );
102 |   },
103 |   ApiLoaderMd,
104 | );
105 | 
```

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

```typescript
 1 | import { useThemes } from "../../components-core/theming/ThemeContext";
 2 | import { createComponentRenderer } from "../../components-core/renderers";
 3 | import { Button } from "../Button/ButtonNative";
 4 | import { Icon } from "../Icon/IconNative";
 5 | import { createMetadata, dClick } from "../metadata-helpers";
 6 | import { noop } from "lodash-es";
 7 | 
 8 | const COMP = "ToneChangerButton";
 9 | const LIGHT_TO_DARK_ICON = "lightToDark:ToneChangerButton";
10 | const DARK_TO_LIGHT_ICON = "darkToLight:ToneChangerButton";
11 | 
12 | export const defaultProps = {
13 |   lightToDarkIcon: LIGHT_TO_DARK_ICON,
14 |   darkToLightIcon: DARK_TO_LIGHT_ICON,
15 |   onClick: noop,
16 | };
17 | 
18 | export const ToneChangerButtonMd = createMetadata({
19 |   status: "stable",
20 |   description: "`ToneChangerButton` enables the user to switch between light and dark modes.",
21 |   props: {
22 |     lightToDarkIcon: {
23 |       description:
24 |         `The icon displayed when the theme is in light mode and will switch to dark. You can change ` +
25 |         `the default icon for all ${COMP} instances with the "icon.lightToDark:ToneChangerButton" ` +
26 |         `declaration in the app configuration file.`,
27 |       defaultValue: defaultProps.lightToDarkIcon,
28 |     },
29 |     darkToLightIcon: {
30 |       description:
31 |         `The icon displayed when the theme is in dark mode and will switch to light. You can change ` +
32 |         `the default icon for all ${COMP} instances with the "icon.darkToLight:ToneChangerButton" ` +
33 |         `declaration in the app configuration file.`,
34 |       defaultValue: defaultProps.darkToLightIcon,
35 |     },
36 |   },
37 |   events: {
38 |     click: dClick(COMP),
39 |   },
40 | });
41 | 
42 | export function ToneChangerButton({
43 |   lightToDarkIcon = defaultProps.lightToDarkIcon,
44 |   darkToLightIcon = defaultProps.darkToLightIcon,
45 |   onClick = defaultProps.onClick,
46 | }) {
47 |   const { activeThemeTone, setActiveThemeTone } = useThemes();
48 | 
49 |   // Use the direct icon name as both the main icon and the fallback
50 |   // This ensures we always have a working icon
51 |   const iconName = activeThemeTone === "light" ? lightToDarkIcon : darkToLightIcon;
52 |   const fallbackIcon = activeThemeTone === "light" ? "lightToDark" : "darkToLight";
53 | 
54 |   return (
55 |     <Button
56 |       variant="ghost"
57 |       style={{ flexShrink: 0 }}
58 |       icon={<Icon name={iconName} fallback={fallbackIcon} />}
59 |       onClick={() => {
60 |         if (activeThemeTone === "light") {
61 |           setActiveThemeTone("dark");
62 |           onClick?.("dark");
63 |         } else {
64 |           setActiveThemeTone("light");
65 |           onClick?.("light");
66 |         }
67 |       }}
68 |     />
69 |   );
70 | }
71 | 
72 | /**
73 |  * Define the renderer for the ToneChangerButton component
74 |  */
75 | export const toneChangerButtonComponentRenderer = createComponentRenderer(
76 |   COMP,
77 |   ToneChangerButtonMd,
78 |   ({ node, extractValue, lookupEventHandler }) => {
79 |     return (
80 |       <ToneChangerButton
81 |         onClick={lookupEventHandler("click")}
82 |         lightToDarkIcon={extractValue.asOptionalString(node.props.lightToDarkIcon)}
83 |         darkToLightIcon={extractValue.asOptionalString(node.props.darkToLightIcon)}
84 |       />
85 |     );
86 |   },
87 | );
88 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/Pages/PagesNative.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import type { CSSProperties, ReactNode } from "react";
  2 | import { useMemo } from "react";
  3 | import { Navigate, Route, Routes, useParams } from "@remix-run/react";
  4 | import classnames from "classnames";
  5 | 
  6 | import type { ComponentDef } from "../../abstractions/ComponentDefs";
  7 | import type { LayoutContext, RenderChildFn, ValueExtractor } from "../../abstractions/RendererDefs";
  8 | import { EMPTY_ARRAY, EMPTY_OBJECT } from "../../components-core/constants";
  9 | import type { PageMd } from "./Pages";
 10 | import styles from "./Pages.module.scss";
 11 | 
 12 | // Default props for Pages component
 13 | export const defaultProps = {
 14 |   fallbackPath: "/",
 15 | };
 16 | 
 17 | // --- We need this component to make sure all the child routes are wrapped in a
 18 | // --- container and  this way they can access the routeParams
 19 | type RouteWrapperProps = {
 20 |   childRoute?: ComponentDef | Array<ComponentDef>;
 21 |   renderChild: RenderChildFn;
 22 |   layoutContext?: LayoutContext;
 23 |   style?: CSSProperties;
 24 |   className?: string;
 25 |   uid?: string;
 26 | };
 27 | 
 28 | export function RouteWrapper({
 29 |   childRoute = EMPTY_ARRAY,
 30 |   renderChild,
 31 |   layoutContext,
 32 |   style,
 33 |   className,
 34 |   uid,
 35 | }: RouteWrapperProps) {
 36 |   const params = useParams();
 37 | 
 38 |   //we need to wrap the child route in a container to make sure the route params are available.
 39 |   // we do this wrapping by providing an empty object to vars.
 40 |   // this way it becomes an 'implicit' container (vars/state inside this container is propagated to the parent)
 41 |   const wrappedWithContainer = useMemo(() => {
 42 |     if (Array.isArray(childRoute)) {
 43 |       return {
 44 |         type: "Fragment",
 45 |         uid,
 46 |         vars: EMPTY_OBJECT,
 47 |         children: childRoute,
 48 |       };
 49 |     }
 50 |     return {
 51 |       type: "Fragment",
 52 |       uid,
 53 |       vars: EMPTY_OBJECT,
 54 |       children: [childRoute],
 55 |     };
 56 |   }, [childRoute, uid]);
 57 | 
 58 |   return (
 59 |     <div
 60 |       key={JSON.stringify(params)}
 61 |       className={classnames(className, styles.wrapper, "xmlui-page-root")}
 62 |       style={style}
 63 |     >
 64 |       {renderChild(wrappedWithContainer, layoutContext)}
 65 |     </div>
 66 |   );
 67 | }
 68 | 
 69 | type PageComponentDef = ComponentDef<typeof PageMd>;
 70 | 
 71 | type PagesProps = {
 72 |   fallbackPath?: string;
 73 |   node?: ComponentDef;
 74 |   renderChild: RenderChildFn;
 75 |   extractValue: ValueExtractor;
 76 |   children?: ReactNode;
 77 |   className?: ReactNode;
 78 | };
 79 | 
 80 | export function Pages({
 81 |   node,
 82 |   renderChild,
 83 |   extractValue,
 84 |   fallbackPath = defaultProps.fallbackPath,
 85 | }: PagesProps) {
 86 |   const routes: Array<PageComponentDef> = [];
 87 |   const restChildren: Array<ComponentDef> = [];
 88 |   node.children?.forEach((child) => {
 89 |     if (child.type === "Page") {
 90 |       routes.push(child as PageComponentDef);
 91 |     } else {
 92 |       restChildren.push(child);
 93 |     }
 94 |   });
 95 |   return (
 96 |     <>
 97 |       <Routes>
 98 |         {routes.map((child, i) => {
 99 |           return (
100 |             <Route path={extractValue(child.props.url)} key={i} element={renderChild(child)} />
101 |           );
102 |         })}
103 |         {fallbackPath && <Route path="*" element={<Navigate to={fallbackPath} replace  />} />}
104 |       </Routes>
105 |       {renderChild(restChildren)}
106 |     </>
107 |   );
108 | }
109 | 
```

--------------------------------------------------------------------------------
/docs/public/pages/app-structure.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Structure of an XMLUI app
  2 | 
  3 | The [XMLUI Invoice demo app](https://github.com/xmlui-org/xmlui-invoice/releases) exhibits the typical structure of an XMLUI app.
  4 | 
  5 | ```xmlui-tree
  6 | <root>
  7 |   index.html
  8 |   Main.xmlui
  9 |   config.json
 10 |   components
 11 |     ClientDetails.xmlui
 12 |     Clients.xmlui
 13 |     ...
 14 |     MonthlyRevenue.xmlui
 15 |     WeeklyRevenue.xmlui
 16 |   resources
 17 |     favicon.ico
 18 |     xmlui-logo-inverted.svg
 19 |     xmlui-logo.svg
 20 |   themes
 21 |     invoice.json
 22 |   xmlui
 23 |     0.9.23.js
 24 |     charts-0.1.21.js
 25 |   start.bat
 26 |   start.sh
 27 |   api.json
 28 |   data.db
 29 |   xmlui-test-server
 30 | ```
 31 | 
 32 | > [!INFO] The `xmlui` folder contains the xmlui engine with a version number, specifically `0.9.23.js`. We recommend this practice in order to know when/whether to upgrade.
 33 | 
 34 | 
 35 | | file| description |
 36 | |---|---|
 37 | | **`index.html`** | The default webpage to display |
 38 | | **`Main.xmlui`** | The XMLUI app's entry point |
 39 | | **`config.json`** | The XMLUI app's configuration file |
 40 | | **`components`** | The folder with your custom components |
 41 | | **`resources`** | The folder with static app resources |
 42 | | **`themes`** | The folder with your custom themes |
 43 | | **`xmlui`** | The folder with the XMLUI core framework and extensions  |
 44 | | **`start.bat`** | The batch file to start the test server on Windows |
 45 | | **`start.sh`** | The bash script file to start the test server on Mac, Linux, or WSL |
 46 | | **`api.json`** | *Optional*: API description file for use with xmlui-test-server |
 47 | | **`data.db`** | *Optional*: SQLite database for use with xmlui-test-server|
 48 | | **`xmlui-test-server`** | *Optional*: server, you can use any static web server|
 49 | 
 50 | 
 51 | You can deploy this tree structure (minus the optional `api.json`, `data.db`, and `xmlui-test-server`) to any static webserver that's configured to serve `index.html`. Consider this minimal app.
 52 | 
 53 | ```xmlui-tree
 54 | xmlui-minimal
 55 |   index.html
 56 |   Main.xmlui
 57 |   components
 58 |     Home.xmlui
 59 |   resources
 60 |     favicon.ico
 61 |     xmlui-logo-inverted.svg
 62 |     xmlui-logo.svg
 63 |   xmlui
 64 |     0.9.23.js
 65 | ```
 66 | 
 67 | ## index.html
 68 | 
 69 | ```html
 70 | <!DOCTYPE html>
 71 | <html lang="en">
 72 | 
 73 | <head>
 74 |     <meta charset="UTF-8" />
 75 |     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 76 |     <script src="xmlui/0.9.23.js"></script>
 77 | </head>
 78 | 
 79 | <body>
 80 | </body>
 81 | 
 82 | </html>
 83 | ```
 84 | 
 85 | ## Main.xmlui
 86 | 
 87 | ```xmlui
 88 | <App name="XMLUI Minimal">
 89 | 
 90 |   <NavPanel>
 91 |     <NavLink label="Home" to="/Home" />
 92 |   </NavPanel>
 93 | 
 94 |   <Pages>
 95 |     <Page url="/Home">
 96 |       <Home />
 97 |     </Page>
 98 |   </Pages>
 99 | 
100 | </App>
101 | ```
102 | 
103 | ## Home.xmlui
104 | 
105 | ```xmlui
106 | <Component name="Home" >
107 | 
108 | A minimal XMLUI app
109 | 
110 | </Component>
111 | ```
112 | 
113 | ## Local deployment
114 | 
115 | If you are working locally, in a folder at the root of this tree, here are some ways you can serve the app.
116 | 
117 | If you have node.js and npm:
118 | 
119 | ```
120 | npx -y http-server
121 | 
122 | $ npx -y http-server
123 | Starting up http-server, serving ./
124 | 
125 | Available on:
126 |   http://127.0.0.1:8080
127 | ```
128 | 
129 | If you have python:
130 | 
131 | ```
132 | $ python -m http.server 8080
133 | Serving HTTP on :: port 8080 (http://[::]:8080/) ...
134 | ```
135 | 
136 | In either case, visit http://localhost:8080 to view the app.
137 | 
138 | See also [Hosted deployment](/hosted-deployment).
139 | 
140 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/Charts/DonutChart/DonutChart.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import { createComponentRenderer } from "../../../components-core/renderers";
 2 | import styles from "../PieChart/PieChartNative.module.scss";
 3 | import { defaultProps, PieChart } from "../PieChart/PieChartNative";
 4 | import { parseScssVar } from "../../../components-core/theming/themeVars";
 5 | import { createMetadata } from "../../metadata-helpers";
 6 | 
 7 | const COMP = "DonutChart";
 8 | 
 9 | const defaultPropsDonut = {
10 |   ...defaultProps,
11 |   innerRadius: 60,
12 | };
13 | 
14 | export const DonutChartMd = createMetadata({
15 |   status: "experimental",
16 |   description: "A derivative of [PieChart](/components/PieChart) with a hollow center. " +
17 |     "Note that the height of the component or its parent needs to be set explicitly.",
18 |   props: {
19 |     data: {
20 |       description: "The data to be displayed in the chart. Needs to be an array of objects.",
21 |     },
22 |     nameKey: {
23 |       description:
24 |         "Specifies the key in the data objects that will be used to label the different data series.",
25 |       valueType: "string",
26 |     },
27 |     dataKey: {
28 |       description:
29 |         "This property specifies the key in the data objects that will be used to render the chart.",
30 |       valueType: "string",
31 |     },
32 |     showLabel: {
33 |       description: "Toggles whether to show labels (\`true\`) or not (\`false\`).",
34 |       valueType: "boolean",
35 |       defaultValue: defaultPropsDonut.showLabel,
36 |     },
37 |     innerRadius: {
38 |       description: "Sets the inner radius of the donut chart.",
39 |       valueType: "number",
40 |       defaultValue: defaultPropsDonut.innerRadius,
41 |     },
42 |     showLabelList: {
43 |       description: "Whether to show labels in a list (\`true\`) or not (\`false\`).",
44 |       valueType: "boolean",
45 |       defaultValue: defaultPropsDonut.showLabelList,
46 |     },
47 |     showLegend: {
48 |       description: "Whether to show a legend (\`true\`) or not (\`false\`).",
49 |       valueType: "boolean",
50 |       defaultValue: defaultPropsDonut.showLegend,
51 |     },
52 |   },
53 |   themeVars: parseScssVar(styles.themeVars),
54 |   defaultThemeVars: {
55 |     "textColor-labelList-PieChart": "$textColor-primary",
56 |   },
57 | });
58 | 
59 | export const donutChartComponentRenderer = createComponentRenderer(
60 |   COMP,
61 |   DonutChartMd,
62 |   ({ extractValue, node, className, renderChild }) => {
63 |     return (
64 |       <PieChart
65 |         showLabelList={extractValue.asOptionalBoolean(
66 |           node.props?.showLabelList,
67 |           defaultPropsDonut.showLabelList,
68 |         )}
69 |         innerRadius={extractValue.asOptionalNumber(
70 |           node.props?.innerRadius,
71 |           defaultPropsDonut.innerRadius,
72 |         )}
73 |         data={extractValue(node.props?.data)}
74 |         className={className}
75 |         showLabel={extractValue.asOptionalBoolean(
76 |           node.props?.showLabel,
77 |           defaultPropsDonut.showLabel,
78 |         )}
79 |         dataKey={extractValue(node.props?.dataKey)}
80 |         nameKey={extractValue(node.props?.nameKey)}
81 |         showLegend={extractValue.asOptionalBoolean(
82 |           node.props?.showLegend,
83 |           defaultPropsDonut.showLegend,
84 |         )}
85 |       >
86 |         {renderChild(node.children)}
87 |       </PieChart>
88 |     );
89 |   },
90 | );
91 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/List/List.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 | $themeVars: ();
  5 | @function createThemeVar($componentVariable) {
  6 |   $themeVars: t.appendThemeVar($themeVars, $componentVariable) !global;
  7 |   @return t.getThemeVar($themeVars, $componentVariable);
  8 | }
  9 | 
 10 | @layer components {
 11 |   .outerWrapper {
 12 |     overflow: auto;
 13 |     //max-height: 100%;
 14 |     overflow-anchor: none;
 15 | 
 16 |     &.hasOutsideScroll {
 17 |       overflow: initial;
 18 |     }
 19 |   }
 20 | 
 21 |   .innerWrapper {
 22 |     visibility: hidden;
 23 |     display: flex;
 24 |     flex-direction: column;
 25 |     min-height: 100%;
 26 | 
 27 |     &.reverse {
 28 |       justify-content: flex-end;
 29 |     }
 30 |   }
 31 | 
 32 |   .infoWrapper {
 33 |     width: 100%;
 34 |     margin: 0 auto;
 35 |   }
 36 | 
 37 |   .loadingWrapper {
 38 |     display: flex;
 39 |     flex-direction: row;
 40 |     justify-content: center;
 41 |     padding-top: t.$space-2;
 42 |     padding-bottom: t.$space-2;
 43 |   }
 44 | 
 45 |   .noRows {
 46 |     width: 100%;
 47 |     text-align: center;
 48 |     margin-top: t.$space-4;
 49 |   }
 50 | 
 51 |   // --- We export the theme variables to add them to the component renderer
 52 |   :export {
 53 |     themeVars: t.json-stringify($themeVars);
 54 |   }
 55 | 
 56 |   .borderCollapse {
 57 |     &:not(.sectioned) {
 58 |       .row {
 59 |         //first row in the list (but not the last)
 60 |         &:first-child:not(:last-child) {
 61 |           & > * {
 62 |             border-bottom-left-radius: 0;
 63 |             border-bottom-right-radius: 0;
 64 |             border-bottom: 0;
 65 |           }
 66 |         }
 67 | 
 68 |         //last row in the list (but not the first)
 69 |         &:last-child:not(:first-child) {
 70 |           & > * {
 71 |             border-top-left-radius: 0;
 72 |             border-top-right-radius: 0;
 73 |           }
 74 |         }
 75 | 
 76 |         //rows in the middle of the list
 77 |         &:not(:first-child):not(:last-child) {
 78 |           & > * {
 79 |             border-bottom-left-radius: 0;
 80 |             border-bottom-right-radius: 0;
 81 |             border-top-left-radius: 0;
 82 |             border-top-right-radius: 0;
 83 |             border-bottom: 0;
 84 |           }
 85 |         }
 86 |       }
 87 |     }
 88 | 
 89 |     &.sectioned {
 90 |       //.row after the section header (first row in a section)
 91 |       .section + .row:not(:has(+ .sectionFooter)) {
 92 |         & > * {
 93 |           border-bottom-left-radius: 0;
 94 |           border-bottom-right-radius: 0;
 95 |           border-bottom: 0;
 96 |         }
 97 |       }
 98 | 
 99 |       //.row before the sectionFooter (last row in a section)
100 |       .row:has(+ .sectionFooter):not(.section + .row) {
101 |         & > * {
102 |           border-top-left-radius: 0;
103 |           border-top-right-radius: 0;
104 |         }
105 |       }
106 | 
107 |       //we select the rows that has .row as direct sibling, but not the first row of a section (rows in the middle of the section)
108 |       .row:has(+ .row):not(.section + .row) {
109 |         & > * {
110 |           border-bottom-left-radius: 0;
111 |           border-bottom-right-radius: 0;
112 |           border-top-left-radius: 0;
113 |           border-top-right-radius: 0;
114 |           border-bottom: 0;
115 |         }
116 |       }
117 |     }
118 |   }
119 | }
120 | 
121 | // --- We export the theme variables to add them to the component renderer
122 | :export {
123 |   themeVars: t.json-stringify($themeVars);
124 | }
125 | 
```

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

```typescript
 1 | import { expect, test } from "../../testing/fixtures";
 2 | 
 3 | // =============================================================================
 4 | // BASIC FUNCTIONALITY TESTS
 5 | // =============================================================================
 6 | 
 7 | test.describe("Basic Functionality", () => {
 8 |   test("renders in light mode by default", async ({ initTestBed, page }) => {
 9 |     await initTestBed(`
10 |       <App>
11 |         <ToneSwitch />
12 |         <Text>{activeThemeTone}</Text>
13 |       </App>
14 |     `);
15 |     const toggle = page.getByRole("switch");
16 |     await expect(toggle).toBeVisible();
17 |     await expect(page.getByText("light")).toBeVisible();
18 |   });
19 | 
20 |   test("toggles to dark mode when clicked", async ({ initTestBed, page }) => {
21 |     await initTestBed(`
22 |       <App>
23 |         <ToneSwitch />
24 |         <Text>{activeThemeTone}</Text>
25 |       </App>
26 |     `);
27 |     const toggle = page.getByRole("switch");
28 |     await expect(toggle).toBeVisible();
29 |     await toggle.click({ force: true });
30 |     await expect(page.getByText("dark")).toBeVisible();
31 |     await expect(toggle).toBeChecked();
32 |   });
33 | 
34 |   test("toggles back to light mode when clicked again", async ({ initTestBed, page }) => {
35 |     await initTestBed(`
36 |       <App>
37 |         <ToneSwitch />
38 |         <Text>{activeThemeTone}</Text>
39 |       </App>
40 |     `);
41 |     const toggle = page.getByRole("switch");
42 |     await expect(toggle).toBeVisible();
43 |     await toggle.click({ force: true });
44 |     await expect(page.getByText("dark")).toBeVisible();
45 |     await expect(toggle).toBeChecked();
46 |     await toggle.click({ force: true });
47 |     await expect(page.getByText("light")).toBeVisible();
48 |     await expect(toggle).not.toBeChecked();
49 |   });
50 | });
51 | 
52 | // =============================================================================
53 | // ACCESSIBILITY TESTS
54 | // =============================================================================
55 | 
56 | test.describe("Accessibility", () => {
57 |   test("has switch role", async ({ initTestBed, page }) => {
58 |     await initTestBed(`<ToneSwitch />`);
59 |     const toggle = page.getByRole("switch");
60 |     await expect(toggle).toBeVisible();
61 |   });
62 | 
63 |   test("is keyboard accessible with Space key", async ({ initTestBed, page }) => {
64 |     await initTestBed(`<ToneSwitch />`);
65 |     const toggle = page.getByRole("switch");
66 |     
67 |     await toggle.focus();
68 |     await expect(toggle).toBeFocused();
69 |     
70 |     await page.keyboard.press("Space");
71 |     await expect(toggle).toBeChecked();
72 |   });
73 | 
74 |   test("maintains focus during interactions", async ({ initTestBed, page }) => {
75 |     await initTestBed(`<ToneSwitch />`);
76 |     const toggle = page.getByRole("switch");
77 |     
78 |     await toggle.focus();
79 |     await toggle.click({ force: true });
80 |     await expect(toggle).toBeFocused();
81 |   });
82 | 
83 |   test("has appropriate aria-checked state", async ({ initTestBed, page }) => {
84 |     await initTestBed(`<ToneSwitch />`);
85 |     const toggle = page.getByRole("switch");
86 |     
87 |     await expect(toggle).toHaveAttribute("aria-checked", "false");
88 |     
89 |     await toggle.click({ force: true });
90 |     await expect(toggle).toHaveAttribute("aria-checked", "true");
91 |   });
92 | });
93 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/Charts/PieChart/PieChart.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import { defaultProps, PieChart } from "./PieChartNative";
 2 | import styles from "./PieChartNative.module.scss";
 3 | import { LabelPositionValues } from "../utils/abstractions";
 4 | import { parseScssVar } from "../../../components-core/theming/themeVars";
 5 | import { createComponentRenderer } from "../../../components-core/renderers";
 6 | import type { LabelPosition } from "recharts/types/component/Label";
 7 | import { createMetadata, d } from "../../metadata-helpers";
 8 | 
 9 | const COMP = "PieChart";
10 | 
11 | export const PieChartMd = createMetadata({
12 |   status: "experimental",
13 |   description:
14 |     "`PieChart` visualizes proportional data as circular segments; each slice " +
15 |     "represents a percentage of the whole. Note that the height of the component or " +
16 |     "its parent needs to be set explicitly.",
17 |   docFolder: "Charts/PieChart",
18 |   props: {
19 |     data: {
20 |       description: "The data to be displayed in the chart. Needs to be an array of objects.",
21 |     },
22 |     nameKey: {
23 |       description:
24 |         "Specifies the key in the data objects that will be used to label the different data series.",
25 |       valueType: "string",
26 |     },
27 |     dataKey: {
28 |       description:
29 |         "This property specifies the key in the data objects that will be used to render the chart.",
30 |       valueType: "string",
31 |     },
32 |     showLabel: {
33 |       description: "Toggles whether to show labels (\`true\`) or not (\`false\`).",
34 |       valueType: "boolean",
35 |       defaultValue: defaultProps.showLabel,
36 |     },
37 |     showLabelList: {
38 |       description: "Whether to show labels in a list (\`true\`) or not (\`false\`).",
39 |       valueType: "boolean",
40 |       defaultValue: defaultProps.showLabelList,
41 |     },
42 |     labelListPosition: {
43 |       description: "The position of the label list.",
44 |       valueType: "string",
45 |       defaultValue: defaultProps.labelListPosition,
46 |       availableValues: LabelPositionValues,
47 |     },
48 |     outerRadius: d(
49 |       "The outer radius of the pie chart, can be a number or a string (e.g., '100%').",
50 |     ),
51 |     showLegend: {
52 |       description: "Toggles whether to show legend (\`true\`) or not (\`false\`).",
53 |       valueType: "boolean",
54 |       defaultValue: defaultProps.showLegend,
55 |     }
56 |   },
57 |   themeVars: parseScssVar(styles.themeVars),
58 |   defaultThemeVars: {
59 |     "textColor-labelList-PieChart": "$textColor-primary",
60 |   },
61 | });
62 | 
63 | export const pieChartComponentRenderer = createComponentRenderer(
64 |   COMP,
65 |   PieChartMd,
66 |   ({ extractValue, node, className, renderChild }) => {
67 |     return (
68 |       <PieChart
69 |         showLabelList={extractValue.asOptionalBoolean(node.props?.showLabelList)}
70 |         labelListPosition={extractValue.asOptionalString(node.props?.labelListPosition) as LabelPosition}
71 |         data={extractValue(node.props?.data)}
72 |         className={className}
73 |         showLabel={extractValue.asOptionalBoolean(node.props?.showLabel)}
74 |         showLegend={extractValue.asOptionalBoolean(node.props?.showLegend)}
75 |         dataKey={extractValue(node.props?.dataKey)}
76 |         nameKey={extractValue(node.props?.nameKey)}
77 |       >
78 |         {renderChild(node.children)}
79 |       </PieChart>
80 |     );
81 |   },
82 | );
83 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/Tooltip/Tooltip.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 | $themeVars: ();
  5 | @function createThemeVar($componentVariable) {
  6 |   $themeVars: t.appendThemeVar($themeVars, $componentVariable) !global;
  7 |   @return t.getThemeVar($themeVars, $componentVariable);
  8 | }
  9 | 
 10 | $component: "Tooltip";
 11 | $themeVars: t.composePaddingVars($themeVars, $component);
 12 | $themeVars: t.composeBorderVars($themeVars, $component);
 13 | 
 14 | 
 15 | // --- Theme variables for Tooltip component
 16 | $backgroundColor-Tooltip: createThemeVar("backgroundColor-#{$component}");
 17 | $textColor-Tooltip: createThemeVar("textColor-#{$component}");
 18 | $fontSize-Tooltip: createThemeVar("fontSize-#{$component}");
 19 | $lineHeight-Tooltip: createThemeVar("lineHeight-#{$component}");
 20 | $boxShadow-Tooltip: createThemeVar("boxShadow-#{$component}");
 21 | $fill-arrow-Tooltip: createThemeVar("fill-arrow-#{$component}");
 22 | $stroke-arrow-Tooltip: createThemeVar("stroke-arrow-#{$component}");
 23 | $strokeWidth-arrow-Tooltip: createThemeVar("strokeWidth-arrow-#{$component}");  
 24 | $animationDuration-Tooltip: createThemeVar("animationDuration-#{$component}");
 25 | $animation-Tooltip: createThemeVar("animation-#{$component}");
 26 | 
 27 | /* Tooltip styles */
 28 | 
 29 | .hiddenTrigger {
 30 |   position: fixed;
 31 |   left: 0;
 32 |   top: 0;
 33 |   width: 1px;
 34 |   height: 1px;
 35 |   pointer-events: none;
 36 |   z-index: -1;
 37 |   opacity: 0;
 38 | }
 39 | 
 40 | .content {
 41 |   @include t.paddingVars($themeVars, $component);
 42 |   @include t.borderVars($themeVars, $component);
 43 |   font-size: $fontSize-Tooltip;
 44 |   line-height: $lineHeight-Tooltip;
 45 |   color: $textColor-Tooltip;
 46 |   background-color: $backgroundColor-Tooltip;
 47 |   box-shadow: $boxShadow-Tooltip;
 48 |   user-select: none;
 49 |   animation-duration: $animationDuration-Tooltip;
 50 |   animation-timing-function: $animation-Tooltip;
 51 |   will-change: transform, opacity;
 52 |   z-index: 9999;
 53 | }
 54 | 
 55 | .content[data-state='delayed-open'][data-side='top'] {
 56 |   animation-name: slideDownAndFade;
 57 | }
 58 | 
 59 | .content[data-state='delayed-open'][data-side='right'] {
 60 |   animation-name: slideLeftAndFade;
 61 | }
 62 | 
 63 | .content[data-state='delayed-open'][data-side='bottom'] {
 64 |   animation-name: slideUpAndFade;
 65 | }
 66 | 
 67 | .content[data-state='delayed-open'][data-side='left'] {
 68 |   animation-name: slideRightAndFade;
 69 | }
 70 | 
 71 | .arrow {
 72 |   fill: $fill-arrow-Tooltip;
 73 |   stroke: $stroke-arrow-Tooltip;
 74 |   stroke-width: $strokeWidth-arrow-Tooltip;
 75 | }
 76 | 
 77 | @keyframes slideUpAndFade {
 78 |   from {
 79 |     opacity: 0;
 80 |     transform: translateY(2px);
 81 |   }
 82 |   to {
 83 |     opacity: 1;
 84 |     transform: translateY(0);
 85 |   }
 86 | }
 87 | 
 88 | @keyframes slideRightAndFade {
 89 |   from {
 90 |     opacity: 0;
 91 |     transform: translateX(-2px);
 92 |   }
 93 |   to {
 94 |     opacity: 1;
 95 |     transform: translateX(0);
 96 |   }
 97 | }
 98 | 
 99 | @keyframes slideDownAndFade {
100 |   from {
101 |     opacity: 0;
102 |     transform: translateY(-2px);
103 |   }
104 |   to {
105 |     opacity: 1;
106 |     transform: translateY(0);
107 |   }
108 | }
109 | 
110 | @keyframes slideLeftAndFade {
111 |   from {
112 |     opacity: 0;
113 |     transform: translateX(2px);
114 |   }
115 |   to {
116 |     opacity: 1;
117 |     transform: translateX(0);
118 |   }
119 | }
120 | 
121 | // --- We export the theme variables to add them to the component renderer
122 | :export {
123 |   themeVars: t.json-stringify($themeVars);
124 | }
125 | 
```

--------------------------------------------------------------------------------
/xmlui/tests/parsers/scripting/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", () => {
  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 | 
```

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

```typescript
 1 | /**
 2 |  * Gets a proxy function for one that does not support async operations
 3 |  * @param fn Function to replace with a proxy
 4 |  * @param origArgs Original function arguments
 5 |  * @param context Function context ("this" of the function invocation)
 6 |  * @return The proxy, if found; otherwise the original function
 7 |  */
 8 | export function getAsyncProxy(fn: Function, origArgs: any[], context: any): Function {
 9 |     const proxyFn = asyncProxies.get(fn);
10 |     if (!proxyFn) return fn;
11 | 
12 |     origArgs.unshift(context);
13 |     return proxyFn;
14 | }
15 | 
16 | // Async implementations for JavaScript functions that do not support async arguments
17 | const asyncProxies = new Map<Function, Function>();
18 | asyncProxies.set(Array.prototype.filter, asyncFilter);
19 | asyncProxies.set(Array.prototype.forEach, asyncForEach);
20 | asyncProxies.set(Array.prototype.map, asyncMap);
21 | asyncProxies.set(Array.prototype.every, asyncEvery);
22 | asyncProxies.set(Array.prototype.findIndex, asyncFindIndex);
23 | asyncProxies.set(Array.prototype.find, asyncFind);
24 | asyncProxies.set(Array.prototype.flatMap, asyncFlatMap);
25 | asyncProxies.set(Array.prototype.some, asyncSome);
26 | 
27 | // The async implementation of Array.prototype.some
28 | async function asyncSome(arr: any[], predicate: (...args: any[]) => boolean) {
29 |   const results = await Promise.all(arr.map(predicate));
30 |   return arr.some((_v, index) => results[index]);
31 | }
32 | 
33 | // The async implementation of Array.prototype.filter
34 | async function asyncFilter(arr: any[], predicate: (...args: any[]) => boolean) {
35 |   const results = await Promise.all(arr.map(predicate));
36 |   return arr.filter((_v, index) => results[index]);
37 | }
38 | 
39 | // The async implementation of Array.prototype.forEach
40 | async function asyncForEach(arr: any[], predicate: (...args: any[]) => void) {
41 |   for (let i = 0; i < arr.length; i++) {
42 |     await predicate(arr[i], i, arr);
43 |   }
44 | }
45 | 
46 | // The async implementation of Array.prototype.map
47 | async function asyncMap(arr: any[], predicate: (...args: any[]) => Promise<any[]>) {
48 |   const result = [];
49 |   for (let i = 0; i < arr.length; i++) {
50 |     result.push(await predicate(arr[i], i, arr));
51 |   }
52 |   return result;
53 | }
54 | 
55 | // The async implementation of Array.prototype.asyncEvery
56 | async function asyncEvery(arr: any[], callback: (...args: any[]) => any) {
57 |   const results = await Promise.all(arr.map(callback));
58 |   return results.every((_v, index) => results[index]);
59 | }
60 | 
61 | // The async implementation of Array.prototype.asyncFind
62 | async function asyncFind(arr: any[], predicate: (...args: any[]) => boolean) {
63 |   const results = await Promise.all(arr.map(predicate));
64 |   return arr.find((_v, index) => results[index]);
65 | }
66 | 
67 | // The async implementation of Array.prototype.asyncFindIndex
68 | async function asyncFindIndex(arr: any[], predicate: (...args: any[]) => boolean) {
69 |   const results = await Promise.all(arr.map(predicate));
70 |   return arr.findIndex((_v, index) => results[index]);
71 | }
72 | 
73 | // The async implementation of Array.prototype.asyncFlatMap
74 | async function asyncFlatMap(arr: any[], predicate: (...args: any[]) => boolean) {
75 |   const results = await Promise.all(arr.map(predicate));
76 |   return arr.flatMap((_v, index) => results[index]);
77 | }
78 | 
```
Page 16/182FirstPrevNextLast