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

# Files

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

```markdown
  1 | # XMLUI Component Conventions
  2 | 
  3 | This document outlines the conventions and patterns used in the XMLUI component system, based on analysis of components like Avatar, Button, and Card.
  4 | 
  5 | ## Component Structure
  6 | 
  7 | ### Dual-File Pattern
  8 | 
  9 | Components are structured using a dual-file pattern:
 10 | 
 11 | - **Native Component** (`*Native.tsx`)
 12 |   - Pure React implementation
 13 |   - Uses `forwardRef` pattern
 14 |   - Contains the actual rendering logic
 15 |   - Defines prop types and default props
 16 | 
 17 | - **Renderer Component** (`.tsx`)
 18 |   - Provides metadata using `createMetadata`
 19 |   - Registers component with `createComponentRenderer`
 20 |   - Defines theme variables
 21 |   - Maps XMLUI props to native component props
 22 | 
 23 | Example relationship:
 24 | ```typescript
 25 | // Avatar.tsx (Renderer)
 26 | export const avatarComponentRenderer = createComponentRenderer(
 27 |   "Avatar",
 28 |   AvatarMd,
 29 |   ({ node, extractValue, lookupEventHandler, layoutCss, extractResourceUrl }) => {
 30 |     return (
 31 |       <Avatar
 32 |         size={node.props?.size}
 33 |         url={extractResourceUrl(node.props.url)}
 34 |         name={extractValue(node.props.name)}
 35 |         style={layoutCss}
 36 |         onClick={lookupEventHandler("click")}
 37 |       />
 38 |     );
 39 |   },
 40 | );
 41 | 
 42 | // AvatarNative.tsx (Implementation)
 43 | export const Avatar = forwardRef(function Avatar(
 44 |   { size = defaultProps.size, url, name, style, onClick, ...rest }: Props,
 45 |   ref: Ref<any>,
 46 | ) {
 47 |   // Implementation details...
 48 | });
 49 | ```
 50 | 
 51 | ### Single-File Pattern Variation
 52 | 
 53 | Some XMLUI components are implemented using a single-file pattern:
 54 | 
 55 | - **Combined Component** (`.tsx`)
 56 |   - Contains both the React implementation and XMLUI renderer in a single file
 57 |   - Defines metadata using `createMetadata`
 58 |   - Registers component with `createComponentRenderer`
 59 |   - Does not separate the implementation into a `*Native.tsx` file
 60 |   - Often used for simpler components or those that primarily compose other native components
 61 | 
 62 | Example: `ToneChangerButton.tsx` combines the implementation and renderer in one file:
 63 | 
 64 | ```typescript
 65 | export function ToneChangerButton({
 66 |   lightToDarkIcon = defaultProps.lightToDarkIcon,
 67 |   darkToLightIcon = defaultProps.darkToLightIcon,
 68 | }) {
 69 |   // Implementation...
 70 | }
 71 | 
 72 | export const toneChangerButtonComponentRenderer = createComponentRenderer(
 73 |   COMP,
 74 |   ToneChangerButtonMd,
 75 |   ({ node, extractValue }) => {
 76 |     return (
 77 |       <ToneChangerButton
 78 |         lightToDarkIcon={extractValue.asOptionalString(node.props.lightToDarkIcon)}
 79 |         darkToLightIcon={extractValue.asOptionalString(node.props.darkToLightIcon)}
 80 |       />
 81 |     );
 82 |   },
 83 | );
 84 | ```
 85 | 
 86 | This variation is still a fully functional XMLUI component and is registered in the ComponentProvider, making it available in XMLUI markup.
 87 | 
 88 | ## Component API and State
 89 | 
 90 | ### API Registration
 91 | 
 92 | Components expose methods through a standardized API registration pattern:
 93 | 
 94 | ```typescript
 95 | useEffect(() => {
 96 |   registerComponentApi?.({
 97 |     setValue,
 98 |     focus,
 99 |   });
100 | }, [registerComponentApi, setValue, focus]);
101 | ```
102 | 
103 | ### State Synchronization
104 | 
105 | Components keep their internal state synchronized with XMLUI:
106 | 
107 | ```typescript
108 | // Update component state and notify XMLUI
109 | const setValue = useEvent((newValue) => {
110 |   setInternalState(newValue);
111 |   updateState?.({ value: newValue });
112 | });
113 | 
114 | // Sync state on initial render or changes
115 | useEffect(() => {
116 |   updateState?.({ value: currentState });
117 | }, [updateState, currentState]);
118 | ```
119 | 
120 | ## Event Handling
121 | 
122 | Events are:
123 | 1. Declared in component metadata
124 | 2. Implemented in the native component
125 | 3. Connected via `lookupEventHandler` in the renderer
126 | 
127 | Common events:
128 | - `click` / `onClick`
129 | - `didChange` (value changes)
130 | - `gotFocus` / `lostFocus`
131 | - Component-specific events (e.g., `onReset`)
132 | 
133 | ## Styling and Theming
134 | 
135 | ### SCSS Module Pattern
136 | 
137 | - Each component has its own SCSS module (e.g., `Avatar.module.scss`)
138 | - Theme variables follow naming convention: `propertyName-ComponentName`
139 | - Variables are exported and parsed with `parseScssVar`
140 | - CSS classes are composed with the `classnames` library
141 | 
142 | ### Theme Variables
143 | 
144 | Theme variables are defined in the component metadata:
145 | 
146 | ```typescript
147 | defaultThemeVars: {
148 |   [`borderRadius-${COMP}`]: "4px",
149 |   [`boxShadow-${COMP}`]: "inset 0 0 0 1px rgba(4,32,69,0.1)",
150 |   [`textColor-${COMP}`]: "$textColor-secondary",
151 |   // ...other variables
152 | }
153 | ```
154 | 
155 | Components can be styled using the theme system or through direct props.
156 | 
157 | ## Component Registration
158 | 
159 | Components are registered with the `ComponentRegistry` during framework initialization:
160 | 
161 | ```typescript
162 | if (process.env.VITE_USED_COMPONENTS_Avatar !== "false") {
163 |   this.registerCoreComponent(avatarComponentRenderer);
164 | }
165 | ```
166 | 
167 | This allows conditional inclusion of components and provides centralized component management.
168 | 
169 | ## Testing
170 | 
171 | Components use a driver pattern for testing:
172 | 
173 | ```typescript
174 | // Each component has a dedicated driver class
175 | export class AvatarDriver extends ComponentDriver {
176 |   // Driver-specific methods
177 | }
178 | 
179 | // Used in tests
180 | test("can render 2 initials", async ({ initTestBed, createAvatarDriver }) => {
181 |   await initTestBed(`<Avatar name="Tim Smith"/>`);
182 |   await expect((await createAvatarDriver()).component).toContainText("TS");
183 | });
184 | ```
185 | 
186 | ## Reusable Component System
187 | 
188 | XMLUI supports user-defined components using the `<Component>` tag:
189 | 
190 | ```xml
191 | <Component name="InfoCard">
192 |   <Card width="{$props.width}" borderRadius="8px" boxShadow="$boxShadow-spread">
193 |     <Text>{$props.title}</Text>
194 |     <Text fontWeight="$fontWeight-extra-bold" fontSize="larger">
195 |       { $props.currency === 'true' ? '$' + $props.value : $props.value }
196 |     </Text>
197 |   </Card>
198 | </Component>
199 | ```
200 | 
201 | Components can access properties via `$props` context variable, and expose methods through the API registration mechanism.
202 | 
203 | ## Layout Integration
204 | 
205 | Components behave differently depending on their parent layout containers:
206 | 
207 | - In `Stack` layouts, component layout properties might be ignored
208 | - In `FlowLayout`, components get wrapped in container elements
209 | - Explicit layout containers within components help control arrangement
210 | 
211 | ## Native-Only React Components
212 | 
213 | The following components in the XMLUI codebase are implemented as native React components only. These components don't have corresponding XMLUI renderers registered in the ComponentProvider and are not directly available in XMLUI markup. Instead, they serve as internal implementation details, UI utilities, or components used by other XMLUI components.
214 | 
215 | - `InspectButton`: A button component used for turning inspection mode on/off in XMLUI development environment
216 | - `ProfileMenu`: A profile menu component used within other components but not exposed directly to XMLUI
217 | - `Toggle`: A toggle component that provides base functionality that may be used by other components
218 | - `VisuallyHidden`: A utility component that wraps Radix UI's VisuallyHidden for accessibility
219 | - `SlotItem`: An internal component for implementing the slot mechanism
220 | - `IconProvider`: Provides icon context for the icon system
221 | - `IconRegistryContext`: Manages icon registry context
222 | 
223 | ### Component Structure Observations
224 | 
225 | 1. **Pure Native Components** tend to:
226 |    - Be located in a single file (no paired renderer)
227 |    - Have a `.tsx` extension (sometimes with a `.module.scss` file)
228 |    - Not include `createComponentRenderer` or `createMetadata` calls
229 |    - Often be used internally by other XMLUI components
230 | 
231 | 2. **Helper Components**:
232 |    - Typically simple with a focused utility purpose
233 |    - May be wrappers around third-party components
234 |    - Often have minimal props and internal state
235 | 
236 | These native-only components demonstrate the architectural separation in XMLUI, where not every React component needs to be exposed to the XMLUI markup language. This separation enables internal implementation flexibility while maintaining a clean API surface for XMLUI users.
237 | 
238 | ## Best Practices
239 | 
240 | 1. Keep native component implementations pure and focused
241 | 2. Define clear metadata and documentation for components
242 | 3. Support proper theming through theme variables
243 | 4. Implement consistent API and event patterns
244 | 5. Ensure proper testing with component drivers
245 | 6. Support accessibility through ARIA attributes and keyboard navigation
246 | 7. Ensure proper reference forwarding through `forwardRef`
247 | 8. Provide sensible defaults for all props
248 | 
```

--------------------------------------------------------------------------------
/blog/public/mockServiceWorker.js:
--------------------------------------------------------------------------------

