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

# Directory Structure

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

# Files

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

```typescript
  1 | import { AreaChart, defaultProps } from "./AreaChartNative";
  2 | import { createComponentRenderer } from "../../../components-core/renderers";
  3 | import { createMetadata } from "../../metadata-helpers";
  4 | import { MemoizedItem } from "../../container-helpers";
  5 | 
  6 | const COMP = "AreaChart";
  7 | 
  8 | export const AreaChartMd = createMetadata({
  9 |   status: "experimental",
 10 |   description: "Interactive area chart for showing data trends over time with filled areas under the curve",
 11 |   docFolder: "Charts/AreaChart",
 12 |   
 13 |   props: {
 14 |     data: {
 15 |       description:
 16 |         "This property is used to provide the component with data to display. " +
 17 |         "The data needs to be an array of objects.",
 18 |     },
 19 |     dataKeys: {
 20 |       description:
 21 |         "This property specifies the keys in the data objects that should be used for rendering the chart elements. " +
 22 |         "E.g. 'value' or 'amount'.",
 23 |       valueType: "string",
 24 |     },
 25 |     nameKey: {
 26 |       description:
 27 |         "Specifies the key in the data objects that will be used to label the different data series.",
 28 |       valueType: "string",
 29 |     },
 30 |     hideX: {
 31 |       description:
 32 |         "Determines whether the X-axis should be hidden. If set to `true`, the axis will not be rendered.",
 33 |       valueType: "boolean",
 34 |       defaultValue: defaultProps.hideX,
 35 |     },
 36 |     hideY: {
 37 |       description:
 38 |         "Determines whether the Y-axis should be hidden. If set to `true`, the axis will not be rendered.",
 39 |       valueType: "boolean",
 40 |       defaultValue: defaultProps.hideY,
 41 |     },
 42 |     hideTickX: {
 43 |       description:
 44 |         "Determines whether the X-axis tick labels should be hidden. If set to `true`, the tick labels will not be rendered.",
 45 |       valueType: "boolean",
 46 |       defaultValue: defaultProps.hideTickX,
 47 |     },
 48 |     hideTickY: {
 49 |       description:
 50 |         "Determines whether the Y-axis tick labels should be hidden. If set to `true`, the tick labels will not be rendered.",
 51 |       valueType: "boolean",
 52 |       defaultValue: defaultProps.hideTickY,
 53 |     },
 54 |     hideTooltip: {
 55 |       description:
 56 |         "Determines whether the tooltip should be hidden. If set to `true`, the tooltip will not be rendered.",
 57 |       valueType: "boolean",
 58 |       defaultValue: defaultProps.hideTooltip,
 59 |     },
 60 |     showLegend: {
 61 |       description:
 62 |         "Determines whether the legend should be shown. If set to `true`, the legend will be rendered.",
 63 |       valueType: "boolean",
 64 |       defaultValue: defaultProps.showLegend,
 65 |     },
 66 |     stacked: {
 67 |       description:
 68 |         "Determines whether multiple areas should be stacked on top of each other. If set to `true`, areas will be stacked.",
 69 |       valueType: "boolean",
 70 |       defaultValue: defaultProps.stacked,
 71 |     },
 72 |     curved: {
 73 |       description:
 74 |         "Determines whether the area lines should be curved (smooth) or straight. If set to `true`, lines will be curved.",
 75 |       valueType: "boolean",
 76 |       defaultValue: defaultProps.curved,
 77 |     },
 78 |     tooltipTemplate: {
 79 |       description: "This property allows replacing the default template to display a tooltip.",
 80 |     },
 81 |   },
 82 |   
 83 |   events: {
 84 |     // Standard chart events - customize based on chart type
 85 |   },
 86 |   
 87 |   apis: {
 88 |     // Chart-specific APIs if needed
 89 |   },
 90 |   
 91 |   contextVars: {
 92 |     // Add context variables if needed
 93 |   },
 94 | });
 95 | 
 96 | // Component renderer
 97 | export const areaChartComponentRenderer = createComponentRenderer(
 98 |   COMP,
 99 |   AreaChartMd,
100 |   ({ extractValue, node, className, lookupSyncCallback, renderChild }: any) => {
101 |     return (
102 |       <AreaChart
103 |         className={className}
104 |         tickFormatterX={lookupSyncCallback(node.props?.tickFormatterX)}
105 |         tickFormatterY={lookupSyncCallback(node.props?.tickFormatterY)}
106 |         data={extractValue(node.props?.data)}
107 |         nameKey={extractValue(node.props?.nameKey)}
108 |         dataKeys={extractValue(node.props?.dataKeys)}
109 |         hideX={extractValue.asOptionalBoolean(node.props?.hideX)}
110 |         hideY={extractValue.asOptionalBoolean(node.props?.hideY)}
111 |         hideTickX={extractValue.asOptionalBoolean(node.props?.hideTickX)}
112 |         hideTickY={extractValue.asOptionalBoolean(node.props?.hideTickY)}
113 |         hideTooltip={extractValue.asOptionalBoolean(node.props?.hideTooltip)}
114 |         showLegend={extractValue.asOptionalBoolean(node.props?.showLegend)}
115 |         stacked={extractValue.asOptionalBoolean(node.props?.stacked)}
116 |         curved={extractValue.asOptionalBoolean(node.props?.curved)}
117 |         tooltipRenderer={
118 |           node.props.tooltipTemplate
119 |             ? (tooltipData) => {
120 |                 return (
121 |                   <MemoizedItem
122 |                     node={node.props.tooltipTemplate}
123 |                     item={tooltipData}
124 |                     contextVars={{
125 |                       $tooltip: tooltipData,
126 |                     }}
127 |                     renderChild={renderChild}
128 |                   />
129 |                 );
130 |               }
131 |             : undefined
132 |         }
133 |       >
134 |         {renderChild(node.children)}
135 |       </AreaChart>
136 |     );
137 |   },
138 | );
139 | 
```

--------------------------------------------------------------------------------
/xmlui/src/abstractions/ThemingDefs.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import type { Dispatch, SetStateAction } from "react";
  2 | 
  3 | // This type describes one the available theme tones.
  4 | export type ThemeTone = "light" | "dark";
  5 | 
  6 | // When rendering any part of an XMLUI app, the styles to apply are enclosed in a 
  7 | // theme scope. Most apps use a single theme scope that includes all nodes within 
  8 | // the root app node. However, any app can use multiple theme scopes.
  9 | //
 10 | // The scope determines how the app applies styles to the particular section. This 
 11 | // type defines the properties of such a theme scope.
 12 | export type ThemeScope = {
 13 |   // Gets the id of the scope's theme
 14 |   activeThemeId: string; 
 15 | 
 16 |   // Gets the current tone of the scope's theme
 17 |   activeThemeTone: ThemeTone; 
 18 | 
 19 |   // The HTML element that works as the root of the theme's scope.
 20 |   root: HTMLElement | undefined;
 21 | 
 22 |   // Sets the root HTML element the theme is assigned to
 23 |   setRoot: Dispatch<SetStateAction<HTMLElement | undefined>>;
 24 | 
 25 |   // The active theme in the current scope
 26 |   activeTheme: ThemeDefinition; 
 27 | 
 28 |   // This hash object stores the CSS theme variable names with their CSS values 
 29 |   // definition, like "--xmlui-verticalAlignment-Text-sub": "sub";
 30 |   // "--xmlui-backgroundColor": "var(--xmlui-color-surface-50)"
 31 |   themeStyles: Record<string, string>;
 32 | 
 33 |   // This hash object stores the theme variable names with their CSS values definition,
 34 |   // like "verticalAlignment-Text-sub": "sub"; 
 35 |   // "backgroundColor": "var(--xmlui-color-surface-50)".
 36 |   themeVars: Record<string, string>;
 37 | 
 38 |   // This function retrieves the physical path of the provided resource. The path can
 39 |   // be used as a URL in HTML tags, like in the `src` attribute of `<img>`.
 40 |   getResourceUrl: (resourceString?: string) => string | undefined;
 41 | 
 42 |   // This function gets the value of the specified theme variable.
 43 |   getThemeVar: (themeVar: string) => string | undefined;
 44 | };
 45 | 
 46 | // This type represents the object managing app themes. When an app runs, styles are
 47 | // applied according to the current (active) application theme and tone.
 48 | export type AppThemes = {
 49 |   // Sets the active theme id
 50 |   setActiveThemeId: (newThemeId: string) => void; 
 51 | 
 52 |   // Sets the active theme tone
 53 |   setActiveThemeTone: (newTone: ThemeTone) => void; 
 54 | 
 55 |   // Toggles the current theme tone
 56 |   toggleThemeTone: () => void; 
 57 | 
 58 |   // Gets the id of the active theme
 59 |   activeThemeId: string; 
 60 | 
 61 |   // Gets the tone of the active theme
 62 |   activeThemeTone: ThemeTone; 
 63 | 
 64 |   // This array holds all theme definitions available in the app.
 65 |   themes: Array<ThemeDefinition>; 
 66 | 
 67 |   // This array holds all resource definitions available in the app.
 68 |   resources: Record<string, string>; 
 69 | 
 70 |   // During the build process, resources may be renamed (resource folder and file
 71 |   // hierarchy flattened). This map resolves the original resource URLs to their
 72 |   // corresponding names created during the build.
 73 |   resourceMap: Record<string, string>;
 74 | 
 75 |   // This array lists the ids of available themes in the app.
 76 |   availableThemeIds: Array<string>; 
 77 | 
 78 |   // This property holds the current theme definition used in the app.
 79 |   activeTheme: ThemeDefinition; 
 80 | };
 81 | 
 82 | // This type describes a font definition resource.
 83 | export type FontDef =
 84 |   | {
 85 |       // Specifies a name that will be used as the font face value for font properties
 86 |       fontFamily: string;
 87 | 
 88 |       // A fontStyle value. Accepts two values to specify a range that is supported by
 89 |       // a font-face, for example `fontStyle: oblique 20deg 50deg`
 90 |       fontStyle?: string;
 91 | 
 92 |       // A font-weight value. Accepts two values to specify a range that is supported by
 93 |       // a font-face, for example `font-weight: 100 900`
 94 |       fontWeight?: string;
 95 | 
 96 |       // This property determines how a font face is displayed based on whether and
 97 |       // when it is downloaded and ready to use.
 98 |       fontDisplay?: string;
 99 | 
100 |       // The mime type of the font file
101 |       format?: string; 
102 | 
103 |       // Specifies references to font resources.
104 |       src: string; 
105 |     }
106 |   | string;
107 | 
108 | export interface ThemeDefinitionDetails {
109 |   themeVars?: Record<string, string>;
110 |   resources?: Record<string, string | FontDef>;
111 | }
112 | 
113 | // This type represents a theme definition object. Theme files can use this object's 
114 | // JSON-serialized format to define an app theme; an app can have multiple theme files.
115 | export interface ThemeDefinition extends ThemeDefinitionDetails {
116 |   // Theme id
117 |   id: string; 
118 | 
119 |   // Optional theme name
120 |   name?: string; 
121 | 
122 |   // A theme can extend existing themes. The extension means that the theme variable
123 |   // values defined in the new theme override the base theme's variable values.
124 |   extends?: string | Array<string>;
125 | 
126 |   // This property defines the tone-dependent theme variable values. When a theme 
127 |   // variable value is resolved, the common theme variable values are overridden with 
128 |   // their theme-specific values.
129 |   tones?: Record<string | ThemeTone, ThemeDefinitionDetails>;
130 | }
131 | 
132 | export type DefaultThemeVars = Record<string | ThemeTone, string | Record<string, string>>;
133 | 
```

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

```markdown
  1 | %-DESC-START
  2 | 
  3 | **Key features:**
  4 | - **External content embedding**: Load web pages, documents, or media from external URLs
  5 | - **Security controls**: Built-in sandbox and permission policies for safe content isolation
  6 | - **HTML content support**: Display inline HTML content without external sources
  7 | - **Event handling**: Track loading states with load events
  8 | 
  9 | %-DESC-END
 10 | 
 11 | %-PROP-START src
 12 | 
 13 | ```xmlui-pg copy display name="Example: src"
 14 | <App>
 15 |   <IFrame 
 16 |     src="https://example.com" 
 17 |     width="100%" 
 18 |     height="300px" />
 19 | </App>
 20 | ```
 21 | 
 22 | %-PROP-END
 23 | 
 24 | %-PROP-START srcdoc
 25 | 
 26 | ```xmlui-pg copy display name="Example: srcdoc"
 27 | <App>
 28 |   <IFrame 
 29 |     srcdoc="
 30 |       <h1>Hello World</h1>
 31 |       <p>This is embedded HTML content with <strong>formatting</strong>.</p>
 32 |     "
 33 |     width="100%" 
 34 |     height="200px" />
 35 | </App>
 36 | ```
 37 | 
 38 | %-PROP-END
 39 | 
 40 | %-PROP-START allow
 41 | 
 42 | The `allow` property controls which browser features the embedded content can access. Common values include camera, microphone, geolocation, and fullscreen permissions.
 43 | 
 44 | ```xmlui-pg copy display name="Example: allow"
 45 | <App>
 46 |   <IFrame
 47 |       src="https://www.youtube.com/embed/dQw4w9WgXcQ"
 48 |       allow="camera; microphone; geolocation"
 49 |       width="560px"
 50 |       height="315px"
 51 |       title="Rick Astley - Never Gonna Give You Up (Official Video)"
 52 |     />
 53 | </App>
 54 | ```
 55 | 
 56 | %-PROP-END
 57 | 
 58 | %-PROP-START name
 59 | 
 60 | ```xmlui-pg copy display name="Example: name" /name="myFrame"/
 61 | <App>
 62 |   <VStack gap="$space-2">
 63 |     <Button 
 64 |       label="Open 'Kraftwerk: The Model' in IFrame" 
 65 |       onClick="window.open('https://www.youtube.com/embed/-s4zRw16tMA', 'myFrame')" 
 66 |     />
 67 |     <IFrame 
 68 |       src="https://example.com"
 69 |       name="myFrame"
 70 |       width="100%" 
 71 |       height="300px" />
 72 |   </VStack>
 73 | </App>
 74 | ```
 75 | 
 76 | %-PROP-END
 77 | 
 78 | %-EVENT-START load
 79 | 
 80 | ```xmlui-pg copy display name="Example: load"
 81 | <App var.loadStatus="Loading...">
 82 |   <VStack gap="$space-2">
 83 |     <Text value="Status: {loadStatus}" />
 84 |     <IFrame 
 85 |       src="https://example.com"
 86 |       onLoad="loadStatus = 'Content loaded successfully!'"
 87 |       width="100%" 
 88 |       height="200px" />
 89 |   </VStack>
 90 | </App>
 91 | ```
 92 | 
 93 | %-EVENT-END
 94 | 
 95 | %-STYLE-START
 96 | 
 97 | ### Size Control
 98 | 
 99 | IFrame supports these theme variables for consistent sizing:
100 | - `width-IFrame`
101 | - `height-IFrame`
102 | - `borderRadius-IFrame`
103 | - `border-IFrame`
104 | 
105 | ```xmlui-pg display copy name="Example: IFrame with custom styling"
106 | <App>
107 |   <Theme 
108 |     width-IFrame="400px" 
109 |     height-IFrame="250px"
110 |     borderRadius-IFrame="8px"
111 |     border-IFrame="2px solid $primaryColor">
112 |     <IFrame src="https://example.com" />
113 |   </Theme>
114 | </App>
115 | ```
116 | 
117 | %-STYLE-END
118 | 
119 | %-API-START postMessage
120 | 
121 | ```xmlui-pg copy display name="Example: postMessage" /postMessage/
122 | <App>
123 |   <VStack var.messageStatus="Ready to send" gap="$space-2">
124 |     <Button 
125 |       label="Send Message to IFrame" 
126 |       onClick="
127 |         myIframe.postMessage({type: 'greeting', text: 'Hello from parent!'}, '*');
128 |         messageStatus = 'Message sent!';
129 |       " />
130 |     <Card title="Status: {messageStatus}" />
131 |     <IFrame 
132 |       id="myIframe"
133 |       srcdoc="
134 |         <script>
135 |           window.addEventListener('message', (event) => \{
136 |             console.log('Received message:', event.data);
137 |             document.body.innerHTML = 
138 |               '<h1>Message: ' + JSON.stringify(event.data) + '</h1>';
139 |           });
140 |         </script>
141 |         <h1>Waiting for message...</h1>
142 |       "
143 |       width="100%" 
144 |       height="200px" />
145 |   </VStack>
146 | </App>
147 | ```
148 | 
149 | %-API-END
150 | 
151 | %-API-START getContentWindow
152 | 
153 | Get access to the iframe's content window object. Returns null if the content window is not accessible.
154 | 
155 | ```xmlui-pg copy display name="Example: getContentWindow" /getContentWindow/
156 | <App>
157 |   <VStack var.windowStatus="Not checked yet" gap="$space-2">
158 |     <Button 
159 |       label="Check Content Window" 
160 |       onClick="
161 |         const contentWindow = myIframe.getContentWindow();
162 |         windowStatus = contentWindow 
163 |           ? 'Content window is accessible' 
164 |           : 'Content window is not accessible';
165 |       " />
166 |     <Card title="Status: {windowStatus}" />
167 |     <IFrame 
168 |       id="myIframe"
169 |       src="https://example.com"
170 |       width="100%" 
171 |       height="200px" />
172 |   </VStack>
173 | </App>
174 | ```
175 | 
176 | %-API-END
177 | 
178 | %-API-START getContentDocument
179 | 
180 | Get access to the iframe's content document object. Returns null if the content document is not accessible.
181 | 
182 | ```xmlui-pg copy display name="Example: getContentDocument" /getContentDocument/
183 | <App>
184 |   <VStack var.iFrameTitle="<not queried yet>" >
185 |     <Button 
186 |       label="Get Document Title" 
187 |       onClick="
188 |         const contentDoc = myIframe.getContentDocument();
189 |         iFrameTitle = contentDoc 
190 |           ? contentDoc.title 
191 |           : 'Content document not accessible';
192 |       " />
193 |     <Card title="IFrame title: {iFrameTitle}" />
194 |     <IFrame 
195 |       id="myIframe"
196 |       srcdoc="
197 |         <html>
198 |           <head><title>My Awesome Document</title></head>
199 |           <body><h1>Awesome Content</h1></body>
200 |         </html>"
201 |       width="100%" 
202 |       height="200px" />
203 |   </VStack>
204 | </App>
205 | ```
206 | 
207 | %-API-END
208 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components-core/interception/Backend.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { isArray, isObject, mapValues } from "lodash-es";
  2 | 
  3 | import type { BindingTreeEvaluationContext } from "../script-runner/BindingTreeEvaluationContext";
  4 | import { delay } from "../utils/misc";
  5 | import { runEventHandlerCode } from "../utils/statementUtils";
  6 | import { dateFunctions } from "../appContext/date-functions";
  7 | import { miscellaneousUtils } from "../appContext/misc-utils";
  8 | import { getDate } from "../utils/date-utils";
  9 | import Errors from "../interception/Errors";
 10 | import type { AuthService } from "../interception/ApiInterceptor";
 11 | import type {
 12 |   BackendDefinition,
 13 |   BackendEnvironment,
 14 |   IDatabase,
 15 |   RequestParams,
 16 | } from "./abstractions";
 17 | 
 18 | // Use this backend environment as the default
 19 | export const defaultBackendEnvironment: BackendEnvironment = {
 20 |   getDate: (date?: string | number | Date) => (date ? new Date(date) : new Date()),
 21 | };
 22 | 
 23 | const mapValuesDeep = (obj: any, cb: (o: any) => any): any => {
 24 |   if (isArray(obj)) {
 25 |     return obj.map((innerObj) => mapValuesDeep(innerObj, cb));
 26 |   } else if (isObject(obj)) {
 27 |     return mapValues(obj, (val) => mapValuesDeep(val, cb));
 28 |   } else {
 29 |     return cb(obj);
 30 |   }
 31 | };
 32 | 
 33 | export class CookieService {
 34 |   private cookies: Record<string, string | Array<string>> = {};
 35 |   public setCookie(key: string, value: string | Array<string>) {
 36 |     this.cookies[key] = value;
 37 |   }
 38 | 
 39 |   public getCookieHeader() {
 40 |     const cookieArrays: Array<[string, string]> = [];
 41 | 
 42 |     Object.entries(this.cookies).forEach(([key, value]) => {
 43 |       if (Array.isArray(value)) {
 44 |         value.forEach((val) => cookieArrays.push(["Set-Cookie", `${key}=${val}`]));
 45 |       } else {
 46 |         cookieArrays.push(["Set-Cookie", `${key}=${value}`]);
 47 |       }
 48 |     });
 49 | 
 50 |     return new Headers(cookieArrays);
 51 |   }
 52 | }
 53 | 
 54 | export class HeaderService {
 55 |   private headers: Record<string, string> = {};
 56 |   public setHeader(key: string, value: string) {
 57 |     this.headers[key] = value;
 58 |   }
 59 | 
 60 |   public getHeaders() {
 61 |     const headersArray: Array<[string, string]> = [];
 62 | 
 63 |     Object.entries(this.headers).forEach(([key, value]) => {
 64 |       headersArray.push([key, value]);
 65 |     });
 66 | 
 67 |     return new Headers(headersArray);
 68 |   }
 69 | }
 70 | 
 71 | export class Backend {
 72 |   private readonly resolvedHelpers?: Record<string, any>;
 73 |   private readonly apiStateHash: Record<string, any> = {};
 74 | 
 75 |   constructor(
 76 |     public readonly definition: BackendDefinition,
 77 |     public readonly db: IDatabase,
 78 |     public readonly authService: AuthService,
 79 |   ) {
 80 |     this.resolvedHelpers = mapValuesDeep(definition.helpers, (helper) => {
 81 |       if (typeof helper === "string") {
 82 |         return (...params: any[]) => this.runFn(helper, ...params);
 83 |       }
 84 |       return helper;
 85 |     });
 86 |     if (definition.initialize) {
 87 |       void this.runFn(definition.initialize);
 88 |     }
 89 |   }
 90 | 
 91 |   async executeOperation(
 92 |     operationId: string,
 93 |     requestParams: RequestParams,
 94 |     cookieService: CookieService,
 95 |     headerService: HeaderService,
 96 |   ) {
 97 |     const handler = this.definition.operations?.[operationId];
 98 |     if (!handler) {
 99 |       throw new Error(`Unknown backend operation: ${operationId}`);
100 |     }
101 |     return await this.runFn(handler, requestParams, cookieService, headerService);
102 |   }
103 | 
104 |   private async runFn(src: string, ...args: any[]) {
105 |     let localContext = {
106 |       ...this.resolvedHelpers,
107 |       $db: this.db,
108 |       $state: this.apiStateHash,
109 |       $authService: this.authService,
110 |       $env: defaultBackendEnvironment,
111 |       $loggedInUser: this.authService.getLoggedInUser(),
112 |       $pathParams: args[0]?.pathParams,
113 |       $queryParams: args[0]?.queryParams,
114 |       $requestBody: args[0]?.requestBody,
115 |       $cookies: args[0]?.cookies,
116 |       $requestHeaders: args[0]?.requestHeaders,
117 |       $cookieService: args[1], //TODO really ugly, temporary solution
118 |       $headerService: args[2], //TODO really ugly, temporary solution
119 |     };
120 |     const evalContext = createEvalContext({
121 |       localContext: localContext,
122 |       eventArgs: args,
123 |       appContext: {
124 |         ...dateFunctions,
125 |         ...miscellaneousUtils,
126 |         delay,
127 |         Errors,
128 |         createFile: (...args: any[]) => {
129 |           return new File(args[0], args[1], args[2]);
130 |         },
131 |         appendBlob: (blob1: Blob | undefined | null, blob2: Blob) => {
132 |           if (blob1 && blob2) {
133 |             return new Blob([blob1, blob2], { type: blob1.type || blob2.type });
134 |           }
135 |           if (blob1) {
136 |             return blob1;
137 |           }
138 |           if (blob2) {
139 |             return blob2;
140 |           }
141 |           return null;
142 |         },
143 |         getDate,
144 |       },
145 |     });
146 | 
147 |     await runEventHandlerCode(src, evalContext);
148 | 
149 |     return evalContext.mainThread?.blocks?.length
150 |       ? evalContext.mainThread.blocks[evalContext.mainThread.blocks.length - 1].returnValue
151 |       : undefined;
152 |   }
153 | }
154 | 
155 | function createEvalContext(
156 |   parts: Partial<BindingTreeEvaluationContext>,
157 | ): BindingTreeEvaluationContext {
158 |   return {
159 |     ...{
160 |       mainThread: {
161 |         childThreads: [],
162 |         blocks: [{ vars: {} }],
163 |         loops: [],
164 |         breakLabelValue: -1,
165 |       },
166 |     },
167 |     ...parts,
168 |   };
169 | }
170 | 
```

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

```markdown
  1 | %-DESC-START
  2 | 
  3 | It is often used in forms, see [this guide](/forms) for details.
  4 | 
  5 | %-DESC-END
  6 | 
  7 | %-PROP-START autoSize
  8 | 
  9 | > **Note**: If either `autoSize`, `maxRows` or `minRows` is set, the `rows` prop has no effect.
 10 | 
 11 | Write multiple lines in the `TextArea` in the demo below to see how it resizes automatically.
 12 | 
 13 | ```xmlui-pg copy display name="Example: autoSize" height="240px"
 14 | <App>
 15 |   <TextArea autoSize="true" />
 16 | </App>
 17 | ```
 18 | 
 19 | %-PROP-END
 20 | 
 21 | %-PROP-START enabled
 22 | 
 23 | ```xmlui-pg copy display name="Example: enabled"
 24 | <App>
 25 |   <TextArea enabled="false" />
 26 | </App>
 27 | ```
 28 | 
 29 | %-PROP-END
 30 | 
 31 | %-PROP-START enterSubmits
 32 | 
 33 | Press `Enter` after writing something in the `TextArea` in the demo below.
 34 | See [Using Forms](/forms) for details.
 35 | 
 36 | ```xmlui-pg copy display name="Example: enterSubmits"
 37 | <App>
 38 |   <Form onSubmit="toast.success(JSON.stringify(address.value))">
 39 |     <TextArea
 40 |       id="address"
 41 |       enterSubmits="true"
 42 |       initialValue="Suzy Queue, 4455 Landing Lange, APT 4, Louisville, KY 40018-1234" />
 43 |   </Form>
 44 | </App>
 45 | ```
 46 | 
 47 | %-PROP-END
 48 | 
 49 | %-PROP-START initialValue
 50 | 
 51 | The initial value displayed in the input field.
 52 | 
 53 | ```xmlui-pg copy display name="Example: initialValue"
 54 | <App>
 55 |   <TextArea initialValue="Example text" />
 56 | </App>
 57 | ```
 58 | 
 59 | %-PROP-END
 60 | 
 61 | %-PROP-START maxRows
 62 | 
 63 | > **Note**: If either `autoSize`, `maxRows` or `minRows` is set, the `rows` prop has no effect.
 64 | 
 65 | ```xmlui-pg copy {3} display name="Example: maxRows" height="160px"
 66 | <App>
 67 |   <TextArea
 68 |     maxRows="3"
 69 |     initialValue="Lorem ipsum dolor sit amet,
 70 |     consectetur adipiscing elit,
 71 |     sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
 72 |     Ut enim ad minim veniam,
 73 |     quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat." />
 74 | </App>
 75 | ```
 76 | 
 77 | %-PROP-END
 78 | 
 79 | %-PROP-START minRows
 80 | 
 81 | > **Note**: If either `autoSize`, `maxRows` or `minRows` is set, the `rows` prop has no effect.
 82 | 
 83 | ```xmlui-pg copy display name="Example: minRows" height="200px"
 84 | <App>
 85 |   <TextArea minRows="3" initialValue="Lorem ipsum dolor sit amet..." />
 86 | </App>
 87 | ```
 88 | 
 89 | %-PROP-END
 90 | 
 91 | %-PROP-START placeholder
 92 | 
 93 | ```xmlui-pg copy display name="Example: placeholder"
 94 | <App>
 95 |   <TextArea placeholder="This is a placeholder" />
 96 | </App>
 97 | ```
 98 | 
 99 | %-PROP-END
