#
tokens: 49904/50000 9/1627 files (page 41/141)
lines: off (toggle) GitHub
raw markdown copy
This is page 41 of 141. Use http://codebase.md/xmlui-org/xmlui/xmlui-standalone.umd.js?lines=false&page={x} to view the full context.

# Directory Structure

```
├── .changeset
│   ├── config.json
│   └── lemon-zoos-prove.md
├── .eslintrc.cjs
├── .github
│   ├── build-checklist.png
│   ├── ISSUE_TEMPLATE
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   └── workflows
│       ├── deploy-blog-optimized.yml
│       ├── deploy-blog.yml
│       ├── deploy-docs-optimized.yml
│       ├── deploy-docs.yml
│       ├── prepare-versions.yml
│       ├── release-packages.yml
│       ├── run-all-tests.yml
│       └── run-smoke-tests.yml
├── .gitignore
├── .prettierrc.js
├── .vscode
│   ├── launch.json
│   └── settings.json
├── blog
│   ├── .gitignore
│   ├── .gitkeep
│   ├── CHANGELOG.md
│   ├── extensions.ts
│   ├── index.html
│   ├── index.ts
│   ├── package.json
│   ├── public
│   │   ├── blog
│   │   │   ├── images
│   │   │   │   ├── an-advanced-codefence.gif
│   │   │   │   ├── an-advanced-codefence.mp4
│   │   │   │   ├── blog-page-component.png
│   │   │   │   ├── blog-scrabble.png
│   │   │   │   ├── codefence-runner.png
│   │   │   │   ├── integrated-blog-search.png
│   │   │   │   ├── lorem-ipsum.png
│   │   │   │   ├── playground-checkbox-source.png
│   │   │   │   ├── playground.png
│   │   │   │   ├── use-xmlui-mcp-to-find-a-howto.png
│   │   │   │   └── xmlui-demo-gallery.png
│   │   │   ├── introducing-xmlui.md
│   │   │   ├── lorem-ipsum.md
│   │   │   ├── newest-post.md
│   │   │   ├── older-post.md
│   │   │   ├── xmlui-playground.md
│   │   │   └── xmlui-powered-blog.md
│   │   ├── mockServiceWorker.js
│   │   ├── resources
│   │   │   ├── favicon.ico
│   │   │   ├── files
│   │   │   │   └── for-download
│   │   │   │       └── xmlui
│   │   │   │           └── xmlui-standalone.umd.js
│   │   │   ├── github.svg
│   │   │   ├── llms.txt
│   │   │   ├── logo-dark.svg
│   │   │   ├── logo.svg
│   │   │   ├── pg-popout.svg
│   │   │   ├── rss.svg
│   │   │   └── xmlui-logo.svg
│   │   ├── serve.json
│   │   └── 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
│   │           ├── HelloMd.md
│   │           ├── HeroSection.md
│   │           └── ScrollToTop.md
│   ├── extensions.ts
│   ├── index.html
│   ├── index.ts
│   ├── package.json
│   ├── public
│   │   ├── feed.rss
│   │   ├── mockServiceWorker.js
│   │   ├── pages
│   │   │   ├── _meta.json
│   │   │   ├── app-structure.md
│   │   │   ├── build-editor-component.md
│   │   │   ├── build-hello-world-component.md
│   │   │   ├── components-intro.md
│   │   │   ├── context-variables.md
│   │   │   ├── forms.md
│   │   │   ├── globals.md
│   │   │   ├── glossary.md
│   │   │   ├── helper-tags.md
│   │   │   ├── hosted-deployment.md
│   │   │   ├── howto
│   │   │   │   ├── assign-a-complex-json-literal-to-a-component-variable.md
│   │   │   │   ├── chain-a-refetch.md
│   │   │   │   ├── control-cache-invalidation.md
│   │   │   │   ├── debounce-user-input-for-api-calls.md
│   │   │   │   ├── debug-a-component.md
│   │   │   │   ├── delay-a-datasource-until-another-datasource-is-ready.md
│   │   │   │   ├── delegate-a-method.md
│   │   │   │   ├── do-custom-form-validation.md
│   │   │   │   ├── expose-a-method-from-a-component.md
│   │   │   │   ├── filter-and-transform-data-from-an-api.md
│   │   │   │   ├── group-items-in-list-by-a-property.md
│   │   │   │   ├── handle-background-operations.md
│   │   │   │   ├── hide-an-element-until-its-datasource-is-ready.md
│   │   │   │   ├── make-a-set-of-equal-width-cards.md
│   │   │   │   ├── make-a-table-responsive.md
│   │   │   │   ├── make-navpanel-width-responsive.md
│   │   │   │   ├── modify-a-value-reported-in-a-column.md
│   │   │   │   ├── paginate-a-list.md
│   │   │   │   ├── pass-data-to-a-modal-dialog.md
│   │   │   │   ├── react-to-button-click-not-keystrokes.md
│   │   │   │   ├── set-the-initial-value-of-a-select-from-fetched-data.md
│   │   │   │   ├── share-a-modaldialog-across-components.md
│   │   │   │   ├── sync-selections-between-table-and-list-views.md
│   │   │   │   ├── update-ui-optimistically.md
│   │   │   │   ├── use-built-in-form-validation.md
│   │   │   │   └── use-the-same-modaldialog-to-add-or-edit.md
│   │   │   ├── howto.md
│   │   │   ├── intro.md
│   │   │   ├── layout.md
│   │   │   ├── markup.md
│   │   │   ├── mcp.md
│   │   │   ├── modal-dialogs.md
│   │   │   ├── news-and-reviews.md
│   │   │   ├── reactive-intro.md
│   │   │   ├── refactoring.md
│   │   │   ├── routing-and-links.md
│   │   │   ├── samples
│   │   │   │   ├── color-palette.xmlui
│   │   │   │   ├── color-values.xmlui
│   │   │   │   ├── shadow-sizes.xmlui
│   │   │   │   ├── spacing-sizes.xmlui
│   │   │   │   ├── swatch.xmlui
│   │   │   │   ├── theme-gallery-brief.xmlui
│   │   │   │   └── theme-gallery.xmlui
│   │   │   ├── scoping.md
│   │   │   ├── scripting.md
│   │   │   ├── styles-and-themes
│   │   │   │   ├── common-units.md
│   │   │   │   ├── layout-props.md
│   │   │   │   ├── theme-variable-defaults.md
│   │   │   │   ├── theme-variables.md
│   │   │   │   └── themes.md
│   │   │   ├── template-properties.md
│   │   │   ├── test.md
│   │   │   ├── tutorial-01.md
│   │   │   ├── tutorial-02.md
│   │   │   ├── tutorial-03.md
│   │   │   ├── tutorial-04.md
│   │   │   ├── tutorial-05.md
│   │   │   ├── tutorial-06.md
│   │   │   ├── tutorial-07.md
│   │   │   ├── tutorial-08.md
│   │   │   ├── tutorial-09.md
│   │   │   ├── tutorial-10.md
│   │   │   ├── tutorial-11.md
│   │   │   ├── tutorial-12.md
│   │   │   ├── universal-properties.md
│   │   │   ├── user-defined-components.md
│   │   │   ├── vscode.md
│   │   │   ├── working-with-markdown.md
│   │   │   ├── working-with-text.md
│   │   │   ├── xmlui-animations
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   ├── Animation.md
│   │   │   │   ├── FadeAnimation.md
│   │   │   │   ├── FadeInAnimation.md
│   │   │   │   ├── FadeOutAnimation.md
│   │   │   │   ├── ScaleAnimation.md
│   │   │   │   └── SlideInAnimation.md
│   │   │   ├── xmlui-charts
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   ├── BarChart.md
│   │   │   │   ├── DonutChart.md
│   │   │   │   ├── LabelList.md
│   │   │   │   ├── Legend.md
│   │   │   │   ├── LineChart.md
│   │   │   │   └── PieChart.md
│   │   │   ├── xmlui-pdf
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   └── Pdf.md
│   │   │   └── xmlui-spreadsheet
│   │   │       ├── _meta.json
│   │   │       ├── _overview.md
│   │   │       └── Spreadsheet.md
│   │   ├── resources
│   │   │   ├── devdocs
│   │   │   │   ├── debug-proxy-object-2.png
│   │   │   │   ├── debug-proxy-object.png
│   │   │   │   ├── table_editor_01.png
│   │   │   │   ├── table_editor_02.png
│   │   │   │   ├── table_editor_03.png
│   │   │   │   ├── table_editor_04.png
│   │   │   │   ├── table_editor_05.png
│   │   │   │   ├── table_editor_06.png
│   │   │   │   ├── table_editor_07.png
│   │   │   │   ├── table_editor_08.png
│   │   │   │   ├── table_editor_09.png
│   │   │   │   ├── table_editor_10.png
│   │   │   │   ├── table_editor_11.png
│   │   │   │   ├── table-editor-01.png
│   │   │   │   ├── table-editor-02.png
│   │   │   │   ├── table-editor-03.png
│   │   │   │   ├── table-editor-04.png
│   │   │   │   ├── table-editor-06.png
│   │   │   │   ├── table-editor-07.png
│   │   │   │   ├── table-editor-08.png
│   │   │   │   ├── table-editor-09.png
│   │   │   │   └── xmlui-rendering-of-tiptap-markdown.png
│   │   │   ├── favicon.ico
│   │   │   ├── files
│   │   │   │   ├── clients.json
│   │   │   │   ├── daily-revenue.json
│   │   │   │   ├── dashboard-stats.json
│   │   │   │   ├── demo.xmlui
│   │   │   │   ├── demo.xmlui.xs
│   │   │   │   ├── downloads
│   │   │   │   │   └── downloads.json
│   │   │   │   ├── for-download
│   │   │   │   │   ├── index-with-api.html
│   │   │   │   │   ├── index.html
│   │   │   │   │   ├── mockApi.js
│   │   │   │   │   ├── start-darwin.sh
│   │   │   │   │   ├── start-linux.sh
│   │   │   │   │   ├── start.bat
│   │   │   │   │   └── xmlui
│   │   │   │   │       └── xmlui-standalone.umd.js
│   │   │   │   ├── getting-started
│   │   │   │   │   ├── cl-tutorial-final.zip
│   │   │   │   │   ├── cl-tutorial.zip
│   │   │   │   │   ├── cl-tutorial2.zip
│   │   │   │   │   ├── cl-tutorial3.zip
│   │   │   │   │   ├── cl-tutorial4.zip
│   │   │   │   │   ├── cl-tutorial5.zip
│   │   │   │   │   ├── cl-tutorial6.zip
│   │   │   │   │   ├── getting-started.zip
│   │   │   │   │   ├── hello-xmlui.zip
│   │   │   │   │   ├── xmlui-empty.zip
│   │   │   │   │   └── xmlui-starter.zip
│   │   │   │   ├── howto
│   │   │   │   │   └── component-icons
│   │   │   │   │       └── up-arrow.svg
│   │   │   │   ├── invoices.json
│   │   │   │   ├── monthly-status.json
│   │   │   │   ├── news-and-reviews.json
│   │   │   │   ├── products.json
│   │   │   │   ├── releases.json
│   │   │   │   ├── tutorials
│   │   │   │   │   ├── datasource
│   │   │   │   │   │   └── api.ts
│   │   │   │   │   └── p2do
│   │   │   │   │       ├── api.ts
│   │   │   │   │       └── todo-logo.svg
│   │   │   │   └── xmlui.json
│   │   │   ├── github.svg
│   │   │   ├── images
│   │   │   │   ├── apiaction-tutorial
│   │   │   │   │   ├── add-success.png
│   │   │   │   │   ├── apiaction-param.png
│   │   │   │   │   ├── change-completed.png
│   │   │   │   │   ├── change-in-progress.png
│   │   │   │   │   ├── confirm-delete.png
│   │   │   │   │   ├── data-error.png
│   │   │   │   │   ├── data-progress.png
│   │   │   │   │   ├── data-success.png
│   │   │   │   │   ├── display-1.png
│   │   │   │   │   ├── item-deleted.png
│   │   │   │   │   ├── item-updated.png
│   │   │   │   │   ├── missing-api-key.png
│   │   │   │   │   ├── new-item-added.png
│   │   │   │   │   └── test-message.png
│   │   │   │   ├── chat-api
│   │   │   │   │   └── domain-model.svg
│   │   │   │   ├── components
│   │   │   │   │   ├── image
│   │   │   │   │   │   └── breakfast.jpg
│   │   │   │   │   ├── markdown
│   │   │   │   │   │   └── colors.png
│   │   │   │   │   └── modal
│   │   │   │   │       ├── deep_link_dialog_1.jpg
│   │   │   │   │       └── deep_link_dialog_2.jpg
│   │   │   │   ├── create-apps
│   │   │   │   │   ├── collapsed-vertical.png
│   │   │   │   │   ├── using-forms-warning-dialog.png
│   │   │   │   │   └── using-forms.png
│   │   │   │   ├── datasource-tutorial
│   │   │   │   │   ├── data-with-header.png
│   │   │   │   │   ├── filtered-data.png
│   │   │   │   │   ├── filtered-items.png
│   │   │   │   │   ├── initial-page-items.png
│   │   │   │   │   ├── list-items.png
│   │   │   │   │   ├── next-page-items.png
│   │   │   │   │   ├── no-data.png
│   │   │   │   │   ├── pagination-1.jpg
│   │   │   │   │   ├── pagination-1.png
│   │   │   │   │   ├── polling-1.png
│   │   │   │   │   ├── refetch-data.png
│   │   │   │   │   ├── slow-loading.png
│   │   │   │   │   ├── test-message.png
│   │   │   │   │   ├── Thumbs.db
│   │   │   │   │   ├── unconventional-data.png
│   │   │   │   │   └── unfiltered-items.png
│   │   │   │   ├── flower.jpg
│   │   │   │   ├── get-started
│   │   │   │   │   ├── add-new-contact.png
│   │   │   │   │   ├── app-modified.png
│   │   │   │   │   ├── app-start.png
│   │   │   │   │   ├── app-with-boxes.png
│   │   │   │   │   ├── app-with-toast.png
│   │   │   │   │   ├── boilerplate-structure.png
│   │   │   │   │   ├── cl-initial.png
│   │   │   │   │   ├── cl-start.png
│   │   │   │   │   ├── contact-counts.png
│   │   │   │   │   ├── contact-dialog-title.png
│   │   │   │   │   ├── contact-dialog.png
│   │   │   │   │   ├── contact-menus.png
│   │   │   │   │   ├── contact-predicates.png
│   │   │   │   │   ├── context-menu.png
│   │   │   │   │   ├── dashboard-numbers.png
│   │   │   │   │   ├── default-contact-list.png
│   │   │   │   │   ├── delete-contact.png
│   │   │   │   │   ├── delete-task.png
│   │   │   │   │   ├── detailed-template.png
│   │   │   │   │   ├── edit-contact-details.png
│   │   │   │   │   ├── edited-contact-saved.png
│   │   │   │   │   ├── empty-sections.png
│   │   │   │   │   ├── filter-completed.png
│   │   │   │   │   ├── fullwidth-desktop.png
│   │   │   │   │   ├── fullwidth-mobile.png
│   │   │   │   │   ├── initial-table.png
│   │   │   │   │   ├── items-and-badges.png
│   │   │   │   │   ├── loading-message.png
│   │   │   │   │   ├── new-contact-button.png
│   │   │   │   │   ├── new-contact-saved.png
│   │   │   │   │   ├── no-empty-sections.png
│   │   │   │   │   ├── personal-todo-initial.png
│   │   │   │   │   ├── piechart.png
│   │   │   │   │   ├── review-today.png
│   │   │   │   │   ├── rudimentary-dashboard.png
│   │   │   │   │   ├── section-collapsed.png
│   │   │   │   │   ├── sectioned-items.png
│   │   │   │   │   ├── sections-ordered.png
│   │   │   │   │   ├── spacex-list-with-links.png
│   │   │   │   │   ├── spacex-list.png
│   │   │   │   │   ├── start-personal-todo-1.png
│   │   │   │   │   ├── submit-new-contact.png
│   │   │   │   │   ├── submit-new-task.png
│   │   │   │   │   ├── syntax-highlighting.png
│   │   │   │   │   ├── table-with-badge.png
│   │   │   │   │   ├── template-with-card.png
│   │   │   │   │   ├── test-emulated-api.png
│   │   │   │   │   ├── Thumbs.db
│   │   │   │   │   ├── todo-logo.png
│   │   │   │   │   └── xmlui-tools.png
│   │   │   │   ├── HelloApp.png
│   │   │   │   ├── HelloApp2.png
│   │   │   │   ├── logos
│   │   │   │   │   ├── xmlui1.svg
│   │   │   │   │   ├── xmlui2.svg
│   │   │   │   │   ├── xmlui3.svg
│   │   │   │   │   ├── xmlui4.svg
│   │   │   │   │   ├── xmlui5.svg
│   │   │   │   │   ├── xmlui6.svg
│   │   │   │   │   └── xmlui7.svg
│   │   │   │   ├── pdf
│   │   │   │   │   └── dummy-pdf.jpg
│   │   │   │   ├── rendering-engine
│   │   │   │   │   ├── AppEngine-flow.svg
│   │   │   │   │   ├── Component.svg
│   │   │   │   │   ├── CompoundComponent.svg
│   │   │   │   │   ├── RootComponent.svg
│   │   │   │   │   └── tree-with-containers.svg
│   │   │   │   ├── reviewers-guide
│   │   │   │   │   ├── AppEngine-flow.svg
│   │   │   │   │   └── incbutton-in-action.png
│   │   │   │   ├── tools
│   │   │   │   │   └── boilerplate-structure.png
│   │   │   │   ├── try.svg
│   │   │   │   ├── tutorial
│   │   │   │   │   ├── app-chat-history.png
│   │   │   │   │   ├── app-content-placeholder.png
│   │   │   │   │   ├── app-header-and-content.png
│   │   │   │   │   ├── app-links-channel-selected.png
│   │   │   │   │   ├── app-links-click.png
│   │   │   │   │   ├── app-navigation.png
│   │   │   │   │   ├── finished-ex01.png
│   │   │   │   │   ├── finished-ex02.png
│   │   │   │   │   ├── hello.png
│   │   │   │   │   ├── splash-screen-advanced.png
│   │   │   │   │   ├── splash-screen-after-click.png
│   │   │   │   │   ├── splash-screen-centered.png
│   │   │   │   │   ├── splash-screen-events.png
│   │   │   │   │   ├── splash-screen-expression.png
│   │   │   │   │   ├── splash-screen-reuse-after.png
│   │   │   │   │   ├── splash-screen-reuse-before.png
│   │   │   │   │   └── splash-screen.png
│   │   │   │   └── tutorial-01.png
│   │   │   ├── llms.txt
│   │   │   ├── logo-dark.svg
│   │   │   ├── logo.svg
│   │   │   ├── pg-popout.svg
│   │   │   └── xmlui-logo.svg
│   │   ├── serve.json
│   │   └── web.config
│   ├── scripts
│   │   ├── download-latest-xmlui.js
│   │   ├── generate-rss.js
│   │   ├── get-releases.js
│   │   └── utils.js
│   ├── src
│   │   ├── components
│   │   │   ├── BlogOverview.xmlui
│   │   │   ├── BlogPage.xmlui
│   │   │   ├── Boxes.xmlui
│   │   │   ├── Breadcrumb.xmlui
│   │   │   ├── ChangeLog.xmlui
│   │   │   ├── ColorPalette.xmlui
│   │   │   ├── DocumentLinks.xmlui
│   │   │   ├── DocumentPage.xmlui
│   │   │   ├── DocumentPageNoTOC.xmlui
│   │   │   ├── Icons.xmlui
│   │   │   ├── IncButton.xmlui
│   │   │   ├── IncButton2.xmlui
│   │   │   ├── NameValue.xmlui
│   │   │   ├── PageNotFound.xmlui
│   │   │   ├── PaletteItem.xmlui
│   │   │   ├── Palettes.xmlui
│   │   │   ├── SectionHeader.xmlui
│   │   │   ├── TBD.xmlui
│   │   │   ├── Test.xmlui
│   │   │   ├── ThemesIntro.xmlui
│   │   │   ├── ThousandThemes.xmlui
│   │   │   ├── TubeStops.xmlui
│   │   │   ├── TubeStops.xmlui.xs
│   │   │   └── TwoColumnCode.xmlui
│   │   ├── config.ts
│   │   ├── Main.xmlui
│   │   └── themes
│   │       ├── docs-theme.ts
│   │       ├── earthtone.ts
│   │       ├── xmlui-gray-on-default.ts
│   │       ├── xmlui-green-on-default.ts
│   │       └── xmlui-orange-on-default.ts
│   └── tsconfig.json
├── LICENSE
├── package-lock.json
├── package.json
├── packages
│   ├── tsconfig.json
│   ├── xmlui-animations
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── Animation.tsx
│   │       ├── AnimationNative.tsx
│   │       ├── FadeAnimation.tsx
│   │       ├── FadeInAnimation.tsx
│   │       ├── FadeOutAnimation.tsx
│   │       ├── index.tsx
│   │       ├── ScaleAnimation.tsx
│   │       └── SlideInAnimation.tsx
│   ├── xmlui-devtools
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   ├── src
│   │   │   ├── devtools
│   │   │   │   ├── DevTools.tsx
│   │   │   │   ├── DevToolsNative.module.scss
│   │   │   │   ├── DevToolsNative.tsx
│   │   │   │   ├── ModalDialog.module.scss
│   │   │   │   ├── ModalDialog.tsx
│   │   │   │   ├── ModalVisibilityContext.tsx
│   │   │   │   ├── Tooltip.module.scss
│   │   │   │   ├── Tooltip.tsx
│   │   │   │   └── utils.ts
│   │   │   ├── editor
│   │   │   │   └── Editor.tsx
│   │   │   └── index.tsx
│   │   └── vite.config-overrides.ts
│   ├── xmlui-hello-world
│   │   ├── .gitignore
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── HelloWorld.module.scss
│   │       ├── HelloWorld.tsx
│   │       ├── HelloWorldNative.tsx
│   │       └── index.tsx
│   ├── xmlui-os-frames
│   │   ├── .gitignore
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── index.tsx
│   │       ├── IPhoneFrame.module.scss
│   │       ├── IPhoneFrame.tsx
│   │       ├── MacOSAppFrame.module.scss
│   │       ├── MacOSAppFrame.tsx
│   │       ├── WindowsAppFrame.module.scss
│   │       └── WindowsAppFrame.tsx
│   ├── xmlui-pdf
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   ├── components
│   │   │   │   └── Pdf.xmlui
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── index.tsx
│   │       ├── LazyPdfNative.tsx
│   │       ├── Pdf.module.scss
│   │       └── Pdf.tsx
│   ├── xmlui-playground
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── hooks
│   │       │   ├── usePlayground.ts
│   │       │   └── useToast.ts
│   │       ├── index.tsx
│   │       ├── playground
│   │       │   ├── Box.module.scss
│   │       │   ├── Box.tsx
│   │       │   ├── CodeSelector.tsx
│   │       │   ├── ConfirmationDialog.module.scss
│   │       │   ├── ConfirmationDialog.tsx
│   │       │   ├── Editor.tsx
│   │       │   ├── Header.module.scss
│   │       │   ├── Header.tsx
│   │       │   ├── Playground.tsx
│   │       │   ├── PlaygroundContent.module.scss
│   │       │   ├── PlaygroundContent.tsx
│   │       │   ├── PlaygroundNative.module.scss
│   │       │   ├── PlaygroundNative.tsx
│   │       │   ├── Preview.module.scss
│   │       │   ├── Preview.tsx
│   │       │   ├── Select.module.scss
│   │       │   ├── StandalonePlayground.tsx
│   │       │   ├── StandalonePlaygroundNative.module.scss
│   │       │   ├── StandalonePlaygroundNative.tsx
│   │       │   ├── ThemeSwitcher.module.scss
│   │       │   ├── ThemeSwitcher.tsx
│   │       │   ├── ToneSwitcher.tsx
│   │       │   ├── Tooltip.module.scss
│   │       │   ├── Tooltip.tsx
│   │       │   └── utils.ts
│   │       ├── providers
│   │       │   ├── Toast.module.scss
│   │       │   └── ToastProvider.tsx
│   │       ├── state
│   │       │   └── store.ts
│   │       ├── themes
│   │       │   └── theme.ts
│   │       └── utils
│   │           └── helpers.ts
│   ├── xmlui-search
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── index.tsx
│   │       ├── Search.module.scss
│   │       └── Search.tsx
│   ├── xmlui-spreadsheet
│   │   ├── .gitignore
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   └── src
│   │       ├── index.tsx
│   │       ├── Spreadsheet.tsx
│   │       └── SpreadsheetNative.tsx
│   └── xmlui-website-blocks
│       ├── .gitignore
│       ├── CHANGELOG.md
│       ├── demo
│       │   ├── components
│       │   │   ├── HeroBackgroundBreakoutPage.xmlui
│       │   │   ├── HeroBackgroundsPage.xmlui
│       │   │   ├── HeroContentsPage.xmlui
│       │   │   ├── HeroTextAlignPage.xmlui
│       │   │   ├── HeroTextPage.xmlui
│       │   │   └── HeroTonesPage.xmlui
│       │   ├── Main.xmlui
│       │   └── themes
│       │       └── default.ts
│       ├── index.html
│       ├── index.ts
│       ├── meta
│       │   └── componentsMetadata.ts
│       ├── package.json
│       ├── public
│       │   └── resources
│       │       ├── building.jpg
│       │       └── xmlui-logo.svg
│       └── src
│           ├── Carousel
│           │   ├── Carousel.module.scss
│           │   ├── Carousel.tsx
│           │   ├── CarouselContext.tsx
│           │   └── CarouselNative.tsx
│           ├── FancyButton
│           │   ├── FancyButton.module.scss
│           │   ├── FancyButton.tsx
│           │   └── FancyButton.xmlui
│           ├── Hello
│           │   ├── Hello.tsx
│           │   ├── Hello.xmlui
│           │   └── Hello.xmlui.xs
│           ├── HeroSection
│           │   ├── HeroSection.module.scss
│           │   ├── HeroSection.spec.ts
│           │   ├── HeroSection.tsx
│           │   └── HeroSectionNative.tsx
│           ├── index.tsx
│           ├── ScrollToTop
│           │   ├── ScrollToTop.module.scss
│           │   ├── ScrollToTop.tsx
│           │   └── ScrollToTopNative.tsx
│           └── vite-env.d.ts
├── playwright.config.ts
├── README.md
├── tools
│   ├── codefence
│   │   └── xmlui-code-fence-docs.md
│   ├── create-app
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── create-app.ts
│   │   ├── helpers
│   │   │   ├── copy.ts
│   │   │   ├── get-pkg-manager.ts
│   │   │   ├── git.ts
│   │   │   ├── install.ts
│   │   │   ├── is-folder-empty.ts
│   │   │   ├── is-writeable.ts
│   │   │   ├── make-dir.ts
│   │   │   └── validate-pkg.ts
│   │   ├── index.ts
│   │   ├── package.json
│   │   ├── templates
│   │   │   ├── default
│   │   │   │   └── ts
│   │   │   │       ├── gitignore
│   │   │   │       ├── index.html
│   │   │   │       ├── index.ts
│   │   │   │       ├── public
│   │   │   │       │   ├── mockServiceWorker.js
│   │   │   │       │   ├── resources
│   │   │   │       │   │   ├── favicon.ico
│   │   │   │       │   │   └── xmlui-logo.svg
│   │   │   │       │   └── serve.json
│   │   │   │       └── src
│   │   │   │           ├── components
│   │   │   │           │   ├── ApiAware.xmlui
│   │   │   │           │   ├── Home.xmlui
│   │   │   │           │   ├── IncButton.xmlui
│   │   │   │           │   └── PagePanel.xmlui
│   │   │   │           ├── config.ts
│   │   │   │           └── Main.xmlui
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   └── tsconfig.json
│   ├── create-xmlui-hello-world
│   │   ├── index.js
│   │   └── package.json
│   └── vscode
│       ├── .gitignore
│       ├── .vscode
│       │   ├── launch.json
│       │   └── tasks.json
│       ├── .vscodeignore
│       ├── build.sh
│       ├── CHANGELOG.md
│       ├── esbuild.js
│       ├── eslint.config.mjs
│       ├── formatter-docs.md
│       ├── generate-test-sample.sh
│       ├── LICENSE.md
│       ├── package-lock.json
│       ├── package.json
│       ├── README.md
│       ├── resources
│       │   ├── xmlui-logo.png
│       │   └── xmlui-markup-syntax-highlighting.png
│       ├── src
│       │   ├── extension.ts
│       │   └── server.ts
│       ├── syntaxes
│       │   └── xmlui.tmLanguage.json
│       ├── test-samples
│       │   └── sample.xmlui
│       ├── tsconfig.json
│       └── tsconfig.tsbuildinfo
├── turbo.json
└── xmlui
    ├── .gitignore
    ├── bin
    │   ├── bootstrap.cjs
    │   ├── bootstrap.js
    │   ├── build-lib.ts
    │   ├── build.ts
    │   ├── index.ts
    │   ├── preview.ts
    │   ├── start.ts
    │   ├── vite-xmlui-plugin.ts
    │   └── viteConfig.ts
    ├── CHANGELOG.md
    ├── conventions
    │   ├── component-qa-checklist.md
    │   ├── copilot-conventions.md
    │   ├── create-xmlui-components.md
    │   ├── mermaid.md
    │   ├── testing-conventions.md
    │   └── xmlui-in-a-nutshell.md
    ├── dev-docs
    │   ├── accessibility.md
    │   ├── build-system.md
    │   ├── build-xmlui.md
    │   ├── component-behaviors.md
    │   ├── 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
    │   ├── ud-components.md
    │   └── xmlui-repo.md
    ├── package.json
    ├── scripts
    │   ├── coverage-only.js
    │   ├── e2e-test-summary.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
    │   ├── 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.spec.ts
    │   │   │   │   ├── LabelList.tsx
    │   │   │   │   ├── LabelListNative.module.scss
    │   │   │   │   └── LabelListNative.tsx
    │   │   │   ├── Legend
    │   │   │   │   ├── Legend.spec.ts
    │   │   │   │   ├── Legend.tsx
    │   │   │   │   └── LegendNative.tsx
    │   │   │   ├── LineChart
    │   │   │   │   ├── LineChart.md
    │   │   │   │   ├── LineChart.module.scss
    │   │   │   │   ├── LineChart.spec.ts
    │   │   │   │   ├── LineChart.tsx
    │   │   │   │   └── LineChartNative.tsx
    │   │   │   ├── PieChart
    │   │   │   │   ├── PieChart.md
    │   │   │   │   ├── PieChart.spec.ts
    │   │   │   │   ├── PieChart.tsx
    │   │   │   │   ├── PieChartNative.module.scss
    │   │   │   │   └── PieChartNative.tsx
    │   │   │   ├── RadarChart
    │   │   │   │   ├── RadarChart.md
    │   │   │   │   ├── RadarChart.spec.ts
    │   │   │   │   ├── RadarChart.tsx
    │   │   │   │   └── RadarChartNative.tsx
    │   │   │   ├── Tooltip
    │   │   │   │   ├── TooltipContent.module.scss
    │   │   │   │   ├── TooltipContent.spec.ts
    │   │   │   │   └── TooltipContent.tsx
    │   │   │   └── utils
    │   │   │       ├── abstractions.ts
    │   │   │       └── ChartProvider.tsx
    │   │   ├── Checkbox
    │   │   │   ├── Checkbox.md
    │   │   │   ├── Checkbox.spec.ts
    │   │   │   └── Checkbox.tsx
    │   │   ├── CodeBlock
    │   │   │   ├── CodeBlock.module.scss
    │   │   │   ├── CodeBlock.spec.ts
    │   │   │   ├── CodeBlock.tsx
    │   │   │   ├── CodeBlockNative.tsx
    │   │   │   └── highlight-code.ts
    │   │   ├── collectedComponentMetadata.ts
    │   │   ├── ColorPicker
    │   │   │   ├── ColorPicker.md
    │   │   │   ├── ColorPicker.module.scss
    │   │   │   ├── ColorPicker.spec.ts
    │   │   │   ├── ColorPicker.tsx
    │   │   │   └── ColorPickerNative.tsx
    │   │   ├── Column
    │   │   │   ├── Column.md
    │   │   │   ├── Column.tsx
    │   │   │   ├── ColumnNative.tsx
    │   │   │   ├── doc-resources
    │   │   │   │   └── list-component-data.js
    │   │   │   └── TableContext.tsx
    │   │   ├── component-utils.ts
    │   │   ├── ComponentProvider.tsx
    │   │   ├── ComponentRegistryContext.tsx
    │   │   ├── container-helpers.tsx
    │   │   ├── ContentSeparator
    │   │   │   ├── ContentSeparator.md
    │   │   │   ├── ContentSeparator.module.scss
    │   │   │   ├── ContentSeparator.spec.ts
    │   │   │   ├── ContentSeparator.tsx
    │   │   │   └── ContentSeparatorNative.tsx
    │   │   ├── DataSource
    │   │   │   ├── DataSource.md
    │   │   │   └── DataSource.tsx
    │   │   ├── DateInput
    │   │   │   ├── DateInput.md
    │   │   │   ├── DateInput.module.scss
    │   │   │   ├── DateInput.spec.ts
    │   │   │   ├── DateInput.tsx
    │   │   │   └── DateInputNative.tsx
    │   │   ├── DatePicker
    │   │   │   ├── DatePicker.md
    │   │   │   ├── DatePicker.module.scss
    │   │   │   ├── DatePicker.spec.ts
    │   │   │   ├── DatePicker.tsx
    │   │   │   └── DatePickerNative.tsx
    │   │   ├── DropdownMenu
    │   │   │   ├── DropdownMenu.md
    │   │   │   ├── DropdownMenu.module.scss
    │   │   │   ├── DropdownMenu.spec.ts
    │   │   │   ├── DropdownMenu.tsx
    │   │   │   ├── DropdownMenuNative.tsx
    │   │   │   ├── MenuItem.md
    │   │   │   └── SubMenuItem.md
    │   │   ├── EmojiSelector
    │   │   │   ├── EmojiSelector.md
    │   │   │   ├── EmojiSelector.spec.ts
    │   │   │   ├── EmojiSelector.tsx
    │   │   │   └── EmojiSelectorNative.tsx
    │   │   ├── ExpandableItem
    │   │   │   ├── ExpandableItem.module.scss
    │   │   │   ├── ExpandableItem.spec.ts
    │   │   │   ├── ExpandableItem.tsx
    │   │   │   └── ExpandableItemNative.tsx
    │   │   ├── FileInput
    │   │   │   ├── FileInput.md
    │   │   │   ├── FileInput.module.scss
    │   │   │   ├── FileInput.spec.ts
    │   │   │   ├── FileInput.tsx
    │   │   │   └── FileInputNative.tsx
    │   │   ├── FileUploadDropZone
    │   │   │   ├── FileUploadDropZone.md
    │   │   │   ├── FileUploadDropZone.module.scss
    │   │   │   ├── FileUploadDropZone.spec.ts
    │   │   │   ├── FileUploadDropZone.tsx
    │   │   │   └── FileUploadDropZoneNative.tsx
    │   │   ├── FlowLayout
    │   │   │   ├── FlowLayout.md
    │   │   │   ├── FlowLayout.module.scss
    │   │   │   ├── FlowLayout.spec.ts
    │   │   │   ├── FlowLayout.spec.ts-snapshots
    │   │   │   │   └── Edge-cases-boxShadow-is-not-clipped-1-non-smoke-darwin.png
    │   │   │   ├── FlowLayout.tsx
    │   │   │   └── FlowLayoutNative.tsx
    │   │   ├── Footer
    │   │   │   ├── Footer.md
    │   │   │   ├── Footer.module.scss
    │   │   │   ├── Footer.spec.ts
    │   │   │   ├── Footer.tsx
    │   │   │   └── FooterNative.tsx
    │   │   ├── Form
    │   │   │   ├── Form.md
    │   │   │   ├── Form.module.scss
    │   │   │   ├── Form.spec.ts
    │   │   │   ├── Form.tsx
    │   │   │   ├── formActions.ts
    │   │   │   ├── FormContext.ts
    │   │   │   └── FormNative.tsx
    │   │   ├── FormItem
    │   │   │   ├── FormItem.md
    │   │   │   ├── FormItem.module.scss
    │   │   │   ├── FormItem.spec.ts
    │   │   │   ├── FormItem.tsx
    │   │   │   ├── FormItemNative.tsx
    │   │   │   ├── HelperText.module.scss
    │   │   │   ├── HelperText.tsx
    │   │   │   ├── ItemWithLabel.tsx
    │   │   │   └── Validations.ts
    │   │   ├── FormSection
    │   │   │   ├── FormSection.md
    │   │   │   ├── FormSection.ts
    │   │   │   └── FormSection.xmlui
    │   │   ├── Fragment
    │   │   │   ├── Fragment.spec.ts
    │   │   │   └── Fragment.tsx
    │   │   ├── Heading
    │   │   │   ├── abstractions.ts
    │   │   │   ├── H1.md
    │   │   │   ├── H1.spec.ts
    │   │   │   ├── H2.md
    │   │   │   ├── H2.spec.ts
    │   │   │   ├── H3.md
    │   │   │   ├── H3.spec.ts
    │   │   │   ├── H4.md
    │   │   │   ├── H4.spec.ts
    │   │   │   ├── H5.md
    │   │   │   ├── H5.spec.ts
    │   │   │   ├── H6.md
    │   │   │   ├── H6.spec.ts
    │   │   │   ├── Heading.md
    │   │   │   ├── Heading.module.scss
    │   │   │   ├── Heading.spec.ts
    │   │   │   ├── Heading.tsx
    │   │   │   └── HeadingNative.tsx
    │   │   ├── HoverCard
    │   │   │   ├── HoverCard.tsx
    │   │   │   └── HovercardNative.tsx
    │   │   ├── HtmlTags
    │   │   │   ├── HtmlTags.module.scss
    │   │   │   ├── HtmlTags.spec.ts
    │   │   │   └── HtmlTags.tsx
    │   │   ├── Icon
    │   │   │   ├── AdmonitionDanger.tsx
    │   │   │   ├── AdmonitionInfo.tsx
    │   │   │   ├── AdmonitionNote.tsx
    │   │   │   ├── AdmonitionTip.tsx
    │   │   │   ├── AdmonitionWarning.tsx
    │   │   │   ├── ApiIcon.tsx
    │   │   │   ├── ArrowDropDown.module.scss
    │   │   │   ├── ArrowDropDown.tsx
    │   │   │   ├── ArrowDropUp.module.scss
    │   │   │   ├── ArrowDropUp.tsx
    │   │   │   ├── ArrowLeft.module.scss
    │   │   │   ├── ArrowLeft.tsx
    │   │   │   ├── ArrowRight.module.scss
    │   │   │   ├── ArrowRight.tsx
    │   │   │   ├── Attach.tsx
    │   │   │   ├── Binding.module.scss
    │   │   │   ├── Binding.tsx
    │   │   │   ├── BoardIcon.tsx
    │   │   │   ├── BoxIcon.tsx
    │   │   │   ├── CheckIcon.tsx
    │   │   │   ├── ChevronDownIcon.tsx
    │   │   │   ├── ChevronLeft.tsx
    │   │   │   ├── ChevronRight.tsx
    │   │   │   ├── ChevronUpIcon.tsx
    │   │   │   ├── CodeFileIcon.tsx
    │   │   │   ├── CodeSandbox.tsx
    │   │   │   ├── CompactListIcon.tsx
    │   │   │   ├── ContentCopyIcon.tsx
    │   │   │   ├── DarkToLightIcon.tsx
    │   │   │   ├── DatabaseIcon.module.scss
    │   │   │   ├── DatabaseIcon.tsx
    │   │   │   ├── DocFileIcon.tsx
    │   │   │   ├── DocIcon.tsx
    │   │   │   ├── DotMenuHorizontalIcon.tsx
    │   │   │   ├── DotMenuIcon.tsx
    │   │   │   ├── EmailIcon.tsx
    │   │   │   ├── EmptyFolderIcon.tsx
    │   │   │   ├── ErrorIcon.tsx
    │   │   │   ├── ExpressionIcon.tsx
    │   │   │   ├── FillPlusCricleIcon.tsx
    │   │   │   ├── FilterIcon.tsx
    │   │   │   ├── FolderIcon.tsx
    │   │   │   ├── GlobeIcon.tsx
    │   │   │   ├── HomeIcon.tsx
    │   │   │   ├── HyperLinkIcon.tsx
    │   │   │   ├── Icon.md
    │   │   │   ├── Icon.module.scss
    │   │   │   ├── Icon.spec.ts
    │   │   │   ├── Icon.tsx
    │   │   │   ├── IconNative.tsx
    │   │   │   ├── ImageFileIcon.tsx
    │   │   │   ├── Inspect.tsx
    │   │   │   ├── LightToDark.tsx
    │   │   │   ├── LinkIcon.tsx
    │   │   │   ├── ListIcon.tsx
    │   │   │   ├── LooseListIcon.tsx
    │   │   │   ├── MoonIcon.tsx
    │   │   │   ├── MoreOptionsIcon.tsx
    │   │   │   ├── NoSortIcon.tsx
    │   │   │   ├── PDFIcon.tsx
    │   │   │   ├── PenIcon.tsx
    │   │   │   ├── PhoneIcon.tsx
    │   │   │   ├── PhotoIcon.tsx
    │   │   │   ├── PlusIcon.tsx
    │   │   │   ├── SearchIcon.tsx
    │   │   │   ├── ShareIcon.tsx
    │   │   │   ├── SortAscendingIcon.tsx
    │   │   │   ├── SortDescendingIcon.tsx
    │   │   │   ├── StarsIcon.tsx
    │   │   │   ├── SunIcon.tsx
    │   │   │   ├── svg
    │   │   │   │   ├── admonition_danger.svg
    │   │   │   │   ├── admonition_info.svg
    │   │   │   │   ├── admonition_note.svg
    │   │   │   │   ├── admonition_tip.svg
    │   │   │   │   ├── admonition_warning.svg
    │   │   │   │   ├── api.svg
    │   │   │   │   ├── arrow-dropdown.svg
    │   │   │   │   ├── arrow-left.svg
    │   │   │   │   ├── arrow-right.svg
    │   │   │   │   ├── arrow-up.svg
    │   │   │   │   ├── attach.svg
    │   │   │   │   ├── binding.svg
    │   │   │   │   ├── box.svg
    │   │   │   │   ├── bulb.svg
    │   │   │   │   ├── code-file.svg
    │   │   │   │   ├── code-sandbox.svg
    │   │   │   │   ├── dark_to_light.svg
    │   │   │   │   ├── database.svg
    │   │   │   │   ├── doc.svg
    │   │   │   │   ├── empty-folder.svg
    │   │   │   │   ├── expression.svg
    │   │   │   │   ├── eye-closed.svg
    │   │   │   │   ├── eye-dark.svg
    │   │   │   │   ├── eye.svg
    │   │   │   │   ├── file-text.svg
    │   │   │   │   ├── filter.svg
    │   │   │   │   ├── folder.svg
    │   │   │   │   ├── img.svg
    │   │   │   │   ├── inspect.svg
    │   │   │   │   ├── light_to_dark.svg
    │   │   │   │   ├── moon.svg
    │   │   │   │   ├── pdf.svg
    │   │   │   │   ├── photo.svg
    │   │   │   │   ├── share.svg
    │   │   │   │   ├── stars.svg
    │   │   │   │   ├── sun.svg
    │   │   │   │   ├── trending-down.svg
    │   │   │   │   ├── trending-level.svg
    │   │   │   │   ├── trending-up.svg
    │   │   │   │   ├── txt.svg
    │   │   │   │   ├── unknown-file.svg
    │   │   │   │   ├── unlink.svg
    │   │   │   │   └── xls.svg
    │   │   │   ├── TableDeleteColumnIcon.tsx
    │   │   │   ├── TableDeleteRowIcon.tsx
    │   │   │   ├── TableInsertColumnIcon.tsx
    │   │   │   ├── TableInsertRowIcon.tsx
    │   │   │   ├── TrashIcon.tsx
    │   │   │   ├── TrendingDownIcon.tsx
    │   │   │   ├── TrendingLevelIcon.tsx
    │   │   │   ├── TrendingUpIcon.tsx
    │   │   │   ├── TxtIcon.tsx
    │   │   │   ├── UnknownFileIcon.tsx
    │   │   │   ├── UnlinkIcon.tsx
    │   │   │   ├── UserIcon.tsx
    │   │   │   ├── WarningIcon.tsx
    │   │   │   └── XlsIcon.tsx
    │   │   ├── IconProvider.tsx
    │   │   ├── IconRegistryContext.tsx
    │   │   ├── IFrame
    │   │   │   ├── IFrame.md
    │   │   │   ├── IFrame.module.scss
    │   │   │   ├── IFrame.spec.ts
    │   │   │   ├── IFrame.tsx
    │   │   │   └── IFrameNative.tsx
    │   │   ├── Image
    │   │   │   ├── Image.md
    │   │   │   ├── Image.module.scss
    │   │   │   ├── Image.spec.ts
    │   │   │   ├── Image.tsx
    │   │   │   └── ImageNative.tsx
    │   │   ├── Input
    │   │   │   ├── index.ts
    │   │   │   ├── InputAdornment.module.scss
    │   │   │   ├── InputAdornment.tsx
    │   │   │   ├── InputDivider.module.scss
    │   │   │   ├── InputDivider.tsx
    │   │   │   ├── InputLabel.module.scss
    │   │   │   ├── InputLabel.tsx
    │   │   │   ├── PartialInput.module.scss
    │   │   │   └── PartialInput.tsx
    │   │   ├── InspectButton
    │   │   │   ├── InspectButton.module.scss
    │   │   │   └── InspectButton.tsx
    │   │   ├── Items
    │   │   │   ├── Items.md
    │   │   │   ├── Items.spec.ts
    │   │   │   ├── Items.tsx
    │   │   │   └── ItemsNative.tsx
    │   │   ├── Link
    │   │   │   ├── Link.md
    │   │   │   ├── Link.module.scss
    │   │   │   ├── Link.spec.ts
    │   │   │   ├── Link.tsx
    │   │   │   └── LinkNative.tsx
    │   │   ├── List
    │   │   │   ├── doc-resources
    │   │   │   │   └── list-component-data.js
    │   │   │   ├── List.md
    │   │   │   ├── List.module.scss
    │   │   │   ├── List.spec.ts
    │   │   │   ├── List.tsx
    │   │   │   └── ListNative.tsx
    │   │   ├── Logo
    │   │   │   ├── doc-resources
    │   │   │   │   └── xmlui-logo.svg
    │   │   │   ├── Logo.md
    │   │   │   ├── Logo.tsx
    │   │   │   └── LogoNative.tsx
    │   │   ├── Markdown
    │   │   │   ├── CodeText.module.scss
    │   │   │   ├── CodeText.tsx
    │   │   │   ├── Markdown.md
    │   │   │   ├── Markdown.module.scss
    │   │   │   ├── Markdown.spec.ts
    │   │   │   ├── Markdown.tsx
    │   │   │   ├── MarkdownNative.tsx
    │   │   │   ├── parse-binding-expr.ts
    │   │   │   └── utils.ts
    │   │   ├── metadata-helpers.ts
    │   │   ├── ModalDialog
    │   │   │   ├── ConfirmationModalContextProvider.tsx
    │   │   │   ├── Dialog.module.scss
    │   │   │   ├── Dialog.tsx
    │   │   │   ├── ModalDialog.md
    │   │   │   ├── ModalDialog.module.scss
    │   │   │   ├── ModalDialog.spec.ts
    │   │   │   ├── ModalDialog.tsx
    │   │   │   ├── ModalDialogNative.tsx
    │   │   │   └── ModalVisibilityContext.tsx
    │   │   ├── NavGroup
    │   │   │   ├── NavGroup.md
    │   │   │   ├── NavGroup.module.scss
    │   │   │   ├── NavGroup.spec.ts
    │   │   │   ├── NavGroup.tsx
    │   │   │   ├── NavGroupContext.ts
    │   │   │   └── NavGroupNative.tsx
    │   │   ├── NavLink
    │   │   │   ├── NavLink.md
    │   │   │   ├── NavLink.module.scss
    │   │   │   ├── NavLink.spec.ts
    │   │   │   ├── NavLink.tsx
    │   │   │   └── NavLinkNative.tsx
    │   │   ├── NavPanel
    │   │   │   ├── NavPanel.md
    │   │   │   ├── NavPanel.module.scss
    │   │   │   ├── NavPanel.spec.ts
    │   │   │   ├── NavPanel.tsx
    │   │   │   └── NavPanelNative.tsx
    │   │   ├── NestedApp
    │   │   │   ├── AppWithCodeView.module.scss
    │   │   │   ├── AppWithCodeView.tsx
    │   │   │   ├── AppWithCodeViewNative.tsx
    │   │   │   ├── defaultProps.tsx
    │   │   │   ├── logo.svg
    │   │   │   ├── NestedApp.module.scss
    │   │   │   ├── NestedApp.tsx
    │   │   │   ├── NestedAppNative.tsx
    │   │   │   ├── Tooltip.module.scss
    │   │   │   ├── Tooltip.tsx
    │   │   │   └── utils.ts
    │   │   ├── NoResult
    │   │   │   ├── NoResult.md
    │   │   │   ├── NoResult.module.scss
    │   │   │   ├── NoResult.spec.ts
    │   │   │   ├── NoResult.tsx
    │   │   │   └── NoResultNative.tsx
    │   │   ├── NumberBox
    │   │   │   ├── numberbox-abstractions.ts
    │   │   │   ├── NumberBox.md
    │   │   │   ├── NumberBox.module.scss
    │   │   │   ├── NumberBox.spec.ts
    │   │   │   ├── NumberBox.tsx
    │   │   │   └── NumberBoxNative.tsx
    │   │   ├── Option
    │   │   │   ├── Option.md
    │   │   │   ├── Option.spec.ts
    │   │   │   ├── Option.tsx
    │   │   │   ├── OptionNative.tsx
    │   │   │   └── OptionTypeProvider.tsx
    │   │   ├── PageMetaTitle
    │   │   │   ├── PageMetaTilteNative.tsx
    │   │   │   ├── PageMetaTitle.md
    │   │   │   ├── PageMetaTitle.spec.ts
    │   │   │   └── PageMetaTitle.tsx
    │   │   ├── Pages
    │   │   │   ├── Page.md
    │   │   │   ├── Pages.md
    │   │   │   ├── Pages.module.scss
    │   │   │   ├── Pages.tsx
    │   │   │   └── PagesNative.tsx
    │   │   ├── Pagination
    │   │   │   ├── Pagination.md
    │   │   │   ├── Pagination.module.scss
    │   │   │   ├── Pagination.spec.ts
    │   │   │   ├── Pagination.tsx
    │   │   │   └── PaginationNative.tsx
    │   │   ├── PositionedContainer
    │   │   │   ├── PositionedContainer.module.scss
    │   │   │   ├── PositionedContainer.tsx
    │   │   │   └── PositionedContainerNative.tsx
    │   │   ├── ProfileMenu
    │   │   │   ├── ProfileMenu.module.scss
    │   │   │   └── ProfileMenu.tsx
    │   │   ├── ProgressBar
    │   │   │   ├── ProgressBar.md
    │   │   │   ├── ProgressBar.module.scss
    │   │   │   ├── ProgressBar.spec.ts
    │   │   │   ├── ProgressBar.tsx
    │   │   │   └── ProgressBarNative.tsx
    │   │   ├── Queue
    │   │   │   ├── Queue.md
    │   │   │   ├── Queue.spec.ts
    │   │   │   ├── Queue.tsx
    │   │   │   ├── queueActions.ts
    │   │   │   └── QueueNative.tsx
    │   │   ├── RadioGroup
    │   │   │   ├── RadioGroup.md
    │   │   │   ├── RadioGroup.module.scss
    │   │   │   ├── RadioGroup.spec.ts
    │   │   │   ├── RadioGroup.tsx
    │   │   │   ├── RadioGroupNative.tsx
    │   │   │   ├── RadioItem.tsx
    │   │   │   └── RadioItemNative.tsx
    │   │   ├── RealTimeAdapter
    │   │   │   ├── RealTimeAdapter.tsx
    │   │   │   └── RealTimeAdapterNative.tsx
    │   │   ├── Redirect
    │   │   │   ├── Redirect.md
    │   │   │   ├── Redirect.spec.ts
    │   │   │   └── Redirect.tsx
    │   │   ├── ResponsiveBar
    │   │   │   ├── README.md
    │   │   │   ├── ResponsiveBar.md
    │   │   │   ├── ResponsiveBar.module.scss
    │   │   │   ├── ResponsiveBar.spec.ts
    │   │   │   ├── ResponsiveBar.tsx
    │   │   │   └── ResponsiveBarNative.tsx
    │   │   ├── Select
    │   │   │   ├── HiddenOption.tsx
    │   │   │   ├── OptionContext.ts
    │   │   │   ├── Select.md
    │   │   │   ├── Select.module.scss
    │   │   │   ├── Select.spec.ts
    │   │   │   ├── Select.tsx
    │   │   │   ├── SelectContext.tsx
    │   │   │   └── SelectNative.tsx
    │   │   ├── SelectionStore
    │   │   │   ├── SelectionStore.md
    │   │   │   ├── SelectionStore.tsx
    │   │   │   └── SelectionStoreNative.tsx
    │   │   ├── Slider
    │   │   │   ├── Slider.md
    │   │   │   ├── Slider.module.scss
    │   │   │   ├── Slider.spec.ts
    │   │   │   ├── Slider.tsx
    │   │   │   └── SliderNative.tsx
    │   │   ├── Slot
    │   │   │   ├── Slot.md
    │   │   │   ├── Slot.spec.ts
    │   │   │   └── Slot.ts
    │   │   ├── SlotItem.tsx
    │   │   ├── SpaceFiller
    │   │   │   ├── SpaceFiller.md
    │   │   │   ├── SpaceFiller.module.scss
    │   │   │   ├── SpaceFiller.spec.ts
    │   │   │   ├── SpaceFiller.tsx
    │   │   │   └── SpaceFillerNative.tsx
    │   │   ├── Spinner
    │   │   │   ├── Spinner.md
    │   │   │   ├── Spinner.module.scss
    │   │   │   ├── Spinner.spec.ts
    │   │   │   ├── Spinner.tsx
    │   │   │   └── SpinnerNative.tsx
    │   │   ├── Splitter
    │   │   │   ├── HSplitter.md
    │   │   │   ├── HSplitter.spec.ts
    │   │   │   ├── Splitter.md
    │   │   │   ├── Splitter.module.scss
    │   │   │   ├── Splitter.spec.ts
    │   │   │   ├── Splitter.tsx
    │   │   │   ├── SplitterNative.tsx
    │   │   │   ├── utils.ts
    │   │   │   ├── VSplitter.md
    │   │   │   └── VSplitter.spec.ts
    │   │   ├── Stack
    │   │   │   ├── CHStack.md
    │   │   │   ├── CHStack.spec.ts
    │   │   │   ├── CVStack.md
    │   │   │   ├── CVStack.spec.ts
    │   │   │   ├── HStack.md
    │   │   │   ├── HStack.spec.ts
    │   │   │   ├── Stack.md
    │   │   │   ├── Stack.module.scss
    │   │   │   ├── Stack.spec.ts
    │   │   │   ├── Stack.tsx
    │   │   │   ├── StackNative.tsx
    │   │   │   ├── VStack.md
    │   │   │   └── VStack.spec.ts
    │   │   ├── StickyBox
    │   │   │   ├── StickyBox.md
    │   │   │   ├── StickyBox.module.scss
    │   │   │   ├── StickyBox.tsx
    │   │   │   └── StickyBoxNative.tsx
    │   │   ├── Switch
    │   │   │   ├── Switch.md
    │   │   │   ├── Switch.spec.ts
    │   │   │   └── Switch.tsx
    │   │   ├── Table
    │   │   │   ├── doc-resources
    │   │   │   │   └── list-component-data.js
    │   │   │   ├── react-table-config.d.ts
    │   │   │   ├── Table.md
    │   │   │   ├── Table.module.scss
    │   │   │   ├── Table.spec.ts
    │   │   │   ├── Table.tsx
    │   │   │   ├── TableNative.tsx
    │   │   │   └── useRowSelection.tsx
    │   │   ├── TableOfContents
    │   │   │   ├── TableOfContents.module.scss
    │   │   │   ├── TableOfContents.spec.ts
    │   │   │   ├── TableOfContents.tsx
    │   │   │   └── TableOfContentsNative.tsx
    │   │   ├── Tabs
    │   │   │   ├── TabContext.tsx
    │   │   │   ├── TabItem.md
    │   │   │   ├── TabItem.tsx
    │   │   │   ├── TabItemNative.tsx
    │   │   │   ├── Tabs.md
    │   │   │   ├── Tabs.module.scss
    │   │   │   ├── Tabs.spec.ts
    │   │   │   ├── Tabs.tsx
    │   │   │   └── TabsNative.tsx
    │   │   ├── Text
    │   │   │   ├── Text.md
    │   │   │   ├── Text.module.scss
    │   │   │   ├── Text.spec.ts
    │   │   │   ├── Text.tsx
    │   │   │   └── TextNative.tsx
    │   │   ├── TextArea
    │   │   │   ├── TextArea.md
    │   │   │   ├── TextArea.module.scss
    │   │   │   ├── TextArea.spec.ts
    │   │   │   ├── TextArea.tsx
    │   │   │   ├── TextAreaNative.tsx
    │   │   │   ├── TextAreaResizable.tsx
    │   │   │   └── useComposedRef.ts
    │   │   ├── TextBox
    │   │   │   ├── TextBox.md
    │   │   │   ├── TextBox.module.scss
    │   │   │   ├── TextBox.spec.ts
    │   │   │   ├── TextBox.tsx
    │   │   │   └── TextBoxNative.tsx
    │   │   ├── Theme
    │   │   │   ├── NotificationToast.tsx
    │   │   │   ├── Theme.md
    │   │   │   ├── Theme.module.scss
    │   │   │   ├── Theme.spec.ts
    │   │   │   ├── Theme.tsx
    │   │   │   └── ThemeNative.tsx
    │   │   ├── TimeInput
    │   │   │   ├── TimeInput.md
    │   │   │   ├── TimeInput.module.scss
    │   │   │   ├── TimeInput.spec.ts
    │   │   │   ├── TimeInput.tsx
    │   │   │   ├── TimeInputNative.tsx
    │   │   │   └── utils.ts
    │   │   ├── Timer
    │   │   │   ├── Timer.md
    │   │   │   ├── Timer.spec.ts
    │   │   │   ├── Timer.tsx
    │   │   │   └── TimerNative.tsx
    │   │   ├── Toggle
    │   │   │   ├── Toggle.module.scss
    │   │   │   └── Toggle.tsx
    │   │   ├── ToneChangerButton
    │   │   │   ├── ToneChangerButton.md
    │   │   │   ├── ToneChangerButton.spec.ts
    │   │   │   └── ToneChangerButton.tsx
    │   │   ├── ToneSwitch
    │   │   │   ├── ToneSwitch.md
    │   │   │   ├── ToneSwitch.module.scss
    │   │   │   ├── ToneSwitch.spec.ts
    │   │   │   ├── ToneSwitch.tsx
    │   │   │   └── ToneSwitchNative.tsx
    │   │   ├── Tooltip
    │   │   │   ├── Tooltip.md
    │   │   │   ├── Tooltip.module.scss
    │   │   │   ├── Tooltip.spec.ts
    │   │   │   ├── Tooltip.tsx
    │   │   │   └── TooltipNative.tsx
    │   │   ├── Tree
    │   │   │   ├── testData.ts
    │   │   │   ├── Tree-dynamic.spec.ts
    │   │   │   ├── Tree-icons.spec.ts
    │   │   │   ├── Tree.md
    │   │   │   ├── Tree.spec.ts
    │   │   │   ├── TreeComponent.module.scss
    │   │   │   ├── TreeComponent.tsx
    │   │   │   └── TreeNative.tsx
    │   │   ├── TreeDisplay
    │   │   │   ├── TreeDisplay.md
    │   │   │   ├── TreeDisplay.module.scss
    │   │   │   ├── TreeDisplay.tsx
    │   │   │   └── TreeDisplayNative.tsx
    │   │   ├── ValidationSummary
    │   │   │   ├── ValidationSummary.module.scss
    │   │   │   └── ValidationSummary.tsx
    │   │   └── VisuallyHidden.tsx
    │   ├── components-core
    │   │   ├── abstractions
    │   │   │   ├── ComponentRenderer.ts
    │   │   │   ├── LoaderRenderer.ts
    │   │   │   ├── standalone.ts
    │   │   │   └── treeAbstractions.ts
    │   │   ├── action
    │   │   │   ├── actions.ts
    │   │   │   ├── APICall.tsx
    │   │   │   ├── FileDownloadAction.tsx
    │   │   │   ├── FileUploadAction.tsx
    │   │   │   ├── NavigateAction.tsx
    │   │   │   └── TimedAction.tsx
    │   │   ├── ApiBoundComponent.tsx
    │   │   ├── appContext
    │   │   │   ├── date-functions.ts
    │   │   │   ├── math-function.ts
    │   │   │   └── misc-utils.ts
    │   │   ├── AppContext.tsx
    │   │   ├── behaviors
    │   │   │   ├── Behavior.tsx
    │   │   │   └── CoreBehaviors.tsx
    │   │   ├── component-hooks.ts
    │   │   ├── ComponentDecorator.tsx
    │   │   ├── ComponentViewer.tsx
    │   │   ├── CompoundComponent.tsx
    │   │   ├── constants.ts
    │   │   ├── DebugViewProvider.tsx
    │   │   ├── descriptorHelper.ts
    │   │   ├── devtools
    │   │   │   ├── InspectorDialog.module.scss
    │   │   │   ├── InspectorDialog.tsx
    │   │   │   └── InspectorDialogVisibilityContext.tsx
    │   │   ├── EngineError.ts
    │   │   ├── event-handlers.ts
    │   │   ├── InspectorButton.module.scss
    │   │   ├── InspectorContext.tsx
    │   │   ├── interception
    │   │   │   ├── abstractions.ts
    │   │   │   ├── ApiInterceptor.ts
    │   │   │   ├── ApiInterceptorProvider.tsx
    │   │   │   ├── apiInterceptorWorker.ts
    │   │   │   ├── Backend.ts
    │   │   │   ├── Errors.ts
    │   │   │   ├── IndexedDb.ts
    │   │   │   ├── initMock.ts
    │   │   │   ├── InMemoryDb.ts
    │   │   │   ├── ReadonlyCollection.ts
    │   │   │   └── useApiInterceptorContext.tsx
    │   │   ├── loader
    │   │   │   ├── ApiLoader.tsx
    │   │   │   ├── DataLoader.tsx
    │   │   │   ├── ExternalDataLoader.tsx
    │   │   │   ├── Loader.tsx
    │   │   │   ├── MockLoaderRenderer.tsx
    │   │   │   └── PageableLoader.tsx
    │   │   ├── LoaderComponent.tsx
    │   │   ├── markup-check.ts
    │   │   ├── parts.ts
    │   │   ├── renderers.ts
    │   │   ├── rendering
    │   │   │   ├── AppContent.tsx
    │   │   │   ├── AppRoot.tsx
    │   │   │   ├── AppWrapper.tsx
    │   │   │   ├── buildProxy.ts
    │   │   │   ├── collectFnVarDeps.ts
    │   │   │   ├── ComponentAdapter.tsx
    │   │   │   ├── ComponentWrapper.tsx
    │   │   │   ├── Container.tsx
    │   │   │   ├── containers.ts
    │   │   │   ├── ContainerWrapper.tsx
    │   │   │   ├── ErrorBoundary.module.scss
    │   │   │   ├── ErrorBoundary.tsx
    │   │   │   ├── InvalidComponent.module.scss
    │   │   │   ├── InvalidComponent.tsx
    │   │   │   ├── nodeUtils.ts
    │   │   │   ├── reducer.ts
    │   │   │   ├── renderChild.tsx
    │   │   │   ├── StandaloneComponent.tsx
    │   │   │   ├── StateContainer.tsx
    │   │   │   ├── UnknownComponent.module.scss
    │   │   │   ├── UnknownComponent.tsx
    │   │   │   └── valueExtractor.ts
    │   │   ├── reportEngineError.ts
    │   │   ├── RestApiProxy.ts
    │   │   ├── script-runner
    │   │   │   ├── asyncProxy.ts
    │   │   │   ├── AttributeValueParser.ts
    │   │   │   ├── bannedFunctions.ts
    │   │   │   ├── BindingTreeEvaluationContext.ts
    │   │   │   ├── eval-tree-async.ts
    │   │   │   ├── eval-tree-common.ts
    │   │   │   ├── eval-tree-sync.ts
    │   │   │   ├── ParameterParser.ts
    │   │   │   ├── process-statement-async.ts
    │   │   │   ├── process-statement-common.ts
    │   │   │   ├── process-statement-sync.ts
    │   │   │   ├── ScriptingSourceTree.ts
    │   │   │   ├── simplify-expression.ts
    │   │   │   ├── statement-queue.ts
    │   │   │   └── visitors.ts
    │   │   ├── StandaloneApp.tsx
    │   │   ├── StandaloneExtensionManager.ts
    │   │   ├── TableOfContentsContext.tsx
    │   │   ├── theming
    │   │   │   ├── _themes.scss
    │   │   │   ├── component-layout-resolver.ts
    │   │   │   ├── extendThemeUtils.ts
    │   │   │   ├── hvar.ts
    │   │   │   ├── layout-resolver.ts
    │   │   │   ├── parse-layout-props.ts
    │   │   │   ├── StyleContext.tsx
    │   │   │   ├── StyleRegistry.ts
    │   │   │   ├── ThemeContext.tsx
    │   │   │   ├── ThemeProvider.tsx
    │   │   │   ├── themes
    │   │   │   │   ├── base-utils.ts
    │   │   │   │   ├── palette.ts
    │   │   │   │   ├── root.ts
    │   │   │   │   ├── solid.ts
    │   │   │   │   ├── theme-colors.ts
    │   │   │   │   └── xmlui.ts
    │   │   │   ├── themeVars.module.scss
    │   │   │   ├── themeVars.ts
    │   │   │   ├── transformThemeVars.ts
    │   │   │   └── utils.ts
    │   │   ├── utils
    │   │   │   ├── actionUtils.ts
    │   │   │   ├── audio-utils.ts
    │   │   │   ├── base64-utils.ts
    │   │   │   ├── compound-utils.ts
    │   │   │   ├── css-utils.ts
    │   │   │   ├── DataLoaderQueryKeyGenerator.ts
    │   │   │   ├── date-utils.ts
    │   │   │   ├── extractParam.ts
    │   │   │   ├── hooks.tsx
    │   │   │   ├── LruCache.ts
    │   │   │   ├── mergeProps.ts
    │   │   │   ├── misc.ts
    │   │   │   ├── request-params.ts
    │   │   │   ├── statementUtils.ts
    │   │   │   └── treeUtils.ts
    │   │   └── xmlui-parser.ts
    │   ├── index-standalone.ts
    │   ├── index.scss
    │   ├── index.ts
    │   ├── language-server
    │   │   ├── server-common.ts
    │   │   ├── server-web-worker.ts
    │   │   ├── server.ts
    │   │   ├── services
    │   │   │   ├── common
    │   │   │   │   ├── docs-generation.ts
    │   │   │   │   ├── lsp-utils.ts
    │   │   │   │   ├── metadata-utils.ts
    │   │   │   │   └── syntax-node-utilities.ts
    │   │   │   ├── completion.ts
    │   │   │   ├── diagnostic.ts
    │   │   │   ├── format.ts
    │   │   │   └── hover.ts
    │   │   └── xmlui-metadata-generated.js
    │   ├── logging
    │   │   ├── LoggerContext.tsx
    │   │   ├── LoggerInitializer.tsx
    │   │   ├── LoggerService.ts
    │   │   └── xmlui.ts
    │   ├── logo.svg
    │   ├── parsers
    │   │   ├── common
    │   │   │   ├── GenericToken.ts
    │   │   │   ├── InputStream.ts
    │   │   │   └── utils.ts
    │   │   ├── scripting
    │   │   │   ├── code-behind-collect.ts
    │   │   │   ├── Lexer.ts
    │   │   │   ├── modules.ts
    │   │   │   ├── Parser.ts
    │   │   │   ├── ParserError.ts
    │   │   │   ├── ScriptingNodeTypes.ts
    │   │   │   ├── TokenTrait.ts
    │   │   │   ├── TokenType.ts
    │   │   │   └── tree-visitor.ts
    │   │   ├── style-parser
    │   │   │   ├── errors.ts
    │   │   │   ├── source-tree.ts
    │   │   │   ├── StyleInputStream.ts
    │   │   │   ├── StyleLexer.ts
    │   │   │   ├── StyleParser.ts
    │   │   │   └── tokens.ts
    │   │   └── xmlui-parser
    │   │       ├── CharacterCodes.ts
    │   │       ├── diagnostics.ts
    │   │       ├── fileExtensions.ts
    │   │       ├── index.ts
    │   │       ├── lint.ts
    │   │       ├── parser.ts
    │   │       ├── ParserError.ts
    │   │       ├── scanner.ts
    │   │       ├── syntax-kind.ts
    │   │       ├── syntax-node.ts
    │   │       ├── transform.ts
    │   │       ├── utils.ts
    │   │       ├── xmlui-serializer.ts
    │   │       └── xmlui-tree.ts
    │   ├── react-app-env.d.ts
    │   ├── syntax
    │   │   ├── monaco
    │   │   │   ├── grammar.monacoLanguage.ts
    │   │   │   ├── index.ts
    │   │   │   ├── xmlui-dark.ts
    │   │   │   ├── xmlui-light.ts
    │   │   │   └── xmluiscript.monacoLanguage.ts
    │   │   └── textMate
    │   │       ├── index.ts
    │   │       ├── xmlui-dark.json
    │   │       ├── xmlui-light.json
    │   │       ├── xmlui.json
    │   │       └── xmlui.tmLanguage.json
    │   ├── testing
    │   │   ├── assertions.ts
    │   │   ├── component-test-helpers.ts
    │   │   ├── ComponentDrivers.ts
    │   │   ├── drivers
    │   │   │   ├── DateInputDriver.ts
    │   │   │   ├── index.ts
    │   │   │   ├── ModalDialogDriver.ts
    │   │   │   ├── NumberBoxDriver.ts
    │   │   │   ├── TextBoxDriver.ts
    │   │   │   ├── TimeInputDriver.ts
    │   │   │   ├── TimerDriver.ts
    │   │   │   └── TreeDriver.ts
    │   │   ├── fixtures.ts
    │   │   ├── index.ts
    │   │   ├── infrastructure
    │   │   │   ├── index.html
    │   │   │   ├── main.tsx
    │   │   │   ├── public
    │   │   │   │   ├── mockServiceWorker.js
    │   │   │   │   ├── resources
    │   │   │   │   │   ├── bell.svg
    │   │   │   │   │   ├── box.svg
    │   │   │   │   │   ├── doc.svg
    │   │   │   │   │   ├── eye.svg
    │   │   │   │   │   ├── flower-640x480.jpg
    │   │   │   │   │   ├── sun.svg
    │   │   │   │   │   ├── test-image-100x100.jpg
    │   │   │   │   │   └── txt.svg
    │   │   │   │   └── serve.json
    │   │   │   └── TestBed.tsx
    │   │   └── themed-app-test-helpers.ts
    │   └── vite-env.d.ts
    ├── tests
    │   ├── components
    │   │   ├── CodeBlock
    │   │   │   └── hightlight-code.test.ts
    │   │   ├── playground-pattern.test.ts
    │   │   └── Tree
    │   │       └── Tree-states.test.ts
    │   ├── components-core
    │   │   ├── abstractions
    │   │   │   └── treeAbstractions.test.ts
    │   │   ├── container
    │   │   │   └── buildProxy.test.ts
    │   │   ├── interception
    │   │   │   ├── orderBy.test.ts
    │   │   │   ├── ReadOnlyCollection.test.ts
    │   │   │   └── request-param-converter.test.ts
    │   │   ├── scripts-runner
    │   │   │   ├── AttributeValueParser.test.ts
    │   │   │   ├── eval-tree-arrow-async.test.ts
    │   │   │   ├── eval-tree-arrow.test.ts
    │   │   │   ├── eval-tree-func-decl-async.test.ts
    │   │   │   ├── eval-tree-func-decl.test.ts
    │   │   │   ├── eval-tree-pre-post.test.ts
    │   │   │   ├── eval-tree-regression.test.ts
    │   │   │   ├── eval-tree.test.ts
    │   │   │   ├── function-proxy.test.ts
    │   │   │   ├── parser-regression.test.ts
    │   │   │   ├── process-event.test.ts
    │   │   │   ├── process-function.test.ts
    │   │   │   ├── process-implicit-context.test.ts
    │   │   │   ├── process-statement-asgn.test.ts
    │   │   │   ├── process-statement-destruct.test.ts
    │   │   │   ├── process-statement-regs.test.ts
    │   │   │   ├── process-statement-sync.test.ts
    │   │   │   ├── process-statement.test.ts
    │   │   │   ├── process-switch-sync.test.ts
    │   │   │   ├── process-switch.test.ts
    │   │   │   ├── process-try-sync.test.ts
    │   │   │   ├── process-try.test.ts
    │   │   │   └── test-helpers.ts
    │   │   ├── test-metadata-handler.ts
    │   │   ├── theming
    │   │   │   ├── border-segments.test.ts
    │   │   │   ├── component-layout.resolver.test.ts
    │   │   │   ├── layout-property-parser.test.ts
    │   │   │   ├── layout-resolver.test.ts
    │   │   │   ├── layout-resolver2.test.ts
    │   │   │   ├── layout-vp-override.test.ts
    │   │   │   └── padding-segments.test.ts
    │   │   └── utils
    │   │       ├── date-utils.test.ts
    │   │       ├── format-human-elapsed-time.test.ts
    │   │       └── LruCache.test.ts
    │   ├── language-server
    │   │   ├── completion.test.ts
    │   │   ├── format.test.ts
    │   │   ├── hover.test.ts
    │   │   └── mockData.ts
    │   └── parsers
    │       ├── common
    │       │   └── input-stream.test.ts
    │       ├── markdown
    │       │   └── parse-binding-expression.test.ts
    │       ├── parameter-parser.test.ts
    │       ├── paremeter-parser.test.ts
    │       ├── scripting
    │       │   ├── eval-tree-arrow.test.ts
    │       │   ├── eval-tree-pre-post.test.ts
    │       │   ├── eval-tree.test.ts
    │       │   ├── function-proxy.test.ts
    │       │   ├── lexer-literals.test.ts
    │       │   ├── lexer-misc.test.ts
    │       │   ├── module-parse.test.ts
    │       │   ├── parser-arrow.test.ts
    │       │   ├── parser-assignments.test.ts
    │       │   ├── parser-binary.test.ts
    │       │   ├── parser-destructuring.test.ts
    │       │   ├── parser-errors.test.ts
    │       │   ├── parser-expressions.test.ts
    │       │   ├── parser-function.test.ts
    │       │   ├── parser-literals.test.ts
    │       │   ├── parser-primary.test.ts
    │       │   ├── parser-regex.test.ts
    │       │   ├── parser-statements.test.ts
    │       │   ├── parser-unary.test.ts
    │       │   ├── process-event.test.ts
    │       │   ├── process-implicit-context.test.ts
    │       │   ├── process-statement-asgn.test.ts
    │       │   ├── process-statement-destruct.test.ts
    │       │   ├── process-statement-regs.test.ts
    │       │   ├── process-statement-sync.test.ts
    │       │   ├── process-statement.test.ts
    │       │   ├── process-switch-sync.test.ts
    │       │   ├── process-switch.test.ts
    │       │   ├── process-try-sync.test.ts
    │       │   ├── process-try.test.ts
    │       │   ├── simplify-expression.test.ts
    │       │   ├── statement-hooks.test.ts
    │       │   └── test-helpers.ts
    │       ├── style-parser
    │       │   ├── generateHvarChain.test.ts
    │       │   ├── parseHVar.test.ts
    │       │   ├── parser.test.ts
    │       │   └── tokens.test.ts
    │       └── xmlui
    │           ├── lint.test.ts
    │           ├── parser.test.ts
    │           ├── scanner.test.ts
    │           ├── transform.attr.test.ts
    │           ├── transform.circular.test.ts
    │           ├── transform.element.test.ts
    │           ├── transform.errors.test.ts
    │           ├── transform.escape.test.ts
    │           ├── transform.regression.test.ts
    │           ├── transform.script.test.ts
    │           ├── transform.test.ts
    │           └── xmlui.ts
    ├── tests-e2e
    │   ├── api-bound-component-regression.spec.ts
    │   ├── api-call-as-extracted-component.spec.ts
    │   ├── assign-to-object-or-array-regression.spec.ts
    │   ├── binding-regression.spec.ts
    │   ├── children-as-template-context-vars.spec.ts
    │   ├── compound-component.spec.ts
    │   ├── context-vars-regression.spec.ts
    │   ├── data-bindings.spec.ts
    │   ├── datasource-and-api-usage-in-var.spec.ts
    │   ├── datasource-direct-binding.spec.ts
    │   ├── datasource-onLoaded-regression.spec.ts
    │   ├── modify-array-item-regression.spec.ts
    │   ├── namespaces.spec.ts
    │   ├── push-to-array-regression.spec.ts
    │   ├── screen-breakpoints.spec.ts
    │   ├── scripting.spec.ts
    │   ├── state-scope-in-pages.spec.ts
    │   └── state-var-scopes.spec.ts
    ├── tsconfig.bin.json
    ├── tsconfig.json
    ├── tsconfig.node.json
    ├── vite.config.ts
    └── vitest.config.ts
```