```javascript
  1 | /* eslint-disable */
  2 | /* tslint:disable */
  3 | 
  4 | /**
  5 |  * Mock Service Worker.
  6 |  * @see https://github.com/mswjs/msw
  7 |  * - Please do NOT modify this file.
  8 |  * - Please do NOT serve this file on production.
  9 |  */
 10 | 
 11 | const PACKAGE_VERSION = '2.8.4'
 12 | const INTEGRITY_CHECKSUM = '00729d72e3b82faf54ca8b9621dbb96f'
 13 | const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
 14 | const activeClientIds = new Set()
 15 | 
 16 | self.addEventListener('install', function () {
 17 |   self.skipWaiting()
 18 | })
 19 | 
 20 | self.addEventListener('activate', function (event) {
 21 |   event.waitUntil(self.clients.claim())
 22 | })
 23 | 
 24 | self.addEventListener('message', async function (event) {
 25 |   const clientId = event.source.id
 26 | 
 27 |   if (!clientId || !self.clients) {
 28 |     return
 29 |   }
 30 | 
 31 |   const client = await self.clients.get(clientId)
 32 | 
 33 |   if (!client) {
 34 |     return
 35 |   }
 36 | 
 37 |   const allClients = await self.clients.matchAll({
 38 |     type: 'window',
 39 |   })
 40 | 
 41 |   switch (event.data) {
 42 |     case 'KEEPALIVE_REQUEST': {
 43 |       sendToClient(client, {
 44 |         type: 'KEEPALIVE_RESPONSE',
 45 |       })
 46 |       break
 47 |     }
 48 | 
 49 |     case 'INTEGRITY_CHECK_REQUEST': {
 50 |       sendToClient(client, {
 51 |         type: 'INTEGRITY_CHECK_RESPONSE',
 52 |         payload: {
 53 |           packageVersion: PACKAGE_VERSION,
 54 |           checksum: INTEGRITY_CHECKSUM,
 55 |         },
 56 |       })
 57 |       break
 58 |     }
 59 | 
 60 |     case 'MOCK_ACTIVATE': {
 61 |       activeClientIds.add(clientId)
 62 | 
 63 |       sendToClient(client, {
 64 |         type: 'MOCKING_ENABLED',
 65 |         payload: {
 66 |           client: {
 67 |             id: client.id,
 68 |             frameType: client.frameType,
 69 |           },
 70 |         },
 71 |       })
 72 |       break
 73 |     }
 74 | 
 75 |     case 'MOCK_DEACTIVATE': {
 76 |       activeClientIds.delete(clientId)
 77 |       break
 78 |     }
 79 | 
 80 |     case 'CLIENT_CLOSED': {
 81 |       activeClientIds.delete(clientId)
 82 | 
 83 |       const remainingClients = allClients.filter((client) => {
 84 |         return client.id !== clientId
 85 |       })
 86 | 
 87 |       // Unregister itself when there are no more clients
 88 |       if (remainingClients.length === 0) {
 89 |         self.registration.unregister()
 90 |       }
 91 | 
 92 |       break
 93 |     }
 94 |   }
 95 | })
 96 | 
 97 | self.addEventListener('fetch', function (event) {
 98 |   const { request } = event
 99 | 
100 |   // Bypass navigation requests.
101 |   if (request.mode === 'navigate') {
102 |     return
103 |   }
104 | 
105 |   // Opening the DevTools triggers the "only-if-cached" request
106 |   // that cannot be handled by the worker. Bypass such requests.
107 |   if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
108 |     return
109 |   }
110 | 
111 |   // Bypass all requests when there are no active clients.
112 |   // Prevents the self-unregistered worked from handling requests
113 |   // after it's been deleted (still remains active until the next reload).
114 |   if (activeClientIds.size === 0) {
115 |     return
116 |   }
117 | 
118 |   // Generate unique request ID.
119 |   const requestId = crypto.randomUUID()
120 |   event.respondWith(handleRequest(event, requestId))
121 | })
122 | 
123 | async function handleRequest(event, requestId) {
124 |   const client = await resolveMainClient(event)
125 |   const response = await getResponse(event, client, requestId)
126 | 
127 |   // Send back the response clone for the "response:*" life-cycle events.
128 |   // Ensure MSW is active and ready to handle the message, otherwise
129 |   // this message will pend indefinitely.
130 |   if (client && activeClientIds.has(client.id)) {
131 |     ;(async function () {
132 |       const responseClone = response.clone()
133 | 
134 |       sendToClient(
135 |         client,
136 |         {
137 |           type: 'RESPONSE',
138 |           payload: {
139 |             requestId,
140 |             isMockedResponse: IS_MOCKED_RESPONSE in response,
141 |             type: responseClone.type,
142 |             status: responseClone.status,
143 |             statusText: responseClone.statusText,
144 |             body: responseClone.body,
145 |             headers: Object.fromEntries(responseClone.headers.entries()),
146 |           },
147 |         },
148 |         [responseClone.body],
149 |       )
150 |     })()
151 |   }
152 | 
153 |   return response
154 | }
155 | 
156 | // Resolve the main client for the given event.
157 | // Client that issues a request doesn't necessarily equal the client
158 | // that registered the worker. It's with the latter the worker should
159 | // communicate with during the response resolving phase.
160 | async function resolveMainClient(event) {
161 |   const client = await self.clients.get(event.clientId)
162 | 
163 |   if (activeClientIds.has(event.clientId)) {
164 |     return client
165 |   }
166 | 
167 |   if (client?.frameType === 'top-level') {
168 |     return client
169 |   }
170 | 
171 |   const allClients = await self.clients.matchAll({
172 |     type: 'window',
173 |   })
174 | 
175 |   return allClients
176 |     .filter((client) => {
177 |       // Get only those clients that are currently visible.
178 |       return client.visibilityState === 'visible'
179 |     })
180 |     .find((client) => {
181 |       // Find the client ID that's recorded in the
182 |       // set of clients that have registered the worker.
183 |       return activeClientIds.has(client.id)
184 |     })
185 | }
186 | 
187 | async function getResponse(event, client, requestId) {
188 |   const { request } = event
189 | 
190 |   // Clone the request because it might've been already used
191 |   // (i.e. its body has been read and sent to the client).
192 |   const requestClone = request.clone()
193 | 
194 |   function passthrough() {
195 |     // Cast the request headers to a new Headers instance
196 |     // so the headers can be manipulated with.
197 |     const headers = new Headers(requestClone.headers)
198 | 
199 |     // Remove the "accept" header value that marked this request as passthrough.
200 |     // This prevents request alteration and also keeps it compliant with the
201 |     // user-defined CORS policies.
202 |     const acceptHeader = headers.get('accept')
203 |     if (acceptHeader) {
204 |       const values = acceptHeader.split(',').map((value) => value.trim())
205 |       const filteredValues = values.filter(
206 |         (value) => value !== 'msw/passthrough',
207 |       )
208 | 
209 |       if (filteredValues.length > 0) {
210 |         headers.set('accept', filteredValues.join(', '))
211 |       } else {
212 |         headers.delete('accept')
213 |       }
214 |     }
215 | 
216 |     return fetch(requestClone, { headers })
217 |   }
218 | 
219 |   // Bypass mocking when the client is not active.
220 |   if (!client) {
221 |     return passthrough()
222 |   }
223 | 
224 |   // Bypass initial page load requests (i.e. static assets).
225 |   // The absence of the immediate/parent client in the map of the active clients
226 |   // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
227 |   // and is not ready to handle requests.
228 |   if (!activeClientIds.has(client.id)) {
229 |     return passthrough()
230 |   }
231 | 
232 |   // Notify the client that a request has been intercepted.
233 |   const requestBuffer = await request.arrayBuffer()
234 |   const clientMessage = await sendToClient(
235 |     client,
236 |     {
237 |       type: 'REQUEST',
238 |       payload: {
239 |         id: requestId,
240 |         url: request.url,
241 |         mode: request.mode,
242 |         method: request.method,
243 |         headers: Object.fromEntries(request.headers.entries()),
244 |         cache: request.cache,
245 |         credentials: request.credentials,
246 |         destination: request.destination,
247 |         integrity: request.integrity,
248 |         redirect: request.redirect,
249 |         referrer: request.referrer,
250 |         referrerPolicy: request.referrerPolicy,
251 |         body: requestBuffer,
252 |         keepalive: request.keepalive,
253 |       },
254 |     },
255 |     [requestBuffer],
256 |   )
257 | 
258 |   switch (clientMessage.type) {
259 |     case 'MOCK_RESPONSE': {
260 |       return respondWithMock(clientMessage.data)
261 |     }
262 | 
263 |     case 'PASSTHROUGH': {
264 |       return passthrough()
265 |     }
266 |   }
267 | 
268 |   return passthrough()
269 | }
270 | 
271 | function sendToClient(client, message, transferrables = []) {
272 |   return new Promise((resolve, reject) => {
273 |     const channel = new MessageChannel()
274 | 
275 |     channel.port1.onmessage = (event) => {
276 |       if (event.data && event.data.error) {
277 |         return reject(event.data.error)
278 |       }
279 | 
280 |       resolve(event.data)
281 |     }
282 | 
283 |     client.postMessage(
284 |       message,
285 |       [channel.port2].concat(transferrables.filter(Boolean)),
286 |     )
287 |   })
288 | }
289 | 
290 | async function respondWithMock(response) {
291 |   // Setting response status code to 0 is a no-op.
292 |   // However, when responding with a "Response.error()", the produced Response
293 |   // instance will have status code set to 0. Since it's not possible to create
294 |   // a Response instance with status code 0, handle that use-case separately.
295 |   if (response.status === 0) {
296 |     return Response.error()
297 |   }
298 | 
299 |   const mockedResponse = new Response(response.body, response)
300 | 
301 |   Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, {
302 |     value: true,
303 |     enumerable: true,
304 |   })
305 | 
306 |   return mockedResponse
307 | }
308 | 
```

--------------------------------------------------------------------------------
/docs/public/mockServiceWorker.js:
--------------------------------------------------------------------------------

