This is page 98 of 186. Use http://codebase.md/xmlui-org/xmlui/tools/vscode/resources/assets/img/bg-iphone-14-pro.jpg?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .changeset
│   └── config.json
├── .eslintrc.cjs
├── .github
│   ├── build-checklist.png
│   ├── ISSUE_TEMPLATE
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   └── workflows
│       ├── deploy-blog-optimized.yml
│       ├── deploy-blog-swa.yml
│       ├── deploy-blog.yml
│       ├── deploy-docs-optimized.yml
│       ├── deploy-docs.yml
│       ├── prepare-versions.yml
│       ├── release-packages.yml
│       ├── run-all-tests.yml
│       └── run-smoke-tests.yml
├── .gitignore
├── .prettierrc.js
├── .vscode
│   ├── launch.json
│   └── settings.json
├── blog
│   ├── .gitignore
│   ├── .gitkeep
│   ├── CHANGELOG.md
│   ├── extensions.ts
│   ├── index.html
│   ├── index.ts
│   ├── package.json
│   ├── public
│   │   ├── blog
│   │   │   ├── images
│   │   │   │   ├── an-advanced-codefence.gif
│   │   │   │   ├── an-advanced-codefence.mp4
│   │   │   │   ├── blog-page-component.png
│   │   │   │   ├── blog-scrabble.png
│   │   │   │   ├── codefence-runner.png
│   │   │   │   ├── integrated-blog-search.png
│   │   │   │   ├── lorem-ipsum.png
│   │   │   │   ├── playground-checkbox-source.png
│   │   │   │   ├── playground.png
│   │   │   │   ├── use-xmlui-mcp-to-find-a-howto.png
│   │   │   │   └── xmlui-demo-gallery.png
│   │   │   ├── introducing-xmlui.md
│   │   │   ├── lorem-ipsum.md
│   │   │   ├── newest-post.md
│   │   │   ├── older-post.md
│   │   │   ├── xmlui-playground.md
│   │   │   └── xmlui-powered-blog.md
│   │   ├── mockServiceWorker.js
│   │   ├── resources
│   │   │   ├── favicon.ico
│   │   │   ├── files
│   │   │   │   └── for-download
│   │   │   │       └── xmlui
│   │   │   │           └── xmlui-standalone.umd.js
│   │   │   ├── github.svg
│   │   │   ├── llms.txt
│   │   │   ├── logo-dark.svg
│   │   │   ├── logo.svg
│   │   │   ├── pg-popout.svg
│   │   │   ├── rss.svg
│   │   │   └── xmlui-logo.svg
│   │   ├── serve.json
│   │   ├── staticwebapp.config.json
│   │   └── web.config
│   ├── scripts
│   │   ├── download-latest-xmlui.js
│   │   ├── generate-rss.js
│   │   ├── get-releases.js
│   │   └── utils.js
│   ├── src
│   │   ├── components
│   │   │   ├── BlogOverview.xmlui
│   │   │   ├── BlogPage.xmlui
│   │   │   └── PageNotFound.xmlui
│   │   ├── config.ts
│   │   ├── Main.xmlui
│   │   └── themes
│   │       └── blog-theme.ts
│   └── tsconfig.json
├── CONTRIBUTING.md
├── docs
│   ├── .gitignore
│   ├── CHANGELOG.md
│   ├── ComponentRefLinks.txt
│   ├── content
│   │   ├── _meta.json
│   │   ├── components
│   │   │   ├── _meta.json
│   │   │   ├── _overview.md
│   │   │   ├── APICall.md
│   │   │   ├── App.md
│   │   │   ├── AppHeader.md
│   │   │   ├── AppState.md
│   │   │   ├── AutoComplete.md
│   │   │   ├── Avatar.md
│   │   │   ├── Backdrop.md
│   │   │   ├── Badge.md
│   │   │   ├── BarChart.md
│   │   │   ├── Bookmark.md
│   │   │   ├── Breakout.md
│   │   │   ├── Button.md
│   │   │   ├── Card.md
│   │   │   ├── Carousel.md
│   │   │   ├── ChangeListener.md
│   │   │   ├── Checkbox.md
│   │   │   ├── CHStack.md
│   │   │   ├── ColorPicker.md
│   │   │   ├── Column.md
│   │   │   ├── ContentSeparator.md
│   │   │   ├── CVStack.md
│   │   │   ├── DataSource.md
│   │   │   ├── DateInput.md
│   │   │   ├── DatePicker.md
│   │   │   ├── DonutChart.md
│   │   │   ├── DropdownMenu.md
│   │   │   ├── EmojiSelector.md
│   │   │   ├── ExpandableItem.md
│   │   │   ├── FileInput.md
│   │   │   ├── FileUploadDropZone.md
│   │   │   ├── FlowLayout.md
│   │   │   ├── Footer.md
│   │   │   ├── Form.md
│   │   │   ├── FormItem.md
│   │   │   ├── FormSection.md
│   │   │   ├── Fragment.md
│   │   │   ├── H1.md
│   │   │   ├── H2.md
│   │   │   ├── H3.md
│   │   │   ├── H4.md
│   │   │   ├── H5.md
│   │   │   ├── H6.md
│   │   │   ├── Heading.md
│   │   │   ├── HSplitter.md
│   │   │   ├── HStack.md
│   │   │   ├── Icon.md
│   │   │   ├── IFrame.md
│   │   │   ├── Image.md
│   │   │   ├── Items.md
│   │   │   ├── LabelList.md
│   │   │   ├── Legend.md
│   │   │   ├── LineChart.md
│   │   │   ├── Link.md
│   │   │   ├── List.md
│   │   │   ├── Logo.md
│   │   │   ├── Markdown.md
│   │   │   ├── MenuItem.md
│   │   │   ├── MenuSeparator.md
│   │   │   ├── ModalDialog.md
│   │   │   ├── NavGroup.md
│   │   │   ├── NavLink.md
│   │   │   ├── NavPanel.md
│   │   │   ├── NoResult.md
│   │   │   ├── NumberBox.md
│   │   │   ├── Option.md
│   │   │   ├── Page.md
│   │   │   ├── PageMetaTitle.md
│   │   │   ├── Pages.md
│   │   │   ├── Pagination.md
│   │   │   ├── PasswordInput.md
│   │   │   ├── PieChart.md
│   │   │   ├── ProgressBar.md
│   │   │   ├── Queue.md
│   │   │   ├── RadioGroup.md
│   │   │   ├── RealTimeAdapter.md
│   │   │   ├── Redirect.md
│   │   │   ├── Select.md
│   │   │   ├── Slider.md
│   │   │   ├── Slot.md
│   │   │   ├── SpaceFiller.md
│   │   │   ├── Spinner.md
│   │   │   ├── Splitter.md
│   │   │   ├── Stack.md
│   │   │   ├── StickyBox.md
│   │   │   ├── SubMenuItem.md
│   │   │   ├── Switch.md
│   │   │   ├── TabItem.md
│   │   │   ├── Table.md
│   │   │   ├── TableOfContents.md
│   │   │   ├── Tabs.md
│   │   │   ├── Text.md
│   │   │   ├── TextArea.md
│   │   │   ├── TextBox.md
│   │   │   ├── Theme.md
│   │   │   ├── TimeInput.md
│   │   │   ├── Timer.md
│   │   │   ├── ToneChangerButton.md
│   │   │   ├── ToneSwitch.md
│   │   │   ├── Tooltip.md
│   │   │   ├── Tree.md
│   │   │   ├── VSplitter.md
│   │   │   ├── VStack.md
│   │   │   ├── xmlui-animations
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   ├── Animation.md
│   │   │   │   ├── FadeAnimation.md
│   │   │   │   ├── FadeInAnimation.md
│   │   │   │   ├── FadeOutAnimation.md
│   │   │   │   ├── ScaleAnimation.md
│   │   │   │   └── SlideInAnimation.md
│   │   │   ├── xmlui-pdf
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   └── Pdf.md
│   │   │   ├── xmlui-spreadsheet
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   └── Spreadsheet.md
│   │   │   └── xmlui-website-blocks
│   │   │       ├── _meta.json
│   │   │       ├── _overview.md
│   │   │       ├── Carousel.md
│   │   │       ├── HelloMd.md
│   │   │       ├── HeroSection.md
│   │   │       └── ScrollToTop.md
│   │   └── extensions
│   │       ├── _meta.json
│   │       ├── xmlui-animations
│   │       │   ├── _meta.json
│   │       │   ├── _overview.md
│   │       │   ├── Animation.md
│   │       │   ├── FadeAnimation.md
│   │       │   ├── FadeInAnimation.md
│   │       │   ├── FadeOutAnimation.md
│   │       │   ├── ScaleAnimation.md
│   │       │   └── SlideInAnimation.md
│   │       └── xmlui-website-blocks
│   │           ├── _meta.json
│   │           ├── _overview.md
│   │           ├── Carousel.md
│   │           ├── FancyButton.md
│   │           ├── HeroSection.md
│   │           └── ScrollToTop.md
│   ├── extensions.ts
│   ├── index.html
│   ├── index.ts
│   ├── package.json
│   ├── public
│   │   ├── feed.rss
│   │   ├── mockServiceWorker.js
│   │   ├── pages
│   │   │   ├── _meta.json
│   │   │   ├── app-structure.md
│   │   │   ├── build-editor-component.md
│   │   │   ├── build-hello-world-component.md
│   │   │   ├── components-intro.md
│   │   │   ├── context-variables.md
│   │   │   ├── forms.md
│   │   │   ├── globals.md
│   │   │   ├── glossary.md
│   │   │   ├── helper-tags.md
│   │   │   ├── hosted-deployment.md
│   │   │   ├── howto
│   │   │   │   ├── assign-a-complex-json-literal-to-a-component-variable.md
│   │   │   │   ├── chain-a-refetch.md
│   │   │   │   ├── control-cache-invalidation.md
│   │   │   │   ├── debounce-user-input-for-api-calls.md
│   │   │   │   ├── debounce-with-changelistener.md
│   │   │   │   ├── debug-a-component.md
│   │   │   │   ├── delay-a-datasource-until-another-datasource-is-ready.md
│   │   │   │   ├── delegate-a-method.md
│   │   │   │   ├── do-custom-form-validation.md
│   │   │   │   ├── expose-a-method-from-a-component.md
│   │   │   │   ├── filter-and-transform-data-from-an-api.md
│   │   │   │   ├── group-items-in-list-by-a-property.md
│   │   │   │   ├── handle-background-operations.md
│   │   │   │   ├── hide-an-element-until-its-datasource-is-ready.md
│   │   │   │   ├── make-a-set-of-equal-width-cards.md
│   │   │   │   ├── make-a-table-responsive.md
│   │   │   │   ├── make-navpanel-width-responsive.md
│   │   │   │   ├── modify-a-value-reported-in-a-column.md
│   │   │   │   ├── paginate-a-list.md
│   │   │   │   ├── pass-data-to-a-modal-dialog.md
│   │   │   │   ├── react-to-button-click-not-keystrokes.md
│   │   │   │   ├── set-the-initial-value-of-a-select-from-fetched-data.md
│   │   │   │   ├── share-a-modaldialog-across-components.md
│   │   │   │   ├── sync-selections-between-table-and-list-views.md
│   │   │   │   ├── update-ui-optimistically.md
│   │   │   │   ├── use-built-in-form-validation.md
│   │   │   │   └── use-the-same-modaldialog-to-add-or-edit.md
│   │   │   ├── howto.md
│   │   │   ├── intro.md
│   │   │   ├── layout.md
│   │   │   ├── markup.md
│   │   │   ├── mcp.md
│   │   │   ├── modal-dialogs.md
│   │   │   ├── news-and-reviews.md
│   │   │   ├── reactive-intro.md
│   │   │   ├── refactoring.md
│   │   │   ├── routing-and-links.md
│   │   │   ├── samples
│   │   │   │   ├── color-palette.xmlui
│   │   │   │   ├── color-values.xmlui
│   │   │   │   ├── shadow-sizes.xmlui
│   │   │   │   ├── spacing-sizes.xmlui
│   │   │   │   ├── swatch.xmlui
│   │   │   │   ├── theme-gallery-brief.xmlui
│   │   │   │   └── theme-gallery.xmlui
│   │   │   ├── scoping.md
│   │   │   ├── scripting.md
│   │   │   ├── styles-and-themes
│   │   │   │   ├── common-units.md
│   │   │   │   ├── layout-props.md
│   │   │   │   ├── theme-variable-defaults.md
│   │   │   │   ├── theme-variables.md
│   │   │   │   └── themes.md
│   │   │   ├── template-properties.md
│   │   │   ├── test.md
│   │   │   ├── tutorial-01.md
│   │   │   ├── tutorial-02.md
│   │   │   ├── tutorial-03.md
│   │   │   ├── tutorial-04.md
│   │   │   ├── tutorial-05.md
│   │   │   ├── tutorial-06.md
│   │   │   ├── tutorial-07.md
│   │   │   ├── tutorial-08.md
│   │   │   ├── tutorial-09.md
│   │   │   ├── tutorial-10.md
│   │   │   ├── tutorial-11.md
│   │   │   ├── tutorial-12.md
│   │   │   ├── universal-properties.md
│   │   │   ├── user-defined-components.md
│   │   │   ├── vscode.md
│   │   │   ├── working-with-markdown.md
│   │   │   ├── working-with-text.md
│   │   │   ├── xmlui-animations
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   ├── Animation.md
│   │   │   │   ├── FadeAnimation.md
│   │   │   │   ├── FadeInAnimation.md
│   │   │   │   ├── FadeOutAnimation.md
│   │   │   │   ├── ScaleAnimation.md
│   │   │   │   └── SlideInAnimation.md
│   │   │   ├── xmlui-charts
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   ├── BarChart.md
│   │   │   │   ├── DonutChart.md
│   │   │   │   ├── LabelList.md
│   │   │   │   ├── Legend.md
│   │   │   │   ├── LineChart.md
│   │   │   │   └── PieChart.md
│   │   │   ├── xmlui-pdf
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   └── Pdf.md
│   │   │   └── xmlui-spreadsheet
│   │   │       ├── _meta.json
│   │   │       ├── _overview.md
│   │   │       └── Spreadsheet.md
│   │   ├── resources
│   │   │   ├── devdocs
│   │   │   │   ├── debug-proxy-object-2.png
│   │   │   │   ├── debug-proxy-object.png
│   │   │   │   ├── table_editor_01.png
│   │   │   │   ├── table_editor_02.png
│   │   │   │   ├── table_editor_03.png
│   │   │   │   ├── table_editor_04.png
│   │   │   │   ├── table_editor_05.png
│   │   │   │   ├── table_editor_06.png
│   │   │   │   ├── table_editor_07.png
│   │   │   │   ├── table_editor_08.png
│   │   │   │   ├── table_editor_09.png
│   │   │   │   ├── table_editor_10.png
│   │   │   │   ├── table_editor_11.png
│   │   │   │   ├── table-editor-01.png
│   │   │   │   ├── table-editor-02.png
│   │   │   │   ├── table-editor-03.png
│   │   │   │   ├── table-editor-04.png
│   │   │   │   ├── table-editor-06.png
│   │   │   │   ├── table-editor-07.png
│   │   │   │   ├── table-editor-08.png
│   │   │   │   ├── table-editor-09.png
│   │   │   │   └── xmlui-rendering-of-tiptap-markdown.png
│   │   │   ├── favicon.ico
│   │   │   ├── files
│   │   │   │   ├── clients.json
│   │   │   │   ├── daily-revenue.json
│   │   │   │   ├── dashboard-stats.json
│   │   │   │   ├── demo.xmlui
│   │   │   │   ├── demo.xmlui.xs
│   │   │   │   ├── downloads
│   │   │   │   │   └── downloads.json
│   │   │   │   ├── for-download
│   │   │   │   │   ├── index-with-api.html
│   │   │   │   │   ├── index.html
│   │   │   │   │   ├── mockApi.js
│   │   │   │   │   ├── start-darwin.sh
│   │   │   │   │   ├── start-linux.sh
│   │   │   │   │   ├── start.bat
│   │   │   │   │   └── xmlui
│   │   │   │   │       └── xmlui-standalone.umd.js
│   │   │   │   ├── getting-started
│   │   │   │   │   ├── cl-tutorial-final.zip
│   │   │   │   │   ├── cl-tutorial.zip
│   │   │   │   │   ├── cl-tutorial2.zip
│   │   │   │   │   ├── cl-tutorial3.zip
│   │   │   │   │   ├── cl-tutorial4.zip
│   │   │   │   │   ├── cl-tutorial5.zip
│   │   │   │   │   ├── cl-tutorial6.zip
│   │   │   │   │   ├── getting-started.zip
│   │   │   │   │   ├── hello-xmlui.zip
│   │   │   │   │   ├── xmlui-empty.zip
│   │   │   │   │   └── xmlui-starter.zip
│   │   │   │   ├── howto
│   │   │   │   │   └── component-icons
│   │   │   │   │       └── up-arrow.svg
│   │   │   │   ├── invoices.json
│   │   │   │   ├── monthly-status.json
│   │   │   │   ├── news-and-reviews.json
│   │   │   │   ├── products.json
│   │   │   │   ├── releases.json
│   │   │   │   ├── tutorials
│   │   │   │   │   ├── datasource
│   │   │   │   │   │   └── api.ts
│   │   │   │   │   └── p2do
│   │   │   │   │       ├── api.ts
│   │   │   │   │       └── todo-logo.svg
│   │   │   │   └── xmlui.json
│   │   │   ├── github.svg
│   │   │   ├── images
│   │   │   │   ├── apiaction-tutorial
│   │   │   │   │   ├── add-success.png
│   │   │   │   │   ├── apiaction-param.png
│   │   │   │   │   ├── change-completed.png
│   │   │   │   │   ├── change-in-progress.png
│   │   │   │   │   ├── confirm-delete.png
│   │   │   │   │   ├── data-error.png
│   │   │   │   │   ├── data-progress.png
│   │   │   │   │   ├── data-success.png
│   │   │   │   │   ├── display-1.png
│   │   │   │   │   ├── item-deleted.png
│   │   │   │   │   ├── item-updated.png
│   │   │   │   │   ├── missing-api-key.png
│   │   │   │   │   ├── new-item-added.png
│   │   │   │   │   └── test-message.png
│   │   │   │   ├── chat-api
│   │   │   │   │   └── domain-model.svg
│   │   │   │   ├── components
│   │   │   │   │   ├── image
│   │   │   │   │   │   └── breakfast.jpg
│   │   │   │   │   ├── markdown
│   │   │   │   │   │   └── colors.png
│   │   │   │   │   └── modal
│   │   │   │   │       ├── deep_link_dialog_1.jpg
│   │   │   │   │       └── deep_link_dialog_2.jpg
│   │   │   │   ├── create-apps
│   │   │   │   │   ├── collapsed-vertical.png
│   │   │   │   │   ├── using-forms-warning-dialog.png
│   │   │   │   │   └── using-forms.png
│   │   │   │   ├── datasource-tutorial
│   │   │   │   │   ├── data-with-header.png
│   │   │   │   │   ├── filtered-data.png
│   │   │   │   │   ├── filtered-items.png
│   │   │   │   │   ├── initial-page-items.png
│   │   │   │   │   ├── list-items.png
│   │   │   │   │   ├── next-page-items.png
│   │   │   │   │   ├── no-data.png
│   │   │   │   │   ├── pagination-1.jpg
│   │   │   │   │   ├── pagination-1.png
│   │   │   │   │   ├── polling-1.png
│   │   │   │   │   ├── refetch-data.png
│   │   │   │   │   ├── slow-loading.png
│   │   │   │   │   ├── test-message.png
│   │   │   │   │   ├── Thumbs.db
│   │   │   │   │   ├── unconventional-data.png
│   │   │   │   │   └── unfiltered-items.png
│   │   │   │   ├── flower.jpg
│   │   │   │   ├── get-started
│   │   │   │   │   ├── add-new-contact.png
│   │   │   │   │   ├── app-modified.png
│   │   │   │   │   ├── app-start.png
│   │   │   │   │   ├── app-with-boxes.png
│   │   │   │   │   ├── app-with-toast.png
│   │   │   │   │   ├── boilerplate-structure.png
│   │   │   │   │   ├── cl-initial.png
│   │   │   │   │   ├── cl-start.png
│   │   │   │   │   ├── contact-counts.png
│   │   │   │   │   ├── contact-dialog-title.png
│   │   │   │   │   ├── contact-dialog.png
│   │   │   │   │   ├── contact-menus.png
│   │   │   │   │   ├── contact-predicates.png
│   │   │   │   │   ├── context-menu.png
│   │   │   │   │   ├── dashboard-numbers.png
│   │   │   │   │   ├── default-contact-list.png
│   │   │   │   │   ├── delete-contact.png
│   │   │   │   │   ├── delete-task.png
│   │   │   │   │   ├── detailed-template.png
│   │   │   │   │   ├── edit-contact-details.png
│   │   │   │   │   ├── edited-contact-saved.png
│   │   │   │   │   ├── empty-sections.png
│   │   │   │   │   ├── filter-completed.png
│   │   │   │   │   ├── fullwidth-desktop.png
│   │   │   │   │   ├── fullwidth-mobile.png
│   │   │   │   │   ├── initial-table.png
│   │   │   │   │   ├── items-and-badges.png
│   │   │   │   │   ├── loading-message.png
│   │   │   │   │   ├── new-contact-button.png
│   │   │   │   │   ├── new-contact-saved.png
│   │   │   │   │   ├── no-empty-sections.png
│   │   │   │   │   ├── personal-todo-initial.png
│   │   │   │   │   ├── piechart.png
│   │   │   │   │   ├── review-today.png
│   │   │   │   │   ├── rudimentary-dashboard.png
│   │   │   │   │   ├── section-collapsed.png
│   │   │   │   │   ├── sectioned-items.png
│   │   │   │   │   ├── sections-ordered.png
│   │   │   │   │   ├── spacex-list-with-links.png
│   │   │   │   │   ├── spacex-list.png
│   │   │   │   │   ├── start-personal-todo-1.png
│   │   │   │   │   ├── submit-new-contact.png
│   │   │   │   │   ├── submit-new-task.png
│   │   │   │   │   ├── syntax-highlighting.png
│   │   │   │   │   ├── table-with-badge.png
│   │   │   │   │   ├── template-with-card.png
│   │   │   │   │   ├── test-emulated-api.png
│   │   │   │   │   ├── Thumbs.db
│   │   │   │   │   ├── todo-logo.png
│   │   │   │   │   └── xmlui-tools.png
│   │   │   │   ├── HelloApp.png
│   │   │   │   ├── HelloApp2.png
│   │   │   │   ├── logos
│   │   │   │   │   ├── xmlui1.svg
│   │   │   │   │   ├── xmlui2.svg
│   │   │   │   │   ├── xmlui3.svg
│   │   │   │   │   ├── xmlui4.svg
│   │   │   │   │   ├── xmlui5.svg
│   │   │   │   │   ├── xmlui6.svg
│   │   │   │   │   └── xmlui7.svg
│   │   │   │   ├── pdf
│   │   │   │   │   └── dummy-pdf.jpg
│   │   │   │   ├── rendering-engine
│   │   │   │   │   ├── AppEngine-flow.svg
│   │   │   │   │   ├── Component.svg
│   │   │   │   │   ├── CompoundComponent.svg
│   │   │   │   │   ├── RootComponent.svg
│   │   │   │   │   └── tree-with-containers.svg
│   │   │   │   ├── reviewers-guide
│   │   │   │   │   ├── AppEngine-flow.svg
│   │   │   │   │   └── incbutton-in-action.png
│   │   │   │   ├── tools
│   │   │   │   │   └── boilerplate-structure.png
│   │   │   │   ├── try.svg
│   │   │   │   ├── tutorial
│   │   │   │   │   ├── app-chat-history.png
│   │   │   │   │   ├── app-content-placeholder.png
│   │   │   │   │   ├── app-header-and-content.png
│   │   │   │   │   ├── app-links-channel-selected.png
│   │   │   │   │   ├── app-links-click.png
│   │   │   │   │   ├── app-navigation.png
│   │   │   │   │   ├── finished-ex01.png
│   │   │   │   │   ├── finished-ex02.png
│   │   │   │   │   ├── hello.png
│   │   │   │   │   ├── splash-screen-advanced.png
│   │   │   │   │   ├── splash-screen-after-click.png
│   │   │   │   │   ├── splash-screen-centered.png
│   │   │   │   │   ├── splash-screen-events.png
│   │   │   │   │   ├── splash-screen-expression.png
│   │   │   │   │   ├── splash-screen-reuse-after.png
│   │   │   │   │   ├── splash-screen-reuse-before.png
│   │   │   │   │   └── splash-screen.png
│   │   │   │   └── tutorial-01.png
│   │   │   ├── llms.txt
│   │   │   ├── logo-dark.svg
│   │   │   ├── logo.svg
│   │   │   ├── pg-popout.svg
│   │   │   └── xmlui-logo.svg
│   │   ├── serve.json
│   │   └── web.config
│   ├── scripts
│   │   ├── download-latest-xmlui.js
│   │   ├── generate-rss.js
│   │   ├── get-releases.js
│   │   └── utils.js
│   ├── src
│   │   ├── components
│   │   │   ├── BlogOverview.xmlui
│   │   │   ├── BlogPage.xmlui
│   │   │   ├── Boxes.xmlui
│   │   │   ├── Breadcrumb.xmlui
│   │   │   ├── ChangeLog.xmlui
│   │   │   ├── ColorPalette.xmlui
│   │   │   ├── DocumentLinks.xmlui
│   │   │   ├── DocumentPage.xmlui
│   │   │   ├── DocumentPageNoTOC.xmlui
│   │   │   ├── Icons.xmlui
│   │   │   ├── IncButton.xmlui
│   │   │   ├── IncButton2.xmlui
│   │   │   ├── NameValue.xmlui
│   │   │   ├── PageNotFound.xmlui
│   │   │   ├── PaletteItem.xmlui
│   │   │   ├── Palettes.xmlui
│   │   │   ├── SectionHeader.xmlui
│   │   │   ├── TBD.xmlui
│   │   │   ├── Test.xmlui
│   │   │   ├── ThemesIntro.xmlui
│   │   │   ├── ThousandThemes.xmlui
│   │   │   ├── TubeStops.xmlui
│   │   │   ├── TubeStops.xmlui.xs
│   │   │   └── TwoColumnCode.xmlui
│   │   ├── config.ts
│   │   ├── Main.xmlui
│   │   └── themes
│   │       ├── docs-theme.ts
│   │       ├── earthtone.ts
│   │       ├── xmlui-gray-on-default.ts
│   │       ├── xmlui-green-on-default.ts
│   │       └── xmlui-orange-on-default.ts
│   └── tsconfig.json
├── LICENSE
├── package-lock.json
├── package.json
├── packages
│   ├── tsconfig.json
│   ├── xmlui-animations
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── Animation.tsx
│   │       ├── AnimationNative.tsx
│   │       ├── FadeAnimation.tsx
│   │       ├── FadeInAnimation.tsx
│   │       ├── FadeOutAnimation.tsx
│   │       ├── index.tsx
│   │       ├── ScaleAnimation.tsx
│   │       └── SlideInAnimation.tsx
│   ├── xmlui-devtools
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   ├── src
│   │   │   ├── devtools
│   │   │   │   ├── DevTools.tsx
│   │   │   │   ├── DevToolsNative.module.scss
│   │   │   │   ├── DevToolsNative.tsx
│   │   │   │   ├── ModalDialog.module.scss
│   │   │   │   ├── ModalDialog.tsx
│   │   │   │   ├── ModalVisibilityContext.tsx
│   │   │   │   ├── Tooltip.module.scss
│   │   │   │   ├── Tooltip.tsx
│   │   │   │   └── utils.ts
│   │   │   ├── editor
│   │   │   │   └── Editor.tsx
│   │   │   └── index.tsx
│   │   └── vite.config-overrides.ts
│   ├── xmlui-hello-world
│   │   ├── .gitignore
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── HelloWorld.module.scss
│   │       ├── HelloWorld.tsx
│   │       ├── HelloWorldNative.tsx
│   │       └── index.tsx
│   ├── xmlui-os-frames
│   │   ├── .gitignore
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── index.tsx
│   │       ├── IPhoneFrame.module.scss
│   │       ├── IPhoneFrame.tsx
│   │       ├── MacOSAppFrame.module.scss
│   │       ├── MacOSAppFrame.tsx
│   │       ├── WindowsAppFrame.module.scss
│   │       └── WindowsAppFrame.tsx
│   ├── xmlui-pdf
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   ├── components
│   │   │   │   └── Pdf.xmlui
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── index.tsx
│   │       ├── LazyPdfNative.tsx
│   │       ├── Pdf.module.scss
│   │       └── Pdf.tsx
│   ├── xmlui-playground
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── hooks
│   │       │   ├── usePlayground.ts
│   │       │   └── useToast.ts
│   │       ├── index.tsx
│   │       ├── playground
│   │       │   ├── Box.module.scss
│   │       │   ├── Box.tsx
│   │       │   ├── CodeSelector.tsx
│   │       │   ├── ConfirmationDialog.module.scss
│   │       │   ├── ConfirmationDialog.tsx
│   │       │   ├── Editor.tsx
│   │       │   ├── Header.module.scss
│   │       │   ├── Header.tsx
│   │       │   ├── Playground.tsx
│   │       │   ├── PlaygroundContent.module.scss
│   │       │   ├── PlaygroundContent.tsx
│   │       │   ├── PlaygroundNative.module.scss
│   │       │   ├── PlaygroundNative.tsx
│   │       │   ├── Preview.module.scss
│   │       │   ├── Preview.tsx
│   │       │   ├── Select.module.scss
│   │       │   ├── StandalonePlayground.tsx
│   │       │   ├── StandalonePlaygroundNative.module.scss
│   │       │   ├── StandalonePlaygroundNative.tsx
│   │       │   ├── ThemeSwitcher.module.scss
│   │       │   ├── ThemeSwitcher.tsx
│   │       │   ├── ToneSwitcher.tsx
│   │       │   ├── Tooltip.module.scss
│   │       │   ├── Tooltip.tsx
│   │       │   └── utils.ts
│   │       ├── providers
│   │       │   ├── Toast.module.scss
│   │       │   └── ToastProvider.tsx
│   │       ├── state
│   │       │   └── store.ts
│   │       ├── themes
│   │       │   └── theme.ts
│   │       └── utils
│   │           └── helpers.ts
│   ├── xmlui-search
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── index.tsx
│   │       ├── Search.module.scss
│   │       └── Search.tsx
│   ├── xmlui-spreadsheet
│   │   ├── .gitignore
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── index.tsx
│   │       ├── Spreadsheet.tsx
│   │       └── SpreadsheetNative.tsx
│   └── xmlui-website-blocks
│       ├── .gitignore
│       ├── CHANGELOG.md
│       ├── demo
│       │   ├── components
│       │   │   ├── HeroBackgroundBreakoutPage.xmlui
│       │   │   ├── HeroBackgroundsPage.xmlui
│       │   │   ├── HeroContentsPage.xmlui
│       │   │   ├── HeroTextAlignPage.xmlui
│       │   │   ├── HeroTextPage.xmlui
│       │   │   └── HeroTonesPage.xmlui
│       │   ├── Main.xmlui
│       │   └── themes
│       │       └── default.ts
│       ├── index.html
│       ├── index.ts
│       ├── meta
│       │   └── componentsMetadata.ts
│       ├── package.json
│       ├── public
│       │   └── resources
│       │       ├── building.jpg
│       │       └── xmlui-logo.svg
│       └── src
│           ├── Carousel
│           │   ├── Carousel.module.scss
│           │   ├── Carousel.tsx
│           │   ├── CarouselContext.tsx
│           │   └── CarouselNative.tsx
│           ├── FancyButton
│           │   ├── FancyButton.module.scss
│           │   ├── FancyButton.tsx
│           │   └── FancyButton.xmlui
│           ├── Hello
│           │   ├── Hello.tsx
│           │   ├── Hello.xmlui
│           │   └── Hello.xmlui.xs
│           ├── HeroSection
│           │   ├── HeroSection.module.scss
│           │   ├── HeroSection.spec.ts
│           │   ├── HeroSection.tsx
│           │   └── HeroSectionNative.tsx
│           ├── index.tsx
│           ├── ScrollToTop
│           │   ├── ScrollToTop.module.scss
│           │   ├── ScrollToTop.tsx
│           │   └── ScrollToTopNative.tsx
│           └── vite-env.d.ts
├── playwright.config.ts
├── README.md
├── tools
│   ├── codefence
│   │   └── xmlui-code-fence-docs.md
│   ├── create-app
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── create-app.ts
│   │   ├── helpers
│   │   │   ├── copy.ts
│   │   │   ├── get-pkg-manager.ts
│   │   │   ├── git.ts
│   │   │   ├── install.ts
│   │   │   ├── is-folder-empty.ts
│   │   │   ├── is-writeable.ts
│   │   │   ├── make-dir.ts
│   │   │   └── validate-pkg.ts
│   │   ├── index.ts
│   │   ├── package.json
│   │   ├── templates
│   │   │   ├── default
│   │   │   │   └── ts
│   │   │   │       ├── gitignore
│   │   │   │       ├── index.html
│   │   │   │       ├── index.ts
│   │   │   │       ├── public
│   │   │   │       │   ├── mockServiceWorker.js
│   │   │   │       │   ├── resources
│   │   │   │       │   │   ├── favicon.ico
│   │   │   │       │   │   └── xmlui-logo.svg
│   │   │   │       │   └── serve.json
│   │   │   │       └── src
│   │   │   │           ├── components
│   │   │   │           │   ├── ApiAware.xmlui
│   │   │   │           │   ├── Home.xmlui
│   │   │   │           │   ├── IncButton.xmlui
│   │   │   │           │   └── PagePanel.xmlui
│   │   │   │           ├── config.ts
│   │   │   │           └── Main.xmlui
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   └── tsconfig.json
│   ├── create-xmlui-hello-world
│   │   ├── index.js
│   │   └── package.json
│   └── vscode
│       ├── .gitignore
│       ├── .vscode
│       │   ├── launch.json
│       │   └── tasks.json
│       ├── .vscodeignore
│       ├── build.sh
│       ├── CHANGELOG.md
│       ├── esbuild.js
│       ├── eslint.config.mjs
│       ├── formatter-docs.md
│       ├── generate-test-sample.sh
│       ├── LICENSE.md
│       ├── package-lock.json
│       ├── package.json
│       ├── README.md
│       ├── resources
│       │   ├── xmlui-logo.png
│       │   └── xmlui-markup-syntax-highlighting.png
│       ├── src
│       │   ├── extension.ts
│       │   └── server.ts
│       ├── syntaxes
│       │   └── xmlui.tmLanguage.json
│       ├── test-samples
│       │   └── sample.xmlui
│       ├── tsconfig.json
│       └── tsconfig.tsbuildinfo
├── turbo.json
└── xmlui
    ├── .gitignore
    ├── bin
    │   ├── bootstrap.cjs
    │   ├── bootstrap.js
    │   ├── build-lib.ts
    │   ├── build.ts
    │   ├── index.ts
    │   ├── preview.ts
    │   ├── start.ts
    │   ├── vite-xmlui-plugin.ts
    │   └── viteConfig.ts
    ├── CHANGELOG.md
    ├── conventions
    │   ├── component-qa-checklist.md
    │   ├── copilot-conventions.md
    │   ├── create-xmlui-components.md
    │   ├── mermaid.md
    │   ├── testing-conventions.md
    │   └── xmlui-in-a-nutshell.md
    ├── dev-docs
    │   ├── accessibility.md
    │   ├── build-system.md
    │   ├── build-xmlui.md
    │   ├── component-behaviors.md
    │   ├── component-metadata.md
    │   ├── components-with-options.md
    │   ├── containers.md
    │   ├── data-operations.md
    │   ├── glossary.md
    │   ├── index.md
    │   ├── next
    │   │   ├── component-dev-guide.md
    │   │   ├── configuration-management-enhancement-summary.md
    │   │   ├── documentation-scripts-refactoring-complete-summary.md
    │   │   ├── documentation-scripts-refactoring-plan.md
    │   │   ├── duplicate-pattern-extraction-summary.md
    │   │   ├── error-handling-standardization-summary.md
    │   │   ├── generating-component-reference.md
    │   │   ├── index.md
    │   │   ├── logging-consistency-implementation-summary.md
    │   │   ├── project-build.md
    │   │   ├── project-structure.md
    │   │   ├── theme-context.md
    │   │   ├── tiptap-design-considerations.md
    │   │   ├── working-with-code.md
    │   │   ├── xmlui-runtime-architecture
    │   │   └── xmlui-wcag-accessibility-report.md
    │   ├── react-fundamentals.md
    │   ├── release-method.md
    │   ├── standalone-app.md
    │   ├── theme-variables-refactoring.md
    │   ├── ud-components.md
    │   └── xmlui-repo.md
    ├── package.json
    ├── scripts
    │   ├── coverage-only.js
    │   ├── e2e-test-summary.js
    │   ├── extract-component-metadata.js
    │   ├── generate-docs
    │   │   ├── build-downloads-map.mjs
    │   │   ├── build-pages-map.mjs
    │   │   ├── components-config.json
    │   │   ├── configuration-management.mjs
    │   │   ├── constants.mjs
    │   │   ├── create-theme-files.mjs
    │   │   ├── DocsGenerator.mjs
    │   │   ├── error-handling.mjs
    │   │   ├── extensions-config.json
    │   │   ├── folders.mjs
    │   │   ├── generate-summary-files.mjs
    │   │   ├── get-docs.mjs
    │   │   ├── input-handler.mjs
    │   │   ├── logger.mjs
    │   │   ├── logging-standards.mjs
    │   │   ├── MetadataProcessor.mjs
    │   │   ├── pattern-utilities.mjs
    │   │   └── utils.mjs
    │   ├── generate-metadata-markdown.js
    │   ├── get-langserver-metadata.js
    │   ├── inline-links.mjs
    │   └── README-e2e-summary.md
    ├── src
    │   ├── abstractions
    │   │   ├── _conventions.md
    │   │   ├── ActionDefs.ts
    │   │   ├── AppContextDefs.ts
    │   │   ├── ComponentDefs.ts
    │   │   ├── ContainerDefs.ts
    │   │   ├── ExtensionDefs.ts
    │   │   ├── FunctionDefs.ts
    │   │   ├── RendererDefs.ts
    │   │   ├── scripting
    │   │   │   ├── BlockScope.ts
    │   │   │   ├── Compilation.ts
    │   │   │   ├── LogicalThread.ts
    │   │   │   ├── LoopScope.ts
    │   │   │   ├── modules.ts
    │   │   │   ├── ScriptParserError.ts
    │   │   │   ├── Token.ts
    │   │   │   ├── TryScope.ts
    │   │   │   └── TryScopeExp.ts
    │   │   └── ThemingDefs.ts
    │   ├── components
    │   │   ├── _conventions.md
    │   │   ├── abstractions.ts
    │   │   ├── Accordion
    │   │   │   ├── Accordion.md
    │   │   │   ├── Accordion.module.scss
    │   │   │   ├── Accordion.spec.ts
    │   │   │   ├── Accordion.tsx
    │   │   │   ├── AccordionContext.tsx
    │   │   │   ├── AccordionItem.tsx
    │   │   │   ├── AccordionItemNative.tsx
    │   │   │   └── AccordionNative.tsx
    │   │   ├── Animation
    │   │   │   └── AnimationNative.tsx
    │   │   ├── APICall
    │   │   │   ├── APICall.md
    │   │   │   ├── APICall.spec.ts
    │   │   │   ├── APICall.tsx
    │   │   │   └── APICallNative.tsx
    │   │   ├── App
    │   │   │   ├── App.md
    │   │   │   ├── App.module.scss
    │   │   │   ├── App.spec.ts
    │   │   │   ├── App.tsx
    │   │   │   ├── AppLayoutContext.ts
    │   │   │   ├── AppNative.tsx
    │   │   │   ├── AppStateContext.ts
    │   │   │   ├── doc-resources
    │   │   │   │   ├── condensed-sticky.xmlui
    │   │   │   │   ├── condensed.xmlui
    │   │   │   │   ├── horizontal-sticky.xmlui
    │   │   │   │   ├── horizontal.xmlui
    │   │   │   │   ├── vertical-full-header.xmlui
    │   │   │   │   ├── vertical-sticky.xmlui
    │   │   │   │   └── vertical.xmlui
    │   │   │   ├── IndexerContext.ts
    │   │   │   ├── LinkInfoContext.ts
    │   │   │   ├── SearchContext.tsx
    │   │   │   ├── Sheet.module.scss
    │   │   │   └── Sheet.tsx
    │   │   ├── AppHeader
    │   │   │   ├── AppHeader.md
    │   │   │   ├── AppHeader.module.scss
    │   │   │   ├── AppHeader.spec.ts
    │   │   │   ├── AppHeader.tsx
    │   │   │   └── AppHeaderNative.tsx
    │   │   ├── AppState
    │   │   │   ├── AppState.md
    │   │   │   ├── AppState.spec.ts
    │   │   │   ├── AppState.tsx
    │   │   │   └── AppStateNative.tsx
    │   │   ├── AutoComplete
    │   │   │   ├── AutoComplete.md
    │   │   │   ├── AutoComplete.module.scss
    │   │   │   ├── AutoComplete.spec.ts
    │   │   │   ├── AutoComplete.tsx
    │   │   │   ├── AutoCompleteContext.tsx
    │   │   │   └── AutoCompleteNative.tsx
    │   │   ├── Avatar
    │   │   │   ├── Avatar.md
    │   │   │   ├── Avatar.module.scss
    │   │   │   ├── Avatar.spec.ts
    │   │   │   ├── Avatar.tsx
    │   │   │   └── AvatarNative.tsx
    │   │   ├── Backdrop
    │   │   │   ├── Backdrop.md
    │   │   │   ├── Backdrop.module.scss
    │   │   │   ├── Backdrop.spec.ts
    │   │   │   ├── Backdrop.tsx
    │   │   │   └── BackdropNative.tsx
    │   │   ├── Badge
    │   │   │   ├── Badge.md
    │   │   │   ├── Badge.module.scss
    │   │   │   ├── Badge.spec.ts
    │   │   │   ├── Badge.tsx
    │   │   │   └── BadgeNative.tsx
    │   │   ├── Bookmark
    │   │   │   ├── Bookmark.md
    │   │   │   ├── Bookmark.module.scss
    │   │   │   ├── Bookmark.spec.ts
    │   │   │   ├── Bookmark.tsx
    │   │   │   └── BookmarkNative.tsx
    │   │   ├── Breakout
    │   │   │   ├── Breakout.module.scss
    │   │   │   ├── Breakout.spec.ts
    │   │   │   ├── Breakout.tsx
    │   │   │   └── BreakoutNative.tsx
    │   │   ├── Button
    │   │   │   ├── Button-style.spec.ts
    │   │   │   ├── Button.md
    │   │   │   ├── Button.module.scss
    │   │   │   ├── Button.spec.ts
    │   │   │   ├── Button.tsx
    │   │   │   └── ButtonNative.tsx
    │   │   ├── Card
    │   │   │   ├── Card.md
    │   │   │   ├── Card.module.scss
    │   │   │   ├── Card.spec.ts
    │   │   │   ├── Card.tsx
    │   │   │   └── CardNative.tsx
    │   │   ├── Carousel
    │   │   │   ├── Carousel.md
    │   │   │   ├── Carousel.module.scss
    │   │   │   ├── Carousel.spec.ts
    │   │   │   ├── Carousel.tsx
    │   │   │   ├── CarouselContext.tsx
    │   │   │   ├── CarouselItem.tsx
    │   │   │   ├── CarouselItemNative.tsx
    │   │   │   └── CarouselNative.tsx
    │   │   ├── ChangeListener
    │   │   │   ├── ChangeListener.md
    │   │   │   ├── ChangeListener.spec.ts
    │   │   │   ├── ChangeListener.tsx
    │   │   │   └── ChangeListenerNative.tsx
    │   │   ├── chart-color-schemes.ts
    │   │   ├── Charts
    │   │   │   ├── AreaChart
    │   │   │   │   ├── AreaChart.md
    │   │   │   │   ├── AreaChart.spec.ts
    │   │   │   │   ├── AreaChart.tsx
    │   │   │   │   └── AreaChartNative.tsx
    │   │   │   ├── BarChart
    │   │   │   │   ├── BarChart.md
    │   │   │   │   ├── BarChart.module.scss
    │   │   │   │   ├── BarChart.spec.ts
    │   │   │   │   ├── BarChart.tsx
    │   │   │   │   └── BarChartNative.tsx
    │   │   │   ├── DonutChart
    │   │   │   │   ├── DonutChart.spec.ts
    │   │   │   │   └── DonutChart.tsx
    │   │   │   ├── LabelList
    │   │   │   │   ├── LabelList.module.scss
    │   │   │   │   ├── LabelList.spec.ts
    │   │   │   │   ├── LabelList.tsx
    │   │   │   │   └── LabelListNative.tsx
    │   │   │   ├── Legend
    │   │   │   │   ├── Legend.spec.ts
    │   │   │   │   ├── Legend.tsx
    │   │   │   │   └── LegendNative.tsx
    │   │   │   ├── LineChart
    │   │   │   │   ├── LineChart.md
    │   │   │   │   ├── LineChart.module.scss
    │   │   │   │   ├── LineChart.spec.ts
    │   │   │   │   ├── LineChart.tsx
    │   │   │   │   └── LineChartNative.tsx
    │   │   │   ├── PieChart
    │   │   │   │   ├── PieChart.md
    │   │   │   │   ├── PieChart.spec.ts
    │   │   │   │   ├── PieChart.tsx
    │   │   │   │   ├── PieChartNative.module.scss
    │   │   │   │   └── PieChartNative.tsx
    │   │   │   ├── RadarChart
    │   │   │   │   ├── RadarChart.md
    │   │   │   │   ├── RadarChart.spec.ts
    │   │   │   │   ├── RadarChart.tsx
    │   │   │   │   └── RadarChartNative.tsx
    │   │   │   ├── Tooltip
    │   │   │   │   ├── TooltipContent.module.scss
    │   │   │   │   ├── TooltipContent.spec.ts
    │   │   │   │   └── TooltipContent.tsx
    │   │   │   └── utils
    │   │   │       ├── abstractions.ts
    │   │   │       └── ChartProvider.tsx
    │   │   ├── Checkbox
    │   │   │   ├── Checkbox.md
    │   │   │   ├── Checkbox.spec.ts
    │   │   │   └── Checkbox.tsx
    │   │   ├── CodeBlock
    │   │   │   ├── CodeBlock.module.scss
    │   │   │   ├── CodeBlock.spec.ts
    │   │   │   ├── CodeBlock.tsx
    │   │   │   ├── CodeBlockNative.tsx
    │   │   │   └── highlight-code.ts
    │   │   ├── collectedComponentMetadata.ts
    │   │   ├── ColorPicker
    │   │   │   ├── ColorPicker.md
    │   │   │   ├── ColorPicker.module.scss
    │   │   │   ├── ColorPicker.spec.ts
    │   │   │   ├── ColorPicker.tsx
    │   │   │   └── ColorPickerNative.tsx
    │   │   ├── Column
    │   │   │   ├── Column.md
    │   │   │   ├── Column.tsx
    │   │   │   ├── ColumnNative.tsx
    │   │   │   ├── doc-resources
    │   │   │   │   └── list-component-data.js
    │   │   │   └── TableContext.tsx
    │   │   ├── component-utils.ts
    │   │   ├── ComponentProvider.tsx
    │   │   ├── ComponentRegistryContext.tsx
    │   │   ├── container-helpers.tsx
    │   │   ├── ContentSeparator
    │   │   │   ├── ContentSeparator.md
    │   │   │   ├── ContentSeparator.module.scss
    │   │   │   ├── ContentSeparator.spec.ts
    │   │   │   ├── ContentSeparator.tsx
    │   │   │   └── ContentSeparatorNative.tsx
    │   │   ├── DataSource
    │   │   │   ├── DataSource.md
    │   │   │   └── DataSource.tsx
    │   │   ├── DateInput
    │   │   │   ├── DateInput.md
    │   │   │   ├── DateInput.module.scss
    │   │   │   ├── DateInput.spec.ts
    │   │   │   ├── DateInput.tsx
    │   │   │   └── DateInputNative.tsx
    │   │   ├── DatePicker
    │   │   │   ├── DatePicker.md
    │   │   │   ├── DatePicker.module.scss
    │   │   │   ├── DatePicker.spec.ts
    │   │   │   ├── DatePicker.tsx
    │   │   │   └── DatePickerNative.tsx
    │   │   ├── DropdownMenu
    │   │   │   ├── DropdownMenu.md
    │   │   │   ├── DropdownMenu.module.scss
    │   │   │   ├── DropdownMenu.spec.ts
    │   │   │   ├── DropdownMenu.tsx
    │   │   │   ├── DropdownMenuNative.tsx
    │   │   │   ├── MenuItem.md
    │   │   │   └── SubMenuItem.md
    │   │   ├── EmojiSelector
    │   │   │   ├── EmojiSelector.md
    │   │   │   ├── EmojiSelector.spec.ts
    │   │   │   ├── EmojiSelector.tsx
    │   │   │   └── EmojiSelectorNative.tsx
    │   │   ├── ExpandableItem
    │   │   │   ├── ExpandableItem.module.scss
    │   │   │   ├── ExpandableItem.spec.ts
    │   │   │   ├── ExpandableItem.tsx
    │   │   │   └── ExpandableItemNative.tsx
    │   │   ├── FileInput
    │   │   │   ├── FileInput.md
    │   │   │   ├── FileInput.module.scss
    │   │   │   ├── FileInput.spec.ts
    │   │   │   ├── FileInput.tsx
    │   │   │   └── FileInputNative.tsx
    │   │   ├── FileUploadDropZone
    │   │   │   ├── FileUploadDropZone.md
    │   │   │   ├── FileUploadDropZone.module.scss
    │   │   │   ├── FileUploadDropZone.spec.ts
    │   │   │   ├── FileUploadDropZone.tsx
    │   │   │   └── FileUploadDropZoneNative.tsx
    │   │   ├── FlowLayout
    │   │   │   ├── FlowLayout.md
    │   │   │   ├── FlowLayout.module.scss
    │   │   │   ├── FlowLayout.spec.ts
    │   │   │   ├── FlowLayout.spec.ts-snapshots
    │   │   │   │   └── Edge-cases-boxShadow-is-not-clipped-1-non-smoke-darwin.png
    │   │   │   ├── FlowLayout.tsx
    │   │   │   └── FlowLayoutNative.tsx
    │   │   ├── Footer
    │   │   │   ├── Footer.md
    │   │   │   ├── Footer.module.scss
    │   │   │   ├── Footer.spec.ts
    │   │   │   ├── Footer.tsx
    │   │   │   └── FooterNative.tsx
    │   │   ├── Form
    │   │   │   ├── Form.md
    │   │   │   ├── Form.module.scss
    │   │   │   ├── Form.spec.ts
    │   │   │   ├── Form.tsx
    │   │   │   ├── formActions.ts
    │   │   │   ├── FormContext.ts
    │   │   │   └── FormNative.tsx
    │   │   ├── FormItem
    │   │   │   ├── FormItem.md
    │   │   │   ├── FormItem.module.scss
    │   │   │   ├── FormItem.spec.ts
    │   │   │   ├── FormItem.tsx
    │   │   │   ├── FormItemNative.tsx
    │   │   │   ├── HelperText.module.scss
    │   │   │   ├── HelperText.tsx
    │   │   │   ├── ItemWithLabel.tsx
    │   │   │   └── Validations.ts
    │   │   ├── FormSection
    │   │   │   ├── FormSection.md
    │   │   │   ├── FormSection.ts
    │   │   │   └── FormSection.xmlui
    │   │   ├── Fragment
    │   │   │   ├── Fragment.spec.ts
    │   │   │   └── Fragment.tsx
    │   │   ├── Heading
    │   │   │   ├── abstractions.ts
    │   │   │   ├── H1.md
    │   │   │   ├── H1.spec.ts
    │   │   │   ├── H2.md
    │   │   │   ├── H2.spec.ts
    │   │   │   ├── H3.md
    │   │   │   ├── H3.spec.ts
    │   │   │   ├── H4.md
    │   │   │   ├── H4.spec.ts
    │   │   │   ├── H5.md
    │   │   │   ├── H5.spec.ts
    │   │   │   ├── H6.md
    │   │   │   ├── H6.spec.ts
    │   │   │   ├── Heading.md
    │   │   │   ├── Heading.module.scss
    │   │   │   ├── Heading.spec.ts
    │   │   │   ├── Heading.tsx
    │   │   │   └── HeadingNative.tsx
    │   │   ├── HoverCard
    │   │   │   ├── HoverCard.tsx
    │   │   │   └── HovercardNative.tsx
    │   │   ├── HtmlTags
    │   │   │   ├── HtmlTags.module.scss
    │   │   │   ├── HtmlTags.spec.ts
    │   │   │   └── HtmlTags.tsx
    │   │   ├── Icon
    │   │   │   ├── AdmonitionDanger.tsx
    │   │   │   ├── AdmonitionInfo.tsx
    │   │   │   ├── AdmonitionNote.tsx
    │   │   │   ├── AdmonitionTip.tsx
    │   │   │   ├── AdmonitionWarning.tsx
    │   │   │   ├── ApiIcon.tsx
    │   │   │   ├── ArrowDropDown.module.scss
    │   │   │   ├── ArrowDropDown.tsx
    │   │   │   ├── ArrowDropUp.module.scss
    │   │   │   ├── ArrowDropUp.tsx
    │   │   │   ├── ArrowLeft.module.scss
    │   │   │   ├── ArrowLeft.tsx
    │   │   │   ├── ArrowRight.module.scss
    │   │   │   ├── ArrowRight.tsx
    │   │   │   ├── Attach.tsx
    │   │   │   ├── Binding.module.scss
    │   │   │   ├── Binding.tsx
    │   │   │   ├── BoardIcon.tsx
    │   │   │   ├── BoxIcon.tsx
    │   │   │   ├── CheckIcon.tsx
    │   │   │   ├── ChevronDownIcon.tsx
    │   │   │   ├── ChevronLeft.tsx
    │   │   │   ├── ChevronRight.tsx
    │   │   │   ├── ChevronUpIcon.tsx
    │   │   │   ├── CodeFileIcon.tsx
    │   │   │   ├── CodeSandbox.tsx
    │   │   │   ├── CompactListIcon.tsx
    │   │   │   ├── ContentCopyIcon.tsx
    │   │   │   ├── DarkToLightIcon.tsx
    │   │   │   ├── DatabaseIcon.module.scss
    │   │   │   ├── DatabaseIcon.tsx
    │   │   │   ├── DocFileIcon.tsx
    │   │   │   ├── DocIcon.tsx
    │   │   │   ├── DotMenuHorizontalIcon.tsx
    │   │   │   ├── DotMenuIcon.tsx
    │   │   │   ├── EmailIcon.tsx
    │   │   │   ├── EmptyFolderIcon.tsx
    │   │   │   ├── ErrorIcon.tsx
    │   │   │   ├── ExpressionIcon.tsx
    │   │   │   ├── FillPlusCricleIcon.tsx
    │   │   │   ├── FilterIcon.tsx
    │   │   │   ├── FolderIcon.tsx
    │   │   │   ├── GlobeIcon.tsx
    │   │   │   ├── HomeIcon.tsx
    │   │   │   ├── HyperLinkIcon.tsx
    │   │   │   ├── Icon.md
    │   │   │   ├── Icon.module.scss
    │   │   │   ├── Icon.spec.ts
    │   │   │   ├── Icon.tsx
    │   │   │   ├── IconNative.tsx
    │   │   │   ├── ImageFileIcon.tsx
    │   │   │   ├── Inspect.tsx
    │   │   │   ├── LightToDark.tsx
    │   │   │   ├── LinkIcon.tsx
    │   │   │   ├── ListIcon.tsx
    │   │   │   ├── LooseListIcon.tsx
    │   │   │   ├── MoonIcon.tsx
    │   │   │   ├── MoreOptionsIcon.tsx
    │   │   │   ├── NoSortIcon.tsx
    │   │   │   ├── PDFIcon.tsx
    │   │   │   ├── PenIcon.tsx
    │   │   │   ├── PhoneIcon.tsx
    │   │   │   ├── PhotoIcon.tsx
    │   │   │   ├── PlusIcon.tsx
    │   │   │   ├── SearchIcon.tsx
    │   │   │   ├── ShareIcon.tsx
    │   │   │   ├── SortAscendingIcon.tsx
    │   │   │   ├── SortDescendingIcon.tsx
    │   │   │   ├── StarsIcon.tsx
    │   │   │   ├── SunIcon.tsx
    │   │   │   ├── svg
    │   │   │   │   ├── admonition_danger.svg
    │   │   │   │   ├── admonition_info.svg
    │   │   │   │   ├── admonition_note.svg
    │   │   │   │   ├── admonition_tip.svg
    │   │   │   │   ├── admonition_warning.svg
    │   │   │   │   ├── api.svg
    │   │   │   │   ├── arrow-dropdown.svg
    │   │   │   │   ├── arrow-left.svg
    │   │   │   │   ├── arrow-right.svg
    │   │   │   │   ├── arrow-up.svg
    │   │   │   │   ├── attach.svg
    │   │   │   │   ├── binding.svg
    │   │   │   │   ├── box.svg
    │   │   │   │   ├── bulb.svg
    │   │   │   │   ├── code-file.svg
    │   │   │   │   ├── code-sandbox.svg
    │   │   │   │   ├── dark_to_light.svg
    │   │   │   │   ├── database.svg
    │   │   │   │   ├── doc.svg
    │   │   │   │   ├── empty-folder.svg
    │   │   │   │   ├── expression.svg
    │   │   │   │   ├── eye-closed.svg
    │   │   │   │   ├── eye-dark.svg
    │   │   │   │   ├── eye.svg
    │   │   │   │   ├── file-text.svg
    │   │   │   │   ├── filter.svg
    │   │   │   │   ├── folder.svg
    │   │   │   │   ├── img.svg
    │   │   │   │   ├── inspect.svg
    │   │   │   │   ├── light_to_dark.svg
    │   │   │   │   ├── moon.svg
    │   │   │   │   ├── pdf.svg
    │   │   │   │   ├── photo.svg
    │   │   │   │   ├── share.svg
    │   │   │   │   ├── stars.svg
    │   │   │   │   ├── sun.svg
    │   │   │   │   ├── trending-down.svg
    │   │   │   │   ├── trending-level.svg
    │   │   │   │   ├── trending-up.svg
    │   │   │   │   ├── txt.svg
    │   │   │   │   ├── unknown-file.svg
    │   │   │   │   ├── unlink.svg
    │   │   │   │   └── xls.svg
    │   │   │   ├── TableDeleteColumnIcon.tsx
    │   │   │   ├── TableDeleteRowIcon.tsx
    │   │   │   ├── TableInsertColumnIcon.tsx
    │   │   │   ├── TableInsertRowIcon.tsx
    │   │   │   ├── TrashIcon.tsx
    │   │   │   ├── TrendingDownIcon.tsx
    │   │   │   ├── TrendingLevelIcon.tsx
    │   │   │   ├── TrendingUpIcon.tsx
    │   │   │   ├── TxtIcon.tsx
    │   │   │   ├── UnknownFileIcon.tsx
    │   │   │   ├── UnlinkIcon.tsx
    │   │   │   ├── UserIcon.tsx
    │   │   │   ├── WarningIcon.tsx
    │   │   │   └── XlsIcon.tsx
    │   │   ├── IconProvider.tsx
    │   │   ├── IconRegistryContext.tsx
    │   │   ├── IFrame
    │   │   │   ├── IFrame.md
    │   │   │   ├── IFrame.module.scss
    │   │   │   ├── IFrame.spec.ts
    │   │   │   ├── IFrame.tsx
    │   │   │   └── IFrameNative.tsx
    │   │   ├── Image
    │   │   │   ├── Image.md
    │   │   │   ├── Image.module.scss
    │   │   │   ├── Image.spec.ts
    │   │   │   ├── Image.tsx
    │   │   │   └── ImageNative.tsx
    │   │   ├── Input
    │   │   │   ├── index.ts
    │   │   │   ├── InputAdornment.module.scss
    │   │   │   ├── InputAdornment.tsx
    │   │   │   ├── InputDivider.module.scss
    │   │   │   ├── InputDivider.tsx
    │   │   │   ├── InputLabel.module.scss
    │   │   │   ├── InputLabel.tsx
    │   │   │   ├── PartialInput.module.scss
    │   │   │   └── PartialInput.tsx
    │   │   ├── InspectButton
    │   │   │   ├── InspectButton.module.scss
    │   │   │   └── InspectButton.tsx
    │   │   ├── Items
    │   │   │   ├── Items.md
    │   │   │   ├── Items.spec.ts
    │   │   │   ├── Items.tsx
    │   │   │   └── ItemsNative.tsx
    │   │   ├── Link
    │   │   │   ├── Link.md
    │   │   │   ├── Link.module.scss
    │   │   │   ├── Link.spec.ts
    │   │   │   ├── Link.tsx
    │   │   │   └── LinkNative.tsx
    │   │   ├── List
    │   │   │   ├── doc-resources
    │   │   │   │   └── list-component-data.js
    │   │   │   ├── List.md
    │   │   │   ├── List.module.scss
    │   │   │   ├── List.spec.ts
    │   │   │   ├── List.tsx
    │   │   │   └── ListNative.tsx
    │   │   ├── Logo
    │   │   │   ├── doc-resources
    │   │   │   │   └── xmlui-logo.svg
    │   │   │   ├── Logo.md
    │   │   │   ├── Logo.tsx
    │   │   │   └── LogoNative.tsx
    │   │   ├── Markdown
    │   │   │   ├── CodeText.module.scss
    │   │   │   ├── CodeText.tsx
    │   │   │   ├── Markdown.md
    │   │   │   ├── Markdown.module.scss
    │   │   │   ├── Markdown.spec.ts
    │   │   │   ├── Markdown.tsx
    │   │   │   ├── MarkdownNative.tsx
    │   │   │   ├── parse-binding-expr.ts
    │   │   │   └── utils.ts
    │   │   ├── metadata-helpers.ts
    │   │   ├── ModalDialog
    │   │   │   ├── ConfirmationModalContextProvider.tsx
    │   │   │   ├── Dialog.module.scss
    │   │   │   ├── Dialog.tsx
    │   │   │   ├── ModalDialog.md
    │   │   │   ├── ModalDialog.module.scss
    │   │   │   ├── ModalDialog.spec.ts
    │   │   │   ├── ModalDialog.tsx
    │   │   │   ├── ModalDialogNative.tsx
    │   │   │   └── ModalVisibilityContext.tsx
    │   │   ├── NavGroup
    │   │   │   ├── NavGroup.md
    │   │   │   ├── NavGroup.module.scss
    │   │   │   ├── NavGroup.spec.ts
    │   │   │   ├── NavGroup.tsx
    │   │   │   ├── NavGroupContext.ts
    │   │   │   └── NavGroupNative.tsx
    │   │   ├── NavLink
    │   │   │   ├── NavLink.md
    │   │   │   ├── NavLink.module.scss
    │   │   │   ├── NavLink.spec.ts
    │   │   │   ├── NavLink.tsx
    │   │   │   └── NavLinkNative.tsx
    │   │   ├── NavPanel
    │   │   │   ├── NavPanel.md
    │   │   │   ├── NavPanel.module.scss
    │   │   │   ├── NavPanel.spec.ts
    │   │   │   ├── NavPanel.tsx
    │   │   │   └── NavPanelNative.tsx
    │   │   ├── NestedApp
    │   │   │   ├── AppWithCodeView.module.scss
    │   │   │   ├── AppWithCodeView.tsx
    │   │   │   ├── AppWithCodeViewNative.tsx
    │   │   │   ├── defaultProps.tsx
    │   │   │   ├── logo.svg
    │   │   │   ├── NestedApp.module.scss
    │   │   │   ├── NestedApp.tsx
    │   │   │   ├── NestedAppNative.tsx
    │   │   │   ├── Tooltip.module.scss
    │   │   │   ├── Tooltip.tsx
    │   │   │   └── utils.ts
    │   │   ├── NoResult
    │   │   │   ├── NoResult.md
    │   │   │   ├── NoResult.module.scss
    │   │   │   ├── NoResult.spec.ts
    │   │   │   ├── NoResult.tsx
    │   │   │   └── NoResultNative.tsx
    │   │   ├── NumberBox
    │   │   │   ├── numberbox-abstractions.ts
    │   │   │   ├── NumberBox.md
    │   │   │   ├── NumberBox.module.scss
    │   │   │   ├── NumberBox.spec.ts
    │   │   │   ├── NumberBox.tsx
    │   │   │   └── NumberBoxNative.tsx
    │   │   ├── Option
    │   │   │   ├── Option.md
    │   │   │   ├── Option.spec.ts
    │   │   │   ├── Option.tsx
    │   │   │   ├── OptionNative.tsx
    │   │   │   └── OptionTypeProvider.tsx
    │   │   ├── PageMetaTitle
    │   │   │   ├── PageMetaTilteNative.tsx
    │   │   │   ├── PageMetaTitle.md
    │   │   │   ├── PageMetaTitle.spec.ts
    │   │   │   └── PageMetaTitle.tsx
    │   │   ├── Pages
    │   │   │   ├── Page.md
    │   │   │   ├── Pages.md
    │   │   │   ├── Pages.module.scss
    │   │   │   ├── Pages.tsx
    │   │   │   └── PagesNative.tsx
    │   │   ├── Pagination
    │   │   │   ├── Pagination.md
    │   │   │   ├── Pagination.module.scss
    │   │   │   ├── Pagination.spec.ts
    │   │   │   ├── Pagination.tsx
    │   │   │   └── PaginationNative.tsx
    │   │   ├── PositionedContainer
    │   │   │   ├── PositionedContainer.module.scss
    │   │   │   ├── PositionedContainer.tsx
    │   │   │   └── PositionedContainerNative.tsx
    │   │   ├── ProfileMenu
    │   │   │   ├── ProfileMenu.module.scss
    │   │   │   └── ProfileMenu.tsx
    │   │   ├── ProgressBar
    │   │   │   ├── ProgressBar.md
    │   │   │   ├── ProgressBar.module.scss
    │   │   │   ├── ProgressBar.spec.ts
    │   │   │   ├── ProgressBar.tsx
    │   │   │   └── ProgressBarNative.tsx
    │   │   ├── Queue
    │   │   │   ├── Queue.md
    │   │   │   ├── Queue.spec.ts
    │   │   │   ├── Queue.tsx
    │   │   │   ├── queueActions.ts
    │   │   │   └── QueueNative.tsx
    │   │   ├── RadioGroup
    │   │   │   ├── RadioGroup.md
    │   │   │   ├── RadioGroup.module.scss
    │   │   │   ├── RadioGroup.spec.ts
    │   │   │   ├── RadioGroup.tsx
    │   │   │   ├── RadioGroupNative.tsx
    │   │   │   ├── RadioItem.tsx
    │   │   │   └── RadioItemNative.tsx
    │   │   ├── RealTimeAdapter
    │   │   │   ├── RealTimeAdapter.tsx
    │   │   │   └── RealTimeAdapterNative.tsx
    │   │   ├── Redirect
    │   │   │   ├── Redirect.md
    │   │   │   ├── Redirect.spec.ts
    │   │   │   └── Redirect.tsx
    │   │   ├── ResponsiveBar
    │   │   │   ├── README.md
    │   │   │   ├── ResponsiveBar.md
    │   │   │   ├── ResponsiveBar.module.scss
    │   │   │   ├── ResponsiveBar.spec.ts
    │   │   │   ├── ResponsiveBar.tsx
    │   │   │   └── ResponsiveBarNative.tsx
    │   │   ├── Select
    │   │   │   ├── HiddenOption.tsx
    │   │   │   ├── OptionContext.ts
    │   │   │   ├── Select.md
    │   │   │   ├── Select.module.scss
    │   │   │   ├── Select.spec.ts
    │   │   │   ├── Select.tsx
    │   │   │   ├── SelectContext.tsx
    │   │   │   └── SelectNative.tsx
    │   │   ├── SelectionStore
    │   │   │   ├── SelectionStore.md
    │   │   │   ├── SelectionStore.tsx
    │   │   │   └── SelectionStoreNative.tsx
    │   │   ├── Slider
    │   │   │   ├── Slider.md
    │   │   │   ├── Slider.module.scss
    │   │   │   ├── Slider.spec.ts
    │   │   │   ├── Slider.tsx
    │   │   │   └── SliderNative.tsx
    │   │   ├── Slot
    │   │   │   ├── Slot.md
    │   │   │   ├── Slot.spec.ts
    │   │   │   └── Slot.ts
    │   │   ├── SlotItem.tsx
    │   │   ├── SpaceFiller
    │   │   │   ├── SpaceFiller.md
    │   │   │   ├── SpaceFiller.module.scss
    │   │   │   ├── SpaceFiller.spec.ts
    │   │   │   ├── SpaceFiller.tsx
    │   │   │   └── SpaceFillerNative.tsx
    │   │   ├── Spinner
    │   │   │   ├── Spinner.md
    │   │   │   ├── Spinner.module.scss
    │   │   │   ├── Spinner.spec.ts
    │   │   │   ├── Spinner.tsx
    │   │   │   └── SpinnerNative.tsx
    │   │   ├── Splitter
    │   │   │   ├── HSplitter.md
    │   │   │   ├── HSplitter.spec.ts
    │   │   │   ├── Splitter.md
    │   │   │   ├── Splitter.module.scss
    │   │   │   ├── Splitter.spec.ts
    │   │   │   ├── Splitter.tsx
    │   │   │   ├── SplitterNative.tsx
    │   │   │   ├── utils.ts
    │   │   │   ├── VSplitter.md
    │   │   │   └── VSplitter.spec.ts
    │   │   ├── Stack
    │   │   │   ├── CHStack.md
    │   │   │   ├── CHStack.spec.ts
    │   │   │   ├── CVStack.md
    │   │   │   ├── CVStack.spec.ts
    │   │   │   ├── HStack.md
    │   │   │   ├── HStack.spec.ts
    │   │   │   ├── Stack.md
    │   │   │   ├── Stack.module.scss
    │   │   │   ├── Stack.spec.ts
    │   │   │   ├── Stack.tsx
    │   │   │   ├── StackNative.tsx
    │   │   │   ├── VStack.md
    │   │   │   └── VStack.spec.ts
    │   │   ├── StickyBox
    │   │   │   ├── StickyBox.md
    │   │   │   ├── StickyBox.module.scss
    │   │   │   ├── StickyBox.tsx
    │   │   │   └── StickyBoxNative.tsx
    │   │   ├── Switch
    │   │   │   ├── Switch.md
    │   │   │   ├── Switch.spec.ts
    │   │   │   └── Switch.tsx
    │   │   ├── Table
    │   │   │   ├── doc-resources
    │   │   │   │   └── list-component-data.js
    │   │   │   ├── react-table-config.d.ts
    │   │   │   ├── Table.md
    │   │   │   ├── Table.module.scss
    │   │   │   ├── Table.spec.ts
    │   │   │   ├── Table.tsx
    │   │   │   ├── TableNative.tsx
    │   │   │   └── useRowSelection.tsx
    │   │   ├── TableOfContents
    │   │   │   ├── TableOfContents.module.scss
    │   │   │   ├── TableOfContents.spec.ts
    │   │   │   ├── TableOfContents.tsx
    │   │   │   └── TableOfContentsNative.tsx
    │   │   ├── Tabs
    │   │   │   ├── TabContext.tsx
    │   │   │   ├── TabItem.md
    │   │   │   ├── TabItem.tsx
    │   │   │   ├── TabItemNative.tsx
    │   │   │   ├── Tabs.md
    │   │   │   ├── Tabs.module.scss
    │   │   │   ├── Tabs.spec.ts
    │   │   │   ├── Tabs.tsx
    │   │   │   └── TabsNative.tsx
    │   │   ├── Text
    │   │   │   ├── Text.md
    │   │   │   ├── Text.module.scss
    │   │   │   ├── Text.spec.ts
    │   │   │   ├── Text.tsx
    │   │   │   └── TextNative.tsx
    │   │   ├── TextArea
    │   │   │   ├── TextArea.md
    │   │   │   ├── TextArea.module.scss
    │   │   │   ├── TextArea.spec.ts
    │   │   │   ├── TextArea.tsx
    │   │   │   ├── TextAreaNative.tsx
    │   │   │   ├── TextAreaResizable.tsx
    │   │   │   └── useComposedRef.ts
    │   │   ├── TextBox
    │   │   │   ├── TextBox.md
    │   │   │   ├── TextBox.module.scss
    │   │   │   ├── TextBox.spec.ts
    │   │   │   ├── TextBox.tsx
    │   │   │   └── TextBoxNative.tsx
    │   │   ├── Theme
    │   │   │   ├── NotificationToast.tsx
    │   │   │   ├── Theme.md
    │   │   │   ├── Theme.module.scss
    │   │   │   ├── Theme.spec.ts
    │   │   │   ├── Theme.tsx
    │   │   │   └── ThemeNative.tsx
    │   │   ├── TimeInput
    │   │   │   ├── TimeInput.md
    │   │   │   ├── TimeInput.module.scss
    │   │   │   ├── TimeInput.spec.ts
    │   │   │   ├── TimeInput.tsx
    │   │   │   ├── TimeInputNative.tsx
    │   │   │   └── utils.ts
    │   │   ├── Timer
    │   │   │   ├── Timer.md
    │   │   │   ├── Timer.spec.ts
    │   │   │   ├── Timer.tsx
    │   │   │   └── TimerNative.tsx
    │   │   ├── Toggle
    │   │   │   ├── Toggle.module.scss
    │   │   │   └── Toggle.tsx
    │   │   ├── ToneChangerButton
    │   │   │   ├── ToneChangerButton.md
    │   │   │   ├── ToneChangerButton.spec.ts
    │   │   │   └── ToneChangerButton.tsx
    │   │   ├── ToneSwitch
    │   │   │   ├── ToneSwitch.md
    │   │   │   ├── ToneSwitch.module.scss
    │   │   │   ├── ToneSwitch.spec.ts
    │   │   │   ├── ToneSwitch.tsx
    │   │   │   └── ToneSwitchNative.tsx
    │   │   ├── Tooltip
    │   │   │   ├── Tooltip.md
    │   │   │   ├── Tooltip.module.scss
    │   │   │   ├── Tooltip.spec.ts
    │   │   │   ├── Tooltip.tsx
    │   │   │   └── TooltipNative.tsx
    │   │   ├── Tree
    │   │   │   ├── testData.ts
    │   │   │   ├── Tree-dynamic.spec.ts
    │   │   │   ├── Tree-icons.spec.ts
    │   │   │   ├── Tree.md
    │   │   │   ├── Tree.spec.ts
    │   │   │   ├── TreeComponent.module.scss
    │   │   │   ├── TreeComponent.tsx
    │   │   │   └── TreeNative.tsx
    │   │   ├── TreeDisplay
    │   │   │   ├── TreeDisplay.md
    │   │   │   ├── TreeDisplay.module.scss
    │   │   │   ├── TreeDisplay.tsx
    │   │   │   └── TreeDisplayNative.tsx
    │   │   ├── ValidationSummary
    │   │   │   ├── ValidationSummary.module.scss
    │   │   │   └── ValidationSummary.tsx
    │   │   └── VisuallyHidden.tsx
    │   ├── components-core
    │   │   ├── abstractions
    │   │   │   ├── ComponentRenderer.ts
    │   │   │   ├── LoaderRenderer.ts
    │   │   │   ├── standalone.ts
    │   │   │   └── treeAbstractions.ts
    │   │   ├── action
    │   │   │   ├── actions.ts
    │   │   │   ├── APICall.tsx
    │   │   │   ├── FileDownloadAction.tsx
    │   │   │   ├── FileUploadAction.tsx
    │   │   │   ├── NavigateAction.tsx
    │   │   │   └── TimedAction.tsx
    │   │   ├── ApiBoundComponent.tsx
    │   │   ├── appContext
    │   │   │   ├── date-functions.ts
    │   │   │   ├── math-function.ts
    │   │   │   └── misc-utils.ts
    │   │   ├── AppContext.tsx
    │   │   ├── behaviors
    │   │   │   ├── Behavior.tsx
    │   │   │   └── CoreBehaviors.tsx
    │   │   ├── component-hooks.ts
    │   │   ├── ComponentDecorator.tsx
    │   │   ├── ComponentViewer.tsx
    │   │   ├── CompoundComponent.tsx
    │   │   ├── constants.ts
    │   │   ├── DebugViewProvider.tsx
    │   │   ├── descriptorHelper.ts
    │   │   ├── devtools
    │   │   │   ├── InspectorDialog.module.scss
    │   │   │   ├── InspectorDialog.tsx
    │   │   │   └── InspectorDialogVisibilityContext.tsx
    │   │   ├── EngineError.ts
    │   │   ├── event-handlers.ts
    │   │   ├── InspectorButton.module.scss
    │   │   ├── InspectorContext.tsx
    │   │   ├── interception
    │   │   │   ├── abstractions.ts
    │   │   │   ├── ApiInterceptor.ts
    │   │   │   ├── ApiInterceptorProvider.tsx
    │   │   │   ├── apiInterceptorWorker.ts
    │   │   │   ├── Backend.ts
    │   │   │   ├── Errors.ts
    │   │   │   ├── IndexedDb.ts
    │   │   │   ├── initMock.ts
    │   │   │   ├── InMemoryDb.ts
    │   │   │   ├── ReadonlyCollection.ts
    │   │   │   └── useApiInterceptorContext.tsx
    │   │   ├── loader
    │   │   │   ├── ApiLoader.tsx
    │   │   │   ├── DataLoader.tsx
    │   │   │   ├── ExternalDataLoader.tsx
    │   │   │   ├── Loader.tsx
    │   │   │   ├── MockLoaderRenderer.tsx
    │   │   │   └── PageableLoader.tsx
    │   │   ├── LoaderComponent.tsx
    │   │   ├── markup-check.ts
    │   │   ├── parts.ts
    │   │   ├── renderers.ts
    │   │   ├── rendering
    │   │   │   ├── AppContent.tsx
    │   │   │   ├── AppRoot.tsx
    │   │   │   ├── AppWrapper.tsx
    │   │   │   ├── buildProxy.ts
    │   │   │   ├── collectFnVarDeps.ts
    │   │   │   ├── ComponentAdapter.tsx
    │   │   │   ├── ComponentWrapper.tsx
    │   │   │   ├── Container.tsx
    │   │   │   ├── containers.ts
    │   │   │   ├── ContainerWrapper.tsx
    │   │   │   ├── ErrorBoundary.module.scss
    │   │   │   ├── ErrorBoundary.tsx
    │   │   │   ├── InvalidComponent.module.scss
    │   │   │   ├── InvalidComponent.tsx
    │   │   │   ├── nodeUtils.ts
    │   │   │   ├── reducer.ts
    │   │   │   ├── renderChild.tsx
    │   │   │   ├── StandaloneComponent.tsx
    │   │   │   ├── StateContainer.tsx
    │   │   │   ├── UnknownComponent.module.scss
    │   │   │   ├── UnknownComponent.tsx
    │   │   │   └── valueExtractor.ts
    │   │   ├── reportEngineError.ts
    │   │   ├── RestApiProxy.ts
    │   │   ├── script-runner
    │   │   │   ├── asyncProxy.ts
    │   │   │   ├── AttributeValueParser.ts
    │   │   │   ├── bannedFunctions.ts
    │   │   │   ├── BindingTreeEvaluationContext.ts
    │   │   │   ├── eval-tree-async.ts
    │   │   │   ├── eval-tree-common.ts
    │   │   │   ├── eval-tree-sync.ts
    │   │   │   ├── ParameterParser.ts
    │   │   │   ├── process-statement-async.ts
    │   │   │   ├── process-statement-common.ts
    │   │   │   ├── process-statement-sync.ts
    │   │   │   ├── ScriptingSourceTree.ts
    │   │   │   ├── simplify-expression.ts
    │   │   │   ├── statement-queue.ts
    │   │   │   └── visitors.ts
    │   │   ├── StandaloneApp.tsx
    │   │   ├── StandaloneExtensionManager.ts
    │   │   ├── TableOfContentsContext.tsx
    │   │   ├── theming
    │   │   │   ├── _themes.scss
    │   │   │   ├── component-layout-resolver.ts
    │   │   │   ├── extendThemeUtils.ts
    │   │   │   ├── hvar.ts
    │   │   │   ├── layout-resolver.ts
    │   │   │   ├── parse-layout-props.ts
    │   │   │   ├── StyleContext.tsx
    │   │   │   ├── StyleRegistry.ts
    │   │   │   ├── ThemeContext.tsx
    │   │   │   ├── ThemeProvider.tsx
    │   │   │   ├── themes
    │   │   │   │   ├── base-utils.ts
    │   │   │   │   ├── palette.ts
    │   │   │   │   ├── root.ts
    │   │   │   │   ├── solid.ts
    │   │   │   │   ├── theme-colors.ts
    │   │   │   │   └── xmlui.ts
    │   │   │   ├── themeVars.module.scss
    │   │   │   ├── themeVars.ts
    │   │   │   ├── transformThemeVars.ts
    │   │   │   └── utils.ts
    │   │   ├── utils
    │   │   │   ├── actionUtils.ts
    │   │   │   ├── audio-utils.ts
    │   │   │   ├── base64-utils.ts
    │   │   │   ├── compound-utils.ts
    │   │   │   ├── css-utils.ts
    │   │   │   ├── DataLoaderQueryKeyGenerator.ts
    │   │   │   ├── date-utils.ts
    │   │   │   ├── extractParam.ts
    │   │   │   ├── hooks.tsx
    │   │   │   ├── LruCache.ts
    │   │   │   ├── mergeProps.ts
    │   │   │   ├── misc.ts
    │   │   │   ├── request-params.ts
    │   │   │   ├── statementUtils.ts
    │   │   │   └── treeUtils.ts
    │   │   └── xmlui-parser.ts
    │   ├── index-standalone.ts
    │   ├── index.scss
    │   ├── index.ts
    │   ├── language-server
    │   │   ├── server-common.ts
    │   │   ├── server-web-worker.ts
    │   │   ├── server.ts
    │   │   ├── services
    │   │   │   ├── common
    │   │   │   │   ├── docs-generation.ts
    │   │   │   │   ├── lsp-utils.ts
    │   │   │   │   ├── metadata-utils.ts
    │   │   │   │   └── syntax-node-utilities.ts
    │   │   │   ├── completion.ts
    │   │   │   ├── diagnostic.ts
    │   │   │   ├── format.ts
    │   │   │   └── hover.ts
    │   │   └── xmlui-metadata-generated.js
    │   ├── logging
    │   │   ├── LoggerContext.tsx
    │   │   ├── LoggerInitializer.tsx
    │   │   ├── LoggerService.ts
    │   │   └── xmlui.ts
    │   ├── logo.svg
    │   ├── parsers
    │   │   ├── common
    │   │   │   ├── GenericToken.ts
    │   │   │   ├── InputStream.ts
    │   │   │   └── utils.ts
    │   │   ├── scripting
    │   │   │   ├── code-behind-collect.ts
    │   │   │   ├── Lexer.ts
    │   │   │   ├── modules.ts
    │   │   │   ├── Parser.ts
    │   │   │   ├── ParserError.ts
    │   │   │   ├── ScriptingNodeTypes.ts
    │   │   │   ├── TokenTrait.ts
    │   │   │   ├── TokenType.ts
    │   │   │   └── tree-visitor.ts
    │   │   ├── style-parser
    │   │   │   ├── errors.ts
    │   │   │   ├── source-tree.ts
    │   │   │   ├── StyleInputStream.ts
    │   │   │   ├── StyleLexer.ts
    │   │   │   ├── StyleParser.ts
    │   │   │   └── tokens.ts
    │   │   └── xmlui-parser
    │   │       ├── CharacterCodes.ts
    │   │       ├── diagnostics.ts
    │   │       ├── fileExtensions.ts
    │   │       ├── index.ts
    │   │       ├── lint.ts
    │   │       ├── parser.ts
    │   │       ├── ParserError.ts
    │   │       ├── scanner.ts
    │   │       ├── syntax-kind.ts
    │   │       ├── syntax-node.ts
    │   │       ├── transform.ts
    │   │       ├── utils.ts
    │   │       ├── xmlui-serializer.ts
    │   │       └── xmlui-tree.ts
    │   ├── react-app-env.d.ts
    │   ├── syntax
    │   │   ├── monaco
    │   │   │   ├── grammar.monacoLanguage.ts
    │   │   │   ├── index.ts
    │   │   │   ├── xmlui-dark.ts
    │   │   │   ├── xmlui-light.ts
    │   │   │   └── xmluiscript.monacoLanguage.ts
    │   │   └── textMate
    │   │       ├── index.ts
    │   │       ├── xmlui-dark.json
    │   │       ├── xmlui-light.json
    │   │       ├── xmlui.json
    │   │       └── xmlui.tmLanguage.json
    │   ├── testing
    │   │   ├── assertions.ts
    │   │   ├── component-test-helpers.ts
    │   │   ├── ComponentDrivers.ts
    │   │   ├── drivers
    │   │   │   ├── DateInputDriver.ts
    │   │   │   ├── index.ts
    │   │   │   ├── ModalDialogDriver.ts
    │   │   │   ├── NumberBoxDriver.ts
    │   │   │   ├── TextBoxDriver.ts
    │   │   │   ├── TimeInputDriver.ts
    │   │   │   ├── TimerDriver.ts
    │   │   │   └── TreeDriver.ts
    │   │   ├── fixtures.ts
    │   │   ├── index.ts
    │   │   ├── infrastructure
    │   │   │   ├── index.html
    │   │   │   ├── main.tsx
    │   │   │   ├── public
    │   │   │   │   ├── mockServiceWorker.js
    │   │   │   │   ├── resources
    │   │   │   │   │   ├── bell.svg
    │   │   │   │   │   ├── box.svg
    │   │   │   │   │   ├── doc.svg
    │   │   │   │   │   ├── eye.svg
    │   │   │   │   │   ├── flower-640x480.jpg
    │   │   │   │   │   ├── sun.svg
    │   │   │   │   │   ├── test-image-100x100.jpg
    │   │   │   │   │   └── txt.svg
    │   │   │   │   └── serve.json
    │   │   │   └── TestBed.tsx
    │   │   └── themed-app-test-helpers.ts
    │   └── vite-env.d.ts
    ├── tests
    │   ├── components
    │   │   ├── CodeBlock
    │   │   │   └── hightlight-code.test.ts
    │   │   ├── playground-pattern.test.ts
    │   │   └── Tree
    │   │       └── Tree-states.test.ts
    │   ├── components-core
    │   │   ├── abstractions
    │   │   │   └── treeAbstractions.test.ts
    │   │   ├── container
    │   │   │   └── buildProxy.test.ts
    │   │   ├── interception
    │   │   │   ├── orderBy.test.ts
    │   │   │   ├── ReadOnlyCollection.test.ts
    │   │   │   └── request-param-converter.test.ts
    │   │   ├── scripts-runner
    │   │   │   ├── AttributeValueParser.test.ts
    │   │   │   ├── eval-tree-arrow-async.test.ts
    │   │   │   ├── eval-tree-arrow.test.ts
    │   │   │   ├── eval-tree-func-decl-async.test.ts
    │   │   │   ├── eval-tree-func-decl.test.ts
    │   │   │   ├── eval-tree-pre-post.test.ts
    │   │   │   ├── eval-tree-regression.test.ts
    │   │   │   ├── eval-tree.test.ts
    │   │   │   ├── function-proxy.test.ts
    │   │   │   ├── parser-regression.test.ts
    │   │   │   ├── process-event.test.ts
    │   │   │   ├── process-function.test.ts
    │   │   │   ├── process-implicit-context.test.ts
    │   │   │   ├── process-statement-asgn.test.ts
    │   │   │   ├── process-statement-destruct.test.ts
    │   │   │   ├── process-statement-regs.test.ts
    │   │   │   ├── process-statement-sync.test.ts
    │   │   │   ├── process-statement.test.ts
    │   │   │   ├── process-switch-sync.test.ts
    │   │   │   ├── process-switch.test.ts
    │   │   │   ├── process-try-sync.test.ts
    │   │   │   ├── process-try.test.ts
    │   │   │   └── test-helpers.ts
    │   │   ├── test-metadata-handler.ts
    │   │   ├── theming
    │   │   │   ├── border-segments.test.ts
    │   │   │   ├── component-layout.resolver.test.ts
    │   │   │   ├── layout-property-parser.test.ts
    │   │   │   ├── layout-resolver.test.ts
    │   │   │   ├── layout-resolver2.test.ts
    │   │   │   ├── layout-vp-override.test.ts
    │   │   │   └── padding-segments.test.ts
    │   │   └── utils
    │   │       ├── date-utils.test.ts
    │   │       ├── format-human-elapsed-time.test.ts
    │   │       └── LruCache.test.ts
    │   ├── language-server
    │   │   ├── completion.test.ts
    │   │   ├── format.test.ts
    │   │   ├── hover.test.ts
    │   │   └── mockData.ts
    │   └── parsers
    │       ├── common
    │       │   └── input-stream.test.ts
    │       ├── markdown
    │       │   └── parse-binding-expression.test.ts
    │       ├── parameter-parser.test.ts
    │       ├── paremeter-parser.test.ts
    │       ├── scripting
    │       │   ├── eval-tree-arrow.test.ts
    │       │   ├── eval-tree-pre-post.test.ts
    │       │   ├── eval-tree.test.ts
    │       │   ├── function-proxy.test.ts
    │       │   ├── lexer-literals.test.ts
    │       │   ├── lexer-misc.test.ts
    │       │   ├── module-parse.test.ts
    │       │   ├── parser-arrow.test.ts
    │       │   ├── parser-assignments.test.ts
    │       │   ├── parser-binary.test.ts
    │       │   ├── parser-destructuring.test.ts
    │       │   ├── parser-errors.test.ts
    │       │   ├── parser-expressions.test.ts
    │       │   ├── parser-function.test.ts
    │       │   ├── parser-literals.test.ts
    │       │   ├── parser-primary.test.ts
    │       │   ├── parser-regex.test.ts
    │       │   ├── parser-statements.test.ts
    │       │   ├── parser-unary.test.ts
    │       │   ├── process-event.test.ts
    │       │   ├── process-implicit-context.test.ts
    │       │   ├── process-statement-asgn.test.ts
    │       │   ├── process-statement-destruct.test.ts
    │       │   ├── process-statement-regs.test.ts
    │       │   ├── process-statement-sync.test.ts
    │       │   ├── process-statement.test.ts
    │       │   ├── process-switch-sync.test.ts
    │       │   ├── process-switch.test.ts
    │       │   ├── process-try-sync.test.ts
    │       │   ├── process-try.test.ts
    │       │   ├── simplify-expression.test.ts
    │       │   ├── statement-hooks.test.ts
    │       │   └── test-helpers.ts
    │       ├── style-parser
    │       │   ├── generateHvarChain.test.ts
    │       │   ├── parseHVar.test.ts
    │       │   ├── parser.test.ts
    │       │   └── tokens.test.ts
    │       └── xmlui
    │           ├── lint.test.ts
    │           ├── parser.test.ts
    │           ├── scanner.test.ts
    │           ├── transform.attr.test.ts
    │           ├── transform.circular.test.ts
    │           ├── transform.element.test.ts
    │           ├── transform.errors.test.ts
    │           ├── transform.escape.test.ts
    │           ├── transform.regression.test.ts
    │           ├── transform.script.test.ts
    │           ├── transform.test.ts
    │           └── xmlui.ts
    ├── tests-e2e
    │   ├── api-bound-component-regression.spec.ts
    │   ├── api-call-as-extracted-component.spec.ts
    │   ├── assign-to-object-or-array-regression.spec.ts
    │   ├── binding-regression.spec.ts
    │   ├── children-as-template-context-vars.spec.ts
    │   ├── compound-component.spec.ts
    │   ├── context-vars-regression.spec.ts
    │   ├── data-bindings.spec.ts
    │   ├── datasource-and-api-usage-in-var.spec.ts
    │   ├── datasource-direct-binding.spec.ts
    │   ├── datasource-onLoaded-regression.spec.ts
    │   ├── modify-array-item-regression.spec.ts
    │   ├── namespaces.spec.ts
    │   ├── push-to-array-regression.spec.ts
    │   ├── screen-breakpoints.spec.ts
    │   ├── scripting.spec.ts
    │   ├── state-scope-in-pages.spec.ts
    │   └── state-var-scopes.spec.ts
    ├── tsconfig.bin.json
    ├── tsconfig.json
    ├── tsconfig.node.json
    ├── vite.config.ts
    └── vitest.config.ts
