#
tokens: 49866/50000 12/1629 files (page 35/188)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 35 of 188. Use http://codebase.md/xmlui-org/xmlui/tools/vscode/resources/assets/img/%7Bsrc%7D?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .changeset
│   └── config.json
├── .eslintrc.cjs
├── .github
│   ├── build-checklist.png
│   ├── ISSUE_TEMPLATE
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   └── workflows
│       ├── deploy-blog-optimized.yml
│       ├── deploy-blog-swa.yml
│       ├── deploy-blog.yml
│       ├── deploy-docs-optimized.yml
│       ├── deploy-docs-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
│   │           ├── HelloMd.md
│   │           ├── HeroSection.md
│   │           └── ScrollToTop.md
│   ├── extensions.ts
│   ├── index.html
│   ├── index.ts
│   ├── package.json
│   ├── public
│   │   ├── feed.rss
│   │   ├── mockServiceWorker.js
│   │   ├── pages
│   │   │   ├── _meta.json
│   │   │   ├── app-structure.md
│   │   │   ├── build-editor-component.md
│   │   │   ├── build-hello-world-component.md
│   │   │   ├── components-intro.md
│   │   │   ├── context-variables.md
│   │   │   ├── forms.md
│   │   │   ├── globals.md
│   │   │   ├── glossary.md
│   │   │   ├── helper-tags.md
│   │   │   ├── hosted-deployment.md
│   │   │   ├── howto
│   │   │   │   ├── assign-a-complex-json-literal-to-a-component-variable.md
│   │   │   │   ├── chain-a-refetch.md
│   │   │   │   ├── 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
    │   │   │   └── test-padding.xmlui
    │   │   ├── 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