```javascript
  1 | /* eslint-disable */
  2 | /* tslint:disable */
  3 | 
  4 | /**
  5 |  * Mock Service Worker.
  6 |  * @see https://github.com/mswjs/msw
  7 |  * - Please do NOT modify this file.
  8 |  * - Please do NOT serve this file on production.
  9 |  */
 10 | 
 11 | const PACKAGE_VERSION = '2.8.4'
 12 | const INTEGRITY_CHECKSUM = '00729d72e3b82faf54ca8b9621dbb96f'
 13 | const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
 14 | const activeClientIds = new Set()
 15 | 
 16 | self.addEventListener('install', function () {
 17 |   self.skipWaiting()
 18 | })
 19 | 
 20 | self.addEventListener('activate', function (event) {
 21 |   event.waitUntil(self.clients.claim())
 22 | })
 23 | 
 24 | self.addEventListener('message', async function (event) {
 25 |   const clientId = event.source.id
 26 | 
 27 |   if (!clientId || !self.clients) {
 28 |     return
 29 |   }
 30 | 
 31 |   const client = await self.clients.get(clientId)
 32 | 
 33 |   if (!client) {
 34 |     return
 35 |   }
 36 | 
 37 |   const allClients = await self.clients.matchAll({
 38 |     type: 'window',
 39 |   })
 40 | 
 41 |   switch (event.data) {
 42 |     case 'KEEPALIVE_REQUEST': {
 43 |       sendToClient(client, {
 44 |         type: 'KEEPALIVE_RESPONSE',
 45 |       })
 46 |       break
 47 |     }
 48 | 
 49 |     case 'INTEGRITY_CHECK_REQUEST': {
 50 |       sendToClient(client, {
 51 |         type: 'INTEGRITY_CHECK_RESPONSE',
 52 |         payload: {
 53 |           packageVersion: PACKAGE_VERSION,
 54 |           checksum: INTEGRITY_CHECKSUM,
 55 |         },
 56 |       })
 57 |       break
 58 |     }
 59 | 
 60 |     case 'MOCK_ACTIVATE': {
 61 |       activeClientIds.add(clientId)
 62 | 
 63 |       sendToClient(client, {
 64 |         type: 'MOCKING_ENABLED',
 65 |         payload: {
 66 |           client: {
 67 |             id: client.id,
 68 |             frameType: client.frameType,
 69 |           },
 70 |         },
 71 |       })
 72 |       break
 73 |     }
 74 | 
 75 |     case 'MOCK_DEACTIVATE': {
 76 |       activeClientIds.delete(clientId)
 77 |       break
 78 |     }
 79 | 
 80 |     case 'CLIENT_CLOSED': {
 81 |       activeClientIds.delete(clientId)
 82 | 
 83 |       const remainingClients = allClients.filter((client) => {
 84 |         return client.id !== clientId
 85 |       })
 86 | 
 87 |       // Unregister itself when there are no more clients
 88 |       if (remainingClients.length === 0) {
 89 |         self.registration.unregister()
 90 |       }
 91 | 
 92 |       break
 93 |     }
 94 |   }
 95 | })
 96 | 
 97 | self.addEventListener('fetch', function (event) {
 98 |   const { request } = event
 99 | 
100 |   // Bypass navigation requests.
101 |   if (request.mode === 'navigate') {
102 |     return
103 |   }
104 | 
105 |   // Opening the DevTools triggers the "only-if-cached" request
106 |   // that cannot be handled by the worker. Bypass such requests.
107 |   if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
108 |     return
109 |   }
110 | 
111 |   // Bypass all requests when there are no active clients.
112 |   // Prevents the self-unregistered worked from handling requests
113 |   // after it's been deleted (still remains active until the next reload).
114 |   if (activeClientIds.size === 0) {
115 |     return
116 |   }
117 | 
118 |   // Generate unique request ID.
119 |   const requestId = crypto.randomUUID()
120 |   event.respondWith(handleRequest(event, requestId))
121 | })
122 | 
123 | async function handleRequest(event, requestId) {
124 |   const client = await resolveMainClient(event)
125 |   const response = await getResponse(event, client, requestId)
126 | 
127 |   // Send back the response clone for the "response:*" life-cycle events.
128 |   // Ensure MSW is active and ready to handle the message, otherwise
129 |   // this message will pend indefinitely.
130 |   if (client && activeClientIds.has(client.id)) {
131 |     ;(async function () {
132 |       const responseClone = response.clone()
133 | 
134 |       sendToClient(
135 |         client,
136 |         {
137 |           type: 'RESPONSE',
138 |           payload: {
139 |             requestId,
140 |             isMockedResponse: IS_MOCKED_RESPONSE in response,
141 |             type: responseClone.type,
142 |             status: responseClone.status,
143 |             statusText: responseClone.statusText,
144 |             body: responseClone.body,
145 |             headers: Object.fromEntries(responseClone.headers.entries()),
146 |           },
147 |         },
148 |         [responseClone.body],
149 |       )
150 |     })()
151 |   }
152 | 
153 |   return response
154 | }
155 | 
156 | // Resolve the main client for the given event.
157 | // Client that issues a request doesn't necessarily equal the client
158 | // that registered the worker. It's with the latter the worker should
159 | // communicate with during the response resolving phase.
160 | async function resolveMainClient(event) {
161 |   const client = await self.clients.get(event.clientId)
162 | 
163 |   if (activeClientIds.has(event.clientId)) {
164 |     return client
165 |   }
166 | 
167 |   if (client?.frameType === 'top-level') {
168 |     return client
169 |   }
170 | 
171 |   const allClients = await self.clients.matchAll({
172 |     type: 'window',
173 |   })
174 | 
175 |   return allClients
176 |     .filter((client) => {
177 |       // Get only those clients that are currently visible.
178 |       return client.visibilityState === 'visible'
179 |     })
180 |     .find((client) => {
181 |       // Find the client ID that's recorded in the
182 |       // set of clients that have registered the worker.
183 |       return activeClientIds.has(client.id)
184 |     })
185 | }
186 | 
187 | async function getResponse(event, client, requestId) {
188 |   const { request } = event
189 | 
190 |   // Clone the request because it might've been already used
191 |   // (i.e. its body has been read and sent to the client).
192 |   const requestClone = request.clone()
193 | 
194 |   function passthrough() {
195 |     // Cast the request headers to a new Headers instance
196 |     // so the headers can be manipulated with.
197 |     const headers = new Headers(requestClone.headers)
198 | 
199 |     // Remove the "accept" header value that marked this request as passthrough.
200 |     // This prevents request alteration and also keeps it compliant with the
201 |     // user-defined CORS policies.
202 |     const acceptHeader = headers.get('accept')
203 |     if (acceptHeader) {
204 |       const values = acceptHeader.split(',').map((value) => value.trim())
205 |       const filteredValues = values.filter(
206 |         (value) => value !== 'msw/passthrough',
207 |       )
208 | 
209 |       if (filteredValues.length > 0) {
210 |         headers.set('accept', filteredValues.join(', '))
211 |       } else {
212 |         headers.delete('accept')
213 |       }
214 |     }
215 | 
216 |     return fetch(requestClone, { headers })
217 |   }
218 | 
219 |   // Bypass mocking when the client is not active.
220 |   if (!client) {
221 |     return passthrough()
222 |   }
223 | 
224 |   // Bypass initial page load requests (i.e. static assets).
225 |   // The absence of the immediate/parent client in the map of the active clients
226 |   // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
227 |   // and is not ready to handle requests.
228 |   if (!activeClientIds.has(client.id)) {
229 |     return passthrough()
230 |   }
231 | 
232 |   // Notify the client that a request has been intercepted.
233 |   const requestBuffer = await request.arrayBuffer()
234 |   const clientMessage = await sendToClient(
235 |     client,
236 |     {
237 |       type: 'REQUEST',
238 |       payload: {
239 |         id: requestId,
240 |         url: request.url,
241 |         mode: request.mode,
242 |         method: request.method,
243 |         headers: Object.fromEntries(request.headers.entries()),
244 |         cache: request.cache,
245 |         credentials: request.credentials,
246 |         destination: request.destination,
247 |         integrity: request.integrity,
248 |         redirect: request.redirect,
249 |         referrer: request.referrer,
250 |         referrerPolicy: request.referrerPolicy,
251 |         body: requestBuffer,
252 |         keepalive: request.keepalive,
253 |       },
254 |     },
255 |     [requestBuffer],
256 |   )
257 | 
258 |   switch (clientMessage.type) {
259 |     case 'MOCK_RESPONSE': {
260 |       return respondWithMock(clientMessage.data)
261 |     }
262 | 
263 |     case 'PASSTHROUGH': {
264 |       return passthrough()
265 |     }
266 |   }
267 | 
268 |   return passthrough()
269 | }
270 | 
271 | function sendToClient(client, message, transferrables = []) {
272 |   return new Promise((resolve, reject) => {
273 |     const channel = new MessageChannel()
274 | 
275 |     channel.port1.onmessage = (event) => {
276 |       if (event.data && event.data.error) {
277 |         return reject(event.data.error)
278 |       }
279 | 
280 |       resolve(event.data)
281 |     }
282 | 
283 |     client.postMessage(
284 |       message,
285 |       [channel.port2].concat(transferrables.filter(Boolean)),
286 |     )
287 |   })
288 | }
289 | 
290 | async function respondWithMock(response) {
291 |   // Setting response status code to 0 is a no-op.
292 |   // However, when responding with a "Response.error()", the produced Response
293 |   // instance will have status code set to 0. Since it's not possible to create
294 |   // a Response instance with status code 0, handle that use-case separately.
295 |   if (response.status === 0) {
296 |     return Response.error()
297 |   }
298 | 
299 |   const mockedResponse = new Response(response.body, response)
300 | 
301 |   Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, {
302 |     value: true,
303 |     enumerable: true,
304 |   })
305 | 
306 |   return mockedResponse
307 | }
308 | 
```

--------------------------------------------------------------------------------
/tools/create-app/templates/default/ts/public/mockServiceWorker.js:
--------------------------------------------------------------------------------

