This is page 100 of 186. Use http://codebase.md/xmlui-org/xmlui/xmlui/tools/vscode/resources/xmlui-markup-syntax-highlighting.png?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .changeset
│ └── config.json
├── .eslintrc.cjs
├── .github
│ ├── build-checklist.png
│ ├── ISSUE_TEMPLATE
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ └── workflows
│ ├── deploy-blog-optimized.yml
│ ├── deploy-blog-swa.yml
│ ├── deploy-blog.yml
│ ├── deploy-docs-optimized.yml
│ ├── deploy-docs.yml
│ ├── prepare-versions.yml
│ ├── release-packages.yml
│ ├── run-all-tests.yml
│ └── run-smoke-tests.yml
├── .gitignore
├── .prettierrc.js
├── .vscode
│ ├── launch.json
│ └── settings.json
├── blog
│ ├── .gitignore
│ ├── .gitkeep
│ ├── CHANGELOG.md
│ ├── extensions.ts
│ ├── index.html
│ ├── index.ts
│ ├── package.json
│ ├── public
│ │ ├── blog
│ │ │ ├── images
│ │ │ │ ├── an-advanced-codefence.gif
│ │ │ │ ├── an-advanced-codefence.mp4
│ │ │ │ ├── blog-page-component.png
│ │ │ │ ├── blog-scrabble.png
│ │ │ │ ├── codefence-runner.png
│ │ │ │ ├── integrated-blog-search.png
│ │ │ │ ├── lorem-ipsum.png
│ │ │ │ ├── playground-checkbox-source.png
│ │ │ │ ├── playground.png
│ │ │ │ ├── use-xmlui-mcp-to-find-a-howto.png
│ │ │ │ └── xmlui-demo-gallery.png
│ │ │ ├── introducing-xmlui.md
│ │ │ ├── lorem-ipsum.md
│ │ │ ├── newest-post.md
│ │ │ ├── older-post.md
│ │ │ ├── xmlui-playground.md
│ │ │ └── xmlui-powered-blog.md
│ │ ├── mockServiceWorker.js
│ │ ├── resources
│ │ │ ├── favicon.ico
│ │ │ ├── files
│ │ │ │ └── for-download
│ │ │ │ └── xmlui
│ │ │ │ └── xmlui-standalone.umd.js
│ │ │ ├── github.svg
│ │ │ ├── llms.txt
│ │ │ ├── logo-dark.svg
│ │ │ ├── logo.svg
│ │ │ ├── pg-popout.svg
│ │ │ ├── rss.svg
│ │ │ └── xmlui-logo.svg
│ │ ├── serve.json
│ │ ├── staticwebapp.config.json
│ │ └── web.config
│ ├── scripts
│ │ ├── download-latest-xmlui.js
│ │ ├── generate-rss.js
│ │ ├── get-releases.js
│ │ └── utils.js
│ ├── src
│ │ ├── components
│ │ │ ├── BlogOverview.xmlui
│ │ │ ├── BlogPage.xmlui
│ │ │ └── PageNotFound.xmlui
│ │ ├── config.ts
│ │ ├── Main.xmlui
│ │ └── themes
│ │ └── blog-theme.ts
│ └── tsconfig.json
├── CONTRIBUTING.md
├── docs
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── ComponentRefLinks.txt
│ ├── content
│ │ ├── _meta.json
│ │ ├── components
│ │ │ ├── _meta.json
│ │ │ ├── _overview.md
│ │ │ ├── APICall.md
│ │ │ ├── App.md
│ │ │ ├── AppHeader.md
│ │ │ ├── AppState.md
│ │ │ ├── AutoComplete.md
│ │ │ ├── Avatar.md
│ │ │ ├── Backdrop.md
│ │ │ ├── Badge.md
│ │ │ ├── BarChart.md
│ │ │ ├── Bookmark.md
│ │ │ ├── Breakout.md
│ │ │ ├── Button.md
│ │ │ ├── Card.md
│ │ │ ├── Carousel.md
│ │ │ ├── ChangeListener.md
│ │ │ ├── Checkbox.md
│ │ │ ├── CHStack.md
│ │ │ ├── ColorPicker.md
│ │ │ ├── Column.md
│ │ │ ├── ContentSeparator.md
│ │ │ ├── CVStack.md
│ │ │ ├── DataSource.md
│ │ │ ├── DateInput.md
│ │ │ ├── DatePicker.md
│ │ │ ├── DonutChart.md
│ │ │ ├── DropdownMenu.md
│ │ │ ├── EmojiSelector.md
│ │ │ ├── ExpandableItem.md
│ │ │ ├── FileInput.md
│ │ │ ├── FileUploadDropZone.md
│ │ │ ├── FlowLayout.md
│ │ │ ├── Footer.md
│ │ │ ├── Form.md
│ │ │ ├── FormItem.md
│ │ │ ├── FormSection.md
│ │ │ ├── Fragment.md
│ │ │ ├── H1.md
│ │ │ ├── H2.md
│ │ │ ├── H3.md
│ │ │ ├── H4.md
│ │ │ ├── H5.md
│ │ │ ├── H6.md
│ │ │ ├── Heading.md
│ │ │ ├── HSplitter.md
│ │ │ ├── HStack.md
│ │ │ ├── Icon.md
│ │ │ ├── IFrame.md
│ │ │ ├── Image.md
│ │ │ ├── Items.md
│ │ │ ├── LabelList.md
│ │ │ ├── Legend.md
│ │ │ ├── LineChart.md
│ │ │ ├── Link.md
│ │ │ ├── List.md
│ │ │ ├── Logo.md
│ │ │ ├── Markdown.md
│ │ │ ├── MenuItem.md
│ │ │ ├── MenuSeparator.md
│ │ │ ├── ModalDialog.md
│ │ │ ├── NavGroup.md
│ │ │ ├── NavLink.md
│ │ │ ├── NavPanel.md
│ │ │ ├── NoResult.md
│ │ │ ├── NumberBox.md
│ │ │ ├── Option.md
│ │ │ ├── Page.md
│ │ │ ├── PageMetaTitle.md
│ │ │ ├── Pages.md
│ │ │ ├── Pagination.md
│ │ │ ├── PasswordInput.md
│ │ │ ├── PieChart.md
│ │ │ ├── ProgressBar.md
│ │ │ ├── Queue.md
│ │ │ ├── RadioGroup.md
│ │ │ ├── RealTimeAdapter.md
│ │ │ ├── Redirect.md
│ │ │ ├── Select.md
│ │ │ ├── Slider.md
│ │ │ ├── Slot.md
│ │ │ ├── SpaceFiller.md
│ │ │ ├── Spinner.md
│ │ │ ├── Splitter.md
│ │ │ ├── Stack.md
│ │ │ ├── StickyBox.md
│ │ │ ├── SubMenuItem.md
│ │ │ ├── Switch.md
│ │ │ ├── TabItem.md
│ │ │ ├── Table.md
│ │ │ ├── TableOfContents.md
│ │ │ ├── Tabs.md
│ │ │ ├── Text.md
│ │ │ ├── TextArea.md
│ │ │ ├── TextBox.md
│ │ │ ├── Theme.md
│ │ │ ├── TimeInput.md
│ │ │ ├── Timer.md
│ │ │ ├── ToneChangerButton.md
│ │ │ ├── ToneSwitch.md
│ │ │ ├── Tooltip.md
│ │ │ ├── Tree.md
│ │ │ ├── VSplitter.md
│ │ │ ├── VStack.md
│ │ │ ├── xmlui-animations
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ ├── Animation.md
│ │ │ │ ├── FadeAnimation.md
│ │ │ │ ├── FadeInAnimation.md
│ │ │ │ ├── FadeOutAnimation.md
│ │ │ │ ├── ScaleAnimation.md
│ │ │ │ └── SlideInAnimation.md
│ │ │ ├── xmlui-pdf
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ └── Pdf.md
│ │ │ ├── xmlui-spreadsheet
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ └── Spreadsheet.md
│ │ │ └── xmlui-website-blocks
│ │ │ ├── _meta.json
│ │ │ ├── _overview.md
│ │ │ ├── Carousel.md
│ │ │ ├── HelloMd.md
│ │ │ ├── HeroSection.md
│ │ │ └── ScrollToTop.md
│ │ └── extensions
│ │ ├── _meta.json
│ │ ├── xmlui-animations
│ │ │ ├── _meta.json
│ │ │ ├── _overview.md
│ │ │ ├── Animation.md
│ │ │ ├── FadeAnimation.md
│ │ │ ├── FadeInAnimation.md
│ │ │ ├── FadeOutAnimation.md
│ │ │ ├── ScaleAnimation.md
│ │ │ └── SlideInAnimation.md
│ │ └── xmlui-website-blocks
│ │ ├── _meta.json
│ │ ├── _overview.md
│ │ ├── Carousel.md
│ │ ├── FancyButton.md
│ │ ├── HeroSection.md
│ │ └── ScrollToTop.md
│ ├── extensions.ts
│ ├── index.html
│ ├── index.ts
│ ├── package.json
│ ├── public
│ │ ├── feed.rss
│ │ ├── mockServiceWorker.js
│ │ ├── pages
│ │ │ ├── _meta.json
│ │ │ ├── app-structure.md
│ │ │ ├── build-editor-component.md
│ │ │ ├── build-hello-world-component.md
│ │ │ ├── components-intro.md
│ │ │ ├── context-variables.md
│ │ │ ├── forms.md
│ │ │ ├── globals.md
│ │ │ ├── glossary.md
│ │ │ ├── helper-tags.md
│ │ │ ├── hosted-deployment.md
│ │ │ ├── howto
│ │ │ │ ├── assign-a-complex-json-literal-to-a-component-variable.md
│ │ │ │ ├── chain-a-refetch.md
│ │ │ │ ├── control-cache-invalidation.md
│ │ │ │ ├── debounce-user-input-for-api-calls.md
│ │ │ │ ├── debounce-with-changelistener.md
│ │ │ │ ├── debug-a-component.md
│ │ │ │ ├── delay-a-datasource-until-another-datasource-is-ready.md
│ │ │ │ ├── delegate-a-method.md
│ │ │ │ ├── do-custom-form-validation.md
│ │ │ │ ├── expose-a-method-from-a-component.md
│ │ │ │ ├── filter-and-transform-data-from-an-api.md
│ │ │ │ ├── group-items-in-list-by-a-property.md
│ │ │ │ ├── handle-background-operations.md
│ │ │ │ ├── hide-an-element-until-its-datasource-is-ready.md
│ │ │ │ ├── make-a-set-of-equal-width-cards.md
│ │ │ │ ├── make-a-table-responsive.md
│ │ │ │ ├── make-navpanel-width-responsive.md
│ │ │ │ ├── modify-a-value-reported-in-a-column.md
│ │ │ │ ├── paginate-a-list.md
│ │ │ │ ├── pass-data-to-a-modal-dialog.md
│ │ │ │ ├── react-to-button-click-not-keystrokes.md
│ │ │ │ ├── set-the-initial-value-of-a-select-from-fetched-data.md
│ │ │ │ ├── share-a-modaldialog-across-components.md
│ │ │ │ ├── sync-selections-between-table-and-list-views.md
│ │ │ │ ├── update-ui-optimistically.md
│ │ │ │ ├── use-built-in-form-validation.md
│ │ │ │ └── use-the-same-modaldialog-to-add-or-edit.md
│ │ │ ├── howto.md
│ │ │ ├── intro.md
│ │ │ ├── layout.md
│ │ │ ├── markup.md
│ │ │ ├── mcp.md
│ │ │ ├── modal-dialogs.md
│ │ │ ├── news-and-reviews.md
│ │ │ ├── reactive-intro.md
│ │ │ ├── refactoring.md
│ │ │ ├── routing-and-links.md
│ │ │ ├── samples
│ │ │ │ ├── color-palette.xmlui
│ │ │ │ ├── color-values.xmlui
│ │ │ │ ├── shadow-sizes.xmlui
│ │ │ │ ├── spacing-sizes.xmlui
│ │ │ │ ├── swatch.xmlui
│ │ │ │ ├── theme-gallery-brief.xmlui
│ │ │ │ └── theme-gallery.xmlui
│ │ │ ├── scoping.md
│ │ │ ├── scripting.md
│ │ │ ├── styles-and-themes
│ │ │ │ ├── common-units.md
│ │ │ │ ├── layout-props.md
│ │ │ │ ├── theme-variable-defaults.md
│ │ │ │ ├── theme-variables.md
│ │ │ │ └── themes.md
│ │ │ ├── template-properties.md
│ │ │ ├── test.md
│ │ │ ├── tutorial-01.md
│ │ │ ├── tutorial-02.md
│ │ │ ├── tutorial-03.md
│ │ │ ├── tutorial-04.md
│ │ │ ├── tutorial-05.md
│ │ │ ├── tutorial-06.md
│ │ │ ├── tutorial-07.md
│ │ │ ├── tutorial-08.md
│ │ │ ├── tutorial-09.md
│ │ │ ├── tutorial-10.md
│ │ │ ├── tutorial-11.md
│ │ │ ├── tutorial-12.md
│ │ │ ├── universal-properties.md
│ │ │ ├── user-defined-components.md
│ │ │ ├── vscode.md
│ │ │ ├── working-with-markdown.md
│ │ │ ├── working-with-text.md
│ │ │ ├── xmlui-animations
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ ├── Animation.md
│ │ │ │ ├── FadeAnimation.md
│ │ │ │ ├── FadeInAnimation.md
│ │ │ │ ├── FadeOutAnimation.md
│ │ │ │ ├── ScaleAnimation.md
│ │ │ │ └── SlideInAnimation.md
│ │ │ ├── xmlui-charts
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ ├── BarChart.md
│ │ │ │ ├── DonutChart.md
│ │ │ │ ├── LabelList.md
│ │ │ │ ├── Legend.md
│ │ │ │ ├── LineChart.md
│ │ │ │ └── PieChart.md
│ │ │ ├── xmlui-pdf
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ └── Pdf.md
│ │ │ └── xmlui-spreadsheet
│ │ │ ├── _meta.json
│ │ │ ├── _overview.md
│ │ │ └── Spreadsheet.md
│ │ ├── resources
│ │ │ ├── devdocs
│ │ │ │ ├── debug-proxy-object-2.png
│ │ │ │ ├── debug-proxy-object.png
│ │ │ │ ├── table_editor_01.png
│ │ │ │ ├── table_editor_02.png
│ │ │ │ ├── table_editor_03.png
│ │ │ │ ├── table_editor_04.png
│ │ │ │ ├── table_editor_05.png
│ │ │ │ ├── table_editor_06.png
│ │ │ │ ├── table_editor_07.png
│ │ │ │ ├── table_editor_08.png
│ │ │ │ ├── table_editor_09.png
│ │ │ │ ├── table_editor_10.png
│ │ │ │ ├── table_editor_11.png
│ │ │ │ ├── table-editor-01.png
│ │ │ │ ├── table-editor-02.png
│ │ │ │ ├── table-editor-03.png
│ │ │ │ ├── table-editor-04.png
│ │ │ │ ├── table-editor-06.png
│ │ │ │ ├── table-editor-07.png
│ │ │ │ ├── table-editor-08.png
│ │ │ │ ├── table-editor-09.png
│ │ │ │ └── xmlui-rendering-of-tiptap-markdown.png
│ │ │ ├── favicon.ico
│ │ │ ├── files
│ │ │ │ ├── clients.json
│ │ │ │ ├── daily-revenue.json
│ │ │ │ ├── dashboard-stats.json
│ │ │ │ ├── demo.xmlui
│ │ │ │ ├── demo.xmlui.xs
│ │ │ │ ├── downloads
│ │ │ │ │ └── downloads.json
│ │ │ │ ├── for-download
│ │ │ │ │ ├── index-with-api.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ ├── mockApi.js
│ │ │ │ │ ├── start-darwin.sh
│ │ │ │ │ ├── start-linux.sh
│ │ │ │ │ ├── start.bat
│ │ │ │ │ └── xmlui
│ │ │ │ │ └── xmlui-standalone.umd.js
│ │ │ │ ├── getting-started
│ │ │ │ │ ├── cl-tutorial-final.zip
│ │ │ │ │ ├── cl-tutorial.zip
│ │ │ │ │ ├── cl-tutorial2.zip
│ │ │ │ │ ├── cl-tutorial3.zip
│ │ │ │ │ ├── cl-tutorial4.zip
│ │ │ │ │ ├── cl-tutorial5.zip
│ │ │ │ │ ├── cl-tutorial6.zip
│ │ │ │ │ ├── getting-started.zip
│ │ │ │ │ ├── hello-xmlui.zip
│ │ │ │ │ ├── xmlui-empty.zip
│ │ │ │ │ └── xmlui-starter.zip
│ │ │ │ ├── howto
│ │ │ │ │ └── component-icons
│ │ │ │ │ └── up-arrow.svg
│ │ │ │ ├── invoices.json
│ │ │ │ ├── monthly-status.json
│ │ │ │ ├── news-and-reviews.json
│ │ │ │ ├── products.json
│ │ │ │ ├── releases.json
│ │ │ │ ├── tutorials
│ │ │ │ │ ├── datasource
│ │ │ │ │ │ └── api.ts
│ │ │ │ │ └── p2do
│ │ │ │ │ ├── api.ts
│ │ │ │ │ └── todo-logo.svg
│ │ │ │ └── xmlui.json
│ │ │ ├── github.svg
│ │ │ ├── images
│ │ │ │ ├── apiaction-tutorial
│ │ │ │ │ ├── add-success.png
│ │ │ │ │ ├── apiaction-param.png
│ │ │ │ │ ├── change-completed.png
│ │ │ │ │ ├── change-in-progress.png
│ │ │ │ │ ├── confirm-delete.png
│ │ │ │ │ ├── data-error.png
│ │ │ │ │ ├── data-progress.png
│ │ │ │ │ ├── data-success.png
│ │ │ │ │ ├── display-1.png
│ │ │ │ │ ├── item-deleted.png
│ │ │ │ │ ├── item-updated.png
│ │ │ │ │ ├── missing-api-key.png
│ │ │ │ │ ├── new-item-added.png
│ │ │ │ │ └── test-message.png
│ │ │ │ ├── chat-api
│ │ │ │ │ └── domain-model.svg
│ │ │ │ ├── components
│ │ │ │ │ ├── image
│ │ │ │ │ │ └── breakfast.jpg
│ │ │ │ │ ├── markdown
│ │ │ │ │ │ └── colors.png
│ │ │ │ │ └── modal
│ │ │ │ │ ├── deep_link_dialog_1.jpg
│ │ │ │ │ └── deep_link_dialog_2.jpg
│ │ │ │ ├── create-apps
│ │ │ │ │ ├── collapsed-vertical.png
│ │ │ │ │ ├── using-forms-warning-dialog.png
│ │ │ │ │ └── using-forms.png
│ │ │ │ ├── datasource-tutorial
│ │ │ │ │ ├── data-with-header.png
│ │ │ │ │ ├── filtered-data.png
│ │ │ │ │ ├── filtered-items.png
│ │ │ │ │ ├── initial-page-items.png
│ │ │ │ │ ├── list-items.png
│ │ │ │ │ ├── next-page-items.png
│ │ │ │ │ ├── no-data.png
│ │ │ │ │ ├── pagination-1.jpg
│ │ │ │ │ ├── pagination-1.png
│ │ │ │ │ ├── polling-1.png
│ │ │ │ │ ├── refetch-data.png
│ │ │ │ │ ├── slow-loading.png
│ │ │ │ │ ├── test-message.png
│ │ │ │ │ ├── Thumbs.db
│ │ │ │ │ ├── unconventional-data.png
│ │ │ │ │ └── unfiltered-items.png
│ │ │ │ ├── flower.jpg
│ │ │ │ ├── get-started
│ │ │ │ │ ├── add-new-contact.png
│ │ │ │ │ ├── app-modified.png
│ │ │ │ │ ├── app-start.png
│ │ │ │ │ ├── app-with-boxes.png
│ │ │ │ │ ├── app-with-toast.png
│ │ │ │ │ ├── boilerplate-structure.png
│ │ │ │ │ ├── cl-initial.png
│ │ │ │ │ ├── cl-start.png
│ │ │ │ │ ├── contact-counts.png
│ │ │ │ │ ├── contact-dialog-title.png
│ │ │ │ │ ├── contact-dialog.png
│ │ │ │ │ ├── contact-menus.png
│ │ │ │ │ ├── contact-predicates.png
│ │ │ │ │ ├── context-menu.png
│ │ │ │ │ ├── dashboard-numbers.png
│ │ │ │ │ ├── default-contact-list.png
│ │ │ │ │ ├── delete-contact.png
│ │ │ │ │ ├── delete-task.png
│ │ │ │ │ ├── detailed-template.png
│ │ │ │ │ ├── edit-contact-details.png
│ │ │ │ │ ├── edited-contact-saved.png
│ │ │ │ │ ├── empty-sections.png
│ │ │ │ │ ├── filter-completed.png
│ │ │ │ │ ├── fullwidth-desktop.png
│ │ │ │ │ ├── fullwidth-mobile.png
│ │ │ │ │ ├── initial-table.png
│ │ │ │ │ ├── items-and-badges.png
│ │ │ │ │ ├── loading-message.png
│ │ │ │ │ ├── new-contact-button.png
│ │ │ │ │ ├── new-contact-saved.png
│ │ │ │ │ ├── no-empty-sections.png
│ │ │ │ │ ├── personal-todo-initial.png
│ │ │ │ │ ├── piechart.png
│ │ │ │ │ ├── review-today.png
│ │ │ │ │ ├── rudimentary-dashboard.png
│ │ │ │ │ ├── section-collapsed.png
│ │ │ │ │ ├── sectioned-items.png
│ │ │ │ │ ├── sections-ordered.png
│ │ │ │ │ ├── spacex-list-with-links.png
│ │ │ │ │ ├── spacex-list.png
│ │ │ │ │ ├── start-personal-todo-1.png
│ │ │ │ │ ├── submit-new-contact.png
│ │ │ │ │ ├── submit-new-task.png
│ │ │ │ │ ├── syntax-highlighting.png
│ │ │ │ │ ├── table-with-badge.png
│ │ │ │ │ ├── template-with-card.png
│ │ │ │ │ ├── test-emulated-api.png
│ │ │ │ │ ├── Thumbs.db
│ │ │ │ │ ├── todo-logo.png
│ │ │ │ │ └── xmlui-tools.png
│ │ │ │ ├── HelloApp.png
│ │ │ │ ├── HelloApp2.png
│ │ │ │ ├── logos
│ │ │ │ │ ├── xmlui1.svg
│ │ │ │ │ ├── xmlui2.svg
│ │ │ │ │ ├── xmlui3.svg
│ │ │ │ │ ├── xmlui4.svg
│ │ │ │ │ ├── xmlui5.svg
│ │ │ │ │ ├── xmlui6.svg
│ │ │ │ │ └── xmlui7.svg
│ │ │ │ ├── pdf
│ │ │ │ │ └── dummy-pdf.jpg
│ │ │ │ ├── rendering-engine
│ │ │ │ │ ├── AppEngine-flow.svg
│ │ │ │ │ ├── Component.svg
│ │ │ │ │ ├── CompoundComponent.svg
│ │ │ │ │ ├── RootComponent.svg
│ │ │ │ │ └── tree-with-containers.svg
│ │ │ │ ├── reviewers-guide
│ │ │ │ │ ├── AppEngine-flow.svg
│ │ │ │ │ └── incbutton-in-action.png
│ │ │ │ ├── tools
│ │ │ │ │ └── boilerplate-structure.png
│ │ │ │ ├── try.svg
│ │ │ │ ├── tutorial
│ │ │ │ │ ├── app-chat-history.png
│ │ │ │ │ ├── app-content-placeholder.png
│ │ │ │ │ ├── app-header-and-content.png
│ │ │ │ │ ├── app-links-channel-selected.png
│ │ │ │ │ ├── app-links-click.png
│ │ │ │ │ ├── app-navigation.png
│ │ │ │ │ ├── finished-ex01.png
│ │ │ │ │ ├── finished-ex02.png
│ │ │ │ │ ├── hello.png
│ │ │ │ │ ├── splash-screen-advanced.png
│ │ │ │ │ ├── splash-screen-after-click.png
│ │ │ │ │ ├── splash-screen-centered.png
│ │ │ │ │ ├── splash-screen-events.png
│ │ │ │ │ ├── splash-screen-expression.png
│ │ │ │ │ ├── splash-screen-reuse-after.png
│ │ │ │ │ ├── splash-screen-reuse-before.png
│ │ │ │ │ └── splash-screen.png
│ │ │ │ └── tutorial-01.png
│ │ │ ├── llms.txt
│ │ │ ├── logo-dark.svg
│ │ │ ├── logo.svg
│ │ │ ├── pg-popout.svg
│ │ │ └── xmlui-logo.svg
│ │ ├── serve.json
│ │ └── web.config
│ ├── scripts
│ │ ├── download-latest-xmlui.js
│ │ ├── generate-rss.js
│ │ ├── get-releases.js
│ │ └── utils.js
│ ├── src
│ │ ├── components
│ │ │ ├── BlogOverview.xmlui
│ │ │ ├── BlogPage.xmlui
│ │ │ ├── Boxes.xmlui
│ │ │ ├── Breadcrumb.xmlui
│ │ │ ├── ChangeLog.xmlui
│ │ │ ├── ColorPalette.xmlui
│ │ │ ├── DocumentLinks.xmlui
│ │ │ ├── DocumentPage.xmlui
│ │ │ ├── DocumentPageNoTOC.xmlui
│ │ │ ├── Icons.xmlui
│ │ │ ├── IncButton.xmlui
│ │ │ ├── IncButton2.xmlui
│ │ │ ├── NameValue.xmlui
│ │ │ ├── PageNotFound.xmlui
│ │ │ ├── PaletteItem.xmlui
│ │ │ ├── Palettes.xmlui
│ │ │ ├── SectionHeader.xmlui
│ │ │ ├── TBD.xmlui
│ │ │ ├── Test.xmlui
│ │ │ ├── ThemesIntro.xmlui
│ │ │ ├── ThousandThemes.xmlui
│ │ │ ├── TubeStops.xmlui
│ │ │ ├── TubeStops.xmlui.xs
│ │ │ └── TwoColumnCode.xmlui
│ │ ├── config.ts
│ │ ├── Main.xmlui
│ │ └── themes
│ │ ├── docs-theme.ts
│ │ ├── earthtone.ts
│ │ ├── xmlui-gray-on-default.ts
│ │ ├── xmlui-green-on-default.ts
│ │ └── xmlui-orange-on-default.ts
│ └── tsconfig.json
├── LICENSE
├── package-lock.json
├── package.json
├── packages
│ ├── tsconfig.json
│ ├── xmlui-animations
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── Animation.tsx
│ │ ├── AnimationNative.tsx
│ │ ├── FadeAnimation.tsx
│ │ ├── FadeInAnimation.tsx
│ │ ├── FadeOutAnimation.tsx
│ │ ├── index.tsx
│ │ ├── ScaleAnimation.tsx
│ │ └── SlideInAnimation.tsx
│ ├── xmlui-devtools
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── devtools
│ │ │ │ ├── DevTools.tsx
│ │ │ │ ├── DevToolsNative.module.scss
│ │ │ │ ├── DevToolsNative.tsx
│ │ │ │ ├── ModalDialog.module.scss
│ │ │ │ ├── ModalDialog.tsx
│ │ │ │ ├── ModalVisibilityContext.tsx
│ │ │ │ ├── Tooltip.module.scss
│ │ │ │ ├── Tooltip.tsx
│ │ │ │ └── utils.ts
│ │ │ ├── editor
│ │ │ │ └── Editor.tsx
│ │ │ └── index.tsx
│ │ └── vite.config-overrides.ts
│ ├── xmlui-hello-world
│ │ ├── .gitignore
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── HelloWorld.module.scss
│ │ ├── HelloWorld.tsx
│ │ ├── HelloWorldNative.tsx
│ │ └── index.tsx
│ ├── xmlui-os-frames
│ │ ├── .gitignore
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── index.tsx
│ │ ├── IPhoneFrame.module.scss
│ │ ├── IPhoneFrame.tsx
│ │ ├── MacOSAppFrame.module.scss
│ │ ├── MacOSAppFrame.tsx
│ │ ├── WindowsAppFrame.module.scss
│ │ └── WindowsAppFrame.tsx
│ ├── xmlui-pdf
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ ├── components
│ │ │ │ └── Pdf.xmlui
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── index.tsx
│ │ ├── LazyPdfNative.tsx
│ │ ├── Pdf.module.scss
│ │ └── Pdf.tsx
│ ├── xmlui-playground
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── hooks
│ │ │ ├── usePlayground.ts
│ │ │ └── useToast.ts
│ │ ├── index.tsx
│ │ ├── playground
│ │ │ ├── Box.module.scss
│ │ │ ├── Box.tsx
│ │ │ ├── CodeSelector.tsx
│ │ │ ├── ConfirmationDialog.module.scss
│ │ │ ├── ConfirmationDialog.tsx
│ │ │ ├── Editor.tsx
│ │ │ ├── Header.module.scss
│ │ │ ├── Header.tsx
│ │ │ ├── Playground.tsx
│ │ │ ├── PlaygroundContent.module.scss
│ │ │ ├── PlaygroundContent.tsx
│ │ │ ├── PlaygroundNative.module.scss
│ │ │ ├── PlaygroundNative.tsx
│ │ │ ├── Preview.module.scss
│ │ │ ├── Preview.tsx
│ │ │ ├── Select.module.scss
│ │ │ ├── StandalonePlayground.tsx
│ │ │ ├── StandalonePlaygroundNative.module.scss
│ │ │ ├── StandalonePlaygroundNative.tsx
│ │ │ ├── ThemeSwitcher.module.scss
│ │ │ ├── ThemeSwitcher.tsx
│ │ │ ├── ToneSwitcher.tsx
│ │ │ ├── Tooltip.module.scss
│ │ │ ├── Tooltip.tsx
│ │ │ └── utils.ts
│ │ ├── providers
│ │ │ ├── Toast.module.scss
│ │ │ └── ToastProvider.tsx
│ │ ├── state
│ │ │ └── store.ts
│ │ ├── themes
│ │ │ └── theme.ts
│ │ └── utils
│ │ └── helpers.ts
│ ├── xmlui-search
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── index.tsx
│ │ ├── Search.module.scss
│ │ └── Search.tsx
│ ├── xmlui-spreadsheet
│ │ ├── .gitignore
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── index.tsx
│ │ ├── Spreadsheet.tsx
│ │ └── SpreadsheetNative.tsx
│ └── xmlui-website-blocks
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── demo
│ │ ├── components
│ │ │ ├── HeroBackgroundBreakoutPage.xmlui
│ │ │ ├── HeroBackgroundsPage.xmlui
│ │ │ ├── HeroContentsPage.xmlui
│ │ │ ├── HeroTextAlignPage.xmlui
│ │ │ ├── HeroTextPage.xmlui
│ │ │ └── HeroTonesPage.xmlui
│ │ ├── Main.xmlui
│ │ └── themes
│ │ └── default.ts
│ ├── index.html
│ ├── index.ts
│ ├── meta
│ │ └── componentsMetadata.ts
│ ├── package.json
│ ├── public
│ │ └── resources
│ │ ├── building.jpg
│ │ └── xmlui-logo.svg
│ └── src
│ ├── Carousel
│ │ ├── Carousel.module.scss
│ │ ├── Carousel.tsx
│ │ ├── CarouselContext.tsx
│ │ └── CarouselNative.tsx
│ ├── FancyButton
│ │ ├── FancyButton.module.scss
│ │ ├── FancyButton.tsx
│ │ └── FancyButton.xmlui
│ ├── Hello
│ │ ├── Hello.tsx
│ │ ├── Hello.xmlui
│ │ └── Hello.xmlui.xs
│ ├── HeroSection
│ │ ├── HeroSection.module.scss
│ │ ├── HeroSection.spec.ts
│ │ ├── HeroSection.tsx
│ │ └── HeroSectionNative.tsx
│ ├── index.tsx
│ ├── ScrollToTop
│ │ ├── ScrollToTop.module.scss
│ │ ├── ScrollToTop.tsx
│ │ └── ScrollToTopNative.tsx
│ └── vite-env.d.ts
├── playwright.config.ts
├── README.md
├── tools
│ ├── codefence
│ │ └── xmlui-code-fence-docs.md
│ ├── create-app
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── create-app.ts
│ │ ├── helpers
│ │ │ ├── copy.ts
│ │ │ ├── get-pkg-manager.ts
│ │ │ ├── git.ts
│ │ │ ├── install.ts
│ │ │ ├── is-folder-empty.ts
│ │ │ ├── is-writeable.ts
│ │ │ ├── make-dir.ts
│ │ │ └── validate-pkg.ts
│ │ ├── index.ts
│ │ ├── package.json
│ │ ├── templates
│ │ │ ├── default
│ │ │ │ └── ts
│ │ │ │ ├── gitignore
│ │ │ │ ├── index.html
│ │ │ │ ├── index.ts
│ │ │ │ ├── public
│ │ │ │ │ ├── mockServiceWorker.js
│ │ │ │ │ ├── resources
│ │ │ │ │ │ ├── favicon.ico
│ │ │ │ │ │ └── xmlui-logo.svg
│ │ │ │ │ └── serve.json
│ │ │ │ └── src
│ │ │ │ ├── components
│ │ │ │ │ ├── ApiAware.xmlui
│ │ │ │ │ ├── Home.xmlui
│ │ │ │ │ ├── IncButton.xmlui
│ │ │ │ │ └── PagePanel.xmlui
│ │ │ │ ├── config.ts
│ │ │ │ └── Main.xmlui
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── tsconfig.json
│ ├── create-xmlui-hello-world
│ │ ├── index.js
│ │ └── package.json
│ └── vscode
│ ├── .gitignore
│ ├── .vscode
│ │ ├── launch.json
│ │ └── tasks.json
│ ├── .vscodeignore
│ ├── build.sh
│ ├── CHANGELOG.md
│ ├── esbuild.js
│ ├── eslint.config.mjs
│ ├── formatter-docs.md
│ ├── generate-test-sample.sh
│ ├── LICENSE.md
│ ├── package-lock.json
│ ├── package.json
│ ├── README.md
│ ├── resources
│ │ ├── xmlui-logo.png
│ │ └── xmlui-markup-syntax-highlighting.png
│ ├── src
│ │ ├── extension.ts
│ │ └── server.ts
│ ├── syntaxes
│ │ └── xmlui.tmLanguage.json
│ ├── test-samples
│ │ └── sample.xmlui
│ ├── tsconfig.json
│ └── tsconfig.tsbuildinfo
├── turbo.json
└── xmlui
├── .gitignore
├── bin
│ ├── bootstrap.cjs
│ ├── bootstrap.js
│ ├── build-lib.ts
│ ├── build.ts
│ ├── index.ts
│ ├── preview.ts
│ ├── start.ts
│ ├── vite-xmlui-plugin.ts
│ └── viteConfig.ts
├── CHANGELOG.md
├── conventions
│ ├── component-qa-checklist.md
│ ├── copilot-conventions.md
│ ├── create-xmlui-components.md
│ ├── mermaid.md
│ ├── testing-conventions.md
│ └── xmlui-in-a-nutshell.md
├── dev-docs
│ ├── accessibility.md
│ ├── build-system.md
│ ├── build-xmlui.md
│ ├── component-behaviors.md
│ ├── component-metadata.md
│ ├── components-with-options.md
│ ├── containers.md
│ ├── data-operations.md
│ ├── glossary.md
│ ├── index.md
│ ├── next
│ │ ├── component-dev-guide.md
│ │ ├── configuration-management-enhancement-summary.md
│ │ ├── documentation-scripts-refactoring-complete-summary.md
│ │ ├── documentation-scripts-refactoring-plan.md
│ │ ├── duplicate-pattern-extraction-summary.md
│ │ ├── error-handling-standardization-summary.md
│ │ ├── generating-component-reference.md
│ │ ├── index.md
│ │ ├── logging-consistency-implementation-summary.md
│ │ ├── project-build.md
│ │ ├── project-structure.md
│ │ ├── theme-context.md
│ │ ├── tiptap-design-considerations.md
│ │ ├── working-with-code.md
│ │ ├── xmlui-runtime-architecture
│ │ └── xmlui-wcag-accessibility-report.md
│ ├── react-fundamentals.md
│ ├── release-method.md
│ ├── standalone-app.md
│ ├── theme-variables-refactoring.md
│ ├── ud-components.md
│ └── xmlui-repo.md
├── package.json
├── scripts
│ ├── coverage-only.js
│ ├── e2e-test-summary.js
│ ├── extract-component-metadata.js
│ ├── generate-docs
│ │ ├── build-downloads-map.mjs
│ │ ├── build-pages-map.mjs
│ │ ├── components-config.json
│ │ ├── configuration-management.mjs
│ │ ├── constants.mjs
│ │ ├── create-theme-files.mjs
│ │ ├── DocsGenerator.mjs
│ │ ├── error-handling.mjs
│ │ ├── extensions-config.json
│ │ ├── folders.mjs
│ │ ├── generate-summary-files.mjs
│ │ ├── get-docs.mjs
│ │ ├── input-handler.mjs
│ │ ├── logger.mjs
│ │ ├── logging-standards.mjs
│ │ ├── MetadataProcessor.mjs
│ │ ├── pattern-utilities.mjs
│ │ └── utils.mjs
│ ├── generate-metadata-markdown.js
│ ├── get-langserver-metadata.js
│ ├── inline-links.mjs
│ └── README-e2e-summary.md
├── src
│ ├── abstractions
│ │ ├── _conventions.md
│ │ ├── ActionDefs.ts
│ │ ├── AppContextDefs.ts
│ │ ├── ComponentDefs.ts
│ │ ├── ContainerDefs.ts
│ │ ├── ExtensionDefs.ts
│ │ ├── FunctionDefs.ts
│ │ ├── RendererDefs.ts
│ │ ├── scripting
│ │ │ ├── BlockScope.ts
│ │ │ ├── Compilation.ts
│ │ │ ├── LogicalThread.ts
│ │ │ ├── LoopScope.ts
│ │ │ ├── modules.ts
│ │ │ ├── ScriptParserError.ts
│ │ │ ├── Token.ts
│ │ │ ├── TryScope.ts
│ │ │ └── TryScopeExp.ts
│ │ └── ThemingDefs.ts
│ ├── components
│ │ ├── _conventions.md
│ │ ├── abstractions.ts
│ │ ├── Accordion
│ │ │ ├── Accordion.md
│ │ │ ├── Accordion.module.scss
│ │ │ ├── Accordion.spec.ts
│ │ │ ├── Accordion.tsx
│ │ │ ├── AccordionContext.tsx
│ │ │ ├── AccordionItem.tsx
│ │ │ ├── AccordionItemNative.tsx
│ │ │ └── AccordionNative.tsx
│ │ ├── Animation
│ │ │ └── AnimationNative.tsx
│ │ ├── APICall
│ │ │ ├── APICall.md
│ │ │ ├── APICall.spec.ts
│ │ │ ├── APICall.tsx
│ │ │ └── APICallNative.tsx
│ │ ├── App
│ │ │ ├── App.md
│ │ │ ├── App.module.scss
│ │ │ ├── App.spec.ts
│ │ │ ├── App.tsx
│ │ │ ├── AppLayoutContext.ts
│ │ │ ├── AppNative.tsx
│ │ │ ├── AppStateContext.ts
│ │ │ ├── doc-resources
│ │ │ │ ├── condensed-sticky.xmlui
│ │ │ │ ├── condensed.xmlui
│ │ │ │ ├── horizontal-sticky.xmlui
│ │ │ │ ├── horizontal.xmlui
│ │ │ │ ├── vertical-full-header.xmlui
│ │ │ │ ├── vertical-sticky.xmlui
│ │ │ │ └── vertical.xmlui
│ │ │ ├── IndexerContext.ts
│ │ │ ├── LinkInfoContext.ts
│ │ │ ├── SearchContext.tsx
│ │ │ ├── Sheet.module.scss
│ │ │ └── Sheet.tsx
│ │ ├── AppHeader
│ │ │ ├── AppHeader.md
│ │ │ ├── AppHeader.module.scss
│ │ │ ├── AppHeader.spec.ts
│ │ │ ├── AppHeader.tsx
│ │ │ └── AppHeaderNative.tsx
│ │ ├── AppState
│ │ │ ├── AppState.md
│ │ │ ├── AppState.spec.ts
│ │ │ ├── AppState.tsx
│ │ │ └── AppStateNative.tsx
│ │ ├── AutoComplete
│ │ │ ├── AutoComplete.md
│ │ │ ├── AutoComplete.module.scss
│ │ │ ├── AutoComplete.spec.ts
│ │ │ ├── AutoComplete.tsx
│ │ │ ├── AutoCompleteContext.tsx
│ │ │ └── AutoCompleteNative.tsx
│ │ ├── Avatar
│ │ │ ├── Avatar.md
│ │ │ ├── Avatar.module.scss
│ │ │ ├── Avatar.spec.ts
│ │ │ ├── Avatar.tsx
│ │ │ └── AvatarNative.tsx
│ │ ├── Backdrop
│ │ │ ├── Backdrop.md
│ │ │ ├── Backdrop.module.scss
│ │ │ ├── Backdrop.spec.ts
│ │ │ ├── Backdrop.tsx
│ │ │ └── BackdropNative.tsx
│ │ ├── Badge
│ │ │ ├── Badge.md
│ │ │ ├── Badge.module.scss
│ │ │ ├── Badge.spec.ts
│ │ │ ├── Badge.tsx
│ │ │ └── BadgeNative.tsx
│ │ ├── Bookmark
│ │ │ ├── Bookmark.md
│ │ │ ├── Bookmark.module.scss
│ │ │ ├── Bookmark.spec.ts
│ │ │ ├── Bookmark.tsx
│ │ │ └── BookmarkNative.tsx
│ │ ├── Breakout
│ │ │ ├── Breakout.module.scss
│ │ │ ├── Breakout.spec.ts
│ │ │ ├── Breakout.tsx
│ │ │ └── BreakoutNative.tsx
│ │ ├── Button
│ │ │ ├── Button-style.spec.ts
│ │ │ ├── Button.md
│ │ │ ├── Button.module.scss
│ │ │ ├── Button.spec.ts
│ │ │ ├── Button.tsx
│ │ │ └── ButtonNative.tsx
│ │ ├── Card
│ │ │ ├── Card.md
│ │ │ ├── Card.module.scss
│ │ │ ├── Card.spec.ts
│ │ │ ├── Card.tsx
│ │ │ └── CardNative.tsx
│ │ ├── Carousel
│ │ │ ├── Carousel.md
│ │ │ ├── Carousel.module.scss
│ │ │ ├── Carousel.spec.ts
│ │ │ ├── Carousel.tsx
│ │ │ ├── CarouselContext.tsx
│ │ │ ├── CarouselItem.tsx
│ │ │ ├── CarouselItemNative.tsx
│ │ │ └── CarouselNative.tsx
│ │ ├── ChangeListener
│ │ │ ├── ChangeListener.md
│ │ │ ├── ChangeListener.spec.ts
│ │ │ ├── ChangeListener.tsx
│ │ │ └── ChangeListenerNative.tsx
│ │ ├── chart-color-schemes.ts
│ │ ├── Charts
│ │ │ ├── AreaChart
│ │ │ │ ├── AreaChart.md
│ │ │ │ ├── AreaChart.spec.ts
│ │ │ │ ├── AreaChart.tsx
│ │ │ │ └── AreaChartNative.tsx
│ │ │ ├── BarChart
│ │ │ │ ├── BarChart.md
│ │ │ │ ├── BarChart.module.scss
│ │ │ │ ├── BarChart.spec.ts
│ │ │ │ ├── BarChart.tsx
│ │ │ │ └── BarChartNative.tsx
│ │ │ ├── DonutChart
│ │ │ │ ├── DonutChart.spec.ts
│ │ │ │ └── DonutChart.tsx
│ │ │ ├── LabelList
│ │ │ │ ├── LabelList.module.scss
│ │ │ │ ├── LabelList.spec.ts
│ │ │ │ ├── LabelList.tsx
│ │ │ │ └── LabelListNative.tsx
│ │ │ ├── Legend
│ │ │ │ ├── Legend.spec.ts
│ │ │ │ ├── Legend.tsx
│ │ │ │ └── LegendNative.tsx
│ │ │ ├── LineChart
│ │ │ │ ├── LineChart.md
│ │ │ │ ├── LineChart.module.scss
│ │ │ │ ├── LineChart.spec.ts
│ │ │ │ ├── LineChart.tsx
│ │ │ │ └── LineChartNative.tsx
│ │ │ ├── PieChart
│ │ │ │ ├── PieChart.md
│ │ │ │ ├── PieChart.spec.ts
│ │ │ │ ├── PieChart.tsx
│ │ │ │ ├── PieChartNative.module.scss
│ │ │ │ └── PieChartNative.tsx
│ │ │ ├── RadarChart
│ │ │ │ ├── RadarChart.md
│ │ │ │ ├── RadarChart.spec.ts
│ │ │ │ ├── RadarChart.tsx
│ │ │ │ └── RadarChartNative.tsx
│ │ │ ├── Tooltip
│ │ │ │ ├── TooltipContent.module.scss
│ │ │ │ ├── TooltipContent.spec.ts
│ │ │ │ └── TooltipContent.tsx
│ │ │ └── utils
│ │ │ ├── abstractions.ts
│ │ │ └── ChartProvider.tsx
│ │ ├── Checkbox
│ │ │ ├── Checkbox.md
│ │ │ ├── Checkbox.spec.ts
│ │ │ └── Checkbox.tsx
│ │ ├── CodeBlock
│ │ │ ├── CodeBlock.module.scss
│ │ │ ├── CodeBlock.spec.ts
│ │ │ ├── CodeBlock.tsx
│ │ │ ├── CodeBlockNative.tsx
│ │ │ └── highlight-code.ts
│ │ ├── collectedComponentMetadata.ts
│ │ ├── ColorPicker
│ │ │ ├── ColorPicker.md
│ │ │ ├── ColorPicker.module.scss
│ │ │ ├── ColorPicker.spec.ts
│ │ │ ├── ColorPicker.tsx
│ │ │ └── ColorPickerNative.tsx
│ │ ├── Column
│ │ │ ├── Column.md
│ │ │ ├── Column.tsx
│ │ │ ├── ColumnNative.tsx
│ │ │ ├── doc-resources
│ │ │ │ └── list-component-data.js
│ │ │ └── TableContext.tsx
│ │ ├── component-utils.ts
│ │ ├── ComponentProvider.tsx
│ │ ├── ComponentRegistryContext.tsx
│ │ ├── container-helpers.tsx
│ │ ├── ContentSeparator
│ │ │ ├── ContentSeparator.md
│ │ │ ├── ContentSeparator.module.scss
│ │ │ ├── ContentSeparator.spec.ts
│ │ │ ├── ContentSeparator.tsx
│ │ │ └── ContentSeparatorNative.tsx
│ │ ├── DataSource
│ │ │ ├── DataSource.md
│ │ │ └── DataSource.tsx
│ │ ├── DateInput
│ │ │ ├── DateInput.md
│ │ │ ├── DateInput.module.scss
│ │ │ ├── DateInput.spec.ts
│ │ │ ├── DateInput.tsx
│ │ │ └── DateInputNative.tsx
│ │ ├── DatePicker
│ │ │ ├── DatePicker.md
│ │ │ ├── DatePicker.module.scss
│ │ │ ├── DatePicker.spec.ts
│ │ │ ├── DatePicker.tsx
│ │ │ └── DatePickerNative.tsx
│ │ ├── DropdownMenu
│ │ │ ├── DropdownMenu.md
│ │ │ ├── DropdownMenu.module.scss
│ │ │ ├── DropdownMenu.spec.ts
│ │ │ ├── DropdownMenu.tsx
│ │ │ ├── DropdownMenuNative.tsx
│ │ │ ├── MenuItem.md
│ │ │ └── SubMenuItem.md
│ │ ├── EmojiSelector
│ │ │ ├── EmojiSelector.md
│ │ │ ├── EmojiSelector.spec.ts
│ │ │ ├── EmojiSelector.tsx
│ │ │ └── EmojiSelectorNative.tsx
│ │ ├── ExpandableItem
│ │ │ ├── ExpandableItem.module.scss
│ │ │ ├── ExpandableItem.spec.ts
│ │ │ ├── ExpandableItem.tsx
│ │ │ └── ExpandableItemNative.tsx
│ │ ├── FileInput
│ │ │ ├── FileInput.md
│ │ │ ├── FileInput.module.scss
│ │ │ ├── FileInput.spec.ts
│ │ │ ├── FileInput.tsx
│ │ │ └── FileInputNative.tsx
│ │ ├── FileUploadDropZone
│ │ │ ├── FileUploadDropZone.md
│ │ │ ├── FileUploadDropZone.module.scss
│ │ │ ├── FileUploadDropZone.spec.ts
│ │ │ ├── FileUploadDropZone.tsx
│ │ │ └── FileUploadDropZoneNative.tsx
│ │ ├── FlowLayout
│ │ │ ├── FlowLayout.md
│ │ │ ├── FlowLayout.module.scss
│ │ │ ├── FlowLayout.spec.ts
│ │ │ ├── FlowLayout.spec.ts-snapshots
│ │ │ │ └── Edge-cases-boxShadow-is-not-clipped-1-non-smoke-darwin.png
│ │ │ ├── FlowLayout.tsx
│ │ │ └── FlowLayoutNative.tsx
│ │ ├── Footer
│ │ │ ├── Footer.md
│ │ │ ├── Footer.module.scss
│ │ │ ├── Footer.spec.ts
│ │ │ ├── Footer.tsx
│ │ │ └── FooterNative.tsx
│ │ ├── Form
│ │ │ ├── Form.md
│ │ │ ├── Form.module.scss
│ │ │ ├── Form.spec.ts
│ │ │ ├── Form.tsx
│ │ │ ├── formActions.ts
│ │ │ ├── FormContext.ts
│ │ │ └── FormNative.tsx
│ │ ├── FormItem
│ │ │ ├── FormItem.md
│ │ │ ├── FormItem.module.scss
│ │ │ ├── FormItem.spec.ts
│ │ │ ├── FormItem.tsx
│ │ │ ├── FormItemNative.tsx
│ │ │ ├── HelperText.module.scss
│ │ │ ├── HelperText.tsx
│ │ │ ├── ItemWithLabel.tsx
│ │ │ └── Validations.ts
│ │ ├── FormSection
│ │ │ ├── FormSection.md
│ │ │ ├── FormSection.ts
│ │ │ └── FormSection.xmlui
│ │ ├── Fragment
│ │ │ ├── Fragment.spec.ts
│ │ │ └── Fragment.tsx
│ │ ├── Heading
│ │ │ ├── abstractions.ts
│ │ │ ├── H1.md
│ │ │ ├── H1.spec.ts
│ │ │ ├── H2.md
│ │ │ ├── H2.spec.ts
│ │ │ ├── H3.md
│ │ │ ├── H3.spec.ts
│ │ │ ├── H4.md
│ │ │ ├── H4.spec.ts
│ │ │ ├── H5.md
│ │ │ ├── H5.spec.ts
│ │ │ ├── H6.md
│ │ │ ├── H6.spec.ts
│ │ │ ├── Heading.md
│ │ │ ├── Heading.module.scss
│ │ │ ├── Heading.spec.ts
│ │ │ ├── Heading.tsx
│ │ │ └── HeadingNative.tsx
│ │ ├── HoverCard
│ │ │ ├── HoverCard.tsx
│ │ │ └── HovercardNative.tsx
│ │ ├── HtmlTags
│ │ │ ├── HtmlTags.module.scss
│ │ │ ├── HtmlTags.spec.ts
│ │ │ └── HtmlTags.tsx
│ │ ├── Icon
│ │ │ ├── AdmonitionDanger.tsx
│ │ │ ├── AdmonitionInfo.tsx
│ │ │ ├── AdmonitionNote.tsx
│ │ │ ├── AdmonitionTip.tsx
│ │ │ ├── AdmonitionWarning.tsx
│ │ │ ├── ApiIcon.tsx
│ │ │ ├── ArrowDropDown.module.scss
│ │ │ ├── ArrowDropDown.tsx
│ │ │ ├── ArrowDropUp.module.scss
│ │ │ ├── ArrowDropUp.tsx
│ │ │ ├── ArrowLeft.module.scss
│ │ │ ├── ArrowLeft.tsx
│ │ │ ├── ArrowRight.module.scss
│ │ │ ├── ArrowRight.tsx
│ │ │ ├── Attach.tsx
│ │ │ ├── Binding.module.scss
│ │ │ ├── Binding.tsx
│ │ │ ├── BoardIcon.tsx
│ │ │ ├── BoxIcon.tsx
│ │ │ ├── CheckIcon.tsx
│ │ │ ├── ChevronDownIcon.tsx
│ │ │ ├── ChevronLeft.tsx
│ │ │ ├── ChevronRight.tsx
│ │ │ ├── ChevronUpIcon.tsx
│ │ │ ├── CodeFileIcon.tsx
│ │ │ ├── CodeSandbox.tsx
│ │ │ ├── CompactListIcon.tsx
│ │ │ ├── ContentCopyIcon.tsx
│ │ │ ├── DarkToLightIcon.tsx
│ │ │ ├── DatabaseIcon.module.scss
│ │ │ ├── DatabaseIcon.tsx
│ │ │ ├── DocFileIcon.tsx
│ │ │ ├── DocIcon.tsx
│ │ │ ├── DotMenuHorizontalIcon.tsx
│ │ │ ├── DotMenuIcon.tsx
│ │ │ ├── EmailIcon.tsx
│ │ │ ├── EmptyFolderIcon.tsx
│ │ │ ├── ErrorIcon.tsx
│ │ │ ├── ExpressionIcon.tsx
│ │ │ ├── FillPlusCricleIcon.tsx
│ │ │ ├── FilterIcon.tsx
│ │ │ ├── FolderIcon.tsx
│ │ │ ├── GlobeIcon.tsx
│ │ │ ├── HomeIcon.tsx
│ │ │ ├── HyperLinkIcon.tsx
│ │ │ ├── Icon.md
│ │ │ ├── Icon.module.scss
│ │ │ ├── Icon.spec.ts
│ │ │ ├── Icon.tsx
│ │ │ ├── IconNative.tsx
│ │ │ ├── ImageFileIcon.tsx
│ │ │ ├── Inspect.tsx
│ │ │ ├── LightToDark.tsx
│ │ │ ├── LinkIcon.tsx
│ │ │ ├── ListIcon.tsx
│ │ │ ├── LooseListIcon.tsx
│ │ │ ├── MoonIcon.tsx
│ │ │ ├── MoreOptionsIcon.tsx
│ │ │ ├── NoSortIcon.tsx
│ │ │ ├── PDFIcon.tsx
│ │ │ ├── PenIcon.tsx
│ │ │ ├── PhoneIcon.tsx
│ │ │ ├── PhotoIcon.tsx
│ │ │ ├── PlusIcon.tsx
│ │ │ ├── SearchIcon.tsx
│ │ │ ├── ShareIcon.tsx
│ │ │ ├── SortAscendingIcon.tsx
│ │ │ ├── SortDescendingIcon.tsx
│ │ │ ├── StarsIcon.tsx
│ │ │ ├── SunIcon.tsx
│ │ │ ├── svg
│ │ │ │ ├── admonition_danger.svg
│ │ │ │ ├── admonition_info.svg
│ │ │ │ ├── admonition_note.svg
│ │ │ │ ├── admonition_tip.svg
│ │ │ │ ├── admonition_warning.svg
│ │ │ │ ├── api.svg
│ │ │ │ ├── arrow-dropdown.svg
│ │ │ │ ├── arrow-left.svg
│ │ │ │ ├── arrow-right.svg
│ │ │ │ ├── arrow-up.svg
│ │ │ │ ├── attach.svg
│ │ │ │ ├── binding.svg
│ │ │ │ ├── box.svg
│ │ │ │ ├── bulb.svg
│ │ │ │ ├── code-file.svg
│ │ │ │ ├── code-sandbox.svg
│ │ │ │ ├── dark_to_light.svg
│ │ │ │ ├── database.svg
│ │ │ │ ├── doc.svg
│ │ │ │ ├── empty-folder.svg
│ │ │ │ ├── expression.svg
│ │ │ │ ├── eye-closed.svg
│ │ │ │ ├── eye-dark.svg
│ │ │ │ ├── eye.svg
│ │ │ │ ├── file-text.svg
│ │ │ │ ├── filter.svg
│ │ │ │ ├── folder.svg
│ │ │ │ ├── img.svg
│ │ │ │ ├── inspect.svg
│ │ │ │ ├── light_to_dark.svg
│ │ │ │ ├── moon.svg
│ │ │ │ ├── pdf.svg
│ │ │ │ ├── photo.svg
│ │ │ │ ├── share.svg
│ │ │ │ ├── stars.svg
│ │ │ │ ├── sun.svg
│ │ │ │ ├── trending-down.svg
│ │ │ │ ├── trending-level.svg
│ │ │ │ ├── trending-up.svg
│ │ │ │ ├── txt.svg
│ │ │ │ ├── unknown-file.svg
│ │ │ │ ├── unlink.svg
│ │ │ │ └── xls.svg
│ │ │ ├── TableDeleteColumnIcon.tsx
│ │ │ ├── TableDeleteRowIcon.tsx
│ │ │ ├── TableInsertColumnIcon.tsx
│ │ │ ├── TableInsertRowIcon.tsx
│ │ │ ├── TrashIcon.tsx
│ │ │ ├── TrendingDownIcon.tsx
│ │ │ ├── TrendingLevelIcon.tsx
│ │ │ ├── TrendingUpIcon.tsx
│ │ │ ├── TxtIcon.tsx
│ │ │ ├── UnknownFileIcon.tsx
│ │ │ ├── UnlinkIcon.tsx
│ │ │ ├── UserIcon.tsx
│ │ │ ├── WarningIcon.tsx
│ │ │ └── XlsIcon.tsx
│ │ ├── IconProvider.tsx
│ │ ├── IconRegistryContext.tsx
│ │ ├── IFrame
│ │ │ ├── IFrame.md
│ │ │ ├── IFrame.module.scss
│ │ │ ├── IFrame.spec.ts
│ │ │ ├── IFrame.tsx
│ │ │ └── IFrameNative.tsx
│ │ ├── Image
│ │ │ ├── Image.md
│ │ │ ├── Image.module.scss
│ │ │ ├── Image.spec.ts
│ │ │ ├── Image.tsx
│ │ │ └── ImageNative.tsx
│ │ ├── Input
│ │ │ ├── index.ts
│ │ │ ├── InputAdornment.module.scss
│ │ │ ├── InputAdornment.tsx
│ │ │ ├── InputDivider.module.scss
│ │ │ ├── InputDivider.tsx
│ │ │ ├── InputLabel.module.scss
│ │ │ ├── InputLabel.tsx
│ │ │ ├── PartialInput.module.scss
│ │ │ └── PartialInput.tsx
│ │ ├── InspectButton
│ │ │ ├── InspectButton.module.scss
│ │ │ └── InspectButton.tsx
│ │ ├── Items
│ │ │ ├── Items.md
│ │ │ ├── Items.spec.ts
│ │ │ ├── Items.tsx
│ │ │ └── ItemsNative.tsx
│ │ ├── Link
│ │ │ ├── Link.md
│ │ │ ├── Link.module.scss
│ │ │ ├── Link.spec.ts
│ │ │ ├── Link.tsx
│ │ │ └── LinkNative.tsx
│ │ ├── List
│ │ │ ├── doc-resources
│ │ │ │ └── list-component-data.js
│ │ │ ├── List.md
│ │ │ ├── List.module.scss
│ │ │ ├── List.spec.ts
│ │ │ ├── List.tsx
│ │ │ └── ListNative.tsx
│ │ ├── Logo
│ │ │ ├── doc-resources
│ │ │ │ └── xmlui-logo.svg
│ │ │ ├── Logo.md
│ │ │ ├── Logo.tsx
│ │ │ └── LogoNative.tsx
│ │ ├── Markdown
│ │ │ ├── CodeText.module.scss
│ │ │ ├── CodeText.tsx
│ │ │ ├── Markdown.md
│ │ │ ├── Markdown.module.scss
│ │ │ ├── Markdown.spec.ts
│ │ │ ├── Markdown.tsx
│ │ │ ├── MarkdownNative.tsx
│ │ │ ├── parse-binding-expr.ts
│ │ │ └── utils.ts
│ │ ├── metadata-helpers.ts
│ │ ├── ModalDialog
│ │ │ ├── ConfirmationModalContextProvider.tsx
│ │ │ ├── Dialog.module.scss
│ │ │ ├── Dialog.tsx
│ │ │ ├── ModalDialog.md
│ │ │ ├── ModalDialog.module.scss
│ │ │ ├── ModalDialog.spec.ts
│ │ │ ├── ModalDialog.tsx
│ │ │ ├── ModalDialogNative.tsx
│ │ │ └── ModalVisibilityContext.tsx
│ │ ├── NavGroup
│ │ │ ├── NavGroup.md
│ │ │ ├── NavGroup.module.scss
│ │ │ ├── NavGroup.spec.ts
│ │ │ ├── NavGroup.tsx
│ │ │ ├── NavGroupContext.ts
│ │ │ └── NavGroupNative.tsx
│ │ ├── NavLink
│ │ │ ├── NavLink.md
│ │ │ ├── NavLink.module.scss
│ │ │ ├── NavLink.spec.ts
│ │ │ ├── NavLink.tsx
│ │ │ └── NavLinkNative.tsx
│ │ ├── NavPanel
│ │ │ ├── NavPanel.md
│ │ │ ├── NavPanel.module.scss
│ │ │ ├── NavPanel.spec.ts
│ │ │ ├── NavPanel.tsx
│ │ │ └── NavPanelNative.tsx
│ │ ├── NestedApp
│ │ │ ├── AppWithCodeView.module.scss
│ │ │ ├── AppWithCodeView.tsx
│ │ │ ├── AppWithCodeViewNative.tsx
│ │ │ ├── defaultProps.tsx
│ │ │ ├── logo.svg
│ │ │ ├── NestedApp.module.scss
│ │ │ ├── NestedApp.tsx
│ │ │ ├── NestedAppNative.tsx
│ │ │ ├── Tooltip.module.scss
│ │ │ ├── Tooltip.tsx
│ │ │ └── utils.ts
│ │ ├── NoResult
│ │ │ ├── NoResult.md
│ │ │ ├── NoResult.module.scss
│ │ │ ├── NoResult.spec.ts
│ │ │ ├── NoResult.tsx
│ │ │ └── NoResultNative.tsx
│ │ ├── NumberBox
│ │ │ ├── numberbox-abstractions.ts
│ │ │ ├── NumberBox.md
│ │ │ ├── NumberBox.module.scss
│ │ │ ├── NumberBox.spec.ts
│ │ │ ├── NumberBox.tsx
│ │ │ └── NumberBoxNative.tsx
│ │ ├── Option
│ │ │ ├── Option.md
│ │ │ ├── Option.spec.ts
│ │ │ ├── Option.tsx
│ │ │ ├── OptionNative.tsx
│ │ │ └── OptionTypeProvider.tsx
│ │ ├── PageMetaTitle
│ │ │ ├── PageMetaTilteNative.tsx
│ │ │ ├── PageMetaTitle.md
│ │ │ ├── PageMetaTitle.spec.ts
│ │ │ └── PageMetaTitle.tsx
│ │ ├── Pages
│ │ │ ├── Page.md
│ │ │ ├── Pages.md
│ │ │ ├── Pages.module.scss
│ │ │ ├── Pages.tsx
│ │ │ └── PagesNative.tsx
│ │ ├── Pagination
│ │ │ ├── Pagination.md
│ │ │ ├── Pagination.module.scss
│ │ │ ├── Pagination.spec.ts
│ │ │ ├── Pagination.tsx
│ │ │ └── PaginationNative.tsx
│ │ ├── PositionedContainer
│ │ │ ├── PositionedContainer.module.scss
│ │ │ ├── PositionedContainer.tsx
│ │ │ └── PositionedContainerNative.tsx
│ │ ├── ProfileMenu
│ │ │ ├── ProfileMenu.module.scss
│ │ │ └── ProfileMenu.tsx
│ │ ├── ProgressBar
│ │ │ ├── ProgressBar.md
│ │ │ ├── ProgressBar.module.scss
│ │ │ ├── ProgressBar.spec.ts
│ │ │ ├── ProgressBar.tsx
│ │ │ └── ProgressBarNative.tsx
│ │ ├── Queue
│ │ │ ├── Queue.md
│ │ │ ├── Queue.spec.ts
│ │ │ ├── Queue.tsx
│ │ │ ├── queueActions.ts
│ │ │ └── QueueNative.tsx
│ │ ├── RadioGroup
│ │ │ ├── RadioGroup.md
│ │ │ ├── RadioGroup.module.scss
│ │ │ ├── RadioGroup.spec.ts
│ │ │ ├── RadioGroup.tsx
│ │ │ ├── RadioGroupNative.tsx
│ │ │ ├── RadioItem.tsx
│ │ │ └── RadioItemNative.tsx
│ │ ├── RealTimeAdapter
│ │ │ ├── RealTimeAdapter.tsx
│ │ │ └── RealTimeAdapterNative.tsx
│ │ ├── Redirect
│ │ │ ├── Redirect.md
│ │ │ ├── Redirect.spec.ts
│ │ │ └── Redirect.tsx
│ │ ├── ResponsiveBar
│ │ │ ├── README.md
│ │ │ ├── ResponsiveBar.md
│ │ │ ├── ResponsiveBar.module.scss
│ │ │ ├── ResponsiveBar.spec.ts
│ │ │ ├── ResponsiveBar.tsx
│ │ │ └── ResponsiveBarNative.tsx
│ │ ├── Select
│ │ │ ├── HiddenOption.tsx
│ │ │ ├── OptionContext.ts
│ │ │ ├── Select.md
│ │ │ ├── Select.module.scss
│ │ │ ├── Select.spec.ts
│ │ │ ├── Select.tsx
│ │ │ ├── SelectContext.tsx
│ │ │ └── SelectNative.tsx
│ │ ├── SelectionStore
│ │ │ ├── SelectionStore.md
│ │ │ ├── SelectionStore.tsx
│ │ │ └── SelectionStoreNative.tsx
│ │ ├── Slider
│ │ │ ├── Slider.md
│ │ │ ├── Slider.module.scss
│ │ │ ├── Slider.spec.ts
│ │ │ ├── Slider.tsx
│ │ │ └── SliderNative.tsx
│ │ ├── Slot
│ │ │ ├── Slot.md
│ │ │ ├── Slot.spec.ts
│ │ │ └── Slot.ts
│ │ ├── SlotItem.tsx
│ │ ├── SpaceFiller
│ │ │ ├── SpaceFiller.md
│ │ │ ├── SpaceFiller.module.scss
│ │ │ ├── SpaceFiller.spec.ts
│ │ │ ├── SpaceFiller.tsx
│ │ │ └── SpaceFillerNative.tsx
│ │ ├── Spinner
│ │ │ ├── Spinner.md
│ │ │ ├── Spinner.module.scss
│ │ │ ├── Spinner.spec.ts
│ │ │ ├── Spinner.tsx
│ │ │ └── SpinnerNative.tsx
│ │ ├── Splitter
│ │ │ ├── HSplitter.md
│ │ │ ├── HSplitter.spec.ts
│ │ │ ├── Splitter.md
│ │ │ ├── Splitter.module.scss
│ │ │ ├── Splitter.spec.ts
│ │ │ ├── Splitter.tsx
│ │ │ ├── SplitterNative.tsx
│ │ │ ├── utils.ts
│ │ │ ├── VSplitter.md
│ │ │ └── VSplitter.spec.ts
│ │ ├── Stack
│ │ │ ├── CHStack.md
│ │ │ ├── CHStack.spec.ts
│ │ │ ├── CVStack.md
│ │ │ ├── CVStack.spec.ts
│ │ │ ├── HStack.md
│ │ │ ├── HStack.spec.ts
│ │ │ ├── Stack.md
│ │ │ ├── Stack.module.scss
│ │ │ ├── Stack.spec.ts
│ │ │ ├── Stack.tsx
│ │ │ ├── StackNative.tsx
│ │ │ ├── VStack.md
│ │ │ └── VStack.spec.ts
│ │ ├── StickyBox
│ │ │ ├── StickyBox.md
│ │ │ ├── StickyBox.module.scss
│ │ │ ├── StickyBox.tsx
│ │ │ └── StickyBoxNative.tsx
│ │ ├── Switch
│ │ │ ├── Switch.md
│ │ │ ├── Switch.spec.ts
│ │ │ └── Switch.tsx
│ │ ├── Table
│ │ │ ├── doc-resources
│ │ │ │ └── list-component-data.js
│ │ │ ├── react-table-config.d.ts
│ │ │ ├── Table.md
│ │ │ ├── Table.module.scss
│ │ │ ├── Table.spec.ts
│ │ │ ├── Table.tsx
│ │ │ ├── TableNative.tsx
│ │ │ └── useRowSelection.tsx
│ │ ├── TableOfContents
│ │ │ ├── TableOfContents.module.scss
│ │ │ ├── TableOfContents.spec.ts
│ │ │ ├── TableOfContents.tsx
│ │ │ └── TableOfContentsNative.tsx
│ │ ├── Tabs
│ │ │ ├── TabContext.tsx
│ │ │ ├── TabItem.md
│ │ │ ├── TabItem.tsx
│ │ │ ├── TabItemNative.tsx
│ │ │ ├── Tabs.md
│ │ │ ├── Tabs.module.scss
│ │ │ ├── Tabs.spec.ts
│ │ │ ├── Tabs.tsx
│ │ │ └── TabsNative.tsx
│ │ ├── Text
│ │ │ ├── Text.md
│ │ │ ├── Text.module.scss
│ │ │ ├── Text.spec.ts
│ │ │ ├── Text.tsx
│ │ │ └── TextNative.tsx
│ │ ├── TextArea
│ │ │ ├── TextArea.md
│ │ │ ├── TextArea.module.scss
│ │ │ ├── TextArea.spec.ts
│ │ │ ├── TextArea.tsx
│ │ │ ├── TextAreaNative.tsx
│ │ │ ├── TextAreaResizable.tsx
│ │ │ └── useComposedRef.ts
│ │ ├── TextBox
│ │ │ ├── TextBox.md
│ │ │ ├── TextBox.module.scss
│ │ │ ├── TextBox.spec.ts
│ │ │ ├── TextBox.tsx
│ │ │ └── TextBoxNative.tsx
│ │ ├── Theme
│ │ │ ├── NotificationToast.tsx
│ │ │ ├── Theme.md
│ │ │ ├── Theme.module.scss
│ │ │ ├── Theme.spec.ts
│ │ │ ├── Theme.tsx
│ │ │ └── ThemeNative.tsx
│ │ ├── TimeInput
│ │ │ ├── TimeInput.md
│ │ │ ├── TimeInput.module.scss
│ │ │ ├── TimeInput.spec.ts
│ │ │ ├── TimeInput.tsx
│ │ │ ├── TimeInputNative.tsx
│ │ │ └── utils.ts
│ │ ├── Timer
│ │ │ ├── Timer.md
│ │ │ ├── Timer.spec.ts
│ │ │ ├── Timer.tsx
│ │ │ └── TimerNative.tsx
│ │ ├── Toggle
│ │ │ ├── Toggle.module.scss
│ │ │ └── Toggle.tsx
│ │ ├── ToneChangerButton
│ │ │ ├── ToneChangerButton.md
│ │ │ ├── ToneChangerButton.spec.ts
│ │ │ └── ToneChangerButton.tsx
│ │ ├── ToneSwitch
│ │ │ ├── ToneSwitch.md
│ │ │ ├── ToneSwitch.module.scss
│ │ │ ├── ToneSwitch.spec.ts
│ │ │ ├── ToneSwitch.tsx
│ │ │ └── ToneSwitchNative.tsx
│ │ ├── Tooltip
│ │ │ ├── Tooltip.md
│ │ │ ├── Tooltip.module.scss
│ │ │ ├── Tooltip.spec.ts
│ │ │ ├── Tooltip.tsx
│ │ │ └── TooltipNative.tsx
│ │ ├── Tree
│ │ │ ├── testData.ts
│ │ │ ├── Tree-dynamic.spec.ts
│ │ │ ├── Tree-icons.spec.ts
│ │ │ ├── Tree.md
│ │ │ ├── Tree.spec.ts
│ │ │ ├── TreeComponent.module.scss
│ │ │ ├── TreeComponent.tsx
│ │ │ └── TreeNative.tsx
│ │ ├── TreeDisplay
│ │ │ ├── TreeDisplay.md
│ │ │ ├── TreeDisplay.module.scss
│ │ │ ├── TreeDisplay.tsx
│ │ │ └── TreeDisplayNative.tsx
│ │ ├── ValidationSummary
│ │ │ ├── ValidationSummary.module.scss
│ │ │ └── ValidationSummary.tsx
│ │ └── VisuallyHidden.tsx
│ ├── components-core
│ │ ├── abstractions
│ │ │ ├── ComponentRenderer.ts
│ │ │ ├── LoaderRenderer.ts
│ │ │ ├── standalone.ts
│ │ │ └── treeAbstractions.ts
│ │ ├── action
│ │ │ ├── actions.ts
│ │ │ ├── APICall.tsx
│ │ │ ├── FileDownloadAction.tsx
│ │ │ ├── FileUploadAction.tsx
│ │ │ ├── NavigateAction.tsx
│ │ │ └── TimedAction.tsx
│ │ ├── ApiBoundComponent.tsx
│ │ ├── appContext
│ │ │ ├── date-functions.ts
│ │ │ ├── math-function.ts
│ │ │ └── misc-utils.ts
│ │ ├── AppContext.tsx
│ │ ├── behaviors
│ │ │ ├── Behavior.tsx
│ │ │ └── CoreBehaviors.tsx
│ │ ├── component-hooks.ts
│ │ ├── ComponentDecorator.tsx
│ │ ├── ComponentViewer.tsx
│ │ ├── CompoundComponent.tsx
│ │ ├── constants.ts
│ │ ├── DebugViewProvider.tsx
│ │ ├── descriptorHelper.ts
│ │ ├── devtools
│ │ │ ├── InspectorDialog.module.scss
│ │ │ ├── InspectorDialog.tsx
│ │ │ └── InspectorDialogVisibilityContext.tsx
│ │ ├── EngineError.ts
│ │ ├── event-handlers.ts
│ │ ├── InspectorButton.module.scss
│ │ ├── InspectorContext.tsx
│ │ ├── interception
│ │ │ ├── abstractions.ts
│ │ │ ├── ApiInterceptor.ts
│ │ │ ├── ApiInterceptorProvider.tsx
│ │ │ ├── apiInterceptorWorker.ts
│ │ │ ├── Backend.ts
│ │ │ ├── Errors.ts
│ │ │ ├── IndexedDb.ts
│ │ │ ├── initMock.ts
│ │ │ ├── InMemoryDb.ts
│ │ │ ├── ReadonlyCollection.ts
│ │ │ └── useApiInterceptorContext.tsx
│ │ ├── loader
│ │ │ ├── ApiLoader.tsx
│ │ │ ├── DataLoader.tsx
│ │ │ ├── ExternalDataLoader.tsx
│ │ │ ├── Loader.tsx
│ │ │ ├── MockLoaderRenderer.tsx
│ │ │ └── PageableLoader.tsx
│ │ ├── LoaderComponent.tsx
│ │ ├── markup-check.ts
│ │ ├── parts.ts
│ │ ├── renderers.ts
│ │ ├── rendering
│ │ │ ├── AppContent.tsx
│ │ │ ├── AppRoot.tsx
│ │ │ ├── AppWrapper.tsx
│ │ │ ├── buildProxy.ts
│ │ │ ├── collectFnVarDeps.ts
│ │ │ ├── ComponentAdapter.tsx
│ │ │ ├── ComponentWrapper.tsx
│ │ │ ├── Container.tsx
│ │ │ ├── containers.ts
│ │ │ ├── ContainerWrapper.tsx
│ │ │ ├── ErrorBoundary.module.scss
│ │ │ ├── ErrorBoundary.tsx
│ │ │ ├── InvalidComponent.module.scss
│ │ │ ├── InvalidComponent.tsx
│ │ │ ├── nodeUtils.ts
│ │ │ ├── reducer.ts
│ │ │ ├── renderChild.tsx
│ │ │ ├── StandaloneComponent.tsx
│ │ │ ├── StateContainer.tsx
│ │ │ ├── UnknownComponent.module.scss
│ │ │ ├── UnknownComponent.tsx
│ │ │ └── valueExtractor.ts
│ │ ├── reportEngineError.ts
│ │ ├── RestApiProxy.ts
│ │ ├── script-runner
│ │ │ ├── asyncProxy.ts
│ │ │ ├── AttributeValueParser.ts
│ │ │ ├── bannedFunctions.ts
│ │ │ ├── BindingTreeEvaluationContext.ts
│ │ │ ├── eval-tree-async.ts
│ │ │ ├── eval-tree-common.ts
│ │ │ ├── eval-tree-sync.ts
│ │ │ ├── ParameterParser.ts
│ │ │ ├── process-statement-async.ts
│ │ │ ├── process-statement-common.ts
│ │ │ ├── process-statement-sync.ts
│ │ │ ├── ScriptingSourceTree.ts
│ │ │ ├── simplify-expression.ts
│ │ │ ├── statement-queue.ts
│ │ │ └── visitors.ts
│ │ ├── StandaloneApp.tsx
│ │ ├── StandaloneExtensionManager.ts
│ │ ├── TableOfContentsContext.tsx
│ │ ├── theming
│ │ │ ├── _themes.scss
│ │ │ ├── component-layout-resolver.ts
│ │ │ ├── extendThemeUtils.ts
│ │ │ ├── hvar.ts
│ │ │ ├── layout-resolver.ts
│ │ │ ├── parse-layout-props.ts
│ │ │ ├── StyleContext.tsx
│ │ │ ├── StyleRegistry.ts
│ │ │ ├── ThemeContext.tsx
│ │ │ ├── ThemeProvider.tsx
│ │ │ ├── themes
│ │ │ │ ├── base-utils.ts
│ │ │ │ ├── palette.ts
│ │ │ │ ├── root.ts
│ │ │ │ ├── solid.ts
│ │ │ │ ├── theme-colors.ts
│ │ │ │ └── xmlui.ts
│ │ │ ├── themeVars.module.scss
│ │ │ ├── themeVars.ts
│ │ │ ├── transformThemeVars.ts
│ │ │ └── utils.ts
│ │ ├── utils
│ │ │ ├── actionUtils.ts
│ │ │ ├── audio-utils.ts
│ │ │ ├── base64-utils.ts
│ │ │ ├── compound-utils.ts
│ │ │ ├── css-utils.ts
│ │ │ ├── DataLoaderQueryKeyGenerator.ts
│ │ │ ├── date-utils.ts
│ │ │ ├── extractParam.ts
│ │ │ ├── hooks.tsx
│ │ │ ├── LruCache.ts
│ │ │ ├── mergeProps.ts
│ │ │ ├── misc.ts
│ │ │ ├── request-params.ts
│ │ │ ├── statementUtils.ts
│ │ │ └── treeUtils.ts
│ │ └── xmlui-parser.ts
│ ├── index-standalone.ts
│ ├── index.scss
│ ├── index.ts
│ ├── language-server
│ │ ├── server-common.ts
│ │ ├── server-web-worker.ts
│ │ ├── server.ts
│ │ ├── services
│ │ │ ├── common
│ │ │ │ ├── docs-generation.ts
│ │ │ │ ├── lsp-utils.ts
│ │ │ │ ├── metadata-utils.ts
│ │ │ │ └── syntax-node-utilities.ts
│ │ │ ├── completion.ts
│ │ │ ├── diagnostic.ts
│ │ │ ├── format.ts
│ │ │ └── hover.ts
│ │ └── xmlui-metadata-generated.js
│ ├── logging
│ │ ├── LoggerContext.tsx
│ │ ├── LoggerInitializer.tsx
│ │ ├── LoggerService.ts
│ │ └── xmlui.ts
│ ├── logo.svg
│ ├── parsers
│ │ ├── common
│ │ │ ├── GenericToken.ts
│ │ │ ├── InputStream.ts
│ │ │ └── utils.ts
│ │ ├── scripting
│ │ │ ├── code-behind-collect.ts
│ │ │ ├── Lexer.ts
│ │ │ ├── modules.ts
│ │ │ ├── Parser.ts
│ │ │ ├── ParserError.ts
│ │ │ ├── ScriptingNodeTypes.ts
│ │ │ ├── TokenTrait.ts
│ │ │ ├── TokenType.ts
│ │ │ └── tree-visitor.ts
│ │ ├── style-parser
│ │ │ ├── errors.ts
│ │ │ ├── source-tree.ts
│ │ │ ├── StyleInputStream.ts
│ │ │ ├── StyleLexer.ts
│ │ │ ├── StyleParser.ts
│ │ │ └── tokens.ts
│ │ └── xmlui-parser
│ │ ├── CharacterCodes.ts
│ │ ├── diagnostics.ts
│ │ ├── fileExtensions.ts
│ │ ├── index.ts
│ │ ├── lint.ts
│ │ ├── parser.ts
│ │ ├── ParserError.ts
│ │ ├── scanner.ts
│ │ ├── syntax-kind.ts
│ │ ├── syntax-node.ts
│ │ ├── transform.ts
│ │ ├── utils.ts
│ │ ├── xmlui-serializer.ts
│ │ └── xmlui-tree.ts
│ ├── react-app-env.d.ts
│ ├── syntax
│ │ ├── monaco
│ │ │ ├── grammar.monacoLanguage.ts
│ │ │ ├── index.ts
│ │ │ ├── xmlui-dark.ts
│ │ │ ├── xmlui-light.ts
│ │ │ └── xmluiscript.monacoLanguage.ts
│ │ └── textMate
│ │ ├── index.ts
│ │ ├── xmlui-dark.json
│ │ ├── xmlui-light.json
│ │ ├── xmlui.json
│ │ └── xmlui.tmLanguage.json
│ ├── testing
│ │ ├── assertions.ts
│ │ ├── component-test-helpers.ts
│ │ ├── ComponentDrivers.ts
│ │ ├── drivers
│ │ │ ├── DateInputDriver.ts
│ │ │ ├── index.ts
│ │ │ ├── ModalDialogDriver.ts
│ │ │ ├── NumberBoxDriver.ts
│ │ │ ├── TextBoxDriver.ts
│ │ │ ├── TimeInputDriver.ts
│ │ │ ├── TimerDriver.ts
│ │ │ └── TreeDriver.ts
│ │ ├── fixtures.ts
│ │ ├── index.ts
│ │ ├── infrastructure
│ │ │ ├── index.html
│ │ │ ├── main.tsx
│ │ │ ├── public
│ │ │ │ ├── mockServiceWorker.js
│ │ │ │ ├── resources
│ │ │ │ │ ├── bell.svg
│ │ │ │ │ ├── box.svg
│ │ │ │ │ ├── doc.svg
│ │ │ │ │ ├── eye.svg
│ │ │ │ │ ├── flower-640x480.jpg
│ │ │ │ │ ├── sun.svg
│ │ │ │ │ ├── test-image-100x100.jpg
│ │ │ │ │ └── txt.svg
│ │ │ │ └── serve.json
│ │ │ └── TestBed.tsx
│ │ └── themed-app-test-helpers.ts
│ └── vite-env.d.ts
├── tests
│ ├── components
│ │ ├── CodeBlock
│ │ │ └── hightlight-code.test.ts
│ │ ├── playground-pattern.test.ts
│ │ └── Tree
│ │ └── Tree-states.test.ts
│ ├── components-core
│ │ ├── abstractions
│ │ │ └── treeAbstractions.test.ts
│ │ ├── container
│ │ │ └── buildProxy.test.ts
│ │ ├── interception
│ │ │ ├── orderBy.test.ts
│ │ │ ├── ReadOnlyCollection.test.ts
│ │ │ └── request-param-converter.test.ts
│ │ ├── scripts-runner
│ │ │ ├── AttributeValueParser.test.ts
│ │ │ ├── eval-tree-arrow-async.test.ts
│ │ │ ├── eval-tree-arrow.test.ts
│ │ │ ├── eval-tree-func-decl-async.test.ts
│ │ │ ├── eval-tree-func-decl.test.ts
│ │ │ ├── eval-tree-pre-post.test.ts
│ │ │ ├── eval-tree-regression.test.ts
│ │ │ ├── eval-tree.test.ts
│ │ │ ├── function-proxy.test.ts
│ │ │ ├── parser-regression.test.ts
│ │ │ ├── process-event.test.ts
│ │ │ ├── process-function.test.ts
│ │ │ ├── process-implicit-context.test.ts
│ │ │ ├── process-statement-asgn.test.ts
│ │ │ ├── process-statement-destruct.test.ts
│ │ │ ├── process-statement-regs.test.ts
│ │ │ ├── process-statement-sync.test.ts
│ │ │ ├── process-statement.test.ts
│ │ │ ├── process-switch-sync.test.ts
│ │ │ ├── process-switch.test.ts
│ │ │ ├── process-try-sync.test.ts
│ │ │ ├── process-try.test.ts
│ │ │ └── test-helpers.ts
│ │ ├── test-metadata-handler.ts
│ │ ├── theming
│ │ │ ├── border-segments.test.ts
│ │ │ ├── component-layout.resolver.test.ts
│ │ │ ├── layout-property-parser.test.ts
│ │ │ ├── layout-resolver.test.ts
│ │ │ ├── layout-resolver2.test.ts
│ │ │ ├── layout-vp-override.test.ts
│ │ │ └── padding-segments.test.ts
│ │ └── utils
│ │ ├── date-utils.test.ts
│ │ ├── format-human-elapsed-time.test.ts
│ │ └── LruCache.test.ts
│ ├── language-server
│ │ ├── completion.test.ts
│ │ ├── format.test.ts
│ │ ├── hover.test.ts
│ │ └── mockData.ts
│ └── parsers
│ ├── common
│ │ └── input-stream.test.ts
│ ├── markdown
│ │ └── parse-binding-expression.test.ts
│ ├── parameter-parser.test.ts
│ ├── paremeter-parser.test.ts
│ ├── scripting
│ │ ├── eval-tree-arrow.test.ts
│ │ ├── eval-tree-pre-post.test.ts
│ │ ├── eval-tree.test.ts
│ │ ├── function-proxy.test.ts
│ │ ├── lexer-literals.test.ts
│ │ ├── lexer-misc.test.ts
│ │ ├── module-parse.test.ts
│ │ ├── parser-arrow.test.ts
│ │ ├── parser-assignments.test.ts
│ │ ├── parser-binary.test.ts
│ │ ├── parser-destructuring.test.ts
│ │ ├── parser-errors.test.ts
│ │ ├── parser-expressions.test.ts
│ │ ├── parser-function.test.ts
│ │ ├── parser-literals.test.ts
│ │ ├── parser-primary.test.ts
│ │ ├── parser-regex.test.ts
│ │ ├── parser-statements.test.ts
│ │ ├── parser-unary.test.ts
│ │ ├── process-event.test.ts
│ │ ├── process-implicit-context.test.ts
│ │ ├── process-statement-asgn.test.ts
│ │ ├── process-statement-destruct.test.ts
│ │ ├── process-statement-regs.test.ts
│ │ ├── process-statement-sync.test.ts
│ │ ├── process-statement.test.ts
│ │ ├── process-switch-sync.test.ts
│ │ ├── process-switch.test.ts
│ │ ├── process-try-sync.test.ts
│ │ ├── process-try.test.ts
│ │ ├── simplify-expression.test.ts
│ │ ├── statement-hooks.test.ts
│ │ └── test-helpers.ts
│ ├── style-parser
│ │ ├── generateHvarChain.test.ts
│ │ ├── parseHVar.test.ts
│ │ ├── parser.test.ts
│ │ └── tokens.test.ts
│ └── xmlui
│ ├── lint.test.ts
│ ├── parser.test.ts
│ ├── scanner.test.ts
│ ├── transform.attr.test.ts
│ ├── transform.circular.test.ts
│ ├── transform.element.test.ts
│ ├── transform.errors.test.ts
│ ├── transform.escape.test.ts
│ ├── transform.regression.test.ts
│ ├── transform.script.test.ts
│ ├── transform.test.ts
│ └── xmlui.ts
├── tests-e2e
│ ├── api-bound-component-regression.spec.ts
│ ├── api-call-as-extracted-component.spec.ts
│ ├── assign-to-object-or-array-regression.spec.ts
│ ├── binding-regression.spec.ts
│ ├── children-as-template-context-vars.spec.ts
│ ├── compound-component.spec.ts
│ ├── context-vars-regression.spec.ts
│ ├── data-bindings.spec.ts
│ ├── datasource-and-api-usage-in-var.spec.ts
│ ├── datasource-direct-binding.spec.ts
│ ├── datasource-onLoaded-regression.spec.ts
│ ├── modify-array-item-regression.spec.ts
│ ├── namespaces.spec.ts
│ ├── push-to-array-regression.spec.ts
│ ├── screen-breakpoints.spec.ts
│ ├── scripting.spec.ts
│ ├── state-scope-in-pages.spec.ts
│ └── state-var-scopes.spec.ts
├── tsconfig.bin.json
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── vitest.config.ts
```
# Files
--------------------------------------------------------------------------------
/docs/public/resources/llms.txt:
--------------------------------------------------------------------------------
```
1 | # XMLUI Framework
2 |
3 | XMLUI is a declarative framework for building user interfaces with XML markup and flexible theming. XMLUI enables developers to create sophisticated web applications with little or no knowledge of JavaScript, CSS, or React.
4 |
5 | ## Core Philosophy
6 |
7 | XMLUI apps are:
8 | - **Easy to create** - Build on the web platform with minimal programming knowledge
9 | - **Beautiful by default** - Enjoy themes that look great out of the box and are easy to modify
10 | - **Connected** - Read and write APIs with little or no scripting
11 | - **Modular** - Use a comprehensive suite of 90+ components that you can extend
12 | - **Easy to deploy** - Just drop a handful of files onto a static webserver
13 |
14 | ### Key Features
15 | - **Reactive data binding** with automatic UI updates (like spreadsheets)
16 | - **90+ built-in components** covering all application needs
17 | - **Virtualized performance** for large datasets (List, Table components)
18 | - **Template properties** for extensive component customization (25+ templates)
19 | - **Helper tags** (`<variable>`, `<property>`, `<event>`) for clean markup organization
20 | - **Comprehensive theming** system with 7 built-in theme variants
21 | - **Real-time data sources** and seamless API integration
22 | - **Built-in routing** and navigation management
23 | - **No CSS required** for most styling needs
24 |
25 | ### Basic Syntax
26 | ```xml
27 | <App>
28 | <variable name="count" value="{0}" />
29 | <Button onClick="count++" label="Count: {count}" />
30 | <Text>{count}</Text>
31 | </App>
32 | ```
33 |
34 | ## Application Structure
35 |
36 | ### File Structure
37 | ```
38 | app/
39 | ├── index.html # Entry point with XMLUI script reference
40 | ├── Main.xmlui # Root App component
41 | ├── config.json # App configuration (optional)
42 | ├── components/ # User-defined components
43 | │ ├── Dashboard.xmlui
44 | │ └── UserCard.xmlui
45 | ├── resources/ # Static assets (images, icons)
46 | ├── themes/ # Custom theme definitions
47 | └── xmlui/ # XMLUI framework files
48 | └── 0.9.23.js
49 | ```
50 |
51 | ### Main.xmlui Structure
52 | ```xml
53 | <App name="My Application" layout="vertical-sticky">
54 | <AppHeader>
55 | <property name="logoTemplate">
56 | <Heading level="h3" value="My App" />
57 | </property>
58 | </AppHeader>
59 |
60 | <NavPanel>
61 | <NavLink label="Home" to="/" icon="home" />
62 | <NavGroup label="Management">
63 | <NavLink label="Users" to="/users" />
64 | <NavLink label="Settings" to="/settings" />
65 | </NavGroup>
66 | </NavPanel>
67 |
68 | <Pages fallbackPath="/">
69 | <Page url="/">
70 | <Dashboard />
71 | </Page>
72 | <Page url="/users">
73 | <UserList />
74 | </Page>
75 | </Pages>
76 |
77 | <Footer>© 2024 My Company</Footer>
78 | </App>
79 | ```
80 |
81 | ## Component Categories
82 |
83 | ### Application Structure (7 components)
84 | - **App** - Root container with 7 layout templates:
85 | - `horizontal` / `horizontal-sticky` - Stacked header, nav, content, footer
86 | - `vertical` / `vertical-sticky` / `vertical-full-header` - Left sidebar navigation
87 | - `condensed` / `condensed-sticky` - Combined header/nav bar (default)
88 | - **AppHeader** - Top navigation with logo, title, profile areas
89 | - **NavPanel** - Navigation container supporting hierarchical menus
90 | - **Pages/Page** - Declarative routing with URL patterns and `$routeParams`
91 | - **Footer** - Application footer area
92 | - **Theme** - Styling contexts without CSS
93 | - **PageMetaTitle** - Dynamic browser tab titles
94 |
95 | ### Layout Components (15+ components)
96 | **Primary Containers:**
97 | - **Stack/VStack/HStack** - Fundamental layout with orientation, alignment, gaps
98 | - **CHStack/CVStack** - Centered horizontal/vertical stacks
99 | - **FlowLayout** - Horizontal layout with automatic wrapping and responsive sizing
100 | - **Grid** - Grid-based layouts
101 | - **Splitter/HSplitter/VSplitter** - Resizable divided containers
102 |
103 | **Content Organization:**
104 | - **Card** - Content boundaries with padding, borders, shadows
105 | - **Backdrop** - Semi-transparent overlays with optional content
106 | - **ContentSeparator** - Visual dividers (horizontal/vertical lines)
107 | - **StickyBox** - Fixed positioning (top/bottom)
108 | - **Breakout** - Full-width sections ignoring parent constraints
109 | - **SpaceFiller** - Flexible space allocation and line breaks
110 |
111 | ### Form Components (15+ components)
112 | **Form Structure:**
113 | - **Form** - Data binding, validation, submission with `$data` context
114 | - **FormItem** - Field wrapper with validation, labeling, `$value` context
115 | - **FormSection** - Field grouping with FlowLayout
116 |
117 | **Input Controls:**
118 | - **TextBox/TextArea/PasswordInput** - Text input with validation support
119 | - **NumberBox** - Numeric input with spinners and formatting
120 | - **DatePicker** - Calendar-based date selection
121 | - **FileInput/FileUploadDropZone** - File selection and drag-drop upload
122 |
123 | **Selection Controls:**
124 | - **Select/AutoComplete** - Dropdown selection with search and custom templates
125 | - **RadioGroup** - Mutually exclusive selection
126 | - **Checkbox/Switch** - Boolean controls
127 | - **Slider** - Numeric range selection with single/dual thumbs
128 |
129 | **Specialized:**
130 | - **ColorPicker** - RGB/HSL/HEX color selection
131 | - **EmojiSelector** - System emoji browser
132 | - **Option** - Data structure for selection components
133 |
134 | ### Data Display (12+ components)
135 | **High-Performance Lists:**
136 | - **List** - Virtualized, groupable, sortable lists for thousands of items
137 | - Context: `$item`, `$itemIndex`, `$isFirst`, `$isLast`, `$group`
138 | - Features: grouping, sorting, pagination, empty state handling
139 | - **Items** - Lightweight iteration without virtualization
140 | - **Table** - Structured data with Column components and sorting
141 |
142 | **Typography:**
143 | - **Text** - Styled text with variants (abbr, cite, code, deleted, inserted, keyboard)
144 | - **Heading/H1-H6** - Semantic headings with anchor generation
145 | - **Link** - Navigation with internal/external URL support
146 | - **Markdown** - Rich text formatting with markdown syntax
147 |
148 | **Media & Status:**
149 | - **Image** - Responsive images with aspect ratio control
150 | - **Icon** - Scalable vector icons from built-in registry
151 | - **Avatar** - Circular profile images with fallback initials
152 | - **Logo** - Application branding with light/dark variants
153 | - **Badge** - Status indicators and tags with color mapping
154 | - **ProgressBar** - Task completion visualization
155 | - **Spinner** - Indeterminate loading states
156 | - **NoResult** - Empty state displays
157 |
158 | **Content Organization:**
159 | - **Tabs/TabItem** - Switchable content panels
160 | - **ExpandableItem** - Collapsible sections (like HTML details)
161 | - **TableOfContents** - Auto-generated navigation from headings
162 |
163 | ### Interactive Components (8+ components)
164 | **Menus:**
165 | - **DropdownMenu** - Space-efficient action menus with trigger templates
166 | - **MenuItem/SubMenuItem** - Menu items with icons, actions, nested submenus
167 | - **MenuSeparator** - Visual menu grouping
168 |
169 | **Dialogs:**
170 | - **ModalDialog** - Overlay dialogs with parameters and programmatic control
171 |
172 | **Navigation:**
173 | - **NavLink** - Smart navigation with active state detection
174 | - **NavGroup** - Collapsible hierarchical menu containers
175 |
176 | **Utilities:**
177 | - **Bookmark** - Scroll targets for navigation
178 | - **ToneChangerButton** - Light/dark mode toggle
179 |
180 | ### Data Management (6+ components)
181 | **API Integration:**
182 | - **DataSource** - Automatic data fetching with reactive URL binding
183 | - **APICall** - Manual CRUD operations with success/error handling
184 | - **RealTimeAdapter** - WebSocket/SSE integration
185 |
186 | **State Management:**
187 | - **AppState** - Global state persistence across navigation
188 | - **ChangeListener** - Reactive value monitoring and side effects
189 |
190 | **Background Processing:**
191 | - **Queue** - FIFO task processing with UI progress feedback
192 |
193 | ### Chart Components (5 components)
194 | - **BarChart** - Horizontal/vertical bars, grouped/stacked layouts
195 | - **LineChart** - Connected points for trends and time series data
196 | - **PieChart/DonutChart** - Proportional circular visualizations
197 | - **Legend** - Standalone chart legends with custom positioning
198 |
199 | ### Utility Components (5+ components)
200 | - **Fragment** - Conditional rendering and component grouping
201 | - **Redirect** - Internal navigation redirects with conditions
202 | - **Column** - Table column definitions with sorting and custom content
203 | - **LabelList** - Custom chart labeling
204 |
205 | ### Extension Packages
206 | **XMLUI Animations (Experimental):**
207 | - **FadeAnimation/FadeInAnimation/FadeOutAnimation** - Opacity transitions
208 | - **ScaleAnimation** - Size transformations
209 | - **SlideInAnimation** - Directional entry animations
210 |
211 | ## XML Markup Fundamentals
212 |
213 | ### Properties
214 | Properties can be literal strings or JavaScript expressions in curly braces:
215 | ```xml
216 | <!-- Literal -->
217 | <Text value="Hello World" />
218 |
219 | <!-- Expression -->
220 | <Text value="Result: {6 * 7}" />
221 |
222 | <!-- JSON Array -->
223 | <Items data="{['Apple', 'Banana', 'Cherry']}">
224 | <Text>{$item}</Text>
225 | </Items>
226 |
227 | <!-- JSON Object -->
228 | <Form data='{{ name: "John", age: 30 }}'>
229 | <FormItem bindTo="name" />
230 | <FormItem bindTo="age" />
231 | </Form>
232 | ```
233 |
234 | ### Variables
235 | Components can declare reactive variables using two syntaxes:
236 | ```xml
237 | <!-- Attribute syntax -->
238 | <App var.count="{0}" var.message="Hello">
239 | <Text>{message}: {count}</Text>
240 | </App>
241 |
242 | <!-- Helper tag syntax -->
243 | <App>
244 | <variable name="count" value="{0}" />
245 | <variable name="message" value="Hello" />
246 | <Text>{message}: {count}</Text>
247 | </App>
248 | ```
249 |
250 | ### Reactive Variables
251 | Variables automatically update dependent expressions:
252 | ```xml
253 | <App var.count="{0}" var.doubleCount="{count * 2}">
254 | <Button onClick="count++" label="Increment" />
255 | <Text>Count: {count}</Text>
256 | <Text>Double: {doubleCount}</Text> <!-- Updates automatically -->
257 | </App>
258 | ```
259 |
260 | ### Event Handlers
261 | Events can be declared as attributes or using helper tags:
262 | ```xml
263 | <!-- Attribute syntax -->
264 | <Button onClick="count++" label="Click me" />
265 |
266 | <!-- Helper tag syntax (required for component handlers) -->
267 | <Button label="Save">
268 | <event name="click">
269 | <APICall url="/api/save" method="POST" body="{formData}" />
270 | </event>
271 | </Button>
272 | ```
273 |
274 | ## Helper Tags
275 |
276 | ### `<variable>` - State Management
277 | Alternative to `var.` attribute syntax:
278 | ```xml
279 | <variable name="user" value='{{ name: "John", role: "admin" }}' />
280 | <variable name="isLoading" value="{false}" />
281 | <variable name="items" value="{[]}" />
282 | ```
283 |
284 | ### `<property>` - Template Content
285 | For template properties containing markup:
286 | ```xml
287 | <List data="{users}">
288 | <property name="itemTemplate">
289 | <Card>
290 | <HStack gap="$space-2">
291 | <Avatar src="{$item.avatar}" />
292 | <VStack>
293 | <Text variant="strong">{$item.name}</Text>
294 | <Text color="muted">{$item.email}</Text>
295 | </VStack>
296 | </HStack>
297 | </Card>
298 | </property>
299 |
300 | <property name="emptyListTemplate">
301 | <VStack horizontalAlignment="center" padding="$space-8">
302 | <Icon name="user-x" size="xl" color="muted" />
303 | <Text color="muted">No users found</Text>
304 | </VStack>
305 | </property>
306 | </List>
307 | ```
308 |
309 | ### `<event>` - Action Handlers
310 | For complex event handling with components:
311 | ```xml
312 | <Button label="Process Data">
313 | <event name="click">
314 | <APICall
315 | url="/api/process"
316 | method="POST"
317 | body="{selectedItems}"
318 | onSuccess="toast('Processing complete!'); data.refresh()"
319 | onError="toast('Failed to process', 'error')" />
320 | </event>
321 | </Button>
322 | ```
323 |
324 | ## Template Properties System
325 |
326 | 25+ template properties for extensive customization:
327 |
328 | ### Application Templates (5)
329 | ```xml
330 | <App>
331 | <property name="logoTemplate">
332 | <HStack gap="$space-1">
333 | <Icon name="star" color="primary" />
334 | <Heading level="h3" value="My App" />
335 | </HStack>
336 | </property>
337 | </App>
338 |
339 | <AppHeader>
340 | <property name="profileMenuTemplate">
341 | <DropdownMenu>
342 | <MenuItem label="Profile" icon="user" />
343 | <MenuItem label="Settings" icon="settings" />
344 | <MenuSeparator />
345 | <MenuItem label="Logout" icon="logout" />
346 | </DropdownMenu>
347 | </property>
348 | </AppHeader>
349 | ```
350 |
351 | ### Form Templates (3)
352 | ```xml
353 | <Form>
354 | <property name="buttonRowTemplate">
355 | <HStack gap="$space-2" horizontalAlignment="end">
356 | <Button type="button" label="Cancel" variant="outlined" />
357 | <Button type="submit" label="Save" variant="solid" />
358 | </HStack>
359 | </property>
360 | </Form>
361 |
362 | <FormItem field="category">
363 | <property name="inputTemplate">
364 | <Select>
365 | <Option value="work" label="Work" />
366 | <Option value="personal" label="Personal" />
367 | </Select>
368 | </property>
369 | </FormItem>
370 | ```
371 |
372 | ### Data Display Templates (8)
373 | ```xml
374 | <List data="{products}" groupBy="category">
375 | <property name="groupHeaderTemplate">
376 | <HStack justifyContent="space-between" padding="$space-2">
377 | <Text variant="subtitle">{$group.key}</Text>
378 | <Badge value="{$group.items.length}" />
379 | </HStack>
380 | </property>
381 |
382 | <property name="itemTemplate">
383 | <Card>
384 | <Text variant="strong">{$item.name}</Text>
385 | <Text>${$item.price}</Text>
386 | </Card>
387 | </property>
388 |
389 | <property name="emptyListTemplate">
390 | <Text color="muted">No products available</Text>
391 | </property>
392 | </List>
393 | ```
394 |
395 | ## Context Variables
396 |
397 | Special variables automatically provided by XMLUI within specific scopes:
398 |
399 | ### Form Context
400 | - **`$data`** - Complete form data object (inside `<Form>`)
401 | - **`$value`** - Current field value (inside `<FormItem>`)
402 | - **`$validationResult`** - Field validation status
403 | - **`$setValue`** - Function to programmatically set field values
404 |
405 | ```xml
406 | <Form data='{{ name: "", email: "" }}'>
407 | <FormItem bindTo="name">
408 | <Text>Current value: {$value}</Text>
409 | <TextBox placeholder="Enter name" />
410 | </FormItem>
411 |
412 | <Text>Form data: {JSON.stringify($data)}</Text>
413 | </Form>
414 | ```
415 |
416 | ### Data Iteration Context
417 | - **`$item`** - Current item in data iterations
418 | - **`$itemIndex`** - Zero-based index of current item
419 | - **`$isFirst/$isLast`** - Boolean position indicators
420 |
421 | ```xml
422 | <Items data="{products}">
423 | <HStack gap="$space-2">
424 | <Badge value="{$itemIndex + 1}" />
425 | <Text>{$item.name}</Text>
426 | {$isFirst && <Badge value="First" />}
427 | {$isLast && <Badge value="Last" />}
428 | </HStack>
429 | </Items>
430 | ```
431 |
432 | ### Grouping Context (List with groupBy)
433 | - **`$group`** - Group information object
434 | - `$group.key` - Group identifier
435 | - `$group.items` - Items in this group
436 | - `$group.id` - Unique group ID
437 |
438 | ```xml
439 | <List data="{orders}" groupBy="status">
440 | <property name="groupHeaderTemplate">
441 | <HStack justifyContent="space-between">
442 | <Text variant="strong">{$group.key} Orders</Text>
443 | <Badge value="{$group.items.length}" />
444 | </HStack>
445 | </property>
446 | </List>
447 | ```
448 |
449 | ### Navigation Context
450 | - **`$routeParams`** - URL parameters from route patterns
451 |
452 | ```xml
453 | <Pages>
454 | <Page url="/user/:userId">
455 | <Text>Viewing user: {$routeParams.userId}</Text>
456 | </Page>
457 | </Pages>
458 | ```
459 |
460 | ### Component Context
461 | - **`$props`** - Properties passed to user-defined components
462 | - **`var.myVar`** - Scoped variables declared in markup
463 | - **`componentId`** - Reference to components with `id` attributes
464 |
465 | ## Reactive Data Binding
466 |
467 | XMLUI's reactive system automatically updates UI when data changes:
468 |
469 | ### Basic Reactivity
470 | ```xml
471 | <App>
472 | <!-- User selection drives other components -->
473 | <Select id="category" initialValue="electronics">
474 | <Option value="electronics" label="Electronics" />
475 | <Option value="clothing" label="Clothing" />
476 | </Select>
477 |
478 | <!-- DataSource reacts to selection changes -->
479 | <DataSource
480 | id="products"
481 | url="/api/products?category={category.value}"
482 | resultSelector="data" />
483 |
484 | <!-- Multiple components use the same data -->
485 | <Text>Found {products.value?.length || 0} products</Text>
486 | <List data="{products.value}">
487 | <property name="itemTemplate">
488 | <Card title="{$item.name}" subtitle="${$item.price}" />
489 | </property>
490 | </List>
491 | </App>
492 | ```
493 |
494 | ### Advanced Data Flow with Forms
495 | ```xml
496 | <App>
497 | <!-- Form drives API calls -->
498 | <Form id="searchForm" data='{{ query: "", minPrice: 0 }}'>
499 | <FormItem bindTo="query" label="Search">
500 | <TextBox placeholder="Product name..." />
501 | </FormItem>
502 | <FormItem bindTo="minPrice" label="Min Price">
503 | <NumberBox />
504 | </FormItem>
505 | </Form>
506 |
507 | <!-- DataSource reacts to form changes -->
508 | <DataSource
509 | id="results"
510 | url="/api/search?q={searchForm.data.query}&minPrice={searchForm.data.minPrice}"
511 | resultSelector="products" />
512 |
513 | <!-- UI updates automatically -->
514 | <List data="{results.value}" loading="{results.loading}">
515 | <property name="itemTemplate">
516 | <Card title="{$item.name}" subtitle="${$item.price}" />
517 | </property>
518 | <property name="emptyListTemplate">
519 | <Text>No products match your criteria</Text>
520 | </property>
521 | </List>
522 | </App>
523 | ```
524 |
525 | ## Layout System
526 |
527 | ### Fundamental Containers
528 |
529 | **Stack Variants:**
530 | - **VStack** - Vertical layout (each child on new row)
531 | - **HStack** - Horizontal layout (children in same row)
532 | - **CHStack/CVStack** - Centered horizontal/vertical stacks
533 | - **Stack** - Configurable orientation with `orientation` property
534 |
535 | **Flow Layout:**
536 | - **FlowLayout** - Horizontal with wrapping, percentage-aware sizing
537 |
538 | ### Layout Properties
539 | - **Alignment**: `horizontalAlignment`, `verticalAlignment` (start, center, end)
540 | - **Spacing**: `gap`, `padding` (use theme variables like `$space-2`, `$gap-loose`)
541 | - **Sizing**: `width`, `height`, `minWidth`, `maxWidth` etc.
542 |
543 | ### Dimension Units
544 | - **No value** - Container determines size based on content
545 | - **Fixed units** - px, rem, em (container respects exact size)
546 | - **Percentage** - % of parent container (50%, 100%)
547 | - **Star sizing** - * weights for distributing remaining space (*, 2*, 3*)
548 |
549 | ### Layout Examples
550 | ```xml
551 | <!-- Responsive card grid -->
552 | <FlowLayout>
553 | <Card width="300px">Content 1</Card>
554 | <Card width="300px">Content 2</Card>
555 | <Card width="300px">Content 3</Card>
556 | </FlowLayout>
557 |
558 | <!-- Dashboard layout with star sizing -->
559 | <HStack height="100vh">
560 | <!-- Sidebar takes fixed width -->
561 | <VStack width="250px" backgroundColor="$color-surface">
562 | <Navigation />
563 | </VStack>
564 |
565 | <!-- Main content takes remaining space -->
566 | <VStack width="*" padding="$space-4">
567 | <!-- Header takes content height -->
568 | <Header />
569 |
570 | <!-- Content area takes remaining height -->
571 | <VStack height="*">
572 | <MainContent />
573 | </VStack>
574 | </VStack>
575 | </HStack>
576 |
577 | <!-- Centered dialog -->
578 | <CVStack height="100vh" width="100vw">
579 | <Card width="400px" padding="$space-6">
580 | <ModalContent />
581 | </Card>
582 | </CVStack>
583 | ```
584 |
585 | ## Theming System
586 |
587 | ### Built-in Themes
588 | 7 theme variants available:
589 | - **xmlui** (default blue)
590 | - **xmlui-green**
591 | - **xmlui-gray**
592 | - **xmlui-orange**
593 | - **xmlui-purple**
594 | - **xmlui-cyan**
595 | - **xmlui-red**
596 |
597 | Each theme supports light and dark tones.
598 |
599 | ### Theme Usage
600 | ```xml
601 | <!-- Global theme -->
602 | <Theme themeId="xmlui-green" tone="dark">
603 | <App>...</App>
604 | </Theme>
605 |
606 | <!-- Scoped theme overrides -->
607 | <Theme
608 | backgroundColor-Button="red"
609 | borderRadius-Button="8px"
610 | color-text-Button="white">
611 | <Button label="Danger Action" />
612 | </Theme>
613 | ```
614 |
615 | ### Theme Variables
616 | **Colors:**
617 | ```css
618 | --color-primary, --color-secondary, --color-accent
619 | --color-background, --color-surface, --color-overlay
620 | --color-text, --color-muted, --color-inverse
621 | --color-success, --color-warn, --color-danger, --color-info
622 | ```
623 |
624 | **Spacing:**
625 | ```css
626 | --space-xs, --space-sm, --space-normal, --space-lg, --space-xl
627 | --space-2, --space-4, --space-8, --space-16, --space-32, --space-64
628 | --gap-tight, --gap-normal, --gap-loose
629 | ```
630 |
631 | **Typography:**
632 | ```css
633 | --font-size-xs, --font-size-sm, --font-size-normal, --font-size-lg
634 | --font-weight-normal, --font-weight-medium, --font-weight-bold
635 | --line-height-normal, --line-height-relaxed
636 | ```
637 |
638 | ## User-Defined Components
639 |
640 | ### Component Definition
641 | ```xml
642 | <!-- components/UserCard.xmlui -->
643 | <Component name="UserCard">
644 | <Card>
645 | <HStack gap="$space-2">
646 | <Avatar src="{$props.user.avatar}" name="{$props.user.name}" />
647 | <VStack>
648 | <Text variant="strong">{$props.user.name}</Text>
649 | <Text color="muted">{$props.user.email}</Text>
650 | <Text>{$props.user.role ?? 'User'}</Text>
651 | </VStack>
652 | </HStack>
653 | </Card>
654 | </Component>
655 | ```
656 |
657 | ### Component Usage
658 | ```xml
659 | <App>
660 | <UserCard user='{{ name: "John Doe", email: "[email protected]", role: "Admin" }}' />
661 | </App>
662 | ```
663 |
664 | ### Component with Methods and Events
665 | ```xml
666 | <Component
667 | name="Counter"
668 | var.count="{$props.initialValue ?? 0}"
669 | method.reset="() => count = 0"
670 | method.setValue="(value) => count = value">
671 |
672 | <HStack gap="$space-2">
673 | <Button onClick="count--" label="-" />
674 | <Text>{count}</Text>
675 | <Button onClick="count++" label="+" />
676 | <Button onClick="emitEvent('valueChanged', count)" label="Notify" />
677 | </HStack>
678 | </Component>
679 |
680 | <!-- Usage -->
681 | <Counter
682 | id="myCounter"
683 | initialValue="{10}"
684 | onValueChanged="(value) => toast('Count changed to: ' + value)" />
685 | <Button onClick="myCounter.reset()" label="Reset Counter" />
686 | ```
687 |
688 | ### Slots for Content Injection
689 | ```xml
690 | <Component name="Dialog">
691 | <Card padding="$space-6">
692 | <VStack gap="$space-4">
693 | <!-- Named slot with context -->
694 | <Slot name="headerTemplate" title="{$props.title}">
695 | <Heading level="h2">{$props.title}</Heading>
696 | </Slot>
697 |
698 | <!-- Default slot for main content -->
699 | <Slot>
700 | <Text>Default content when no children provided</Text>
701 | </Slot>
702 |
703 | <!-- Named slot for actions -->
704 | <Slot name="actionsTemplate">
705 | <Button label="OK" />
706 | </Slot>
707 | </VStack>
708 | </Card>
709 | </Component>
710 |
711 | <!-- Usage -->
712 | <Dialog title="Confirm Action">
713 | <property name="headerTemplate">
714 | <HStack gap="$space-2">
715 | <Icon name="alert-triangle" color="warn" />
716 | <Text variant="strong">{$title}</Text>
717 | </HStack>
718 | </property>
719 |
720 | <Text>Are you sure you want to delete this item?</Text>
721 |
722 | <property name="actionsTemplate">
723 | <HStack gap="$space-2">
724 | <Button label="Cancel" variant="outlined" />
725 | <Button label="Delete" variant="solid" themeColor="danger" />
726 | </HStack>
727 | </property>
728 | </Dialog>
729 | ```
730 |
731 | ## Performance Features
732 |
733 | ### Virtualization
734 | - **List** - Automatically virtualizes large datasets (thousands of items)
735 | - **Table** - Virtual scrolling for massive data tables
736 | - Zero configuration required
737 |
738 | ### Efficient Updates
739 | - Smart reactivity only updates dependent components
740 | - Batched DOM updates
741 | - Minimal re-rendering
742 |
743 | ### Loading States
744 | ```xml
745 | <DataSource id="users" url="/api/users" />
746 | <List data="{users.value}" loading="{users.loading}">
747 | <property name="itemTemplate">
748 | <UserCard user="{$item}" />
749 | </property>
750 | <property name="emptyListTemplate">
751 | <VStack horizontalAlignment="center" padding="$space-8">
752 | <Spinner />
753 | <Text>Loading users...</Text>
754 | </VStack>
755 | </property>
756 | </List>
757 | ```
758 |
759 | ## Deployment
760 |
761 | ### Static Hosting
762 | XMLUI apps are static files that can be deployed anywhere:
763 | - **Development**: `python -m http.server` or `npx http-server`
764 | - **Production**: Any static host (Netlify, AWS S3, GitHub Pages)
765 |
766 | ### Minimal Deployment
767 | ```
768 | app/
769 | ├── index.html
770 | ├── Main.xmlui
771 | └── xmlui/
772 | └── 0.9.23.js
773 | ```
774 |
775 | The framework automatically loads components from the `components/` folder and handles routing without server configuration.
776 |
777 | ## Best Practices
778 |
779 | ### Application Architecture
780 | 1. **Start with App component** defining layout and navigation structure
781 | 2. **Use Pages for routing** with meaningful URL patterns
782 | 3. **Organize components** in logical folders by feature
783 | 4. **Leverage template properties** instead of custom CSS for customization
784 |
785 | ### Data Management
786 | 1. **Use DataSource for reads**, APICall for writes
787 | 2. **Implement loading states** and error handling
788 | 3. **Utilize reactive binding** for automatic UI updates
789 | 4. **Structure forms** with proper validation and field binding
790 |
791 | ### Performance
792 | 1. **Choose List over Items** for large datasets (1000+ items)
793 | 2. **Use virtualization** features for tables and lists
794 | 3. **Implement pagination** for very large datasets
795 | 4. **Optimize data fetching** with proper caching
796 |
797 | ### Code Organization
798 | 1. **Break down complex UIs** into reusable components
799 | 2. **Use meaningful component and variable names**
800 | 3. **Organize navigation** hierarchically with NavGroup
801 | 4. **Handle empty states** and error conditions gracefully
802 |
803 | XMLUI enables rapid development of professional web applications through declarative markup, comprehensive theming, and automatic reactive updates. The framework handles modern web complexity while maintaining simplicity for developers of all skill levels.
804 |
```
--------------------------------------------------------------------------------
/xmlui/src/testing/fixtures.ts:
--------------------------------------------------------------------------------
```typescript
1 | /* eslint react-hooks/rules-of-hooks: 0 */
2 | // The above exception is needed since it fires a false-positive
3 | // for the "use" function coming from the playwright test framework
4 | import { test as baseTest } from "@playwright/test";
5 | import type { Locator, Page } from "playwright-core";
6 |
7 | import type { ComponentDef, CompoundComponentDef } from "../abstractions/ComponentDefs";
8 | import { xmlUiMarkupToComponent } from "../components-core/xmlui-parser";
9 | import type { StandaloneAppDescription } from "../components-core/abstractions/standalone";
10 | import {
11 | type ComponentDriverParams,
12 | type ComponentDriver,
13 | AccordionDriver,
14 | AppFooterDriver,
15 | AppHeaderDriver,
16 | AvatarDriver,
17 | BadgeDriver,
18 | ButtonDriver,
19 | CardDriver,
20 | ContentSeparatorDriver,
21 | FormDriver,
22 | FormItemDriver,
23 | HeadingDriver,
24 | HStackDriver,
25 | HtmlTagDriver,
26 | IconDriver,
27 | ItemsDriver,
28 | LinkDriver,
29 | ListDriver,
30 | MarkdownDriver,
31 | NavGroupDriver,
32 | NavLinkDriver,
33 | NavPanelDriver,
34 | NoResultDriver,
35 | OptionDriver,
36 | ProgressBarDriver,
37 | RadioGroupDriver,
38 | RangeDriver,
39 | SelectDriver,
40 | SplitterDriver,
41 | StackDriver,
42 | TestStateDriver,
43 | TextAreaDriver,
44 | TextDriver,
45 | ValidationDisplayDriver,
46 | ValidationSummaryDriver,
47 | VStackDriver,
48 | DatePickerDriver,
49 | AutoCompleteDriver,
50 | CodeBlockDriver,
51 | CheckboxDriver,
52 | DropdownMenuDriver,
53 | ExpandableItemDriver,
54 | FileInputDriver,
55 | FileUploadDropZoneDriver,
56 | LabelDriver,
57 | BackdropDriver,
58 | SpinnerDriver,
59 | SliderDriver,
60 | } from "./ComponentDrivers";
61 | import { parseComponentIfNecessary } from "./component-test-helpers";
62 | import { TimeInputDriver } from "./drivers/TimeInputDriver";
63 | import { TimerDriver } from "./drivers/TimerDriver";
64 | import { DateInputDriver } from "./drivers/DateInputDriver";
65 | import { ModalDialogDriver } from "./drivers/ModalDialogDriver";
66 | import { TextBoxDriver } from "./drivers/TextBoxDriver";
67 | import { NumberBoxDriver } from "./drivers/NumberBoxDriver";
68 | import { TreeDriver } from "./drivers/TreeDriver";
69 |
70 | export { expect } from "./assertions";
71 |
72 | const isCI = process?.env?.CI === "true";
73 |
74 | // -----------------------------------------------------------------
75 | // --- Utility
76 |
77 | /**
78 | * Writes an error in the console to indicate if multiple elements have the same testId
79 | */
80 | async function getOnlyFirstLocator(page: Page, testId: string) {
81 | const locators = page.getByTestId(testId);
82 | if ((await locators.count()) > 1) {
83 | // console.error(
84 | // `More than one element found with testId: ${testId}! Ignoring all but the first.`,
85 | // );
86 | return locators.first();
87 | }
88 | return locators;
89 | }
90 |
91 | class Clipboard {
92 | private page: Page;
93 | private content: string = "";
94 |
95 | constructor(page: Page) {
96 | this.page = page;
97 | }
98 |
99 | init() {
100 | return () => {
101 | window.navigator.clipboard.readText = () => Promise.resolve(this.content);
102 | window.navigator.clipboard.read = () => {
103 | throw new Error("Clipboard read not implemented in mocked environment");
104 | };
105 | window.navigator.clipboard.writeText = (text) => {
106 | this.content = text;
107 | return Promise.resolve(undefined);
108 | };
109 | window.navigator.clipboard.write = (items) => {
110 | throw new Error("Clipboard write not implemented in mocked environment");
111 | };
112 | };
113 | }
114 |
115 | /**
116 | * Reads the text from the clipboard.
117 | *
118 | * @returns The text from the clipboard.
119 | */
120 | async read() {
121 | const handle = await this.page.evaluateHandle(() => navigator.clipboard.readText());
122 | return handle.jsonValue();
123 | }
124 |
125 | /**
126 | * Writes the text to the clipboard.
127 | *
128 | * @param text - The text to write to the clipboard.
129 | */
130 | async write(text: string) {
131 | await this.page.evaluate((text) => navigator.clipboard.writeText(text), text);
132 | }
133 |
134 | async clear() {
135 | await this.page.evaluate(() => navigator.clipboard.writeText(""));
136 | }
137 |
138 | /**
139 | * Copies the text from the given locator to the clipboard.
140 | *
141 | * Steps:
142 | * 1. Focus the locator.
143 | * 2. Select the text.
144 | * 3. Copy the text to the clipboard. (ControlOrMeta+C)
145 | *
146 | * @param locator - a Locator to focus and copy from
147 | */
148 | async copy(locator: Locator) {
149 | await locator.focus();
150 | await locator.selectText();
151 | await this.page.keyboard.press("ControlOrMeta+C");
152 | }
153 |
154 | /**
155 | * Pastes the text from the clipboard to the given locator.
156 | *
157 | * Steps:
158 | * 1. Focus the locator.
159 | * 2. Paste the text from the clipboard. (ControlOrMeta+V)
160 | *
161 | * @param locator - a Locator to focus and paste to
162 | */
163 | async paste(locator: Locator) {
164 | await locator.focus();
165 | await this.page.keyboard.press("ControlOrMeta+V");
166 | }
167 | }
168 |
169 | function mapThemeRelatedVars(description: TestBedDescription): TestBedDescription {
170 | const { themes, defaultTheme, testThemeVars, ...rest } = description ?? {};
171 |
172 | if (themes) {
173 | return { themes, defaultTheme: defaultTheme ?? "xmlui", ...rest };
174 | }
175 |
176 | const testTheme = {
177 | id: "test",
178 | name: "Test",
179 | extends: "xmlui",
180 | themeVars: testThemeVars,
181 | };
182 |
183 | return { themes: [testTheme], defaultTheme: "test", ...rest };
184 | }
185 |
186 | // -----------------------------------------------------------------
187 | // --- TestBed and Driver Fixtures
188 |
189 | export type TestBedDescription = Omit<
190 | Partial<StandaloneAppDescription>,
191 | "entryPoint" | "components"
192 | > & {
193 | testThemeVars?: Record<string, string>;
194 | components?: string[];
195 | };
196 |
197 | export const test = baseTest.extend<TestDriverExtenderProps>({
198 | // NOTE: the base Playwright test can be extended with fixture methods
199 | // as well as any other language constructs we deem useful
200 | baseComponentTestId: "test-id-component",
201 | testStateViewTestId: "test-state-view-testid",
202 |
203 | initTestBed: async ({ page, baseComponentTestId, testStateViewTestId }, use) => {
204 | await use(async (source: string, description?: TestBedDescription) => {
205 | // Default test icon resources
206 | const defaultTestResources = {
207 | "icon.box": "/resources/box.svg",
208 | "icon.doc": "/resources/doc.svg",
209 | "icon.sun": "/resources/sun.svg",
210 | "icon.eye": "/resources/eye.svg",
211 | "icon.txt": "/resources/txt.svg",
212 | "icon.bell": "/resources/bell.svg",
213 | };
214 | // --- Initialize XMLUI App
215 | const { errors, component } = xmlUiMarkupToComponent(`
216 | <Fragment var.testState="{null}">
217 | ${source}
218 | <Stack width="0" height="0">
219 | <Text
220 | testId="${testStateViewTestId}"
221 | value="{ typeof testState === 'undefined' ? 'undefined' : JSON.stringify(testState) }"/>
222 | </Stack>
223 | </Fragment>
224 | `);
225 |
226 | if (errors.length > 0) {
227 | throw { errors };
228 | }
229 | const entryPoint = component as ComponentDef;
230 |
231 | const components = description?.components?.map((c) => {
232 | const { component, errors, erroneousCompoundComponentName } = parseComponentIfNecessary(c);
233 | if (erroneousCompoundComponentName) {
234 | throw new Error(
235 | `Error parsing component "${erroneousCompoundComponentName}": ${errors.join("\n")}`,
236 | );
237 | }
238 | return component as CompoundComponentDef;
239 | });
240 |
241 | if (source !== "" && entryPoint.children) {
242 | const sourceBaseComponent = entryPoint.children[0];
243 | const isCompoundComponentRoot =
244 | components &&
245 | components?.length > 0 &&
246 | components?.map((c) => c.name).includes(sourceBaseComponent.type);
247 |
248 | if (!isCompoundComponentRoot && !sourceBaseComponent.testId) {
249 | sourceBaseComponent.testId = baseComponentTestId;
250 | } else if (
251 | isCompoundComponentRoot &&
252 | sourceBaseComponent.children?.length === 1 &&
253 | !sourceBaseComponent.children?.[0].testId
254 | ) {
255 | // If the source is a compound component, we need to set the testId on the first & only child
256 | sourceBaseComponent.children[0].testId = baseComponentTestId;
257 | }
258 | }
259 | const themedDescription = mapThemeRelatedVars(description);
260 |
261 | // Merge default test resources with any provided resources
262 | const mergedResources = {
263 | ...defaultTestResources,
264 | ...themedDescription.resources,
265 | };
266 |
267 | const _appDescription: StandaloneAppDescription = {
268 | name: "test bed app",
269 | ...themedDescription,
270 | resources: mergedResources,
271 | components,
272 | entryPoint,
273 | };
274 |
275 | const clipboard = new Clipboard(page);
276 | // --- Mock the clipboard API if in CI
277 | if (isCI) {
278 | await page.addInitScript(clipboard.init);
279 | }
280 |
281 | await page.addInitScript((app) => {
282 | // @ts-ignore
283 | window.TEST_ENV = app;
284 | }, _appDescription);
285 | const { width, height } = page.viewportSize();
286 | await page.goto("/");
287 |
288 | // Create test icon locators
289 | const testIcons = {
290 | boxIcon: page.getByTestId("box-svg"),
291 | docIcon: page.getByTestId("doc-svg"),
292 | sunIcon: page.getByTestId("sun-svg"),
293 | eyeIcon: page.getByTestId("eye-svg"),
294 | txtIcon: page.getByTestId("txt-svg"),
295 | bellIcon: page.getByTestId("bell-svg"),
296 | };
297 |
298 | return {
299 | testStateDriver: new TestStateDriver(page.getByTestId(testStateViewTestId)),
300 | clipboard,
301 | width: width ?? 0,
302 | height: height ?? 0,
303 | testIcons,
304 | };
305 | });
306 | },
307 |
308 | createDriver: async <T extends new (...args: ComponentDriverParams[]) => any>(
309 | { page, baseComponentTestId },
310 | use,
311 | ) => {
312 | await use(async (driverClass: T, testIdOrLocator?: string | Locator) => {
313 | let locator: Locator = undefined;
314 | if (testIdOrLocator === undefined || typeof testIdOrLocator === "string") {
315 | locator = await getOnlyFirstLocator(page, testIdOrLocator ?? baseComponentTestId);
316 | } else if (typeof testIdOrLocator === "object") {
317 | locator = testIdOrLocator;
318 | }
319 |
320 | return new driverClass({
321 | locator,
322 | page,
323 | });
324 | });
325 | },
326 |
327 | createButtonDriver: async ({ createDriver }, use) => {
328 | await use((testIdOrLocator?: string | Locator) => {
329 | return createDriver(ButtonDriver, testIdOrLocator);
330 | });
331 | },
332 | createBackdropDriver: async ({ createDriver }, use) => {
333 | await use((testIdOrLocator?: string | Locator) => {
334 | return createDriver(BackdropDriver, testIdOrLocator);
335 | });
336 | },
337 | createContentSeparatorDriver: async ({ createDriver }, use) => {
338 | await use((testIdOrLocator?: string | Locator) => {
339 | return createDriver(ContentSeparatorDriver, testIdOrLocator);
340 | });
341 | },
342 | createAvatarDriver: async ({ createDriver }, use) => {
343 | await use((testIdOrLocator?: string | Locator) => {
344 | return createDriver(AvatarDriver, testIdOrLocator);
345 | });
346 | },
347 | createFormDriver: async ({ createDriver }, use) => {
348 | await use((testIdOrLocator?: string | Locator) => {
349 | return createDriver(FormDriver, testIdOrLocator);
350 | });
351 | },
352 | createFormItemDriver: async ({ createDriver }, use) => {
353 | await use((testIdOrLocator?: string | Locator) => {
354 | return createDriver(FormItemDriver, testIdOrLocator);
355 | });
356 | },
357 | createValidationSummaryDriver: async ({ createDriver }, use) => {
358 | await use((testIdOrLocator?: string | Locator) => {
359 | return createDriver(ValidationSummaryDriver, testIdOrLocator);
360 | });
361 | },
362 | createValidationDisplayDriver: async ({ createDriver }, use) => {
363 | await use((testIdOrLocator?: string | Locator) => {
364 | return createDriver(ValidationDisplayDriver, testIdOrLocator);
365 | });
366 | },
367 | createSplitterDriver: async ({ createDriver }, use) => {
368 | await use((testIdOrLocator?: string | Locator) => {
369 | return createDriver(SplitterDriver, testIdOrLocator);
370 | });
371 | },
372 | createMarkdownDriver: async ({ createDriver }, use) => {
373 | await use((testIdOrLocator?: string | Locator) => {
374 | return createDriver(MarkdownDriver, testIdOrLocator);
375 | });
376 | },
377 | createItemsDriver: async ({ createDriver }, use) => {
378 | await use((testIdOrLocator?: string | Locator) => {
379 | return createDriver(ItemsDriver, testIdOrLocator);
380 | });
381 | },
382 | createRangeDriver: async ({ createDriver }, use) => {
383 | await use((testIdOrLocator?: string | Locator) => {
384 | return createDriver(RangeDriver, testIdOrLocator);
385 | });
386 | },
387 | createDatePickerDriver: async ({ createDriver }, use) => {
388 | await use((testIdOrLocator?: string | Locator) => {
389 | return createDriver(DatePickerDriver, testIdOrLocator);
390 | });
391 | },
392 | createExpandableItemDriver: async ({ createDriver }, use) => {
393 | await use((testIdOrLocator?: string | Locator) => {
394 | return createDriver(ExpandableItemDriver, testIdOrLocator);
395 | });
396 | },
397 | createFileInputDriver: async ({ createDriver }, use) => {
398 | await use((testIdOrLocator?: string | Locator) => {
399 | return createDriver(FileInputDriver, testIdOrLocator);
400 | });
401 | },
402 | createFileUploadDropZoneDriver: async ({ createDriver }, use) => {
403 | await use((testIdOrLocator?: string | Locator) => {
404 | return createDriver(FileUploadDropZoneDriver, testIdOrLocator);
405 | });
406 | },
407 | createAutoCompleteDriver: async ({ createDriver }, use) => {
408 | await use((testIdOrLocator?: string | Locator) => {
409 | return createDriver(AutoCompleteDriver, testIdOrLocator);
410 | });
411 | },
412 | createSelectDriver: async ({ createDriver }, use) => {
413 | await use((testIdOrLocator?: string | Locator) => {
414 | return createDriver(SelectDriver, testIdOrLocator);
415 | });
416 | },
417 | createRadioGroupDriver: async ({ createDriver }, use) => {
418 | await use((testIdOrLocator?: string | Locator) => {
419 | return createDriver(RadioGroupDriver, testIdOrLocator);
420 | });
421 | },
422 | createNumberBoxDriver: async ({ createDriver }, use) => {
423 | await use((testIdOrLocator?: string | Locator) => {
424 | return createDriver(NumberBoxDriver, testIdOrLocator);
425 | });
426 | },
427 | createTextBoxDriver: async ({ createDriver }, use) => {
428 | await use((testIdOrLocator?: string | Locator) => {
429 | return createDriver(TextBoxDriver, testIdOrLocator);
430 | });
431 | },
432 | createSliderDriver: async ({ createDriver }, use) => {
433 | await use((testIdOrLocator?: string | Locator) => {
434 | return createDriver(SliderDriver, testIdOrLocator);
435 | });
436 | },
437 | createTextAreaDriver: async ({ createDriver }, use) => {
438 | await use((testIdOrLocator?: string | Locator) => {
439 | return createDriver(TextAreaDriver, testIdOrLocator);
440 | });
441 | },
442 | createProgressBarDriver: async ({ createDriver }, use) => {
443 | await use((testIdOrLocator?: string | Locator) => {
444 | return createDriver(ProgressBarDriver, testIdOrLocator);
445 | });
446 | },
447 | createListDriver: async ({ createDriver }, use) => {
448 | await use((testIdOrLocator?: string | Locator) => {
449 | return createDriver(ListDriver, testIdOrLocator);
450 | });
451 | },
452 | createTextDriver: async ({ createDriver }, use) => {
453 | await use((testIdOrLocator?: string | Locator) => {
454 | return createDriver(TextDriver, testIdOrLocator);
455 | });
456 | },
457 | createHeadingDriver: async ({ createDriver }, use) => {
458 | await use((testIdOrLocator?: string | Locator) => {
459 | return createDriver(HeadingDriver, testIdOrLocator);
460 | });
461 | },
462 | createIconDriver: async ({ createDriver }, use) => {
463 | await use((testIdOrLocator?: string | Locator) => {
464 | return createDriver(IconDriver, testIdOrLocator);
465 | });
466 | },
467 | createStackDriver: async ({ createDriver }, use) => {
468 | await use((testIdOrLocator?: string | Locator) => {
469 | return createDriver(StackDriver, testIdOrLocator);
470 | });
471 | },
472 | createHStackDriver: async ({ createDriver }, use) => {
473 | await use((testIdOrLocator?: string | Locator) => {
474 | return createDriver(HStackDriver, testIdOrLocator);
475 | });
476 | },
477 | createVStackDriver: async ({ createDriver }, use) => {
478 | await use((testIdOrLocator?: string | Locator) => {
479 | return createDriver(VStackDriver, testIdOrLocator);
480 | });
481 | },
482 | createLinkDriver: async ({ createDriver }, use) => {
483 | await use((testIdOrLocator?: string | Locator) => {
484 | return createDriver(LinkDriver, testIdOrLocator);
485 | });
486 | },
487 | createNavLinkDriver: async ({ createDriver }, use) => {
488 | await use((testIdOrLocator?: string | Locator) => {
489 | return createDriver(NavLinkDriver, testIdOrLocator);
490 | });
491 | },
492 | createNavGroupDriver: async ({ createDriver }, use) => {
493 | await use((testIdOrLocator?: string | Locator) => {
494 | return createDriver(NavGroupDriver, testIdOrLocator);
495 | });
496 | },
497 | createNavPanelDriver: async ({ createDriver }, use) => {
498 | await use((testIdOrLocator?: string | Locator) => {
499 | return createDriver(NavPanelDriver, testIdOrLocator);
500 | });
501 | },
502 | createCardDriver: async ({ createDriver }, use) => {
503 | await use((testIdOrLocator?: string | Locator) => {
504 | return createDriver(CardDriver, testIdOrLocator);
505 | });
506 | },
507 | createAccordionDriver: async ({ createDriver }, use) => {
508 | await use((testIdOrLocator?: string | Locator) => {
509 | return createDriver(AccordionDriver, testIdOrLocator);
510 | });
511 | },
512 | createAppHeaderDriver: async ({ createDriver }, use) => {
513 | await use((testIdOrLocator?: string | Locator) => {
514 | return createDriver(AppHeaderDriver, testIdOrLocator);
515 | });
516 | },
517 | createAppFooterDriver: async ({ createDriver }, use) => {
518 | await use((testIdOrLocator?: string | Locator) => {
519 | return createDriver(AppFooterDriver, testIdOrLocator);
520 | });
521 | },
522 | createBadgeDriver: async ({ createDriver }, use) => {
523 | await use((testIdOrLocator?: string | Locator) => {
524 | return createDriver(BadgeDriver, testIdOrLocator);
525 | });
526 | },
527 | createNoResultDriver: async ({ createDriver }, use) => {
528 | await use((testIdOrLocator?: string | Locator) => {
529 | return createDriver(NoResultDriver, testIdOrLocator);
530 | });
531 | },
532 | createOptionDriver: async ({ createDriver }, use) => {
533 | await use((testIdOrLocator?: string | Locator) => {
534 | return createDriver(OptionDriver, testIdOrLocator);
535 | });
536 | },
537 | createHtmlTagDriver: async ({ createDriver }, use) => {
538 | await use((testIdOrLocator?: string | Locator) => {
539 | return createDriver(HtmlTagDriver, testIdOrLocator);
540 | });
541 | },
542 | createCodeBlockDriver: async ({ createDriver }, use) => {
543 | await use((testIdOrLocator?: string | Locator) => {
544 | return createDriver(CodeBlockDriver, testIdOrLocator);
545 | });
546 | },
547 | createCheckboxDriver: async ({ createDriver }, use) => {
548 | await use((testIdOrLocator?: string | Locator) => {
549 | return createDriver(CheckboxDriver, testIdOrLocator);
550 | });
551 | },
552 | createLabelDriver: async ({ createDriver }, use) => {
553 | await use((testIdOrLocator?: string | Locator) => {
554 | return createDriver(LabelDriver, testIdOrLocator);
555 | });
556 | },
557 | createSpinnerDriver: async ({ createDriver }, use) => {
558 | await use((testIdOrLocator?: string | Locator) => {
559 | return createDriver(SpinnerDriver, testIdOrLocator);
560 | });
561 | },
562 | createDropdownMenuDriver: async ({ createDriver }, use) => {
563 | await use((testIdOrLocator?: string | Locator) => {
564 | return createDriver(DropdownMenuDriver, testIdOrLocator);
565 | });
566 | },
567 | createTimeInputDriver: async ({ createDriver }, use) => {
568 | await use((testIdOrLocator?: string | Locator) => {
569 | return createDriver(TimeInputDriver, testIdOrLocator);
570 | });
571 | },
572 | createTimerDriver: async ({ createDriver }, use) => {
573 | await use((testIdOrLocator?: string | Locator) => {
574 | return createDriver(TimerDriver, testIdOrLocator);
575 | });
576 | },
577 | createDateInputDriver: async ({ createDriver }, use) => {
578 | await use((testIdOrLocator?: string | Locator) => {
579 | return createDriver(DateInputDriver, testIdOrLocator);
580 | });
581 | },
582 | createModalDialogDriver: async ({ createDriver }, use) => {
583 | await use((testIdOrLocator?: string | Locator) => {
584 | return createDriver(ModalDialogDriver, testIdOrLocator);
585 | });
586 | },
587 | createTreeDriver: async ({ createDriver }, use) => {
588 | await use((testIdOrLocator?: string | Locator) => {
589 | return createDriver(TreeDriver, testIdOrLocator);
590 | });
591 | },
592 | });
593 |
594 | // --- Types
595 |
596 | type ComponentDriverMethod<T extends ComponentDriver> = (
597 | testIdOrLocator?: string | Locator,
598 | ) => Promise<T>;
599 |
600 | type TestDriverExtenderProps = {
601 | testStateViewTestId: string;
602 | baseComponentTestId: string;
603 | initTestBed: (
604 | source: string,
605 | description?: TestBedDescription,
606 | ) => Promise<{
607 | testStateDriver: TestStateDriver;
608 | clipboard: Clipboard;
609 | width: number;
610 | height: number;
611 | testIcons: {
612 | boxIcon: Locator;
613 | docIcon: Locator;
614 | sunIcon: Locator;
615 | eyeIcon: Locator;
616 | txtIcon: Locator;
617 | bellIcon: Locator;
618 | };
619 | }>;
620 | createDriver: <T extends new (...args: ComponentDriverParams[]) => any>(
621 | driverClass: T,
622 | testIdOrLocator?: string | Locator,
623 | ) => Promise<InstanceType<T>>;
624 | createButtonDriver: ComponentDriverMethod<ButtonDriver>;
625 | createBackdropDriver: ComponentDriverMethod<BackdropDriver>;
626 | createContentSeparatorDriver: ComponentDriverMethod<ContentSeparatorDriver>;
627 | createAvatarDriver: ComponentDriverMethod<AvatarDriver>;
628 | createFormDriver: ComponentDriverMethod<FormDriver>;
629 | createFormItemDriver: ComponentDriverMethod<FormItemDriver>;
630 | createValidationSummaryDriver: ComponentDriverMethod<ValidationSummaryDriver>;
631 | createValidationDisplayDriver: ComponentDriverMethod<ValidationDisplayDriver>;
632 | createSplitterDriver: ComponentDriverMethod<SplitterDriver>;
633 | createMarkdownDriver: ComponentDriverMethod<MarkdownDriver>;
634 | createItemsDriver: ComponentDriverMethod<ItemsDriver>;
635 | createSliderDriver: ComponentDriverMethod<SliderDriver>;
636 | createRangeDriver: ComponentDriverMethod<RangeDriver>;
637 | createDatePickerDriver: ComponentDriverMethod<DatePickerDriver>;
638 | createExpandableItemDriver: ComponentDriverMethod<ExpandableItemDriver>;
639 | createFileInputDriver: ComponentDriverMethod<FileInputDriver>;
640 | createFileUploadDropZoneDriver: ComponentDriverMethod<FileUploadDropZoneDriver>;
641 | createAutoCompleteDriver: ComponentDriverMethod<AutoCompleteDriver>;
642 | createSelectDriver: ComponentDriverMethod<SelectDriver>;
643 | createRadioGroupDriver: ComponentDriverMethod<RadioGroupDriver>;
644 | createNumberBoxDriver: ComponentDriverMethod<NumberBoxDriver>;
645 | createTextBoxDriver: ComponentDriverMethod<TextBoxDriver>;
646 | createTextAreaDriver: ComponentDriverMethod<TextAreaDriver>;
647 | createProgressBarDriver: ComponentDriverMethod<ProgressBarDriver>;
648 | createListDriver: ComponentDriverMethod<ListDriver>;
649 | createTextDriver: ComponentDriverMethod<TextDriver>;
650 | createHeadingDriver: ComponentDriverMethod<HeadingDriver>;
651 | createIconDriver: ComponentDriverMethod<IconDriver>;
652 | createStackDriver: ComponentDriverMethod<StackDriver>;
653 | createHStackDriver: ComponentDriverMethod<HStackDriver>;
654 | createVStackDriver: ComponentDriverMethod<VStackDriver>;
655 | createLinkDriver: ComponentDriverMethod<LinkDriver>;
656 | createNavLinkDriver: ComponentDriverMethod<NavLinkDriver>;
657 | createNavGroupDriver: ComponentDriverMethod<NavGroupDriver>;
658 | createNavPanelDriver: ComponentDriverMethod<NavPanelDriver>;
659 | createCardDriver: ComponentDriverMethod<CardDriver>;
660 | createAccordionDriver: ComponentDriverMethod<AccordionDriver>;
661 | createAppHeaderDriver: ComponentDriverMethod<AppHeaderDriver>;
662 | createAppFooterDriver: ComponentDriverMethod<AppFooterDriver>;
663 | createBadgeDriver: ComponentDriverMethod<BadgeDriver>;
664 | createNoResultDriver: ComponentDriverMethod<NoResultDriver>;
665 | createOptionDriver: ComponentDriverMethod<OptionDriver>;
666 | createHtmlTagDriver: ComponentDriverMethod<HtmlTagDriver>;
667 | createCodeBlockDriver: ComponentDriverMethod<CodeBlockDriver>;
668 | createCheckboxDriver: ComponentDriverMethod<CheckboxDriver>;
669 | createLabelDriver: ComponentDriverMethod<LabelDriver>;
670 | createSpinnerDriver: ComponentDriverMethod<SpinnerDriver>;
671 | createDropdownMenuDriver: ComponentDriverMethod<DropdownMenuDriver>;
672 | createTimeInputDriver: ComponentDriverMethod<TimeInputDriver>;
673 | createTimerDriver: ComponentDriverMethod<TimerDriver>;
674 | createDateInputDriver: ComponentDriverMethod<DateInputDriver>;
675 | createModalDialogDriver: ComponentDriverMethod<ModalDialogDriver>;
676 | createTreeDriver: ComponentDriverMethod<TreeDriver>;
677 | };
678 |
```