100 | 
101 | %-PROP-START readOnly
102 | 
103 | ```xmlui-pg copy display name="Example: readOnly"
104 | <App>
105 |   <TextArea initialValue="Example text" readOnly="{true}" />
106 | </App>
107 | ```
108 | 
109 | %-PROP-END
110 | 
111 | %-PROP-START resize
112 | 
113 | If you allow resizing, the `TextArea` turns off automatic sizing.
114 | 
115 | When you allow vertical resizing, you can limit the sizable range according to `minRows` and `maxRows`.
116 | 
117 | Drag the small resize indicators at the bottom right on each of the controls in the demo.
118 | 
119 | ```xmlui-pg copy display name="Example: resize" height="300px"
120 | <App>
121 |   <TextArea resize="vertical" minRows="1" maxRows="8" />
122 |   <TextArea resize="both" />
123 | </App>
124 | ```
125 | 
126 | %-PROP-END
127 | 
128 | %-PROP-START rows
129 | 
130 | > **Note**: If either `autoSize`, `maxRows` or `minRows` is set, the `rows` prop has no effect.
131 | 
132 | ```xmlui-pg copy display name="Example: rows"
133 | <App>
134 |   <TextArea rows="10" />
135 | </App>
136 | ```
137 | 
138 | %-PROP-END
139 | 
140 | %-PROP-START validationStatus
141 | 
142 | This prop is used to visually indicate status changes reacting to form field validation.
143 | 
144 | ```xmlui-pg copy display name="Example: validationStatus"
145 | <App>
146 |   <TextArea />
147 |   <TextArea validationStatus="valid" />
148 |   <TextArea validationStatus="warning" />
149 |   <TextArea validationStatus="error" />
150 | </App>
151 | ```
152 | 
153 | %-PROP-END
154 | 
155 | %-EVENT-START didChange
156 | 
157 | Write in the input field and see how the `Text` underneath it is updated in parallel.
158 | 
159 | ```xmlui-pg copy display name="Example: didChange"
160 | <App var.field="">
161 |   <TextArea 
162 |     initialValue="{field}" 
163 |     onDidChange="(val) => field = val" 
164 |   />
165 |   <Text value="{field}" />
166 | </App>
167 | ```
168 | 
169 | %-EVENT-END
170 | 
171 | %-EVENT-START gotFocus
172 | 
173 | Clicking on the `TextArea` in the example demo changes the label text.
174 | Note how clicking elsewhere resets the text to the original.
175 | 
176 | ```xmlui-pg copy display name="Example: gotFocus/lostFocus"
177 | <App>
178 |   <TextArea
179 |     initialValue="{focused === true ? 'I got focused!' : 'I lost focus...'}"
180 |     onGotFocus="focused = true"
181 |     onLostFocus="focused = false"
182 |     var.focused="{false}" />
183 | </App>
184 | ```
185 | 
186 | %-EVENT-END
187 | 
188 | %-API-START focus
189 | 
190 | ```xmlui-pg copy display name="Example: focus"
191 | <App>
192 |   <Button label="Trigger Focus" onClick="inputComponent.focus()" />
193 |   <TextArea id="inputComponent" />
194 | </App>
195 | ```
196 | 
197 | %-API-END
198 | 
199 | %-API-START value
200 | 
201 | In the example below, typing in the `TextArea` will also display the length of the text typed into it above the field:
202 | 
203 | ```xmlui-pg copy display name="Example: value"
204 | <App>
205 |   <Text value="TextArea content length: {inputComponent.value.length}" />
206 |   <TextArea id="inputComponent" />
207 | </App>
208 | ```
209 | 
210 | %-API-END
211 | 
212 | %-API-START setValue
213 | 
214 | ```xmlui-pg copy display name="Example: setValue"
215 | <App var.changes="">
216 |   <TextArea
217 |     id="inputField"
218 |     readOnly="true"
219 |     onDidChange="changes++" />
220 |   <HStack>
221 |     <Button
222 |       label="Check"
223 |       onClick="inputField.setValue('example ')" />
224 |     <Text value="Number of changes: {changes}" />
225 |   </HStack>
226 | </App>
227 | ```
228 | 
229 | %-API-END
230 | 
```

--------------------------------------------------------------------------------
/xmlui/scripts/generate-docs/generate-summary-files.mjs:
--------------------------------------------------------------------------------

```
  1 | import * as fs from "fs";
  2 | import * as path from "path";
  3 | import { FOLDERS } from "./folders.mjs";
  4 | import { createTable, getSectionBeforeAndAfter } from "./utils.mjs";
  5 | import { logger, LOGGER_LEVELS, processError } from "./logger.mjs";
  6 | import {
  7 |   COMPONENT_STATUS_CONFIG,
  8 |   SUMMARY_FILE_CONFIG,
  9 |   OUTPUT_FILES
 10 | } from "./constants.mjs";
 11 | 
 12 | const ACCEPTED_STATUSES = COMPONENT_STATUS_CONFIG.ACCEPTED_STATUSES;
 13 | const DEFAULT_STATUS = COMPONENT_STATUS_CONFIG.DEFAULT_STATUS;
 14 | 
 15 | logger.setLevels(LOGGER_LEVELS.warning, LOGGER_LEVELS.error);
 16 | logger.info("Generating summary files...");
 17 | 
 18 | // components
 19 | logger.info("Components summary");
 20 | 
 21 | const componentsMetaFolder = path.join(FOLDERS.script, "metadata", "components");
 22 | const componentsOutFolder = path.join(FOLDERS.docsRoot, "content", "components");
 23 | 
 24 | generateComponentsSummary(
 25 |   path.join(componentsMetaFolder, OUTPUT_FILES.METADATA_JSON),
 26 |   "",
 27 |   componentsOutFolder,
 28 |   "_overview.md",
 29 |   SUMMARY_FILE_CONFIG.COMPONENTS_OVERVIEW_HEADER,
 30 | );
 31 | 
 32 | logger.info("Components summary DONE");
 33 | 
 34 | // NOTE: Unused
 35 | // extensions
 36 | // logger.info("Extensions summary");
 37 | 
 38 | // const extensionsMetaFolder = path.join(FOLDERS.script, "metadata", "extensions");
 39 | // fs.readdirSync(extensionsMetaFolder).forEach((file) => {
 40 | //   if (path.extname(file) === ".json") {
 41 | 
 42 | //     let extensionName = path.basename(file, ".json");
 43 | //     extensionName = extensionName.replace("-metadata", "");
 44 | //     const extensionOutFolder = path.join(FOLDERS.docsRoot, "content", "extensions", extensionName);
 45 | 
 46 | //     generateComponentsSummary(
 47 | //       path.join(extensionsMetaFolder, file),
 48 | //       `extensions/${extensionName}`,
 49 | //       extensionOutFolder,
 50 | //       `_overview.md`,
 51 | //       SUMMARY_FILE_CONFIG.PACKAGE_COMPONENTS_HEADER,
 52 | //     );
 53 | //   }
 54 | // });
 55 | 
 56 | // logger.info("Extensions summary DONE");
 57 | 
 58 | // ---
 59 | 
 60 | /**
 61 |  * Generates the component summary table and adds it to the provided file.
 62 |  * The function looks for the summary section in the provided file and regenerates it if present,
 63 |  * otherwise it appends one to the end of the file.
 64 |  * @param {string} metadataFile The path & name of the file containing the component metadata
 65 |  * @param {string} urlPath the path that is used to point to the generated component article in the docs
 66 |  * @param {string} outFolder The folder to add the summary to
 67 |  * @param {string} summaryFile The name of the file (with extesion) to add the summary to
 68 |  * @param {string} summarySectionName The section to look for and add the summary to
 69 |  * @param {boolean?} hasRowNums Whether to add row numbers to the summary table
 70 |  */
 71 | function generateComponentsSummary(
 72 |   metadataFile,
 73 |   urlPath,
 74 |   outFolder,
 75 |   summaryFile,
 76 |   summarySectionName,
 77 |   hasRowNums,
 78 | ) {
 79 |   try {
 80 |     if (!fs.existsSync(metadataFile)) {
 81 |       throw new Error(
 82 |         `Metadata file does not exist: ${metadataFile}. Please run generate-docs first.`,
 83 |       );
 84 |     }
 85 |     
 86 |     const outFile = path.join(outFolder, summaryFile ?? `_overview.md`);
 87 |     if (!fs.existsSync(outFile)) {
 88 |       fs.writeFileSync(outFile, "");
 89 |     }
 90 | 
 91 |     const metadata = JSON.parse(fs.readFileSync(metadataFile, "utf8"));
 92 | 
 93 |     const table = createSummaryTable(metadata, urlPath, outFolder, hasRowNums);
 94 | 
 95 |     const fileContents = fs.readFileSync(outFile, "utf8");
 96 |     let { beforeSection, afterSection } = getSectionBeforeAndAfter(
 97 |       fileContents,
 98 |       summarySectionName,
 99 |     );
100 | 
101 |     beforeSection = beforeSection.length > 0 ? beforeSection + "\n\n" : beforeSection;
102 |     const summary = beforeSection + `${summarySectionName}\n\n` + table + "\n" + afterSection;
103 |     fs.writeFileSync(outFile, summary);
104 |   } catch (error) {
105 |     processError(error);
106 |   }
107 | }
108 | 
109 | /**
110 |  * Translates a metadata object to a summary table in markdown.
111 |  * @param {Record<string, any>} metadata object with components and their metadata
112 |  * @param {string} urlPath the path that is used to point to the generated component article in the docs
113 |  * @param {string} filePath the path that contains the generated component article file itself
114 |  * @param {boolean?} hasRowNums should the table have numbered rows
115 |  * @returns stringified markdown table
116 |  */
117 | function createSummaryTable(metadata, urlPath, filePath, hasRowNums = false) {
118 |   const headers = [{ value: "Component", style: "center" }, "Description"];
119 |   const rows = metadata
120 |     .sort((a, b) => a.displayName.localeCompare(b.displayName))
121 |     .filter((component) => {
122 |       const componentStatus = component.status ?? DEFAULT_STATUS;
123 |       return !ACCEPTED_STATUSES.includes(componentStatus) ? false : true;
124 |     })
125 |     .map((component) => {
126 |       const componentFilePath = path.join(filePath, `${component.displayName}.md`);
127 |       const componentUrl = urlPath ? `./${urlPath}/${component.displayName}` : `./${component.displayName}`;
128 |       return [
129 |         fs.existsSync(componentFilePath)
130 |           ? `[${component.displayName}](${componentUrl})`
131 |           : component.displayName,
132 |         component.description,
133 |       ];
134 |     });
135 | 
136 |   return createTable({ headers, rows, rowNums: hasRowNums });
137 | }
138 | 
```

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

```typescript
  1 | import { createComponentRenderer } from "../../components-core/renderers";
  2 | import { createMetadata } from "../metadata-helpers";
  3 | import { parseScssVar } from "../../components-core/theming/themeVars";
  4 | import { Tooltip } from "./TooltipNative";
  5 | import type { TooltipProps } from "./TooltipNative";
  6 | import styles from "./Tooltip.module.scss";
  7 | 
  8 | const COMP = "Tooltip";
  9 | 
 10 | export const TooltipMd = createMetadata({
 11 |   status: "stable",
 12 |   description: "A tooltip component that displays text when hovering over trigger content.",
 13 |   props: {
 14 |     text: {
 15 |       description: "The text content to display in the tooltip",
 16 |       type: "string",
 17 |       isRequired: false,
 18 |     },
 19 |     markdown: {
 20 |       description: "The markdown content to display in the tooltip",
 21 |       type: "string",
 22 |       isRequired: false,
 23 |     },
 24 |     tooltipTemplate: {
 25 |       description: "The template for the tooltip content",
 26 |       type: "Component",
 27 |       isRequired: false,
 28 |     },
 29 |     delayDuration: {
 30 |       description:
 31 |         "The duration from when the mouse enters a tooltip trigger until the tooltip opens (in ms)",
 32 |       type: "number",
 33 |       defaultValue: 700,
 34 |     },
 35 |     skipDelayDuration: {
 36 |       description:
 37 |         "How much time a user has to enter another trigger without incurring a delay again (in ms)",
 38 |       type: "number",
 39 |       defaultValue: 300,
 40 |     },
 41 |     defaultOpen: {
 42 |       description: "The open state of the tooltip when it is initially rendered",
 43 |       type: "boolean",
 44 |       defaultValue: false,
 45 |     },
 46 |     showArrow: {
 47 |       description: "Whether to show the arrow pointing to the trigger element",
 48 |       type: "boolean",
 49 |       defaultValue: false,
 50 |     },
 51 |     side: {
 52 |       description: "The preferred side of the trigger to render against when open",
 53 |       type: "string",
 54 |       availableValues: ["top", "right", "bottom", "left"],
 55 |       defaultValue: "top",
 56 |     },
 57 |     align: {
 58 |       description: "The preferred alignment against the trigger",
 59 |       type: "string",
 60 |       availableValues: ["start", "center", "end"],
 61 |       defaultValue: "center",
 62 |     },
 63 |     sideOffset: {
 64 |       description: "The distance in pixels from the trigger",
 65 |       type: "number",
 66 |       defaultValue: 4,
 67 |     },
 68 |     alignOffset: {
 69 |       description: "An offset in pixels from the 'start' or 'end' alignment options",
 70 |       type: "number",
 71 |       defaultValue: 0,
 72 |     },
 73 |     avoidCollisions: {
 74 |       description:
 75 |         "When true, overrides the side and align preferences to prevent collisions with boundary edges",
 76 |       type: "boolean",
 77 |       defaultValue: true,
 78 |     },
 79 |   },
 80 |   events: {},
 81 |   apis: {},
 82 |   contextVars: {},
 83 |   themeVars: parseScssVar(styles.themeVars),
 84 |   limitThemeVarsToComponent: true,
 85 |   defaultThemeVars: {
 86 |     [`backgroundColor-${COMP}`]: "$color-surface-0",
 87 |     [`border-${COMP}`]: "none",
 88 |     [`textColor-${COMP}`]: "$textcolor-primary",
 89 |     [`borderRadius-${COMP}`]: "4px",
 90 |     [`fontSize-${COMP}`]: "15px",
 91 |     [`lineHeight-${COMP}`]: "1",
 92 |     [`paddingTop-${COMP}`]: "10px",
 93 |     [`paddingBottom-${COMP}`]: "10px",
 94 |     [`paddingLeft-${COMP}`]: "15px",
 95 |     [`paddingRight-${COMP}`]: "15px",
 96 |     [`boxShadow-${COMP}`]:
 97 |       "hsl(206 22% 7% / 35%) 0px 10px 38px -10px, hsl(206 22% 7% / 20%) 0px 10px 20px -15px",
 98 |     [`fill-arrow-${COMP}`]: "$color-surface-200",
 99 |     [`stroke-arrow-${COMP}`]: "$color-surface-200",
100 |     [`strokeWidth-arrow-${COMP}`]: "0",
101 |     [`animationDuration-${COMP}`]: "400ms",
102 |     [`animation-${COMP}`]: "cubic-bezier(0.16, 1, 0.3, 1)",
103 |     dark: {
104 |       [`backgroundColor-${COMP}`]: "$color-surface-200",
105 |     },
106 |   },
107 | });
108 | 
109 | export const tooltipComponentRenderer = createComponentRenderer(
110 |   "Tooltip",
111 |   TooltipMd,
112 |   ({ node, extractValue, renderChild, layoutContext }) => {
113 |     // If there are no children, do not render anything
114 |     if (!node.children || node.children.length === 0) {
115 |       return null;
116 |     }
117 | 
118 |     // If text is not provided, do not render anything
119 |     const text = extractValue.asOptionalString(node.props.text);
120 |     const markdown = extractValue.asOptionalString(node.props.markdown);
121 |     const tooltipTemplate = node.props.tooltipTemplate;
122 | 
123 |     return (
124 |       <Tooltip
125 |         text={text}
126 |         markdown={markdown}
127 |         tooltipTemplate={renderChild(tooltipTemplate)}
128 |         delayDuration={extractValue.asOptionalNumber(node.props.delayDuration)}
129 |         skipDelayDuration={extractValue.asOptionalNumber(node.props.skipDelayDuration)}
130 |         defaultOpen={extractValue.asOptionalBoolean(node.props.defaultOpen)}
131 |         showArrow={extractValue.asOptionalBoolean(node.props.showArrow)}
132 |         side={extractValue.asOptionalString(node.props.side) as TooltipProps["side"]}
133 |         align={extractValue.asOptionalString(node.props.align) as TooltipProps["align"]}
134 |         sideOffset={extractValue.asOptionalNumber(node.props.sideOffset)}
135 |         alignOffset={extractValue.asOptionalNumber(node.props.alignOffset)}
136 |         avoidCollisions={extractValue.asOptionalBoolean(node.props.avoidCollisions)}
137 |       >
138 |         {renderChild(node.children, layoutContext)}
139 |       </Tooltip>
140 |     );
141 |   },
142 | );
143 | 
```

--------------------------------------------------------------------------------
/xmlui/src/testing/themed-app-test-helpers.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import type { BrowserContext, Locator, Page } from "@playwright/test";
  2 | import { xmlUiMarkupToComponent } from "../components-core/xmlui-parser";
  3 | import type { ThemeDefinition } from "../abstractions/ThemingDefs";
  4 | import type { ComponentDef, CompoundComponentDef } from "../abstractions/ComponentDefs";
  5 | import type { StandaloneAppDescription } from "../components-core/abstractions/standalone";
  6 | 
  7 | type EntryPoint = string | Record<string, any>;
  8 | type UnparsedAppDescription = Omit<Partial<StandaloneAppDescription>, "entryPoint"> & {
  9 |   entryPoint?: EntryPoint;
 10 | };
 11 | 
 12 | export type ThemeTestDesc = {
 13 |   themeVar: string;
 14 |   themeVarAsCSS: string;
 15 |   expected: string;
 16 |   dependsOnVars?: Record<string, string>;
 17 | };
 18 | 
 19 | function parseComponent(entryPoint: ComponentDef<any> | string) {
 20 |   if (typeof entryPoint === "string") {
 21 |     return xmlUiMarkupToComponent(entryPoint).component;
 22 |   }
 23 |   return entryPoint;
 24 | }
 25 | 
 26 | export async function initApp(
 27 |   page: Page,
 28 |   appDescription: UnparsedAppDescription,
 29 |   url: string = "/",
 30 |   resources = {},
 31 | ) {
 32 |   const { entryPoint, components } = appDescription;
 33 | 
 34 |   const _appDescription: StandaloneAppDescription = {
 35 |     ...appDescription,
 36 |     name: appDescription.name || "Test App",
 37 |     entryPoint: parseComponent(entryPoint as ComponentDef) as ComponentDef,
 38 |     resources,
 39 |     components: (!components
 40 |       ? undefined
 41 |       : Array.isArray(components)
 42 |         ? components.map((comp) => parseComponent(comp as unknown as ComponentDef))
 43 |         : [parseComponent(components)]) as CompoundComponentDef[],
 44 |   };
 45 | 
 46 |   await page.addInitScript((app) => {
 47 |     // @ts-ignore
 48 |     window.TEST_ENV = app;
 49 |   }, _appDescription);
 50 |   await page.goto(url);
 51 | }
 52 | 
 53 | export async function prepPage(
 54 |   co: BrowserContext,
 55 |   appDesc: StandaloneAppDescription,
 56 |   url: string = "/",
 57 | ) {
 58 |   const context = co;
 59 |   const page = await context.newPage();
 60 |   await initApp(page, appDesc, url);
 61 |   return page;
 62 | }
 63 | 
 64 | export async function initThemedApp(
 65 |   page: Page,
 66 |   entryPoint: EntryPoint,
 67 |   theme: Partial<ThemeDefinition>,
 68 | ) {
 69 |   theme.id ??= "testTheme";
 70 |   theme.name ??= "Custom Test theme";
 71 |   await initApp(page, { entryPoint, defaultTheme: theme.id, themes: [theme as any] });
 72 | }
 73 | 
 74 | /**
 75 |  * @param percentage a percenage value as a string, like "40%"
 76 |  * @param scalarOf100Percent The value to multiply the percentage by
 77 |  */
 78 | export function scalePercentBy(scalarOf100Percent: number, percentage: string) {
 79 |   if (!percentage.endsWith("%")) {
 80 |     throw new Error("argument doesn't end with % sign");
 81 |   }
 82 |   const percentageNum = Number(percentage.slice(0, -1));
 83 |   return (scalarOf100Percent / 100) * percentageNum;
 84 | }
 85 | 
 86 | export function getBoundingRect(locator: Locator) {
 87 |   return locator.evaluate((element) => element.getBoundingClientRect());
 88 | }
 89 | 
 90 | export async function getFullRectangle(locator: Locator) {
 91 |   const boundingRect = await locator.evaluate((element) => element.getBoundingClientRect());
 92 | 
 93 |   const margins = await getElementStyles(locator, [
 94 |     "margin-left",
 95 |     "margin-right",
 96 |     "margin-top",
 97 |     "margin-bottom",
 98 |   ]);
 99 |   const marginLeft = parseFloat(margins["margin-left"]);
100 |   const marginRight = parseFloat(margins["margin-right"]);
101 |   const marginTop = parseFloat(margins["margin-top"]);
102 |   const marginBottom = parseFloat(margins["margin-bottom"]);
103 | 
104 |   const width = boundingRect.width + marginLeft + marginRight;
105 |   const height = boundingRect.height + marginTop + marginBottom;
106 |   const left = boundingRect.left - marginLeft;
107 |   const right = boundingRect.right + marginRight;
108 |   const top = boundingRect.top - marginTop;
109 |   const bottom = boundingRect.bottom + marginBottom;
110 |   return { width, height, left, right, top, bottom };
111 | }
112 | 
113 | export async function isElementOverflown(locator: Locator, direction: "x" | "y" | "both" = "both") {
114 |   const [width, height, scrollWidth, scrollHeight] = await locator.evaluate((element) => [
115 |     element.clientWidth,
116 |     element.clientHeight,
117 |     element.scrollWidth,
118 |     element.scrollHeight,
119 |   ]);
120 |   if (direction === "x") return scrollWidth > width;
121 |   if (direction === "y") return scrollHeight > height;
122 |   return scrollWidth > width && scrollHeight > height;
123 | }
124 | 
125 | export function pixelStrToNum(pixelStr: string) {
126 |   return Number(pixelStr.replace("px", ""));
127 | }
128 | 
129 | export function getElementStyle(locator: Locator, style: string) {
130 |   return locator.evaluate(
131 |     (element, style) => window.getComputedStyle(element).getPropertyValue(style),
132 |     style,
133 |   );
134 | }
135 | 
136 | /**
137 |  * Retreives all the provided style properties from the locator
138 |  * @returns an object with the keys being the elements of the styles argument
139 |  */
140 | export function getElementStyles(locator: Locator, styles: string[] = []) {
141 |   return locator.evaluate(
142 |     (element, styles) =>
143 |       Object.fromEntries(
144 |         styles.map((styleName) => [
145 |           styleName,
146 |           window.getComputedStyle(element).getPropertyValue(styleName),
147 |         ]),
148 |       ),
149 |     styles,
150 |   );
151 | }
152 | 
153 | export async function getStyle(page: Page, testId: string, style: string) {
154 |   const locator = page.getByTestId(testId);
155 |   return await getElementStyle(locator, style);
156 | }
157 | 
```

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