```javascript
  1 | /* eslint-disable */
  2 | /* tslint:disable */
  3 | 
  4 | /**
  5 |  * Mock Service Worker.
  6 |  * @see https://github.com/mswjs/msw
  7 |  * - Please do NOT modify this file.
  8 |  * - Please do NOT serve this file on production.
  9 |  */
 10 | 
 11 | const PACKAGE_VERSION = '2.8.4'
 12 | const INTEGRITY_CHECKSUM = '00729d72e3b82faf54ca8b9621dbb96f'
 13 | const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
 14 | const activeClientIds = new Set()
 15 | 
 16 | self.addEventListener('install', function () {
 17 |   self.skipWaiting()
 18 | })
 19 | 
 20 | self.addEventListener('activate', function (event) {
 21 |   event.waitUntil(self.clients.claim())
 22 | })
 23 | 
 24 | self.addEventListener('message', async function (event) {
 25 |   const clientId = event.source.id
 26 | 
 27 |   if (!clientId || !self.clients) {
 28 |     return
 29 |   }
 30 | 
 31 |   const client = await self.clients.get(clientId)
 32 | 
 33 |   if (!client) {
 34 |     return
 35 |   }
 36 | 
 37 |   const allClients = await self.clients.matchAll({
 38 |     type: 'window',
 39 |   })
 40 | 
 41 |   switch (event.data) {
 42 |     case 'KEEPALIVE_REQUEST': {
 43 |       sendToClient(client, {
 44 |         type: 'KEEPALIVE_RESPONSE',
 45 |       })
 46 |       break
 47 |     }
 48 | 
 49 |     case 'INTEGRITY_CHECK_REQUEST': {
 50 |       sendToClient(client, {
 51 |         type: 'INTEGRITY_CHECK_RESPONSE',
 52 |         payload: {
 53 |           packageVersion: PACKAGE_VERSION,
 54 |           checksum: INTEGRITY_CHECKSUM,
 55 |         },
 56 |       })
 57 |       break
 58 |     }
 59 | 
 60 |     case 'MOCK_ACTIVATE': {
 61 |       activeClientIds.add(clientId)
 62 | 
 63 |       sendToClient(client, {
 64 |         type: 'MOCKING_ENABLED',
 65 |         payload: {
 66 |           client: {
 67 |             id: client.id,
 68 |             frameType: client.frameType,
 69 |           },
 70 |         },
 71 |       })
 72 |       break
 73 |     }
 74 | 
 75 |     case 'MOCK_DEACTIVATE': {
 76 |       activeClientIds.delete(clientId)
 77 |       break
 78 |     }
 79 | 
 80 |     case 'CLIENT_CLOSED': {
 81 |       activeClientIds.delete(clientId)
 82 | 
 83 |       const remainingClients = allClients.filter((client) => {
 84 |         return client.id !== clientId
 85 |       })
 86 | 
 87 |       // Unregister itself when there are no more clients
 88 |       if (remainingClients.length === 0) {
 89 |         self.registration.unregister()
 90 |       }
 91 | 
 92 |       break
 93 |     }
 94 |   }
 95 | })
 96 | 
 97 | self.addEventListener('fetch', function (event) {
 98 |   const { request } = event
 99 | 
100 |   // Bypass navigation requests.
101 |   if (request.mode === 'navigate') {
102 |     return
103 |   }
104 | 
105 |   // Opening the DevTools triggers the "only-if-cached" request
106 |   // that cannot be handled by the worker. Bypass such requests.
107 |   if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
108 |     return
109 |   }
110 | 
111 |   // Bypass all requests when there are no active clients.
112 |   // Prevents the self-unregistered worked from handling requests
113 |   // after it's been deleted (still remains active until the next reload).
114 |   if (activeClientIds.size === 0) {
115 |     return
116 |   }
117 | 
118 |   // Generate unique request ID.
119 |   const requestId = crypto.randomUUID()
120 |   event.respondWith(handleRequest(event, requestId))
121 | })
122 | 
123 | async function handleRequest(event, requestId) {
124 |   const client = await resolveMainClient(event)
125 |   const response = await getResponse(event, client, requestId)
126 | 
127 |   // Send back the response clone for the "response:*" life-cycle events.
128 |   // Ensure MSW is active and ready to handle the message, otherwise
129 |   // this message will pend indefinitely.
130 |   if (client && activeClientIds.has(client.id)) {
131 |     ;(async function () {
132 |       const responseClone = response.clone()
133 | 
134 |       sendToClient(
135 |         client,
136 |         {
137 |           type: 'RESPONSE',
138 |           payload: {
139 |             requestId,
140 |             isMockedResponse: IS_MOCKED_RESPONSE in response,
141 |             type: responseClone.type,
142 |             status: responseClone.status,
143 |             statusText: responseClone.statusText,
144 |             body: responseClone.body,
145 |             headers: Object.fromEntries(responseClone.headers.entries()),
146 |           },
147 |         },
148 |         [responseClone.body],
149 |       )
150 |     })()
151 |   }
152 | 
153 |   return response
154 | }
155 | 
156 | // Resolve the main client for the given event.
157 | // Client that issues a request doesn't necessarily equal the client
158 | // that registered the worker. It's with the latter the worker should
159 | // communicate with during the response resolving phase.
160 | async function resolveMainClient(event) {
161 |   const client = await self.clients.get(event.clientId)
162 | 
163 |   if (activeClientIds.has(event.clientId)) {
164 |     return client
165 |   }
166 | 
167 |   if (client?.frameType === 'top-level') {
168 |     return client
169 |   }
170 | 
171 |   const allClients = await self.clients.matchAll({
172 |     type: 'window',
173 |   })
174 | 
175 |   return allClients
176 |     .filter((client) => {
177 |       // Get only those clients that are currently visible.
178 |       return client.visibilityState === 'visible'
179 |     })
180 |     .find((client) => {
181 |       // Find the client ID that's recorded in the
182 |       // set of clients that have registered the worker.
183 |       return activeClientIds.has(client.id)
184 |     })
185 | }
186 | 
187 | async function getResponse(event, client, requestId) {
188 |   const { request } = event
189 | 
190 |   // Clone the request because it might've been already used
191 |   // (i.e. its body has been read and sent to the client).
192 |   const requestClone = request.clone()
193 | 
194 |   function passthrough() {
195 |     // Cast the request headers to a new Headers instance
196 |     // so the headers can be manipulated with.
197 |     const headers = new Headers(requestClone.headers)
198 | 
199 |     // Remove the "accept" header value that marked this request as passthrough.
200 |     // This prevents request alteration and also keeps it compliant with the
201 |     // user-defined CORS policies.
202 |     const acceptHeader = headers.get('accept')
203 |     if (acceptHeader) {
204 |       const values = acceptHeader.split(',').map((value) => value.trim())
205 |       const filteredValues = values.filter(
206 |         (value) => value !== 'msw/passthrough',
207 |       )
208 | 
209 |       if (filteredValues.length > 0) {
210 |         headers.set('accept', filteredValues.join(', '))
211 |       } else {
212 |         headers.delete('accept')
213 |       }
214 |     }
215 | 
216 |     return fetch(requestClone, { headers })
217 |   }
218 | 
219 |   // Bypass mocking when the client is not active.
220 |   if (!client) {
221 |     return passthrough()
222 |   }
223 | 
224 |   // Bypass initial page load requests (i.e. static assets).
225 |   // The absence of the immediate/parent client in the map of the active clients
226 |   // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
227 |   // and is not ready to handle requests.
228 |   if (!activeClientIds.has(client.id)) {
229 |     return passthrough()
230 |   }
231 | 
232 |   // Notify the client that a request has been intercepted.
233 |   const requestBuffer = await request.arrayBuffer()
234 |   const clientMessage = await sendToClient(
235 |     client,
236 |     {
237 |       type: 'REQUEST',
238 |       payload: {
239 |         id: requestId,
240 |         url: request.url,
241 |         mode: request.mode,
242 |         method: request.method,
243 |         headers: Object.fromEntries(request.headers.entries()),
244 |         cache: request.cache,
245 |         credentials: request.credentials,
246 |         destination: request.destination,
247 |         integrity: request.integrity,
248 |         redirect: request.redirect,
249 |         referrer: request.referrer,
250 |         referrerPolicy: request.referrerPolicy,
251 |         body: requestBuffer,
252 |         keepalive: request.keepalive,
253 |       },
254 |     },
255 |     [requestBuffer],
256 |   )
257 | 
258 |   switch (clientMessage.type) {
259 |     case 'MOCK_RESPONSE': {
260 |       return respondWithMock(clientMessage.data)
261 |     }
262 | 
263 |     case 'PASSTHROUGH': {
264 |       return passthrough()
265 |     }
266 |   }
267 | 
268 |   return passthrough()
269 | }
270 | 
271 | function sendToClient(client, message, transferrables = []) {
272 |   return new Promise((resolve, reject) => {
273 |     const channel = new MessageChannel()
274 | 
275 |     channel.port1.onmessage = (event) => {
276 |       if (event.data && event.data.error) {
277 |         return reject(event.data.error)
278 |       }
279 | 
280 |       resolve(event.data)
281 |     }
282 | 
283 |     client.postMessage(
284 |       message,
285 |       [channel.port2].concat(transferrables.filter(Boolean)),
286 |     )
287 |   })
288 | }
289 | 
290 | async function respondWithMock(response) {
291 |   // Setting response status code to 0 is a no-op.
292 |   // However, when responding with a "Response.error()", the produced Response
293 |   // instance will have status code set to 0. Since it's not possible to create
294 |   // a Response instance with status code 0, handle that use-case separately.
295 |   if (response.status === 0) {
296 |     return Response.error()
297 |   }
298 | 
299 |   const mockedResponse = new Response(response.body, response)
300 | 
301 |   Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, {
302 |     value: true,
303 |     enumerable: true,
304 |   })
305 | 
306 |   return mockedResponse
307 | }
308 | 
```

--------------------------------------------------------------------------------
/xmlui/src/testing/infrastructure/public/mockServiceWorker.js:
--------------------------------------------------------------------------------

