This is page 16 of 186. Use http://codebase.md/xmlui-org/xmlui/assets/img/main.tsx?format=md&lines=true&page={x} to view the full context.

# Directory Structure

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

# Files

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

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

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

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

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

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

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

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

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

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

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

```markdown
  1 | %-DESC-START
  2 | 
  3 | Most properties of the component focus on the primary section (e.g. sizing).
  4 | 
  5 | See also: [HSplitter](/components/HSplitter), [VSplitter](/components/VSplitter).
  6 | 
  7 | %-DESC-END
  8 | 
  9 | %-PROP-START floating
 10 | 
 11 | ```xmlui-pg copy display name="Example: floating"
 12 | <App>
 13 |   <Splitter height="200px" floating="true">
 14 |     <Stack backgroundColor="lightblue" height="100%" />
 15 |     <Stack backgroundColor="darksalmon" height="100%" />
 16 |   </Splitter>
 17 | </App>
 18 | ```
 19 | 
 20 | %-PROP-END
 21 | 
 22 | %-PROP-START initialPrimarySize
 23 | 
 24 | ```xmlui-pg copy display name="Example: initialPrimarySize"
 25 | <App>
 26 |   <Splitter height="200px" initialPrimarySize="40%">
 27 |     <Stack backgroundColor="lightblue" height="100%" />
 28 |     <Stack backgroundColor="darksalmon" height="100%" />
 29 |   </Splitter>
 30 | </App>
 31 | ```
 32 | 
 33 | %-PROP-END
 34 | 
 35 | %-PROP-START maxPrimarySize
 36 | 
 37 | ```xmlui-pg copy display name="Example: maxPrimarySize"
 38 | <App>
 39 |   <Splitter height="200px" maxPrimarySize="80%">
 40 |     <Stack backgroundColor="lightblue" height="100%" />
 41 |     <Stack backgroundColor="darksalmon" height="100%" />
 42 |   </Splitter>
 43 | </App>
 44 | ```
 45 | 
 46 | ```xmlui-pg copy display name="Example: maxPrimarySize with negative value (from end)"
 47 | <App>
 48 |   <Splitter height="200px" maxPrimarySize="-50px">
 49 |     <Stack backgroundColor="lightblue" height="100%" />
 50 |     <Stack backgroundColor="darksalmon" height="100%" />
 51 |   </Splitter>
 52 | </App>
 53 | ```
 54 | 
 55 | %-PROP-END
 56 | 
 57 | %-PROP-START minPrimarySize
 58 | 
 59 | ```xmlui-pg copy display name="Example: minPrimarySize"
 60 | <App>
 61 |   <Splitter height="200px" minPrimarySize="40px">
 62 |     <Stack backgroundColor="lightblue" height="100%" />
 63 |     <Stack backgroundColor="darksalmon" height="100%" />
 64 |   </Splitter>
 65 | </App>
 66 | ```
 67 | 
 68 | %-PROP-END
 69 | 
 70 | %-PROP-START orientation
 71 | 
 72 | ```xmlui-pg copy display name="Example: orientation"
 73 | <App>
 74 |   <Splitter height="200px" orientation="horizontal">
 75 |     <Stack backgroundColor="lightblue" height="100%" />
 76 |     <Stack backgroundColor="darksalmon" height="100%" />
 77 |   </Splitter>
 78 | </App>
 79 | ```
 80 | 
 81 | %-PROP-END
 82 | 
 83 | %-PROP-START splitterTemplate
 84 | 
 85 | ```xmlui-pg copy {2-4} display name="Example: splitterTemplate"
 86 | <App>
 87 |   <Splitter height="200px">
 88 |     <property name="splitterTemplate">
 89 |       <ContentSeparator backgroundColor="green" height="4px" />
 90 |     </property>
 91 |     <Stack backgroundColor="lightblue" height="100%" />
 92 |     <Stack backgroundColor="darksalmon" height="100%" />
 93 |   </Splitter>
 94 | </App>
 95 | ```
 96 | 
 97 | %-PROP-END
 98 | 
 99 | %-PROP-START swapped
100 | 
101 | ```xmlui-pg copy display name="Example: swapped"
102 | <App>
103 |   <Splitter height="200px" swapped="true">
104 |     <Stack backgroundColor="lightblue" height="100%" />
105 |     <Stack backgroundColor="darksalmon" height="100%" />
106 |   </Splitter>
107 | </App>
108 | ```
109 | 
110 | %-PROP-END
111 | 
112 | %-EVENT-START resize
113 | 
114 | ```xmlui-pg copy {2} display name="Example: resize"
115 | <App height="200px" var.counter="{0}">
116 |   <Splitter onResize="counter++">
117 |     <Stack backgroundColor="lightblue" height="100%">
118 |       <Text value="Resize event called {counter} number of times" />
119 |     </Stack>
120 |     <Stack backgroundColor="darksalmon" height="100%" />
121 |   </Splitter>
122 | </App>
123 | ```
124 | 
125 | %-EVENT-END
126 | 
```