# Files

--------------------------------------------------------------------------------
/tools/vscode/CHANGELOG.md:
--------------------------------------------------------------------------------

```markdown
# xmlui-vscode

## 0.11.2

### Patch Changes

- Updated dependencies [c1f306f]
  - [email protected]

## 0.11.1

### Patch Changes

- Updated dependencies [7bbbb1d]
  - [email protected]

## 0.11.0

### Patch Changes

- Updated dependencies [fe503eb]
- Updated dependencies [06bb966]
- Updated dependencies [19145d2]
- Updated dependencies [e6b5810]
- Updated dependencies [db94656]
- Updated dependencies [fe503eb]
- Updated dependencies [82ddbe7]
- Updated dependencies [5109dce]
- Updated dependencies [75b701b]
  - [email protected]

## 0.10.26

### Patch Changes

- Updated dependencies [e1b8d58]
- Updated dependencies [1ad832c]
  - [email protected]

## 0.10.25

### Patch Changes

- Updated dependencies [e7c503e]
- Updated dependencies [5fe3052]
- Updated dependencies [5fe3052]
- Updated dependencies [250647b]
  - [email protected]

## 0.10.24

### Patch Changes

- Updated dependencies [3e361c4]
- Updated dependencies [3e361c4]
  - [email protected]

## 0.10.23

### Patch Changes

- Updated dependencies [bf18444]
- Updated dependencies [6d3bb89]
- Updated dependencies [89c69af]
- Updated dependencies [4cfebf0]
- Updated dependencies [145cd68]
  - [email protected]

## 0.10.22

### Patch Changes

- Updated dependencies [501f60a]
- Updated dependencies [1020f1c]
  - [email protected]

## 0.10.21

### Patch Changes

- Updated dependencies [6fd4d62]
  - [email protected]

## 0.10.20

### Patch Changes

- Updated dependencies [26eac90]
- Updated dependencies [f53edff]
- Updated dependencies [1840916]
- Updated dependencies [c6be7a3]
- Updated dependencies [6aaefaf]
- Updated dependencies [28d2585]
- Updated dependencies [e29a231]
- Updated dependencies [22162c0]
- Updated dependencies [e90232b]
  - [email protected]

## 0.10.19

### Patch Changes

- Updated dependencies [facb257]
- Updated dependencies [6084c14]
- Updated dependencies [e1fa9d7]
  - [email protected]

## 0.10.18

### Patch Changes

- Updated dependencies [202f2b2]
- Updated dependencies [6650ee8]
- Updated dependencies [da98994]
- Updated dependencies [8394663]
  - [email protected]

## 0.10.17

### Patch Changes

- Updated dependencies [07dae0b]
  - [email protected]

## 0.10.16

### Patch Changes

- Updated dependencies [0ba6612]
- Updated dependencies [7b78052]
- Updated dependencies [314b429]
- Updated dependencies [a1dea8f]
- Updated dependencies [cff754c]
  - [email protected]

## 0.10.15

### Patch Changes

- Updated dependencies [3c8ad14]
- Updated dependencies [5502fea]
- Updated dependencies [e08f0ba]
- Updated dependencies [5502fea]
- Updated dependencies [db618b5]
- Updated dependencies [a795b3d]
- Updated dependencies [5851c02]
  - [email protected]

## 0.10.14

### Patch Changes

- Updated dependencies [618049b]
- Updated dependencies [215a142]
- Updated dependencies [65b52e1]
- Updated dependencies [0cc2178]
- Updated dependencies [53d4ed9]
  - [email protected]

## 0.10.13

### Patch Changes

- Updated dependencies [9401ee0]
- Updated dependencies [eb62858]
- Updated dependencies [eb62858]
- Updated dependencies [eb62858]
- Updated dependencies [eb62858]
- Updated dependencies [eb62858]
- Updated dependencies [eb62858]
- Updated dependencies [243b7fa]
- Updated dependencies [eb62858]
  - [email protected]

## 0.10.12

### Patch Changes

- Updated dependencies [f12a042]
- Updated dependencies [8731eb8]
- Updated dependencies [eb6454f]
- Updated dependencies [1210852]
  - [email protected]

## 0.10.11

### Patch Changes

- Updated dependencies [8c76c8d]
- Updated dependencies [d56c3e5]
- Updated dependencies [e42d367]
- Updated dependencies [f539526]
- Updated dependencies [19ce234]
- Updated dependencies [455b6c0]
- Updated dependencies [e90dc73]
- Updated dependencies [819b563]
- Updated dependencies [b57dfa2]
- Updated dependencies [9dd0f97]
- Updated dependencies [19ce234]
- Updated dependencies [898346d]
- Updated dependencies [705dd04]
  - [email protected]

## 0.10.10

### Patch Changes

- Updated dependencies [fff80c5]
  - [email protected]

## 0.10.9

### Patch Changes

- Updated dependencies [879c09d]
- Updated dependencies [3ad8514]
- Updated dependencies [0c69245]
- Updated dependencies [4ad31fc]
- Updated dependencies [c99f184]
- Updated dependencies [5032e4a]
- Updated dependencies [2394f36]
  - [email protected]

## 0.10.8

### Patch Changes

- Updated dependencies [a4d62c4]
- Updated dependencies [7ed2918]
  - [email protected]

## 0.10.7

### Patch Changes

- Updated dependencies [664ea4f]
- Updated dependencies [a739a26]
- Updated dependencies [bdb54dd]
- Updated dependencies [81724c6]
  - [email protected]

## 0.10.6

### Patch Changes

- Updated dependencies [6464ec8]
  - [email protected]

## 0.10.5

### Patch Changes

- Updated dependencies [d38351d]
  - [email protected]

## 0.10.4

### Patch Changes

- Updated dependencies [43fd8c5]
- Updated dependencies [1df8e5d]
- Updated dependencies [0d5d9d1]
- Updated dependencies [3def673]
- Updated dependencies [428ebea]
- Updated dependencies [a12ce66]
  - [email protected]

## 0.10.3

### Patch Changes

- Updated dependencies [2e512bb]
- Updated dependencies [46d1d18]
- Updated dependencies [6bc9ed1]
- Updated dependencies [0b1f983]
- Updated dependencies [a2637f3]
- Updated dependencies [eb4d592]
  - [email protected]

## 0.10.2

### Patch Changes

- Updated dependencies [ff14e15]
- Updated dependencies [1451a94]
  - [email protected]

## 0.10.1

### Patch Changes

- Updated dependencies [442416b]
- Updated dependencies [a018431]
- Updated dependencies [33cb547]
- Updated dependencies [b5d7537]
  - [email protected]

## 0.10.0

### Patch Changes

- Updated dependencies [6d0ce52]
- Updated dependencies [8c98f33]
- Updated dependencies [ef86593]
- Updated dependencies [da5f4e7]
- Updated dependencies [47c7a2d]
- Updated dependencies [740f904]
- Updated dependencies [5009c52]
- Updated dependencies [000a311]
- Updated dependencies [eb8b958]
- Updated dependencies [2f5ec32]
  - [email protected]

## 0.9.101

### Patch Changes

- Updated dependencies [791b0be]
  - [email protected]

## 0.9.100

### Patch Changes

- Updated dependencies [2dbf6d2]
  - [email protected]

## 0.9.99

### Patch Changes

- Updated dependencies [e5a09fb]
- Updated dependencies [36360f6]
  - [email protected]

## 0.9.98

### Patch Changes

- Updated dependencies [ff781f3]
- Updated dependencies [377f0f2]
- Updated dependencies [ce0ff76]
- Updated dependencies [208768a]
  - [email protected]

## 0.9.97

### Patch Changes

- Updated dependencies [f7e8019]
  - [email protected]

## 0.9.96

### Patch Changes

- Updated dependencies [3196156]
- Updated dependencies [cfee78a]
- Updated dependencies [f51002a]
- Updated dependencies [3fa52d9]
  - [email protected]

## 0.9.95

### Patch Changes

- Updated dependencies [af6a7a0]
- Updated dependencies [69a2a8f]
- Updated dependencies [29c68fe]
  - [email protected]

## 0.9.94

### Patch Changes

- Updated dependencies [1d9365c]
  - [email protected]

## 0.9.93

### Patch Changes

- Updated dependencies [af17117]
- Updated dependencies [44da3d9]
- Updated dependencies [b7a6b9a]
- Updated dependencies [bc95844]
- Updated dependencies [52d94a2]
- Updated dependencies [6629ce5]
- Updated dependencies [0254471]
- Updated dependencies [3318cfb]
  - [email protected]

## 0.9.92

### Patch Changes

- Updated dependencies [347cda1]
  - [email protected]

## 0.9.91

### Patch Changes

- Updated dependencies [6a7d779]
  - [email protected]

## 0.9.90

### Patch Changes

- Updated dependencies [4b57f7e]
  - [email protected]

## 0.9.89

### Patch Changes

- Updated dependencies [2968eb9]
- Updated dependencies [94f4eb5]
- Updated dependencies [8364c03]
  - [email protected]

## 0.9.88

### Patch Changes

- d4235e9: feat: layout properties displayed later in completion list
- Updated dependencies [b79d7d8]
  - [email protected]

## 0.9.87

### Patch Changes

- Updated dependencies [33846c2]
  - [email protected]

## 0.9.86

### Patch Changes

- Updated dependencies [48af60d]
  - [email protected]

## 0.9.85

### Patch Changes

- Updated dependencies [ee8d6ad]
- Updated dependencies [9ca7572]
- Updated dependencies [6944d2f]
- Updated dependencies [c0c10e7]
- Updated dependencies [cbe1ef2]
  - [email protected]

## 0.9.84

### Patch Changes

- Updated dependencies [c54abf3]
  - [email protected]

## 0.9.83

### Patch Changes

- Updated dependencies [8e3d6a3]
- Updated dependencies [8644010]
  - [email protected]

## 0.9.82

### Patch Changes

- Updated dependencies [3bc29ae]
- Updated dependencies [1101bf5]
- Updated dependencies [cd8db58]
- Updated dependencies [13beb58]
- Updated dependencies [79c1d8a]
  - [email protected]

## 0.9.81

### Patch Changes

- Updated dependencies [59680b7]
  - [email protected]

## 0.9.80

### Patch Changes

- Updated dependencies [4598566]
- Updated dependencies [14e6a7d]
- Updated dependencies [cf05bd2]
  - [email protected]

## 0.9.79

### Patch Changes

- Updated dependencies [ad21a31]
  - [email protected]

## 0.9.78

### Patch Changes

- Updated dependencies [94a68f0]
- Updated dependencies [94a68f0]
- Updated dependencies [163a45c]
- Updated dependencies [7ce528b]
- Updated dependencies [c6eb9a8]
  - [email protected]

## 0.9.77

### Patch Changes

- Updated dependencies [c867f38]
  - [email protected]

## 0.9.76

### Patch Changes

- 15bf622: fix: add escaped \{ to textmate syntax, eliminate double extraction of props in FormItem causing bugs with escaped open curly brace being parsed as start of binding expression.
- Updated dependencies [aa08a8c]
- Updated dependencies [15bf622]
- Updated dependencies [5761868]
  - [email protected]

## 0.9.75

### Patch Changes

- 2edefdd: feat: ensure xmlui-vscode is versioned with xmlui
- Updated dependencies [c876be8]
  - [email protected]

## 0.1.2

### Patch Changes

- 2e808fa: Add custom xmlui formatter to better handle formatting erroneous syntax, long lines, and xmlui specific syntax, like backtick quoted strings, key-only attributes, etc...
- Updated dependencies [96273bf]
- Updated dependencies [1a81bcf]
  - [email protected]

## 0.1.1

### Patch Changes

- e964286: Add formating to language server and fix error recovery when tag name is erroneous
- Updated dependencies [de8d63c]
- Updated dependencies [bd6d1b4]
- Updated dependencies [db5a5f4]
- Updated dependencies [69b4402]
  - [email protected]

## 0.0.5

### Patch Changes

- 42416ba: test change for CI #2
- Updated dependencies [42416ba]
  - [email protected]

## 0.0.3

### Patch Changes

- e43b92a: another test change

## 0.0.2

### Patch Changes

- 3be75a4: test release for CI
- Updated dependencies [8d662f3]
  - [email protected]

```