```javascript
  1 | /* eslint-disable */
  2 | /* tslint:disable */
  3 | 
  4 | /**
  5 |  * Mock Service Worker.
  6 |  * @see https://github.com/mswjs/msw
  7 |  * - Please do NOT modify this file.
  8 |  * - Please do NOT serve this file on production.
  9 |  */
 10 | 
 11 | const PACKAGE_VERSION = '2.8.4'
 12 | const INTEGRITY_CHECKSUM = '00729d72e3b82faf54ca8b9621dbb96f'
 13 | const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
 14 | const activeClientIds = new Set()
 15 | 
 16 | self.addEventListener('install', function () {
 17 |   self.skipWaiting()
 18 | })
 19 | 
 20 | self.addEventListener('activate', function (event) {
 21 |   event.waitUntil(self.clients.claim())
 22 | })
 23 | 
 24 | self.addEventListener('message', async function (event) {
 25 |   const clientId = event.source.id
 26 | 
 27 |   if (!clientId || !self.clients) {
 28 |     return
 29 |   }
 30 | 
 31 |   const client = await self.clients.get(clientId)
 32 | 
 33 |   if (!client) {
 34 |     return
 35 |   }
 36 | 
 37 |   const allClients = await self.clients.matchAll({
 38 |     type: 'window',
 39 |   })
 40 | 
 41 |   switch (event.data) {
 42 |     case 'KEEPALIVE_REQUEST': {
 43 |       sendToClient(client, {
 44 |         type: 'KEEPALIVE_RESPONSE',
 45 |       })
 46 |       break
 47 |     }
 48 | 
 49 |     case 'INTEGRITY_CHECK_REQUEST': {
 50 |       sendToClient(client, {
 51 |         type: 'INTEGRITY_CHECK_RESPONSE',
 52 |         payload: {
 53 |           packageVersion: PACKAGE_VERSION,
 54 |           checksum: INTEGRITY_CHECKSUM,
 55 |         },
 56 |       })
 57 |       break
 58 |     }
 59 | 
 60 |     case 'MOCK_ACTIVATE': {
 61 |       activeClientIds.add(clientId)
 62 | 
 63 |       sendToClient(client, {
 64 |         type: 'MOCKING_ENABLED',
 65 |         payload: {
 66 |           client: {
 67 |             id: client.id,
 68 |             frameType: client.frameType,
 69 |           },
 70 |         },
 71 |       })
 72 |       break
 73 |     }
 74 | 
 75 |     case 'MOCK_DEACTIVATE': {
 76 |       activeClientIds.delete(clientId)
 77 |       break
 78 |     }
 79 | 
 80 |     case 'CLIENT_CLOSED': {
 81 |       activeClientIds.delete(clientId)
 82 | 
 83 |       const remainingClients = allClients.filter((client) => {
 84 |         return client.id !== clientId
 85 |       })
 86 | 
 87 |       // Unregister itself when there are no more clients
 88 |       if (remainingClients.length === 0) {
 89 |         self.registration.unregister()
 90 |       }
 91 | 
 92 |       break
 93 |     }
 94 |   }
 95 | })
 96 | 
 97 | self.addEventListener('fetch', function (event) {
 98 |   const { request } = event
 99 | 
100 |   // Bypass navigation requests.
101 |   if (request.mode === 'navigate') {
102 |     return
103 |   }
104 | 
105 |   // Opening the DevTools triggers the "only-if-cached" request
106 |   // that cannot be handled by the worker. Bypass such requests.
107 |   if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
108 |     return
109 |   }
110 | 
111 |   // Bypass all requests when there are no active clients.
112 |   // Prevents the self-unregistered worked from handling requests
113 |   // after it's been deleted (still remains active until the next reload).
114 |   if (activeClientIds.size === 0) {
115 |     return
116 |   }
117 | 
118 |   // Generate unique request ID.
119 |   const requestId = crypto.randomUUID()
120 |   event.respondWith(handleRequest(event, requestId))
121 | })
122 | 
123 | async function handleRequest(event, requestId) {
124 |   const client = await resolveMainClient(event)
125 |   const response = await getResponse(event, client, requestId)
126 | 
127 |   // Send back the response clone for the "response:*" life-cycle events.
128 |   // Ensure MSW is active and ready to handle the message, otherwise
129 |   // this message will pend indefinitely.
130 |   if (client && activeClientIds.has(client.id)) {
131 |     ;(async function () {
132 |       const responseClone = response.clone()
133 | 
134 |       sendToClient(
135 |         client,
136 |         {
137 |           type: 'RESPONSE',
138 |           payload: {
139 |             requestId,
140 |             isMockedResponse: IS_MOCKED_RESPONSE in response,
141 |             type: responseClone.type,
142 |             status: responseClone.status,
143 |             statusText: responseClone.statusText,
144 |             body: responseClone.body,
145 |             headers: Object.fromEntries(responseClone.headers.entries()),
146 |           },
147 |         },
148 |         [responseClone.body],
149 |       )
150 |     })()
151 |   }
152 | 
153 |   return response
154 | }
155 | 
156 | // Resolve the main client for the given event.
157 | // Client that issues a request doesn't necessarily equal the client
158 | // that registered the worker. It's with the latter the worker should
159 | // communicate with during the response resolving phase.
160 | async function resolveMainClient(event) {
161 |   const client = await self.clients.get(event.clientId)
162 | 
163 |   if (activeClientIds.has(event.clientId)) {
164 |     return client
165 |   }
166 | 
167 |   if (client?.frameType === 'top-level') {
168 |     return client
169 |   }
170 | 
171 |   const allClients = await self.clients.matchAll({
172 |     type: 'window',
173 |   })
174 | 
175 |   return allClients
176 |     .filter((client) => {
177 |       // Get only those clients that are currently visible.
178 |       return client.visibilityState === 'visible'
179 |     })
180 |     .find((client) => {
181 |       // Find the client ID that's recorded in the
182 |       // set of clients that have registered the worker.
183 |       return activeClientIds.has(client.id)
184 |     })
185 | }
186 | 
187 | async function getResponse(event, client, requestId) {
188 |   const { request } = event
189 | 
190 |   // Clone the request because it might've been already used
191 |   // (i.e. its body has been read and sent to the client).
192 |   const requestClone = request.clone()
193 | 
194 |   function passthrough() {
195 |     // Cast the request headers to a new Headers instance
196 |     // so the headers can be manipulated with.
197 |     const headers = new Headers(requestClone.headers)
198 | 
199 |     // Remove the "accept" header value that marked this request as passthrough.
200 |     // This prevents request alteration and also keeps it compliant with the
201 |     // user-defined CORS policies.
202 |     const acceptHeader = headers.get('accept')
203 |     if (acceptHeader) {
204 |       const values = acceptHeader.split(',').map((value) => value.trim())
205 |       const filteredValues = values.filter(
206 |         (value) => value !== 'msw/passthrough',
207 |       )
208 | 
209 |       if (filteredValues.length > 0) {
210 |         headers.set('accept', filteredValues.join(', '))
211 |       } else {
212 |         headers.delete('accept')
213 |       }
214 |     }
215 | 
216 |     return fetch(requestClone, { headers })
217 |   }
218 | 
219 |   // Bypass mocking when the client is not active.
220 |   if (!client) {
221 |     return passthrough()
222 |   }
223 | 
224 |   // Bypass initial page load requests (i.e. static assets).
225 |   // The absence of the immediate/parent client in the map of the active clients
226 |   // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
227 |   // and is not ready to handle requests.
228 |   if (!activeClientIds.has(client.id)) {
229 |     return passthrough()
230 |   }
231 | 
232 |   // Notify the client that a request has been intercepted.
233 |   const requestBuffer = await request.arrayBuffer()
234 |   const clientMessage = await sendToClient(
235 |     client,
236 |     {
237 |       type: 'REQUEST',
238 |       payload: {
239 |         id: requestId,
240 |         url: request.url,
241 |         mode: request.mode,
242 |         method: request.method,
243 |         headers: Object.fromEntries(request.headers.entries()),
244 |         cache: request.cache,
245 |         credentials: request.credentials,
246 |         destination: request.destination,
247 |         integrity: request.integrity,
248 |         redirect: request.redirect,
249 |         referrer: request.referrer,
250 |         referrerPolicy: request.referrerPolicy,
251 |         body: requestBuffer,
252 |         keepalive: request.keepalive,
253 |       },
254 |     },
255 |     [requestBuffer],
256 |   )
257 | 
258 |   switch (clientMessage.type) {
259 |     case 'MOCK_RESPONSE': {
260 |       return respondWithMock(clientMessage.data)
261 |     }
262 | 
263 |     case 'PASSTHROUGH': {
264 |       return passthrough()
265 |     }
266 |   }
267 | 
268 |   return passthrough()
269 | }
270 | 
271 | function sendToClient(client, message, transferrables = []) {
272 |   return new Promise((resolve, reject) => {
273 |     const channel = new MessageChannel()
274 | 
275 |     channel.port1.onmessage = (event) => {
276 |       if (event.data && event.data.error) {
277 |         return reject(event.data.error)
278 |       }
279 | 
280 |       resolve(event.data)
281 |     }
282 | 
283 |     client.postMessage(
284 |       message,
285 |       [channel.port2].concat(transferrables.filter(Boolean)),
286 |     )
287 |   })
288 | }
289 | 
290 | async function respondWithMock(response) {
291 |   // Setting response status code to 0 is a no-op.
292 |   // However, when responding with a "Response.error()", the produced Response
293 |   // instance will have status code set to 0. Since it's not possible to create
294 |   // a Response instance with status code 0, handle that use-case separately.
295 |   if (response.status === 0) {
296 |     return Response.error()
297 |   }
298 | 
299 |   const mockedResponse = new Response(response.body, response)
300 | 
301 |   Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, {
302 |     value: true,
303 |     enumerable: true,
304 |   })
305 | 
306 |   return mockedResponse
307 | }
308 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/Tree/Tree-icons.spec.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { expect, test } from "../../testing/fixtures";
  2 | import { flatTreeData, flatTreeDataWithIcons1, flatTreeDataWithIcons2, flatTreeDataWithIconsAndAlias1 } from "./testData";
  3 | 
  4 | test("default collapsed icon appears", async ({ initTestBed, createTreeDriver }) => {
  5 |   await initTestBed(`
  6 |       <VStack height="400px">
  7 |         <Tree testId="tree" data='{${JSON.stringify(flatTreeData)}}' />
  8 |       </VStack>
  9 |     `);
 10 | 
 11 |   const tree = await createTreeDriver("tree");
 12 |   await expect(tree.getIconByName("chevronright")).toBeVisible();
 13 |   await expect(tree.getIconByName("chevrondown")).not.toBeVisible();
 14 | });
 15 | 
 16 | test("custom iconCollapsed appears", async ({ initTestBed, createTreeDriver }) => {
 17 |   await initTestBed(`
 18 |       <VStack height="400px">
 19 |         <Tree 
 20 |           testId="tree"
 21 |           data='{${JSON.stringify(flatTreeData)}}'
 22 |           iconCollapsed="phone"
 23 |           iconExpanded="email"
 24 |         />
 25 |       </VStack>
 26 |     `);
 27 | 
 28 |   const tree = await createTreeDriver("tree");
 29 |   await expect(tree.getIconByName("phone")).toBeVisible();
 30 |   await expect(tree.getIconByName("email")).not.toBeVisible();
 31 | });
 32 | 
 33 | test("default expanded icon appears", async ({ initTestBed, createTreeDriver }) => {
 34 |   await initTestBed(`
 35 |       <VStack height="400px">
 36 |         <Tree 
 37 |           testId="tree"
 38 |           defaultExpanded="all"
 39 |           data='{${JSON.stringify(flatTreeData)}}'
 40 |         />
 41 |       </VStack>
 42 |     `);
 43 | 
 44 |   const tree = await createTreeDriver("tree");
 45 |   await expect(tree.getIconByName("chevrondown")).toBeVisible();
 46 | });
 47 | 
 48 | test("custom iconExpanded appears", async ({ initTestBed, createTreeDriver }) => {
 49 |   await initTestBed(`
 50 |       <VStack height="400px">
 51 |         <Tree 
 52 |           testId="tree"
 53 |           defaultExpanded="all"
 54 |           data='{${JSON.stringify(flatTreeData)}}'
 55 |           iconCollapsed="phone"
 56 |           iconExpanded="email"
 57 |         />
 58 |       </VStack>
 59 |     `);
 60 | 
 61 |   const tree = await createTreeDriver("tree");
 62 |   await expect(tree.getIconByName("phone")).not.toBeVisible();
 63 |   await expect(tree.getIconsByName("email")).toHaveCount(2);
 64 | });
 65 | 
 66 | test("both custom icons work together", async ({ initTestBed, createTreeDriver, page }) => {
 67 |   await initTestBed(`
 68 |       <VStack height="400px">
 69 |         <Tree 
 70 |           id="tree"
 71 |           data='{${JSON.stringify(flatTreeData)}}'
 72 |           iconCollapsed="phone"
 73 |           iconExpanded="email"
 74 |         >
 75 |           <property name="itemTemplate">
 76 |             <HStack testId="{$item.id}" verticalAlignment="center">
 77 |               <Icon name="folder" />
 78 |               <Text value="{$item.name}" />
 79 |             </HStack>
 80 |           </property>
 81 |         </Tree>
 82 |         <Button testId="expand1" onClick="tree.expandNode(1)">Expand Node 1</Button>
 83 |         <Button testId="expand2" onClick="tree.collapseNode(1)">Collapse Node 2</Button>
 84 |       </VStack>
 85 | 
 86 |     `);
 87 | 
 88 |   const tree = await createTreeDriver("tree");
 89 |   await expect(tree.component).toBeVisible();
 90 | 
 91 |   // Initially should show collapsed icon
 92 |   await expect(tree.getIconsByName("phone")).toBeVisible();
 93 |   await expect(tree.getIconsByName("email")).not.toBeVisible();
 94 | 
 95 |   // Expand the first node
 96 |   await page.getByTestId("expand1").click();
 97 | 
 98 |   // Should now show expanded icon and hide collapsed icon
 99 |   await expect(tree.getIconsByName("email")).toBeVisible();
100 |   await expect(tree.getIconsByName("phone")).toBeVisible();
101 | 
102 |   // Collapse again
103 |   await page.getByTestId("expand2").click();
104 | 
105 |   // Should show collapsed icon again
106 |   await expect(tree.getIconsByName("phone")).toBeVisible();
107 |   await expect(tree.getIconsByName("email")).not.toBeVisible();
108 | });
109 | 
110 | test("iconExpanded fields are used", async ({ initTestBed, page, createTreeDriver }) => {
111 |   await initTestBed(`
112 |       <VStack height="400px">
113 |         <Tree 
114 |           testId="tree" 
115 |           id="tree"
116 |           defaultExpanded="first-level"
117 |           data='{${JSON.stringify(flatTreeDataWithIcons1)}}' />
118 |         <Button testId="expand1" onClick="tree.expandNode(2)">Expand Node 2</Button>
119 |       </VStack>
120 |     `);
121 | 
122 |   const tree = await createTreeDriver("tree");
123 | 
124 |   // --- Initila state
125 |   await expect(tree.getIconByName("phone")).toBeVisible();
126 |   await expect(tree.getIconByName("email")).not.toBeVisible();
127 |   await expect(tree.getIconsByName("chevronright")).toHaveCount(1);
128 | 
129 |   await page.getByTestId("expand1").click();
130 | 
131 |   // --- After expanding node 2
132 |   await expect(tree.getIconByName("phone")).toBeVisible();
133 |   await expect(tree.getIconByName("email")).toBeVisible();
134 |   await expect(tree.getIconsByName("chevronright")).toHaveCount(0);
135 | });
136 | 
137 | test("iconExpanded fields (with alias) are used", async ({
138 |   initTestBed,
139 |   page,
140 |   createTreeDriver,
141 | }) => {
142 |   await initTestBed(`
143 |       <VStack height="400px">
144 |         <Tree 
145 |           testId="tree" 
146 |           id="tree"
147 |           iconExpandedField="iconExp"
148 |           defaultExpanded="first-level"
149 |           data='{${JSON.stringify(flatTreeDataWithIconsAndAlias1)}}' />
150 |         <Button testId="expand1" onClick="tree.expandNode(2)">Expand Node 2</Button>
151 |       </VStack>
152 |     `);
153 | 
154 |   const tree = await createTreeDriver("tree");
155 | 
156 |   // --- Initila state
157 |   await expect(tree.getIconByName("phone")).toBeVisible();
158 |   await expect(tree.getIconByName("email")).not.toBeVisible();
159 |   await expect(tree.getIconsByName("chevronright")).toHaveCount(1);
160 | 
161 |   await page.getByTestId("expand1").click();
162 | 
163 |   // --- After expanding node 2
164 |   await expect(tree.getIconByName("phone")).toBeVisible();
165 |   await expect(tree.getIconByName("email")).toBeVisible();
166 |   await expect(tree.getIconsByName("chevronright")).toHaveCount(0);
167 | });
168 | 
169 | test("iconCollapsed fields are used", async ({ initTestBed, page, createTreeDriver }) => {
170 |   await initTestBed(`
171 |       <VStack height="400px">
172 |         <Tree 
173 |           testId="tree" 
174 |           id="tree"
175 |           defaultExpanded="none"
176 |           data='{${JSON.stringify(flatTreeDataWithIcons2)}}' />
177 |         <Button testId="expand1" onClick="tree.expandNode(1)">Expand Node 1</Button>
178 |         <Button testId="expand2" onClick="tree.expandNode(2)">Expand Node 2</Button>
179 |       </VStack>
180 |     `);
181 | 
182 |   const tree = await createTreeDriver("tree");
183 | 
184 |   // --- Initila state
185 |   await expect(tree.getIconByName("phone")).toBeVisible();
186 |   await expect(tree.getIconByName("email")).not.toBeVisible();
187 |   await expect(tree.getIconsByName("chevronright")).toHaveCount(0);
188 | 
189 |   await page.getByTestId("expand1").click();
190 | 
191 |   // --- After expanding node 1
192 |   await expect(tree.getIconByName("phone")).not.toBeVisible();
193 |   await expect(tree.getIconByName("email")).toBeVisible();
194 |   await expect(tree.getIconsByName("chevrondown")).toHaveCount(1);
195 | 
196 |   await page.getByTestId("expand2").click();
197 | 
198 |   // --- After expanding node 2
199 |   await expect(tree.getIconByName("phone")).not.toBeVisible();
200 |   await expect(tree.getIconByName("email")).not.toBeVisible();
201 |   await expect(tree.getIconsByName("chevrondown")).toHaveCount(2);
202 | });
203 | 
204 | test("iconCollapsed fields (with alias) are used", async ({ initTestBed, page, createTreeDriver }) => {
205 |   await initTestBed(`
206 |       <VStack height="400px">
207 |         <Tree 
208 |           testId="tree" 
209 |           id="tree"
210 |           iconCollapsedField="iconColl"
211 |           defaultExpanded="none"
212 |           data='{${JSON.stringify(flatTreeDataWithIcons2)}}' />
213 |         <Button testId="expand1" onClick="tree.expandNode(1)">Expand Node 1</Button>
214 |         <Button testId="expand2" onClick="tree.expandNode(2)">Expand Node 2</Button>
215 |       </VStack>
216 |     `);
217 | 
218 |   const tree = await createTreeDriver("tree");
219 | 
220 |   // --- Initila state
221 |   await expect(tree.getIconByName("phone")).toBeVisible();
222 |   await expect(tree.getIconByName("email")).not.toBeVisible();
223 |   await expect(tree.getIconsByName("chevronright")).toHaveCount(0);
224 | 
225 |   await page.getByTestId("expand1").click();
226 | 
227 |   // --- After expanding node 1
228 |   await expect(tree.getIconByName("phone")).not.toBeVisible();
229 |   await expect(tree.getIconByName("email")).toBeVisible();
230 |   await expect(tree.getIconsByName("chevrondown")).toHaveCount(1);
231 | 
232 |   await page.getByTestId("expand2").click();
233 | 
234 |   // --- After expanding node 2
235 |   await expect(tree.getIconByName("phone")).not.toBeVisible();
236 |   await expect(tree.getIconByName("email")).not.toBeVisible();
237 |   await expect(tree.getIconsByName("chevrondown")).toHaveCount(2);
238 | });
239 | 
```

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