--------------------------------------------------------------------------------
/.github/workflows/run-all-tests.yml:
--------------------------------------------------------------------------------

```yaml
 1 | name: All Tests (nightly run)
 2 | 
 3 | concurrency: # Concurrency ensures that only a single job or workflow using the same concurrency group will run at a time.
 4 |   group: component-e2e-testing-nightly
 5 |   cancel-in-progress: true
 6 | 
 7 | on:
 8 |   workflow_dispatch:
 9 |   schedule:
10 |     - cron: "39 1 * * *"
11 | jobs:
12 |   check-commit:
13 |     runs-on: ubuntu-latest
14 |     env:
15 |       NODE_OPTIONS: "--max-old-space-size=8192"
16 |     outputs:
17 |       should_test: ${{ steps.check.outputs.should_test }}
18 |     steps:
19 |       - uses: actions/checkout@v4
20 |       - id: check
21 |         name: Determine if the commit has been tested already
22 |         run: |
23 |           # Always run tests if triggered by workflow_dispatch
24 |           if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
25 |             echo "Workflow dispatch triggered, always run tests"
26 |             echo "should_test=true" >> $GITHUB_OUTPUT
27 |             exit 0
28 |           fi
29 | 
30 |           current_time_epoch=$(date +%s)
31 |           last_commit_time_epoch=$(git log -1 --format=%ct)
32 |           one_day_epoch=$((60 * 60 * 24))
33 |           threshold_time=$((last_commit_time_epoch + one_day_epoch))
34 | 
35 |           if [ $current_time_epoch -gt $threshold_time ]; then
36 |               echo "Last commit is older than 24 hours, skipping tests"
37 |               echo "should_test=false" >> $GITHUB_OUTPUT
38 |           else
39 |               echo "Last commit is within the last 24 hours, will not skip tests"
40 |               echo "should_test=true" >> $GITHUB_OUTPUT
41 |           fi
42 |   test:
43 |     needs: check-commit
44 |     if: needs.check-commit.outputs.should_test == 'true'
45 |     timeout-minutes: 60
46 |     runs-on: ubuntu-latest
47 |     env:
48 |       NODE_OPTIONS: "--max-old-space-size=8192"
49 |     steps:
50 |       - uses: actions/checkout@v4
51 |       - uses: actions/setup-node@v4
52 |         with:
53 |           node-version: 22
54 |           cache: "npm"
55 |       - name: Install node dependencies
56 |         run: npm ci --prefer-offline
57 |       - name: Cache for Turbo
58 |         uses: rharkor/caching-for-turbo@v2.3.1
59 |       - name: Store Playwright's Version
60 |         run: |
61 |           PLAYWRIGHT_VERSION=$(npm ls @playwright/test | grep @playwright | sed 's/.*@//' | sort | head -n 1)
62 |           echo "Playwright's Version: $PLAYWRIGHT_VERSION"
63 |           echo "PLAYWRIGHT_VERSION=$PLAYWRIGHT_VERSION" >> $GITHUB_ENV
64 |       - name: Cache Playwright Browsers for Playwright's Version
65 |         id: cache-playwright-browsers
66 |         uses: actions/cache@v4
67 |         with:
68 |           path: ~/.cache/ms-playwright
69 |           key: playwright-browsers-${{ env.PLAYWRIGHT_VERSION }}
70 |       - name: Install Playwright Browsers
71 |         if: steps.cache-playwright-browsers.outputs.cache-hit != 'true'
72 |         run: npx playwright install --with-deps
73 |       - name: ensure we can build xmlui and the extensions
74 |         run: npm run build-xmlui
75 |       - name: run all tests
76 |         run: npm run test
77 |       - uses: actions/upload-artifact@v4
78 |         with:
79 |           name: playwright-report
80 |           path: xmlui/playwright-report/
81 |           retention-days: 30
82 | 
```

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

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

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

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

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

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

