This is page 119 of 182. Use http://codebase.md/xmlui-org/xmlui/mockApiDef.js?lines=true&page={x} to view the full context. # Directory Structure ``` ├── .changeset │ ├── config.json │ ├── cool-queens-look.md │ └── twelve-guests-care.md ├── .eslintrc.cjs ├── .github │ ├── build-checklist.png │ ├── ISSUE_TEMPLATE │ │ ├── bug_report.md │ │ └── feature_request.md │ └── workflows │ ├── deploy-blog.yml │ ├── deploy-docs-optimized.yml │ ├── deploy-docs.yml │ ├── prepare-versions.yml │ ├── release-packages.yml │ ├── run-all-tests.yml │ └── run-smoke-tests.yml ├── .gitignore ├── .prettierrc.js ├── .vscode │ ├── launch.json │ └── settings.json ├── blog │ ├── .gitignore │ ├── .gitkeep │ ├── CHANGELOG.md │ ├── extensions.ts │ ├── index.html │ ├── index.ts │ ├── package.json │ ├── public │ │ ├── blog │ │ │ ├── images │ │ │ │ ├── blog-page-component.png │ │ │ │ ├── blog-scrabble.png │ │ │ │ ├── integrated-blog-search.png │ │ │ │ └── lorem-ipsum.png │ │ │ ├── lorem-ipsum.md │ │ │ ├── newest-post.md │ │ │ ├── older-post.md │ │ │ └── welcome-to-the-xmlui-blog.md │ │ ├── mockServiceWorker.js │ │ ├── netlify.toml │ │ ├── resources │ │ │ ├── favicon.ico │ │ │ ├── files │ │ │ │ └── for-download │ │ │ │ └── xmlui │ │ │ │ └── xmlui-standalone.umd.js │ │ │ ├── github.svg │ │ │ ├── llms.txt │ │ │ ├── logo-dark.svg │ │ │ ├── logo.svg │ │ │ ├── pg-popout.svg │ │ │ └── xmlui-logo.svg │ │ ├── serve.json │ │ └── web.config │ ├── scripts │ │ ├── download-latest-xmlui.js │ │ ├── generate-rss.js │ │ ├── get-releases.js │ │ └── utils.js │ ├── src │ │ ├── components │ │ │ ├── BlogOverview.xmlui │ │ │ ├── BlogPage.xmlui │ │ │ ├── Debug.xmlui │ │ │ └── PageNotFound.xmlui │ │ ├── config.ts │ │ ├── Main.xmlui │ │ ├── Main.xmlui.xs │ │ └── themes │ │ ├── docs-theme.ts │ │ ├── earthtone.ts │ │ ├── xmlui-gray-on-default.ts │ │ ├── xmlui-green-on-default.ts │ │ └── xmlui-orange-on-default.ts │ └── tsconfig.json ├── CONTRIBUTING.md ├── docs │ ├── .gitignore │ ├── CHANGELOG.md │ ├── ComponentRefLinks.txt │ ├── content │ │ ├── _meta.json │ │ ├── components │ │ │ ├── _meta.json │ │ │ ├── _overview.md │ │ │ ├── APICall.md │ │ │ ├── App.md │ │ │ ├── AppHeader.md │ │ │ ├── AppState.md │ │ │ ├── AutoComplete.md │ │ │ ├── Avatar.md │ │ │ ├── Backdrop.md │ │ │ ├── Badge.md │ │ │ ├── BarChart.md │ │ │ ├── Bookmark.md │ │ │ ├── Breakout.md │ │ │ ├── Button.md │ │ │ ├── Card.md │ │ │ ├── Carousel.md │ │ │ ├── ChangeListener.md │ │ │ ├── Checkbox.md │ │ │ ├── CHStack.md │ │ │ ├── ColorPicker.md │ │ │ ├── Column.md │ │ │ ├── ContentSeparator.md │ │ │ ├── CVStack.md │ │ │ ├── DataSource.md │ │ │ ├── DateInput.md │ │ │ ├── DatePicker.md │ │ │ ├── DonutChart.md │ │ │ ├── DropdownMenu.md │ │ │ ├── EmojiSelector.md │ │ │ ├── ExpandableItem.md │ │ │ ├── FileInput.md │ │ │ ├── FileUploadDropZone.md │ │ │ ├── FlowLayout.md │ │ │ ├── Footer.md │ │ │ ├── Form.md │ │ │ ├── FormItem.md │ │ │ ├── FormSection.md │ │ │ ├── Fragment.md │ │ │ ├── H1.md │ │ │ ├── H2.md │ │ │ ├── H3.md │ │ │ ├── H4.md │ │ │ ├── H5.md │ │ │ ├── H6.md │ │ │ ├── Heading.md │ │ │ ├── HSplitter.md │ │ │ ├── HStack.md │ │ │ ├── Icon.md │ │ │ ├── IFrame.md │ │ │ ├── Image.md │ │ │ ├── Items.md │ │ │ ├── LabelList.md │ │ │ ├── Legend.md │ │ │ ├── LineChart.md │ │ │ ├── Link.md │ │ │ ├── List.md │ │ │ ├── Logo.md │ │ │ ├── Markdown.md │ │ │ ├── MenuItem.md │ │ │ ├── MenuSeparator.md │ │ │ ├── ModalDialog.md │ │ │ ├── NavGroup.md │ │ │ ├── NavLink.md │ │ │ ├── NavPanel.md │ │ │ ├── NoResult.md │ │ │ ├── NumberBox.md │ │ │ ├── Option.md │ │ │ ├── Page.md │ │ │ ├── PageMetaTitle.md │ │ │ ├── Pages.md │ │ │ ├── Pagination.md │ │ │ ├── PasswordInput.md │ │ │ ├── PieChart.md │ │ │ ├── ProgressBar.md │ │ │ ├── Queue.md │ │ │ ├── RadioGroup.md │ │ │ ├── RealTimeAdapter.md │ │ │ ├── Redirect.md │ │ │ ├── Select.md │ │ │ ├── Slider.md │ │ │ ├── Slot.md │ │ │ ├── SpaceFiller.md │ │ │ ├── Spinner.md │ │ │ ├── Splitter.md │ │ │ ├── Stack.md │ │ │ ├── StickyBox.md │ │ │ ├── SubMenuItem.md │ │ │ ├── Switch.md │ │ │ ├── TabItem.md │ │ │ ├── Table.md │ │ │ ├── TableOfContents.md │ │ │ ├── Tabs.md │ │ │ ├── Text.md │ │ │ ├── TextArea.md │ │ │ ├── TextBox.md │ │ │ ├── Theme.md │ │ │ ├── TimeInput.md │ │ │ ├── Timer.md │ │ │ ├── ToneChangerButton.md │ │ │ ├── ToneSwitch.md │ │ │ ├── Tooltip.md │ │ │ ├── Tree.md │ │ │ ├── VSplitter.md │ │ │ ├── VStack.md │ │ │ ├── xmlui-animations │ │ │ │ ├── _meta.json │ │ │ │ ├── _overview.md │ │ │ │ ├── Animation.md │ │ │ │ ├── FadeAnimation.md │ │ │ │ ├── FadeInAnimation.md │ │ │ │ ├── FadeOutAnimation.md │ │ │ │ ├── ScaleAnimation.md │ │ │ │ └── SlideInAnimation.md │ │ │ ├── xmlui-pdf │ │ │ │ ├── _meta.json │ │ │ │ ├── _overview.md │ │ │ │ └── Pdf.md │ │ │ ├── xmlui-spreadsheet │ │ │ │ ├── _meta.json │ │ │ │ ├── _overview.md │ │ │ │ └── Spreadsheet.md │ │ │ └── xmlui-website-blocks │ │ │ ├── _meta.json │ │ │ ├── _overview.md │ │ │ ├── Carousel.md │ │ │ ├── HelloMd.md │ │ │ ├── HeroSection.md │ │ │ └── ScrollToTop.md │ │ └── extensions │ │ ├── _meta.json │ │ ├── xmlui-animations │ │ │ ├── _meta.json │ │ │ ├── _overview.md │ │ │ ├── Animation.md │ │ │ ├── FadeAnimation.md │ │ │ ├── FadeInAnimation.md │ │ │ ├── FadeOutAnimation.md │ │ │ ├── ScaleAnimation.md │ │ │ └── SlideInAnimation.md │ │ └── xmlui-website-blocks │ │ ├── _meta.json │ │ ├── _overview.md │ │ ├── Carousel.md │ │ ├── HelloMd.md │ │ ├── HeroSection.md │ │ └── ScrollToTop.md │ ├── extensions.ts │ ├── index.html │ ├── index.ts │ ├── package.json │ ├── public │ │ ├── feed.rss │ │ ├── mockServiceWorker.js │ │ ├── pages │ │ │ ├── _meta.json │ │ │ ├── app-structure.md │ │ │ ├── build-editor-component.md │ │ │ ├── build-hello-world-component.md │ │ │ ├── components-intro.md │ │ │ ├── context-variables.md │ │ │ ├── forms.md │ │ │ ├── globals.md │ │ │ ├── glossary.md │ │ │ ├── helper-tags.md │ │ │ ├── hosted-deployment.md │ │ │ ├── howto │ │ │ │ ├── assign-a-complex-json-literal-to-a-component-variable.md │ │ │ │ ├── chain-a-refetch.md │ │ │ │ ├── debug-a-component.md │ │ │ │ ├── delay-a-datasource-until-another-datasource-is-ready.md │ │ │ │ ├── delegate-a-method.md │ │ │ │ ├── do-custom-form-validation.md │ │ │ │ ├── expose-a-method-from-a-component.md │ │ │ │ ├── filter-and-transform-data-from-an-api.md │ │ │ │ ├── group-items-in-list-by-a-property.md │ │ │ │ ├── handle-background-operations.md │ │ │ │ ├── hide-an-element-until-its-datasource-is-ready.md │ │ │ │ ├── make-a-set-of-equal-width-cards.md │ │ │ │ ├── make-a-table-responsive.md │ │ │ │ ├── make-navpanel-width-responsive.md │ │ │ │ ├── modify-a-value-reported-in-a-column.md │ │ │ │ ├── paginate-a-list.md │ │ │ │ ├── pass-data-to-a-modal-dialog.md │ │ │ │ ├── react-to-button-click-not-keystrokes.md │ │ │ │ ├── set-the-initial-value-of-a-select-from-fetched-data.md │ │ │ │ ├── share-a-modaldialog-across-components.md │ │ │ │ ├── sync-selections-between-table-and-list-views.md │ │ │ │ ├── update-ui-optimistically.md │ │ │ │ ├── use-built-in-form-validation.md │ │ │ │ └── use-the-same-modaldialog-to-add-or-edit.md │ │ │ ├── howto.md │ │ │ ├── intro.md │ │ │ ├── layout.md │ │ │ ├── markup.md │ │ │ ├── mcp.md │ │ │ ├── modal-dialogs.md │ │ │ ├── news-and-reviews.md │ │ │ ├── reactive-intro.md │ │ │ ├── refactoring.md │ │ │ ├── routing-and-links.md │ │ │ ├── samples │ │ │ │ ├── color-palette.xmlui │ │ │ │ ├── color-values.xmlui │ │ │ │ ├── shadow-sizes.xmlui │ │ │ │ ├── spacing-sizes.xmlui │ │ │ │ ├── swatch.xmlui │ │ │ │ ├── theme-gallery-brief.xmlui │ │ │ │ └── theme-gallery.xmlui │ │ │ ├── scoping.md │ │ │ ├── scripting.md │ │ │ ├── styles-and-themes │ │ │ │ ├── common-units.md │ │ │ │ ├── layout-props.md │ │ │ │ ├── theme-variable-defaults.md │ │ │ │ ├── theme-variables.md │ │ │ │ └── themes.md │ │ │ ├── template-properties.md │ │ │ ├── test.md │ │ │ ├── tutorial-01.md │ │ │ ├── tutorial-02.md │ │ │ ├── tutorial-03.md │ │ │ ├── tutorial-04.md │ │ │ ├── tutorial-05.md │ │ │ ├── tutorial-06.md │ │ │ ├── tutorial-07.md │ │ │ ├── tutorial-08.md │ │ │ ├── tutorial-09.md │ │ │ ├── tutorial-10.md │ │ │ ├── tutorial-11.md │ │ │ ├── tutorial-12.md │ │ │ ├── universal-properties.md │ │ │ ├── user-defined-components.md │ │ │ ├── vscode.md │ │ │ ├── working-with-markdown.md │ │ │ ├── working-with-text.md │ │ │ ├── xmlui-animations │ │ │ │ ├── _meta.json │ │ │ │ ├── _overview.md │ │ │ │ ├── Animation.md │ │ │ │ ├── FadeAnimation.md │ │ │ │ ├── FadeInAnimation.md │ │ │ │ ├── FadeOutAnimation.md │ │ │ │ ├── ScaleAnimation.md │ │ │ │ └── SlideInAnimation.md │ │ │ ├── xmlui-charts │ │ │ │ ├── _meta.json │ │ │ │ ├── _overview.md │ │ │ │ ├── BarChart.md │ │ │ │ ├── DonutChart.md │ │ │ │ ├── LabelList.md │ │ │ │ ├── Legend.md │ │ │ │ ├── LineChart.md │ │ │ │ └── PieChart.md │ │ │ ├── xmlui-pdf │ │ │ │ ├── _meta.json │ │ │ │ ├── _overview.md │ │ │ │ └── Pdf.md │ │ │ └── xmlui-spreadsheet │ │ │ ├── _meta.json │ │ │ ├── _overview.md │ │ │ └── Spreadsheet.md │ │ ├── resources │ │ │ ├── devdocs │ │ │ │ ├── debug-proxy-object-2.png │ │ │ │ ├── debug-proxy-object.png │ │ │ │ ├── table_editor_01.png │ │ │ │ ├── table_editor_02.png │ │ │ │ ├── table_editor_03.png │ │ │ │ ├── table_editor_04.png │ │ │ │ ├── table_editor_05.png │ │ │ │ ├── table_editor_06.png │ │ │ │ ├── table_editor_07.png │ │ │ │ ├── table_editor_08.png │ │ │ │ ├── table_editor_09.png │ │ │ │ ├── table_editor_10.png │ │ │ │ ├── table_editor_11.png │ │ │ │ ├── table-editor-01.png │ │ │ │ ├── table-editor-02.png │ │ │ │ ├── table-editor-03.png │ │ │ │ ├── table-editor-04.png │ │ │ │ ├── table-editor-06.png │ │ │ │ ├── table-editor-07.png │ │ │ │ ├── table-editor-08.png │ │ │ │ ├── table-editor-09.png │ │ │ │ └── xmlui-rendering-of-tiptap-markdown.png │ │ │ ├── favicon.ico │ │ │ ├── files │ │ │ │ ├── clients.json │ │ │ │ ├── daily-revenue.json │ │ │ │ ├── dashboard-stats.json │ │ │ │ ├── demo.xmlui │ │ │ │ ├── demo.xmlui.xs │ │ │ │ ├── downloads │ │ │ │ │ └── downloads.json │ │ │ │ ├── for-download │ │ │ │ │ ├── index-with-api.html │ │ │ │ │ ├── index.html │ │ │ │ │ ├── mockApi.js │ │ │ │ │ ├── start-darwin.sh │ │ │ │ │ ├── start-linux.sh │ │ │ │ │ ├── start.bat │ │ │ │ │ └── xmlui │ │ │ │ │ └── xmlui-standalone.umd.js │ │ │ │ ├── getting-started │ │ │ │ │ ├── cl-tutorial-final.zip │ │ │ │ │ ├── cl-tutorial.zip │ │ │ │ │ ├── cl-tutorial2.zip │ │ │ │ │ ├── cl-tutorial3.zip │ │ │ │ │ ├── cl-tutorial4.zip │ │ │ │ │ ├── cl-tutorial5.zip │ │ │ │ │ ├── cl-tutorial6.zip │ │ │ │ │ ├── getting-started.zip │ │ │ │ │ ├── hello-xmlui.zip │ │ │ │ │ ├── xmlui-empty.zip │ │ │ │ │ └── xmlui-starter.zip │ │ │ │ ├── howto │ │ │ │ │ └── component-icons │ │ │ │ │ └── up-arrow.svg │ │ │ │ ├── invoices.json │ │ │ │ ├── monthly-status.json │ │ │ │ ├── news-and-reviews.json │ │ │ │ ├── products.json │ │ │ │ ├── releases.json │ │ │ │ ├── tutorials │ │ │ │ │ ├── datasource │ │ │ │ │ │ └── api.ts │ │ │ │ │ └── p2do │ │ │ │ │ ├── api.ts │ │ │ │ │ └── todo-logo.svg │ │ │ │ └── xmlui.json │ │ │ ├── github.svg │ │ │ ├── images │ │ │ │ ├── apiaction-tutorial │ │ │ │ │ ├── add-success.png │ │ │ │ │ ├── apiaction-param.png │ │ │ │ │ ├── change-completed.png │ │ │ │ │ ├── change-in-progress.png │ │ │ │ │ ├── confirm-delete.png │ │ │ │ │ ├── data-error.png │ │ │ │ │ ├── data-progress.png │ │ │ │ │ ├── data-success.png │ │ │ │ │ ├── display-1.png │ │ │ │ │ ├── item-deleted.png │ │ │ │ │ ├── item-updated.png │ │ │ │ │ ├── missing-api-key.png │ │ │ │ │ ├── new-item-added.png │ │ │ │ │ └── test-message.png │ │ │ │ ├── chat-api │ │ │ │ │ └── domain-model.svg │ │ │ │ ├── components │ │ │ │ │ ├── image │ │ │ │ │ │ └── breakfast.jpg │ │ │ │ │ ├── markdown │ │ │ │ │ │ └── colors.png │ │ │ │ │ └── modal │ │ │ │ │ ├── deep_link_dialog_1.jpg │ │ │ │ │ └── deep_link_dialog_2.jpg │ │ │ │ ├── create-apps │ │ │ │ │ ├── collapsed-vertical.png │ │ │ │ │ ├── using-forms-warning-dialog.png │ │ │ │ │ └── using-forms.png │ │ │ │ ├── datasource-tutorial │ │ │ │ │ ├── data-with-header.png │ │ │ │ │ ├── filtered-data.png │ │ │ │ │ ├── filtered-items.png │ │ │ │ │ ├── initial-page-items.png │ │ │ │ │ ├── list-items.png │ │ │ │ │ ├── next-page-items.png │ │ │ │ │ ├── no-data.png │ │ │ │ │ ├── pagination-1.jpg │ │ │ │ │ ├── pagination-1.png │ │ │ │ │ ├── polling-1.png │ │ │ │ │ ├── refetch-data.png │ │ │ │ │ ├── slow-loading.png │ │ │ │ │ ├── test-message.png │ │ │ │ │ ├── Thumbs.db │ │ │ │ │ ├── unconventional-data.png │ │ │ │ │ └── unfiltered-items.png │ │ │ │ ├── flower.jpg │ │ │ │ ├── get-started │ │ │ │ │ ├── add-new-contact.png │ │ │ │ │ ├── app-modified.png │ │ │ │ │ ├── app-start.png │ │ │ │ │ ├── app-with-boxes.png │ │ │ │ │ ├── app-with-toast.png │ │ │ │ │ ├── boilerplate-structure.png │ │ │ │ │ ├── cl-initial.png │ │ │ │ │ ├── cl-start.png │ │ │ │ │ ├── contact-counts.png │ │ │ │ │ ├── contact-dialog-title.png │ │ │ │ │ ├── contact-dialog.png │ │ │ │ │ ├── contact-menus.png │ │ │ │ │ ├── contact-predicates.png │ │ │ │ │ ├── context-menu.png │ │ │ │ │ ├── dashboard-numbers.png │ │ │ │ │ ├── default-contact-list.png │ │ │ │ │ ├── delete-contact.png │ │ │ │ │ ├── delete-task.png │ │ │ │ │ ├── detailed-template.png │ │ │ │ │ ├── edit-contact-details.png │ │ │ │ │ ├── edited-contact-saved.png │ │ │ │ │ ├── empty-sections.png │ │ │ │ │ ├── filter-completed.png │ │ │ │ │ ├── fullwidth-desktop.png │ │ │ │ │ ├── fullwidth-mobile.png │ │ │ │ │ ├── initial-table.png │ │ │ │ │ ├── items-and-badges.png │ │ │ │ │ ├── loading-message.png │ │ │ │ │ ├── new-contact-button.png │ │ │ │ │ ├── new-contact-saved.png │ │ │ │ │ ├── no-empty-sections.png │ │ │ │ │ ├── personal-todo-initial.png │ │ │ │ │ ├── piechart.png │ │ │ │ │ ├── review-today.png │ │ │ │ │ ├── rudimentary-dashboard.png │ │ │ │ │ ├── section-collapsed.png │ │ │ │ │ ├── sectioned-items.png │ │ │ │ │ ├── sections-ordered.png │ │ │ │ │ ├── spacex-list-with-links.png │ │ │ │ │ ├── spacex-list.png │ │ │ │ │ ├── start-personal-todo-1.png │ │ │ │ │ ├── submit-new-contact.png │ │ │ │ │ ├── submit-new-task.png │ │ │ │ │ ├── syntax-highlighting.png │ │ │ │ │ ├── table-with-badge.png │ │ │ │ │ ├── template-with-card.png │ │ │ │ │ ├── test-emulated-api.png │ │ │ │ │ ├── Thumbs.db │ │ │ │ │ ├── todo-logo.png │ │ │ │ │ └── xmlui-tools.png │ │ │ │ ├── HelloApp.png │ │ │ │ ├── HelloApp2.png │ │ │ │ ├── logos │ │ │ │ │ ├── xmlui1.svg │ │ │ │ │ ├── xmlui2.svg │ │ │ │ │ ├── xmlui3.svg │ │ │ │ │ ├── xmlui4.svg │ │ │ │ │ ├── xmlui5.svg │ │ │ │ │ ├── xmlui6.svg │ │ │ │ │ └── xmlui7.svg │ │ │ │ ├── pdf │ │ │ │ │ └── dummy-pdf.jpg │ │ │ │ ├── rendering-engine │ │ │ │ │ ├── AppEngine-flow.svg │ │ │ │ │ ├── Component.svg │ │ │ │ │ ├── CompoundComponent.svg │ │ │ │ │ ├── RootComponent.svg │ │ │ │ │ └── tree-with-containers.svg │ │ │ │ ├── reviewers-guide │ │ │ │ │ ├── AppEngine-flow.svg │ │ │ │ │ └── incbutton-in-action.png │ │ │ │ ├── tools │ │ │ │ │ └── boilerplate-structure.png │ │ │ │ ├── try.svg │ │ │ │ ├── tutorial │ │ │ │ │ ├── app-chat-history.png │ │ │ │ │ ├── app-content-placeholder.png │ │ │ │ │ ├── app-header-and-content.png │ │ │ │ │ ├── app-links-channel-selected.png │ │ │ │ │ ├── app-links-click.png │ │ │ │ │ ├── app-navigation.png │ │ │ │ │ ├── finished-ex01.png │ │ │ │ │ ├── finished-ex02.png │ │ │ │ │ ├── hello.png │ │ │ │ │ ├── splash-screen-advanced.png │ │ │ │ │ ├── splash-screen-after-click.png │ │ │ │ │ ├── splash-screen-centered.png │ │ │ │ │ ├── splash-screen-events.png │ │ │ │ │ ├── splash-screen-expression.png │ │ │ │ │ ├── splash-screen-reuse-after.png │ │ │ │ │ ├── splash-screen-reuse-before.png │ │ │ │ │ └── splash-screen.png │ │ │ │ └── tutorial-01.png │ │ │ ├── llms.txt │ │ │ ├── logo-dark.svg │ │ │ ├── logo.svg │ │ │ ├── pg-popout.svg │ │ │ └── xmlui-logo.svg │ │ ├── serve.json │ │ └── web.config │ ├── scripts │ │ ├── download-latest-xmlui.js │ │ ├── generate-rss.js │ │ ├── get-releases.js │ │ └── utils.js │ ├── src │ │ ├── components │ │ │ ├── BlogOverview.xmlui │ │ │ ├── BlogPage.xmlui │ │ │ ├── Boxes.xmlui │ │ │ ├── Breadcrumb.xmlui │ │ │ ├── ChangeLog.xmlui │ │ │ ├── ColorPalette.xmlui │ │ │ ├── DocumentLinks.xmlui │ │ │ ├── DocumentPage.xmlui │ │ │ ├── DocumentPageNoTOC.xmlui │ │ │ ├── Icons.xmlui │ │ │ ├── IncButton.xmlui │ │ │ ├── IncButton2.xmlui │ │ │ ├── NameValue.xmlui │ │ │ ├── PageNotFound.xmlui │ │ │ ├── PaletteItem.xmlui │ │ │ ├── Palettes.xmlui │ │ │ ├── SectionHeader.xmlui │ │ │ ├── TBD.xmlui │ │ │ ├── Test.xmlui │ │ │ ├── ThemesIntro.xmlui │ │ │ ├── ThousandThemes.xmlui │ │ │ ├── TubeStops.xmlui │ │ │ ├── TubeStops.xmlui.xs │ │ │ └── TwoColumnCode.xmlui │ │ ├── config.ts │ │ ├── Main.xmlui │ │ └── themes │ │ ├── docs-theme.ts │ │ ├── earthtone.ts │ │ ├── xmlui-gray-on-default.ts │ │ ├── xmlui-green-on-default.ts │ │ └── xmlui-orange-on-default.ts │ └── tsconfig.json ├── LICENSE ├── package-lock.json ├── package.json ├── packages │ ├── xmlui-animations │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── demo │ │ │ └── Main.xmlui │ │ ├── index.html │ │ ├── index.ts │ │ ├── meta │ │ │ └── componentsMetadata.ts │ │ ├── package.json │ │ ├── src │ │ │ ├── Animation.tsx │ │ │ ├── AnimationNative.tsx │ │ │ ├── FadeAnimation.tsx │ │ │ ├── FadeInAnimation.tsx │ │ │ ├── FadeOutAnimation.tsx │ │ │ ├── index.tsx │ │ │ ├── ScaleAnimation.tsx │ │ │ └── SlideInAnimation.tsx │ │ └── tsconfig.json │ ├── xmlui-devtools │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── demo │ │ │ └── Main.xmlui │ │ ├── index.html │ │ ├── index.ts │ │ ├── meta │ │ │ └── componentsMetadata.ts │ │ ├── package.json │ │ ├── src │ │ │ ├── devtools │ │ │ │ ├── DevTools.tsx │ │ │ │ ├── DevToolsNative.module.scss │ │ │ │ ├── DevToolsNative.tsx │ │ │ │ ├── ModalDialog.module.scss │ │ │ │ ├── ModalDialog.tsx │ │ │ │ ├── ModalVisibilityContext.tsx │ │ │ │ ├── Tooltip.module.scss │ │ │ │ ├── Tooltip.tsx │ │ │ │ └── utils.ts │ │ │ ├── editor │ │ │ │ └── Editor.tsx │ │ │ └── index.tsx │ │ ├── tsconfig.json │ │ └── vite.config-overrides.ts │ ├── xmlui-hello-world │ │ ├── .gitignore │ │ ├── index.ts │ │ ├── meta │ │ │ └── componentsMetadata.ts │ │ ├── package.json │ │ ├── src │ │ │ ├── HelloWorld.module.scss │ │ │ ├── HelloWorld.tsx │ │ │ ├── HelloWorldNative.tsx │ │ │ └── index.tsx │ │ └── tsconfig.json │ ├── xmlui-os-frames │ │ ├── .gitignore │ │ ├── demo │ │ │ └── Main.xmlui │ │ ├── index.html │ │ ├── index.ts │ │ ├── meta │ │ │ └── componentsMetadata.ts │ │ ├── package.json │ │ ├── src │ │ │ ├── index.tsx │ │ │ ├── IPhoneFrame.module.scss │ │ │ ├── IPhoneFrame.tsx │ │ │ ├── MacOSAppFrame.module.scss │ │ │ ├── MacOSAppFrame.tsx │ │ │ ├── WindowsAppFrame.module.scss │ │ │ └── WindowsAppFrame.tsx │ │ └── tsconfig.json │ ├── xmlui-pdf │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── demo │ │ │ ├── components │ │ │ │ └── Pdf.xmlui │ │ │ └── Main.xmlui │ │ ├── index.html │ │ ├── index.ts │ │ ├── meta │ │ │ └── componentsMetadata.ts │ │ ├── package.json │ │ ├── src │ │ │ ├── index.tsx │ │ │ ├── LazyPdfNative.tsx │ │ │ ├── Pdf.module.scss │ │ │ └── Pdf.tsx │ │ └── tsconfig.json │ ├── xmlui-playground │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── demo │ │ │ └── Main.xmlui │ │ ├── index.html │ │ ├── index.ts │ │ ├── meta │ │ │ └── componentsMetadata.ts │ │ ├── package.json │ │ ├── src │ │ │ ├── hooks │ │ │ │ ├── usePlayground.ts │ │ │ │ └── useToast.ts │ │ │ ├── index.tsx │ │ │ ├── playground │ │ │ │ ├── Box.module.scss │ │ │ │ ├── Box.tsx │ │ │ │ ├── CodeSelector.tsx │ │ │ │ ├── ConfirmationDialog.module.scss │ │ │ │ ├── ConfirmationDialog.tsx │ │ │ │ ├── Editor.tsx │ │ │ │ ├── Header.module.scss │ │ │ │ ├── Header.tsx │ │ │ │ ├── Playground.tsx │ │ │ │ ├── PlaygroundContent.module.scss │ │ │ │ ├── PlaygroundContent.tsx │ │ │ │ ├── PlaygroundNative.module.scss │ │ │ │ ├── PlaygroundNative.tsx │ │ │ │ ├── Preview.module.scss │ │ │ │ ├── Preview.tsx │ │ │ │ ├── Select.module.scss │ │ │ │ ├── StandalonePlayground.tsx │ │ │ │ ├── StandalonePlaygroundNative.module.scss │ │ │ │ ├── StandalonePlaygroundNative.tsx │ │ │ │ ├── ThemeSwitcher.module.scss │ │ │ │ ├── ThemeSwitcher.tsx │ │ │ │ ├── ToneSwitcher.tsx │ │ │ │ ├── Tooltip.module.scss │ │ │ │ ├── Tooltip.tsx │ │ │ │ └── utils.ts │ │ │ ├── providers │ │ │ │ ├── Toast.module.scss │ │ │ │ └── ToastProvider.tsx │ │ │ ├── state │ │ │ │ └── store.ts │ │ │ ├── themes │ │ │ │ └── theme.ts │ │ │ └── utils │ │ │ └── helpers.ts │ │ └── tsconfig.json │ ├── xmlui-search │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── demo │ │ │ └── Main.xmlui │ │ ├── index.html │ │ ├── index.ts │ │ ├── meta │ │ │ └── componentsMetadata.ts │ │ ├── package.json │ │ ├── src │ │ │ ├── index.tsx │ │ │ ├── Search.module.scss │ │ │ └── Search.tsx │ │ └── tsconfig.json │ ├── xmlui-spreadsheet │ │ ├── .gitignore │ │ ├── demo │ │ │ └── Main.xmlui │ │ ├── index.html │ │ ├── index.ts │ │ ├── meta │ │ │ └── componentsMetadata.ts │ │ ├── package.json │ │ ├── src │ │ │ ├── index.tsx │ │ │ ├── Spreadsheet.tsx │ │ │ └── SpreadsheetNative.tsx │ │ └── tsconfig.json │ └── xmlui-website-blocks │ ├── .gitignore │ ├── CHANGELOG.md │ ├── demo │ │ ├── components │ │ │ ├── HeroBackgroundBreakoutPage.xmlui │ │ │ ├── HeroBackgroundsPage.xmlui │ │ │ ├── HeroContentsPage.xmlui │ │ │ ├── HeroTextAlignPage.xmlui │ │ │ ├── HeroTextPage.xmlui │ │ │ └── HeroTonesPage.xmlui │ │ ├── Main.xmlui │ │ └── themes │ │ └── default.ts │ ├── index.html │ ├── index.ts │ ├── meta │ │ └── componentsMetadata.ts │ ├── package.json │ ├── public │ │ └── resources │ │ ├── building.jpg │ │ └── xmlui-logo.svg │ ├── src │ │ ├── Carousel │ │ │ ├── Carousel.module.scss │ │ │ ├── Carousel.tsx │ │ │ ├── CarouselContext.tsx │ │ │ └── CarouselNative.tsx │ │ ├── FancyButton │ │ │ ├── FancyButton.module.scss │ │ │ ├── FancyButton.tsx │ │ │ └── FancyButton.xmlui │ │ ├── Hello │ │ │ ├── Hello.tsx │ │ │ ├── Hello.xmlui │ │ │ └── Hello.xmlui.xs │ │ ├── HeroSection │ │ │ ├── HeroSection.module.scss │ │ │ ├── HeroSection.tsx │ │ │ └── HeroSectionNative.tsx │ │ ├── index.tsx │ │ ├── ScrollToTop │ │ │ ├── ScrollToTop.module.scss │ │ │ ├── ScrollToTop.tsx │ │ │ └── ScrollToTopNative.tsx │ │ └── vite-env.d.ts │ └── tsconfig.json ├── README.md ├── tools │ ├── codefence │ │ └── xmlui-code-fence-docs.md │ ├── create-app │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── create-app.ts │ │ ├── helpers │ │ │ ├── copy.ts │ │ │ ├── get-pkg-manager.ts │ │ │ ├── git.ts │ │ │ ├── install.ts │ │ │ ├── is-folder-empty.ts │ │ │ ├── is-writeable.ts │ │ │ ├── make-dir.ts │ │ │ └── validate-pkg.ts │ │ ├── index.ts │ │ ├── package.json │ │ ├── templates │ │ │ ├── default │ │ │ │ └── ts │ │ │ │ ├── gitignore │ │ │ │ ├── index.html │ │ │ │ ├── index.ts │ │ │ │ ├── public │ │ │ │ │ ├── mockServiceWorker.js │ │ │ │ │ ├── resources │ │ │ │ │ │ ├── favicon.ico │ │ │ │ │ │ └── xmlui-logo.svg │ │ │ │ │ └── serve.json │ │ │ │ └── src │ │ │ │ ├── components │ │ │ │ │ ├── ApiAware.xmlui │ │ │ │ │ ├── Home.xmlui │ │ │ │ │ ├── IncButton.xmlui │ │ │ │ │ └── PagePanel.xmlui │ │ │ │ ├── config.ts │ │ │ │ └── Main.xmlui │ │ │ ├── index.ts │ │ │ └── types.ts │ │ └── tsconfig.json │ ├── create-xmlui-hello-world │ │ ├── index.js │ │ └── package.json │ └── vscode │ ├── .gitignore │ ├── .vscode │ │ ├── launch.json │ │ └── tasks.json │ ├── .vscodeignore │ ├── build.sh │ ├── CHANGELOG.md │ ├── esbuild.js │ ├── eslint.config.mjs │ ├── formatter-docs.md │ ├── generate-test-sample.sh │ ├── LICENSE.md │ ├── package-lock.json │ ├── package.json │ ├── README.md │ ├── resources │ │ ├── xmlui-logo.png │ │ └── xmlui-markup-syntax-highlighting.png │ ├── src │ │ ├── extension.ts │ │ └── server.ts │ ├── syntaxes │ │ └── xmlui.tmLanguage.json │ ├── test-samples │ │ └── sample.xmlui │ ├── tsconfig.json │ └── tsconfig.tsbuildinfo ├── turbo.json └── xmlui ├── .gitignore ├── bin │ ├── bootstrap.js │ ├── build-lib.ts │ ├── build.ts │ ├── index.ts │ ├── preview.ts │ ├── start.ts │ ├── vite-xmlui-plugin.ts │ └── viteConfig.ts ├── CHANGELOG.md ├── conventions │ ├── component-qa-checklist.md │ ├── copilot-conventions.md │ ├── create-xmlui-components.md │ ├── mermaid.md │ ├── testing-conventions.md │ └── xmlui-in-a-nutshell.md ├── dev-docs │ ├── accessibility.md │ ├── build-system.md │ ├── build-xmlui.md │ ├── component-behaviors.md │ ├── containers.md │ ├── glossary.md │ ├── index.md │ ├── next │ │ ├── component-dev-guide.md │ │ ├── configuration-management-enhancement-summary.md │ │ ├── documentation-scripts-refactoring-complete-summary.md │ │ ├── documentation-scripts-refactoring-plan.md │ │ ├── duplicate-pattern-extraction-summary.md │ │ ├── error-handling-standardization-summary.md │ │ ├── generating-component-reference.md │ │ ├── index.md │ │ ├── logging-consistency-implementation-summary.md │ │ ├── project-build.md │ │ ├── project-structure.md │ │ ├── theme-context.md │ │ ├── tiptap-design-considerations.md │ │ ├── working-with-code.md │ │ ├── xmlui-runtime-architecture │ │ └── xmlui-wcag-accessibility-report.md │ ├── react-fundamentals.md │ ├── release-method.md │ ├── standalone-app.md │ ├── state-management.md │ ├── ud-components.md │ └── xmlui-repo.md ├── package.json ├── playwright.config.ts ├── scripts │ ├── coverage-only.js │ ├── e2e-test-summary.js │ ├── generate-docs │ │ ├── build-downloads-map.mjs │ │ ├── build-pages-map.mjs │ │ ├── components-config.json │ │ ├── configuration-management.mjs │ │ ├── constants.mjs │ │ ├── create-theme-files.mjs │ │ ├── DocsGenerator.mjs │ │ ├── error-handling.mjs │ │ ├── extensions-config.json │ │ ├── folders.mjs │ │ ├── generate-summary-files.mjs │ │ ├── get-docs.mjs │ │ ├── input-handler.mjs │ │ ├── logger.mjs │ │ ├── logging-standards.mjs │ │ ├── MetadataProcessor.mjs │ │ ├── pattern-utilities.mjs │ │ └── utils.mjs │ ├── get-langserver-metadata.mjs │ ├── inline-links.mjs │ └── README-e2e-summary.md ├── src │ ├── abstractions │ │ ├── _conventions.md │ │ ├── ActionDefs.ts │ │ ├── AppContextDefs.ts │ │ ├── ComponentDefs.ts │ │ ├── ContainerDefs.ts │ │ ├── ExtensionDefs.ts │ │ ├── FunctionDefs.ts │ │ ├── RendererDefs.ts │ │ ├── scripting │ │ │ ├── BlockScope.ts │ │ │ ├── Compilation.ts │ │ │ ├── LogicalThread.ts │ │ │ ├── LoopScope.ts │ │ │ ├── modules.ts │ │ │ ├── ScriptParserError.ts │ │ │ ├── Token.ts │ │ │ ├── TryScope.ts │ │ │ └── TryScopeExp.ts │ │ └── ThemingDefs.ts │ ├── components │ │ ├── _conventions.md │ │ ├── abstractions.ts │ │ ├── Accordion │ │ │ ├── Accordion.md │ │ │ ├── Accordion.module.scss │ │ │ ├── Accordion.spec.ts │ │ │ ├── Accordion.tsx │ │ │ ├── AccordionContext.tsx │ │ │ ├── AccordionItem.tsx │ │ │ ├── AccordionItemNative.tsx │ │ │ └── AccordionNative.tsx │ │ ├── Animation │ │ │ └── AnimationNative.tsx │ │ ├── APICall │ │ │ ├── APICall.md │ │ │ ├── APICall.spec.ts │ │ │ ├── APICall.tsx │ │ │ └── APICallNative.tsx │ │ ├── App │ │ │ ├── App.md │ │ │ ├── App.module.scss │ │ │ ├── App.spec.ts │ │ │ ├── App.tsx │ │ │ ├── AppLayoutContext.ts │ │ │ ├── AppNative.tsx │ │ │ ├── AppStateContext.ts │ │ │ ├── doc-resources │ │ │ │ ├── condensed-sticky.xmlui │ │ │ │ ├── condensed.xmlui │ │ │ │ ├── horizontal-sticky.xmlui │ │ │ │ ├── horizontal.xmlui │ │ │ │ ├── vertical-full-header.xmlui │ │ │ │ ├── vertical-sticky.xmlui │ │ │ │ └── vertical.xmlui │ │ │ ├── IndexerContext.ts │ │ │ ├── LinkInfoContext.ts │ │ │ ├── SearchContext.tsx │ │ │ ├── Sheet.module.scss │ │ │ └── Sheet.tsx │ │ ├── AppHeader │ │ │ ├── AppHeader.md │ │ │ ├── AppHeader.module.scss │ │ │ ├── AppHeader.spec.ts │ │ │ ├── AppHeader.tsx │ │ │ └── AppHeaderNative.tsx │ │ ├── AppState │ │ │ ├── AppState.md │ │ │ ├── AppState.spec.ts │ │ │ ├── AppState.tsx │ │ │ └── AppStateNative.tsx │ │ ├── AutoComplete │ │ │ ├── AutoComplete.md │ │ │ ├── AutoComplete.module.scss │ │ │ ├── AutoComplete.spec.ts │ │ │ ├── AutoComplete.tsx │ │ │ ├── AutoCompleteContext.tsx │ │ │ └── AutoCompleteNative.tsx │ │ ├── Avatar │ │ │ ├── Avatar.md │ │ │ ├── Avatar.module.scss │ │ │ ├── Avatar.spec.ts │ │ │ ├── Avatar.tsx │ │ │ └── AvatarNative.tsx │ │ ├── Backdrop │ │ │ ├── Backdrop.md │ │ │ ├── Backdrop.module.scss │ │ │ ├── Backdrop.spec.ts │ │ │ ├── Backdrop.tsx │ │ │ └── BackdropNative.tsx │ │ ├── Badge │ │ │ ├── Badge.md │ │ │ ├── Badge.module.scss │ │ │ ├── Badge.spec.ts │ │ │ ├── Badge.tsx │ │ │ └── BadgeNative.tsx │ │ ├── Bookmark │ │ │ ├── Bookmark.md │ │ │ ├── Bookmark.module.scss │ │ │ ├── Bookmark.spec.ts │ │ │ ├── Bookmark.tsx │ │ │ └── BookmarkNative.tsx │ │ ├── Breakout │ │ │ ├── Breakout.module.scss │ │ │ ├── Breakout.spec.ts │ │ │ ├── Breakout.tsx │ │ │ └── BreakoutNative.tsx │ │ ├── Button │ │ │ ├── Button-style.spec.ts │ │ │ ├── Button.md │ │ │ ├── Button.module.scss │ │ │ ├── Button.spec.ts │ │ │ ├── Button.tsx │ │ │ └── ButtonNative.tsx │ │ ├── Card │ │ │ ├── Card.md │ │ │ ├── Card.module.scss │ │ │ ├── Card.spec.ts │ │ │ ├── Card.tsx │ │ │ └── CardNative.tsx │ │ ├── Carousel │ │ │ ├── Carousel.md │ │ │ ├── Carousel.module.scss │ │ │ ├── Carousel.spec.ts │ │ │ ├── Carousel.tsx │ │ │ ├── CarouselContext.tsx │ │ │ ├── CarouselItem.tsx │ │ │ ├── CarouselItemNative.tsx │ │ │ └── CarouselNative.tsx │ │ ├── ChangeListener │ │ │ ├── ChangeListener.md │ │ │ ├── ChangeListener.spec.ts │ │ │ ├── ChangeListener.tsx │ │ │ └── ChangeListenerNative.tsx │ │ ├── chart-color-schemes.ts │ │ ├── Charts │ │ │ ├── AreaChart │ │ │ │ ├── AreaChart.md │ │ │ │ ├── AreaChart.spec.ts │ │ │ │ ├── AreaChart.tsx │ │ │ │ └── AreaChartNative.tsx │ │ │ ├── BarChart │ │ │ │ ├── BarChart.md │ │ │ │ ├── BarChart.module.scss │ │ │ │ ├── BarChart.spec.ts │ │ │ │ ├── BarChart.tsx │ │ │ │ └── BarChartNative.tsx │ │ │ ├── DonutChart │ │ │ │ ├── DonutChart.spec.ts │ │ │ │ └── DonutChart.tsx │ │ │ ├── LabelList │ │ │ │ ├── LabelList.spec.ts │ │ │ │ ├── LabelList.tsx │ │ │ │ ├── LabelListNative.module.scss │ │ │ │ └── LabelListNative.tsx │ │ │ ├── Legend │ │ │ │ ├── Legend.spec.ts │ │ │ │ ├── Legend.tsx │ │ │ │ └── LegendNative.tsx │ │ │ ├── LineChart │ │ │ │ ├── LineChart.md │ │ │ │ ├── LineChart.module.scss │ │ │ │ ├── LineChart.spec.ts │ │ │ │ ├── LineChart.tsx │ │ │ │ └── LineChartNative.tsx │ │ │ ├── PieChart │ │ │ │ ├── PieChart.md │ │ │ │ ├── PieChart.spec.ts │ │ │ │ ├── PieChart.tsx │ │ │ │ ├── PieChartNative.module.scss │ │ │ │ └── PieChartNative.tsx │ │ │ ├── RadarChart │ │ │ │ ├── RadarChart.md │ │ │ │ ├── RadarChart.spec.ts │ │ │ │ ├── RadarChart.tsx │ │ │ │ └── RadarChartNative.tsx │ │ │ ├── Tooltip │ │ │ │ ├── TooltipContent.module.scss │ │ │ │ ├── TooltipContent.spec.ts │ │ │ │ └── TooltipContent.tsx │ │ │ └── utils │ │ │ ├── abstractions.ts │ │ │ └── ChartProvider.tsx │ │ ├── Checkbox │ │ │ ├── Checkbox.md │ │ │ ├── Checkbox.spec.ts │ │ │ └── Checkbox.tsx │ │ ├── CodeBlock │ │ │ ├── CodeBlock.module.scss │ │ │ ├── CodeBlock.spec.ts │ │ │ ├── CodeBlock.tsx │ │ │ ├── CodeBlockNative.tsx │ │ │ └── highlight-code.ts │ │ ├── collectedComponentMetadata.ts │ │ ├── ColorPicker │ │ │ ├── ColorPicker.md │ │ │ ├── ColorPicker.module.scss │ │ │ ├── ColorPicker.spec.ts │ │ │ ├── ColorPicker.tsx │ │ │ └── ColorPickerNative.tsx │ │ ├── Column │ │ │ ├── Column.md │ │ │ ├── Column.tsx │ │ │ ├── ColumnNative.tsx │ │ │ ├── doc-resources │ │ │ │ └── list-component-data.js │ │ │ └── TableContext.tsx │ │ ├── component-utils.ts │ │ ├── ComponentProvider.tsx │ │ ├── ComponentRegistryContext.tsx │ │ ├── container-helpers.tsx │ │ ├── ContentSeparator │ │ │ ├── ContentSeparator.md │ │ │ ├── ContentSeparator.module.scss │ │ │ ├── ContentSeparator.spec.ts │ │ │ ├── ContentSeparator.tsx │ │ │ └── ContentSeparatorNative.tsx │ │ ├── DataSource │ │ │ ├── DataSource.md │ │ │ └── DataSource.tsx │ │ ├── DateInput │ │ │ ├── DateInput.md │ │ │ ├── DateInput.module.scss │ │ │ ├── DateInput.spec.ts │ │ │ ├── DateInput.tsx │ │ │ └── DateInputNative.tsx │ │ ├── DatePicker │ │ │ ├── DatePicker.md │ │ │ ├── DatePicker.module.scss │ │ │ ├── DatePicker.spec.ts │ │ │ ├── DatePicker.tsx │ │ │ └── DatePickerNative.tsx │ │ ├── DropdownMenu │ │ │ ├── DropdownMenu.md │ │ │ ├── DropdownMenu.module.scss │ │ │ ├── DropdownMenu.spec.ts │ │ │ ├── DropdownMenu.tsx │ │ │ ├── DropdownMenuNative.tsx │ │ │ ├── MenuItem.md │ │ │ └── SubMenuItem.md │ │ ├── EmojiSelector │ │ │ ├── EmojiSelector.md │ │ │ ├── EmojiSelector.spec.ts │ │ │ ├── EmojiSelector.tsx │ │ │ └── EmojiSelectorNative.tsx │ │ ├── ExpandableItem │ │ │ ├── ExpandableItem.module.scss │ │ │ ├── ExpandableItem.spec.ts │ │ │ ├── ExpandableItem.tsx │ │ │ └── ExpandableItemNative.tsx │ │ ├── FileInput │ │ │ ├── FileInput.md │ │ │ ├── FileInput.module.scss │ │ │ ├── FileInput.spec.ts │ │ │ ├── FileInput.tsx │ │ │ └── FileInputNative.tsx │ │ ├── FileUploadDropZone │ │ │ ├── FileUploadDropZone.md │ │ │ ├── FileUploadDropZone.module.scss │ │ │ ├── FileUploadDropZone.spec.ts │ │ │ ├── FileUploadDropZone.tsx │ │ │ └── FileUploadDropZoneNative.tsx │ │ ├── FlowLayout │ │ │ ├── FlowLayout.md │ │ │ ├── FlowLayout.module.scss │ │ │ ├── FlowLayout.spec.ts │ │ │ ├── FlowLayout.spec.ts-snapshots │ │ │ │ └── Edge-cases-boxShadow-is-not-clipped-1-non-smoke-darwin.png │ │ │ ├── FlowLayout.tsx │ │ │ └── FlowLayoutNative.tsx │ │ ├── Footer │ │ │ ├── Footer.md │ │ │ ├── Footer.module.scss │ │ │ ├── Footer.spec.ts │ │ │ ├── Footer.tsx │ │ │ └── FooterNative.tsx │ │ ├── Form │ │ │ ├── Form.md │ │ │ ├── Form.module.scss │ │ │ ├── Form.spec.ts │ │ │ ├── Form.tsx │ │ │ ├── formActions.ts │ │ │ ├── FormContext.ts │ │ │ └── FormNative.tsx │ │ ├── FormItem │ │ │ ├── FormItem.md │ │ │ ├── FormItem.module.scss │ │ │ ├── FormItem.spec.ts │ │ │ ├── FormItem.tsx │ │ │ ├── FormItemNative.tsx │ │ │ ├── HelperText.module.scss │ │ │ ├── HelperText.tsx │ │ │ ├── ItemWithLabel.tsx │ │ │ └── Validations.ts │ │ ├── FormSection │ │ │ ├── FormSection.md │ │ │ ├── FormSection.ts │ │ │ └── FormSection.xmlui │ │ ├── Fragment │ │ │ ├── Fragment.spec.ts │ │ │ └── Fragment.tsx │ │ ├── Heading │ │ │ ├── abstractions.ts │ │ │ ├── H1.md │ │ │ ├── H1.spec.ts │ │ │ ├── H2.md │ │ │ ├── H2.spec.ts │ │ │ ├── H3.md │ │ │ ├── H3.spec.ts │ │ │ ├── H4.md │ │ │ ├── H4.spec.ts │ │ │ ├── H5.md │ │ │ ├── H5.spec.ts │ │ │ ├── H6.md │ │ │ ├── H6.spec.ts │ │ │ ├── Heading.md │ │ │ ├── Heading.module.scss │ │ │ ├── Heading.spec.ts │ │ │ ├── Heading.tsx │ │ │ └── HeadingNative.tsx │ │ ├── HoverCard │ │ │ ├── HoverCard.tsx │ │ │ └── HovercardNative.tsx │ │ ├── HtmlTags │ │ │ ├── HtmlTags.module.scss │ │ │ ├── HtmlTags.spec.ts │ │ │ └── HtmlTags.tsx │ │ ├── Icon │ │ │ ├── AdmonitionDanger.tsx │ │ │ ├── AdmonitionInfo.tsx │ │ │ ├── AdmonitionNote.tsx │ │ │ ├── AdmonitionTip.tsx │ │ │ ├── AdmonitionWarning.tsx │ │ │ ├── ApiIcon.tsx │ │ │ ├── ArrowDropDown.module.scss │ │ │ ├── ArrowDropDown.tsx │ │ │ ├── ArrowDropUp.module.scss │ │ │ ├── ArrowDropUp.tsx │ │ │ ├── ArrowLeft.module.scss │ │ │ ├── ArrowLeft.tsx │ │ │ ├── ArrowRight.module.scss │ │ │ ├── ArrowRight.tsx │ │ │ ├── Attach.tsx │ │ │ ├── Binding.module.scss │ │ │ ├── Binding.tsx │ │ │ ├── BoardIcon.tsx │ │ │ ├── BoxIcon.tsx │ │ │ ├── CheckIcon.tsx │ │ │ ├── ChevronDownIcon.tsx │ │ │ ├── ChevronLeft.tsx │ │ │ ├── ChevronRight.tsx │ │ │ ├── ChevronUpIcon.tsx │ │ │ ├── CodeFileIcon.tsx │ │ │ ├── CodeSandbox.tsx │ │ │ ├── CompactListIcon.tsx │ │ │ ├── ContentCopyIcon.tsx │ │ │ ├── DarkToLightIcon.tsx │ │ │ ├── DatabaseIcon.module.scss │ │ │ ├── DatabaseIcon.tsx │ │ │ ├── DocFileIcon.tsx │ │ │ ├── DocIcon.tsx │ │ │ ├── DotMenuHorizontalIcon.tsx │ │ │ ├── DotMenuIcon.tsx │ │ │ ├── EmailIcon.tsx │ │ │ ├── EmptyFolderIcon.tsx │ │ │ ├── ErrorIcon.tsx │ │ │ ├── ExpressionIcon.tsx │ │ │ ├── FillPlusCricleIcon.tsx │ │ │ ├── FilterIcon.tsx │ │ │ ├── FolderIcon.tsx │ │ │ ├── GlobeIcon.tsx │ │ │ ├── HomeIcon.tsx │ │ │ ├── HyperLinkIcon.tsx │ │ │ ├── Icon.md │ │ │ ├── Icon.module.scss │ │ │ ├── Icon.spec.ts │ │ │ ├── Icon.tsx │ │ │ ├── IconNative.tsx │ │ │ ├── ImageFileIcon.tsx │ │ │ ├── Inspect.tsx │ │ │ ├── LightToDark.tsx │ │ │ ├── LinkIcon.tsx │ │ │ ├── ListIcon.tsx │ │ │ ├── LooseListIcon.tsx │ │ │ ├── MoonIcon.tsx │ │ │ ├── MoreOptionsIcon.tsx │ │ │ ├── NoSortIcon.tsx │ │ │ ├── PDFIcon.tsx │ │ │ ├── PenIcon.tsx │ │ │ ├── PhoneIcon.tsx │ │ │ ├── PhotoIcon.tsx │ │ │ ├── PlusIcon.tsx │ │ │ ├── SearchIcon.tsx │ │ │ ├── ShareIcon.tsx │ │ │ ├── SortAscendingIcon.tsx │ │ │ ├── SortDescendingIcon.tsx │ │ │ ├── StarsIcon.tsx │ │ │ ├── SunIcon.tsx │ │ │ ├── svg │ │ │ │ ├── admonition_danger.svg │ │ │ │ ├── admonition_info.svg │ │ │ │ ├── admonition_note.svg │ │ │ │ ├── admonition_tip.svg │ │ │ │ ├── admonition_warning.svg │ │ │ │ ├── api.svg │ │ │ │ ├── arrow-dropdown.svg │ │ │ │ ├── arrow-left.svg │ │ │ │ ├── arrow-right.svg │ │ │ │ ├── arrow-up.svg │ │ │ │ ├── attach.svg │ │ │ │ ├── binding.svg │ │ │ │ ├── box.svg │ │ │ │ ├── bulb.svg │ │ │ │ ├── code-file.svg │ │ │ │ ├── code-sandbox.svg │ │ │ │ ├── dark_to_light.svg │ │ │ │ ├── database.svg │ │ │ │ ├── doc.svg │ │ │ │ ├── empty-folder.svg │ │ │ │ ├── expression.svg │ │ │ │ ├── eye-closed.svg │ │ │ │ ├── eye-dark.svg │ │ │ │ ├── eye.svg │ │ │ │ ├── file-text.svg │ │ │ │ ├── filter.svg │ │ │ │ ├── folder.svg │ │ │ │ ├── img.svg │ │ │ │ ├── inspect.svg │ │ │ │ ├── light_to_dark.svg │ │ │ │ ├── moon.svg │ │ │ │ ├── pdf.svg │ │ │ │ ├── photo.svg │ │ │ │ ├── share.svg │ │ │ │ ├── stars.svg │ │ │ │ ├── sun.svg │ │ │ │ ├── trending-down.svg │ │ │ │ ├── trending-level.svg │ │ │ │ ├── trending-up.svg │ │ │ │ ├── txt.svg │ │ │ │ ├── unknown-file.svg │ │ │ │ ├── unlink.svg │ │ │ │ └── xls.svg │ │ │ ├── TableDeleteColumnIcon.tsx │ │ │ ├── TableDeleteRowIcon.tsx │ │ │ ├── TableInsertColumnIcon.tsx │ │ │ ├── TableInsertRowIcon.tsx │ │ │ ├── TrashIcon.tsx │ │ │ ├── TrendingDownIcon.tsx │ │ │ ├── TrendingLevelIcon.tsx │ │ │ ├── TrendingUpIcon.tsx │ │ │ ├── TxtIcon.tsx │ │ │ ├── UnknownFileIcon.tsx │ │ │ ├── UnlinkIcon.tsx │ │ │ ├── UserIcon.tsx │ │ │ ├── WarningIcon.tsx │ │ │ └── XlsIcon.tsx │ │ ├── IconProvider.tsx │ │ ├── IconRegistryContext.tsx │ │ ├── IFrame │ │ │ ├── IFrame.md │ │ │ ├── IFrame.module.scss │ │ │ ├── IFrame.spec.ts │ │ │ ├── IFrame.tsx │ │ │ └── IFrameNative.tsx │ │ ├── Image │ │ │ ├── Image.md │ │ │ ├── Image.module.scss │ │ │ ├── Image.spec.ts │ │ │ ├── Image.tsx │ │ │ └── ImageNative.tsx │ │ ├── Input │ │ │ ├── index.ts │ │ │ ├── InputAdornment.module.scss │ │ │ ├── InputAdornment.tsx │ │ │ ├── InputDivider.module.scss │ │ │ ├── InputDivider.tsx │ │ │ ├── InputLabel.module.scss │ │ │ ├── InputLabel.tsx │ │ │ ├── PartialInput.module.scss │ │ │ └── PartialInput.tsx │ │ ├── InspectButton │ │ │ ├── InspectButton.module.scss │ │ │ └── InspectButton.tsx │ │ ├── Items │ │ │ ├── Items.md │ │ │ ├── Items.spec.ts │ │ │ ├── Items.tsx │ │ │ └── ItemsNative.tsx │ │ ├── Link │ │ │ ├── Link.md │ │ │ ├── Link.module.scss │ │ │ ├── Link.spec.ts │ │ │ ├── Link.tsx │ │ │ └── LinkNative.tsx │ │ ├── List │ │ │ ├── doc-resources │ │ │ │ └── list-component-data.js │ │ │ ├── List.md │ │ │ ├── List.module.scss │ │ │ ├── List.spec.ts │ │ │ ├── List.tsx │ │ │ └── ListNative.tsx │ │ ├── Logo │ │ │ ├── doc-resources │ │ │ │ └── xmlui-logo.svg │ │ │ ├── Logo.md │ │ │ ├── Logo.tsx │ │ │ └── LogoNative.tsx │ │ ├── Markdown │ │ │ ├── CodeText.module.scss │ │ │ ├── CodeText.tsx │ │ │ ├── Markdown.md │ │ │ ├── Markdown.module.scss │ │ │ ├── Markdown.spec.ts │ │ │ ├── Markdown.tsx │ │ │ ├── MarkdownNative.tsx │ │ │ ├── parse-binding-expr.ts │ │ │ └── utils.ts │ │ ├── metadata-helpers.ts │ │ ├── ModalDialog │ │ │ ├── ConfirmationModalContextProvider.tsx │ │ │ ├── Dialog.module.scss │ │ │ ├── Dialog.tsx │ │ │ ├── ModalDialog.md │ │ │ ├── ModalDialog.module.scss │ │ │ ├── ModalDialog.spec.ts │ │ │ ├── ModalDialog.tsx │ │ │ ├── ModalDialogNative.tsx │ │ │ └── ModalVisibilityContext.tsx │ │ ├── NavGroup │ │ │ ├── NavGroup.md │ │ │ ├── NavGroup.module.scss │ │ │ ├── NavGroup.spec.ts │ │ │ ├── NavGroup.tsx │ │ │ ├── NavGroupContext.ts │ │ │ └── NavGroupNative.tsx │ │ ├── NavLink │ │ │ ├── NavLink.md │ │ │ ├── NavLink.module.scss │ │ │ ├── NavLink.spec.ts │ │ │ ├── NavLink.tsx │ │ │ └── NavLinkNative.tsx │ │ ├── NavPanel │ │ │ ├── NavPanel.md │ │ │ ├── NavPanel.module.scss │ │ │ ├── NavPanel.spec.ts │ │ │ ├── NavPanel.tsx │ │ │ └── NavPanelNative.tsx │ │ ├── NestedApp │ │ │ ├── AppWithCodeView.module.scss │ │ │ ├── AppWithCodeView.tsx │ │ │ ├── AppWithCodeViewNative.tsx │ │ │ ├── defaultProps.tsx │ │ │ ├── logo.svg │ │ │ ├── NestedApp.module.scss │ │ │ ├── NestedApp.tsx │ │ │ ├── NestedAppNative.tsx │ │ │ ├── Tooltip.module.scss │ │ │ ├── Tooltip.tsx │ │ │ └── utils.ts │ │ ├── NoResult │ │ │ ├── NoResult.md │ │ │ ├── NoResult.module.scss │ │ │ ├── NoResult.spec.ts │ │ │ ├── NoResult.tsx │ │ │ └── NoResultNative.tsx │ │ ├── NumberBox │ │ │ ├── numberbox-abstractions.ts │ │ │ ├── NumberBox.md │ │ │ ├── NumberBox.module.scss │ │ │ ├── NumberBox.spec.ts │ │ │ ├── NumberBox.tsx │ │ │ └── NumberBoxNative.tsx │ │ ├── Option │ │ │ ├── Option.md │ │ │ ├── Option.spec.ts │ │ │ ├── Option.tsx │ │ │ ├── OptionNative.tsx │ │ │ └── OptionTypeProvider.tsx │ │ ├── PageMetaTitle │ │ │ ├── PageMetaTilteNative.tsx │ │ │ ├── PageMetaTitle.md │ │ │ ├── PageMetaTitle.spec.ts │ │ │ └── PageMetaTitle.tsx │ │ ├── Pages │ │ │ ├── Page.md │ │ │ ├── Pages.md │ │ │ ├── Pages.module.scss │ │ │ ├── Pages.tsx │ │ │ └── PagesNative.tsx │ │ ├── Pagination │ │ │ ├── Pagination.md │ │ │ ├── Pagination.module.scss │ │ │ ├── Pagination.spec.ts │ │ │ ├── Pagination.tsx │ │ │ └── PaginationNative.tsx │ │ ├── PositionedContainer │ │ │ ├── PositionedContainer.module.scss │ │ │ ├── PositionedContainer.tsx │ │ │ └── PositionedContainerNative.tsx │ │ ├── ProfileMenu │ │ │ ├── ProfileMenu.module.scss │ │ │ └── ProfileMenu.tsx │ │ ├── ProgressBar │ │ │ ├── ProgressBar.md │ │ │ ├── ProgressBar.module.scss │ │ │ ├── ProgressBar.spec.ts │ │ │ ├── ProgressBar.tsx │ │ │ └── ProgressBarNative.tsx │ │ ├── Queue │ │ │ ├── Queue.md │ │ │ ├── Queue.spec.ts │ │ │ ├── Queue.tsx │ │ │ ├── queueActions.ts │ │ │ └── QueueNative.tsx │ │ ├── RadioGroup │ │ │ ├── RadioGroup.md │ │ │ ├── RadioGroup.module.scss │ │ │ ├── RadioGroup.spec.ts │ │ │ ├── RadioGroup.tsx │ │ │ ├── RadioGroupNative.tsx │ │ │ ├── RadioItem.tsx │ │ │ └── RadioItemNative.tsx │ │ ├── RealTimeAdapter │ │ │ ├── RealTimeAdapter.tsx │ │ │ └── RealTimeAdapterNative.tsx │ │ ├── Redirect │ │ │ ├── Redirect.md │ │ │ ├── Redirect.spec.ts │ │ │ └── Redirect.tsx │ │ ├── ResponsiveBar │ │ │ ├── README.md │ │ │ ├── ResponsiveBar.md │ │ │ ├── ResponsiveBar.module.scss │ │ │ ├── ResponsiveBar.spec.ts │ │ │ ├── ResponsiveBar.tsx │ │ │ └── ResponsiveBarNative.tsx │ │ ├── Select │ │ │ ├── HiddenOption.tsx │ │ │ ├── MultiSelectOption.tsx │ │ │ ├── OptionContext.ts │ │ │ ├── Select.md │ │ │ ├── Select.module.scss │ │ │ ├── Select.spec.ts │ │ │ ├── Select.tsx │ │ │ ├── SelectContext.tsx │ │ │ ├── SelectNative.tsx │ │ │ ├── SelectOption.tsx │ │ │ └── SimpleSelect.tsx │ │ ├── SelectionStore │ │ │ ├── SelectionStore.md │ │ │ ├── SelectionStore.tsx │ │ │ └── SelectionStoreNative.tsx │ │ ├── Slider │ │ │ ├── Slider.md │ │ │ ├── Slider.module.scss │ │ │ ├── Slider.spec.ts │ │ │ ├── Slider.tsx │ │ │ └── SliderNative.tsx │ │ ├── Slot │ │ │ ├── Slot.md │ │ │ ├── Slot.spec.ts │ │ │ └── Slot.ts │ │ ├── SlotItem.tsx │ │ ├── SpaceFiller │ │ │ ├── SpaceFiller.md │ │ │ ├── SpaceFiller.module.scss │ │ │ ├── SpaceFiller.spec.ts │ │ │ ├── SpaceFiller.tsx │ │ │ └── SpaceFillerNative.tsx │ │ ├── Spinner │ │ │ ├── Spinner.md │ │ │ ├── Spinner.module.scss │ │ │ ├── Spinner.spec.ts │ │ │ ├── Spinner.tsx │ │ │ └── SpinnerNative.tsx │ │ ├── Splitter │ │ │ ├── HSplitter.md │ │ │ ├── HSplitter.spec.ts │ │ │ ├── Splitter.md │ │ │ ├── Splitter.module.scss │ │ │ ├── Splitter.spec.ts │ │ │ ├── Splitter.tsx │ │ │ ├── SplitterNative.tsx │ │ │ ├── utils.ts │ │ │ ├── VSplitter.md │ │ │ └── VSplitter.spec.ts │ │ ├── Stack │ │ │ ├── CHStack.md │ │ │ ├── CHStack.spec.ts │ │ │ ├── CVStack.md │ │ │ ├── CVStack.spec.ts │ │ │ ├── HStack.md │ │ │ ├── HStack.spec.ts │ │ │ ├── Stack.md │ │ │ ├── Stack.module.scss │ │ │ ├── Stack.spec.ts │ │ │ ├── Stack.tsx │ │ │ ├── StackNative.tsx │ │ │ ├── VStack.md │ │ │ └── VStack.spec.ts │ │ ├── StickyBox │ │ │ ├── StickyBox.md │ │ │ ├── StickyBox.module.scss │ │ │ ├── StickyBox.tsx │ │ │ └── StickyBoxNative.tsx │ │ ├── Switch │ │ │ ├── Switch.md │ │ │ ├── Switch.spec.ts │ │ │ └── Switch.tsx │ │ ├── Table │ │ │ ├── doc-resources │ │ │ │ └── list-component-data.js │ │ │ ├── react-table-config.d.ts │ │ │ ├── Table.md │ │ │ ├── Table.module.scss │ │ │ ├── Table.spec.ts │ │ │ ├── Table.tsx │ │ │ ├── TableNative.tsx │ │ │ └── useRowSelection.tsx │ │ ├── TableOfContents │ │ │ ├── TableOfContents.module.scss │ │ │ ├── TableOfContents.spec.ts │ │ │ ├── TableOfContents.tsx │ │ │ └── TableOfContentsNative.tsx │ │ ├── Tabs │ │ │ ├── TabContext.tsx │ │ │ ├── TabItem.md │ │ │ ├── TabItem.tsx │ │ │ ├── TabItemNative.tsx │ │ │ ├── Tabs.md │ │ │ ├── Tabs.module.scss │ │ │ ├── Tabs.spec.ts │ │ │ ├── Tabs.tsx │ │ │ └── TabsNative.tsx │ │ ├── Text │ │ │ ├── Text.md │ │ │ ├── Text.module.scss │ │ │ ├── Text.spec.ts │ │ │ ├── Text.tsx │ │ │ └── TextNative.tsx │ │ ├── TextArea │ │ │ ├── TextArea.md │ │ │ ├── TextArea.module.scss │ │ │ ├── TextArea.spec.ts │ │ │ ├── TextArea.tsx │ │ │ ├── TextAreaNative.tsx │ │ │ ├── TextAreaResizable.tsx │ │ │ └── useComposedRef.ts │ │ ├── TextBox │ │ │ ├── TextBox.md │ │ │ ├── TextBox.module.scss │ │ │ ├── TextBox.spec.ts │ │ │ ├── TextBox.tsx │ │ │ └── TextBoxNative.tsx │ │ ├── Theme │ │ │ ├── NotificationToast.tsx │ │ │ ├── Theme.md │ │ │ ├── Theme.module.scss │ │ │ ├── Theme.spec.ts │ │ │ ├── Theme.tsx │ │ │ └── ThemeNative.tsx │ │ ├── TimeInput │ │ │ ├── TimeInput.md │ │ │ ├── TimeInput.module.scss │ │ │ ├── TimeInput.spec.ts │ │ │ ├── TimeInput.tsx │ │ │ ├── TimeInputNative.tsx │ │ │ └── utils.ts │ │ ├── Timer │ │ │ ├── Timer.md │ │ │ ├── Timer.spec.ts │ │ │ ├── Timer.tsx │ │ │ └── TimerNative.tsx │ │ ├── Toggle │ │ │ ├── Toggle.module.scss │ │ │ └── Toggle.tsx │ │ ├── ToneChangerButton │ │ │ ├── ToneChangerButton.md │ │ │ ├── ToneChangerButton.spec.ts │ │ │ └── ToneChangerButton.tsx │ │ ├── ToneSwitch │ │ │ ├── ToneSwitch.md │ │ │ ├── ToneSwitch.module.scss │ │ │ ├── ToneSwitch.spec.ts │ │ │ ├── ToneSwitch.tsx │ │ │ └── ToneSwitchNative.tsx │ │ ├── Tooltip │ │ │ ├── Tooltip.md │ │ │ ├── Tooltip.module.scss │ │ │ ├── Tooltip.spec.ts │ │ │ ├── Tooltip.tsx │ │ │ └── TooltipNative.tsx │ │ ├── Tree │ │ │ ├── testData.ts │ │ │ ├── Tree-dynamic.spec.ts │ │ │ ├── Tree-icons.spec.ts │ │ │ ├── Tree.md │ │ │ ├── Tree.spec.ts │ │ │ ├── TreeComponent.module.scss │ │ │ ├── TreeComponent.tsx │ │ │ └── TreeNative.tsx │ │ ├── TreeDisplay │ │ │ ├── TreeDisplay.md │ │ │ ├── TreeDisplay.module.scss │ │ │ ├── TreeDisplay.tsx │ │ │ └── TreeDisplayNative.tsx │ │ ├── ValidationSummary │ │ │ ├── ValidationSummary.module.scss │ │ │ └── ValidationSummary.tsx │ │ └── VisuallyHidden.tsx │ ├── components-core │ │ ├── abstractions │ │ │ ├── ComponentRenderer.ts │ │ │ ├── LoaderRenderer.ts │ │ │ ├── standalone.ts │ │ │ └── treeAbstractions.ts │ │ ├── action │ │ │ ├── actions.ts │ │ │ ├── APICall.tsx │ │ │ ├── FileDownloadAction.tsx │ │ │ ├── FileUploadAction.tsx │ │ │ ├── NavigateAction.tsx │ │ │ └── TimedAction.tsx │ │ ├── ApiBoundComponent.tsx │ │ ├── appContext │ │ │ ├── date-functions.ts │ │ │ ├── math-function.ts │ │ │ └── misc-utils.ts │ │ ├── AppContext.tsx │ │ ├── behaviors │ │ │ ├── Behavior.tsx │ │ │ └── CoreBehaviors.tsx │ │ ├── component-hooks.ts │ │ ├── ComponentDecorator.tsx │ │ ├── ComponentViewer.tsx │ │ ├── CompoundComponent.tsx │ │ ├── constants.ts │ │ ├── DebugViewProvider.tsx │ │ ├── descriptorHelper.ts │ │ ├── devtools │ │ │ ├── InspectorDialog.module.scss │ │ │ ├── InspectorDialog.tsx │ │ │ └── InspectorDialogVisibilityContext.tsx │ │ ├── EngineError.ts │ │ ├── event-handlers.ts │ │ ├── InspectorButton.module.scss │ │ ├── InspectorContext.tsx │ │ ├── interception │ │ │ ├── abstractions.ts │ │ │ ├── ApiInterceptor.ts │ │ │ ├── ApiInterceptorProvider.tsx │ │ │ ├── apiInterceptorWorker.ts │ │ │ ├── Backend.ts │ │ │ ├── Errors.ts │ │ │ ├── IndexedDb.ts │ │ │ ├── initMock.ts │ │ │ ├── InMemoryDb.ts │ │ │ ├── ReadonlyCollection.ts │ │ │ └── useApiInterceptorContext.tsx │ │ ├── loader │ │ │ ├── ApiLoader.tsx │ │ │ ├── DataLoader.tsx │ │ │ ├── ExternalDataLoader.tsx │ │ │ ├── Loader.tsx │ │ │ ├── MockLoaderRenderer.tsx │ │ │ └── PageableLoader.tsx │ │ ├── LoaderComponent.tsx │ │ ├── markup-check.ts │ │ ├── parts.ts │ │ ├── renderers.ts │ │ ├── rendering │ │ │ ├── AppContent.tsx │ │ │ ├── AppRoot.tsx │ │ │ ├── AppWrapper.tsx │ │ │ ├── buildProxy.ts │ │ │ ├── collectFnVarDeps.ts │ │ │ ├── ComponentAdapter.tsx │ │ │ ├── ComponentWrapper.tsx │ │ │ ├── Container.tsx │ │ │ ├── containers.ts │ │ │ ├── ContainerWrapper.tsx │ │ │ ├── ErrorBoundary.module.scss │ │ │ ├── ErrorBoundary.tsx │ │ │ ├── InvalidComponent.module.scss │ │ │ ├── InvalidComponent.tsx │ │ │ ├── nodeUtils.ts │ │ │ ├── reducer.ts │ │ │ ├── renderChild.tsx │ │ │ ├── StandaloneComponent.tsx │ │ │ ├── StateContainer.tsx │ │ │ ├── UnknownComponent.module.scss │ │ │ ├── UnknownComponent.tsx │ │ │ └── valueExtractor.ts │ │ ├── reportEngineError.ts │ │ ├── RestApiProxy.ts │ │ ├── script-runner │ │ │ ├── asyncProxy.ts │ │ │ ├── AttributeValueParser.ts │ │ │ ├── bannedFunctions.ts │ │ │ ├── BindingTreeEvaluationContext.ts │ │ │ ├── eval-tree-async.ts │ │ │ ├── eval-tree-common.ts │ │ │ ├── eval-tree-sync.ts │ │ │ ├── ParameterParser.ts │ │ │ ├── process-statement-async.ts │ │ │ ├── process-statement-common.ts │ │ │ ├── process-statement-sync.ts │ │ │ ├── ScriptingSourceTree.ts │ │ │ ├── simplify-expression.ts │ │ │ ├── statement-queue.ts │ │ │ └── visitors.ts │ │ ├── StandaloneApp.tsx │ │ ├── StandaloneExtensionManager.ts │ │ ├── TableOfContentsContext.tsx │ │ ├── theming │ │ │ ├── _themes.scss │ │ │ ├── component-layout-resolver.ts │ │ │ ├── extendThemeUtils.ts │ │ │ ├── hvar.ts │ │ │ ├── layout-resolver.ts │ │ │ ├── parse-layout-props.ts │ │ │ ├── StyleContext.tsx │ │ │ ├── StyleRegistry.ts │ │ │ ├── ThemeContext.tsx │ │ │ ├── ThemeProvider.tsx │ │ │ ├── themes │ │ │ │ ├── base-utils.ts │ │ │ │ ├── palette.ts │ │ │ │ ├── root.ts │ │ │ │ ├── solid.ts │ │ │ │ ├── theme-colors.ts │ │ │ │ └── xmlui.ts │ │ │ ├── themeVars.module.scss │ │ │ ├── themeVars.ts │ │ │ ├── transformThemeVars.ts │ │ │ └── utils.ts │ │ ├── utils │ │ │ ├── actionUtils.ts │ │ │ ├── audio-utils.ts │ │ │ ├── compound-utils.ts │ │ │ ├── css-utils.ts │ │ │ ├── DataLoaderQueryKeyGenerator.ts │ │ │ ├── date-utils.ts │ │ │ ├── extractParam.ts │ │ │ ├── hooks.tsx │ │ │ ├── LruCache.ts │ │ │ ├── mergeProps.ts │ │ │ ├── misc.ts │ │ │ ├── request-params.ts │ │ │ ├── statementUtils.ts │ │ │ └── treeUtils.ts │ │ └── xmlui-parser.ts │ ├── index-standalone.ts │ ├── index.scss │ ├── index.ts │ ├── language-server │ │ ├── server-common.ts │ │ ├── server-web-worker.ts │ │ ├── server.ts │ │ ├── services │ │ │ ├── common │ │ │ │ ├── docs-generation.ts │ │ │ │ ├── lsp-utils.ts │ │ │ │ ├── metadata-utils.ts │ │ │ │ └── syntax-node-utilities.ts │ │ │ ├── completion.ts │ │ │ ├── diagnostic.ts │ │ │ ├── format.ts │ │ │ └── hover.ts │ │ └── xmlui-metadata-generated.mjs │ ├── logging │ │ ├── LoggerContext.tsx │ │ ├── LoggerInitializer.tsx │ │ ├── LoggerService.ts │ │ └── xmlui.ts │ ├── logo.svg │ ├── parsers │ │ ├── common │ │ │ ├── GenericToken.ts │ │ │ ├── InputStream.ts │ │ │ └── utils.ts │ │ ├── scripting │ │ │ ├── code-behind-collect.ts │ │ │ ├── Lexer.ts │ │ │ ├── modules.ts │ │ │ ├── Parser.ts │ │ │ ├── ParserError.ts │ │ │ ├── ScriptingNodeTypes.ts │ │ │ ├── TokenTrait.ts │ │ │ ├── TokenType.ts │ │ │ └── tree-visitor.ts │ │ ├── style-parser │ │ │ ├── errors.ts │ │ │ ├── source-tree.ts │ │ │ ├── StyleInputStream.ts │ │ │ ├── StyleLexer.ts │ │ │ ├── StyleParser.ts │ │ │ └── tokens.ts │ │ └── xmlui-parser │ │ ├── CharacterCodes.ts │ │ ├── diagnostics.ts │ │ ├── fileExtensions.ts │ │ ├── index.ts │ │ ├── lint.ts │ │ ├── parser.ts │ │ ├── ParserError.ts │ │ ├── scanner.ts │ │ ├── syntax-kind.ts │ │ ├── syntax-node.ts │ │ ├── transform.ts │ │ ├── utils.ts │ │ ├── xmlui-serializer.ts │ │ └── xmlui-tree.ts │ ├── react-app-env.d.ts │ ├── syntax │ │ ├── monaco │ │ │ ├── grammar.monacoLanguage.ts │ │ │ ├── index.ts │ │ │ ├── xmlui-dark.ts │ │ │ ├── xmlui-light.ts │ │ │ └── xmluiscript.monacoLanguage.ts │ │ └── textMate │ │ ├── index.ts │ │ ├── xmlui-dark.json │ │ ├── xmlui-light.json │ │ ├── xmlui.json │ │ └── xmlui.tmLanguage.json │ ├── testing │ │ ├── assertions.ts │ │ ├── component-test-helpers.ts │ │ ├── ComponentDrivers.ts │ │ ├── drivers │ │ │ ├── DateInputDriver.ts │ │ │ ├── ModalDialogDriver.ts │ │ │ ├── NumberBoxDriver.ts │ │ │ ├── TextBoxDriver.ts │ │ │ ├── TimeInputDriver.ts │ │ │ ├── TimerDriver.ts │ │ │ └── TreeDriver.ts │ │ ├── fixtures.ts │ │ ├── infrastructure │ │ │ ├── index.html │ │ │ ├── main.tsx │ │ │ ├── public │ │ │ │ ├── mockServiceWorker.js │ │ │ │ ├── resources │ │ │ │ │ ├── bell.svg │ │ │ │ │ ├── box.svg │ │ │ │ │ ├── doc.svg │ │ │ │ │ ├── eye.svg │ │ │ │ │ ├── flower-640x480.jpg │ │ │ │ │ ├── sun.svg │ │ │ │ │ ├── test-image-100x100.jpg │ │ │ │ │ └── txt.svg │ │ │ │ └── serve.json │ │ │ └── TestBed.tsx │ │ └── themed-app-test-helpers.ts │ └── vite-env.d.ts ├── tests │ ├── components │ │ ├── CodeBlock │ │ │ └── hightlight-code.test.ts │ │ ├── playground-pattern.test.ts │ │ └── Tree │ │ └── Tree-states.test.ts │ ├── components-core │ │ ├── abstractions │ │ │ └── treeAbstractions.test.ts │ │ ├── container │ │ │ └── buildProxy.test.ts │ │ ├── interception │ │ │ ├── orderBy.test.ts │ │ │ ├── ReadOnlyCollection.test.ts │ │ │ └── request-param-converter.test.ts │ │ ├── scripts-runner │ │ │ ├── AttributeValueParser.test.ts │ │ │ ├── eval-tree-arrow-async.test.ts │ │ │ ├── eval-tree-arrow.test.ts │ │ │ ├── eval-tree-func-decl-async.test.ts │ │ │ ├── eval-tree-func-decl.test.ts │ │ │ ├── eval-tree-pre-post.test.ts │ │ │ ├── eval-tree-regression.test.ts │ │ │ ├── eval-tree.test.ts │ │ │ ├── function-proxy.test.ts │ │ │ ├── parser-regression.test.ts │ │ │ ├── process-event.test.ts │ │ │ ├── process-function.test.ts │ │ │ ├── process-implicit-context.test.ts │ │ │ ├── process-statement-asgn.test.ts │ │ │ ├── process-statement-destruct.test.ts │ │ │ ├── process-statement-regs.test.ts │ │ │ ├── process-statement-sync.test.ts │ │ │ ├── process-statement.test.ts │ │ │ ├── process-switch-sync.test.ts │ │ │ ├── process-switch.test.ts │ │ │ ├── process-try-sync.test.ts │ │ │ ├── process-try.test.ts │ │ │ └── test-helpers.ts │ │ ├── test-metadata-handler.ts │ │ ├── theming │ │ │ ├── border-segments.test.ts │ │ │ ├── component-layout.resolver.test.ts │ │ │ ├── layout-property-parser.test.ts │ │ │ ├── layout-resolver.test.ts │ │ │ ├── layout-resolver2.test.ts │ │ │ ├── layout-vp-override.test.ts │ │ │ └── padding-segments.test.ts │ │ └── utils │ │ ├── date-utils.test.ts │ │ ├── format-human-elapsed-time.test.ts │ │ └── LruCache.test.ts │ ├── language-server │ │ ├── completion.test.ts │ │ ├── format.test.ts │ │ ├── hover.test.ts │ │ └── mockData.ts │ └── parsers │ ├── common │ │ └── input-stream.test.ts │ ├── markdown │ │ └── parse-binding-expression.test.ts │ ├── parameter-parser.test.ts │ ├── paremeter-parser.test.ts │ ├── scripting │ │ ├── eval-tree-arrow.test.ts │ │ ├── eval-tree-pre-post.test.ts │ │ ├── eval-tree.test.ts │ │ ├── function-proxy.test.ts │ │ ├── lexer-literals.test.ts │ │ ├── lexer-misc.test.ts │ │ ├── module-parse.test.ts │ │ ├── parser-arrow.test.ts │ │ ├── parser-assignments.test.ts │ │ ├── parser-binary.test.ts │ │ ├── parser-destructuring.test.ts │ │ ├── parser-errors.test.ts │ │ ├── parser-expressions.test.ts │ │ ├── parser-function.test.ts │ │ ├── parser-literals.test.ts │ │ ├── parser-primary.test.ts │ │ ├── parser-regex.test.ts │ │ ├── parser-statements.test.ts │ │ ├── parser-unary.test.ts │ │ ├── process-event.test.ts │ │ ├── process-implicit-context.test.ts │ │ ├── process-statement-asgn.test.ts │ │ ├── process-statement-destruct.test.ts │ │ ├── process-statement-regs.test.ts │ │ ├── process-statement-sync.test.ts │ │ ├── process-statement.test.ts │ │ ├── process-switch-sync.test.ts │ │ ├── process-switch.test.ts │ │ ├── process-try-sync.test.ts │ │ ├── process-try.test.ts │ │ ├── simplify-expression.test.ts │ │ ├── statement-hooks.test.ts │ │ └── test-helpers.ts │ ├── style-parser │ │ ├── generateHvarChain.test.ts │ │ ├── parseHVar.test.ts │ │ ├── parser.test.ts │ │ └── tokens.test.ts │ └── xmlui │ ├── lint.test.ts │ ├── parser.test.ts │ ├── scanner.test.ts │ ├── transform.attr.test.ts │ ├── transform.circular.test.ts │ ├── transform.element.test.ts │ ├── transform.errors.test.ts │ ├── transform.escape.test.ts │ ├── transform.regression.test.ts │ ├── transform.script.test.ts │ ├── transform.test.ts │ └── xmlui.ts ├── tests-e2e │ ├── api-bound-component-regression.spec.ts │ ├── api-call-as-extracted-component.spec.ts │ ├── assign-to-object-or-array-regression.spec.ts │ ├── binding-regression.spec.ts │ ├── children-as-template-context-vars.spec.ts │ ├── compound-component.spec.ts │ ├── context-vars-regression.spec.ts │ ├── data-bindings.spec.ts │ ├── datasource-and-api-usage-in-var.spec.ts │ ├── datasource-direct-binding.spec.ts │ ├── datasource-onLoaded-regression.spec.ts │ ├── modify-array-item-regression.spec.ts │ ├── namespaces.spec.ts │ ├── push-to-array-regression.spec.ts │ ├── screen-breakpoints.spec.ts │ ├── scripting.spec.ts │ ├── state-scope-in-pages.spec.ts │ └── state-var-scopes.spec.ts ├── tsconfig.bin.json ├── tsconfig.json ├── tsconfig.node.json ├── vite.config.ts └── vitest.config.ts ``` # Files -------------------------------------------------------------------------------- /docs/content/components/Button.md: -------------------------------------------------------------------------------- ```markdown 1 | # Button [#button] 2 | 3 | `Button` is the primary interactive component for triggering actions like form submissions, navigation, opening modals, and API calls. It supports multiple visual styles and sizes to match different UI contexts and importance levels. 4 | 5 | **Key features:** 6 | - **Visual hierarchy**: Choose from `solid`, `outlined`, or `ghost` variants to indicate importance 7 | - **Theme colors**: Use `primary`, `secondary`, or `attention` colors for different action types 8 | - **Icon support**: Add icons before or after text, or create icon-only buttons 9 | - **Form integration**: Automatically handles form submission when used in forms 10 | 11 | ## Properties [#properties] 12 | 13 | ### `autoFocus` (default: false) [#autofocus-default-false] 14 | 15 | Indicates if the button should receive focus when the page loads. 16 | 17 | ### `contentPosition` (default: "center") [#contentposition-default-center] 18 | 19 | This optional value determines how the label and icon (or nested children) should be placedinside the Button component. 20 | 21 | Available values: 22 | 23 | | Value | Description | 24 | | --- | --- | 25 | | `center` | Place the content in the middle **(default)** | 26 | | `start` | Justify the content to the left (to the right if in right-to-left) | 27 | | `end` | Justify the content to the right (to the left if in right-to-left) | 28 | 29 | ```xmlui-pg copy display name="Example: content position" 30 | <App> 31 | <Button width="200px" icon="drive" label="Button" contentPosition="center" /> 32 | <Button width="200px" icon="drive" label="Button" contentPosition="start" /> 33 | <Button width="200px" icon="drive" label="Button" contentPosition="end" /> 34 | <Button width="200px" contentPosition="end"> 35 | This is a nested text 36 | </Button> 37 | </App> 38 | ``` 39 | 40 | ### `contextualLabel` [#contextuallabel] 41 | 42 | This optional value is used to provide an accessible name for the Button in the context of its usage. 43 | 44 | ### `enabled` (default: true) [#enabled-default-true] 45 | 46 | The value of this property indicates whether the button accepts actions (`true`) or does not react to them (`false`). 47 | 48 | ```xmlui-pg copy display name="Example: enabled" 49 | <App> 50 | <HStack> 51 | <Button label="I am enabled (by default)" /> 52 | <Button label="I am enabled explicitly" enabled="true" /> 53 | <Button label="I am not enabled" enabled="false" /> 54 | </HStack> 55 | </App> 56 | ``` 57 | 58 | ### `icon` [#icon] 59 | 60 | This string value denotes an icon name. The framework will render an icon if XMLUI recognizes the icon by its name. If no label is specified and an icon is set, the Button displays only that icon. 61 | 62 | ```xmlui-pg copy display name="Example: icon" 63 | <App> 64 | <HStack> 65 | <Button icon="drive" label="Let there be drive" /> 66 | <Button icon="drive" /> 67 | </HStack> 68 | </App> 69 | ``` 70 | 71 | ### `iconPosition` (default: "start") [#iconposition-default-start] 72 | 73 | This optional string determines the location of the icon in the Button. 74 | 75 | Available values: 76 | 77 | | Value | Description | 78 | | --- | --- | 79 | | `start` | The icon will appear at the start (left side when the left-to-right direction is set) **(default)** | 80 | | `end` | The icon will appear at the end (right side when the left-to-right direction is set) | 81 | 82 | ```xmlui-pg copy display name="Example: icon position" 83 | <App> 84 | <HStack> 85 | <Button icon="drive" label="Left" /> 86 | <Button icon="drive" label="Right" iconPosition="right" /> 87 | </HStack> 88 | <HStack> 89 | <Button icon="drive" label="Start" iconPosition="start" /> 90 | <Button icon="drive" label="End" iconPosition="end" /> 91 | </HStack> 92 | <HStack> 93 | <Button 94 | icon="drive" 95 | label="Start (right-to-left)" 96 | iconPosition="start" 97 | direction="rtl" /> 98 | <Button 99 | icon="drive" 100 | label="End (right-to-left)" 101 | iconPosition="end" 102 | direction="rtl" /> 103 | </HStack> 104 | </App> 105 | ``` 106 | 107 | ### `label` [#label] 108 | 109 | This property is an optional string to set a label for the Button. If no label is specified and an icon is set, the Button will modify its styling to look like a small icon button. When the Button has nested children, it will display them and ignore the value of the `label` prop. 110 | 111 | ```xmlui-pg copy display name="Example: label" 112 | <App> 113 | <Button label="I am the button label" /> 114 | <Button /> 115 | <Button label="I am the button label"> 116 | <Icon name="trash" /> 117 | I am a text nested into Button 118 | </Button> 119 | </App> 120 | ``` 121 | 122 | ### `orientation` (default: "horizontal") [#orientation-default-horizontal] 123 | 124 | This property sets the main axis along which the nested components are rendered. 125 | 126 | Available values: 127 | 128 | | Value | Description | 129 | | --- | --- | 130 | | `horizontal` | The component will fill the available space horizontally **(default)** | 131 | | `vertical` | The component will fill the available space vertically | 132 | 133 | ### `size` (default: "sm") [#size-default-sm] 134 | 135 | Sets the size of the button. 136 | 137 | Available values: 138 | 139 | | Value | Description | 140 | | --- | --- | 141 | | `xs` | Extra small | 142 | | `sm` | Small **(default)** | 143 | | `md` | Medium | 144 | | `lg` | Large | 145 | | `xl` | Extra large | 146 | 147 | ```xmlui-pg copy display name="Example: size" 148 | <App> 149 | <HStack> 150 | <Button icon="drive" label="default" /> 151 | <Button icon="drive" label="extra-small" size="xs" /> 152 | <Button icon="drive" label="small" size="sm" /> 153 | <Button icon="drive" label="medium" size="md" /> 154 | <Button icon="drive" label="large" size="lg" /> 155 | </HStack> 156 | <HStack> 157 | <Button label="default" /> 158 | <Button label="extra-small" size="xs" /> 159 | <Button label="small" size="sm" /> 160 | <Button label="medium" size="md" /> 161 | <Button label="large" size="lg" /> 162 | </HStack> 163 | </App> 164 | ``` 165 | 166 | ### `themeColor` (default: "primary") [#themecolor-default-primary] 167 | 168 | Sets the button color scheme defined in the application theme. 169 | 170 | Available values: 171 | 172 | | Value | Description | 173 | | --- | --- | 174 | | `attention` | Attention state theme color | 175 | | `primary` | Primary theme color **(default)** | 176 | | `secondary` | Secondary theme color | 177 | 178 | ```xmlui-pg copy display name="Example: theme colors" 179 | <App> 180 | <HStack> 181 | <Button label="Button" themeColor="primary" /> 182 | <Button label="Button" themeColor="secondary" /> 183 | <Button label="Button" themeColor="attention" /> 184 | </HStack> 185 | </App> 186 | ``` 187 | 188 | ### `type` (default: "button") [#type-default-button] 189 | 190 | This optional string describes how the Button appears in an HTML context. You rarely need to set this property explicitly. 191 | 192 | Available values: 193 | 194 | | Value | Description | 195 | | --- | --- | 196 | | `button` | Regular behavior that only executes logic if explicitly determined. **(default)** | 197 | | `submit` | The button submits the form data to the server. This is the default for buttons in a Form or NativeForm component. | 198 | | `reset` | Resets all the controls to their initial values. Using it is ill advised for UX reasons. | 199 | 200 | ### `variant` (default: "solid") [#variant-default-solid] 201 | 202 | The button variant determines the level of emphasis the button should possess. 203 | 204 | Available values: 205 | 206 | | Value | Description | 207 | | --- | --- | 208 | | `solid` | A button with a border and a filled background. **(default)** | 209 | | `outlined` | The button is displayed with a border and a transparent background. | 210 | | `ghost` | A button with no border and fill. Only the label is visible; the background is colored when hovered or clicked. | 211 | 212 | ```xmlui-pg copy display name="Example: variant" 213 | <App> 214 | <HStack> 215 | <Button label="default (solid)" /> 216 | <Button label="solid" variant="solid" /> 217 | <Button label="outlined" variant="outlined" /> 218 | <Button label="ghost" variant="ghost" /> 219 | </HStack> 220 | </App> 221 | ``` 222 | 223 | ## Events [#events] 224 | 225 | ### `click` [#click] 226 | 227 | This event is triggered when the Button is clicked. 228 | 229 | ```xmlui-pg copy display name="Example: click" 230 | <App> 231 | <Button label="Click me!" onClick="toast('Button clicked')" /> 232 | </App> 233 | ``` 234 | 235 | ### `gotFocus` [#gotfocus] 236 | 237 | This event is triggered when the Button has received the focus. 238 | 239 | ```xmlui-pg copy display name="Example: gotFocus" 240 | <App var.text="No event" > 241 | <HStack verticalAlignment="center" > 242 | <Button label="First, click me!" 243 | onGotFocus="text = 'Focus received'" 244 | onLostFocus="text = 'Focus lost'" /> 245 | <Text value="Then, me!"/> 246 | </HStack> 247 | <Text value="{text}" /> 248 | </App> 249 | ``` 250 | 251 | ### `lostFocus` [#lostfocus] 252 | 253 | This event is triggered when the Button has lost the focus. 254 | 255 | (See the example above) 256 | 257 | ## Exposed Methods [#exposed-methods] 258 | 259 | This component does not expose any methods. 260 | 261 | ## Styling [#styling] 262 | 263 | ### Fixed width and height [#fixed-width-and-height] 264 | 265 | Using a set of buttons with a fixed width or height is often helpful. So `Button` supports these theme variables: 266 | - `width-Button` 267 | - `height-Button` 268 | 269 | Avoid setting the `width-Button` and `height-Button` styles in the theme definition. Instead, wrap the affected button group into a `Theme` component as in the following example: 270 | 271 | ```xmlui-pg copy name="Example: Buttons with fixed width" 272 | <App> 273 | <HStack> 274 | <Theme width-Button="120px"> 275 | <Button label="Short" /> 276 | <Button label="Longer" /> 277 | <Button label="Longest" /> 278 | <Button label="Disabled" enabled="false" /> 279 | <Button label="Outlined" variant="outlined" /> 280 | </Theme> 281 | </HStack> 282 | </App> 283 | ``` 284 | 285 | ### Theme Variables [#theme-variables] 286 | 287 | | Variable | Default Value (Light) | Default Value (Dark) | 288 | | --- | --- | --- | 289 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button--disabled | $backgroundColor--disabled | $backgroundColor--disabled | 290 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention | $backgroundColor-attention | $backgroundColor-attention | 291 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention--active | $color-danger-500 | $color-danger-500 | 292 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention--hover | $color-danger-400 | $color-danger-400 | 293 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention-ghost--active | $color-danger-100 | $color-danger-100 | 294 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention-ghost--hover | $color-danger-50 | $color-danger-50 | 295 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention-outlined--active | $color-danger-100 | $color-danger-100 | 296 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention-outlined--hover | $color-danger-50 | $color-danger-50 | 297 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention-solid | *none* | *none* | 298 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention-solid--active | *none* | *none* | 299 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention-solid--hover | *none* | *none* | 300 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary | $color-primary-500 | $color-primary-500 | 301 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary--active | $color-primary-500 | $color-primary-500 | 302 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary--hover | $color-primary-400 | $color-primary-400 | 303 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary-ghost--active | $color-primary-100 | $color-primary-100 | 304 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary-ghost--hover | $color-primary-50 | $color-primary-50 | 305 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary-outlined--active | $color-primary-100 | $color-primary-100 | 306 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary-outlined--hover | $color-primary-50 | $color-primary-50 | 307 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary-solid | *none* | *none* | 308 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary-solid--active | *none* | *none* | 309 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary-solid--hover | *none* | *none* | 310 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary | $color-secondary-500 | $color-secondary-500 | 311 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary--active | $color-secondary-500 | $color-secondary-500 | 312 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary--hover | $color-secondary-400 | $color-secondary-400 | 313 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary-ghost--active | $color-secondary-100 | $color-secondary-100 | 314 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary-ghost--hover | $color-secondary-100 | $color-secondary-100 | 315 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined--active | $color-secondary-100 | $color-secondary-100 | 316 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined--hover | $color-secondary-50 | $color-secondary-50 | 317 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary-solid | *none* | *none* | 318 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary-solid--active | *none* | *none* | 319 | | [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary-solid--hover | *none* | *none* | 320 | | [borderColor](../styles-and-themes/common-units/#color)-Button--disabled | $borderColor--disabled | $borderColor--disabled | 321 | | [borderColor](../styles-and-themes/common-units/#color)-Button-attention | $color-attention | $color-attention | 322 | | [borderColor](../styles-and-themes/common-units/#color)-Button-attention-outlined | *none* | *none* | 323 | | [borderColor](../styles-and-themes/common-units/#color)-Button-attention-outlined--active | *none* | *none* | 324 | | [borderColor](../styles-and-themes/common-units/#color)-Button-attention-outlined--hover | *none* | *none* | 325 | | [borderColor](../styles-and-themes/common-units/#color)-Button-attention-solid | *none* | *none* | 326 | | [borderColor](../styles-and-themes/common-units/#color)-Button-attention-solid--active | *none* | *none* | 327 | | [borderColor](../styles-and-themes/common-units/#color)-Button-attention-solid--hover | *none* | *none* | 328 | | [borderColor](../styles-and-themes/common-units/#color)-Button-primary | $color-primary-500 | $color-primary-500 | 329 | | [borderColor](../styles-and-themes/common-units/#color)-Button-primary-outlined | $color-primary-600 | $color-primary-600 | 330 | | [borderColor](../styles-and-themes/common-units/#color)-Button-primary-outlined--active | *none* | *none* | 331 | | [borderColor](../styles-and-themes/common-units/#color)-Button-primary-outlined--hover | $color-primary-500 | $color-primary-500 | 332 | | [borderColor](../styles-and-themes/common-units/#color)-Button-primary-solid | *none* | *none* | 333 | | [borderColor](../styles-and-themes/common-units/#color)-Button-primary-solid--active | *none* | *none* | 334 | | [borderColor](../styles-and-themes/common-units/#color)-Button-primary-solid--hover | *none* | *none* | 335 | | [borderColor](../styles-and-themes/common-units/#color)-Button-secondary | $color-secondary-100 | $color-secondary-100 | 336 | | [borderColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined | *none* | *none* | 337 | | [borderColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined--active | *none* | *none* | 338 | | [borderColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined--hover | *none* | *none* | 339 | | [borderColor](../styles-and-themes/common-units/#color)-Button-secondary-solid | *none* | *none* | 340 | | [borderColor](../styles-and-themes/common-units/#color)-Button-secondary-solid--active | *none* | *none* | 341 | | [borderColor](../styles-and-themes/common-units/#color)-Button-secondary-solid--hover | *none* | *none* | 342 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button | $borderRadius | $borderRadius | 343 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-attention-ghost | *none* | *none* | 344 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-attention-outlined | *none* | *none* | 345 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-attention-solid | *none* | *none* | 346 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-primary-ghost | *none* | *none* | 347 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-primary-outlined | *none* | *none* | 348 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-primary-solid | *none* | *none* | 349 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-secondary-ghost | *none* | *none* | 350 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-secondary-outlined | *none* | *none* | 351 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-secondary-solid | *none* | *none* | 352 | | [borderStyle](../styles-and-themes/common-units/#border-style)-Button | solid | solid | 353 | | [borderStyle](../styles-and-themes/common-units/#border-style)-Button-attention-outlined | *none* | *none* | 354 | | [borderStyle](../styles-and-themes/common-units/#border-style)-Button-attention-solid | *none* | *none* | 355 | | [borderStyle](../styles-and-themes/common-units/#border-style)-Button-primary-outlined | *none* | *none* | 356 | | [borderStyle](../styles-and-themes/common-units/#border-style)-Button-primary-solid | *none* | *none* | 357 | | [borderStyle](../styles-and-themes/common-units/#border-style)-Button-secondary-outlined | *none* | *none* | 358 | | [borderStyle](../styles-and-themes/common-units/#border-style)-Button-secondary-solid | *none* | *none* | 359 | | [borderWidth](../styles-and-themes/common-units/#size)-Button | 1px | 1px | 360 | | [borderWidth](../styles-and-themes/common-units/#size)-Button-attention-ghost | *none* | *none* | 361 | | [borderWidth](../styles-and-themes/common-units/#size)-Button-attention-outlined | *none* | *none* | 362 | | [borderWidth](../styles-and-themes/common-units/#size)-Button-attention-solid | *none* | *none* | 363 | | [borderWidth](../styles-and-themes/common-units/#size)-Button-primary-ghost | *none* | *none* | 364 | | [borderWidth](../styles-and-themes/common-units/#size)-Button-primary-outlined | *none* | *none* | 365 | | [borderWidth](../styles-and-themes/common-units/#size)-Button-primary-solid | *none* | *none* | 366 | | [borderWidth](../styles-and-themes/common-units/#size)-Button-secondary-ghost | *none* | *none* | 367 | | [borderWidth](../styles-and-themes/common-units/#size)-Button-secondary-outlined | *none* | *none* | 368 | | [borderWidth](../styles-and-themes/common-units/#size)-Button-secondary-solid | *none* | *none* | 369 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-attention-outlined | *none* | *none* | 370 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-attention-solid | *none* | *none* | 371 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-attention-solid--active | *none* | *none* | 372 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-primary-outlined | *none* | *none* | 373 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-primary-solid | *none* | *none* | 374 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-primary-solid--active | *none* | *none* | 375 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-secondary-outlined | *none* | *none* | 376 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-secondary-solid | *none* | *none* | 377 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-secondary-solid--active | *none* | *none* | 378 | | [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-attention-ghost | *none* | *none* | 379 | | [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-attention-outlined | *none* | *none* | 380 | | [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-attention-solid | *none* | *none* | 381 | | [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-primary-ghost | *none* | *none* | 382 | | [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-primary-outlined | *none* | *none* | 383 | | [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-primary-solid | *none* | *none* | 384 | | [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-secondary-ghost | *none* | *none* | 385 | | [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-secondary-outlined | *none* | *none* | 386 | | [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-secondary-solid | *none* | *none* | 387 | | [fontSize](../styles-and-themes/common-units/#size)-Button | $fontSize-sm | $fontSize-sm | 388 | | [fontSize](../styles-and-themes/common-units/#size)-Button-attention-ghost | *none* | *none* | 389 | | [fontSize](../styles-and-themes/common-units/#size)-Button-attention-outlined | *none* | *none* | 390 | | [fontSize](../styles-and-themes/common-units/#size)-Button-attention-solid | *none* | *none* | 391 | | [fontSize](../styles-and-themes/common-units/#size)-Button-primary-ghost | *none* | *none* | 392 | | [fontSize](../styles-and-themes/common-units/#size)-Button-primary-outlined | *none* | *none* | 393 | | [fontSize](../styles-and-themes/common-units/#size)-Button-primary-solid | *none* | *none* | 394 | | [fontSize](../styles-and-themes/common-units/#size)-Button-secondary-ghost | *none* | *none* | 395 | | [fontSize](../styles-and-themes/common-units/#size)-Button-secondary-outlined | *none* | *none* | 396 | | [fontSize](../styles-and-themes/common-units/#size)-Button-secondary-solid | *none* | *none* | 397 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button | $fontWeight-medium | $fontWeight-medium | 398 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-attention-ghost | *none* | *none* | 399 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-attention-outlined | *none* | *none* | 400 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-attention-solid | *none* | *none* | 401 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-primary-ghost | *none* | *none* | 402 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-primary-outlined | *none* | *none* | 403 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-primary-solid | *none* | *none* | 404 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-secondary-ghost | *none* | *none* | 405 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-secondary-outlined | *none* | *none* | 406 | | [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-secondary-solid | *none* | *none* | 407 | | [height](../styles-and-themes/common-units/#size)-Button | fit-content | fit-content | 408 | | [outlineColor](../styles-and-themes/common-units/#color)-Button--focus | $outlineColor--focus | $outlineColor--focus | 409 | | [outlineColor](../styles-and-themes/common-units/#color)-Button-attention-ghost--focus | *none* | *none* | 410 | | [outlineColor](../styles-and-themes/common-units/#color)-Button-attention-outlined--focus | *none* | *none* | 411 | | [outlineColor](../styles-and-themes/common-units/#color)-Button-attention-solid--focus | *none* | *none* | 412 | | [outlineColor](../styles-and-themes/common-units/#color)-Button-primary-ghost--focus | *none* | *none* | 413 | | [outlineColor](../styles-and-themes/common-units/#color)-Button-primary-outlined--focus | *none* | *none* | 414 | | [outlineColor](../styles-and-themes/common-units/#color)-Button-primary-solid--focus | *none* | *none* | 415 | | [outlineColor](../styles-and-themes/common-units/#color)-Button-secondary-ghost--focus | *none* | *none* | 416 | | [outlineColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined--focus | *none* | *none* | 417 | | [outlineColor](../styles-and-themes/common-units/#color)-Button-secondary-solid--focus | *none* | *none* | 418 | | [outlineOffset](../styles-and-themes/common-units/#size)-Button--focus | $outlineOffset--focus | $outlineOffset--focus | 419 | | [outlineOffset](../styles-and-themes/common-units/#size)-Button-attention-ghost--focus | *none* | *none* | 420 | | [outlineOffset](../styles-and-themes/common-units/#size)-Button-attention-outlined--focus | *none* | *none* | 421 | | [outlineOffset](../styles-and-themes/common-units/#size)-Button-attention-solid--focus | *none* | *none* | 422 | | [outlineOffset](../styles-and-themes/common-units/#size)-Button-primary-ghost--focus | *none* | *none* | 423 | | [outlineOffset](../styles-and-themes/common-units/#size)-Button-primary-outlined--focus | *none* | *none* | 424 | | [outlineOffset](../styles-and-themes/common-units/#size)-Button-primary-solid--focus | *none* | *none* | 425 | | [outlineOffset](../styles-and-themes/common-units/#size)-Button-secondary-ghost--focus | *none* | *none* | 426 | | [outlineOffset](../styles-and-themes/common-units/#size)-Button-secondary-outlined--focus | *none* | *none* | 427 | | [outlineOffset](../styles-and-themes/common-units/#size)-Button-secondary-solid--focus | *none* | *none* | 428 | | [outlineStyle](../styles-and-themes/common-units/#border)-Button--focus | $outlineStyle--focus | $outlineStyle--focus | 429 | | [outlineStyle](../styles-and-themes/common-units/#border)-Button-attention-ghost--focus | *none* | *none* | 430 | | [outlineStyle](../styles-and-themes/common-units/#border)-Button-attention-outlined--focus | *none* | *none* | 431 | | [outlineStyle](../styles-and-themes/common-units/#border)-Button-attention-solid--focus | *none* | *none* | 432 | | [outlineStyle](../styles-and-themes/common-units/#border)-Button-primary-ghost--focus | *none* | *none* | 433 | | [outlineStyle](../styles-and-themes/common-units/#border)-Button-primary-outlined--focus | *none* | *none* | 434 | | [outlineStyle](../styles-and-themes/common-units/#border)-Button-primary-solid--focus | *none* | *none* | 435 | | [outlineStyle](../styles-and-themes/common-units/#border)-Button-secondary-ghost--focus | *none* | *none* | 436 | | [outlineStyle](../styles-and-themes/common-units/#border)-Button-secondary-outlined--focus | *none* | *none* | 437 | | [outlineStyle](../styles-and-themes/common-units/#border)-Button-secondary-solid--focus | *none* | *none* | 438 | | [outlineWidth](../styles-and-themes/common-units/#size)-Button--focus | $outlineWidth--focus | $outlineWidth--focus | 439 | | [outlineWidth](../styles-and-themes/common-units/#size)-Button-attention-ghost--focus | *none* | *none* | 440 | | [outlineWidth](../styles-and-themes/common-units/#size)-Button-attention-outlined--focus | *none* | *none* | 441 | | [outlineWidth](../styles-and-themes/common-units/#size)-Button-attention-solid--focus | *none* | *none* | 442 | | [outlineWidth](../styles-and-themes/common-units/#size)-Button-primary-ghost--focus | *none* | *none* | 443 | | [outlineWidth](../styles-and-themes/common-units/#size)-Button-primary-outlined--focus | *none* | *none* | 444 | | [outlineWidth](../styles-and-themes/common-units/#size)-Button-primary-solid--focus | *none* | *none* | 445 | | [outlineWidth](../styles-and-themes/common-units/#size)-Button-secondary-ghost--focus | *none* | *none* | 446 | | [outlineWidth](../styles-and-themes/common-units/#size)-Button-secondary-outlined--focus | *none* | *none* | 447 | | [outlineWidth](../styles-and-themes/common-units/#size)-Button-secondary-solid--focus | *none* | *none* | 448 | | [padding](../styles-and-themes/common-units/#size)-Button | *none* | *none* | 449 | | [padding](../styles-and-themes/common-units/#size)-Button-lg | *none* | *none* | 450 | | [padding](../styles-and-themes/common-units/#size)-Button-md | *none* | *none* | 451 | | [padding](../styles-and-themes/common-units/#size)-Button-sm | *none* | *none* | 452 | | [padding](../styles-and-themes/common-units/#size)-Button-xs | *none* | *none* | 453 | | [paddingBottom](../styles-and-themes/common-units/#size)-Button | *none* | *none* | 454 | | [paddingBottom](../styles-and-themes/common-units/#size)-Button-lg | *none* | *none* | 455 | | [paddingBottom](../styles-and-themes/common-units/#size)-Button-md | *none* | *none* | 456 | | [paddingBottom](../styles-and-themes/common-units/#size)-Button-sm | *none* | *none* | 457 | | [paddingBottom](../styles-and-themes/common-units/#size)-Button-xs | *none* | *none* | 458 | | [paddingHorizontal](../styles-and-themes/common-units/#size)-Button | *none* | *none* | 459 | | [paddingHorizontal](../styles-and-themes/common-units/#size)-Button-lg | $space-5 | $space-5 | 460 | | [paddingHorizontal](../styles-and-themes/common-units/#size)-Button-md | $space-4 | $space-4 | 461 | | [paddingHorizontal](../styles-and-themes/common-units/#size)-Button-sm | $space-4 | $space-4 | 462 | | [paddingHorizontal](../styles-and-themes/common-units/#size)-Button-xs | $space-1 | $space-1 | 463 | | [paddingLeft](../styles-and-themes/common-units/#size)-Button | *none* | *none* | 464 | | [paddingLeft](../styles-and-themes/common-units/#size)-Button-lg | *none* | *none* | 465 | | [paddingLeft](../styles-and-themes/common-units/#size)-Button-md | *none* | *none* | 466 | | [paddingLeft](../styles-and-themes/common-units/#size)-Button-sm | *none* | *none* | 467 | | [paddingLeft](../styles-and-themes/common-units/#size)-Button-xs | *none* | *none* | 468 | | [paddingRight](../styles-and-themes/common-units/#size)-Button | *none* | *none* | 469 | | [paddingRight](../styles-and-themes/common-units/#size)-Button-lg | *none* | *none* | 470 | | [paddingRight](../styles-and-themes/common-units/#size)-Button-md | *none* | *none* | 471 | | [paddingRight](../styles-and-themes/common-units/#size)-Button-sm | *none* | *none* | 472 | | [paddingRight](../styles-and-themes/common-units/#size)-Button-xs | *none* | *none* | 473 | | [paddingTop](../styles-and-themes/common-units/#size)-Button | *none* | *none* | 474 | | [paddingTop](../styles-and-themes/common-units/#size)-Button-lg | *none* | *none* | 475 | | [paddingTop](../styles-and-themes/common-units/#size)-Button-md | *none* | *none* | 476 | | [paddingTop](../styles-and-themes/common-units/#size)-Button-sm | *none* | *none* | 477 | | [paddingTop](../styles-and-themes/common-units/#size)-Button-xs | *none* | *none* | 478 | | [paddingVertical](../styles-and-themes/common-units/#size)-Button | *none* | *none* | 479 | | [paddingVertical](../styles-and-themes/common-units/#size)-Button-lg | $space-4 | $space-4 | 480 | | [paddingVertical](../styles-and-themes/common-units/#size)-Button-md | $space-3 | $space-3 | 481 | | [paddingVertical](../styles-and-themes/common-units/#size)-Button-sm | $space-2 | $space-2 | 482 | | [paddingVertical](../styles-and-themes/common-units/#size)-Button-xs | $space-0_5 | $space-0_5 | 483 | | [textColor](../styles-and-themes/common-units/#color)-Button | $color-surface-950 | $color-surface-950 | 484 | | [textColor](../styles-and-themes/common-units/#color)-Button--disabled | $textColor--disabled | $textColor--disabled | 485 | | [textColor](../styles-and-themes/common-units/#color)-Button-attention-ghost | *none* | *none* | 486 | | [textColor](../styles-and-themes/common-units/#color)-Button-attention-ghost--active | *none* | *none* | 487 | | [textColor](../styles-and-themes/common-units/#color)-Button-attention-ghost--hover | *none* | *none* | 488 | | [textColor](../styles-and-themes/common-units/#color)-Button-attention-outlined | *none* | *none* | 489 | | [textColor](../styles-and-themes/common-units/#color)-Button-attention-outlined--active | *none* | *none* | 490 | | [textColor](../styles-and-themes/common-units/#color)-Button-attention-outlined--hover | *none* | *none* | 491 | | [textColor](../styles-and-themes/common-units/#color)-Button-attention-solid | *none* | *none* | 492 | | [textColor](../styles-and-themes/common-units/#color)-Button-attention-solid--active | *none* | *none* | 493 | | [textColor](../styles-and-themes/common-units/#color)-Button-attention-solid--hover | *none* | *none* | 494 | | [textColor](../styles-and-themes/common-units/#color)-Button-primary-ghost | *none* | *none* | 495 | | [textColor](../styles-and-themes/common-units/#color)-Button-primary-ghost--active | *none* | *none* | 496 | | [textColor](../styles-and-themes/common-units/#color)-Button-primary-ghost--hover | *none* | *none* | 497 | | [textColor](../styles-and-themes/common-units/#color)-Button-primary-outlined | $color-primary-900 | $color-primary-900 | 498 | | [textColor](../styles-and-themes/common-units/#color)-Button-primary-outlined--active | $color-primary-900 | $color-primary-900 | 499 | | [textColor](../styles-and-themes/common-units/#color)-Button-primary-outlined--hover | $color-primary-950 | $color-primary-950 | 500 | | [textColor](../styles-and-themes/common-units/#color)-Button-primary-solid | *none* | *none* | 501 | | [textColor](../styles-and-themes/common-units/#color)-Button-primary-solid--active | *none* | *none* | 502 | | [textColor](../styles-and-themes/common-units/#color)-Button-primary-solid--hover | *none* | *none* | 503 | | [textColor](../styles-and-themes/common-units/#color)-Button-secondary-ghost | *none* | *none* | 504 | | [textColor](../styles-and-themes/common-units/#color)-Button-secondary-ghost--active | *none* | *none* | 505 | | [textColor](../styles-and-themes/common-units/#color)-Button-secondary-ghost--hover | *none* | *none* | 506 | | [textColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined | *none* | *none* | 507 | | [textColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined--active | *none* | *none* | 508 | | [textColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined--hover | *none* | *none* | 509 | | [textColor](../styles-and-themes/common-units/#color)-Button-secondary-solid | *none* | *none* | 510 | | [textColor](../styles-and-themes/common-units/#color)-Button-secondary-solid--active | *none* | *none* | 511 | | [textColor](../styles-and-themes/common-units/#color)-Button-secondary-solid--hover | *none* | *none* | 512 | | [textColor](../styles-and-themes/common-units/#color)-Button-solid | $const-color-surface-50 | $const-color-surface-50 | 513 | | [width](../styles-and-themes/common-units/#size)-Button | fit-content | fit-content | 514 | ``` -------------------------------------------------------------------------------- /xmlui/src/components/TableOfContents/TableOfContents.spec.ts: -------------------------------------------------------------------------------- ```typescript 1 | import { SKIP_REASON } from "../../testing/component-test-helpers"; 2 | import { expect, test } from "../../testing/fixtures"; 3 | 4 | // ============================================================================= 5 | // BASIC FUNCTIONALITY TESTS 6 | // ============================================================================= 7 | 8 | test.describe("Basic Functionality", () => { 9 | test("renders table of contents links with headings", async ({ initTestBed, page }) => { 10 | await page.setViewportSize({ height: 600, width: 800 }); 11 | await initTestBed(` 12 | <Page> 13 | <HStack> 14 | <VStack gap="800px"> 15 | <Heading value="First Heading" /> 16 | <Heading value="Second Heading" /> 17 | <Heading value="Third Heading" /> 18 | bottom of the page text 19 | </VStack> 20 | <TableOfContents /> 21 | </HStack> 22 | </Page>`); 23 | 24 | const tocLinks = page.getByRole("link", { name: /Heading/ }); 25 | await expect(tocLinks).toHaveCount(3); 26 | await expect(page.getByRole("link", { name: "First Heading" })).toBeVisible(); 27 | await expect(page.getByRole("link", { name: "Second Heading" })).toBeVisible(); 28 | await expect(page.getByRole("link", { name: "Third Heading" })).toBeVisible(); 29 | }); 30 | 31 | test("renders table of contents with bookmarks", async ({ initTestBed, page }) => { 32 | await page.setViewportSize({ height: 600, width: 800 }); 33 | await initTestBed(` 34 | <Page> 35 | <HStack> 36 | <VStack gap="800px"> 37 | <Bookmark id="section1" title="Section One" level="{2}"> 38 | section one content 39 | </Bookmark> 40 | <Bookmark id="section2" title="Section Two" level="{3}"> 41 | section two content 42 | </Bookmark> 43 | bottom of the page text 44 | </VStack> 45 | <TableOfContents /> 46 | </HStack> 47 | </Page> 48 | `); 49 | 50 | const tocLinks = page.getByRole("link"); 51 | await expect(tocLinks).toHaveCount(2); 52 | await expect(page.getByRole("link", { name: "Section One" })).toBeVisible(); 53 | await expect(page.getByRole("link", { name: "Section Two" })).toBeVisible(); 54 | }); 55 | 56 | test("renders table of contents with mixed headings and bookmarks", async ({ 57 | initTestBed, 58 | page, 59 | }) => { 60 | await page.setViewportSize({ height: 600, width: 800 }); 61 | await initTestBed(` 62 | <Page> 63 | <HStack> 64 | <VStack gap="800px"> 65 | <Heading level="h1" value="Main Title" /> 66 | <Bookmark id="intro" title="Introduction" level="{2}"> 67 | introduction content 68 | </Bookmark> 69 | <Heading level="h2" value="Chapter One" /> 70 | <Bookmark id="summary" title="Summary" level="{3}"> 71 | summary content 72 | </Bookmark> 73 | bottom of the page text 74 | </VStack> 75 | <TableOfContents /> 76 | </HStack> 77 | </Page> 78 | `); 79 | 80 | const tocLinks = page.getByRole("link"); 81 | await expect(tocLinks).toHaveCount(4); 82 | await expect(page.getByRole("link", { name: "Main Title" })).toBeVisible(); 83 | await expect(page.getByRole("link", { name: "Introduction" })).toBeVisible(); 84 | await expect(page.getByRole("link", { name: "Chapter One" })).toBeVisible(); 85 | await expect(page.getByRole("link", { name: "Summary" })).toBeVisible(); 86 | }); 87 | 88 | // ============================================================================= 89 | // DOCUMENTATION USAGE PATTERNS 90 | // ============================================================================= 91 | 92 | test.describe("Documentation Usage Patterns", () => { 93 | test("navigates to headings when clicked", async ({ initTestBed, page }) => { 94 | await page.setViewportSize({ height: 600, width: 800 }); 95 | await initTestBed(` 96 | <Page> 97 | <HStack> 98 | <VStack gap="800px"> 99 | <Heading level="h2" value="Section A" /> 100 | <Heading level="h2" value="Section B" /> 101 | <Heading level="h2" value="Section C" /> 102 | bottom of the page text 103 | </VStack> 104 | <TableOfContents /> 105 | </HStack> 106 | </Page> 107 | `); 108 | 109 | const sectionA = page.getByRole("heading", { name: "Section A" }); 110 | const sectionB = page.getByRole("heading", { name: "Section B" }); 111 | const sectionC = page.getByRole("heading", { name: "Section C" }); 112 | 113 | // Initially, Section A should be visible 114 | await expect(sectionA).toBeInViewport(); 115 | await expect(sectionB).not.toBeInViewport(); 116 | await expect(sectionC).not.toBeInViewport(); 117 | 118 | // Click on Section B in TOC 119 | const sectionBLink = page.getByRole("link", { name: "Section B" }); 120 | await sectionBLink.click(); 121 | await expect(sectionB).toBeInViewport(); 122 | 123 | // Click on Section C in TOC 124 | const sectionCLink = page.getByRole("link", { name: "Section C" }); 125 | await sectionCLink.click(); 126 | await expect(sectionB).not.toBeInViewport(); 127 | await expect(sectionC).toBeInViewport(); 128 | }); 129 | 130 | test("navigates to bookmarks when clicked", async ({ initTestBed, page }) => { 131 | await page.setViewportSize({ height: 600, width: 800 }); 132 | await initTestBed(` 133 | <Page> 134 | <HStack> 135 | <VStack gap="800px"> 136 | <Bookmark id="bookmark-a" title="Bookmark A" level="{2}"> 137 | bookmark a content 138 | </Bookmark> 139 | <Bookmark id="bookmark-b" title="Bookmark B" level="{2}"> 140 | bookmark b content 141 | </Bookmark> 142 | <Bookmark id="bookmark-c" title="Bookmark C" level="{2}"> 143 | bookmark c content 144 | </Bookmark> 145 | bottom of the page text 146 | </VStack> 147 | <TableOfContents /> 148 | </HStack> 149 | </Page> 150 | `); 151 | 152 | const contentA = page.getByText("bookmark a content"); 153 | const contentB = page.getByText("bookmark b content"); 154 | const contentC = page.getByText("bookmark c content"); 155 | 156 | // Initially, Bookmark A should be visible 157 | await expect(contentA).toBeInViewport(); 158 | await expect(contentB).not.toBeInViewport(); 159 | await expect(contentC).not.toBeInViewport(); 160 | 161 | // Click on Bookmark B in TOC 162 | const bookmarkBLink = page.getByRole("link", { name: "Bookmark B" }); 163 | await bookmarkBLink.click(); 164 | await expect(contentB).toBeInViewport(); 165 | 166 | // Click on Bookmark C in TOC 167 | const bookmarkCLink = page.getByRole("link", { name: "Bookmark C" }); 168 | await bookmarkCLink.click(); 169 | await expect(contentC).toBeInViewport(); 170 | }); 171 | 172 | test("shows active item in table of contents", async ({ initTestBed, page }) => { 173 | await page.setViewportSize({ height: 600, width: 800 }); 174 | await initTestBed(` 175 | <Page> 176 | <HStack> 177 | <VStack gap="800px"> 178 | <Heading level="h2" value="First Section" /> 179 | <Heading level="h2" value="Second Section" /> 180 | <Heading level="h2" value="Thirsd Section" /> 181 | bottom of the page text 182 | </VStack> 183 | <TableOfContents /> 184 | </HStack> 185 | </Page> 186 | `); 187 | 188 | const secondHeading = page.getByRole("heading", { name: "Second Section" }); 189 | 190 | // Click on second section 191 | const secondLink = page.getByRole("link", { name: "Second Section" }); 192 | await secondLink.click(); 193 | await expect(secondHeading).toBeInViewport(); 194 | 195 | // Check if the active item has the correct class or styling 196 | const activeItem = page.locator("[aria-current='page']"); 197 | await expect(activeItem).toHaveText("Second Section"); 198 | }); 199 | }); 200 | 201 | // ============================================================================= 202 | // PROPERTY TESTS 203 | // ============================================================================= 204 | 205 | test.describe("maxHeadingLevel property", () => { 206 | test("limits headings to specified level", async ({ initTestBed, page }) => { 207 | await page.setViewportSize({ height: 600, width: 800 }); 208 | await initTestBed(` 209 | <Page> 210 | <HStack> 211 | <VStack gap="800px"> 212 | <Heading level="h1" value="H1 Title" /> 213 | <Heading level="h2" value="H2 Title" /> 214 | <Heading level="h3" value="H3 Title" /> 215 | <Heading level="h4" value="H4 Title" /> 216 | <Heading level="h5" value="H5 Title" /> 217 | <Heading level="h6" value="H6 Title" /> 218 | bottom of the page text 219 | </VStack> 220 | <TableOfContents maxHeadingLevel="{3}" /> 221 | </HStack> 222 | </Page> 223 | `); 224 | 225 | // Should show H1, H2, H3 but not H4, H5, H6 226 | await expect(page.getByRole("link", { name: "H1 Title" })).toBeVisible(); 227 | await expect(page.getByRole("link", { name: "H2 Title" })).toBeVisible(); 228 | await expect(page.getByRole("link", { name: "H3 Title" })).toBeVisible(); 229 | await expect(page.getByRole("link", { name: "H4 Title" })).not.toBeVisible(); 230 | await expect(page.getByRole("link", { name: "H5 Title" })).not.toBeVisible(); 231 | await expect(page.getByRole("link", { name: "H6 Title" })).not.toBeVisible(); 232 | }); 233 | 234 | test("shows only H1 when maxHeadingLevel is 1", async ({ initTestBed, page }) => { 235 | await page.setViewportSize({ height: 600, width: 800 }); 236 | await initTestBed(` 237 | <Page> 238 | <HStack> 239 | <VStack gap="800px"> 240 | <Heading level="h1" value="Only H1" /> 241 | <Heading level="h2" value="Hidden H2" /> 242 | <Heading level="h3" value="Hidden H3" /> 243 | bottom of the page text 244 | </VStack> 245 | <TableOfContents maxHeadingLevel="{1}" /> 246 | </HStack> 247 | </Page> 248 | `); 249 | 250 | await expect(page.getByRole("link", { name: "Only H1" })).toBeVisible(); 251 | await expect(page.getByRole("link", { name: "Hidden H2" })).not.toBeVisible(); 252 | await expect(page.getByRole("link", { name: "Hidden H3" })).not.toBeVisible(); 253 | }); 254 | 255 | test("limits bookmarks to specified level", async ({ initTestBed, page }) => { 256 | await page.setViewportSize({ height: 600, width: 800 }); 257 | await initTestBed(` 258 | <Page> 259 | <HStack> 260 | <VStack gap="800px"> 261 | <Bookmark id="levelNone" title="Bookmark level none"> 262 | content no level 263 | </Bookmark> 264 | <Bookmark id="level1" title="Level 1 Bookmark" level="{1}"> 265 | level 1 content 266 | </Bookmark> 267 | <Bookmark id="level2" title="Level 2 Bookmark" level="{2}"> 268 | level 2 content 269 | </Bookmark> 270 | <Bookmark id="level3" title="Level 3 Bookmark" level="{3}"> 271 | level 3 content 272 | </Bookmark> 273 | <Bookmark id="level4" title="Level 4 Bookmark" level="{4}"> 274 | level 4 content 275 | </Bookmark> 276 | bottom of the page text 277 | </VStack> 278 | <TableOfContents maxHeadingLevel="{2}" /> 279 | </HStack> 280 | </Page> 281 | `); 282 | 283 | await expect(page.getByRole("link", { name: "Bookmark level none" })).toBeVisible(); 284 | await expect(page.getByRole("link", { name: "Level 1 Bookmark" })).toBeVisible(); 285 | await expect(page.getByRole("link", { name: "Level 2 Bookmark" })).toBeVisible(); 286 | await expect(page.getByRole("link", { name: "Level 3 Bookmark" })).not.toBeVisible(); 287 | await expect(page.getByRole("link", { name: "Level 4 Bookmark" })).not.toBeVisible(); 288 | }); 289 | }); 290 | 291 | test.describe("omitH1 property", () => { 292 | test("excludes H1 headings when omitH1 is true", async ({ initTestBed, page }) => { 293 | await page.setViewportSize({ height: 600, width: 800 }); 294 | await initTestBed(` 295 | <Page> 296 | <HStack> 297 | <VStack gap="800px"> 298 | <Heading level="h1" value="H1 Title" /> 299 | <Heading level="h2" value="H2 Title" /> 300 | <Heading level="h3" value="H3 Title" /> 301 | bottom of the page text 302 | </VStack> 303 | <TableOfContents omitH1="{true}" /> 304 | </HStack> 305 | </Page> 306 | `); 307 | 308 | await expect(page.getByRole("link", { name: "H1 Title" })).not.toBeVisible(); 309 | await expect(page.getByRole("link", { name: "H2 Title" })).toBeVisible(); 310 | await expect(page.getByRole("link", { name: "H3 Title" })).toBeVisible(); 311 | }); 312 | 313 | test("includes H1 headings when omitH1 is false", async ({ initTestBed, page }) => { 314 | await page.setViewportSize({ height: 600, width: 800 }); 315 | await initTestBed(` 316 | <Page> 317 | <HStack> 318 | <VStack gap="800px"> 319 | <Heading level="h1" value="Page Title" /> 320 | <Heading level="h2" value="Section Title" /> 321 | bottom of the page text 322 | </VStack> 323 | <TableOfContents omitH1="{false}" /> 324 | </HStack> 325 | </Page> 326 | `); 327 | 328 | await expect(page.getByRole("link", { name: "Page Title" })).toBeVisible(); 329 | await expect(page.getByRole("link", { name: "Section Title" })).toBeVisible(); 330 | }); 331 | 332 | test("excludes level 1 bookmarks when omitH1 is true", async ({ initTestBed, page }) => { 333 | await page.setViewportSize({ height: 600, width: 800 }); 334 | await initTestBed(` 335 | <Page> 336 | <HStack> 337 | <VStack gap="800px"> 338 | <Bookmark id="no-lvl" title="No level section"> 339 | no level section content 340 | </Bookmark> 341 | <Bookmark id="main" title="Main Section" level="{1}"> 342 | main section content 343 | </Bookmark> 344 | <Bookmark id="sub" title="Subsection" level="{2}"> 345 | subsection content 346 | </Bookmark> 347 | bottom of the page text 348 | </VStack> 349 | <TableOfContents omitH1="{true}" /> 350 | </HStack> 351 | </Page> 352 | `); 353 | 354 | await expect(page.getByRole("link", { name: "No level section" })).not.toBeVisible(); 355 | await expect(page.getByRole("link", { name: "Main Section" })).not.toBeVisible(); 356 | await expect(page.getByRole("link", { name: "Subsection" })).toBeVisible(); 357 | }); 358 | }); 359 | 360 | test.describe("smoothScrolling property", () => { 361 | test("applies smooth scrolling when enabled", async ({ initTestBed, page }) => { 362 | await page.setViewportSize({ height: 600, width: 800 }); 363 | await initTestBed(` 364 | <Page> 365 | <HStack> 366 | <VStack gap="800px"> 367 | <Heading level="h2" value="Smooth Section" /> 368 | <Heading level="h2" value="Another Section" /> 369 | bottom of the page text 370 | </VStack> 371 | <TableOfContents smoothScrolling="{true}" /> 372 | </HStack> 373 | </Page> 374 | `); 375 | 376 | const secondHeading = page.getByRole("heading", { name: "Another Section" }); 377 | const link = page.getByRole("link", { name: "Another Section" }); 378 | 379 | await link.click(); 380 | await expect(secondHeading).toBeInViewport(); 381 | }); 382 | 383 | test("works without smooth scrolling when disabled", async ({ initTestBed, page }) => { 384 | await page.setViewportSize({ height: 600, width: 800 }); 385 | await initTestBed(` 386 | <Page> 387 | <HStack> 388 | <VStack gap="800px"> 389 | <Heading level="h2" value="Regular Section" /> 390 | <Heading level="h2" value="Another Section" /> 391 | bottom of the page text 392 | </VStack> 393 | <TableOfContents smoothScrolling="{false}" /> 394 | </HStack> 395 | </Page> 396 | `); 397 | 398 | const secondHeading = page.getByRole("heading", { name: "Another Section" }); 399 | const link = page.getByRole("link", { name: "Another Section" }); 400 | 401 | await link.click(); 402 | await expect(secondHeading).toBeInViewport(); 403 | }); 404 | }); 405 | 406 | // ============================================================================= 407 | // ID PROPERTY TESTS 408 | // ============================================================================= 409 | }); 410 | 411 | // ============================================================================= 412 | // ACCESSIBILITY TESTS 413 | // ============================================================================= 414 | 415 | test.describe("Accessibility", () => { 416 | test("supports keyboard navigation", async ({ initTestBed, page }) => { 417 | await page.setViewportSize({ height: 600, width: 800 }); 418 | await initTestBed(` 419 | <Page> 420 | <HStack> 421 | <VStack gap="800px"> 422 | <Heading level="h2" value="First Section" /> 423 | <Heading level="h2" value="Second Section" /> 424 | bottom of the page text 425 | </VStack> 426 | <TableOfContents /> 427 | </HStack> 428 | </Page> 429 | `); 430 | 431 | const nav = page.getByRole("navigation"); 432 | await nav.focus(); 433 | 434 | // Tab to first link 435 | await page.keyboard.press("Tab"); 436 | const firstLink = page.getByRole("link", { name: "First Section" }); 437 | await expect(firstLink).toBeFocused(); 438 | 439 | // Tab to second link 440 | await page.keyboard.press("Tab"); 441 | const secondLink = page.getByRole("link", { name: "Second Section" }); 442 | await expect(secondLink).toBeFocused(); 443 | 444 | // Enter should activate the link 445 | const secondHeading = page.getByRole("heading", { name: "Second Section" }); 446 | await page.keyboard.press("Enter"); 447 | await expect(secondHeading).toBeInViewport(); 448 | }); 449 | }); 450 | 451 | // ============================================================================= 452 | // THEME VARIABLES TESTS 453 | // ============================================================================= 454 | 455 | test.describe("Theme Variables", () => { 456 | test("applies container theme variables", async ({ initTestBed, page }) => { 457 | await page.setViewportSize({ height: 600, width: 800 }); 458 | await initTestBed( 459 | ` 460 | <Page> 461 | <HStack> 462 | <VStack> 463 | <Heading level="h1" value="Test Heading" /> 464 | bottom of the page text 465 | </VStack> 466 | <TableOfContents /> 467 | </HStack> 468 | </Page> 469 | `, 470 | { 471 | testThemeVars: { 472 | "backgroundColor-TableOfContents": "rgb(255, 0, 0)", 473 | "width-TableOfContents": "300px", 474 | "height-TableOfContents": "400px", 475 | "padding-TableOfContents": "20px", 476 | "borderWidth-TableOfContents": "2px", 477 | "borderColor-TableOfContents": "rgb(0, 255, 0)", 478 | "borderStyle-TableOfContents": "solid", 479 | }, 480 | }, 481 | ); 482 | 483 | const tocContainer = page.getByRole("navigation"); 484 | 485 | await Promise.all([ 486 | expect(tocContainer).toHaveCSS("background-color", "rgb(255, 0, 0)"), 487 | expect(tocContainer).toHaveCSS("width", "300px"), 488 | expect(tocContainer).toHaveCSS("height", "400px"), 489 | expect(tocContainer).toHaveCSS("padding", "20px"), 490 | expect(tocContainer).toHaveCSS("border-width", "2px"), 491 | expect(tocContainer).toHaveCSS("border-color", "rgb(0, 255, 0)"), 492 | expect(tocContainer).toHaveCSS("border-style", "solid"), 493 | ]); 494 | }); 495 | 496 | test("applies item base theme variables", async ({ initTestBed, page }) => { 497 | await page.setViewportSize({ height: 600, width: 800 }); 498 | await initTestBed( 499 | ` 500 | <Page> 501 | <HStack> 502 | <VStack> 503 | <Heading level="h2" value="Test Heading" /> 504 | bottom of the page text 505 | </VStack> 506 | <TableOfContents /> 507 | </HStack> 508 | </Page> 509 | `, 510 | { 511 | testThemeVars: { 512 | "textColor-TableOfContentsItem": "rgb(255, 0, 0)", 513 | "fontSize-TableOfContentsItem": "18px", 514 | "fontWeight-TableOfContentsItem": "700", 515 | "padding-TableOfContentsItem": "25px", 516 | //This theme var below should not be needed, but currently is 517 | "padding-TableOfContentsItem-level-2": "25px", 518 | }, 519 | }, 520 | ); 521 | 522 | const tocLink = page.getByRole("link", { name: "Test Heading" }); 523 | await Promise.all([ 524 | expect(tocLink).toHaveCSS("color", "rgb(255, 0, 0)"), 525 | expect(tocLink).toHaveCSS("font-size", "18px"), 526 | expect(tocLink).toHaveCSS("font-weight", "700"), 527 | expect(tocLink).toHaveCSS("padding", "25px"), 528 | ]); 529 | }); 530 | 531 | test("applies level-specific theme variables for H1", async ({ initTestBed, page }) => { 532 | await initTestBed( 533 | ` 534 | <Page> 535 | <HStack> 536 | <VStack> 537 | <Heading level="h1" value="Level 1 Heading" /> 538 | <Heading level="h1" value="Active Heading " /> 539 | </VStack> 540 | <TableOfContents /> 541 | </HStack> 542 | </Page> 543 | `, 544 | { 545 | testThemeVars: { 546 | "padding-TableOfContentsItem-level-1": "25px", 547 | "fontSize-TableOfContentsItem-level-1": "22px", 548 | "fontWeight-TableOfContentsItem-level-1": "800", 549 | "textColor-TableOfContentsItem-level-1": "rgb(0, 0, 255)", 550 | }, 551 | }, 552 | ); 553 | 554 | const h1Link = page.getByRole("link", { name: "Level 1 Heading" }); 555 | 556 | await Promise.all([ 557 | expect(h1Link).toHaveCSS("padding", "25px"), 558 | expect(h1Link).toHaveCSS("font-size", "22px"), 559 | expect(h1Link).toHaveCSS("font-weight", "800"), 560 | expect(h1Link).toHaveCSS("color", "rgb(0, 0, 255)"), 561 | ]); 562 | }); 563 | 564 | test("applies level-specific theme variables for H2", async ({ initTestBed, page }) => { 565 | await initTestBed( 566 | ` 567 | <Page> 568 | <HStack> 569 | <VStack> 570 | <Heading level="h2" value="Level 2 Heading" /> 571 | <Heading level="h2" value="Active heading" /> 572 | </VStack> 573 | <TableOfContents /> 574 | </HStack> 575 | </Page> 576 | `, 577 | { 578 | testThemeVars: { 579 | "padding-TableOfContentsItem-level-2": "20px", 580 | "fontSize-TableOfContentsItem-level-2": "20px", 581 | "fontWeight-TableOfContentsItem-level-2": "600", 582 | "textColor-TableOfContentsItem-level-2": "rgb(255, 255, 0)", 583 | }, 584 | }, 585 | ); 586 | 587 | const h2Link = page.getByRole("link", { name: "Level 2 Heading" }); 588 | 589 | await Promise.all([ 590 | expect(h2Link).toHaveCSS("padding", "20px"), 591 | expect(h2Link).toHaveCSS("font-size", "20px"), 592 | expect(h2Link).toHaveCSS("font-weight", "600"), 593 | expect(h2Link).toHaveCSS("color", "rgb(255, 255, 0)"), 594 | ]); 595 | }); 596 | 597 | test("applies level-specific theme variables for H6", async ({ initTestBed, page }) => { 598 | await initTestBed( 599 | ` 600 | <Page> 601 | <HStack> 602 | <VStack> 603 | <Heading level="h6" value="Level 6 Heading" /> 604 | bottom of the page text 605 | </VStack> 606 | <TableOfContents /> 607 | </HStack> 608 | </Page> 609 | `, 610 | { 611 | testThemeVars: { 612 | "padding-TableOfContentsItem-level-6": "8px", 613 | "fontSize-TableOfContentsItem-level-6": "12px", 614 | "fontWeight-TableOfContentsItem-level-6": "400", 615 | "fontStyle-TableOfContentsItem-level-6": "italic", 616 | }, 617 | }, 618 | ); 619 | 620 | const h6Link = page.getByRole("link", { name: "Level 6 Heading" }); 621 | 622 | await Promise.all([ 623 | expect(h6Link).toHaveCSS("padding", "8px"), 624 | expect(h6Link).toHaveCSS("font-size", "12px"), 625 | expect(h6Link).toHaveCSS("font-weight", "400"), 626 | expect(h6Link).toHaveCSS("font-style", "italic"), 627 | ]); 628 | }); 629 | 630 | test("applies hover state theme variables", async ({ initTestBed, page }) => { 631 | await page.setViewportSize({ height: 600, width: 800 }); 632 | await initTestBed( 633 | ` 634 | <Page> 635 | <HStack> 636 | <VStack> 637 | <Heading level="h2" value="First Heading" /> 638 | <Heading level="h2" value="Hover Test" /> 639 | bottom of the page text 640 | </VStack> 641 | <TableOfContents /> 642 | </HStack> 643 | </Page> 644 | `, 645 | { 646 | testThemeVars: { 647 | "backgroundColor-TableOfContentsItem--hover": "rgb(200, 200, 200)", 648 | "textColor-TableOfContentsItem--hover": "rgb(100, 100, 100)", 649 | "fontWeight-TableOfContentsItem--hover": "900", 650 | }, 651 | }, 652 | ); 653 | 654 | // First click on the second heading to make it active 655 | const secondHeading = page.getByRole("link", { name: "Hover Test" }); 656 | await secondHeading.click(); 657 | 658 | // Now hover over the first heading (which should not be active) 659 | const firstHeading = page.getByRole("link", { name: "First Heading" }); 660 | const listItem = firstHeading.locator(".."); 661 | 662 | await firstHeading.hover(); 663 | 664 | await Promise.all([ 665 | expect(listItem).toHaveCSS("background-color", "rgb(200, 200, 200)"), 666 | expect(firstHeading).toHaveCSS("color", "rgb(100, 100, 100)"), 667 | expect(firstHeading).toHaveCSS("font-weight", "900"), 668 | ]); 669 | }); 670 | 671 | test("applies active state theme variables", async ({ initTestBed, page }) => { 672 | await page.setViewportSize({ height: 600, width: 800 }); 673 | await initTestBed( 674 | ` 675 | <Page> 676 | <HStack> 677 | <VStack> 678 | <Heading level="h2" value="Active Test" /> 679 | <Heading level="h3" value="Another Section" /> 680 | bottom of the page text 681 | </VStack> 682 | <TableOfContents /> 683 | </HStack> 684 | </Page> 685 | `, 686 | { 687 | testThemeVars: { 688 | "backgroundColor-TableOfContentsItem--active": "rgb(150, 150, 255)", 689 | "textColor-TableOfContentsItem--active": "rgb(50, 50, 150)", 690 | "fontWeight-TableOfContentsItem--active": "bold", 691 | }, 692 | }, 693 | ); 694 | 695 | const activeLink = page.getByRole("link", { name: "Another Section" }); 696 | await activeLink.click(); 697 | 698 | const activeListItem = page.locator("[class*='active']").first(); 699 | const activeLinkElement = activeListItem.getByRole("link"); 700 | 701 | await Promise.all([ 702 | expect(activeListItem).toHaveCSS("background-color", "rgb(150, 150, 255)"), 703 | expect(activeLinkElement).toHaveCSS("color", "rgb(50, 50, 150)"), 704 | expect(activeLinkElement).toHaveCSS("font-weight", "700"), // 'bold' maps to 700 705 | ]); 706 | }); 707 | }); 708 | 709 | // ============================================================================= 710 | // OTHER EDGE CASE TESTS 711 | // ============================================================================= 712 | 713 | test.describe("Other Edge Cases", () => { 714 | test.describe("id property handling", () => { 715 | test("handles unicode characters in heading titles", async ({ initTestBed, page }) => { 716 | await page.setViewportSize({ height: 600, width: 800 }); 717 | await initTestBed(` 718 | <Page> 719 | <HStack> 720 | <VStack gap="800px"> 721 | top of the page text 722 | <Heading level="h2" value="测试标题-émojis🚀" /> 723 | bottom of the page text 724 | </VStack> 725 | <TableOfContents /> 726 | </HStack> 727 | </Page> 728 | `); 729 | 730 | const unicodeHeading = page.getByRole("heading", { name: "测试标题-émojis🚀" }); 731 | const unicodeLink = page.getByRole("link", { name: "测试标题-émojis🚀" }); 732 | 733 | await expect(unicodeLink).toBeVisible(); 734 | await unicodeLink.click(); 735 | await expect(unicodeHeading).toBeInViewport(); 736 | }); 737 | 738 | test("handles bookmarks with special characters", async ({ initTestBed, page }) => { 739 | await page.setViewportSize({ height: 600, width: 800 }); 740 | await initTestBed(` 741 | <Page> 742 | <HStack> 743 | <VStack gap="800px"> 744 | top of the page text 745 | <Bookmark id="special-bookmark_test section" title="Special Bookmark" level="{2}"> 746 | special bookmark content 747 | </Bookmark> 748 | bottom of the page text 749 | </VStack> 750 | <TableOfContents /> 751 | </HStack> 752 | </Page> 753 | `); 754 | 755 | const bookmarkContent = page.getByText("special bookmark content"); 756 | const bookmarkLink = page.getByRole("link", { name: "Special Bookmark" }); 757 | 758 | await expect(bookmarkLink).toBeVisible(); 759 | await bookmarkLink.click(); 760 | await expect(bookmarkContent).toBeInViewport(); 761 | await page.waitForURL(/#special-bookmark_test(%20| )section$/); 762 | }); 763 | }); 764 | 765 | test("handles no headings or bookmarks gracefully", async ({ initTestBed, page }) => { 766 | await page.setViewportSize({ height: 600, width: 800 }); 767 | await initTestBed(` 768 | <Page> 769 | <HStack> 770 | <VStack gap="800px"> 771 | <Text>Just some text content</Text> 772 | bottom of the page text 773 | </VStack> 774 | <TableOfContents /> 775 | </HStack> 776 | </Page> 777 | `); 778 | 779 | const tocContainer = page.getByRole("link"); 780 | await expect(tocContainer).not.toBeVisible(); 781 | }); 782 | 783 | test("handles null props gracefully", async ({ initTestBed, page }) => { 784 | await page.setViewportSize({ height: 600, width: 800 }); 785 | await initTestBed(` 786 | <Page> 787 | <HStack> 788 | <VStack gap="800px"> 789 | top of the page text 790 | <Heading level="h2" value="Test Heading" /> 791 | bottom of the page text 792 | </VStack> 793 | <TableOfContents maxHeadingLevel="{null}" omitH1="{null}" smoothScrolling="{null}" /> 794 | </HStack> 795 | </Page> 796 | `); 797 | 798 | const testHeading = page.getByRole("heading", { name: "Test Heading" }); 799 | const testLink = page.getByRole("link", { name: "Test Heading" }); 800 | 801 | await expect(testLink).toBeVisible(); 802 | await testLink.click(); 803 | await expect(testHeading).toBeInViewport(); 804 | }); 805 | 806 | test("handles undefined props gracefully", async ({ initTestBed, page }) => { 807 | await page.setViewportSize({ height: 600, width: 800 }); 808 | await initTestBed(` 809 | <Page> 810 | <HStack> 811 | <VStack gap="800px"> 812 | <Heading level="h1" value="Test H1" /> 813 | <Heading level="h2" value="Test H2" /> 814 | bottom of the page text 815 | </VStack> 816 | <TableOfContents maxHeadingLevel="{undefined}" omitH1="{undefined}" smoothScrolling="{undefined}" /> 817 | </HStack> 818 | </Page> 819 | `); 820 | 821 | await expect(page.getByRole("link", { name: "Test H1" })).toBeVisible(); 822 | await expect(page.getByRole("link", { name: "Test H2" })).toBeVisible(); 823 | }); 824 | }); 825 | 826 | test.describe("Interactions with Bookmark props", () => { 827 | test("uses bookmark title fallback when title and content is empty", async ({ 828 | initTestBed, 829 | page, 830 | }) => { 831 | await initTestBed(` 832 | <Page> 833 | <HStack> 834 | <VStack gap="800px"> 835 | <Bookmark id="fallback-test" title=""/> 836 | </VStack> 837 | <TableOfContents /> 838 | </HStack> 839 | </Page> 840 | `); 841 | 842 | const tocItem = page.getByRole("link", { name: "fallback-test" }); 843 | await expect(tocItem).toBeVisible(); 844 | }); 845 | 846 | test("uses bookmark id as fallback when both title and content are empty", async ({ 847 | initTestBed, 848 | page, 849 | }) => { 850 | await initTestBed(` 851 | <Page> 852 | <HStack> 853 | <VStack gap="800px"> 854 | <Bookmark id="id-fallback" title="" /> 855 | </VStack> 856 | <TableOfContents /> 857 | </HStack> 858 | </Page> 859 | `); 860 | 861 | const tocItem = page.getByRole("link", { name: "id-fallback" }); 862 | await expect(tocItem).toBeVisible(); 863 | }); 864 | 865 | test("excludes bookmarks with omitFromToc=true", async ({ initTestBed, page }) => { 866 | await initTestBed(` 867 | <Page> 868 | <HStack> 869 | <VStack gap="800px"> 870 | <Bookmark id="visible" title="Visible Bookmark"> 871 | visible content 872 | </Bookmark> 873 | <Bookmark id="hidden" title="Hidden Bookmark" omitFromToc="{true}"> 874 | hidden content 875 | </Bookmark> 876 | <Bookmark id="also-visible" title="Also Visible"> 877 | also visible content 878 | </Bookmark> 879 | </VStack> 880 | <TableOfContents /> 881 | </HStack> 882 | </Page> 883 | `); 884 | 885 | const visibleItem = page.getByRole("link", { name: "Visible Bookmark" }); 886 | const hiddenItem = page.getByRole("link", { name: "Hidden Bookmark" }); 887 | const alsoVisibleItem = page.getByRole("link", { name: "Also Visible" }); 888 | 889 | await expect(visibleItem).toBeVisible(); 890 | await expect(hiddenItem).not.toBeVisible(); 891 | await expect(alsoVisibleItem).toBeVisible(); 892 | }); 893 | 894 | test("handles bookmarks without id gracefully", async ({ initTestBed, page }) => { 895 | await initTestBed(` 896 | <Page> 897 | <HStack> 898 | <VStack gap="800px"> 899 | <Bookmark title="No ID Bookmark"> 900 | content without id 901 | </Bookmark> 902 | <Bookmark id="with-id" title="With ID"> 903 | content with id 904 | </Bookmark> 905 | </VStack> 906 | <TableOfContents /> 907 | </HStack> 908 | </Page> 909 | `); 910 | 911 | const noIdItem = page.getByRole("link", { name: "No ID Bookmark" }); 912 | const withIdItem = page.getByRole("link", { name: "With ID" }); 913 | 914 | await expect(noIdItem).not.toBeVisible(); 915 | await expect(withIdItem).toBeVisible(); 916 | }); 917 | 918 | test("respects bookmark level in omitH1 filtering", async ({ initTestBed, page }) => { 919 | await initTestBed(` 920 | <Page> 921 | <HStack> 922 | <VStack gap="800px"> 923 | <Bookmark id="level1" title="Level 1 Bookmark" level="{1}"> 924 | level 1 content 925 | </Bookmark> 926 | <Bookmark id="level2" title="Level 2 Bookmark" level="{2}"> 927 | level 2 content 928 | </Bookmark> 929 | </VStack> 930 | <TableOfContents omitH1="{true}" /> 931 | </HStack> 932 | </Page> 933 | `); 934 | 935 | const level1Item = page.getByRole("link", { name: "Level 1 Bookmark" }); 936 | const level2Item = page.getByRole("link", { name: "Level 2 Bookmark" }); 937 | 938 | await expect(level1Item).not.toBeVisible(); 939 | await expect(level2Item).toBeVisible(); 940 | }); 941 | 942 | test("uses content text as title over id when title is undefined", async ({ 943 | initTestBed, 944 | page, 945 | }) => { 946 | await initTestBed(` 947 | <Page> 948 | <HStack> 949 | <VStack gap="800px"> 950 | <Bookmark id="content-text"> 951 | Content as title text 952 | </Bookmark> 953 | </VStack> 954 | <TableOfContents /> 955 | </HStack> 956 | </Page> 957 | `); 958 | 959 | const tocItem = page.getByRole("link", { name: "Content as title text" }); 960 | await expect(tocItem).toBeVisible(); 961 | }); 962 | }); 963 | ```