```typescript
  1 | import type React from "react";
  2 | 
  3 | import styles from "./Stack.module.scss";
  4 | 
  5 | import type { ComponentDef, ComponentPropertyMetadata } from "../../abstractions/ComponentDefs";
  6 | import type { RenderChildFn } from "../../abstractions/RendererDefs";
  7 | import type { AsyncFunction } from "../../abstractions/FunctionDefs";
  8 | import type { ValueExtractor } from "../../abstractions/RendererDefs";
  9 | import { createComponentRenderer } from "../../components-core/renderers";
 10 | import { isComponentDefChildren } from "../../components-core/utils/misc";
 11 | import { NotAComponentDefError } from "../../components-core/EngineError";
 12 | import { parseScssVar } from "../../components-core/theming/themeVars";
 13 | import { createMetadata, dClick, dInternal } from "../metadata-helpers";
 14 | import { DEFAULT_ORIENTATION, Stack, defaultProps } from "./StackNative";
 15 | import { alignmentOptionValues } from "../abstractions";
 16 | 
 17 | const COMP = "Stack";
 18 | 
 19 | const HORIZONTAL_ALIGNMENT: ComponentPropertyMetadata = {
 20 |   description: "Manages the horizontal content alignment for each child element in the Stack.",
 21 |   availableValues: alignmentOptionValues,
 22 |   valueType: "string",
 23 |   defaultValue: "start",
 24 | };
 25 | const VERTICAL_ALIGNMENT: ComponentPropertyMetadata = {
 26 |   description: "Manages the vertical content alignment for each child element in the Stack.",
 27 |   availableValues: alignmentOptionValues,
 28 |   valueType: "string",
 29 |   defaultValue: "start",
 30 | };
 31 | 
 32 | const stackMd = createMetadata({
 33 |   status: "stable",
 34 |   description:
 35 |     "`Stack` is the fundamental layout container that organizes child elements in " +
 36 |     "configurable horizontal or vertical arrangements. As the most versatile building " +
 37 |     "block in XMLUI's layout system, it provides comprehensive alignment, spacing, " +
 38 |     "and flow control options that serve as the foundation for all specialized stack variants.",
 39 |   props: {
 40 |     gap: {
 41 |       description: "Optional size value indicating the gap between child elements.",
 42 |       valueType: "string",
 43 |       defaultValue: "$gap-normal",
 44 |     },
 45 |     reverse: {
 46 |       description: "Optional boolean property to reverse the order of child elements.",
 47 |       valueType: "boolean",
 48 |       defaultValue: defaultProps.reverse,
 49 |     },
 50 |     wrapContent: {
 51 |       description:
 52 |         "Optional boolean which wraps the content if set to true and the available " +
 53 |         "space is not big enough. Works only with horizontal orientations.",
 54 |       valueType: "boolean",
 55 |       defaultValue: false,
 56 |     },
 57 |     orientation: {
 58 |       description:
 59 |         "An optional property that governs the Stack's orientation (whether " +
 60 |         "the Stack lays out its children in a row or a column).",
 61 |       availableValues: ["horizontal", "vertical"],
 62 |       valueType: "string",
 63 |       defaultValue: defaultProps.orientation,
 64 |     },
 65 |     horizontalAlignment: HORIZONTAL_ALIGNMENT,
 66 |     verticalAlignment: VERTICAL_ALIGNMENT,
 67 |     hoverContainer: {
 68 |       ...dInternal("Reserved for future use"),
 69 |       defaultValue: defaultProps.hoverContainer,
 70 |     },
 71 |     visibleOnHover: {
 72 |       ...dInternal("Reserved for future use"),
 73 |       defaultValue: defaultProps.visibleOnHover,
 74 |     },
 75 |   },
 76 |   events: {
 77 |     click: dClick(COMP),
 78 |     mounted: dInternal("Reserved for future use"),
 79 |   },
 80 |   themeVars: parseScssVar(styles.themeVars),
 81 | });
 82 | 
 83 | export const StackMd = {
 84 |   ...stackMd,
 85 |   props: {
 86 |     ...stackMd.props,
 87 |   },
 88 | };
 89 | type StackComponentDef = ComponentDef<typeof StackMd>;
 90 | 
 91 | export const VStackMd = {
 92 |   ...StackMd,
 93 |   specializedFrom: COMP,
 94 |   description: `This component represents a stack rendering its contents vertically.`,
 95 |   props: {
 96 |     ...stackMd.props,
 97 |   },
 98 | };
 99 | type VStackComponentDef = ComponentDef<typeof VStackMd>;
100 | 
101 | export const HStackMd = {
102 |   ...StackMd,
103 |   specializedFrom: COMP,
104 |   description: `This component represents a stack rendering its contents horizontally.`,
105 |   props: {
106 |     ...stackMd.props,
107 |   },
108 | };
109 | type HStackComponentDef = ComponentDef<typeof HStackMd>;
110 | 
111 | export const CVStackMd = {
112 |   ...StackMd,
113 |   specializedFrom: COMP,
114 |   description:
115 |     `This component represents a stack that renders its contents vertically ` +
116 |     `and aligns that in the center along both axes.`,
117 | };
118 | type CVStackComponentDef = ComponentDef<typeof CVStackMd>;
119 | 
120 | export const CHStackMd = {
121 |   ...StackMd,
122 |   specializedFrom: COMP,
123 |   description:
124 |     `This component represents a stack that renders its contents horizontally ` +
125 |     `and aligns that in the center along both axes.`,
126 | };
127 | type CHStackComponentDef = ComponentDef<typeof CHStackMd>;
128 | 
129 | type RenderStackPars = {
130 |   node:
131 |     | StackComponentDef
132 |     | VStackComponentDef
133 |     | HStackComponentDef
134 |     | CVStackComponentDef
135 |     | CHStackComponentDef;
136 |   extractValue: ValueExtractor;
137 |   className?: string;
138 |   lookupEventHandler: (
139 |     eventName: keyof NonNullable<StackComponentDef["events"]>,
140 |   ) => AsyncFunction | undefined;
141 |   renderChild: RenderChildFn;
142 |   orientation: string;
143 |   horizontalAlignment: string;
144 |   verticalAlignment: string;
145 | };
146 | 
147 | function renderStack({
148 |   node,
149 |   extractValue,
150 |   className,
151 |   orientation,
152 |   horizontalAlignment,
153 |   verticalAlignment,
154 |   lookupEventHandler,
155 |   renderChild,
156 | }: RenderStackPars) {
157 |   if (!isComponentDefChildren(node.children)) {
158 |     throw new NotAComponentDefError();
159 |   }
160 |   return (
161 |     <Stack
162 |       orientation={orientation}
163 |       horizontalAlignment={horizontalAlignment}
164 |       verticalAlignment={verticalAlignment}
165 |       reverse={extractValue(node.props?.reverse)}
166 |       hoverContainer={extractValue(node.props?.hoverContainer)}
167 |       visibleOnHover={extractValue(node.props?.visibleOnHover)}
168 |       className={className}
169 |       onMount={lookupEventHandler("mounted")}
170 |     >
171 |       {renderChild(node.children, {
172 |         type: "Stack",
173 |         orientation,
174 |       })}
175 |     </Stack>
176 |   );
177 | }
178 | 
179 | export const stackComponentRenderer = createComponentRenderer(
180 |   COMP,
181 |   StackMd,
182 |   ({ node, extractValue, renderChild, className, lookupEventHandler }) => {
183 |     const orientation = extractValue(node.props?.orientation) || DEFAULT_ORIENTATION;
184 |     const horizontalAlignment = extractValue(node.props?.horizontalAlignment);
185 |     const verticalAlignment = extractValue(node.props?.verticalAlignment);
186 |     return renderStack({
187 |       node,
188 |       extractValue,
189 |       className,
190 |       orientation,
191 |       horizontalAlignment,
192 |       verticalAlignment,
193 |       lookupEventHandler,
194 |       renderChild,
195 |     });
196 |   },
197 | );
198 | 
199 | export const vStackComponentRenderer = createComponentRenderer(
200 |   "VStack",
201 |   VStackMd,
202 |   ({ node, extractValue, renderChild, className, lookupEventHandler }) => {
203 |     const horizontalAlignment = extractValue(node.props?.horizontalAlignment);
204 |     const verticalAlignment = extractValue(node.props?.verticalAlignment);
205 |     return renderStack({
206 |       node,
207 |       extractValue,
208 |       className,
209 |       lookupEventHandler,
210 |       renderChild,
211 |       orientation: "vertical",
212 |       horizontalAlignment,
213 |       verticalAlignment,
214 |     });
215 |   },
216 | );
217 | 
218 | export const hStackComponentRenderer = createComponentRenderer(
219 |   "HStack",
220 |   HStackMd,
221 |   ({ node, extractValue, renderChild, className, lookupEventHandler }) => {
222 |     const horizontalAlignment = extractValue(node.props?.horizontalAlignment);
223 |     const verticalAlignment = extractValue(node.props?.verticalAlignment);
224 |     return renderStack({
225 |       node,
226 |       extractValue,
227 |       className,
228 |       lookupEventHandler,
229 |       renderChild,
230 |       orientation: "horizontal",
231 |       horizontalAlignment,
232 |       verticalAlignment,
233 |     });
234 |   },
235 | );
236 | 
237 | export const cvStackComponentRenderer = createComponentRenderer(
238 |   "CVStack",
239 |   CVStackMd,
240 |   ({ node, extractValue, renderChild, className, lookupEventHandler }) => {
241 |     return renderStack({
242 |       node,
243 |       extractValue,
244 |       className,
245 |       lookupEventHandler,
246 |       renderChild,
247 |       orientation: "vertical",
248 |       horizontalAlignment: "center",
249 |       verticalAlignment: "center",
250 |     });
251 |   },
252 | );
253 | 
254 | export const chStackComponentRenderer = createComponentRenderer(
255 |   "CHStack",
256 |   CHStackMd,
257 |   ({ node, extractValue, renderChild, className, lookupEventHandler }) => {
258 |     return renderStack({
259 |       node,
260 |       extractValue,
261 |       className,
262 |       lookupEventHandler,
263 |       renderChild,
264 |       orientation: "horizontal",
265 |       horizontalAlignment: "center",
266 |       verticalAlignment: "center",
267 |     });
268 |   },
269 | );
270 | 
```

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