```
# Files
--------------------------------------------------------------------------------
/docs/public/pages/layout.md:
--------------------------------------------------------------------------------
```markdown
  1 | # Layout
  2 | 
  3 | An XMLUI app is a hierarchical component tree in which parent components nest their children. Components like `HStack`, `VStack`, and `FlowLayout` use specialized layout strategies to arrange their children.
  4 | 
  5 | ## Viewport
  6 | 
  7 | Each component has a rectangular UI patch for rendering its content (and nested children). This is the component's **viewport**. The component decides (according to its rendering strategy) how it places its contents into the viewport. It may fill it partially, stretch the content to fill the entire viewport, or even overflow it vertically and/or horizontally.
  8 | 
  9 | The following app contains two components, an `App`, and a `Text`:
 10 | 
 11 | ```xmlui-pg display name="Example: viewport"
 12 | <App border="2px dotted red">
 13 |   <Text width="30%" border="2px dotted green">Hello from XMLUI</Text>
 14 | </App>
 15 | ```
 16 | 
 17 | The borders mark the viewport boundaries of the components:
 18 | 
 19 | - `App`: The dotted red border is the app's viewport boundary. An `App` has the entire browser window as its viewport; however, it reserves some space to the left and right for scrollbars (to avoid viewport resizing when a vertical scrollbar appears or gets removed).
 20 | - `Text`: The dotted green border is the text's viewport boundary. Its parent, `App`, uses some padding around its children.
 21 | 
 22 | ## Orientation
 23 | 
 24 | When rendering its children, a component may render them with vertical or horizontal orientation.
 25 | 
 26 | - Vertical orientation: Each child begins a new row when its parent displays it.
 27 | - Horizontal orientation: Each child appears in the same row as its previous sibling. In case of overflow the component can decide to push the child to a new row.
 28 | 
 29 | `App` uses vertical orientation by default; `HStack` (horizontal stack) uses horizontal orientation.
 30 | 
 31 | 
 32 | ```xmlui-pg display name="Example: orientation"
 33 | <App>
 34 |   <Text>First item</Text>
 35 |   <HStack>
 36 |     <Text>Second item</Text>
 37 |     <Text>Third item</Text>
 38 |     <Text>Fourth item</Text>
 39 |   </HStack>
 40 |   <Text>Fifth item</Text>
 41 | </App>
 42 | ```
 43 | 
 44 | ## Direction
 45 | 
 46 | Some languages (such as Hebrew and Arabic) are read from right to left. XMLUI components use this information to change their children's rendering direction. This example shows right-to-left.
 47 | 
 48 | ```xmlui-pg copy display name="Example: direction" /direction="rtl"/
 49 | <App direction="rtl">
 50 |   <Text>First item</Text>
 51 |   <HStack>
 52 |     <Text>Second item</Text>
 53 |     <Text>Third item</Text>
 54 |     <Text>Fourth item</Text>
 55 |   </HStack>
 56 |   <Text>Fifth item</Text>
 57 | </App>
 58 | ```
 59 | 
 60 | ## Paddings and gaps
 61 | 
 62 | Each component may adjust the padding around children and gaps between adjacent children.
 63 | 
 64 | 
 65 | ```xmlui-pg display name="Example: paddings and gaps"
 66 | <App border="2px dotted red">
 67 |   <Text border="2px dotted green">First item</Text>
 68 |   <HStack border="2px dotted green">
 69 |     <Text border="2px dotted purple">Second item</Text>
 70 |     <Text border="2px dotted purple">Third item</Text>
 71 |     <Text border="2px dotted purple">Fourth item</Text>
 72 |   </HStack>
 73 |   <Text border="2px dotted green">Fifth item</Text>
 74 | </App>
 75 | ```
 76 | 
 77 | - `App` applies vertical and horizontal padding, which is why the top left corner of the red border and the green border do not meet. It also adds gaps, which are the spaces between the green border areas.
 78 | - `HStack` uses no paddings so the top left corner of its green border and the first item's top-left corner (the purple border) meet. Like `App`, `HStack` adds gaps, here shown as spaces between the purple border areas.
 79 | 
 80 | > [!INFO]
 81 | > Web and desktop UI frameworks typically use margins to establish layout. XMLUI layout components do not use margins, they only use paddings and gaps. Although you can use margins, they tend to complicate layouts so use them as a last resort.
 82 | 
 83 | ## Dimensions
 84 | 
 85 | Each component has a default strategy for determining the dimensions (height and width) of its children.
 86 | `VStack` determines its dimensions according to its content. If we want to display a 40px by 60px orange box with nothing in it and 60px wide orange-red box with empty content, we must explicitly set dimensions (and background color).
 87 | 
 88 | ```xmlui-pg display name="Example: dimensions"
 89 | <App>
 90 |   <VStack height="40px" width="60px" backgroundColor="orangered" />
 91 | </App>
 92 | ```
 93 | 
 94 | ## Alignment
 95 | 
 96 | Components can align their children in the viewport both vertically and horizontally.
 97 | 
 98 | ```xmlui-pg display name="Example: alignment" /horizontalAlignment/ /verticalAlignment/
 99 | <App>
100 |   <HStack>
101 |     <VStack 
102 |       width="50%" 
103 |       border="2px dotted red" 
104 |       height="200px" 
105 |       horizontalAlignment="end"
106 |     >
107 |       <Text>Item #1</Text>
108 |       <Text>Item #2</Text>
109 |       <Text>Item #3</Text>
110 |     </VStack>
111 |     <VStack
112 |       width="50%" 
113 |       border="2px 
114 |       dotted green" 
115 |       height="200px" 
116 |       verticalAlignment="center"
117 |     >
118 |       <Text>Item #1</Text>
119 |       <Text>Item #2</Text>
120 |       <Text>Item #3</Text>
121 |     </VStack>
122 |   </HStack>
123 | </App>
124 | ```
125 | 
126 | The component with the red border aligns its children vertically to the start and horizontally to the end. The green-bordered component aligns its children vertically to the center and horizontally to the start.
127 | 
128 | ## Layout containers
129 | 
130 | XMLUI uses only two fundamental layout containers, `Stack`, and `FlowLayout`. All other container-like components (such as `Card`, `List`, and others) apply these to establish more sophisticated layout arrangements.
131 | 
132 | `Stack` is a layout container that uses a particular orientation (vertical or horizontal) to render its children in a single column or row. If the children do not fit into the viewport, they overflow. `Stack` has two specialized variants, `HStack` (horizontal stack) and `VStack` (vertical stack).
133 | 
134 | `FlowLayout` is a layout container that renders its children horizontally while they fit into the current row; otherwise, the child enters a new row. If the children do not fit into the viewport, they overflow.
135 | 
136 | > [!INFO]
137 | > Your application markup must have a single root component. The browser window is an implicit `VStack` layout container with that root element as its single child.
138 | 
139 | ## Dimension units
140 | 
141 | To explicitly control a child's dimensions, instead of it being determined by its content, you can set one or more of these [properties](/styles-and-themes/layout-props): `width`, `height`, `minWidth`, `minHeight`, `maxWidth`, and `maxHeight` using several kinds of values.
142 | 
143 | - **No value**. The layout container determines the default size of the child element according to its strategy.
144 | - **Container-independent size value**. All sizes except percentage (`%`) and star sizes (`*`) belong to this category. The container respects the child's requested size.
145 | - **Percentage size**. The container calculates the child's requested size as a percentage of the viewport's corresponding dimension.
146 | - **Star size**. The child provides a weight the parent container utilizes when distributing the _remaining space_ among its children. The remaining space is the parent viewport's size minus the sum sizes of child components within the first two categories (no value, container-independent size value).
147 | 
148 | ## Gaps
149 | 
150 | The fundamental layout containers apply a default gap ensuring that children have some space between them.
151 | 
152 | ```xmlui-pg copy display name="Example: default gaps"
153 | <App>
154 |   <HStack>
155 |     <Button>First button</Button>
156 |     <Button>Second button</Button>
157 |     <Button>Third button</Button>
158 |   </HStack>
159 | </App>
160 | ```
161 | 
162 | You can remove the gaps.
163 | 
164 | ```xmlui-pg copy display /gap="0"/ name="Example: default gaps removed"
165 | <App>
166 |   <HStack gap="0">
167 |     <Button>First button</Button>
168 |     <Button>Second button</Button>
169 |     <Button>Third button</Button>
170 |   </HStack>
171 | </App>
172 | ```
173 | 
174 | 
175 | XMLUI offers several [predefined gap values](/styles-and-themes/theme-variables#spacing-in-layout-containers). Use these instead of inline literals like "16px" or "0.5rem" to enable theming and consistent design.
176 | 
177 | ```xmlui-pg copy /gap="$gap-tight"/ /gap="$gap-loose"/ name="Example: predefined gap values"
178 | <App>
179 |   <VStack>
180 |     <HStack gap="$gap-tight">
181 |       <Button>First button</Button>
182 |       <Button>Second button</Button>
183 |       <Button>Third button</Button>
184 |     </HStack>
185 |     <HStack gap="$gap-loose">
186 |       <Button>First button</Button>
187 |       <Button>Second button</Button>
188 |       <Button>Third button</Button>
189 |     </HStack>
190 |   </VStack>
191 | </App>
192 | ```
193 | 
194 | ## Rendering children
195 | 
196 | Layout containers render their children in declaration order, subject to the current page direction (left-to-right or right-to-left).
197 | 
198 | This markup displays five boxes; the third is wider than the others.
199 | 
200 | ```xmlui-pg name="Example: VStack"
201 | ---app display copy 
202 | <App>
203 |   <VStack>
204 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
205 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
206 |     <Stack height="20px" width="80%" backgroundColor="orangered" />
207 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
208 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
209 |   </VStack>
210 | </App>
211 | ---desc
212 | In a `VStack` each child takes a new row.
213 | ```
214 | 
215 | 
216 | ```xmlui-pg name="Example: HStack"
217 | ---app copy display
218 | <App>
219 |   <HStack>
220 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
221 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
222 |     <Stack height="20px" width="80%" backgroundColor="orangered" />
223 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
224 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
225 |   </HStack>
226 | </App>
227 | ---desc
228 | In an `HStack` they occupy one row. The app provides a horizontal scrollbar to accommodate overflow.
229 | ```
230 | 
231 | 
232 | ```xmlui-pg name="Example: HStack"
233 | ---app copy display
234 | <App>
235 |   <FlowLayout>
236 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
237 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
238 |     <Stack height="20px" width="80%" backgroundColor="orangered" />
239 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
240 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
241 |   </FlowLayout>
242 | </App>
243 | ---desc
244 | In a `FlowLayout` the children occupy new rows as needed.
245 | ```
246 | 
247 | If you set an explicit `height` the layout container will use that height; otherwise, it accommodates the height of its children. This example uses the natural height of the content.
248 | 
249 | ```xmlui-pg copy display name="Example: Text in VStack"
250 | <VStack
251 |   backgroundColor="cyan"
252 |   horizontalAlignment="center"
253 |   verticalAlignment="center">
254 |   This is some text within a VStack
255 | </VStack>
256 | ```
257 | 
258 | This example increases the height.
259 | 
260 | ```xmlui-pg copy display name="Example: VStack with explicit height"
261 | <VStack
262 |   height="160px"
263 |   backgroundColor="cyan"
264 |   horizontalAlignment="center"
265 |   verticalAlignment="center">
266 |   This is some text within a VStack
267 | </VStack>
268 | ```
269 | 
270 | ## Container width
271 | 
272 | Unless you use an explicit width, a layout container uses the entire width of its viewport. This example uses implicit width.
273 | 
274 | ```xmlui-pg copy display name="Example: default container width"
275 | <VStack
276 |   backgroundColor="cyan"
277 |   horizontalAlignment="center"
278 |   verticalAlignment="center">
279 |   This is some text within a VStack
280 | </VStack>
281 | ```
282 | 
283 | This one uses explicit width.
284 | 
285 | ```xmlui-pg copy display /width="400px"/ name="Example: explicit container width"
286 | <VStack
287 |   width="400px"
288 |   backgroundColor="cyan"
289 |   horizontalAlignment="center"
290 |   verticalAlignment="center">
291 |   This is some text within a VStack
292 | </VStack>
293 | ```
294 | 
295 | When you explicitly set the width of a layout container and the content is wider, it will break or overflow.
296 | 
297 | ## Stack
298 | 
299 | `Stack` renders its child items horizontally or vertically according to its `orientation` property, optionally providing some gap between child components.
300 | 
301 | You can assign the `horizontal` or `vertical` values to the `Stack` component's `orientation` property to declare its rendering orientation. The default value is `vertical`.
302 | 
303 | > [!INFO]
304 | > Use `Stack` when the `orientation` property can vary as the result of an expression. If the orientation is static, use `VStack` (equivalent to `<Stack orientation="vertical">`) or `HStack` (`<Stack orientation="horizontal">`).
305 | 
306 | ### Alignment
307 | 
308 | The `horizontalAlignment` and `verticalAlignment` properties govern alignment within a stack, using values like `start`, `end`, and `center`. See the full list of values [here](/styles-and-themes/common-units#alignment)
309 | 
310 | This markup aligns the children of an `HStack` horizontally in the center:
311 | 
312 | ```xmlui-pg copy display /horizontalAlignment="center"/ name="Example: horizontally centered content in a HStack"
313 | <HStack horizontalAlignment="center">
314 |   <Stack backgroundColor="red" height="36px" width="36px" />
315 |   <Stack backgroundColor="green" height="36px" width="36px" />
316 |   <Stack backgroundColor="blue" height="36px" width="36px" />
317 | </HStack>
318 | ```
319 | 
320 | This markup aligns the children of a `VStack` horizontally to the end (right edge):
321 | 
322 | ```xmlui-pg copy display /horizontalAlignment="end"/ name="Example: horizontally centered content in a VStack"
323 | <VStack  horizontalAlignment="end">
324 |   <Stack backgroundColor="red" height="36px" width="36px" />
325 |   <Stack backgroundColor="green" height="36px" width="36px" />
326 |   <Stack backgroundColor="blue" height="36px" width="36px" />
327 | </VStack>
328 | ```
329 | 
330 | This markup aligns the children of an `HStack` vertically in the center:
331 | 
332 | ```xmlui-pg copy display /verticalAlignment="center"/ name="Exmaple: vertically centered text in a HStack"
333 | <HStack verticalAlignment="center">
334 |   <Stack backgroundColor="red" height="36px" width="36px" />
335 |   <Stack backgroundColor="green" height="72px" width="36px" />
336 |   <Stack backgroundColor="blue" height="48px" width="36px" />
337 | </HStack>
338 | ```
339 | 
340 | ## VStack
341 | 
342 | A `VStack` component displays each of its children in a new row. If a child has no explicit (or component-specific) width, the `VStack` stretches the component to the entire viewport width. `VStack` keeps the child components' heights intact.
343 | 
344 | ```xmlui-pg copy display name="Example: rendering children in a VStack "
345 | <VStack>
346 |   <H2 backgroundColor="orangered">I'm a heading with colored background</H2>
347 |   <Button>I'm a button</Button>
348 | </VStack>
349 | ```
350 | 
351 | The `H2` component has no explicit size, so its width is set to the width of the text content (as the background color indicates). Though the `Button` component has no explicit size, it has a component-specific one (according to its content), so it is not stretched horizontally. The button is taller than the `VStack`, so its height determines the `VStack` height, and the text height is stretched to that.
352 | 
353 | When you use a `VStack` child with percentage height, the effective height is calculated from the entire stack height. Such a setup may cause overflow if the sum of percentages equals 100%, as the gaps between children are also included in the stack height. This example demonstrates an overflow.
354 | 
355 | ```xmlui-pg copy display name="Example: VStack with percentage height (overflow)"
356 | <VStack height="200px" border="4px dotted green">
357 |   <Stack backgroundColor="cyan" height="50%" />
358 |   <Stack backgroundColor="orangered" height="50%" />
359 | </VStack>
360 | ```
361 | 
362 | There is no overflow when the stack does not apply gaps.
363 | 
364 | ```xmlui-pg copy display /gap="0"/ name="Example: VStack with percentage height (no overflow)"
365 | <VStack gap="0" height="200px" border="4px dotted green">
366 |   <Stack backgroundColor="cyan" height="50%" />
367 |   <Stack backgroundColor="orangered" height="50%" />
368 | </VStack>
369 | ```
370 | 
371 | When you use a `VStack` child height with star sizing, the effective height is calculated from the remaining height of the entire stack after subtracting the heights of explicitly-sized children and gaps.
372 | Such a configuration will not cause overflow.
373 | 
374 | ```xmlui-pg copy display name="Example: VStack with star-sized height"
375 | <VStack height="240px" border="4px dotted green">
376 |   <Stack backgroundColor="cyan" height="*" />
377 |   <H3>I'm a heading</H3>
378 |   <Stack backgroundColor="orangered" height="5*" />
379 | </VStack>
380 | ```
381 | 
382 | ## HStack
383 | 
384 | An `HStack` component displays each of its children in a single row. If a child has no explicit (or component-specific) width, the `HStack` fits the component width to its content. `HStack` sets the child components' heights to the stack's viewport height.
385 | 
386 | ```xmlui-pg copy display name="Example: rendering children in a HStack"
387 | <HStack>
388 |   <H2 backgroundColor="orangered">I'm a heading with colored background</H2>
389 |   <Button>I'm a button</Button>
390 | </HStack>
391 | ```
392 | 
393 | The `H2` component has no explicit size, so it's stretched to the viewport width (as the background color indicates). Though `Button` has no explicit size, it has a component-specific one (according to its content), so it is not stretched.
394 | 
395 | When you use a `HStack` child with percentage width, the effective width is calculated from the stack's viewport width. Such a setup may cause horizontal overflow if the sum of percentages equals 100%, as the gaps between children are also included in the stack height.
396 | 
397 | ```xmlui-pg copy display name="Example: HStack with percentage width (overflow)"
398 | <HStack border="4px dotted green" height="200px">
399 |   <Stack backgroundColor="cyan" width="50%" />
400 |   <Stack backgroundColor="orangered" width="50%" />
401 | </HStack>
402 | ```
403 | 
404 | 
405 | When the stack does not apply gaps, there is no overflow:
406 | 
407 | ```xmlui-pg copy display /gap="0"/ name="Example: HStack with percentage width (no overflow)"
408 | <HStack gap="0" border="4px dotted green" height="200px">
409 |   <Stack backgroundColor="cyan" width="50%" />
410 |   <Stack backgroundColor="orangered" width="50%" />
411 | </HStack>
412 | ```
413 | 
414 | When you use a `HStack` child with star sizing, the effective width is calculated from the remaining width of the stack's viewport width after subtracting the widths of explicitly sized children and gaps. Such a configuration will not cause overflow.
415 | 
416 | ```xmlui-pg copy display name="Example: HStack with star-sized width"
417 | <HStack height="60px" border="4px dotted green">
418 |   <Stack backgroundColor="cyan" width="*" />
419 |   <H3>I'm a heading</H3>
420 |   <Stack backgroundColor="orangered" width="2*" />
421 | </HStack>
422 | ```
423 | 
424 | `HStack` has a `wrapContent` property. If you set it to `true`, the engine starts a new line (or column) when the subsequent child to render would overflow in the current line. Here the fourth child does not fit in the first line entirely, so it overflows:
425 | 
426 | ```xmlui-pg copy display name="Example: HStack with overflow in a single row"
427 | <HStack>
428 |   <Stack backgroundColor="red" height="36px" width="25%" />
429 |   <Stack backgroundColor="green" height="36px" width="40%" />
430 |   <Stack backgroundColor="blue" height="36px" width="20%" />
431 |   <Stack backgroundColor="purple" height="36px" width="30%" />
432 | </HStack>
433 | ```
434 | 
435 | With `wrapContent` flag, the forth child begins a new line.
436 | 
437 | ```xmlui-pg copy display /wrapContent="true"/ name="Example: HStack with wrapContent"
438 | <HStack wrapContent="true">
439 |   <Stack backgroundColor="red" height="36px" width="25%" />
440 |   <Stack backgroundColor="green" height="36px" width="40%" />
441 |   <Stack backgroundColor="blue" height="36px" width="20%" />
442 |   <Stack backgroundColor="purple" height="36px" width="30%" />
443 | </HStack>
444 | ```
445 | 
446 | ## CHStack
447 | 
448 | `CHStack` is a shorthand version of `Stack` with a horizontal orientation and centered contents.
449 | 
450 | ```xmlui-pg copy display name="Example: CHStack"
451 | <CHStack height="100px" width="200px" backgroundColor="lightgray">
452 |   <Stack backgroundColor="red" height="36px" width="36px" />
453 |   <Stack backgroundColor="green" height="72px" width="36px" />
454 |   <Stack backgroundColor="blue" height="48px" width="36px" />
455 | </CHStack>
456 | ```
457 | 
458 | ## CVStack
459 | 
460 | `CVStack` is a shorthand version of `Stack` with a vertical orientation and centered contents.
461 | 
462 | ```xmlui-pg display copy name="Example: CVStack"
463 | <CVStack height="200px" width="100px" backgroundColor="lightgray">
464 |   <Stack backgroundColor="red" height="36px" width="36px" />
465 |   <Stack backgroundColor="green" height="36px" width="72px" />
466 |   <Stack backgroundColor="blue" height="36px" width="48px" />
467 | </CVStack>
468 | ```
469 | 
470 | ## FlowLayout
471 | 
472 | `FlowLayout` component is effectively a horizontal stack with content wrapping. Though it implements the same behavior, it has extra features:
473 | 
474 | - **Percentage sizing**: `FlowLayout` considers the gaps between child elements when using percentage sizing, unlike `Stack`.
475 | - **Responsiveness**: `FlowLayout` resizes percentage-sized children on mobile devices.
476 | 
477 | When you use an `HStack` with percentage sizing and the sum width of children is 100%, an overflow will occur because gaps require extra space.
478 | 
479 | ```xmlui-pg copy display name="Example: HStack with overflow"
480 | <HStack>
481 |   <Stack backgroundColor="red" height="36px" width="25%" />
482 |   <Stack backgroundColor="green" height="36px" width="50%" />
483 |   <Stack backgroundColor="blue" height="36px" width="25%" />
484 | </HStack>
485 | ```
486 | 
487 | `FlowLayout` handles this sizing issue by adjusting the child component dimensions, accounting for the gaps.
488 | 
489 | ```xmlui-pg copy display name="Example: FlowLayout"
490 | <FlowLayout>
491 |   <Stack backgroundColor="red" height="36px" width="25%" />
492 |   <Stack backgroundColor="green" height="36px" width="50%" />
493 |   <Stack backgroundColor="blue" height="36px" width="25%" />
494 | </FlowLayout>
495 | ```
496 | 
497 | `FlowLayout` caps the size of items exceeding the available width. Here the red box is too wide but `FlowLayout` trims it back to 100% width.
498 | 
499 | ```xmlui-pg copy display /width="1000000px"/ name="Example: FlowLayout with size capping"
500 | <FlowLayout>
501 |   <Stack backgroundColor="red" height="36px" width="1000000px" />
502 |   <Stack backgroundColor="green" height="36px" width="50%" />
503 |   <Stack backgroundColor="blue" height="36px" width="25%" />
504 | </FlowLayout>
505 | ```
506 | 
507 | 
508 | Note how the extreme width of the first child is capped to the space available for the `FlowLayout`, while the other children's sizes remain unmodified:
509 | 
510 | ## SpaceFiller
511 | 
512 | `SpaceFiller` fills unused space in layout containers. Its behavior depends on the layout container in which it is used. In a `Stack`, it pushes the children following it to the other end of the container.
513 | 
514 | ```xmlui-pg copy display name="Example: SpaceFiller in a HStack"
515 | <HStack>
516 |   <Stack width="36px" height="36px" backgroundColor="red" />
517 |   <SpaceFiller />
518 |   <Stack width="36px" height="36px" backgroundColor="blue" />
519 | </HStack>
520 | ```
521 | 
522 | In a `FlowLayout`, it acts as a line break for a row. The children following the `SpaceFiller` begin a new line.
523 | 
524 | ```xmlui-pg copy display name="Example: SpaceFiller in a FlowLayout"
525 | <FlowLayout>
526 |   <Stack width="20%" height="36px" backgroundColor="red" />
527 |   <SpaceFiller />
528 |   <Stack width="20%" height="36px" backgroundColor="green" />
529 |   <Stack width="20%" height="36px" backgroundColor="blue" />
530 | </FlowLayout>
531 | ```
532 | 
533 | ## Splitter
534 | 
535 | `Splitter` divides a container into two resizable sections (a primary and a secondary) and puts a draggable bar between them. It has two specialized variants, `HSplitter` and `VSplitter`, which separate the two sections vertically and horizontally.
536 | 
537 | Here's a horizontal splitter that sets some constraints on the size of the primary section.
538 | 
539 | ```xmlui-pg copy display height="200px" name="Example: Splitter"
540 | <HSplitter
541 |   height="100%"
542 |   minPrimarySize="15%"
543 |   maxPrimarySize="85%">
544 |   <CVStack backgroundColor="lightblue" height="100%">Primary</CVStack>
545 |   <CVStack backgroundColor="darksalmon" height="100%">Secondary</CVStack>
546 | </HSplitter>
547 | ```
548 | 
549 | Try dragging the splitter bar between the sections to see how it works.
550 | 
551 | 
```
--------------------------------------------------------------------------------
/xmlui/src/components/Select/Select.module.scss:
--------------------------------------------------------------------------------
```scss
  1 | @use "../../components-core/theming/themes" as t;
  2 | 
  3 | // --- This code snippet is required to collect the theme variables used in this module
  4 | $themeVars: ();
  5 | $animDuration: 0.1s;
  6 | 
  7 | @function createThemeVar($componentVariable) {
  8 |   $themeVars: t.appendThemeVar($themeVars, $componentVariable) !global;
  9 |   @return t.getThemeVar($themeVars, $componentVariable);
 10 | }
 11 | 
 12 | $componentName: "Select";
 13 | $themeVars: t.composeBorderVars($themeVars, $componentName);
 14 | $themeVars: t.composePaddingVars($themeVars, $componentName);
 15 | $themeVars: t.composePaddingVars($themeVars, "item-#{$componentName}");
 16 | 
 17 | // Variables for default variant
 18 | $borderRadius-Select--default: createThemeVar("Input:borderRadius-#{$componentName}--default");
 19 | $borderColor-Select--default: createThemeVar("Input:borderColor-#{$componentName}--default");
 20 | $borderWidth-Select--default: createThemeVar("Input:borderWidth-#{$componentName}--default");
 21 | $borderStyle-Select--default: createThemeVar("Input:borderStyle-#{$componentName}--default");
 22 | $fontSize-Select--default: createThemeVar("Input:fontSize-#{$componentName}--default");
 23 | $backgroundColor-Select--default: createThemeVar("Input:backgroundColor-#{$componentName}--default");
 24 | $boxShadow-Select--default: createThemeVar("Input:boxShadow-#{$componentName}--default");
 25 | $textColor-Select--default: createThemeVar("Input:textColor-#{$componentName}--default");
 26 | $borderColor-Select--default--hover: createThemeVar("Input:borderColor-#{$componentName}--default--hover");
 27 | $backgroundColor-Select--default--hover: createThemeVar("Input:backgroundColor-#{$componentName}--default--hover");
 28 | $boxShadow-Select--default--hover: createThemeVar("Input:boxShadow-#{$componentName}--default--hover");
 29 | $textColor-Select--default--hover: createThemeVar("Input:textColor-#{$componentName}--default--hover");
 30 | $outlineWidth-Select--default--focus: createThemeVar("Input:outlineWidth-#{$componentName}--default--focus");
 31 | $outlineColor-Select--default--focus: createThemeVar("Input:outlineColor-#{$componentName}--default--focus");
 32 | $outlineStyle-Select--default--focus: createThemeVar("Input:outlineStyle-#{$componentName}--default--focus");
 33 | $outlineOffset-Select--default--focus: createThemeVar("Input:outlineOffset-#{$componentName}--default--focus");
 34 | $textColor-placeholder-Select--default: createThemeVar("Input:textColor-placeholder-#{$componentName}--default");
 35 | $fontSize-placeholder-Select--default: createThemeVar("Input:fontSize-placeholder-#{$componentName}--default");
 36 | 
 37 | // Variables for error variant
 38 | $borderRadius-Select--error: createThemeVar("Input:borderRadius-#{$componentName}--error");
 39 | $borderColor-Select--error: createThemeVar("Input:borderColor-#{$componentName}--error");
 40 | $borderWidth-Select--error: createThemeVar("Input:borderWidth-#{$componentName}--error");
 41 | $borderStyle-Select--error: createThemeVar("Input:borderStyle-#{$componentName}--error");
 42 | $fontSize-Select--error: createThemeVar("Input:fontSize-#{$componentName}--error");
 43 | $backgroundColor-Select--error: createThemeVar("Input:backgroundColor-#{$componentName}--error");
 44 | $boxShadow-Select--error: createThemeVar("Input:boxShadow-#{$componentName}--error");
 45 | $textColor-Select--error: createThemeVar("Input:textColor-#{$componentName}--error");
 46 | $borderColor-Select--error--hover: createThemeVar("Input:borderColor-#{$componentName}--error--hover");
 47 | $backgroundColor-Select--error--hover: createThemeVar("Input:backgroundColor-#{$componentName}--error--hover");
 48 | $boxShadow-Select--error--hover: createThemeVar("Input:boxShadow-#{$componentName}--error--hover");
 49 | $textColor-Select--error--hover: createThemeVar("Input:textColor-#{$componentName}--error--hover");
 50 | $outlineWidth-Select--error--focus: createThemeVar("Input:outlineWidth-#{$componentName}--error--focus");
 51 | $outlineColor-Select--error--focus: createThemeVar("Input:outlineColor-#{$componentName}--error--focus");
 52 | $outlineStyle-Select--error--focus: createThemeVar("Input:outlineStyle-#{$componentName}--error--focus");
 53 | $outlineOffset-Select--error--focus: createThemeVar("Input:outlineOffset-#{$componentName}--error--focus");
 54 | $textColor-placeholder-Select--error: createThemeVar("Input:textColor-placeholder-#{$componentName}--error");
 55 | $fontSize-placeholder-Select--error: createThemeVar("Input:fontSize-placeholder-#{$componentName}--error");
 56 | 
 57 | // Variables for warning variant
 58 | $borderRadius-Select--warning: createThemeVar("Input:borderRadius-#{$componentName}--warning");
 59 | $borderColor-Select--warning: createThemeVar("Input:borderColor-#{$componentName}--warning");
 60 | $borderWidth-Select--warning: createThemeVar("Input:borderWidth-#{$componentName}--warning");
 61 | $borderStyle-Select--warning: createThemeVar("Input:borderStyle-#{$componentName}--warning");
 62 | $fontSize-Select--warning: createThemeVar("Input:fontSize-#{$componentName}--warning");
 63 | $backgroundColor-Select--warning: createThemeVar("Input:backgroundColor-#{$componentName}--warning");
 64 | $boxShadow-Select--warning: createThemeVar("Input:boxShadow-#{$componentName}--warning");
 65 | $textColor-Select--warning: createThemeVar("Input:textColor-#{$componentName}--warning");
 66 | $borderColor-Select--warning--hover: createThemeVar("Input:borderColor-#{$componentName}--warning--hover");
 67 | $backgroundColor-Select--warning--hover: createThemeVar("Input:backgroundColor-#{$componentName}--warning--hover");
 68 | $boxShadow-Select--warning--hover: createThemeVar("Input:boxShadow-#{$componentName}--warning--hover");
 69 | $textColor-Select--warning--hover: createThemeVar("Input:textColor-#{$componentName}--warning--hover");
 70 | $outlineWidth-Select--warning--focus: createThemeVar("Input:outlineWidth-#{$componentName}--warning--focus");
 71 | $outlineColor-Select--warning--focus: createThemeVar("Input:outlineColor-#{$componentName}--warning--focus");
 72 | $outlineStyle-Select--warning--focus: createThemeVar("Input:outlineStyle-#{$componentName}--warning--focus");
 73 | $outlineOffset-Select--warning--focus: createThemeVar("Input:outlineOffset-#{$componentName}--warning--focus");
 74 | $textColor-placeholder-Select--warning: createThemeVar("Input:textColor-placeholder-#{$componentName}--warning");
 75 | $fontSize-placeholder-Select--warning: createThemeVar("Input:fontSize-placeholder-#{$componentName}--warning");
 76 | 
 77 | // Variables for success variant
 78 | $borderRadius-Select--success: createThemeVar("Input:borderRadius-#{$componentName}--success");
 79 | $borderColor-Select--success: createThemeVar("Input:borderColor-#{$componentName}--success");
 80 | $borderWidth-Select--success: createThemeVar("Input:borderWidth-#{$componentName}--success");
 81 | $borderStyle-Select--success: createThemeVar("Input:borderStyle-#{$componentName}--success");
 82 | $fontSize-Select--success: createThemeVar("Input:fontSize-#{$componentName}--success");
 83 | $backgroundColor-Select--success: createThemeVar("Input:backgroundColor-#{$componentName}--success");
 84 | $boxShadow-Select--success: createThemeVar("Input:boxShadow-#{$componentName}--success");
 85 | $textColor-Select--success: createThemeVar("Input:textColor-#{$componentName}--success");
 86 | $borderColor-Select--success--hover: createThemeVar("Input:borderColor-#{$componentName}--success--hover");
 87 | $backgroundColor-Select--success--hover: createThemeVar("Input:backgroundColor-#{$componentName}--success--hover");
 88 | $boxShadow-Select--success--hover: createThemeVar("Input:boxShadow-#{$componentName}--success--hover");
 89 | $textColor-Select--success--hover: createThemeVar("Input:textColor-#{$componentName}--success--hover");
 90 | $outlineWidth-Select--success--focus: createThemeVar("Input:outlineWidth-#{$componentName}--success--focus");
 91 | $outlineColor-Select--success--focus: createThemeVar("Input:outlineColor-#{$componentName}--success--focus");
 92 | $outlineStyle-Select--success--focus: createThemeVar("Input:outlineStyle-#{$componentName}--success--focus");
 93 | $outlineOffset-Select--success--focus: createThemeVar("Input:outlineOffset-#{$componentName}--success--focus");
 94 | $textColor-placeholder-Select--success: createThemeVar("Input:textColor-placeholder-#{$componentName}--success");
 95 | $fontSize-placeholder-Select--success: createThemeVar("Input:fontSize-placeholder-#{$componentName}--success");
 96 | 
 97 | // Variables for @layer section
 98 | $backgroundColor-Select--disabled: createThemeVar("Input:backgroundColor-#{$componentName}--disabled");
 99 | $textColor-Select--disabled: createThemeVar("Input:textColor-#{$componentName}--disabled");
100 | $borderColor-Select--disabled: createThemeVar("Input:borderColor-#{$componentName}--disabled");
101 | $outlineWidth-Select--focus: createThemeVar("Input:outlineWidth-#{$componentName}--focus");
102 | $outlineColor-Select--focus: createThemeVar("Input:outlineColor-#{$componentName}--focus");
103 | $outlineStyle-Select--focus: createThemeVar("Input:outlineStyle-#{$componentName}--focus");
104 | $outlineOffset-Select--focus: createThemeVar("Input:outlineOffset-#{$componentName}--focus");
105 | $textColor-placeholder-Select: createThemeVar("Input:textColor-placeholder-#{$componentName}");
106 | $paddingVertical-Select-badge: createThemeVar("paddingVertical-#{$componentName}-badge");
107 | $paddingHorizontal-Select-badge: createThemeVar("paddingHorizontal-#{$componentName}-badge");
108 | $borderRadius-Select-badge: createThemeVar("borderRadius-#{$componentName}-badge");
109 | $fontSize-Select-badge: createThemeVar("Input:fontSize-#{$componentName}-badge");
110 | $backgroundColor-Select-badge: createThemeVar("Input:backgroundColor-#{$componentName}-badge");
111 | $textColor-Select-badge: createThemeVar("Input:textColor-#{$componentName}-badge");
112 | $backgroundColor-Select-badge--hover: createThemeVar("Input:backgroundColor-#{$componentName}-badge--hover");
113 | $textColor-Select-badge--hover: createThemeVar("Input:textColor-#{$componentName}-badge--hover");
114 | $backgroundColor-Select-badge--active: createThemeVar("Input:backgroundColor-#{$componentName}-badge--active");
115 | $textColor-Select-badge--active: createThemeVar("Input:textColor-#{$componentName}-badge--active");
116 | $backgroundColor-menu-Select: createThemeVar("Input:backgroundColor-menu-#{$componentName}");
117 | $borderRadius-menu-Select: createThemeVar("Input:borderRadius-menu-#{$componentName}");
118 | $boxShadow-menu-Select: createThemeVar("Input:boxShadow-menu-#{$componentName}");
119 | $borderWidth-menu-Select: createThemeVar("Input:borderWidth-menu-#{$componentName}");
120 | $borderColor-menu-Select: createThemeVar("Input:borderColor-menu-#{$componentName}");
121 | $backgroundColor-item-Select: createThemeVar("backgroundColor-item-#{$componentName}");
122 | $backgroundColor-item-Select--active: createThemeVar("backgroundColor-item-#{$componentName}--active");
123 | $backgroundColor-item-Select--hover: createThemeVar("backgroundColor-item-#{$componentName}--hover");
124 | $textColor-item-Select--disabled: createThemeVar("textColor-item-#{$componentName}--disabled");
125 | $opacity-text-item-Select--disabled: createThemeVar("opacity-text-item-#{$componentName}--disabled");
126 | $textColor-indicator-Select: createThemeVar("textColor-indicator-#{$componentName}");
127 | 
128 | 
129 | // --- CSS properties of a particular Select variant
130 | @mixin variant($variantName) {
131 |   border-radius: createThemeVar("Input:borderRadius-#{$componentName}--#{$variantName}");
132 |   border-color: createThemeVar("Input:borderColor-#{$componentName}--#{$variantName}");
133 |   border-width: createThemeVar("Input:borderWidth-#{$componentName}--#{$variantName}");
134 |   border-style: createThemeVar("Input:borderStyle-#{$componentName}--#{$variantName}");
135 |   font-size: createThemeVar("Input:fontSize-#{$componentName}--#{$variantName}");
136 |   background-color: createThemeVar("Input:backgroundColor-#{$componentName}--#{$variantName}");
137 |   box-shadow: createThemeVar("Input:boxShadow-#{$componentName}--#{$variantName}");
138 |   color: createThemeVar("Input:textColor-#{$componentName}--#{$variantName}");
139 | 
140 |   &:not(:disabled) {
141 |     &:hover {
142 |       border-color: createThemeVar("Input:borderColor-#{$componentName}--#{$variantName}--hover");
143 |       background-color: createThemeVar("Input:backgroundColor-#{$componentName}--#{$variantName}--hover");
144 |       box-shadow: createThemeVar("Input:boxShadow-#{$componentName}--#{$variantName}--hover");
145 |       color: createThemeVar("Input:textColor-#{$componentName}--#{$variantName}--hover");
146 |     }
147 | 
148 |     &:focus-visible {
149 |       outline-width: createThemeVar('Input:outlineWidth-#{$componentName}--#{$variantName}--focus');
150 |       outline-color: createThemeVar('Input:outlineColor-#{$componentName}--#{$variantName}--focus');
151 |       outline-style: createThemeVar('Input:outlineStyle-#{$componentName}--#{$variantName}--focus');
152 |       outline-offset: createThemeVar('Input:outlineOffset-#{$componentName}--#{$variantName}--focus');
153 |     }
154 |   }
155 | 
156 |   &::placeholder {
157 |     color: createThemeVar("Input:textColor-placeholder-#{$componentName}--#{$variantName}");
158 |     font-size: createThemeVar("Input:fontSize-placeholder-#{$componentName}--#{$variantName}");
159 |   }
160 | }
161 | 
162 | @layer components {
163 |   // =============================================================================
164 |   // SHARED COMPONENTS (used by both SimpleSelect and MultiSelect)
165 |   // =============================================================================
166 | 
167 |   /**
168 |    * Common trigger styles for both SimpleSelect and searchable/multiSelect
169 |    */
170 |   .selectTrigger {
171 |     outline: none;
172 |     width: 100%;
173 |     gap: t.$space-1;
174 |     display: flex;
175 |     flex-direction: row;
176 |     flex-wrap: wrap;
177 |     @include t.paddingVars($themeVars, $componentName);
178 | 
179 |     @include variant("default");
180 | 
181 |     &.error {
182 |       @include variant("error");
183 |     }
184 | 
185 |     &.warning {
186 |       @include variant("warning");
187 |     }
188 | 
189 |     &.valid {
190 |       @include variant("success");
191 |     }
192 | 
193 |     &.disabled {
194 |       cursor: not-allowed;
195 |       opacity: 0.5;
196 |       background-color: $backgroundColor-Select--disabled;
197 |       color: $textColor-Select--disabled;
198 |       border-color: $borderColor-Select--disabled;
199 |     }
200 | 
201 |     &:focus {
202 |       outline-width: $outlineWidth-Select--focus;
203 |       outline-color: $outlineColor-Select--focus;
204 |       outline-style: $outlineStyle-Select--focus;
205 |       outline-offset: $outlineOffset-Select--focus;
206 |     }
207 | 
208 |     .placeholder {
209 |       flex:1;
210 |       display: flex;
211 |       justify-content: start;
212 |       align-items: center;
213 |       color: $textColor-placeholder-Select;
214 |     }
215 |   }
216 | 
217 |   .selectTrigger>span {
218 |     display: -webkit-box;
219 |     -webkit-box-orient: vertical;
220 |     -webkit-line-clamp: 1;
221 |     line-clamp: 1;
222 |     overflow: hidden;
223 |   }
224 | 
225 |   /**
226 |    * Common trigger value and actions
227 |    */
228 | 
229 |   .actions {
230 |     display: flex;
231 |     align-items: center;
232 |     flex-shrink: 0;
233 |   }
234 | 
235 |   .action {
236 |     cursor: pointer;
237 |   }
238 | 
239 |   /**
240 |    * Common empty state
241 |    */
242 |   .emptyList {
243 |     display: flex;
244 |     gap: .2rem;
245 |     padding: 10px 0;
246 |     justify-content: center;
247 |     align-items: center;
248 |     font-size: 14px;
249 |     width: 100%;
250 |   }
251 | 
252 |   // =============================================================================
253 |   // MULTI-SELECT SPECIFIC (searchable + multiSelect)
254 |   // =============================================================================
255 | 
256 |   /**
257 |    * Badge display for multi-select values
258 |    */
259 |   .badgeListContainer {
260 |     display: flex;
261 |     flex: 1;
262 |     justify-content: space-between;
263 |     align-items: center;
264 |   }
265 | 
266 |   .badgeList {
267 |     position: relative;
268 |     align-items: center;
269 |     display: flex;
270 |     flex-wrap: wrap;
271 |     gap: 0.25rem;
272 |   }
273 | 
274 |   .inputWrapper {
275 |     display: flex;
276 |     align-items: center;
277 |     min-width: fit-content;
278 |     flex: 1;
279 |     gap: t.$space-1;
280 |   }
281 | 
282 |   .badge {
283 |     width: fit-content;
284 |     height: fit-content;
285 |     min-width: 0;
286 |     padding: $paddingVertical-Select-badge $paddingHorizontal-Select-badge;
287 |     transition: color 0.2s, background-color 0.2s;
288 |     user-select: none;
289 |     cursor: pointer;
290 |     display: flex;
291 |     gap: t.$space-1;
292 |     justify-content: center;
293 |     align-items: center;
294 |     border-radius: $borderRadius-Select-badge;
295 |     font-size: $fontSize-Select-badge;
296 |     background-color: $backgroundColor-Select-badge;
297 |     color: $textColor-Select-badge;
298 | 
299 |     &:hover {
300 |       background-color: $backgroundColor-Select-badge--hover;
301 |       color: $textColor-Select-badge--hover;
302 |     }
303 | 
304 |     &:active {
305 |       background-color: $backgroundColor-Select-badge--active;
306 |       color: $textColor-Select-badge--active;
307 |     }
308 |   }
309 | 
310 |   /**
311 |    * Search input and dropdown for searchable/multi-select
312 |    */
313 | 
314 |   .selectContent {
315 |     z-index: 1000;
316 |     outline: none;
317 |     overflow: auto;
318 |     background-color: $backgroundColor-menu-Select;
319 |     border-radius: $borderRadius-menu-Select;
320 |     box-shadow: $boxShadow-menu-Select;
321 |     border: $borderWidth-menu-Select solid $borderColor-menu-Select;
322 |   }
323 | 
324 |   .command {
325 |     width: 100%;
326 |     height: auto;
327 |     overflow: visible;
328 |   }
329 | 
330 |   .commandInputContainer {
331 |     display: flex;
332 |     align-items: center;
333 |     padding: 0 12px;
334 |     border-bottom: 1px solid t.$borderColor;
335 |   }
336 | 
337 |   .commandInput {
338 |     width: 100%;
339 |     background-color: transparent;
340 |     outline: none;
341 |     padding: t.$space-2;
342 | 
343 |     &:disabled {
344 |       cursor: not-allowed;
345 |       opacity: 0.5;
346 |     }
347 | 
348 | 
349 | 
350 |     &:focus-within {
351 |       outline: none;
352 |     }
353 |   }
354 | 
355 |   .commandList {
356 |     width: 100%;
357 |     overflow: auto;
358 |   }
359 | 
360 |   /**
361 |    * MultiSelectOption component (used in searchable/multi-select dropdown)
362 |    */
363 |   .multiSelectOption {
364 |     @include t.paddingVars($themeVars, "item-#{$componentName}");
365 |     display: flex;
366 |     gap: t.$space-1;
367 |     align-items: center;
368 |     justify-content: space-between;
369 |     cursor: pointer;
370 |     transition: background-color 0.2s ease;
371 |     background-color: $backgroundColor-item-Select;
372 | 
373 |     .multiSelectOptionContent {
374 |       width: 100%;
375 |       display: flex;
376 |       align-items: center;
377 |       justify-content: space-between;
378 |     }
379 | 
380 |     &[aria-selected="true"] {
381 |       background-color: $backgroundColor-item-Select--active;
382 |     }
383 | 
384 |     &:hover,
385 |     &.highlighted {
386 |       background-color: $backgroundColor-item-Select--hover;
387 |     }
388 | 
389 |     &[data-selected=true] {
390 |       background-color: $backgroundColor-item-Select--active;
391 |     }
392 | 
393 |     &[aria-disabled="true"],
394 |     &.disabledOption {
395 |       pointer-events: none;
396 |       cursor: not-allowed;
397 |       color: $textColor-item-Select--disabled;
398 |       font-style: italic;
399 |     }
400 | 
401 |     &[data-disabled=true] {
402 |       pointer-events: none;
403 |       opacity: $opacity-text-item-Select--disabled;
404 |       cursor: not-allowed;
405 |       font-style: italic;
406 |     }
407 |   }
408 | 
409 |   // =============================================================================
410 |   // SIMPLE SELECT (non-searchable, single select using Radix UI)
411 |   // =============================================================================
412 | 
413 |   /**
414 |    * Trigger value display for SimpleSelect
415 |    */
416 |   .selectValue {
417 |     flex: 1;
418 |     display: flex;
419 |     align-items: center;
420 |     min-height: t.$space-7;
421 |     outline: none;
422 |     background-color: transparent;
423 |     font-size: t.$fontSize;
424 |   }
425 | 
426 |   .action {
427 |     font-size: t.$fontSize;
428 |   }
429 | 
430 |   /**
431 |    * Dropdown content container
432 |    */
433 |   .selectDropdownContent {
434 |     position: relative;
435 |     width: 100%;
436 |     max-height: 280px;
437 |     z-index: 1000;
438 |     overflow: auto;
439 |     background-color: $backgroundColor-menu-Select;
440 |     border-radius: $borderRadius-menu-Select;
441 |     box-shadow: $boxShadow-menu-Select;
442 |     border: $borderWidth-menu-Select solid $borderColor-menu-Select;
443 | 
444 |     &[data-state='open'] {
445 |       animation: fadeIn $animDuration ease-in-out, zoomIn $animDuration ease-in-out;
446 |     }
447 | 
448 |     &[data-state='closed'] {
449 |       animation: fadeOut $animDuration ease-in-out, zoomOut $animDuration ease-in-out;
450 |     }
451 | 
452 |     &[data-side='bottom'] {
453 |       animation: slideInFromTop 0.08s ease-in-out;
454 |       transform: translateY(0.15rem);
455 |     }
456 | 
457 |     &[data-side='left'] {
458 |       animation: slideInFromRight $animDuration ease-in-out;
459 |       transform: translateX(-0.15rem);
460 |     }
461 | 
462 |     &[data-side='right'] {
463 |       animation: slideInFromLeft $animDuration ease-in-out;
464 |       transform: translateX(0.15rem);
465 |     }
466 | 
467 |     &[data-side='top'] {
468 |       animation: slideInFromBottom $animDuration ease-in-out;
469 |       transform: translateY(-0.15rem);
470 |     }
471 |   }
472 | 
473 |   .selectViewport {
474 |     height: fit-content;
475 |     width: 100%;
476 |   }
477 | 
478 |   .selectScrollUpButton {
479 |     display: flex;
480 |     cursor: default;
481 |     align-items: center;
482 |     justify-content: center;
483 |     padding-top: 0.25rem;
484 |     padding-bottom: 0.25rem;
485 |   }
486 | 
487 |   .selectScrollDownButton {
488 |     display: flex;
489 |     cursor: default;
490 |     align-items: center;
491 |     justify-content: center;
492 |     padding-top: 0.25rem;
493 |     padding-bottom: 0.25rem;
494 |   }
495 | 
496 |   .selectEmpty {
497 |     display: flex;
498 |     gap: .2rem;
499 |     height: 100%;
500 |     padding: 10px 0;
501 |     justify-content: center;
502 |     align-items: center;
503 |     font-size: 14px;
504 |     width: 100%;
505 |   }
506 | 
507 |   /**
508 |    * SelectOption component (used in SimpleSelect dropdown)
509 |    */
510 |   .selectOption {
511 |     @include t.paddingVars($themeVars, "item-#{$componentName}");
512 |     transition: background-color 0.2s ease;
513 |     background-color: $backgroundColor-item-Select;
514 |     gap: t.$space-1;
515 |     position: relative;
516 |     display: flex;
517 |     cursor: pointer;
518 |     user-select: none;
519 |     align-items: center;
520 |     outline: none;
521 |     justify-content: space-between;
522 | 
523 |     &[data-state=checked] {
524 |       background-color: $backgroundColor-item-Select--active;
525 |     }
526 | 
527 |     &[data-highlighted] {
528 |       background-color: $backgroundColor-item-Select--hover;
529 |     }
530 | 
531 |     .selectOptionContent {
532 |       display: flex;
533 |       flex: 1;
534 |       cursor: pointer;
535 |       user-select: none;
536 |       align-items: center;
537 |       outline: none;
538 |     }
539 | 
540 |     &[data-disabled] {
541 |       pointer-events: none;
542 |       opacity: $opacity-text-item-Select--disabled;
543 |       cursor: not-allowed;
544 |       font-style: italic;
545 |     }
546 |   }
547 | 
548 |   .selectOptionIndicator {
549 |     display: flex;
550 |     margin-right: 0.5rem;
551 |     flex-shrink: 0;
552 |     height: 0.875rem;
553 |     width: 0.875rem;
554 |     align-items: center;
555 |     justify-content: center;
556 |     color: $textColor-indicator-Select;
557 |   }
558 | 
559 |   // =============================================================================
560 |   // UTILITY CLASSES
561 |   // =============================================================================
562 | 
563 |   .loading {
564 |     padding: 0.5rem 1rem;
565 |   }
566 | 
567 |   .srOnly {
568 |     position: absolute;
569 |     width: 1px;
570 |     height: 1px;
571 |     padding: 0;
572 |     margin: -1px;
573 |     overflow: hidden;
574 |     clip: rect(0, 0, 0, 0);
575 |     white-space: nowrap;
576 |     border: 0;
577 |   }
578 | 
579 |   @keyframes fadeIn {
580 |     from {
581 |       opacity: 0;
582 |     }
583 | 
584 |     to {
585 |       opacity: 1;
586 |     }
587 |   }
588 | 
589 |   @keyframes fadeOut {
590 |     from {
591 |       opacity: 1;
592 |     }
593 | 
594 |     to {
595 |       opacity: 0;
596 |     }
597 |   }
598 | 
599 |   @keyframes zoomIn {
600 |     from {
601 |       transform: scale(0.95);
602 |     }
603 | 
604 |     to {
605 |       transform: scale(1);
606 |     }
607 |   }
608 | 
609 |   @keyframes zoomOut {
610 |     from {
611 |       transform: scale(1);
612 |     }
613 | 
614 |     to {
615 |       transform: scale(0.95);
616 |     }
617 |   }
618 | 
619 |   @keyframes slideInFromTop {
620 |     from {
621 |       transform: translateY(-0.75rem);
622 |     }
623 | 
624 |     to {
625 |       transform: translateY(0);
626 |     }
627 |   }
628 | 
629 |   @keyframes slideInFromBottom {
630 |     from {
631 |       transform: translateY(0.75rem);
632 |     }
633 | 
634 |     to {
635 |       transform: translateY(0);
636 |     }
637 |   }
638 | 
639 |   @keyframes slideInFromLeft {
640 |     from {
641 |       transform: translateX(-100%);
642 |     }
643 | 
644 |     to {
645 |       transform: translateX(0);
646 |     }
647 |   }
648 | 
649 |   @keyframes slideInFromRight {
650 |     from {
651 |       transform: translateX(100%);
652 |     }
653 | 
654 |     to {
655 |       transform: translateX(0);
656 |     }
657 |   }
658 | }
659 | 
660 | // --- We export the theme variables to add them to the component renderer
661 | :export {
662 |   themeVars: t.json-stringify($themeVars);
663 | }
664 | 
```
--------------------------------------------------------------------------------
/xmlui/src/components/Carousel/Carousel.spec.ts:
--------------------------------------------------------------------------------
```typescript
  1 | import { test, expect } from "../../testing/fixtures";
  2 | 
  3 | // =============================================================================
  4 | // BASIC FUNCTIONALITY TESTS
  5 | // =============================================================================
  6 | 
  7 | test.describe("Basic Functionality", () => {
  8 |   test("component renders", async ({ page, initTestBed }) => {
  9 |     await initTestBed(`<Carousel testId="carousel"></Carousel>`);
 10 |     await expect(page.getByTestId("carousel")).toBeVisible();
 11 |   });
 12 | 
 13 |   test("component renders with correct role", async ({ page, initTestBed }) => {
 14 |     await initTestBed(`<Carousel></Carousel>`);
 15 |     await expect(page.getByRole("region")).toBeVisible();
 16 |   });
 17 | 
 18 |   // NOTE: all carousel items are visible by default in embla-carousel
 19 |   // From this point on, instead of visibility checks, we check that the correct slide is in the viewport
 20 |   test("component renders with correct role on items", async ({ page, initTestBed }) => {
 21 |     await initTestBed(`
 22 |       <Carousel>
 23 |         <CarouselItem>Slide 1</CarouselItem>
 24 |         <CarouselItem>Slide 2</CarouselItem>
 25 |         <CarouselItem>Slide 3</CarouselItem>
 26 |       </Carousel>
 27 |     `);
 28 |     const slides = page.getByRole("region").getByRole("group");
 29 |     await expect(slides).toHaveCount(3);
 30 |     await expect(slides.nth(0)).toContainText("Slide 1");
 31 |     await expect(slides.nth(1)).toContainText("Slide 2");
 32 |     await expect(slides.nth(2)).toContainText("Slide 3");
 33 |   });
 34 | 
 35 |   test("renders slide #2 if startIndex is 1", async ({ page, initTestBed }) => {
 36 |     await initTestBed(`
 37 |       <Carousel startIndex="1">
 38 |         <CarouselItem>Slide 1</CarouselItem>
 39 |         <CarouselItem>Slide 2</CarouselItem>
 40 |         <CarouselItem>Slide 3</CarouselItem>
 41 |       </Carousel>
 42 |     `);
 43 |     await expect(page.getByRole("region").getByRole("group").nth(1)).toBeInViewport();
 44 |   });
 45 | 
 46 |   test("controls prop displays controls", async ({ page, initTestBed }) => {
 47 |     await initTestBed(`
 48 |       <Carousel controls="true">
 49 |         <CarouselItem>Slide 1</CarouselItem>
 50 |         <CarouselItem>Slide 2</CarouselItem>
 51 |         <CarouselItem>Slide 3</CarouselItem>
 52 |       </Carousel>
 53 |     `);
 54 |     await expect(page.getByRole("button", { name: "Previous Slide" })).toBeVisible();
 55 |     await expect(page.getByRole("button", { name: "Next Slide" })).toBeVisible();
 56 |   });
 57 | 
 58 |   test("component scrolls to next slide on control click", async ({ page, initTestBed }) => {
 59 |     await initTestBed(`
 60 |       <Carousel controls="true">
 61 |         <CarouselItem>Slide 1</CarouselItem>
 62 |         <CarouselItem>Slide 2</CarouselItem>
 63 |         <CarouselItem>Slide 3</CarouselItem>
 64 |       </Carousel>
 65 |     `);
 66 |     // Click next button
 67 |     await page.getByRole("button", { name: "Next Slide" }).click();
 68 | 
 69 |     // Verify second slide is now visible
 70 |     await expect(page.getByRole("region").getByRole("group").nth(1)).toBeInViewport();
 71 |   });
 72 | 
 73 |   test("component scrolls to previous slide on control click", async ({ page, initTestBed }) => {
 74 |     await initTestBed(`
 75 |       <Carousel startIndex="1" controls="true">
 76 |         <CarouselItem>Slide 1</CarouselItem>
 77 |         <CarouselItem>Slide 2</CarouselItem>
 78 |         <CarouselItem>Slide 3</CarouselItem>
 79 |       </Carousel>
 80 |     `);
 81 |     // Verify we start on slide 2
 82 |     await expect(page.getByRole("region").getByRole("group").nth(1)).toBeInViewport();
 83 | 
 84 |     // Click previous button
 85 |     await page.getByRole("button", { name: "Previous Slide" }).click();
 86 | 
 87 |     // Verify first slide is now visible
 88 |     const firstSlide = page.getByRole("region").getByRole("group").first();
 89 |     await expect(firstSlide).toBeInViewport();
 90 |   });
 91 | 
 92 |   test("component navigates to slide on indicator click", async ({ page, initTestBed }) => {
 93 |     await initTestBed(`
 94 |       <Carousel>
 95 |         <CarouselItem>Slide 1</CarouselItem>
 96 |         <CarouselItem>Slide 2</CarouselItem>
 97 |         <CarouselItem>Slide 3</CarouselItem>
 98 |       </Carousel>
 99 |     `);
100 | 
101 |     // Click on the third indicator
102 |     const indicators = page.getByRole("tab", { name: "Go to slide 3" });
103 |     await indicators.click();
104 | 
105 |     // Verify third slide is visible
106 |     const thirdSlide = page.getByRole("region").getByRole("group").nth(2);
107 |     await expect(thirdSlide).toBeInViewport();
108 |   });
109 | 
110 |   test("component loops correctly when loop is enabled", async ({ page, initTestBed }) => {
111 |     await initTestBed(`
112 |       <Carousel loop="true" startIndex="2">
113 |         <CarouselItem>Slide 1</CarouselItem>
114 |         <CarouselItem>Slide 2</CarouselItem>
115 |         <CarouselItem>Slide 3</CarouselItem>
116 |       </Carousel>
117 |     `);
118 |     // Verify we're on the last slide
119 |     await expect(page.getByRole("region").getByRole("group").nth(2)).toBeInViewport();
120 | 
121 |     // Click next again to loop back to first slide
122 |     await page.getByRole("button", { name: "Next Slide" }).click();
123 | 
124 |     // Verify we're back on the first slide
125 |     await expect(page.getByRole("region").getByRole("group").first()).toBeInViewport();
126 |   });
127 | 
128 |   test("component autoplay works correctly", async ({ page, initTestBed }) => {
129 |     await initTestBed(`
130 |       <Carousel autoplay="true" autoplayInterval="100">
131 |         <CarouselItem>Slide 1</CarouselItem>
132 |         <CarouselItem>Slide 2</CarouselItem>
133 |         <CarouselItem>Slide 3</CarouselItem>
134 |       </Carousel>
135 |     `);
136 |     const slides = page.getByRole("region").getByRole("group");
137 | 
138 |     // Verify first slide is initially visible
139 |     await expect(slides.first()).toBeInViewport();
140 | 
141 |     await page.waitForTimeout(200);
142 |     await expect(slides.nth(1)).toBeInViewport();
143 |   });
144 | });
145 | 
146 | // =============================================================================
147 | // ACCESSIBILITY TESTS
148 | // =============================================================================
149 | 
150 | // --- Used this resource for a11y testing best practices: https://www.w3.org/WAI/ARIA/apg/patterns/carousel/
151 | test.describe("Accessibility", () => {
152 |   test("regular carousel has correct a11y attributes", async ({ page, initTestBed }) => {
153 |     await initTestBed(`
154 |       <Carousel indicators="false">
155 |         <CarouselItem>Slide 1</CarouselItem>
156 |         <CarouselItem>Slide 2</CarouselItem>
157 |       </Carousel>
158 |     `);
159 |     const carousel = page.getByRole("region");
160 |     const slides = carousel.getByRole("group");
161 | 
162 |     await expect(carousel).toHaveAttribute("aria-roledescription", "carousel");
163 |     await expect(slides.first()).toHaveAttribute("aria-roledescription", "slide");
164 |   });
165 | 
166 |   test("tabbed carousel has correct a11y attributes", async ({ page, initTestBed }) => {
167 |     await initTestBed(`
168 |       <Carousel indicators="true">
169 |         <CarouselItem>Slide 1</CarouselItem>
170 |       </Carousel>
171 |     `);
172 |     const carousel = page.getByRole("region");
173 |     const slides = carousel.getByRole("group");
174 | 
175 |     await expect(slides.first()).toHaveAttribute("role", "group tabpanel");
176 |     await expect(slides.first()).not.toHaveAttribute("aria-roledescription", "slide");
177 |   });
178 | 
179 |   test("carousel controls have correct a11y attributes", async ({ page, initTestBed }) => {
180 |     await initTestBed(`
181 |       <Carousel controls="true">
182 |         <CarouselItem>Slide 1</CarouselItem>
183 |         <CarouselItem>Slide 2</CarouselItem>
184 |       </Carousel>
185 |     `);
186 |     const prevControl = page.getByRole("button", { name: "Previous Slide" });
187 |     const nextControl = page.getByRole("button", { name: "Next Slide" });
188 | 
189 |     await expect(prevControl).toHaveAttribute("aria-label", "Previous Slide");
190 |     await expect(nextControl).toHaveAttribute("aria-label", "Next Slide");
191 |   });
192 | 
193 |   test("component is keyboard navigable", async ({ page, initTestBed }) => {
194 |     await initTestBed(`
195 |     <Carousel>
196 |       <CarouselItem>Slide 1</CarouselItem>
197 |       <CarouselItem>Slide 2</CarouselItem>
198 |       <CarouselItem>Slide 3</CarouselItem>
199 |     </Carousel>
200 |   `);
201 | 
202 |     // Focus the carousel container
203 |     await page.getByRole("region").focus();
204 | 
205 |     // Press right arrow key
206 |     await page.keyboard.press("ArrowRight");
207 | 
208 |     // Verify second slide is visible
209 |     const secondSlide = page.getByRole("region").getByRole("group").nth(1);
210 |     await expect(secondSlide).toBeInViewport();
211 | 
212 |     // Press left arrow key
213 |     await page.keyboard.press("ArrowLeft");
214 | 
215 |     // Verify first slide is visible again
216 |     const firstSlide = page.getByRole("region").getByRole("group").first();
217 |     await expect(firstSlide).toBeInViewport();
218 |   });
219 | });
220 | 
221 | // =============================================================================
222 | // VISUAL STATE TESTS
223 | // =============================================================================
224 | 
225 | test.describe("Visual States", () => {
226 |   test("component width", async ({ page, initTestBed }) => {
227 |     await initTestBed(
228 |       `<Carousel width="500px">
229 |         <CarouselItem>Slide 1</CarouselItem>
230 |         <CarouselItem>Slide 2</CarouselItem>
231 |       </Carousel>`
232 |     );
233 |     const carousel = page.getByRole("region");
234 |     await expect(carousel).toHaveCSS("width", "500px");
235 |   });
236 | 
237 |   test("component height", async ({ page, initTestBed }) => {
238 |     await initTestBed(
239 |       `<Carousel height="500px">
240 |         <CarouselItem>Slide 1</CarouselItem>
241 |         <CarouselItem>Slide 2</CarouselItem>
242 |       </Carousel>`
243 |     );
244 |     const carousel = page.getByRole("region");
245 |     await expect(carousel).toHaveCSS("height", "500px");
246 |   });
247 | 
248 |   test("component control background color", async ({ page, initTestBed }) => {
249 |     await initTestBed(
250 |       `<Carousel controls="true">
251 |         <CarouselItem>Slide 1</CarouselItem>
252 |         <CarouselItem>Slide 2</CarouselItem>
253 |       </Carousel>`,
254 |       {
255 |         testThemeVars: {
256 |           "backgroundColor-control-Carousel": "rgb(255, 0, 0)",
257 |         },
258 |       },
259 |     );
260 |     const control = page.getByRole("button", { name: "Next Slide" });
261 |     await expect(control).toHaveCSS("background-color", "rgb(255, 0, 0)");
262 |   });
263 | 
264 |   test("component control text color", async ({ page, initTestBed }) => {
265 |     await initTestBed(
266 |       `<Carousel controls="true">
267 |         <CarouselItem>Slide 1</CarouselItem>
268 |         <CarouselItem>Slide 2</CarouselItem>
269 |       </Carousel>`,
270 |       {
271 |         testThemeVars: {
272 |           "textColor-control-Carousel": "rgb(0, 0, 255)",
273 |         },
274 |       },
275 |     );
276 |     const control = page.getByRole("button", { name: "Next Slide" });
277 |     await expect(control).toHaveCSS("color", "rgb(0, 0, 255)");
278 |   });
279 | 
280 |   test("component indicator width", async ({ page, initTestBed }) => {
281 |     await initTestBed(
282 |       `<Carousel indicators="true">
283 |         <CarouselItem>Slide 1</CarouselItem>
284 |         <CarouselItem>Slide 2</CarouselItem>
285 |       </Carousel>`,
286 |       {
287 |         testThemeVars: {
288 |           "width-indicator-Carousel": "20px",
289 |         },
290 |       },
291 |     );
292 |     const indicator = page.getByRole("tab", { name: "Go to slide 1" });
293 |     await expect(indicator).toHaveCSS("width", "20px");
294 |   });
295 | 
296 |   test("component control height", async ({ page, initTestBed }) => {
297 |     await initTestBed(
298 |       `<Carousel controls="true">
299 |         <CarouselItem>Slide 1</CarouselItem>
300 |         <CarouselItem>Slide 2</CarouselItem>
301 |       </Carousel>`,
302 |       {
303 |         testThemeVars: {
304 |           "height-control-Carousel": "50px",
305 |         },
306 |       },
307 |     );
308 |     const control = page.getByRole("button", { name: "Next Slide" });
309 |     await expect(control).toHaveCSS("height", "50px");
310 |   });
311 | 
312 |   test("component control width", async ({ page, initTestBed }) => {
313 |     await initTestBed(
314 |       `<Carousel controls="true">
315 |         <CarouselItem>Slide 1</CarouselItem>
316 |         <CarouselItem>Slide 2</CarouselItem>
317 |       </Carousel>`,
318 |       {
319 |         testThemeVars: {
320 |           "width-control-Carousel": "50px",
321 |         },
322 |       },
323 |     );
324 |     const control = page.getByRole("button", { name: "Next Slide" });
325 |     await expect(control).toHaveCSS("width", "50px");
326 |   });
327 | 
328 |   test("component control border radius", async ({ page, initTestBed }) => {
329 |     await initTestBed(
330 |       `<Carousel controls="true">
331 |         <CarouselItem>Slide 1</CarouselItem>
332 |         <CarouselItem>Slide 2</CarouselItem>
333 |       </Carousel>`,
334 |       {
335 |         testThemeVars: {
336 |           "borderRadius-control-Carousel": "10px",
337 |         },
338 |       },
339 |     );
340 |     const control = page.getByRole("button", { name: "Next Slide" });
341 |     await expect(control).toHaveCSS("border-radius", "10px");
342 |   });
343 | 
344 |   test("component control hover background color", async ({ page, initTestBed }) => {
345 |     await initTestBed(
346 |       `<Carousel controls="true">
347 |         <CarouselItem>Slide 1</CarouselItem>
348 |         <CarouselItem>Slide 2</CarouselItem>
349 |       </Carousel>`,
350 |       {
351 |         testThemeVars: {
352 |           "backgroundColor-control-hover-Carousel": "rgb(255, 165, 0)",
353 |         },
354 |       },
355 |     );
356 |     const control = page.getByRole("button", { name: "Next Slide" });
357 |     await control.hover();
358 |     await expect(control).toHaveCSS("background-color", "rgb(255, 165, 0)");
359 |   });
360 | 
361 |   test("component control hover text color", async ({ page, initTestBed }) => {
362 |     await initTestBed(
363 |       `<Carousel controls="true">
364 |         <CarouselItem>Slide 1</CarouselItem>
365 |         <CarouselItem>Slide 2</CarouselItem>
366 |       </Carousel>`,
367 |       {
368 |         testThemeVars: {
369 |           "textColor-control-hover-Carousel": "rgb(255, 255, 255)",
370 |         },
371 |       },
372 |     );
373 |     const control = page.getByRole("button", { name: "Next Slide" });
374 |     await control.hover();
375 |     await expect(control).toHaveCSS("color", "rgb(255, 255, 255)");
376 |   });
377 | 
378 |   test("component control active background color", async ({ page, initTestBed }) => {
379 |     await initTestBed(
380 |       `<Carousel controls="true">
381 |         <CarouselItem>Slide 1</CarouselItem>
382 |         <CarouselItem>Slide 2</CarouselItem>
383 |       </Carousel>`,
384 |       {
385 |         testThemeVars: {
386 |           "backgroundColor-control-active-Carousel": "rgb(0, 128, 0)",
387 |         },
388 |       },
389 |     );
390 |     const control = page.getByRole("button", { name: "Next Slide" });
391 |     await control.hover();
392 |     await page.mouse.down();
393 |     await expect(control).toHaveCSS("background-color", "rgb(0, 128, 0)");
394 |   });
395 | 
396 |   test("component control active text color", async ({ page, initTestBed }) => {
397 |     await initTestBed(
398 |       `<Carousel controls="true">
399 |         <CarouselItem>Slide 1</CarouselItem>
400 |         <CarouselItem>Slide 2</CarouselItem>
401 |       </Carousel>`,
402 |       {
403 |         testThemeVars: {
404 |           "textColor-control-active-Carousel": "rgb(255, 255, 0)",
405 |         },
406 |       },
407 |     );
408 |     const control = page.getByRole("button", { name: "Next Slide" });
409 |     await control.hover();
410 |     await page.mouse.down();
411 |     await expect(control).toHaveCSS("color", "rgb(255, 255, 0)");
412 |   });
413 | 
414 |   test("component control disabled background color", async ({ page, initTestBed }) => {
415 |     await initTestBed(
416 |       `<Carousel controls="true" loop="false">
417 |         <CarouselItem>Slide 1</CarouselItem>
418 |       </Carousel>`,
419 |       {
420 |         testThemeVars: {
421 |           "backgroundColor-control-disabled-Carousel": "rgb(200, 200, 200)",
422 |         },
423 |       },
424 |     );
425 |     const control = page.getByRole("button", { name: "Next Slide" });
426 |     await expect(control).toHaveCSS("background-color", "rgb(200, 200, 200)");
427 |   });
428 | 
429 |   test("component control disabled text color", async ({ page, initTestBed }) => {
430 |     await initTestBed(
431 |       `<Carousel controls="true" loop="false">
432 |         <CarouselItem>Slide 1</CarouselItem>
433 |       </Carousel>`,
434 |       {
435 |         testThemeVars: {
436 |           "textColor-control-disabled-Carousel": "rgb(150, 150, 150)",
437 |         },
438 |       },
439 |     );
440 |     const control = page.getByRole("button", { name: "Next Slide" });
441 |     await expect(control).toHaveCSS("color", "rgb(150, 150, 150)");
442 |   });
443 | 
444 |   test("component indicator height", async ({ page, initTestBed }) => {
445 |     await initTestBed(
446 |       `<Carousel indicators="true">
447 |         <CarouselItem>Slide 1</CarouselItem>
448 |         <CarouselItem>Slide 2</CarouselItem>
449 |       </Carousel>`,
450 |       {
451 |         testThemeVars: {
452 |           "height-indicator-Carousel": "15px",
453 |         },
454 |       },
455 |     );
456 |     const indicator = page.getByRole("tab", { name: "Go to slide 1" });
457 |     await expect(indicator).toHaveCSS("height", "15px");
458 |   });
459 | 
460 |   test("component indicator background color", async ({ page, initTestBed }) => {
461 |     await initTestBed(
462 |       `<Carousel indicators="true">
463 |         <CarouselItem>Slide 1</CarouselItem>
464 |         <CarouselItem>Slide 2</CarouselItem>
465 |       </Carousel>`,
466 |       {
467 |         testThemeVars: {
468 |           "backgroundColor-indicator-Carousel": "rgb(100, 100, 100)",
469 |         },
470 |       },
471 |     );
472 |     const indicator = page.getByRole("tab", { name: "Go to slide 2" });
473 |     await expect(indicator).toHaveCSS("background-color", "rgb(100, 100, 100)");
474 |   });
475 | 
476 |   test("component indicator text color", async ({ page, initTestBed }) => {
477 |     await initTestBed(
478 |       `<Carousel indicators="true">
479 |         <CarouselItem>Slide 1</CarouselItem>
480 |         <CarouselItem>Slide 2</CarouselItem>
481 |       </Carousel>`,
482 |       {
483 |         testThemeVars: {
484 |           "textColor-indicator-Carousel": "rgb(50, 50, 50)",
485 |         },
486 |       },
487 |     );
488 |     const indicator = page.getByRole("tab", { name: "Go to slide 2" });
489 |     await expect(indicator).toHaveCSS("color", "rgb(50, 50, 50)");
490 |   });
491 | 
492 |   test("component indicator hover background color", async ({ page, initTestBed }) => {
493 |     await initTestBed(
494 |       `<Carousel indicators="true">
495 |         <CarouselItem>Slide 1</CarouselItem>
496 |         <CarouselItem>Slide 2</CarouselItem>
497 |       </Carousel>`,
498 |       {
499 |         testThemeVars: {
500 |           "backgroundColor-indicator-hover-Carousel": "rgb(150, 150, 255)",
501 |         },
502 |       },
503 |     );
504 |     const indicator = page.getByRole("tab", { name: "Go to slide 2" });
505 |     await indicator.hover();
506 |     await expect(indicator).toHaveCSS("background-color", "rgb(150, 150, 255)");
507 |   });
508 | 
509 |   test("component indicator hover text color", async ({ page, initTestBed }) => {
510 |     await initTestBed(
511 |       `<Carousel indicators="true">
512 |         <CarouselItem>Slide 1</CarouselItem>
513 |         <CarouselItem>Slide 2</CarouselItem>
514 |       </Carousel>`,
515 |       {
516 |         testThemeVars: {
517 |           "textColor-indicator-hover-Carousel": "rgb(255, 100, 100)",
518 |         },
519 |       },
520 |     );
521 |     const indicator = page.getByRole("tab", { name: "Go to slide 2" });
522 |     await indicator.hover();
523 |     await expect(indicator).toHaveCSS("color", "rgb(255, 100, 100)");
524 |   });
525 | 
526 |   test("component indicator active background color", async ({ page, initTestBed }) => {
527 |     await initTestBed(
528 |       `<Carousel indicators="true">
529 |         <CarouselItem>Slide 1</CarouselItem>
530 |         <CarouselItem>Slide 2</CarouselItem>
531 |       </Carousel>`,
532 |       {
533 |         testThemeVars: {
534 |           "backgroundColor-indicator-active-Carousel": "rgb(0, 0, 255)",
535 |         },
536 |       },
537 |     );
538 |     const indicator = page.getByRole("tab", { name: "Go to slide 1" });
539 |     await expect(indicator).toHaveCSS("background-color", "rgb(0, 0, 255)");
540 |   });
541 | 
542 |   test("component indicator active text color", async ({ page, initTestBed }) => {
543 |     await initTestBed(
544 |       `<Carousel indicators="true">
545 |         <CarouselItem>Slide 1</CarouselItem>
546 |         <CarouselItem>Slide 2</CarouselItem>
547 |       </Carousel>`,
548 |       {
549 |         testThemeVars: {
550 |           "textColor-indicator-active-Carousel": "rgb(255, 255, 255)",
551 |         },
552 |       },
553 |     );
554 |     const indicator = page.getByRole("tab", { name: "Go to slide 1" });
555 |     await expect(indicator).toHaveCSS("color", "rgb(255, 255, 255)");
556 |   });
557 | });
558 | 
559 | // =============================================================================
560 | // EDGE CASE TESTS
561 | // =============================================================================
562 | 
563 | test.describe("Edge Cases", () => {
564 |   test("component handles many slides efficiently", async ({ page, initTestBed }) => {
565 |     const itemNum = 20;
566 | 
567 |     // Create many carousel items
568 |     let carouselItems = "";
569 |     for (let i = 1; i <= itemNum; i++) {
570 |       carouselItems += `<CarouselItem>Slide ${i}</CarouselItem>`;
571 |     }
572 | 
573 |     await initTestBed(`
574 |       <Carousel>
575 |         ${carouselItems}
576 |       </Carousel>
577 |     `);
578 | 
579 |     // Verify carousel renders
580 |     await expect(page.getByRole("region")).toBeVisible();
581 |     const slides = page.getByRole("region").getByRole("group");
582 | 
583 |     // Verify all slides are created
584 |     await expect(slides).toHaveCount(itemNum);
585 | 
586 |     // Verify we can navigate through slides
587 |     await page
588 |       .getByRole("button", { name: "Next Slide" })
589 |       .click({ clickCount: itemNum, delay: 100 });
590 | 
591 |     // Verify we've navigated to the correct slide
592 |     await expect(slides.last()).toBeInViewport();
593 |   });
594 | 
595 |   test("component displays tab indicators for many slides", async ({ page, initTestBed }) => {
596 |     // Create many carousel items
597 |     let carouselItems = "";
598 |     for (let i = 1; i <= 20; i++) {
599 |       carouselItems += `<CarouselItem>Slide ${i}</CarouselItem>`;
600 |     }
601 | 
602 |     await initTestBed(`
603 |       <Carousel indicators="true" controls="false">
604 |         ${carouselItems}
605 |       </Carousel>
606 |     `);
607 | 
608 |     // Verify carousel renders
609 |     await expect(page.getByRole("region").getByRole("tab")).toHaveCount(20);
610 |   });
611 | 
612 |   test("component works without indicators and controls", async ({ page, initTestBed }) => {
613 |     await initTestBed(`
614 |       <Carousel indicators="false" controls="false">
615 |         <CarouselItem>Slide 1</CarouselItem>
616 |         <CarouselItem>Slide 2</CarouselItem>
617 |       </Carousel>
618 |     `);
619 | 
620 |     // Verify carousel container renders
621 |     await expect(page.getByRole("region")).toBeVisible();
622 | 
623 |     // Verify indicators are not visible
624 |     await expect(page.getByRole("region").getByRole("tablist")).not.toBeVisible();
625 | 
626 |     // Verify controls are not visible
627 |     await expect(
628 |       page.getByRole("region").getByRole("button", { name: "Previous Slide" }),
629 |     ).not.toBeVisible();
630 |     await expect(
631 |       page.getByRole("region").getByRole("button", { name: "Next Slide" }),
632 |     ).not.toBeVisible();
633 |   });
634 | });
635 | 
636 | // =============================================================================
637 | // INTEGRATION TESTS
638 | // =============================================================================
639 | 
640 | test.describe("Integration", () => {
641 |   test("component works correctly with custom content", async ({ page, initTestBed }) => {
642 |     await initTestBed(`
643 |       <Carousel>
644 |         <CarouselItem>
645 |           <Card title="Card 1" />
646 |         </CarouselItem>
647 |         <CarouselItem>
648 |           <Card title="Card 2" />
649 |         </CarouselItem>
650 |       </Carousel>
651 |     `);
652 |     await expect(page.getByRole("group").first()).toContainText("Card 1");
653 |     await expect(page.getByRole("group").last()).toContainText("Card 2");
654 |   });
655 | 
656 |   test("component handles custom control icon on Prev button", async ({ page, initTestBed }) => {
657 |     await initTestBed(
658 |       `
659 |           <Carousel controls="true" prevIcon="test">
660 |             <CarouselItem>Slide 1</CarouselItem>
661 |             <CarouselItem>Slide 2</CarouselItem>
662 |           </Carousel>    
663 |         `,
664 |       {
665 |         resources: {
666 |           "icon.test": "resources/bell.svg",
667 |         },
668 |       },
669 |     );
670 |     const useElement = page.getByRole("button", { name: "Previous Slide" }).locator("svg use");
671 |     await expect(useElement).toHaveAttribute("href", expect.stringMatching(/#bell/));
672 |   });
673 | 
674 |   test("component handles custom control icon on Next button", async ({ page, initTestBed }) => {
675 |     await initTestBed(
676 |       `
677 |           <Carousel controls="true" nextIcon="test">
678 |             <CarouselItem>Slide 1</CarouselItem>
679 |             <CarouselItem>Slide 2</CarouselItem>
680 |           </Carousel>    
681 |         `,
682 |       {
683 |         resources: {
684 |           "icon.test": "resources/bell.svg",
685 |         },
686 |       },
687 |     );
688 |     const useElement = page.getByRole("button", { name: "Next Slide" }).locator("svg use");
689 |     await expect(useElement).toHaveAttribute("href", expect.stringMatching(/#bell/));
690 |   });
691 | });
692 | 
```