```typescript
  1 | import styles from "./ExpandableItem.module.scss";
  2 | 
  3 | import { createComponentRenderer } from "../../components-core/renderers";
  4 | import { parseScssVar } from "../../components-core/theming/themeVars";
  5 | import { iconPositionMd } from "../abstractions";
  6 | import { createMetadata, d, dComponent } from "../../components/metadata-helpers";
  7 | import { defaultExpandableItemProps, ExpandableItem } from "./ExpandableItemNative";
  8 | 
  9 | const COMP = "ExpandableItem";
 10 | 
 11 | export const ExpandableItemMd = createMetadata({
 12 |   status: "stable",
 13 |   description:
 14 |     "`ExpandableItem` creates expandable/collapsible section, similar to the HTML " +
 15 |     "details disclosure element. When the user clicks on the `summary` the content " +
 16 |     "expands or collapses.",
 17 |   props: {
 18 |     summary: dComponent("The summary content that is always visible and acts as the trigger."),
 19 |     initiallyExpanded: {
 20 |       description: "Determines if the component is initially expanded when rendered.",
 21 |       valueType: "boolean",
 22 |       defaultValue: defaultExpandableItemProps.initiallyExpanded,
 23 |     },
 24 |     enabled: {
 25 |       description:
 26 |         "When true, the expandable item can be opened and closed. When false, it cannot be toggled.",
 27 |       valueType: "boolean",
 28 |       defaultValue: defaultExpandableItemProps.enabled,
 29 |     },
 30 |     iconCollapsed: {
 31 |       description: "The icon to display when the item is collapsed.",
 32 |       valueType: "string",
 33 |       defaultValue: defaultExpandableItemProps.iconCollapsed,
 34 |     },
 35 |     iconExpanded: {
 36 |       description: "The icon to display when the item is expanded.",
 37 |       valueType: "string",
 38 |       defaultValue: defaultExpandableItemProps.iconExpanded,
 39 |     },
 40 |     iconPosition: {
 41 |       description: "Determines the position of the icon (start or end).",
 42 |       valueType: "string",
 43 |       availableValues: iconPositionMd,
 44 |       defaultValue: defaultExpandableItemProps.iconPosition,
 45 |     },
 46 |     withSwitch: {
 47 |       description: "When true, a switch is used instead of an icon to toggle the expanded state.",
 48 |       valueType: "boolean",
 49 |       defaultValue: defaultExpandableItemProps.withSwitch,
 50 |     },
 51 |   },
 52 |   events: {
 53 |     expandedChange: d(
 54 |       `This event fires when the expandable item is expanded or collapsed. It provides a boolean value indicating the new state.`,
 55 |     ),
 56 |   },
 57 |   apis: {
 58 |     expand: {
 59 |       description: `This method expands the item.`,
 60 |       signature: "expand(): void",
 61 |     },
 62 |     collapse: {
 63 |       description: `This method collapses the item.`,
 64 |       signature: "collapse(): void",
 65 |     },
 66 |     toggle: {
 67 |       description: `This method toggles the item's expanded state.`,
 68 |       signature: "toggle(): void",
 69 |     },
 70 |     isExpanded: {
 71 |       description: `This method returns a boolean indicating whether the item is currently expanded.`,
 72 |       signature: "isExpanded(): boolean",
 73 |     },
 74 |   },
 75 |   themeVars: parseScssVar(styles.themeVars),
 76 |   limitThemeVarsToComponent: true,
 77 |   defaultThemeVars: {
 78 |     [`backgroundColor-${COMP}`]: "transparent",
 79 |     [`color-${COMP}`]: "$textColor-primary",
 80 |     [`color-${COMP}--disabled`]: "$textColor--disabled",
 81 |     [`fontFamily-${COMP}`]: "$fontFamily",
 82 |     [`borderColor-${COMP}`]: "$borderColor",
 83 |     [`borderWidth-${COMP}`]: "0",
 84 |     [`borderBottomWidth-${COMP}`]: "1px",
 85 |     [`borderStyle-${COMP}`]: "solid",
 86 |     [`borderRadius-${COMP}`]: "0",
 87 |     [`paddingTop-${COMP}`]: "$space-2",
 88 |     [`paddingBottom-${COMP}`]: "$space-2",
 89 |     [`paddingLeft-${COMP}`]: "$space-0",
 90 |     [`paddingRight-${COMP}`]: "$space-0",
 91 |     [`gap-${COMP}`]: "$space-2",
 92 |     [`paddingLeft-content-${COMP}`]: "$space-3",
 93 |     [`paddingRight-content-${COMP}`]: "$space-3",
 94 |     [`paddingVertical-content-${COMP}`]: "$space-2",
 95 |     [`transition-${COMP}`]: "0.2s ease",
 96 |   },
 97 | });
 98 | 
 99 | export const expandableItemComponentRenderer = createComponentRenderer(
100 |   COMP,
101 |   ExpandableItemMd,
102 |   ({ node, renderChild, lookupEventHandler, registerComponentApi, extractValue, className }) => {
103 |     return (
104 |       <ExpandableItem
105 |         summary={extractValue(node.props?.summary)}
106 |         initiallyExpanded={extractValue.asOptionalBoolean(
107 |           node.props.initiallyExpanded,
108 |           defaultExpandableItemProps.initiallyExpanded,
109 |         )}
110 |         enabled={extractValue.asOptionalBoolean(
111 |           node.props.enabled,
112 |           defaultExpandableItemProps.enabled,
113 |         )}
114 |         iconExpanded={
115 |           extractValue(node.props?.iconExpanded) ?? defaultExpandableItemProps.iconExpanded
116 |         }
117 |         iconCollapsed={
118 |           extractValue(node.props?.iconCollapsed) ?? defaultExpandableItemProps.iconCollapsed
119 |         }
120 |         iconPosition={
121 |           extractValue.asOptionalString(node.props.iconPosition) ??
122 |           defaultExpandableItemProps.iconPosition
123 |         }
124 |         withSwitch={extractValue.asOptionalBoolean(
125 |           node.props.withSwitch,
126 |           defaultExpandableItemProps.withSwitch,
127 |         )}
128 |         onExpandedChange={lookupEventHandler("expandedChange")}
129 |         className={className}
130 |         registerComponentApi={registerComponentApi}
131 |       >
132 |         {renderChild(node.children)}
133 |       </ExpandableItem>
134 |     );
135 |   },
136 | );
137 | 
```

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

```markdown
  1 | # Slot [#slot]
  2 | 
  3 | Placeholder in a reusable component. Signs the slot where the component's injected children should be rendered.
  4 | 
  5 | ## Using Slot [#using-slot]
  6 | 
  7 | You can add `Slot` to a user-defined component as a placeholder. When you refer to the particular component in the markup, the children are transposed to the `Slot`.
  8 | 
  9 | ```xmlui-pg name="Using Slot"
 10 | ---app copy display {3-5}
 11 | <App name="XMLUI Hello World">
 12 |   <ActionBar>
 13 |     <Button label="Create" onClick="window.alert('Create clicked')" />
 14 |     <Button label="Edit" onClick="window.alert('Edit clicked')" />
 15 |     <Button label="Delete" onClick="window.alert('Delete clicked')" />
 16 |   </ActionBar>
 17 | </App>
 18 | ---desc
 19 | The app flows down three buttons to the `ActionBar` to render.
 20 | ---comp copy display {5}
 21 | <Component name="ActionBar">
 22 |   <Card>
 23 |     <H3>Use these actions</H3>
 24 |     <HStack>
 25 |       <Slot />
 26 |     </HStack>
 27 |   </Card>
 28 | </Component>
 29 | ---desc
 30 | `ActionBar` renders the passed children by replacing `Slot` with them.
 31 | ```
 32 | 
 33 | ## Default Slot content [#default-slot-content]
 34 | 
 35 | You can provide default content for the `Slot`. If the user-defined component does not have any children, XMLUI will render the default content.
 36 | 
 37 | ```xmlui-pg
 38 | ---app copy display name="Define default Slot content"
 39 | <App>
 40 |   <ActionBar />
 41 | </App>
 42 | ---comp copy display {6}
 43 | <Component name="ActionBar">
 44 |   <Card>
 45 |     <H3>Use these actions</H3>
 46 |     <HStack>
 47 |       <Slot>
 48 |         <Button label="Default" onClick="window.alert('Default clicked')" />
 49 |       </Slot>
 50 |     </HStack>
 51 |   </Card>
 52 | </Component>
 53 | ```
 54 | 
 55 | ## Named Slots [#named-slots]
 56 | 
 57 | You can add multiple slots to a user-defined component; you can have a default slot and several *named* slots. Slot names should end with `template`, and you can use the `<property>` markup syntax to declare their values.
 58 | 
 59 | ```xmlui-pg
 60 | ---app copy display name="Using named Slots" {4, 7, 9-11}
 61 | <App>
 62 |   <ActionBar>
 63 |     <property name="headerTemplate">
 64 |       <H2>Click one of these actions</H2>
 65 |     </property>
 66 |     <property name="footerTemplate">
 67 |       <Text>Footer content goes here</Text>
 68 |     </property>
 69 |     <Button label="Create" onClick="window.alert('Create clicked')" />
 70 |     <Button label="Edit" onClick="window.alert('Edit clicked')" />
 71 |     <Button label="Delete" onClick="window.alert('Delete clicked')" />
 72 |   </ActionBar>
 73 | </App>
 74 | ---desc
 75 | This app passes a header template and a footer template slot to the `ActionBar` component and also declares buttons to render.
 76 | ---comp copy display {3-5, 7-9, 11}
 77 | <Component name="ActionBar">
 78 |   <Card>
 79 |     <Slot name="headerTemplate">
 80 |       <H3>Use these actions</H3>
 81 |     </Slot>
 82 |     <HStack>
 83 |       <Slot>
 84 |         <Button label="Default" onClick="window.alert('Default clicked')" />
 85 |       </Slot>
 86 |     </HStack>
 87 |     <Slot name="footerTemplate" />
 88 |   </Card>
 89 | </Component>
 90 | ---desc
 91 | XMLUI finds the appropriate slots by their name and transposes their content received from the app. Just like the default slot, named slots can have default content.
 92 | ```
 93 | 
 94 | > [!WARN] XMLUI will display an error message when the `Slot` name does not end with "Template".
 95 | 
 96 | ## Template properties [#template-properties]
 97 | 
 98 | The user-defined component can provide properties for the actual template.
 99 | 