--------------------------------------------------------------------------------
/xmlui/src/components/CodeBlock/highlight-code.ts:
--------------------------------------------------------------------------------

```typescript
import { type ReactNode, isValidElement } from "react";
import { encodeToBase64, decodeFromBase64 } from "../../components-core/utils/base64-utils";

const highlightRowsClass = "codeBlockHighlightRow";
const highlightSubstringsClass = "codeBlockHighlightString";
const highlightSubstringsEmphasisClass = "codeBlockHighlightStringEmphasis";

// Re-export for backward compatibility
export { encodeToBase64, decodeFromBase64 };

/**
 * This function handles two things:
 * 1. The extraction of meta information from code blocks and exposing them as data-meta attributes
 * 2. The highlighting of code blocks providing the highlighter function with meta information
 * @param node The React node containing the code block
 * @param codeHighlighter The highlighter object containing the highlight function and the available languages
 * @returns CSS class names for the codefence and the HTML string with highlighted code tokens
 */
export function parseMetaAndHighlightCode(
  node: ReactNode,
  codeHighlighter: CodeHighlighter,
  themeTone?: string,
): HighlighterResults | null {
  // parse
  const rawCodeStr = getCodeStrFromNode(node);
  const rawMeta = getCodeMetaFromNode(node, CodeHighlighterMetaKeysData);
  // map
  const codeStr = transformCodeLines(rawCodeStr);
  const meta = extractMetaFromChildren(rawMeta, codeStr);

  const { language, ...restMeta } = meta;
  if (language && codeHighlighter.availableLangs.includes(language)) {
    // NOTE: Keep in mind, at this point, we are working with the markdown text
    try{
      const htmlCodeStr = codeHighlighter.highlight(codeStr, language, restMeta, themeTone);
      const match = htmlCodeStr.match(/<pre\b[^>]*\bclass\s*=\s*["']([^"']*)["'][^>]*>/i);
      const classNames = match ? match[1] : null;

      // NOTE: Why remove the <pre>?
      // Shiki appends <pre> tags to the highlighted code,
      // so we would get <pre><pre><code>...</code></pre></pre>
      let cleanedHtmlStr = htmlCodeStr.replace(/<pre\b[^>]*>|<\/pre>/gi, "");

      const numberedRowClass = meta.rowNumbers ? "numbered" : "";
      cleanedHtmlStr = cleanedHtmlStr.replaceAll(
        /<span class="line"/g,
        `<span class="line ${numberedRowClass}"`,
      );

      return { classNames, cleanedHtmlStr, codeStr, meta };
    } catch (e){
      // this could happen in safari after the optimized build (some regexp issues, could be remix/vite/shiki related, TBD)
      return {
        meta,
        codeStr,
        cleanedHtmlStr: codeStr,
        classNames: null
      };
    }

  }
  return null;
}

function getCodeStrFromNode(node: ReactNode) {
  if (typeof node === "string") {
    return node;
  }

  if (isValidElement(node) && node.props && node.props.children) {
    if (Array.isArray(node.props.children)) {
      return node.props.children.map(getCodeStrFromNode).join("");
    }
    return getCodeStrFromNode(node.props.children);
  }
  return "";
}

function getCodeMetaFromNode(node: ReactNode, keys: string[]) {
  if (!node) return {};
  if (typeof node === "string") return {};
  if (typeof node === "number") return {};
  if (typeof node === "boolean") return {};
  if (Array.isArray(node)) return {};

  if (
    isValidElement(node) &&
    node.props &&
    node.props.children &&
    typeof node.props.children === "string"
  ) {
    return Object.entries(node.props)
      .filter(([key, _]) => keys.includes(key))
      .reduce(
        (acc, [key, value]) => {
          acc[key] = value;
          return acc;
        },
        {} as Record<string, any>,
      );
  }
  return {};
}

export function transformCodeLines(node: string) {
  const splitNode = node.split(/\r?\n/);
  for (let i = 0; i < splitNode.length; i++) {
    // Backslash before a codefence indicates an escaped codefence
    // -> don't render the backslash
    if (splitNode[i].startsWith("\\```")) {
      splitNode[i] = splitNode[i].replace("\\```", "```");
    }
  }

  // Remove empty lines from start and end
  let startTrimIdx = 0;
  let endTrimIdx = splitNode.length - 1;
  for (let i = 0; i < splitNode.length; i++) {
    if (splitNode[i].trim() !== "") {
      startTrimIdx = i;
      break;
    }
  }
  for (let i = splitNode.length - 1; i >= 0; i--) {
    if (splitNode[i].trim() !== "") {
      endTrimIdx = i;
      break;
    }
  }

  splitNode.splice(0, startTrimIdx);
  splitNode.splice(endTrimIdx + 1);
  return splitNode.join("\n");
}