--------------------------------------------------------------------------------
/xmlui/src/components/Markdown/CodeText.module.scss:
--------------------------------------------------------------------------------

```scss
  1 | @use "../../components-core/theming/themes" as t;
  2 | 
  3 | $themeVars: ();
  4 | @function createThemeVar($componentVariable) {
  5 |   $themeVars: t.appendThemeVar($themeVars, $componentVariable) !global;
  6 |   @return t.getThemeVar($themeVars, $componentVariable);
  7 | }
  8 | 
  9 | $component: "Text";
 10 | 
 11 | @mixin textVariant($variant) {
 12 |   $variantName: if($variant == "", "#{$component}", "#{$component}-#{$variant}");
 13 |   $themeVars: t.composePaddingVars($themeVars, $variantName);
 14 |   $themeVars: t.composeBorderVars($themeVars, $variantName);
 15 |   $themeVars: t.composeTextVars($themeVars, $variantName, $component);
 16 |   @include t.paddingVars($themeVars, $variantName);
 17 |   @include t.borderVars($themeVars, $variantName);
 18 |   @include t.textVars($themeVars, $variantName);
 19 |   margin-top: createThemeVar("marginTop-#{$variantName}");
 20 |   margin-bottom: createThemeVar("marginBottom-#{$variantName}");
 21 |   margin-left: createThemeVar("marginLeft-#{$variantName}");
 22 |   margin-right: createThemeVar("marginRight-#{$variantName}");
 23 |   vertical-align: createThemeVar("verticalAlignment-#{$variantName}");
 24 | }
 25 | 
 26 | @layer components {
 27 |   .codeText {
 28 |     overflow: hidden;
 29 |     text-overflow: ellipsis;
 30 |     margin: 0;
 31 |     padding: 0;
 32 |     min-height: fit-content;
 33 | 
 34 |     // --- Styling <pre><code> elements
 35 | 
 36 |     // codefence/<pre> elements are block level by default, even in another text element
 37 |     // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre
 38 |     .text.codefence {
 39 |       display: block;
 40 |       margin-top: createThemeVar("marginTop-#{$component}-codefence");
 41 |       margin-bottom: createThemeVar("marginBottom-#{$component}-codefence");
 42 |       height: 100%;
 43 |     }
 44 | 
 45 |     // For inline code
 46 |     :not(.text.codefence) > &.code,
 47 |     :not(.text.codefence) > &code {
 48 |       @include textVariant("code");
 49 |     }
 50 | 
 51 |     // For code blocks using <![CDATA[ + <code> tags
 52 |     &.codefence:has(> .text.code),
 53 |     &.codefence:has(> code) {
 54 |       @include textVariant("codefence");
 55 |       // TEMP: solution for a demo - need to re-evaluate how to truncate/wrap code blocks
 56 |       overflow-x: auto;
 57 |       text-overflow: initial;
 58 |     }
 59 | 
 60 |     // TEMP: experimental - may be removed
 61 |     &.codefence:has(> code > span) {
 62 |       padding-inline: 0;
 63 |     }
 64 |     &.codefence > code > span:not([class*="numbered"]) {
 65 |       padding-inline: t.$space-3;
 66 |     }
 67 | 
 68 |     &.codefence > code {
 69 |       font-family: createThemeVar("fontFamily-#{$component}-codefence");
 70 |       padding-left: 0;
 71 |     }
 72 | 
 73 |     &.codefence > code::before {
 74 |       counter-reset: listing;
 75 |     }
 76 | 
 77 |     &.codefence > code > span {
 78 |       display: inline-block;
 79 |       width: 100%;
 80 |     }
 81 |     &.codefence > code > span[class*="numbered"] {
 82 |       counter-increment: listing;
 83 |     }
 84 | 
 85 |     &.codefence > code > span[class*="numbered"]::before {
 86 |       content: counter(listing);
 87 |       display: inline-block;
 88 |       width: t.$space-12;
 89 |       padding-left: auto;
 90 |       padding-right: t.$space-5;
 91 |       margin-left: auto;
 92 |       text-align: right;
 93 |       color: t.$textColor-secondary;
 94 |     }
 95 |   }
 96 | }
 97 | 
 98 | :export {
 99 |   themeVars: t.json-stringify($themeVars);
100 | }
101 | 
```

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

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

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

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

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

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

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

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

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

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

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

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

