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

# Directory Structure

```
├── .changeset
│   ├── config.json
│   └── cyan-tools-design.md
├── .eslintrc.cjs
├── .github
│   ├── build-checklist.png
│   ├── ISSUE_TEMPLATE
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   └── workflows
│       ├── deploy-blog-optimized.yml
│       ├── deploy-blog-swa.yml
│       ├── deploy-blog.yml
│       ├── deploy-docs-optimized.yml
│       ├── deploy-docs-swa.yml
│       ├── deploy-docs.yml
│       ├── prepare-versions.yml
│       ├── release-packages.yml
│       ├── run-all-tests.yml
│       └── run-smoke-tests.yml
├── .gitignore
├── .prettierrc.js
├── .vscode
│   ├── launch.json
│   └── settings.json
├── blog
│   ├── .gitignore
│   ├── .gitkeep
│   ├── CHANGELOG.md
│   ├── extensions.ts
│   ├── index.html
│   ├── index.ts
│   ├── package.json
│   ├── public
│   │   ├── blog
│   │   │   ├── images
│   │   │   │   ├── an-advanced-codefence.gif
│   │   │   │   ├── an-advanced-codefence.mp4
│   │   │   │   ├── blog-page-component.png
│   │   │   │   ├── blog-scrabble.png
│   │   │   │   ├── codefence-runner.png
│   │   │   │   ├── integrated-blog-search.png
│   │   │   │   ├── lorem-ipsum.png
│   │   │   │   ├── playground-checkbox-source.png
│   │   │   │   ├── playground.png
│   │   │   │   ├── use-xmlui-mcp-to-find-a-howto.png
│   │   │   │   └── xmlui-demo-gallery.png
│   │   │   ├── introducing-xmlui.md
│   │   │   ├── lorem-ipsum.md
│   │   │   ├── newest-post.md
│   │   │   ├── older-post.md
│   │   │   ├── xmlui-playground.md
│   │   │   └── xmlui-powered-blog.md
│   │   ├── mockServiceWorker.js
│   │   ├── resources
│   │   │   ├── favicon.ico
│   │   │   ├── files
│   │   │   │   └── for-download
│   │   │   │       └── xmlui
│   │   │   │           └── xmlui-standalone.umd.js
│   │   │   ├── github.svg
│   │   │   ├── 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.module.scss
│   │       │   ├── CodeSelector.tsx
│   │       │   ├── ConfirmationDialog.module.scss
│   │       │   ├── ConfirmationDialog.tsx
│   │       │   ├── Editor.tsx
│   │       │   ├── Header.module.scss
│   │       │   ├── Header.tsx
│   │       │   ├── Playground.tsx
│   │       │   ├── PlaygroundContent.module.scss
│   │       │   ├── PlaygroundContent.tsx
│   │       │   ├── PlaygroundNative.module.scss
│   │       │   ├── PlaygroundNative.tsx
│   │       │   ├── Preview.tsx
│   │       │   ├── StandalonePlayground.tsx
│   │       │   ├── StandalonePlaygroundNative.module.scss
│   │       │   ├── StandalonePlaygroundNative.tsx
│   │       │   ├── ThemeSwitcher.module.scss
│   │       │   ├── ThemeSwitcher.tsx
│   │       │   └── utils.ts
│   │       ├── providers
│   │       │   ├── Toast.module.scss
│   │       │   └── ToastProvider.tsx
│   │       ├── state
│   │       │   └── store.ts
│   │       ├── themes
│   │       │   └── theme.ts
│   │       └── utils
│   │           └── helpers.ts
│   ├── xmlui-search
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── index.tsx
│   │       ├── Search.module.scss
│   │       └── Search.tsx
│   ├── xmlui-spreadsheet
│   │   ├── .gitignore
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── index.tsx
│   │       ├── Spreadsheet.tsx
│   │       └── SpreadsheetNative.tsx
│   └── xmlui-website-blocks
│       ├── .gitignore
│       ├── CHANGELOG.md
│       ├── demo
│       │   ├── components
│       │   │   ├── HeroBackgroundBreakoutPage.xmlui
│       │   │   ├── HeroBackgroundsPage.xmlui
│       │   │   ├── HeroContentsPage.xmlui
│       │   │   ├── HeroTextAlignPage.xmlui
│       │   │   ├── HeroTextPage.xmlui
│       │   │   └── HeroTonesPage.xmlui
│       │   ├── Main.xmlui
│       │   └── themes
│       │       └── default.ts
│       ├── index.html
│       ├── index.ts
│       ├── meta
│       │   └── componentsMetadata.ts
│       ├── package.json
│       ├── public
│       │   └── resources
│       │       ├── building.jpg
│       │       └── xmlui-logo.svg
│       └── src
│           ├── Carousel
│           │   ├── Carousel.module.scss
│           │   ├── Carousel.tsx
│           │   ├── CarouselContext.tsx
│           │   └── CarouselNative.tsx
│           ├── FancyButton
│           │   ├── FancyButton.module.scss
│           │   ├── FancyButton.tsx
│           │   └── FancyButton.xmlui
│           ├── Hello
│           │   ├── Hello.tsx
│           │   ├── Hello.xmlui
│           │   └── Hello.xmlui.xs
│           ├── HeroSection
│           │   ├── HeroSection.module.scss
│           │   ├── HeroSection.spec.ts
│           │   ├── HeroSection.tsx
│           │   └── HeroSectionNative.tsx
│           ├── index.tsx
│           ├── ScrollToTop
│           │   ├── ScrollToTop.module.scss
│           │   ├── ScrollToTop.tsx
│           │   └── ScrollToTopNative.tsx
│           └── vite-env.d.ts
├── playwright.config.ts
├── README.md
├── tools
│   ├── codefence
│   │   └── xmlui-code-fence-docs.md
│   ├── create-app
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── create-app.ts
│   │   ├── helpers
│   │   │   ├── copy.ts
│   │   │   ├── get-pkg-manager.ts
│   │   │   ├── git.ts
│   │   │   ├── install.ts
│   │   │   ├── is-folder-empty.ts
│   │   │   ├── is-writeable.ts
│   │   │   ├── make-dir.ts
│   │   │   └── validate-pkg.ts
│   │   ├── index.ts
│   │   ├── package.json
│   │   ├── templates
│   │   │   ├── default
│   │   │   │   └── ts
│   │   │   │       ├── gitignore
│   │   │   │       ├── index.html
│   │   │   │       ├── index.ts
│   │   │   │       ├── public
│   │   │   │       │   ├── mockServiceWorker.js
│   │   │   │       │   ├── resources
│   │   │   │       │   │   ├── favicon.ico
│   │   │   │       │   │   └── xmlui-logo.svg
│   │   │   │       │   └── serve.json
│   │   │   │       └── src
│   │   │   │           ├── components
│   │   │   │           │   ├── ApiAware.xmlui
│   │   │   │           │   ├── Home.xmlui
│   │   │   │           │   ├── IncButton.xmlui
│   │   │   │           │   └── PagePanel.xmlui
│   │   │   │           ├── config.ts
│   │   │   │           └── Main.xmlui
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   └── tsconfig.json
│   ├── create-xmlui-hello-world
│   │   ├── index.js
│   │   └── package.json
│   └── vscode
│       ├── .gitignore
│       ├── .vscode
│       │   ├── launch.json
│       │   └── tasks.json
│       ├── .vscodeignore
│       ├── build.sh
│       ├── CHANGELOG.md
│       ├── esbuild.js
│       ├── eslint.config.mjs
│       ├── formatter-docs.md
│       ├── generate-test-sample.sh
│       ├── LICENSE.md
│       ├── package-lock.json
│       ├── package.json
│       ├── README.md
│       ├── resources
│       │   ├── xmlui-logo.png
│       │   └── xmlui-markup-syntax-highlighting.png
│       ├── src
│       │   ├── extension.ts
│       │   └── server.ts
│       ├── syntaxes
│       │   └── xmlui.tmLanguage.json
│       ├── test-samples
│       │   └── sample.xmlui
│       ├── tsconfig.json
│       └── tsconfig.tsbuildinfo
├── turbo.json
└── xmlui
    ├── .gitignore
    ├── bin
    │   ├── bootstrap.cjs
    │   ├── bootstrap.js
    │   ├── build-lib.ts
    │   ├── build.ts
    │   ├── index.ts
    │   ├── preview.ts
    │   ├── start.ts
    │   ├── vite-xmlui-plugin.ts
    │   └── viteConfig.ts
    ├── CHANGELOG.md
    ├── conventions
    │   ├── component-qa-checklist.md
    │   ├── copilot-conventions.md
    │   ├── create-xmlui-components.md
    │   ├── mermaid.md
    │   ├── testing-conventions.md
    │   └── xmlui-in-a-nutshell.md
    ├── dev-docs
    │   ├── accessibility.md
    │   ├── build-system.md
    │   ├── build-xmlui.md
    │   ├── component-behaviors.md
    │   ├── component-metadata.md
    │   ├── components-with-options.md
    │   ├── containers.md
    │   ├── data-operations.md
    │   ├── glossary.md
    │   ├── index.md
    │   ├── next
    │   │   ├── component-dev-guide.md
    │   │   ├── configuration-management-enhancement-summary.md
    │   │   ├── documentation-scripts-refactoring-complete-summary.md
    │   │   ├── documentation-scripts-refactoring-plan.md
    │   │   ├── duplicate-pattern-extraction-summary.md
    │   │   ├── error-handling-standardization-summary.md
    │   │   ├── generating-component-reference.md
    │   │   ├── index.md
    │   │   ├── logging-consistency-implementation-summary.md
    │   │   ├── project-build.md
    │   │   ├── project-structure.md
    │   │   ├── theme-context.md
    │   │   ├── tiptap-design-considerations.md
    │   │   ├── working-with-code.md
    │   │   ├── xmlui-runtime-architecture
    │   │   └── xmlui-wcag-accessibility-report.md
    │   ├── react-fundamentals.md
    │   ├── release-method.md
    │   ├── standalone-app.md
    │   ├── theme-variables-refactoring.md
    │   ├── ud-components.md
    │   └── xmlui-repo.md
    ├── package.json
    ├── scripts
    │   ├── coverage-only.js
    │   ├── e2e-test-summary.js
    │   ├── extract-component-metadata.js
    │   ├── generate-docs
    │   │   ├── build-downloads-map.mjs
    │   │   ├── build-pages-map.mjs
    │   │   ├── components-config.json
    │   │   ├── configuration-management.mjs
    │   │   ├── constants.mjs
    │   │   ├── create-theme-files.mjs
    │   │   ├── DocsGenerator.mjs
    │   │   ├── error-handling.mjs
    │   │   ├── extensions-config.json
    │   │   ├── folders.mjs
    │   │   ├── generate-summary-files.mjs
    │   │   ├── get-docs.mjs
    │   │   ├── input-handler.mjs
    │   │   ├── logger.mjs
    │   │   ├── logging-standards.mjs
    │   │   ├── MetadataProcessor.mjs
    │   │   ├── pattern-utilities.mjs
    │   │   └── utils.mjs
    │   ├── generate-metadata-markdown.js
    │   ├── get-langserver-metadata.js
    │   ├── inline-links.mjs
    │   └── README-e2e-summary.md
    ├── src
    │   ├── abstractions
    │   │   ├── _conventions.md
    │   │   ├── ActionDefs.ts
    │   │   ├── AppContextDefs.ts
    │   │   ├── ComponentDefs.ts
    │   │   ├── ContainerDefs.ts
    │   │   ├── ExtensionDefs.ts
    │   │   ├── FunctionDefs.ts
    │   │   ├── RendererDefs.ts
    │   │   ├── scripting
    │   │   │   ├── BlockScope.ts
    │   │   │   ├── Compilation.ts
    │   │   │   ├── LogicalThread.ts
    │   │   │   ├── LoopScope.ts
    │   │   │   ├── modules.ts
    │   │   │   ├── ScriptParserError.ts
    │   │   │   ├── Token.ts
    │   │   │   ├── TryScope.ts
    │   │   │   └── TryScopeExp.ts
    │   │   └── ThemingDefs.ts
    │   ├── components
    │   │   ├── _conventions.md
    │   │   ├── abstractions.ts
    │   │   ├── Accordion
    │   │   │   ├── Accordion.md
    │   │   │   ├── Accordion.module.scss
    │   │   │   ├── Accordion.spec.ts
    │   │   │   ├── Accordion.tsx
    │   │   │   ├── AccordionContext.tsx
    │   │   │   ├── AccordionItem.tsx
    │   │   │   ├── AccordionItemNative.tsx
    │   │   │   └── AccordionNative.tsx
    │   │   ├── Animation
    │   │   │   └── AnimationNative.tsx
    │   │   ├── APICall
    │   │   │   ├── APICall.md
    │   │   │   ├── APICall.spec.ts
    │   │   │   ├── APICall.tsx
    │   │   │   └── APICallNative.tsx
    │   │   ├── App
    │   │   │   ├── App.md
    │   │   │   ├── App.module.scss
    │   │   │   ├── App.spec.ts
    │   │   │   ├── App.tsx
    │   │   │   ├── AppLayoutContext.ts
    │   │   │   ├── AppNative.tsx
    │   │   │   ├── AppStateContext.ts
    │   │   │   ├── doc-resources
    │   │   │   │   ├── condensed-sticky.xmlui
    │   │   │   │   ├── condensed.xmlui
    │   │   │   │   ├── horizontal-sticky.xmlui
    │   │   │   │   ├── horizontal.xmlui
    │   │   │   │   ├── vertical-full-header.xmlui
    │   │   │   │   ├── vertical-sticky.xmlui
    │   │   │   │   └── vertical.xmlui
    │   │   │   ├── IndexerContext.ts
    │   │   │   ├── LinkInfoContext.ts
    │   │   │   ├── SearchContext.tsx
    │   │   │   ├── Sheet.module.scss
    │   │   │   └── Sheet.tsx
    │   │   ├── AppHeader
    │   │   │   ├── AppHeader.md
    │   │   │   ├── AppHeader.module.scss
    │   │   │   ├── AppHeader.spec.ts
    │   │   │   ├── AppHeader.tsx
    │   │   │   └── AppHeaderNative.tsx
    │   │   ├── AppState
    │   │   │   ├── AppState.md
    │   │   │   ├── AppState.spec.ts
    │   │   │   ├── AppState.tsx
    │   │   │   └── AppStateNative.tsx
    │   │   ├── AutoComplete
    │   │   │   ├── AutoComplete.md
    │   │   │   ├── AutoComplete.module.scss
    │   │   │   ├── AutoComplete.spec.ts
    │   │   │   ├── AutoComplete.tsx
    │   │   │   ├── AutoCompleteContext.tsx
    │   │   │   └── AutoCompleteNative.tsx
    │   │   ├── Avatar
    │   │   │   ├── Avatar.md
    │   │   │   ├── Avatar.module.scss
    │   │   │   ├── Avatar.spec.ts
    │   │   │   ├── Avatar.tsx
    │   │   │   └── AvatarNative.tsx
    │   │   ├── Backdrop
    │   │   │   ├── Backdrop.md
    │   │   │   ├── Backdrop.module.scss
    │   │   │   ├── Backdrop.spec.ts
    │   │   │   ├── Backdrop.tsx
    │   │   │   └── BackdropNative.tsx
    │   │   ├── Badge
    │   │   │   ├── Badge.md
    │   │   │   ├── Badge.module.scss
    │   │   │   ├── Badge.spec.ts
    │   │   │   ├── Badge.tsx
    │   │   │   └── BadgeNative.tsx
    │   │   ├── Bookmark
    │   │   │   ├── Bookmark.md
    │   │   │   ├── Bookmark.module.scss
    │   │   │   ├── Bookmark.spec.ts
    │   │   │   ├── Bookmark.tsx
    │   │   │   └── BookmarkNative.tsx
    │   │   ├── Breakout
    │   │   │   ├── Breakout.module.scss
    │   │   │   ├── Breakout.spec.ts
    │   │   │   ├── Breakout.tsx
    │   │   │   └── BreakoutNative.tsx
    │   │   ├── Button
    │   │   │   ├── Button-style.spec.ts
    │   │   │   ├── Button.md
    │   │   │   ├── Button.module.scss
    │   │   │   ├── Button.spec.ts
    │   │   │   ├── Button.tsx
    │   │   │   └── ButtonNative.tsx
    │   │   ├── Card
    │   │   │   ├── Card.md
    │   │   │   ├── Card.module.scss
    │   │   │   ├── Card.spec.ts
    │   │   │   ├── Card.tsx
    │   │   │   └── CardNative.tsx
    │   │   ├── Carousel
    │   │   │   ├── Carousel.md
    │   │   │   ├── Carousel.module.scss
    │   │   │   ├── Carousel.spec.ts
    │   │   │   ├── Carousel.tsx
    │   │   │   ├── CarouselContext.tsx
    │   │   │   ├── CarouselItem.tsx
    │   │   │   ├── CarouselItemNative.tsx
    │   │   │   └── CarouselNative.tsx
    │   │   ├── ChangeListener
    │   │   │   ├── ChangeListener.md
    │   │   │   ├── ChangeListener.spec.ts
    │   │   │   ├── ChangeListener.tsx
    │   │   │   └── ChangeListenerNative.tsx
    │   │   ├── chart-color-schemes.ts
    │   │   ├── Charts
    │   │   │   ├── AreaChart
    │   │   │   │   ├── AreaChart.md
    │   │   │   │   ├── AreaChart.spec.ts
    │   │   │   │   ├── AreaChart.tsx
    │   │   │   │   └── AreaChartNative.tsx
    │   │   │   ├── BarChart
    │   │   │   │   ├── BarChart.md
    │   │   │   │   ├── BarChart.module.scss
    │   │   │   │   ├── BarChart.spec.ts
    │   │   │   │   ├── BarChart.tsx
    │   │   │   │   └── BarChartNative.tsx
    │   │   │   ├── DonutChart
    │   │   │   │   ├── DonutChart.spec.ts
    │   │   │   │   └── DonutChart.tsx
    │   │   │   ├── LabelList
    │   │   │   │   ├── LabelList.module.scss
    │   │   │   │   ├── LabelList.spec.ts
    │   │   │   │   ├── LabelList.tsx
    │   │   │   │   └── LabelListNative.tsx
    │   │   │   ├── Legend
    │   │   │   │   ├── Legend.spec.ts
    │   │   │   │   ├── Legend.tsx
    │   │   │   │   └── LegendNative.tsx
    │   │   │   ├── LineChart
    │   │   │   │   ├── LineChart.md
    │   │   │   │   ├── LineChart.module.scss
    │   │   │   │   ├── LineChart.spec.ts
    │   │   │   │   ├── LineChart.tsx
    │   │   │   │   └── LineChartNative.tsx
    │   │   │   ├── PieChart
    │   │   │   │   ├── PieChart.md
    │   │   │   │   ├── PieChart.spec.ts
    │   │   │   │   ├── PieChart.tsx
    │   │   │   │   ├── PieChartNative.module.scss
    │   │   │   │   └── PieChartNative.tsx
    │   │   │   ├── RadarChart
    │   │   │   │   ├── RadarChart.md
    │   │   │   │   ├── RadarChart.spec.ts
    │   │   │   │   ├── RadarChart.tsx
    │   │   │   │   └── RadarChartNative.tsx
    │   │   │   ├── Tooltip
    │   │   │   │   ├── TooltipContent.module.scss
    │   │   │   │   ├── TooltipContent.spec.ts
    │   │   │   │   └── TooltipContent.tsx
    │   │   │   └── utils
    │   │   │       ├── abstractions.ts
    │   │   │       └── ChartProvider.tsx
    │   │   ├── Checkbox
    │   │   │   ├── Checkbox.md
    │   │   │   ├── Checkbox.spec.ts
    │   │   │   └── Checkbox.tsx
    │   │   ├── CodeBlock
    │   │   │   ├── CodeBlock.module.scss
    │   │   │   ├── CodeBlock.spec.ts
    │   │   │   ├── CodeBlock.tsx
    │   │   │   ├── CodeBlockNative.tsx
    │   │   │   └── highlight-code.ts
    │   │   ├── collectedComponentMetadata.ts
    │   │   ├── ColorPicker
    │   │   │   ├── ColorPicker.md
    │   │   │   ├── ColorPicker.module.scss
    │   │   │   ├── ColorPicker.spec.ts
    │   │   │   ├── ColorPicker.tsx
    │   │   │   └── ColorPickerNative.tsx
    │   │   ├── Column
    │   │   │   ├── Column.md
    │   │   │   ├── Column.tsx
    │   │   │   ├── ColumnNative.tsx
    │   │   │   ├── doc-resources
    │   │   │   │   └── list-component-data.js
    │   │   │   └── TableContext.tsx
    │   │   ├── component-utils.ts
    │   │   ├── ComponentProvider.tsx
    │   │   ├── ComponentRegistryContext.tsx
    │   │   ├── container-helpers.tsx
    │   │   ├── ContentSeparator
    │   │   │   ├── ContentSeparator.md
    │   │   │   ├── ContentSeparator.module.scss
    │   │   │   ├── ContentSeparator.spec.ts
    │   │   │   ├── ContentSeparator.tsx
    │   │   │   └── ContentSeparatorNative.tsx
    │   │   ├── 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.json
    ├── tsdown.config.ts
    ├── vite.config.ts
    └── vitest.config.ts
```