export function extractMetaFromChildren(
  meta: Record<string, any>,
  code: string = "",
): CodeHighlighterMeta {
  if (!meta) return {};

  return {
    // NOTE: Row numbers are disabled for now, because applying the highlight class removes the "numbered" class
    /* [CodeHighlighterMetaKeys.rowNumbers.prop]: parseBoolean(
      meta[CodeHighlighterMetaKeys.rowNumbers.data],
    ), */
    [CodeHighlighterMetaKeys.language.prop]: meta[CodeHighlighterMetaKeys.language.data],
    [CodeHighlighterMetaKeys.copy.prop]: parseBoolean(meta[CodeHighlighterMetaKeys.copy.data]),
    [CodeHighlighterMetaKeys.filename.prop]: meta[CodeHighlighterMetaKeys.filename.data],
    [CodeHighlighterMetaKeys.highlightRows.prop]: parseRowHighlights(
      code,
      meta[CodeHighlighterMetaKeys.highlightRows.data],
    ),
    [CodeHighlighterMetaKeys.highlightSubstrings.prop]: parseSubstringHighlights(
      code,
      meta[CodeHighlighterMetaKeys.highlightSubstrings.data],
    ),
    [CodeHighlighterMetaKeys.highlightSubstringsEmphasized.prop]: parseSubstringHighlights(
      code,
      meta[CodeHighlighterMetaKeys.highlightSubstringsEmphasized.data],
      true,
    ),
  };
}