--------------------------------------------------------------------------------
/xmlui/tests/parsers/scripting/eval-tree-arrow.test.ts:
--------------------------------------------------------------------------------

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

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

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

--------------------------------------------------------------------------------
/docs/public/pages/user-defined-components.md:
--------------------------------------------------------------------------------

```markdown
 1 | # User-defined components
 2 | 
 3 | You can define your own components, pass properties to them, and use them interchangeably with core components. When you find yourself writing a component with more than a few dozen lines of XMLUI markup, consider refactoring in order to name and package the key blocks of code. This strategy not only enables reuse but, just as importantly, ensures that the refactored component will be easy to read and maintain.
 4 | 
 5 | Such refactoring requires you to create and name new `.xmlui` files, identify inline elements that need to be passed as properties from a refactored component, and use those properties in newly-created subcomponents. Historically that kind of overhead has been a disincentive to refactoring in any programming environment. Now you can often outsource that gruntwork to AI assistants. It works particularly well with XMLUI, we use this strategy extensively, and we highly recommend it.
 6 | 
 7 | Here's a simple component to package a name/value pair.
 8 | 
 9 | ```xmlui-pg display noHeader
10 | ---app display
11 | <App>
12 |   <NameValue name="Mary" value="123" />
13 | </App>
14 | ---comp display
15 | <Component name="NameValue">
16 |   <Card width="20%">
17 |     <Text>Name: { $props.name} </Text>
18 |     <Text>Value: { $props.value} </Text>
19 |   </Card>
20 | </Component>
21 | ```
22 | 
23 | The component's name must start with an uppercase letter followed by letters, digits, the underscore (`_`), or the dollar sign (`$`) character. Components must be placed into separate files in the `components` folder within the app's root folder. The component's name must match its filename.
24 | 
25 | Here's how you can define default values for properties.
26 | 
27 | ```xmlui
28 | <Component name="NameValue">
29 |   <Card width="20%">
30 |     <Text>Name: { $props.name ?? '[no name]' } </Text>
31 |     <Text>Value: { $props.value ?? '[no value]' } </Text>
32 |   </Card>
33 | </Component>
34 | ```
35 | 
36 | ## Events
37 | 
38 | The `<IncButton>` component increments its value for every click, and notifies its environment by firing an event. The event's handler receives the current counter as an event parameter.
39 | 
40 | ```xmlui-pg noHeader
41 | ---app display
42 | <App>
43 |   <Card width="30%">
44 |     <variable name="text" value=""/>
45 |     <IncButton onIncremented="(clickCount) => text += ' ' + clickCount" />
46 |     <Text value="{text}" />
47 |   </Card>
48 | </App>
49 | ---comp display
50 | <Component name="IncButton">
51 |   <variable name="count" value="{0}" />
52 |   <Button
53 |     label="Click to increment: {count}"
54 |     onClick="count++; emitEvent('incremented', count)"
55 |   />
56 | </Component>
57 | ```
58 | 
59 | ## Methods
60 | 
61 | The `<UsingInternalModal>` component exports the `open` method of the `ModalDialog` that it defines.
62 | 
63 | ```xmlui-pg noHeader
64 | ---app display
65 | <App height="300px" >
66 |   <UsingInternalModal id="component"/>
67 |   <Button label="Open the internal dialog" onClick="component.openDialog()" />
68 | </App>
69 | ---comp display
70 | <Component name="UsingInternalModal">
71 |   <ModalDialog id="dialog" title="Example Dialog">
72 |     <Button label="Close Dialog" onClick="dialog.close()" />
73 |   </ModalDialog>
74 | 
75 |   <H1>Using an Internal Modal Dialog</H1>
76 | 
77 |   <method name="openDialog">
78 |     console.log('internal method called')
79 |     dialog.open();
80 |   </method>
81 | </Component>
82 | ```
83 | 
```

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

