This is page 98 of 191. Use http://codebase.md/xmlui-org/xmlui/0.9.23.js?format=md&lines=true&page={x} to view the full context.

# Directory Structure

```
├── .changeset
│   └── config.json
├── .eslintrc.cjs
├── .github
│   ├── build-checklist.png
│   ├── ISSUE_TEMPLATE
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   └── workflows
│       ├── deploy-blog-optimized.yml
│       ├── deploy-blog-swa.yml
│       ├── deploy-blog.yml
│       ├── deploy-docs-optimized.yml
│       ├── deploy-docs-swa.yml
│       ├── deploy-docs.yml
│       ├── prepare-versions.yml
│       ├── release-packages.yml
│       ├── run-all-tests.yml
│       └── run-smoke-tests.yml
├── .gitignore
├── .prettierrc.js
├── .vscode
│   ├── launch.json
│   └── settings.json
├── blog
│   ├── .gitignore
│   ├── .gitkeep
│   ├── CHANGELOG.md
│   ├── extensions.ts
│   ├── index.html
│   ├── index.ts
│   ├── package.json
│   ├── public
│   │   ├── blog
│   │   │   ├── images
│   │   │   │   ├── an-advanced-codefence.gif
│   │   │   │   ├── an-advanced-codefence.mp4
│   │   │   │   ├── blog-page-component.png
│   │   │   │   ├── blog-scrabble.png
│   │   │   │   ├── codefence-runner.png
│   │   │   │   ├── integrated-blog-search.png
│   │   │   │   ├── lorem-ipsum.png
│   │   │   │   ├── playground-checkbox-source.png
│   │   │   │   ├── playground.png
│   │   │   │   ├── use-xmlui-mcp-to-find-a-howto.png
│   │   │   │   └── xmlui-demo-gallery.png
│   │   │   ├── introducing-xmlui.md
│   │   │   ├── lorem-ipsum.md
│   │   │   ├── newest-post.md
│   │   │   ├── older-post.md
│   │   │   ├── xmlui-playground.md
│   │   │   └── xmlui-powered-blog.md
│   │   ├── mockServiceWorker.js
│   │   ├── resources
│   │   │   ├── favicon.ico
│   │   │   ├── files
│   │   │   │   └── for-download
│   │   │   │       └── xmlui
│   │   │   │           └── xmlui-standalone.umd.js
│   │   │   ├── github.svg
│   │   │   ├── 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
│   │   │   ├── ResponsiveBar.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
    │   │   │   ├── ResponsiveBarItem.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/src/components/NumberBox/NumberBoxNative.tsx:
--------------------------------------------------------------------------------

```typescript
  1 | import React, {
  2 |   type CSSProperties,
  3 |   type ForwardedRef,
  4 |   forwardRef,
  5 |   useCallback,
  6 |   useEffect,
  7 |   useId,
  8 |   useRef,
  9 | } from "react";
 10 | import classnames from "classnames";
 11 | 
 12 | import styles from "./NumberBox.module.scss";
 13 | 
 14 | import type { RegisterComponentApiFn, UpdateStateFn } from "../../abstractions/RendererDefs";
 15 | import { noop } from "../../components-core/constants";
 16 | import { useEvent } from "../../components-core/utils/misc";
 17 | import {
 18 |   clamp,
 19 |   DECIMAL_SEPARATOR,
 20 |   DEFAULT_STEP,
 21 |   EXPONENTIAL_SEPARATOR,
 22 |   FLOAT_REGEXP,
 23 |   INT_REGEXP,
 24 |   isEmptyLike,
 25 |   mapToRepresentation,
 26 |   NUMBERBOX_MAX_VALUE,
 27 |   toUsableNumber,
 28 | } from "./numberbox-abstractions";
 29 | import { type ValidationStatus } from "../abstractions";
 30 | import { Icon } from "../Icon/IconNative";
 31 | import { Adornment } from "../Input/InputAdornment";
 32 | import { Button } from "../Button/ButtonNative";
 33 | import { PART_END_ADORNMENT, PART_INPUT, PART_START_ADORNMENT } from "../../components-core/parts";
 34 | 
 35 | const PART_SPINNER_UP = "spinnerUp";
 36 | const PART_SPINNER_DOWN = "spinnerDown";
 37 | 
 38 | // Default props for NumberBox component
 39 | export const defaultProps = {
 40 |   enabled: true,
 41 |   validationStatus: "none" as ValidationStatus,
 42 |   hasSpinBox: true,
 43 |   integersOnly: false,
 44 |   zeroOrPositive: false,
 45 |   min: -NUMBERBOX_MAX_VALUE,
 46 |   max: NUMBERBOX_MAX_VALUE,
 47 |   step: 1,
 48 |   updateState: noop,
 49 |   onDidChange: noop,
 50 |   onFocus: noop,
 51 |   onBlur: noop,
 52 | };
 53 | 
 54 | // =====================================================================================================================
 55 | // React NumberBox component definition
 56 | 
 57 | type Props = {
 58 |   id?: string;
 59 |   value?: number | string | null;
 60 |   initialValue?: number | string | null;
 61 |   style?: CSSProperties;
 62 |   className?: string;
 63 |   step?: number | string;
 64 |   enabled?: boolean;
 65 |   placeholder?: string;
 66 |   hasSpinBox?: boolean;
 67 |   validationStatus?: ValidationStatus;
 68 |   min?: number;
 69 |   max?: number;
 70 |   maxLength?: number;
 71 |   integersOnly?: boolean;
 72 |   zeroOrPositive?: boolean;
 73 |   updateState?: UpdateStateFn;
 74 |   onDidChange?: (newValue: number | string | null | undefined) => void;
 75 |   onFocus?: () => void;
 76 |   onBlur?: () => void;
 77 |   registerComponentApi?: RegisterComponentApiFn;
 78 |   startText?: string;
 79 |   startIcon?: string;
 80 |   endText?: string;
 81 |   endIcon?: string;
 82 |   gap?: string;
 83 |   spinnerUpIcon?: string;
 84 |   spinnerDownIcon?: string;
 85 |   autoFocus?: boolean;
 86 |   readOnly?: boolean;
 87 |   required?: boolean;
 88 |   direction?: "ltr" | "rtl";
 89 | };
 90 | 
 91 | export const NumberBox = forwardRef(function NumberBox(
 92 |   {
 93 |     id,
 94 |     value,
 95 |     initialValue,
 96 |     style,
 97 |     className,
 98 |     enabled = defaultProps.enabled,
 99 |     placeholder,
100 |     validationStatus = defaultProps.validationStatus,
101 |     hasSpinBox = defaultProps.hasSpinBox,
102 |     step = defaultProps.step,
103 |     integersOnly = defaultProps.integersOnly,
104 |     zeroOrPositive = defaultProps.zeroOrPositive,
105 |     min = zeroOrPositive ? 0 : defaultProps.min,
106 |     max = defaultProps.max,
107 |     maxLength,
108 |     updateState = defaultProps.updateState,
109 |     onDidChange = defaultProps.onDidChange,
110 |     onFocus = defaultProps.onFocus,
111 |     onBlur = defaultProps.onBlur,
112 |     registerComponentApi,
113 |     startText,
114 |     startIcon,
115 |     endText,
116 |     endIcon,
117 |     gap,
118 |     spinnerUpIcon,
119 |     spinnerDownIcon,
120 |     autoFocus,
121 |     readOnly,
122 |     required,
123 |     direction,
124 |     ...rest
125 |   }: Props,
126 |   forwardedRef: ForwardedRef<HTMLDivElement>,
127 | ) {
128 |   const _id = useId();
129 |   id = id || _id;
130 |   // --- Ensure the provided value is a number or null
131 | 
132 |   // Ensure the provided minimum is not smaller than the 0 if zeroOrPositive is set to true
133 |   min = Math.max(zeroOrPositive ? 0 : -NUMBERBOX_MAX_VALUE, min);
134 | 
135 |   // Step must be an integer since floating point arithmetic needs a deeper dive.
136 |   // probably some way to integrate with https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat
137 |   // since there are footguns, like 0.1 + 0.2 = 0.0000...04
138 |   const _step = toUsableNumber(step, true) ?? DEFAULT_STEP;
139 | 
140 |   const inputRef = useRef<HTMLInputElement>(null);
141 |   const upButton = useRef<HTMLButtonElement>(null);
142 |   const downButton = useRef<HTMLButtonElement>(null);
143 | 
144 |   useEffect(() => {
145 |     if (autoFocus) {
146 |       setTimeout(() => {
147 |         inputRef.current?.focus();
148 |       }, 0);
149 |     }
150 |   }, [autoFocus]);
151 | 
152 |   // --- Convert to representable string value (from number | null | undefined)
153 |   const [valueStrRep, setValueStrRep] = React.useState<string>(mapToRepresentation(value));
154 |   useEffect(() => {
155 |     setValueStrRep(mapToRepresentation(value));
156 |   }, [value]);
157 | 
158 |   // --- Initialize the related field with the input's initial value
159 |   useEffect(() => {
160 |     updateState({ value: initialValue }, { initial: true });
161 |   }, [initialValue, updateState]);
162 | 
163 |   // --- Handle the value change events for this input
164 |   const updateValue = useCallback(
165 |     (newValue: string | number | null | undefined, rep: string) => {
166 |       setValueStrRep(rep);
167 |       updateState({ value: newValue });
168 |       onDidChange(newValue);
169 |     },
170 |     [onDidChange, updateState],
171 |   );
172 | 
173 |   // --- Keypress
174 |   const onInputChange = useCallback(
175 |     (event: React.ChangeEvent<HTMLInputElement>) => {
176 |       // const newValue = sanitizeInput(event.target.value.trim(), value, integersOnly, zeroOrPositive, min, max);
177 |       // if (!newValue) return;
178 |       // updateValue(newValue[0], newValue[1]);
179 |       const value = event.target.value;
180 |       const repr = value;
181 |       updateValue(value, repr);
182 |     },
183 |     [updateValue],
184 |   );
185 | 
186 |   // --- Stepper logic
187 |   const handleIncStep = useCallback(() => {
188 |     if (readOnly) return;
189 |     const newValue = applyStep(valueStrRep, _step, min, max, integersOnly);
190 | 
191 |     if (newValue === undefined) return;
192 |     updateValue(newValue, newValue.toString());
193 |   }, [valueStrRep, _step, min, max, integersOnly, updateValue, readOnly]);
194 | 
195 |   const handleDecStep = useCallback(() => {
196 |     if (readOnly) return;
197 |     const newValue = applyStep(valueStrRep, -_step, min, max, integersOnly);
198 | 
199 |     if (newValue === undefined) return;
200 |     updateValue(newValue, newValue.toString());
201 |   }, [valueStrRep, _step, min, max, integersOnly, updateValue, readOnly]);
202 | 
203 |   // --- Register stepper logic to buttons
204 |   useLongPress(upButton.current, handleIncStep);
205 |   useLongPress(downButton.current, handleDecStep);
206 | 
207 |   // --- Shared character validation logic
208 |   const processCharacterInput = useCallback(
209 |     (
210 |       char: string,
211 |       currentValue: string,
212 |       currentPos: number,
213 |       predictedValue: string,
214 |       isForPaste: boolean = false,
215 |     ): {
216 |       shouldAccept: boolean;
217 |       newValue?: string;
218 |       newPos?: number;
219 |       shouldPreventDefault?: boolean;
220 |     } => {
221 |       // --- Are the caret after the exponential separator?
222 |       const beforeCaret = currentValue.substring(0, currentPos);
223 |       const expPos = beforeCaret.indexOf(EXPONENTIAL_SEPARATOR);
224 | 
225 |       let shouldAccept = true;
226 |       let shouldPreventDefault = false;
227 |       let newValue = currentValue;
228 |       let newPos = currentPos;
229 | 
230 |       switch (char) {
231 |         case "-":
232 |           shouldAccept = false;
233 |           shouldPreventDefault = true;
234 |           if (zeroOrPositive) {
235 |             // --- No minus sign allowed
236 |             break;
237 |           }
238 |           if (expPos === -1) {
239 |             // --- Change the first char to "-" if we are before the exponential separator and it's not already there
240 |             if (!currentValue.startsWith("-")) {
241 |               newValue = "-" + currentValue;
242 |               newPos = currentPos + 1;
243 |             }
244 |           } else {
245 |             // --- Change the char after the exponential separator to "-" if it's not already there
246 |             if (currentValue[expPos + 1] !== "-") {
247 |               newValue =
248 |                 currentValue.substring(0, expPos + 1) + "-" + currentValue.substring(expPos + 1);
249 |               newPos = currentPos + 1;
250 |             }
251 |           }
252 |           break;
253 |         case "+":
254 |           shouldAccept = false;
255 |           shouldPreventDefault = true;
256 |           if (expPos === -1) {
257 |             // --- Remove the first char if it's "-" and we are before the exponential separator
258 |             if (currentValue.startsWith("-")) {
259 |               newValue = currentValue.substring(1);
260 |               newPos = Math.max(0, currentPos - 1);
261 |             }
262 |           } else {
263 |             // --- Remove the char after the exponential separator if it's "-"
264 |             if (currentValue[expPos + 1] === "-") {
265 |               newValue = currentValue.substring(0, expPos + 1) + currentValue.substring(expPos + 2);
266 |               newPos = Math.max(expPos + 1, currentPos - 1);
267 |             }
268 |           }
269 |           break;
270 |         case "0":
271 |           // --- Prevent leading zeros (before decimal or exponential separator)
272 |           if (currentValue === "0") {
273 |             shouldAccept = false;
274 |             shouldPreventDefault = true;
275 |           }
276 |           break;
277 |         case "1":
278 |         case "2":
279 |         case "3":
280 |         case "4":
281 |         case "5":
282 |         case "6":
283 |         case "7":
284 |         case "8":
285 |         case "9":
286 |           // --- Replace leading zero with this digit
287 |           if (currentValue === "0" && currentPos === 1) {
288 |             if (isForPaste) {
289 |               newValue = char;
290 |               shouldAccept = false; // Don't add it again for paste
291 |             } else {
292 |               newValue = char;
293 |               newPos = 1;
294 |               shouldPreventDefault = true;
295 |             }
296 |           }
297 |           break;
298 |         case DECIMAL_SEPARATOR:
299 |           // --- Prevent multiple decimal separators (integers only),
300 |           // --- or decimal separator after the exponential separator
301 |           if (integersOnly || currentValue.includes(DECIMAL_SEPARATOR) || expPos !== -1) {
302 |             shouldAccept = false;
303 |             shouldPreventDefault = true;
304 |           } else if (predictedValue.startsWith(DECIMAL_SEPARATOR) && currentPos === 0) {
305 |             newValue = "0" + predictedValue;
306 |             newPos = currentPos + 2;
307 |             shouldPreventDefault = true;
308 |           }
309 |           break;
310 |         case EXPONENTIAL_SEPARATOR:
311 |           // --- Prevent exponential notation for integers
312 |           if (integersOnly) {
313 |             shouldAccept = false;
314 |             shouldPreventDefault = true;
315 |             break;
316 |           }
317 |           // --- Prevent multiple exponential separators
318 |           if (currentValue.includes(EXPONENTIAL_SEPARATOR)) {
319 |             shouldAccept = false;
320 |             shouldPreventDefault = true;
321 |           }
322 |           break;
323 |         default:
324 |           // --- Only allow digits for single characters
325 |           if (char >= "0" && char <= "9") {
326 |             // --- Prevent digits before minus sign
327 |             if (currentValue.startsWith("-") && currentPos === 0) {
328 |               shouldAccept = false;
329 |               shouldPreventDefault = true;
330 |               break;
331 |             }
332 | 
333 |             // --- For beforeInput, check for too many digits after exponential separator
334 |             if (!isForPaste && expPos !== -1) {
335 |               const tooManyDigitsAfterExponentialSeparator = (
336 |                 pos: number,
337 |                 maxDigits: number,
338 |               ): boolean => {
339 |                 let numDigitsAfter = 0;
340 |                 while (pos < currentValue.length) {
341 |                   if (/\d/.test(currentValue[pos++])) {
342 |                     numDigitsAfter++;
343 |                   } else {
344 |                     numDigitsAfter = maxDigits + 1;
345 |                     break;
346 |                   }
347 |                 }
348 |                 return numDigitsAfter > maxDigits;
349 |               };
350 | 
351 |               if (tooManyDigitsAfterExponentialSeparator(expPos + 1, 1)) {
352 |                 shouldAccept = false;
353 |                 shouldPreventDefault = true;
354 |               }
355 |             }
356 |           } else {
357 |             // --- Reject non-digit characters
358 |             shouldAccept = false;
359 |             shouldPreventDefault = true;
360 |           }
361 |           break;
362 |       }
363 | 
364 |       return { shouldAccept, newValue, newPos, shouldPreventDefault };
365 |     },
366 |     [integersOnly, zeroOrPositive],
367 |   );
368 | 
369 |   // --- This logic prevents the user from typing invalid characters (in the current typing context)
370 |   const handleOnBeforeInput = (event: any) => {
371 |     const currentValue: string = event.target.value ?? "";
372 |     const currentPos = event.target.selectionStart;
373 |     const expectedNewValue =
374 |       currentValue.substring(0, currentPos) +
375 |       event.data +
376 |       currentValue.substring(event.target.selectionEnd);
377 | 
378 |     // --- Handle multi-character input (paste) through the legacy path
379 |     if (event.data?.length > 1) {
380 |       let shouldPreventDefault = false;
381 |       const selectionStart = event.target.selectionStart;
382 |       let newInput = event.data;
383 | 
384 |       // --- Decide whether to accept the optional sign character
385 |       if (newInput.startsWith("-")) {
386 |         if (selectionStart > 0) {
387 |           shouldPreventDefault = true;
388 |         }
389 |       } else if (newInput.startsWith("+")) {
390 |         shouldPreventDefault = true;
391 |       }
392 | 
393 |       if (!shouldPreventDefault) {
394 |         // --- Check for integers
395 |         if (integersOnly && !INT_REGEXP.test(expectedNewValue)) {
396 |           // --- The result is not an integer, drop the pasted input
397 |           shouldPreventDefault = true;
398 |         } else if (!FLOAT_REGEXP.test(expectedNewValue)) {
399 |           // --- The result is not a float, drop the pasted input
400 |           shouldPreventDefault = true;
401 |         }
402 |       }
403 | 
404 |       if (shouldPreventDefault) {
405 |         event.preventDefault();
406 |       }
407 |       return;
408 |     }
409 | 
410 |     // --- Single character processing
411 |     const result = processCharacterInput(
412 |       event.data,
413 |       currentValue,
414 |       currentPos,
415 |       expectedNewValue,
416 |       false,
417 |     );
418 | 
419 |     if (result.shouldPreventDefault) {
420 |       event.preventDefault();
421 |     }
422 | 
423 |     // --- Apply value changes if needed
424 |     if (result.newValue !== currentValue) {
425 |       const setNewValue = (newValue: string, pos: number) => {
426 |         event.target.value = newValue;
427 |         updateValue(newValue, newValue);
428 |         inputRef.current?.setSelectionRange(pos, pos);
429 |       };
430 |       setNewValue(result.newValue!, result.newPos!);
431 |     }
432 |   };
433 | 
434 |   // --- Handle paste events by applying the same character validation logic
435 |   const handleOnPaste = useCallback(
436 |     (event: React.ClipboardEvent<HTMLInputElement>) => {
437 |       event.preventDefault();
438 | 
439 |       const pastedText = event.clipboardData.getData("text/plain");
440 |       if (!pastedText) return;
441 | 
442 |       const inputElement = event.currentTarget;
443 |       const currentValue = inputElement.value ?? "";
444 |       const selectionStart = inputElement.selectionStart ?? 0;
445 |       const selectionEnd = inputElement.selectionEnd ?? 0;
446 |       const expectedNewValue =
447 |         currentValue.substring(0, selectionStart) +
448 |         pastedText +
449 |         currentValue.substring(selectionEnd);
450 | 
451 |       // --- Start with the value before the selection
452 |       let resultValue = currentValue.substring(0, selectionStart);
453 |       let currentPos = selectionStart;
454 | 
455 |       // --- Process each character from the pasted text
456 |       for (let i = 0; i < pastedText.length; i++) {
457 |         const char = pastedText[i];
458 | 
459 |         const result = processCharacterInput(char, resultValue, currentPos, expectedNewValue, true);
460 | 
461 |         if (result.shouldAccept) {
462 |           resultValue =
463 |             resultValue.substring(0, currentPos) + char + resultValue.substring(currentPos);
464 |           currentPos++;
465 |         } else if (result.newValue !== resultValue) {
466 |           // --- Handle special cases like sign changes or zero replacement
467 |           resultValue = result.newValue!;
468 |           currentPos = result.newPos!;
469 |         }
470 |       }
471 | 
472 |       // --- Add the rest of the original value after the selection
473 |       resultValue += currentValue.substring(selectionEnd);
474 | 
475 |       // --- Final validation - ensure the result is a valid number format
476 |       let isValidFinal = false;
477 |       if (integersOnly) {
478 |         isValidFinal = INT_REGEXP.test(resultValue) || resultValue === "" || resultValue === "-";
479 |       } else {
480 |         isValidFinal = FLOAT_REGEXP.test(resultValue) || resultValue === "" || resultValue === "-";
481 |       }
482 | 
483 |       // --- Apply the result if valid
484 |       if (isValidFinal) {
485 |         inputElement.value = resultValue;
486 |         updateValue(resultValue, resultValue);
487 |         inputElement.setSelectionRange(currentPos, currentPos);
488 |       }
489 |     },
490 |     [processCharacterInput, updateValue, integersOnly],
491 |   );
492 | 
493 |   // --- Setting steppers with keyboard
494 |   const handleOnKey = useCallback(
495 |     (event: React.KeyboardEvent<HTMLInputElement>) => {
496 |       if (event.code === "ArrowUp") {
497 |         event.preventDefault();
498 |         handleIncStep();
499 |       }
500 |       if (event.code === "ArrowDown") {
501 |         event.preventDefault();
502 |         handleDecStep();
503 |       }
504 |     },
505 |     [handleIncStep, handleDecStep],
506 |   );
507 | 
508 |   // --- Manage obtaining and losing focus & blur
509 |   const handleOnFocus = useCallback(() => {
510 |     onFocus?.();
511 |   }, [onFocus]);
512 | 
513 |   const handleOnBlur = useCallback(() => {
514 |     // --- Get the current input value
515 |     const currentInputValue = inputRef.current?.value ?? "";
516 | 
517 |     // --- Check if we need to add a trailing zero
518 |     let finalValue = currentInputValue;
519 |     if (!integersOnly && currentInputValue.endsWith(DECIMAL_SEPARATOR)) {
520 |       // --- Add trailing zero if the value ends with decimal separator
521 |       finalValue = currentInputValue + "0";
522 |     }
523 | 
524 |     // --- Convert to number and clamp to min/max bounds
525 |     const numericValue = toUsableNumber(finalValue, integersOnly);
526 |     if (!isEmptyLike(numericValue)) {
527 |       const clampedValue = clamp(numericValue, min, max);
528 |       if (clampedValue !== numericValue) {
529 |         const clampedString = clampedValue.toString();
530 |         finalValue = clampedString;
531 | 
532 |         // --- Update the input field immediately
533 |         if (inputRef.current) {
534 |           inputRef.current.value = clampedString;
535 |         }
536 |       }
537 |     }
538 | 
539 |     // --- Update the state if the final value is different from current input
540 |     if (finalValue !== currentInputValue) {
541 |       updateValue(finalValue, finalValue);
542 |     } else {
543 |       // --- Use the standard representation mapping
544 |       setValueStrRep(mapToRepresentation(value));
545 |     }
546 | 
547 |     onBlur?.();
548 |   }, [value, onBlur, integersOnly, updateValue, min, max]);
549 | 
550 |   const focus = useCallback(() => {
551 |     inputRef.current?.focus();
552 |   }, []);
553 | 
554 |   const setValue = useEvent((newValue) => {
555 |     updateValue(newValue, isEmptyLike(newValue) ? "" : String(newValue));
556 |   });
557 | 
558 |   useEffect(() => {
559 |     registerComponentApi?.({
560 |       focus,
561 |       setValue,
562 |     });
563 |   }, [focus, registerComponentApi, setValue]);
564 | 
565 |   return (
566 |       <div
567 |         {...rest}
568 |         className={classnames(className, styles.inputRoot,{
569 |           [styles.readOnly]: readOnly,
570 |           [styles.disabled]: !enabled,
571 |           [styles.noSpinBox]: !hasSpinBox,
572 |           [styles.error]: validationStatus === "error",
573 |           [styles.warning]: validationStatus === "warning",
574 |           [styles.valid]: validationStatus === "valid",
575 |           [styles.rtl]: direction === "rtl",
576 |         })}
577 |         id={id}
578 |         ref={forwardedRef}
579 |         tabIndex={-1}
580 |         onFocus={() => {
581 |           inputRef.current?.focus();
582 |         }}
583 |         style={{ ...style, gap }}
584 |       >
585 |         <Adornment
586 |           data-part-id={PART_START_ADORNMENT}
587 |           text={startText}
588 |           iconName={startIcon}
589 |           className={classnames(styles.adornment)}
590 |         />
591 |         <input
592 |           id={id}
593 |           data-part-id={PART_INPUT}
594 |           type="text"
595 |           inputMode="numeric"
596 |           className={classnames(styles.input, {
597 |             [styles.readOnly]: readOnly,
598 |           })}
599 |           disabled={!enabled}
600 |           value={valueStrRep}
601 |           step={step}
602 |           placeholder={placeholder}
603 |           onChange={onInputChange}
604 |           onFocus={handleOnFocus}
605 |           onBlur={handleOnBlur}
606 |           onBeforeInput={handleOnBeforeInput}
607 |           onPaste={handleOnPaste}
608 |           onKeyDown={handleOnKey}
609 |           readOnly={readOnly}
610 |           ref={inputRef}
611 |           autoFocus={autoFocus}
612 |           maxLength={maxLength}
613 |           required={required}
614 |         />
615 |         <Adornment
616 |           data-part-id={PART_END_ADORNMENT}
617 |           text={endText}
618 |           iconName={endIcon}
619 |           className={classnames(styles.adornment)}
620 |         />
621 |         {hasSpinBox && (
622 |           <div className={styles.spinnerBox}>
623 |             <Button
624 |               data-part-id={PART_SPINNER_UP}
625 |               data-spinner="up"
626 |               type="button"
627 |               role="spinbutton"
628 |               variant={"ghost"}
629 |               themeColor={"secondary"}
630 |               tabIndex={-1}
631 |               className={styles.spinnerButton}
632 |               disabled={!enabled || readOnly}
633 |               ref={upButton}
634 |             >
635 |               <Icon name={spinnerUpIcon || "spinnerUp:NumberBox"} fallback="chevronup" size="sm" />
636 |             </Button>
637 |             <Button
638 |               data-part-id={PART_SPINNER_DOWN}
639 |               data-spinner="down"
640 |               type="button"
641 |               role="spinbutton"
642 |               tabIndex={-1}
643 |               variant={"ghost"}
644 |               themeColor={"secondary"}
645 |               className={styles.spinnerButton}
646 |               disabled={!enabled || readOnly}
647 |               ref={downButton}
648 |             >
649 |               <Icon
650 |                 name={spinnerDownIcon || "spinnerDown:NumberBox"}
651 |                 fallback="chevrondown"
652 |                 size="sm"
653 |               />
654 |             </Button>
655 |           </div>
656 |         )}
657 |       </div>
658 |   );
659 | });
660 | 
661 | function applyStep(
662 |   valueStrRep: string,
663 |   step: number,
664 |   min: number,
665 |   max: number,
666 |   integersOnly: boolean,
667 | ) {
668 |   const currentValue = toUsableNumber(valueStrRep, integersOnly);
669 |   if (isEmptyLike(currentValue)) {
670 |     return;
671 |   }
672 |   return clamp(currentValue + step, min, max);
673 | }
674 | 
675 | function useLongPress(elementRef: HTMLElement | null, action: () => void, delay: number = 500) {
676 |   const timeoutId = useRef(0);
677 |   const intervalId = useRef(0);
678 |   const savedAction = useRef<() => void>(action);
679 | 
680 |   // Remember the latest action callback, since it is different every render
681 |   useEffect(() => {
682 |     savedAction.current = action;
683 |   }, [action]);
684 | 
685 |   useEffect(() => {
686 |     const onMouseDown = () => {
687 |       savedAction.current?.();
688 | 
689 |       timeoutId.current = window.setTimeout(() => {
690 |         intervalId.current = window.setInterval(() => {
691 |           savedAction.current?.();
692 |         }, 100);
693 |       }, delay);
694 |     };
695 | 
696 |     const onMouseUp = () => {
697 |       clearTimeout(timeoutId.current);
698 |       clearInterval(intervalId.current);
699 |     };
700 | 
701 |     const onMouseOut = () => {
702 |       clearTimeout(timeoutId.current);
703 |       clearInterval(intervalId.current);
704 |     };
705 | 
706 |     elementRef?.addEventListener("mousedown", onMouseDown);
707 |     elementRef?.addEventListener("mouseup", onMouseUp);
708 |     elementRef?.addEventListener("mouseout", onMouseOut);
709 | 
710 |     return () => {
711 |       elementRef?.removeEventListener("mousedown", onMouseDown);
712 |       elementRef?.removeEventListener("mouseup", onMouseUp);
713 |       elementRef?.removeEventListener("mouseout", onMouseOut);
714 |     };
715 |   }, [elementRef, action, delay]);
716 | }
717 | 
```

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

```markdown
  1 | # NumberBox [#numberbox]
  2 | 
  3 | `NumberBox` provides a specialized input field for numeric values with built-in validation, spinner buttons, and flexible formatting options. It supports both integer and floating-point numbers, handles empty states as null values, and integrates seamlessly with form validation.
  4 | 
  5 | **Key features:**
  6 | - **Flexible numeric input**: Accepts integers, floating-point numbers, or empty values (stored as null)
  7 | - **Input constraints**: Configure minimum/maximum values, integer-only mode, and positive-only restrictions
  8 | - **Spinner buttons**: Built-in increment/decrement buttons with customizable step values and icons
  9 | - **Visual adornments**: Add icons or text to the start and end of the input field
 10 | - **Validation**: Built-in validation status indicators and form compatibility
 11 | - **Smart paste handling**: Only accepts pasted content that results in valid numeric values
 12 | 
 13 | The `NumberBox` is often used in forms. See the [this guide](/forms) for details.
 14 | 
 15 | ## Properties [#properties]
 16 | 
 17 | ### `autoFocus` (default: false) [#autofocus-default-false]
 18 | 
 19 | If this property is set to `true`, the component gets the focus automatically when displayed.
 20 | 
 21 | If this boolean prop is set to true, the `NumberBox` input will be focused when appearing on the UI.
 22 | 
 23 | ### `enabled` (default: true) [#enabled-default-true]
 24 | 
 25 | This boolean property value indicates whether the component responds to user events (`true`) or not (`false`).
 26 | 
 27 | Controls whether the input field is enabled (`true`) or disabled (`false`).
 28 | 
 29 | ```xmlui-pg copy display name="Example: enabled"
 30 | <App>
 31 |   <NumberBox enabled="false" />
 32 | </App>
 33 | ```
 34 | 
 35 | ### `endIcon` [#endicon]
 36 | 
 37 | This property sets an optional icon to appear on the end (right side when the left-to-right direction is set) of the input.
 38 | 
 39 | This string prop enables the display of an icon on the right side (left-to-right display) of the input field by providing a valid [icon name]().
 40 | 
 41 | ```xmlui-pg copy display name="Example: endIcon"
 42 | <App>
 43 |   <NumberBox endIcon="email" />
 44 | </App>
 45 | ```
 46 | 
 47 | It is possible to set the other adornments as well: [`endText`](#endtext), [`startIcon`](#starticon) and [`startText`](#starttext).
 48 | 
 49 | ```xmlui-pg copy display name="Example: all adornments"
 50 | <App>
 51 |   <NumberBox startIcon="hyperlink" startText="www." endIcon="email" endText=".com" />
 52 | </App>
 53 | ```
 54 | 
 55 | ### `endText` [#endtext]
 56 | 
 57 | This property sets an optional text to appear on the end (right side when the left-to-right direction is set) of the input.
 58 | 
 59 | This string prop enables the display of a custom string on the right side (left-to-right display) of the input field.
 60 | 
 61 | ```xmlui-pg copy display name="Example: endText"
 62 | <App>
 63 |   <NumberBox endText=".com" />
 64 | </App>
 65 | ```
 66 | 
 67 | It is possible to set the other adornments as well: [`endIcon`](#endicon), [`startIcon`](#starticon) and [`startText`](#starttext).
 68 | 
 69 | ```xmlui-pg copy display name="Example: all adornments"
 70 | <App>
 71 |   <NumberBox startIcon="hyperlink" startText="www." endIcon="email" endText=".com" />
 72 | </App>
 73 | ```
 74 | 
 75 | ### `gap` [#gap]
 76 | 
 77 | This property defines the gap between the adornments and the input area.
 78 | 
 79 | ### `hasSpinBox` (default: true) [#hasspinbox-default-true]
 80 | 
 81 | This boolean prop shows (`true`) or hides (`false`) the spinner buttons for the input field.
 82 | 
 83 | ```xmlui-pg copy display name="Example: hasSpinBox"
 84 | <App>
 85 |   <NumberBox hasSpinBox="true" initialValue="3" />
 86 |   <NumberBox hasSpinBox="false" initialValue="34" />
 87 | </App>
 88 | ```
 89 | 
 90 | ### `initialValue` [#initialvalue]
 91 | 
 92 | This property sets the component's initial value.
 93 | 
 94 | The initial value displayed in the input field.
 95 | 
 96 | ```xmlui-pg copy display name="Example: initialValue"
 97 | <App>
 98 |   <NumberBox initialValue="123" />
 99 | </App>
100 | ```
101 | 
102 | ### `integersOnly` (default: false) [#integersonly-default-false]
103 | 
104 | This boolean property signs whether the input field accepts integers only (`true`) or not (`false`).
105 | 
106 | ```xmlui-pg copy display name="Example: integersOnly"
107 | <App>
108 |   <NumberBox integersOnly="true" initialValue="42" />
109 |   <NumberBox integersOnly="false" initialValue="{Math.PI}" />
110 | </App>
111 | ```
112 | 
113 | ### `maxLength` [#maxlength]
114 | 
115 | This property sets the maximum length of the input it accepts.
116 | 
117 | ### `maxValue` (default: 999999999999999) [#maxvalue-default-999999999999999]
118 | 
119 | The maximum value the input field allows. Can be a float or an integer if [`integersOnly`](#integersonly) is set to `false`, otherwise it can only be an integer.If not set, no maximum value check is done.
120 | 
121 | The maximum value the input field allows.
122 | Can be a float or an integer if [`integersOnly`](#integersonly) is set to `false`,
123 | otherwise it can only be an integer.
124 | 
125 | Try to enter a bigger value into the input field below than the maximum allowed.
126 | 
127 | ```xmlui-pg copy display name="Example: maxValue"
128 | <App>
129 |   <NumberBox maxValue="100" initialValue="99" />
130 | </App>
131 | ```
132 | 
133 | ### `minValue` (default: -999999999999999) [#minvalue-default-999999999999999]
134 | 
135 | The minimum value the input field allows. Can be a float or an integer if [`integersOnly`](#integersonly) is set to `false`, otherwise it can only be an integer.If not set, no minimum value check is done.
136 | 
137 | Try to enter a bigger value into the input field below than the minimum allowed.
138 | 
139 | ```xmlui-pg copy display name="Example: minValue"
140 | <App>
141 |   <NumberBox minValue="-100" initialValue="-99" />
142 | </App>
143 | ```
144 | 
145 | ### `placeholder` [#placeholder]
146 | 
147 | An optional placeholder text that is visible in the input field when its empty.
148 | 
149 | A placeholder text that is visible in the input field when its empty.
150 | 
151 | ```xmlui-pg copy display name="Example: placeholder"
152 | <App>
153 |   <NumberBox placeholder="This is a placeholder" />
154 | </App>
155 | ```
156 | 
157 | ### `readOnly` (default: false) [#readonly-default-false]
158 | 
159 | Set this property to `true` to disallow changing the component value.
160 | 
161 | If true, the component's value cannot be modified with user interactions.
162 | 
163 | ```xmlui-pg copy display name="Example: readOnly"
164 | <App>
165 |   <NumberBox initialValue="123" readOnly="true" />
166 | </App>
167 | ```
168 | 
169 | ### `required` (default: false) [#required-default-false]
170 | 
171 | Set this property to `true` to indicate it must have a value before submitting the containing form.
172 | 
173 | ### `spinnerDownIcon` [#spinnerdownicon]
174 | 
175 | Allows setting an alternate icon displayed in the NumberBox spinner for decrementing values. You can change the default icon for all NumberBox instances with the "icon.spinnerDown:NumberBox" declaration in the app configuration file.
176 | 
177 | ### `spinnerUpIcon` [#spinnerupicon]
178 | 
179 | Allows setting an alternate icon displayed in the NumberBox spinner for incrementing values. You can change the default icon for all NumberBox instances with the "icon.spinnerUp:NumberBox" declaration in the app configuration file.
180 | 
181 | ### `startIcon` [#starticon]
182 | 
183 | This property sets an optional icon to appear at the start (left side when the left-to-right direction is set) of the input.
184 | 
185 | This string prop enables the display of an icon on the left side (left-to-right display) of the input field by providing a valid [icon name]().
186 | 
187 | ```xmlui-pg copy display name="Example: startIcon"
188 | <App>
189 |   <NumberBox startIcon="hyperlink" />
190 | </App>
191 | ```
192 | 
193 | It is possible to set the other adornments as well: [`endText`](#endtext), [`startIcon`](#starticon) and [`startText`](#starttext).
194 | 
195 | ```xmlui-pg copy display name="Example: all adornments"
196 | <App>
197 |   <NumberBox startIcon="hyperlink" startText="www." endIcon="email" endText=".com" />
198 | </App>
199 | ```
200 | 
201 | ### `startText` [#starttext]
202 | 
203 | This property sets an optional text to appear at the start (left side when the left-to-right direction is set) of the input.
204 | 
205 | This string prop enables the display of a custom string on the left side (left-to-right display) of the input field.
206 | 
207 | ```xmlui-pg copy display name="Example: startText"
208 | <App>
209 |   <NumberBox startText="www." />
210 | </App>
211 | ```
212 | 
213 | It is possible to set the other adornments as well: [`endIcon`](#endicon), [`startIcon`](#starticon) and [`endText`](#endtext).
214 | 
215 | ```xmlui-pg copy display name="Example: all adornments"
216 | <App>
217 |   <NumberBox startIcon="hyperlink" startText="www." endIcon="email" endText=".com" />
218 | </App>
219 | ```
220 | 
221 | ### `step` (default: 1) [#step-default-1]
222 | 
223 | This prop governs how big the step when clicking on the spinner of the field.
224 | 
225 | The default stepping value is **1**.
226 | 
227 | Note that only integers are allowed to be entered.
228 | 
229 | ```xmlui-pg copy display name="Example: step"
230 | <App>
231 |   <NumberBox initialValue="10" step="10" />
232 | </App>
233 | ```
234 | 
235 | ### `validationStatus` (default: "none") [#validationstatus-default-none]
236 | 
237 | This property allows you to set the validation status of the input component.
238 | 
239 | Available values:
240 | 
241 | | Value | Description |
242 | | --- | --- |
243 | | `valid` | Visual indicator for an input that is accepted |
244 | | `warning` | Visual indicator for an input that produced a warning |
245 | | `error` | Visual indicator for an input that produced an error |
246 | 
247 | This prop is used to visually indicate status changes reacting to form field validation.
248 | 
249 | | Value     | Description                                           |
250 | | :-------- | :---------------------------------------------------- |
251 | | `valid`   | Visual indicator for an input that is accepted        |
252 | | `warning` | Visual indicator for an input that produced a warning |
253 | | `error`   | Visual indicator for an input that produced an error  |
254 | 
255 | ```xmlui-pg copy display name="Example: validationStatus"
256 | <App>
257 |   <NumberBox />
258 |   <NumberBox validationStatus="valid" />
259 |   <NumberBox validationStatus="warning" />
260 |   <NumberBox validationStatus="error" />
261 | </App>
262 | ```
263 | 
264 | ### `zeroOrPositive` (default: false) [#zeroorpositive-default-false]
265 | 
266 | This boolean property determines whether the input value can only be 0 or positive numbers (`true`) or also negative (`false`).
267 | 
268 | This boolean property determines whether the input value can only be 0 or positive numbers (`true`) or also negative (`false`).
269 | By default, this property is set to `false`.
270 | 
271 | ```xmlui-pg copy display name="Example: zeroOrPositive"
272 | <App>
273 |   <NumberBox initialValue="123" zeroOrPositive="true" />
274 | </App>
275 | ```
276 | 
277 | ## Events [#events]
278 | 
279 | ### `didChange` [#didchange]
280 | 
281 | This event is triggered when value of NumberBox has changed.
282 | 
283 | This event is triggered after the user has changed the field value.
284 | 
285 | Write in the input field and see how the `Text` underneath it is updated in parallel.
286 | 
287 | ```xmlui-pg copy {2} display name="Example: didChange"
288 | <App var.field="0">
289 |   <NumberBox initialValue="{field}" onDidChange="(val) => field = val" />
290 |   <Text value="{field}" />
291 | </App>
292 | ```
293 | 
294 | ### `gotFocus` [#gotfocus]
295 | 
296 | This event is triggered when the NumberBox has received the focus.
297 | 
298 | This event is triggered when the `NumberBox` receives focus. The following sample demonstrates this event.
299 | 
300 | ```xmlui-pg
301 | ---app copy {3-4} display name="Example: gotFocus"
302 | <App var.focused="{false}">
303 |   <NumberBox
304 |     onGotFocus="focused = true"
305 |     onLostFocus="focused = false" />
306 |   <Text>The NumberBox is {focused ? '' : 'not'} focused</Text>
307 | </App>
308 | ---desc
309 | Click into the `NumberBox` (and then click the text below):
310 | ```
311 | 
312 | ### `lostFocus` [#lostfocus]
313 | 
314 | This event is triggered when the NumberBox has lost the focus.
315 | 
316 | This event is triggered when the `NumberBox` loses focus.
317 | 
318 | (See the example above)
319 | 
320 | ## Exposed Methods [#exposed-methods]
321 | 
322 | ### `focus` [#focus]
323 | 
324 | This API focuses the input field of the `NumberBox`. You can use it to programmatically focus the field.
325 | 
326 | **Signature**: `focus(): void`
327 | 
328 | ### `setValue` [#setvalue]
329 | 
330 | This API sets the value of the `NumberBox`. You can use it to programmatically change the value.
331 | 
332 | **Signature**: `setValue(value: number | undefined): void`
333 | 
334 | You can use this method to set the component's current value programmatically.
335 | 
336 | ```xmlui-pg copy {3, 9, 12} display name="Example: value and setValue"
337 | <App>
338 |   <NumberBox
339 |     id="numberbox"
340 |     readOnly="true"
341 |   />
342 |   <HStack>
343 |     <Button
344 |       label="Set to 100"
345 |       onClick="numberbox.setValue(100)" />
346 |     <Button
347 |       label="Set to 0"
348 |       onClick="numberbox.setValue(0)" />
349 |   </HStack>
350 | </App>
351 | ```
352 | 
353 | ### `value` [#value]
354 | 
355 | This API retrieves the current value of the `NumberBox`. You can use it to get the value programmatically.
356 | 
357 | **Signature**: `get value(): number | undefined`
358 | 
359 | You can query this read-only API property to get the input component's current value.
360 | 
361 | See an example in the `setValue` API method.
362 | 
363 | ## Parts [#parts]
364 | 
365 | The component has some parts that can be styled through layout properties and theme variables separately:
366 | 
367 | - **`endAdornment`**: The adornment displayed at the end of the text box.
368 | - **`input`**: The text box input area.
369 | - **`label`**: The label displayed for the text box.
370 | - **`startAdornment`**: The adornment displayed at the start of the text box.
371 | 
372 | ## Styling [#styling]
373 | 
374 | ### Theme Variables [#theme-variables]
375 | 
376 | | Variable | Default Value (Light) | Default Value (Dark) |
377 | | --- | --- | --- |
378 | | [backgroundColor](../styles-and-themes/common-units/#color)-NumberBox--default | *none* | *none* |
379 | | [backgroundColor](../styles-and-themes/common-units/#color)-NumberBox--default--focus | *none* | *none* |
380 | | [backgroundColor](../styles-and-themes/common-units/#color)-NumberBox--default--hover | *none* | *none* |
381 | | [backgroundColor](../styles-and-themes/common-units/#color)-NumberBox--disabled | *none* | *none* |
382 | | [backgroundColor](../styles-and-themes/common-units/#color)-NumberBox--error | *none* | *none* |
383 | | [backgroundColor](../styles-and-themes/common-units/#color)-NumberBox--error--focus | *none* | *none* |
384 | | [backgroundColor](../styles-and-themes/common-units/#color)-NumberBox--error--hover | *none* | *none* |
385 | | [backgroundColor](../styles-and-themes/common-units/#color)-NumberBox--success | *none* | *none* |
386 | | [backgroundColor](../styles-and-themes/common-units/#color)-NumberBox--success--focus | *none* | *none* |
387 | | [backgroundColor](../styles-and-themes/common-units/#color)-NumberBox--success--hover | *none* | *none* |
388 | | [backgroundColor](../styles-and-themes/common-units/#color)-NumberBox--warning | *none* | *none* |
389 | | [backgroundColor](../styles-and-themes/common-units/#color)-NumberBox--warning--focus | *none* | *none* |
390 | | [backgroundColor](../styles-and-themes/common-units/#color)-NumberBox--warning--hover | *none* | *none* |
391 | | [borderColor](../styles-and-themes/common-units/#color)-NumberBox--default | *none* | *none* |
392 | | [borderColor](../styles-and-themes/common-units/#color)-NumberBox--default--focus | *none* | *none* |
393 | | [borderColor](../styles-and-themes/common-units/#color)-NumberBox--default--hover | *none* | *none* |
394 | | [borderColor](../styles-and-themes/common-units/#color)-NumberBox--disabled | *none* | *none* |
395 | | [borderColor](../styles-and-themes/common-units/#color)-NumberBox--error | *none* | *none* |
396 | | [borderColor](../styles-and-themes/common-units/#color)-NumberBox--error--focus | *none* | *none* |
397 | | [borderColor](../styles-and-themes/common-units/#color)-NumberBox--error--hover | *none* | *none* |
398 | | [borderColor](../styles-and-themes/common-units/#color)-NumberBox--success | *none* | *none* |
399 | | [borderColor](../styles-and-themes/common-units/#color)-NumberBox--success--focus | *none* | *none* |
400 | | [borderColor](../styles-and-themes/common-units/#color)-NumberBox--success--hover | *none* | *none* |
401 | | [borderColor](../styles-and-themes/common-units/#color)-NumberBox--warning | *none* | *none* |
402 | | [borderColor](../styles-and-themes/common-units/#color)-NumberBox--warning--focus | *none* | *none* |
403 | | [borderColor](../styles-and-themes/common-units/#color)-NumberBox--warning--hover | *none* | *none* |
404 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-NumberBox--default | *none* | *none* |
405 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-NumberBox--error | *none* | *none* |
406 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-NumberBox--success | *none* | *none* |
407 | | [borderRadius](../styles-and-themes/common-units/#border-rounding)-NumberBox--warning | *none* | *none* |
408 | | [borderStyle](../styles-and-themes/common-units/#border-style)-NumberBox--default | *none* | *none* |
409 | | [borderStyle](../styles-and-themes/common-units/#border-style)-NumberBox--error | *none* | *none* |
410 | | [borderStyle](../styles-and-themes/common-units/#border-style)-NumberBox--success | *none* | *none* |
411 | | [borderStyle](../styles-and-themes/common-units/#border-style)-NumberBox--warning | *none* | *none* |
412 | | [borderWidth](../styles-and-themes/common-units/#size)-NumberBox--default | *none* | *none* |
413 | | [borderWidth](../styles-and-themes/common-units/#size)-NumberBox--error | *none* | *none* |
414 | | [borderWidth](../styles-and-themes/common-units/#size)-NumberBox--success | *none* | *none* |
415 | | [borderWidth](../styles-and-themes/common-units/#size)-NumberBox--warning | *none* | *none* |
416 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-NumberBox--default | *none* | *none* |
417 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-NumberBox--default--focus | *none* | *none* |
418 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-NumberBox--default--hover | *none* | *none* |
419 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-NumberBox--error | *none* | *none* |
420 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-NumberBox--error--focus | *none* | *none* |
421 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-NumberBox--error--hover | *none* | *none* |
422 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-NumberBox--success | *none* | *none* |
423 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-NumberBox--success--focus | *none* | *none* |
424 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-NumberBox--success--hover | *none* | *none* |
425 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-NumberBox--warning | *none* | *none* |
426 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-NumberBox--warning--focus | *none* | *none* |
427 | | [boxShadow](../styles-and-themes/common-units/#boxShadow)-NumberBox--warning--hover | *none* | *none* |
428 | | [color](../styles-and-themes/common-units/#color)-adornment-NumberBox--default | *none* | *none* |
429 | | [color](../styles-and-themes/common-units/#color)-adornment-NumberBox--error | *none* | *none* |
430 | | [color](../styles-and-themes/common-units/#color)-adornment-NumberBox--success | *none* | *none* |
431 | | [color](../styles-and-themes/common-units/#color)-adornment-NumberBox--warning | *none* | *none* |
432 | | [fontSize](../styles-and-themes/common-units/#size)-NumberBox--default | *none* | *none* |
433 | | [fontSize](../styles-and-themes/common-units/#size)-NumberBox--error | *none* | *none* |
434 | | [fontSize](../styles-and-themes/common-units/#size)-NumberBox--success | *none* | *none* |
435 | | [fontSize](../styles-and-themes/common-units/#size)-NumberBox--warning | *none* | *none* |
436 | | [fontSize](../styles-and-themes/common-units/#size)-placeholder-NumberBox--default | *none* | *none* |
437 | | [fontSize](../styles-and-themes/common-units/#size)-placeholder-NumberBox--error | *none* | *none* |
438 | | [fontSize](../styles-and-themes/common-units/#size)-placeholder-NumberBox--success | *none* | *none* |
439 | | [fontSize](../styles-and-themes/common-units/#size)-placeholder-NumberBox--warning | *none* | *none* |
440 | | [gap](../styles-and-themes/common-units/#size)-adornment-NumberBox | *none* | *none* |
441 | | [outlineColor](../styles-and-themes/common-units/#color)-NumberBox--default--focus | *none* | *none* |
442 | | [outlineColor](../styles-and-themes/common-units/#color)-NumberBox--error--focus | *none* | *none* |
443 | | [outlineColor](../styles-and-themes/common-units/#color)-NumberBox--success--focus | *none* | *none* |
444 | | [outlineColor](../styles-and-themes/common-units/#color)-NumberBox--warning--focus | *none* | *none* |
445 | | [outlineOffset](../styles-and-themes/common-units/#size)-NumberBox--default--focus | *none* | *none* |
446 | | [outlineOffset](../styles-and-themes/common-units/#size)-NumberBox--error--focus | *none* | *none* |
447 | | [outlineOffset](../styles-and-themes/common-units/#size)-NumberBox--success--focus | *none* | *none* |
448 | | [outlineOffset](../styles-and-themes/common-units/#size)-NumberBox--warning--focus | *none* | *none* |
449 | | [outlineStyle](../styles-and-themes/common-units/#border)-NumberBox--default--focus | *none* | *none* |
450 | | [outlineStyle](../styles-and-themes/common-units/#border)-NumberBox--error--focus | *none* | *none* |
451 | | [outlineStyle](../styles-and-themes/common-units/#border)-NumberBox--success--focus | *none* | *none* |
452 | | [outlineStyle](../styles-and-themes/common-units/#border)-NumberBox--warning--focus | *none* | *none* |
453 | | [outlineWidth](../styles-and-themes/common-units/#size)-NumberBox--default--focus | *none* | *none* |
454 | | [outlineWidth](../styles-and-themes/common-units/#size)-NumberBox--error--focus | *none* | *none* |
455 | | [outlineWidth](../styles-and-themes/common-units/#size)-NumberBox--success--focus | *none* | *none* |
456 | | [outlineWidth](../styles-and-themes/common-units/#size)-NumberBox--warning--focus | *none* | *none* |
457 | | [padding](../styles-and-themes/common-units/#size)-NumberBox | *none* | *none* |
458 | | [paddingBottom](../styles-and-themes/common-units/#size)-NumberBox | *none* | *none* |
459 | | [paddingHorizontal](../styles-and-themes/common-units/#size)-NumberBox | $space-2 | $space-2 |
460 | | [paddingLeft](../styles-and-themes/common-units/#size)-NumberBox | *none* | *none* |
461 | | [paddingRight](../styles-and-themes/common-units/#size)-NumberBox | *none* | *none* |
462 | | [paddingTop](../styles-and-themes/common-units/#size)-NumberBox | *none* | *none* |
463 | | [paddingVertical](../styles-and-themes/common-units/#size)-NumberBox | $space-2 | $space-2 |
464 | | [textColor](../styles-and-themes/common-units/#color)-NumberBox--default | *none* | *none* |
465 | | [textColor](../styles-and-themes/common-units/#color)-NumberBox--default--focus | *none* | *none* |
466 | | [textColor](../styles-and-themes/common-units/#color)-NumberBox--default--hover | *none* | *none* |
467 | | [textColor](../styles-and-themes/common-units/#color)-NumberBox--disabled | *none* | *none* |
468 | | [textColor](../styles-and-themes/common-units/#color)-NumberBox--error | *none* | *none* |
469 | | [textColor](../styles-and-themes/common-units/#color)-NumberBox--error--focus | *none* | *none* |
470 | | [textColor](../styles-and-themes/common-units/#color)-NumberBox--error--hover | *none* | *none* |
471 | | [textColor](../styles-and-themes/common-units/#color)-NumberBox--success | *none* | *none* |
472 | | [textColor](../styles-and-themes/common-units/#color)-NumberBox--success--focus | *none* | *none* |
473 | | [textColor](../styles-and-themes/common-units/#color)-NumberBox--success--hover | *none* | *none* |
474 | | [textColor](../styles-and-themes/common-units/#color)-NumberBox--warning | *none* | *none* |
475 | | [textColor](../styles-and-themes/common-units/#color)-NumberBox--warning--focus | *none* | *none* |
476 | | [textColor](../styles-and-themes/common-units/#color)-NumberBox--warning--hover | *none* | *none* |
477 | | [textColor](../styles-and-themes/common-units/#color)-placeholder-NumberBox--default | *none* | *none* |
478 | | [textColor](../styles-and-themes/common-units/#color)-placeholder-NumberBox--error | *none* | *none* |
479 | | [textColor](../styles-and-themes/common-units/#color)-placeholder-NumberBox--success | *none* | *none* |
480 | | [textColor](../styles-and-themes/common-units/#color)-placeholder-NumberBox--warning | *none* | *none* |
481 | 
```

--------------------------------------------------------------------------------
/docs/public/pages/layout.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Layout
  2 | 
  3 | An XMLUI app is a hierarchical component tree in which parent components nest their children. Components like `HStack`, `VStack`, and `FlowLayout` use specialized layout strategies to arrange their children.
  4 | 
  5 | ## Viewport
  6 | 
  7 | Each component has a rectangular UI patch for rendering its content (and nested children). This is the component's **viewport**. The component decides (according to its rendering strategy) how it places its contents into the viewport. It may fill it partially, stretch the content to fill the entire viewport, or even overflow it vertically and/or horizontally.
  8 | 
  9 | The following app contains two components, an `App`, and a `Text`:
 10 | 
 11 | ```xmlui-pg display name="Example: viewport"
 12 | <App border="2px dotted red">
 13 |   <Text width="30%" border="2px dotted green">Hello from XMLUI</Text>
 14 | </App>
 15 | ```
 16 | 
 17 | The borders mark the viewport boundaries of the components:
 18 | 
 19 | - `App`: The dotted red border is the app's viewport boundary. An `App` has the entire browser window as its viewport; however, it reserves some space to the left and right for scrollbars (to avoid viewport resizing when a vertical scrollbar appears or gets removed).
 20 | - `Text`: The dotted green border is the text's viewport boundary. Its parent, `App`, uses some padding around its children.
 21 | 
 22 | ## Orientation
 23 | 
 24 | When rendering its children, a component may render them with vertical or horizontal orientation.
 25 | 
 26 | - Vertical orientation: Each child begins a new row when its parent displays it.
 27 | - Horizontal orientation: Each child appears in the same row as its previous sibling. In case of overflow the component can decide to push the child to a new row.
 28 | 
 29 | `App` uses vertical orientation by default; `HStack` (horizontal stack) uses horizontal orientation.
 30 | 
 31 | 
 32 | ```xmlui-pg display name="Example: orientation"
 33 | <App>
 34 |   <Text>First item</Text>
 35 |   <HStack>
 36 |     <Text>Second item</Text>
 37 |     <Text>Third item</Text>
 38 |     <Text>Fourth item</Text>
 39 |   </HStack>
 40 |   <Text>Fifth item</Text>
 41 | </App>
 42 | ```
 43 | 
 44 | ## Direction
 45 | 
 46 | Some languages (such as Hebrew and Arabic) are read from right to left. XMLUI components use this information to change their children's rendering direction. This example shows right-to-left.
 47 | 
 48 | ```xmlui-pg copy display name="Example: direction" /direction="rtl"/
 49 | <App direction="rtl">
 50 |   <Text>First item</Text>
 51 |   <HStack>
 52 |     <Text>Second item</Text>
 53 |     <Text>Third item</Text>
 54 |     <Text>Fourth item</Text>
 55 |   </HStack>
 56 |   <Text>Fifth item</Text>
 57 | </App>
 58 | ```
 59 | 
 60 | ## Paddings and gaps
 61 | 
 62 | Each component may adjust the padding around children and gaps between adjacent children.
 63 | 
 64 | 
 65 | ```xmlui-pg display name="Example: paddings and gaps"
 66 | <App border="2px dotted red">
 67 |   <Text border="2px dotted green">First item</Text>
 68 |   <HStack border="2px dotted green">
 69 |     <Text border="2px dotted purple">Second item</Text>
 70 |     <Text border="2px dotted purple">Third item</Text>
 71 |     <Text border="2px dotted purple">Fourth item</Text>
 72 |   </HStack>
 73 |   <Text border="2px dotted green">Fifth item</Text>
 74 | </App>
 75 | ```
 76 | 
 77 | - `App` applies vertical and horizontal padding, which is why the top left corner of the red border and the green border do not meet. It also adds gaps, which are the spaces between the green border areas.
 78 | - `HStack` uses no paddings so the top left corner of its green border and the first item's top-left corner (the purple border) meet. Like `App`, `HStack` adds gaps, here shown as spaces between the purple border areas.
 79 | 
 80 | > [!INFO]
 81 | > Web and desktop UI frameworks typically use margins to establish layout. XMLUI layout components do not use margins, they only use paddings and gaps. Although you can use margins, they tend to complicate layouts so use them as a last resort.
 82 | 
 83 | ## Dimensions
 84 | 
 85 | Each component has a default strategy for determining the dimensions (height and width) of its children.
 86 | `VStack` determines its dimensions according to its content. If we want to display a 40px by 60px orange box with nothing in it and 60px wide orange-red box with empty content, we must explicitly set dimensions (and background color).
 87 | 
 88 | ```xmlui-pg display name="Example: dimensions"
 89 | <App>
 90 |   <VStack height="40px" width="60px" backgroundColor="orangered" />
 91 | </App>
 92 | ```
 93 | 
 94 | ## Alignment
 95 | 
 96 | Components can align their children in the viewport both vertically and horizontally.
 97 | 
 98 | ```xmlui-pg display name="Example: alignment" /horizontalAlignment/ /verticalAlignment/
 99 | <App>
100 |   <HStack>
101 |     <VStack 
102 |       width="50%" 
103 |       border="2px dotted red" 
104 |       height="200px" 
105 |       horizontalAlignment="end"
106 |     >
107 |       <Text>Item #1</Text>
108 |       <Text>Item #2</Text>
109 |       <Text>Item #3</Text>
110 |     </VStack>
111 |     <VStack
112 |       width="50%" 
113 |       border="2px 
114 |       dotted green" 
115 |       height="200px" 
116 |       verticalAlignment="center"
117 |     >
118 |       <Text>Item #1</Text>
119 |       <Text>Item #2</Text>
120 |       <Text>Item #3</Text>
121 |     </VStack>
122 |   </HStack>
123 | </App>
124 | ```
125 | 
126 | The component with the red border aligns its children vertically to the start and horizontally to the end. The green-bordered component aligns its children vertically to the center and horizontally to the start.
127 | 
128 | ## Layout containers
129 | 
130 | XMLUI uses only two fundamental layout containers, `Stack`, and `FlowLayout`. All other container-like components (such as `Card`, `List`, and others) apply these to establish more sophisticated layout arrangements.
131 | 
132 | `Stack` is a layout container that uses a particular orientation (vertical or horizontal) to render its children in a single column or row. If the children do not fit into the viewport, they overflow. `Stack` has two specialized variants, `HStack` (horizontal stack) and `VStack` (vertical stack).
133 | 
134 | `FlowLayout` is a layout container that renders its children horizontally while they fit into the current row; otherwise, the child enters a new row. If the children do not fit into the viewport, they overflow.
135 | 
136 | > [!INFO]
137 | > Your application markup must have a single root component. The browser window is an implicit `VStack` layout container with that root element as its single child.
138 | 
139 | ## Dimension units
140 | 
141 | To explicitly control a child's dimensions, instead of it being determined by its content, you can set one or more of these [properties](/styles-and-themes/layout-props): `width`, `height`, `minWidth`, `minHeight`, `maxWidth`, and `maxHeight` using several kinds of values.
142 | 
143 | - **No value**. The layout container determines the default size of the child element according to its strategy.
144 | - **Container-independent size value**. All sizes except percentage (`%`) and star sizes (`*`) belong to this category. The container respects the child's requested size.
145 | - **Percentage size**. The container calculates the child's requested size as a percentage of the viewport's corresponding dimension.
146 | - **Star size**. The child provides a weight the parent container utilizes when distributing the _remaining space_ among its children. The remaining space is the parent viewport's size minus the sum sizes of child components within the first two categories (no value, container-independent size value).
147 | 
148 | ## Gaps
149 | 
150 | The fundamental layout containers apply a default gap ensuring that children have some space between them.
151 | 
152 | ```xmlui-pg copy display name="Example: default gaps"
153 | <App>
154 |   <HStack>
155 |     <Button>First button</Button>
156 |     <Button>Second button</Button>
157 |     <Button>Third button</Button>
158 |   </HStack>
159 | </App>
160 | ```
161 | 
162 | You can remove the gaps.
163 | 
164 | ```xmlui-pg copy display /gap="0"/ name="Example: default gaps removed"
165 | <App>
166 |   <HStack gap="0">
167 |     <Button>First button</Button>
168 |     <Button>Second button</Button>
169 |     <Button>Third button</Button>
170 |   </HStack>
171 | </App>
172 | ```
173 | 
174 | 
175 | XMLUI offers several [predefined gap values](/styles-and-themes/theme-variables#spacing-in-layout-containers). Use these instead of inline literals like "16px" or "0.5rem" to enable theming and consistent design.
176 | 
177 | ```xmlui-pg copy /gap="$gap-tight"/ /gap="$gap-loose"/ name="Example: predefined gap values"
178 | <App>
179 |   <VStack>
180 |     <HStack gap="$gap-tight">
181 |       <Button>First button</Button>
182 |       <Button>Second button</Button>
183 |       <Button>Third button</Button>
184 |     </HStack>
185 |     <HStack gap="$gap-loose">
186 |       <Button>First button</Button>
187 |       <Button>Second button</Button>
188 |       <Button>Third button</Button>
189 |     </HStack>
190 |   </VStack>
191 | </App>
192 | ```
193 | 
194 | ## Rendering children
195 | 
196 | Layout containers render their children in declaration order, subject to the current page direction (left-to-right or right-to-left).
197 | 
198 | This markup displays five boxes; the third is wider than the others.
199 | 
200 | ```xmlui-pg name="Example: VStack"
201 | ---app display copy 
202 | <App>
203 |   <VStack>
204 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
205 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
206 |     <Stack height="20px" width="80%" backgroundColor="orangered" />
207 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
208 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
209 |   </VStack>
210 | </App>
211 | ---desc
212 | In a `VStack` each child takes a new row.
213 | ```
214 | 
215 | 
216 | ```xmlui-pg name="Example: HStack"
217 | ---app copy display
218 | <App>
219 |   <HStack>
220 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
221 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
222 |     <Stack height="20px" width="80%" backgroundColor="orangered" />
223 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
224 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
225 |   </HStack>
226 | </App>
227 | ---desc
228 | In an `HStack` they occupy one row. The app provides a horizontal scrollbar to accommodate overflow.
229 | ```
230 | 
231 | 
232 | ```xmlui-pg name="Example: HStack"
233 | ---app copy display
234 | <App>
235 |   <FlowLayout>
236 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
237 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
238 |     <Stack height="20px" width="80%" backgroundColor="orangered" />
239 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
240 |     <Stack height="20px" width="20%" backgroundColor="orangered" />
241 |   </FlowLayout>
242 | </App>
243 | ---desc
244 | In a `FlowLayout` the children occupy new rows as needed.
245 | ```
246 | 
247 | If you set an explicit `height` the layout container will use that height; otherwise, it accommodates the height of its children. This example uses the natural height of the content.
248 | 
249 | ```xmlui-pg copy display name="Example: Text in VStack"
250 | <VStack
251 |   backgroundColor="cyan"
252 |   horizontalAlignment="center"
253 |   verticalAlignment="center">
254 |   This is some text within a VStack
255 | </VStack>
256 | ```
257 | 
258 | This example increases the height.
259 | 
260 | ```xmlui-pg copy display name="Example: VStack with explicit height"
261 | <VStack
262 |   height="160px"
263 |   backgroundColor="cyan"
264 |   horizontalAlignment="center"
265 |   verticalAlignment="center">
266 |   This is some text within a VStack
267 | </VStack>
268 | ```
269 | 
270 | ## Container width
271 | 
272 | Unless you use an explicit width, a layout container uses the entire width of its viewport. This example uses implicit width.
273 | 
274 | ```xmlui-pg copy display name="Example: default container width"
275 | <VStack
276 |   backgroundColor="cyan"
277 |   horizontalAlignment="center"
278 |   verticalAlignment="center">
279 |   This is some text within a VStack
280 | </VStack>
281 | ```
282 | 
283 | This one uses explicit width.
284 | 
285 | ```xmlui-pg copy display /width="400px"/ name="Example: explicit container width"
286 | <VStack
287 |   width="400px"
288 |   backgroundColor="cyan"
289 |   horizontalAlignment="center"
290 |   verticalAlignment="center">
291 |   This is some text within a VStack
292 | </VStack>
293 | ```
294 | 
295 | When you explicitly set the width of a layout container and the content is wider, it will break or overflow.
296 | 
297 | ## Stack
298 | 
299 | `Stack` renders its child items horizontally or vertically according to its `orientation` property, optionally providing some gap between child components.
300 | 
301 | You can assign the `horizontal` or `vertical` values to the `Stack` component's `orientation` property to declare its rendering orientation. The default value is `vertical`.
302 | 
303 | > [!INFO]
304 | > Use `Stack` when the `orientation` property can vary as the result of an expression. If the orientation is static, use `VStack` (equivalent to `<Stack orientation="vertical">`) or `HStack` (`<Stack orientation="horizontal">`).
305 | 
306 | ### Alignment
307 | 
308 | The `horizontalAlignment` and `verticalAlignment` properties govern alignment within a stack, using values like `start`, `end`, and `center`. See the full list of values [here](/styles-and-themes/common-units#alignment)
309 | 
310 | This markup aligns the children of an `HStack` horizontally in the center:
311 | 
312 | ```xmlui-pg copy display /horizontalAlignment="center"/ name="Example: horizontally centered content in a HStack"
313 | <HStack horizontalAlignment="center">
314 |   <Stack backgroundColor="red" height="36px" width="36px" />
315 |   <Stack backgroundColor="green" height="36px" width="36px" />
316 |   <Stack backgroundColor="blue" height="36px" width="36px" />
317 | </HStack>
318 | ```
319 | 
320 | This markup aligns the children of a `VStack` horizontally to the end (right edge):
321 | 
322 | ```xmlui-pg copy display /horizontalAlignment="end"/ name="Example: horizontally centered content in a VStack"
323 | <VStack  horizontalAlignment="end">
324 |   <Stack backgroundColor="red" height="36px" width="36px" />
325 |   <Stack backgroundColor="green" height="36px" width="36px" />
326 |   <Stack backgroundColor="blue" height="36px" width="36px" />
327 | </VStack>
328 | ```
329 | 
330 | This markup aligns the children of an `HStack` vertically in the center:
331 | 
332 | ```xmlui-pg copy display /verticalAlignment="center"/ name="Exmaple: vertically centered text in a HStack"
333 | <HStack verticalAlignment="center">
334 |   <Stack backgroundColor="red" height="36px" width="36px" />
335 |   <Stack backgroundColor="green" height="72px" width="36px" />
336 |   <Stack backgroundColor="blue" height="48px" width="36px" />
337 | </HStack>
338 | ```
339 | 
340 | ## VStack
341 | 
342 | A `VStack` component displays each of its children in a new row. If a child has no explicit (or component-specific) width, the `VStack` stretches the component to the entire viewport width. `VStack` keeps the child components' heights intact.
343 | 
344 | ```xmlui-pg copy display name="Example: rendering children in a VStack "
345 | <VStack>
346 |   <H2 backgroundColor="orangered">I'm a heading with colored background</H2>
347 |   <Button>I'm a button</Button>
348 | </VStack>
349 | ```
350 | 
351 | The `H2` component has no explicit size, so its width is set to the width of the text content (as the background color indicates). Though the `Button` component has no explicit size, it has a component-specific one (according to its content), so it is not stretched horizontally. The button is taller than the `VStack`, so its height determines the `VStack` height, and the text height is stretched to that.
352 | 
353 | When you use a `VStack` child with percentage height, the effective height is calculated from the entire stack height. Such a setup may cause overflow if the sum of percentages equals 100%, as the gaps between children are also included in the stack height. This example demonstrates an overflow.
354 | 
355 | ```xmlui-pg copy display name="Example: VStack with percentage height (overflow)"
356 | <VStack height="200px" border="4px dotted green">
357 |   <Stack backgroundColor="cyan" height="50%" />
358 |   <Stack backgroundColor="orangered" height="50%" />
359 | </VStack>
360 | ```
361 | 
362 | There is no overflow when the stack does not apply gaps.
363 | 
364 | ```xmlui-pg copy display /gap="0"/ name="Example: VStack with percentage height (no overflow)"
365 | <VStack gap="0" height="200px" border="4px dotted green">
366 |   <Stack backgroundColor="cyan" height="50%" />
367 |   <Stack backgroundColor="orangered" height="50%" />
368 | </VStack>
369 | ```
370 | 
371 | When you use a `VStack` child height with star sizing, the effective height is calculated from the remaining height of the entire stack after subtracting the heights of explicitly-sized children and gaps.
372 | Such a configuration will not cause overflow.
373 | 
374 | ```xmlui-pg copy display name="Example: VStack with star-sized height"
375 | <VStack height="240px" border="4px dotted green">
376 |   <Stack backgroundColor="cyan" height="*" />
377 |   <H3>I'm a heading</H3>
378 |   <Stack backgroundColor="orangered" height="5*" />
379 | </VStack>
380 | ```
381 | 
382 | ## HStack
383 | 
384 | An `HStack` component displays each of its children in a single row. If a child has no explicit (or component-specific) width, the `HStack` fits the component width to its content. `HStack` sets the child components' heights to the stack's viewport height.
385 | 
386 | ```xmlui-pg copy display name="Example: rendering children in a HStack"
387 | <HStack>
388 |   <H2 backgroundColor="orangered">I'm a heading with colored background</H2>
389 |   <Button>I'm a button</Button>
390 | </HStack>
391 | ```
392 | 
393 | The `H2` component has no explicit size, so it's stretched to the viewport width (as the background color indicates). Though `Button` has no explicit size, it has a component-specific one (according to its content), so it is not stretched.
394 | 
395 | When you use a `HStack` child with percentage width, the effective width is calculated from the stack's viewport width. Such a setup may cause horizontal overflow if the sum of percentages equals 100%, as the gaps between children are also included in the stack height.
396 | 
397 | ```xmlui-pg copy display name="Example: HStack with percentage width (overflow)"
398 | <HStack border="4px dotted green" height="200px">
399 |   <Stack backgroundColor="cyan" width="50%" />
400 |   <Stack backgroundColor="orangered" width="50%" />
401 | </HStack>
402 | ```
403 | 
404 | 
405 | When the stack does not apply gaps, there is no overflow:
406 | 
407 | ```xmlui-pg copy display /gap="0"/ name="Example: HStack with percentage width (no overflow)"
408 | <HStack gap="0" border="4px dotted green" height="200px">
409 |   <Stack backgroundColor="cyan" width="50%" />
410 |   <Stack backgroundColor="orangered" width="50%" />
411 | </HStack>
412 | ```
413 | 
414 | When you use a `HStack` child with star sizing, the effective width is calculated from the remaining width of the stack's viewport width after subtracting the widths of explicitly sized children and gaps. Such a configuration will not cause overflow.
415 | 
416 | ```xmlui-pg copy display name="Example: HStack with star-sized width"
417 | <HStack height="60px" border="4px dotted green">
418 |   <Stack backgroundColor="cyan" width="*" />
419 |   <H3>I'm a heading</H3>
420 |   <Stack backgroundColor="orangered" width="2*" />
421 | </HStack>
422 | ```
423 | 
424 | `HStack` has a `wrapContent` property. If you set it to `true`, the engine starts a new line (or column) when the subsequent child to render would overflow in the current line. Here the fourth child does not fit in the first line entirely, so it overflows:
425 | 
426 | ```xmlui-pg copy display name="Example: HStack with overflow in a single row"
427 | <HStack>
428 |   <Stack backgroundColor="red" height="36px" width="25%" />
429 |   <Stack backgroundColor="green" height="36px" width="40%" />
430 |   <Stack backgroundColor="blue" height="36px" width="20%" />
431 |   <Stack backgroundColor="purple" height="36px" width="30%" />
432 | </HStack>
433 | ```
434 | 
435 | With `wrapContent` flag, the forth child begins a new line.
436 | 
437 | ```xmlui-pg copy display /wrapContent="true"/ name="Example: HStack with wrapContent"
438 | <HStack wrapContent="true">
439 |   <Stack backgroundColor="red" height="36px" width="25%" />
440 |   <Stack backgroundColor="green" height="36px" width="40%" />
441 |   <Stack backgroundColor="blue" height="36px" width="20%" />
442 |   <Stack backgroundColor="purple" height="36px" width="30%" />
443 | </HStack>
444 | ```
445 | 
446 | ## CHStack
447 | 
448 | `CHStack` is a shorthand version of `Stack` with a horizontal orientation and centered contents.
449 | 
450 | ```xmlui-pg copy display name="Example: CHStack"
451 | <CHStack height="100px" width="200px" backgroundColor="lightgray">
452 |   <Stack backgroundColor="red" height="36px" width="36px" />
453 |   <Stack backgroundColor="green" height="72px" width="36px" />
454 |   <Stack backgroundColor="blue" height="48px" width="36px" />
455 | </CHStack>
456 | ```
457 | 
458 | ## CVStack
459 | 
460 | `CVStack` is a shorthand version of `Stack` with a vertical orientation and centered contents.
461 | 
462 | ```xmlui-pg display copy name="Example: CVStack"
463 | <CVStack height="200px" width="100px" backgroundColor="lightgray">
464 |   <Stack backgroundColor="red" height="36px" width="36px" />
465 |   <Stack backgroundColor="green" height="36px" width="72px" />
466 |   <Stack backgroundColor="blue" height="36px" width="48px" />
467 | </CVStack>
468 | ```
469 | 
470 | ## FlowLayout
471 | 
472 | `FlowLayout` component is effectively a horizontal stack with content wrapping. Though it implements the same behavior, it has extra features:
473 | 
474 | - **Percentage sizing**: `FlowLayout` considers the gaps between child elements when using percentage sizing, unlike `Stack`.
475 | - **Responsiveness**: `FlowLayout` resizes percentage-sized children on mobile devices.
476 | 
477 | When you use an `HStack` with percentage sizing and the sum width of children is 100%, an overflow will occur because gaps require extra space.
478 | 
479 | ```xmlui-pg copy display name="Example: HStack with overflow"
480 | <HStack>
481 |   <Stack backgroundColor="red" height="36px" width="25%" />
482 |   <Stack backgroundColor="green" height="36px" width="50%" />
483 |   <Stack backgroundColor="blue" height="36px" width="25%" />
484 | </HStack>
485 | ```
486 | 
487 | `FlowLayout` handles this sizing issue by adjusting the child component dimensions, accounting for the gaps.
488 | 
489 | ```xmlui-pg copy display name="Example: FlowLayout"
490 | <FlowLayout>
491 |   <Stack backgroundColor="red" height="36px" width="25%" />
492 |   <Stack backgroundColor="green" height="36px" width="50%" />
493 |   <Stack backgroundColor="blue" height="36px" width="25%" />
494 | </FlowLayout>
495 | ```
496 | 
497 | `FlowLayout` caps the size of items exceeding the available width. Here the red box is too wide but `FlowLayout` trims it back to 100% width.
498 | 
499 | ```xmlui-pg copy display /width="1000000px"/ name="Example: FlowLayout with size capping"
500 | <FlowLayout>
501 |   <Stack backgroundColor="red" height="36px" width="1000000px" />
502 |   <Stack backgroundColor="green" height="36px" width="50%" />
503 |   <Stack backgroundColor="blue" height="36px" width="25%" />
504 | </FlowLayout>
505 | ```
506 | 
507 | 
508 | Note how the extreme width of the first child is capped to the space available for the `FlowLayout`, while the other children's sizes remain unmodified:
509 | 
510 | ## SpaceFiller
511 | 
512 | `SpaceFiller` fills unused space in layout containers. Its behavior depends on the layout container in which it is used. In a `Stack`, it pushes the children following it to the other end of the container.
513 | 
514 | ```xmlui-pg copy display name="Example: SpaceFiller in a HStack"
515 | <HStack>
516 |   <Stack width="36px" height="36px" backgroundColor="red" />
517 |   <SpaceFiller />
518 |   <Stack width="36px" height="36px" backgroundColor="blue" />
519 | </HStack>
520 | ```
521 | 
522 | In a `FlowLayout`, it acts as a line break for a row. The children following the `SpaceFiller` begin a new line.
523 | 
524 | ```xmlui-pg copy display name="Example: SpaceFiller in a FlowLayout"
525 | <FlowLayout>
526 |   <Stack width="20%" height="36px" backgroundColor="red" />
527 |   <SpaceFiller />
528 |   <Stack width="20%" height="36px" backgroundColor="green" />
529 |   <Stack width="20%" height="36px" backgroundColor="blue" />
530 | </FlowLayout>
531 | ```
532 | 
533 | ## Splitter
534 | 
535 | `Splitter` divides a container into two resizable sections (a primary and a secondary) and puts a draggable bar between them. It has two specialized variants, `HSplitter` and `VSplitter`, which separate the two sections vertically and horizontally.
536 | 
537 | Here's a horizontal splitter that sets some constraints on the size of the primary section.
538 | 
539 | ```xmlui-pg copy display height="200px" name="Example: Splitter"
540 | <HSplitter
541 |   height="100%"
542 |   minPrimarySize="15%"
543 |   maxPrimarySize="85%">
544 |   <CVStack backgroundColor="lightblue" height="100%">Primary</CVStack>
545 |   <CVStack backgroundColor="darksalmon" height="100%">Secondary</CVStack>
546 | </HSplitter>
547 | ```
548 | 
549 | Try dragging the splitter bar between the sections to see how it works.
550 | 
551 | 
```