function parseBoolean(str?: string) {
  if (str === "true") return true;
  if (str === "false") return false;
  return false;
}

function parseRowHighlights(code: string, str?: string): DecorationItem[] {
  if (!str) return [];
  if (str === "") return [];
  const codeLines = code.split("\n");
  return str
    .split(",")
    .map((item) => {
      item = item.trim();
      const split = item.split("-");
      let start = -1;
      let end = -1;

      if (split.length === 0) return { start, end, properties: { class: highlightRowsClass } };
      if (split.length > 2) return { start, end, properties: { class: highlightRowsClass } };
      if (split[0] === "") return { start, end, properties: { class: highlightRowsClass } };
      if (split[1] === "") return { start, end, properties: { class: highlightRowsClass } };
      start = 0;
      end = 0;

      // Start Index
      const startIdx = validate(parse(split[0]));
      start = getLineLengthIndex(startIdx);

      // End Index
      const endIdx = split.length === 1 ? startIdx : validate(parse(split[1]));
      let endLineLength = 0;
      if (endIdx >= 0 && codeLines[endIdx] !== undefined) {
        endLineLength = codeLines[endIdx].length;
      }
      end = getLineLengthIndex(endIdx) + endLineLength;

      return { start, end, properties: { class: highlightRowsClass } };
    })
    .filter((item) => {
      if (item.start <= -1 || item.end <= -1) return false;
      if (item.start > code.length || item.end > code.length) return false;
      return true;
    });

  function parse(value: string): number {
    const parsed = parseInt(value, 10);
    if (Number.isNaN(parsed)) return -1;
    return parsed;
  }

  function validate(parsed: number): number {
    // correct for 0-indexed array
    parsed -= 1;
    // check bounds
    if (parsed < 0 || parsed >= codeLines.length) return -1;
    return parsed;
  }

  function getLineLengthIndex(lineNumber: number) {
    if (lineNumber < 0) return -1;
    if (lineNumber === 0) return 0;

    let count = 0;
    let index = 0;
    while (count < lineNumber && index !== -1) {
      index = code.indexOf('\n', index);
      if (index !== -1) {
        index++; // Move past the '\n'
        count++;
      }
    }
    return (index !== -1) ? index : -1;
  }
}

function parseSubstringHighlights(
  code: string,
  str?: string,
  emphasized = false,
): DecorationItem[] {
  if (!str) return [];
  if (!code) return [];
  return str
    .split(" ")
    .map((item) => decodeFromBase64(item))
    .filter((item) => item.trim() !== "")
    .reduce((acc, item) => acc.concat(findAllNonOverlappingSubstrings(code, item)), []);

  function findAllNonOverlappingSubstrings(str: string, code: string) {
    const result: DecorationItem[] = [];
    let startIndex = 0;
    const searchLength = code.length;

    while (startIndex <= str.length - searchLength) {
      const index = str.indexOf(code, startIndex);
      if (index === -1) break;

      result.push({
        start: index,
        end: index + searchLength,
        properties: {
          class: emphasized ? highlightSubstringsEmphasisClass : highlightSubstringsClass,
        },
      });
      startIndex = index + searchLength; // Jump past this match
    }

    return result;
  }
}

export type CodeHighlighter = {
  // Returns html in string!
  highlight: (
    code: string,
    language: string,
    meta?: CodeHighlighterMeta,
    themeTone?: string,
  ) => string;
  availableLangs: string[];
};

export function isCodeHighlighter(obj: any): obj is CodeHighlighter {
  return obj && obj.highlight && typeof obj.highlight === "function" && obj.availableLangs;
}

type HighlighterResults = {
  classNames: string | null;
  cleanedHtmlStr: string;
  codeStr: string;
  meta: CodeHighlighterMeta;
};

export type CodeHighlighterMeta = {
  language?: string;
  copy?: boolean;
  filename?: string;
  rowNumbers?: boolean;
  highlightRows?: DecorationItem[];
  highlightSubstrings?: DecorationItem[];
};

type DecorationItem = {
  start: number;
  end: number;
  properties: { class?: string; style?: string };
};

export const CodeHighlighterMetaKeys = {
  language: { data: "data-language", prop: "language" },
  copy: { data: "data-copy", prop: "copy" },
  filename: { data: "data-filename", prop: "filename" },
  rowNumbers: { data: "data-row-numbers", prop: "rowNumbers" },
  highlightRows: { data: "data-highlight-rows", prop: "highlightRows" },
  highlightSubstrings: { data: "data-highlight-substrings", prop: "highlightSubstrings" },
  highlightSubstringsEmphasized: {
    data: "data-highlight-substrings-emp",
    prop: "highlightSubstringsEmphasized",
  },
};
export const CodeHighlighterMetaKeysData = Object.values(CodeHighlighterMetaKeys).map(
  (item) => item.data,
);

```

--------------------------------------------------------------------------------
/xmlui/src/components-core/ApiBoundComponent.tsx:
--------------------------------------------------------------------------------

```typescript
import type { MutableRefObject } from "react";
import React, { useMemo } from "react";

import type { ComponentDef, ParentRenderContext } from "../abstractions/ComponentDefs";
import type { LayoutContext, RenderChildFn } from "../abstractions/RendererDefs";
import { parseAttributeValue } from "./script-runner/AttributeValueParser";

type ApiBoundComponentProps = {
  uid: symbol;
  node: ComponentDef;
  apiBoundProps: Array<string>;
  apiBoundEvents: Array<string>;
  renderChild: RenderChildFn;
  layoutContextRef?: MutableRefObject<LayoutContext | undefined>;
  parentRendererContext?: ParentRenderContext;
};

export function ApiBoundComponent({
  uid,
  node,
  apiBoundProps,
  apiBoundEvents,
  renderChild,
  layoutContextRef,
  parentRendererContext,
}: ApiBoundComponentProps) {
  const wrappedWithAdapter = useMemo(() => {
    function generateloaderUid(key: string) {
      return `${node.uid}_data_${key}`;
    }

    // Generates a string representation of an event handler function that calls 
    // the appropriate action. This function is used recursively for nested actions.
    function generateEventHandler(actionComponent: any): string {
      const { type } = actionComponent;

      // Prepares an event handler, which can be several types of data
      // (string for inline JS functions, parsed objects, or nested action components)
      const prepareEvent = (eventData: any) => {
        if (!eventData) {
          return "undefined";
        }
        if (typeof eventData === "string") {
          return `"${eventData}"`;
        }
        if (typeof eventData.type === "string") {
          return generateEventHandler(eventData);
        }
        return JSON.stringify(eventData);
      };

      // --- Prepare event handlers
      const { success, error, progress, beforeRequest } = actionComponent.events || {};
      switch (type) {
        case "FileUpload": {
          const {
            invalidates,
            asForm,
            formParams,
            queryParams,
            rawBody,
            body,
            url,
            headers,
            method,
            file,
          } = actionComponent.props;
          return `(eventArgs) => {
            return Actions.upload({
              asForm: ${JSON.stringify(asForm)}, 
              formParams: ${JSON.stringify(formParams)}, 
              queryParams: ${JSON.stringify(queryParams)}, 
              rawBody: ${JSON.stringify(rawBody)}, 
              body: ${JSON.stringify(body)}, 
              url: ${JSON.stringify(url)}, 
              headers: ${JSON.stringify(headers)}, 
              method: ${JSON.stringify(method)}, 
              file: ${JSON.stringify(file)}, 
              params: { '$param': eventArgs }, 
              onError: ${prepareEvent(error)}, 
              onSuccess: ${prepareEvent(success)}, 
              onProgress: eventArgs.onProgress, 
              invalidates: ${
                invalidates === undefined ? undefined : JSON.stringify(invalidates)
              }  }, { resolveBindingExpressions: true });
          }`;
        }
        case "FileDownload": {
          const { url, queryParams, rawBody, body, headers, method, fileName } =
            actionComponent.props;
          return `(eventArgs) => {
            return Actions.download({
              queryParams: ${JSON.stringify(queryParams)}, 
              rawBody: ${JSON.stringify(rawBody)}, 
              body: ${JSON.stringify(body)}, 
              url: ${JSON.stringify(url)}, 
              headers: ${JSON.stringify(headers)}, 
              method: ${JSON.stringify(method)}, 
              fileName: ${JSON.stringify(fileName)}, 
              params: { '$param': eventArgs },
            }, { resolveBindingExpressions: true });
          }`;
        }
        case "APICall": {
          const { when, uid } = actionComponent;

          const {
            confirmTitle,
            confirmMessage,
            confirmButtonLabel,
            inProgressNotificationMessage,
            completedNotificationMessage,
            errorNotificationMessage,
            invalidates,
            updates,
            optimisticValue,
            getOptimisticValue,
            headers,
            payloadType,
            method,
            url,
            queryParams,
            rawBody,
            body,
          } = actionComponent.props;

          return `(eventArgs, options) => {
            return Actions.callApi({
              uid: ${JSON.stringify(uid)},
              headers: ${JSON.stringify(headers)}, 
              method: ${JSON.stringify(method)}, 
              url: ${JSON.stringify(url)}, 
              queryParams: ${JSON.stringify(queryParams)}, 
              rawBody: ${JSON.stringify(rawBody)}, 
              body: ${JSON.stringify(body)} || (options?.passAsDefaultBody ? eventArgs : undefined), 
              confirmTitle: ${JSON.stringify(confirmTitle)}, 
              confirmMessage: ${JSON.stringify(confirmMessage)}, 
              confirmButtonLabel: ${JSON.stringify(confirmButtonLabel)}, 
              inProgressNotificationMessage: ${JSON.stringify(inProgressNotificationMessage)}, 
              completedNotificationMessage: ${JSON.stringify(completedNotificationMessage)}, 
              errorNotificationMessage: ${JSON.stringify(errorNotificationMessage)}, 
              params: { '$param': eventArgs }, 
              onError: ${prepareEvent(error)}, 
              onProgress: ${prepareEvent(progress)}, 
              onBeforeRequest: ${prepareEvent(beforeRequest)}, 
              onSuccess: ${prepareEvent(success)}, 
              updates: ${JSON.stringify(updates)}, 
              optimisticValue: ${JSON.stringify(optimisticValue)}, 
              payloadType: ${JSON.stringify(payloadType)}, 
              getOptimisticValue: ${JSON.stringify(getOptimisticValue)}, 
              invalidates: ${invalidates === undefined ? undefined : JSON.stringify(invalidates)}, 
              when: ${when === undefined ? undefined : JSON.stringify(when)} }, { resolveBindingExpressions: true });
          }`;
        }
        default: {
          throw new Error("Unknown event handler component type: ", type);
        }
      }
    }

    const loaders: Array<ComponentDef> = [...(node.loaders || [])];
    const events = { ...(node.events || {}) } as any;
    const props = { ...(node.props || {}) } as any;
    const vars = { ...(node.vars || {}) };
    const api = { ...(node.api || {}) };

    apiBoundEvents.forEach((key) => {
      const actionComponent = node.events![key];
      events[key] = generateEventHandler(actionComponent);
    });

    apiBoundProps.forEach((key) => {
      const isDatasourceRef = node.props![key]?.type === "DataSourceRef";
      const loaderUid = node.props![key].uid || generateloaderUid(key);
      const operation = node.props![key].props || node.props![key];
      const loaderEvents: Record<string, any> = {};
      Object.entries(node.events || {}).forEach(([eventKey, value]) => {
        if (eventKey.startsWith(key)) {
          const capitalizedEventName = eventKey.substring(key.length);
          const eventName =
            capitalizedEventName.charAt(0).toLowerCase() + capitalizedEventName.slice(1);
          loaderEvents[eventName] = value;
        }
      });
      if (key === "data") {
        props.__DATA_RESOLVED = true;
      }
      if (!isDatasourceRef) {
        loaders.push({
          type: "DataLoader",
          uid: loaderUid,
          props: operation,
          events: loaderEvents,
        });
        api[`fetch_${key}`] = `() => { ${loaderUid}.refetch(); }`;
        api[`update_${key}`] = `(updaterFn) => { ${loaderUid}.update(updaterFn); }`;
        api[`addItem_${key}`] = `(element, index) => {  ${loaderUid}.addItem(element, index); }`;
        api[`getItems_${key}`] = `() => { return ${loaderUid}.getItems(); }`;
        api[`deleteItem_${key}`] = `(element) => { ${loaderUid}.deleteItem(element); }`;
        if (key === "data") {
          props._data_url = operation.url;
        }
      }
      //illesg really experimental
      let prefetchKey = null;
      const { segments } = parseAttributeValue(operation.url?.trim());
      if (segments?.length === 1) {
        if (segments[0].literal) {
          prefetchKey = `"${segments[0].literal}"`;
        } else if (segments[0].expr) {
          // we remove the first and last characters, which are the curly braces
          prefetchKey = operation.url?.trim().substring(1, operation.url.length - 1);
        }
      }
      if (prefetchKey === null) {
        props[key] = `{ ${loaderUid}.value }`;
      } else {
        props[key] =
          `{ ${loaderUid}.value || ( appGlobals.prefetchedContent[${prefetchKey}] || appGlobals.prefetchedContent['/' + ${prefetchKey}] ) }`;
      }
      props.loading = `{ ${loaderUid}.inProgress === undefined ? true : ${loaderUid}.inProgress}`;
      props.pageInfo = `{${loaderUid}.pageInfo}`;
      events.requestFetchPrevPage = `${loaderUid}.fetchPrevPage()`;
      events.requestFetchNextPage = `${loaderUid}.fetchNextPage()`;
      // TODO if the user provides a requestRefetch handler, we should call it
      //  and then call the loader's refetch method if it returns !false;
      //  requestRefetch could receive parameters to select which apibound props to refetch
      events.requestRefetch = `()=> ${loaderUid}.refetch();`;
    });

    const wrapped = {
      ...node,
      containerUid: uid,
      apiBoundContainer: true,
      props,
      events,
    };
    if (loaders.length) {
      //to make sure that we don't wrap the component with a container if we don't have to
      wrapped.loaders = loaders;
    }
    if (Object.keys(vars).length) {
      //to make sure that we don't wrap the component with a container if we don't have to
      wrapped.vars = vars;
    }
    if (Object.keys(api).length) {
      //to make sure that we don't wrap the component with a container if we don't have to
      wrapped.api = api;
    }
    return wrapped;
  }, [apiBoundEvents, apiBoundProps, node, uid]);

  // useEffect(() => {
  //   console.log("wrapped with adapter changed", wrappedWithAdapter);
  // }, [wrappedWithAdapter]);

  const renderedChild = renderChild(
    wrappedWithAdapter,
    layoutContextRef?.current,
    parentRendererContext,
  );
  return React.isValidElement(renderedChild) ? renderedChild : <>{renderedChild}</>;
}