```scss
  1 | @use "../../components-core/theming/themes" as t;
  2 | 
  3 | // --- This code snippet is required to collect the theme variables used in this module
  4 | $themeVars: ();
  5 | @function createThemeVar($componentVariable) {
  6 |   $themeVars: t.appendThemeVar($themeVars, $componentVariable) !global;
  7 |   @return t.getThemeVar($themeVars, $componentVariable);
  8 | }
  9 | 
 10 | $component: "Accordion";
 11 | $themeVars: t.composeBorderVars($themeVars, $component);
 12 | $themeVars: t.composePaddingVars($themeVars, $component);
 13 | $borderRadius: createThemeVar("borderRadius-#{$component}");
 14 | 
 15 | 
 16 | @layer components {
 17 |   .root {
 18 |     overflow: hidden;
 19 |     width: 100%;
 20 |     //box-shadow: 0 2px 10px var(--black-a4);
 21 |     @include t.borderVars($themeVars, $component);
 22 |     @include t.paddingVars($themeVars, $component);
 23 |   }
 24 | 
 25 |   .item {
 26 |     overflow: hidden;
 27 |     margin-top: 1px;
 28 |     box-sizing: border-box;
 29 | 
 30 |     &:first-child {
 31 |       margin-top: 0;
 32 |       border-top-left-radius: $borderRadius;
 33 |       border-top-right-radius: $borderRadius;
 34 |     }
 35 | 
 36 |     &:last-child {
 37 |       border-bottom-left-radius: $borderRadius;
 38 |       border-bottom-right-radius: $borderRadius;
 39 |     }
 40 | 
 41 |     &:focus-within {
 42 |       position: relative;
 43 |       z-index: 1;
 44 |     }
 45 |   }
 46 | 
 47 |   .header {
 48 |     display: flex;
 49 |     margin: 0;
 50 |   }
 51 | 
 52 |   .trigger {
 53 |     font-family: inherit;
 54 |     flex: 1;
 55 |     display: inline-flex;
 56 |     align-items: createThemeVar("verticalAlignment-header-#{$component}");
 57 |     justify-content: space-between;
 58 |     line-height: 1;
 59 |     box-sizing: border-box;
 60 |     font-size: createThemeVar("fontSize-header-#{$component}");
 61 |     font-weight: createThemeVar("fontWeight-header-#{$component}");
 62 |     font-style: createThemeVar("fontStyle-header-#{$component}");
 63 |     padding: createThemeVar("paddingVertical-header-#{$component}") createThemeVar("paddingHorizontal-header-#{$component}");
 64 |     background-color: createThemeVar("backgroundColor-header-#{$component}");
 65 |     color: createThemeVar("color-header-#{$component}");
 66 | 
 67 |     &:hover {
 68 |       background-color: createThemeVar("backgroundColor-header-#{$component}-hover");
 69 |     }
 70 | 
 71 |     &.triggerStart {
 72 |       flex-direction: row-reverse;
 73 |     }
 74 |   }
 75 | 
 76 |   .contentWrapper {
 77 |     overflow: hidden;
 78 |     color: createThemeVar("color-content-#{$component}");
 79 |     background-color: createThemeVar("backgroundColor-content-#{$component}");
 80 | 
 81 |     &[data-state='open'] {
 82 |       animation: slideDown 300ms cubic-bezier(0.87, 0, 0.13, 1);
 83 |     }
 84 | 
 85 |     &[data-state='closed'] {
 86 |       animation: slideUp 300ms cubic-bezier(0.87, 0, 0.13, 1);
 87 |     }
 88 |   }
 89 | 
 90 |   .content {
 91 |     padding: t.$space-2;
 92 |   }
 93 | 
 94 |   .chevron {
 95 |     width: createThemeVar("width-icon-#{$component}");
 96 |     height: createThemeVar("height-icon-#{$component}");
 97 |     color: createThemeVar("color-icon-#{$component}");
 98 |   }
 99 | 
100 |   @keyframes slideDown {
101 |     from {
102 |       height: 0;
103 |     }
104 |     to {
105 |       height: var(--radix-accordion-content-height);
106 |     }
107 |   }
108 | 
109 |   @keyframes slideUp {
110 |     from {
111 |       height: var(--radix-accordion-content-height);
112 |     }
113 |     to {
114 |       height: 0;
115 |     }
116 |   }
117 | }
118 | 
119 | 
120 | 
121 | // --- We export the theme variables to add them to the component renderer
122 | :export {
123 |   themeVars: t.json-stringify($themeVars);
124 | }
125 | 
```