--------------------------------------------------------------------------------
/packages/xmlui-website-blocks/src/ScrollToTop/ScrollToTopNative.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import { forwardRef, useEffect, useState, useCallback } from "react";
  2 | import { Icon } from "xmlui";
  3 | import classnames from "classnames";
  4 | import styles from "./ScrollToTop.module.scss";
  5 | 
  6 | type Props = {
  7 |   position?: "start" | "center" | "end";
  8 |   visible?: boolean;
  9 |   threshold?: number;
 10 |   icon?: string;
 11 |   behavior?: "smooth" | "instant" | "auto";
 12 |   onClick?: () => void;
 13 |   className?: string;
 14 |   style?: React.CSSProperties;
 15 | };
 16 | 
 17 | export const defaultProps: Pick<Props, "position" | "visible" | "threshold" | "icon" | "behavior"> = {
 18 |   position: "end",
 19 |   visible: true,
 20 |   threshold: 300,
 21 |   icon: "chevronup",
 22 |   behavior: "smooth",
 23 | };
 24 | 
 25 | export const ScrollToTop = forwardRef<HTMLButtonElement, Props>(
 26 |   function ScrollToTop(
 27 |     {
 28 |       position = defaultProps.position,
 29 |       visible = defaultProps.visible,
 30 |       threshold = defaultProps.threshold,
 31 |       icon = defaultProps.icon,
 32 |       behavior = defaultProps.behavior,
 33 |       onClick,
 34 |       className,
 35 |       style,
 36 |     }: Props,
 37 |     ref,
 38 |   ) {
 39 |     const [isVisible, setIsVisible] = useState(false);
 40 | 
 41 |     // Validate position and fall back to "end" if invalid
 42 |     const validPosition = ["start", "center", "end"].includes(position || "") ? position : "end";
 43 |     
 44 |     // Validate behavior and fall back to "smooth" if invalid
 45 |     const validBehavior = ["smooth", "instant", "auto"].includes(behavior || "") ? behavior : "smooth";
 46 | 
 47 |     // Check scroll position to determine visibility
 48 |     useEffect(() => {
 49 |       if (!visible) {
 50 |         setIsVisible(false);
 51 |         return;
 52 |       }
 53 | 
 54 |       const handleScroll = () => {
 55 |         // Check multiple possible scroll containers using the same logic as scroll-to-top
 56 |         const windowScrollTop = window.pageYOffset || document.documentElement.scrollTop;
 57 |         const bodyScrollTop = document.body.scrollTop;
 58 |         
 59 |         let maxScrollTop = Math.max(windowScrollTop, bodyScrollTop);
 60 |         
 61 |         // Check all elements that might be scrolled (same as in handleClick)
 62 |         const allElements = document.querySelectorAll('*');
 63 |         allElements.forEach((element) => {
 64 |           if (element instanceof HTMLElement && element.scrollTop > 0) {
 65 |             maxScrollTop = Math.max(maxScrollTop, element.scrollTop);
 66 |           }
 67 |         });
 68 |         
 69 |         // Also check common XMLUI containers
 70 |         const xmluiContainers = document.querySelectorAll(
 71 |           '.xmlui-app, .xmlui-page, .xmlui-container, [data-xmlui], main, .main, #root, .app'
 72 |         );
 73 |         xmluiContainers.forEach((element) => {
 74 |           if (element instanceof HTMLElement) {
 75 |             maxScrollTop = Math.max(maxScrollTop, element.scrollTop);
 76 |           }
 77 |         });
 78 |         
 79 |         // If threshold is 0, show the button regardless of scroll position
 80 |         if (threshold === 0) {
 81 |           setIsVisible(true);
 82 |         } else {
 83 |           setIsVisible(maxScrollTop > (threshold || 0));
 84 |         }
 85 |       };
 86 | 
 87 |       window.addEventListener("scroll", handleScroll);
 88 |       document.addEventListener("scroll", handleScroll, true); // Capture phase for all scroll events
 89 |       
 90 |       // Also listen to scroll events on common container elements
 91 |       const xmluiContainers = document.querySelectorAll(
 92 |         '.xmlui-app, .xmlui-page, .xmlui-container, [data-xmlui], main, .main, #root, .app'
 93 |       );
 94 |       xmluiContainers.forEach((element) => {
 95 |         element.addEventListener("scroll", handleScroll);
 96 |       });
 97 |       
 98 |       handleScroll(); // Check initial position
 99 | 
100 |       return () => {
101 |         window.removeEventListener("scroll", handleScroll);
102 |         document.removeEventListener("scroll", handleScroll, true);
103 |         xmluiContainers.forEach((element) => {
104 |           element.removeEventListener("scroll", handleScroll);
105 |         });
106 |       };
107 |     }, [visible, threshold]);
108 | 
109 |     // Scroll to top functionality
110 |     const handleClick = useCallback(() => {
111 |       // Force scroll to top using multiple methods
112 |       // This will work regardless of which container is scrolled
113 |       
114 |       // Convert behavior prop to ScrollBehavior type
115 |       const scrollBehavior: ScrollBehavior = validBehavior === "instant" ? "instant" : validBehavior === "auto" ? "auto" : "smooth";
116 |       
117 |       // Method 1: Standard window scroll
118 |       window.scrollTo({ top: 0, behavior: scrollBehavior });
119 |       
120 |       // Method 2: Direct property setting (for instant behavior)
121 |       if (validBehavior === "instant") {
122 |         document.documentElement.scrollTop = 0;
123 |         document.body.scrollTop = 0;
124 |       }
125 |       
126 |       // Method 3: Find and scroll any scrolled containers
127 |       const allElements = document.querySelectorAll('*');
128 |       allElements.forEach((element) => {
129 |         if (element instanceof HTMLElement && element.scrollTop > 0) {
130 |           if (validBehavior === "instant") {
131 |             element.scrollTop = 0;
132 |           } else {
133 |             element.scrollTo({ top: 0, behavior: scrollBehavior });
134 |           }
135 |         }
136 |       });
137 |       
138 |       // Method 4: Scroll specific XMLUI containers (common patterns)
139 |       const xmluiContainers = document.querySelectorAll(
140 |         '.xmlui-app, .xmlui-page, .xmlui-container, [data-xmlui], main, .main, #root, .app'
141 |       );
142 |       xmluiContainers.forEach((element) => {
143 |         if (element instanceof HTMLElement) {
144 |           if (validBehavior === "instant") {
145 |             element.scrollTop = 0;
146 |           } else {
147 |             element.scrollTo({ top: 0, behavior: scrollBehavior });
148 |           }
149 |         }
150 |       });
151 |       
152 |       onClick?.();
153 |     }, [validBehavior, onClick]);
154 | 
155 |     if (!isVisible) {
156 |       return null;
157 |     }
158 | 
159 |     return (
160 |       <button
161 |         ref={ref}
162 |         className={classnames(
163 |           styles.scrollToTop,
164 |           {
165 |             [styles.positionStart]: validPosition === "start",
166 |             [styles.positionCenter]: validPosition === "center",
167 |             [styles.positionEnd]: validPosition === "end",
168 |           },
169 |           className,
170 |         )}
171 |         onClick={handleClick}
172 |         style={style}
173 |         aria-label="Scroll to top"
174 |         type="button"
175 |       >
176 |         <Icon name={icon} fallback="chevronup" aria-hidden />
177 |       </button>
178 |     );
179 |   },
180 | );
181 | 
```

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

```markdown
  1 | # Splitter [#splitter]
  2 | 
  3 | `Splitter` component divides a container into two resizable sections. These are are identified by their names: primary and secondary. They have a draggable bar between them. When only a single child is visible (due to conditional rendering with `when` attributes), the splitter bar is not displayed and the single panel stretches to fill the entire viewport of the splitter container.
  4 | 
  5 | Most properties of the component focus on the primary section (e.g. sizing).
  6 | 
  7 | See also: [HSplitter](/components/HSplitter), [VSplitter](/components/VSplitter).
  8 | 
  9 | ## Properties [#properties]
 10 | 
 11 | ### `floating` (default: false) [#floating-default-false]
 12 | 
 13 | Toggles whether the resizer is visible (`false`) or not (`true`) when not hovered or dragged. The default value is `false`, meaning the resizer is visible all the time.
 14 | 
 15 | ```xmlui-pg copy display name="Example: floating"
 16 | <App>
 17 |   <Splitter height="200px" floating="true">
 18 |     <Stack backgroundColor="lightblue" height="100%" />
 19 |     <Stack backgroundColor="darksalmon" height="100%" />
 20 |   </Splitter>
 21 | </App>
 22 | ```
 23 | 
 24 | ### `initialPrimarySize` (default: "50%") [#initialprimarysize-default-50-]
 25 | 
 26 | This optional number property sets the initial size of the primary section. The unit of the size value is in pixels or percentages.
 27 | 
 28 | ```xmlui-pg copy display name="Example: initialPrimarySize"
 29 | <App>
 30 |   <Splitter height="200px" initialPrimarySize="40%">
 31 |     <Stack backgroundColor="lightblue" height="100%" />
 32 |     <Stack backgroundColor="darksalmon" height="100%" />
 33 |   </Splitter>
 34 | </App>
 35 | ```
 36 | 
 37 | ### `maxPrimarySize` (default: "100%") [#maxprimarysize-default-100-]
 38 | 
 39 | This property sets the maximum size the primary section can have. The unit of the size value is in pixels or percentages. Negative values are supported and calculate from the end of the container (e.g., "-20%" means "80% of container", "-100px" means "container size - 100px").
 40 | 
 41 | ```xmlui-pg copy display name="Example: maxPrimarySize"
 42 | <App>
 43 |   <Splitter height="200px" maxPrimarySize="80%">
 44 |     <Stack backgroundColor="lightblue" height="100%" />
 45 |     <Stack backgroundColor="darksalmon" height="100%" />
 46 |   </Splitter>
 47 | </App>
 48 | ```
 49 | 
 50 | ```xmlui-pg copy display name="Example: maxPrimarySize with negative value (from end)"
 51 | <App>
 52 |   <Splitter height="200px" maxPrimarySize="-50px">
 53 |     <Stack backgroundColor="lightblue" height="100%" />
 54 |     <Stack backgroundColor="darksalmon" height="100%" />
 55 |   </Splitter>
 56 | </App>
 57 | ```
 58 | 
 59 | ### `minPrimarySize` (default: "0%") [#minprimarysize-default-0-]
 60 | 
 61 | This property sets the minimum size the primary section can have. The unit of the size value is in pixels or percentages.
 62 | 
 63 | ```xmlui-pg copy display name="Example: minPrimarySize"
 64 | <App>
 65 |   <Splitter height="200px" minPrimarySize="40px">
 66 |     <Stack backgroundColor="lightblue" height="100%" />
 67 |     <Stack backgroundColor="darksalmon" height="100%" />
 68 |   </Splitter>
 69 | </App>
 70 | ```
 71 | 
 72 | ### `orientation` (default: "vertical") [#orientation-default-vertical]
 73 | 
 74 | Sets whether the `Splitter` divides the container horizontally and lays out the section on top of each other (`vertical`), or vertically by placing the sections next to each other (`horizontal`).
 75 | 
 76 | Available values: `horizontal`, `vertical` **(default)**
 77 | 
 78 | ```xmlui-pg copy display name="Example: orientation"
 79 | <App>
 80 |   <Splitter height="200px" orientation="horizontal">
 81 |     <Stack backgroundColor="lightblue" height="100%" />
 82 |     <Stack backgroundColor="darksalmon" height="100%" />
 83 |   </Splitter>
 84 | </App>
 85 | ```
 86 | 
 87 | ### `splitterTemplate` [#splittertemplate]
 88 | 
 89 | The divider can be customized using XMLUI components via this property.
 90 | 
 91 | ```xmlui-pg copy {2-4} display name="Example: splitterTemplate"
 92 | <App>
 93 |   <Splitter height="200px">
 94 |     <property name="splitterTemplate">
 95 |       <ContentSeparator backgroundColor="green" height="4px" />
 96 |     </property>
 97 |     <Stack backgroundColor="lightblue" height="100%" />
 98 |     <Stack backgroundColor="darksalmon" height="100%" />
 99 |   </Splitter>
100 | </App>
101 | ```
102 | 
103 | ### `swapped` (default: false) [#swapped-default-false]
104 | 
105 | This optional booelan property indicates whether the `Splitter` sections are layed out as primary and secondary (`false`) or secondary and primary (`true`) from left to right.
106 | 
107 | ```xmlui-pg copy display name="Example: swapped"
108 | <App>
109 |   <Splitter height="200px" swapped="true">
110 |     <Stack backgroundColor="lightblue" height="100%" />
111 |     <Stack backgroundColor="darksalmon" height="100%" />
112 |   </Splitter>
113 | </App>
114 | ```
115 | 
116 | ## Events [#events]
117 | 
118 | ### `resize` [#resize]
119 | 
120 | This event fires when the component is resized.
121 | 
122 | ```xmlui-pg copy {2} display name="Example: resize"
123 | <App height="200px" var.counter="{0}">
124 |   <Splitter onResize="counter++">
125 |     <Stack backgroundColor="lightblue" height="100%">
126 |       <Text value="Resize event called {counter} number of times" />
127 |     </Stack>
128 |     <Stack backgroundColor="darksalmon" height="100%" />
129 |   </Splitter>
130 | </App>
131 | ```
132 | 
133 | ## Exposed Methods [#exposed-methods]
134 | 
135 | This component does not expose any methods.
136 | 
137 | ## Styling [#styling]
138 | 
139 | ### Theme Variables [#theme-variables]
140 | 
141 | | Variable | Default Value (Light) | Default Value (Dark) |
142 | | --- | --- | --- |
143 | | [backgroundColor](../styles-and-themes/common-units/#color)-resizer-Splitter | $color-surface-100 | $color-surface-100 |
144 | | [backgroundColor](../styles-and-themes/common-units/#color)-Splitter | *none* | *none* |
145 | | [border](../styles-and-themes/common-units/#border)-Splitter | *none* | *none* |
146 | | [borderColor](../styles-and-themes/common-units/#color)-Splitter | *none* | *none* |
147 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-Splitter | *none* | *none* |
148 | | [borderStyle](../styles-and-themes/common-units/#border-style)-Splitter | *none* | *none* |
149 | | [borderWidth](../styles-and-themes/common-units/#size)-Splitter | *none* | *none* |
150 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-Splitter | *none* | *none* |
151 | | [cursor](../styles-and-themes/common-units/#cursor)-resizer-horizontal-Splitter | ew-resize | ew-resize |
152 | | [cursor](../styles-and-themes/common-units/#cursor)-resizer-vertical-Splitter | ns-resize | ns-resize |
153 | | [thickness](../styles-and-themes/common-units/#size)-resizer-Splitter | 5px | 5px |
154 | 
```

--------------------------------------------------------------------------------
/xmlui/tests/components-core/scripts-runner/AttributeValueParser.test.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { assert, describe, expect, it } from "vitest";
  2 | 
  3 | import { parseAttributeValue } from "../../../src/components-core/script-runner/AttributeValueParser";
  4 | import { Identifier, ObjectLiteral, T_IDENTIFIER } from "../../../src/components-core/script-runner/ScriptingSourceTree";
  5 | import { T_OBJECT_LITERAL } from "../../../src/parsers/scripting/ScriptingNodeTypes";
  6 | 
  7 | describe("Attribute value parsing", () => {
  8 |   it("Empty value", () => {
  9 |     // --- Act
 10 |     const source = "";
 11 |     const val = parseAttributeValue(source)!;
 12 | 
 13 |     // --- Assert
 14 |     expect(val.__PARSED).toBe(true);
 15 |     expect(val.parseId).toBeTypeOf("number");
 16 |     expect(val.segments).toHaveLength(0);
 17 |   });
 18 | 
 19 |   it("single string literal", () => {
 20 |     // --- Act
 21 |     const source = "hello";
 22 |     const val = parseAttributeValue(source)!;
 23 | 
 24 |     // --- Assert
 25 |     expect(val.__PARSED).toBe(true);
 26 |     expect(val.parseId).toBeTypeOf("number");
 27 |     expect(val.segments).toHaveLength(1);
 28 |     expect(val.segments![0].expr).toBeUndefined();
 29 |     expect(val.segments![0].literal).toBe("hello");
 30 |   });
 31 | 
 32 |   it("single expression value", () => {
 33 |     // --- Act
 34 |     const source = "{myId}";
 35 |     const val = parseAttributeValue(source)!;
 36 | 
 37 |     // --- Assert
 38 |     expect(val.__PARSED).toBe(true);
 39 |     expect(val.segments).toHaveLength(1);
 40 |     expect(val.segments![0].expr).toBeDefined();
 41 |     expect(val.segments![0].literal).toBeUndefined();
 42 |     expect(val.segments![0].expr.type).toBe(T_IDENTIFIER);
 43 |     expect((val.segments![0].expr as Identifier).name).toBe("myId");
 44 |   });
 45 | 
 46 |   it("compound value #1", () => {
 47 |     // --- Act
 48 |     const source = "{myId}hello";
 49 |     const val = parseAttributeValue(source)!;
 50 | 
 51 |     // --- Assert
 52 |     expect(val.__PARSED).toBe(true);
 53 |     expect(val.parseId).toBeTypeOf("number");
 54 |     expect(val.segments).toHaveLength(2);
 55 |     expect(val.segments![0].expr).toBeDefined();
 56 |     expect(val.segments![0].literal).toBeUndefined();
 57 |     expect(val.segments![0].expr.type).toBe(T_IDENTIFIER);
 58 |     expect((val.segments![0].expr as Identifier).name).toBe("myId");
 59 |     expect(val.segments![1].expr).toBeUndefined();
 60 |     expect(val.segments![1].literal).toBe("hello");
 61 |   });
 62 | 
 63 |   it("compound value #2", () => {
 64 |     // --- Act
 65 |     const source = "hello{myId}";
 66 |     const val = parseAttributeValue(source)!;
 67 | 
 68 |     // --- Assert
 69 |     expect(val.__PARSED).toBe(true);
 70 |     expect(val.parseId).toBeTypeOf("number");
 71 |     expect(val.segments).toHaveLength(2);
 72 |     expect(val.segments![0].expr).toBeUndefined();
 73 |     expect(val.segments![0].literal).toBe("hello");
 74 |     expect(val.segments![1].expr).toBeDefined();
 75 |     expect(val.segments![1].literal).toBeUndefined();
 76 |     expect(val.segments![1].expr.type).toBe(T_IDENTIFIER);
 77 |     expect((val.segments![1].expr as Identifier).name).toBe("myId");
 78 |   });
 79 | 
 80 |   it("compound value #3", () => {
 81 |     // --- Act
 82 |     const source = "hello{myId}world";
 83 |     const val = parseAttributeValue(source)!;
 84 | 
 85 |     // --- Assert
 86 |     expect(val.__PARSED).toBe(true);
 87 |     expect(val.parseId).toBeTypeOf("number");
 88 |     expect(val.segments).toHaveLength(3);
 89 |     expect(val.segments![0].expr).toBeUndefined();
 90 |     expect(val.segments![0].literal).toBe("hello");
 91 |     expect(val.segments![1].expr).toBeDefined();
 92 |     expect(val.segments![1].literal).toBeUndefined();
 93 |     expect(val.segments![1].expr.type).toBe(T_IDENTIFIER);
 94 |     expect((val.segments![1].expr as Identifier).name).toBe("myId");
 95 |     expect(val.segments![2].expr).toBeUndefined();
 96 |     expect(val.segments![2].literal).toBe("world");
 97 |   });
 98 | 
 99 |   it("value with escaped brace #1", () => {
100 |     // --- Act
101 |     const source = "\\{myId";
102 |     const val = parseAttributeValue(source)!;
103 | 
104 |     // --- Assert
105 |     expect(val.__PARSED).toBe(true);
106 |     expect(val.parseId).toBeTypeOf("number");
107 |     expect(val.segments).toHaveLength(1);
108 |     expect(val.segments![0].expr).toBeUndefined();
109 |     expect(val.segments![0].literal).toBe("{myId");
110 |   });
111 | 
112 |   it("value with escaped brace #2", () => {
113 |     // --- Act
114 |     const source = "\\{myId}hello";
115 |     const val = parseAttributeValue(source)!;
116 | 
117 |     // --- Assert
118 |     expect(val.__PARSED).toBe(true);
119 |     expect(val.parseId).toBeTypeOf("number");
120 |     expect(val.segments).toHaveLength(1);
121 |     expect(val.segments![0].expr).toBeUndefined();
122 |     expect(val.segments![0].literal).toBe("{myId}hello");
123 |   });
124 | 
125 |   it("value with escaped brace #3", () => {
126 |     // --- Act
127 |     const source = "hello\\{myId}";
128 |     const val = parseAttributeValue(source)!;
129 | 
130 |     // --- Assert
131 |     expect(val.__PARSED).toBe(true);
132 |     expect(val.parseId).toBeTypeOf("number");
133 |     expect(val.segments).toHaveLength(1);
134 |     expect(val.segments![0].expr).toBeUndefined();
135 |     expect(val.segments![0].literal).toBe("hello{myId}");
136 |   });
137 | 
138 |   it("value with escaped brace #4", () => {
139 |     // --- Act
140 |     const source = "hello\\{myId}{world}";
141 |     const val = parseAttributeValue(source)!;
142 | 
143 |     // --- Assert
144 |     expect(val.__PARSED).toBe(true);
145 |     expect(val.parseId).toBeTypeOf("number");
146 |     expect(val.segments).toHaveLength(2);
147 |     expect(val.segments![0].expr).toBeUndefined();
148 |     expect(val.segments![0].literal).toBe("hello{myId}");
149 |     expect(val.segments![1].expr).toBeDefined();
150 |     expect(val.segments![1].literal).toBeUndefined();
151 |     expect(val.segments![1].expr.type).toBe(T_IDENTIFIER);
152 |     expect((val.segments![1].expr as Identifier).name).toBe("world");
153 |   });
154 | 
155 |   it("value with unclosed brace", () => {
156 |     // --- Act
157 |     const source = "{myId";
158 |     try {
159 |       const val = parseAttributeValue(source)!;
160 |     } catch (err) {
161 |       expect(err.toString()).toContain("Unclosed");
162 |       return;
163 |     }
164 |     assert.fail("Exception expected");
165 |   });
166 | 
167 |     it("object value #1", () => {
168 |     // --- Act
169 |     const source = "{{ from: from, to: to }}";
170 |     const val = parseAttributeValue(source)!;
171 | 
172 |     // --- Assert
173 |     expect(val.__PARSED).toBe(true);
174 |     expect(val.parseId).toBeTypeOf("number");
175 |     expect(val.segments).toHaveLength(1);
176 |     expect(val.segments![0].expr).toBeDefined();
177 |     expect(val.segments![0].literal).toBeUndefined();
178 |     expect(val.segments![0].expr.type).toBe(T_OBJECT_LITERAL);
179 |     expect((val.segments![0].expr as ObjectLiteral).props.length).toBe(2);
180 |   });
181 | 
182 | });
```

--------------------------------------------------------------------------------
/docs/public/pages/tutorial-10.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Search
  2 | 
  3 | The `Search` component uses [Tabs](/components/Tabs) to enable switching between two different search experiences.
  4 | 
  5 | ```xmlui-pg display  noHeader
  6 | ---app display
  7 | <App>
  8 |   <Search />
  9 | </App>
 10 | ---comp display
 11 | <Component name="Search">
 12 | 
 13 |   <Tabs>
 14 |     <TabItem label="Find invoices issued after date">
 15 |       <SearchInvoicesAfter />
 16 |     </TabItem>
 17 |     <TabItem label="Search clients, products, and invoices">
 18 |       <SearchEverything />
 19 |     </TabItem>
 20 |   </Tabs>
 21 | 
 22 | </Component>
 23 | ---comp display
 24 | <Component name="SearchInvoicesAfter">
 25 | This is SearchInvoicesAfter.
 26 | </Component>
 27 | ---comp display
 28 | <Component name="SearchEverything">
 29 | This is SearchEverything.
 30 | </Component>
 31 | ---desc
 32 | Try switching between the two tabs.
 33 | ```
 34 | 
 35 | ## Search invoices after date
 36 | 
 37 | Here is `SearchInvoicesAfter`. Try changing the date.
 38 | 
 39 | 
 40 | ```xmlui-pg  noHeader
 41 | ---app display
 42 | <App>
 43 |   <SearchInvoicesAfter />
 44 | </App>
 45 | ---comp
 46 | <Component
 47 |     name="StatusBadge"
 48 |     var.statusColors="{{
 49 |         draft: { background: '#f59e0b', label: 'white' },
 50 |         sent: { background: '#3b82f6', label: 'white' },
 51 |         paid: { background: '#10b981', label: 'white' }
 52 |     }}"
 53 | >
 54 |     <Badge
 55 |         value="{$props.status}"
 56 |         colorMap="{statusColors}"
 57 |         variant="pill"
 58 |     />
 59 | </Component>
 60 | ---comp
 61 | <Component name="SearchInvoicesAfter">
 62 | 
 63 |     <VStack marginTop="1rem">
 64 |         <DatePicker
 65 |             id="dateAfter"
 66 |             width="20rem"
 67 |             initialValue="2025-01-01"
 68 |             dateFormat="yyyy-MM-dd"
 69 |             onDidChange="(val) => console.log('Date selected:', val)"
 70 |         />
 71 | 
 72 |         <DataSource
 73 |             id="invoicesAfter"
 74 |             url="/resources/files/invoices.json"
 75 |             when="{dateAfter.value}"
 76 |             transformResult="{(data) => window.filterInvoicesAfter(data || [], dateAfter.value)}"
 77 |         />
 78 | 
 79 |         <ChangeListener
 80 |             listenTo="{dateAfter.value}"
 81 |             onDidChange="invoicesAfter.reload()"
 82 |         />
 83 | 
 84 |         <Fragment when="{invoicesAfter}">
 85 |           <Card>
 86 |               <VStack>
 87 |                   <Table data="{ invoicesAfter }">
 88 |                       <Column  bindTo="client" header="Client" />
 89 |                       <Column  bindTo="issue_date" header="Issue Date">
 90 |                           { window.formatDate($item.issue_date) }
 91 |                       </Column>
 92 |                       <Column  header="Status">
 93 |                           <StatusBadge status="{$item.status}" />
 94 |                       </Column>
 95 |                       <Column  bindTo="total" header="Total" >
 96 |                           ${$item.total}
 97 |                       </Column>
 98 |                   </Table>
 99 |               </VStack>
100 |           </Card>
101 |         </Fragment>
102 |     </VStack>
103 | 
104 | </Component>
105 | ```
106 | 
107 | 
108 | ```xmlui /when/
109 | <Component name="SearchInvoicesAfter">
110 |     <VStack paddingTop="$space-4">
111 |         <DatePicker
112 |           id="dateAfter"
113 |           width="20rem"
114 |           initialValue="2025-01-01"
115 |           dateFormat="yyyy-MM-dd"
116 |           onDidChange="(val) => console.log('Date selected:', val)"
117 |         />
118 |         <Card when="{dateAfter.value}">
119 |             <Table data="/api/invoices/after/{dateAfter.value}">
120 |                 <Column bindTo="name" header="Client"/>
121 |                 <Column bindTo="issue_date" header="Issue Date">
122 |                     { window.formatDate($item.issue_date) }
123 |                 </Column>
124 |                 <Column header="Status">
125 |                     <StatusBadge status="{$item.status}"/>
126 |                 </Column>
127 |                 <Column bindTo="total" header="Total">
128 |                     ${$item.total}
129 |                 </Column>
130 |             </Table>
131 |         </Card>
132 |     </VStack>
133 | </Component>
134 | ```
135 | 
136 | The `when` guards the [DatePicker](/components/DatePicker)'s `dateAfter`, so the `Table`
137 | s `data` URL won't fire until its dependent variable is ready.
138 | 
139 | > [!INFO]
140 | > You can use the `when` property on *any* XMLUI component to prevent it from rendering until some condition is true.
141 | 
142 | 
143 | ## Search everything
144 | 
145 | Here is `SearchEverything`. Try typing `a`, then `c`, then `m`, and watch the results converge dynamically on `Acme`.
146 | 
147 | ```xmlui-pg height="400px"  noHeader
148 | ---app
149 | <App>
150 |   <SearchEverything />
151 | </App>
152 | ---comp
153 | <Component name="SearchEverything">
154 | 
155 |     <VStack marginTop="1rem">
156 |         <TextBox
157 |             placeholder="Enter search term..."
158 |             width="25rem"
159 |             id="searchTerm"
160 |         />
161 | 
162 |         <DataSource id="clients" url="/resources/files/clients.json" />
163 |         <DataSource id="products" url="/resources/files/products.json" />
164 |         <DataSource id="allInvoices" url="/resources/files/invoices.json" />
165 | 
166 |         <Fragment when="{searchTerm.value}">
167 |             <Card>
168 |                 <VStack>
169 |                     <Text>Found {window.filterSearchResults(clients, products, allInvoices, searchTerm.value).length} results for
170 |                         "{searchTerm.value}":</Text>
171 |                     <Table data="{window.filterSearchResults(clients, products, allInvoices, searchTerm.value)}">
172 |                         <Column  bindTo="table_name" header="Type" width="100px" />
173 |                         <Column  bindTo="title" header="Title" width="*" />
174 |                         <Column  bindTo="snippet" header="Match Details" width="3*" />
175 |                     </Table>
176 |                 </VStack>
177 |             </Card>
178 |         </Fragment>
179 |     </VStack>
180 | 
181 | </Component>
182 | ```
183 | 
184 | It's similar to `SearchInvoicesAfter`.
185 | 
186 | ```xmlui /when=/
187 | <Component name="SearchEverything">
188 | 
189 |     <VStack paddingTop="$space-4">
190 |         <TextBox
191 |             placeholder="Enter search term..."
192 |             width="25rem"
193 |             id="searchTerm"
194 |         />
195 | 
196 |         <Card when="{searchTerm.value}">
197 |             <DataSource
198 |               id="search"
199 |               url="/api/search/{searchTerm.value}"
200 |             />
201 |             <Text>Found {search.value ? search.value.length : 0} results for
202 |                 "{searchTerm.value}":</Text>
203 |             <Table data="{search}">
204 |                 <Column  bindTo="table_name" header="Type" width="100px" />
205 |                 <Column  bindTo="title" header="Title" width="*" />
206 |                 <Column  bindTo="snippet" header="Match Details" width="3*" />
207 |             </Table>
208 |         </Card>
209 |     </VStack>
210 | 
211 | </Component>
212 | ```
```

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

```markdown
  1 | # LineChart [#linechart]
  2 | 
  3 | `LineChart` displays data as connected points over a continuous axis, ideal for showing trends, changes over time, or relationships between variables. Use it time series data, progress tracking, and comparing multiple data series on the same scale.
  4 | 
  5 | The LineChart component accommodates the size of its parent unless you set it explicitly:
  6 | 
  7 | ```xmlui-pg copy display height="300px" name="Example: dimension determined by the parent" /Card height="240px" width="75%"/
  8 | <Card height="240px" width="75%">
  9 |   <LineChart
 10 |     data="{[
 11 |         { 'sprint': 'Sprint 1', 'A': 44 },
 12 |         { 'sprint': 'Sprint 2', 'A': 32 },
 13 |         { 'sprint': 'Sprint 3', 'A': 48 },
 14 |         { 'sprint': 'Sprint 4', 'A': 72 }
 15 |        ]}"
 16 |     yKeys="{['A']}"
 17 |     xKey="sprint"
 18 |   />
 19 | </Card>
 20 | ```
 21 | 
 22 | ```xmlui-pg copy display height="300px" name="Example: dimension overwritten by LineChart" /height="240px"/ /height="200px"/
 23 | <Card height="240px">
 24 |   <LineChart
 25 |     height="200px"
 26 |     data="{[
 27 |         { 'sprint': 'Sprint 1', 'A': 44 },
 28 |         { 'sprint': 'Sprint 2', 'A': 32 },
 29 |         { 'sprint': 'Sprint 3', 'A': 48 },
 30 |         { 'sprint': 'Sprint 4', 'A': 72 }
 31 |        ]}"
 32 |     yKeys="{['A']}"
 33 |     xKey="sprint"
 34 |   />
 35 | </Card>
 36 | ```
 37 | 
 38 | **Key features:**
 39 | - **Flexible orientation**: Choose horizontal or vertical bar layouts
 40 | - **Multiple data series**: Display several metrics on the same chart with different colored bars
 41 | - **Stacked vs grouped**: Stack bars on top of each other or place them side by side
 42 | - **Custom formatting**: Use `tickFormatter` to format axis labels and [`LabelList`](/components/LabelList) for data labels
 43 | 
 44 | ## Properties [#properties]
 45 | 
 46 | ### `data` [#data]
 47 | 
 48 | The data to be displayed in the line chart.It needs to be an array of objects, where each object represents a data point.
 49 | 
 50 | ### `hideTickX` (default: false) [#hidetickx-default-false]
 51 | 
 52 | Determines whether the X-axis ticks should be hidden. If set to (`true`), the ticks will not be displayed.
 53 | 
 54 | ### `hideTickY` (default: false) [#hideticky-default-false]
 55 | 
 56 | Determines whether the Y-axis ticks should be hidden. If set to (`true`), the ticks will not be displayed.
 57 | 
 58 | ### `hideTooltip` (default: false) [#hidetooltip-default-false]
 59 | 
 60 | Determines whether the tooltip should be hidden.If set to (`true`), no tooltip will be shown when hovering over data points.
 61 | 
 62 | ### `hideX` (default: false) [#hidex-default-false]
 63 | 
 64 | Determines whether the X-axis should be hidden. If set to (`true`), the axis will not be displayed.
 65 | 
 66 | ### `hideY` (default: false) [#hidey-default-false]
 67 | 
 68 | Determines whether the Y-axis should be hidden. If set to (`true`), the axis will not be displayed.
 69 | 
 70 | ### `marginBottom` [#marginbottom]
 71 | 
 72 | The bottom margin of the chart
 73 | 
 74 | ### `marginLeft` [#marginleft]
 75 | 
 76 | The left margin of the chart
 77 | 
 78 | ### `marginRight` [#marginright]
 79 | 
 80 | The right margin of the chart
 81 | 
 82 | ### `marginTop` [#margintop]
 83 | 
 84 | The top margin of the chart
 85 | 
 86 | ### `showLegend` (default: false) [#showlegend-default-false]
 87 | 
 88 | Determines whether the legend should be displayed.
 89 | 
 90 | ### `tickFormatterX` [#tickformatterx]
 91 | 
 92 | A function that formats the X-axis tick labels. It receives a tick value and returns a formatted string.
 93 | 
 94 | ```xmlui-pg copy display height="320px" name="Example: tickFormatterX" /tickFormatterX/
 95 | <App>
 96 |   <LineChart
 97 |     height="240px"
 98 |     data="{[
 99 |         { 'sprint': 'Sprint 1', 'A': 44 },
100 |         { 'sprint': 'Sprint 2', 'A': 32 },
101 |         { 'sprint': 'Sprint 3', 'A': 48 },
102 |         { 'sprint': 'Sprint 4', 'A': 72 }
103 |        ]}"
104 |     yKeys="{['A']}"
105 |     xKey="sprint"
106 |     tickFormatterX="{(value) => '(' + value + ')'}"
107 |   />
108 | </App>
109 | ```
110 | 
111 | ### `tickFormatterY` [#tickformattery]
112 | 
113 | A function that formats the Y-axis tick labels. It receives a tick value and returns a formatted string.
114 | 
115 | ```xmlui-pg copy display height="320px" name="Example: tickFormatterY" /tickFormatterY/
116 | <App>
117 |   <LineChart
118 |     height="240px"
119 |     data="{[
120 |         { 'sprint': 'Sprint 1', 'A': 44 },
121 |         { 'sprint': 'Sprint 2', 'A': 32 },
122 |         { 'sprint': 'Sprint 3', 'A': 48 },
123 |         { 'sprint': 'Sprint 4', 'A': 72 }
124 |        ]}"
125 |     yKeys="{['A']}"
126 |     xKey="sprint"
127 |     tickFormatterY="{(value) => '$' + value}"
128 |   />
129 | </App>
130 | ```
131 | 
132 | ### `tooltipTemplate` [#tooltiptemplate]
133 | 
134 | This property allows replacing the default template to display a tooltip.
135 | 
136 | ```xmlui-pg copy display height="320px" name="Example: tooltipTemplate" /tooltipTemplate/
137 | <App>
138 |   <LineChart
139 |     height="240px"
140 |     data="{[
141 |         { 'sprint': 'Sprint 1', 'A': 44, 'B': 28 },
142 |         { 'sprint': 'Sprint 2', 'A': 32, 'B': 41 },
143 |         { 'sprint': 'Sprint 3', 'A': 48, 'B': 35 },
144 |         { 'sprint': 'Sprint 4', 'A': 72, 'B': 58 }
145 |        ]}"
146 |     yKeys="{['A', 'B']}"
147 |     xKey="sprint"
148 |   >
149 |       <property name="tooltipTemplate">
150 |         <VStack backgroundColor='white' padding="$space-2">
151 |           <Text fontWeight='bold'>{$tooltip.label}</Text>
152 |           <Items data="{$tooltip.payload}">
153 |             <HStack gap="$space-2" verticalAlignment="center">
154 |               <Stack
155 |                 width="8px"
156 |                 height="8px"
157 |                 backgroundColor="{$item.color}" />
158 |               <Text>{$item.label}: {$item.value}</Text>
159 |             </HStack>
160 |           </Items>
161 |         </VStack>
162 |       </property>
163 |   </LineChart>
164 | </App>
165 | ```
166 | 
167 | The `tooltipTemplate` prop allows you to customize the appearance and content of chart tooltips. The template receives a `$tooltip` context variable containing:
168 | 
169 | - `$tooltip.label`: The label for the data point (typically the yKey value)
170 | - `$tooltip.payload`: An object containing all data values for the hovered point
171 | - `$tooltip.active`: Boolean indicating if the tooltip is currently active
172 | 
173 | ### `xKey` [#xkey]
174 | 
175 | The key in the data objects used for labeling different data series.
176 | 
177 | ### `yKeys` [#ykeys]
178 | 
179 | This property specifies the keys in the data objects that should be used for rendering the lines.
180 | 
181 | ## Events [#events]
182 | 
183 | This component does not have any events.
184 | 
185 | ## Exposed Methods [#exposed-methods]
186 | 
187 | This component does not expose any methods.
188 | 
189 | ## Styling [#styling]
190 | 
191 | ### Theme Variables [#theme-variables]
192 | 
193 | | Variable | Default Value (Light) | Default Value (Dark) |
194 | | --- | --- | --- |
195 | | [width](../styles-and-themes/common-units/#size)-line-LineChart | 1px | 1px |
196 | 
```

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

```typescript
  1 | import styles from "./Carousel.module.scss";
  2 | 
  3 | import { createComponentRenderer } from "../../components-core/renderers";
  4 | import { parseScssVar } from "../../components-core/theming/themeVars";
  5 | import { createMetadata, d, dDidChange } from "../metadata-helpers";
  6 | import { CarouselComponent, defaultProps } from "./CarouselNative";
  7 | import { orientationOptionMd } from "../abstractions";
  8 | 
  9 | const COMP = "Carousel";
 10 | 
 11 | export const CarouselMd = createMetadata({
 12 |   status: "stable",
 13 |   description:
 14 |     `This component displays a slideshow by cycling through elements (images, text, or ` +
 15 |     `custom slides) like a carousel.`,
 16 |   props: {
 17 |     orientation: {
 18 |       description:
 19 |         "This property indicates the orientation of the carousel. The `horizontal` " +
 20 |         "value indicates that the carousel moves horizontally, and the `vertical` " +
 21 |         "value indicates that the carousel moves vertically.",
 22 |       availableValues: orientationOptionMd,
 23 |       valueType: "string",
 24 |       defaultValue: defaultProps.orientation,
 25 |     },
 26 |     indicators: {
 27 |       description: "Display the individual slides as buttons (`true`) or not (`false`).",
 28 |       valueType: "boolean",
 29 |       defaultValue: defaultProps.indicators,
 30 |     },
 31 |     controls: {
 32 |       description: "Display the previous/next controls (`true`) or not (`false`).",
 33 |       valueType: "boolean",
 34 |       defaultValue: defaultProps.controls,
 35 |     },
 36 |     autoplay: {
 37 |       description: "Start scrolling the carousel automatically (`true`) or not (`false`).",
 38 |       valueType: "boolean",
 39 |       defaultValue: defaultProps.autoplay,
 40 |     },
 41 |     loop: {
 42 |       description: "Sets whether the carousel should loop back to the start/end when it reaches the last/first slide.",
 43 |       valueType: "boolean",
 44 |       defaultValue: defaultProps.loop,
 45 |     },
 46 |     startIndex: {
 47 |       description: "The index of the first slide to display.",
 48 |       valueType: "number",
 49 |       defaultValue: defaultProps.startIndex,
 50 |     },
 51 |     transitionDuration: {
 52 |       description: "The duration of the transition between slides.",
 53 |       valueType: "number",
 54 |       defaultValue: defaultProps.transitionDuration,
 55 |     },
 56 |     autoplayInterval: {
 57 |       description: "Specifies the interval between autoplay transitions.",
 58 |       valueType: "number",
 59 |       defaultValue: defaultProps.autoplayInterval,
 60 |     },
 61 |     stopAutoplayOnInteraction: {
 62 |       description: "This property indicates whether autoplay stops on user interaction.",
 63 |       valueType: "boolean",
 64 |       defaultValue: defaultProps.stopAutoplayOnInteraction,
 65 |     },
 66 |     prevIcon: {
 67 |       description: "The icon to display for the previous control.",
 68 |       valueType: "string",
 69 |     },
 70 |     nextIcon: {
 71 |       description: "The icon to display for the next control.",
 72 |       valueType: "string",
 73 |     },
 74 |   },
 75 |   events: {
 76 |     displayDidChange: dDidChange(COMP),
 77 |   },
 78 |   apis: {
 79 |     canScrollPrev: {
 80 |       description: `This method returns \`true\` if the carousel can scroll to the previous slide.`,
 81 |       signature: "canScrollPrev(): boolean",
 82 |     },
 83 |     canScrollNext: {
 84 |       description: `This method returns \`true\` if the carousel can scroll to the next slide.`,
 85 |       signature: "canScrollNext(): boolean",
 86 |     },
 87 |     scrollTo: {
 88 |       description: `This method scrolls the carousel to the specified slide index.`,
 89 |       signature: "scrollTo(index: number): void",
 90 |       parameters: {
 91 |         index: "The index of the slide to scroll to.",
 92 |       },
 93 |     },
 94 |     scrollPrev: {
 95 |       signature: "scrollPrev(): void",
 96 |       description: "This method scrolls the carousel to the previous slide.",
 97 |     },
 98 |     scrollNext: {
 99 |       signature: "scrollNext(): void",
100 |       description: "This method scrolls the carousel to the next slide.",
101 |     },
102 |   },
103 |   themeVars: parseScssVar(styles.themeVars),
104 |   defaultThemeVars: {
105 |     [`backgroundColor-control-${COMP}`]: "$color-primary",
106 |     [`textColor-control-${COMP}`]: "$textColor",
107 |     [`backgroundColor-control-hover-${COMP}`]: "$color-primary",
108 |     [`textColor-control-hover-${COMP}`]: "$textColor",
109 |     [`backgroundColor-control-active-${COMP}`]: "$color-primary",
110 |     [`backgroundColor-control-disabled-${COMP}`]: "$color-surface-200",
111 |     [`textColor-control-disabled-${COMP}`]: "$textColor-disabled",
112 |     [`textColor-control-active-${COMP}`]: "$color-primary",
113 |     [`backgroundColor-indicator-${COMP}`]: "$color-surface-200",
114 |     [`backgroundColor-indicator-active-${COMP}`]: "$color-primary",
115 |     [`textColor-indicator-${COMP}`]: "$color-primary",
116 |     [`textColor-indicator-active-${COMP}`]: "$color-primary",
117 |     [`backgroundColor-indicator-hover-${COMP}`]: "$color-surface-200",
118 |     [`textColor-indicator-hover-${COMP}`]: "$color-primary",
119 |     [`width-indicator-${COMP}`]: "25px",
120 |     [`height-indicator-${COMP}`]: "6px",
121 |     [`height-control-${COMP}`]: "36px",
122 |     [`width-control-${COMP}`]: "36px",
123 |     [`borderRadius-control-${COMP}`]: "50%",
124 |     [`height-${COMP}`]: "100%",
125 |     [`width-${COMP}`]: "100%",
126 |   },
127 | });
128 | 
129 | export const carouselComponentRenderer = createComponentRenderer(
130 |   COMP,
131 |   CarouselMd,
132 |   ({ node, renderChild, className, extractValue, lookupEventHandler, registerComponentApi }) => {
133 |     return (
134 |       <CarouselComponent
135 |         className={className}
136 |         stopAutoplayOnInteraction={extractValue.asOptionalBoolean(
137 |           node.props?.stopAutoplayOnInteraction,
138 |         )}
139 |         autoplayInterval={extractValue.asOptionalNumber(node.props?.autoplayInterval)}
140 |         transitionDuration={extractValue.asOptionalNumber(node.props?.transitionDuration)}
141 |         indicators={extractValue.asOptionalBoolean(node.props?.indicators)}
142 |         controls={extractValue.asOptionalBoolean(node.props?.controls)}
143 |         orientation={extractValue(node.props?.orientation)}
144 |         onDisplayDidChange={lookupEventHandler("displayDidChange")}
145 |         autoplay={extractValue.asOptionalBoolean(node.props?.autoplay)}
146 |         registerComponentApi={registerComponentApi}
147 |         loop={extractValue.asOptionalBoolean(node.props?.loop)}
148 |         startIndex={extractValue.asOptionalNumber(node.props?.startIndex)}
149 |         prevIcon={extractValue(node.props?.prevIcon)}
150 |         nextIcon={extractValue(node.props?.nextIcon)}
151 |       >
152 |         {renderChild(node.children)}
153 |       </CarouselComponent>
154 |     );
155 |   },
156 | );
157 | 
```

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

```typescript
  1 | import styles from "./Carousel.module.scss";
  2 | 
  3 | import { createComponentRenderer, parseScssVar, createMetadata, d } from "xmlui";
  4 | 
  5 | const dDidChange = (componentName: string) => d(`This event is fired when the displayed content of the ${componentName} changes.`);
  6 | const orientationOptionMd = ["horizontal", "vertical"];
  7 | import { CarouselComponent, defaultProps } from "./CarouselNative";
  8 | 
  9 | const COMP = "CarouselNew";
 10 | 
 11 | export const CarouselMd = createMetadata({
 12 |   status: "stable",
 13 |   description:
 14 |     `This component displays a slideshow by cycling through elements (images, text, or ` +
 15 |     `custom slides) like a carousel.`,
 16 |   props: {
 17 |     orientation: {
 18 |       description:
 19 |         "This property indicates the orientation of the carousel. The `horizontal` " +
 20 |         "value indicates that the carousel moves horizontally, and the `vertical` " +
 21 |         "value indicates that the carousel moves vertically.",
 22 |       availableValues: orientationOptionMd,
 23 |       valueType: "string",
 24 |       defaultValue: defaultProps.orientation,
 25 |     },
 26 |     indicators: {
 27 |       description: "Display the individual slides as buttons (`true`) or not (`false`).",
 28 |       valueType: "boolean",
 29 |       defaultValue: defaultProps.indicators,
 30 |     },
 31 |     controls: {
 32 |       description: "Display the previous/next controls (`true`) or not (`false`).",
 33 |       valueType: "boolean",
 34 |       defaultValue: defaultProps.controls,
 35 |     },
 36 |     autoplay: {
 37 |       description: "Start scrolling the carousel automatically (`true`) or not (`false`).",
 38 |       valueType: "boolean",
 39 |       defaultValue: defaultProps.autoplay,
 40 |     },
 41 |     loop: {
 42 |       description: "Sets whether the carousel should loop back to the start/end when it reaches the last/first slide.",
 43 |       valueType: "boolean",
 44 |       defaultValue: defaultProps.loop,
 45 |     },
 46 |     startIndex: {
 47 |       description: "The index of the first slide to display.",
 48 |       valueType: "number",
 49 |       defaultValue: defaultProps.startIndex,
 50 |     },
 51 |     transitionDuration: {
 52 |       description: "The duration of the transition between slides.",
 53 |       valueType: "number",
 54 |       defaultValue: defaultProps.transitionDuration,
 55 |     },
 56 |     autoplayInterval: {
 57 |       description: "Specifies the interval between autoplay transitions.",
 58 |       valueType: "number",
 59 |       defaultValue: defaultProps.autoplayInterval,
 60 |     },
 61 |     stopAutoplayOnInteraction: {
 62 |       description: "This property indicates whether autoplay stops on user interaction.",
 63 |       valueType: "boolean",
 64 |       defaultValue: defaultProps.stopAutoplayOnInteraction,
 65 |     },
 66 |     prevIcon: {
 67 |       description: "The icon to display for the previous control.",
 68 |       valueType: "string",
 69 |     },
 70 |     nextIcon: {
 71 |       description: "The icon to display for the next control.",
 72 |       valueType: "string",
 73 |     },
 74 |   },
 75 |   events: {
 76 |     displayDidChange: dDidChange(COMP),
 77 |   },
 78 |   apis: {
 79 |     canScrollPrev: {
 80 |       description: `This method returns \`true\` if the carousel can scroll to the previous slide.`,
 81 |       signature: "canScrollPrev(): boolean",
 82 |     },
 83 |     canScrollNext: {
 84 |       description: `This method returns \`true\` if the carousel can scroll to the next slide.`,
 85 |       signature: "canScrollNext(): boolean",
 86 |     },
 87 |     scrollTo: {
 88 |       description: `This method scrolls the carousel to the specified slide index.`,
 89 |       signature: "scrollTo(index: number): void",
 90 |       parameters: {
 91 |         index: "The index of the slide to scroll to.",
 92 |       },
 93 |     },
 94 |     scrollPrev: {
 95 |       signature: "scrollPrev(): void",
 96 |       description: "This method scrolls the carousel to the previous slide.",
 97 |     },
 98 |     scrollNext: {
 99 |       signature: "scrollNext(): void",
100 |       description: "This method scrolls the carousel to the next slide.",
101 |     },
102 |   },
103 |   themeVars: parseScssVar(styles.themeVars),
104 |   defaultThemeVars: {
105 |     [`backgroundColor-control-${COMP}`]: "$color-primary",
106 |     [`textColor-control-${COMP}`]: "$textColor",
107 |     [`backgroundColor-control-hover-${COMP}`]: "$color-primary",
108 |     [`textColor-control-hover-${COMP}`]: "$textColor",
109 |     [`backgroundColor-control-active-${COMP}`]: "$color-primary",
110 |     [`backgroundColor-control-disabled-${COMP}`]: "$color-surface-200",
111 |     [`textColor-control-disabled-${COMP}`]: "$textColor-disabled",
112 |     [`textColor-control-active-${COMP}`]: "$color-primary",
113 |     [`backgroundColor-indicator-${COMP}`]: "$color-surface-200",
114 |     [`backgroundColor-indicator-active-${COMP}`]: "$color-primary",
115 |     [`textColor-indicator-${COMP}`]: "$color-primary",
116 |     [`textColor-indicator-active-${COMP}`]: "$color-primary",
117 |     [`backgroundColor-indicator-hover-${COMP}`]: "$color-surface-200",
118 |     [`textColor-indicator-hover-${COMP}`]: "$color-primary",
119 |     [`width-indicator-${COMP}`]: "25px",
120 |     [`height-indicator-${COMP}`]: "6px",
121 |     [`height-control-${COMP}`]: "36px",
122 |     [`width-control-${COMP}`]: "36px",
123 |     [`borderRadius-control-${COMP}`]: "50%",
124 |     [`height-${COMP}`]: "100%",
125 |     [`width-${COMP}`]: "100%",
126 |   },
127 | } as const);
128 | 
129 | export const carouselComponentRenderer = createComponentRenderer(
130 |   COMP,
131 |   CarouselMd,
132 |   ({ node, renderChild, className, extractValue, lookupEventHandler, registerComponentApi }) => {
133 |     const props = (node.props as typeof CarouselMd.props)!;
134 |     return (
135 |       <CarouselComponent
136 |         className={className}
137 |         stopAutoplayOnInteraction={extractValue.asOptionalBoolean(
138 |           props.stopAutoplayOnInteraction,
139 |         )}
140 |         autoplayInterval={extractValue.asOptionalNumber(props.autoplayInterval)}
141 |         transitionDuration={extractValue.asOptionalNumber(props.transitionDuration)}
142 |         indicators={extractValue.asOptionalBoolean(props.indicators)}
143 |         controls={extractValue.asOptionalBoolean(props.controls)}
144 |         orientation={extractValue(props.orientation)}
145 |         onDisplayDidChange={lookupEventHandler("displayDidChange")}
146 |         autoplay={extractValue.asOptionalBoolean(props.autoplay)}
147 |         registerComponentApi={registerComponentApi}
148 |         loop={extractValue.asOptionalBoolean(props.loop)}
149 |         startIndex={extractValue.asOptionalNumber(props.startIndex)}
150 |         prevIcon={extractValue(props.prevIcon)}
151 |         nextIcon={extractValue(props.nextIcon)}
152 |       >
153 |         {renderChild(node.children)}
154 |       </CarouselComponent>
155 |     );
156 |   },
157 | );
158 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/FlowLayout/FlowLayoutNative.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import {
  2 |   type CSSProperties,
  3 |   type Dispatch,
  4 |   type ForwardedRef,
  5 |   forwardRef,
  6 |   type ReactNode,
  7 |   type SetStateAction,
  8 |   createContext,
  9 |   useContext,
 10 |   useMemo,
 11 |   useState,
 12 | } from "react";
 13 | import classnames from "classnames";
 14 | import { noop } from "lodash-es";
 15 | 
 16 | import styles from "./FlowLayout.module.scss";
 17 | 
 18 | import { useTheme } from "../../components-core/theming/ThemeContext";
 19 | import { normalizeCssValueForCalc, getSizeString } from "../../components-core/utils/css-utils";
 20 | import { useIsomorphicLayoutEffect, useMediaQuery } from "../../components-core/utils/hooks";
 21 | import { resolveLayoutProps } from "../../components-core/theming/layout-resolver";
 22 | import { useAppContext } from "../../components-core/AppContext";
 23 | 
 24 | type FlowItemProps = {
 25 |   children: ReactNode;
 26 |   width?: string | number;
 27 |   minWidth?: string | number;
 28 |   maxWidth?: string | number;
 29 |   forceBreak?: boolean;
 30 | };
 31 | 
 32 | const resolvedCssVars: Record<string, any> = {};
 33 | 
 34 | interface IFlowLayoutContext {
 35 |   rowGap: string | number;
 36 |   columnGap: string | number;
 37 |   setNumberOfChildren: Dispatch<SetStateAction<number>>;
 38 | }
 39 | 
 40 | const FlowLayoutContext = createContext<IFlowLayoutContext>({
 41 |   rowGap: 0,
 42 |   columnGap: 0,
 43 |   setNumberOfChildren: noop,
 44 | });
 45 | 
 46 | export const FlowItemBreak = ({ force }: { force?: boolean }) => (
 47 |   <div className={classnames(styles.break, { [styles.forceBreak]: force })} />
 48 | );
 49 | 
 50 | export const FlowItemWrapper = forwardRef(function FlowItemWrapper(
 51 |   { children, forceBreak, ...restProps }: FlowItemProps,
 52 |   ref: any,
 53 | ) {
 54 |   const { rowGap, columnGap, setNumberOfChildren } = useContext(FlowLayoutContext);
 55 |   const { mediaSize } = useAppContext();
 56 |   useIsomorphicLayoutEffect(() => {
 57 |     setNumberOfChildren((prev) => prev + 1);
 58 |     return () => {
 59 |       setNumberOfChildren((prev) => prev - 1);
 60 |     };
 61 |   }, [setNumberOfChildren]);
 62 |   const { root } = useTheme();
 63 |   const _width = restProps.width || "100%";
 64 |   const _minWidth = restProps.minWidth || undefined;
 65 |   const _maxWidth = restProps.maxWidth || undefined;
 66 | 
 67 |   const {
 68 |     width = _width,
 69 |     minWidth,
 70 |     maxWidth,
 71 |     flex,
 72 |   } = useMemo(() => {
 73 |     return (
 74 |       // --- New layout resolution
 75 |       resolveLayoutProps(
 76 |         { width: _width, maxWidth: _maxWidth, minWidth: _minWidth },
 77 |         {
 78 |           type: "Stack",
 79 |           orientation: "horizontal",
 80 |         },
 81 |       ).cssProps || {}
 82 | 
 83 |       // --- Old layout resolution
 84 |       // compileLayout(
 85 |       //   { width: _width, maxWidth: _maxWidth, minWidth: _minWidth },
 86 |       //   activeTheme.themeVars,
 87 |       //   {
 88 |       //     type: "Stack",
 89 |       //     orientation: "horizontal",
 90 |       //   },
 91 |       // ).cssProps || {}
 92 |     );
 93 |   }, [_maxWidth, _minWidth, _width]);
 94 | 
 95 |   const resolvedWidth = useMemo(() => {
 96 |     if (width && typeof width === "string" && width.startsWith("var(")) {
 97 |       if (!resolvedCssVars[width]) {
 98 |         const varName = width.substring(4, width.length - 1);
 99 |         const resolved = getComputedStyle(root || document.body).getPropertyValue(varName);
100 |         resolvedCssVars[width] = resolved || _width;
101 |       }
102 |       return resolvedCssVars[width];
103 |     }
104 |     return width || _width;
105 |   }, [_width, root, width]);
106 | 
107 |   const isWidthPercentage = typeof resolvedWidth === "string" && resolvedWidth.endsWith("%");
108 | 
109 |   const _columnGap = normalizeCssValueForCalc(columnGap);
110 | 
111 |   let responsiveWidth;
112 |   if(isWidthPercentage){
113 |     const percNumber = parseFloat(resolvedWidth);
114 |     if(mediaSize.sizeIndex <= 1){
115 |       let percentage = percNumber * 4;
116 |       if(percentage > 50){
117 |         responsiveWidth = `100%`
118 |       } else {
119 |         responsiveWidth = `min(${percentage}%, 100%)`
120 |       }
121 |     } else if(mediaSize.sizeIndex <= 2){
122 |       let percentage = percNumber * 3;
123 |       if(percentage >= 50 && percentage <= 75){
124 |         responsiveWidth = `50%`
125 |       } else if(percentage > 75){
126 |         responsiveWidth = `100%`
127 |       } else {
128 |         responsiveWidth = `min(${percentage}%, 100%)`
129 |       }
130 |     } else {
131 |       responsiveWidth = `min(${width}, 100%)`;
132 |     }
133 |   } else {
134 |     responsiveWidth = `min(calc(${width} + ${_columnGap}), 100%)`;
135 |   }
136 | 
137 |   const outerWrapperStyle: CSSProperties = {
138 |     minWidth,
139 |     maxWidth,
140 |     width: responsiveWidth,
141 |     paddingBottom: rowGap,
142 |     flex,
143 |   };
144 | 
145 |   const isStarSizing = flex !== undefined;
146 |   if (isStarSizing) {
147 |     //star sizing
148 |     outerWrapperStyle.width = "100%";
149 |     outerWrapperStyle.minWidth = minWidth || "1px";
150 |   }
151 |   return (
152 |     <>
153 |       <div
154 |         style={{ ...outerWrapperStyle, paddingRight: _columnGap }}
155 |         className={classnames(styles.flowItem, {
156 |           [styles.starSized]: isStarSizing,
157 |         })}
158 |         ref={ref}
159 |       >
160 |         {children}
161 |       </div>
162 |       {isStarSizing && <FlowItemBreak />}
163 |     </>
164 |   );
165 | });
166 | 
167 | type FlowLayoutProps = {
168 |   style?: CSSProperties;
169 |   className?: string;
170 |   columnGap: string | number;
171 |   rowGap: string | number;
172 |   children: ReactNode;
173 | };
174 | 
175 | export const defaultProps: Pick<FlowLayoutProps, "columnGap" | "rowGap"> = {
176 |   columnGap: "$gap-normal",
177 |   rowGap: "$gap-normal",
178 | };
179 | 
180 | export const FlowLayout = forwardRef(function FlowLayout(
181 |   { style, className, columnGap = 0, rowGap = 0, children, ...rest }: FlowLayoutProps,
182 |   forwardedRef: ForwardedRef<HTMLDivElement>,
183 | ) {
184 |   const [numberOfChildren, setNumberOfChildren] = useState(0);
185 |   const safeColumnGap = numberOfChildren === 1 ? 0 : columnGap;
186 | 
187 |   // --- Be smart about rowGap
188 |   const _rowGap = getSizeString(rowGap);
189 |   const _columnGap = getSizeString(safeColumnGap);
190 | 
191 |   const innerStyle = useMemo(
192 |     () => ({
193 |       // We put a negative margin on the container to fill the space for the row's last columnGap
194 |       marginRight: `calc(-1 * ${_columnGap})`,
195 |       marginBottom: `calc(-1 * ${_rowGap})`,
196 |     }),
197 |     [_columnGap, _rowGap],
198 |   );
199 | 
200 |   const flowLayoutContextValue = useMemo(() => {
201 |     return {
202 |       rowGap: _rowGap,
203 |       columnGap: _columnGap,
204 |       setNumberOfChildren,
205 |     };
206 |   }, [_columnGap, _rowGap]);
207 |   return (
208 |     <FlowLayoutContext.Provider value={flowLayoutContextValue}>
209 |       <div style={style} className={className} ref={forwardedRef} {...rest}>
210 |         <div className={styles.outer}>
211 |           <div className={classnames(styles.flowContainer, styles.horizontal)} style={innerStyle}>
212 |             {children}
213 |           </div>
214 |         </div>
215 |       </div>
216 |     </FlowLayoutContext.Provider>
217 |   );
218 | });
219 | 
```

--------------------------------------------------------------------------------
/packages/xmlui-devtools/src/devtools/ModalDialog.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import React, { type CSSProperties, type ReactNode, useEffect, useRef, useState } from "react";
  2 | import { composeRefs } from "@radix-ui/react-compose-refs";
  3 | import classnames from "classnames";
  4 | import * as Dialog from "@radix-ui/react-dialog";
  5 | 
  6 | import styles from "./ModalDialog.module.scss";
  7 | import { Button, Icon, useTheme } from "xmlui";
  8 | import { motion, AnimatePresence } from "framer-motion";
  9 | import { Tooltip } from "./Tooltip";
 10 | 
 11 | // =====================================================================================================================
 12 | // React component definition
 13 | 
 14 | type ModalProps = {
 15 |   style?: CSSProperties;
 16 |   className?: string;
 17 |   children?: ReactNode;
 18 |   isOpen: boolean;
 19 |   setIsOpen: (isOpen: boolean) => void;
 20 |   popupPlayground: () => void;
 21 |   clickPosition: { x: number; y: number };
 22 | };
 23 | 
 24 | const overlayVariants = {
 25 |   visible: { opacity: 1 },
 26 |   hidden: { opacity: 0 },
 27 | };
 28 | 
 29 | const contentVariants = {
 30 |   initial: (custom: { x: number; y: number }) => ({
 31 |     opacity: 0,
 32 |     scale: 0.2,
 33 |     x: custom.x - window.innerWidth / 2,
 34 |     y: custom.y - window.innerHeight / 2,
 35 |   }),
 36 |   animate: {
 37 |     opacity: 1,
 38 |     scale: 1,
 39 |     x: 0,
 40 |     y: 0,
 41 |   },
 42 |   exit: {
 43 |     opacity: 0,
 44 |     scale: 0.2,
 45 |     transition: { duration: 0.2 },
 46 |   },
 47 | };
 48 | 
 49 | function durationToSeconds(durationString?: string) {
 50 |   if (!durationString) {
 51 |     return undefined;
 52 |   }
 53 |   const trimmedString = durationString.trim();
 54 | 
 55 |   if (trimmedString.endsWith("ms")) {
 56 |     const milliseconds = parseFloat(trimmedString);
 57 |     return milliseconds / 1000;
 58 |   } else if (trimmedString.endsWith("s")) {
 59 |     return parseFloat(trimmedString);
 60 |   } else {
 61 |     return parseFloat(trimmedString);
 62 |   }
 63 | }
 64 | 
 65 | export const ModalDialog = React.forwardRef(
 66 |   ({ children, style, isOpen, setIsOpen, popupPlayground, clickPosition }: ModalProps, ref) => {
 67 |     const { root, getThemeVar } = useTheme();
 68 |     const modalRef = useRef<HTMLDivElement>(null);
 69 |     const composedRef = ref ? composeRefs(ref, modalRef) : modalRef;
 70 |     const [rendered, setRendered] = useState(true);
 71 | 
 72 |     useEffect(() => {
 73 |       if (isOpen) {
 74 |         modalRef.current?.focus();
 75 |       }
 76 |     }, [isOpen]);
 77 | 
 78 |     // https://github.com/radix-ui/primitives/issues/2122#issuecomment-2140827998
 79 |     useEffect(() => {
 80 |       if (isOpen) {
 81 |         // Pushing the change to the end of the call stack
 82 |         const timer = setTimeout(() => {
 83 |           document.body.style.pointerEvents = "";
 84 |         }, 0);
 85 | 
 86 |         return () => clearTimeout(timer);
 87 |       } else {
 88 |         document.body.style.pointerEvents = "auto";
 89 |       }
 90 |     }, [isOpen]);
 91 | 
 92 |     if (!root) {
 93 |       return null;
 94 |     }
 95 | 
 96 |     const onExitComplete = () => {
 97 |       setIsOpen(false);
 98 |     };
 99 | 
100 |     return (
101 |       <Dialog.Root defaultOpen={false} open={isOpen} onOpenChange={setRendered}>
102 |         <Dialog.Portal container={root}>
103 |           <AnimatePresence onExitComplete={onExitComplete}>
104 |             {rendered && (
105 |               <Dialog.Overlay className={styles.overlay} forceMount>
106 |                 <motion.div
107 |                   key="overlay"
108 |                   className={styles.overlayBg}
109 |                   variants={overlayVariants}
110 |                   initial="hidden"
111 |                   animate="visible"
112 |                   exit="hidden"
113 |                   transition={{
114 |                     duration: 0.2,
115 |                     ease: [0.16, 1, 0.3, 1],
116 |                   }}
117 |                 />
118 |                 <motion.div
119 |                   className={styles.contentWrapper}
120 |                   variants={contentVariants}
121 |                   custom={{ x: clickPosition.x, y: clickPosition.y }}
122 |                   initial="initial"
123 |                   animate="animate"
124 |                   exit="exit"
125 |                   transition={{
126 |                     duration:
127 |                       durationToSeconds(getThemeVar("duration-startAnimation-ModalDialog")) || 0.8,
128 |                     ease: [0.16, 1, 0.3, 1],
129 |                   }}
130 |                 >
131 |                   <Dialog.Content
132 |                     className={classnames(styles.content)}
133 |                     forceMount
134 |                     onPointerDownOutside={(event) => {
135 |                       if (
136 |                         event.target instanceof Element &&
137 |                         event.target.closest("._debug-inspect-button") !== null
138 |                       ) {
139 |                         //we prevent the auto modal close on clicking the inspect button
140 |                         event.preventDefault();
141 |                       }
142 |                     }}
143 |                     ref={composedRef}
144 |                     style={{ ...style, gap: undefined }}
145 |                   >
146 |                     <Dialog.Title style={{ marginTop: 0 }}>
147 |                       <header id="dialogTitle" className={styles.dialogTitle}>
148 |                         <div className={styles.header}>
149 |                           <Button variant={"ghost"} size={"sm"}>
150 |                             Code
151 |                           </Button>
152 |                           <div className={styles.actions}>
153 |                             <Tooltip label={"View and edit in new full-width window"}>
154 |                               <Button
155 |                                 onClick={popupPlayground}
156 |                                 size={"xs"}
157 |                                 variant={"ghost"}
158 |                                 icon={<Icon name={"new-window"} />}
159 |                               />
160 |                             </Tooltip>
161 |                             <Tooltip label={"Close DevTools"}>
162 |                               <Button
163 |                                 onClick={() => setRendered(false)}
164 |                                 size={"xs"}
165 |                                 variant={"ghost"}
166 |                                 icon={<Icon name={"close"} />}
167 |                               />
168 |                             </Tooltip>
169 |                           </div>
170 |                         </div>
171 |                       </header>
172 |                     </Dialog.Title>
173 |                     <div className={styles.innerContent} style={{ gap: style?.gap }}>
174 |                       {children}
175 |                     </div>
176 |                   </Dialog.Content>
177 |                 </motion.div>
178 |               </Dialog.Overlay>
179 |             )}
180 |           </AnimatePresence>
181 |         </Dialog.Portal>
182 |       </Dialog.Root>
183 |     );
184 |   },
185 | );
186 | 
187 | ModalDialog.displayName = "ModalDialog";
188 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components-core/rendering/ContainerWrapper.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import {
  2 |   forwardRef,
  3 |   memo,
  4 |   type MutableRefObject,
  5 |   type ReactNode,
  6 |   type RefObject,
  7 |   useMemo,
  8 | } from "react";
  9 | import type { ComponentDef, ParentRenderContext } from "../../abstractions/ComponentDefs";
 10 | import type { LayoutContext } from "../../abstractions/RendererDefs";
 11 | import type { ContainerDispatcher } from "../abstractions/ComponentRenderer";
 12 | import type { ProxyAction } from "../rendering/buildProxy";
 13 | import { ErrorBoundary } from "../rendering/ErrorBoundary";
 14 | import { StateContainer } from "./StateContainer";
 15 | 
 16 | /**
 17 |  * This type is the internal representation of a container component, which manages the state of its children.
 18 |  */
 19 | export interface ContainerWrapperDef extends ComponentDef {
 20 |   type: "Container";
 21 | 
 22 |   // --- The unique identifier of the container
 23 |   containerUid?: symbol;
 24 | 
 25 |   // --- The context values this container provides to its children
 26 |   contextVars?: Record<string, any>;
 27 | 
 28 |   // --- If true, this is an API-bound container
 29 |   apiBoundContainer?: boolean;
 30 | }
 31 | 
 32 | /**
 33 |  * We store the state application state in a hierarchical structure of
 34 |  * containers. This type represents the state within a single container
 35 |  * stored as key and value pairs.
 36 |  */
 37 | export type ContainerState = Record<string | symbol, any>;
 38 | 
 39 | /**
 40 |  * Components can provide an API that other components can invoke (using
 41 |  * the host component ID). This type defines the shape of a hash object that
 42 |  * stores the API endpoints.
 43 |  */
 44 | export type ComponentApi = Record<string, ((...args: any[]) => any) | boolean | number | string>;
 45 | 
 46 | /**
 47 |  * This type declares that function's signature, which registers an exposed
 48 |  * component method (API endpoint).
 49 |  */
 50 | export type RegisterComponentApiFnInner = (componentUid: symbol, api: ComponentApi) => void;
 51 | 
 52 | /**
 53 |  * This type declares that function's signature, which runs a clean-up activity.
 54 |  */
 55 | export type ComponentCleanupFn = (uid: symbol) => void;
 56 | 
 57 | /**
 58 |  * This function checks if a particular component needs a wrapping container to
 59 |  * manage its internal state, which is closed from its external context but
 60 |  * available to its children.
 61 |  * @param node The component definition node to check
 62 |  * @returns Tru, if the component needs a wrapping container
 63 |  */
 64 | export function isContainerLike(node: ComponentDef) {
 65 |   if (node.type === "Container") {
 66 |     return true;
 67 |   }
 68 | 
 69 |   // --- If any of the following properties have a value, we need a container
 70 |   return !!(
 71 |     node.loaders ||
 72 |     node.vars ||
 73 |     node.uses ||
 74 |     node.contextVars ||
 75 |     node.functions ||
 76 |     node.scriptCollected
 77 |   );
 78 | }
 79 | 
 80 | /**
 81 |  * This type is that function's signature, which signs that an entire
 82 |  * state variable or its nested part has been changed.
 83 |  */
 84 | export type StatePartChangedFn = (
 85 |   // --- String representing the component path ("a.b", "a.b[3].c", etc.)
 86 |   path: string[],
 87 | 
 88 |   // --- The new value of the changed part
 89 |   value: any,
 90 | 
 91 |   // --- The target component that has changed (along the path)
 92 |   target: string,
 93 | 
 94 |   // --- Type of change
 95 |   action: ProxyAction,
 96 | ) => void;
 97 | 
 98 | // --- Properties of the ComponentContainer component
 99 | type Props = {
100 |   node: ContainerWrapperDef;
101 |   resolvedKey?: string;
102 |   parentState: ContainerState;
103 |   parentStatePartChanged: StatePartChangedFn;
104 |   parentRegisterComponentApi: RegisterComponentApiFnInner;
105 |   parentDispatch: ContainerDispatcher;
106 |   parentRenderContext?: ParentRenderContext;
107 |   layoutContextRef: MutableRefObject<LayoutContext | undefined>;
108 |   uidInfoRef?: RefObject<Record<string, any>>;
109 |   children?: ReactNode;
110 | };
111 | 
112 | /**
113 |  * This component is a container that manages the state of its children. It
114 |  * provides a context for the children to access the state and the API of the
115 |  * parent component.
116 |  */
117 | export const ContainerWrapper = memo(
118 |   forwardRef(function ContainerWrapper(
119 |     {
120 |       node,
121 |       resolvedKey,
122 |       parentState,
123 |       parentStatePartChanged,
124 |       parentRegisterComponentApi,
125 |       parentDispatch,
126 |       parentRenderContext,
127 |       layoutContextRef,
128 |       uidInfoRef,
129 |       children,
130 |       ...rest
131 |     }: Props,
132 |     ref,
133 |   ) {
134 |     // --- Make sure the component node is wrapped with a container
135 |     const containerizedNode = useMemo(() => getWrappedWithContainer(node), [node]);
136 | 
137 |     return (
138 |       <ErrorBoundary node={node} location={"container"}>
139 |         <StateContainer
140 |           node={containerizedNode as any}
141 |           resolvedKey={resolvedKey}
142 |           parentState={parentState}
143 |           parentStatePartChanged={parentStatePartChanged}
144 |           parentRegisterComponentApi={parentRegisterComponentApi}
145 |           parentDispatch={parentDispatch}
146 |           parentRenderContext={parentRenderContext}
147 |           layoutContextRef={layoutContextRef}
148 |           uidInfoRef={uidInfoRef}
149 |           isImplicit={node.type !== "Container" && containerizedNode.uses === undefined} //in this case it's an auto-wrapped component
150 |           ref={ref}
151 |           {...rest}
152 |         >
153 |           {children}
154 |         </StateContainer>
155 |       </ErrorBoundary>
156 |     );
157 |   }),
158 | );
159 | 
160 | /**
161 |  * Wraps the specified component node with a container
162 |  * @param node The component node to wrap
163 |  * @returns A "Container" node
164 |  */
165 | const getWrappedWithContainer = (node: ContainerWrapperDef) => {
166 |   if (node.type === "Container") {
167 |     // --- Already wrapped
168 |     return node;
169 |   }
170 | 
171 |   // --- Clone the node and remove the properties that will be moved to the container
172 |   // --- Note: we need the "when" property in the ModalDialog component, so we don't remove it
173 |   const wrappedNode = { ...node, props: { ...node.props } };
174 |   delete wrappedNode.loaders;
175 |   delete wrappedNode.vars;
176 |   delete wrappedNode.functions;
177 |   delete wrappedNode.script;
178 |   delete wrappedNode.scriptCollected;
179 |   delete wrappedNode.scriptError;
180 |   delete wrappedNode.uses;
181 |   delete (wrappedNode.props as any)?.uses;
182 |   delete wrappedNode.api;
183 |   delete wrappedNode.contextVars;
184 | 
185 |   // --- Do the wrapping
186 |   return {
187 |     type: "Container",
188 |     uid: node.uid,
189 |     when: node.when,
190 |     loaders: node.loaders,
191 |     vars: node.vars,
192 |     functions: node.functions,
193 |     scriptCollected: node.scriptCollected,
194 |     scriptError: node.scriptError,
195 |     uses: node.uses,
196 |     api: node.api,
197 |     containerUid: node?.containerUid,
198 |     apiBoundContainer: node?.apiBoundContainer,
199 |     contextVars: node.contextVars,
200 |     props: {
201 |       debug: (node.props as any)?.debug,
202 |     },
203 |     children: [wrappedNode],
204 |   } as ContainerWrapperDef;
205 | };
206 | 
```

--------------------------------------------------------------------------------
/xmlui/src/language-server/server-common.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import type {
  2 |   Connection,
  3 |   InitializeParams,
  4 |   TextDocumentPositionParams,
  5 |   InitializeResult,
  6 |   HoverParams,
  7 |   TextDocumentContentChangeEvent,
  8 |   TextDocumentChangeEvent,
  9 |   Diagnostic,
 10 |   Position,
 11 |   DocumentFormattingParams,
 12 | } from "vscode-languageserver";
 13 | import {
 14 |   MarkupKind,
 15 |   TextDocumentSyncKind,
 16 |   DidChangeConfigurationNotification,
 17 |   TextDocuments,
 18 | } from "vscode-languageserver";
 19 | import { TextDocument } from "vscode-languageserver-textdocument";
 20 | import collectedComponentMetadata from "./xmlui-metadata-generated.js";
 21 | import type { XmluiCompletionItem } from "./services/completion";
 22 | import { handleCompletion, handleCompletionResolve } from "./services/completion";
 23 | import { handleHover } from "./services/hover";
 24 | import { handleDocumentFormatting } from "./services/format";
 25 | import {
 26 |   createXmlUiParser,
 27 |   Error,
 28 |   type GetText,
 29 |   type ParseResult,
 30 | } from "../parsers/xmlui-parser/parser";
 31 | import {
 32 |   MetadataProvider,
 33 |   type ComponentMetadataCollection,
 34 | } from "./services/common/metadata-utils";
 35 | import { getDiagnostics } from "./services/diagnostic";
 36 | 
 37 | const metaByComp = collectedComponentMetadata as ComponentMetadataCollection;
 38 | const metadataProvider = new MetadataProvider(metaByComp);
 39 | 
 40 | export function start(connection: Connection) {
 41 |   // Also include all preview / proposed LSP features.
 42 |   // Create a simple text document manager.
 43 |   const documents = new TextDocuments(TextDocument);
 44 | 
 45 |   let hasConfigurationCapability = false;
 46 |   let hasWorkspaceFolderCapability = false;
 47 |   let hasDiagnosticRelatedInformationCapability = false;
 48 | 
 49 |   connection.onInitialize((params: InitializeParams) => {
 50 |     connection.console.log("Initializing!");
 51 |     const capabilities = params.capabilities;
 52 | 
 53 |     // Does the client support the `workspace/configuration` request?
 54 |     // If not, we fall back using global settings.
 55 |     hasConfigurationCapability = !!(
 56 |       capabilities.workspace && !!capabilities.workspace.configuration
 57 |     );
 58 |     hasWorkspaceFolderCapability = !!(
 59 |       capabilities.workspace && !!capabilities.workspace.workspaceFolders
 60 |     );
 61 |     hasDiagnosticRelatedInformationCapability = !!(
 62 |       capabilities.textDocument &&
 63 |       capabilities.textDocument.publishDiagnostics &&
 64 |       capabilities.textDocument.publishDiagnostics.relatedInformation
 65 |     );
 66 | 
 67 |     const result: InitializeResult = {
 68 |       capabilities: {
 69 |         textDocumentSync: TextDocumentSyncKind.Incremental,
 70 |         completionProvider: {
 71 |           resolveProvider: true,
 72 |           triggerCharacters: ["<", "/"],
 73 |         },
 74 |         hoverProvider: true,
 75 |         documentFormattingProvider: true,
 76 |       },
 77 |     };
 78 |     if (hasWorkspaceFolderCapability) {
 79 |       result.capabilities.workspace = {
 80 |         workspaceFolders: {
 81 |           supported: true,
 82 |         },
 83 |       };
 84 |     }
 85 |     return result;
 86 |   });
 87 | 
 88 |   connection.onInitialized(() => {
 89 |     if (hasConfigurationCapability) {
 90 |       // Register for all configuration changes.
 91 |       void connection.client.register(DidChangeConfigurationNotification.type, undefined);
 92 |     }
 93 |     if (hasWorkspaceFolderCapability) {
 94 |       connection.workspace.onDidChangeWorkspaceFolders((_event) => {
 95 |         connection.console.log("Workspace folder change event received.");
 96 |       });
 97 |     }
 98 |   });
 99 | 
100 |   connection.onCompletion(({ position, textDocument }: TextDocumentPositionParams) => {
101 |     const document = documents.get(textDocument.uri);
102 |     if (!document) {
103 |       return [];
104 |     }
105 |     const parseResult = parseDocument(document);
106 |     return handleCompletion(
107 |       {
108 |         parseResult: parseResult.parseResult,
109 |         getText: parseResult.getText,
110 |         metaByComp: metadataProvider,
111 |         offsetToPos: (offset: number) => document.positionAt(offset),
112 |       },
113 |       document.offsetAt(position),
114 |     );
115 |   });
116 | 
117 |   connection.onCompletionResolve((completionItem: XmluiCompletionItem) => {
118 |     return handleCompletionResolve({ metaByComp: metadataProvider, item: completionItem });
119 |   });
120 | 
121 |   connection.onHover(({ position, textDocument }: HoverParams) => {
122 |     const document = documents.get(textDocument.uri);
123 |     if (!document) {
124 |       return null;
125 |     }
126 | 
127 |     const { parseResult, getText } = parseDocument(document);
128 |     const ctx = {
129 |       node: parseResult.node,
130 |       getText,
131 |       metaByComp: metadataProvider,
132 |       offsetToPosition: (offset: number) => document.positionAt(offset),
133 |     };
134 |     return handleHover(ctx, document.offsetAt(position));
135 |   });
136 | 
137 |   connection.onDocumentFormatting(({ textDocument, options }: DocumentFormattingParams) => {
138 |     const document = documents.get(textDocument.uri);
139 |     if (!document) {
140 |       return null;
141 |     }
142 |     const {
143 |       parseResult: { node },
144 |       getText,
145 |     } = parseDocument(document);
146 |     return handleDocumentFormatting({
147 |       node,
148 |       getText,
149 |       options,
150 |       offsetToPosition: (offset) => document.positionAt(offset),
151 |     });
152 |   });
153 | 
154 |   const parsedDocuments = new Map();
155 |   function parseDocument(document: TextDocument): {
156 |     parseResult: ParseResult;
157 |     getText: GetText;
158 |   } {
159 |     const parseForDoc = parsedDocuments.get(document.uri);
160 |     if (parseForDoc !== undefined) {
161 |       if (parseForDoc.version === document.version) {
162 |         return {
163 |           parseResult: parseForDoc.parseResult,
164 |           getText: parseForDoc.getText,
165 |         };
166 |       }
167 |     }
168 |     const parser = createXmlUiParser(document.getText());
169 |     const parseResult = parser.parse();
170 |     parsedDocuments.set(document.uri, {
171 |       parseResult,
172 |       version: document.version,
173 |       getText: parser.getText,
174 |     });
175 |     return { parseResult, getText: parser.getText };
176 |   }
177 |   documents.onDidClose(({ document }) => {
178 |     parsedDocuments.delete(document.uri);
179 |   });
180 | 
181 |   documents.onDidChangeContent(handleDocunentContentChange);
182 | 
183 |   function handleDocunentContentChange({ document }: { document: TextDocument }) {
184 |     const { parseResult } = parseDocument(document);
185 |     const ctx = {
186 |       parseResult,
187 |       offsetToPos: (offset: number) => document.positionAt(offset),
188 |     };
189 | 
190 |     const diagnostics = getDiagnostics(ctx);
191 |     void connection.sendDiagnostics({
192 |       version: document.version,
193 |       uri: document.uri,
194 |       diagnostics,
195 |     });
196 |   }
197 | 
198 |   // Make the text document manager listen on the connection
199 |   // for open, change and close text document events
200 |   documents.listen(connection);
201 | 
202 |   // Listen on the connection
203 |   console.log("starting to listen");
204 |   connection.listen();
205 | }
206 | 
```

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

```typescript
  1 | import { SKIP_REASON } from "../../testing/component-test-helpers";
  2 | import { expect, test } from "../../testing/fixtures";
  3 | import { getFullRectangle } from "../../testing/themed-app-test-helpers";
  4 | 
  5 | test.describe("Basic Functionality", () => {
  6 |   test("component renders with basic props", async ({ page, initTestBed }) => {
  7 |     await initTestBed(`<Spinner />`);
  8 | 
  9 |     const spinner = page.getByRole("status");
 10 |     await expect(spinner).toBeVisible();
 11 |   });
 12 | 
 13 |   test("component renders with delay prop", async ({ page, initTestBed }) => {
 14 |     await initTestBed(`<Spinner delay="0" />`);
 15 | 
 16 |     const spinner = page.getByRole("status");
 17 |     await expect(spinner).toBeVisible();
 18 |   });
 19 | 
 20 |   test("component renders with fullScreen prop", async ({ page, initTestBed }) => {
 21 |     await initTestBed(`<Spinner fullScreen="true" />`);
 22 | 
 23 |     const spinner = page.getByRole("status");
 24 |     await expect(spinner).toBeVisible();
 25 |   });
 26 | });
 27 | 
 28 | test.describe("Accessibility", () => {
 29 |   test("component has correct accessibility attributes", async ({ page, initTestBed }) => {
 30 |     await initTestBed(`<Spinner />`);
 31 | 
 32 |     const spinner = page.getByRole("status");
 33 |     await expect(spinner).toHaveAttribute("aria-label", "loading", { ignoreCase: true });
 34 |   });
 35 | 
 36 |   test("component maintains accessibility with fullScreen", async ({ page, initTestBed }) => {
 37 |     await initTestBed(`<Spinner fullScreen="true" />`);
 38 | 
 39 |     const spinner = page.getByRole("status");
 40 |     await expect(spinner).toHaveAttribute("aria-label", "loading", { ignoreCase: true });
 41 |   });
 42 | });
 43 | 
 44 | test.describe("Theme Variables", () => {
 45 |   test("component applies theme variables", async ({ page, initTestBed }) => {
 46 |     await initTestBed(`<Spinner delay="0" />`, {
 47 |       testThemeVars: {
 48 |         "size-Spinner": "60px",
 49 |         "thickness-Spinner": "6px",
 50 |         "borderColor-Spinner": "rgb(255, 0, 0)",
 51 |       },
 52 |     });
 53 | 
 54 |     const spinnerRing = page.locator("[data-part-id='ring']").first();
 55 | 
 56 |     await expect(spinnerRing).toHaveCSS("border-top-color", "rgb(255, 0, 0)");
 57 |   });
 58 | });
 59 | 
 60 | test.describe("Delay Behavior", () => {
 61 |   test("component respects delay prop", { tag: "@smoke" }, async ({ page, initTestBed }) => {
 62 |     await initTestBed(`
 63 |       <Fragment>
 64 |         control-text
 65 |         <Spinner delay="500" />
 66 |       </Fragment>`);
 67 | 
 68 |     await page.getByText("control-text").waitFor({ state: "visible" });
 69 |     const spinner = page.getByRole("status");
 70 |     await expect(spinner).not.toBeVisible({ timeout: 0 });
 71 | 
 72 |     await expect(spinner).toBeVisible();
 73 |   });
 74 | 
 75 |   test("component shows immediately with zero delay", async ({ page, initTestBed }) => {
 76 |     await initTestBed(`
 77 |       <Fragment>
 78 |         control-text
 79 |         <Spinner delay="0" />
 80 |       </Fragment>`);
 81 | 
 82 |     await page.getByText("control-text").waitFor({ state: "visible" });
 83 |     const spinner = page.getByRole("status");
 84 |     await expect(spinner).toBeVisible({ timeout: 0 });
 85 |   });
 86 | 
 87 |   test("component shows immediately with null delay", async ({ page, initTestBed }) => {
 88 |     await initTestBed(`
 89 |       <Fragment>
 90 |         control-text
 91 |         <Spinner delay="{null}" />
 92 |       </Fragment>`);
 93 | 
 94 |     await page.getByText("control-text").waitFor({ state: "visible" });
 95 |     const spinner = page.getByRole("status");
 96 |     await expect(spinner).toBeVisible({ timeout: 0 });
 97 |   });
 98 | 
 99 |   test("component shows immediately with undefined delay", async ({ page, initTestBed }) => {
100 |     await initTestBed(`
101 |       <Fragment>
102 |         control-text
103 |         <Spinner delay="{undefined}" />
104 |       </Fragment>`);
105 | 
106 |     await page.getByText("control-text").waitFor({ state: "visible" });
107 |     const spinner = page.getByRole("status");
108 |     await expect(spinner).toBeVisible({ timeout: 0 });
109 |   });
110 | 
111 |   test("component handles negative delay values", async ({ page, initTestBed }) => {
112 |     await initTestBed(`
113 |       <Fragment>
114 |         control-text
115 |         <Spinner delay="-100" />
116 |       </Fragment>`);
117 | 
118 |     await page.getByText("control-text").waitFor({ state: "visible" });
119 |     const spinner = page.getByRole("status");
120 |     await expect(spinner).toBeVisible({ timeout: 0 });
121 |   });
122 | 
123 |   test("component respects numeric delay prop", async ({ page, initTestBed }) => {
124 |     await initTestBed(`
125 |       <Fragment>
126 |         control-text
127 |         <Spinner delay="{ 500 }" />
128 |       </Fragment>`);
129 | 
130 |     await page.getByText("control-text").waitFor({ state: "visible" });
131 |     const spinner = page.getByRole("status");
132 |     await expect(spinner).not.toBeVisible({ timeout: 0 });
133 | 
134 |     await expect(spinner).toBeVisible();
135 |   });
136 | });
137 | 
138 | test.describe("Full Screen Mode", () => {
139 |   test("component renders in fullScreen mode", async ({ page, initTestBed }) => {
140 |     await initTestBed(`<Spinner fullScreen="true" />`);
141 |     const spinner = page.getByRole("status");
142 |     await expect(spinner).toBeVisible();
143 | 
144 |     const { width } = await getFullRectangle(spinner);
145 |     expect(width).toEqual(page.viewportSize().width);
146 |   });
147 | 
148 |   test("component renders normally without fullScreen", async ({ page, initTestBed }) => {
149 |     await initTestBed(`<Spinner fullScreen="false" />`);
150 | 
151 |     const spinner = page.getByRole("status");
152 |     await expect(spinner).toBeVisible();
153 | 
154 |     const { width } = await getFullRectangle(spinner);
155 |     expect(width).not.toEqual(page.viewportSize().width);
156 |   });
157 | });
158 | 
159 | test.describe("Edge Cases", { tag: "@smoke" }, () => {
160 |   test("delayed fullScreen spinner spans viewport width", async ({ page, initTestBed }) => {
161 |     await initTestBed(`
162 |       <Fragment>
163 |         control-text
164 |         <Spinner fullScreen="true" delay="{ 500 }" />
165 |       </Fragment>`);
166 | 
167 |     await page.getByText("control-text").waitFor({ state: "visible" });
168 |     const spinner = page.getByRole("status");
169 |     await expect(spinner).not.toBeVisible({ timeout: 0 });
170 | 
171 |     await expect(spinner).toBeVisible();
172 | 
173 |     const { width } = await getFullRectangle(spinner);
174 |     expect(width).toEqual(page.viewportSize().width);
175 |   });
176 | 
177 |   test("button behind fullScreen spinner can't be clicked", async ({ page, initTestBed }) => {
178 |     const { testStateDriver } = await initTestBed(`
179 |       <Fragment>
180 |         <Button label="Click Me" onClick="testState = clicked" />
181 |         <Spinner fullScreen="true" />
182 |       </Fragment>`);
183 | 
184 |     const spinner = page.getByRole("status");
185 |     await expect(spinner).toBeVisible();
186 | 
187 |     await page.getByRole("button").click({ force: true });
188 | 
189 |     await expect.poll(testStateDriver.testState).not.toEqual("clicked");
190 |   });
191 | });
192 | 
```
Page 35/188FirstPrevNextLast