```typescript
  1 | import styles from "./TextBox.module.scss";
  2 | 
  3 | import type { RegisterComponentApiFn, ValueExtractor } from "../../abstractions/RendererDefs";
  4 | import type { AsyncFunction } from "../../abstractions/FunctionDefs";
  5 | import type { LookupActionOptions } from "../../abstractions/ActionDefs";
  6 | import { type ComponentDef } from "../../abstractions/ComponentDefs";
  7 | import { createComponentRenderer } from "../../components-core/renderers";
  8 | import { parseScssVar } from "../../components-core/theming/themeVars";
  9 | import {
 10 |   createMetadata,
 11 |   dAutoFocus,
 12 |   dDidChange,
 13 |   dEnabled,
 14 |   dEndIcon,
 15 |   dEndText,
 16 |   dGotFocus,
 17 |   dInitialValue,
 18 |   dLostFocus,
 19 |   dMaxLength,
 20 |   dPlaceholder,
 21 |   dReadonly,
 22 |   dRequired,
 23 |   dStartIcon,
 24 |   dStartText,
 25 |   dValidationStatus,
 26 | } from "../metadata-helpers";
 27 | import { TextBox, defaultProps } from "./TextBoxNative";
 28 | 
 29 | const COMP = "TextBox";
 30 | 
 31 | export const TextBoxMd = createMetadata({
 32 |   status: "stable",
 33 |   description:
 34 |     "`TextBox` captures user text input for forms, search fields, and data entry " +
 35 |     "with support for validation, icons, and formatting hints.",
 36 |   parts: {
 37 |     label: {
 38 |       description: "The label displayed for the text box.",
 39 |     },
 40 |     startAdornment: {
 41 |       description: "The adornment displayed at the start of the text box.",
 42 |     },
 43 |     endAdornment: {
 44 |       description: "The adornment displayed at the end of the text box.",
 45 |     },
 46 |     input: {
 47 |       description: "The text box input area.",
 48 |     }
 49 |   },
 50 |   defaultPart: "input",
 51 |   props: {
 52 |     placeholder: dPlaceholder(),
 53 |     initialValue: {
 54 |       ...dInitialValue(),
 55 |       defaultValue: defaultProps.initialValue,
 56 |     },
 57 |     maxLength: dMaxLength(),
 58 |     autoFocus: dAutoFocus(),
 59 |     required: dRequired(),
 60 |     readOnly: dReadonly(),
 61 |     enabled: {
 62 |       ...dEnabled(),
 63 |       defaultValue: defaultProps.enabled,
 64 |     },
 65 |     validationStatus: {
 66 |       ...dValidationStatus(),
 67 |       defaultValue: defaultProps.validationStatus,
 68 |     },
 69 |     startText: dStartText(),
 70 |     startIcon: dStartIcon(),
 71 |     endText: dEndText(),
 72 |     endIcon: dEndIcon(),
 73 |     gap: {
 74 |       description:
 75 |         "This property defines the gap between the adornments and the input area. If not " +
 76 |         "set, the gap declared by the current theme is used.",
 77 |     },
 78 |     showPasswordToggle: {
 79 |       description:
 80 |         "If `true`, a toggle button is displayed to switch between showing and hiding the password input.",
 81 |       defaultValue: false,
 82 |     },
 83 |     passwordVisibleIcon: {
 84 |       description:
 85 |         "The icon to display when the password is visible (when showPasswordToggle is true).",
 86 |       valueType: "string",
 87 |       defaultValue: "eye",
 88 |     },
 89 |     passwordHiddenIcon: {
 90 |       description:
 91 |         "The icon to display when the password is hidden (when showPasswordToggle is true).",
 92 |       valueType: "string",
 93 |       defaultValue: "eye-off",
 94 |     },
 95 |   },
 96 |   events: {
 97 |     gotFocus: dGotFocus(COMP),
 98 |     lostFocus: dLostFocus(COMP),
 99 |     didChange: dDidChange(COMP),
100 |   },
101 |   apis: {
102 |     focus: {
103 |       description: `This method sets the focus on the \`${COMP}\` component.`,
104 |       signature: "focus(): void",
105 |     },
106 |     value: {
107 |       description: `You can query the component's value. If no value is set, it will retrieve \`undefined\`.`,
108 |       signature: "get value(): string | undefined",
109 |     },
110 |     setValue: {
111 |       description: `This API sets the value of the \`${COMP}\`. You can use it to programmatically change the value.`,
112 |       signature: "setValue(value: string): void",
113 |       parameters: {
114 |         value: "The new value to set. If the value is empty, it will clear the input.",
115 |       },
116 |     },
117 |   },
118 |   themeVars: parseScssVar(styles.themeVars),
119 |   defaultThemeVars: {
120 |     // TODO: When FormItem is themed, move these defaults there
121 |     "borderRadius-Input": "$borderRadius",
122 |     "textColor-Input": "$textColor-primary",
123 |     "backgroundColor-Input--disabled": "$backgroundColor--disabled",
124 |     "borderWidth-Input": "1px",
125 |     "minHeight-Input": "39px",
126 |     [`paddingHorizontal-${COMP}`]: "$space-2",
127 |     [`paddingVertical-${COMP}`]: "$space-2",
128 |     "gap-adornment-Input": "$space-2",
129 |     "borderStyle-Input": "solid",
130 |     "borderColor-Input--disabled": "$borderColor--disabled",
131 |     "textColor-Input--disabled": "$textColor--disabled",
132 |     "borderColor-Input--default": "$borderColor-Input-default",
133 |     "borderColor-Input--default--hover": "$borderColor-Input-default--hover",
134 |     "borderColor-Input--error": "$borderColor-Input-default--error",
135 |     "borderColor-Input--warning": "$borderColor-Input-default--warning",
136 |     "borderColor-Input--success": "$borderColor-Input-default--success",
137 |     "textColor-placeholder-Input": "$textColor-subtitle",
138 |     "color-adornment-Input": "$textColor-subtitle",
139 | 
140 |     "outlineColor-Input--focus": "$outlineColor--focus",
141 |     "outlineWidth-Input--focus": "$outlineWidth--focus",
142 |     "outlineStyle-Input--focus": "$outlineStyle--focus",
143 |     "outlineOffset-Input--focus": "$outlineOffset--focus",
144 |     "color-passwordToggle-Input": "$textColor-subtitle",
145 | 
146 |     light: {
147 |       // --- No light-specific theme vars
148 |     },
149 |     dark: {
150 |       // --- No dark-specific theme vars
151 |     },
152 |   },
153 | });
154 | 
155 | type TextBoxComponentDef = ComponentDef<typeof TextBoxMd>;
156 | 
157 | function renderTextBox(
158 |   className: string | undefined,
159 |   state: any,
160 |   updateState: (componentState: any) => void,
161 |   extractValue: ValueExtractor,
162 |   node: TextBoxComponentDef,
163 |   lookupEventHandler: (
164 |     eventName: keyof NonNullable<TextBoxComponentDef["events"]>,
165 |     actionOptions?: LookupActionOptions,
166 |   ) => AsyncFunction | undefined,
167 |   registerComponentApi: RegisterComponentApiFn,
168 |   type: "text" | "password" = "text",
169 | ) {
170 |   // TODO: How can we use the gap from the className?
171 |   //delete layoutCss.gap;
172 |   return (
173 |     <TextBox
174 |       type={type}
175 |       className={className}
176 |       value={state.value}
177 |       updateState={updateState}
178 |       initialValue={extractValue(node.props.initialValue)}
179 |       maxLength={extractValue(node.props.maxLength)}
180 |       enabled={extractValue.asOptionalBoolean(node.props.enabled)}
181 |       placeholder={extractValue.asOptionalString(node.props.placeholder)}
182 |       validationStatus={extractValue(node.props.validationStatus)}
183 |       onDidChange={lookupEventHandler("didChange")}
184 |       onFocus={lookupEventHandler("gotFocus")}
185 |       onBlur={lookupEventHandler("lostFocus")}
186 |       registerComponentApi={registerComponentApi}
187 |       startText={extractValue.asOptionalString(node.props.startText)}
188 |       startIcon={extractValue.asOptionalString(node.props.startIcon)}
189 |       endText={extractValue.asOptionalString(node.props.endText)}
190 |       endIcon={extractValue.asOptionalString(node.props.endIcon)}
191 |       gap={extractValue.asOptionalString(node.props.gap)}
192 |       autoFocus={extractValue.asOptionalBoolean(node.props.autoFocus)}
193 |       readOnly={extractValue.asOptionalBoolean(node.props.readOnly)}
194 |       required={extractValue.asOptionalBoolean(node.props.required)}
195 |       showPasswordToggle={extractValue.asOptionalBoolean(node.props.showPasswordToggle, false)}
196 |       passwordVisibleIcon={extractValue.asOptionalString(node.props.passwordVisibleIcon)}
197 |       passwordHiddenIcon={extractValue.asOptionalString(node.props.passwordHiddenIcon)}
198 |     />
199 |   );
200 | }
201 | 
202 | export const textBoxComponentRenderer = createComponentRenderer(
203 |   COMP,
204 |   TextBoxMd,
205 |   ({
206 |     node,
207 |     state,
208 |     updateState,
209 |     lookupEventHandler,
210 |     extractValue,
211 |     className,
212 |     registerComponentApi,
213 |   }) => {
214 |     return renderTextBox(
215 |       className,
216 |       state,
217 |       updateState,
218 |       extractValue,
219 |       node as TextBoxComponentDef,
220 |       lookupEventHandler,
221 |       registerComponentApi,
222 |     );
223 |   },
224 | );
225 | 
226 | export const PasswordMd = createMetadata({
227 |   ...TextBoxMd,
228 |   description:
229 |     "`Password` is a specialized [TextBox](/components/TextBox) that enables users " +
230 |     "to input and edit passwords.",
231 | });
232 | 
233 | export const passwordInputComponentRenderer = createComponentRenderer(
234 |   "PasswordInput",
235 |   PasswordMd,
236 |   ({
237 |     node,
238 |     state,
239 |     updateState,
240 |     lookupEventHandler,
241 |     extractValue,
242 |     className,
243 |     registerComponentApi,
244 |   }) => {
245 |     return renderTextBox(
246 |       className,
247 |       state,
248 |       updateState,
249 |       extractValue,
250 |       node as TextBoxComponentDef,
251 |       lookupEventHandler,
252 |       registerComponentApi,
253 |       "password",
254 |     );
255 |   },
256 | );
257 | 
```

--------------------------------------------------------------------------------
/packages/xmlui-website-blocks/src/FancyButton/FancyButton.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import { createUserDefinedComponentRenderer, dClick, dGotFocus, dLostFocus } from "xmlui";
  2 | import { createMetadata } from "xmlui";
  3 | import componentSource from "./FancyButton.xmlui";
  4 | import { PropertyValueDescription } from "xmlui/src/abstractions/ComponentDefs";
  5 | 
  6 | export const alignmentOptionMd: PropertyValueDescription[] = [
  7 |   { value: "center", description: "Place the content in the middle" },
  8 |   {
  9 |     value: "start",
 10 |     description: "Justify the content to the left (to the right if in right-to-left)",
 11 |   },
 12 |   {
 13 |     value: "end",
 14 |     description: "Justify the content to the right (to the left if in right-to-left)",
 15 |   },
 16 | ];
 17 | 
 18 | export const sizeMd: PropertyValueDescription[] = [
 19 |   { value: "xs", description: "Extra small" },
 20 |   { value: "sm", description: "Small" },
 21 |   { value: "md", description: "Medium" },
 22 |   { value: "lg", description: "Large" },
 23 |   { value: "xl", description: "Extra large" },
 24 | ];
 25 | 
 26 | export const iconPositionMd: PropertyValueDescription[] = [
 27 |   {
 28 |     value: "start",
 29 |     description:
 30 |       "The icon will appear at the start (left side when the left-to-right direction is set)",
 31 |   },
 32 |   {
 33 |     value: "end",
 34 |     description:
 35 |       "The icon will appear at the end (right side when the left-to-right direction is set)",
 36 |   },
 37 | ];
 38 | 
 39 | export const buttonTypesMd: PropertyValueDescription[] = [
 40 |   {
 41 |     value: "button",
 42 |     description: "Regular behavior that only executes logic if explicitly determined.",
 43 |   },
 44 |   {
 45 |     value: "submit",
 46 |     description:
 47 |       "The button submits the form data to the server. This is the default for buttons in a Form or NativeForm component.",
 48 |   },
 49 |   {
 50 |     value: "reset",
 51 |     description:
 52 |       "Resets all the controls to their initial values. Using it is ill advised for UX reasons.",
 53 |   },
 54 | ];
 55 | 
 56 | const COMP = "FancyButton";
 57 | 
 58 | const fancyButtonVariantMd = [
 59 |   { value: "rounded", description: "Rounded variant with soft corners" },
 60 |   { value: "square", description: "Square variant with sharp corners" },
 61 |   { value: "pill", description: "Pill variant with fully rounded edges" },
 62 |   { value: "outlinedPill", description: "Outlined pill variant with fully rounded edges" },
 63 | ];
 64 | 
 65 | export const FancyButtonMd = createMetadata({
 66 |   status: "experimental",
 67 |   description:
 68 |     "`FancyButton` is an enhanced interactive component for triggering actions with " +
 69 |     "advanced styling options. It provides rounded and square variants for different " +
 70 |     "design aesthetics while maintaining all standard button functionality.",
 71 |   props: {
 72 |     autoFocus: {
 73 |       description: "Indicates if the button should receive focus when the page loads.",
 74 |       isRequired: false,
 75 |       type: "boolean",
 76 |       defaultValue: false,
 77 |     },
 78 |     variant: {
 79 |       description: "The button variant determines the visual style and corner treatment.",
 80 |       isRequired: false,
 81 |       type: "string",
 82 |       availableValues: fancyButtonVariantMd,
 83 |       defaultValue: "rounded",
 84 |     },
 85 |     size: {
 86 |       description: "Sets the size of the button.",
 87 |       isRequired: false,
 88 |       type: "string",
 89 |       availableValues: sizeMd,
 90 |       defaultValue: "md",
 91 |     },
 92 |     label: {
 93 |       description:
 94 |         `This property is an optional string to set a label for the ${COMP}. If no label is ` +
 95 |         `specified and an icon is set, the ${COMP} will modify its styling to look like a ` +
 96 |         `small icon button. When the ${COMP} has nested children, it will display them and ` +
 97 |         `ignore the value of the \`label\` prop.`,
 98 |       type: "string",
 99 |     },
