This is page 96 of 190. Use http://codebase.md/xmlui-org/xmlui/xmlui-latest.js?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .changeset
│ ├── config.json
│ └── small-tires-beg.md
├── .eslintrc.cjs
├── .github
│ ├── build-checklist.png
│ ├── ISSUE_TEMPLATE
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ └── workflows
│ ├── deploy-blog-optimized.yml
│ ├── deploy-blog-swa.yml
│ ├── deploy-blog.yml
│ ├── deploy-docs-optimized.yml
│ ├── deploy-docs-swa.yml
│ ├── deploy-docs.yml
│ ├── prepare-versions.yml
│ ├── release-packages.yml
│ ├── run-all-tests.yml
│ └── run-smoke-tests.yml
├── .gitignore
├── .prettierrc.js
├── .vscode
│ ├── launch.json
│ └── settings.json
├── blog
│ ├── .gitignore
│ ├── .gitkeep
│ ├── CHANGELOG.md
│ ├── extensions.ts
│ ├── index.html
│ ├── index.ts
│ ├── package.json
│ ├── public
│ │ ├── blog
│ │ │ ├── images
│ │ │ │ ├── an-advanced-codefence.gif
│ │ │ │ ├── an-advanced-codefence.mp4
│ │ │ │ ├── blog-page-component.png
│ │ │ │ ├── blog-scrabble.png
│ │ │ │ ├── codefence-runner.png
│ │ │ │ ├── integrated-blog-search.png
│ │ │ │ ├── lorem-ipsum.png
│ │ │ │ ├── playground-checkbox-source.png
│ │ │ │ ├── playground.png
│ │ │ │ ├── use-xmlui-mcp-to-find-a-howto.png
│ │ │ │ └── xmlui-demo-gallery.png
│ │ │ ├── introducing-xmlui.md
│ │ │ ├── lorem-ipsum.md
│ │ │ ├── newest-post.md
│ │ │ ├── older-post.md
│ │ │ ├── xmlui-playground.md
│ │ │ └── xmlui-powered-blog.md
│ │ ├── mockServiceWorker.js
│ │ ├── resources
│ │ │ ├── favicon.ico
│ │ │ ├── files
│ │ │ │ └── for-download
│ │ │ │ └── xmlui
│ │ │ │ └── xmlui-standalone.umd.js
│ │ │ ├── github.svg
│ │ │ ├── icons
│ │ │ │ ├── github.svg
│ │ │ │ └── rss.svg
│ │ │ ├── llms.txt
│ │ │ ├── logo-dark.svg
│ │ │ ├── logo.svg
│ │ │ ├── pg-popout.svg
│ │ │ ├── rss.svg
│ │ │ └── xmlui-logo.svg
│ │ ├── serve.json
│ │ ├── staticwebapp.config.json
│ │ └── web.config
│ ├── scripts
│ │ ├── download-latest-xmlui.js
│ │ ├── generate-rss.js
│ │ ├── get-releases.js
│ │ └── utils.js
│ ├── src
│ │ ├── components
│ │ │ ├── BlogOverview.xmlui
│ │ │ ├── BlogPage.xmlui
│ │ │ ├── LinkButton.xmlui
│ │ │ ├── PageNotFound.xmlui
│ │ │ └── Separator.xmlui
│ │ ├── config.ts
│ │ ├── Main.xmlui
│ │ └── themes
│ │ └── blog-theme.ts
│ └── tsconfig.json
├── CONTRIBUTING.md
├── docs
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── ComponentRefLinks.txt
│ ├── content
│ │ ├── _meta.json
│ │ ├── components
│ │ │ ├── _meta.json
│ │ │ ├── _overview.md
│ │ │ ├── APICall.md
│ │ │ ├── App.md
│ │ │ ├── AppHeader.md
│ │ │ ├── AppState.md
│ │ │ ├── AutoComplete.md
│ │ │ ├── Avatar.md
│ │ │ ├── Backdrop.md
│ │ │ ├── Badge.md
│ │ │ ├── BarChart.md
│ │ │ ├── Bookmark.md
│ │ │ ├── Breakout.md
│ │ │ ├── Button.md
│ │ │ ├── Card.md
│ │ │ ├── Carousel.md
│ │ │ ├── ChangeListener.md
│ │ │ ├── Checkbox.md
│ │ │ ├── CHStack.md
│ │ │ ├── ColorPicker.md
│ │ │ ├── Column.md
│ │ │ ├── ContentSeparator.md
│ │ │ ├── CVStack.md
│ │ │ ├── DataSource.md
│ │ │ ├── DateInput.md
│ │ │ ├── DatePicker.md
│ │ │ ├── DonutChart.md
│ │ │ ├── DropdownMenu.md
│ │ │ ├── EmojiSelector.md
│ │ │ ├── ExpandableItem.md
│ │ │ ├── FileInput.md
│ │ │ ├── FileUploadDropZone.md
│ │ │ ├── FlowLayout.md
│ │ │ ├── Footer.md
│ │ │ ├── Form.md
│ │ │ ├── FormItem.md
│ │ │ ├── FormSection.md
│ │ │ ├── Fragment.md
│ │ │ ├── H1.md
│ │ │ ├── H2.md
│ │ │ ├── H3.md
│ │ │ ├── H4.md
│ │ │ ├── H5.md
│ │ │ ├── H6.md
│ │ │ ├── Heading.md
│ │ │ ├── HSplitter.md
│ │ │ ├── HStack.md
│ │ │ ├── Icon.md
│ │ │ ├── IFrame.md
│ │ │ ├── Image.md
│ │ │ ├── Items.md
│ │ │ ├── LabelList.md
│ │ │ ├── Legend.md
│ │ │ ├── LineChart.md
│ │ │ ├── Link.md
│ │ │ ├── List.md
│ │ │ ├── Logo.md
│ │ │ ├── Markdown.md
│ │ │ ├── MenuItem.md
│ │ │ ├── MenuSeparator.md
│ │ │ ├── ModalDialog.md
│ │ │ ├── NavGroup.md
│ │ │ ├── NavLink.md
│ │ │ ├── NavPanel.md
│ │ │ ├── NoResult.md
│ │ │ ├── NumberBox.md
│ │ │ ├── Option.md
│ │ │ ├── Page.md
│ │ │ ├── PageMetaTitle.md
│ │ │ ├── Pages.md
│ │ │ ├── Pagination.md
│ │ │ ├── PasswordInput.md
│ │ │ ├── PieChart.md
│ │ │ ├── ProgressBar.md
│ │ │ ├── Queue.md
│ │ │ ├── RadioGroup.md
│ │ │ ├── RealTimeAdapter.md
│ │ │ ├── Redirect.md
│ │ │ ├── Select.md
│ │ │ ├── Slider.md
│ │ │ ├── Slot.md
│ │ │ ├── SpaceFiller.md
│ │ │ ├── Spinner.md
│ │ │ ├── Splitter.md
│ │ │ ├── Stack.md
│ │ │ ├── StickyBox.md
│ │ │ ├── SubMenuItem.md
│ │ │ ├── Switch.md
│ │ │ ├── TabItem.md
│ │ │ ├── Table.md
│ │ │ ├── TableOfContents.md
│ │ │ ├── Tabs.md
│ │ │ ├── Text.md
│ │ │ ├── TextArea.md
│ │ │ ├── TextBox.md
│ │ │ ├── Theme.md
│ │ │ ├── TimeInput.md
│ │ │ ├── Timer.md
│ │ │ ├── ToneChangerButton.md
│ │ │ ├── ToneSwitch.md
│ │ │ ├── Tooltip.md
│ │ │ ├── Tree.md
│ │ │ ├── VSplitter.md
│ │ │ ├── VStack.md
│ │ │ ├── xmlui-animations
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ ├── Animation.md
│ │ │ │ ├── FadeAnimation.md
│ │ │ │ ├── FadeInAnimation.md
│ │ │ │ ├── FadeOutAnimation.md
│ │ │ │ ├── ScaleAnimation.md
│ │ │ │ └── SlideInAnimation.md
│ │ │ ├── xmlui-pdf
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ └── Pdf.md
│ │ │ ├── xmlui-spreadsheet
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ └── Spreadsheet.md
│ │ │ └── xmlui-website-blocks
│ │ │ ├── _meta.json
│ │ │ ├── _overview.md
│ │ │ ├── Carousel.md
│ │ │ ├── HelloMd.md
│ │ │ ├── HeroSection.md
│ │ │ └── ScrollToTop.md
│ │ └── extensions
│ │ ├── _meta.json
│ │ ├── xmlui-animations
│ │ │ ├── _meta.json
│ │ │ ├── _overview.md
│ │ │ ├── Animation.md
│ │ │ ├── FadeAnimation.md
│ │ │ ├── FadeInAnimation.md
│ │ │ ├── FadeOutAnimation.md
│ │ │ ├── ScaleAnimation.md
│ │ │ └── SlideInAnimation.md
│ │ └── xmlui-website-blocks
│ │ ├── _meta.json
│ │ ├── _overview.md
│ │ ├── Carousel.md
│ │ ├── HelloMd.md
│ │ ├── HeroSection.md
│ │ └── ScrollToTop.md
│ ├── extensions.ts
│ ├── index.html
│ ├── index.ts
│ ├── package.json
│ ├── public
│ │ ├── feed.rss
│ │ ├── mockServiceWorker.js
│ │ ├── pages
│ │ │ ├── _meta.json
│ │ │ ├── app-structure.md
│ │ │ ├── build-editor-component.md
│ │ │ ├── build-hello-world-component.md
│ │ │ ├── components-intro.md
│ │ │ ├── context-variables.md
│ │ │ ├── forms.md
│ │ │ ├── globals.md
│ │ │ ├── glossary.md
│ │ │ ├── helper-tags.md
│ │ │ ├── hosted-deployment.md
│ │ │ ├── howto
│ │ │ │ ├── assign-a-complex-json-literal-to-a-component-variable.md
│ │ │ │ ├── chain-a-refetch.md
│ │ │ │ ├── control-cache-invalidation.md
│ │ │ │ ├── debounce-user-input-for-api-calls.md
│ │ │ │ ├── debounce-with-changelistener.md
│ │ │ │ ├── debug-a-component.md
│ │ │ │ ├── delay-a-datasource-until-another-datasource-is-ready.md
│ │ │ │ ├── delegate-a-method.md
│ │ │ │ ├── do-custom-form-validation.md
│ │ │ │ ├── expose-a-method-from-a-component.md
│ │ │ │ ├── filter-and-transform-data-from-an-api.md
│ │ │ │ ├── group-items-in-list-by-a-property.md
│ │ │ │ ├── handle-background-operations.md
│ │ │ │ ├── hide-an-element-until-its-datasource-is-ready.md
│ │ │ │ ├── make-a-set-of-equal-width-cards.md
│ │ │ │ ├── make-a-table-responsive.md
│ │ │ │ ├── make-navpanel-width-responsive.md
│ │ │ │ ├── modify-a-value-reported-in-a-column.md
│ │ │ │ ├── paginate-a-list.md
│ │ │ │ ├── pass-data-to-a-modal-dialog.md
│ │ │ │ ├── react-to-button-click-not-keystrokes.md
│ │ │ │ ├── set-the-initial-value-of-a-select-from-fetched-data.md
│ │ │ │ ├── share-a-modaldialog-across-components.md
│ │ │ │ ├── sync-selections-between-table-and-list-views.md
│ │ │ │ ├── update-ui-optimistically.md
│ │ │ │ ├── use-built-in-form-validation.md
│ │ │ │ ├── use-modal-dialog-onclose.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
│ │ │ ├── icons
│ │ │ │ ├── github.svg
│ │ │ │ └── rss.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
│ │ ├── staticwebapp.config.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
│ │ │ ├── LinkButton.xmlui
│ │ │ ├── NameValue.xmlui
│ │ │ ├── PageNotFound.xmlui
│ │ │ ├── PaletteItem.xmlui
│ │ │ ├── Palettes.xmlui
│ │ │ ├── SectionHeader.xmlui
│ │ │ ├── Separator.xmlui
│ │ │ ├── TBD.xmlui
│ │ │ ├── Test.xmlui
│ │ │ ├── ThemesIntro.xmlui
│ │ │ ├── ThousandThemes.xmlui
│ │ │ ├── TubeStops.xmlui
│ │ │ ├── TubeStops.xmlui.xs
│ │ │ └── TwoColumnCode.xmlui
│ │ ├── config.ts
│ │ ├── Main.xmlui
│ │ └── themes
│ │ ├── docs-theme.ts
│ │ ├── earthtone.ts
│ │ ├── xmlui-gray-on-default.ts
│ │ ├── xmlui-green-on-default.ts
│ │ └── xmlui-orange-on-default.ts
│ └── tsconfig.json
├── LICENSE
├── package-lock.json
├── package.json
├── packages
│ ├── tsconfig.json
│ ├── xmlui-animations
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── Animation.tsx
│ │ ├── AnimationNative.tsx
│ │ ├── FadeAnimation.tsx
│ │ ├── FadeInAnimation.tsx
│ │ ├── FadeOutAnimation.tsx
│ │ ├── index.tsx
│ │ ├── ScaleAnimation.tsx
│ │ └── SlideInAnimation.tsx
│ ├── xmlui-devtools
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── devtools
│ │ │ │ ├── DevTools.tsx
│ │ │ │ ├── DevToolsNative.module.scss
│ │ │ │ ├── DevToolsNative.tsx
│ │ │ │ ├── ModalDialog.module.scss
│ │ │ │ ├── ModalDialog.tsx
│ │ │ │ ├── ModalVisibilityContext.tsx
│ │ │ │ ├── Tooltip.module.scss
│ │ │ │ ├── Tooltip.tsx
│ │ │ │ └── utils.ts
│ │ │ ├── editor
│ │ │ │ └── Editor.tsx
│ │ │ └── index.tsx
│ │ └── vite.config-overrides.ts
│ ├── xmlui-hello-world
│ │ ├── .gitignore
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── HelloWorld.module.scss
│ │ ├── HelloWorld.tsx
│ │ ├── HelloWorldNative.tsx
│ │ └── index.tsx
│ ├── xmlui-os-frames
│ │ ├── .gitignore
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── index.tsx
│ │ ├── IPhoneFrame.module.scss
│ │ ├── IPhoneFrame.tsx
│ │ ├── MacOSAppFrame.module.scss
│ │ ├── MacOSAppFrame.tsx
│ │ ├── WindowsAppFrame.module.scss
│ │ └── WindowsAppFrame.tsx
│ ├── xmlui-pdf
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ ├── components
│ │ │ │ └── Pdf.xmlui
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── index.tsx
│ │ ├── LazyPdfNative.tsx
│ │ ├── Pdf.module.scss
│ │ └── Pdf.tsx
│ ├── xmlui-playground
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── hooks
│ │ │ ├── usePlayground.ts
│ │ │ └── useToast.ts
│ │ ├── index.tsx
│ │ ├── playground
│ │ │ ├── Box.module.scss
│ │ │ ├── Box.tsx
│ │ │ ├── CodeSelector.module.scss
│ │ │ ├── CodeSelector.tsx
│ │ │ ├── ConfirmationDialog.module.scss
│ │ │ ├── ConfirmationDialog.tsx
│ │ │ ├── Editor.tsx
│ │ │ ├── Header.module.scss
│ │ │ ├── Header.tsx
│ │ │ ├── Playground.tsx
│ │ │ ├── PlaygroundContent.module.scss
│ │ │ ├── PlaygroundContent.tsx
│ │ │ ├── PlaygroundNative.module.scss
│ │ │ ├── PlaygroundNative.tsx
│ │ │ ├── Preview.tsx
│ │ │ ├── StandalonePlayground.tsx
│ │ │ ├── StandalonePlaygroundNative.module.scss
│ │ │ ├── StandalonePlaygroundNative.tsx
│ │ │ ├── ThemeSwitcher.module.scss
│ │ │ ├── ThemeSwitcher.tsx
│ │ │ └── utils.ts
│ │ ├── providers
│ │ │ ├── Toast.module.scss
│ │ │ └── ToastProvider.tsx
│ │ ├── state
│ │ │ └── store.ts
│ │ ├── themes
│ │ │ └── theme.ts
│ │ └── utils
│ │ └── helpers.ts
│ ├── xmlui-search
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── index.tsx
│ │ ├── Search.module.scss
│ │ └── Search.tsx
│ ├── xmlui-spreadsheet
│ │ ├── .gitignore
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── index.tsx
│ │ ├── Spreadsheet.tsx
│ │ └── SpreadsheetNative.tsx
│ └── xmlui-website-blocks
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── demo
│ │ ├── components
│ │ │ ├── HeroBackgroundBreakoutPage.xmlui
│ │ │ ├── HeroBackgroundsPage.xmlui
│ │ │ ├── HeroContentsPage.xmlui
│ │ │ ├── HeroTextAlignPage.xmlui
│ │ │ ├── HeroTextPage.xmlui
│ │ │ └── HeroTonesPage.xmlui
│ │ ├── Main.xmlui
│ │ └── themes
│ │ └── default.ts
│ ├── index.html
│ ├── index.ts
│ ├── meta
│ │ └── componentsMetadata.ts
│ ├── package.json
│ ├── public
│ │ └── resources
│ │ ├── building.jpg
│ │ └── xmlui-logo.svg
│ └── src
│ ├── Carousel
│ │ ├── Carousel.module.scss
│ │ ├── Carousel.tsx
│ │ ├── CarouselContext.tsx
│ │ └── CarouselNative.tsx
│ ├── FancyButton
│ │ ├── FancyButton.module.scss
│ │ ├── FancyButton.tsx
│ │ └── FancyButton.xmlui
│ ├── Hello
│ │ ├── Hello.tsx
│ │ ├── Hello.xmlui
│ │ └── Hello.xmlui.xs
│ ├── HeroSection
│ │ ├── HeroSection.module.scss
│ │ ├── HeroSection.spec.ts
│ │ ├── HeroSection.tsx
│ │ └── HeroSectionNative.tsx
│ ├── index.tsx
│ ├── ScrollToTop
│ │ ├── ScrollToTop.module.scss
│ │ ├── ScrollToTop.tsx
│ │ └── ScrollToTopNative.tsx
│ └── vite-env.d.ts
├── playwright.config.ts
├── README.md
├── tools
│ ├── codefence
│ │ └── xmlui-code-fence-docs.md
│ ├── create-app
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── create-app.ts
│ │ ├── helpers
│ │ │ ├── copy.ts
│ │ │ ├── get-pkg-manager.ts
│ │ │ ├── git.ts
│ │ │ ├── install.ts
│ │ │ ├── is-folder-empty.ts
│ │ │ ├── is-writeable.ts
│ │ │ ├── make-dir.ts
│ │ │ └── validate-pkg.ts
│ │ ├── index.ts
│ │ ├── package.json
│ │ ├── templates
│ │ │ ├── default
│ │ │ │ └── ts
│ │ │ │ ├── gitignore
│ │ │ │ ├── index.html
│ │ │ │ ├── index.ts
│ │ │ │ ├── public
│ │ │ │ │ ├── mockServiceWorker.js
│ │ │ │ │ ├── resources
│ │ │ │ │ │ ├── favicon.ico
│ │ │ │ │ │ └── xmlui-logo.svg
│ │ │ │ │ └── serve.json
│ │ │ │ └── src
│ │ │ │ ├── components
│ │ │ │ │ ├── ApiAware.xmlui
│ │ │ │ │ ├── Home.xmlui
│ │ │ │ │ ├── IncButton.xmlui
│ │ │ │ │ └── PagePanel.xmlui
│ │ │ │ ├── config.ts
│ │ │ │ └── Main.xmlui
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── tsconfig.json
│ ├── create-xmlui-hello-world
│ │ ├── index.js
│ │ └── package.json
│ └── vscode
│ ├── .gitignore
│ ├── .vscode
│ │ ├── launch.json
│ │ └── tasks.json
│ ├── .vscodeignore
│ ├── build.sh
│ ├── CHANGELOG.md
│ ├── esbuild.js
│ ├── eslint.config.mjs
│ ├── formatter-docs.md
│ ├── generate-test-sample.sh
│ ├── LICENSE.md
│ ├── package-lock.json
│ ├── package.json
│ ├── README.md
│ ├── resources
│ │ ├── xmlui-logo.png
│ │ └── xmlui-markup-syntax-highlighting.png
│ ├── src
│ │ ├── extension.ts
│ │ └── server.ts
│ ├── syntaxes
│ │ └── xmlui.tmLanguage.json
│ ├── test-samples
│ │ └── sample.xmlui
│ ├── tsconfig.json
│ └── tsconfig.tsbuildinfo
├── turbo.json
└── xmlui
├── .gitignore
├── bin
│ ├── bootstrap.cjs
│ ├── bootstrap.js
│ ├── build-lib.ts
│ ├── build.ts
│ ├── index.ts
│ ├── preview.ts
│ ├── start.ts
│ ├── vite-xmlui-plugin.ts
│ └── viteConfig.ts
├── CHANGELOG.md
├── conventions
│ ├── component-qa-checklist.md
│ ├── copilot-conventions.md
│ ├── create-xmlui-components.md
│ ├── mermaid.md
│ ├── testing-conventions.md
│ └── xmlui-in-a-nutshell.md
├── dev-docs
│ ├── accessibility.md
│ ├── build-system.md
│ ├── build-xmlui.md
│ ├── component-behaviors.md
│ ├── component-metadata.md
│ ├── components-with-options.md
│ ├── containers.md
│ ├── data-operations.md
│ ├── glossary.md
│ ├── index.md
│ ├── next
│ │ ├── component-dev-guide.md
│ │ ├── configuration-management-enhancement-summary.md
│ │ ├── documentation-scripts-refactoring-complete-summary.md
│ │ ├── documentation-scripts-refactoring-plan.md
│ │ ├── duplicate-pattern-extraction-summary.md
│ │ ├── error-handling-standardization-summary.md
│ │ ├── generating-component-reference.md
│ │ ├── index.md
│ │ ├── logging-consistency-implementation-summary.md
│ │ ├── project-build.md
│ │ ├── project-structure.md
│ │ ├── theme-context.md
│ │ ├── tiptap-design-considerations.md
│ │ ├── working-with-code.md
│ │ ├── xmlui-runtime-architecture
│ │ └── xmlui-wcag-accessibility-report.md
│ ├── react-fundamentals.md
│ ├── release-method.md
│ ├── standalone-app.md
│ ├── theme-variables-refactoring.md
│ ├── ud-components.md
│ └── xmlui-repo.md
├── package.json
├── scripts
│ ├── coverage-only.js
│ ├── e2e-test-summary.js
│ ├── extract-component-metadata.js
│ ├── generate-docs
│ │ ├── build-downloads-map.mjs
│ │ ├── build-pages-map.mjs
│ │ ├── components-config.json
│ │ ├── configuration-management.mjs
│ │ ├── constants.mjs
│ │ ├── create-theme-files.mjs
│ │ ├── DocsGenerator.mjs
│ │ ├── error-handling.mjs
│ │ ├── extensions-config.json
│ │ ├── folders.mjs
│ │ ├── generate-summary-files.mjs
│ │ ├── get-docs.mjs
│ │ ├── input-handler.mjs
│ │ ├── logger.mjs
│ │ ├── logging-standards.mjs
│ │ ├── MetadataProcessor.mjs
│ │ ├── pattern-utilities.mjs
│ │ └── utils.mjs
│ ├── generate-metadata-markdown.js
│ ├── get-langserver-metadata.js
│ ├── inline-links.mjs
│ └── README-e2e-summary.md
├── src
│ ├── abstractions
│ │ ├── _conventions.md
│ │ ├── ActionDefs.ts
│ │ ├── AppContextDefs.ts
│ │ ├── ComponentDefs.ts
│ │ ├── ContainerDefs.ts
│ │ ├── ExtensionDefs.ts
│ │ ├── FunctionDefs.ts
│ │ ├── RendererDefs.ts
│ │ ├── scripting
│ │ │ ├── BlockScope.ts
│ │ │ ├── Compilation.ts
│ │ │ ├── LogicalThread.ts
│ │ │ ├── LoopScope.ts
│ │ │ ├── modules.ts
│ │ │ ├── ScriptParserError.ts
│ │ │ ├── Token.ts
│ │ │ ├── TryScope.ts
│ │ │ └── TryScopeExp.ts
│ │ └── ThemingDefs.ts
│ ├── components
│ │ ├── _conventions.md
│ │ ├── abstractions.ts
│ │ ├── Accordion
│ │ │ ├── Accordion.md
│ │ │ ├── Accordion.module.scss
│ │ │ ├── Accordion.spec.ts
│ │ │ ├── Accordion.tsx
│ │ │ ├── AccordionContext.tsx
│ │ │ ├── AccordionItem.tsx
│ │ │ ├── AccordionItemNative.tsx
│ │ │ └── AccordionNative.tsx
│ │ ├── Animation
│ │ │ └── AnimationNative.tsx
│ │ ├── APICall
│ │ │ ├── APICall.md
│ │ │ ├── APICall.spec.ts
│ │ │ ├── APICall.tsx
│ │ │ └── APICallNative.tsx
│ │ ├── App
│ │ │ ├── App.md
│ │ │ ├── App.module.scss
│ │ │ ├── App.spec.ts
│ │ │ ├── App.tsx
│ │ │ ├── AppLayoutContext.ts
│ │ │ ├── AppNative.tsx
│ │ │ ├── AppStateContext.ts
│ │ │ ├── doc-resources
│ │ │ │ ├── condensed-sticky.xmlui
│ │ │ │ ├── condensed.xmlui
│ │ │ │ ├── horizontal-sticky.xmlui
│ │ │ │ ├── horizontal.xmlui
│ │ │ │ ├── vertical-full-header.xmlui
│ │ │ │ ├── vertical-sticky.xmlui
│ │ │ │ └── vertical.xmlui
│ │ │ ├── IndexerContext.ts
│ │ │ ├── LinkInfoContext.ts
│ │ │ ├── SearchContext.tsx
│ │ │ ├── Sheet.module.scss
│ │ │ └── Sheet.tsx
│ │ ├── AppHeader
│ │ │ ├── AppHeader.md
│ │ │ ├── AppHeader.module.scss
│ │ │ ├── AppHeader.spec.ts
│ │ │ ├── AppHeader.tsx
│ │ │ └── AppHeaderNative.tsx
│ │ ├── AppState
│ │ │ ├── AppState.md
│ │ │ ├── AppState.spec.ts
│ │ │ ├── AppState.tsx
│ │ │ └── AppStateNative.tsx
│ │ ├── AutoComplete
│ │ │ ├── AutoComplete.md
│ │ │ ├── AutoComplete.module.scss
│ │ │ ├── AutoComplete.spec.ts
│ │ │ ├── AutoComplete.tsx
│ │ │ ├── AutoCompleteContext.tsx
│ │ │ └── AutoCompleteNative.tsx
│ │ ├── Avatar
│ │ │ ├── Avatar.md
│ │ │ ├── Avatar.module.scss
│ │ │ ├── Avatar.spec.ts
│ │ │ ├── Avatar.tsx
│ │ │ └── AvatarNative.tsx
│ │ ├── Backdrop
│ │ │ ├── Backdrop.md
│ │ │ ├── Backdrop.module.scss
│ │ │ ├── Backdrop.spec.ts
│ │ │ ├── Backdrop.tsx
│ │ │ └── BackdropNative.tsx
│ │ ├── Badge
│ │ │ ├── Badge.md
│ │ │ ├── Badge.module.scss
│ │ │ ├── Badge.spec.ts
│ │ │ ├── Badge.tsx
│ │ │ └── BadgeNative.tsx
│ │ ├── Bookmark
│ │ │ ├── Bookmark.md
│ │ │ ├── Bookmark.module.scss
│ │ │ ├── Bookmark.spec.ts
│ │ │ ├── Bookmark.tsx
│ │ │ └── BookmarkNative.tsx
│ │ ├── Breakout
│ │ │ ├── Breakout.module.scss
│ │ │ ├── Breakout.spec.ts
│ │ │ ├── Breakout.tsx
│ │ │ └── BreakoutNative.tsx
│ │ ├── Button
│ │ │ ├── Button-style.spec.ts
│ │ │ ├── Button.md
│ │ │ ├── Button.module.scss
│ │ │ ├── Button.spec.ts
│ │ │ ├── Button.tsx
│ │ │ └── ButtonNative.tsx
│ │ ├── Card
│ │ │ ├── Card.md
│ │ │ ├── Card.module.scss
│ │ │ ├── Card.spec.ts
│ │ │ ├── Card.tsx
│ │ │ └── CardNative.tsx
│ │ ├── Carousel
│ │ │ ├── Carousel.md
│ │ │ ├── Carousel.module.scss
│ │ │ ├── Carousel.spec.ts
│ │ │ ├── Carousel.tsx
│ │ │ ├── CarouselContext.tsx
│ │ │ ├── CarouselItem.tsx
│ │ │ ├── CarouselItemNative.tsx
│ │ │ └── CarouselNative.tsx
│ │ ├── ChangeListener
│ │ │ ├── ChangeListener.md
│ │ │ ├── ChangeListener.spec.ts
│ │ │ ├── ChangeListener.tsx
│ │ │ └── ChangeListenerNative.tsx
│ │ ├── chart-color-schemes.ts
│ │ ├── Charts
│ │ │ ├── AreaChart
│ │ │ │ ├── AreaChart.md
│ │ │ │ ├── AreaChart.spec.ts
│ │ │ │ ├── AreaChart.tsx
│ │ │ │ └── AreaChartNative.tsx
│ │ │ ├── BarChart
│ │ │ │ ├── BarChart.md
│ │ │ │ ├── BarChart.module.scss
│ │ │ │ ├── BarChart.spec.ts
│ │ │ │ ├── BarChart.tsx
│ │ │ │ └── BarChartNative.tsx
│ │ │ ├── DonutChart
│ │ │ │ ├── DonutChart.spec.ts
│ │ │ │ └── DonutChart.tsx
│ │ │ ├── LabelList
│ │ │ │ ├── LabelList.module.scss
│ │ │ │ ├── LabelList.spec.ts
│ │ │ │ ├── LabelList.tsx
│ │ │ │ └── LabelListNative.tsx
│ │ │ ├── Legend
│ │ │ │ ├── Legend.spec.ts
│ │ │ │ ├── Legend.tsx
│ │ │ │ └── LegendNative.tsx
│ │ │ ├── LineChart
│ │ │ │ ├── LineChart.md
│ │ │ │ ├── LineChart.module.scss
│ │ │ │ ├── LineChart.spec.ts
│ │ │ │ ├── LineChart.tsx
│ │ │ │ └── LineChartNative.tsx
│ │ │ ├── PieChart
│ │ │ │ ├── PieChart.md
│ │ │ │ ├── PieChart.spec.ts
│ │ │ │ ├── PieChart.tsx
│ │ │ │ ├── PieChartNative.module.scss
│ │ │ │ └── PieChartNative.tsx
│ │ │ ├── RadarChart
│ │ │ │ ├── RadarChart.md
│ │ │ │ ├── RadarChart.spec.ts
│ │ │ │ ├── RadarChart.tsx
│ │ │ │ └── RadarChartNative.tsx
│ │ │ ├── Tooltip
│ │ │ │ ├── TooltipContent.module.scss
│ │ │ │ ├── TooltipContent.spec.ts
│ │ │ │ └── TooltipContent.tsx
│ │ │ └── utils
│ │ │ ├── abstractions.ts
│ │ │ └── ChartProvider.tsx
│ │ ├── Checkbox
│ │ │ ├── Checkbox.md
│ │ │ ├── Checkbox.spec.ts
│ │ │ └── Checkbox.tsx
│ │ ├── CodeBlock
│ │ │ ├── CodeBlock.module.scss
│ │ │ ├── CodeBlock.spec.ts
│ │ │ ├── CodeBlock.tsx
│ │ │ ├── CodeBlockNative.tsx
│ │ │ └── highlight-code.ts
│ │ ├── collectedComponentMetadata.ts
│ │ ├── ColorPicker
│ │ │ ├── ColorPicker.md
│ │ │ ├── ColorPicker.module.scss
│ │ │ ├── ColorPicker.spec.ts
│ │ │ ├── ColorPicker.tsx
│ │ │ └── ColorPickerNative.tsx
│ │ ├── Column
│ │ │ ├── Column.md
│ │ │ ├── Column.tsx
│ │ │ ├── ColumnNative.tsx
│ │ │ ├── doc-resources
│ │ │ │ └── list-component-data.js
│ │ │ └── TableContext.tsx
│ │ ├── component-utils.ts
│ │ ├── ComponentProvider.tsx
│ │ ├── ComponentRegistryContext.tsx
│ │ ├── container-helpers.tsx
│ │ ├── ContentSeparator
│ │ │ ├── ContentSeparator.md
│ │ │ ├── ContentSeparator.module.scss
│ │ │ ├── ContentSeparator.spec.ts
│ │ │ ├── ContentSeparator.tsx
│ │ │ ├── ContentSeparatorNative.tsx
│ │ │ └── test-padding.xmlui
│ │ ├── DataSource
│ │ │ ├── DataSource.md
│ │ │ └── DataSource.tsx
│ │ ├── DateInput
│ │ │ ├── DateInput.md
│ │ │ ├── DateInput.module.scss
│ │ │ ├── DateInput.spec.ts
│ │ │ ├── DateInput.tsx
│ │ │ └── DateInputNative.tsx
│ │ ├── DatePicker
│ │ │ ├── DatePicker.md
│ │ │ ├── DatePicker.module.scss
│ │ │ ├── DatePicker.spec.ts
│ │ │ ├── DatePicker.tsx
│ │ │ └── DatePickerNative.tsx
│ │ ├── DropdownMenu
│ │ │ ├── DropdownMenu.md
│ │ │ ├── DropdownMenu.module.scss
│ │ │ ├── DropdownMenu.spec.ts
│ │ │ ├── DropdownMenu.tsx
│ │ │ ├── DropdownMenuNative.tsx
│ │ │ ├── MenuItem.md
│ │ │ └── SubMenuItem.md
│ │ ├── EmojiSelector
│ │ │ ├── EmojiSelector.md
│ │ │ ├── EmojiSelector.spec.ts
│ │ │ ├── EmojiSelector.tsx
│ │ │ └── EmojiSelectorNative.tsx
│ │ ├── ExpandableItem
│ │ │ ├── ExpandableItem.module.scss
│ │ │ ├── ExpandableItem.spec.ts
│ │ │ ├── ExpandableItem.tsx
│ │ │ └── ExpandableItemNative.tsx
│ │ ├── FileInput
│ │ │ ├── FileInput.md
│ │ │ ├── FileInput.module.scss
│ │ │ ├── FileInput.spec.ts
│ │ │ ├── FileInput.tsx
│ │ │ └── FileInputNative.tsx
│ │ ├── FileUploadDropZone
│ │ │ ├── FileUploadDropZone.md
│ │ │ ├── FileUploadDropZone.module.scss
│ │ │ ├── FileUploadDropZone.spec.ts
│ │ │ ├── FileUploadDropZone.tsx
│ │ │ └── FileUploadDropZoneNative.tsx
│ │ ├── FlowLayout
│ │ │ ├── FlowLayout.md
│ │ │ ├── FlowLayout.module.scss
│ │ │ ├── FlowLayout.spec.ts
│ │ │ ├── FlowLayout.spec.ts-snapshots
│ │ │ │ └── Edge-cases-boxShadow-is-not-clipped-1-non-smoke-darwin.png
│ │ │ ├── FlowLayout.tsx
│ │ │ └── FlowLayoutNative.tsx
│ │ ├── Footer
│ │ │ ├── Footer.md
│ │ │ ├── Footer.module.scss
│ │ │ ├── Footer.spec.ts
│ │ │ ├── Footer.tsx
│ │ │ └── FooterNative.tsx
│ │ ├── Form
│ │ │ ├── Form.md
│ │ │ ├── Form.module.scss
│ │ │ ├── Form.spec.ts
│ │ │ ├── Form.tsx
│ │ │ ├── formActions.ts
│ │ │ ├── FormContext.ts
│ │ │ └── FormNative.tsx
│ │ ├── FormItem
│ │ │ ├── FormItem.md
│ │ │ ├── FormItem.module.scss
│ │ │ ├── FormItem.spec.ts
│ │ │ ├── FormItem.tsx
│ │ │ ├── FormItemNative.tsx
│ │ │ ├── HelperText.module.scss
│ │ │ ├── HelperText.tsx
│ │ │ ├── ItemWithLabel.tsx
│ │ │ └── Validations.ts
│ │ ├── FormSection
│ │ │ ├── FormSection.md
│ │ │ ├── FormSection.ts
│ │ │ └── FormSection.xmlui
│ │ ├── Fragment
│ │ │ ├── Fragment.spec.ts
│ │ │ └── Fragment.tsx
│ │ ├── Heading
│ │ │ ├── abstractions.ts
│ │ │ ├── H1.md
│ │ │ ├── H1.spec.ts
│ │ │ ├── H2.md
│ │ │ ├── H2.spec.ts
│ │ │ ├── H3.md
│ │ │ ├── H3.spec.ts
│ │ │ ├── H4.md
│ │ │ ├── H4.spec.ts
│ │ │ ├── H5.md
│ │ │ ├── H5.spec.ts
│ │ │ ├── H6.md
│ │ │ ├── H6.spec.ts
│ │ │ ├── Heading.md
│ │ │ ├── Heading.module.scss
│ │ │ ├── Heading.spec.ts
│ │ │ ├── Heading.tsx
│ │ │ └── HeadingNative.tsx
│ │ ├── HoverCard
│ │ │ ├── HoverCard.tsx
│ │ │ └── HovercardNative.tsx
│ │ ├── HtmlTags
│ │ │ ├── HtmlTags.module.scss
│ │ │ ├── HtmlTags.spec.ts
│ │ │ └── HtmlTags.tsx
│ │ ├── Icon
│ │ │ ├── AdmonitionDanger.tsx
│ │ │ ├── AdmonitionInfo.tsx
│ │ │ ├── AdmonitionNote.tsx
│ │ │ ├── AdmonitionTip.tsx
│ │ │ ├── AdmonitionWarning.tsx
│ │ │ ├── ApiIcon.tsx
│ │ │ ├── ArrowDropDown.module.scss
│ │ │ ├── ArrowDropDown.tsx
│ │ │ ├── ArrowDropUp.module.scss
│ │ │ ├── ArrowDropUp.tsx
│ │ │ ├── ArrowLeft.module.scss
│ │ │ ├── ArrowLeft.tsx
│ │ │ ├── ArrowRight.module.scss
│ │ │ ├── ArrowRight.tsx
│ │ │ ├── Attach.tsx
│ │ │ ├── Binding.module.scss
│ │ │ ├── Binding.tsx
│ │ │ ├── BoardIcon.tsx
│ │ │ ├── BoxIcon.tsx
│ │ │ ├── CheckIcon.tsx
│ │ │ ├── ChevronDownIcon.tsx
│ │ │ ├── ChevronLeft.tsx
│ │ │ ├── ChevronRight.tsx
│ │ │ ├── ChevronUpIcon.tsx
│ │ │ ├── CodeFileIcon.tsx
│ │ │ ├── CodeSandbox.tsx
│ │ │ ├── CompactListIcon.tsx
│ │ │ ├── ContentCopyIcon.tsx
│ │ │ ├── DarkToLightIcon.tsx
│ │ │ ├── DatabaseIcon.module.scss
│ │ │ ├── DatabaseIcon.tsx
│ │ │ ├── DocFileIcon.tsx
│ │ │ ├── DocIcon.tsx
│ │ │ ├── DotMenuHorizontalIcon.tsx
│ │ │ ├── DotMenuIcon.tsx
│ │ │ ├── EmailIcon.tsx
│ │ │ ├── EmptyFolderIcon.tsx
│ │ │ ├── ErrorIcon.tsx
│ │ │ ├── ExpressionIcon.tsx
│ │ │ ├── FillPlusCricleIcon.tsx
│ │ │ ├── FilterIcon.tsx
│ │ │ ├── FolderIcon.tsx
│ │ │ ├── GlobeIcon.tsx
│ │ │ ├── HomeIcon.tsx
│ │ │ ├── HyperLinkIcon.tsx
│ │ │ ├── Icon.md
│ │ │ ├── Icon.module.scss
│ │ │ ├── Icon.spec.ts
│ │ │ ├── Icon.tsx
│ │ │ ├── IconNative.tsx
│ │ │ ├── ImageFileIcon.tsx
│ │ │ ├── Inspect.tsx
│ │ │ ├── LightToDark.tsx
│ │ │ ├── LinkIcon.tsx
│ │ │ ├── ListIcon.tsx
│ │ │ ├── LooseListIcon.tsx
│ │ │ ├── MoonIcon.tsx
│ │ │ ├── MoreOptionsIcon.tsx
│ │ │ ├── NoSortIcon.tsx
│ │ │ ├── PDFIcon.tsx
│ │ │ ├── PenIcon.tsx
│ │ │ ├── PhoneIcon.tsx
│ │ │ ├── PhotoIcon.tsx
│ │ │ ├── PlusIcon.tsx
│ │ │ ├── SearchIcon.tsx
│ │ │ ├── ShareIcon.tsx
│ │ │ ├── SortAscendingIcon.tsx
│ │ │ ├── SortDescendingIcon.tsx
│ │ │ ├── StarsIcon.tsx
│ │ │ ├── SunIcon.tsx
│ │ │ ├── svg
│ │ │ │ ├── admonition_danger.svg
│ │ │ │ ├── admonition_info.svg
│ │ │ │ ├── admonition_note.svg
│ │ │ │ ├── admonition_tip.svg
│ │ │ │ ├── admonition_warning.svg
│ │ │ │ ├── api.svg
│ │ │ │ ├── arrow-dropdown.svg
│ │ │ │ ├── arrow-left.svg
│ │ │ │ ├── arrow-right.svg
│ │ │ │ ├── arrow-up.svg
│ │ │ │ ├── attach.svg
│ │ │ │ ├── binding.svg
│ │ │ │ ├── box.svg
│ │ │ │ ├── bulb.svg
│ │ │ │ ├── code-file.svg
│ │ │ │ ├── code-sandbox.svg
│ │ │ │ ├── dark_to_light.svg
│ │ │ │ ├── database.svg
│ │ │ │ ├── doc.svg
│ │ │ │ ├── empty-folder.svg
│ │ │ │ ├── expression.svg
│ │ │ │ ├── eye-closed.svg
│ │ │ │ ├── eye-dark.svg
│ │ │ │ ├── eye.svg
│ │ │ │ ├── file-text.svg
│ │ │ │ ├── filter.svg
│ │ │ │ ├── folder.svg
│ │ │ │ ├── img.svg
│ │ │ │ ├── inspect.svg
│ │ │ │ ├── light_to_dark.svg
│ │ │ │ ├── moon.svg
│ │ │ │ ├── pdf.svg
│ │ │ │ ├── photo.svg
│ │ │ │ ├── share.svg
│ │ │ │ ├── stars.svg
│ │ │ │ ├── sun.svg
│ │ │ │ ├── trending-down.svg
│ │ │ │ ├── trending-level.svg
│ │ │ │ ├── trending-up.svg
│ │ │ │ ├── txt.svg
│ │ │ │ ├── unknown-file.svg
│ │ │ │ ├── unlink.svg
│ │ │ │ └── xls.svg
│ │ │ ├── TableDeleteColumnIcon.tsx
│ │ │ ├── TableDeleteRowIcon.tsx
│ │ │ ├── TableInsertColumnIcon.tsx
│ │ │ ├── TableInsertRowIcon.tsx
│ │ │ ├── TrashIcon.tsx
│ │ │ ├── TrendingDownIcon.tsx
│ │ │ ├── TrendingLevelIcon.tsx
│ │ │ ├── TrendingUpIcon.tsx
│ │ │ ├── TxtIcon.tsx
│ │ │ ├── UnknownFileIcon.tsx
│ │ │ ├── UnlinkIcon.tsx
│ │ │ ├── UserIcon.tsx
│ │ │ ├── WarningIcon.tsx
│ │ │ └── XlsIcon.tsx
│ │ ├── IconProvider.tsx
│ │ ├── IconRegistryContext.tsx
│ │ ├── IFrame
│ │ │ ├── IFrame.md
│ │ │ ├── IFrame.module.scss
│ │ │ ├── IFrame.spec.ts
│ │ │ ├── IFrame.tsx
│ │ │ └── IFrameNative.tsx
│ │ ├── Image
│ │ │ ├── Image.md
│ │ │ ├── Image.module.scss
│ │ │ ├── Image.spec.ts
│ │ │ ├── Image.tsx
│ │ │ └── ImageNative.tsx
│ │ ├── Input
│ │ │ ├── index.ts
│ │ │ ├── InputAdornment.module.scss
│ │ │ ├── InputAdornment.tsx
│ │ │ ├── InputDivider.module.scss
│ │ │ ├── InputDivider.tsx
│ │ │ ├── InputLabel.module.scss
│ │ │ ├── InputLabel.tsx
│ │ │ ├── PartialInput.module.scss
│ │ │ └── PartialInput.tsx
│ │ ├── InspectButton
│ │ │ ├── InspectButton.module.scss
│ │ │ └── InspectButton.tsx
│ │ ├── Items
│ │ │ ├── Items.md
│ │ │ ├── Items.spec.ts
│ │ │ ├── Items.tsx
│ │ │ └── ItemsNative.tsx
│ │ ├── Link
│ │ │ ├── Link.md
│ │ │ ├── Link.module.scss
│ │ │ ├── Link.spec.ts
│ │ │ ├── Link.tsx
│ │ │ └── LinkNative.tsx
│ │ ├── List
│ │ │ ├── doc-resources
│ │ │ │ └── list-component-data.js
│ │ │ ├── List.md
│ │ │ ├── List.module.scss
│ │ │ ├── List.spec.ts
│ │ │ ├── List.tsx
│ │ │ └── ListNative.tsx
│ │ ├── Logo
│ │ │ ├── doc-resources
│ │ │ │ └── xmlui-logo.svg
│ │ │ ├── Logo.md
│ │ │ ├── Logo.tsx
│ │ │ └── LogoNative.tsx
│ │ ├── Markdown
│ │ │ ├── CodeText.module.scss
│ │ │ ├── CodeText.tsx
│ │ │ ├── Markdown.md
│ │ │ ├── Markdown.module.scss
│ │ │ ├── Markdown.spec.ts
│ │ │ ├── Markdown.tsx
│ │ │ ├── MarkdownNative.tsx
│ │ │ ├── parse-binding-expr.ts
│ │ │ └── utils.ts
│ │ ├── metadata-helpers.ts
│ │ ├── ModalDialog
│ │ │ ├── ConfirmationModalContextProvider.tsx
│ │ │ ├── Dialog.module.scss
│ │ │ ├── Dialog.tsx
│ │ │ ├── ModalDialog.md
│ │ │ ├── ModalDialog.module.scss
│ │ │ ├── ModalDialog.spec.ts
│ │ │ ├── ModalDialog.tsx
│ │ │ ├── ModalDialogNative.tsx
│ │ │ └── ModalVisibilityContext.tsx
│ │ ├── NavGroup
│ │ │ ├── NavGroup.md
│ │ │ ├── NavGroup.module.scss
│ │ │ ├── NavGroup.spec.ts
│ │ │ ├── NavGroup.tsx
│ │ │ ├── NavGroupContext.ts
│ │ │ └── NavGroupNative.tsx
│ │ ├── NavLink
│ │ │ ├── NavLink.md
│ │ │ ├── NavLink.module.scss
│ │ │ ├── NavLink.spec.ts
│ │ │ ├── NavLink.tsx
│ │ │ └── NavLinkNative.tsx
│ │ ├── NavPanel
│ │ │ ├── NavPanel.md
│ │ │ ├── NavPanel.module.scss
│ │ │ ├── NavPanel.spec.ts
│ │ │ ├── NavPanel.tsx
│ │ │ └── NavPanelNative.tsx
│ │ ├── NestedApp
│ │ │ ├── AppWithCodeView.module.scss
│ │ │ ├── AppWithCodeView.tsx
│ │ │ ├── AppWithCodeViewNative.tsx
│ │ │ ├── defaultProps.tsx
│ │ │ ├── logo.svg
│ │ │ ├── NestedApp.module.scss
│ │ │ ├── NestedApp.tsx
│ │ │ ├── NestedAppNative.tsx
│ │ │ ├── Tooltip.module.scss
│ │ │ ├── Tooltip.tsx
│ │ │ └── utils.ts
│ │ ├── NoResult
│ │ │ ├── NoResult.md
│ │ │ ├── NoResult.module.scss
│ │ │ ├── NoResult.spec.ts
│ │ │ ├── NoResult.tsx
│ │ │ └── NoResultNative.tsx
│ │ ├── NumberBox
│ │ │ ├── numberbox-abstractions.ts
│ │ │ ├── NumberBox.md
│ │ │ ├── NumberBox.module.scss
│ │ │ ├── NumberBox.spec.ts
│ │ │ ├── NumberBox.tsx
│ │ │ └── NumberBoxNative.tsx
│ │ ├── Option
│ │ │ ├── Option.md
│ │ │ ├── Option.spec.ts
│ │ │ ├── Option.tsx
│ │ │ ├── OptionNative.tsx
│ │ │ └── OptionTypeProvider.tsx
│ │ ├── PageMetaTitle
│ │ │ ├── PageMetaTilteNative.tsx
│ │ │ ├── PageMetaTitle.md
│ │ │ ├── PageMetaTitle.spec.ts
│ │ │ └── PageMetaTitle.tsx
│ │ ├── Pages
│ │ │ ├── Page.md
│ │ │ ├── Pages.md
│ │ │ ├── Pages.module.scss
│ │ │ ├── Pages.tsx
│ │ │ └── PagesNative.tsx
│ │ ├── Pagination
│ │ │ ├── Pagination.md
│ │ │ ├── Pagination.module.scss
│ │ │ ├── Pagination.spec.ts
│ │ │ ├── Pagination.tsx
│ │ │ └── PaginationNative.tsx
│ │ ├── PositionedContainer
│ │ │ ├── PositionedContainer.module.scss
│ │ │ ├── PositionedContainer.tsx
│ │ │ └── PositionedContainerNative.tsx
│ │ ├── ProfileMenu
│ │ │ ├── ProfileMenu.module.scss
│ │ │ └── ProfileMenu.tsx
│ │ ├── ProgressBar
│ │ │ ├── ProgressBar.md
│ │ │ ├── ProgressBar.module.scss
│ │ │ ├── ProgressBar.spec.ts
│ │ │ ├── ProgressBar.tsx
│ │ │ └── ProgressBarNative.tsx
│ │ ├── Queue
│ │ │ ├── Queue.md
│ │ │ ├── Queue.spec.ts
│ │ │ ├── Queue.tsx
│ │ │ ├── queueActions.ts
│ │ │ └── QueueNative.tsx
│ │ ├── RadioGroup
│ │ │ ├── RadioGroup.md
│ │ │ ├── RadioGroup.module.scss
│ │ │ ├── RadioGroup.spec.ts
│ │ │ ├── RadioGroup.tsx
│ │ │ ├── RadioGroupNative.tsx
│ │ │ ├── RadioItem.tsx
│ │ │ └── RadioItemNative.tsx
│ │ ├── RealTimeAdapter
│ │ │ ├── RealTimeAdapter.tsx
│ │ │ └── RealTimeAdapterNative.tsx
│ │ ├── Redirect
│ │ │ ├── Redirect.md
│ │ │ ├── Redirect.spec.ts
│ │ │ └── Redirect.tsx
│ │ ├── ResponsiveBar
│ │ │ ├── README.md
│ │ │ ├── ResponsiveBar.md
│ │ │ ├── ResponsiveBar.module.scss
│ │ │ ├── ResponsiveBar.spec.ts
│ │ │ ├── ResponsiveBar.tsx
│ │ │ └── ResponsiveBarNative.tsx
│ │ ├── Select
│ │ │ ├── HiddenOption.tsx
│ │ │ ├── OptionContext.ts
│ │ │ ├── Select.md
│ │ │ ├── Select.module.scss
│ │ │ ├── Select.spec.ts
│ │ │ ├── Select.tsx
│ │ │ ├── SelectContext.tsx
│ │ │ └── SelectNative.tsx
│ │ ├── SelectionStore
│ │ │ ├── SelectionStore.md
│ │ │ ├── SelectionStore.tsx
│ │ │ └── SelectionStoreNative.tsx
│ │ ├── Slider
│ │ │ ├── Slider.md
│ │ │ ├── Slider.module.scss
│ │ │ ├── Slider.spec.ts
│ │ │ ├── Slider.tsx
│ │ │ └── SliderNative.tsx
│ │ ├── Slot
│ │ │ ├── Slot.md
│ │ │ ├── Slot.spec.ts
│ │ │ └── Slot.ts
│ │ ├── SlotItem.tsx
│ │ ├── SpaceFiller
│ │ │ ├── SpaceFiller.md
│ │ │ ├── SpaceFiller.module.scss
│ │ │ ├── SpaceFiller.spec.ts
│ │ │ ├── SpaceFiller.tsx
│ │ │ └── SpaceFillerNative.tsx
│ │ ├── Spinner
│ │ │ ├── Spinner.md
│ │ │ ├── Spinner.module.scss
│ │ │ ├── Spinner.spec.ts
│ │ │ ├── Spinner.tsx
│ │ │ └── SpinnerNative.tsx
│ │ ├── Splitter
│ │ │ ├── HSplitter.md
│ │ │ ├── HSplitter.spec.ts
│ │ │ ├── Splitter.md
│ │ │ ├── Splitter.module.scss
│ │ │ ├── Splitter.spec.ts
│ │ │ ├── Splitter.tsx
│ │ │ ├── SplitterNative.tsx
│ │ │ ├── utils.ts
│ │ │ ├── VSplitter.md
│ │ │ └── VSplitter.spec.ts
│ │ ├── Stack
│ │ │ ├── CHStack.md
│ │ │ ├── CHStack.spec.ts
│ │ │ ├── CVStack.md
│ │ │ ├── CVStack.spec.ts
│ │ │ ├── HStack.md
│ │ │ ├── HStack.spec.ts
│ │ │ ├── Stack.md
│ │ │ ├── Stack.module.scss
│ │ │ ├── Stack.spec.ts
│ │ │ ├── Stack.tsx
│ │ │ ├── StackNative.tsx
│ │ │ ├── VStack.md
│ │ │ └── VStack.spec.ts
│ │ ├── StickyBox
│ │ │ ├── StickyBox.md
│ │ │ ├── StickyBox.module.scss
│ │ │ ├── StickyBox.tsx
│ │ │ └── StickyBoxNative.tsx
│ │ ├── Switch
│ │ │ ├── Switch.md
│ │ │ ├── Switch.spec.ts
│ │ │ └── Switch.tsx
│ │ ├── Table
│ │ │ ├── doc-resources
│ │ │ │ └── list-component-data.js
│ │ │ ├── react-table-config.d.ts
│ │ │ ├── Table.md
│ │ │ ├── Table.module.scss
│ │ │ ├── Table.spec.ts
│ │ │ ├── Table.tsx
│ │ │ ├── TableNative.tsx
│ │ │ └── useRowSelection.tsx
│ │ ├── TableOfContents
│ │ │ ├── TableOfContents.module.scss
│ │ │ ├── TableOfContents.spec.ts
│ │ │ ├── TableOfContents.tsx
│ │ │ └── TableOfContentsNative.tsx
│ │ ├── Tabs
│ │ │ ├── TabContext.tsx
│ │ │ ├── TabItem.md
│ │ │ ├── TabItem.tsx
│ │ │ ├── TabItemNative.tsx
│ │ │ ├── Tabs.md
│ │ │ ├── Tabs.module.scss
│ │ │ ├── Tabs.spec.ts
│ │ │ ├── Tabs.tsx
│ │ │ └── TabsNative.tsx
│ │ ├── Text
│ │ │ ├── Text.md
│ │ │ ├── Text.module.scss
│ │ │ ├── Text.spec.ts
│ │ │ ├── Text.tsx
│ │ │ └── TextNative.tsx
│ │ ├── TextArea
│ │ │ ├── TextArea.md
│ │ │ ├── TextArea.module.scss
│ │ │ ├── TextArea.spec.ts
│ │ │ ├── TextArea.tsx
│ │ │ ├── TextAreaNative.tsx
│ │ │ ├── TextAreaResizable.tsx
│ │ │ └── useComposedRef.ts
│ │ ├── TextBox
│ │ │ ├── TextBox.md
│ │ │ ├── TextBox.module.scss
│ │ │ ├── TextBox.spec.ts
│ │ │ ├── TextBox.tsx
│ │ │ └── TextBoxNative.tsx
│ │ ├── Theme
│ │ │ ├── NotificationToast.tsx
│ │ │ ├── Theme.md
│ │ │ ├── Theme.module.scss
│ │ │ ├── Theme.spec.ts
│ │ │ ├── Theme.tsx
│ │ │ └── ThemeNative.tsx
│ │ ├── TimeInput
│ │ │ ├── TimeInput.md
│ │ │ ├── TimeInput.module.scss
│ │ │ ├── TimeInput.spec.ts
│ │ │ ├── TimeInput.tsx
│ │ │ ├── TimeInputNative.tsx
│ │ │ └── utils.ts
│ │ ├── Timer
│ │ │ ├── Timer.md
│ │ │ ├── Timer.spec.ts
│ │ │ ├── Timer.tsx
│ │ │ └── TimerNative.tsx
│ │ ├── Toggle
│ │ │ ├── Toggle.module.scss
│ │ │ └── Toggle.tsx
│ │ ├── ToneChangerButton
│ │ │ ├── ToneChangerButton.md
│ │ │ ├── ToneChangerButton.spec.ts
│ │ │ └── ToneChangerButton.tsx
│ │ ├── ToneSwitch
│ │ │ ├── ToneSwitch.md
│ │ │ ├── ToneSwitch.module.scss
│ │ │ ├── ToneSwitch.spec.ts
│ │ │ ├── ToneSwitch.tsx
│ │ │ └── ToneSwitchNative.tsx
│ │ ├── Tooltip
│ │ │ ├── Tooltip.md
│ │ │ ├── Tooltip.module.scss
│ │ │ ├── Tooltip.spec.ts
│ │ │ ├── Tooltip.tsx
│ │ │ └── TooltipNative.tsx
│ │ ├── Tree
│ │ │ ├── testData.ts
│ │ │ ├── Tree-dynamic.spec.ts
│ │ │ ├── Tree-icons.spec.ts
│ │ │ ├── Tree.md
│ │ │ ├── Tree.spec.ts
│ │ │ ├── TreeComponent.module.scss
│ │ │ ├── TreeComponent.tsx
│ │ │ └── TreeNative.tsx
│ │ ├── TreeDisplay
│ │ │ ├── TreeDisplay.md
│ │ │ ├── TreeDisplay.module.scss
│ │ │ ├── TreeDisplay.tsx
│ │ │ └── TreeDisplayNative.tsx
│ │ ├── ValidationSummary
│ │ │ ├── ValidationSummary.module.scss
│ │ │ └── ValidationSummary.tsx
│ │ └── VisuallyHidden.tsx
│ ├── components-core
│ │ ├── abstractions
│ │ │ ├── ComponentRenderer.ts
│ │ │ ├── LoaderRenderer.ts
│ │ │ ├── standalone.ts
│ │ │ └── treeAbstractions.ts
│ │ ├── action
│ │ │ ├── actions.ts
│ │ │ ├── APICall.tsx
│ │ │ ├── FileDownloadAction.tsx
│ │ │ ├── FileUploadAction.tsx
│ │ │ ├── NavigateAction.tsx
│ │ │ └── TimedAction.tsx
│ │ ├── ApiBoundComponent.tsx
│ │ ├── appContext
│ │ │ ├── date-functions.ts
│ │ │ ├── math-function.ts
│ │ │ └── misc-utils.ts
│ │ ├── AppContext.tsx
│ │ ├── behaviors
│ │ │ ├── Behavior.tsx
│ │ │ └── CoreBehaviors.tsx
│ │ ├── component-hooks.ts
│ │ ├── ComponentDecorator.tsx
│ │ ├── ComponentViewer.tsx
│ │ ├── CompoundComponent.tsx
│ │ ├── constants.ts
│ │ ├── DebugViewProvider.tsx
│ │ ├── descriptorHelper.ts
│ │ ├── devtools
│ │ │ ├── InspectorDialog.module.scss
│ │ │ ├── InspectorDialog.tsx
│ │ │ └── InspectorDialogVisibilityContext.tsx
│ │ ├── EngineError.ts
│ │ ├── event-handlers.ts
│ │ ├── InspectorButton.module.scss
│ │ ├── InspectorContext.tsx
│ │ ├── interception
│ │ │ ├── abstractions.ts
│ │ │ ├── ApiInterceptor.ts
│ │ │ ├── ApiInterceptorProvider.tsx
│ │ │ ├── apiInterceptorWorker.ts
│ │ │ ├── Backend.ts
│ │ │ ├── Errors.ts
│ │ │ ├── IndexedDb.ts
│ │ │ ├── initMock.ts
│ │ │ ├── InMemoryDb.ts
│ │ │ ├── ReadonlyCollection.ts
│ │ │ └── useApiInterceptorContext.tsx
│ │ ├── loader
│ │ │ ├── ApiLoader.tsx
│ │ │ ├── DataLoader.tsx
│ │ │ ├── ExternalDataLoader.tsx
│ │ │ ├── Loader.tsx
│ │ │ ├── MockLoaderRenderer.tsx
│ │ │ └── PageableLoader.tsx
│ │ ├── LoaderComponent.tsx
│ │ ├── markup-check.ts
│ │ ├── parts.ts
│ │ ├── renderers.ts
│ │ ├── rendering
│ │ │ ├── AppContent.tsx
│ │ │ ├── AppRoot.tsx
│ │ │ ├── AppWrapper.tsx
│ │ │ ├── buildProxy.ts
│ │ │ ├── collectFnVarDeps.ts
│ │ │ ├── ComponentAdapter.tsx
│ │ │ ├── ComponentWrapper.tsx
│ │ │ ├── Container.tsx
│ │ │ ├── containers.ts
│ │ │ ├── ContainerWrapper.tsx
│ │ │ ├── ErrorBoundary.module.scss
│ │ │ ├── ErrorBoundary.tsx
│ │ │ ├── InvalidComponent.module.scss
│ │ │ ├── InvalidComponent.tsx
│ │ │ ├── nodeUtils.ts
│ │ │ ├── reducer.ts
│ │ │ ├── renderChild.tsx
│ │ │ ├── StandaloneComponent.tsx
│ │ │ ├── StateContainer.tsx
│ │ │ ├── UnknownComponent.module.scss
│ │ │ ├── UnknownComponent.tsx
│ │ │ └── valueExtractor.ts
│ │ ├── reportEngineError.ts
│ │ ├── RestApiProxy.ts
│ │ ├── script-runner
│ │ │ ├── asyncProxy.ts
│ │ │ ├── AttributeValueParser.ts
│ │ │ ├── bannedFunctions.ts
│ │ │ ├── BindingTreeEvaluationContext.ts
│ │ │ ├── eval-tree-async.ts
│ │ │ ├── eval-tree-common.ts
│ │ │ ├── eval-tree-sync.ts
│ │ │ ├── ParameterParser.ts
│ │ │ ├── process-statement-async.ts
│ │ │ ├── process-statement-common.ts
│ │ │ ├── process-statement-sync.ts
│ │ │ ├── ScriptingSourceTree.ts
│ │ │ ├── simplify-expression.ts
│ │ │ ├── statement-queue.ts
│ │ │ └── visitors.ts
│ │ ├── StandaloneApp.tsx
│ │ ├── StandaloneExtensionManager.ts
│ │ ├── TableOfContentsContext.tsx
│ │ ├── theming
│ │ │ ├── _themes.scss
│ │ │ ├── component-layout-resolver.ts
│ │ │ ├── extendThemeUtils.ts
│ │ │ ├── hvar.ts
│ │ │ ├── layout-resolver.ts
│ │ │ ├── parse-layout-props.ts
│ │ │ ├── StyleContext.tsx
│ │ │ ├── StyleRegistry.ts
│ │ │ ├── ThemeContext.tsx
│ │ │ ├── ThemeProvider.tsx
│ │ │ ├── themes
│ │ │ │ ├── base-utils.ts
│ │ │ │ ├── palette.ts
│ │ │ │ ├── root.ts
│ │ │ │ ├── solid.ts
│ │ │ │ ├── theme-colors.ts
│ │ │ │ └── xmlui.ts
│ │ │ ├── themeVars.module.scss
│ │ │ ├── themeVars.ts
│ │ │ ├── transformThemeVars.ts
│ │ │ └── utils.ts
│ │ ├── utils
│ │ │ ├── actionUtils.ts
│ │ │ ├── audio-utils.ts
│ │ │ ├── base64-utils.ts
│ │ │ ├── compound-utils.ts
│ │ │ ├── css-utils.ts
│ │ │ ├── DataLoaderQueryKeyGenerator.ts
│ │ │ ├── date-utils.ts
│ │ │ ├── extractParam.ts
│ │ │ ├── hooks.tsx
│ │ │ ├── LruCache.ts
│ │ │ ├── mergeProps.ts
│ │ │ ├── misc.ts
│ │ │ ├── request-params.ts
│ │ │ ├── statementUtils.ts
│ │ │ └── treeUtils.ts
│ │ └── xmlui-parser.ts
│ ├── index-standalone.ts
│ ├── index.scss
│ ├── index.ts
│ ├── language-server
│ │ ├── server-common.ts
│ │ ├── server-web-worker.ts
│ │ ├── server.ts
│ │ ├── services
│ │ │ ├── common
│ │ │ │ ├── docs-generation.ts
│ │ │ │ ├── lsp-utils.ts
│ │ │ │ ├── metadata-utils.ts
│ │ │ │ └── syntax-node-utilities.ts
│ │ │ ├── completion.ts
│ │ │ ├── diagnostic.ts
│ │ │ ├── format.ts
│ │ │ └── hover.ts
│ │ └── xmlui-metadata-generated.js
│ ├── logging
│ │ ├── LoggerContext.tsx
│ │ ├── LoggerInitializer.tsx
│ │ ├── LoggerService.ts
│ │ └── xmlui.ts
│ ├── logo.svg
│ ├── parsers
│ │ ├── common
│ │ │ ├── GenericToken.ts
│ │ │ ├── InputStream.ts
│ │ │ └── utils.ts
│ │ ├── scripting
│ │ │ ├── code-behind-collect.ts
│ │ │ ├── Lexer.ts
│ │ │ ├── modules.ts
│ │ │ ├── Parser.ts
│ │ │ ├── ParserError.ts
│ │ │ ├── ScriptingNodeTypes.ts
│ │ │ ├── TokenTrait.ts
│ │ │ ├── TokenType.ts
│ │ │ └── tree-visitor.ts
│ │ ├── style-parser
│ │ │ ├── errors.ts
│ │ │ ├── source-tree.ts
│ │ │ ├── StyleInputStream.ts
│ │ │ ├── StyleLexer.ts
│ │ │ ├── StyleParser.ts
│ │ │ └── tokens.ts
│ │ └── xmlui-parser
│ │ ├── CharacterCodes.ts
│ │ ├── diagnostics.ts
│ │ ├── fileExtensions.ts
│ │ ├── index.ts
│ │ ├── lint.ts
│ │ ├── parser.ts
│ │ ├── ParserError.ts
│ │ ├── scanner.ts
│ │ ├── syntax-kind.ts
│ │ ├── syntax-node.ts
│ │ ├── transform.ts
│ │ ├── utils.ts
│ │ ├── xmlui-serializer.ts
│ │ └── xmlui-tree.ts
│ ├── react-app-env.d.ts
│ ├── syntax
│ │ ├── monaco
│ │ │ ├── grammar.monacoLanguage.ts
│ │ │ ├── index.ts
│ │ │ ├── xmlui-dark.ts
│ │ │ ├── xmlui-light.ts
│ │ │ └── xmluiscript.monacoLanguage.ts
│ │ └── textMate
│ │ ├── index.ts
│ │ ├── xmlui-dark.json
│ │ ├── xmlui-light.json
│ │ ├── xmlui.json
│ │ └── xmlui.tmLanguage.json
│ ├── testing
│ │ ├── assertions.ts
│ │ ├── component-test-helpers.ts
│ │ ├── ComponentDrivers.ts
│ │ ├── drivers
│ │ │ ├── DateInputDriver.ts
│ │ │ ├── index.ts
│ │ │ ├── ModalDialogDriver.ts
│ │ │ ├── NumberBoxDriver.ts
│ │ │ ├── TextBoxDriver.ts
│ │ │ ├── TimeInputDriver.ts
│ │ │ ├── TimerDriver.ts
│ │ │ └── TreeDriver.ts
│ │ ├── fixtures.ts
│ │ ├── index.ts
│ │ └── infrastructure
│ │ ├── index.html
│ │ ├── main.tsx
│ │ ├── public
│ │ │ ├── mockServiceWorker.js
│ │ │ ├── resources
│ │ │ │ ├── bell.svg
│ │ │ │ ├── box.svg
│ │ │ │ ├── doc.svg
│ │ │ │ ├── eye.svg
│ │ │ │ ├── flower-640x480.jpg
│ │ │ │ ├── sun.svg
│ │ │ │ ├── test-image-100x100.jpg
│ │ │ │ └── txt.svg
│ │ │ └── serve.json
│ │ └── TestBed.tsx
│ └── vite-env.d.ts
├── tests
│ ├── components
│ │ ├── CodeBlock
│ │ │ └── hightlight-code.test.ts
│ │ ├── playground-pattern.test.ts
│ │ └── Tree
│ │ └── Tree-states.test.ts
│ ├── components-core
│ │ ├── abstractions
│ │ │ └── treeAbstractions.test.ts
│ │ ├── container
│ │ │ └── buildProxy.test.ts
│ │ ├── interception
│ │ │ ├── orderBy.test.ts
│ │ │ ├── ReadOnlyCollection.test.ts
│ │ │ └── request-param-converter.test.ts
│ │ ├── scripts-runner
│ │ │ ├── AttributeValueParser.test.ts
│ │ │ ├── eval-tree-arrow-async.test.ts
│ │ │ ├── eval-tree-arrow.test.ts
│ │ │ ├── eval-tree-func-decl-async.test.ts
│ │ │ ├── eval-tree-func-decl.test.ts
│ │ │ ├── eval-tree-pre-post.test.ts
│ │ │ ├── eval-tree-regression.test.ts
│ │ │ ├── eval-tree.test.ts
│ │ │ ├── function-proxy.test.ts
│ │ │ ├── parser-regression.test.ts
│ │ │ ├── process-event.test.ts
│ │ │ ├── process-function.test.ts
│ │ │ ├── process-implicit-context.test.ts
│ │ │ ├── process-statement-asgn.test.ts
│ │ │ ├── process-statement-destruct.test.ts
│ │ │ ├── process-statement-regs.test.ts
│ │ │ ├── process-statement-sync.test.ts
│ │ │ ├── process-statement.test.ts
│ │ │ ├── process-switch-sync.test.ts
│ │ │ ├── process-switch.test.ts
│ │ │ ├── process-try-sync.test.ts
│ │ │ ├── process-try.test.ts
│ │ │ └── test-helpers.ts
│ │ ├── test-metadata-handler.ts
│ │ ├── theming
│ │ │ ├── border-segments.test.ts
│ │ │ ├── component-layout.resolver.test.ts
│ │ │ ├── layout-property-parser.test.ts
│ │ │ ├── layout-resolver.test.ts
│ │ │ ├── layout-resolver2.test.ts
│ │ │ ├── layout-vp-override.test.ts
│ │ │ └── padding-segments.test.ts
│ │ └── utils
│ │ ├── date-utils.test.ts
│ │ ├── format-human-elapsed-time.test.ts
│ │ └── LruCache.test.ts
│ ├── language-server
│ │ ├── completion.test.ts
│ │ ├── format.test.ts
│ │ ├── hover.test.ts
│ │ └── mockData.ts
│ └── parsers
│ ├── common
│ │ └── input-stream.test.ts
│ ├── markdown
│ │ └── parse-binding-expression.test.ts
│ ├── parameter-parser.test.ts
│ ├── paremeter-parser.test.ts
│ ├── scripting
│ │ ├── eval-tree-arrow.test.ts
│ │ ├── eval-tree-pre-post.test.ts
│ │ ├── eval-tree.test.ts
│ │ ├── function-proxy.test.ts
│ │ ├── lexer-literals.test.ts
│ │ ├── lexer-misc.test.ts
│ │ ├── module-parse.test.ts
│ │ ├── parser-arrow.test.ts
│ │ ├── parser-assignments.test.ts
│ │ ├── parser-binary.test.ts
│ │ ├── parser-destructuring.test.ts
│ │ ├── parser-errors.test.ts
│ │ ├── parser-expressions.test.ts
│ │ ├── parser-function.test.ts
│ │ ├── parser-literals.test.ts
│ │ ├── parser-primary.test.ts
│ │ ├── parser-regex.test.ts
│ │ ├── parser-statements.test.ts
│ │ ├── parser-unary.test.ts
│ │ ├── process-event.test.ts
│ │ ├── process-implicit-context.test.ts
│ │ ├── process-statement-asgn.test.ts
│ │ ├── process-statement-destruct.test.ts
│ │ ├── process-statement-regs.test.ts
│ │ ├── process-statement-sync.test.ts
│ │ ├── process-statement.test.ts
│ │ ├── process-switch-sync.test.ts
│ │ ├── process-switch.test.ts
│ │ ├── process-try-sync.test.ts
│ │ ├── process-try.test.ts
│ │ ├── simplify-expression.test.ts
│ │ ├── statement-hooks.test.ts
│ │ └── test-helpers.ts
│ ├── style-parser
│ │ ├── generateHvarChain.test.ts
│ │ ├── parseHVar.test.ts
│ │ ├── parser.test.ts
│ │ └── tokens.test.ts
│ └── xmlui
│ ├── lint.test.ts
│ ├── parser.test.ts
│ ├── scanner.test.ts
│ ├── transform.attr.test.ts
│ ├── transform.circular.test.ts
│ ├── transform.element.test.ts
│ ├── transform.errors.test.ts
│ ├── transform.escape.test.ts
│ ├── transform.regression.test.ts
│ ├── transform.script.test.ts
│ ├── transform.test.ts
│ └── xmlui.ts
├── tests-e2e
│ ├── api-bound-component-regression.spec.ts
│ ├── api-call-as-extracted-component.spec.ts
│ ├── assign-to-object-or-array-regression.spec.ts
│ ├── binding-regression.spec.ts
│ ├── children-as-template-context-vars.spec.ts
│ ├── compound-component.spec.ts
│ ├── context-vars-regression.spec.ts
│ ├── data-bindings.spec.ts
│ ├── datasource-and-api-usage-in-var.spec.ts
│ ├── datasource-direct-binding.spec.ts
│ ├── datasource-onLoaded-regression.spec.ts
│ ├── modify-array-item-regression.spec.ts
│ ├── namespaces.spec.ts
│ ├── push-to-array-regression.spec.ts
│ ├── screen-breakpoints.spec.ts
│ ├── scripting.spec.ts
│ ├── state-scope-in-pages.spec.ts
│ └── state-var-scopes.spec.ts
├── tsconfig.json
├── tsdown.config.ts
├── vite.config.ts
└── vitest.config.ts
```
# Files
--------------------------------------------------------------------------------
/xmlui/tests/language-server/format.test.ts:
--------------------------------------------------------------------------------
```typescript
1 | import { describe, test, expect } from "vitest";
2 | import { format, type FormatOptions } from "../../src/language-server/services/format";
3 | import { createXmlUiParser, toDbgString } from "../../src/parsers/xmlui-parser";
4 |
5 | describe("XML Formatter", () => {
6 | describe("Format Options", () => {
7 | test("should respect custom indentation", () => {
8 | const input = "<Fragment><Text>Content</Text></Fragment>";
9 | const result = formatTwice(input, { tabSize: 4, insertSpaces: true });
10 |
11 | expect(result).toEqual(
12 | `<Fragment>
13 | <Text>
14 | Content
15 | </Text>
16 | </Fragment>`,
17 | );
18 | });
19 |
20 | test("should respect tab indentation", () => {
21 | const input = "<Fragment><Text>Content</Text></Fragment>";
22 | const result = formatTwice(input, { tabSize: 4, insertSpaces: false });
23 |
24 | expect(result).toEqual(
25 | `<Fragment>
26 | \t<Text>
27 | \t\tContent
28 | \t</Text>
29 | </Fragment>`,
30 | );
31 | });
32 | });
33 |
34 | describe("Basic XML Formatting", () => {
35 | test("should format simple xmlui fragment", () => {
36 | const input = '<Fragment><Text testId="textShort" width="200px">Short</Text></Fragment>';
37 | const result = formatTwice(input);
38 |
39 | expect(result).toEqual(
40 | `<Fragment>
41 | <Text testId="textShort" width="200px">
42 | Short
43 | </Text>
44 | </Fragment>`,
45 | );
46 | });
47 |
48 | test("should format nested xmlui elements", () => {
49 | const input =
50 | '<Fragment><Text testId="textShort" width="200px">Short</Text><Text testId="textLong" width="200px" maxLines="2">Long text content</Text></Fragment>';
51 | const result = formatTwice(input);
52 |
53 | expect(result).toEqual(
54 | `<Fragment>
55 | <Text testId="textShort" width="200px">
56 | Short
57 | </Text>
58 | <Text testId="textLong" width="200px" maxLines="2">
59 | Long text content
60 | </Text>
61 | </Fragment>`,
62 | );
63 | });
64 |
65 | test("should preserve text content", () => {
66 | const input =
67 | "<Text>Though this long text does not fit into a single line, please do not break it!</Text>";
68 | const result = formatTwice(input);
69 |
70 | expect(result).toEqual(
71 | `<Text>
72 | Though this long text does not fit into a single line, please do not break it!
73 | </Text>`,
74 | );
75 | });
76 |
77 | test("should format self-closing tags", () => {
78 | const input = '<Fragment><Input type="text"/><Button/></Fragment>';
79 | const result = formatTwice(input);
80 |
81 | expect(result).toEqual(
82 | `<Fragment>
83 | <Input type="text" />
84 | <Button />
85 | </Fragment>`,
86 | );
87 | });
88 |
89 | test("should format key-only attribue", () => {
90 | const input = '<Fragment><Input type="text" enabled/><Button/></Fragment>';
91 | const result = formatTwice(input);
92 |
93 | expect(result).toEqual(
94 | `<Fragment>
95 | <Input type="text" enabled />
96 | <Button />
97 | </Fragment>`,
98 | );
99 | });
100 | });
101 |
102 | describe("CDATA Handling", () => {
103 | test("should preserve CDATA sections", () => {
104 | const input = "<Fragment><Text><![CDATA[Some <special> content & more]]></Text></Fragment>";
105 | const result = formatTwice(input);
106 |
107 | expect(result).toEqual(
108 | `<Fragment>
109 | <Text>
110 | <![CDATA[Some <special> content & more]]>
111 | </Text>
112 | </Fragment>`,
113 | );
114 | });
115 |
116 | test("should format XML with multiple CDATA sections", () => {
117 | const input =
118 | "<Fragment><Text><![CDATA[First CDATA]]></Text><Text><![CDATA[Second CDATA with <tags>]]></Text></Fragment>";
119 | const result = formatTwice(input);
120 |
121 | expect(result).toEqual(
122 | `<Fragment>
123 | <Text>
124 | <![CDATA[First CDATA]]>
125 | </Text>
126 | <Text>
127 | <![CDATA[Second CDATA with <tags>]]>
128 | </Text>
129 | </Fragment>`,
130 | );
131 | });
132 |
133 | test("should handle CDATA with special characters", () => {
134 | const input = "<Text><![CDATA[Content with & < > \" ' characters]]></Text>";
135 | const result = formatTwice(input);
136 |
137 | expect(result).toEqual(
138 | `<Text>
139 | <![CDATA[Content with & < > " ' characters]]>
140 | </Text>`,
141 | );
142 | });
143 | });
144 |
145 | describe("newlines", () => {
146 | test("keeps single blank line", () => {
147 | const result = formatTwice("<A />\n\n<A />");
148 | expect(result).toEqual(`<A />\n\n<A />`);
149 | });
150 |
151 | test("converts single whitespace only line to blank line", () => {
152 | const result = formatTwice("<A />\n \n<A />");
153 | expect(result).toEqual(`<A />\n\n<A />`);
154 | });
155 |
156 | test("keeps blank line around comment only line", () => {
157 | const result = formatTwice(`<A />
158 |
159 | <!--c-->
160 |
161 | <A />`);
162 | expect(result).toEqual(`<A />
163 |
164 | <!--c-->
165 |
166 | <A />`);
167 | });
168 |
169 | test("collapses multiple blank lines around comment only line", () => {
170 | const result = formatTwice(`<A />
171 |
172 |
173 | <!--c-->
174 |
175 |
176 | <A />`);
177 | expect(result).toEqual(`<A />
178 |
179 | <!--c-->
180 |
181 | <A />`);
182 | });
183 | test("collapses multiple blank lines around 2 comment only line", () => {
184 | const result = formatTwice(`<A />
185 |
186 |
187 | <!--c--><!--c-->
188 |
189 |
190 | <A />`);
191 | expect(result).toEqual(`<A />
192 |
193 | <!--c-->
194 | <!--c-->
195 |
196 | <A />`);
197 | });
198 |
199 | test("collapses multiple blank lines into single one", () => {
200 | const result = formatTwice("<A />\n\n\n<A />");
201 | expect(result).toEqual(`<A />\n\n<A />`);
202 | });
203 |
204 | test("collapses multiple whitespace only lines into single blank line", () => {
205 | const result = formatTwice("<A />\n \n \n<A />");
206 | expect(result).toEqual(`<A />\n\n<A />`);
207 | });
208 | });
209 |
210 | describe("comments", () => {
211 | test("should handle comment before tag name", () => {
212 | const input = `<<!--c-->n attr="val" attr2>
213 | text1
214 | <n2
215 | attr3="val2"
216 | attr4 />
217 | text2
218 | </n>`;
219 | const result = formatTwice(input);
220 |
221 | expect(result).toEqual(
222 | `< <!--c--> n attr="val" attr2>
223 | text1
224 | <n2
225 | attr3="val2"
226 | attr4
227 | />
228 | text2
229 | </n>`,
230 | );
231 | });
232 |
233 | test("should handle comment after tag name", () => {
234 | const input = `<n<!--c--> attr="val" attr2>
235 | text1
236 | <n2
237 | attr3="val2"
238 | attr4 />
239 | text2
240 | </n>`;
241 | const result = formatTwice(input);
242 |
243 | expect(result).toEqual(
244 | `<n <!--c--> attr="val" attr2>
245 | text1
246 | <n2
247 | attr3="val2"
248 | attr4
249 | />
250 | text2
251 | </n>`,
252 | );
253 | });
254 |
255 | test("should handle comment between attribute name and =", () => {
256 | const input = `<n attr<!--c-->="val" attr2>
257 | text1
258 | <n2
259 | attr3="val2"
260 | attr4 />
261 | text2
262 | </n>`;
263 | const result = formatTwice(input);
264 |
265 | expect(result).toEqual(
266 | `<n attr <!--c--> ="val" attr2>
267 | text1
268 | <n2
269 | attr3="val2"
270 | attr4
271 | />
272 | text2
273 | </n>`,
274 | );
275 | });
276 |
277 | test("should handle comment before attribute value", () => {
278 | const input = `<n attr=<!--c-->"val" attr2>
279 | text1
280 | <n2
281 | attr3="val2"
282 | attr4
283 | />
284 | text2
285 | </n>`;
286 | const result = formatTwice(input);
287 |
288 | expect(result).toEqual(
289 | `<n attr= <!--c--> "val" attr2>
290 | text1
291 | <n2
292 | attr3="val2"
293 | attr4
294 | />
295 | text2
296 | </n>`,
297 | );
298 | });
299 |
300 | test("should handle comment between attributes", () => {
301 | const input = `<n attr="val"<!--c--> attr2>
302 | text1
303 | <n2
304 | attr3="val2"
305 | attr4
306 | />
307 | text2
308 | </n>`;
309 | const result = formatTwice(input);
310 |
311 | expect(result).toEqual(
312 | `<n attr="val" <!--c--> attr2>
313 | text1
314 | <n2
315 | attr3="val2"
316 | attr4
317 | />
318 | text2
319 | </n>`,
320 | );
321 | });
322 |
323 | test("should handle comment after last attribute", () => {
324 | const input = `<n attr="val" attr2<!--c-->>
325 | text1
326 | <n2
327 | attr3="val2"
328 | attr4
329 | />
330 | text2
331 | </n>`;
332 | const result = formatTwice(input);
333 |
334 | expect(result).toEqual(
335 | `<n attr="val" attr2 <!--c-->>
336 | text1
337 | <n2
338 | attr3="val2"
339 | attr4
340 | />
341 | text2
342 | </n>`,
343 | );
344 | });
345 |
346 | test("should handle comment after opening tag", () => {
347 | const input = `<n attr="val" attr2><!--c-->
348 | text1
349 | <n2
350 | attr3="val2"
351 | attr4
352 | />
353 | text2
354 | </n>`;
355 | const result = formatTwice(input);
356 |
357 | expect(result).toEqual(
358 | `<n attr="val" attr2>
359 | <!--c-->
360 | text1
361 | <n2
362 | attr3="val2"
363 | attr4
364 | />
365 | text2
366 | </n>`,
367 | );
368 | });
369 |
370 | test("should handle comment before text content", () => {
371 | const input = `<n attr="val" attr2>
372 | <!--c-->text1
373 | <n2
374 | attr3="val2"
375 | attr4
376 | />
377 | text2
378 | </n>`;
379 | const result = formatTwice(input);
380 |
381 | expect(result).toEqual(
382 | `<n attr="val" attr2>
383 | <!--c-->text1
384 | <n2
385 | attr3="val2"
386 | attr4
387 | />
388 | text2
389 | </n>`,
390 | );
391 | });
392 |
393 | test("should handle comment after text content", () => {
394 | const input = `<n attr="val" attr2>
395 | text1<!--c-->
396 | <n2
397 | attr3="val2"
398 | attr4
399 | />
400 | text2
401 | </n>`;
402 | const result = formatTwice(input);
403 |
404 | expect(result).toEqual(
405 | `<n attr="val" attr2>
406 | text1 <!--c-->
407 | <n2
408 | attr3="val2"
409 | attr4
410 | />
411 | text2
412 | </n>`,
413 | );
414 | });
415 |
416 | test("should handle comment before child element", () => {
417 | const input = `<n attr="val" attr2>
418 | text1
419 | <!--c--><n2
420 | attr3="val2"
421 | attr4
422 | />
423 | text2
424 | </n>`;
425 | const result = formatTwice(input);
426 |
427 | expect(result).toEqual(
428 | `<n attr="val" attr2>
429 | text1
430 | <!--c-->
431 | <n2
432 | attr3="val2"
433 | attr4
434 | />
435 | text2
436 | </n>`,
437 | );
438 | });
439 |
440 | test("should handle comment in self closing tag after name", () => {
441 | const input = `<n attr="val" attr2>
442 | text1
443 | <n2<!--c-->
444 | attr3="val2"
445 | attr4
446 | />
447 | text2
448 | </n>`;
449 | const result = formatTwice(input);
450 |
451 | expect(result).toEqual(
452 | `<n attr="val" attr2>
453 | text1
454 | <n2
455 | <!--c-->
456 | attr3="val2"
457 | attr4
458 | />
459 | text2
460 | </n>`,
461 | );
462 | });
463 |
464 | test("should handle comment in self closing tag after newline name", () => {
465 | const input = `<n attr="val" attr2>
466 | text1
467 | <n2
468 | <!--c-->attr3="val2"
469 | attr4
470 | />
471 | text2
472 | </n>`;
473 | const result = formatTwice(input);
474 |
475 | expect(result).toEqual(
476 | `<n attr="val" attr2>
477 | text1
478 | <n2
479 | <!--c-->
480 | attr3="val2"
481 | attr4
482 | />
483 | text2
484 | </n>`,
485 | );
486 | });
487 |
488 | test("should handle comment in self closing tag between attributes", () => {
489 | const input = `<n attr="val" attr2>
490 | text1
491 | <n2
492 | attr3="val2"<!--c-->
493 | attr4
494 | />
495 | text2
496 | </n>`;
497 | const result = formatTwice(input);
498 |
499 | expect(result).toEqual(
500 | `<n attr="val" attr2>
501 | text1
502 | <n2
503 | attr3="val2"
504 | <!--c-->
505 | attr4
506 | />
507 | text2
508 | </n>`,
509 | );
510 | });
511 |
512 | test("should handle comment before self-closing tag closing", () => {
513 | const input = `<n attr="val" attr2>
514 | text1
515 | <n2
516 | attr3="val2"
517 | attr4
518 | <!--c-->
519 | />
520 | text2
521 | </n>`;
522 | const result = formatTwice(input);
523 |
524 | expect(result).toEqual(
525 | `<n attr="val" attr2>
526 | text1
527 | <n2
528 | attr3="val2"
529 | attr4
530 | <!--c-->
531 | />
532 | text2
533 | </n>`,
534 | );
535 | });
536 |
537 | test("should handle comment between text and closing tag", () => {
538 | const input = `<n attr="val" attr2>
539 | text1
540 | <n2
541 | attr3="val2"
542 | attr4
543 | />
544 | text2<!--c-->
545 | </n>`;
546 | const result = formatTwice(input);
547 |
548 | expect(result).toEqual(
549 | `<n attr="val" attr2>
550 | text1
551 | <n2
552 | attr3="val2"
553 | attr4
554 | />
555 | text2 <!--c-->
556 | </n>`,
557 | );
558 | });
559 |
560 | test("should handle comment between text with newline and closing tag", () => {
561 | const input = `<n attr="val" attr2>
562 | text1
563 | <n2
564 | attr3="val2"
565 | attr4
566 | />
567 | text2
568 | <!--c-->
569 | </n>`;
570 | const result = formatTwice(input);
571 |
572 | expect(result).toEqual(
573 | `<n attr="val" attr2>
574 | text1
575 | <n2
576 | attr3="val2"
577 | attr4
578 | />
579 | text2
580 | <!--c-->
581 | </n>`,
582 | );
583 | });
584 |
585 | test("should handle comment right after last tag", () => {
586 | const input = `<n attr="val" attr2>
587 | text1
588 | <n2
589 | attr3="val2"
590 | attr4
591 | />
592 | text2
593 | </n><!--c-->`;
594 | const result = formatTwice(input);
595 |
596 | expect(result).toEqual(
597 | `<n attr="val" attr2>
598 | text1
599 | <n2
600 | attr3="val2"
601 | attr4
602 | />
603 | text2
604 | </n> <!--c-->`,
605 | );
606 | });
607 |
608 | test("should handle comment after closeNodeStart", () => {
609 | const input = `<n attr="val" attr2>
610 | text1
611 | <n2
612 | attr3="val2"
613 | attr4
614 | />
615 | text2
616 | </<!--c-->n>`;
617 | const result = formatTwice(input);
618 |
619 | expect(result).toEqual(
620 | `<n attr="val" attr2>
621 | text1
622 | <n2
623 | attr3="val2"
624 | attr4
625 | />
626 | text2
627 | </ <!--c--> n>`,
628 | );
629 | });
630 |
631 | test("should handle comment after closeing tag name", () => {
632 | const input = `<n attr="val" attr2>
633 | text1
634 | <n2
635 | attr3="val2"
636 | attr4
637 | />
638 | text2
639 | </n<!--c-->>`;
640 | const result = formatTwice(input);
641 |
642 | expect(result).toEqual(
643 | `<n attr="val" attr2>
644 | text1
645 | <n2
646 | attr3="val2"
647 | attr4
648 | />
649 | text2
650 | </n <!--c-->>`,
651 | );
652 | });
653 |
654 | test("single comment between tags does not break line", () => {
655 | const input = `<n>
656 | <n1 /> <!-- c -->
657 | <n2 />
658 | </n>`;
659 | const result = formatTwice(input);
660 |
661 | expect(result).toEqual(
662 | `<n>
663 | <n1 /> <!-- c -->
664 | <n2 />
665 | </n>`,
666 | );
667 | });
668 |
669 | test("single comment between tags keeps linebreak", () => {
670 | const input = `<n>
671 | <n1 />
672 | <!-- c -->
673 | <n2 />
674 | </n>`;
675 | const result = formatTwice(input);
676 |
677 | expect(result).toEqual(
678 | `<n>
679 | <n1 />
680 | <!-- c -->
681 | <n2 />
682 | </n>`,
683 | );
684 | });
685 |
686 | test("adds newline after single comment between tags", () => {
687 | const input = `<n>
688 | <n1 />
689 | <!-- c --><n2 />
690 | </n>`;
691 | const result = formatTwice(input);
692 |
693 | expect(result).toEqual(
694 | `<n>
695 | <n1 />
696 | <!-- c -->
697 | <n2 />
698 | </n>`,
699 | );
700 | });
701 |
702 | test("single comment as the only content in tag", () => {
703 | const input = `<n> <!-- c --> </n>`;
704 | const result = formatTwice(input);
705 |
706 | expect(result).toEqual(`<n> <!-- c -->
707 | </n>`);
708 | });
709 |
710 | test("2 comments as the only content in tag", () => {
711 | const input = `<n> <!-- c --> <!-- d --> </n>`;
712 | const result = formatTwice(input);
713 |
714 | expect(result).toEqual(
715 | `<n> <!-- c -->
716 | <!-- d -->
717 | </n>`,
718 | );
719 | });
720 |
721 | test("single comment, error node in before attributes", () => {
722 | const input = `<n attr="val" <!-- long, long commonet long, long commonet long, long commonet long, long commonet --> attr2 ? ></n2>`;
723 | const result = formatTwice(input);
724 |
725 | expect(result).toEqual(
726 | `<n
727 | attr="val"
728 | <!-- long, long commonet long, long commonet long, long commonet long, long commonet -->
729 | attr2 ?
730 | ></n2>`,
731 | );
732 | });
733 |
734 | test("single comment before ':' in tag name ", () => {
735 | const input = `<ns<!-- c -->:n attr="val" />`;
736 | const result = formatTwice(input);
737 |
738 | expect(result).toEqual(`<ns <!-- c --> :n attr="val" />`);
739 | });
740 |
741 | test("single comment after ':' in tag name ", () => {
742 | const input = `<ns:<!-- c -->n attr="val" />`;
743 | const result = formatTwice(input);
744 |
745 | expect(result).toEqual(`<ns: <!-- c --> n attr="val" />`);
746 | });
747 |
748 | test("single comment before ':' in attr name", () => {
749 | const input = `<n ns<!-- c -->:attr="val" />`;
750 | const result = formatTwice(input);
751 |
752 | expect(result).toEqual(`<n ns <!-- c --> :attr="val" />`);
753 | });
754 |
755 | test("single comment after ':' in attr name", () => {
756 | const input = `<n ns:<!-- c -->attr="val" />`;
757 | const result = formatTwice(input);
758 |
759 | expect(result).toEqual(`<n ns: <!-- c --> attr="val" />`);
760 | });
761 |
762 | test("should handle comments before eof", () => {
763 | const input = `<Fragment><Text>Content</Text></Fragment>
764 | <!-- This is a comment -->`;
765 | const result = formatTwice(input);
766 |
767 | expect(result).toEqual(
768 | `<Fragment>
769 | <Text>
770 | Content
771 | </Text>
772 | </Fragment>
773 | <!-- This is a comment -->`,
774 | );
775 | });
776 |
777 | test("should handle comments after text, before eof", () => {
778 | const input = `Content <!-- c-->`;
779 | const result = formatTwice(input);
780 |
781 | expect(result).toEqual(`Content <!-- c-->`);
782 | });
783 | });
784 | describe("Edge Cases", () => {
785 | test("should handle empty string", () => {
786 | const result = formatTwice("");
787 | expect(result).toEqual("");
788 | });
789 |
790 | test("should handle whitespace-only string", () => {
791 | const result = formatTwice(" \n \t ");
792 | expect(result).toEqual("");
793 | });
794 |
795 | test("should handle single self-closing tag", () => {
796 | const input = '<Input type="text"/>';
797 | const result = formatTwice(input);
798 |
799 | expect(result).toEqual(`<Input type="text" />`);
800 | });
801 |
802 | test("should handle deeply nested elements", () => {
803 | const input =
804 | "<Fragment><Container><Section><Text>Deep content</Text></Section></Container></Fragment>";
805 | const result = formatTwice(input);
806 |
807 | expect(result).toEqual(
808 | `<Fragment>
809 | <Container>
810 | <Section>
811 | <Text>
812 | Deep content
813 | </Text>
814 | </Section>
815 | </Container>
816 | </Fragment>`,
817 | );
818 | });
819 |
820 | test("should handle mixed content", () => {
821 | const input = "<Text>Before<Bold>bold</Bold>After</Text>";
822 | const result = formatTwice(input);
823 |
824 | expect(result).toEqual(
825 | `<Text>
826 | Before
827 | <Bold>
828 | bold
829 | </Bold>
830 | After
831 | </Text>`,
832 | );
833 | });
834 | });
835 |
836 | describe("Real-world xmlui Examples", () => {
837 | test("should format typical xmlui component", () => {
838 | const input = `<Fragment>
839 | <Text testId="textShort" width="200px">Short</Text>
840 | <Text testId="textLong" width="200px" maxLines="2">
841 | Though this long text does not fit into a single line, please do not break it!
842 | </Text>
843 | </Fragment>`;
844 |
845 | const result = formatTwice(input);
846 |
847 | expect(result).toEqual(
848 | `<Fragment>
849 | <Text testId="textShort" width="200px">
850 | Short
851 | </Text>
852 | <Text testId="textLong" width="200px" maxLines="2">
853 | Though this long text does not fit into a single line, please do not break it!
854 | </Text>
855 | </Fragment>`,
856 | );
857 | });
858 |
859 | test("should format long attribute list in paired tag", () => {
860 | const input =
861 | '<Button testId="submitBtn" variant="primary" size="large" disabled="false" onClick="handleClick">Submit</Button>';
862 | const result = formatTwice(input);
863 |
864 | expect(result).toEqual(
865 | `<Button
866 | testId="submitBtn"
867 | variant="primary"
868 | size="large"
869 | disabled="false"
870 | onClick="handleClick"
871 | >
872 | Submit
873 | </Button>`,
874 | );
875 | });
876 |
877 | test("should format long attribute list in self-closing tag", () => {
878 | const input =
879 | '<Button testId="submitBtn" variant="primary" size="large" disabled="false" onClick="handleClick"/>';
880 | const result = formatTwice(input);
881 |
882 | expect(result).toEqual(
883 | `<Button
884 | testId="submitBtn"
885 | variant="primary"
886 | size="large"
887 | disabled="false"
888 | onClick="handleClick"
889 | />`,
890 | );
891 | });
892 |
893 | test("should format complex xmlui layout", () => {
894 | const input =
895 | "<Fragment><Header><Title>Page Title</Title></Header><Main><Section><Text>Content</Text><Button>Action</Button></Section></Main><Footer><Text>Footer content</Text></Footer></Fragment>";
896 | const result = formatTwice(input);
897 |
898 | expect(result).toEqual(
899 | `<Fragment>
900 | <Header>
901 | <Title>
902 | Page Title
903 | </Title>
904 | </Header>
905 | <Main>
906 | <Section>
907 | <Text>
908 | Content
909 | </Text>
910 | <Button>
911 | Action
912 | </Button>
913 | </Section>
914 | </Main>
915 | <Footer>
916 | <Text>
917 | Footer content
918 | </Text>
919 | </Footer>
920 | </Fragment>`,
921 | );
922 | });
923 | });
924 |
925 | describe("Additional Test Cases", () => {
926 | test("should handle multiple comments in same line", () => {
927 | const input = `<Fragment><!-- comment1 --><!-- comment2 --><Text>Content</Text></Fragment>`;
928 | const result = formatTwice(input);
929 |
930 | expect(result).toEqual(
931 | `<Fragment> <!-- comment1 -->
932 | <!-- comment2 -->
933 | <Text>
934 | Content
935 | </Text>
936 | </Fragment>`,
937 | );
938 | });
939 |
940 | test("should handle XML with namespaces", () => {
941 | const input = `<ns:Fragment xmlns:ns="http://example.com">
942 | <ns:Text>Content</ns:Text>
943 | </ns:Fragment>`;
944 | const result = formatTwice(input);
945 |
946 | expect(result).toEqual(
947 | `<ns:Fragment xmlns:ns="http://example.com">
948 | <ns:Text>
949 | Content
950 | </ns:Text>
951 | </ns:Fragment>`,
952 | );
953 | });
954 |
955 | test("should handle XML with escaped content", () => {
956 | const input = `<Fragment>
957 | <Text><div>Content</div> & "quotes"</Text>
958 | </Fragment>`;
959 | const result = formatTwice(input);
960 |
961 | expect(result).toEqual(
962 | `<Fragment>
963 | <Text>
964 | <div>Content</div> & "quotes"
965 | </Text>
966 | </Fragment>`,
967 | );
968 | });
969 |
970 | test("should handle XML with mixed line endings", () => {
971 | const input = `<Fragment>\r\n<Text>Content</Text>\r\n</Fragment>`;
972 | const result = formatTwice(input);
973 |
974 | expect(result).toEqual(
975 | `<Fragment>
976 | <Text>
977 | Content
978 | </Text>
979 | </Fragment>`,
980 | );
981 | });
982 |
983 | test("should handle XML with trailing whitespace", () => {
984 | const input = `<Fragment/> `;
985 | const result = formatTwice(input);
986 |
987 | expect(result).toEqual(`<Fragment />`);
988 | });
989 |
990 | test("should handle XML with very long lines", () => {
991 | const input = `<Fragment><Text attr1="value1" attr2="value2" attr3="value3" attr4="value4" attr5="value5" attr6="value6" attr7="value7" attr8="value8" attr9="value9" attr10="value10">text content</Text></Fragment>`;
992 | const result = formatTwice(input);
993 |
994 | expect(result).toEqual(
995 | `<Fragment>
996 | <Text
997 | attr1="value1"
998 | attr2="value2"
999 | attr3="value3"
1000 | attr4="value4"
1001 | attr5="value5"
1002 | attr6="value6"
1003 | attr7="value7"
1004 | attr8="value8"
1005 | attr9="value9"
1006 | attr10="value10"
1007 | >
1008 | text content
1009 | </Text>
1010 | </Fragment>`,
1011 | );
1012 | });
1013 | });
1014 | });
1015 |
1016 | function formatFromString(
1017 | input: string,
1018 | options: FormatOptions = { tabSize: 2, insertSpaces: true },
1019 | ) {
1020 | const parser = createXmlUiParser(input);
1021 | const { node } = parser.parse();
1022 | const defaultOptions: FormatOptions = { insertSpaces: true, tabSize: 2, ...options };
1023 |
1024 | return format(node, parser.getText, defaultOptions);
1025 | }
1026 |
1027 | /* also tests idempotency */
1028 | function formatTwice(input: string, options: FormatOptions = { tabSize: 2, insertSpaces: true }) {
1029 | const firstFormat = formatFromString(input, options);
1030 | const secondFormat = formatFromString(firstFormat, options);
1031 |
1032 | expect(firstFormat).toBe(secondFormat);
1033 | return firstFormat;
1034 | }
1035 |
```
--------------------------------------------------------------------------------
/xmlui/src/components-core/theming/themes/root.ts:
--------------------------------------------------------------------------------
```typescript
1 | import type { ThemeDefinition } from "../../../abstractions/ThemingDefs";
2 | import { palette } from "./palette";
3 |
4 | const {
5 | $colorSurface0,
6 | $colorSurface50,
7 | $colorSurface100,
8 | $colorSurface200A80,
9 | $colorSurface200A70,
10 | $colorSurface200,
11 | $colorSurface300,
12 | $colorSurface400,
13 | $colorSurface500,
14 | $colorSurface500A80,
15 | $colorSurface500A60,
16 | $colorSurface600,
17 | $colorSurface700,
18 | $colorSurface800,
19 | $colorSurface900,
20 | $colorSurface950,
21 |
22 | $colorPrimary50,
23 | $colorPrimary950,
24 |
25 | $colorWarn700,
26 |
27 | $colorDanger400,
28 | $colorDanger500,
29 | $colorDanger600,
30 | $colorDanger700,
31 |
32 | $colorSuccess600,
33 |
34 | $colorInfo600,
35 | $colorInfo800,
36 | } = palette;
37 |
38 | // --- This theme contains the application-bound base theme variables and their default values.
39 | // --- Individual controls also add their component-specific default theme variable values.
40 | export const RootThemeDefinition: ThemeDefinition = {
41 | id: "root",
42 | resources: {
43 | // "font.inter": "https://rsms.me/inter/inter.css",
44 | },
45 | themeVars: {
46 | // --- The unit of measurement for all sizes/spaces
47 | "space-base": "0.25rem",
48 |
49 | // --- Default surface color shades (form white to black)
50 | "const-color-surface-0": "white",
51 | "const-color-surface-50": "hsl(204, 30.3%, 96.5%)",
52 | "const-color-surface-100": "hsl(204, 30.3%, 93%)",
53 | "const-color-surface-200": "hsl(204, 30.3%, 85%)",
54 | "const-color-surface-300": "hsl(204, 30.3%, 75%)",
55 | "const-color-surface-400": "hsl(204, 30.3%, 65%)",
56 | "const-color-surface-500": "hsl(204, 30.3%, 52%)", // #6894AD
57 | "const-color-surface-600": "hsl(204, 30.3%, 45%)",
58 | "const-color-surface-700": "hsl(204, 30.3%, 35%)",
59 | "const-color-surface-800": "hsl(204, 30.3%, 27%)",
60 | "const-color-surface-900": "hsl(204, 30.3%, 16%)",
61 | "const-color-surface-950": "hsl(204, 30.3%, 13%)",
62 | "const-color-surface-1000": "hsl(204, 30.3%, 9%)",
63 | "const-color-surface": "$const-color-surface-500",
64 |
65 | // --- Primary color shades (bluish)
66 | "const-color-primary-50": "hsl(212,71.9%,94.5%)",
67 | "const-color-primary-100": "hsl(212,71.9%,89.1%)",
68 | "const-color-primary-200": "hsl(212,71.9%,78.1%)",
69 | "const-color-primary-300": "hsl(212,71.9%,67.2%)",
70 | "const-color-primary-400": "hsl(212,71.9%,56.3%)",
71 | "const-color-primary-500": "#206bc4",
72 | "const-color-primary-600": "hsl(212,71.9%,36.3%)",
73 | "const-color-primary-700": "hsl(212,71.9%,27.2%)",
74 | "const-color-primary-800": "hsl(212,71.9%,18.1%)",
75 | "const-color-primary-900": "hsl(212,71.9%,9.1%)",
76 | "const-color-primary-950": "hsl(212,71.9%,4.5%)",
77 | "const-color-primary": "$const-color-primary-500",
78 |
79 | // --- Secondary color shades (steel-bluish)
80 | "const-color-secondary-50": "hsl(211.7,21.2%,96.9%)",
81 | "const-color-secondary-100": "hsl(211.7,21.2%,93.7%)",
82 | "const-color-secondary-200": "hsl(211.7,21.2%,87.4%)",
83 | "const-color-secondary-300": "hsl(211.7,21.2%,81.1%)",
84 | "const-color-secondary-400": "hsl(211.7,21.2%,74.8%)",
85 | "const-color-secondary-500": "#6c7a91",
86 | "const-color-secondary-600": "hsl(211.7,21.2%,54.8%)",
87 | "const-color-secondary-700": "hsl(211.7,21.2%,41.1%)",
88 | "const-color-secondary-800": "hsl(211.7,21.2%,27.4%)",
89 | "const-color-secondary-900": "hsl(211.7,21.2%,13.7%)",
90 | "const-color-secondary-950": "hsl(211.7,21.2%,6.9%)",
91 | "const-color-secondary": "$const-color-secondary-500",
92 |
93 | // --- Warning color shades (orange shades)
94 | "const-color-warn-50": "hsl(45, 100%, 97%)",
95 | "const-color-warn-100": "hsl(45, 100%, 91%)",
96 | "const-color-warn-200": "hsl(45, 100%, 80%)",
97 | "const-color-warn-300": "hsl(45, 100%, 70%)",
98 | "const-color-warn-400": "hsl(45, 100%, 60%)",
99 | "const-color-warn-500": "hsl(35, 100%, 50%)", // #ff980a
100 | "const-color-warn-600": "hsl(35, 100%, 45%)",
101 | "const-color-warn-700": "hsl(35, 100%, 40%)",
102 | "const-color-warn-800": "hsl(35, 100%, 35%)",
103 | "const-color-warn-900": "hsl(35, 100%, 30%)",
104 | "const-color-warn-950": "hsl(35, 100%, 15%)",
105 | "const-color-warn": "$const-color-warn-500",
106 |
107 | // --- Danger color shades (reddish)
108 | "const-color-danger-50": "hsl(356, 100%, 95%)",
109 | "const-color-danger-100": "hsl(356, 100%, 91%)",
110 | "const-color-danger-200": "hsl(356, 100%, 80%)",
111 | "const-color-danger-300": "hsl(356, 100%, 70%)",
112 | "const-color-danger-400": "hsl(356, 100%, 60%)",
113 | "const-color-danger-500": "hsl(356, 100%, 50%)", // #ff3240
114 | "const-color-danger-600": "hsl(356, 100%, 45%)",
115 | "const-color-danger-700": "hsl(356, 100%, 40%)",
116 | "const-color-danger-800": "hsl(356, 100%, 35%)",
117 | "const-color-danger-900": "hsl(356, 100%, 30%)",
118 | "const-color-danger-950": "hsl(356, 100%, 15%)",
119 | "const-color-danger": "$const-color-danger-600",
120 | "const-color-attention": "$const-color-danger-500",
121 |
122 | // --- Success color shades (greenish)
123 | "const-color-success-50": "hsl(129.5, 58.4%, 96.4%)",
124 | "const-color-success-100": "hsl(129.5, 58.4%, 92.9%)",
125 | "const-color-success-200": "hsl(129.5, 58.4%, 85.7%)",
126 | "const-color-success-300": "hsl(129.5, 58.4%, 78.6%)",
127 | "const-color-success-400": "hsl(129.5, 58.4%, 71.5%)",
128 | "const-color-success-500": "hsl(129.5, 58.4%, 51.5%)", // #2fb344
129 | "const-color-success-600": "hsl(129.5, 58.4%, 45%)",
130 | "const-color-success-700": "hsl(129.5, 58.4%, 38.6%)",
131 | "const-color-success-800": "hsl(129.5, 58.4%, 25.7%)",
132 | "const-color-success-900": "hsl(129.5, 58.4%, 12.9%)",
133 | "const-color-success-950": "hsl(129.5, 58.4%, 6.4%)",
134 | "const-color-success": "$const-color-success-500",
135 |
136 | "const-color-info-50": "hsl(183, 97%, 95%)",
137 | "const-color-info-100": "hsl(183, 97%, 90%)",
138 | "const-color-info-200": "hsl(183, 97%, 80%)",
139 | "const-color-info-300": "hsl(183, 97%, 70%)",
140 | "const-color-info-400": "hsl(183, 97%, 60%)",
141 | "const-color-info-500": "hsl(183, 97%, 50%)", // #02C4CE
142 | "const-color-info-600": "hsl(183, 97%, 45%)",
143 | "const-color-info-700": "hsl(183, 97%, 35%)",
144 | "const-color-info-800": "hsl(183, 97%, 25%)",
145 | "const-color-info-900": "hsl(183, 97%, 15%)",
146 | "const-color-info-950": "hsl(183, 97%, 10%)",
147 |
148 | // --- Font weights
149 | "fontWeight-light": "300",
150 | "fontWeight-normal": "400",
151 | "fontWeight-medium": "500",
152 | "fontWeight-bold": "600",
153 | "fontWeight-extra-bold": "900",
154 |
155 | // --- Default text colors (component use these values as their defaults)
156 | "textColor-primary": "$color-surface-950",
157 | "textColor-attention": "$color-danger-600",
158 | "textColor-subtitle": "$color-surface-500",
159 | "textColor--disabled": "$color-surface-400",
160 |
161 | // --- Default background colors (component use these values as their defaults)
162 | "backgroundColor-primary": "$color-surface-50",
163 | "backgroundColor-secondary": "$color-surface-50",
164 | "backgroundColor-attention": "$color-attention",
165 | "backgroundColor--disabled": "$color-surface-50",
166 | "backgroundColor--selected": "$color-primary-50",
167 |
168 | // --- Various default colors
169 | "color-info": "$color-info-500",
170 | "color-valid": "$color-success-600",
171 | "color-warning": "$color-warn-700",
172 | "color-error": "$color-danger-500",
173 |
174 | // --- The sans-serif font set
175 | "fontFamily-sans-serif":
176 | "'Inter', -apple-system, BlinkMacSystemFont, San Francisco, Segoe UI, Roboto, Helvetica Neue, sans-serif",
177 |
178 | // --- The monospace font set
179 | "fontFamily-monospace": "Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace",
180 | "font-feature-settings": "'cv03', 'cv04', 'cv11'",
181 |
182 | // --- Some media breakpoints (review them)
183 | "maxWidth-phone": "576px",
184 | "maxWidth-landscape-phone": "768px",
185 | "maxWidth-tablet": "992px",
186 | "maxWidth-desktop": "1200px",
187 | "maxWidth-large-desktop": "1400px",
188 |
189 | // --- The app's default radius value
190 | borderRadius: "4px",
191 | "outlineColor--focus": "rgb(from $color-primary-500 r g b / 0.5)",
192 | "outlineWidth--focus": "2px",
193 | "outlineStyle--focus": "solid",
194 | "outlineOffset--focus": "0",
195 |
196 | // --- The app's default font family
197 | fontFamily: "$fontFamily-sans-serif",
198 |
199 | // --- Various font sizes (relative to the current context)
200 | "fontSize-tiny": "0.625rem",
201 | "fontSize-xs": "0.75rem",
202 | "fontSize-code": "0.85rem",
203 | "fontSize-sm": "0.875rem",
204 | "fontSize-base": "1rem",
205 | "fontSize-lg": "1.125rem",
206 | "fontSize-xl": "1.25rem",
207 | "fontSize-2xl": "1.5rem",
208 | "fontSize-3xl": "1.875rem",
209 | "fontSize-4xl": "2.25rem",
210 | "fontSize-5xl": "3rem",
211 | "fontSize-6xl": "3.75rem",
212 | "fontSize-7xl": "4.5rem",
213 | "fontSize-8xl": "6rem",
214 | "fontSize-9xl": "8rem",
215 |
216 | // --- The default font size
217 | fontSize: "$fontSize-base",
218 |
219 | // --- Various line height values
220 | // --- Default line height values (relative to the base unit, "space-base")
221 | "lineHeight-none": "1",
222 | "lineHeight-tight": "1.25",
223 | "lineHeight-snug": "1.375",
224 | "lineHeight-normal": "1.5",
225 | "lineHeight-relaxed": "1.625",
226 | "lineHeight-loose": "2",
227 |
228 | // --- Predefined gap sizes
229 | "gap-none": "$space-0",
230 | "gap-tight": "$space-2",
231 | "gap-normal": "$space-4",
232 | "gap-loose": "$space-8",
233 |
234 | // --- Predefined paddings
235 | "padding-none": "$space-0",
236 | "padding-tight": "$space-2",
237 | "padding-normal": "$space-4",
238 | "padding-loose": "$space-8",
239 |
240 | // --- Predefined spaces
241 | "space-none": "$space-0",
242 | "space-tight": "$space-2",
243 | "space-normal": "$space-4",
244 | "space-loose": "$space-8",
245 |
246 | // --- Font used for body
247 | fontWeight: "$fontWeight-normal",
248 |
249 | // --- Various default values (review them)
250 | "borderColor-dropdown-item": "$borderColor",
251 |
252 | // --- Various predefined shadow values
253 | boxShadow: "0 1px 3px 0 rgba(0, 0, 0, .1), 0 1px 2px 0 rgba(0, 0, 0, .06)",
254 | "boxShadow-md": "0 4px 6px -1px rgba(0, 0, 0, .1), 0 2px 4px -1px rgba(0, 0, 0, .06)",
255 | "boxShadow-xl":
256 | "0 16px 24px 2px rgba(0, 0, 0, 0.07), 0 6px 30px 5px rgba(0, 0, 0, 0.06), 0 8px 10px -5px rgba(0, 0, 0, 0.1)",
257 | "boxShadow-xxl": "0 8px 17px 0 rgba(0, 0, 0, .2), 0 6px 20px 0 rgba(0, 0, 0, .19)",
258 | "boxShadow-spread": "0px 0px 30px rgba(0, 0, 0, 0.1)",
259 | "boxShadow-spread-2": "-6px -4px 40px 10px rgba(0, 0, 0, 0.1)",
260 | "boxShadow-spread-2-xl": "-6px -4px 40px 18px rgba(0, 0, 0, 0.1)",
261 |
262 | // --- The default maximum content width
263 | "maxWidth-content": "1280px",
264 |
265 | // --- The default maximum content column width
266 | "maxWidth-columnContent": "800px",
267 |
268 | // --- Background colors
269 | backgroundColor: "$color-surface-subtle",
270 | "backgroundColor-overlay": "rgba(0, 0, 0, 0.2)",
271 | "backgroundColor-dropdown-item--hover": $colorSurface50,
272 | "backgroundColor-dropdown-item--active": $colorSurface100,
273 | "backgroundColor-dropdown-item--active-hover": $colorSurface50,
274 | "backgroundColor-tree-row--selected--before": $colorPrimary50,
275 |
276 | // --- Border colors
277 | borderColor: "rgb(from $color-surface-900 r g b / 0.1)",
278 | "borderColor--disabled": $colorSurface100,
279 |
280 | // --- Text colors
281 | "textColor-secondary": $colorSurface600,
282 |
283 | // --- Input is an abstract component, so we define its default theme variables here
284 | "backgroundColor-Input-default": $colorSurface0,
285 | "backgroundColor-Input-success": $colorSurface0,
286 | "backgroundColor-Input-warning": $colorSurface0,
287 | "backgroundColor-Input-error": $colorSurface0,
288 |
289 | "borderColor-Input-default": $colorSurface200,
290 | "borderColor-Input-default--hover": $colorSurface600,
291 | "borderColor-Input-default--focus": $colorSurface600,
292 | "borderColor-Input-default--success": $colorSuccess600,
293 | "borderColor-Input-default--warning": $colorWarn700,
294 | "borderColor-Input-default--error": $colorDanger500,
295 |
296 | // --- InputLabel is a React component, so we define its default theme variables here
297 | "textColor-InputLabel-required": $colorDanger600,
298 | },
299 | tones: {
300 | light: {
301 | themeVars: {
302 | // --- Default surface color shades (form white to black)
303 | "color-surface-0": "$const-color-surface-0",
304 | "color-surface-50": "$const-color-surface-50",
305 | "color-surface-100": "$const-color-surface-100",
306 | "color-surface-200": "$const-color-surface-200",
307 | "color-surface-300": "$const-color-surface-300",
308 | "color-surface-400": "$const-color-surface-400",
309 | "color-surface-500": "$const-color-surface-500",
310 | "color-surface-600": "$const-color-surface-600",
311 | "color-surface-700": "$const-color-surface-700",
312 | "color-surface-800": "$const-color-surface-800",
313 | "color-surface-900": "$const-color-surface-900",
314 | "color-surface-950": "$const-color-surface-950",
315 | "color-surface-1000": "$const-color-surface-1000",
316 | "color-surface": "$const-color-surface-500",
317 | "color-surface-base": "$color-surface-0",
318 | "color-surface-lower": "$color-surface-100",
319 | "color-surface-raised": "$color-surface-0",
320 | "color-surface-subtle": "$color-surface-50",
321 |
322 | // --- Primary color shades (bluish)
323 | "color-primary-50": "$const-color-primary-50",
324 | "color-primary-100": "$const-color-primary-100",
325 | "color-primary-200": "$const-color-primary-200",
326 | "color-primary-300": "$const-color-primary-300",
327 | "color-primary-400": "$const-color-primary-400",
328 | "color-primary-500": "$const-color-primary-500",
329 | "color-primary-600": "$const-color-primary-600",
330 | "color-primary-700": "$const-color-primary-700",
331 | "color-primary-800": "$const-color-primary-800",
332 | "color-primary-900": "$const-color-primary-900",
333 | "color-primary-950": "$const-color-primary-950",
334 | "color-primary": "$const-color-primary-500",
335 |
336 | // --- Secondary color shades (steel-bluish)
337 | "color-secondary-50": "$const-color-secondary-50",
338 | "color-secondary-100": "$const-color-secondary-100",
339 | "color-secondary-200": "$const-color-secondary-200",
340 | "color-secondary-300": "$const-color-secondary-300",
341 | "color-secondary-400": "$const-color-secondary-400",
342 | "color-secondary-500": "$const-color-secondary-500",
343 | "color-secondary-600": "$const-color-secondary-600",
344 | "color-secondary-700": "$const-color-secondary-700",
345 | "color-secondary-800": "$const-color-secondary-800",
346 | "color-secondary-900": "$const-color-secondary-900",
347 | "color-secondary-950": "$const-color-secondary-950",
348 | "color-secondary": "$const-color-secondary-500",
349 |
350 | // --- Warning color shades (orange shades)
351 | "color-warn-50": "$const-color-warn-50",
352 | "color-warn-100": "$const-color-warn-100",
353 | "color-warn-200": "$const-color-warn-200",
354 | "color-warn-300": "$const-color-warn-300",
355 | "color-warn-400": "$const-color-warn-400",
356 | "color-warn-500": "$const-color-warn-500",
357 | "color-warn-600": "$const-color-warn-600",
358 | "color-warn-700": "$const-color-warn-700",
359 | "color-warn-800": "$const-color-warn-800",
360 | "color-warn-900": "$const-color-warn-900",
361 | "color-warn-950": "$const-color-warn-950",
362 | "color-warn": "$const-color-warn-500",
363 |
364 | // --- Danger color shades (reddish)
365 | "color-danger-50": "$const-color-danger-50",
366 | "color-danger-100": "$const-color-danger-100",
367 | "color-danger-200": "$const-color-danger-200",
368 | "color-danger-300": "$const-color-danger-300",
369 | "color-danger-400": "$const-color-danger-400",
370 | "color-danger-500": "$const-color-danger-500",
371 | "color-danger-600": "$const-color-danger-600",
372 | "color-danger-700": "$const-color-danger-700",
373 | "color-danger-800": "$const-color-danger-800",
374 | "color-danger-900": "$const-color-danger-900",
375 | "color-danger-950": "$const-color-danger-950",
376 | "color-danger": "$const-color-danger-600",
377 | "color-attention": "$const-color-danger-500",
378 |
379 | // --- Success color shades (greenish)
380 | "color-success-50": "$const-color-success-50",
381 | "color-success-100": "$const-color-success-100",
382 | "color-success-200": "$const-color-success-200",
383 | "color-success-300": "$const-color-success-300",
384 | "color-success-400": "$const-color-success-400",
385 | "color-success-500": "$const-color-success-500",
386 | "color-success-600": "$const-color-success-600",
387 | "color-success-700": "$const-color-success-700",
388 | "color-success-800": "$const-color-success-800",
389 | "color-success-900": "$const-color-success-900",
390 | "color-success-950": "$const-color-success-950",
391 | "color-success": "$const-color-success-500",
392 |
393 | "color-info-50 ": "$const-color-info-50 ",
394 | "color-info-100": "$const-color-info-100",
395 | "color-info-200": "$const-color-info-200",
396 | "color-info-300": "$const-color-info-300",
397 | "color-info-400": "$const-color-info-400",
398 | "color-info-500": "$const-color-info-500",
399 | "color-info-600": "$const-color-info-600",
400 | "color-info-700": "$const-color-info-700",
401 | "color-info-800": "$const-color-info-800",
402 | "color-info-900": "$const-color-info-900",
403 | "color-info-950": "$const-color-info-950",
404 | "color-info": "$const-color-info-800",
405 | },
406 | },
407 | dark: {
408 | themeVars: {
409 | // --- Default surface color shades (form white to black)
410 | "color-surface-0": "$const-color-surface-1000",
411 | "color-surface-50": "$const-color-surface-950",
412 | "color-surface-100": "$const-color-surface-900",
413 | "color-surface-200": "$const-color-surface-800",
414 | "color-surface-300": "$const-color-surface-700",
415 | "color-surface-400": "$const-color-surface-600",
416 | "color-surface-500": "$const-color-surface-500",
417 | "color-surface-600": "$const-color-surface-400",
418 | "color-surface-700": "$const-color-surface-300",
419 | "color-surface-800": "$const-color-surface-200",
420 | "color-surface-900": "$const-color-surface-100",
421 | "color-surface-950": "$const-color-surface-50",
422 | "color-surface-1000": "$const-color-surface-0",
423 | "color-surface": "$const-color-surface-500",
424 | "color-surface-base": "$color-surface-0",
425 | "color-surface-lower": "$color-surface-0",
426 | "color-surface-raised": "$color-surface-100",
427 | "color-surface-subtle": "$color-surface-50",
428 |
429 | // --- Primary color shades (bluish)
430 | "color-primary-50": "$const-color-primary-950",
431 | "color-primary-100": "$const-color-primary-900",
432 | "color-primary-200": "$const-color-primary-800",
433 | "color-primary-300": "$const-color-primary-700",
434 | "color-primary-400": "$const-color-primary-600",
435 | "color-primary-500": "$const-color-primary-500",
436 | "color-primary-600": "$const-color-primary-400",
437 | "color-primary-700": "$const-color-primary-300",
438 | "color-primary-800": "$const-color-primary-200",
439 | "color-primary-900": "$const-color-primary-100",
440 | "color-primary-950": "$const-color-primary-50",
441 | "color-primary": "$const-color-primary-500",
442 |
443 | // --- Secondary color shades (steel-bluish)
444 | "color-secondary-50": "$const-color-secondary-950",
445 | "color-secondary-100": "$const-color-secondary-900",
446 | "color-secondary-200": "$const-color-secondary-800",
447 | "color-secondary-300": "$const-color-secondary-700",
448 | "color-secondary-400": "$const-color-secondary-600",
449 | "color-secondary-500": "$const-color-secondary-500",
450 | "color-secondary-600": "$const-color-secondary-400",
451 | "color-secondary-700": "$const-color-secondary-300",
452 | "color-secondary-800": "$const-color-secondary-200",
453 | "color-secondary-900": "$const-color-secondary-100",
454 | "color-secondary-950": "$const-color-secondary-50",
455 | "color-secondary": "$const-color-secondary-500",
456 |
457 | // --- Warning color shades (orange shades)
458 | "color-warn-50": "$const-color-warn-950",
459 | "color-warn-100": "$const-color-warn-900",
460 | "color-warn-200": "$const-color-warn-800",
461 | "color-warn-300": "$const-color-warn-700",
462 | "color-warn-400": "$const-color-warn-600",
463 | "color-warn-500": "$const-color-warn-500",
464 | "color-warn-600": "$const-color-warn-400",
465 | "color-warn-700": "$const-color-warn-300",
466 | "color-warn-800": "$const-color-warn-200",
467 | "color-warn-900": "$const-color-warn-100",
468 | "color-warn-950": "$const-color-warn-50",
469 | "color-warn": "$const-color-warn-500",
470 |
471 | // --- Danger color shades (reddish)
472 | "color-danger-50": "$const-color-danger-950",
473 | "color-danger-100": "$const-color-danger-900",
474 | "color-danger-200": "$const-color-danger-800",
475 | "color-danger-300": "$const-color-danger-700",
476 | "color-danger-400": "$const-color-danger-600",
477 | "color-danger-500": "$const-color-danger-500",
478 | "color-danger-600": "$const-color-danger-400",
479 | "color-danger-700": "$const-color-danger-300",
480 | "color-danger-800": "$const-color-danger-200",
481 | "color-danger-900": "$const-color-danger-100",
482 | "color-danger-950": "$const-color-danger-50",
483 | "color-danger": "$const-color-danger-500",
484 | "color-attention": "$const-color-danger-400",
485 |
486 | // --- Success color shades (greenish)
487 | "color-success-50": "$const-color-success-950",
488 | "color-success-100": "$const-color-success-900",
489 | "color-success-200": "$const-color-success-800",
490 | "color-success-300": "$const-color-success-700",
491 | "color-success-400": "$const-color-success-600",
492 | "color-success-500": "$const-color-success-500",
493 | "color-success-600": "$const-color-success-400",
494 | "color-success-700": "$const-color-success-300",
495 | "color-success-800": "$const-color-success-200",
496 | "color-success-900": "$const-color-success-100",
497 | "color-success-950": "$const-color-success-50",
498 | "color-success": "$const-color-success-500",
499 |
500 | "color-info-50 ": "$const-color-info-950 ",
501 | "color-info-100": "$const-color-info-900",
502 | "color-info-200": "$const-color-info-800",
503 | "color-info-300": "$const-color-info-700",
504 | "color-info-400": "$const-color-info-600",
505 | "color-info-500": "$const-color-info-500",
506 | "color-info-600": "$const-color-info-400",
507 | "color-info-700": "$const-color-info-300",
508 | "color-info-800": "$const-color-info-200",
509 | "color-info-900": "$const-color-info-100",
510 | "color-info-950": "$const-color-info-50",
511 | "color-info": "$const-color-info-200",
512 | },
513 | },
514 | },
515 | };
516 |
```