100 | ```xmlui-pg
101 | ---app copy display name="Using template properties" /header/ /name="headerTemplate"/ /$processedHeader/
102 | <App>
103 |   <ActionBar header="Action Bar Example">
104 |     <property name="headerTemplate">
105 |       <Text variant="title">{$processedHeader}</Text>
106 |     </property>
107 |     <Button label="Create" onClick="window.alert('Create clicked')" />
108 |     <Button label="Edit" onClick="window.alert('Edit clicked')" />
109 |     <Button label="Delete" onClick="window.alert('Delete clicked')" />
110 |   </ActionBar>
111 | </App>
112 | ---desc
113 | The app passes a `header` property value to the `ActionBar` component. `Actionbar` utilizes this property, transforms it, and passes it back to the template in the `$processedHeader` context variable so that the app can use it. `$processHeader` is available only within the `headerTemplate` slot.
114 | ---comp copy display /transformedHeader/ /processedHeader="{transformedHeader}"/
115 | <Component name="ActionBar">
116 |   <Card var.transformedHeader="*** {$props.header.toUpperCase()} ***">
117 |     <Slot name="headerTemplate" processedHeader="{transformedHeader}" >
118 |       <H3>{transformedHeader}</H3>
119 |     </Slot>
120 |     <HStack>
121 |       <Slot>
122 |         <Button label="Default" onClick="window.alert('Default clicked')" />
123 |       </Slot>
124 |     </HStack>
125 |   </Card>
126 | </Component>
127 | ---desc
128 | `Actionbar` transforms the `header` property and stores it internally in the `transformedHeader` variable. It utilizes the value in the default header definition and also passes it back to the actual template definition with the `processedHeader` name. XMLUI creates the `$processedHeader` context variable from this name.
129 | ```
130 | 
131 | ## Properties [#properties]
132 | 
133 | ### `name` [#name]
134 | 
135 | This optional property defines the name of the slot.
136 | 
137 | ## Events [#events]
138 | 
139 | This component does not have any events.
140 | 
141 | ## Exposed Methods [#exposed-methods]
142 | 
143 | This component does not expose any methods.
144 | 
145 | ## Styling [#styling]
146 | 
147 | This component does not have any styles.
148 | 
```

--------------------------------------------------------------------------------
/tools/create-app/templates/default/ts/public/resources/xmlui-logo.svg:
--------------------------------------------------------------------------------

```
 1 | <svg width="115" height="35" viewBox="0 0 46 14" fill="none"
 2 |     xmlns="http://www.w3.org/2000/svg">
 3 |     <path d="M19.8926 3.32031V9.57227H23.4199C23.7012 9.57227 23.916 9.64062 24.0645 9.77734C24.2168 9.91406 24.293 10.0859 24.293 10.293C24.293 10.5039 24.2188 10.6758 24.0703 10.8086C23.9219 10.9375 23.7051 11.002 23.4199 11.002H19.2188C18.8398 11.002 18.5664 10.918 18.3984 10.75C18.2344 10.582 18.1523 10.3105 18.1523 9.93555V3.32031C18.1523 2.96875 18.2305 2.70508 18.3867 2.5293C18.5469 2.35352 18.7559 2.26562 19.0137 2.26562C19.2754 2.26562 19.4863 2.35352 19.6465 2.5293C19.8105 2.70117 19.8926 2.96484 19.8926 3.32031Z" fill="#008EE5" />
 4 |     <path d="M11.0918 9.70898L9.71484 4.23633V10.166C9.71484 10.4941 9.64062 10.7402 9.49219 10.9043C9.34766 11.0684 9.1543 11.1504 8.91211 11.1504C8.67773 11.1504 8.48633 11.0703 8.33789 10.9102C8.18945 10.7461 8.11523 10.498 8.11523 10.166V3.36914C8.11523 2.99414 8.21289 2.74219 8.4082 2.61328C8.60352 2.48047 8.86719 2.41406 9.19922 2.41406H9.73828C10.0625 2.41406 10.2969 2.44336 10.4414 2.50195C10.5898 2.56055 10.6992 2.66602 10.7695 2.81836C10.8398 2.9707 10.9199 3.21875 11.0098 3.5625L12.2578 8.26758L13.5059 3.5625C13.5957 3.21875 13.6758 2.9707 13.7461 2.81836C13.8164 2.66602 13.9238 2.56055 14.0684 2.50195C14.2168 2.44336 14.4531 2.41406 14.7773 2.41406H15.3164C15.6484 2.41406 15.9121 2.48047 16.1074 2.61328C16.3027 2.74219 16.4004 2.99414 16.4004 3.36914V10.166C16.4004 10.4941 16.3262 10.7402 16.1777 10.9043C16.0332 11.0684 15.8379 11.1504 15.5918 11.1504C15.3613 11.1504 15.1719 11.0684 15.0234 10.9043C14.875 10.7402 14.8008 10.4941 14.8008 10.166V4.23633L13.4238 9.70898C13.334 10.0645 13.2598 10.3262 13.2012 10.4941C13.1465 10.6582 13.043 10.8086 12.8906 10.9453C12.7383 11.082 12.5273 11.1504 12.2578 11.1504C12.0547 11.1504 11.8828 11.1055 11.7422 11.0156C11.6016 10.9297 11.4922 10.8184 11.4141 10.6816C11.3359 10.5449 11.2734 10.3945 11.2266 10.2305C11.1836 10.0625 11.1387 9.88867 11.0918 9.70898Z" fill="#008EE5" />
 5 |     <path d="M0.621094 9.33203L2.54297 6.52539L0.925781 4.0293C0.773438 3.78711 0.658203 3.58008 0.580078 3.4082C0.505859 3.23242 0.46875 3.06445 0.46875 2.9043C0.46875 2.74023 0.541016 2.59375 0.685547 2.46484C0.833984 2.33203 1.01367 2.26562 1.22461 2.26562C1.4668 2.26562 1.6543 2.33789 1.78711 2.48242C1.92383 2.62305 2.11133 2.88672 2.34961 3.27344L3.63867 5.35938L5.01562 3.27344C5.12891 3.09766 5.22461 2.94727 5.30273 2.82227C5.38477 2.69727 5.46289 2.59375 5.53711 2.51172C5.61133 2.42969 5.69336 2.36914 5.7832 2.33008C5.87695 2.28711 5.98438 2.26562 6.10547 2.26562C6.32422 2.26562 6.50195 2.33203 6.63867 2.46484C6.7793 2.59375 6.84961 2.74805 6.84961 2.92773C6.84961 3.18945 6.69922 3.54492 6.39844 3.99414L4.70508 6.52539L6.52734 9.33203C6.69141 9.57812 6.81055 9.7832 6.88477 9.94727C6.95898 10.1074 6.99609 10.2598 6.99609 10.4043C6.99609 10.541 6.96289 10.666 6.89648 10.7793C6.83008 10.8926 6.73633 10.9824 6.61523 11.0488C6.49414 11.1152 6.35742 11.1484 6.20508 11.1484C6.04102 11.1484 5.90234 11.1133 5.78906 11.043C5.67578 10.9766 5.58398 10.8926 5.51367 10.791C5.44336 10.6895 5.3125 10.4922 5.12109 10.1992L3.60938 7.82031L2.00391 10.2695C1.87891 10.4648 1.78906 10.6016 1.73438 10.6797C1.68359 10.7578 1.62109 10.834 1.54688 10.9082C1.47266 10.9824 1.38477 11.041 1.2832 11.084C1.18164 11.127 1.0625 11.1484 0.925781 11.1484C0.714844 11.1484 0.539062 11.084 0.398438 10.9551C0.261719 10.8262 0.193359 10.6387 0.193359 10.3926C0.193359 10.1035 0.335938 9.75 0.621094 9.33203Z" fill="#008EE5" />
 6 |     <rect x="27" width="19" height="14" rx="2" fill="#008EE5" />
 7 |     <path d="M40.125 10.0879V3.32031C40.125 2.96875 40.2051 2.70508 40.3652 2.5293C40.5254 2.35352 40.7324 2.26562 40.9863 2.26562C41.248 2.26562 41.459 2.35352 41.6191 2.5293C41.7832 2.70117 41.8652 2.96484 41.8652 3.32031V10.0879C41.8652 10.4434 41.7832 10.709 41.6191 10.8848C41.459 11.0605 41.248 11.1484 40.9863 11.1484C40.7363 11.1484 40.5293 11.0605 40.3652 10.8848C40.2051 10.7051 40.125 10.4395 40.125 10.0879Z" fill="white" />
 8 |     <path d="M30.9492 7.45117V3.32031C30.9492 2.96875 31.0273 2.70508 31.1836 2.5293C31.3438 2.35352 31.5527 2.26562 31.8105 2.26562C32.0801 2.26562 32.293 2.35352 32.4492 2.5293C32.6094 2.70508 32.6895 2.96875 32.6895 3.32031V7.54492C32.6895 8.02539 32.7422 8.42773 32.8477 8.75195C32.957 9.07227 33.1484 9.32227 33.4219 9.50195C33.6953 9.67773 34.0781 9.76562 34.5703 9.76562C35.25 9.76562 35.7305 9.58594 36.0117 9.22656C36.293 8.86328 36.4336 8.31445 36.4336 7.58008V3.32031C36.4336 2.96484 36.5117 2.70117 36.668 2.5293C36.8242 2.35352 37.0332 2.26562 37.2949 2.26562C37.5566 2.26562 37.7676 2.35352 37.9277 2.5293C38.0918 2.70117 38.1738 2.96484 38.1738 3.32031V7.45117C38.1738 8.12305 38.1074 8.68359 37.9746 9.13281C37.8457 9.58203 37.5996 9.97656 37.2363 10.3164C36.9238 10.6055 36.5605 10.8164 36.1465 10.9492C35.7324 11.082 35.248 11.1484 34.6934 11.1484C34.0332 11.1484 33.4648 11.0781 32.9883 10.9375C32.5117 10.793 32.123 10.5723 31.8223 10.2754C31.5215 9.97461 31.3008 9.5918 31.1602 9.12695C31.0195 8.6582 30.9492 8.09961 30.9492 7.45117Z" fill="white" />
 9 | </svg>