# Files

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

```markdown
  1 | # Tree [#tree]
  2 | 
  3 | The `Tree` component is a virtualized tree component that displays hierarchical data with support for flat and hierarchy data formats.
  4 | 
  5 | **Key features:**
  6 | - **Flat and hierarchical data structures**: You can select the most convenient data format to represent the tree. A set of properties enables you to map your data structure to the visual representation of the tree.
  7 | - **Flexible expand/collapse**: You have several properties to represent the expanded and collapsed state of tree nodes. You can also specify several options that determine which tree items are collapsed initially. 
  8 | - **Tree API**: Several exposed methods allow you to manage the tree's view state imperatively.
  9 | 
 10 | ## Specifying Data [#specifying-data]
 11 | 
 12 | With the `dataFormat` property, you can select between "flat" or "hierarchy" formats. The component transforms the data according to the value of this property into a visual representation.
 13 | 
 14 | The "flat" and "hierarchy" data structures both use these fields for a particular tree node:
 15 | - `id`: Unique ID of tree node
 16 | - `name`: The field to be used as the display label
 17 | - `icon`: An optional icon identifier. If specified, this icon is displayed with the tree item.
 18 | - `iconExpanded`: An optional icon identifier. This icon is displayed when the field is expanded.
 19 | - `iconCollapsed`: An optional icon identifier. This icon is displayed when the field is collapsed.
 20 | - `selectable`: Indicates if the node can be selected.
 21 | 
 22 | The "flat" structure refers to its direct parent node via the `parentId` property, which contains the ID of the node it is referring to.
 23 | 
 24 | The "hierarchy" structure uses a `children` property, which is an array of nested child nodes (using the common node property set above).
 25 | 
 26 | This example demonstrates the use of the "flat" data mode:
 27 | 
 28 | ```xmlui-pg display copy height="220px" /"flat"/ /parentId/ name="Example: flat data format"
 29 | <App>
 30 |   <Tree
 31 |     testId="tree"
 32 |     dataFormat="flat"
 33 |     defaultExpanded="all"
 34 |     data='{[
 35 |       { id: 1, icon:"folder", name: "Root Item 1", parentId: null },
 36 |       { id: 2, icon:"folder", name: "Child Item 1.1", parentId: 1 },
 37 |       { id: 3, icon: "code", name: "Child Item 1.2", parentId: 1 },
 38 |       { id: 4, icon: "code", name: "Grandchild Item 1.1.1", parentId: 2 },
 39 |     ]}'>
 40 |   </Tree>
 41 | </App>
 42 | ```
 43 | 
 44 | This example demonstrates the use of the "hiearchy" data mode:
 45 | 
 46 | ```xmlui-pg display copy height="220px" /"flat"/ /children/ name="Example: hierarchical data format"
 47 | <App>
 48 |   <Tree
 49 |     testId="tree"
 50 |     dataFormat="hierarchy"
 51 |     defaultExpanded="all"
 52 |     data='{[
 53 |       {
 54 |         id: 1, icon: "folder", name: "Root Item 1",
 55 |         children: [
 56 |           { id: 2, icon: "code", name: "Child Item 1.1" },
 57 |           { id: 3, icon: "folder", name: "Child Item 1.2",
 58 |             children: [
 59 |               { id: 4, icon: "code", name: "Grandchild Item 1.2.1"}
 60 |             ],
 61 |           }
 62 |         ],
 63 |       },
 64 |     ]}'>
 65 |   </Tree>
 66 | </App>
 67 | ```
 68 | 
 69 | When you use data (for example, retrieved from a backend), those structures may use different property names. The `Tree` component allows mapping data field names through these properties: 
 70 | - `idField` (default: `id`)
 71 | - `nameField` (default: `name`)
 72 | - `iconField`  (default: `icon`)
 73 | - `iconExpandedField` (default: `iconExpanded`)
 74 | - `iconCollapsedField` (default: `iconCollapsed`)
 75 | - `parentIdField` (default: `parentId`)
 76 | - `childrenField` (default: `children`)
 77 | - `selectableField` (default: `selectable`)
 78 | 
 79 | The following example uses the `idField`, `nameField`, and `parentIdField` mapping properties:
 80 | 
 81 | ```xmlui-pg display copy height="220px" /idField/ /nameField/ /parentIdField/ /uid/ /label/ /parent/ name="Example: mapping data fields"
 82 | <App>
 83 |   <Tree
 84 |     testId="tree"
 85 |     dataFormat="flat"
 86 |     defaultExpanded="all"
 87 |     idField="uid"
 88 |     nameField="label"
 89 |     parentIdField="parent"
 90 |     data='{[
 91 |       { uid: 1, icon:"folder", label: "Root Item 1", parent: null },
 92 |       { uid: 2, icon:"folder", label: "Child Item 1.1", parent: 1 },
 93 |       { uid: 3, icon: "code", label: "Child Item 1.2", parent: 1 },
 94 |       { uid: 4, icon: "code", label: "Grandchild Item 1.1.1", parent: 2 },
 95 |     ]}'>
 96 |   </Tree>
 97 | </App>
 98 | ```
 99 | 
100 | ## Expanding and collapsing tree nodes [#expanding-and-collapsing-tree-nodes]
101 | 
102 | By default, when you click a tree node outside of its expand/collapse icon,  the specified item is selected. With the `expandOnItemClick` property (using the `true` value), you can change this behavior to expand or collapse the item when clicking its surface anywhere.
103 | 
104 | You can use the `defaultExpanded` property to specify what nodes you want to see expanded initially. You can set this property to a list of node IDs or a string. When you specify IDs, the component expands the hierarchy to reveal the specified nodes. When the value is a string, you can use these options:
105 | - `none`: all nodes are collapsed (default)
106 | - `first-level`: all first-level nodes are expanded
107 | - `all`: all nodes are expanded
108 | 
109 | The following example demonstrates the use of `defaultExpanded` with tree node IDs:
110 | 
111 | ```xmlui-pg display copy height="300px" /doc-root/ /proj-web/ /media-profile-pic/ name="Example: defaultExpanded with node IDs"
112 | <App>
113 |   <Tree
114 |     testId="tree"
115 |     dataFormat="flat"
116 |     defaultExpanded="{['doc-root', 'proj-web', 'media-profile-pic']}"
117 |     data='{[
118 |       // Branch A: Documents
119 |       { id: "doc-root", name: "[Documents]", parentId: null },
120 |       { id: "doc-reports", name: "Reports", parentId: "doc-root" },
121 |       { id: "doc-invoices", name: "Invoices", parentId: "doc-root" },
122 |       { id: "doc-q1-report", name: "Q1 Report.pdf", parentId: "doc-reports" },
123 |       { id: "doc-q2-report", name: "Q2 Report.pdf", parentId: "doc-reports" },
124 |       { id: "doc-inv-001", name: "Invoice-001.pdf", parentId: "doc-invoices" },
125 | 
126 |       // Branch B: Projects
127 |       { id: "proj-root", name: "Projects", parentId: null },
128 |       { id: "proj-web", name: "[Web Apps]", parentId: "proj-root" },
129 |       { id: "proj-mobile", name: "Mobile Apps", parentId: "proj-root" },
130 |       { id: "proj-ecommerce", name: "E-commerce Site", parentId: "proj-web" },
131 |       { id: "proj-dashboard", name: "Admin Dashboard", parentId: "proj-web" },
132 |       { id: "proj-ios-app", name: "iOS Shopping App", parentId: "proj-mobile" },
133 | 
134 |       // Branch C: Media
135 |       { id: "media-root", name: "Media", parentId: null },
136 |       { id: "media-images", name: "Images", parentId: "media-root" },
137 |       { id: "media-videos", name: "Videos", parentId: "media-root" },
138 |       { id: "media-profile-pic", name: "[profile.jpg]", parentId: "media-images" },
139 |       { id: "media-banner", name: "banner.png", parentId: "media-images" },
140 |     ]}'>
141 |   </Tree>
142 | </App>
143 | ```
144 | 
145 | You have several options to style the icons representing the expanded or collapsed state:
146 | - The icons used for the expanded and collapsed states can be changed with the `iconExpanded` and `iconCollapsed` properties, respectively.
147 | - You can specify a different size with the `iconSize` property (using only numeric values considered as pixels)
148 | - Using a rotate animation when changing the state with the `animateExpand` flag.
149 | The following option demonstrates the last two options:
150 | 
151 | ```xmlui-pg display copy {4-5} height="220px" name="Example: expand/collapse options"
152 | <App>
153 |   <Tree
154 |     testId="tree"
155 |     iconSize="24"
156 |     animateExpand
157 |     dataFormat="flat"
158 |     defaultExpanded="all"
159 |     data='{[
160 |       { id: 1, name: "Root Item 1", parentId: null },
161 |       { id: 2, name: "Child Item 1.1", parentId: 1 },
162 |       { id: 3, name: "Child Item 1.2", parentId: 1 },
163 |       { id: 4, name: "Grandchild Item 1.1.1", parentId: 2 },
164 |     ]}'>
165 |   </Tree>
166 | </App>
167 | ```
168 | 
169 | ## Selection [#selection]
170 | 
171 | Each tree node is selectable by default, unless the node item's data does not have a `selectable` property (or the one specified in `selectedField`).
172 | A selectable item can be selected by clicking the mouse or pressing the Enter or Space keys when it has focus.
173 | 
174 | You can set the `selectedValue` property to define the selected tree item, ot use the `selectNode` exposed method for imperative selection.
175 | 
176 | ## Item templates [#item-templates]
177 | 
178 | You can override the default template used to display a tree item with the `itemTemplate` property. The template definition can use the `$item` context variable to access the item's attributes for display. `$item` provides these properties:
179 | - `id`: The unique node ID
180 | - `name`: The name of the node
181 | - `depth`: The depth level in the tree
182 | - `isExpanded`: Indicates if the tree node is expanded
183 | - `hasChildren`: Indicates if the tree node has children
184 | - `children`: The children of the tree node
185 | - `selectable`: Indicates if the node can be selected
186 | - `parentId`: The ID of the node's parent
187 | - `parentIds`: A list of parent IDs from the root node to the direct parent of the node
188 | - `path`: An array with the node names following the path from the root node to the displayed node.
189 | - `loadingState`: The current state of a dynamic node ("unloaded", "loading", or "loaded")
190 | 
191 | This example demonstrates these concepts:
192 | 
193 | ```xmlui-pg display copy {20-30} height="400px" /$item.id/ /$item.name/ /$item.hasChildren/ name="Example: itemTemplate"
194 | <App>
195 |   <Tree
196 |     testId="tree"
197 |     id="tree"
198 |     defaultExpanded="all"
199 |     data='{[
200 |         { id: "root", name: "My Files", parentId: null },
201 |         { id: "doc-root", name: "Documents", parentId: "root" },
202 |         { id: "doc-reports", name: "Reports", parentId: "doc-root" },
203 |         { id: "doc-q1-report", name: "Q1 Report.pdf", parentId: "doc-reports" },
204 |         { id: "doc-q2-report", name: "Q2 Report.pdf", parentId: "doc-reports" },
205 |         { id: "proj-root", name: "Projects", parentId: "root" },
206 |         { id: "proj-web", name: "Web Apps", parentId: "proj-root" },
207 |         { id: "proj-ecommerce", name: "E-commerce Site", parentId: "proj-web" },
208 |         { id: "proj-dashboard", name: "Admin Dashboard", parentId: "proj-web" },
209 |         { id: "media-root", name: "Media", parentId: "root" },
210 |         { id: "media-images", name: "Images", parentId: "media-root" },
211 |         { id: "media-videos", name: "Videos", parentId: "media-root" },
212 |       ]}'>
213 |     <property name="itemTemplate">
214 |       <HStack testId="{$item.id}" verticalAlignment="center" gap="$space-1">
215 |         <Icon name="{$item.hasChildren ? 'folder' : 'code'}" />
216 |         <Text>
217 |           ({$item.id}):
218 |         </Text>
219 |         <Text variant="strong">
220 |           {$item.name}
221 |         </Text>
222 |       </HStack>
223 |     </property>
224 |   </Tree>
225 | </App>
226 | ```
227 | 
228 | ## Dynamic tree nodes [#dynamic-tree-nodes]
229 | 
230 | When initializing the tree with its `data` property, you can set the `dynamic` property of the node to `true` (you can use a field name alias with the `dynamicField` property). When you extend a dynamic node, the tree fires the `loadChildren` event, and the nodes returned by the event handler will be the actual nodes.
231 | 
232 | By default, nodes are not dynamic.
233 | 
234 | While the child nodes are being queried, the tree node displays a spinner to indicate the loading state.
235 | 
236 | You can use the `markNodeUnloaded` exposed method to reset the state of an already loaded dynamic tree node. The next time the user expands the node, its content will be loaded again.
237 | 
238 | The following sample demonstrates this feature. Click the "Child Item 1.2" node to check how it loads its children. Click the Unload button to reload the items when the node is expanded the next time.
239 | 
240 | ```xmlui-pg display copy {16-19} height="340px" /dynamic: true/ /onLoadChildren/ name="Example: dynamic nodes"
241 | <App var.loadCount="{0}">
242 |   <Tree
243 |     testId="tree"
244 |     defaultExpanded="all"
245 |     id="tree"
246 |     itemClickExpands
247 |     data='{[
248 |       { id: 1, name: "Root Item 1", parentId: null },
249 |       { id: 2, name: "Child Item 1.1", parentId: 1 },
250 |       { id: 3, name: "Child Item 1.2", parentId: 1, dynamic: true },
251 |       { id: 4, name: "Child Item 1.3", parentId: 1 },
252 |     ]}'
253 |     onLoadChildren="(node) => {
254 |       loadCount++;
255 |       delay(1000); 
256 |       return ([
257 |         { id: 5, name: `Dynamic Item 1.2.1 (${loadCount})` },
258 |         { id: 6, name: `Dynamic Item 2.2.2 (${loadCount})` },
259 |       ])
260 |     }"
261 |     >
262 |     <property name="itemTemplate">
263 |       <HStack testId="{$item.id}" verticalAlignment="center" gap="$space-1">
264 |         <Icon name="{$item.hasChildren 
265 |           ? ($item.loadingState === 'loaded' ? 'folder' : 'folder-outline' ) 
266 |           : 'code'}" 
267 |         />
268 |         <Text>{$item.name}</Text>
269 |       </HStack>
270 |     </property>
271 |   </Tree>
272 |   <Button onClick="tree.markNodeUnloaded(3)">Unload</Button>
273 | </App>
274 | ```
275 | 
276 | ## Properties [#properties]
277 | 
278 | ### `animateExpand` (default: false) [#animateexpand-default-false]
279 | 
280 | When true, uses only the collapsed icon and rotates it for expansion instead of switching icons (default: false).
281 | 
282 | ### `autoExpandToSelection` (default: true) [#autoexpandtoselection-default-true]
283 | 
284 | Automatically expand the path to the selected item.
285 | 
286 | ### `childrenField` (default: "children") [#childrenfield-default-children]
287 | 
288 | The property name in source data for child arrays (used in hierarchy format).
289 | 
290 | ### `data` (required) [#data-required]
291 | 
292 | The data source of the tree. Format depends on the dataFormat property.
293 | 
294 | ### `dataFormat` (default: "flat") [#dataformat-default-flat]
295 | 
296 | The input data structure format: "flat" (array with parent relationships) or "hierarchy" (nested objects).
297 | 
298 | ### `defaultExpanded` (default: "none") [#defaultexpanded-default-none]
299 | 
300 | Initial expansion state: "none", "all", "first-level", or array of specific IDs.
301 | 
302 | ### `dynamicField` (default: "dynamic") [#dynamicfield-default-dynamic]
303 | 
304 | The property name in source data for dynamic loading state (default: "dynamic").
305 | 
306 | ### `expandRotation` (default: 90) [#expandrotation-default-90]
307 | 
308 | The number of degrees to rotate the collapsed icon when expanded in animate mode (default: 90).
309 | 
310 | ### `iconCollapsed` (default: "chevronright") [#iconcollapsed-default-chevronright]
311 | 
312 | The icon name to use for collapsed nodes (default: "chevronright").
313 | 
314 | ### `iconCollapsedField` (default: "iconCollapsed") [#iconcollapsedfield-default-iconcollapsed]
315 | 
316 | The property name in source data for collapsed state icons.
317 | 
318 | ### `iconExpanded` (default: "chevrondown") [#iconexpanded-default-chevrondown]
319 | 
320 | The icon name to use for expanded nodes (default: "chevrondown").
321 | 
322 | ### `iconExpandedField` (default: "iconExpanded") [#iconexpandedfield-default-iconexpanded]
323 | 
324 | The property name in source data for expanded state icons.
325 | 
326 | ### `iconField` (default: "icon") [#iconfield-default-icon]
327 | 
328 | The property name in source data for icon identifiers.
329 | 
330 | ### `iconSize` (default: "16") [#iconsize-default-16]
331 | 
332 | The size of the expand/collapse icons (default: "16").
333 | 
334 | ### `idField` (default: "id") [#idfield-default-id]
335 | 
336 | The property name in source data for unique identifiers.
337 | 
338 | ### `itemClickExpands` (default: false) [#itemclickexpands-default-false]
339 | 
340 | Whether clicking anywhere on a tree item should expand/collapse the node, not just the expand/collapse icon.
341 | 
342 | ### `itemHeight` (default: 32) [#itemheight-default-32]
343 | 
344 | The height of each tree row in pixels (default: 35).
345 | 
346 | ### `itemTemplate` [#itemtemplate]
347 | 
348 | The template for each item in the tree.
349 | 
350 | ### `nameField` (default: "name") [#namefield-default-name]
351 | 
352 | The property name in source data for display text.
353 | 
354 | ### `parentIdField` (default: "parentId") [#parentidfield-default-parentid]
355 | 
356 | The property name in source data for parent relationships (used in flat format).
357 | 
358 | ### `selectableField` (default: "selectable") [#selectablefield-default-selectable]
359 | 
360 | The property name in source data for selectable state (default: "selectable").
361 | 
362 | ### `selectedValue` [#selectedvalue]
363 | 
364 | The selected item ID in source data format.
365 | 
366 | ## Events [#events]
367 | 
368 | ### `loadChildren` [#loadchildren]
369 | 
370 | Fired when a tree node needs to load children dynamically. Should return an array of child data.
371 | 
372 | ### `nodeDidCollapse` [#nodedidcollapse]
373 | 
374 | Fired when a tree node is collapsed.
375 | 
376 | ### `nodeDidExpand` [#nodedidexpand]
377 | 
378 | Fired when a tree node is expanded.
379 | 
380 | ### `selectionDidChange` [#selectiondidchange]
381 | 
382 | Fired when the tree selection changes.
383 | 
384 | ## Exposed Methods [#exposed-methods]
385 | 
386 | ### `appendNode` [#appendnode]
387 | 
388 | Add a new node to the tree as a child of the specified parent node.
389 | 
390 | **Signature**: `appendNode(parentNodeId: string | number | null, nodeData: any): void`
391 | 
392 | - `parentNodeId`: The ID of the parent node, or null/undefined to add to root level
393 | - `nodeData`: The node data object using the format specified in dataFormat and field properties
394 | 
395 | ### `clearSelection` [#clearselection]
396 | 
397 | Clear the current selection.
398 | 
399 | **Signature**: `clearSelection(): void`
400 | 
401 | ### `collapseAll` [#collapseall]
402 | 
403 | Collapse all nodes in the tree.
404 | 
405 | **Signature**: `collapseAll(): void`
406 | 
407 | ### `collapseNode` [#collapsenode]
408 | 
409 | Collapse a specific node by its source data ID.
410 | 
411 | **Signature**: `collapseNode(nodeId: string | number): void`
412 | 
413 | - `nodeId`: The ID of the node to collapse (source data format)
414 | 
415 | ### `expandAll` [#expandall]
416 | 
417 | Expand all nodes in the tree.
418 | 
419 | **Signature**: `expandAll(): void`
420 | 
421 | ### `expandNode` [#expandnode]
422 | 
423 | Expand a specific node by its source data ID.
424 | 
425 | **Signature**: `expandNode(nodeId: string | number): void`
426 | 
427 | - `nodeId`: The ID of the node to expand (source data format)
428 | 
429 | ### `expandToLevel` [#expandtolevel]
430 | 
431 | Expand nodes up to the specified depth level (0-based).
432 | 
433 | **Signature**: `expandToLevel(level: number): void`
434 | 
435 | - `level`: The maximum depth level to expand (0 = root level only)
436 | 
437 | ### `getExpandedNodes` [#getexpandednodes]
438 | 
439 | Get an array of currently expanded node IDs in source data format.
440 | 
441 | **Signature**: `getExpandedNodes(): (string | number)[]`
442 | 
443 | ### `getNodeById` [#getnodebyid]
444 | 
445 | Get a tree node by its source data ID.
446 | 
447 | **Signature**: `getNodeById(nodeId: string | number): TreeNode | null`
448 | 
449 | - `nodeId`: The ID of the node to retrieve (source data format)
450 | 
451 | ### `getNodeLoadingState` [#getnodeloadingstate]
452 | 
453 | Get the loading state of a dynamic node.
454 | 
455 | **Signature**: `getNodeLoadingState(nodeId: string | number): NodeLoadingState`
456 | 
457 | - `nodeId`: The ID of the node to check loading state for
458 | 
459 | ### `getSelectedNode` [#getselectednode]
460 | 
461 | Get the currently selected tree node.
462 | 
463 | **Signature**: `getSelectedNode(): TreeNode | null`
464 | 
465 | ### `insertNodeAfter` [#insertnodeafter]
466 | 
467 | Insert a new node after an existing node at the same level.
468 | 
469 | **Signature**: `insertNodeAfter(afterNodeId: string | number, nodeData: any): void`
470 | 
471 | - `afterNodeId`: The ID of the existing node after which the new node should be inserted
472 | - `nodeData`: The node data object using the format specified in dataFormat and field properties
473 | 
474 | ### `insertNodeBefore` [#insertnodebefore]
475 | 
476 | Insert a new node before an existing node at the same level.
477 | 
478 | **Signature**: `insertNodeBefore(beforeNodeId: string | number, nodeData: any): void`
479 | 
480 | - `beforeNodeId`: The ID of the existing node before which the new node should be inserted
481 | - `nodeData`: The node data object using the format specified in dataFormat and field properties
482 | 
483 | ### `markNodeLoaded` [#marknodeloaded]
484 | 
485 | Mark a dynamic node as loaded.
486 | 
487 | **Signature**: `markNodeLoaded(nodeId: string | number): void`
488 | 
489 | - `nodeId`: The ID of the node to mark as loaded
490 | 
491 | ### `markNodeUnloaded` [#marknodeunloaded]
492 | 
493 | Mark a dynamic node as unloaded and collapse it.
494 | 
495 | **Signature**: `markNodeUnloaded(nodeId: string | number): void`
496 | 
497 | - `nodeId`: The ID of the node to mark as unloaded
498 | 
499 | ### `removeChildren` [#removechildren]
500 | 
501 | Remove all children (descendants) of a node while keeping the node itself.
502 | 
503 | **Signature**: `removeChildren(nodeId: string | number): void`
504 | 
505 | - `nodeId`: The ID of the parent node whose children should be removed
506 | 
507 | ### `removeNode` [#removenode]
508 | 
509 | Remove a node and all its descendants from the tree.
510 | 
511 | **Signature**: `removeNode(nodeId: string | number): void`
512 | 
513 | - `nodeId`: The ID of the node to remove (along with all its descendants)
514 | 
515 | ### `scrollIntoView` [#scrollintoview]
516 | 
517 | Scroll to a specific node and expand parent nodes as needed to make it visible.
518 | 
519 | **Signature**: `scrollIntoView(nodeId: string | number, options?: ScrollIntoViewOptions): void`
520 | 
521 | - `nodeId`: The ID of the node to scroll to (source data format)
522 | - `options`: Optional scroll options
523 | 
524 | ### `scrollToItem` [#scrolltoitem]
525 | 
526 | Scroll to a specific node if it's currently visible in the tree.
527 | 
528 | **Signature**: `scrollToItem(nodeId: string | number): void`
529 | 
530 | - `nodeId`: The ID of the node to scroll to (source data format)
531 | 
532 | ### `selectNode` [#selectnode]
533 | 
534 | Programmatically select a node by its source data ID.
535 | 
536 | **Signature**: `selectNode(nodeId: string | number): void`
537 | 
538 | - `nodeId`: The ID of the node to select (source data format)
539 | 
540 | ## Styling [#styling]
541 | 
542 | ### Theme Variables [#theme-variables]
543 | 
544 | | Variable | Default Value (Light) | Default Value (Dark) |
545 | | --- | --- | --- |
546 | | [backgroundColor](../styles-and-themes/common-units/#color)-Tree-row--hover | $color-surface-100 | $color-surface-100 |
547 | | [backgroundColor](../styles-and-themes/common-units/#color)-Tree-row--selected | $color-primary-50 | $color-primary-50 |
548 | | [borderColor](../styles-and-themes/common-units/#color)-Tree-row--focus | $color-primary-500 | $color-primary-500 |
549 | | [outlineColor](../styles-and-themes/common-units/#color)-Tree--focus | $outlineColor--focus | $outlineColor--focus |
550 | | [outlineOffset](../styles-and-themes/common-units/#size)-Tree--focus | $outlineOffset--focus | $outlineOffset--focus |
551 | | [outlineStyle](../styles-and-themes/common-units/#border)-Tree--focus | $outlineStyle--focus | $outlineStyle--focus |
552 | | [outlineWidth](../styles-and-themes/common-units/#size)-Tree--focus | $outlineWidth--focus | $outlineWidth--focus |
553 | | [textColor](../styles-and-themes/common-units/#color)-Tree | $textColor-primary | $textColor-primary |
554 | | [textColor](../styles-and-themes/common-units/#color)-Tree--hover | $textColor-primary | $textColor-primary |
555 | | [textColor](../styles-and-themes/common-units/#color)-Tree--selected | $color-primary-900 | $color-primary-900 |
556 | 
```