```

--------------------------------------------------------------------------------
/xmlui/src/components-core/loader/PageableLoader.tsx:
--------------------------------------------------------------------------------

```typescript
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from "react";
import type { InfiniteData, QueryFunction } from "@tanstack/react-query";
import { useInfiniteQuery } from "@tanstack/react-query";
import produce, { createDraft, finishDraft } from "immer";

import type { RegisterComponentApiFn } from "../../abstractions/RendererDefs";
import type { ComponentDef } from "../../abstractions/ComponentDefs";
import type { ContainerState } from "../rendering/ContainerWrapper";
import type {
  LoaderErrorFn,
  LoaderInProgressChangedFn,
  LoaderLoadedFn,
  TransformResultFn,
} from "../abstractions/LoaderRenderer";
import { extractParam } from "../utils/extractParam";
import { useAppContext } from "../AppContext";
import { usePrevious } from "../utils/hooks";

export type LoaderDirections = "FORWARD" | "BACKWARD" | "BIDIRECTIONAL";

type LoaderProps = {
  state: ContainerState;
  loader: ComponentDef;
  loaderFn: (abortSignal: AbortSignal | undefined, pageParam: string) => Promise<any>;
  queryId?: readonly any[];
  registerComponentApi: RegisterComponentApiFn;
  pollIntervalInSeconds?: number;
  onLoaded?: (...args: any[]) => void;
  loaderInProgressChanged: LoaderInProgressChangedFn;
  loaderIsRefetchingChanged: LoaderInProgressChangedFn;
  loaderLoaded: LoaderLoadedFn;
  loaderError: LoaderErrorFn;
  transformResult?: TransformResultFn;
  structuralSharing?: boolean;
};

export function PageableLoader({
  state,
  loader,
  loaderFn,
  queryId,
  registerComponentApi,
  pollIntervalInSeconds,
  onLoaded,
  loaderInProgressChanged,
  loaderIsRefetchingChanged,
  loaderLoaded,
  loaderError,
  transformResult,
  structuralSharing = true,
}: LoaderProps) {
  const { uid } = loader;
  const appContext = useAppContext();
  const queryKey = useMemo(
    () => (queryId ? queryId : [uid, extractParam(state, loader.props, appContext)]),
    [appContext, loader.props, queryId, state, uid],
  );
  const thizRef = useRef(queryKey);

  const getPreviousPageParam = useCallback(
    (firstPage: any) => {
      let prevPageParam = undefined;
      const prevPageSelector = loader.props.prevPageSelector;
      if (prevPageSelector) {
        prevPageParam = extractParam(
          { $response: firstPage.filter((item) => !item._optimisticValue) },
          prevPageSelector.startsWith("{") ? prevPageSelector : `{$response.${prevPageSelector}}`,
        );
      }
      if (!prevPageParam) {
        return undefined;
      }
      return {
        prevPageParam: prevPageParam,
      };
    },
    [loader.props.prevPageSelector],
  );
  const getNextPageParam = useCallback(
    (lastPage: any) => {
      let nextPageParam = undefined;
      const nextPageSelector = loader.props.nextPageSelector;
      if (nextPageSelector) {
        nextPageParam = extractParam(
          { $response: lastPage },
          nextPageSelector.startsWith("{") ? nextPageSelector : `{$response.${nextPageSelector}}`,
        );
      }
      if (!nextPageParam) {
        return undefined;
      }
      return {
        nextPageParam: nextPageParam,
      };
    },
    [loader.props.nextPageSelector],
  );

  // useEffect(()=>{
  //   console.log("TRANSFORM RESULT CHANGED", transformResult);
  // }, [transformResult]);
  const {
    data,
    status,
    error,
    hasNextPage,
    isFetchingNextPage,
    hasPreviousPage,
    isFetchingPreviousPage,
    isFetching,
    refetch,
    fetchPreviousPage,
    fetchNextPage,
    isRefetching,
  } = useInfiniteQuery({
    queryKey,
    queryFn: useCallback<QueryFunction>(
      async ({ signal, pageParam }) => {
        return await loaderFn(signal, pageParam);
      },
      [loaderFn],
    ),
    structuralSharing,
    select: useCallback(
      (data: any) => {
        let result = [];
        if (data) {
          result = data.pages.flatMap((d) => d);
        }
        const resultSelector = loader.props.resultSelector;
        if (resultSelector) {
          result = extractParam(
            { $response: result },
            resultSelector.startsWith("{") ? resultSelector : `{$response.${resultSelector}}`,
          );
        }
        return transformResult ? transformResult(result) : result;
      },
      [loader.props.resultSelector, transformResult],
    ),
    getPreviousPageParam:
      loader.props.prevPageSelector === undefined ? undefined : getPreviousPageParam,
    getNextPageParam: loader.props.nextPageSelector === undefined ? undefined : getNextPageParam,
  });

  //TODO revisit
  // //we clear all the pages, except the last one (it's suitable for the chat app, but for the other direction we'll have to leave the first page)
  // // otherwise it'll keep it in the cache, and refetch all the pages when you come back
  // //  see more here: https://stackoverflow.com/questions/71286123/reactquery-useinfinitequery-refetching-issue
  // //  and here: https://tanstack.com/query/latest/docs/react/guides/infinite-queries?from=reactQueryV3&original=https%3A%2F%2Ftanstack.com%2Fquery%2Fv3%2Fdocs%2Fguides%2Finfinite-queries#what-happens-when-an-infinite-query-needs-to-be-refetched
  useEffect(() => {
    const queryKey = thizRef.current;
    return () => {
      void appContext.queryClient?.cancelQueries(queryKey);
      appContext.queryClient?.setQueryData(queryKey, (old) => {
        if (!old) {
          return old;
        }
        return produce(old, (draft: any) => {
          draft.pages = draft.pages.length ? [draft.pages[draft.pages.length - 1]] : [];
          // draft.pageParams = draft.pageParams.length ? [draft.pageParams[draft.pageParams.length - 1]] : [];
          draft.pageParams = [];
        });
      });
      loaderLoaded(undefined, undefined);
    };
  }, [appContext.queryClient, loaderLoaded, uid]);

  const prevData = usePrevious(data);
  const prevError = usePrevious(error);

  useLayoutEffect(() => {
    loaderInProgressChanged(isFetching); //TODO isFetchingPrevPage / nextPage
  }, [isFetching, loaderInProgressChanged]);

  useLayoutEffect(() => {
    loaderIsRefetchingChanged(isRefetching); //TODO isFetchingPrevPage / nextPage
  }, [isRefetching, loaderIsRefetchingChanged]);

  const pageInfo = useMemo(() => {
    return {
      hasPrevPage: hasPreviousPage,
      isFetchingPrevPage: isFetchingPreviousPage,
      hasNextPage,
      isFetchingNextPage,
    };
  }, [hasNextPage, hasPreviousPage, isFetchingNextPage, isFetchingPreviousPage]);

  const prevPageInfo = usePrevious(pageInfo);

  useLayoutEffect(() => {
    // console.log("data changed", {
    //   status,
    //   data,
    //   pageInfo,
    // });
    if (status === "success" && (prevData !== data || prevPageInfo !== pageInfo)) {
      loaderLoaded(data, pageInfo);
      //we do this to push the onLoaded callback to the next event loop.
      // It works, because useLayoutEffect will run synchronously after the render, and the onLoaded callback will have
      // access to the latest loader value
      setTimeout(() => {
        onLoaded?.(data, isRefetching);
      }, 0);
    } else if (status === "error" && prevError !== error) {
      loaderError(error);
    }
  }, [
    data,
    error,
    isRefetching,
    loaderError,
    loaderLoaded,
    onLoaded,
    pageInfo,
    prevData,
    prevError,
    prevPageInfo,
    status,
  ]);

  useEffect(() => {
    let intervalId: NodeJS.Timeout;
    if (pollIntervalInSeconds) {
      intervalId = setInterval(() => {
        void refetch();
      }, pollIntervalInSeconds * 1000);
    }
    return () => {
      if (intervalId) {
        clearInterval(intervalId);
      }
    };
  }, [pollIntervalInSeconds, refetch]);

  const fetchPrevPage = useCallback(() => {
    return fetchPreviousPage();
  }, [fetchPreviousPage]);

  const stableFetchNextPage = useCallback(() => {
    return fetchNextPage();
  }, [fetchNextPage]);

  useEffect(() => {
    registerComponentApi({
      fetchPrevPage,
      fetchNextPage: stableFetchNextPage,
      refetch: (options) => {
        void refetch(options);
      },
      update: async (updater) => {
        const oldData = appContext.queryClient?.getQueryData(queryId!) as InfiniteData<any[]>;
        if (!oldData) {
          //loader not loaded yet, we skip the update
          return;
        }
        const originalFlatItems = oldData.pages.flatMap((d) => d);

        const draft = createDraft(oldData);
        const flatItems = [];
        for (let i = 0; i < draft.pages.length; i++) {
          const page = draft.pages[i];
          await updater(page);
          flatItems.push(...page);
        }

        if (flatItems.length !== originalFlatItems.length) {
          throw new Error(
            "Use this method for update only. If you want to add or delete, call the addItem/deleteItem method.",
          );
        }
        const newData = finishDraft(draft);

        // console.log("BEFORE: ", appContext.queryClient?.getQueryData(queryId!));

        appContext.queryClient?.setQueryData(queryId!, newData);

        // console.log("AFTER: ", appContext.queryClient?.getQueryData(queryId!));
      },
      addItem: (element: any, indexToInsert?: number) => {
        const oldData = appContext.queryClient?.getQueryData(queryId!) as InfiniteData<any[]>;
        const draft = createDraft(oldData);

        if (indexToInsert === undefined) {
          draft.pages[draft.pages.length - 1].push(element);
        } else {
          throw new Error("not implemented");
          // TODO is should be something like this
          // //find the pageIndex and itemIndex in that page
          // let pageIndex = -1;
          // let itemIndex = -1;
          // let i = 0;
          // oldData.pages.forEach((page, index)=>{
          //   i += page.result.length;
          //   if(i >= indexToInsert){
          //     pageIndex = index;
          //     itemIndex = i - indexToInsert;
          //     return;
          //   }
          // });
          // draft.pages[pageIndex].result.splice(itemIndex, 0, element);
        }

        const newData = finishDraft(draft);
        appContext.queryClient?.setQueryData(queryId!, newData);
      },
      getItems: () => {
        return data;
      },
      deleteItem: (element: any) => {
        throw new Error("not implemented");
      },
    });
  }, [
    appContext.queryClient,
    fetchPrevPage,
    data,
    loader.uid,
    queryId,
    queryKey,
    refetch,
    registerComponentApi,
    stableFetchNextPage,
  ]);

  return null;
}

```

--------------------------------------------------------------------------------
/xmlui/src/components/Text/Text.module.scss:
--------------------------------------------------------------------------------

```scss
@use "../../components-core/theming/themes" as t;

$themeVars: ();
@function createThemeVar($componentVariable) {
  $themeVars: t.appendThemeVar($themeVars, $componentVariable) !global;
  @return t.getThemeVar($themeVars, $componentVariable);
}

$component: "Text";
$themeVars: t.composeTextVars($themeVars, $component);

@mixin textVariant($variant) {
  $variantName: if($variant == "", "#{$component}", "#{$component}-#{$variant}");
  $themeVars: t.composePaddingVars($themeVars, $variantName);
  $themeVars: t.composeBorderVars($themeVars, $variantName);
  $themeVars: t.composeTextVars($themeVars, $variantName, $component);
  @include t.paddingVars($themeVars, $variantName);
  @include t.borderVars($themeVars, $variantName);
  @include t.textVars($themeVars, $variantName);
  margin-top: createThemeVar("marginTop-#{$variantName}");
  margin-bottom: createThemeVar("marginBottom-#{$variantName}");
  margin-left: createThemeVar("marginLeft-#{$variantName}");
  margin-right: createThemeVar("marginRight-#{$variantName}");
  vertical-align: createThemeVar("verticalAlignment-#{$variantName}");

  &:hover {
    color: createThemeVar("textColor-#{$variantName}--hover");
  }
}

@layer components {
  .text {
    display: inline;
    overflow: hidden;
    text-overflow: ellipsis;
    margin: 0;
    padding: 0;
    min-height: fit-content;

    &.default {
      @include textVariant("");
    }

    &.inherit {
      @include t.ignoreTextVars();
    }

    &.abbr {
      font-weight: createThemeVar("fontWeight-#{$component}-abbr");
      text-transform: createThemeVar("textTransform-#{$component}-abbr");
    }

    &.cite {
      font-style: createThemeVar("fontStyle-#{$component}-cite");
    }

    &.em {
      font-style: createThemeVar("fontStyle-#{$component}-em");
    }

    &.deleted {
      text-decoration-line: createThemeVar("textDecorationLine-#{$component}-deleted");
      text-decoration-color: createThemeVar("textDecorationColor-#{$component}-deleted");
      text-decoration-style: createThemeVar("textDecorationStyle-#{$component}-deleted");
      text-decoration-thickness: createThemeVar("textDecorationThickness-#{$component}-deleted");

      // Based on accessibility concerns
      // Source: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/del
      &::before,
      &::after {
        clip-path: inset(100%);
        clip: rect(1px, 1px, 1px, 1px);
        height: 1px;
        overflow: hidden;
        position: absolute;
        white-space: nowrap;
        width: 1px;
      }
      &::before {
        content: " [deletion start] ";
      }
      &::after {
        content: " [deletion end] ";
      }
    }

    &.inserted {
      text-decoration-line: createThemeVar("textDecorationLine-#{$component}-inserted") !important;
      text-decoration-color: createThemeVar("textDecorationColor-#{$component}-inserted") !important;
      text-decoration-style: createThemeVar("textDecorationStyle-#{$component}-inserted") !important;
      text-decoration-thickness: createThemeVar("textDecorationThickness-#{$component}-inserted") !important;

      // Based on accessibility concerns
      // Source: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ins
      &::before,
      &::after {
        clip-path: inset(100%);
        clip: rect(1px, 1px, 1px, 1px);
        height: 1px;
        overflow: hidden;
        position: absolute;
        white-space: nowrap;
        width: 1px;
      }
      &::before {
        content: " [insertion start] ";
      }
      &::after {
        content: " [insertion end] ";
      }
    }

    // This is just a style placeholder
    &.keyboard {
      background-color: createThemeVar("backgroundColor-#{$component}-keyboard");
      font-family: createThemeVar("fontFamily-#{$component}-keyboard");
      font-weight: createThemeVar("fontWeight-#{$component}-keyboard");
      font-size: createThemeVar("fontSize-#{$component}-keyboard");
      border-width: createThemeVar("borderWidth-#{$component}-keyboard");
      border-color: createThemeVar("borderColor-#{$component}-keyboard");
      border-style: createThemeVar("borderStyle-#{$component}-keyboard");
      border-radius: createThemeVar("borderRadius-#{$component}-keyboard");
      padding-left: createThemeVar("paddingHorizontal-#{$component}-keyboard");
      padding-right: createThemeVar("paddingHorizontal-#{$component}-keyboard");
    }

    &.marked {
      background-color: createThemeVar("backgroundColor-#{$component}-marked");
      color: createThemeVar("textColor-#{$component}-marked");
      font-weight: createThemeVar("fontWeight-#{$component}-marked");
      font-style: createThemeVar("fontStyle-#{$component}-marked");
      line-height: createThemeVar("lineHeight-#{$component}-marked");

      // Based on accessibility concerns
      // Source: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark
      &::before,
      &::after {
        clip-path: inset(100%);
        clip: rect(1px, 1px, 1px, 1px);
        height: 1px;
        overflow: hidden;
        position: absolute;
        white-space: nowrap;
        width: 1px;
      }
      &::before {
        content: " [highlight start] ";
      }
      &::after {
        content: " [highlight end] ";
      }
    }

    &.mono {
      font-family: createThemeVar("fontFamily-#{$component}-mono");
    }

    &.sample {
      font-family: createThemeVar("fontFamily-#{$component}-sample");
      font-size: createThemeVar("fontSize-#{$component}-sample");
    }

    &.sup {
      font-size: createThemeVar("fontSize-#{$component}-sup");
      vertical-align: createThemeVar("verticalAlignment-#{$component}-sup");
    }

    &.sub {
      font-size: createThemeVar("fontSize-#{$component}-sub");
      vertical-align: createThemeVar("verticalAlignment-#{$component}-sub");
    }

    &.var {
      font-style: createThemeVar("fontStyle-#{$component}-var");
    }

    &.title {
      font-size: createThemeVar("fontSize-#{$component}-title");
    }

    &.subtitle {
      font-size: createThemeVar("fontSize-#{$component}-subtitle");
    }

    &.small {
      @include textVariant("small");
    }

    &.code {
      @include textVariant("code");
    }

    &.caption {
      letter-spacing: createThemeVar("letterSpacing-#{$component}-caption");
    }

    &.placeholder {
      color: createThemeVar("textColor-#{$component}-placeholder");
      font-style: createThemeVar("fontStyle-#{$component}-placeholder");
      font-weight: createThemeVar("fontWeight-#{$component}-placeholder");
      font-size: createThemeVar("fontSize-#{$component}-placeholder");
    }

    &.paragraph {
      font-size: createThemeVar("fontSize-#{$component}-paragraph");
      padding-top: createThemeVar("paddingVertical-#{$component}-paragraph");
      padding-bottom: createThemeVar("paddingVertical-#{$component}-paragraph");
    }

    &.subheading {
      font-size: createThemeVar("fontSize-#{$component}-subheading");
      font-weight: createThemeVar("fontWeight-#{$component}-subheading");
      font-style: createThemeVar("fontStyle-#{$component}-subheading");
      letter-spacing: createThemeVar("letterSpacing-#{$component}-subheading");
      text-transform: createThemeVar("textTransform-#{$component}-subheading");
      color: createThemeVar("textColor-#{$component}-subheading");
    }

    &.tableheading {
      margin-top: createThemeVar("marginTop-#{$component}-tableheading");
      margin-bottom: createThemeVar("marginBottom-#{$component}-tableheading");
      padding-left: createThemeVar("paddingHorizontal-#{$component}-tableheading");
      padding-right: createThemeVar("paddingHorizontal-#{$component}-tableheading");
      font-size: createThemeVar("fontSize-#{$component}-tableheading");
      font-weight: createThemeVar("fontWeight-#{$component}-tableheading");
    }

    &.secondary {
      font-size: createThemeVar("fontSize-#{$component}-secondary");
      color: createThemeVar("textColor-#{$component}-secondary");
    }

    &.strong{
      font-weight: t.$fontWeight-bold;
    }
  }

  /*
  This is a Chromium based solution that is supported by most modern browsers.
  See this source for details: https://css-tricks.com/line-clampin/
  */
  .truncateOverflow {
    overflow: hidden;
    overflow-wrap: break-word;
    white-space: nowrap;
    max-width: 100%;
  }

  .preserveLinebreaks {
    white-space: pre-wrap;
    display: inline-block;
  }

  .noEllipsis {
    text-overflow: clip;
  }

  // --- Overflow behavior classes
  .overflowNone {
    // Force single line as per metadata: "No wrapping, text stays on a single line"
    white-space: nowrap;
    // Hide overflow content
    overflow: hidden;
    // Use clip instead of ellipsis
    text-overflow: clip;
    // Constrain width
    max-width: 100%;
  }

  .overflowScroll {
    white-space: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    text-overflow: unset;
    max-width: 100%;
    
    // Ensure scrollbar is visible when needed
    &::-webkit-scrollbar {
      height: 6px;
    }
    
    &::-webkit-scrollbar-track {
      background: transparent;
    }
    
    &::-webkit-scrollbar-thumb {
      background-color: rgba(0, 0, 0, 0.3);
      border-radius: 3px;
    }
  }

  .overflowFlow {
    // Allow text to wrap to multiple lines
    white-space: normal;
    // Hide horizontal overflow, show vertical scrollbar when needed
    overflow-x: hidden;
    overflow-y: auto;
    // Disable text-overflow ellipsis since we want wrapping
    text-overflow: unset;
    // Constrain width but allow height to grow
    max-width: 100%;
    // Change display to block to respect width/height constraints
    display: block;
    // Ensure height constraint is respected in flex contexts
    flex-shrink: 0;
    flex-grow: 0;
    // Use min-height instead of height to avoid conflicts
    min-height: 0;
    
    // Style vertical scrollbar
    &::-webkit-scrollbar {
      width: 6px;
    }
    
    &::-webkit-scrollbar-track {
      background: transparent;
    }
    
    &::-webkit-scrollbar-thumb {
      background-color: rgba(0, 0, 0, 0.3);
      border-radius: 3px;
    }
  }
}