--------------------------------------------------------------------------------
/packages/xmlui-animations/src/FadeAnimation.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import { createComponentRenderer, createMetadata } from "xmlui";
 2 | import { Animation, defaultProps } from "./AnimationNative";
 3 | 
 4 | const COMP = "FadeAnimation";
 5 | 
 6 | const defaultAnimationValues = {
 7 |   from: 0,
 8 |   to: 1,
 9 | };
10 | 
11 | export const FadeAnimationMd = createMetadata({
12 |   status: "experimental",
13 |   description: `The \`${COMP}\` component represents an animation that fades the content with adjustable opacity values.`,
14 |   docFolder: "src",
15 |   props: {
16 |     from: {
17 |       description:
18 |         "Sets the initial opacity of the content." +
19 |         "If the `to` property is not set, the initial opacity set here will be used as the final opacity.",
20 |       valueType: "number",
21 |       defaultValue: defaultAnimationValues.from,
22 |     },
23 |     to: {
24 |       description:
25 |         "Sets the final opacity of the content." +
26 |         "If the `from` property is not set, the initial opacity set here will be used as the final opacity.",
27 |       valueType: "number",
28 |       defaultValue: defaultAnimationValues.to,
29 |     },
30 |     animateWhenInView: {
31 |       description: `Indicates whether the animation should start when the component is in view`,
32 |       valueType: "boolean",
33 |     },
34 |     duration: {
35 |       description: `The duration of the animation in milliseconds`,
36 |       valueType: "number",
37 |     },
38 |     reverse: {
39 |       description: `Indicates whether the animation should run in reverse`,
40 |       defaultValue: defaultProps.reverse,
41 |       valueType: "boolean",
42 |     },
43 |     loop: {
44 |       description: `Indicates whether the animation should loop`,
45 |       defaultValue: defaultProps.loop,
46 |       valueType: "boolean",
47 |     },
48 |     delay: {
49 |       description: `The delay before the animation starts in milliseconds`,
50 |       defaultValue: defaultProps.delay,
51 |       valueType: "number",
52 |     },
53 |   },
54 |   events: {
55 |     started: { description: `Event fired when the animation starts` },
56 |     stopped: { description: `Event fired when the animation stops` },
57 |   },
58 |   apis: {
59 |     start: { description: `Starts the animation` },
60 |     stop: { description: `Stops the animation` },
61 |   },
62 | });
63 | 
64 | export const fadeAnimationRenderer = createComponentRenderer(
65 |   "FadeAnimation",
66 |   FadeAnimationMd,
67 |   ({ node, renderChild, extractValue, registerComponentApi, lookupEventHandler }) => {
68 |     return (
69 |       <Animation
70 |         registerComponentApi={registerComponentApi}
71 |         animation={{
72 |           from: {
73 |             opacity: extractValue.asOptionalNumber(node.props.from, defaultAnimationValues.from),
74 |           },
75 |           to: {
76 |             opacity: extractValue.asOptionalNumber(node.props.to, defaultAnimationValues.to),
77 |           },
78 |         }}
79 |         duration={extractValue.asOptionalNumber(node.props.duration)}
80 |         onStop={lookupEventHandler("stopped")}
81 |         onStart={lookupEventHandler("started")}
82 |         animateWhenInView={extractValue.asOptionalBoolean(node.props.animateWhenInView)}
83 |         reverse={extractValue.asOptionalBoolean(node.props.reverse)}
84 |         loop={extractValue.asOptionalBoolean(node.props.loop)}
85 |         delay={extractValue.asOptionalNumber(node.props.delay)}
86 |       >
87 |         {renderChild(node.children)}
88 |       </Animation>
89 |     );
90 |   },
91 | );
92 | 
```