100 |     type: {
101 |       description:
102 |         `This optional string describes how the ${COMP} appears in an HTML context. You ` +
103 |         `rarely need to set this property explicitly.`,
104 |       availableValues: buttonTypesMd,
105 |       valueType: "string",
106 |       defaultValue: "button",
107 |     },
108 |     enabled: {
109 |       description:
110 |         `The value of this property indicates whether the button accepts actions (\`true\`) ` +
111 |         `or does not react to them (\`false\`).`,
112 |       type: "boolean",
113 |       defaultValue: true,
114 |     },
115 |     icon: {
116 |       description:
117 |         `This string value denotes an icon name. The framework will render an icon if XMLUI ` +
118 |         `recognizes the icon by its name. If no label is specified and an icon is set, the ${COMP} ` +
119 |         `displays only that icon.`,
120 |       type: "string",
121 |     },
122 |     iconPosition: {
123 |       description: `This optional string determines the location of the icon in the ${COMP}.`,
124 |       availableValues: iconPositionMd,
125 |       type: "string",
126 |       defaultValue: "start",
127 |     },
128 |     contentPosition: {
129 |       description:
130 |         `This optional value determines how the label and icon (or nested children) should be placed` +
131 |         `inside the ${COMP} component.`,
132 |       availableValues: alignmentOptionMd,
133 |       type: "string",
134 |       defaultValue: "center",
135 |     },
136 |     contextualLabel: {
137 |       description: `This optional value is used to provide an accessible name for the ${COMP} in the context of its usage.`,
138 |       type: "string",
139 |     },
140 |   },
141 |   events: {
142 |     click: dClick(COMP),
143 |     gotFocus: dGotFocus(COMP),
144 |     lostFocus: dLostFocus(COMP),
145 |   },
146 |   defaultThemeVars: {
147 |     [`fontSize-${COMP}`]: "$fontSize-sm",
148 |     [`fontWeight-${COMP}`]: "$fontWeight-medium",
149 |     [`gap-${COMP}`]: "$space-2",
150 |     [`backgroundColor-${COMP}--disabled`]: "$backgroundColor--disabled",
151 |     [`borderColor-${COMP}--disabled`]: "$borderColor--disabled",
152 |     [`borderStyle-${COMP}`]: "solid",
153 |     [`textColor-${COMP}--disabled`]: "$textColor--disabled",
154 |     [`outlineColor-${COMP}--focus`]: "$outlineColor--focus",
155 |     [`borderWidth-${COMP}`]: "1px",
156 |     [`outlineWidth-${COMP}--focus`]: "$outlineWidth--focus",
157 |     [`outlineStyle-${COMP}--focus`]: "$outlineStyle--focus",
158 |     [`outlineOffset-${COMP}--focus`]: "$outlineOffset--focus",
159 | 
160 |     // Size variant theme variables
161 |     [`paddingHorizontal-${COMP}-xs`]: "$space-3",
162 |     [`paddingVertical-${COMP}-xs`]: "$space-1_5",
163 |     [`fontSize-${COMP}-xs`]: "$fontSize-xs",
164 |     [`gap-${COMP}-xs`]: "$space-2",
165 | 
166 |     [`paddingHorizontal-${COMP}-sm`]: "$space-4",
167 |     [`paddingVertical-${COMP}-sm`]: "$space-2",
168 |     [`fontSize-${COMP}-sm`]: "$fontSize-sm",
169 |     [`gap-${COMP}-sm`]: "$space-2_5",
170 | 
171 |     [`paddingHorizontal-${COMP}-md`]: "$space-5",
172 |     [`paddingVertical-${COMP}-md`]: "$space-2_5",
173 |     [`fontSize-${COMP}-md`]: "$fontSize-xl",
174 |     [`gap-${COMP}-md`]: "$space-3",
175 | 
176 |     [`paddingHorizontal-${COMP}-lg`]: "$space-8",
177 |     [`paddingVertical-${COMP}-lg`]: "$space-3",
178 |     [`fontSize-${COMP}-lg`]: "$fontSize-2xl",
179 |     [`gap-${COMP}-lg`]: "$space-4",
180 | 
181 |     [`paddingHorizontal-${COMP}-xl`]: "$space-10",
182 |     [`paddingVertical-${COMP}-xl`]: "$space-4",
183 |     [`fontSize-${COMP}-xl`]: "$fontSize-4xl",
184 |     [`gap-${COMP}-xl`]: "$space-5",
185 | 
186 |     // Common colors
187 |     [`backgroundColor-${COMP}`]: "$color-primary-500",
188 |     [`backgroundColor-${COMP}--hover`]: "$color-primary-400",
189 |     [`backgroundColor-${COMP}--active`]: "$color-primary-600",
190 |     [`textColor-${COMP}`]: "$const-color-surface-50",
191 |     [`borderColor-${COMP}`]: "$color-primary-500",
192 |     [`borderColor-${COMP}--hover`]: "$color-primary-400",
193 | 
194 |     // Rounded variant theme variables
195 |     [`borderRadius-${COMP}-rounded-xs`]: "6px",
196 |     [`borderRadius-${COMP}-rounded-sm`]: "8px",
197 |     [`borderRadius-${COMP}-rounded-md`]: "12px",
198 |     [`borderRadius-${COMP}-rounded-lg`]: "16px",
199 |     [`borderRadius-${COMP}-rounded-xl`]: "24px",
200 | 
201 |     // Square variant theme variables
202 |     [`borderRadius-${COMP}-square`]: "$space-0",
203 | 
204 |     // Pill variant theme variables
205 |     [`borderRadius-${COMP}-pill`]: "9999px",
206 | 
207 |     // Outlined pill variant theme variables
208 |     [`backgroundColor-${COMP}-outlinedPill`]: "transparent",
209 |     [`backgroundColor-${COMP}-outlinedPill--hover`]: "transparent",
210 |     [`borderRadius-${COMP}-outlinedPill`]: "9999px",
211 |     [`borderColor-${COMP}-outlinedPill--hover`]: "red",
212 |     [`textColor-${COMP}-outlinedPill`]: "$textColor-primary",
213 |     [`borderWidth-${COMP}-outlinedPill-xs`]: "1.5px",
214 |     [`borderWidth-${COMP}-outlinedPill-sm`]: "2px",
215 |     [`borderWidth-${COMP}-outlinedPill-md`]: "2.5px",
216 |     [`borderWidth-${COMP}-outlinedPill-lg`]: "4px",
217 |     [`borderWidth-${COMP}-outlinedPill-xl`]: "5px",
218 |   },
219 | });
220 | 
221 | export const fancyButtonRenderer = createUserDefinedComponentRenderer(
222 |   FancyButtonMd,
223 |   componentSource,
224 | );
225 | 
```
Page 45/186FirstPrevNextLast