10 | 
```

--------------------------------------------------------------------------------
/docs/public/pages/howto/update-ui-optimistically.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Update UI optimistically
  2 | 
  3 | For immediate user feedback, use reactive variables like `localFavorited` and `localFavoritesCount` to update UI state instantly while API calls run in the background.
  4 | 
  5 | ```xmlui-pg copy display name="Click the Like button - immediate feedback"
  6 | ---app display /localFavorited/ /localFavoritesCount/ {37-52}
  7 | <App>
  8 |   <APICall
  9 |     id="favoritePost"
 10 |     method="post"
 11 |     url="/api/posts/{$param}/favorite"
 12 |     inProgressNotificationMessage="Favoriting post..."
 13 |     completedNotificationMessage="Post favorited!" />
 14 |   <APICall
 15 |     id="unfavoritePost"
 16 |     method="post"
 17 |     url="/api/posts/{$param}/unfavorite"
 18 |     inProgressNotificationMessage="Unfavoriting post..."
 19 |     completedNotificationMessage="Post unfavorited!" />
 20 |   <DataSource
 21 |     id="timelineData"
 22 |     url="/api/timeline"
 23 |     method="GET" />
 24 |   <VStack gap="$space-4" padding="$space-4">
 25 |     <Items data="{timelineData}">
 26 |       <Card var.localFavorited="{null}" var.localFavoritesCount="{null}">
 27 |         <VStack>
 28 |           <Text>{$item.author}</Text>
 29 |           <Text>{$item.content}</Text>
 30 |           <HStack gap="$space-4" verticalAlignment="center">
 31 |             <HStack gap="$space-1" verticalAlignment="center">
 32 |               <SocialButton icon="reply" />
 33 |               <Text variant="caption">{$item.replies_count}</Text>
 34 |             </HStack>
 35 |             <HStack gap="$space-1" verticalAlignment="center">
 36 |               <SocialButton icon="trending-up" />
 37 |               <Text variant="caption">{$item.reblogs_count}</Text>
 38 |             </HStack>
 39 |             <HStack gap="$space-1" verticalAlignment="center">
 40 |               <SocialButton
 41 |                 icon="like"
 42 |                 themeColor="{(localFavorited !== null ? localFavorited : $item.favourited) ? 'attention' : 'secondary'}">
 43 |                 <event name="click">
 44 |                   // Get current state (local takes precedence)
 45 |                   const currentFavorited = localFavorited !== null ? localFavorited : $item.favourited;
 46 |                   const currentCount = localFavoritesCount !== null ? localFavoritesCount : ($item.favourites_count || 0);
 47 |                   // Update UI optimistically
 48 |                   localFavorited = !currentFavorited;
 49 |                   localFavoritesCount = currentFavorited ?
 50 |                     Math.max(0, currentCount - 1) :
 51 |                     currentCount + 1;
 52 |                   // Make API call
 53 |                   if (currentFavorited) {
 54 |                     unfavoritePost.execute($item.id).then(() => timelineData.refetch());
 55 |                   } else {
 56 |                     favoritePost.execute($item.id).then(() => timelineData.refetch());
 57 |                   }
 58 |                 </event>
 59 |               </SocialButton>
 60 |               <Text variant="caption">
 61 |                 {localFavoritesCount !== null ? localFavoritesCount : ($item.favourites_count || 0)}
 62 |               </Text>
 63 |             </HStack>
 64 |           </HStack>
 65 |         </VStack>
 66 |       </Card>
 67 |     </Items>
 68 |   </VStack>
 69 | </App>
 70 | ---comp display {8}
 71 | <Component name="SocialButton">
 72 |   <Button
 73 |     borderRadius="50%"
 74 |     icon="{$props.icon}"
 75 |     variant="outlined"
 76 |     themeColor="{$props.themeColor || 'secondary'}"
 77 |     size="xs"
 78 |     onClick="{emitEvent('click')}" />
 79 | </Component>
 80 | ---api
 81 | {
 82 |   "apiUrl": "/api",
 83 |   "initialize": "$state.posts = [
 84 |     {
 85 |       id: '1',
 86 |       content: 'This is a great post about XMLUI!',
 87 |       author: 'John Developer',
 88 |       favourited: false,
 89 |       favourites_count: 5,
 90 |       replies_count: 2,
 91 |       reblogs_count: 1
 92 |     },
 93 |     {
 94 |       id: '2',
 95 |       content: 'Learning optimistic UI updates!',
 96 |       author: 'Jane Designer',
 97 |       favourited: true,
 98 |       favourites_count: 12,
 99 |       replies_count: 4,
100 |       reblogs_count: 3
101 |     }
102 |   ]",
103 |   "operations": {
104 |     "get-timeline": {
105 |       "url": "/timeline",
106 |       "method": "get",
107 |       "handler": "return $state.posts"
108 |     },
109 |     "favorite-post": {
110 |       "url": "/posts/:id/favorite",
111 |       "method": "post",
112 |       "pathParamTypes": {
113 |         "id": "string"
114 |       },
115 |       "handler": "
116 |         delay(2000);
117 |         const post = $state.posts.find(p => p.id === $pathParams.id);
118 |         if (post) {
119 |           post.favourited = true;
120 |           post.favourites_count += 1;
121 |         }
122 |       "
123 |     },
124 |     "unfavorite-post": {
125 |       "url": "/posts/:id/unfavorite",
126 |       "method": "post",
127 |       "pathParamTypes": {
128 |         "id": "string"
129 |       },
130 |       "handler": "
131 |         delay(2000);
132 |         const post = $state.posts.find(p => p.id === $pathParams.id);
133 |         if (post) {
134 |           post.favourited = false;
135 |           post.favourites_count -= 1;
136 |         }
137 |       "
138 |     }
139 |   }
140 | }
141 | ```
142 | 
143 | The relationship between `onClick="{emitEvent('click')}"` in the `SocialButton` component and the `<event name="click">` handler in the main app demonstrates event propagation in XMLUI.
144 | 
145 | The parent component catches the emitted click event and implements the optimistic UI update. This separation allows for:
146 | 
147 | - Component reuse. `SocialButton` can be used anywhere without knowing what action the click should perform.
148 | - Flexible event handling. Different instances of `SocialButton` can handle clicks differently.
149 | 
```

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

