This is page 94 of 143. Use http://codebase.md/xmlui-org/xmlui/tools/vscode/resources/assets/img/bg-iphone-14-pro.jpg?lines=false&page={x} to view the full context.
# Directory Structure
```
├── .changeset
│ └── config.json
├── .eslintrc.cjs
├── .github
│ ├── build-checklist.png
│ ├── ISSUE_TEMPLATE
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ └── workflows
│ ├── deploy-blog-optimized.yml
│ ├── deploy-blog-swa.yml
│ ├── deploy-blog.yml
│ ├── deploy-docs-optimized.yml
│ ├── deploy-docs.yml
│ ├── prepare-versions.yml
│ ├── release-packages.yml
│ ├── run-all-tests.yml
│ └── run-smoke-tests.yml
├── .gitignore
├── .prettierrc.js
├── .vscode
│ ├── launch.json
│ └── settings.json
├── blog
│ ├── .gitignore
│ ├── .gitkeep
│ ├── CHANGELOG.md
│ ├── extensions.ts
│ ├── index.html
│ ├── index.ts
│ ├── package.json
│ ├── public
│ │ ├── blog
│ │ │ ├── images
│ │ │ │ ├── an-advanced-codefence.gif
│ │ │ │ ├── an-advanced-codefence.mp4
│ │ │ │ ├── blog-page-component.png
│ │ │ │ ├── blog-scrabble.png
│ │ │ │ ├── codefence-runner.png
│ │ │ │ ├── integrated-blog-search.png
│ │ │ │ ├── lorem-ipsum.png
│ │ │ │ ├── playground-checkbox-source.png
│ │ │ │ ├── playground.png
│ │ │ │ ├── use-xmlui-mcp-to-find-a-howto.png
│ │ │ │ └── xmlui-demo-gallery.png
│ │ │ ├── introducing-xmlui.md
│ │ │ ├── lorem-ipsum.md
│ │ │ ├── newest-post.md
│ │ │ ├── older-post.md
│ │ │ ├── xmlui-playground.md
│ │ │ └── xmlui-powered-blog.md
│ │ ├── mockServiceWorker.js
│ │ ├── resources
│ │ │ ├── favicon.ico
│ │ │ ├── files
│ │ │ │ └── for-download
│ │ │ │ └── xmlui
│ │ │ │ └── xmlui-standalone.umd.js
│ │ │ ├── github.svg
│ │ │ ├── llms.txt
│ │ │ ├── logo-dark.svg
│ │ │ ├── logo.svg
│ │ │ ├── pg-popout.svg
│ │ │ ├── rss.svg
│ │ │ └── xmlui-logo.svg
│ │ ├── serve.json
│ │ ├── staticwebapp.config.json
│ │ └── web.config
│ ├── scripts
│ │ ├── download-latest-xmlui.js
│ │ ├── generate-rss.js
│ │ ├── get-releases.js
│ │ └── utils.js
│ ├── src
│ │ ├── components
│ │ │ ├── BlogOverview.xmlui
│ │ │ ├── BlogPage.xmlui
│ │ │ └── PageNotFound.xmlui
│ │ ├── config.ts
│ │ ├── Main.xmlui
│ │ └── themes
│ │ └── blog-theme.ts
│ └── tsconfig.json
├── CONTRIBUTING.md
├── docs
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── ComponentRefLinks.txt
│ ├── content
│ │ ├── _meta.json
│ │ ├── components
│ │ │ ├── _meta.json
│ │ │ ├── _overview.md
│ │ │ ├── APICall.md
│ │ │ ├── App.md
│ │ │ ├── AppHeader.md
│ │ │ ├── AppState.md
│ │ │ ├── AutoComplete.md
│ │ │ ├── Avatar.md
│ │ │ ├── Backdrop.md
│ │ │ ├── Badge.md
│ │ │ ├── BarChart.md
│ │ │ ├── Bookmark.md
│ │ │ ├── Breakout.md
│ │ │ ├── Button.md
│ │ │ ├── Card.md
│ │ │ ├── Carousel.md
│ │ │ ├── ChangeListener.md
│ │ │ ├── Checkbox.md
│ │ │ ├── CHStack.md
│ │ │ ├── ColorPicker.md
│ │ │ ├── Column.md
│ │ │ ├── ContentSeparator.md
│ │ │ ├── CVStack.md
│ │ │ ├── DataSource.md
│ │ │ ├── DateInput.md
│ │ │ ├── DatePicker.md
│ │ │ ├── DonutChart.md
│ │ │ ├── DropdownMenu.md
│ │ │ ├── EmojiSelector.md
│ │ │ ├── ExpandableItem.md
│ │ │ ├── FileInput.md
│ │ │ ├── FileUploadDropZone.md
│ │ │ ├── FlowLayout.md
│ │ │ ├── Footer.md
│ │ │ ├── Form.md
│ │ │ ├── FormItem.md
│ │ │ ├── FormSection.md
│ │ │ ├── Fragment.md
│ │ │ ├── H1.md
│ │ │ ├── H2.md
│ │ │ ├── H3.md
│ │ │ ├── H4.md
│ │ │ ├── H5.md
│ │ │ ├── H6.md
│ │ │ ├── Heading.md
│ │ │ ├── HSplitter.md
│ │ │ ├── HStack.md
│ │ │ ├── Icon.md
│ │ │ ├── IFrame.md
│ │ │ ├── Image.md
│ │ │ ├── Items.md
│ │ │ ├── LabelList.md
│ │ │ ├── Legend.md
│ │ │ ├── LineChart.md
│ │ │ ├── Link.md
│ │ │ ├── List.md
│ │ │ ├── Logo.md
│ │ │ ├── Markdown.md
│ │ │ ├── MenuItem.md
│ │ │ ├── MenuSeparator.md
│ │ │ ├── ModalDialog.md
│ │ │ ├── NavGroup.md
│ │ │ ├── NavLink.md
│ │ │ ├── NavPanel.md
│ │ │ ├── NoResult.md
│ │ │ ├── NumberBox.md
│ │ │ ├── Option.md
│ │ │ ├── Page.md
│ │ │ ├── PageMetaTitle.md
│ │ │ ├── Pages.md
│ │ │ ├── Pagination.md
│ │ │ ├── PasswordInput.md
│ │ │ ├── PieChart.md
│ │ │ ├── ProgressBar.md
│ │ │ ├── Queue.md
│ │ │ ├── RadioGroup.md
│ │ │ ├── RealTimeAdapter.md
│ │ │ ├── Redirect.md
│ │ │ ├── Select.md
│ │ │ ├── Slider.md
│ │ │ ├── Slot.md
│ │ │ ├── SpaceFiller.md
│ │ │ ├── Spinner.md
│ │ │ ├── Splitter.md
│ │ │ ├── Stack.md
│ │ │ ├── StickyBox.md
│ │ │ ├── SubMenuItem.md
│ │ │ ├── Switch.md
│ │ │ ├── TabItem.md
│ │ │ ├── Table.md
│ │ │ ├── TableOfContents.md
│ │ │ ├── Tabs.md
│ │ │ ├── Text.md
│ │ │ ├── TextArea.md
│ │ │ ├── TextBox.md
│ │ │ ├── Theme.md
│ │ │ ├── TimeInput.md
│ │ │ ├── Timer.md
│ │ │ ├── ToneChangerButton.md
│ │ │ ├── ToneSwitch.md
│ │ │ ├── Tooltip.md
│ │ │ ├── Tree.md
│ │ │ ├── VSplitter.md
│ │ │ ├── VStack.md
│ │ │ ├── xmlui-animations
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ ├── Animation.md
│ │ │ │ ├── FadeAnimation.md
│ │ │ │ ├── FadeInAnimation.md
│ │ │ │ ├── FadeOutAnimation.md
│ │ │ │ ├── ScaleAnimation.md
│ │ │ │ └── SlideInAnimation.md
│ │ │ ├── xmlui-pdf
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ └── Pdf.md
│ │ │ ├── xmlui-spreadsheet
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ └── Spreadsheet.md
│ │ │ └── xmlui-website-blocks
│ │ │ ├── _meta.json
│ │ │ ├── _overview.md
│ │ │ ├── Carousel.md
│ │ │ ├── HelloMd.md
│ │ │ ├── HeroSection.md
│ │ │ └── ScrollToTop.md
│ │ └── extensions
│ │ ├── _meta.json
│ │ ├── xmlui-animations
│ │ │ ├── _meta.json
│ │ │ ├── _overview.md
│ │ │ ├── Animation.md
│ │ │ ├── FadeAnimation.md
│ │ │ ├── FadeInAnimation.md
│ │ │ ├── FadeOutAnimation.md
│ │ │ ├── ScaleAnimation.md
│ │ │ └── SlideInAnimation.md
│ │ └── xmlui-website-blocks
│ │ ├── _meta.json
│ │ ├── _overview.md
│ │ ├── Carousel.md
│ │ ├── FancyButton.md
│ │ ├── HeroSection.md
│ │ └── ScrollToTop.md
│ ├── extensions.ts
│ ├── index.html
│ ├── index.ts
│ ├── package.json
│ ├── public
│ │ ├── feed.rss
│ │ ├── mockServiceWorker.js
│ │ ├── pages
│ │ │ ├── _meta.json
│ │ │ ├── app-structure.md
│ │ │ ├── build-editor-component.md
│ │ │ ├── build-hello-world-component.md
│ │ │ ├── components-intro.md
│ │ │ ├── context-variables.md
│ │ │ ├── forms.md
│ │ │ ├── globals.md
│ │ │ ├── glossary.md
│ │ │ ├── helper-tags.md
│ │ │ ├── hosted-deployment.md
│ │ │ ├── howto
│ │ │ │ ├── assign-a-complex-json-literal-to-a-component-variable.md
│ │ │ │ ├── chain-a-refetch.md
│ │ │ │ ├── control-cache-invalidation.md
│ │ │ │ ├── debounce-user-input-for-api-calls.md
│ │ │ │ ├── debounce-with-changelistener.md
│ │ │ │ ├── debug-a-component.md
│ │ │ │ ├── delay-a-datasource-until-another-datasource-is-ready.md
│ │ │ │ ├── delegate-a-method.md
│ │ │ │ ├── do-custom-form-validation.md
│ │ │ │ ├── expose-a-method-from-a-component.md
│ │ │ │ ├── filter-and-transform-data-from-an-api.md
│ │ │ │ ├── group-items-in-list-by-a-property.md
│ │ │ │ ├── handle-background-operations.md
│ │ │ │ ├── hide-an-element-until-its-datasource-is-ready.md
│ │ │ │ ├── make-a-set-of-equal-width-cards.md
│ │ │ │ ├── make-a-table-responsive.md
│ │ │ │ ├── make-navpanel-width-responsive.md
│ │ │ │ ├── modify-a-value-reported-in-a-column.md
│ │ │ │ ├── paginate-a-list.md
│ │ │ │ ├── pass-data-to-a-modal-dialog.md
│ │ │ │ ├── react-to-button-click-not-keystrokes.md
│ │ │ │ ├── set-the-initial-value-of-a-select-from-fetched-data.md
│ │ │ │ ├── share-a-modaldialog-across-components.md
│ │ │ │ ├── sync-selections-between-table-and-list-views.md
│ │ │ │ ├── update-ui-optimistically.md
│ │ │ │ ├── use-built-in-form-validation.md
│ │ │ │ └── use-the-same-modaldialog-to-add-or-edit.md
│ │ │ ├── howto.md
│ │ │ ├── intro.md
│ │ │ ├── layout.md
│ │ │ ├── markup.md
│ │ │ ├── mcp.md
│ │ │ ├── modal-dialogs.md
│ │ │ ├── news-and-reviews.md
│ │ │ ├── reactive-intro.md
│ │ │ ├── refactoring.md
│ │ │ ├── routing-and-links.md
│ │ │ ├── samples
│ │ │ │ ├── color-palette.xmlui
│ │ │ │ ├── color-values.xmlui
│ │ │ │ ├── shadow-sizes.xmlui
│ │ │ │ ├── spacing-sizes.xmlui
│ │ │ │ ├── swatch.xmlui
│ │ │ │ ├── theme-gallery-brief.xmlui
│ │ │ │ └── theme-gallery.xmlui
│ │ │ ├── scoping.md
│ │ │ ├── scripting.md
│ │ │ ├── styles-and-themes
│ │ │ │ ├── common-units.md
│ │ │ │ ├── layout-props.md
│ │ │ │ ├── theme-variable-defaults.md
│ │ │ │ ├── theme-variables.md
│ │ │ │ └── themes.md
│ │ │ ├── template-properties.md
│ │ │ ├── test.md
│ │ │ ├── tutorial-01.md
│ │ │ ├── tutorial-02.md
│ │ │ ├── tutorial-03.md
│ │ │ ├── tutorial-04.md
│ │ │ ├── tutorial-05.md
│ │ │ ├── tutorial-06.md
│ │ │ ├── tutorial-07.md
│ │ │ ├── tutorial-08.md
│ │ │ ├── tutorial-09.md
│ │ │ ├── tutorial-10.md
│ │ │ ├── tutorial-11.md
│ │ │ ├── tutorial-12.md
│ │ │ ├── universal-properties.md
│ │ │ ├── user-defined-components.md
│ │ │ ├── vscode.md
│ │ │ ├── working-with-markdown.md
│ │ │ ├── working-with-text.md
│ │ │ ├── xmlui-animations
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ ├── Animation.md
│ │ │ │ ├── FadeAnimation.md
│ │ │ │ ├── FadeInAnimation.md
│ │ │ │ ├── FadeOutAnimation.md
│ │ │ │ ├── ScaleAnimation.md
│ │ │ │ └── SlideInAnimation.md
│ │ │ ├── xmlui-charts
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ ├── BarChart.md
│ │ │ │ ├── DonutChart.md
│ │ │ │ ├── LabelList.md
│ │ │ │ ├── Legend.md
│ │ │ │ ├── LineChart.md
│ │ │ │ └── PieChart.md
│ │ │ ├── xmlui-pdf
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ └── Pdf.md
│ │ │ └── xmlui-spreadsheet
│ │ │ ├── _meta.json
│ │ │ ├── _overview.md
│ │ │ └── Spreadsheet.md
│ │ ├── resources
│ │ │ ├── devdocs
│ │ │ │ ├── debug-proxy-object-2.png
│ │ │ │ ├── debug-proxy-object.png
│ │ │ │ ├── table_editor_01.png
│ │ │ │ ├── table_editor_02.png
│ │ │ │ ├── table_editor_03.png
│ │ │ │ ├── table_editor_04.png
│ │ │ │ ├── table_editor_05.png
│ │ │ │ ├── table_editor_06.png
│ │ │ │ ├── table_editor_07.png
│ │ │ │ ├── table_editor_08.png
│ │ │ │ ├── table_editor_09.png
│ │ │ │ ├── table_editor_10.png
│ │ │ │ ├── table_editor_11.png
│ │ │ │ ├── table-editor-01.png
│ │ │ │ ├── table-editor-02.png
│ │ │ │ ├── table-editor-03.png
│ │ │ │ ├── table-editor-04.png
│ │ │ │ ├── table-editor-06.png
│ │ │ │ ├── table-editor-07.png
│ │ │ │ ├── table-editor-08.png
│ │ │ │ ├── table-editor-09.png
│ │ │ │ └── xmlui-rendering-of-tiptap-markdown.png
│ │ │ ├── favicon.ico
│ │ │ ├── files
│ │ │ │ ├── clients.json
│ │ │ │ ├── daily-revenue.json
│ │ │ │ ├── dashboard-stats.json
│ │ │ │ ├── demo.xmlui
│ │ │ │ ├── demo.xmlui.xs
│ │ │ │ ├── downloads
│ │ │ │ │ └── downloads.json
│ │ │ │ ├── for-download
│ │ │ │ │ ├── index-with-api.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ ├── mockApi.js
│ │ │ │ │ ├── start-darwin.sh
│ │ │ │ │ ├── start-linux.sh
│ │ │ │ │ ├── start.bat
│ │ │ │ │ └── xmlui
│ │ │ │ │ └── xmlui-standalone.umd.js
│ │ │ │ ├── getting-started
│ │ │ │ │ ├── cl-tutorial-final.zip
│ │ │ │ │ ├── cl-tutorial.zip
│ │ │ │ │ ├── cl-tutorial2.zip
│ │ │ │ │ ├── cl-tutorial3.zip
│ │ │ │ │ ├── cl-tutorial4.zip
│ │ │ │ │ ├── cl-tutorial5.zip
│ │ │ │ │ ├── cl-tutorial6.zip
│ │ │ │ │ ├── getting-started.zip
│ │ │ │ │ ├── hello-xmlui.zip
│ │ │ │ │ ├── xmlui-empty.zip
│ │ │ │ │ └── xmlui-starter.zip
│ │ │ │ ├── howto
│ │ │ │ │ └── component-icons
│ │ │ │ │ └── up-arrow.svg
│ │ │ │ ├── invoices.json
│ │ │ │ ├── monthly-status.json
│ │ │ │ ├── news-and-reviews.json
│ │ │ │ ├── products.json
│ │ │ │ ├── releases.json
│ │ │ │ ├── tutorials
│ │ │ │ │ ├── datasource
│ │ │ │ │ │ └── api.ts
│ │ │ │ │ └── p2do
│ │ │ │ │ ├── api.ts
│ │ │ │ │ └── todo-logo.svg
│ │ │ │ └── xmlui.json
│ │ │ ├── github.svg
│ │ │ ├── images
│ │ │ │ ├── apiaction-tutorial
│ │ │ │ │ ├── add-success.png
│ │ │ │ │ ├── apiaction-param.png
│ │ │ │ │ ├── change-completed.png
│ │ │ │ │ ├── change-in-progress.png
│ │ │ │ │ ├── confirm-delete.png
│ │ │ │ │ ├── data-error.png
│ │ │ │ │ ├── data-progress.png
│ │ │ │ │ ├── data-success.png
│ │ │ │ │ ├── display-1.png
│ │ │ │ │ ├── item-deleted.png
│ │ │ │ │ ├── item-updated.png
│ │ │ │ │ ├── missing-api-key.png
│ │ │ │ │ ├── new-item-added.png
│ │ │ │ │ └── test-message.png
│ │ │ │ ├── chat-api
│ │ │ │ │ └── domain-model.svg
│ │ │ │ ├── components
│ │ │ │ │ ├── image
│ │ │ │ │ │ └── breakfast.jpg
│ │ │ │ │ ├── markdown
│ │ │ │ │ │ └── colors.png
│ │ │ │ │ └── modal
│ │ │ │ │ ├── deep_link_dialog_1.jpg
│ │ │ │ │ └── deep_link_dialog_2.jpg
│ │ │ │ ├── create-apps
│ │ │ │ │ ├── collapsed-vertical.png
│ │ │ │ │ ├── using-forms-warning-dialog.png
│ │ │ │ │ └── using-forms.png
│ │ │ │ ├── datasource-tutorial
│ │ │ │ │ ├── data-with-header.png
│ │ │ │ │ ├── filtered-data.png
│ │ │ │ │ ├── filtered-items.png
│ │ │ │ │ ├── initial-page-items.png
│ │ │ │ │ ├── list-items.png
│ │ │ │ │ ├── next-page-items.png
│ │ │ │ │ ├── no-data.png
│ │ │ │ │ ├── pagination-1.jpg
│ │ │ │ │ ├── pagination-1.png
│ │ │ │ │ ├── polling-1.png
│ │ │ │ │ ├── refetch-data.png
│ │ │ │ │ ├── slow-loading.png
│ │ │ │ │ ├── test-message.png
│ │ │ │ │ ├── Thumbs.db
│ │ │ │ │ ├── unconventional-data.png
│ │ │ │ │ └── unfiltered-items.png
│ │ │ │ ├── flower.jpg
│ │ │ │ ├── get-started
│ │ │ │ │ ├── add-new-contact.png
│ │ │ │ │ ├── app-modified.png
│ │ │ │ │ ├── app-start.png
│ │ │ │ │ ├── app-with-boxes.png
│ │ │ │ │ ├── app-with-toast.png
│ │ │ │ │ ├── boilerplate-structure.png
│ │ │ │ │ ├── cl-initial.png
│ │ │ │ │ ├── cl-start.png
│ │ │ │ │ ├── contact-counts.png
│ │ │ │ │ ├── contact-dialog-title.png
│ │ │ │ │ ├── contact-dialog.png
│ │ │ │ │ ├── contact-menus.png
│ │ │ │ │ ├── contact-predicates.png
│ │ │ │ │ ├── context-menu.png
│ │ │ │ │ ├── dashboard-numbers.png
│ │ │ │ │ ├── default-contact-list.png
│ │ │ │ │ ├── delete-contact.png
│ │ │ │ │ ├── delete-task.png
│ │ │ │ │ ├── detailed-template.png
│ │ │ │ │ ├── edit-contact-details.png
│ │ │ │ │ ├── edited-contact-saved.png
│ │ │ │ │ ├── empty-sections.png
│ │ │ │ │ ├── filter-completed.png
│ │ │ │ │ ├── fullwidth-desktop.png
│ │ │ │ │ ├── fullwidth-mobile.png
│ │ │ │ │ ├── initial-table.png
│ │ │ │ │ ├── items-and-badges.png
│ │ │ │ │ ├── loading-message.png
│ │ │ │ │ ├── new-contact-button.png
│ │ │ │ │ ├── new-contact-saved.png
│ │ │ │ │ ├── no-empty-sections.png
│ │ │ │ │ ├── personal-todo-initial.png
│ │ │ │ │ ├── piechart.png
│ │ │ │ │ ├── review-today.png
│ │ │ │ │ ├── rudimentary-dashboard.png
│ │ │ │ │ ├── section-collapsed.png
│ │ │ │ │ ├── sectioned-items.png
│ │ │ │ │ ├── sections-ordered.png
│ │ │ │ │ ├── spacex-list-with-links.png
│ │ │ │ │ ├── spacex-list.png
│ │ │ │ │ ├── start-personal-todo-1.png
│ │ │ │ │ ├── submit-new-contact.png
│ │ │ │ │ ├── submit-new-task.png
│ │ │ │ │ ├── syntax-highlighting.png
│ │ │ │ │ ├── table-with-badge.png
│ │ │ │ │ ├── template-with-card.png
│ │ │ │ │ ├── test-emulated-api.png
│ │ │ │ │ ├── Thumbs.db
│ │ │ │ │ ├── todo-logo.png
│ │ │ │ │ └── xmlui-tools.png
│ │ │ │ ├── HelloApp.png
│ │ │ │ ├── HelloApp2.png
│ │ │ │ ├── logos
│ │ │ │ │ ├── xmlui1.svg
│ │ │ │ │ ├── xmlui2.svg
│ │ │ │ │ ├── xmlui3.svg
│ │ │ │ │ ├── xmlui4.svg
│ │ │ │ │ ├── xmlui5.svg
│ │ │ │ │ ├── xmlui6.svg
│ │ │ │ │ └── xmlui7.svg
│ │ │ │ ├── pdf
│ │ │ │ │ └── dummy-pdf.jpg
│ │ │ │ ├── rendering-engine
│ │ │ │ │ ├── AppEngine-flow.svg
│ │ │ │ │ ├── Component.svg
│ │ │ │ │ ├── CompoundComponent.svg
│ │ │ │ │ ├── RootComponent.svg
│ │ │ │ │ └── tree-with-containers.svg
│ │ │ │ ├── reviewers-guide
│ │ │ │ │ ├── AppEngine-flow.svg
│ │ │ │ │ └── incbutton-in-action.png
│ │ │ │ ├── tools
│ │ │ │ │ └── boilerplate-structure.png
│ │ │ │ ├── try.svg
│ │ │ │ ├── tutorial
│ │ │ │ │ ├── app-chat-history.png
│ │ │ │ │ ├── app-content-placeholder.png
│ │ │ │ │ ├── app-header-and-content.png
│ │ │ │ │ ├── app-links-channel-selected.png
│ │ │ │ │ ├── app-links-click.png
│ │ │ │ │ ├── app-navigation.png
│ │ │ │ │ ├── finished-ex01.png
│ │ │ │ │ ├── finished-ex02.png
│ │ │ │ │ ├── hello.png
│ │ │ │ │ ├── splash-screen-advanced.png
│ │ │ │ │ ├── splash-screen-after-click.png
│ │ │ │ │ ├── splash-screen-centered.png
│ │ │ │ │ ├── splash-screen-events.png
│ │ │ │ │ ├── splash-screen-expression.png
│ │ │ │ │ ├── splash-screen-reuse-after.png
│ │ │ │ │ ├── splash-screen-reuse-before.png
│ │ │ │ │ └── splash-screen.png
│ │ │ │ └── tutorial-01.png
│ │ │ ├── llms.txt
│ │ │ ├── logo-dark.svg
│ │ │ ├── logo.svg
│ │ │ ├── pg-popout.svg
│ │ │ └── xmlui-logo.svg
│ │ ├── serve.json
│ │ └── web.config
│ ├── scripts
│ │ ├── download-latest-xmlui.js
│ │ ├── generate-rss.js
│ │ ├── get-releases.js
│ │ └── utils.js
│ ├── src
│ │ ├── components
│ │ │ ├── BlogOverview.xmlui
│ │ │ ├── BlogPage.xmlui
│ │ │ ├── Boxes.xmlui
│ │ │ ├── Breadcrumb.xmlui
│ │ │ ├── ChangeLog.xmlui
│ │ │ ├── ColorPalette.xmlui
│ │ │ ├── DocumentLinks.xmlui
│ │ │ ├── DocumentPage.xmlui
│ │ │ ├── DocumentPageNoTOC.xmlui
│ │ │ ├── Icons.xmlui
│ │ │ ├── IncButton.xmlui
│ │ │ ├── IncButton2.xmlui
│ │ │ ├── NameValue.xmlui
│ │ │ ├── PageNotFound.xmlui
│ │ │ ├── PaletteItem.xmlui
│ │ │ ├── Palettes.xmlui
│ │ │ ├── SectionHeader.xmlui
│ │ │ ├── TBD.xmlui
│ │ │ ├── Test.xmlui
│ │ │ ├── ThemesIntro.xmlui
│ │ │ ├── ThousandThemes.xmlui
│ │ │ ├── TubeStops.xmlui
│ │ │ ├── TubeStops.xmlui.xs
│ │ │ └── TwoColumnCode.xmlui
│ │ ├── config.ts
│ │ ├── Main.xmlui
│ │ └── themes
│ │ ├── docs-theme.ts
│ │ ├── earthtone.ts
│ │ ├── xmlui-gray-on-default.ts
│ │ ├── xmlui-green-on-default.ts
│ │ └── xmlui-orange-on-default.ts
│ └── tsconfig.json
├── LICENSE
├── package-lock.json
├── package.json
├── packages
│ ├── tsconfig.json
│ ├── xmlui-animations
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── Animation.tsx
│ │ ├── AnimationNative.tsx
│ │ ├── FadeAnimation.tsx
│ │ ├── FadeInAnimation.tsx
│ │ ├── FadeOutAnimation.tsx
│ │ ├── index.tsx
│ │ ├── ScaleAnimation.tsx
│ │ └── SlideInAnimation.tsx
│ ├── xmlui-devtools
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── devtools
│ │ │ │ ├── DevTools.tsx
│ │ │ │ ├── DevToolsNative.module.scss
│ │ │ │ ├── DevToolsNative.tsx
│ │ │ │ ├── ModalDialog.module.scss
│ │ │ │ ├── ModalDialog.tsx
│ │ │ │ ├── ModalVisibilityContext.tsx
│ │ │ │ ├── Tooltip.module.scss
│ │ │ │ ├── Tooltip.tsx
│ │ │ │ └── utils.ts
│ │ │ ├── editor
│ │ │ │ └── Editor.tsx
│ │ │ └── index.tsx
│ │ └── vite.config-overrides.ts
│ ├── xmlui-hello-world
│ │ ├── .gitignore
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── HelloWorld.module.scss
│ │ ├── HelloWorld.tsx
│ │ ├── HelloWorldNative.tsx
│ │ └── index.tsx
│ ├── xmlui-os-frames
│ │ ├── .gitignore
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── index.tsx
│ │ ├── IPhoneFrame.module.scss
│ │ ├── IPhoneFrame.tsx
│ │ ├── MacOSAppFrame.module.scss
│ │ ├── MacOSAppFrame.tsx
│ │ ├── WindowsAppFrame.module.scss
│ │ └── WindowsAppFrame.tsx
│ ├── xmlui-pdf
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ ├── components
│ │ │ │ └── Pdf.xmlui
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── index.tsx
│ │ ├── LazyPdfNative.tsx
│ │ ├── Pdf.module.scss
│ │ └── Pdf.tsx
│ ├── xmlui-playground
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── hooks
│ │ │ ├── usePlayground.ts
│ │ │ └── useToast.ts
│ │ ├── index.tsx
│ │ ├── playground
│ │ │ ├── Box.module.scss
│ │ │ ├── Box.tsx
│ │ │ ├── CodeSelector.tsx
│ │ │ ├── ConfirmationDialog.module.scss
│ │ │ ├── ConfirmationDialog.tsx
│ │ │ ├── Editor.tsx
│ │ │ ├── Header.module.scss
│ │ │ ├── Header.tsx
│ │ │ ├── Playground.tsx
│ │ │ ├── PlaygroundContent.module.scss
│ │ │ ├── PlaygroundContent.tsx
│ │ │ ├── PlaygroundNative.module.scss
│ │ │ ├── PlaygroundNative.tsx
│ │ │ ├── Preview.module.scss
│ │ │ ├── Preview.tsx
│ │ │ ├── Select.module.scss
│ │ │ ├── StandalonePlayground.tsx
│ │ │ ├── StandalonePlaygroundNative.module.scss
│ │ │ ├── StandalonePlaygroundNative.tsx
│ │ │ ├── ThemeSwitcher.module.scss
│ │ │ ├── ThemeSwitcher.tsx
│ │ │ ├── ToneSwitcher.tsx
│ │ │ ├── Tooltip.module.scss
│ │ │ ├── Tooltip.tsx
│ │ │ └── utils.ts
│ │ ├── providers
│ │ │ ├── Toast.module.scss
│ │ │ └── ToastProvider.tsx
│ │ ├── state
│ │ │ └── store.ts
│ │ ├── themes
│ │ │ └── theme.ts
│ │ └── utils
│ │ └── helpers.ts
│ ├── xmlui-search
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── index.tsx
│ │ ├── Search.module.scss
│ │ └── Search.tsx
│ ├── xmlui-spreadsheet
│ │ ├── .gitignore
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── index.tsx
│ │ ├── Spreadsheet.tsx
│ │ └── SpreadsheetNative.tsx
│ └── xmlui-website-blocks
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── demo
│ │ ├── components
│ │ │ ├── HeroBackgroundBreakoutPage.xmlui
│ │ │ ├── HeroBackgroundsPage.xmlui
│ │ │ ├── HeroContentsPage.xmlui
│ │ │ ├── HeroTextAlignPage.xmlui
│ │ │ ├── HeroTextPage.xmlui
│ │ │ └── HeroTonesPage.xmlui
│ │ ├── Main.xmlui
│ │ └── themes
│ │ └── default.ts
│ ├── index.html
│ ├── index.ts
│ ├── meta
│ │ └── componentsMetadata.ts
│ ├── package.json
│ ├── public
│ │ └── resources
│ │ ├── building.jpg
│ │ └── xmlui-logo.svg
│ └── src
│ ├── Carousel
│ │ ├── Carousel.module.scss
│ │ ├── Carousel.tsx
│ │ ├── CarouselContext.tsx
│ │ └── CarouselNative.tsx
│ ├── FancyButton
│ │ ├── FancyButton.module.scss
│ │ ├── FancyButton.tsx
│ │ └── FancyButton.xmlui
│ ├── Hello
│ │ ├── Hello.tsx
│ │ ├── Hello.xmlui
│ │ └── Hello.xmlui.xs
│ ├── HeroSection
│ │ ├── HeroSection.module.scss
│ │ ├── HeroSection.spec.ts
│ │ ├── HeroSection.tsx
│ │ └── HeroSectionNative.tsx
│ ├── index.tsx
│ ├── ScrollToTop
│ │ ├── ScrollToTop.module.scss
│ │ ├── ScrollToTop.tsx
│ │ └── ScrollToTopNative.tsx
│ └── vite-env.d.ts
├── playwright.config.ts
├── README.md
├── tools
│ ├── codefence
│ │ └── xmlui-code-fence-docs.md
│ ├── create-app
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── create-app.ts
│ │ ├── helpers
│ │ │ ├── copy.ts
│ │ │ ├── get-pkg-manager.ts
│ │ │ ├── git.ts
│ │ │ ├── install.ts
│ │ │ ├── is-folder-empty.ts
│ │ │ ├── is-writeable.ts
│ │ │ ├── make-dir.ts
│ │ │ └── validate-pkg.ts
│ │ ├── index.ts
│ │ ├── package.json
│ │ ├── templates
│ │ │ ├── default
│ │ │ │ └── ts
│ │ │ │ ├── gitignore
│ │ │ │ ├── index.html
│ │ │ │ ├── index.ts
│ │ │ │ ├── public
│ │ │ │ │ ├── mockServiceWorker.js
│ │ │ │ │ ├── resources
│ │ │ │ │ │ ├── favicon.ico
│ │ │ │ │ │ └── xmlui-logo.svg
│ │ │ │ │ └── serve.json
│ │ │ │ └── src
│ │ │ │ ├── components
│ │ │ │ │ ├── ApiAware.xmlui
│ │ │ │ │ ├── Home.xmlui
│ │ │ │ │ ├── IncButton.xmlui
│ │ │ │ │ └── PagePanel.xmlui
│ │ │ │ ├── config.ts
│ │ │ │ └── Main.xmlui
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── tsconfig.json
│ ├── create-xmlui-hello-world
│ │ ├── index.js
│ │ └── package.json
│ └── vscode
│ ├── .gitignore
│ ├── .vscode
│ │ ├── launch.json
│ │ └── tasks.json
│ ├── .vscodeignore
│ ├── build.sh
│ ├── CHANGELOG.md
│ ├── esbuild.js
│ ├── eslint.config.mjs
│ ├── formatter-docs.md
│ ├── generate-test-sample.sh
│ ├── LICENSE.md
│ ├── package-lock.json
│ ├── package.json
│ ├── README.md
│ ├── resources
│ │ ├── xmlui-logo.png
│ │ └── xmlui-markup-syntax-highlighting.png
│ ├── src
│ │ ├── extension.ts
│ │ └── server.ts
│ ├── syntaxes
│ │ └── xmlui.tmLanguage.json
│ ├── test-samples
│ │ └── sample.xmlui
│ ├── tsconfig.json
│ └── tsconfig.tsbuildinfo
├── turbo.json
└── xmlui
├── .gitignore
├── bin
│ ├── bootstrap.cjs
│ ├── bootstrap.js
│ ├── build-lib.ts
│ ├── build.ts
│ ├── index.ts
│ ├── preview.ts
│ ├── start.ts
│ ├── vite-xmlui-plugin.ts
│ └── viteConfig.ts
├── CHANGELOG.md
├── conventions
│ ├── component-qa-checklist.md
│ ├── copilot-conventions.md
│ ├── create-xmlui-components.md
│ ├── mermaid.md
│ ├── testing-conventions.md
│ └── xmlui-in-a-nutshell.md
├── dev-docs
│ ├── accessibility.md
│ ├── build-system.md
│ ├── build-xmlui.md
│ ├── component-behaviors.md
│ ├── component-metadata.md
│ ├── components-with-options.md
│ ├── containers.md
│ ├── data-operations.md
│ ├── glossary.md
│ ├── index.md
│ ├── next
│ │ ├── component-dev-guide.md
│ │ ├── configuration-management-enhancement-summary.md
│ │ ├── documentation-scripts-refactoring-complete-summary.md
│ │ ├── documentation-scripts-refactoring-plan.md
│ │ ├── duplicate-pattern-extraction-summary.md
│ │ ├── error-handling-standardization-summary.md
│ │ ├── generating-component-reference.md
│ │ ├── index.md
│ │ ├── logging-consistency-implementation-summary.md
│ │ ├── project-build.md
│ │ ├── project-structure.md
│ │ ├── theme-context.md
│ │ ├── tiptap-design-considerations.md
│ │ ├── working-with-code.md
│ │ ├── xmlui-runtime-architecture
│ │ └── xmlui-wcag-accessibility-report.md
│ ├── react-fundamentals.md
│ ├── release-method.md
│ ├── standalone-app.md
│ ├── theme-variables-refactoring.md
│ ├── ud-components.md
│ └── xmlui-repo.md
├── package.json
├── scripts
│ ├── coverage-only.js
│ ├── e2e-test-summary.js
│ ├── extract-component-metadata.js
│ ├── generate-docs
│ │ ├── build-downloads-map.mjs
│ │ ├── build-pages-map.mjs
│ │ ├── components-config.json
│ │ ├── configuration-management.mjs
│ │ ├── constants.mjs
│ │ ├── create-theme-files.mjs
│ │ ├── DocsGenerator.mjs
│ │ ├── error-handling.mjs
│ │ ├── extensions-config.json
│ │ ├── folders.mjs
│ │ ├── generate-summary-files.mjs
│ │ ├── get-docs.mjs
│ │ ├── input-handler.mjs
│ │ ├── logger.mjs
│ │ ├── logging-standards.mjs
│ │ ├── MetadataProcessor.mjs
│ │ ├── pattern-utilities.mjs
│ │ └── utils.mjs
│ ├── generate-metadata-markdown.js
│ ├── get-langserver-metadata.js
│ ├── inline-links.mjs
│ └── README-e2e-summary.md
├── src
│ ├── abstractions
│ │ ├── _conventions.md
│ │ ├── ActionDefs.ts
│ │ ├── AppContextDefs.ts
│ │ ├── ComponentDefs.ts
│ │ ├── ContainerDefs.ts
│ │ ├── ExtensionDefs.ts
│ │ ├── FunctionDefs.ts
│ │ ├── RendererDefs.ts
│ │ ├── scripting
│ │ │ ├── BlockScope.ts
│ │ │ ├── Compilation.ts
│ │ │ ├── LogicalThread.ts
│ │ │ ├── LoopScope.ts
│ │ │ ├── modules.ts
│ │ │ ├── ScriptParserError.ts
│ │ │ ├── Token.ts
│ │ │ ├── TryScope.ts
│ │ │ └── TryScopeExp.ts
│ │ └── ThemingDefs.ts
│ ├── components
│ │ ├── _conventions.md
│ │ ├── abstractions.ts
│ │ ├── Accordion
│ │ │ ├── Accordion.md
│ │ │ ├── Accordion.module.scss
│ │ │ ├── Accordion.spec.ts
│ │ │ ├── Accordion.tsx
│ │ │ ├── AccordionContext.tsx
│ │ │ ├── AccordionItem.tsx
│ │ │ ├── AccordionItemNative.tsx
│ │ │ └── AccordionNative.tsx
│ │ ├── Animation
│ │ │ └── AnimationNative.tsx
│ │ ├── APICall
│ │ │ ├── APICall.md
│ │ │ ├── APICall.spec.ts
│ │ │ ├── APICall.tsx
│ │ │ └── APICallNative.tsx
│ │ ├── App
│ │ │ ├── App.md
│ │ │ ├── App.module.scss
│ │ │ ├── App.spec.ts
│ │ │ ├── App.tsx
│ │ │ ├── AppLayoutContext.ts
│ │ │ ├── AppNative.tsx
│ │ │ ├── AppStateContext.ts
│ │ │ ├── doc-resources
│ │ │ │ ├── condensed-sticky.xmlui
│ │ │ │ ├── condensed.xmlui
│ │ │ │ ├── horizontal-sticky.xmlui
│ │ │ │ ├── horizontal.xmlui
│ │ │ │ ├── vertical-full-header.xmlui
│ │ │ │ ├── vertical-sticky.xmlui
│ │ │ │ └── vertical.xmlui
│ │ │ ├── IndexerContext.ts
│ │ │ ├── LinkInfoContext.ts
│ │ │ ├── SearchContext.tsx
│ │ │ ├── Sheet.module.scss
│ │ │ └── Sheet.tsx
│ │ ├── AppHeader
│ │ │ ├── AppHeader.md
│ │ │ ├── AppHeader.module.scss
│ │ │ ├── AppHeader.spec.ts
│ │ │ ├── AppHeader.tsx
│ │ │ └── AppHeaderNative.tsx
│ │ ├── AppState
│ │ │ ├── AppState.md
│ │ │ ├── AppState.spec.ts
│ │ │ ├── AppState.tsx
│ │ │ └── AppStateNative.tsx
│ │ ├── AutoComplete
│ │ │ ├── AutoComplete.md
│ │ │ ├── AutoComplete.module.scss
│ │ │ ├── AutoComplete.spec.ts
│ │ │ ├── AutoComplete.tsx
│ │ │ ├── AutoCompleteContext.tsx
│ │ │ └── AutoCompleteNative.tsx
│ │ ├── Avatar
│ │ │ ├── Avatar.md
│ │ │ ├── Avatar.module.scss
│ │ │ ├── Avatar.spec.ts
│ │ │ ├── Avatar.tsx
│ │ │ └── AvatarNative.tsx
│ │ ├── Backdrop
│ │ │ ├── Backdrop.md
│ │ │ ├── Backdrop.module.scss
│ │ │ ├── Backdrop.spec.ts
│ │ │ ├── Backdrop.tsx
│ │ │ └── BackdropNative.tsx
│ │ ├── Badge
│ │ │ ├── Badge.md
│ │ │ ├── Badge.module.scss
│ │ │ ├── Badge.spec.ts
│ │ │ ├── Badge.tsx
│ │ │ └── BadgeNative.tsx
│ │ ├── Bookmark
│ │ │ ├── Bookmark.md
│ │ │ ├── Bookmark.module.scss
│ │ │ ├── Bookmark.spec.ts
│ │ │ ├── Bookmark.tsx
│ │ │ └── BookmarkNative.tsx
│ │ ├── Breakout
│ │ │ ├── Breakout.module.scss
│ │ │ ├── Breakout.spec.ts
│ │ │ ├── Breakout.tsx
│ │ │ └── BreakoutNative.tsx
│ │ ├── Button
│ │ │ ├── Button-style.spec.ts
│ │ │ ├── Button.md
│ │ │ ├── Button.module.scss
│ │ │ ├── Button.spec.ts
│ │ │ ├── Button.tsx
│ │ │ └── ButtonNative.tsx
│ │ ├── Card
│ │ │ ├── Card.md
│ │ │ ├── Card.module.scss
│ │ │ ├── Card.spec.ts
│ │ │ ├── Card.tsx
│ │ │ └── CardNative.tsx
│ │ ├── Carousel
│ │ │ ├── Carousel.md
│ │ │ ├── Carousel.module.scss
│ │ │ ├── Carousel.spec.ts
│ │ │ ├── Carousel.tsx
│ │ │ ├── CarouselContext.tsx
│ │ │ ├── CarouselItem.tsx
│ │ │ ├── CarouselItemNative.tsx
│ │ │ └── CarouselNative.tsx
│ │ ├── ChangeListener
│ │ │ ├── ChangeListener.md
│ │ │ ├── ChangeListener.spec.ts
│ │ │ ├── ChangeListener.tsx
│ │ │ └── ChangeListenerNative.tsx
│ │ ├── chart-color-schemes.ts
│ │ ├── Charts
│ │ │ ├── AreaChart
│ │ │ │ ├── AreaChart.md
│ │ │ │ ├── AreaChart.spec.ts
│ │ │ │ ├── AreaChart.tsx
│ │ │ │ └── AreaChartNative.tsx
│ │ │ ├── BarChart
│ │ │ │ ├── BarChart.md
│ │ │ │ ├── BarChart.module.scss
│ │ │ │ ├── BarChart.spec.ts
│ │ │ │ ├── BarChart.tsx
│ │ │ │ └── BarChartNative.tsx
│ │ │ ├── DonutChart
│ │ │ │ ├── DonutChart.spec.ts
│ │ │ │ └── DonutChart.tsx
│ │ │ ├── LabelList
│ │ │ │ ├── LabelList.module.scss
│ │ │ │ ├── LabelList.spec.ts
│ │ │ │ ├── LabelList.tsx
│ │ │ │ └── LabelListNative.tsx
│ │ │ ├── Legend
│ │ │ │ ├── Legend.spec.ts
│ │ │ │ ├── Legend.tsx
│ │ │ │ └── LegendNative.tsx
│ │ │ ├── LineChart
│ │ │ │ ├── LineChart.md
│ │ │ │ ├── LineChart.module.scss
│ │ │ │ ├── LineChart.spec.ts
│ │ │ │ ├── LineChart.tsx
│ │ │ │ └── LineChartNative.tsx
│ │ │ ├── PieChart
│ │ │ │ ├── PieChart.md
│ │ │ │ ├── PieChart.spec.ts
│ │ │ │ ├── PieChart.tsx
│ │ │ │ ├── PieChartNative.module.scss
│ │ │ │ └── PieChartNative.tsx
│ │ │ ├── RadarChart
│ │ │ │ ├── RadarChart.md
│ │ │ │ ├── RadarChart.spec.ts
│ │ │ │ ├── RadarChart.tsx
│ │ │ │ └── RadarChartNative.tsx
│ │ │ ├── Tooltip
│ │ │ │ ├── TooltipContent.module.scss
│ │ │ │ ├── TooltipContent.spec.ts
│ │ │ │ └── TooltipContent.tsx
│ │ │ └── utils
│ │ │ ├── abstractions.ts
│ │ │ └── ChartProvider.tsx
│ │ ├── Checkbox
│ │ │ ├── Checkbox.md
│ │ │ ├── Checkbox.spec.ts
│ │ │ └── Checkbox.tsx
│ │ ├── CodeBlock
│ │ │ ├── CodeBlock.module.scss
│ │ │ ├── CodeBlock.spec.ts
│ │ │ ├── CodeBlock.tsx
│ │ │ ├── CodeBlockNative.tsx
│ │ │ └── highlight-code.ts
│ │ ├── collectedComponentMetadata.ts
│ │ ├── ColorPicker
│ │ │ ├── ColorPicker.md
│ │ │ ├── ColorPicker.module.scss
│ │ │ ├── ColorPicker.spec.ts
│ │ │ ├── ColorPicker.tsx
│ │ │ └── ColorPickerNative.tsx
│ │ ├── Column
│ │ │ ├── Column.md
│ │ │ ├── Column.tsx
│ │ │ ├── ColumnNative.tsx
│ │ │ ├── doc-resources
│ │ │ │ └── list-component-data.js
│ │ │ └── TableContext.tsx
│ │ ├── component-utils.ts
│ │ ├── ComponentProvider.tsx
│ │ ├── ComponentRegistryContext.tsx
│ │ ├── container-helpers.tsx
│ │ ├── ContentSeparator
│ │ │ ├── ContentSeparator.md
│ │ │ ├── ContentSeparator.module.scss
│ │ │ ├── ContentSeparator.spec.ts
│ │ │ ├── ContentSeparator.tsx
│ │ │ └── ContentSeparatorNative.tsx
│ │ ├── DataSource
│ │ │ ├── DataSource.md
│ │ │ └── DataSource.tsx
│ │ ├── DateInput
│ │ │ ├── DateInput.md
│ │ │ ├── DateInput.module.scss
│ │ │ ├── DateInput.spec.ts
│ │ │ ├── DateInput.tsx
│ │ │ └── DateInputNative.tsx
│ │ ├── DatePicker
│ │ │ ├── DatePicker.md
│ │ │ ├── DatePicker.module.scss
│ │ │ ├── DatePicker.spec.ts
│ │ │ ├── DatePicker.tsx
│ │ │ └── DatePickerNative.tsx
│ │ ├── DropdownMenu
│ │ │ ├── DropdownMenu.md
│ │ │ ├── DropdownMenu.module.scss
│ │ │ ├── DropdownMenu.spec.ts
│ │ │ ├── DropdownMenu.tsx
│ │ │ ├── DropdownMenuNative.tsx
│ │ │ ├── MenuItem.md
│ │ │ └── SubMenuItem.md
│ │ ├── EmojiSelector
│ │ │ ├── EmojiSelector.md
│ │ │ ├── EmojiSelector.spec.ts
│ │ │ ├── EmojiSelector.tsx
│ │ │ └── EmojiSelectorNative.tsx
│ │ ├── ExpandableItem
│ │ │ ├── ExpandableItem.module.scss
│ │ │ ├── ExpandableItem.spec.ts
│ │ │ ├── ExpandableItem.tsx
│ │ │ └── ExpandableItemNative.tsx
│ │ ├── FileInput
│ │ │ ├── FileInput.md
│ │ │ ├── FileInput.module.scss
│ │ │ ├── FileInput.spec.ts
│ │ │ ├── FileInput.tsx
│ │ │ └── FileInputNative.tsx
│ │ ├── FileUploadDropZone
│ │ │ ├── FileUploadDropZone.md
│ │ │ ├── FileUploadDropZone.module.scss
│ │ │ ├── FileUploadDropZone.spec.ts
│ │ │ ├── FileUploadDropZone.tsx
│ │ │ └── FileUploadDropZoneNative.tsx
│ │ ├── FlowLayout
│ │ │ ├── FlowLayout.md
│ │ │ ├── FlowLayout.module.scss
│ │ │ ├── FlowLayout.spec.ts
│ │ │ ├── FlowLayout.spec.ts-snapshots
│ │ │ │ └── Edge-cases-boxShadow-is-not-clipped-1-non-smoke-darwin.png
│ │ │ ├── FlowLayout.tsx
│ │ │ └── FlowLayoutNative.tsx
│ │ ├── Footer
│ │ │ ├── Footer.md
│ │ │ ├── Footer.module.scss
│ │ │ ├── Footer.spec.ts
│ │ │ ├── Footer.tsx
│ │ │ └── FooterNative.tsx
│ │ ├── Form
│ │ │ ├── Form.md
│ │ │ ├── Form.module.scss
│ │ │ ├── Form.spec.ts
│ │ │ ├── Form.tsx
│ │ │ ├── formActions.ts
│ │ │ ├── FormContext.ts
│ │ │ └── FormNative.tsx
│ │ ├── FormItem
│ │ │ ├── FormItem.md
│ │ │ ├── FormItem.module.scss
│ │ │ ├── FormItem.spec.ts
│ │ │ ├── FormItem.tsx
│ │ │ ├── FormItemNative.tsx
│ │ │ ├── HelperText.module.scss
│ │ │ ├── HelperText.tsx
│ │ │ ├── ItemWithLabel.tsx
│ │ │ └── Validations.ts
│ │ ├── FormSection
│ │ │ ├── FormSection.md
│ │ │ ├── FormSection.ts
│ │ │ └── FormSection.xmlui
│ │ ├── Fragment
│ │ │ ├── Fragment.spec.ts
│ │ │ └── Fragment.tsx
│ │ ├── Heading
│ │ │ ├── abstractions.ts
│ │ │ ├── H1.md
│ │ │ ├── H1.spec.ts
│ │ │ ├── H2.md
│ │ │ ├── H2.spec.ts
│ │ │ ├── H3.md
│ │ │ ├── H3.spec.ts
│ │ │ ├── H4.md
│ │ │ ├── H4.spec.ts
│ │ │ ├── H5.md
│ │ │ ├── H5.spec.ts
│ │ │ ├── H6.md
│ │ │ ├── H6.spec.ts
│ │ │ ├── Heading.md
│ │ │ ├── Heading.module.scss
│ │ │ ├── Heading.spec.ts
│ │ │ ├── Heading.tsx
│ │ │ └── HeadingNative.tsx
│ │ ├── HoverCard
│ │ │ ├── HoverCard.tsx
│ │ │ └── HovercardNative.tsx
│ │ ├── HtmlTags
│ │ │ ├── HtmlTags.module.scss
│ │ │ ├── HtmlTags.spec.ts
│ │ │ └── HtmlTags.tsx
│ │ ├── Icon
│ │ │ ├── AdmonitionDanger.tsx
│ │ │ ├── AdmonitionInfo.tsx
│ │ │ ├── AdmonitionNote.tsx
│ │ │ ├── AdmonitionTip.tsx
│ │ │ ├── AdmonitionWarning.tsx
│ │ │ ├── ApiIcon.tsx
│ │ │ ├── ArrowDropDown.module.scss
│ │ │ ├── ArrowDropDown.tsx
│ │ │ ├── ArrowDropUp.module.scss
│ │ │ ├── ArrowDropUp.tsx
│ │ │ ├── ArrowLeft.module.scss
│ │ │ ├── ArrowLeft.tsx
│ │ │ ├── ArrowRight.module.scss
│ │ │ ├── ArrowRight.tsx
│ │ │ ├── Attach.tsx
│ │ │ ├── Binding.module.scss
│ │ │ ├── Binding.tsx
│ │ │ ├── BoardIcon.tsx
│ │ │ ├── BoxIcon.tsx
│ │ │ ├── CheckIcon.tsx
│ │ │ ├── ChevronDownIcon.tsx
│ │ │ ├── ChevronLeft.tsx
│ │ │ ├── ChevronRight.tsx
│ │ │ ├── ChevronUpIcon.tsx
│ │ │ ├── CodeFileIcon.tsx
│ │ │ ├── CodeSandbox.tsx
│ │ │ ├── CompactListIcon.tsx
│ │ │ ├── ContentCopyIcon.tsx
│ │ │ ├── DarkToLightIcon.tsx
│ │ │ ├── DatabaseIcon.module.scss
│ │ │ ├── DatabaseIcon.tsx
│ │ │ ├── DocFileIcon.tsx
│ │ │ ├── DocIcon.tsx
│ │ │ ├── DotMenuHorizontalIcon.tsx
│ │ │ ├── DotMenuIcon.tsx
│ │ │ ├── EmailIcon.tsx
│ │ │ ├── EmptyFolderIcon.tsx
│ │ │ ├── ErrorIcon.tsx
│ │ │ ├── ExpressionIcon.tsx
│ │ │ ├── FillPlusCricleIcon.tsx
│ │ │ ├── FilterIcon.tsx
│ │ │ ├── FolderIcon.tsx
│ │ │ ├── GlobeIcon.tsx
│ │ │ ├── HomeIcon.tsx
│ │ │ ├── HyperLinkIcon.tsx
│ │ │ ├── Icon.md
│ │ │ ├── Icon.module.scss
│ │ │ ├── Icon.spec.ts
│ │ │ ├── Icon.tsx
│ │ │ ├── IconNative.tsx
│ │ │ ├── ImageFileIcon.tsx
│ │ │ ├── Inspect.tsx
│ │ │ ├── LightToDark.tsx
│ │ │ ├── LinkIcon.tsx
│ │ │ ├── ListIcon.tsx
│ │ │ ├── LooseListIcon.tsx
│ │ │ ├── MoonIcon.tsx
│ │ │ ├── MoreOptionsIcon.tsx
│ │ │ ├── NoSortIcon.tsx
│ │ │ ├── PDFIcon.tsx
│ │ │ ├── PenIcon.tsx
│ │ │ ├── PhoneIcon.tsx
│ │ │ ├── PhotoIcon.tsx
│ │ │ ├── PlusIcon.tsx
│ │ │ ├── SearchIcon.tsx
│ │ │ ├── ShareIcon.tsx
│ │ │ ├── SortAscendingIcon.tsx
│ │ │ ├── SortDescendingIcon.tsx
│ │ │ ├── StarsIcon.tsx
│ │ │ ├── SunIcon.tsx
│ │ │ ├── svg
│ │ │ │ ├── admonition_danger.svg
│ │ │ │ ├── admonition_info.svg
│ │ │ │ ├── admonition_note.svg
│ │ │ │ ├── admonition_tip.svg
│ │ │ │ ├── admonition_warning.svg
│ │ │ │ ├── api.svg
│ │ │ │ ├── arrow-dropdown.svg
│ │ │ │ ├── arrow-left.svg
│ │ │ │ ├── arrow-right.svg
│ │ │ │ ├── arrow-up.svg
│ │ │ │ ├── attach.svg
│ │ │ │ ├── binding.svg
│ │ │ │ ├── box.svg
│ │ │ │ ├── bulb.svg
│ │ │ │ ├── code-file.svg
│ │ │ │ ├── code-sandbox.svg
│ │ │ │ ├── dark_to_light.svg
│ │ │ │ ├── database.svg
│ │ │ │ ├── doc.svg
│ │ │ │ ├── empty-folder.svg
│ │ │ │ ├── expression.svg
│ │ │ │ ├── eye-closed.svg
│ │ │ │ ├── eye-dark.svg
│ │ │ │ ├── eye.svg
│ │ │ │ ├── file-text.svg
│ │ │ │ ├── filter.svg
│ │ │ │ ├── folder.svg
│ │ │ │ ├── img.svg
│ │ │ │ ├── inspect.svg
│ │ │ │ ├── light_to_dark.svg
│ │ │ │ ├── moon.svg
│ │ │ │ ├── pdf.svg
│ │ │ │ ├── photo.svg
│ │ │ │ ├── share.svg
│ │ │ │ ├── stars.svg
│ │ │ │ ├── sun.svg
│ │ │ │ ├── trending-down.svg
│ │ │ │ ├── trending-level.svg
│ │ │ │ ├── trending-up.svg
│ │ │ │ ├── txt.svg
│ │ │ │ ├── unknown-file.svg
│ │ │ │ ├── unlink.svg
│ │ │ │ └── xls.svg
│ │ │ ├── TableDeleteColumnIcon.tsx
│ │ │ ├── TableDeleteRowIcon.tsx
│ │ │ ├── TableInsertColumnIcon.tsx
│ │ │ ├── TableInsertRowIcon.tsx
│ │ │ ├── TrashIcon.tsx
│ │ │ ├── TrendingDownIcon.tsx
│ │ │ ├── TrendingLevelIcon.tsx
│ │ │ ├── TrendingUpIcon.tsx
│ │ │ ├── TxtIcon.tsx
│ │ │ ├── UnknownFileIcon.tsx
│ │ │ ├── UnlinkIcon.tsx
│ │ │ ├── UserIcon.tsx
│ │ │ ├── WarningIcon.tsx
│ │ │ └── XlsIcon.tsx
│ │ ├── IconProvider.tsx
│ │ ├── IconRegistryContext.tsx
│ │ ├── IFrame
│ │ │ ├── IFrame.md
│ │ │ ├── IFrame.module.scss
│ │ │ ├── IFrame.spec.ts
│ │ │ ├── IFrame.tsx
│ │ │ └── IFrameNative.tsx
│ │ ├── Image
│ │ │ ├── Image.md
│ │ │ ├── Image.module.scss
│ │ │ ├── Image.spec.ts
│ │ │ ├── Image.tsx
│ │ │ └── ImageNative.tsx
│ │ ├── Input
│ │ │ ├── index.ts
│ │ │ ├── InputAdornment.module.scss
│ │ │ ├── InputAdornment.tsx
│ │ │ ├── InputDivider.module.scss
│ │ │ ├── InputDivider.tsx
│ │ │ ├── InputLabel.module.scss
│ │ │ ├── InputLabel.tsx
│ │ │ ├── PartialInput.module.scss
│ │ │ └── PartialInput.tsx
│ │ ├── InspectButton
│ │ │ ├── InspectButton.module.scss
│ │ │ └── InspectButton.tsx
│ │ ├── Items
│ │ │ ├── Items.md
│ │ │ ├── Items.spec.ts
│ │ │ ├── Items.tsx
│ │ │ └── ItemsNative.tsx
│ │ ├── Link
│ │ │ ├── Link.md
│ │ │ ├── Link.module.scss
│ │ │ ├── Link.spec.ts
│ │ │ ├── Link.tsx
│ │ │ └── LinkNative.tsx
│ │ ├── List
│ │ │ ├── doc-resources
│ │ │ │ └── list-component-data.js
│ │ │ ├── List.md
│ │ │ ├── List.module.scss
│ │ │ ├── List.spec.ts
│ │ │ ├── List.tsx
│ │ │ └── ListNative.tsx
│ │ ├── Logo
│ │ │ ├── doc-resources
│ │ │ │ └── xmlui-logo.svg
│ │ │ ├── Logo.md
│ │ │ ├── Logo.tsx
│ │ │ └── LogoNative.tsx
│ │ ├── Markdown
│ │ │ ├── CodeText.module.scss
│ │ │ ├── CodeText.tsx
│ │ │ ├── Markdown.md
│ │ │ ├── Markdown.module.scss
│ │ │ ├── Markdown.spec.ts
│ │ │ ├── Markdown.tsx
│ │ │ ├── MarkdownNative.tsx
│ │ │ ├── parse-binding-expr.ts
│ │ │ └── utils.ts
│ │ ├── metadata-helpers.ts
│ │ ├── ModalDialog
│ │ │ ├── ConfirmationModalContextProvider.tsx
│ │ │ ├── Dialog.module.scss
│ │ │ ├── Dialog.tsx
│ │ │ ├── ModalDialog.md
│ │ │ ├── ModalDialog.module.scss
│ │ │ ├── ModalDialog.spec.ts
│ │ │ ├── ModalDialog.tsx
│ │ │ ├── ModalDialogNative.tsx
│ │ │ └── ModalVisibilityContext.tsx
│ │ ├── NavGroup
│ │ │ ├── NavGroup.md
│ │ │ ├── NavGroup.module.scss
│ │ │ ├── NavGroup.spec.ts
│ │ │ ├── NavGroup.tsx
│ │ │ ├── NavGroupContext.ts
│ │ │ └── NavGroupNative.tsx
│ │ ├── NavLink
│ │ │ ├── NavLink.md
│ │ │ ├── NavLink.module.scss
│ │ │ ├── NavLink.spec.ts
│ │ │ ├── NavLink.tsx
│ │ │ └── NavLinkNative.tsx
│ │ ├── NavPanel
│ │ │ ├── NavPanel.md
│ │ │ ├── NavPanel.module.scss
│ │ │ ├── NavPanel.spec.ts
│ │ │ ├── NavPanel.tsx
│ │ │ └── NavPanelNative.tsx
│ │ ├── NestedApp
│ │ │ ├── AppWithCodeView.module.scss
│ │ │ ├── AppWithCodeView.tsx
│ │ │ ├── AppWithCodeViewNative.tsx
│ │ │ ├── defaultProps.tsx
│ │ │ ├── logo.svg
│ │ │ ├── NestedApp.module.scss
│ │ │ ├── NestedApp.tsx
│ │ │ ├── NestedAppNative.tsx
│ │ │ ├── Tooltip.module.scss
│ │ │ ├── Tooltip.tsx
│ │ │ └── utils.ts
│ │ ├── NoResult
│ │ │ ├── NoResult.md
│ │ │ ├── NoResult.module.scss
│ │ │ ├── NoResult.spec.ts
│ │ │ ├── NoResult.tsx
│ │ │ └── NoResultNative.tsx
│ │ ├── NumberBox
│ │ │ ├── numberbox-abstractions.ts
│ │ │ ├── NumberBox.md
│ │ │ ├── NumberBox.module.scss
│ │ │ ├── NumberBox.spec.ts
│ │ │ ├── NumberBox.tsx
│ │ │ └── NumberBoxNative.tsx
│ │ ├── Option
│ │ │ ├── Option.md
│ │ │ ├── Option.spec.ts
│ │ │ ├── Option.tsx
│ │ │ ├── OptionNative.tsx
│ │ │ └── OptionTypeProvider.tsx
│ │ ├── PageMetaTitle
│ │ │ ├── PageMetaTilteNative.tsx
│ │ │ ├── PageMetaTitle.md
│ │ │ ├── PageMetaTitle.spec.ts
│ │ │ └── PageMetaTitle.tsx
│ │ ├── Pages
│ │ │ ├── Page.md
│ │ │ ├── Pages.md
│ │ │ ├── Pages.module.scss
│ │ │ ├── Pages.tsx
│ │ │ └── PagesNative.tsx
│ │ ├── Pagination
│ │ │ ├── Pagination.md
│ │ │ ├── Pagination.module.scss
│ │ │ ├── Pagination.spec.ts
│ │ │ ├── Pagination.tsx
│ │ │ └── PaginationNative.tsx
│ │ ├── PositionedContainer
│ │ │ ├── PositionedContainer.module.scss
│ │ │ ├── PositionedContainer.tsx
│ │ │ └── PositionedContainerNative.tsx
│ │ ├── ProfileMenu
│ │ │ ├── ProfileMenu.module.scss
│ │ │ └── ProfileMenu.tsx
│ │ ├── ProgressBar
│ │ │ ├── ProgressBar.md
│ │ │ ├── ProgressBar.module.scss
│ │ │ ├── ProgressBar.spec.ts
│ │ │ ├── ProgressBar.tsx
│ │ │ └── ProgressBarNative.tsx
│ │ ├── Queue
│ │ │ ├── Queue.md
│ │ │ ├── Queue.spec.ts
│ │ │ ├── Queue.tsx
│ │ │ ├── queueActions.ts
│ │ │ └── QueueNative.tsx
│ │ ├── RadioGroup
│ │ │ ├── RadioGroup.md
│ │ │ ├── RadioGroup.module.scss
│ │ │ ├── RadioGroup.spec.ts
│ │ │ ├── RadioGroup.tsx
│ │ │ ├── RadioGroupNative.tsx
│ │ │ ├── RadioItem.tsx
│ │ │ └── RadioItemNative.tsx
│ │ ├── RealTimeAdapter
│ │ │ ├── RealTimeAdapter.tsx
│ │ │ └── RealTimeAdapterNative.tsx
│ │ ├── Redirect
│ │ │ ├── Redirect.md
│ │ │ ├── Redirect.spec.ts
│ │ │ └── Redirect.tsx
│ │ ├── ResponsiveBar
│ │ │ ├── README.md
│ │ │ ├── ResponsiveBar.md
│ │ │ ├── ResponsiveBar.module.scss
│ │ │ ├── ResponsiveBar.spec.ts
│ │ │ ├── ResponsiveBar.tsx
│ │ │ └── ResponsiveBarNative.tsx
│ │ ├── Select
│ │ │ ├── HiddenOption.tsx
│ │ │ ├── OptionContext.ts
│ │ │ ├── Select.md
│ │ │ ├── Select.module.scss
│ │ │ ├── Select.spec.ts
│ │ │ ├── Select.tsx
│ │ │ ├── SelectContext.tsx
│ │ │ └── SelectNative.tsx
│ │ ├── SelectionStore
│ │ │ ├── SelectionStore.md
│ │ │ ├── SelectionStore.tsx
│ │ │ └── SelectionStoreNative.tsx
│ │ ├── Slider
│ │ │ ├── Slider.md
│ │ │ ├── Slider.module.scss
│ │ │ ├── Slider.spec.ts
│ │ │ ├── Slider.tsx
│ │ │ └── SliderNative.tsx
│ │ ├── Slot
│ │ │ ├── Slot.md
│ │ │ ├── Slot.spec.ts
│ │ │ └── Slot.ts
│ │ ├── SlotItem.tsx
│ │ ├── SpaceFiller
│ │ │ ├── SpaceFiller.md
│ │ │ ├── SpaceFiller.module.scss
│ │ │ ├── SpaceFiller.spec.ts
│ │ │ ├── SpaceFiller.tsx
│ │ │ └── SpaceFillerNative.tsx
│ │ ├── Spinner
│ │ │ ├── Spinner.md
│ │ │ ├── Spinner.module.scss
│ │ │ ├── Spinner.spec.ts
│ │ │ ├── Spinner.tsx
│ │ │ └── SpinnerNative.tsx
│ │ ├── Splitter
│ │ │ ├── HSplitter.md
│ │ │ ├── HSplitter.spec.ts
│ │ │ ├── Splitter.md
│ │ │ ├── Splitter.module.scss
│ │ │ ├── Splitter.spec.ts
│ │ │ ├── Splitter.tsx
│ │ │ ├── SplitterNative.tsx
│ │ │ ├── utils.ts
│ │ │ ├── VSplitter.md
│ │ │ └── VSplitter.spec.ts
│ │ ├── Stack
│ │ │ ├── CHStack.md
│ │ │ ├── CHStack.spec.ts
│ │ │ ├── CVStack.md
│ │ │ ├── CVStack.spec.ts
│ │ │ ├── HStack.md
│ │ │ ├── HStack.spec.ts
│ │ │ ├── Stack.md
│ │ │ ├── Stack.module.scss
│ │ │ ├── Stack.spec.ts
│ │ │ ├── Stack.tsx
│ │ │ ├── StackNative.tsx
│ │ │ ├── VStack.md
│ │ │ └── VStack.spec.ts
│ │ ├── StickyBox
│ │ │ ├── StickyBox.md
│ │ │ ├── StickyBox.module.scss
│ │ │ ├── StickyBox.tsx
│ │ │ └── StickyBoxNative.tsx
│ │ ├── Switch
│ │ │ ├── Switch.md
│ │ │ ├── Switch.spec.ts
│ │ │ └── Switch.tsx
│ │ ├── Table
│ │ │ ├── doc-resources
│ │ │ │ └── list-component-data.js
│ │ │ ├── react-table-config.d.ts
│ │ │ ├── Table.md
│ │ │ ├── Table.module.scss
│ │ │ ├── Table.spec.ts
│ │ │ ├── Table.tsx
│ │ │ ├── TableNative.tsx
│ │ │ └── useRowSelection.tsx
│ │ ├── TableOfContents
│ │ │ ├── TableOfContents.module.scss
│ │ │ ├── TableOfContents.spec.ts
│ │ │ ├── TableOfContents.tsx
│ │ │ └── TableOfContentsNative.tsx
│ │ ├── Tabs
│ │ │ ├── TabContext.tsx
│ │ │ ├── TabItem.md
│ │ │ ├── TabItem.tsx
│ │ │ ├── TabItemNative.tsx
│ │ │ ├── Tabs.md
│ │ │ ├── Tabs.module.scss
│ │ │ ├── Tabs.spec.ts
│ │ │ ├── Tabs.tsx
│ │ │ └── TabsNative.tsx
│ │ ├── Text
│ │ │ ├── Text.md
│ │ │ ├── Text.module.scss
│ │ │ ├── Text.spec.ts
│ │ │ ├── Text.tsx
│ │ │ └── TextNative.tsx
│ │ ├── TextArea
│ │ │ ├── TextArea.md
│ │ │ ├── TextArea.module.scss
│ │ │ ├── TextArea.spec.ts
│ │ │ ├── TextArea.tsx
│ │ │ ├── TextAreaNative.tsx
│ │ │ ├── TextAreaResizable.tsx
│ │ │ └── useComposedRef.ts
│ │ ├── TextBox
│ │ │ ├── TextBox.md
│ │ │ ├── TextBox.module.scss
│ │ │ ├── TextBox.spec.ts
│ │ │ ├── TextBox.tsx
│ │ │ └── TextBoxNative.tsx
│ │ ├── Theme
│ │ │ ├── NotificationToast.tsx
│ │ │ ├── Theme.md
│ │ │ ├── Theme.module.scss
│ │ │ ├── Theme.spec.ts
│ │ │ ├── Theme.tsx
│ │ │ └── ThemeNative.tsx
│ │ ├── TimeInput
│ │ │ ├── TimeInput.md
│ │ │ ├── TimeInput.module.scss
│ │ │ ├── TimeInput.spec.ts
│ │ │ ├── TimeInput.tsx
│ │ │ ├── TimeInputNative.tsx
│ │ │ └── utils.ts
│ │ ├── Timer
│ │ │ ├── Timer.md
│ │ │ ├── Timer.spec.ts
│ │ │ ├── Timer.tsx
│ │ │ └── TimerNative.tsx
│ │ ├── Toggle
│ │ │ ├── Toggle.module.scss
│ │ │ └── Toggle.tsx
│ │ ├── ToneChangerButton
│ │ │ ├── ToneChangerButton.md
│ │ │ ├── ToneChangerButton.spec.ts
│ │ │ └── ToneChangerButton.tsx
│ │ ├── ToneSwitch
│ │ │ ├── ToneSwitch.md
│ │ │ ├── ToneSwitch.module.scss
│ │ │ ├── ToneSwitch.spec.ts
│ │ │ ├── ToneSwitch.tsx
│ │ │ └── ToneSwitchNative.tsx
│ │ ├── Tooltip
│ │ │ ├── Tooltip.md
│ │ │ ├── Tooltip.module.scss
│ │ │ ├── Tooltip.spec.ts
│ │ │ ├── Tooltip.tsx
│ │ │ └── TooltipNative.tsx
│ │ ├── Tree
│ │ │ ├── testData.ts
│ │ │ ├── Tree-dynamic.spec.ts
│ │ │ ├── Tree-icons.spec.ts
│ │ │ ├── Tree.md
│ │ │ ├── Tree.spec.ts
│ │ │ ├── TreeComponent.module.scss
│ │ │ ├── TreeComponent.tsx
│ │ │ └── TreeNative.tsx
│ │ ├── TreeDisplay
│ │ │ ├── TreeDisplay.md
│ │ │ ├── TreeDisplay.module.scss
│ │ │ ├── TreeDisplay.tsx
│ │ │ └── TreeDisplayNative.tsx
│ │ ├── ValidationSummary
│ │ │ ├── ValidationSummary.module.scss
│ │ │ └── ValidationSummary.tsx
│ │ └── VisuallyHidden.tsx
│ ├── components-core
│ │ ├── abstractions
│ │ │ ├── ComponentRenderer.ts
│ │ │ ├── LoaderRenderer.ts
│ │ │ ├── standalone.ts
│ │ │ └── treeAbstractions.ts
│ │ ├── action
│ │ │ ├── actions.ts
│ │ │ ├── APICall.tsx
│ │ │ ├── FileDownloadAction.tsx
│ │ │ ├── FileUploadAction.tsx
│ │ │ ├── NavigateAction.tsx
│ │ │ └── TimedAction.tsx
│ │ ├── ApiBoundComponent.tsx
│ │ ├── appContext
│ │ │ ├── date-functions.ts
│ │ │ ├── math-function.ts
│ │ │ └── misc-utils.ts
│ │ ├── AppContext.tsx
│ │ ├── behaviors
│ │ │ ├── Behavior.tsx
│ │ │ └── CoreBehaviors.tsx
│ │ ├── component-hooks.ts
│ │ ├── ComponentDecorator.tsx
│ │ ├── ComponentViewer.tsx
│ │ ├── CompoundComponent.tsx
│ │ ├── constants.ts
│ │ ├── DebugViewProvider.tsx
│ │ ├── descriptorHelper.ts
│ │ ├── devtools
│ │ │ ├── InspectorDialog.module.scss
│ │ │ ├── InspectorDialog.tsx
│ │ │ └── InspectorDialogVisibilityContext.tsx
│ │ ├── EngineError.ts
│ │ ├── event-handlers.ts
│ │ ├── InspectorButton.module.scss
│ │ ├── InspectorContext.tsx
│ │ ├── interception
│ │ │ ├── abstractions.ts
│ │ │ ├── ApiInterceptor.ts
│ │ │ ├── ApiInterceptorProvider.tsx
│ │ │ ├── apiInterceptorWorker.ts
│ │ │ ├── Backend.ts
│ │ │ ├── Errors.ts
│ │ │ ├── IndexedDb.ts
│ │ │ ├── initMock.ts
│ │ │ ├── InMemoryDb.ts
│ │ │ ├── ReadonlyCollection.ts
│ │ │ └── useApiInterceptorContext.tsx
│ │ ├── loader
│ │ │ ├── ApiLoader.tsx
│ │ │ ├── DataLoader.tsx
│ │ │ ├── ExternalDataLoader.tsx
│ │ │ ├── Loader.tsx
│ │ │ ├── MockLoaderRenderer.tsx
│ │ │ └── PageableLoader.tsx
│ │ ├── LoaderComponent.tsx
│ │ ├── markup-check.ts
│ │ ├── parts.ts
│ │ ├── renderers.ts
│ │ ├── rendering
│ │ │ ├── AppContent.tsx
│ │ │ ├── AppRoot.tsx
│ │ │ ├── AppWrapper.tsx
│ │ │ ├── buildProxy.ts
│ │ │ ├── collectFnVarDeps.ts
│ │ │ ├── ComponentAdapter.tsx
│ │ │ ├── ComponentWrapper.tsx
│ │ │ ├── Container.tsx
│ │ │ ├── containers.ts
│ │ │ ├── ContainerWrapper.tsx
│ │ │ ├── ErrorBoundary.module.scss
│ │ │ ├── ErrorBoundary.tsx
│ │ │ ├── InvalidComponent.module.scss
│ │ │ ├── InvalidComponent.tsx
│ │ │ ├── nodeUtils.ts
│ │ │ ├── reducer.ts
│ │ │ ├── renderChild.tsx
│ │ │ ├── StandaloneComponent.tsx
│ │ │ ├── StateContainer.tsx
│ │ │ ├── UnknownComponent.module.scss
│ │ │ ├── UnknownComponent.tsx
│ │ │ └── valueExtractor.ts
│ │ ├── reportEngineError.ts
│ │ ├── RestApiProxy.ts
│ │ ├── script-runner
│ │ │ ├── asyncProxy.ts
│ │ │ ├── AttributeValueParser.ts
│ │ │ ├── bannedFunctions.ts
│ │ │ ├── BindingTreeEvaluationContext.ts
│ │ │ ├── eval-tree-async.ts
│ │ │ ├── eval-tree-common.ts
│ │ │ ├── eval-tree-sync.ts
│ │ │ ├── ParameterParser.ts
│ │ │ ├── process-statement-async.ts
│ │ │ ├── process-statement-common.ts
│ │ │ ├── process-statement-sync.ts
│ │ │ ├── ScriptingSourceTree.ts
│ │ │ ├── simplify-expression.ts
│ │ │ ├── statement-queue.ts
│ │ │ └── visitors.ts
│ │ ├── StandaloneApp.tsx
│ │ ├── StandaloneExtensionManager.ts
│ │ ├── TableOfContentsContext.tsx
│ │ ├── theming
│ │ │ ├── _themes.scss
│ │ │ ├── component-layout-resolver.ts
│ │ │ ├── extendThemeUtils.ts
│ │ │ ├── hvar.ts
│ │ │ ├── layout-resolver.ts
│ │ │ ├── parse-layout-props.ts
│ │ │ ├── StyleContext.tsx
│ │ │ ├── StyleRegistry.ts
│ │ │ ├── ThemeContext.tsx
│ │ │ ├── ThemeProvider.tsx
│ │ │ ├── themes
│ │ │ │ ├── base-utils.ts
│ │ │ │ ├── palette.ts
│ │ │ │ ├── root.ts
│ │ │ │ ├── solid.ts
│ │ │ │ ├── theme-colors.ts
│ │ │ │ └── xmlui.ts
│ │ │ ├── themeVars.module.scss
│ │ │ ├── themeVars.ts
│ │ │ ├── transformThemeVars.ts
│ │ │ └── utils.ts
│ │ ├── utils
│ │ │ ├── actionUtils.ts
│ │ │ ├── audio-utils.ts
│ │ │ ├── base64-utils.ts
│ │ │ ├── compound-utils.ts
│ │ │ ├── css-utils.ts
│ │ │ ├── DataLoaderQueryKeyGenerator.ts
│ │ │ ├── date-utils.ts
│ │ │ ├── extractParam.ts
│ │ │ ├── hooks.tsx
│ │ │ ├── LruCache.ts
│ │ │ ├── mergeProps.ts
│ │ │ ├── misc.ts
│ │ │ ├── request-params.ts
│ │ │ ├── statementUtils.ts
│ │ │ └── treeUtils.ts
│ │ └── xmlui-parser.ts
│ ├── index-standalone.ts
│ ├── index.scss
│ ├── index.ts
│ ├── language-server
│ │ ├── server-common.ts
│ │ ├── server-web-worker.ts
│ │ ├── server.ts
│ │ ├── services
│ │ │ ├── common
│ │ │ │ ├── docs-generation.ts
│ │ │ │ ├── lsp-utils.ts
│ │ │ │ ├── metadata-utils.ts
│ │ │ │ └── syntax-node-utilities.ts
│ │ │ ├── completion.ts
│ │ │ ├── diagnostic.ts
│ │ │ ├── format.ts
│ │ │ └── hover.ts
│ │ └── xmlui-metadata-generated.js
│ ├── logging
│ │ ├── LoggerContext.tsx
│ │ ├── LoggerInitializer.tsx
│ │ ├── LoggerService.ts
│ │ └── xmlui.ts
│ ├── logo.svg
│ ├── parsers
│ │ ├── common
│ │ │ ├── GenericToken.ts
│ │ │ ├── InputStream.ts
│ │ │ └── utils.ts
│ │ ├── scripting
│ │ │ ├── code-behind-collect.ts
│ │ │ ├── Lexer.ts
│ │ │ ├── modules.ts
│ │ │ ├── Parser.ts
│ │ │ ├── ParserError.ts
│ │ │ ├── ScriptingNodeTypes.ts
│ │ │ ├── TokenTrait.ts
│ │ │ ├── TokenType.ts
│ │ │ └── tree-visitor.ts
│ │ ├── style-parser
│ │ │ ├── errors.ts
│ │ │ ├── source-tree.ts
│ │ │ ├── StyleInputStream.ts
│ │ │ ├── StyleLexer.ts
│ │ │ ├── StyleParser.ts
│ │ │ └── tokens.ts
│ │ └── xmlui-parser
│ │ ├── CharacterCodes.ts
│ │ ├── diagnostics.ts
│ │ ├── fileExtensions.ts
│ │ ├── index.ts
│ │ ├── lint.ts
│ │ ├── parser.ts
│ │ ├── ParserError.ts
│ │ ├── scanner.ts
│ │ ├── syntax-kind.ts
│ │ ├── syntax-node.ts
│ │ ├── transform.ts
│ │ ├── utils.ts
│ │ ├── xmlui-serializer.ts
│ │ └── xmlui-tree.ts
│ ├── react-app-env.d.ts
│ ├── syntax
│ │ ├── monaco
│ │ │ ├── grammar.monacoLanguage.ts
│ │ │ ├── index.ts
│ │ │ ├── xmlui-dark.ts
│ │ │ ├── xmlui-light.ts
│ │ │ └── xmluiscript.monacoLanguage.ts
│ │ └── textMate
│ │ ├── index.ts
│ │ ├── xmlui-dark.json
│ │ ├── xmlui-light.json
│ │ ├── xmlui.json
│ │ └── xmlui.tmLanguage.json
│ ├── testing
│ │ ├── assertions.ts
│ │ ├── component-test-helpers.ts
│ │ ├── ComponentDrivers.ts
│ │ ├── drivers
│ │ │ ├── DateInputDriver.ts
│ │ │ ├── index.ts
│ │ │ ├── ModalDialogDriver.ts
│ │ │ ├── NumberBoxDriver.ts
│ │ │ ├── TextBoxDriver.ts
│ │ │ ├── TimeInputDriver.ts
│ │ │ ├── TimerDriver.ts
│ │ │ └── TreeDriver.ts
│ │ ├── fixtures.ts
│ │ ├── index.ts
│ │ ├── infrastructure
│ │ │ ├── index.html
│ │ │ ├── main.tsx
│ │ │ ├── public
│ │ │ │ ├── mockServiceWorker.js
│ │ │ │ ├── resources
│ │ │ │ │ ├── bell.svg
│ │ │ │ │ ├── box.svg
│ │ │ │ │ ├── doc.svg
│ │ │ │ │ ├── eye.svg
│ │ │ │ │ ├── flower-640x480.jpg
│ │ │ │ │ ├── sun.svg
│ │ │ │ │ ├── test-image-100x100.jpg
│ │ │ │ │ └── txt.svg
│ │ │ │ └── serve.json
│ │ │ └── TestBed.tsx
│ │ └── themed-app-test-helpers.ts
│ └── vite-env.d.ts
├── tests
│ ├── components
│ │ ├── CodeBlock
│ │ │ └── hightlight-code.test.ts
│ │ ├── playground-pattern.test.ts
│ │ └── Tree
│ │ └── Tree-states.test.ts
│ ├── components-core
│ │ ├── abstractions
│ │ │ └── treeAbstractions.test.ts
│ │ ├── container
│ │ │ └── buildProxy.test.ts
│ │ ├── interception
│ │ │ ├── orderBy.test.ts
│ │ │ ├── ReadOnlyCollection.test.ts
│ │ │ └── request-param-converter.test.ts
│ │ ├── scripts-runner
│ │ │ ├── AttributeValueParser.test.ts
│ │ │ ├── eval-tree-arrow-async.test.ts
│ │ │ ├── eval-tree-arrow.test.ts
│ │ │ ├── eval-tree-func-decl-async.test.ts
│ │ │ ├── eval-tree-func-decl.test.ts
│ │ │ ├── eval-tree-pre-post.test.ts
│ │ │ ├── eval-tree-regression.test.ts
│ │ │ ├── eval-tree.test.ts
│ │ │ ├── function-proxy.test.ts
│ │ │ ├── parser-regression.test.ts
│ │ │ ├── process-event.test.ts
│ │ │ ├── process-function.test.ts
│ │ │ ├── process-implicit-context.test.ts
│ │ │ ├── process-statement-asgn.test.ts
│ │ │ ├── process-statement-destruct.test.ts
│ │ │ ├── process-statement-regs.test.ts
│ │ │ ├── process-statement-sync.test.ts
│ │ │ ├── process-statement.test.ts
│ │ │ ├── process-switch-sync.test.ts
│ │ │ ├── process-switch.test.ts
│ │ │ ├── process-try-sync.test.ts
│ │ │ ├── process-try.test.ts
│ │ │ └── test-helpers.ts
│ │ ├── test-metadata-handler.ts
│ │ ├── theming
│ │ │ ├── border-segments.test.ts
│ │ │ ├── component-layout.resolver.test.ts
│ │ │ ├── layout-property-parser.test.ts
│ │ │ ├── layout-resolver.test.ts
│ │ │ ├── layout-resolver2.test.ts
│ │ │ ├── layout-vp-override.test.ts
│ │ │ └── padding-segments.test.ts
│ │ └── utils
│ │ ├── date-utils.test.ts
│ │ ├── format-human-elapsed-time.test.ts
│ │ └── LruCache.test.ts
│ ├── language-server
│ │ ├── completion.test.ts
│ │ ├── format.test.ts
│ │ ├── hover.test.ts
│ │ └── mockData.ts
│ └── parsers
│ ├── common
│ │ └── input-stream.test.ts
│ ├── markdown
│ │ └── parse-binding-expression.test.ts
│ ├── parameter-parser.test.ts
│ ├── paremeter-parser.test.ts
│ ├── scripting
│ │ ├── eval-tree-arrow.test.ts
│ │ ├── eval-tree-pre-post.test.ts
│ │ ├── eval-tree.test.ts
│ │ ├── function-proxy.test.ts
│ │ ├── lexer-literals.test.ts
│ │ ├── lexer-misc.test.ts
│ │ ├── module-parse.test.ts
│ │ ├── parser-arrow.test.ts
│ │ ├── parser-assignments.test.ts
│ │ ├── parser-binary.test.ts
│ │ ├── parser-destructuring.test.ts
│ │ ├── parser-errors.test.ts
│ │ ├── parser-expressions.test.ts
│ │ ├── parser-function.test.ts
│ │ ├── parser-literals.test.ts
│ │ ├── parser-primary.test.ts
│ │ ├── parser-regex.test.ts
│ │ ├── parser-statements.test.ts
│ │ ├── parser-unary.test.ts
│ │ ├── process-event.test.ts
│ │ ├── process-implicit-context.test.ts
│ │ ├── process-statement-asgn.test.ts
│ │ ├── process-statement-destruct.test.ts
│ │ ├── process-statement-regs.test.ts
│ │ ├── process-statement-sync.test.ts
│ │ ├── process-statement.test.ts
│ │ ├── process-switch-sync.test.ts
│ │ ├── process-switch.test.ts
│ │ ├── process-try-sync.test.ts
│ │ ├── process-try.test.ts
│ │ ├── simplify-expression.test.ts
│ │ ├── statement-hooks.test.ts
│ │ └── test-helpers.ts
│ ├── style-parser
│ │ ├── generateHvarChain.test.ts
│ │ ├── parseHVar.test.ts
│ │ ├── parser.test.ts
│ │ └── tokens.test.ts
│ └── xmlui
│ ├── lint.test.ts
│ ├── parser.test.ts
│ ├── scanner.test.ts
│ ├── transform.attr.test.ts
│ ├── transform.circular.test.ts
│ ├── transform.element.test.ts
│ ├── transform.errors.test.ts
│ ├── transform.escape.test.ts
│ ├── transform.regression.test.ts
│ ├── transform.script.test.ts
│ ├── transform.test.ts
│ └── xmlui.ts
├── tests-e2e
│ ├── api-bound-component-regression.spec.ts
│ ├── api-call-as-extracted-component.spec.ts
│ ├── assign-to-object-or-array-regression.spec.ts
│ ├── binding-regression.spec.ts
│ ├── children-as-template-context-vars.spec.ts
│ ├── compound-component.spec.ts
│ ├── context-vars-regression.spec.ts
│ ├── data-bindings.spec.ts
│ ├── datasource-and-api-usage-in-var.spec.ts
│ ├── datasource-direct-binding.spec.ts
│ ├── datasource-onLoaded-regression.spec.ts
│ ├── modify-array-item-regression.spec.ts
│ ├── namespaces.spec.ts
│ ├── push-to-array-regression.spec.ts
│ ├── screen-breakpoints.spec.ts
│ ├── scripting.spec.ts
│ ├── state-scope-in-pages.spec.ts
│ └── state-var-scopes.spec.ts
├── tsconfig.bin.json
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── vitest.config.ts
```
# Files
--------------------------------------------------------------------------------
/docs/content/components/Button.md:
--------------------------------------------------------------------------------
```markdown
# Button [#button]
`Button` is the primary interactive component for triggering actions like form submissions, navigation, opening modals, and API calls. It supports multiple visual styles and sizes to match different UI contexts and importance levels.
**Key features:**
- **Visual hierarchy**: Choose from `solid`, `outlined`, or `ghost` variants to indicate importance
- **Theme colors**: Use `primary`, `secondary`, or `attention` colors for different action types
- **Icon support**: Add icons before or after text, or create icon-only buttons
- **Form integration**: Automatically handles form submission when used in forms
## Properties [#properties]
### `autoFocus` (default: false) [#autofocus-default-false]
Indicates if the button should receive focus when the page loads.
### `contentPosition` (default: "center") [#contentposition-default-center]
This optional value determines how the label and icon (or nested children) should be placedinside the Button component.
Available values:
| Value | Description |
| --- | --- |
| `center` | Place the content in the middle **(default)** |
| `start` | Justify the content to the left (to the right if in right-to-left) |
| `end` | Justify the content to the right (to the left if in right-to-left) |
```xmlui-pg copy display name="Example: content position"
<App>
<Button width="200px" icon="drive" label="Button" contentPosition="center" />
<Button width="200px" icon="drive" label="Button" contentPosition="start" />
<Button width="200px" icon="drive" label="Button" contentPosition="end" />
<Button width="200px" contentPosition="end">
This is a nested text
</Button>
</App>
```
### `contextualLabel` [#contextuallabel]
This optional value is used to provide an accessible name for the Button in the context of its usage.
### `enabled` (default: true) [#enabled-default-true]
The value of this property indicates whether the button accepts actions (`true`) or does not react to them (`false`).
```xmlui-pg copy display name="Example: enabled"
<App>
<HStack>
<Button label="I am enabled (by default)" />
<Button label="I am enabled explicitly" enabled="true" />
<Button label="I am not enabled" enabled="false" />
</HStack>
</App>
```
### `icon` [#icon]
This string value denotes an icon name. The framework will render an icon if XMLUI recognizes the icon by its name. If no label is specified and an icon is set, the Button displays only that icon.
```xmlui-pg copy display name="Example: icon"
<App>
<HStack>
<Button icon="drive" label="Let there be drive" />
<Button icon="drive" />
</HStack>
</App>
```
### `iconPosition` (default: "start") [#iconposition-default-start]
This optional string determines the location of the icon in the Button.
Available values:
| Value | Description |
| --- | --- |
| `start` | The icon will appear at the start (left side when the left-to-right direction is set) **(default)** |
| `end` | The icon will appear at the end (right side when the left-to-right direction is set) |
```xmlui-pg copy display name="Example: icon position"
<App>
<HStack>
<Button icon="drive" label="Left" />
<Button icon="drive" label="Right" iconPosition="right" />
</HStack>
<HStack>
<Button icon="drive" label="Start" iconPosition="start" />
<Button icon="drive" label="End" iconPosition="end" />
</HStack>
<HStack>
<Button
icon="drive"
label="Start (right-to-left)"
iconPosition="start"
direction="rtl" />
<Button
icon="drive"
label="End (right-to-left)"
iconPosition="end"
direction="rtl" />
</HStack>
</App>
```
### `label` [#label]
This property is an optional string to set a label for the Button. If no label is specified and an icon is set, the Button will modify its styling to look like a small icon button. When the Button has nested children, it will display them and ignore the value of the `label` prop.
```xmlui-pg copy display name="Example: label"
<App>
<Button label="I am the button label" />
<Button />
<Button label="I am the button label">
<Icon name="trash" />
I am a text nested into Button
</Button>
</App>
```
### `orientation` (default: "horizontal") [#orientation-default-horizontal]
This property sets the main axis along which the nested components are rendered.
Available values:
| Value | Description |
| --- | --- |
| `horizontal` | The component will fill the available space horizontally **(default)** |
| `vertical` | The component will fill the available space vertically |
### `size` (default: "sm") [#size-default-sm]
Sets the size of the button.
Available values:
| Value | Description |
| --- | --- |
| `xs` | Extra small |
| `sm` | Small **(default)** |
| `md` | Medium |
| `lg` | Large |
| `xl` | Extra large |
```xmlui-pg copy display name="Example: size"
<App>
<HStack>
<Button icon="drive" label="default" />
<Button icon="drive" label="extra-small" size="xs" />
<Button icon="drive" label="small" size="sm" />
<Button icon="drive" label="medium" size="md" />
<Button icon="drive" label="large" size="lg" />
</HStack>
<HStack>
<Button label="default" />
<Button label="extra-small" size="xs" />
<Button label="small" size="sm" />
<Button label="medium" size="md" />
<Button label="large" size="lg" />
</HStack>
</App>
```
### `themeColor` (default: "primary") [#themecolor-default-primary]
Sets the button color scheme defined in the application theme.
Available values:
| Value | Description |
| --- | --- |
| `attention` | Attention state theme color |
| `primary` | Primary theme color **(default)** |
| `secondary` | Secondary theme color |
```xmlui-pg copy display name="Example: theme colors"
<App>
<HStack>
<Button label="Button" themeColor="primary" />
<Button label="Button" themeColor="secondary" />
<Button label="Button" themeColor="attention" />
</HStack>
</App>
```
### `type` (default: "button") [#type-default-button]
This optional string describes how the Button appears in an HTML context. You rarely need to set this property explicitly.
Available values:
| Value | Description |
| --- | --- |
| `button` | Regular behavior that only executes logic if explicitly determined. **(default)** |
| `submit` | The button submits the form data to the server. This is the default for buttons in a Form or NativeForm component. |
| `reset` | Resets all the controls to their initial values. Using it is ill advised for UX reasons. |
### `variant` (default: "solid") [#variant-default-solid]
The button variant determines the level of emphasis the button should possess.
Available values:
| Value | Description |
| --- | --- |
| `solid` | A button with a border and a filled background. **(default)** |
| `outlined` | The button is displayed with a border and a transparent background. |
| `ghost` | A button with no border and fill. Only the label is visible; the background is colored when hovered or clicked. |
```xmlui-pg copy display name="Example: variant"
<App>
<HStack>
<Button label="default (solid)" />
<Button label="solid" variant="solid" />
<Button label="outlined" variant="outlined" />
<Button label="ghost" variant="ghost" />
</HStack>
</App>
```
## Events [#events]
### `click` [#click]
This event is triggered when the Button is clicked.
```xmlui-pg copy display name="Example: click"
<App>
<Button label="Click me!" onClick="toast('Button clicked')" />
</App>
```
### `gotFocus` [#gotfocus]
This event is triggered when the Button has received the focus.
```xmlui-pg copy display name="Example: gotFocus"
<App var.text="No event" >
<HStack verticalAlignment="center" >
<Button label="First, click me!"
onGotFocus="text = 'Focus received'"
onLostFocus="text = 'Focus lost'" />
<Text value="Then, me!"/>
</HStack>
<Text value="{text}" />
</App>
```
### `lostFocus` [#lostfocus]
This event is triggered when the Button has lost the focus.
(See the example above)
## Exposed Methods [#exposed-methods]
This component does not expose any methods.
## Styling [#styling]
### Fixed width and height [#fixed-width-and-height]
Using a set of buttons with a fixed width or height is often helpful. So `Button` supports these theme variables:
- `width-Button`
- `height-Button`
Avoid setting the `width-Button` and `height-Button` styles in the theme definition. Instead, wrap the affected button group into a `Theme` component as in the following example:
```xmlui-pg copy name="Example: Buttons with fixed width"
<App>
<HStack>
<Theme width-Button="120px">
<Button label="Short" />
<Button label="Longer" />
<Button label="Longest" />
<Button label="Disabled" enabled="false" />
<Button label="Outlined" variant="outlined" />
</Theme>
</HStack>
</App>
```
### Theme Variables [#theme-variables]
| Variable | Default Value (Light) | Default Value (Dark) |
| --- | --- | --- |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button | transparent | transparent |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button--disabled | $backgroundColor--disabled | $backgroundColor--disabled |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button--hover | *none* | *none* |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention | $backgroundColor-attention | $backgroundColor-attention |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention--active | $color-danger-500 | $color-danger-500 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention--hover | $color-danger-400 | $color-danger-400 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention-ghost--active | $color-danger-100 | $color-danger-100 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention-ghost--hover | $color-danger-50 | $color-danger-50 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention-outlined--active | $color-danger-100 | $color-danger-100 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention-outlined--hover | $color-danger-50 | $color-danger-50 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention-solid | *none* | *none* |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention-solid--active | *none* | *none* |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-attention-solid--hover | *none* | *none* |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary | $color-primary-500 | $color-primary-500 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary--active | $color-primary-500 | $color-primary-500 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary--hover | $color-primary-400 | $color-primary-400 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary-ghost--active | $color-primary-100 | $color-primary-100 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary-ghost--hover | $color-primary-50 | $color-primary-50 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary-outlined--active | $color-primary-100 | $color-primary-100 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary-outlined--hover | $color-primary-50 | $color-primary-50 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary-solid | *none* | *none* |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary-solid--active | *none* | *none* |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-primary-solid--hover | *none* | *none* |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary | $color-secondary-500 | $color-secondary-500 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary--active | $color-secondary-500 | $color-secondary-500 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary--hover | $color-secondary-400 | $color-secondary-400 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary-ghost--active | $color-secondary-100 | $color-secondary-100 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary-ghost--hover | $color-secondary-100 | $color-secondary-100 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined--active | $color-secondary-100 | $color-secondary-100 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined--hover | $color-secondary-50 | $color-secondary-50 |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary-solid | *none* | *none* |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary-solid--active | *none* | *none* |
| [backgroundColor](../styles-and-themes/common-units/#color)-Button-secondary-solid--hover | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-Button | transparent | transparent |
| [borderColor](../styles-and-themes/common-units/#color)-Button--disabled | $borderColor--disabled | $borderColor--disabled |
| [borderColor](../styles-and-themes/common-units/#color)-Button--hover | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-Button-attention | $color-attention | $color-attention |
| [borderColor](../styles-and-themes/common-units/#color)-Button-attention-outlined | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-Button-attention-outlined--active | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-Button-attention-outlined--hover | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-Button-attention-solid | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-Button-attention-solid--active | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-Button-attention-solid--hover | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-Button-primary | $color-primary-500 | $color-primary-500 |
| [borderColor](../styles-and-themes/common-units/#color)-Button-primary-outlined | $color-primary-600 | $color-primary-600 |
| [borderColor](../styles-and-themes/common-units/#color)-Button-primary-outlined--active | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-Button-primary-outlined--hover | $color-primary-500 | $color-primary-500 |
| [borderColor](../styles-and-themes/common-units/#color)-Button-primary-solid | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-Button-primary-solid--active | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-Button-primary-solid--hover | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-Button-secondary | $color-secondary-100 | $color-secondary-100 |
| [borderColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined--active | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined--hover | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-Button-secondary-solid | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-Button-secondary-solid--active | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-Button-secondary-solid--hover | *none* | *none* |
| [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button | $borderRadius | $borderRadius |
| [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-attention-ghost | *none* | *none* |
| [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-attention-outlined | *none* | *none* |
| [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-attention-solid | *none* | *none* |
| [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-primary-ghost | *none* | *none* |
| [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-primary-outlined | *none* | *none* |
| [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-primary-solid | *none* | *none* |
| [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-secondary-ghost | *none* | *none* |
| [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-secondary-outlined | *none* | *none* |
| [borderRadius](../styles-and-themes/common-units/#border-rounding)-Button-secondary-solid | *none* | *none* |
| [borderStyle](../styles-and-themes/common-units/#border-style)-Button | solid | solid |
| [borderStyle](../styles-and-themes/common-units/#border-style)-Button--hover | *none* | *none* |
| [borderStyle](../styles-and-themes/common-units/#border-style)-Button-attention-outlined | *none* | *none* |
| [borderStyle](../styles-and-themes/common-units/#border-style)-Button-attention-solid | *none* | *none* |
| [borderStyle](../styles-and-themes/common-units/#border-style)-Button-primary-outlined | *none* | *none* |
| [borderStyle](../styles-and-themes/common-units/#border-style)-Button-primary-solid | *none* | *none* |
| [borderStyle](../styles-and-themes/common-units/#border-style)-Button-secondary-outlined | *none* | *none* |
| [borderStyle](../styles-and-themes/common-units/#border-style)-Button-secondary-solid | *none* | *none* |
| [borderWidth](../styles-and-themes/common-units/#size)-Button | 1px | 1px |
| [borderWidth](../styles-and-themes/common-units/#size)-Button--hover | *none* | *none* |
| [borderWidth](../styles-and-themes/common-units/#size)-Button-attention-ghost | *none* | *none* |
| [borderWidth](../styles-and-themes/common-units/#size)-Button-attention-outlined | *none* | *none* |
| [borderWidth](../styles-and-themes/common-units/#size)-Button-attention-solid | *none* | *none* |
| [borderWidth](../styles-and-themes/common-units/#size)-Button-primary-ghost | *none* | *none* |
| [borderWidth](../styles-and-themes/common-units/#size)-Button-primary-outlined | *none* | *none* |
| [borderWidth](../styles-and-themes/common-units/#size)-Button-primary-solid | *none* | *none* |
| [borderWidth](../styles-and-themes/common-units/#size)-Button-secondary-ghost | *none* | *none* |
| [borderWidth](../styles-and-themes/common-units/#size)-Button-secondary-outlined | *none* | *none* |
| [borderWidth](../styles-and-themes/common-units/#size)-Button-secondary-solid | *none* | *none* |
| [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button | *none* | *none* |
| [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button--hover | *none* | *none* |
| [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-attention-outlined | *none* | *none* |
| [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-attention-solid | *none* | *none* |
| [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-attention-solid--active | *none* | *none* |
| [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-primary-outlined | *none* | *none* |
| [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-primary-solid | *none* | *none* |
| [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-primary-solid--active | *none* | *none* |
| [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-secondary-outlined | *none* | *none* |
| [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-secondary-solid | *none* | *none* |
| [boxShadow](../styles-and-themes/common-units/#boxShadow)-Button-secondary-solid--active | *none* | *none* |
| [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button | *none* | *none* |
| [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-attention-ghost | *none* | *none* |
| [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-attention-outlined | *none* | *none* |
| [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-attention-solid | *none* | *none* |
| [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-primary-ghost | *none* | *none* |
| [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-primary-outlined | *none* | *none* |
| [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-primary-solid | *none* | *none* |
| [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-secondary-ghost | *none* | *none* |
| [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-secondary-outlined | *none* | *none* |
| [fontFamily](../styles-and-themes/common-units/#fontFamily)-Button-secondary-solid | *none* | *none* |
| [fontSize](../styles-and-themes/common-units/#size)-Button | $fontSize-sm | $fontSize-sm |
| [fontSize](../styles-and-themes/common-units/#size)-Button-attention-ghost | *none* | *none* |
| [fontSize](../styles-and-themes/common-units/#size)-Button-attention-outlined | *none* | *none* |
| [fontSize](../styles-and-themes/common-units/#size)-Button-attention-solid | *none* | *none* |
| [fontSize](../styles-and-themes/common-units/#size)-Button-primary-ghost | *none* | *none* |
| [fontSize](../styles-and-themes/common-units/#size)-Button-primary-outlined | *none* | *none* |
| [fontSize](../styles-and-themes/common-units/#size)-Button-primary-solid | *none* | *none* |
| [fontSize](../styles-and-themes/common-units/#size)-Button-secondary-ghost | *none* | *none* |
| [fontSize](../styles-and-themes/common-units/#size)-Button-secondary-outlined | *none* | *none* |
| [fontSize](../styles-and-themes/common-units/#size)-Button-secondary-solid | *none* | *none* |
| [fontStyle](../styles-and-themes/common-units/#fontStyle)-Button | $fontStyle-normal | $fontStyle-normal |
| [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button | $fontWeight-medium | $fontWeight-medium |
| [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-attention-ghost | *none* | *none* |
| [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-attention-outlined | *none* | *none* |
| [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-attention-solid | *none* | *none* |
| [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-primary-ghost | *none* | *none* |
| [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-primary-outlined | *none* | *none* |
| [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-primary-solid | *none* | *none* |
| [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-secondary-ghost | *none* | *none* |
| [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-secondary-outlined | *none* | *none* |
| [fontWeight](../styles-and-themes/common-units/#fontWeight)-Button-secondary-solid | *none* | *none* |
| [gap](../styles-and-themes/common-units/#size)-Button | $space-2 | $space-2 |
| [height](../styles-and-themes/common-units/#size)-Button | fit-content | fit-content |
| [outlineColor](../styles-and-themes/common-units/#color)-Button--focus | $outlineColor--focus | $outlineColor--focus |
| [outlineColor](../styles-and-themes/common-units/#color)-Button-attention-ghost--focus | *none* | *none* |
| [outlineColor](../styles-and-themes/common-units/#color)-Button-attention-outlined--focus | *none* | *none* |
| [outlineColor](../styles-and-themes/common-units/#color)-Button-attention-solid--focus | *none* | *none* |
| [outlineColor](../styles-and-themes/common-units/#color)-Button-primary-ghost--focus | *none* | *none* |
| [outlineColor](../styles-and-themes/common-units/#color)-Button-primary-outlined--focus | *none* | *none* |
| [outlineColor](../styles-and-themes/common-units/#color)-Button-primary-solid--focus | *none* | *none* |
| [outlineColor](../styles-and-themes/common-units/#color)-Button-secondary-ghost--focus | *none* | *none* |
| [outlineColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined--focus | *none* | *none* |
| [outlineColor](../styles-and-themes/common-units/#color)-Button-secondary-solid--focus | *none* | *none* |
| [outlineOffset](../styles-and-themes/common-units/#size)-Button--focus | $outlineOffset--focus | $outlineOffset--focus |
| [outlineOffset](../styles-and-themes/common-units/#size)-Button-attention-ghost--focus | *none* | *none* |
| [outlineOffset](../styles-and-themes/common-units/#size)-Button-attention-outlined--focus | *none* | *none* |
| [outlineOffset](../styles-and-themes/common-units/#size)-Button-attention-solid--focus | *none* | *none* |
| [outlineOffset](../styles-and-themes/common-units/#size)-Button-primary-ghost--focus | *none* | *none* |
| [outlineOffset](../styles-and-themes/common-units/#size)-Button-primary-outlined--focus | *none* | *none* |
| [outlineOffset](../styles-and-themes/common-units/#size)-Button-primary-solid--focus | *none* | *none* |
| [outlineOffset](../styles-and-themes/common-units/#size)-Button-secondary-ghost--focus | *none* | *none* |
| [outlineOffset](../styles-and-themes/common-units/#size)-Button-secondary-outlined--focus | *none* | *none* |
| [outlineOffset](../styles-and-themes/common-units/#size)-Button-secondary-solid--focus | *none* | *none* |
| [outlineStyle](../styles-and-themes/common-units/#border)-Button--focus | $outlineStyle--focus | $outlineStyle--focus |
| [outlineStyle](../styles-and-themes/common-units/#border)-Button-attention-ghost--focus | *none* | *none* |
| [outlineStyle](../styles-and-themes/common-units/#border)-Button-attention-outlined--focus | *none* | *none* |
| [outlineStyle](../styles-and-themes/common-units/#border)-Button-attention-solid--focus | *none* | *none* |
| [outlineStyle](../styles-and-themes/common-units/#border)-Button-primary-ghost--focus | *none* | *none* |
| [outlineStyle](../styles-and-themes/common-units/#border)-Button-primary-outlined--focus | *none* | *none* |
| [outlineStyle](../styles-and-themes/common-units/#border)-Button-primary-solid--focus | *none* | *none* |
| [outlineStyle](../styles-and-themes/common-units/#border)-Button-secondary-ghost--focus | *none* | *none* |
| [outlineStyle](../styles-and-themes/common-units/#border)-Button-secondary-outlined--focus | *none* | *none* |
| [outlineStyle](../styles-and-themes/common-units/#border)-Button-secondary-solid--focus | *none* | *none* |
| [outlineWidth](../styles-and-themes/common-units/#size)-Button--focus | $outlineWidth--focus | $outlineWidth--focus |
| [outlineWidth](../styles-and-themes/common-units/#size)-Button-attention-ghost--focus | *none* | *none* |
| [outlineWidth](../styles-and-themes/common-units/#size)-Button-attention-outlined--focus | *none* | *none* |
| [outlineWidth](../styles-and-themes/common-units/#size)-Button-attention-solid--focus | *none* | *none* |
| [outlineWidth](../styles-and-themes/common-units/#size)-Button-primary-ghost--focus | *none* | *none* |
| [outlineWidth](../styles-and-themes/common-units/#size)-Button-primary-outlined--focus | *none* | *none* |
| [outlineWidth](../styles-and-themes/common-units/#size)-Button-primary-solid--focus | *none* | *none* |
| [outlineWidth](../styles-and-themes/common-units/#size)-Button-secondary-ghost--focus | *none* | *none* |
| [outlineWidth](../styles-and-themes/common-units/#size)-Button-secondary-outlined--focus | *none* | *none* |
| [outlineWidth](../styles-and-themes/common-units/#size)-Button-secondary-solid--focus | *none* | *none* |
| [padding](../styles-and-themes/common-units/#size)-Button | $space-2 $space-4 | $space-2 $space-4 |
| [padding](../styles-and-themes/common-units/#size)-Button-lg | *none* | *none* |
| [padding](../styles-and-themes/common-units/#size)-Button-md | *none* | *none* |
| [padding](../styles-and-themes/common-units/#size)-Button-sm | *none* | *none* |
| [padding](../styles-and-themes/common-units/#size)-Button-xs | *none* | *none* |
| [paddingBottom](../styles-and-themes/common-units/#size)-Button | *none* | *none* |
| [paddingBottom](../styles-and-themes/common-units/#size)-Button-lg | *none* | *none* |
| [paddingBottom](../styles-and-themes/common-units/#size)-Button-md | *none* | *none* |
| [paddingBottom](../styles-and-themes/common-units/#size)-Button-sm | *none* | *none* |
| [paddingBottom](../styles-and-themes/common-units/#size)-Button-xs | *none* | *none* |
| [paddingHorizontal](../styles-and-themes/common-units/#size)-Button | *none* | *none* |
| [paddingHorizontal](../styles-and-themes/common-units/#size)-Button-lg | $space-5 | $space-5 |
| [paddingHorizontal](../styles-and-themes/common-units/#size)-Button-md | $space-4 | $space-4 |
| [paddingHorizontal](../styles-and-themes/common-units/#size)-Button-sm | $space-4 | $space-4 |
| [paddingHorizontal](../styles-and-themes/common-units/#size)-Button-xs | $space-1 | $space-1 |
| [paddingLeft](../styles-and-themes/common-units/#size)-Button | *none* | *none* |
| [paddingLeft](../styles-and-themes/common-units/#size)-Button-lg | *none* | *none* |
| [paddingLeft](../styles-and-themes/common-units/#size)-Button-md | *none* | *none* |
| [paddingLeft](../styles-and-themes/common-units/#size)-Button-sm | *none* | *none* |
| [paddingLeft](../styles-and-themes/common-units/#size)-Button-xs | *none* | *none* |
| [paddingRight](../styles-and-themes/common-units/#size)-Button | *none* | *none* |
| [paddingRight](../styles-and-themes/common-units/#size)-Button-lg | *none* | *none* |
| [paddingRight](../styles-and-themes/common-units/#size)-Button-md | *none* | *none* |
| [paddingRight](../styles-and-themes/common-units/#size)-Button-sm | *none* | *none* |
| [paddingRight](../styles-and-themes/common-units/#size)-Button-xs | *none* | *none* |
| [paddingTop](../styles-and-themes/common-units/#size)-Button | *none* | *none* |
| [paddingTop](../styles-and-themes/common-units/#size)-Button-lg | *none* | *none* |
| [paddingTop](../styles-and-themes/common-units/#size)-Button-md | *none* | *none* |
| [paddingTop](../styles-and-themes/common-units/#size)-Button-sm | *none* | *none* |
| [paddingTop](../styles-and-themes/common-units/#size)-Button-xs | *none* | *none* |
| [paddingVertical](../styles-and-themes/common-units/#size)-Button | *none* | *none* |
| [paddingVertical](../styles-and-themes/common-units/#size)-Button-lg | $space-4 | $space-4 |
| [paddingVertical](../styles-and-themes/common-units/#size)-Button-md | $space-3 | $space-3 |
| [paddingVertical](../styles-and-themes/common-units/#size)-Button-sm | $space-2 | $space-2 |
| [paddingVertical](../styles-and-themes/common-units/#size)-Button-xs | $space-0_5 | $space-0_5 |
| [textColor](../styles-and-themes/common-units/#color)-Button | $color-surface-950 | $color-surface-950 |
| [textColor](../styles-and-themes/common-units/#color)-Button--disabled | $textColor--disabled | $textColor--disabled |
| [textColor](../styles-and-themes/common-units/#color)-Button--hover | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-attention-ghost | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-attention-ghost--active | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-attention-ghost--hover | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-attention-outlined | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-attention-outlined--active | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-attention-outlined--hover | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-attention-solid | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-attention-solid--active | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-attention-solid--hover | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-primary-ghost | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-primary-ghost--active | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-primary-ghost--hover | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-primary-outlined | $color-primary-900 | $color-primary-900 |
| [textColor](../styles-and-themes/common-units/#color)-Button-primary-outlined--active | $color-primary-900 | $color-primary-900 |
| [textColor](../styles-and-themes/common-units/#color)-Button-primary-outlined--hover | $color-primary-950 | $color-primary-950 |
| [textColor](../styles-and-themes/common-units/#color)-Button-primary-solid | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-primary-solid--active | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-primary-solid--hover | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-secondary-ghost | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-secondary-ghost--active | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-secondary-ghost--hover | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined--active | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-secondary-outlined--hover | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-secondary-solid | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-secondary-solid--active | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-secondary-solid--hover | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-Button-solid | $const-color-surface-50 | $const-color-surface-50 |
| [transition](../styles-and-themes/common-units/#transition)-Button | color 0.2s, background 0.2s | color 0.2s, background 0.2s |
| [transition](../styles-and-themes/common-units/#transition)-Button-attention-solid | *none* | *none* |
| [transition](../styles-and-themes/common-units/#transition)-Button-primary-solid | *none* | *none* |
| [transition](../styles-and-themes/common-units/#transition)-Button-secondary-solid | *none* | *none* |
| [width](../styles-and-themes/common-units/#size)-Button | fit-content | fit-content |
```
--------------------------------------------------------------------------------
/xmlui/src/parsers/scripting/Lexer.ts:
--------------------------------------------------------------------------------
```typescript
import { parseRegExpLiteral } from "@eslint-community/regexpp";
import type { GenericToken } from "../common/GenericToken";
import type { InputStream } from "../common/InputStream";
import { TokenType } from "./TokenType";
type Token = GenericToken<TokenType>;
/**
* This enum indicates the current lexer phase
*/
enum LexerPhase {
// Start getting a token
Start = 0,
// Collecting whitespace
InWhiteSpace,
// Comment phases
InlineCommentTrail,
BlockCommentTrail1,
BlockCommentTrail2,
// Multi-char tokens
Slash,
Dollar,
Or,
Asterisk,
Ampersand,
Equal,
DoubleEqual,
NotEqual,
Exclamation,
AngleLeft,
AngleRight,
SignedShiftRight,
IdTail,
Dot,
DotDot,
Colon,
Zero,
QuestionMark,
HexaFirst,
HexaTail,
BinaryFirst,
BinaryTail,
DecimalOrReal,
RealFractionalFirst,
RealFractionalTail,
RealExponent,
RealExponentSign,
RealExponentTail,
StringTemplateLiteralBackSlash,
StringTemplateLiteral,
String,
StringBackSlash,
StringHexa1,
StringHexa2,
StringUHexa1,
StringUHexa2,
StringUHexa3,
StringUHexa4,
StringUcp1,
StringUcp2,
StringUcp3,
StringUcp4,
StringUcp5,
StringUcp6,
StringUcpTail,
// --- Assignments
Exponent,
Plus,
Minus,
Divide,
Remainder,
ShiftLeft,
ShiftRight,
LogicalAnd,
BitwiseXor,
LogicalOr,
NullCoalesce,
// --- Other
RegEx,
}
/**
* This class implements the lexer of binding expressions
*/
export class Lexer {
// --- Already fetched tokens
private _ahead: Token[] = [];
// --- Prefetched character (from the next token)
private _prefetched: string | null = null;
// --- Prefetched character position (from the next token)
private _prefetchedPos: number | null = null;
// --- Prefetched character column (from the next token)
private _prefetchedColumn: number | null = null;
// --- input position at the beginning of last fetch
private _lastFetchPosition = 0;
private _phaseExternallySet: null | LexerPhase = null;
/**
* Initializes the tokenizer with the input stream
* @param input Input source code stream
*/
constructor(public readonly input: InputStream) {}
/**
* Fetches the next token without advancing to its position
* @param ws If true, retrieve whitespaces too
*/
peek(ws = false): Token {
return this.ahead(0, ws);
}
/**
* Reads tokens ahead
* @param n Number of token positions to read ahead
* @param ws If true, retrieve whitespaces too
*/
ahead(n = 1, ws = false): Token {
if (n > 16) {
throw new Error("Cannot look ahead more than 16 tokens");
}
// --- Prefetch missing tokens
while (this._ahead.length <= n) {
const token = this.fetch();
if (isEof(token)) {
return token;
}
if (ws || (!ws && !isWs(token))) {
this._ahead.push(token);
}
}
return this._ahead[n];
}
/**
* Fetches the next token and advances the stream position
* @param ws If true, retrieve whitespaces too
*/
get(ws = false): Token {
if (this._ahead.length > 0) {
const token = this._ahead.shift();
if (!token) {
throw new Error("Token expected");
}
return token;
}
while (true) {
const token = this.fetch();
if (isEof(token) || ws || (!ws && !isWs(token))) {
return token;
}
}
}
/**
* Gets a RegEx from the current position
*/
getRegEx(): RegExpLexerResult {
return this.fetchRegEx();
}
/**
* Gets the remaining characters after the parsing phase
*/
getTail(): string {
return this._ahead.length > 0
? this.input.getTail(this._ahead[0].startPosition)
: this.input.getTail(this._lastFetchPosition);
}
/** Parsing template literals requires a context sensitive lexer.
* This method has to be called by the parser when the lexer needs to scan a string inside a template literal.
* Call this after the first opening backing and after the parser is done with parsing a placeholder, after the right brace.
*/
setStartingPhaseToTemplateLiteral() {
this._phaseExternallySet = LexerPhase.StringTemplateLiteral;
}
/**
* Fetches the next character from the input stream
*/
private fetchNextChar(): string | null {
if (!this._prefetched) {
this._prefetchedPos = this.input.position;
this._prefetchedColumn = this.input.column;
this._prefetched = this.input.get();
}
return this._prefetched;
}
/**
* Fetches the next token from the input stream
*/
private fetch(): Token {
// --- Captured constants used in nested functions
const input = this.input;
const startPos = this._prefetchedPos || input.position;
const line = input.line;
const startColumn = this._prefetchedColumn || input.column;
this._lastFetchPosition = this.input.position;
// --- State variables
let stringState: string | null = null;
let text = "";
let tokenType = TokenType.Eof;
let lastEndPos = input.position;
let lastEndColumn = input.column;
let ch: string | null = null;
let useResolver = false;
/**
* Appends the last character to the token, and manages positions
*/
const appendTokenChar = (): void => {
text += ch;
this._prefetched = null;
this._prefetchedPos = null;
this._prefetchedColumn = null;
lastEndPos = input.position;
lastEndColumn = input.position;
};
// --- Start from the beginning
let phase: LexerPhase = this.getStartingPhaseThenReset();
// --- Process all token characters
while (true) {
// --- Get the next character
ch = this.fetchNextChar();
// --- In case of EOF, return the current token data
if (ch === null) {
return makeToken();
}
// --- Set the initial token type to unknown for the other characters
if (tokenType === TokenType.Eof) {
tokenType = TokenType.Unknown;
}
// --- Follow the lexer state machine
phaseSwitch: switch (phase) {
// ====================================================================
// Process the first character
case LexerPhase.Start:
switch (ch) {
// --- Go on with whitespaces
case " ":
case "\t":
case "\n":
case "\r":
phase = LexerPhase.InWhiteSpace;
tokenType = TokenType.Ws;
break;
// --- Divide, BlockComment, or EolComment
case "/":
phase = LexerPhase.Slash;
tokenType = TokenType.Divide;
break;
case "$":
phase = LexerPhase.Dollar;
tokenType = TokenType.Identifier;
break;
case "*":
phase = LexerPhase.Asterisk;
tokenType = TokenType.Multiply;
break;
case "%":
phase = LexerPhase.Remainder;
tokenType = TokenType.Remainder;
break;
case "+":
phase = LexerPhase.Plus;
tokenType = TokenType.Plus;
break;
case "-":
phase = LexerPhase.Minus;
tokenType = TokenType.Minus;
break;
case "^":
phase = LexerPhase.BitwiseXor;
tokenType = TokenType.BitwiseXor;
break;
// --- BitwiseOr, LogicalOr
case "|":
phase = LexerPhase.Or;
tokenType = TokenType.BitwiseOr;
break;
// --- BitwiseAnd, LogicalAnd
case "&":
phase = LexerPhase.Ampersand;
tokenType = TokenType.BitwiseAnd;
break;
// --- "?", "?", or "?."
case "?":
phase = LexerPhase.QuestionMark;
tokenType = TokenType.QuestionMark;
break;
case ";":
return completeToken(TokenType.Semicolon);
case ",":
return completeToken(TokenType.Comma);
case "(":
return completeToken(TokenType.LParent);
case ")":
return completeToken(TokenType.RParent);
// --- ":" or "::"
case ":":
phase = LexerPhase.Colon;
tokenType = TokenType.Colon;
break;
case "`":
return completeToken(TokenType.Backtick);
case "[":
return completeToken(TokenType.LSquare);
case "]":
return completeToken(TokenType.RSquare);
case "~":
return completeToken(TokenType.BinaryNot);
case "{":
return completeToken(TokenType.LBrace);
case "}":
return completeToken(TokenType.RBrace);
// --- "=","==", "===", or "=>"
case "=":
phase = LexerPhase.Equal;
tokenType = TokenType.Assignment;
break;
// --- "!", "!=", or "!=="
case "!":
phase = LexerPhase.Exclamation;
tokenType = TokenType.LogicalNot;
break;
// --- "<", "<=", or "<<"
case "<":
phase = LexerPhase.AngleLeft;
tokenType = TokenType.LessThan;
break;
// --- ">", ">=", ">>", or ">>>"
case ">":
phase = LexerPhase.AngleRight;
tokenType = TokenType.GreaterThan;
break;
// --- Decimal or Real literal
case "0":
phase = LexerPhase.Zero;
tokenType = TokenType.DecimalLiteral;
break;
case ".":
phase = LexerPhase.Dot;
tokenType = TokenType.Dot;
break;
// --- String (both " and ' are accepted as string wrappers
case '"':
case "'":
stringState = ch;
phase = LexerPhase.String;
break;
default:
if (isIdStart(ch)) {
useResolver = true;
phase = LexerPhase.IdTail;
tokenType = TokenType.Identifier;
} else if (isDecimalDigit(ch)) {
phase = LexerPhase.DecimalOrReal;
tokenType = TokenType.DecimalLiteral;
} else {
completeToken(TokenType.Unknown);
}
break;
}
break;
// ====================================================================
// Process comments
// --- Looking for the end of whitespace
case LexerPhase.InWhiteSpace:
if (ch !== " " && ch !== "\t" && ch !== "\r" && ch !== "\n") {
return makeToken();
}
break;
// --- Wait for an "*" that may complete a block comment
case LexerPhase.BlockCommentTrail1:
if (ch === "*") {
phase = LexerPhase.BlockCommentTrail2;
}
break;
// --- Wait for a "/" that may complete a block comment
case LexerPhase.BlockCommentTrail2:
if (ch === "/") {
return completeToken(TokenType.BlockComment);
}
break;
case LexerPhase.InlineCommentTrail:
if (ch === "\n") {
return completeToken();
}
break;
// ====================================================================
// Process identifiers
case LexerPhase.IdTail:
if (!isIdContinuation(ch)) {
return makeToken();
}
break;
// ====================================================================
// Process miscellaneous tokens
case LexerPhase.Colon:
return ch === ":" ? completeToken(TokenType.Global) : makeToken();
case LexerPhase.Slash:
if (ch === "*") {
phase = LexerPhase.BlockCommentTrail1;
} else if (ch === "/") {
phase = LexerPhase.InlineCommentTrail;
tokenType = TokenType.EolComment;
} else if (ch === "=") {
return completeToken(TokenType.DivideAssignment);
} else {
return makeToken();
}
break;
case LexerPhase.Plus:
if (ch === "+") {
return completeToken(TokenType.IncOp);
}
return ch === "=" ? completeToken(TokenType.AddAssignment) : makeToken();
case LexerPhase.Minus:
if (ch === "-") {
return completeToken(TokenType.DecOp);
}
return ch === "=" ? completeToken(TokenType.SubtractAssignment) : makeToken();
case LexerPhase.Remainder:
return ch === "=" ? completeToken(TokenType.RemainderAssignment) : makeToken();
case LexerPhase.BitwiseXor:
return ch === "=" ? completeToken(TokenType.BitwiseXorAssignment) : makeToken();
case LexerPhase.Or:
if (ch === "=") {
return completeToken(TokenType.BitwiseOrAssignment);
}
if (ch === "|") {
phase = LexerPhase.LogicalOr;
tokenType = TokenType.LogicalOr;
break;
}
return makeToken();
case LexerPhase.LogicalOr:
return ch === "=" ? completeToken(TokenType.LogicalOrAssignment) : makeToken();
case LexerPhase.Ampersand:
if (ch === "=") {
return completeToken(TokenType.BitwiseAndAssignment);
}
if (ch === "&") {
phase = LexerPhase.LogicalAnd;
tokenType = TokenType.LogicalAnd;
break;
}
return makeToken();
case LexerPhase.LogicalAnd:
return ch === "=" ? completeToken(TokenType.LogicalAndAssignment) : makeToken();
case LexerPhase.Asterisk:
if (ch === "*") {
phase = LexerPhase.Exponent;
tokenType = TokenType.Exponent;
break;
} else if (ch === "=") {
return completeToken(TokenType.MultiplyAssignment);
}
return makeToken();
case LexerPhase.Exponent:
return ch === "=" ? completeToken(TokenType.ExponentAssignment) : makeToken();
case LexerPhase.QuestionMark:
if (ch === "?") {
phase = LexerPhase.NullCoalesce;
tokenType = TokenType.NullCoalesce;
break;
}
if (ch === ".") {
return completeToken(TokenType.OptionalChaining);
}
return makeToken();
case LexerPhase.NullCoalesce:
return ch === "=" ? completeToken(TokenType.NullCoalesceAssignment) : makeToken();
case LexerPhase.Equal:
if (ch === ">") {
return completeToken(TokenType.Arrow);
}
if (ch === "=") {
phase = LexerPhase.DoubleEqual;
tokenType = TokenType.Equal;
break;
}
return makeToken();
case LexerPhase.DoubleEqual:
return ch === "=" ? completeToken(TokenType.StrictEqual) : makeToken();
case LexerPhase.Exclamation:
if (ch === "=") {
phase = LexerPhase.NotEqual;
tokenType = TokenType.NotEqual;
break;
}
return makeToken();
case LexerPhase.NotEqual:
return ch === "=" ? completeToken(TokenType.StrictNotEqual) : makeToken();
case LexerPhase.AngleLeft:
if (ch === "=") {
return completeToken(TokenType.LessThanOrEqual);
}
if (ch === "<") {
phase = LexerPhase.ShiftLeft;
tokenType = TokenType.ShiftLeft;
break;
}
return makeToken();
case LexerPhase.ShiftLeft:
return ch === "=" ? completeToken(TokenType.ShiftLeftAssignment) : makeToken();
case LexerPhase.AngleRight:
if (ch === "=") {
return completeToken(TokenType.GreaterThanOrEqual);
}
if (ch === ">") {
phase = LexerPhase.SignedShiftRight;
tokenType = TokenType.SignedShiftRight;
break;
}
return makeToken();
case LexerPhase.SignedShiftRight:
if (ch === ">") {
phase = LexerPhase.ShiftRight;
tokenType = TokenType.ShiftRight;
break;
}
if (ch === "=") {
return completeToken(TokenType.SignedShiftRightAssignment);
}
return makeToken();
case LexerPhase.ShiftRight:
return ch === "=" ? completeToken(TokenType.ShiftRightAssignment) : makeToken();
// ====================================================================
// --- Literals
case LexerPhase.Zero:
if (ch === "x") {
phase = LexerPhase.HexaFirst;
tokenType = TokenType.Unknown;
} else if (ch === "b") {
phase = LexerPhase.BinaryFirst;
tokenType = TokenType.Unknown;
} else if (isDecimalDigit(ch) || ch === "_") {
phase = LexerPhase.DecimalOrReal;
} else if (ch === ".") {
phase = LexerPhase.RealFractionalFirst;
tokenType = TokenType.Unknown;
} else if (ch === "e" || ch === "E") {
phase = LexerPhase.RealExponent;
tokenType = TokenType.Unknown;
} else {
return makeToken();
}
break;
case LexerPhase.Dot:
if (ch === ".") {
phase = LexerPhase.DotDot;
tokenType = TokenType.Unknown;
break;
}
if (!isDecimalDigit(ch)) {
return makeToken();
}
phase = LexerPhase.RealFractionalTail;
tokenType = TokenType.RealLiteral;
break;
case LexerPhase.DotDot:
return ch === "." ? completeToken(TokenType.Spread) : makeToken();
case LexerPhase.HexaFirst:
if (ch === "_") {
break;
}
if (!isHexadecimalDigit(ch)) {
return makeToken();
}
phase = LexerPhase.HexaTail;
tokenType = TokenType.HexadecimalLiteral;
break;
case LexerPhase.HexaTail:
if (!isHexadecimalDigit(ch) && ch !== "_") {
return makeToken();
}
break;
case LexerPhase.BinaryFirst:
if (ch === "_") {
break;
}
if (!isBinaryDigit(ch)) {
return makeToken();
}
phase = LexerPhase.BinaryTail;
tokenType = TokenType.BinaryLiteral;
break;
case LexerPhase.BinaryTail:
if (!isBinaryDigit(ch) && ch !== "_") {
return makeToken();
}
tokenType = TokenType.BinaryLiteral;
break;
case LexerPhase.DecimalOrReal:
if (isDecimalDigit(ch) || ch === "_") {
break;
} else if (
ch === "." &&
(this.input.peek() === null || isDecimalDigit(this.input.peek()!))
) {
phase = LexerPhase.RealFractionalFirst;
tokenType = TokenType.Unknown;
} else if (ch === "e" || ch === "E") {
phase = LexerPhase.RealExponent;
tokenType = TokenType.Unknown;
} else {
return makeToken();
}
break;
case LexerPhase.RealFractionalFirst:
if (isDecimalDigit(ch)) {
phase = LexerPhase.RealFractionalTail;
tokenType = TokenType.RealLiteral;
} else if (ch === "e" || ch === "E") {
phase = LexerPhase.RealExponent;
} else {
return makeToken();
}
break;
case LexerPhase.RealFractionalTail:
if (ch === "e" || ch === "E") {
phase = LexerPhase.RealExponent;
tokenType = TokenType.Unknown;
} else if (!isDecimalDigit(ch) && ch !== "_") {
return makeToken();
}
break;
case LexerPhase.RealExponent:
if (ch === "+" || ch === "-") {
phase = LexerPhase.RealExponentSign;
} else if (isDecimalDigit(ch)) {
phase = LexerPhase.RealExponentTail;
tokenType = TokenType.RealLiteral;
} else {
return makeToken();
}
break;
case LexerPhase.RealExponentSign:
if (isDecimalDigit(ch)) {
phase = LexerPhase.RealExponentTail;
tokenType = TokenType.RealLiteral;
} else {
return makeToken();
}
break;
case LexerPhase.RealExponentTail:
if (!isDecimalDigit(ch)) {
return makeToken();
}
break;
// A dollar sign is also a valid variable name. When it isn't a dollar left brace, we continue as if it was an identifier
case LexerPhase.Dollar:
if (ch === "{") {
return completeToken(TokenType.DollarLBrace);
}
phase = LexerPhase.IdTail;
useResolver = true;
tokenType = TokenType.Identifier;
if (!isIdContinuation(ch)) {
makeToken();
}
break;
case LexerPhase.StringTemplateLiteralBackSlash: {
phase = LexerPhase.StringTemplateLiteral;
const charAhead1 = this.input.ahead(0);
const charAhead2 = this.input.ahead(1);
if (charAhead1 === "`" || (charAhead1 === "$" && charAhead2 === "{")) {
return completeToken(TokenType.StringLiteral);
}
break;
}
case LexerPhase.StringTemplateLiteral:
switch (ch) {
case "\\":
phase = LexerPhase.StringTemplateLiteralBackSlash;
tokenType = TokenType.Unknown;
break phaseSwitch;
case "`":
return completeToken(TokenType.Backtick);
case "$":
const charAhead = this.input.ahead(0);
if (charAhead === "{") {
appendTokenChar();
this.fetchNextChar();
return completeToken(TokenType.DollarLBrace);
}
}
const charAhead1 = this.input.ahead(0);
const charAhead2 = this.input.ahead(1);
if (charAhead1 === "`" || (charAhead1 === "$" && charAhead2 === "{")) {
return completeToken(TokenType.StringLiteral);
}
break;
case LexerPhase.String:
if (ch === stringState) {
return completeToken(TokenType.StringLiteral);
} else if (isRestrictedInString(ch)) {
return completeToken(TokenType.Unknown);
} else if (ch === "\\") {
phase = LexerPhase.StringBackSlash;
tokenType = TokenType.Unknown;
}
break;
// Start of string character escape
case LexerPhase.StringBackSlash:
switch (ch) {
case "b":
case "f":
case "n":
case "r":
case "t":
case "v":
case "S":
case "0":
case "'":
case '"':
case "`":
case "\\":
phase = LexerPhase.String;
break;
case "x":
phase = LexerPhase.StringHexa1;
break;
case "u":
phase = LexerPhase.StringUHexa1;
break;
default:
phase = LexerPhase.String;
break;
}
break;
// --- First hexadecimal digit of string character escape
case LexerPhase.StringHexa1:
if (isHexadecimalDigit(ch)) {
phase = LexerPhase.StringHexa2;
} else {
return completeToken(TokenType.Unknown);
}
break;
// --- Second hexadecimal digit of character escape
case LexerPhase.StringHexa2:
if (isHexadecimalDigit(ch)) {
phase = LexerPhase.String;
} else {
return completeToken(TokenType.Unknown);
}
break;
// --- First hexadecimal digit of Unicode string character escape
case LexerPhase.StringUHexa1:
if (ch === "{") {
phase = LexerPhase.StringUcp1;
break;
}
if (isHexadecimalDigit(ch)) {
phase = LexerPhase.StringUHexa2;
} else {
return completeToken(TokenType.Unknown);
}
break;
// --- Second hexadecimal digit of Unicode string character escape
case LexerPhase.StringUHexa2:
if (isHexadecimalDigit(ch)) {
phase = LexerPhase.StringUHexa3;
} else {
return completeToken(TokenType.Unknown);
}
break;
// --- Third hexadecimal digit of Unicode string character escape
case LexerPhase.StringUHexa3:
if (isHexadecimalDigit(ch)) {
phase = LexerPhase.StringUHexa4;
} else {
return completeToken(TokenType.Unknown);
}
break;
// --- Fourth hexadecimal digit of Unicode string character escape
case LexerPhase.StringUHexa4:
if (isHexadecimalDigit(ch)) {
phase = LexerPhase.String;
} else {
return completeToken(TokenType.Unknown);
}
break;
// --- First hexadecimal digit of Unicode codepoint string character escape
case LexerPhase.StringUcp1:
if (isHexadecimalDigit(ch)) {
phase = LexerPhase.StringUcp2;
} else {
return completeToken(TokenType.Unknown);
}
break;
// --- Second hexadecimal digit of Unicode codepoint string character escape
case LexerPhase.StringUcp2:
if (ch === "}") {
phase = LexerPhase.String;
} else if (isHexadecimalDigit(ch)) {
phase = LexerPhase.StringUcp3;
} else {
return completeToken(TokenType.Unknown);
}
break;
// --- Third hexadecimal digit of Unicode codepoint string character escape
case LexerPhase.StringUcp3:
if (ch === "}") {
phase = LexerPhase.String;
} else if (isHexadecimalDigit(ch)) {
phase = LexerPhase.StringUcp4;
} else {
return completeToken(TokenType.Unknown);
}
break;
// --- Fourth hexadecimal digit of Unicode codepoint string character escape
case LexerPhase.StringUcp4:
if (ch === "}") {
phase = LexerPhase.String;
} else if (isHexadecimalDigit(ch)) {
phase = LexerPhase.StringUcp5;
} else {
return completeToken(TokenType.Unknown);
}
break;
// --- Fifth hexadecimal digit of Unicode codepoint string character escape
case LexerPhase.StringUcp5:
if (ch === "}") {
phase = LexerPhase.String;
} else if (isHexadecimalDigit(ch)) {
phase = LexerPhase.StringUcp6;
} else {
return completeToken(TokenType.Unknown);
}
break;
// --- Sixth hexadecimal digit of Unicode codepoint string character escape
case LexerPhase.StringUcp6:
if (ch === "}") {
phase = LexerPhase.String;
} else if (isHexadecimalDigit(ch)) {
phase = LexerPhase.StringUcpTail;
} else {
return completeToken(TokenType.Unknown);
}
break;
// --- Closing bracket of Unicode codepoint string character escape
case LexerPhase.StringUcpTail:
if (ch === "}") {
phase = LexerPhase.String;
} else {
return completeToken(TokenType.Unknown);
}
break;
// ====================================================================
// --- We cannot continue
default:
return makeToken();
}
// --- Append the char to the current text
appendTokenChar();
// --- Go on with parsing the next character
}
/**
* Packs the specified type of token to send back
*/
function makeToken(): Token {
if (useResolver) {
tokenType =
resolverHash.get(text) ??
(isIdStart(text[0]) && text[text.length - 1] !== "'"
? TokenType.Identifier
: TokenType.Unknown);
}
return {
text,
type: tokenType,
startPosition: startPos,
endPosition: lastEndPos,
startLine: line,
endLine: line,
startColumn,
endColumn: lastEndColumn,
};
}
/**
* Add the last character to the token and return it
*/
function completeToken(suggestedType?: TokenType): Token {
appendTokenChar();
// --- Send back the token
if (suggestedType !== undefined) {
tokenType = suggestedType;
}
return makeToken();
}
}
getStartingPhaseThenReset(): LexerPhase {
if (this._phaseExternallySet !== null) {
const phase = this._phaseExternallySet;
this._phaseExternallySet = null;
return phase;
}
return LexerPhase.Start;
}
/**
* Fetches the next RegEx token from the input stream
*/
private fetchRegEx(): RegExpLexerResult {
// --- Get the tail
const tailPosition =
this._ahead.length > 0 ? this._ahead[0].startPosition : this._lastFetchPosition;
const tail = this.input.getTail(tailPosition);
// --- Parse the tail. If no error, the entire tail is the RegExp
try {
const regexpResult = parseRegExpLiteral(tail);
const text = regexpResult.raw;
// --- Consume the characters parsed successfully
for (let i = 1; i < text.length; i++) {
this.fetchNextChar();
this._prefetched = null;
this._prefetchedPos = null;
this._prefetchedColumn = null;
}
this._ahead.length = 0;
// --- Return the token
return {
success: true,
pattern: regexpResult.pattern.raw,
flags: regexpResult.flags.raw,
length: text.length,
};
} catch (parseErr: any) {
let errorIndex = parseErr.index;
if (parseErr.toString().includes("Invalid flag")) {
while (errorIndex < tail.length && "dgimsuy".includes(tail[errorIndex])) {
errorIndex++;
}
}
// --- If there is no error, something is wrong
if (errorIndex === undefined) {
return {
success: false,
pattern: tail[0],
};
}
// --- Try to parse the tail before the error position
const tailBeforeError = tail.substring(0, errorIndex);
try {
const regexpResult = parseRegExpLiteral(tailBeforeError);
const text = regexpResult.raw;
// --- Consume the characters parsed successfully
for (let i = 1; i < text.length; i++) {
this.fetchNextChar();
this._prefetched = null;
this._prefetchedPos = null;
this._prefetchedColumn = null;
}
this._ahead.length = 0;
// --- Return the token
return {
success: true,
pattern: regexpResult.pattern.raw,
flags: regexpResult.flags.raw,
length: text.length,
};
} catch (parseErr2) {
// --- This is really not a regexp
return {
success: false,
pattern: tailBeforeError,
};
}
}
}
}
/**
* Reserved ID-like tokens
*/
const resolverHash = new Map<string, TokenType>();
resolverHash.set("typeof", TokenType.Typeof);
resolverHash.set("Infinity", TokenType.Infinity);
resolverHash.set("NaN", TokenType.NaN);
resolverHash.set("true", TokenType.True);
resolverHash.set("false", TokenType.False);
resolverHash.set("undefined", TokenType.Undefined);
resolverHash.set("null", TokenType.Null);
resolverHash.set("in", TokenType.In);
resolverHash.set("let", TokenType.Let);
resolverHash.set("const", TokenType.Const);
resolverHash.set("var", TokenType.Var);
resolverHash.set("if", TokenType.If);
resolverHash.set("else", TokenType.Else);
resolverHash.set("return", TokenType.Return);
resolverHash.set("break", TokenType.Break);
resolverHash.set("continue", TokenType.Continue);
resolverHash.set("do", TokenType.Do);
resolverHash.set("while", TokenType.While);
resolverHash.set("for", TokenType.For);
resolverHash.set("of", TokenType.Of);
resolverHash.set("try", TokenType.Try);
resolverHash.set("catch", TokenType.Catch);
resolverHash.set("finally", TokenType.Finally);
resolverHash.set("throw", TokenType.Throw);
resolverHash.set("switch", TokenType.Switch);
resolverHash.set("case", TokenType.Case);
resolverHash.set("default", TokenType.Default);
resolverHash.set("delete", TokenType.Delete);
resolverHash.set("function", TokenType.Function);
resolverHash.set("as", TokenType.As);
/**
* Tests if a token id EOF
* @param t Token instance
*/
function isEof(t: Token): boolean {
return t.type === TokenType.Eof;
}
/**
* Tests if a token is whitespace
* @param t Token instance
*/
function isWs(t: Token): boolean {
return t.type <= TokenType.Ws;
}
/**
* Tests if a character is an identifier start character
* @param ch Character to test
*/
function isIdStart(ch: string): boolean {
return (ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z") || ch === "_" || ch === "$";
}
/**
* Tests if a character is an identifier continuation character
* @param ch Character to test
*/
function isIdContinuation(ch: string): boolean {
return (
(ch >= "a" && ch <= "z") ||
(ch >= "A" && ch <= "Z") ||
(ch >= "0" && ch <= "9") ||
ch === "_" ||
ch === "$"
);
}
/**
* Tests if a character is a binary digit
* @param ch Character to test
*/
function isBinaryDigit(ch: string): boolean {
return ch === "0" || ch === "1";
}
/**
* Tests if a character is a decimal digit
* @param ch Character to test
*/
function isDecimalDigit(ch: string): boolean {
return ch >= "0" && ch <= "9";
}
/**
* Tests if a character is a hexadecimal digit
* @param ch Character to test
*/
function isHexadecimalDigit(ch: string): boolean {
return (ch >= "0" && ch <= "9") || (ch >= "A" && ch <= "F") || (ch >= "a" && ch <= "f");
}
/**
* Tests if a character is restricted in a string
* @param ch Character to test
*/
function isRestrictedInString(ch: string): boolean {
return ch === "\r" || ch === "\n" || ch === "\u0085" || ch === "\u2028" || ch === "\u2029";
}
// --- Result from RegExp lexing
export type RegExpLexerResult = {
success: boolean;
pattern?: string;
flags?: string;
length?: number;
};
```