This is page 117 of 186. Use http://codebase.md/xmlui-org/xmlui/%7Bnode.props.src?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/content/components/Text.md:
--------------------------------------------------------------------------------
```markdown
1 | # Text [#text]
2 |
3 | The `Text` component displays textual information in a number of optional styles and variants.
4 |
5 | You can learn more about this component in the [Working with Text](/working-with-text) article.
6 |
7 | Also note that variants of the `Text` component are also mapped to HtmlTag components.
8 | See the [variant](#variant) section to check which variant maps to which HtmlTag.
9 |
10 | ## Custom Variants [#custom-variants]
11 |
12 | In addition to the predefined variants, the `Text` component supports **custom variant names** that can be styled using theme variables. This allows you to create application-specific text styles without modifying the component itself.
13 |
14 | When you use a custom variant name (one not in the predefined list), the component automatically applies theme variables following the naming pattern: `{cssProperty}-Text-{variantName}`.
15 |
16 | ```xmlui-pg display name="Example: custom variants"
17 | <App>
18 | <Theme
19 | textColor-Text-brandTitle="rgb(41, 128, 185)"
20 | fontSize-Text-brandTitle="28px"
21 | fontWeight-Text-brandTitle="bold"
22 | letterSpacing-Text-brandTitle="2px"
23 | >
24 | <Text variant="brandTitle">
25 | Welcome to Our Application
26 | </Text>
27 | </Theme>
28 | </App>
29 | ```
30 |
31 | In this example, the custom variant `brandTitle` is styled using theme variables. Any CSS text property can be configured, including `textColor`, `fontSize`, `fontWeight`, `fontFamily`, `textDecoration*`, `lineHeight`, `backgroundColor`, `textTransform`, `letterSpacing`, `wordSpacing`, `textShadow`, and more.
32 |
33 | ## Properties [#properties]
34 |
35 | ### `breakMode` (default: "normal") [#breakmode-default-normal]
36 |
37 | This property controls how text breaks into multiple lines. `normal` uses standard word boundaries, `word` breaks long words to prevent overflow, `anywhere` breaks at any character, `keep` prevents word breaking, and `hyphenate` uses automatic hyphenation. When not specified, uses the default browser behavior or theme variables.
38 |
39 | Available values:
40 |
41 | | Value | Description |
42 | | --- | --- |
43 | | `normal` | Uses standard word boundaries for breaking **(default)** |
44 | | `word` | Breaks long words when necessary to prevent overflow |
45 | | `anywhere` | Breaks at any character if needed to fit content |
46 | | `keep` | Prevents breaking within words entirely |
47 | | `hyphenate` | Uses automatic hyphenation when breaking words |
48 |
49 | ```xmlui-pg copy display name="Example: breakMode"
50 | <App>
51 | <VStack gap="16px">
52 | <VStack gap="8px">
53 | <Text variant="strong">breakMode="normal" (default)</Text>
54 | <Text
55 | width="150px"
56 | backgroundColor="lightblue"
57 | padding="8px"
58 | breakMode="normal">
59 | This text uses standardwordbreaking at natural boundaries
60 | like spaces and hyphens.
61 | </Text>
62 | </VStack>
63 |
64 | <VStack gap="8px">
65 | <Text variant="strong">breakMode="word"</Text>
66 | <Text
67 | width="150px"
68 | backgroundColor="lightgreen"
69 | padding="8px"
70 | breakMode="word">
71 | This text will breakverylongwordswhenneeded to prevent
72 | overflow while preserving readability.
73 | </Text>
74 | </VStack>
75 |
76 | <VStack gap="8px">
77 | <Text variant="strong">breakMode="anywhere"</Text>
78 | <Text
79 | width="150px"
80 | backgroundColor="lightyellow"
81 | padding="8px"
82 | breakMode="anywhere">
83 | Thistext willbreakanywhereif neededtofit thecontainer
84 | eveninthe middleofwords.
85 | </Text>
86 | </VStack>
87 |
88 | <VStack gap="8px">
89 | <Text variant="strong">breakMode="keep"</Text>
90 | <Text
91 | width="150px"
92 | backgroundColor="lightcoral"
93 | padding="8px"
94 | breakMode="keep">
95 | This text will keep verylongwords intact and prevent
96 | breaking within words entirely.
97 | </Text>
98 | </VStack>
99 |
100 | <VStack gap="8px">
101 | <Text variant="strong">breakMode="hyphenate"</Text>
102 | <Text
103 | width="150px"
104 | backgroundColor="lavender"
105 | padding="8px"
106 | breakMode="hyphenate"
107 | lang="en">
108 | This text uses automatic hyphenation for
109 | supercalifragilisticexpialidocious words.
110 | </Text>
111 | </VStack>
112 | </VStack>
113 | </App>
114 | ```
115 |
116 | ### `ellipses` (default: true) [#ellipses-default-true]
117 |
118 | This property indicates whether ellipses should be displayed when the text is cropped (`true`) or not (`false`).
119 |
120 | ```xmlui-pg copy display name="Example: ellipses"
121 | <App>
122 | <VStack width="120px">
123 | <Text
124 | backgroundColor="cyan"
125 | color="black"
126 | maxLines="1"
127 | ellipses="false">
128 | Though this long text does is about to crop!
129 | </Text>
130 | <Text
131 | backgroundColor="cyan"
132 | color="black"
133 | maxLines="1">
134 | Though this long text does is about to crop!
135 | </Text>
136 | </VStack>
137 | </App>
138 | ```
139 |
140 | ### `maxLines` [#maxlines]
141 |
142 | This property determines the maximum number of lines the component can wrap to. If there is no space to display all the contents, the component displays up to as many lines as specified in this property. When the value is not defined, there is no limit on the displayed lines.
143 |
144 | ```xmlui-pg copy display name="Example: maxLines"
145 | <App>
146 | <Text
147 | maxWidth="120px"
148 | backgroundColor="cyan"
149 | color="black"
150 | value="A long text that will likely overflow"
151 | maxLines="2" />
152 | </App>
153 | ```
154 |
155 | ### `overflowMode` (default: "not specified") [#overflowmode-default-not-specified]
156 |
157 | This property controls how text overflow is handled. `none` prevents wrapping and shows no overflow indicator, `ellipsis` shows ellipses when text is truncated, `scroll` forces single line with horizontal scrolling, and `flow` allows multi-line wrapping with vertical scrolling when needed (ignores maxLines). When not specified, uses the default text behavior.
158 |
159 | Available values:
160 |
161 | | Value | Description |
162 | | --- | --- |
163 | | `none` | No wrapping, text stays on a single line with no overflow indicator |
164 | | `ellipsis` | Truncates with an ellipsis (default) |
165 | | `scroll` | Forces single line with horizontal scrolling when content overflows |
166 | | `flow` | Allows text to wrap into multiple lines with vertical scrolling when container height is constrained (ignores maxLines) |
167 |
168 | ```xmlui-pg copy display name="Example: overflowMode"
169 | <App>
170 | <VStack gap="16px">
171 | <VStack gap="8px">
172 | <Text variant="strong">overflowMode="none"</Text>
173 | <Text
174 | width="200px"
175 | backgroundColor="lightcoral"
176 | padding="8px"
177 | overflowMode="none"
178 | maxLines="2">
179 | This is a very long text that will be clipped cleanly without
180 | any overflow indicator when it exceeds the specified lines.
181 | </Text>
182 | </VStack>
183 |
184 | <VStack gap="8px">
185 | <Text variant="strong">overflowMode="ellipsis" (default)</Text>
186 | <Text
187 | width="200px"
188 | backgroundColor="lightblue"
189 | padding="8px"
190 | overflowMode="ellipsis"
191 | maxLines="1">
192 | This is a very long text that will show ellipsis when it
193 | overflows the container width.
194 | </Text>
195 | </VStack>
196 |
197 | <VStack gap="8px">
198 | <Text variant="strong">overflowMode="scroll"</Text>
199 | <Text
200 | width="200px"
201 | backgroundColor="lightgreen"
202 | padding="8px"
203 | overflowMode="scroll">
204 | This is a very long text that will enable horizontal scrolling
205 | when it overflows the container width.
206 | </Text>
207 | </VStack>
208 |
209 | <VStack gap="8px">
210 | <Text variant="strong">overflowMode="flow"</Text>
211 | <Text
212 | width="200px"
213 | height="100px"
214 | backgroundColor="lightyellow"
215 | padding="8px"
216 | overflowMode="flow">
217 | This is a very long text that will wrap to multiple lines and show
218 | a vertical scrollbar when the content exceeds the container height.
219 | This mode ignores maxLines and allows unlimited text wrapping with
220 | vertical scrolling when needed.
221 | </Text>
222 | </VStack>
223 |
224 | <VStack gap="8px">
225 | <Text variant="strong">overflowMode="flow" (no height constraint)</Text>
226 | <Text
227 | width="200px"
228 | backgroundColor="lightpink"
229 | padding="8px"
230 | overflowMode="flow">
231 | This is a very long text that demonstrates flow mode without a
232 | height constraint. The text will wrap to multiple lines naturally
233 | and the container will grow to accommodate all the content. No
234 | scrollbar will appear since there's no height limitation - the text
235 | flows freely across as many lines as needed.
236 | </Text>
237 | </VStack>
238 | </VStack>
239 | </App>
240 | ```
241 |
242 | ### `preserveLinebreaks` (default: false) [#preservelinebreaks-default-false]
243 |
244 | This property indicates if linebreaks should be preserved when displaying text.
245 |
246 | ```xmlui-pg copy {7} display name="Example: preserveLinebreaks"
247 | <App>
248 | <HStack>
249 | <Text
250 | width="250px"
251 | backgroundColor="cyan"
252 | color="black"
253 | preserveLinebreaks="true"
254 | value="(preserve) This long text
255 |
256 | with several line breaks
257 |
258 | does not fit into a viewport with a 200-pixel width." />
259 | <Text
260 | width="250px"
261 | backgroundColor="cyan"
262 | color="black"
263 | preserveLinebreaks="false"
264 | value="(don't preserve) This long text
265 |
266 | with several line breaks
267 |
268 | does not fit into a viewport with a 200-pixel width." />
269 | </HStack>
270 | </App>
271 | ```
272 |
273 | > **Note**: Remember to use the `value` property of the `Text`.
274 | > Linebreaks are converted to spaces when nesting the text inside the `Text` component.
275 |
276 | ### `value` [#value]
277 |
278 | The text to be displayed. This value can also be set via nesting the text into the `Text` component.
279 |
280 | ```xmlui-pg copy display name="Example: value"
281 | <App>
282 | <Text value="An example text" />
283 | <Text>An example text</Text>
284 | </App>
285 | ```
286 |
287 | ### `variant` [#variant]
288 |
289 | An optional string value that provides named presets for text variants with a unique combination of font style, weight, size, color, and other parameters. If not defined, the text uses the current style of its context. In addition to predefined variants, you can specify custom variant names and style them using theme variables with the pattern `{cssProperty}-Text-{variantName}` (e.g., `textColor-Text-brandTitle`, `fontSize-Text-highlight`). See the documentation for a complete list of supported CSS properties.
290 |
291 | Available values:
292 |
293 | | Value | Description |
294 | | --- | --- |
295 | | `abbr` | Represents an abbreviation or acronym |
296 | | `caption` | Represents the caption (or title) of a table |
297 | | `cite` | Is used to mark up the title of a cited work |
298 | | `code` | Represents a line of code |
299 | | `deleted` | Represents text that has been deleted |
300 | | `em` | Marks text to stress emphasis |
301 | | `inherit` | Represents text that inherits the style from its parent element |
302 | | `inserted` | Represents a range of text that has been added to a document |
303 | | `keyboard` | Represents a span of text denoting textual user input from a keyboard or voice input |
304 | | `marked` | Represents text which is marked or highlighted for reference or notation |
305 | | `mono` | Text using a mono style font family |
306 | | `paragraph` | Represents a paragraph |
307 | | `placeholder` | Text that is mostly used as the placeholder style in input controls |
308 | | `sample` | Represents sample (or quoted) output from a computer program |
309 | | `secondary` | Represents a bit dimmed secondary text |
310 | | `small` | Represents side-comments and small print |
311 | | `sub` | Specifies inline text as subscript |
312 | | `strong` | Contents have strong importance |
313 | | `subheading` | Indicates that the text is the subtitle in a heading |
314 | | `subtitle` | Indicates that the text is the subtitle of some other content |
315 | | `sup` | Specifies inline text as superscript |
316 | | `tableheading` | Indicates that the text is a table heading |
317 | | `title` | Indicates that the text is the title of some other content |
318 | | `var` | Represents the name of a variable in a mathematical expression |
319 |
320 | ```xmlui-pg name="Example: variant"
321 | <App>
322 | <HStack>
323 | <Text width="150px">default:</Text>
324 | <Text>This is an example text</Text>
325 | </HStack>
326 | <HStack>
327 | <Text width="150px">paragraph:</Text>
328 | <Text variant="paragraph">This is an example paragraph</Text>
329 | </HStack>
330 | <HStack>
331 | <Text width="150px">abbr:</Text>
332 | <Text variant="abbr">
333 | This is an example text
334 | </Text>
335 | </HStack>
336 | <HStack>
337 | <Text width="150px">cite:</Text>
338 | <Text variant="cite">
339 | This is an example text
340 | </Text>
341 | </HStack>
342 | <HStack>
343 | <Text width="150px">code:</Text>
344 | <Text variant="code">
345 | This is an example text
346 | </Text>
347 | </HStack>
348 | <HStack>
349 | <Text width="150px">deleted:</Text>
350 | <Text variant="deleted">
351 | This is an example text
352 | </Text>
353 | </HStack>
354 | <HStack>
355 | <Text width="150px">inserted:</Text>
356 | <Text variant="inserted">
357 | This is an example text
358 | </Text>
359 | </HStack>
360 | <HStack>
361 | <Text width="150px">keyboard:</Text>
362 | <Text variant="keyboard">
363 | This is an example text
364 | </Text>
365 | </HStack>
366 | <HStack>
367 | <Text width="150px">marked:</Text>
368 | <Text variant="marked">
369 | This is an example text
370 | </Text>
371 | </HStack>
372 | <HStack>
373 | <Text width="150px">sample:</Text>
374 | <Text variant="sample">
375 | This is an example text
376 | </Text>
377 | </HStack>
378 | <HStack>
379 | <Text width="150px">sup:</Text>
380 | <Text>
381 | This is an example text
382 | <Text variant="sup">(with some additional text)</Text>
383 | </Text>
384 | </HStack>
385 | <HStack>
386 | <Text width="150px">sub:</Text>
387 | <Text>
388 | This is an example text
389 | <Text variant="sub">(with some additional text)</Text>
390 | </Text>
391 | </HStack>
392 | <HStack>
393 | <Text width="150px">var:</Text>
394 | <Text variant="var">
395 | This is an example text
396 | </Text>
397 | </HStack>
398 | <HStack>
399 | <Text width="150px">mono:</Text>
400 | <Text variant="mono">
401 | This is an example text
402 | </Text>
403 | </HStack>
404 | <HStack>
405 | <Text width="150px">strong:</Text>
406 | <Text variant="strong">
407 | This is an example text
408 | </Text>
409 | </HStack>
410 | <HStack>
411 | <Text width="150px">em:</Text>
412 | <Text variant="em">
413 | This is an example text
414 | </Text>
415 | </HStack>
416 | <HStack>
417 | <Text width="150px">title:</Text>
418 | <Text variant="title">
419 | This is an example text
420 | </Text>
421 | </HStack>
422 | <HStack>
423 | <Text width="150px">subtitle:</Text>
424 | <Text variant="subtitle">
425 | This is an example text
426 | </Text>
427 | </HStack>
428 | <HStack>
429 | <Text width="150px">small:</Text>
430 | <Text variant="small">
431 | This is an example text
432 | </Text>
433 | </HStack>
434 | <HStack>
435 | <Text width="150px">caption:</Text>
436 | <Text variant="caption">
437 | This is an example text
438 | </Text>
439 | </HStack>
440 | <HStack>
441 | <Text width="150px">placeholder:</Text>
442 | <Text variant="placeholder">
443 | This is an example text
444 | </Text>
445 | </HStack>
446 | <HStack>
447 | <Text width="150px">subheading:</Text>
448 | <Text variant="subheading">
449 | This is an example text
450 | </Text>
451 | </HStack>
452 | <HStack>
453 | <Text width="150px">tableheading:</Text>
454 | <Text variant="tableheading">
455 | This is an example text
456 | </Text>
457 | </HStack>
458 | <HStack>
459 | <Text width="150px">secondary:</Text>
460 | <Text variant="secondary">
461 | This is an example text
462 | </Text>
463 | </HStack>
464 | </App>
465 | ```
466 |
467 | **HtmlTag Mappings**
468 |
469 | The table below indicates which Text `variant` maps to which HtmlTag component.
470 |
471 | | Variant | Component |
472 | | ----------- | --------- |
473 | | `abbr` | abbr |
474 | | `cite` | cite |
475 | | `code` | code |
476 | | `deleted` | del |
477 | | `inserted` | ins |
478 | | `keyboard` | kbd |
479 | | `marked` | mark |
480 | | `sample` | samp |
481 | | `sub` | sub |
482 | | `sup` | sup |
483 | | `var` | var |
484 | | `strong` | strong |
485 | | `em` | em |
486 | | `paragraph` | p |
487 |
488 | ## Events [#events]
489 |
490 | This component does not have any events.
491 |
492 | ## Exposed Methods [#exposed-methods]
493 |
494 | ### `hasOverflow` [#hasoverflow]
495 |
496 | Returns true when the displayed text overflows its container boundaries.
497 |
498 | **Signature**: `hasOverflow(): boolean`
499 |
500 | ## Styling [#styling]
501 |
502 | ### Custom Variant Theme Variables [#custom-variant-theme-variables]
503 |
504 | When using custom variants, you can style them using theme variables with the naming pattern `{propertyName}-Text-{variantName}`. The following CSS properties are supported:
505 |
506 | | Theme Variable Name | Description | Example Value |
507 | |---------------------|-------------|---------------|
508 | | `textColor-Text-{variant}` | Text color | `rgb(255, 0, 0)`, `#ff0000`, `red` |
509 | | `fontFamily-Text-{variant}` | Font family | `"Arial, sans-serif"`, `monospace` |
510 | | `fontSize-Text-{variant}` | Font size | `16px`, `1.5rem`, `large` |
511 | | `fontStyle-Text-{variant}` | Font style | `normal`, `italic`, `oblique` |
512 | | `fontWeight-Text-{variant}` | Font weight | `normal`, `bold`, `700` |
513 | | `fontStretch-Text-{variant}` | Font stretch | `normal`, `expanded`, `condensed` |
514 | | `textDecorationLine-Text-{variant}` | Decoration line type | `none`, `underline`, `overline`, `line-through` |
515 | | `textDecorationColor-Text-{variant}` | Decoration color | `rgb(255, 0, 0)`, `currentColor` |
516 | | `textDecorationStyle-Text-{variant}` | Decoration style | `solid`, `dashed`, `dotted`, `wavy` |
517 | | `textDecorationThickness-Text-{variant}` | Decoration thickness | `2px`, `from-font`, `auto` |
518 | | `textUnderlineOffset-Text-{variant}` | Underline offset | `5px`, `0.2em`, `auto` |
519 | | `lineHeight-Text-{variant}` | Line height | `1.5`, `24px`, `normal` |
520 | | `backgroundColor-Text-{variant}` | Background color | `rgb(255, 255, 0)`, `transparent` |
521 | | `textTransform-Text-{variant}` | Text transformation | `none`, `uppercase`, `lowercase`, `capitalize` |
522 | | `letterSpacing-Text-{variant}` | Space between letters | `1px`, `0.1em`, `normal` |
523 | | `wordSpacing-Text-{variant}` | Space between words | `5px`, `0.2em`, `normal` |
524 | | `textShadow-Text-{variant}` | Text shadow | `2px 2px 4px rgba(0,0,0,0.5)` |
525 | | `textIndent-Text-{variant}` | First line indentation | `20px`, `2em`, `0` |
526 | | `textAlign-Text-{variant}` | Horizontal alignment | `left`, `center`, `right`, `justify` |
527 | | `textAlignLast-Text-{variant}` | Last line alignment | `left`, `center`, `right`, `justify` |
528 | | `wordBreak-Text-{variant}` | Word breaking behavior | `normal`, `break-all`, `keep-all` |
529 | | `wordWrap-Text-{variant}` | Word wrapping | `normal`, `break-word` |
530 | | `direction-Text-{variant}` | Text direction | `ltr`, `rtl` |
531 | | `writingMode-Text-{variant}` | Writing mode | `horizontal-tb`, `vertical-rl`, `vertical-lr` |
532 | | `lineBreak-Text-{variant}` | Line breaking rules | `auto`, `normal`, `strict`, `loose` |
533 |
534 | ```xmlui-pg display name="Example: custom variant styles" /highlight/
535 | <App>
536 | <Theme
537 | textColor-Text-highlight="rgb(255, 193, 7)"
538 | fontWeight-Text-highlight="bold"
539 | backgroundColor-Text-highlight="rgba(0, 0, 0, 0.8)"
540 | padding-Text-highlight="4px 8px"
541 | textShadow-Text-highlight="0 2px 4px rgba(0,0,0,0.5)"
542 | >
543 | <Text variant="highlight">Important Notice</Text>
544 | <Text variant="highlight">This is Important Too</Text>
545 | </Theme>
546 | </App>
547 | ```
548 |
549 | ### Theme Variables [#theme-variables]
550 |
551 | | Variable | Default Value (Light) | Default Value (Dark) |
552 | | --- | --- | --- |
553 | | [backgroundColor](../styles-and-themes/common-units/#color)-Text | *none* | *none* |
554 | | [backgroundColor](../styles-and-themes/common-units/#color)-Text-code | rgb(from $color-surface-100 r g b / 0.4) | rgb(from $color-surface-100 r g b / 0.4) |
555 | | [backgroundColor](../styles-and-themes/common-units/#color)-Text-keyboard | rgb(from $color-surface-100 r g b / 0.4) | rgb(from $color-surface-100 r g b / 0.4) |
556 | | [backgroundColor](../styles-and-themes/common-units/#color)-Text-marked | rgb(from $color-primary-200 r g b / 0.4) | rgb(from $color-primary-400 r g b / 0.4) |
557 | | [borderColor](../styles-and-themes/common-units/#color)-Text-code | $color-surface-100 | $color-surface-100 |
558 | | [borderColor](../styles-and-themes/common-units/#color)-Text-keyboard | $color-surface-300 | $color-surface-300 |
559 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-Text | $borderRadius | $borderRadius |
560 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-Text-code | 4px | 4px |
561 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-Text-keyboard | *none* | *none* |
562 | | [borderStyle](../styles-and-themes/common-units/#border-style)-Text | solid | solid |
563 | | [borderStyle](../styles-and-themes/common-units/#border-style)-Text-code | solid | solid |
564 | | [borderStyle](../styles-and-themes/common-units/#border-style)-Text-keyboard | *none* | *none* |
565 | | [borderWidth](../styles-and-themes/common-units/#size)-Text | $space-0 | $space-0 |
566 | | [borderWidth](../styles-and-themes/common-units/#size)-Text-code | 1px | 1px |
567 | | [borderWidth](../styles-and-themes/common-units/#size)-Text-keyboard | 1px | 1px |
568 | | [direction](../styles-and-themes/layout-props#direction)-Text | *none* | *none* |
569 | | [fontFamily](../styles-and-themes/common-units/#fontFamily)-Text | $fontFamily | $fontFamily |
570 | | [fontFamily](../styles-and-themes/common-units/#fontFamily)-Text-code | $fontFamily-monospace | $fontFamily-monospace |
571 | | [fontFamily](../styles-and-themes/common-units/#fontFamily)-Text-codefence | $fontFamily-monospace | $fontFamily-monospace |
572 | | [fontFamily](../styles-and-themes/common-units/#fontFamily)-Text-keyboard | $fontFamily-monospace | $fontFamily-monospace |
573 | | [fontFamily](../styles-and-themes/common-units/#fontFamily)-Text-mono | $fontFamily-monospace | $fontFamily-monospace |
574 | | [fontFamily](../styles-and-themes/common-units/#fontFamily)-Text-sample | $fontFamily-monospace | $fontFamily-monospace |
575 | | [fontSize](../styles-and-themes/common-units/#size)-Text | $fontSize-sm | $fontSize-sm |
576 | | [fontSize](../styles-and-themes/common-units/#size)-Text-code | $fontSize-sm | $fontSize-sm |
577 | | [fontSize](../styles-and-themes/common-units/#size)-Text-codefence | $fontSize-code | $fontSize-code |
578 | | [fontSize](../styles-and-themes/common-units/#size)-Text-keyboard | $fontSize-sm | $fontSize-sm |
579 | | [fontSize](../styles-and-themes/common-units/#size)-Text-paragraph | *none* | *none* |
580 | | [fontSize](../styles-and-themes/common-units/#size)-Text-placeholder | $fontSize-xs | $fontSize-xs |
581 | | [fontSize](../styles-and-themes/common-units/#size)-Text-sample | $fontSize-sm | $fontSize-sm |
582 | | [fontSize](../styles-and-themes/common-units/#size)-Text-secondary | $fontSize-sm | $fontSize-sm |
583 | | [fontSize](../styles-and-themes/common-units/#size)-Text-small | $fontSize-sm | $fontSize-sm |
584 | | [fontSize](../styles-and-themes/common-units/#size)-Text-sub | $fontSize-xs | $fontSize-xs |
585 | | [fontSize](../styles-and-themes/common-units/#size)-Text-subheading | $fontSize-H6 | $fontSize-H6 |
586 | | [fontSize](../styles-and-themes/common-units/#size)-Text-subtitle | $fontSize-xl | $fontSize-xl |
587 | | [fontSize](../styles-and-themes/common-units/#size)-Text-sup | $fontSize-xs | $fontSize-xs |
588 | | [fontSize](../styles-and-themes/common-units/#size)-Text-tableheading | $fontSize-H6 | $fontSize-H6 |
589 | | [fontSize](../styles-and-themes/common-units/#size)-Text-title | $fontSize-2xl | $fontSize-2xl |
590 | | [fontStretch](../styles-and-themes/common-units/#fontStretch)-Text | *none* | *none* |
591 | | [fontStyle](../styles-and-themes/common-units/#fontStyle)-Text | *none* | *none* |
592 | | [fontStyle](../styles-and-themes/common-units/#fontStyle)-Text-cite | italic | italic |
593 | | [fontStyle](../styles-and-themes/common-units/#fontStyle)-Text-em | italic | italic |
594 | | [fontStyle](../styles-and-themes/common-units/#fontStyle)-Text-marked | *none* | *none* |
595 | | [fontStyle](../styles-and-themes/common-units/#fontStyle)-Text-placeholder | *none* | *none* |
596 | | [fontStyle](../styles-and-themes/common-units/#fontStyle)-Text-subheading | *none* | *none* |
597 | | [fontStyle](../styles-and-themes/common-units/#fontStyle)-Text-var | italic | italic |
598 | | [fontVariant](../styles-and-themes/common-units/#font-variant)-Text | *none* | *none* |
599 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Text | $fontWeight-normal | $fontWeight-normal |
600 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Text-abbr | $fontWeight-bold | $fontWeight-bold |
601 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Text-keyboard | $fontWeight-bold | $fontWeight-bold |
602 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Text-marked | *none* | *none* |
603 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Text-placeholder | *none* | *none* |
604 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Text-strong | $fontWeight-bold | $fontWeight-bold |
605 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Text-subheading | $fontWeight-bold | $fontWeight-bold |
606 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Text-tableheading | $fontWeight-bold | $fontWeight-bold |
607 | | [letterSpacing](../styles-and-themes/common-units/#size)-Text | *none* | *none* |
608 | | [letterSpacing](../styles-and-themes/common-units/#size)-Text-caption | 0.05rem | 0.05rem |
609 | | [letterSpacing](../styles-and-themes/common-units/#size)-Text-subheading | 0.04em | 0.04em |
610 | | [lineBreak](../styles-and-themes/common-units/#line-break)-Text | *none* | *none* |
611 | | [lineHeight](../styles-and-themes/common-units/#size)-Text | *none* | *none* |
612 | | [lineHeight](../styles-and-themes/common-units/#size)-Text-codefence | 1.5 | 1.5 |
613 | | [lineHeight](../styles-and-themes/common-units/#size)-Text-marked | *none* | *none* |
614 | | [marginBottom](../styles-and-themes/common-units/#size)-Text | *none* | *none* |
615 | | [marginBottom](../styles-and-themes/common-units/#size)-Text-code | *none* | *none* |
616 | | [marginBottom](../styles-and-themes/common-units/#size)-Text-small | *none* | *none* |
617 | | [marginBottom](../styles-and-themes/common-units/#size)-Text-tableheading | $space-4 | $space-4 |
618 | | [marginLeft](../styles-and-themes/common-units/#size)-Text | *none* | *none* |
619 | | [marginLeft](../styles-and-themes/common-units/#size)-Text-code | *none* | *none* |
620 | | [marginLeft](../styles-and-themes/common-units/#size)-Text-small | *none* | *none* |
621 | | [marginRight](../styles-and-themes/common-units/#size)-Text | *none* | *none* |
622 | | [marginRight](../styles-and-themes/common-units/#size)-Text-code | *none* | *none* |
623 | | [marginRight](../styles-and-themes/common-units/#size)-Text-small | *none* | *none* |
624 | | [marginTop](../styles-and-themes/common-units/#size)-Text | *none* | *none* |
625 | | [marginTop](../styles-and-themes/common-units/#size)-Text-code | *none* | *none* |
626 | | [marginTop](../styles-and-themes/common-units/#size)-Text-small | *none* | *none* |
627 | | [marginTop](../styles-and-themes/common-units/#size)-Text-tableheading | $space-1 | $space-1 |
628 | | [paddingBottom](../styles-and-themes/common-units/#size)-Text-code | 2px | 2px |
629 | | [paddingHorizontal](../styles-and-themes/common-units/#size)-Text-code | $space-0_5 | $space-0_5 |
630 | | [paddingHorizontal](../styles-and-themes/common-units/#size)-Text-codefence | $space-4 | $space-4 |
631 | | [paddingHorizontal](../styles-and-themes/common-units/#size)-Text-keyboard | $space-1 | $space-1 |
632 | | [paddingHorizontal](../styles-and-themes/common-units/#size)-Text-tableheading | $space-1 | $space-1 |
633 | | [paddingVertical](../styles-and-themes/common-units/#size)-Text-codefence | $space-3 | $space-3 |
634 | | [paddingVertical](../styles-and-themes/common-units/#size)-Text-paragraph | $space-1 | $space-1 |
635 | | [textAlign](../styles-and-themes/common-units/#text-align)-Text | *none* | *none* |
636 | | [textAlignLast](../styles-and-themes/common-units/#text-align)-Text | *none* | *none* |
637 | | [textColor](../styles-and-themes/common-units/#color)-Text | $textColor-primary | $textColor-primary |
638 | | [textColor](../styles-and-themes/common-units/#color)-Text--hover | *none* | *none* |
639 | | [textColor](../styles-and-themes/common-units/#color)-Text-code--hover | *none* | *none* |
640 | | [textColor](../styles-and-themes/common-units/#color)-Text-codefence | $color-surface-900 | $color-surface-900 |
641 | | [textColor](../styles-and-themes/common-units/#color)-Text-marked | *none* | *none* |
642 | | [textColor](../styles-and-themes/common-units/#color)-Text-placeholder | $color-surface-500 | $color-surface-500 |
643 | | [textColor](../styles-and-themes/common-units/#color)-Text-secondary | $textColor-secondary | $textColor-secondary |
644 | | [textColor](../styles-and-themes/common-units/#color)-Text-small--hover | *none* | *none* |
645 | | [textColor](../styles-and-themes/common-units/#color)-Text-subheading | $textColor-secondary | $textColor-secondary |
646 | | [textDecorationColor](../styles-and-themes/common-units/#color)-Text | *none* | *none* |
647 | | [textDecorationColor](../styles-and-themes/common-units/#color)-Text-deleted | *none* | *none* |
648 | | [textDecorationColor](../styles-and-themes/common-units/#color)-Text-inserted | *none* | *none* |
649 | | [textDecorationLine](../styles-and-themes/common-units/#textDecoration)-Text | *none* | *none* |
650 | | [textDecorationLine](../styles-and-themes/common-units/#textDecoration)-Text-deleted | line-through | line-through |
651 | | [textDecorationLine](../styles-and-themes/common-units/#textDecoration)-Text-inserted | underline | underline |
652 | | [textDecorationStyle](../styles-and-themes/common-units/#textDecoration)-Text | *none* | *none* |
653 | | [textDecorationStyle](../styles-and-themes/common-units/#textDecoration)-Text-deleted | *none* | *none* |
654 | | [textDecorationStyle](../styles-and-themes/common-units/#textDecoration)-Text-inserted | *none* | *none* |
655 | | [textDecorationThickness](../styles-and-themes/common-units/#textDecoration)-Text | *none* | *none* |
656 | | [textDecorationThickness](../styles-and-themes/common-units/#textDecoration)-Text-deleted | *none* | *none* |
657 | | [textDecorationThickness](../styles-and-themes/common-units/#textDecoration)-Text-inserted | *none* | *none* |
658 | | [textIndent](../styles-and-themes/common-units/#text-indent)-Text | *none* | *none* |
659 | | [textShadow](../styles-and-themes/common-units/#text-shadow)-Text | *none* | *none* |
660 | | [textTransform](../styles-and-themes/common-units/#textTransform)-Text | *none* | *none* |
661 | | [textTransform](../styles-and-themes/common-units/#textTransform)-Text-abbr | uppercase | uppercase |
662 | | [textTransform](../styles-and-themes/common-units/#textTransform)-Text-subheading | uppercase | uppercase |
663 | | [textUnderlineOffset](../styles-and-themes/common-units/#size)-Text | *none* | *none* |
664 | | [verticalAlignment](../styles-and-themes/common-units/#alignment)-Text | *none* | *none* |
665 | | [verticalAlignment](../styles-and-themes/common-units/#alignment)-Text-code | *none* | *none* |
666 | | [verticalAlignment](../styles-and-themes/common-units/#alignment)-Text-small | *none* | *none* |
667 | | [verticalAlignment](../styles-and-themes/common-units/#alignment)-Text-sub | sub | sub |
668 | | [verticalAlignment](../styles-and-themes/common-units/#alignment)-Text-sup | super | super |
669 | | [wordBreak](../styles-and-themes/common-units/#word-break)-Text | *none* | *none* |
670 | | [wordSpacing](../styles-and-themes/common-units/#word-spacing)-Text | *none* | *none* |
671 | | [wordWrap](../styles-and-themes/common-units/#word-wrap)-Text | *none* | *none* |
672 | | [writingMode](../styles-and-themes/common-units/#writing-mode)-Text | *none* | *none* |
673 |
```
--------------------------------------------------------------------------------
/xmlui/tests/components-core/theming/component-layout.resolver.test.ts:
--------------------------------------------------------------------------------
```typescript
1 | import { describe, expect, it } from "vitest";
2 | import {
3 | BASE_COMPONENT_PART,
4 | resolveComponentLayoutProps,
5 | } from "../../../src/components-core/theming/component-layout-resolver";
6 |
7 | describe("Component property layout", () => {
8 | it("should parse empty", () => {
9 | const result = resolveComponentLayoutProps({});
10 | expect(result).toStrictEqual({});
11 | });
12 |
13 | describe("single component properties", () => {
14 | it("single component property", () => {
15 | const result = resolveComponentLayoutProps({
16 | color: "red",
17 | });
18 | expect(result).toStrictEqual({
19 | [BASE_COMPONENT_PART]: {
20 | baseStyles: { color: "red" },
21 | },
22 | });
23 | });
24 |
25 | it("single component property: paddingHorizontal", () => {
26 | const result = resolveComponentLayoutProps({
27 | paddingHorizontal: "12px",
28 | });
29 | expect(result).toStrictEqual({
30 | [BASE_COMPONENT_PART]: {
31 | baseStyles: { paddingLeft: "12px", paddingRight: "12px" },
32 | },
33 | });
34 | });
35 |
36 | it("single component property: paddingVertical", () => {
37 | const result = resolveComponentLayoutProps({
38 | paddingVertical: "12px",
39 | });
40 | expect(result).toStrictEqual({
41 | [BASE_COMPONENT_PART]: {
42 | baseStyles: { paddingTop: "12px", paddingBottom: "12px" },
43 | },
44 | });
45 | });
46 |
47 | it("single component property: marginHorizontal", () => {
48 | const result = resolveComponentLayoutProps({
49 | marginHorizontal: "12px",
50 | });
51 | expect(result).toStrictEqual({
52 | [BASE_COMPONENT_PART]: {
53 | baseStyles: { marginLeft: "12px", marginRight: "12px" },
54 | },
55 | });
56 | });
57 |
58 | it("single component property: marginVertical", () => {
59 | const result = resolveComponentLayoutProps({
60 | marginVertical: "12px",
61 | });
62 | expect(result).toStrictEqual({
63 | [BASE_COMPONENT_PART]: {
64 | baseStyles: { marginTop: "12px", marginBottom: "12px" },
65 | },
66 | });
67 | });
68 |
69 | it("single component property: borderHorizontal", () => {
70 | const result = resolveComponentLayoutProps({
71 | borderHorizontal: "12px",
72 | });
73 | expect(result).toStrictEqual({
74 | [BASE_COMPONENT_PART]: {
75 | baseStyles: { borderLeft: "12px", borderRight: "12px" },
76 | },
77 | });
78 | });
79 |
80 | it("single component property: borderVertical", () => {
81 | const result = resolveComponentLayoutProps({
82 | borderVertical: "12px",
83 | });
84 | expect(result).toStrictEqual({
85 | [BASE_COMPONENT_PART]: {
86 | baseStyles: { borderTop: "12px", borderBottom: "12px" },
87 | },
88 | });
89 | });
90 |
91 | it("single component property: wrapContent/true", () => {
92 | const result = resolveComponentLayoutProps({
93 | wrapContent: true,
94 | });
95 | expect(result).toStrictEqual({
96 | [BASE_COMPONENT_PART]: {
97 | baseStyles: { flexWrap: "wrap" },
98 | },
99 | });
100 | });
101 |
102 | it("single component property: wrapContent/false", () => {
103 | const result = resolveComponentLayoutProps({
104 | wrapContent: false,
105 | });
106 | expect(result).toStrictEqual({
107 | [BASE_COMPONENT_PART]: {
108 | baseStyles: { flexWrap: "nowrap" },
109 | },
110 | });
111 | });
112 |
113 | it("single component property: canShrink/true", () => {
114 | const result = resolveComponentLayoutProps({
115 | canShrink: true,
116 | });
117 | expect(result).toStrictEqual({
118 | [BASE_COMPONENT_PART]: {
119 | baseStyles: { flexShrink: 1 },
120 | },
121 | });
122 | });
123 |
124 | it("single component property: canShrink/false", () => {
125 | const result = resolveComponentLayoutProps({
126 | canShrink: false,
127 | });
128 | expect(result).toStrictEqual({
129 | [BASE_COMPONENT_PART]: {
130 | baseStyles: { flexShrink: 0 },
131 | },
132 | });
133 | });
134 |
135 | it("single component property: width (no star size)", () => {
136 | const result = resolveComponentLayoutProps({
137 | width: "100px",
138 | });
139 | expect(result).toStrictEqual({
140 | [BASE_COMPONENT_PART]: {
141 | baseStyles: { width: "100px" },
142 | },
143 | });
144 | });
145 |
146 | it("single component property: width (star size)", () => {
147 | const result = resolveComponentLayoutProps(
148 | {
149 | width: "23*",
150 | },
151 | {
152 | type: "Stack",
153 | orientation: "horizontal",
154 | },
155 | );
156 | expect(result).toStrictEqual({
157 | [BASE_COMPONENT_PART]: {
158 | baseStyles: { flex: 23, flexShrink: 1 },
159 | },
160 | });
161 | });
162 |
163 | it("single component property: height (no star size)", () => {
164 | const result = resolveComponentLayoutProps({
165 | height: "100px",
166 | });
167 | expect(result).toStrictEqual({
168 | [BASE_COMPONENT_PART]: {
169 | baseStyles: { height: "100px" },
170 | },
171 | });
172 | });
173 |
174 | it("single component property: height (star size)", () => {
175 | const result = resolveComponentLayoutProps(
176 | {
177 | height: "23*",
178 | },
179 | {
180 | type: "Stack",
181 | orientation: "vertical",
182 | },
183 | );
184 | expect(result).toStrictEqual({
185 | [BASE_COMPONENT_PART]: {
186 | baseStyles: { flex: 23, flexShrink: 1 },
187 | },
188 | });
189 | });
190 | });
191 |
192 | describe("multiple component properties", () => {
193 | it("multiple component properties", () => {
194 | const result = resolveComponentLayoutProps({
195 | color: "red",
196 | backgroundColor: "green",
197 | });
198 | expect(result).toStrictEqual({
199 | [BASE_COMPONENT_PART]: {
200 | baseStyles: { color: "red", backgroundColor: "green" },
201 | },
202 | });
203 | });
204 |
205 | it("multiple component properties: paddingHorizontal", () => {
206 | const result = resolveComponentLayoutProps({
207 | paddingHorizontal: "12px",
208 | backgroundColor: "green",
209 | });
210 | expect(result).toStrictEqual({
211 | [BASE_COMPONENT_PART]: {
212 | baseStyles: { paddingLeft: "12px", paddingRight: "12px", backgroundColor: "green" },
213 | },
214 | });
215 | });
216 |
217 | it("multiple component properties: paddingVertical", () => {
218 | const result = resolveComponentLayoutProps({
219 | paddingVertical: "12px",
220 | backgroundColor: "green",
221 | });
222 | expect(result).toStrictEqual({
223 | [BASE_COMPONENT_PART]: {
224 | baseStyles: { paddingTop: "12px", paddingBottom: "12px", backgroundColor: "green" },
225 | },
226 | });
227 | });
228 |
229 | it("multiple component properties: marginHorizontal", () => {
230 | const result = resolveComponentLayoutProps({
231 | marginHorizontal: "12px",
232 | backgroundColor: "green",
233 | });
234 | expect(result).toStrictEqual({
235 | [BASE_COMPONENT_PART]: {
236 | baseStyles: { marginLeft: "12px", marginRight: "12px", backgroundColor: "green" },
237 | },
238 | });
239 | });
240 |
241 | it("multiple component properties: marginVertical", () => {
242 | const result = resolveComponentLayoutProps({
243 | marginVertical: "12px",
244 | backgroundColor: "green",
245 | });
246 | expect(result).toStrictEqual({
247 | [BASE_COMPONENT_PART]: {
248 | baseStyles: { marginTop: "12px", marginBottom: "12px", backgroundColor: "green" },
249 | },
250 | });
251 | });
252 |
253 | it("multiple component properties: borderHorizontal", () => {
254 | const result = resolveComponentLayoutProps({
255 | borderHorizontal: "12px",
256 | backgroundColor: "green",
257 | });
258 | expect(result).toStrictEqual({
259 | [BASE_COMPONENT_PART]: {
260 | baseStyles: { borderLeft: "12px", borderRight: "12px", backgroundColor: "green" },
261 | },
262 | });
263 | });
264 |
265 | it("multiple component properties: borderVertical", () => {
266 | const result = resolveComponentLayoutProps({
267 | borderVertical: "12px",
268 | backgroundColor: "green",
269 | });
270 | expect(result).toStrictEqual({
271 | [BASE_COMPONENT_PART]: {
272 | baseStyles: { borderTop: "12px", borderBottom: "12px", backgroundColor: "green" },
273 | },
274 | });
275 | });
276 |
277 | it("multiple component properties: wrapContent/true", () => {
278 | const result = resolveComponentLayoutProps({
279 | wrapContent: true,
280 | backgroundColor: "green",
281 | });
282 | expect(result).toStrictEqual({
283 | [BASE_COMPONENT_PART]: {
284 | baseStyles: { flexWrap: "wrap", backgroundColor: "green" },
285 | },
286 | });
287 | });
288 |
289 | it("multiple component properties: wrapContent/false", () => {
290 | const result = resolveComponentLayoutProps({
291 | wrapContent: false,
292 | backgroundColor: "green",
293 | });
294 | expect(result).toStrictEqual({
295 | [BASE_COMPONENT_PART]: {
296 | baseStyles: { flexWrap: "nowrap", backgroundColor: "green" },
297 | },
298 | });
299 | });
300 |
301 | it("multiple component properties: canShrink/true", () => {
302 | const result = resolveComponentLayoutProps({
303 | canShrink: true,
304 | backgroundColor: "green",
305 | });
306 | expect(result).toStrictEqual({
307 | [BASE_COMPONENT_PART]: {
308 | baseStyles: { flexShrink: 1, backgroundColor: "green" },
309 | },
310 | });
311 | });
312 |
313 | it("multiple component properties: canShrink/false", () => {
314 | const result = resolveComponentLayoutProps({
315 | canShrink: false,
316 | backgroundColor: "green",
317 | });
318 | expect(result).toStrictEqual({
319 | [BASE_COMPONENT_PART]: {
320 | baseStyles: { flexShrink: 0, backgroundColor: "green" },
321 | },
322 | });
323 | });
324 |
325 | it("multiple component properties: width (no star size)", () => {
326 | const result = resolveComponentLayoutProps({
327 | width: "100px",
328 | backgroundColor: "green",
329 | });
330 | expect(result).toStrictEqual({
331 | [BASE_COMPONENT_PART]: {
332 | baseStyles: { width: "100px", backgroundColor: "green" },
333 | },
334 | });
335 | });
336 |
337 | it("multiple component properties: width (star size)", () => {
338 | const result = resolveComponentLayoutProps(
339 | {
340 | width: "23*",
341 | backgroundColor: "green",
342 | },
343 | {
344 | type: "Stack",
345 | orientation: "horizontal",
346 | },
347 | );
348 | expect(result).toStrictEqual({
349 | [BASE_COMPONENT_PART]: {
350 | baseStyles: { flex: 23, flexShrink: 1, backgroundColor: "green" },
351 | },
352 | });
353 | });
354 |
355 | it("multiple component properties: height (no star size)", () => {
356 | const result = resolveComponentLayoutProps({
357 | height: "100px",
358 | backgroundColor: "green",
359 | });
360 | expect(result).toStrictEqual({
361 | [BASE_COMPONENT_PART]: {
362 | baseStyles: { height: "100px", backgroundColor: "green" },
363 | },
364 | });
365 | });
366 |
367 | it("multiple component properties: height (star size)", () => {
368 | const result = resolveComponentLayoutProps(
369 | {
370 | height: "23*",
371 | backgroundColor: "green",
372 | },
373 | {
374 | type: "Stack",
375 | orientation: "vertical",
376 | },
377 | );
378 | expect(result).toStrictEqual({
379 | [BASE_COMPONENT_PART]: {
380 | baseStyles: { flex: 23, flexShrink: 1, backgroundColor: "green" },
381 | },
382 | });
383 | });
384 | });
385 |
386 | describe("single component properties with state", () => {
387 | it("single component property with state", () => {
388 | const result = resolveComponentLayoutProps({
389 | "color--hover": "red",
390 | });
391 | expect(result).toStrictEqual({
392 | [BASE_COMPONENT_PART]: {
393 | baseStyles: { states: { hover: { color: "red" } } },
394 | },
395 | });
396 | });
397 |
398 | it("single component property with multiple states #1", () => {
399 | const result = resolveComponentLayoutProps({
400 | "color--hover--active": "red",
401 | });
402 | expect(result).toStrictEqual({
403 | [BASE_COMPONENT_PART]: {
404 | baseStyles: { states: { "hover&active": { color: "red" } } },
405 | },
406 | });
407 | });
408 |
409 | it("single component property with multiple states #2", () => {
410 | const result = resolveComponentLayoutProps({
411 | "color--hover--active--focus": "red",
412 | });
413 | expect(result).toStrictEqual({
414 | [BASE_COMPONENT_PART]: {
415 | baseStyles: { states: { "hover&active&focus": { color: "red" } } },
416 | },
417 | });
418 | });
419 |
420 | it("multiple component properties with state", () => {
421 | const result = resolveComponentLayoutProps({
422 | "color--hover": "red",
423 | "backgroundColor--hover": "blue",
424 | });
425 | expect(result).toStrictEqual({
426 | [BASE_COMPONENT_PART]: {
427 | baseStyles: { states: { hover: { color: "red", backgroundColor: "blue" } } },
428 | },
429 | });
430 | });
431 |
432 | it("multiple component properties with multiple states #1", () => {
433 | const result = resolveComponentLayoutProps({
434 | "color--focus": "red",
435 | "backgroundColor--hover": "blue",
436 | });
437 | expect(result).toStrictEqual({
438 | [BASE_COMPONENT_PART]: {
439 | baseStyles: { states: { focus: { color: "red" }, hover: { backgroundColor: "blue" } } },
440 | },
441 | });
442 | });
443 |
444 | it("multiple component properties with multiple states #2", () => {
445 | const result = resolveComponentLayoutProps({
446 | "color--focus": "red",
447 | "backgroundColor--hover--focus": "blue",
448 | });
449 | expect(result).toStrictEqual({
450 | [BASE_COMPONENT_PART]: {
451 | baseStyles: {
452 | states: { focus: { color: "red" }, "hover&focus": { backgroundColor: "blue" } },
453 | },
454 | },
455 | });
456 | });
457 |
458 | it("multiple component properties with multiple states #3", () => {
459 | const result = resolveComponentLayoutProps({
460 | "color--focus": "red",
461 | "backgroundColor--focus": "blue",
462 | });
463 | expect(result).toStrictEqual({
464 | [BASE_COMPONENT_PART]: {
465 | baseStyles: { states: { focus: { color: "red", backgroundColor: "blue" } } },
466 | },
467 | });
468 | });
469 |
470 | it("multiple component properties with multiple states #4", () => {
471 | const result = resolveComponentLayoutProps({
472 | "color--focus--active": "red",
473 | "backgroundColor--focus": "blue",
474 | });
475 | expect(result).toStrictEqual({
476 | [BASE_COMPONENT_PART]: {
477 | baseStyles: {
478 | states: { focus: { backgroundColor: "blue" }, "focus&active": { color: "red" } },
479 | },
480 | },
481 | });
482 | });
483 | });
484 |
485 | describe("multiple component properties with and without state", () => {
486 | it("multiple component properties with state", () => {
487 | const result = resolveComponentLayoutProps({
488 | "color--hover": "red",
489 | backgroundColor: "green",
490 | });
491 | expect(result).toStrictEqual({
492 | [BASE_COMPONENT_PART]: {
493 | baseStyles: { backgroundColor: "green", states: { hover: { color: "red" } } },
494 | },
495 | });
496 | });
497 |
498 | it("multiple component properties with multiple states #1", () => {
499 | const result = resolveComponentLayoutProps({
500 | "color--hover--active": "red",
501 | backgroundColor: "green",
502 | });
503 | expect(result).toStrictEqual({
504 | [BASE_COMPONENT_PART]: {
505 | baseStyles: { backgroundColor: "green", states: { "hover&active": { color: "red" } } },
506 | },
507 | });
508 | });
509 |
510 | it("multiple component properties with multiple states #2", () => {
511 | const result = resolveComponentLayoutProps({
512 | "color--hover--active--focus": "red",
513 | backgroundColor: "green",
514 | });
515 | expect(result).toStrictEqual({
516 | [BASE_COMPONENT_PART]: {
517 | baseStyles: {
518 | backgroundColor: "green",
519 | states: { "hover&active&focus": { color: "red" } },
520 | },
521 | },
522 | });
523 | });
524 |
525 | it("multiple component properties with state (both with state)", () => {
526 | const result = resolveComponentLayoutProps({
527 | "color--hover": "red",
528 | "backgroundColor--hover": "blue",
529 | });
530 | expect(result).toStrictEqual({
531 | [BASE_COMPONENT_PART]: {
532 | baseStyles: { states: { hover: { color: "red", backgroundColor: "blue" } } },
533 | },
534 | });
535 | });
536 |
537 | it("multiple component properties with multiple states #1 (mixed)", () => {
538 | const result = resolveComponentLayoutProps({
539 | "color--focus": "red",
540 | "backgroundColor--hover": "blue",
541 | padding: "10px",
542 | });
543 | expect(result).toStrictEqual({
544 | [BASE_COMPONENT_PART]: {
545 | baseStyles: {
546 | padding: "10px",
547 | states: { focus: { color: "red" }, hover: { backgroundColor: "blue" } },
548 | },
549 | },
550 | });
551 | });
552 |
553 | it("multiple component properties with multiple states #2 (mixed)", () => {
554 | const result = resolveComponentLayoutProps({
555 | "color--focus": "red",
556 | "backgroundColor--hover--focus": "blue",
557 | margin: "5px",
558 | });
559 | expect(result).toStrictEqual({
560 | [BASE_COMPONENT_PART]: {
561 | baseStyles: {
562 | margin: "5px",
563 | states: { focus: { color: "red" }, "hover&focus": { backgroundColor: "blue" } },
564 | },
565 | },
566 | });
567 | });
568 |
569 | it("multiple component properties with multiple states #3 (mixed)", () => {
570 | const result = resolveComponentLayoutProps({
571 | "color--focus": "red",
572 | "backgroundColor--focus": "blue",
573 | border: "1px solid black",
574 | });
575 | expect(result).toStrictEqual({
576 | [BASE_COMPONENT_PART]: {
577 | baseStyles: {
578 | border: "1px solid black",
579 | states: { focus: { color: "red", backgroundColor: "blue" } },
580 | },
581 | },
582 | });
583 | });
584 |
585 | it("multiple component properties with multiple states #4 (mixed)", () => {
586 | const result = resolveComponentLayoutProps({
587 | "color--focus--active": "red",
588 | "backgroundColor--focus": "blue",
589 | fontSize: "14px",
590 | });
591 | expect(result).toStrictEqual({
592 | [BASE_COMPONENT_PART]: {
593 | baseStyles: {
594 | fontSize: "14px",
595 | states: { focus: { backgroundColor: "blue" }, "focus&active": { color: "red" } },
596 | },
597 | },
598 | });
599 | });
600 | });
601 |
602 | describe("component properties with parts", () => {
603 | it("single component property with part", () => {
604 | const result = resolveComponentLayoutProps({
605 | "color-indicator": "red",
606 | });
607 | expect(result).toStrictEqual({
608 | indicator: {
609 | baseStyles: { color: "red" },
610 | },
611 | });
612 | });
613 |
614 | it("multiple component property with part", () => {
615 | const result = resolveComponentLayoutProps({
616 | "color-indicator": "red",
617 | "backgroundColor-indicator": "green",
618 | });
619 | expect(result).toStrictEqual({
620 | indicator: {
621 | baseStyles: { color: "red", backgroundColor: "green" },
622 | },
623 | });
624 | });
625 |
626 | it("multiple component property with multiple parts #1", () => {
627 | const result = resolveComponentLayoutProps({
628 | "color-indicator": "red",
629 | "backgroundColor-handle": "green",
630 | });
631 | expect(result).toStrictEqual({
632 | indicator: {
633 | baseStyles: { color: "red" },
634 | },
635 | handle: {
636 | baseStyles: { backgroundColor: "green" },
637 | },
638 | });
639 | });
640 |
641 | it("multiple component property with multiple parts #2", () => {
642 | const result = resolveComponentLayoutProps({
643 | "color-indicator": "red",
644 | "backgroundColor-handle": "green",
645 | "fontSize-indicator": "12px",
646 | });
647 | expect(result).toStrictEqual({
648 | indicator: {
649 | baseStyles: { color: "red", fontSize: "12px" },
650 | },
651 | handle: {
652 | baseStyles: { backgroundColor: "green" },
653 | },
654 | });
655 | });
656 | });
657 |
658 | describe("component properties with parts and state", () => {
659 | it("single component property with part and state", () => {
660 | const result = resolveComponentLayoutProps({
661 | "color-indicator--hover": "red",
662 | });
663 | expect(result).toStrictEqual({
664 | indicator: {
665 | baseStyles: { states: { hover: { color: "red" } } },
666 | },
667 | });
668 | });
669 |
670 | it("single component property with part and multiple states #1", () => {
671 | const result = resolveComponentLayoutProps({
672 | "color-indicator--hover--active": "red",
673 | });
674 | expect(result).toStrictEqual({
675 | indicator: {
676 | baseStyles: { states: { "hover&active": { color: "red" } } },
677 | },
678 | });
679 | });
680 |
681 | it("single component property with part and multiple states #2", () => {
682 | const result = resolveComponentLayoutProps({
683 | "color-indicator--hover--active--focus": "red",
684 | });
685 | expect(result).toStrictEqual({
686 | indicator: {
687 | baseStyles: { states: { "hover&active&focus": { color: "red" } } },
688 | },
689 | });
690 | });
691 |
692 | it("multiple component properties with part and state", () => {
693 | const result = resolveComponentLayoutProps({
694 | "color-indicator--hover": "red",
695 | "backgroundColor-indicator--hover": "green",
696 | });
697 | expect(result).toStrictEqual({
698 | indicator: {
699 | baseStyles: { states: { hover: { color: "red", backgroundColor: "green" } } },
700 | },
701 | });
702 | });
703 |
704 | it("multiple component properties with part and multiple states #1", () => {
705 | const result = resolveComponentLayoutProps({
706 | "color-indicator--focus": "red",
707 | "backgroundColor-indicator--hover": "green",
708 | });
709 | expect(result).toStrictEqual({
710 | indicator: {
711 | baseStyles: { states: { focus: { color: "red" }, hover: { backgroundColor: "green" } } },
712 | },
713 | });
714 | });
715 |
716 | it("multiple component properties with part and multiple states #2", () => {
717 | const result = resolveComponentLayoutProps({
718 | "color-indicator--focus": "red",
719 | "backgroundColor-indicator--hover--focus": "green",
720 | });
721 | expect(result).toStrictEqual({
722 | indicator: {
723 | baseStyles: {
724 | states: { focus: { color: "red" }, "hover&focus": { backgroundColor: "green" } },
725 | },
726 | },
727 | });
728 | });
729 |
730 | it("multiple component properties with part and multiple states #3", () => {
731 | const result = resolveComponentLayoutProps({
732 | "color-indicator--focus": "red",
733 | "backgroundColor-indicator--focus": "green",
734 | });
735 | expect(result).toStrictEqual({
736 | indicator: {
737 | baseStyles: { states: { focus: { color: "red", backgroundColor: "green" } } },
738 | },
739 | });
740 | });
741 |
742 | it("multiple component properties with part and multiple states #4", () => {
743 | const result = resolveComponentLayoutProps({
744 | "color-indicator--focus--active": "red",
745 | "backgroundColor-indicator--focus": "green",
746 | });
747 | expect(result).toStrictEqual({
748 | indicator: {
749 | baseStyles: {
750 | states: { focus: { backgroundColor: "green" }, "focus&active": { color: "red" } },
751 | },
752 | },
753 | });
754 | });
755 |
756 | it("multiple component properties with multiple parts and states #1", () => {
757 | const result = resolveComponentLayoutProps({
758 | "color-indicator--hover": "red",
759 | "backgroundColor-handle--focus": "green",
760 | });
761 | expect(result).toStrictEqual({
762 | indicator: {
763 | baseStyles: { states: { hover: { color: "red" } } },
764 | },
765 | handle: {
766 | baseStyles: { states: { focus: { backgroundColor: "green" } } },
767 | },
768 | });
769 | });
770 |
771 | it("multiple component properties with multiple parts and states #2", () => {
772 | const result = resolveComponentLayoutProps({
773 | "color-indicator--hover": "red",
774 | "backgroundColor-handle--focus": "green",
775 | "fontSize-indicator--active": "12px",
776 | });
777 | expect(result).toStrictEqual({
778 | indicator: {
779 | baseStyles: { states: { hover: { color: "red" }, active: { fontSize: "12px" } } },
780 | },
781 | handle: {
782 | baseStyles: { states: { focus: { backgroundColor: "green" } } },
783 | },
784 | });
785 | });
786 |
787 | it("multiple component properties with multiple parts and mixed states", () => {
788 | const result = resolveComponentLayoutProps({
789 | "color-indicator--hover--active": "red",
790 | "backgroundColor-handle--focus": "green",
791 | "fontSize-indicator--hover": "12px",
792 | "border-handle--focus--active": "1px solid black",
793 | });
794 | expect(result).toStrictEqual({
795 | indicator: {
796 | baseStyles: { states: { "hover&active": { color: "red" }, hover: { fontSize: "12px" } } },
797 | },
798 | handle: {
799 | baseStyles: {
800 | states: {
801 | focus: { backgroundColor: "green" },
802 | "focus&active": { border: "1px solid black" },
803 | },
804 | },
805 | },
806 | });
807 | });
808 | });
809 |
810 | describe("mixed component properties, parts, and states", () => {
811 | it("mix of base properties, parts without states, and parts with states", () => {
812 | const result = resolveComponentLayoutProps({
813 | color: "blue", // base property
814 | "backgroundColor-header": "yellow", // part property without state
815 | "fontSize-indicator--hover": "14px", // part property with state
816 | });
817 | expect(result).toStrictEqual({
818 | [BASE_COMPONENT_PART]: {
819 | baseStyles: { color: "blue" },
820 | },
821 | header: {
822 | baseStyles: { backgroundColor: "yellow" },
823 | },
824 | indicator: {
825 | baseStyles: { states: { hover: { fontSize: "14px" } } },
826 | },
827 | });
828 | });
829 |
830 | it("mix of base properties with states and parts with states", () => {
831 | const result = resolveComponentLayoutProps({
832 | "color--hover": "red", // base property with state
833 | "backgroundColor-header--focus": "green", // part property with state
834 | "border-footer": "1px solid black", // part property without state
835 | });
836 | expect(result).toStrictEqual({
837 | [BASE_COMPONENT_PART]: {
838 | baseStyles: { states: { hover: { color: "red" } } },
839 | },
840 | header: {
841 | baseStyles: { states: { focus: { backgroundColor: "green" } } },
842 | },
843 | footer: {
844 | baseStyles: { border: "1px solid black" },
845 | },
846 | });
847 | });
848 |
849 | it("complex mix: base properties, parts, multiple states", () => {
850 | const result = resolveComponentLayoutProps({
851 | width: "100px", // base property
852 | height: "50px", // base property
853 | "color--hover": "red", // base property with state
854 | "backgroundColor--active": "blue", // base property with different state
855 | "fontSize-header": "16px", // part property
856 | "padding-header--hover": "10px", // part property with state
857 | "margin-footer--focus--active": "5px", // part property with multiple states
858 | "border-sidebar": "2px solid gray", // different part property
859 | });
860 | expect(result).toStrictEqual({
861 | [BASE_COMPONENT_PART]: {
862 | baseStyles: {
863 | width: "100px",
864 | height: "50px",
865 | states: {
866 | hover: { color: "red" },
867 | active: { backgroundColor: "blue" },
868 | },
869 | },
870 | },
871 | header: {
872 | baseStyles: {
873 | fontSize: "16px",
874 | states: { hover: { padding: "10px" } },
875 | },
876 | },
877 | footer: {
878 | baseStyles: { states: { "focus&active": { margin: "5px" } } },
879 | },
880 | sidebar: {
881 | baseStyles: { border: "2px solid gray" },
882 | },
883 | });
884 | });
885 |
886 | it("same property applied to different contexts", () => {
887 | const result = resolveComponentLayoutProps({
888 | color: "black", // base color
889 | "color-header": "blue", // header color
890 | "color-footer--hover": "red", // footer color on hover
891 | "color--active": "green", // base color on active
892 | });
893 | expect(result).toStrictEqual({
894 | [BASE_COMPONENT_PART]: {
895 | baseStyles: {
896 | color: "black",
897 | states: { active: { color: "green" } },
898 | },
899 | },
900 | header: {
901 | baseStyles: { color: "blue" },
902 | },
903 | footer: {
904 | baseStyles: { states: { hover: { color: "red" } } },
905 | },
906 | });
907 | });
908 |
909 | it("overlapping states across base and parts", () => {
910 | const result = resolveComponentLayoutProps({
911 | "backgroundColor--hover": "lightblue", // base background on hover
912 | "color--hover": "darkblue", // base color on hover
913 | "fontSize-title--hover": "18px", // title font size on hover
914 | "padding-title--focus": "8px", // title padding on focus
915 | "margin-content--hover--focus": "12px", // content margin on hover and focus
916 | });
917 | expect(result).toStrictEqual({
918 | [BASE_COMPONENT_PART]: {
919 | baseStyles: {
920 | states: {
921 | hover: { backgroundColor: "lightblue", color: "darkblue" },
922 | },
923 | },
924 | },
925 | title: {
926 | baseStyles: {
927 | states: {
928 | hover: { fontSize: "18px" },
929 | focus: { padding: "8px" },
930 | },
931 | },
932 | },
933 | content: {
934 | baseStyles: { states: { "hover&focus": { margin: "12px" } } },
935 | },
936 | });
937 | });
938 |
939 | it("multiple properties per part with mixed states", () => {
940 | const result = resolveComponentLayoutProps({
941 | "width-card": "200px", // card width (no state)
942 | "height-card": "150px", // card height (no state)
943 | "backgroundColor-card--hover": "gray", // card background on hover
944 | "border-card--focus": "2px solid blue", // card border on focus
945 | "color-card--hover--active": "white", // card color on hover and active
946 | "padding-card": "16px", // card padding (no state)
947 | });
948 | expect(result).toStrictEqual({
949 | card: {
950 | baseStyles: {
951 | width: "200px",
952 | height: "150px",
953 | padding: "16px",
954 | states: {
955 | hover: { backgroundColor: "gray" },
956 | focus: { border: "2px solid blue" },
957 | "hover&active": { color: "white" },
958 | },
959 | },
960 | },
961 | });
962 | });
963 |
964 | it("state conflicts and merging across different parts", () => {
965 | const result = resolveComponentLayoutProps({
966 | "color--focus": "red", // base color on focus
967 | "backgroundColor--focus": "yellow", // base background on focus
968 | "fontSize-header--focus": "20px", // header font size on focus
969 | "color-footer--focus": "blue", // footer color on focus (different from base)
970 | "margin-header": "10px", // header margin (no state)
971 | "padding-footer--active": "5px", // footer padding on active
972 | });
973 | expect(result).toStrictEqual({
974 | [BASE_COMPONENT_PART]: {
975 | baseStyles: {
976 | states: {
977 | focus: { color: "red", backgroundColor: "yellow" },
978 | },
979 | },
980 | },
981 | header: {
982 | baseStyles: {
983 | margin: "10px",
984 | states: { focus: { fontSize: "20px" } },
985 | },
986 | },
987 | footer: {
988 | baseStyles: {
989 | states: {
990 | focus: { color: "blue" },
991 | active: { padding: "5px" },
992 | },
993 | },
994 | },
995 | });
996 | });
997 | });
998 |
999 | describe("regression", () => {
1000 | it("has responsive with state", () => {
1001 | const result = resolveComponentLayoutProps({
1002 | backgroundColor: "red",
1003 | "backgroundColor-xxl": "green",
1004 | "backgroundColor-xxl--hover": "blue",
1005 | });
1006 | expect(result).toStrictEqual({
1007 | [BASE_COMPONENT_PART]: {
1008 | baseStyles: {
1009 | backgroundColor: "red",
1010 | },
1011 | responsiveStyles: {
1012 | xxl: {
1013 | backgroundColor: "green",
1014 | states: {
1015 | hover: { backgroundColor: "blue" },
1016 | },
1017 | },
1018 | },
1019 | },
1020 | });
1021 | });
1022 | });
1023 | });
1024 |
```