```typescript
  1 | import styles from "./ModalDialog.module.scss";
  2 | 
  3 | import { createComponentRenderer } from "../../components-core/renderers";
  4 | import { parseScssVar } from "../../components-core/theming/themeVars";
  5 | import { paddingSubject } from "../../components-core/theming/themes/base-utils";
  6 | import { MemoizedItem } from "../container-helpers";
  7 | import { ModalDialog, ModalDialogFrame, defaultProps } from "./ModalDialogNative";
  8 | import { createMetadata, d } from "../metadata-helpers";
  9 | 
 10 | const COMP = "ModalDialog";
 11 | 
 12 | export const ModalDialogMd = createMetadata({
 13 |   status: "stable",
 14 |   description:
 15 |     "`ModalDialog` creates overlay dialogs that appear on top of the main interface, " +
 16 |     "ideal for forms, confirmations, detailed views, or any content that requires " +
 17 |     "focused user attention. Dialogs are programmatically opened using the `open()` " +
 18 |     "method and can receive parameters for dynamic content.",
 19 |   parts: {
 20 |     content: {
 21 |       description: "The main content area of the modal dialog.",
 22 |     },
 23 |     title: {
 24 |       description: "The title area of the modal dialog.",
 25 |     },
 26 |   },
 27 |   props: {
 28 |     fullScreen: {
 29 |       description:
 30 |         `Toggles whether the dialog encompasses the whole UI (\`true\`) or not and has a minimum ` +
 31 |         `width and height (\`false\`).`,
 32 |       valueType: "boolean",
 33 |       defaultValue: defaultProps.fullScreen,
 34 |     },
 35 |     title: d(`Provides a prestyled heading to display the intent of the dialog.`),
 36 |     closeButtonVisible: {
 37 |       description: `Shows (\`true\`) or hides (\`false\`) the visibility of the close button on the dialog.`,
 38 |       valueType: "boolean",
 39 |       defaultValue: defaultProps.closeButtonVisible,
 40 |     },
 41 |   },
 42 |   events: {
 43 |     open: d(
 44 |       `This event is fired when the \`${COMP}\` is opened either via a \`when\` or an ` +
 45 |         `imperative API call (\`open()\`).`,
 46 |     ),
 47 |     close: d(
 48 |       `This event is fired when the close button is pressed or the user clicks outside ` +
 49 |         `the \`${COMP}\`.`,
 50 |     ),
 51 |   },
 52 |   apis: {
 53 |     close: {
 54 |       description:
 55 |         `This method is used to close the \`${COMP}\`. Invoke it using \`modalId.close()\` ` +
 56 |         `where \`modalId\` refers to a \`ModalDialog\` component.`,
 57 |       signature: "close(): void",
 58 |     },
 59 |     open: {
 60 |       description:
 61 |         "This method imperatively opens the modal dialog. You can pass an arbitrary number " +
 62 |         "of parameters to the method. In the `ModalDialog` instance, you can access those " +
 63 |         "with the `\$param` and `\$params` context values.",
 64 |       signature: "open(...params: any[]): void",
 65 |       parameters: {
 66 |         params: "An arbitrary number of parameters that can be used to pass data to the dialog.",
 67 |       },
 68 |     },
 69 |   },
 70 |   contextVars: {
 71 |     $param: d("First parameter passed to the `open()` method"),
 72 |     $params: d(
 73 |       "Array of all parameters passed to `open()` method (access with `$params[0]`, `$params[1]`, etc.)",
 74 |     ),
 75 |   },
 76 |   themeVars: parseScssVar(styles.themeVars),
 77 |   defaultThemeVars: {
 78 |     ...paddingSubject(COMP, { all: "$space-7" }),
 79 |     [`backgroundColor-${COMP}`]: "$backgroundColor-primary",
 80 |     [`backgroundColor-overlay-${COMP}`]: "$backgroundColor-overlay",
 81 |     [`textColor-${COMP}`]: "$textColor-primary",
 82 |     [`borderRadius-${COMP}`]: "$borderRadius",
 83 |     [`fontFamily-${COMP}`]: "$fontFamily",
 84 |     [`maxWidth-${COMP}`]: "450px",
 85 |     [`marginBottom-title-${COMP}`]: "0",
 86 |   },
 87 | });
 88 | 
 89 | export const modalViewComponentRenderer = createComponentRenderer(
 90 |   COMP,
 91 |   ModalDialogMd,
 92 |   ({
 93 |     node,
 94 |     extractValue,
 95 |     className,
 96 |     renderChild,
 97 |     lookupEventHandler,
 98 |     registerComponentApi,
 99 |     layoutContext,
100 |   }) => {
101 |     // gigantic hack: If the ModalDialog is not inside a ModalDialogFrame, wrap it in one
102 |     //   we do this through the layout context, render it through another render loop with the extra $param context var
103 |     //   (note the layoutContext and node on the MemoizedItem)
104 |     // one solution would be to have a renderChild that can take a contextVars argument
105 |     if (!layoutContext?._insideModalFrame) {
106 |       return (
107 |         <ModalDialogFrame
108 |           isInitiallyOpen={extractValue(node.when) !== undefined}
109 |           registerComponentApi={registerComponentApi}
110 |           onClose={lookupEventHandler("close")}
111 |           onOpen={lookupEventHandler("open")}
112 |           renderDialog={({ openParams, ref }) => {
113 |             return (
114 |               <MemoizedItem
115 |                 node={node}
116 |                 renderChild={renderChild}
117 |                 layoutContext={{ _insideModalFrame: true }}
118 |                 contextVars={{ $param: openParams?.[0], $params: openParams }}
119 |               />
120 |             );
121 |           }}
122 |         />
123 |       );
124 |     }
125 | 
126 |     return (
127 |       <ModalDialog
128 |         className={className}
129 |         fullScreen={extractValue.asOptionalBoolean(node.props?.fullScreen)}
130 |         title={extractValue(node.props?.title)}
131 |         closeButtonVisible={extractValue.asOptionalBoolean(node.props.closeButtonVisible)}
132 |         externalAnimation={extractValue.asOptionalBoolean(node.props.externalAnimation)}
133 |       >
134 |         {renderChild(node.children, { type: "Stack" })}
135 |       </ModalDialog>
136 |     );
137 |   },
138 | );
139 | 
```
Page 27/181FirstPrevNextLast