// --- Break mode classes
.breakNormal {
  word-break: normal;
  overflow-wrap: normal;
}

.breakWord {
  overflow-wrap: break-word;
}

.breakAnywhere {
  word-break: break-all;
  overflow-wrap: anywhere;
}

.breakKeep {
  word-break: keep-all;
}

.breakHyphenate {
  hyphens: auto;
  overflow-wrap: break-word;
}

:export {
  themeVars: t.json-stringify($themeVars);
}

```

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

```markdown
# 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.

**Key features:**
- **External content embedding**: Load web pages, documents, or media from external URLs
- **Security controls**: Built-in sandbox and permission policies for safe content isolation
- **HTML content support**: Display inline HTML content without external sources
- **Event handling**: Track loading states with load events

## Properties [#properties]

### `allow` [#allow]

Specifies the permissions policy for the iframe. Controls which features (like camera, microphone, geolocation) the embedded content can use.

The `allow` property controls which browser features the embedded content can access. Common values include camera, microphone, geolocation, and fullscreen permissions.

```xmlui-pg copy display name="Example: allow"
<App>
  <IFrame
      src="https://www.youtube.com/embed/dQw4w9WgXcQ"
      allow="camera; microphone; geolocation"
      width="560px"
      height="315px"
      title="Rick Astley - Never Gonna Give You Up (Official Video)"
    />
</App>
```

### `name` [#name]

Specifies a name for the iframe, which can be used as a target for links and forms.

```xmlui-pg copy display name="Example: name" /name="myFrame"/
<App>
  <VStack gap="$space-2">
    <Button 
      label="Open 'Kraftwerk: The Model' in IFrame" 
      onClick="window.open('https://www.youtube.com/embed/-s4zRw16tMA', 'myFrame')" 
    />
    <IFrame 
      src="https://example.com"
      name="myFrame"
      width="100%" 
      height="300px" />
  </VStack>
</App>
```

### `referrerPolicy` [#referrerpolicy]

Controls how much referrer information is sent when fetching the iframe content.

Available values:

| Value | Description |
| --- | --- |
| `no-referrer` | Never send referrer information |
| `no-referrer-when-downgrade` | Send referrer only for same-security destinations |
| `origin` | Send only the origin as referrer |
| `origin-when-cross-origin` | Send full URL for same-origin, origin only for cross-origin |
| `same-origin` | Send referrer only for same-origin requests |
| `strict-origin` | Send origin only for same-security destinations |
| `strict-origin-when-cross-origin` | Full URL for same-origin, origin for cross-origin same-security |
| `unsafe-url` | Always send full URL as referrer |

### `sandbox` [#sandbox]

Applies extra restrictions to the content in the iframe. Value is a space-separated list of sandbox flags (e.g., 'allow-scripts allow-same-origin').

### `src` [#src]

Specifies the URL of the document to embed in the iframe. Either `src` or `srcdoc` should be specified, but not both.

```xmlui-pg copy display name="Example: src"
<App>
  <IFrame 
    src="https://example.com" 
    width="100%" 
    height="300px" />
</App>
```

### `srcdoc` [#srcdoc]

Specifies the HTML content to display in the iframe. Either `src` or `srcdoc` should be specified, but not both.

```xmlui-pg copy display name="Example: srcdoc"
<App>
  <IFrame 
    srcdoc="
      <h1>Hello World</h1>
      <p>This is embedded HTML content with <strong>formatting</strong>.</p>
    "
    width="100%" 
    height="200px" />
</App>
```

## Events [#events]

### `load` [#load]

This event is triggered when the IFrame content has finished loading.

```xmlui-pg copy display name="Example: load"
<App var.loadStatus="Loading...">
  <VStack gap="$space-2">
    <Text value="Status: {loadStatus}" />
    <IFrame 
      src="https://example.com"
      onLoad="loadStatus = 'Content loaded successfully!'"
      width="100%" 
      height="200px" />
  </VStack>
</App>
```

## Exposed Methods [#exposed-methods]

### `getContentDocument` [#getcontentdocument]

This method returns the content document of the iframe element.

**Signature**: `getContentDocument(): Document | null`

Get access to the iframe's content document object. Returns null if the content document is not accessible.

```xmlui-pg copy display name="Example: getContentDocument" /getContentDocument/
<App>
  <VStack var.iFrameTitle="<not queried yet>" >
    <Button 
      label="Get Document Title" 
      onClick="
        const contentDoc = myIframe.getContentDocument();
        iFrameTitle = contentDoc 
          ? contentDoc.title 
          : 'Content document not accessible';
      " />
    <Card title="IFrame title: {iFrameTitle}" />
    <IFrame 
      id="myIframe"
      srcdoc="
        <html>
          <head><title>My Awesome Document</title></head>
          <body><h1>Awesome Content</h1></body>
        </html>"
      width="100%" 
      height="200px" />
  </VStack>
</App>
```

### `getContentWindow` [#getcontentwindow]

This method returns the content window of the iframe element.

**Signature**: `getContentWindow(): Window | null`

Get access to the iframe's content window object. Returns null if the content window is not accessible.

```xmlui-pg copy display name="Example: getContentWindow" /getContentWindow/
<App>
  <VStack var.windowStatus="Not checked yet" gap="$space-2">
    <Button 
      label="Check Content Window" 
      onClick="
        const contentWindow = myIframe.getContentWindow();
        windowStatus = contentWindow 
          ? 'Content window is accessible' 
          : 'Content window is not accessible';
      " />
    <Card title="Status: {windowStatus}" />
    <IFrame 
      id="myIframe"
      src="https://example.com"
      width="100%" 
      height="200px" />
  </VStack>
</App>
```

### `postMessage` [#postmessage]

This method sends a message to the content window of the iframe.

**Signature**: `postMessage(message: any, targetOrigin?: string): void`

- `message`: The message to send to the iframe's content window.
- `targetOrigin`: The origin to which the message should be sent. Defaults to '*'.

```xmlui-pg copy display name="Example: postMessage" /postMessage/
<App>
  <VStack var.messageStatus="Ready to send" gap="$space-2">
    <Button 
      label="Send Message to IFrame" 
      onClick="
        myIframe.postMessage({type: 'greeting', text: 'Hello from parent!'}, '*');
        messageStatus = 'Message sent!';
      " />
    <Card title="Status: {messageStatus}" />
    <IFrame 
      id="myIframe"
      srcdoc="
        <script>
          window.addEventListener('message', (event) => \{
            console.log('Received message:', event.data);
            document.body.innerHTML = 
              '<h1>Message: ' + JSON.stringify(event.data) + '</h1>';
          });
        </script>
        <h1>Waiting for message...</h1>
      "
      width="100%" 
      height="200px" />
  </VStack>
</App>
```

## Styling [#styling]

### Size Control [#size-control]

IFrame supports these theme variables for consistent sizing:
- `width-IFrame`
- `height-IFrame`
- `borderRadius-IFrame`
- `border-IFrame`

```xmlui-pg display copy name="Example: IFrame with custom styling"
<App>
  <Theme 
    width-IFrame="400px" 
    height-IFrame="250px"
    borderRadius-IFrame="8px"
    border-IFrame="2px solid $primaryColor">
    <IFrame src="https://example.com" />
  </Theme>
</App>
```

### Theme Variables [#theme-variables]