--------------------------------------------------------------------------------
/xmlui/tests/language-server/format.test.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { describe, test, expect } from "vitest";
  2 | import { format, type FormatOptions } from "../../src/language-server/services/format";
  3 | import { createXmlUiParser, toDbgString } from "../../src/parsers/xmlui-parser";
  4 | 
  5 | describe("XML Formatter", () => {
  6 |   describe("Format Options", () => {
  7 |     test("should respect custom indentation", () => {
  8 |       const input = "<Fragment><Text>Content</Text></Fragment>";
  9 |       const result = formatTwice(input, { tabSize: 4, insertSpaces: true });
 10 | 
 11 |       expect(result).toEqual(
 12 |         `<Fragment>
 13 |     <Text>
 14 |         Content
 15 |     </Text>
 16 | </Fragment>`,
 17 |       );
 18 |     });
 19 | 
 20 |     test("should respect tab indentation", () => {
 21 |       const input = "<Fragment><Text>Content</Text></Fragment>";
 22 |       const result = formatTwice(input, { tabSize: 4, insertSpaces: false });
 23 | 
 24 |       expect(result).toEqual(
 25 |         `<Fragment>
 26 | \t<Text>
 27 | \t\tContent
 28 | \t</Text>
 29 | </Fragment>`,
 30 |       );
 31 |     });
 32 |   });
 33 | 
 34 |   describe("Basic XML Formatting", () => {
 35 |     test("should format simple xmlui fragment", () => {
 36 |       const input = '<Fragment><Text testId="textShort" width="200px">Short</Text></Fragment>';
 37 |       const result = formatTwice(input);
 38 | 
 39 |       expect(result).toEqual(
 40 |         `<Fragment>
 41 |   <Text testId="textShort" width="200px">
 42 |     Short
 43 |   </Text>
 44 | </Fragment>`,
 45 |       );
 46 |     });
 47 | 
 48 |     test("should format nested xmlui elements", () => {
 49 |       const input =
 50 |         '<Fragment><Text testId="textShort" width="200px">Short</Text><Text testId="textLong" width="200px" maxLines="2">Long text content</Text></Fragment>';
 51 |       const result = formatTwice(input);
 52 | 
 53 |       expect(result).toEqual(
 54 |         `<Fragment>
 55 |   <Text testId="textShort" width="200px">
 56 |     Short
 57 |   </Text>
 58 |   <Text testId="textLong" width="200px" maxLines="2">
 59 |     Long text content
 60 |   </Text>
 61 | </Fragment>`,
 62 |       );
 63 |     });
 64 | 
 65 |     test("should preserve text content", () => {
 66 |       const input =
 67 |         "<Text>Though this long text does not fit into a single line, please do not break it!</Text>";
 68 |       const result = formatTwice(input);
 69 | 
 70 |       expect(result).toEqual(
 71 |         `<Text>
 72 |   Though this long text does not fit into a single line, please do not break it!
 73 | </Text>`,
 74 |       );
 75 |     });
 76 | 
 77 |     test("should format self-closing tags", () => {
 78 |       const input = '<Fragment><Input type="text"/><Button/></Fragment>';
 79 |       const result = formatTwice(input);
 80 | 
 81 |       expect(result).toEqual(
 82 |         `<Fragment>
 83 |   <Input type="text" />
 84 |   <Button />
 85 | </Fragment>`,
 86 |       );
 87 |     });
 88 | 
 89 |     test("should format key-only attribue", () => {
 90 |       const input = '<Fragment><Input type="text" enabled/><Button/></Fragment>';
 91 |       const result = formatTwice(input);
 92 | 
 93 |       expect(result).toEqual(
 94 |         `<Fragment>
 95 |   <Input type="text" enabled />
 96 |   <Button />
 97 | </Fragment>`,
 98 |       );
 99 |     });
100 |   });
101 | 
102 |   describe("CDATA Handling", () => {
103 |     test("should preserve CDATA sections", () => {
104 |       const input = "<Fragment><Text><![CDATA[Some <special> content & more]]></Text></Fragment>";
105 |       const result = formatTwice(input);
106 | 
107 |       expect(result).toEqual(
108 |         `<Fragment>
109 |   <Text>
110 |     <![CDATA[Some <special> content & more]]>
111 |   </Text>
112 | </Fragment>`,
113 |       );
114 |     });
115 | 
116 |     test("should format XML with multiple CDATA sections", () => {
117 |       const input =
118 |         "<Fragment><Text><![CDATA[First CDATA]]></Text><Text><![CDATA[Second CDATA with <tags>]]></Text></Fragment>";
119 |       const result = formatTwice(input);
120 | 
121 |       expect(result).toEqual(
122 |         `<Fragment>
123 |   <Text>
124 |     <![CDATA[First CDATA]]>
125 |   </Text>
126 |   <Text>
127 |     <![CDATA[Second CDATA with <tags>]]>
128 |   </Text>
129 | </Fragment>`,
130 |       );
131 |     });
132 | 
133 |     test("should handle CDATA with special characters", () => {
134 |       const input = "<Text><![CDATA[Content with & < > \" ' characters]]></Text>";
135 |       const result = formatTwice(input);
136 | 
137 |       expect(result).toEqual(
138 |         `<Text>
139 |   <![CDATA[Content with & < > " ' characters]]>
140 | </Text>`,
141 |       );
142 |     });
143 |   });
144 | 
145 |   describe("newlines", () => {
146 |     test("keeps single blank line", () => {
147 |       const result = formatTwice("<A />\n\n<A />");
148 |       expect(result).toEqual(`<A />\n\n<A />`);
149 |     });
150 | 
151 |     test("converts single whitespace only line to blank line", () => {
152 |       const result = formatTwice("<A />\n   \n<A />");
153 |       expect(result).toEqual(`<A />\n\n<A />`);
154 |     });
155 | 
156 |     test("keeps blank line around comment only line", () => {
157 |       const result = formatTwice(`<A />
158 | 
159 | <!--c-->
160 | 
161 | <A />`);
162 |       expect(result).toEqual(`<A />
163 | 
164 | <!--c-->
165 | 
166 | <A />`);
167 |     });
168 | 
169 |     test("collapses multiple blank lines around comment only line", () => {
170 |       const result = formatTwice(`<A />
171 | 
172 | 
173 |   <!--c-->
174 | 
175 | 
176 | <A />`);
177 |       expect(result).toEqual(`<A />
178 | 
179 | <!--c-->
180 | 
181 | <A />`);
182 |     });
183 |     test("collapses multiple blank lines around 2 comment only line", () => {
184 |       const result = formatTwice(`<A />
185 | 
186 | 
187 |   <!--c--><!--c-->
188 | 
189 | 
190 | <A />`);
191 |       expect(result).toEqual(`<A />
192 | 
193 | <!--c-->
194 | <!--c-->
195 | 
196 | <A />`);
197 |     });
198 | 
199 |     test("collapses multiple blank lines into single one", () => {
200 |       const result = formatTwice("<A />\n\n\n<A />");
201 |       expect(result).toEqual(`<A />\n\n<A />`);
202 |     });
203 | 
204 |     test("collapses multiple whitespace only lines into single blank line", () => {
205 |       const result = formatTwice("<A />\n    \n  \n<A />");
206 |       expect(result).toEqual(`<A />\n\n<A />`);
207 |     });
208 |   });
209 | 
210 |   describe("comments", () => {
211 |     test("should handle comment before tag name", () => {
212 |       const input = `<<!--c-->n attr="val" attr2>
213 |   text1
214 |   <n2
215 |     attr3="val2"
216 |     attr4 />
217 |   text2
218 | </n>`;
219 |       const result = formatTwice(input);
220 | 
221 |       expect(result).toEqual(
222 |         `< <!--c--> n attr="val" attr2>
223 |   text1
224 |   <n2
225 |     attr3="val2"
226 |     attr4 />
227 |   text2
228 | </n>`,
229 |       );
230 |     });
231 | 
232 |     test("should handle comment after tag name", () => {
233 |       const input = `<n<!--c--> attr="val" attr2>
234 |   text1
235 |   <n2
236 |     attr3="val2"
237 |     attr4 />
238 |   text2
239 | </n>`;
240 |       const result = formatTwice(input);
241 | 
242 |       expect(result).toEqual(
243 |         `<n <!--c--> attr="val" attr2>
244 |   text1
245 |   <n2
246 |     attr3="val2"
247 |     attr4 />
248 |   text2
249 | </n>`,
250 |       );
251 |     });
252 | 
253 |     test("should handle comment between attribute name and =", () => {
254 |       const input = `<n attr<!--c-->="val" attr2>
255 |   text1
256 |   <n2
257 |     attr3="val2"
258 |     attr4 />
259 |   text2
260 | </n>`;
261 |       const result = formatTwice(input);
262 | 
263 |       expect(result).toEqual(
264 |         `<n attr <!--c--> ="val" attr2>
265 |   text1
266 |   <n2
267 |     attr3="val2"
268 |     attr4 />
269 |   text2
270 | </n>`,
271 |       );
272 |     });
273 | 
274 |     test("should handle comment before attribute value", () => {
275 |       const input = `<n attr=<!--c-->"val" attr2>
276 |   text1
277 |   <n2
278 |     attr3="val2"
279 |     attr4 />
280 |   text2
281 | </n>`;
282 |       const result = formatTwice(input);
283 | 
284 |       expect(result).toEqual(
285 |         `<n attr= <!--c--> "val" attr2>
286 |   text1
287 |   <n2
288 |     attr3="val2"
289 |     attr4 />
290 |   text2
291 | </n>`,
292 |       );
293 |     });
294 | 
295 |     test("should handle comment between attributes", () => {
296 |       const input = `<n attr="val"<!--c--> attr2>
297 |   text1
298 |   <n2
299 |     attr3="val2"
300 |     attr4 />
301 |   text2
302 | </n>`;
303 |       const result = formatTwice(input);
304 | 
305 |       expect(result).toEqual(
306 |         `<n attr="val" <!--c--> attr2>
307 |   text1
308 |   <n2
309 |     attr3="val2"
310 |     attr4 />
311 |   text2
312 | </n>`,
313 |       );
314 |     });
315 | 
316 |     test("should handle comment after last attribute", () => {
317 |       const input = `<n attr="val" attr2<!--c-->>
318 |   text1
319 |   <n2
320 |     attr3="val2"
321 |     attr4 />
322 |   text2
323 | </n>`;
324 |       const result = formatTwice(input);
325 | 
326 |       expect(result).toEqual(
327 |         `<n attr="val" attr2 <!--c-->>
328 |   text1
329 |   <n2
330 |     attr3="val2"
331 |     attr4 />
332 |   text2
333 | </n>`,
334 |       );
335 |     });
336 | 
337 |     test("should handle comment after opening tag", () => {
338 |       const input = `<n attr="val" attr2><!--c-->
339 |   text1
340 |   <n2
341 |     attr3="val2"
342 |     attr4 />
343 |   text2
344 | </n>`;
345 |       const result = formatTwice(input);
346 | 
347 |       expect(result).toEqual(
348 |         `<n attr="val" attr2>
349 |   <!--c-->
350 |   text1
351 |   <n2
352 |     attr3="val2"
353 |     attr4 />
354 |   text2
355 | </n>`,
356 |       );
357 |     });
358 | 
359 |     test("should handle comment before text content", () => {
360 |       const input = `<n attr="val" attr2>
361 |   <!--c-->text1
362 |   <n2
363 |     attr3="val2"
364 |     attr4 />
365 |   text2
366 | </n>`;
367 |       const result = formatTwice(input);
368 | 
369 |       expect(result).toEqual(
370 |         `<n attr="val" attr2>
371 |   <!--c-->text1
372 |   <n2
373 |     attr3="val2"
374 |     attr4 />
375 |   text2
376 | </n>`,
377 |       );
378 |     });
379 | 
380 |     test("should handle comment after text content", () => {
381 |       const input = `<n attr="val" attr2>
382 |   text1<!--c-->
383 |   <n2
384 |     attr3="val2"
385 |     attr4 />
386 |   text2
387 | </n>`;
388 |       const result = formatTwice(input);
389 | 
390 |       expect(result).toEqual(
391 |         `<n attr="val" attr2>
392 |   text1 <!--c-->
393 |   <n2
394 |     attr3="val2"
395 |     attr4 />
396 |   text2
397 | </n>`,
398 |       );
399 |     });
400 | 
401 |     test("should handle comment before child element", () => {
402 |       const input = `<n attr="val" attr2>
403 |   text1
404 |   <!--c--><n2
405 |     attr3="val2"
406 |     attr4 />
407 |   text2
408 | </n>`;
409 |       const result = formatTwice(input);
410 | 
411 |       expect(result).toEqual(
412 |         `<n attr="val" attr2>
413 |   text1
414 |   <!--c-->
415 |   <n2
416 |     attr3="val2"
417 |     attr4 />
418 |   text2
419 | </n>`,
420 |       );
421 |     });
422 | 
423 |     test("should handle comment in self closing tag after name", () => {
424 |       const input = `<n attr="val" attr2>
425 |   text1
426 |   <n2<!--c-->
427 |     attr3="val2"
428 |     attr4 />
429 |   text2
430 | </n>`;
431 |       const result = formatTwice(input);
432 | 
433 |       expect(result).toEqual(
434 |         `<n attr="val" attr2>
435 |   text1
436 |   <n2
437 |     <!--c-->
438 |     attr3="val2"
439 |     attr4 />
440 |   text2
441 | </n>`,
442 |       );
443 |     });
444 | 
445 |     test("should handle comment in self closing tag after newline name", () => {
446 |       const input = `<n attr="val" attr2>
447 |   text1
448 |   <n2
449 |     <!--c-->attr3="val2"
450 |     attr4 />
451 |   text2
452 | </n>`;
453 |       const result = formatTwice(input);
454 | 
455 |       expect(result).toEqual(
456 |         `<n attr="val" attr2>
457 |   text1
458 |   <n2
459 |     <!--c-->
460 |     attr3="val2"
461 |     attr4 />
462 |   text2
463 | </n>`,
464 |       );
465 |     });
466 | 
467 |     test("should handle comment in self closing tag between attributes", () => {
468 |       const input = `<n attr="val" attr2>
469 |   text1
470 |   <n2
471 |     attr3="val2"<!--c-->
472 |     attr4 />
473 |   text2
474 | </n>`;
475 |       const result = formatTwice(input);
476 | 
477 |       expect(result).toEqual(
478 |         `<n attr="val" attr2>
479 |   text1
480 |   <n2
481 |     attr3="val2"
482 |     <!--c-->
483 |     attr4 />
484 |   text2
485 | </n>`,
486 |       );
487 |     });
488 | 
489 |     test("should handle comment before self-closing tag closing", () => {
490 |       const input = `<n attr="val" attr2>
491 |   text1
492 |   <n2
493 |     attr3="val2"
494 |     attr4<!--c--> />
495 |   text2
496 | </n>`;
497 |       const result = formatTwice(input);
498 | 
499 |       expect(result).toEqual(
500 |         `<n attr="val" attr2>
501 |   text1
502 |   <n2
503 |     attr3="val2"
504 |     attr4
505 |     <!--c--> />
506 |   text2
507 | </n>`,
508 |       );
509 |     });
510 | 
511 |     test("should handle comment between text and closing tag", () => {
512 |       const input = `<n attr="val" attr2>
513 |   text1
514 |   <n2
515 |     attr3="val2"
516 |     attr4 />
517 |   text2<!--c-->
518 | </n>`;
519 |       const result = formatTwice(input);
520 | 
521 |       expect(result).toEqual(
522 |         `<n attr="val" attr2>
523 |   text1
524 |   <n2
525 |     attr3="val2"
526 |     attr4 />
527 |   text2 <!--c-->
528 | </n>`,
529 |       );
530 |     });
531 | 
532 |     test("should handle comment between text with newline and closing tag", () => {
533 |       const input = `<n attr="val" attr2>
534 |   text1
535 |   <n2
536 |     attr3="val2"
537 |     attr4 />
538 |   text2
539 |   <!--c-->
540 | </n>`;
541 |       const result = formatTwice(input);
542 | 
543 |       expect(result).toEqual(
544 |         `<n attr="val" attr2>
545 |   text1
546 |   <n2
547 |     attr3="val2"
548 |     attr4 />
549 |   text2
550 |   <!--c-->
551 | </n>`,
552 |       );
553 |     });
554 | 
555 |     test("should handle comment right after last tag", () => {
556 |       const input = `<n attr="val" attr2>
557 |   text1
558 |   <n2
559 |     attr3="val2"
560 |     attr4 />
561 |   text2
562 | </n><!--c-->`;
563 |       const result = formatTwice(input);
564 | 
565 |       expect(result).toEqual(
566 |         `<n attr="val" attr2>
567 |   text1
568 |   <n2
569 |     attr3="val2"
570 |     attr4 />
571 |   text2
572 | </n> <!--c-->`,
573 |       );
574 |     });
575 | 
576 |     test("should handle comment after closeNodeStart", () => {
577 |       const input = `<n attr="val" attr2>
578 |   text1
579 |   <n2
580 |     attr3="val2"
581 |     attr4 />
582 |   text2
583 | </<!--c-->n>`;
584 |       const result = formatTwice(input);
585 | 
586 |       expect(result).toEqual(
587 |         `<n attr="val" attr2>
588 |   text1
589 |   <n2
590 |     attr3="val2"
591 |     attr4 />
592 |   text2
593 | </ <!--c--> n>`,
594 |       );
595 |     });
596 | 
597 |     test("should handle comment after closeing tag name", () => {
598 |       const input = `<n attr="val" attr2>
599 |   text1
600 |   <n2
601 |     attr3="val2"
602 |     attr4 />
603 |   text2
604 | </n<!--c-->>`;
605 |       const result = formatTwice(input);
606 | 
607 |       expect(result).toEqual(
608 |         `<n attr="val" attr2>
609 |   text1
610 |   <n2
611 |     attr3="val2"
612 |     attr4 />
613 |   text2
614 | </n <!--c-->>`,
615 |       );
616 |     });
617 | 
618 |     test("single comment between tags does not break line", () => {
619 |       const input = `<n>
620 |   <n1 /> <!-- c -->
621 |   <n2 />
622 | </n>`;
623 |       const result = formatTwice(input);
624 | 
625 |       expect(result).toEqual(
626 |         `<n>
627 |   <n1 /> <!-- c -->
628 |   <n2 />
629 | </n>`,
630 |       );
631 |     });
632 | 
633 |     test("single comment between tags keeps linebreak", () => {
634 |       const input = `<n>
635 |   <n1 />
636 | <!-- c -->
637 |   <n2 />
638 | </n>`;
639 |       const result = formatTwice(input);
640 | 
641 |       expect(result).toEqual(
642 |         `<n>
643 |   <n1 />
644 |   <!-- c -->
645 |   <n2 />
646 | </n>`,
647 |       );
648 |     });
649 | 
650 |     test("adds newline after single comment between tags", () => {
651 |       const input = `<n>
652 |   <n1 />
653 | <!-- c --><n2 />
654 | </n>`;
655 |       const result = formatTwice(input);
656 | 
657 |       expect(result).toEqual(
658 |         `<n>
659 |   <n1 />
660 |   <!-- c -->
661 |   <n2 />
662 | </n>`,
663 |       );
664 |     });
665 | 
666 |     test("single comment as the only content in tag", () => {
667 |       const input = `<n> <!-- c --> </n>`;
668 |       const result = formatTwice(input);
669 | 
670 |       expect(result).toEqual(`<n> <!-- c -->
671 | </n>`);
672 |     });
673 | 
674 |     test("2 comments as the only content in tag", () => {
675 |       const input = `<n> <!-- c --> <!-- d --> </n>`;
676 |       const result = formatTwice(input);
677 | 
678 |       expect(result).toEqual(
679 |         `<n> <!-- c -->
680 |   <!-- d -->
681 | </n>`,
682 |       );
683 |     });
684 | 
685 |     test("single comment, error node in before attributes", () => {
686 |       const input = `<n attr="val" <!-- long, long commonet long, long commonet long, long commonet long, long commonet --> attr2 ? ></n2>`;
687 |       const result = formatTwice(input);
688 | 
689 |       expect(result).toEqual(
690 |         `<n
691 |   attr="val"
692 |   <!-- long, long commonet long, long commonet long, long commonet long, long commonet -->
693 |   attr2 ?></n2>`,
694 |       );
695 |     });
696 | 
697 |     test("single comment before ':' in tag name ", () => {
698 |       const input = `<ns<!-- c -->:n attr="val" />`;
699 |       const result = formatTwice(input);
700 | 
701 |       expect(result).toEqual(`<ns <!-- c --> :n attr="val" />`);
702 |     });
703 | 
704 |     test("single comment after ':' in tag name ", () => {
705 |       const input = `<ns:<!-- c -->n attr="val" />`;
706 |       const result = formatTwice(input);
707 | 
708 |       expect(result).toEqual(`<ns: <!-- c --> n attr="val" />`);
709 |     });
710 | 
711 |     test("single comment before ':' in attr name", () => {
712 |       const input = `<n ns<!-- c -->:attr="val" />`;
713 |       const result = formatTwice(input);
714 | 
715 |       expect(result).toEqual(`<n ns <!-- c --> :attr="val" />`);
716 |     });
717 | 
718 |     test("single comment after ':' in attr name", () => {
719 |       const input = `<n ns:<!-- c -->attr="val" />`;
720 |       const result = formatTwice(input);
721 | 
722 |       expect(result).toEqual(`<n ns: <!-- c --> attr="val" />`);
723 |     });
724 | 
725 |     test("should handle comments before eof", () => {
726 |       const input = `<Fragment><Text>Content</Text></Fragment>
727 |         <!-- This is a comment -->`;
728 |       const result = formatTwice(input);
729 | 
730 |       expect(result).toEqual(
731 |         `<Fragment>
732 |   <Text>
733 |     Content
734 |   </Text>
735 | </Fragment>
736 | <!-- This is a comment -->`,
737 |       );
738 |     });
739 | 
740 |     test("should handle comments after text, before eof", () => {
741 |       const input = `Content        <!-- c-->`;
742 |       const result = formatTwice(input);
743 | 
744 |       expect(result).toEqual(`Content <!-- c-->`);
745 |     });
746 |   });
747 |   describe("Edge Cases", () => {
748 |     test("should handle empty string", () => {
749 |       const result = formatTwice("");
750 |       expect(result).toEqual("");
751 |     });
752 | 
753 |     test("should handle whitespace-only string", () => {
754 |       const result = formatTwice("   \n  \t  ");
755 |       expect(result).toEqual("");
756 |     });
757 | 
758 |     test("should handle single self-closing tag", () => {
759 |       const input = '<Input type="text"/>';
760 |       const result = formatTwice(input);
761 | 
762 |       expect(result).toEqual(`<Input type="text" />`);
763 |     });
764 | 
765 |     test("should handle deeply nested elements", () => {
766 |       const input =
767 |         "<Fragment><Container><Section><Text>Deep content</Text></Section></Container></Fragment>";
768 |       const result = formatTwice(input);
769 | 
770 |       expect(result).toEqual(
771 |         `<Fragment>
772 |   <Container>
773 |     <Section>
774 |       <Text>
775 |         Deep content
776 |       </Text>
777 |     </Section>
778 |   </Container>
779 | </Fragment>`,
780 |       );
781 |     });
782 | 
783 |     test("should handle mixed content", () => {
784 |       const input = "<Text>Before<Bold>bold</Bold>After</Text>";
785 |       const result = formatTwice(input);
786 | 
787 |       expect(result).toEqual(
788 |         `<Text>
789 |   Before
790 |   <Bold>
791 |     bold
792 |   </Bold>
793 |   After
794 | </Text>`,
795 |       );
796 |     });
797 |   });
798 | 
799 |   describe("Real-world xmlui Examples", () => {
800 |     test("should format typical xmlui component", () => {
801 |       const input = `<Fragment>
802 |   <Text testId="textShort" width="200px">Short</Text>
803 |   <Text testId="textLong" width="200px" maxLines="2">
804 |     Though this long text does not fit into a single line, please do not break it!
805 |   </Text>
806 | </Fragment>`;
807 | 
808 |       const result = formatTwice(input);
809 | 
810 |       expect(result).toEqual(
811 |         `<Fragment>
812 |   <Text testId="textShort" width="200px">
813 |     Short
814 |   </Text>
815 |   <Text testId="textLong" width="200px" maxLines="2">
816 |     Though this long text does not fit into a single line, please do not break it!
817 |   </Text>
818 | </Fragment>`,
819 |       );
820 |     });
821 | 
822 |     test("should format long attribute list in paired tag", () => {
823 |       const input =
824 |         '<Button testId="submitBtn" variant="primary" size="large" disabled="false" onClick="handleClick">Submit</Button>';
825 |       const result = formatTwice(input);
826 | 
827 |       expect(result).toEqual(
828 |         `<Button
829 |   testId="submitBtn"
830 |   variant="primary"
831 |   size="large"
832 |   disabled="false"
833 |   onClick="handleClick">
834 |   Submit
835 | </Button>`,
836 |       );
837 |     });
838 | 
839 |     test("should format long attribute list in self-closing tag", () => {
840 |       const input =
841 |         '<Button testId="submitBtn" variant="primary" size="large" disabled="false" onClick="handleClick"/>';
842 |       const result = formatTwice(input);
843 | 
844 |       expect(result).toEqual(
845 |         `<Button
846 |   testId="submitBtn"
847 |   variant="primary"
848 |   size="large"
849 |   disabled="false"
850 |   onClick="handleClick" />`,
851 |       );
852 |     });
853 | 
854 |     test("should format complex xmlui layout", () => {
855 |       const input =
856 |         "<Fragment><Header><Title>Page Title</Title></Header><Main><Section><Text>Content</Text><Button>Action</Button></Section></Main><Footer><Text>Footer content</Text></Footer></Fragment>";
857 |       const result = formatTwice(input);
858 | 
859 |       expect(result).toEqual(
860 |         `<Fragment>
861 |   <Header>
862 |     <Title>
863 |       Page Title
864 |     </Title>
865 |   </Header>
866 |   <Main>
867 |     <Section>
868 |       <Text>
869 |         Content
870 |       </Text>
871 |       <Button>
872 |         Action
873 |       </Button>
874 |     </Section>
875 |   </Main>
876 |   <Footer>
877 |     <Text>
878 |       Footer content
879 |     </Text>
880 |   </Footer>
881 | </Fragment>`,
882 |       );
883 |     });
884 |   });
885 | 
886 |   describe("Additional Test Cases", () => {
887 |     test("should handle multiple comments in same line", () => {
888 |       const input = `<Fragment><!-- comment1 --><!-- comment2 --><Text>Content</Text></Fragment>`;
889 |       const result = formatTwice(input);
890 | 
891 |       expect(result).toEqual(
892 |         `<Fragment> <!-- comment1 -->
893 |   <!-- comment2 -->
894 |   <Text>
895 |     Content
896 |   </Text>
897 | </Fragment>`,
898 |       );
899 |     });
900 | 
901 |     test("should handle XML with namespaces", () => {
902 |       const input = `<ns:Fragment xmlns:ns="http://example.com">
903 | <ns:Text>Content</ns:Text>
904 | </ns:Fragment>`;
905 |       const result = formatTwice(input);
906 | 
907 |       expect(result).toEqual(
908 |         `<ns:Fragment xmlns:ns="http://example.com">
909 |   <ns:Text>
910 |     Content
911 |   </ns:Text>
912 | </ns:Fragment>`,
913 |       );
914 |     });
915 | 
916 |     test("should handle XML with escaped content", () => {
917 |       const input = `<Fragment>
918 | <Text>&lt;div&gt;Content&lt;/div&gt; &amp; &quot;quotes&quot;</Text>
919 | </Fragment>`;
920 |       const result = formatTwice(input);
921 | 
922 |       expect(result).toEqual(
923 |         `<Fragment>
924 |   <Text>
925 |     &lt;div&gt;Content&lt;/div&gt; &amp; &quot;quotes&quot;
926 |   </Text>
927 | </Fragment>`,
928 |       );
929 |     });
930 | 
931 |     test("should handle XML with mixed line endings", () => {
932 |       const input = `<Fragment>\r\n<Text>Content</Text>\r\n</Fragment>`;
933 |       const result = formatTwice(input);
934 | 
935 |       expect(result).toEqual(
936 |         `<Fragment>
937 |   <Text>
938 |     Content
939 |   </Text>
940 | </Fragment>`,
941 |       );
942 |     });
943 | 
944 |     test("should handle XML with trailing whitespace", () => {
945 |       const input = `<Fragment/>     `;
946 |       const result = formatTwice(input);
947 | 
948 |       expect(result).toEqual(`<Fragment />`);
949 |     });
950 | 
951 |     test("should handle XML with very long lines", () => {
952 |       const input = `<Fragment><Text attr1="value1" attr2="value2" attr3="value3" attr4="value4" attr5="value5" attr6="value6" attr7="value7" attr8="value8" attr9="value9" attr10="value10">text content</Text></Fragment>`;
953 |       const result = formatTwice(input);
954 | 
955 |       expect(result).toEqual(
956 |         `<Fragment>
957 |   <Text
958 |     attr1="value1"
959 |     attr2="value2"
960 |     attr3="value3"
961 |     attr4="value4"
962 |     attr5="value5"
963 |     attr6="value6"
964 |     attr7="value7"
965 |     attr8="value8"
966 |     attr9="value9"
967 |     attr10="value10">
968 |     text content
969 |   </Text>
970 | </Fragment>`,
971 |       );
972 |     });
973 |   });
974 | });
975 | 
976 | function formatFromString(
977 |   input: string,
978 |   options: FormatOptions = { tabSize: 2, insertSpaces: true },
979 | ) {
980 |   const parser = createXmlUiParser(input);
981 |   const { node } = parser.parse();
982 |   const defaultOptions: FormatOptions = { insertSpaces: true, tabSize: 2, ...options };
983 | 
984 |   return format(node, parser.getText, defaultOptions);
985 | }
986 | 
987 | /* also tests idempotency */
988 | function formatTwice(input: string, options: FormatOptions = { tabSize: 2, insertSpaces: true }) {
989 |   const firstFormat = formatFromString(input, options);
990 |   const secondFormat = formatFromString(firstFormat, options);
991 | 
992 |   expect(firstFormat).toBe(secondFormat);
993 |   return firstFormat;
994 | }
995 | 
```

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

```markdown
  1 | # Components Overview [#components-overview]
  2 | 
  3 | | Component | Description |
  4 | | :---: | --- |
  5 | | [APICall](./APICall) | `APICall` creates, updates or deletes data on the backend, versus [`DataSource`](/components/DataSource) which fetches data. Unlike DataSource, APICall doesn't automatically execute - you must trigger it manually with the `execute()` method, typically from form submissions or button clicks. |
  6 | | [App](./App) | The `App` component is the root container that defines your application's overall structure and layout. It provides a complete UI framework with built-in navigation, header, footer, and content areas that work together seamlessly. |
  7 | | [AppHeader](./AppHeader) | `AppHeader` defines the top navigation bar of your application within the [`App`](/components/App) component. It automatically handles logo placement, application title, and user profile areas with built-in responsive behavior. |
  8 | | [AppState](./AppState) | `AppState` is an invisible component that provides global state management across your entire application. Unlike component variables that are scoped locally, AppState allows any component to access and update shared state without prop drilling. |
  9 | | [AutoComplete](./AutoComplete) | `AutoComplete` is a searchable dropdown input that allows users to type and filter through options, with support for single or multiple selections. Unlike a basic [`Select`](/components/Select), it provides type-ahead functionality and can allow users to create new options. |
 10 | | [Avatar](./Avatar) | `Avatar` displays a user or entity's profile picture as a circular image, with automatic fallback to initials when no image is provided. It's commonly used in headers, user lists, comments, and anywhere you need to represent a person or organization. |
 11 | | [Backdrop](./Backdrop) | The `Backdrop` component is a semi-transparent overlay that appears on top of its child component to obscure or highlight the content behind it. |
 12 | | [Badge](./Badge) | `Badge` displays small text labels with colored backgrounds, commonly used for status indicators, categories, tags, and counts. It supports dynamic color mapping based on content values, useful for status systems and data categorization. |
 13 | | [BarChart](./BarChart) | `BarChart` displays data as horizontal or vertical bars, supporting both grouped and stacked layouts. It's ideal for comparing values across categories, showing revenue trends, or displaying any quantitative data over time or categories. |
 14 | | [Bookmark](./Bookmark) | As its name suggests, this component places a bookmark into its parent component's view. The component has an `id` that you can use in links to navigate (scroll to) the bookmark's location. |
 15 | | [Breakout](./Breakout) | The `Breakout` component creates a breakout section. It allows its child to occupy the entire width of the UI even if the app or the parent container constrains the maximum content width. |
 16 | | [Button](./Button) | `Button` is the primary interactive component for triggering actions like form submissions, navigation, opening modals, and API calls. It supports multiple visual styles and sizes to match different UI contexts and importance levels. |
 17 | | [Card](./Card) | `Card` is a versatile container that groups related content with a visual boundary, typically featuring background color, padding, borders, and rounded corners. It's ideal for organizing information, creating sections, and establishing visual hierarchy in your interface. |
 18 | | [Carousel](./Carousel) | This component displays a slideshow by cycling through elements (images, text, or custom slides) like a carousel. |
 19 | | [ChangeListener](./ChangeListener) | `ChangeListener` is an invisible component that watches for changes in values and triggers actions in response. It's essential for creating reactive behavior when you need to respond to data changes, state updates, or component property modifications outside of normal event handlers. |
 20 | | [Checkbox](./Checkbox) | `Checkbox` allows users to make binary choices with a clickable box that shows checked/unchecked states. It's essential for settings, preferences, multi-select lists, and accepting terms or conditions. |
 21 | | [CHStack](./CHStack) | This component represents a stack that renders its contents horizontally and aligns that in the center along both axes. |
 22 | | [ColorPicker](./ColorPicker) | `ColorPicker` enables users to choose colors by specifying RGB, HSL, or HEX values. |
 23 | | [Column](./Column) | `Column` defines the structure and behavior of individual table columns within a [`Table`](/components/Table) component. Each Column controls data binding, header display, sorting capabilities, sizing, and can contain any XMLUI components for rich cell content. |
 24 | | [ContentSeparator](./ContentSeparator) | `ContentSeparator` creates visual dividers between content sections using horizontal or vertical lines. It's essential for improving readability by breaking up dense content, separating list items, or creating clear boundaries between different UI sections. |
 25 | | [CVStack](./CVStack) | This component represents a stack that renders its contents vertically and aligns that in the center along both axes. |
 26 | | [DataSource](./DataSource) | `DataSource` fetches and caches data from API endpoints, versus [`APICall`](/components/APICall) which creates, updates or deletes data. |
 27 | | [DateInput](./DateInput) | `DateInput` provides a text-based date input interface for selecting single dates or date ranges, with direct keyboard input similar to TimeInput. It offers customizable formatting and validation options without dropdown calendars. |
 28 | | [DatePicker](./DatePicker) | `DatePicker` provides an interactive calendar interface for selecting single dates or date ranges, with customizable formatting and validation options. It displays a text input that opens a calendar popup when clicked, offering both keyboard and mouse interaction. |
 29 | | [DonutChart](./DonutChart) | A derivative of [PieChart](/components/PieChart) with a hollow center. Note that the height of the component or its parent needs to be set explicitly. |
 30 | | [DropdownMenu](./DropdownMenu) | `DropdownMenu` provides a space-efficient way to present multiple options or actions through a collapsible interface. When clicked, the trigger button reveals a menu that can include items, separators, and nested submenus, making it ideal for navigation, action lists, or any situation requiring many options without permanent screen space. |
 31 | | [EmojiSelector](./EmojiSelector) | `EmojiSelector` enables users to browse, search and select emojis from their system's native emoji set. |
 32 | | [ExpandableItem](./ExpandableItem) | `ExpandableItem` creates expandable/collapsible section, similar to the HTML details disclosure element. When the user clicks on the `summary` the content expands or collapses. |
 33 | | [FileInput](./FileInput) | `FileInput` enables users to select files from their device's file system for upload or processing. It combines a text field displaying selected files with a customizable button that opens the system file browser. Use it for forms, media uploads, and document processing workflows. |
 34 | | [FileUploadDropZone](./FileUploadDropZone) | `FileUploadDropZone` enables users to upload files by dragging and dropping files from their local file system onto a designated area within the UI. |
 35 | | [FlowLayout](./FlowLayout) | `FlowLayout` positions content in rows with automatic wrapping. When items exceed the available horizontal space, they automatically wrap to a new line. |
 36 | | [Footer](./Footer) | `Footer` provides a designated area at the bottom of your application for footer content such as branding, copyright notices, or utility controls like theme toggles. |
 37 | | [Form](./Form) | `Form` provides a structured container for collecting and validating user input, with built-in data binding, validation, and submission handling. It automatically manages form state and provides context for nested form controls to work together. |
 38 | | [FormItem](./FormItem) | `FormItem` wraps individual input controls within a `Form`, providing data binding, validation, labeling, and layout functionality. It connects form controls to the parent form's data model and handles validation feedback automatically. **Note:** `FormItem` must be used inside a `Form` component. |
 39 | | [FormSection](./FormSection) | `FormSection` groups elements within a `Form`. Child components are placed in a [FlowLayout](/components/FlowLayout). |
 40 | | [Fragment](./Fragment) | `Fragment` provides conditional rendering. You can use `when=` on any component to render it conditionally, use `Fragment` to apply `when` to a group of components. |
 41 | | [H1](./H1) | Represents a heading level 1 text |
 42 | | [H2](./H2) | Represents a heading level 2 text |
 43 | | [H3](./H3) | Represents a heading level 3 text |
 44 | | [H4](./H4) | Represents a heading level 4 text |
 45 | | [H5](./H5) | Represents a heading level 5 text |
 46 | | [H6](./H6) | Represents a heading level 6 text |
 47 | | [Heading](./Heading) | `Heading` displays hierarchical text headings with semantic importance levels from H1 to H6, following HTML heading standards. It provides text overflow handling, anchor link generation, and integrates with [TableOfContents](/components/TableOfContents). |
 48 | | [HSplitter](./HSplitter) | `Splitter` component divides a container into two resizable sections. These are are identified by their names: primary and secondary. They have a draggable bar between them. |
 49 | | [HStack](./HStack) | This component represents a stack rendering its contents horizontally. |
 50 | | [Icon](./Icon) | `Icon` displays scalable vector icons from XMLUI's built-in icon registry using simple name references. Icons are commonly used in buttons, navigation elements, and status indicators. |
 51 | | [IFrame](./IFrame) | `IFrame` embeds external content from another HTML document into the current page. It provides security controls through sandbox and allow attributes, and supports features like fullscreen display and referrer policy configuration. |
 52 | | [Image](./Image) | `Image` displays pictures from URLs or local sources with built-in responsive sizing, aspect ratio control, and accessibility features. It handles different image formats and provides options for lazy loading and click interactions. |
 53 | | [Items](./Items) | `Items` renders data arrays without built-in layout or styling, providing a lightweight alternative to `List`. Unlike `List`, it provides no virtualization, grouping, or visual formatting — just pure data iteration. |
 54 | | [LabelList](./LabelList) | `LabelList` adds custom data labels to chart components when automatic labeling isn't sufficient. It's a specialized component for advanced chart customization scenarios where you need precise control over label positioning and appearance. |
 55 | | [Legend](./Legend) | `Legend` provides a standalone legend for chart components when you need custom positioning or styling beyond the chart's built-in `showLegend` property. Most charts can display legends automatically, but this component offers precise control over legend placement and alignment. |
 56 | | [LineChart](./LineChart) | `LineChart` displays data as connected points over a continuous axis, ideal for showing trends, changes over time, or relationships between variables. Use it time series data, progress tracking, and comparing multiple data series on the same scale. |
 57 | | [Link](./Link) | `Link` creates clickable navigation elements for internal app routes or external URLs. You can use the `label` and `icon` properties for simple text links, or embed custom components like buttons, cards, or complex layouts for rich interactive link presentations. |
 58 | | [List](./List) | `List` is a high-performance, virtualized container for rendering large datasets with built-in grouping, sorting, and visual formatting. It only renders visible items in the viewport, making it ideal for displaying thousands of records while maintaining smooth scrolling performance. |
 59 | | [Logo](./Logo) | `Logo` displays your application's brand symbol by automatically loading logo images defined in the app manifest. While logos are typically configured using App-level properties (`logo`, `logo-dark`), this component provides direct control when you need custom logo placement or templating. |
 60 | | [Markdown](./Markdown) | `Markdown` renders formatted text using markdown syntax. Use [Text](/working-with-text) for simple, styled text content, and `Markdown` when you need [rich formatting](/working-with-markdown). |
 61 | | [MenuItem](./MenuItem) | `MenuItem` represents individual clickable items within dropdown menus and other menu components. Each menu item can display text, icons, and respond to clicks with either navigation or custom actions, making it the building block for interactive menu systems. |
 62 | | [MenuSeparator](./MenuSeparator) | `MenuSeparator` displays a separator line between menu items to group related menu options within `DropdownMenu`. |
 63 | | [ModalDialog](./ModalDialog) | `ModalDialog` creates overlay dialogs that appear on top of the main interface, ideal for forms, confirmations, detailed views, or any content that requires focused user attention. Dialogs are programmatically opened using the `open()` method and can receive parameters for dynamic content. |
 64 | | [NavGroup](./NavGroup) | `NavGroup` creates collapsible containers for organizing related navigation items into hierarchical menu structures. It groups `NavLink` components and other `NavGroup` components, providing expandable submenus with customizable icons and states. |
 65 | | [NavLink](./NavLink) | `NavLink` creates interactive navigation items that connect users to different destinations within an app or external URLs. It automatically indicates active states, supports custom icons and labels, and can execute custom actions instead of navigation when needed. |
 66 | | [NavPanel](./NavPanel) | `NavPanel` defines the navigation structure within an App, serving as a container for NavLink and NavGroup components that create your application's primary navigation menu. Its appearance and behavior automatically adapt based on the App's layout configuration. |
 67 | | [NoResult](./NoResult) | `NoResult` displays a visual indication that a query or search returned nothing. |
 68 | | [NumberBox](./NumberBox) | `NumberBox` provides a specialized input field for numeric values with built-in validation, spinner buttons, and flexible formatting options. It supports both integer and floating-point numbers, handles empty states as null values, and integrates seamlessly with form validation. |
 69 | | [Option](./Option) | `Option` defines selectable items for choice-based components, providing both the underlying value and display text for selection interfaces. It serves as a non-visual data structure that describes individual choices within [Select](/components/Select), [AutoComplete](/components/AutoComplete), and other selection components. |
 70 | | [Page](./Page) | `Page` defines route endpoints within an application, mapping specific URL patterns to content that displays when users navigate to those routes. Each Page represents a distinct view or screen in your single-page application's routing system. |
 71 | | [PageMetaTitle](./PageMetaTitle) | `PageMetaTitle` dynamically sets or updates the browser tab title, enabling pages and components to override the default application name with context-specific titles. |
 72 | | [Pages](./Pages) | `Pages` serves as the routing coordinator within an [App](/components/App), managing which [Page](/components/Page)  displays based on the current URL. |
 73 | | [Pagination](./Pagination) | `Pagination` enables navigation through large datasets by dividing content into pages. It provides controls for page navigation and can display current page information. |
 74 | | [PasswordInput](./PasswordInput) | `Password` is a specialized [TextBox](/components/TextBox) that enables users to input and edit passwords. |
 75 | | [PieChart](./PieChart) | `PieChart` visualizes proportional data as circular segments; each slice represents a percentage of the whole. Note that the height of the component or its parent needs to be set explicitly. |
 76 | | [ProgressBar](./ProgressBar) | `ProgressBar` provides a visual indicator showing the completion percentage of tasks, processes, or any measurable progress. It displays as a horizontal bar that fills from left to right based on the provided value between 0 (empty) and 1 (complete). |
 77 | | [Queue](./Queue) | `Queue` manages sequential processing of items in FIFO (first-in, first-out) order. It is a non-visual component but provides UI progress reporting and result display. |
 78 | | [RadioGroup](./RadioGroup) | `RadioGroup` creates a mutually exclusive selection interface where users can choose only one option from a group of radio buttons. It manages the selection state and ensures that selecting one option automatically deselects all others in the group. Radio options store their values as strings. Numbers and booleans are converted to strings when assigned, while objects, functions and arrays default to an empty string unless resolved via binding expressions. |
 79 | | [RealTimeAdapter](./RealTimeAdapter) | `RealTimeAdapter` is a non-visual component that listens to real-time events. |
 80 | | [Redirect](./Redirect) | `Redirect` immediately redirects the browser to the URL in its `to` property when it gets visible (its `when` property gets `true`). It works only within [App](/components/App), not externally. |
 81 | | [Select](./Select) | `Select` provides a dropdown interface for choosing from a list of options, supporting both single and multiple selection modes. It offers extensive customization capabilities including search functionality, custom templates, and comprehensive form integration. |
 82 | | [Slider](./Slider) | `Slider` provides an interactive control for selecting numeric values within a defined range, supporting both single value selection and range selection with multiple thumbs. It offers precise control through customizable steps and visual feedback with formatted value display. Hover over the component to see the tooltip with the current value. On mobile, tap the thumb to see the tooltip. |
 83 | | [Slot](./Slot) | Placeholder in a reusable component. Signs the slot where the component's injected children should be rendered. |
 84 | | [SpaceFiller](./SpaceFiller) | `SpaceFiller` works well in layout containers to fill remaining (unused) space. Its behavior depends on the layout container in which it is used. |
 85 | | [Spinner](./Spinner) | `Spinner` is an animated indicator that represents an action in progress with no deterministic progress value. |
 86 | | [Splitter](./Splitter) | `Splitter` component divides a container into two resizable sections. These are are identified by their names: primary and secondary. They have a draggable bar between them. |
 87 | | [Stack](./Stack) | `Stack` is the fundamental layout container that organizes child elements in configurable horizontal or vertical arrangements. As the most versatile building block in XMLUI's layout system, it provides comprehensive alignment, spacing, and flow control options that serve as the foundation for all specialized stack variants. |
 88 | | [StickyBox](./StickyBox) | `StickyBox` remains fixed at the top or bottom of the screen as the user scrolls. |
 89 | | [SubMenuItem](./SubMenuItem) | `SubMenuItem` creates hierarchical menu structures by acting as both a menu item and a container for nested menu items. When clicked or hovered, it reveals a submenu containing additional [MenuItem](/components/MenuItem), [MenuSeparator](/components/MenuSeparator), or other [SubMenuItem](/components/SubMenuItems) components, enabling complex multi-level navigation and action organization. |
 90 | | [Switch](./Switch) | `Switch` enables users to toggle between two states: on and off. |
 91 | | [TabItem](./TabItem) | `TabItem` defines individual tabs within a [Tabs](/components/Tabs) component, providing both the tab header label and the content that displays when the tab is selected. As a non-visual structural component, it serves as a container that organizes content into distinct, switchable sections. |
 92 | | [Table](./Table) | `Table` presents structured data for viewing, sorting, selection, and interaction. |
 93 | | [TableOfContents](./TableOfContents) | `TableOfContents` component collects [Heading](/components/Heading) and [Bookmark](/components/Bookmark) within the current page and displays them in a navigable tree. |
 94 | | [Tabs](./Tabs) | `Tabs` enables users to switch among content panels using clickable tab headers. It provides an efficient way to present multiple related sections in a single interface area, with each tab containing distinct content defined by [TabItem](/components/TabItem) components. |
 95 | | [Text](./Text) | The `Text` component displays textual information in a number of optional styles and variants. |
 96 | | [TextArea](./TextArea) | `TextArea` provides a multiline text input area. |
 97 | | [TextBox](./TextBox) | `TextBox` captures user text input for forms, search fields, and data entry with support for validation, icons, and formatting hints. |
 98 | | [Theme](./Theme) | `Theme` creates styling contexts to customize the appearance of nested components without using CSS. |
 99 | | [TimeInput](./TimeInput) | `TimeInput` provides time input with support for 12-hour and 24-hour formats and configurable precision for hours, minutes, and seconds. |
100 | | [Timer](./Timer) | `Timer` is a non-visual component that fires events at regular intervals. It can be enabled or disabled and ensures that the timer event handler completes before firing the next event. |
101 | | [ToneChangerButton](./ToneChangerButton) | `ToneChangerButton` enables the user to switch between light and dark modes. |
102 | | [ToneSwitch](./ToneSwitch) | `ToneSwitch` enables the user to switch between light and dark modes using a switch control. |
103 | | [Tooltip](./Tooltip) | A tooltip component that displays text when hovering over trigger content. |
104 | | [Tree](./Tree) | The `Tree` component is a virtualized tree component that displays hierarchical data with support for flat and hierarchy data formats. |
105 | | [VSplitter](./VSplitter) | `Splitter` component divides a container into two resizable sections. These are are identified by their names: primary and secondary. They have a draggable bar between them. |
106 | | [VStack](./VStack) | This component represents a stack rendering its contents vertically. |
107 | 
108 | 
```