| Variable | Default Value (Light) | Default Value (Dark) |
| --- | --- | --- |
| [border](../styles-and-themes/common-units/#border)-IFrame | 1px solid $borderColor | 1px solid $borderColor |
| [borderBottom](../styles-and-themes/common-units/#border)-IFrame | *none* | *none* |
| [borderBottomColor](../styles-and-themes/common-units/#color)-IFrame | *none* | *none* |
| [borderBottomStyle](../styles-and-themes/common-units/#border-style)-IFrame | *none* | *none* |
| [borderBottomWidth](../styles-and-themes/common-units/#size)-IFrame | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-IFrame | *none* | *none* |
| [borderEndEndRadius](../styles-and-themes/common-units/#border-rounding)-IFrame | *none* | *none* |
| [borderEndStartRadius](../styles-and-themes/common-units/#border-rounding)-IFrame | *none* | *none* |
| [borderHorizontal](../styles-and-themes/common-units/#border)-IFrame | *none* | *none* |
| [borderHorizontalColor](../styles-and-themes/common-units/#color)-IFrame | *none* | *none* |
| [borderHorizontalStyle](../styles-and-themes/common-units/#border-style)-IFrame | *none* | *none* |
| [borderHorizontalWidth](../styles-and-themes/common-units/#size)-IFrame | *none* | *none* |
| [borderLeft](../styles-and-themes/common-units/#border)-IFrame | *none* | *none* |
| [color](../styles-and-themes/common-units/#color)-IFrame | *none* | *none* |
| [borderLeftStyle](../styles-and-themes/common-units/#border-style)-IFrame | *none* | *none* |
| [borderLeftWidth](../styles-and-themes/common-units/#size)-IFrame | *none* | *none* |
| [borderRadius](../styles-and-themes/common-units/#border-rounding)-IFrame | $borderRadius | $borderRadius |
| [borderRight](../styles-and-themes/common-units/#border)-IFrame | *none* | *none* |
| [color](../styles-and-themes/common-units/#color)-IFrame | *none* | *none* |
| [borderRightStyle](../styles-and-themes/common-units/#border-style)-IFrame | *none* | *none* |
| [borderRightWidth](../styles-and-themes/common-units/#size)-IFrame | *none* | *none* |
| [borderStartEndRadius](../styles-and-themes/common-units/#border-rounding)-IFrame | *none* | *none* |
| [borderStartStartRadius](../styles-and-themes/common-units/#border-rounding)-IFrame | *none* | *none* |
| [borderStyle](../styles-and-themes/common-units/#border-style)-IFrame | *none* | *none* |
| [borderTop](../styles-and-themes/common-units/#border)-IFrame | *none* | *none* |
| [borderTopColor](../styles-and-themes/common-units/#color)-IFrame | *none* | *none* |
| [borderTopStyle](../styles-and-themes/common-units/#border-style)-IFrame | *none* | *none* |
| [borderTopWidth](../styles-and-themes/common-units/#size)-IFrame | *none* | *none* |
| [borderHorizontal](../styles-and-themes/common-units/#border)-IFrame | *none* | *none* |
| [borderVerticalColor](../styles-and-themes/common-units/#color)-IFrame | *none* | *none* |
| [borderVerticalStyle](../styles-and-themes/common-units/#border-style)-IFrame | *none* | *none* |
| [borderVerticalWidth](../styles-and-themes/common-units/#size)-IFrame | *none* | *none* |
| [borderWidth](../styles-and-themes/common-units/#size)-IFrame | *none* | *none* |
| [height](../styles-and-themes/common-units/#size)-IFrame | 300px | 300px |
| [width](../styles-and-themes/common-units/#size)-IFrame | 100% | 100% |

```

--------------------------------------------------------------------------------
/xmlui/src/components/Slider/SliderNative.tsx:
--------------------------------------------------------------------------------

```typescript
import type { CSSProperties, ForwardedRef } from "react";
import React, { useCallback, useEffect, useId, useRef } from "react";
import { forwardRef } from "react";
import { Root, Range, Track, Thumb } from "@radix-ui/react-slider";
import styles from "./Slider.module.scss";
import type { RegisterComponentApiFn, UpdateStateFn } from "../../abstractions/RendererDefs";
import { noop } from "../../components-core/constants";
import { useEvent } from "../../components-core/utils/misc";
import type { ValidationStatus } from "../abstractions";
import classnames from "classnames";
import { Tooltip } from "../Tooltip/TooltipNative";
import { isNaN } from "lodash-es";
import { composeRefs } from "@radix-ui/react-compose-refs";

export type Props = {
  id?: string;
  value?: number | number[];
  initialValue?: number | number[];
  style?: CSSProperties;
  className?: string;
  step?: number;
  max?: number;
  min?: number;
  inverted?: false;
  validationStatus?: ValidationStatus;
  minStepsBetweenThumbs?: number;
  onDidChange?: (newValue: number | number[]) => void;
  onFocus?: (ev: React.FocusEvent<HTMLDivElement>) => void;
  onBlur?: (ev: React.FocusEvent<HTMLDivElement>) => void;
  updateState?: UpdateStateFn;
  registerComponentApi?: RegisterComponentApiFn;
  autoFocus?: boolean;
  readOnly?: boolean;
  tabIndex?: number;
  required?: boolean;
  enabled?: boolean;
  rangeStyle?: CSSProperties;
  thumbStyle?: CSSProperties;
  showValues?: boolean;
  valueFormat?: (value: number) => string;
};

export const defaultProps: Pick<
  Props,
  | "step"
  | "min"
  | "max"
  | "enabled"
  | "validationStatus"
  | "tabIndex"
  | "showValues"
  | "valueFormat"
  | "minStepsBetweenThumbs"
> = {
  step: 1,
  min: 0,
  max: 10,
  enabled: true,
  validationStatus: "none" as ValidationStatus,
  tabIndex: -1,
  showValues: true,
  valueFormat: (value: number) => value.toString(),
  minStepsBetweenThumbs: 1,
};

const parseValue = (val: string | number | undefined, defaultVal: number): number => {
  if (typeof val === "number") {
    return val;
  } else if (typeof val === "string") {
    const parsed = parseFloat(val);
    if (!isNaN(parsed)) {
      return parsed;
    }
  }
  return defaultVal;
};

// Helper function to ensure value is properly formatted
const formatValue = (
  val: number | number[] | undefined,
  defaultVal: number = 0,
  minVal?: number,
  maxVal?: number,
): number[] => {
  const clampValue = (value: number): number => {
    if (minVal !== undefined && value < minVal) return minVal;
    if (maxVal !== undefined && value > maxVal) return maxVal;
    return value;
  };

  if (val === undefined) {
    return [clampValue(defaultVal)];
  }
  if (typeof val === "number") {
    return [clampValue(val)];
  }
  if (Array.isArray(val) && val.length > 0) {
    return val.map(clampValue);
  }
  return [clampValue(defaultVal)];
};

export const Slider = forwardRef(
  (
    {
      id,
      style,
      className,
      step = defaultProps.step,
      min = defaultProps.min,
      max = defaultProps.max,
      inverted,
      updateState,
      onDidChange = noop,
      onFocus = noop,
      onBlur = noop,
      registerComponentApi,
      enabled = defaultProps.enabled,
      value,
      autoFocus,
      readOnly,
      tabIndex = defaultProps.tabIndex,
      required,
      validationStatus = defaultProps.validationStatus,
      initialValue,
      minStepsBetweenThumbs = defaultProps.minStepsBetweenThumbs,
      rangeStyle,
      thumbStyle,
      showValues = defaultProps.showValues,
      valueFormat = defaultProps.valueFormat,
      ...rest
    }: Props,
    forwardedRef: ForwardedRef<HTMLInputElement>,
  ) => {
    const inputRef = useRef(null);
    const ref = forwardedRef ? composeRefs(inputRef, forwardedRef) : inputRef;
    const tooltipRef = useRef<HTMLDivElement>(null);
    const thumbsRef = useRef<(HTMLSpanElement | null)[]>([]);
    min = parseValue(min, defaultProps.min);
    max = parseValue(max, defaultProps.max);

    // Initialize localValue properly
    const [localValue, setLocalValue] = React.useState<number[]>(() =>
      formatValue(value || initialValue, min, min, max),
    );
    const [showTooltip, setShowTooltip] = React.useState(false);
    const onShowTooltip = useCallback(() => setShowTooltip(true), []);
    const onHideTooltip = useCallback(() => setShowTooltip(false), []);

    // Process initialValue on mount
    useEffect(() => {
      let initialVal: number | number[] = min;

      if (typeof initialValue === "string") {
        try {
          // Try to parse as JSON first (for arrays)
          const parsed = JSON.parse(initialValue);
          initialVal = parsed;
        } catch (e) {
          // If not JSON, try to parse as number
          const num = parseFloat(initialValue);
          if (!isNaN(num)) {
            initialVal = num;
          }
        }
      } else if (typeof initialValue === "number") {
        initialVal = initialValue;
      } else if (initialValue !== undefined) {
        initialVal = initialValue;
      }

      // Format the value properly - single call to formatValue with bounds checking
      const formattedValue = formatValue(initialVal, min, min, max);
      setLocalValue(formattedValue);

      // Notify parent component
      if (updateState) {
        updateState(
          {
            value: formattedValue.length === 1 ? formattedValue[0] : formattedValue,
          },
          { initial: true },
        );
      }
    }, [initialValue, min, max, updateState]);

    // Sync with external value changes
    useEffect(() => {
      if (value !== undefined) {
        const formattedValue = formatValue(value, min, min, max);
        setLocalValue(formattedValue);
      }
    }, [value, min, max]);

    const updateValue = useCallback(
      (value: number | number[]) => {
        if (updateState) {
          updateState({ value });
        }
        // Call onDidChange without extra arguments to maintain type compatibility
        onDidChange(value);
      },
      [onDidChange, updateState],
    );

    const onInputChange = useCallback(
      (value: number[]) => {
        if (readOnly) {
          return;
        }
        setLocalValue(value);

        // 👇 Force the DOM element to reflect the latest value synchronously
        if (inputRef.current) {
          inputRef.current.value = value;
        }

        if (value.length > 1) {
          updateValue(value); // calls updateState + onDidChange
        } else if (value.length === 1) {
          updateValue(value[0]);
        }
      },
      [updateValue, readOnly],
    );

    // Component APIs
    const handleOnFocus = useCallback(
      (ev: React.FocusEvent<HTMLInputElement>) => {
        onShowTooltip();
        onFocus?.(ev);
      },
      [onFocus, onShowTooltip],
    );
    const handleOnBlur = useCallback(
      (ev: React.FocusEvent<HTMLInputElement>) => {
        onBlur?.(ev);
      },
      [onBlur],
    );

    const focus = useCallback(() => {
      // Focus the first available thumb
      const firstThumb = thumbsRef.current.find(thumb => thumb !== null);
      if (firstThumb) {
        firstThumb.focus();
      } else {
        inputRef.current?.focus();
      }
    }, []);

    const setValue = useEvent((newValue) => {
      if (readOnly || !enabled) {
        return;
      }
      const formattedValue = formatValue(newValue, min, min, max);
      const valueToUpdate = formattedValue.length === 1 ? formattedValue[0] : formattedValue;
      updateValue(valueToUpdate);
    });

    useEffect(() => {
      registerComponentApi?.({
        focus,
        setValue,
      });
    }, [focus, registerComponentApi, setValue]);

    // Ensure we always have at least one thumb
    const displayValue = localValue.length > 0 ? localValue : formatValue(undefined, min, min, max);

    // Clean up thumbs ref array when number of thumbs changes
    useEffect(() => {
      thumbsRef.current = thumbsRef.current.slice(0, displayValue.length);
    }, [displayValue.length]);

      return (
          <div {...rest} ref={ref} style={style} className={classnames(styles.sliderContainer, className)} data-slider-container>
            <Root
              ref={inputRef}
              minStepsBetweenThumbs={minStepsBetweenThumbs}
              tabIndex={tabIndex}
              aria-readonly={readOnly}
              className={classnames(styles.sliderRoot, {
                [styles.disabled]: !enabled,
                [styles.readOnly]: readOnly,
              })}
              max={max}
              min={min}
              inverted={inverted}
              step={step}
              disabled={!enabled}
              onFocus={handleOnFocus}
              onBlur={handleOnBlur}
              onValueChange={onInputChange}
              onMouseOver={onShowTooltip}
              onMouseLeave={onHideTooltip}
              onPointerDown={onShowTooltip}
              value={displayValue}
            >
            <Track
              data-track
              className={classnames(styles.sliderTrack, {
                [styles.disabled]: !enabled,
                [styles.readOnly]: readOnly,
                [styles.error]: validationStatus === "error",
                [styles.warning]: validationStatus === "warning",
                [styles.valid]: validationStatus === "valid",
              })}
              style={rangeStyle ? { ...rangeStyle } : undefined}
            >
              <Range
                data-range
                className={classnames(styles.sliderRange, {
                  [styles.disabled]: !enabled,
                })}
              />
            </Track>
            {displayValue.map((_, index) => (
              <Tooltip
                key={index}
                ref={tooltipRef}
                text={valueFormat(displayValue[index])}
                delayDuration={100}
                open={showValues && showTooltip}
              >
                <Thumb
                  id={id}
                  aria-required={required}
                  ref={(el) => {
                    thumbsRef.current[index] = el;
                  }}
                  className={classnames(styles.sliderThumb, {
                    [styles.disabled]: !enabled,
                  })}
                  style={thumbStyle ? { ...thumbStyle } : undefined}
                  data-thumb-index={index}
                  autoFocus={autoFocus && index === 0}
                />
              </Tooltip>
            ))}
          </Root>
        </div>
    );
  },
);

Slider.displayName = "Slider";

```

--------------------------------------------------------------------------------
/xmlui/src/components-core/utils/treeUtils.ts:
--------------------------------------------------------------------------------

```typescript
import type {
  FlatTreeNode,
  TreeItem,
  TreeNode,
  UnPackedTreeData,
  TreeFieldConfig,
  NodeLoadingState,
  FlatTreeNodeWithState,
} from "../abstractions/treeAbstractions";

export function flattenNode(
  node: TreeNode,
  depth: number,
  result: FlatTreeNode[],
  openedIds: (string | number)[],
  dynamicField?: string,
  nodeStates?: Map<string | number, NodeLoadingState>,
) {
  const { children, key } = node;
  const isExpanded = openedIds.includes(key);
  // Check if node has actual children OR is a dynamic node that can load children
  const hasActualChildren = !!children && children.length > 0;
  const isDynamic = dynamicField && node[dynamicField];
  const hasChildren = hasActualChildren || isDynamic;
  
  // Get loading state for this node
  const loadingState = nodeStates?.get(key) || (isDynamic ? 'unloaded' : 'loaded');
  
  const flatNode: FlatTreeNodeWithState = {
    ...node,
    hasChildren,
    depth,
    isExpanded,
    loadingState,
    // Ensure key is preserved (in case it was overwritten by ...node spread)
    key: key || node.key || node.id,
  };
  
  result.push(flatNode);

  if (isExpanded && children) {
    for (let child of children) {
      flattenNode(child, depth + 1, result, openedIds, dynamicField, nodeStates);
    }
  }
}

export function toFlatTree(
  treeData: TreeNode[], 
  openedIds: (string | number)[], 
  dynamicField?: string,
  nodeStates?: Map<string | number, NodeLoadingState>
): FlatTreeNodeWithState[] {
  const ret: FlatTreeNodeWithState[] = [];
  treeData.forEach((node) => {
    flattenNode(node, 0, ret, openedIds, dynamicField, nodeStates);
  });

  return ret;
}

export function walkTree(treeData: TreeNode[], visit: (node: TreeNode) => void) {
  treeData.forEach((node) => {
    visit(node);
    walkTree(node.children || [], visit);
  });
}

export function unPackTree(
  items: Array<TreeItem> = [],
  parentIds: Array<string> = [],
  parentPath: Array<number> = [],
): UnPackedTreeData {
  const treeData: Array<TreeNode> = [];
  let treeItemsById: Record<string, TreeNode> = {};

  items.forEach((item, index) => {
    const path = [...parentPath, index];
    const id = item.id || item.cid;
    const childTree = unPackTree(item.children, [...parentIds, id], path);
    const treeItem: TreeNode = {
      ...item,
      id: id,
      key: id,
      parentIds,
      path,
      children: childTree.treeData,
      selectable: item.selectable,
    };
    treeData.push(treeItem);
    treeItemsById[id] = treeItem;
    treeItemsById = {
      ...treeItemsById,
      ...childTree.treeItemsById,
    };
  });

  return {
    treeData,
    treeItemsById,
  };
}

/**
 * Transforms flat array data with parent-child relationships into UnPackedTreeData format
 * @param flatData Array of flat objects with id and parentId relationships
 * @param fieldConfig Configuration for mapping object fields to tree properties
 * @returns UnPackedTreeData structure suitable for Tree component
 */
export function flatToNative(
  flatData: any[],
  fieldConfig: TreeFieldConfig
): UnPackedTreeData {
  if (!flatData || flatData.length === 0) {
    return { treeData: [], treeItemsById: {} };
  }

  // Build parent-to-children map for efficient lookup
  const childrenMap = new Map<string, any[]>();
  const itemsById = new Map<string, any>();
  const rootItems: any[] = [];

  // First pass: organize items and build relationships
  flatData.forEach(item => {
    const id = item[fieldConfig.idField];
    const parentId = item[fieldConfig.parentField || 'parentId'];
    
    // Store item for lookup
    itemsById.set(id, item);
    
    if (parentId && parentId !== '') {
      // Convert parentId to string for consistent type in childrenMap
      const parentKey = String(parentId);
      // Has parent - add to children map
      if (!childrenMap.has(parentKey)) {
        childrenMap.set(parentKey, []);
      }
      childrenMap.get(parentKey)!.push(item);
    } else {
      // Root item
      rootItems.push(item);
    }
  });

  // Generate unique IDs for internal tree structure
  let idCounter = 1;
  const sourceIdToId = new Map<string, string>();
  
  const getOrCreateId = (sourceId: string): string => {
    if (!sourceIdToId.has(sourceId)) {
      sourceIdToId.set(sourceId, `flat_${idCounter++}`);
    }
    return sourceIdToId.get(sourceId)!;
  };

  // Recursive function to build TreeNode structure
  const buildTreeNode = (
    item: any, 
    parentIds: string[] = [], 
    pathSegments: string[] = []
  ): TreeNode => {
    const sourceId = item[fieldConfig.idField];
    const id = getOrCreateId(sourceId);
    const displayName = item[fieldConfig.labelField] || sourceId;
    const currentPath = [...pathSegments, displayName];
    
    // Get children for this item
    const sourceKey = String(sourceId);
    const childItems = childrenMap.get(sourceKey) || [];
    const children: TreeNode[] = childItems.map(childItem => 
      buildTreeNode(childItem, [...parentIds, sourceId], currentPath)
    );

    // Build the TreeNode
    const treeNode: TreeNode = {
      id,
      key: sourceId, // Use source ID as key for expansion state
      path: currentPath,
      displayName,
      parentIds,
      selectable: fieldConfig.selectableField ? (item[fieldConfig.selectableField] ?? true) : true,
      children,
      // Preserve original item properties
      ...item,
      // Add icon properties if configured
      ...(fieldConfig.iconField && item[fieldConfig.iconField] && {
        icon: item[fieldConfig.iconField]
      }),
      ...(fieldConfig.iconExpandedField && item[fieldConfig.iconExpandedField] && {
        iconExpanded: item[fieldConfig.iconExpandedField]
      }),
      ...(fieldConfig.iconCollapsedField && item[fieldConfig.iconCollapsedField] && {
        iconCollapsed: item[fieldConfig.iconCollapsedField]
      })
    };

    return treeNode;
  };

  // Build tree structure from root items
  const treeData: TreeNode[] = rootItems.map(rootItem => 
    buildTreeNode(rootItem)
  );

  // Build lookup map by ID
  const treeItemsById: Record<string, TreeNode> = {};
  const collectNodes = (nodes: TreeNode[]) => {
    nodes.forEach(node => {
      treeItemsById[node.id] = node;
      if (node.children) {
        collectNodes(node.children);
      }
    });
  };
  collectNodes(treeData);

  return {
    treeData,
    treeItemsById,
  };
}

/**
 * Transforms hierarchical nested object data into UnPackedTreeData format
 * @param hierarchyData Single object or array of objects with nested children structure
 * @param fieldConfig Configuration for mapping object fields to tree properties
 * @returns UnPackedTreeData structure suitable for Tree component
 */
export function hierarchyToNative(
  hierarchyData: any,
  fieldConfig: TreeFieldConfig
): UnPackedTreeData {
  if (!hierarchyData) {
    return { treeData: [], treeItemsById: {} };
  }

  // Ensure we're working with an array
  const rootItems = Array.isArray(hierarchyData) ? hierarchyData : [hierarchyData];
  
  if (rootItems.length === 0) {
    return { treeData: [], treeItemsById: {} };
  }

  // Generate unique IDs for internal tree structure
  let idCounter = 1;
  const sourceIdToId = new Map<string, string>();
  
  const getOrCreateId = (sourceId: string): string => {
    if (!sourceIdToId.has(sourceId)) {
      sourceIdToId.set(sourceId, `hierarchy_${idCounter++}`);
    }
    return sourceIdToId.get(sourceId)!;
  };

  // Set to track visited nodes for circular reference detection
  const visitedIds = new Set<string>();

  // Recursive function to build TreeNode structure from hierarchical data
  const buildTreeNode = (
    item: any, 
    parentIds: string[] = [], 
    pathSegments: string[] = []
  ): TreeNode => {
    const sourceId = item[fieldConfig.idField];
    const displayName = item[fieldConfig.labelField] || sourceId;
    
    // Circular reference detection
    if (visitedIds.has(sourceId)) {
      // Return a simple node without children to break the cycle
      const id = getOrCreateId(sourceId);
      return {
        id,
        key: sourceId,
        path: [...pathSegments, displayName],
        displayName,
        parentIds,
        selectable: fieldConfig.selectableField ? (item[fieldConfig.selectableField] ?? true) : true,
        children: [],
        ...item,
        ...(fieldConfig.iconField && item[fieldConfig.iconField] && {
          icon: item[fieldConfig.iconField]
        })
      };
    }

    // Mark as visited
    visitedIds.add(sourceId);

    const id = getOrCreateId(sourceId);
    const currentPath = [...pathSegments, displayName];
    
    // Get children from the specified children field
    const childrenField = fieldConfig.childrenField || 'children';
    const childItems = item[childrenField] || [];
    
    // Recursively build children
    const children: TreeNode[] = childItems.map((childItem: any) => 
      buildTreeNode(childItem, [...parentIds, sourceId], currentPath)
    );

    // Unmark as visited after processing (for depth-first traversal)
    visitedIds.delete(sourceId);

    // Build the TreeNode
    const treeNode: TreeNode = {
      id,
      path: currentPath,
      displayName,
      parentIds,
      selectable: fieldConfig.selectableField ? (item[fieldConfig.selectableField] ?? true) : true,
      // Preserve original item properties (excluding children to avoid overwriting)
      ...item,
      // Add icon properties if configured
      ...(fieldConfig.iconField && item[fieldConfig.iconField] && {
        icon: item[fieldConfig.iconField]
      }),
      ...(fieldConfig.iconExpandedField && item[fieldConfig.iconExpandedField] && {
        iconExpanded: item[fieldConfig.iconExpandedField]
      }),
      ...(fieldConfig.iconCollapsedField && item[fieldConfig.iconCollapsedField] && {
        iconCollapsed: item[fieldConfig.iconCollapsedField]
      }),
      // Set TreeNode-specific properties AFTER spreading item to ensure they're not overwritten
      children, // Use our transformed children, not the original item's children
      key: sourceId, // Use source ID as key for expansion state
    };

    return treeNode;
  };

  // Build tree structure from root items
  const treeData: TreeNode[] = rootItems.map(rootItem => 
    buildTreeNode(rootItem)
  );

  // Build lookup map by ID
  const treeItemsById: Record<string, TreeNode> = {};
  const collectNodes = (nodes: TreeNode[]) => {
    nodes.forEach(node => {
      treeItemsById[node.id] = node;
      if (node.children) {
        collectNodes(node.children);
      }
    });
  };
  collectNodes(treeData);

  return {
    treeData,
    treeItemsById,
  };
}

```

--------------------------------------------------------------------------------
/xmlui/src/components/Bookmark/Bookmark.spec.ts:
--------------------------------------------------------------------------------

```typescript
import { expect, test } from "../../testing/fixtures";

// =============================================================================
// BASIC FUNCTIONALITY TESTS
// =============================================================================

test.describe("Basic Functionality", () => {
  test("renders as standalone bookmark", async ({ initTestBed, page }) => {
    await initTestBed(`<Bookmark id="test-bookmark" />`);
    const bookmark = page.locator("#test-bookmark");
    await expect(bookmark).toHaveCount(1);
  });

  test("renders children", async ({ initTestBed, page }) => {
    await initTestBed(`
      <Bookmark id="test-bookmark">
        <Text>Bookmark content</Text>
      </Bookmark>
    `);
    const bookmark = page.locator("#test-bookmark");
    await expect(bookmark).toBeVisible();
    await expect(bookmark).toContainText("Bookmark content");
  });

  test("renders children without id", async ({ initTestBed, page }) => {
    await initTestBed(`<Bookmark>Content without id</Bookmark>`);
    await expect(page.getByText("Content without id")).toBeVisible();
  });

  // =============================================================================
  // DOCUMENTATION USAGE PATTERNS
  // =============================================================================

  test.describe("Documentation Usage Patterns", () => {
    test("links navigate to standalone bookmarks", async ({ initTestBed, page }) => {
      // Based on documentation example with standalone bookmarks and adjacent content
      await initTestBed(`
        <VStack height="600px" gap="100px">
          <Link to="#red-section">Jump to red</Link>
          <Link to="#green-section">Jump to green</Link>
          <Bookmark id="red-section" />
          <VStack height="700px" backgroundColor="red">Red content</VStack>
          <Bookmark id="green-section" />
          <VStack height="700px" backgroundColor="green">Green content</VStack>
        </VStack>
      `);

      const redLink = page.getByRole("link", { name: "Jump to red" });
      const greenLink = page.getByRole("link", { name: "Jump to green" });

      const redContent = page.getByText("Red content");
      const greenContent = page.getByText("Green content");

      await expect(redContent).toBeInViewport();
      await expect(greenContent).not.toBeInViewport();

      await greenLink.click();
      await page.waitForURL(/#green-section$/);
      await expect(redContent).not.toBeInViewport();
      await expect(greenContent).toBeInViewport();

      await redLink.click();
      await page.waitForURL(/#red-section$/);
      await expect(redContent).toBeInViewport();
      await expect(greenContent).not.toBeInViewport();
    });

    test("links navigate to nested bookmarks", async ({ initTestBed, page }) => {
      // Based on documentation example with standalone bookmarks and adjacent content
      await initTestBed(`
        <VStack height="600px" gap="100px">
          <Link to="#red-section">Jump to red</Link>
          <Link to="#green-section">Jump to green</Link>
          <Bookmark id="red-section" >
            <VStack height="700px" backgroundColor="red">Red content</VStack>
          </Bookmark>
          <Bookmark id="green-section" >
            <VStack height="700px" backgroundColor="green">Green content</VStack>
          </Bookmark>
        </VStack>
      `);

      const redLink = page.getByRole("link", { name: "Jump to red" });
      const greenLink = page.getByRole("link", { name: "Jump to green" });

      const redContent = page.getByText("Red content");
      const greenContent = page.getByText("Green content");

      await expect(redContent).toBeInViewport();
      await expect(greenContent).not.toBeInViewport();

      await greenLink.click();
      await page.waitForURL(/#green-section$/);
      await expect(redContent).not.toBeInViewport();
      await expect(greenContent).toBeInViewport();

      await redLink.click();
      await page.waitForURL(/#red-section$/);
      await expect(redContent).toBeInViewport();
      await expect(greenContent).not.toBeInViewport();
    });
  });

  // =============================================================================
  // ID PROPERTY TESTS
  // =============================================================================

  test.describe("id property", () => {
    test("handles special characters in id", async ({ initTestBed, page }) => {
      await initTestBed(`<Bookmark id="bookmark-with_special.chars" />`);
      const anchor = page.locator('[id="bookmark-with_special.chars"]');
      await expect(anchor).toHaveCount(1);
    });

    test("handles unicode characters in id", async ({ initTestBed, page }) => {
      await initTestBed(`<Bookmark id="书签-émojis🚀" />`);
      const anchor = page.locator('[id="书签-émojis🚀"]');
      await expect(anchor).toHaveCount(1);
    });

    test("handles null id gracefully", async ({ initTestBed, page }) => {
      await initTestBed(`<Bookmark id="{null}">Content</Bookmark>`);
      await expect(page.getByText("Content")).toBeVisible();
    });

    test("handles undefined id gracefully", async ({ initTestBed, page }) => {
      await initTestBed(`<Bookmark id="{undefined}">Content</Bookmark>`);
      await expect(page.getByText("Content")).toBeVisible();
    });

    test("handles object id gracefully", async ({ initTestBed, page }) => {
      await initTestBed(`<Bookmark id="{{a: 1}}">Content</Bookmark>`);
      const anchor = page.locator('[id="[object Object]"]');
      await expect(anchor).toHaveCount(1);
    });
  });

  // =============================================================================
  // SCROLL INTO VIEW API TESTS
  // =============================================================================

  test.describe("scrollIntoView API", () => {
    test("scrollIntoView works in scrollable container", async ({ initTestBed, page }) => {
      await initTestBed(`
        <VStack height="300px">
          <Button onClick="target.scrollIntoView()" >Scroll to Target</Button>
          <VStack height="700px" backgroundColor="lightblue">Top spacer</VStack>
          <Bookmark id="target" ref="bookmarkRef">Target content</Bookmark>
        </VStack>
      `);

      const bookmark = page.locator("#target");
      await expect(bookmark).not.toBeInViewport();

      const button = page.getByRole("button", { name: "Scroll to Target" });
      await button.click();

      await expect(bookmark).toBeInViewport();
    });
  });
});

// =============================================================================
// ACCESSIBILITY TESTS
// =============================================================================

test.describe("Accessibility", () => {
  test("supports keyboard navigation to content", async ({ initTestBed, page }) => {
    await initTestBed(`
      <Bookmark id="keyboard-test">
        <Button>Focusable Content</Button>
      </Bookmark>
    `);

    await page.keyboard.press("Tab");
    const button = page.getByRole("button", { name: "Focusable Content" });
    await expect(button).toBeFocused();
  });
});

// =============================================================================
// OTHER EDGE CASE TESTS
// =============================================================================

test.describe("Other Edge Cases", () => {
  test("links navigate to bookmarks with 'null' other props", async ({ initTestBed, page }) => {
    await initTestBed(`
      <VStack height="600px">
        <Link to="#green-section">Jump to green</Link>
        <VStack height="700px" backgroundColor="red">Red content</VStack>
        <Bookmark id="green-section" level="{null}" title="{null}" omitFromToc="{null}" />
        <VStack height="700px" backgroundColor="green">Green content</VStack>
      </VStack>
    `);

    const greenContent = page.getByText("Green content");
    await expect(greenContent).not.toBeInViewport();

    const greenLink = page.getByRole("link", { name: "Jump to green" });
    await greenLink.click();

    await page.waitForURL(/#green-section$/);
    await expect(greenContent).toBeInViewport();
  });

  test("links navigate to bookmarks with valid other props", async ({ initTestBed, page }) => {
    await initTestBed(`
      <VStack height="600px">
        <Link to="#green-section">Jump to green</Link>
        <VStack height="700px" backgroundColor="red">Red content</VStack>
        <Bookmark id="green-section" level="{50}" title="green content section" omitFromToc="{true}" />
        <VStack height="700px" backgroundColor="green">Green content</VStack>
      </VStack>
    `);

    const greenContent = page.getByText("Green content");
    await expect(greenContent).not.toBeInViewport();

    const greenLink = page.getByRole("link", { name: "Jump to green" });
    await greenLink.click();

    await page.waitForURL(/#green-section$/);
    await expect(greenContent).toBeInViewport();
  });

  test("links navigate to bookmarks with empty children", async ({ initTestBed, page }) => {
    await initTestBed(`
      <VStack height="600px">
        <Link to="#green-section">Jump to green</Link>
        <VStack height="700px" backgroundColor="red">Red content</VStack>
        <Bookmark id="green-section" level="{50}" title="green content section" omitFromToc="{true}" ></Bookmark>
        <VStack height="700px" backgroundColor="green">Green content</VStack>
      </VStack>
    `);

    const greenContent = page.getByText("Green content");
    await expect(greenContent).not.toBeInViewport();

    const greenLink = page.getByRole("link", { name: "Jump to green" });
    await greenLink.click();

    await page.waitForURL(/#green-section$/);
    await expect(greenContent).toBeInViewport();
  });

  test("navigates to dynamic 'id' prop", async ({ initTestBed, page }) => {
    await initTestBed(`
      <VStack var.dynId="initial-id" height="600px">
        <Link to="#green-section">Jump to green</Link>
        <Button onClick="dynId = 'green-section'">Set green section id</Button>
        <VStack height="700px" backgroundColor="red">Red content</VStack>
        <Bookmark id="{dynId}" />
        <VStack height="700px" backgroundColor="green">Green content</VStack>
      </VStack>
    `);

    const greenContent = page.getByText("Green content");
    await expect(greenContent).not.toBeInViewport();

    await page.getByRole("button", { name: "Set green section id" }).click();

    const greenLink = page.getByRole("link", { name: "Jump to green" });
    await greenLink.click();

    await page.waitForURL(/#green-section$/);
    await expect(greenContent).toBeInViewport();
  });
});

```
Page 41/141FirstPrevNextLast