This is page 40 of 143. Use http://codebase.md/xmlui-org/xmlui/%7Bnode.props.src?format=md&lines=false&page={x} to view the full context.

# Directory Structure

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

# Files

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

```markdown
# RadioGroup [#radiogroup]

`RadioGroup` creates a mutually exclusive selection interface where users can choose only one option from a group of radio buttons. It manages the selection state and ensures that selecting one option automatically deselects all others in the group.

Radio options store their values as strings. Numbers and booleans are converted to strings when assigned, while objects, functions and arrays default to an empty string unless resolved via binding expressions.

**Key features:**
- **Exclusive selection**: Only one option can be selected at a time within the group
- **Form integration**: Built-in validation states and seamless form compatibility
- **Flexible layout**: Contains [Option](/components/Option) that can be arranged in any layout structure
- **State management**: Automatically handles selection state and change events
- **Accessibility support**: Proper keyboard navigation and screen reader compatibility
- **Validation indicators**: Visual feedback for error, warning, and valid states

`RadioGroup` is often used in forms. See [this guide](/forms) for details.

## Properties [#properties]

### `autoFocus` (default: false) [#autofocus-default-false]

If this property is set to `true`, the component gets the focus automatically when displayed.

### `enabled` (default: true) [#enabled-default-true]

This boolean property value indicates whether the component responds to user events (`true`) or not (`false`).

This property indicates whether the input accepts user actions (`true`) or not (`false`). The default value is `true`.

```xmlui-pg copy display name="Example: enabled"
<App>
  <RadioGroup initialValue="first" enabled="false">
    <HStack padding="$space-normal">
      <Option label="First Item" value="first"/>
      <Option label="Second Item" value="second"/>
      <Option label="Third Item" value="third"/>
    </HStack>
  </RadioGroup>
</App>
```

### `initialValue` (default: "") [#initialvalue-default-]

This property sets the component's initial value.

This property defines the initial value of the selected option within the group.

```xmlui-pg copy display name="Example: initialValue"
<App>
  <RadioGroup initialValue="first">
    <HStack padding="$space-normal">
      <Option label="First Item" value="first"/>
      <Option label="Second Item" value="second"/>
      <Option label="Third Item" value="third"/>
    </HStack>
  </RadioGroup>
</App>
```

### `readOnly` (default: false) [#readonly-default-false]

Set this property to `true` to disallow changing the component value.

### `required` (default: false) [#required-default-false]

Set this property to `true` to indicate it must have a value before submitting the containing form.

### `validationStatus` (default: "none") [#validationstatus-default-none]

This property allows you to set the validation status of the input component.

Available values:

| Value | Description |
| --- | --- |
| `valid` | Visual indicator for an input that is accepted |
| `warning` | Visual indicator for an input that produced a warning |
| `error` | Visual indicator for an input that produced an error |

This prop is used to visually indicate status changes reacting to form field validation.

| Value     | Description                                           |
| :-------- | :---------------------------------------------------- |
| `valid`   | Visual indicator for an input that is accepted        |
| `warning` | Visual indicator for an input that produced a warning |
| `error`   | Visual indicator for an input that produced an error  |

```xmlui-pg copy display name="Example: validationStatus"
<App>
  <HStack>
    <RadioGroup initialValue="first" validationStatus="error">
      <Option label="First Item" value="first"/>
      <Option label="Second Item" value="second"/>
    </RadioGroup>
    <RadioGroup initialValue="first" validationStatus="warning">
      <Option label="First Item" value="first"/>
      <Option label="Second Item" value="second"/>
    </RadioGroup>
    <RadioGroup initialValue="first" validationStatus="valid">
      <Option label="First Item" value="first"/>
      <Option label="Second Item" value="second"/>
    </RadioGroup>
  </HStack>
</App>
```

## Events [#events]

### `didChange` [#didchange]

This event is triggered when value of RadioGroup has changed.

This event is triggered after the user has changed the field value. The following example uses this event to display the selected option's value:

```xmlui-pg
---app copy display name="Example: didChange"
<App var.field="">
  <RadioGroup initialValue="{field}" onDidChange="(val) => field = val">
    <Option label="First Item" value="first"/>
    <Option label="Second Item" value="second"/>
  </RadioGroup>
  <Text value="{field}" />
</App>
---desc
Select one of the available options and see how the `Text` underneath it is updated in parallel:
```

### `gotFocus` [#gotfocus]

This event is triggered when the RadioGroup has received the focus.

### `lostFocus` [#lostfocus]

This event is triggered when the RadioGroup has lost the focus.

## Exposed Methods [#exposed-methods]

This component does not expose any methods.

## Styling [#styling]

`RadioGroup` is a component that governs its children and stores the selected value. It does not support styling; however, you can style the options within the group. When you set the theme variables for the group's options, use the `RadioGroupOption` name.

### Theme Variables [#theme-variables]

| Variable | Default Value (Light) | Default Value (Dark) |
| --- | --- | --- |
| [backgroundColor](../styles-and-themes/common-units/#color)-checked-RadioGroupOption | $color-primary-500 | $color-primary-500 |
| [backgroundColor](../styles-and-themes/common-units/#color)-checked-RadioGroupOption | $color-primary-500 | $color-primary-500 |
| [backgroundColor](../styles-and-themes/common-units/#color)-checked-RadioGroupOption--disabled | $textColor--disabled | $textColor--disabled |
| [backgroundColor](../styles-and-themes/common-units/#color)-checked-RadioGroupOption--disabled | $textColor--disabled | $textColor--disabled |
| [backgroundColor](../styles-and-themes/common-units/#color)-RadioGroupOption--default | *none* | *none* |
| [backgroundColor](../styles-and-themes/common-units/#color)-RadioGroupOption--disabled | $backgroundColor--disabled | $backgroundColor--disabled |
| [borderColor](../styles-and-themes/common-units/#color)-checked-RadioGroupOption | $color-primary-500 | $color-primary-500 |
| [borderColor](../styles-and-themes/common-units/#color)-checked-RadioGroupOption | $color-primary-500 | $color-primary-500 |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption--default | $color-surface-500 | $color-surface-500 |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption--default | $color-surface-500 | $color-surface-500 |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption--default--active | $color-primary-500 | $color-primary-500 |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption--default--active | $color-primary-500 | $color-primary-500 |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption--default--hover | $color-surface-700 | $color-surface-700 |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption--default--hover | $color-surface-700 | $color-surface-700 |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption--disabled | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption--error | $borderColor-Input--error | $borderColor-Input--error |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption--error | $borderColor-Input--error | $borderColor-Input--error |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption--success | $borderColor-Input--success | $borderColor-Input--success |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption--success | $borderColor-Input--success | $borderColor-Input--success |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption--warning | $borderColor-Input--warning | $borderColor-Input--warning |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption--warning | $borderColor-Input--warning | $borderColor-Input--warning |
| [borderWidth](../styles-and-themes/common-units/#size)-RadioGroupOption | 1px | 1px |
| [borderWidth](../styles-and-themes/common-units/#size)-RadioGroupOption-validation | 2px | 2px |
| [color](../styles-and-themes/common-units/#color)-RadioGroupOption--disabled | *none* | *none* |
| [fontSize](../styles-and-themes/common-units/#size)-RadioGroupOption | $fontSize-sm | $fontSize-sm |
| [fontSize](../styles-and-themes/common-units/#size)-RadioGroupOption | $fontSize-sm | $fontSize-sm |
| [fontWeight](../styles-and-themes/common-units/#fontWeight)-RadioGroupOption | $fontWeight-bold | $fontWeight-bold |
| [fontWeight](../styles-and-themes/common-units/#fontWeight)-RadioGroupOption | $fontWeight-bold | $fontWeight-bold |
| [gap](../styles-and-themes/common-units/#size)-RadioGroupOption | $space-1_5 | $space-1_5 |
| [outlineColor](../styles-and-themes/common-units/#color)-RadioGroupOption--focus | *none* | *none* |
| [outlineOffset](../styles-and-themes/common-units/#size)-RadioGroupOption--focus | *none* | *none* |
| [outlineStyle](../styles-and-themes/common-units/#border)-RadioGroupOption--focus | *none* | *none* |
| [outlineWidth](../styles-and-themes/common-units/#size)-RadioGroupOption--focus | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-RadioGroupOption--default | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-RadioGroupOption--error | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-RadioGroupOption--success | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-RadioGroupOption--warning | *none* | *none* |

```

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

```typescript
import {
  createContext,
  type ReactNode,
  useCallback,
  useContext,
  useEffect,
  useId,
  useMemo,
  useRef,
  useState,
} from "react";
import type { ComponentDef } from "../abstractions/ComponentDefs";
import { usePopper } from "react-popper";
import { createPortal } from "react-dom";
import { useTheme } from "./theming/ThemeContext";
import classnames from "classnames";
import { Button } from "../components/Button/ButtonNative";
import styles from "./InspectorButton.module.scss";
import type { ProjectCompilation } from "../abstractions/scripting/Compilation";
import { InspectorDialog } from "./devtools/InspectorDialog";
import AppWithCodeViewNative from "../components/NestedApp/AppWithCodeViewNative";
import { XmlUiHelper } from "../parsers/xmlui-parser";
import { useAppContext } from "./AppContext";

// --- The context object that is used to store the inspector information.
interface IInspectorContext {
  // --- The list of source files for the components.
  sources?: Record<string, string>;
  attach: (node: ComponentDef, uid: symbol, inspectId: string) => void;
  detach: (uid: symbol, inspectId: string) => void;
  refresh: (inspectId: string) => void;
  devToolsEnabled?: boolean;
  setIsOpen: (isOpen: boolean) => void;
  isOpen: boolean;
  inspectedNode: any;
  projectCompilation: ProjectCompilation | undefined;
  setInspectMode: (inspectMode: (prev: any) => boolean) => void;
  inspectMode: boolean;
  mockApi: any;
  clickPosition: { x: number; y: number };
}

// --- The context object that is used to store the inspector information.
export const InspectorContext = createContext<IInspectorContext | null>(null);

export function InspectorProvider({
  children,
  sources,
  projectCompilation,
  mockApi,
}: {
  children: ReactNode;
  sources?: Record<string, string>;
  projectCompilation?: ProjectCompilation;
  mockApi?: any;
}) {
  const [inspectable, setInspectable] = useState<Record<string, any>>({});
  const [inspectedNode, setInspectedNode] = useState<ComponentDef | null>(null);
  const [showCode, setShowCode] = useState(false);
  const [inspectMode, setInspectMode] = useState(false);
  const [clickPosition, setClickPosition] = useState<{ x: number; y: number }>({
    x: 0,
    y: 0,
  });
  const contextValue: IInspectorContext = useMemo(() => {
    return {
      sources,
      attach: (node, uid, inspectId) => {
        setInspectable((prev) => {
          return {
            ...prev,
            [inspectId]: {
              node,
              uid,
              inspectId,
              key: 0,
            },
          };
        });
      },
      refresh: (inspectId) => {
        setInspectable((prev) => {
          return {
            ...prev,
            [inspectId]: {
              ...prev[inspectId],
              key: prev[inspectId].key + 1,
            },
          };
        });
      },
      detach: (uid, inspectId) => {
        setInspectable((prev) => {
          const ret = { ...prev };
          delete ret[inspectId];
          return ret;
        });
      },
      inspectedNode,
      setIsOpen: setShowCode,
      isOpen: showCode,
      devToolsEnabled: showCode,
      projectCompilation: projectCompilation,
      setInspectMode,
      inspectMode,
      mockApi,
      clickPosition,
    };
  }, [
    sources,
    inspectedNode,
    showCode,
    clickPosition,
    setShowCode,
    projectCompilation,
    inspectMode,
    mockApi,
  ]);

  return (
    <InspectorContext.Provider value={contextValue}>
      {children}
      {process.env.VITE_USER_COMPONENTS_Inspect !== "false" &&
        inspectable &&
        Object.values(inspectable).map((item: any) => {
          return (
            <InspectButton
              inspectedNode={inspectedNode}
              setShowCode={setShowCode}
              setClickPosition={setClickPosition}
              key={item.inspectId + +"-" + item.key}
              inspectId={item.inspectId}
              node={item.node}
              setInspectedNode={setInspectedNode}
              inspectMode={inspectMode}
            />
          );
        })}
    </InspectorContext.Provider>
  );
}

function InspectButton({
  inspectId,
  node,
  inspectedNode,
  setInspectedNode,
  setShowCode,
  inspectMode,
  setClickPosition,
}: {
  inspectId: string;
  node: ComponentDef;
  inspectedNode: any;
  setInspectedNode: (node: any) => void;
  setShowCode: (show: any) => void;
  inspectMode: boolean;
  setClickPosition?: (position: { x: number; y: number }) => void;
}) {
  const { root } = useTheme();
  const [referenceElement, setReferenceElement] = useState<HTMLElement | null>(null);
  const [popperElement, setPopperElement] = useState<HTMLButtonElement | null>(null);
  const { styles: popperStyles, attributes } = usePopper(referenceElement, popperElement, {
    placement: "top-end",
    modifiers: [
      {
        name: "offset",
        options: {
          offset: [-4, -18],
        },
      },
      {
        name: "flip",
        enabled: false,
        // options: {
        //   fallbackPlacements: ['top', 'right'],
        // },
      },
    ],
  });
  const [visible, setVisible] = useState(false);
  const timeoutRef = useRef<number | null>(null);
  const hoverRef = useRef<boolean>(false);

  useEffect(() => {
    if (!referenceElement) {
      return;
    }
    if (inspectedNode?.inspectId === inspectId) {
      referenceElement.classList.add(styles.inspectedNode);
    } else {
      referenceElement.classList.remove(styles.inspectedNode);
    }
  }, [inspectId, inspectedNode, referenceElement]);

  useEffect(() => {
    if (inspectedNode) {
      setShowCode(true);
    } else {
      setShowCode(false);
    }
  }, [inspectedNode]);

  useEffect(() => {
    const htmlElement = document.querySelector(`[data-inspectId="${inspectId}"]`) as HTMLElement;
    if (!htmlElement) {
      return;
    }

    setReferenceElement(htmlElement);

    if (inspectMode) {
      htmlElement.classList.add(styles.inspectableNode);

      const overlay = document.createElement("div");
      overlay.classList.add(styles.inspectOverlay);
      htmlElement.appendChild(overlay);

      overlay.addEventListener("click", () => {
        setInspectedNode((prev) => {
          if (prev?.inspectId === inspectId) {
            return null;
          }
          return { ...node, inspectId };
        });
      });
    }

    if (!inspectMode) {
      htmlElement.classList.remove(styles.inspectableNode);

      setInspectedNode(null);
      setShowCode(false);
      const overlay = htmlElement.querySelector(`.${styles.inspectOverlay}`);

      if (overlay) {
        overlay.remove();
      }

      htmlElement.classList.remove(styles.inspectedNode);
    }

    function mouseenter() {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
      setVisible(true);
    }

    function mouseleave() {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
      if (hoverRef.current) {
        return;
      }
      timeoutRef.current = window.setTimeout(() => {
        setVisible(false);
      }, 100);
    }

    htmlElement.addEventListener("mouseenter", mouseenter);
    htmlElement.addEventListener("mouseleave", mouseleave);
    return () => {
      htmlElement.removeEventListener("mouseenter", mouseenter);
      htmlElement.removeEventListener("mouseleave", mouseleave);
    };
  }, [inspectId, node, inspectMode, setShowCode, setInspectedNode]);

  return (
    <>
      {inspectMode
        ? null
        : visible &&
          !!root &&
          createPortal(
            <Button
              variant={"outlined"}
              className={classnames(styles.wrapper, "_debug-inspect-button")}
              ref={(el) => setPopperElement(el)}
              style={{ ...popperStyles.popper, padding: 0 }}
              {...attributes.popper}
              onMouseEnter={() => {
                hoverRef.current = true;
                if (timeoutRef.current) {
                  clearTimeout(timeoutRef.current);
                  timeoutRef.current = null;
                }
              }}
              onMouseLeave={() => {
                hoverRef.current = false;
                setVisible(false);
              }}
              onClick={() => {
                setInspectedNode(node);
                setShowCode(true);
                setClickPosition({
                  x: popperElement?.getBoundingClientRect().left || 0,
                  y: popperElement?.getBoundingClientRect().top || 0,
                });
              }}
            >
              Show code
            </Button>,
            root,
          )}
    </>
  );
}

export function useDevTools() {
  const context = useContext(InspectorContext);

  if (!context) {
    throw new Error("useDevTools must be used within an InspectorProvider");
  }

  return {
    projectCompilation: context.projectCompilation,
    inspectedNode: context.inspectedNode,
    sources: context.sources,
    isOpen: context.isOpen,
    setIsOpen: context.setIsOpen,
    devToolsEnabled: context.devToolsEnabled,
    mockApi: context.mockApi,
    clickPosition: context.clickPosition,
  };
}

export function useInspectMode() {
  const context = useContext(InspectorContext);
  return {
    setInspectMode: context?.setInspectMode,
    inspectMode: context?.inspectMode,
  };
}

export function useInspector(node: ComponentDef, uid: symbol) {
  const context = useContext(InspectorContext);
  const inspectValue = (node.props as any)?.inspect;
  const shouldInspect = inspectValue === true || inspectValue === "true";
  const inspectId = useId();
  const refreshInspection = useCallback(() => {
    context?.refresh(inspectId);
  }, [context, inspectId]);

  useEffect(() => {
    if (shouldInspect) {
      context?.attach(node, uid, inspectId);
    }
    return () => {
      context?.detach(uid, inspectId);
    };
  }, [context, inspectId, node, shouldInspect, uid]);

  if (shouldInspect && context) {
    return {
      refreshInspection,
      inspectId,
    };
  }
  return {};
}

```

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

```markdown
# DataSource [#datasource]

`DataSource` fetches and caches data from API endpoints, versus [`APICall`](/components/APICall) which creates, updates or deletes data.

**Key characteristics:**
- **Conditional loading**: Use `when` property to prevent fetching until dependent data is ready
- **Built-in caching**: Prevents unnecessary requests and provides instant data access
- **Polling support**: Automatically refetch data at specified intervals
- **Data transformation**: Process and filter responses before components use the data

## Preventing the `DataSource` from Executing [#preventing-the-datasource-from-executing]

Prevent the `DataSource` from executing until the specified condition in the `when` attribute is true.

```xmlui
<DataSource
  id="userProfile"
  url="/api/users/{selectedUserId}/profile"
  when="{selectedUserId}" />
```

## Structural Sharing [#structural-sharing]

`DataSource` uses a technique called "structural sharing" to ensure that as many data references as possible will be kept intact and not cause extra UI refresh. If data is fetched from an API endpoint, you'll usually get a completely new reference by json parsing the response. However, `DataSource` will keep the original reference if *nothing* has changed in the data. If a subset has changed, `DataSource` will keep the unchanged parts and only replace the changed parts.

When you initiate the refetching of data (e.g., with the `refetch` method or setting the `pollIntervalInSeconds` property) and you retrieve data structurally equal with the cached data instance, `DataSource` will not fire the `loaded` event.

By default, structural sharing is turned on. If you do not need this behavior, set the `structuralSharing` property to `false`.

## Properties [#properties]

### `body` [#body]

Set the optional request body. The object you pass is serialized as a JSON string.

### `completedNotificationMessage` [#completednotificationmessage]

Set the message to display when the data fetch completes.If the property value is not set, no completion message is displayed.

This property customizes the success message displayed in a toast after the finished API invocation. The `$result` context variable can refer to the response body. For example, you can use the following code snippet to display the first 100 characters in the completed operation's response body:

```xmlui copy
 <DataSource
  id="ds"
  url="/api/shopping-list"
  completedNotificationMessage="Result: {JSON.stringify($result).substring(0, 100)}" />
```

### `errorNotificationMessage` [#errornotificationmessage]

Set the message to display when the there is an error. You can use the `$error` context value in an expression to refer to the original error message.

This property customizes the message displayed in a toast when the API invocation results in an error. The `$error.statusCode` context variable can refer to the response's status code, while `$error. details` to the response body. For example, you can use the following code snippet to display the status code and the details:

```xmlui copy
 <DataSource
  id="ds"
  method="post"
  url="/api/shopping-list"
  errorNotificationMessage="${error.statusCode}, {JSON.stringify($error.details)}" />
```

### `headers` [#headers]

Set request headers. Pass an object whose keys are header names and values are header values.

### `id` (required) [#id-required]

Set the ID used by other components to access the retrieved data in the `value`property of a `DataSource`, or status info in the `loaded` and `error` properties.When no `id` is set, the component cannot be used programmatically.

### `inProgressNotificationMessage` [#inprogressnotificationmessage]

Set the message to display when the data fetch is in progress. If the property value is not set, no progress message is displayed.

### `method` (default: "get") [#method-default-get]

Set the HTTP method.

Available values: `get` **(default)**, `post`, `put`, `delete`, `patch`, `head`, `options`, `trace`, `connect`

### `nextPageSelector` [#nextpageselector]

When using `DataSource` with paging, the response may contain information about the previous and next page. This property defines the selector that extracts the next page information from the response deserialized to an object.

### `pollIntervalInSeconds` [#pollintervalinseconds]

Set the interval for periodic data fetching. If the data changes on refresh, XMLUI will re-render components that refer directly or indirectly to the `DataSource`. If not set or set to zero, the component does not poll for data.

### `prevPageSelector` [#prevpageselector]

When using `DataSource` with paging, the response may contain information about the previous and next page. This property defines the selector that extracts the previous page information from the response deserialized to an object.

### `queryParams` [#queryparams]

Append optional key-value pairs to the URL.

### `rawBody` [#rawbody]

Set the request body with no serialization. Use it to send a payload  that has already been serialized to a JSON string.

### `resultSelector` [#resultselector]

Set an optional object key to extract a subset of the response data. If this value is not set, the entire response body is considered the result.

The selector can be a simple dot notation path (e.g., `value.results`) or a JavaScript expression that processes the data (e.g., `results.filter(item => item.type === 'active')`). The selector has access to standard JavaScript functions like `map` and `filter`, and operates on the full response body.

Here is a sample response from the HubSpot API.

```json
{
    "results": [
        {
            "id": "88903258744",
            "properties": {
                "company": "HubSpot",
                "createdate": "2025-01-03T23:38:47.449Z",
                "custom_notes": "Nice guy!",
                "email": "bh@hubspot.com",
                "firstname": "Brian",
                "hs_object_id": "88903258744",
                "lastmodifieddate": "2025-02-18T23:13:34.759Z",
                "lastname": "Halligan (Sample Contact)"
            },
            "createdAt": "2025-01-03T23:38:47.449Z",
            "updatedAt": "2025-02-18T23:13:34.759Z",
            "archived": false
        },
        {
            "id": "88918034480",
            "properties": {
                "company": "HubSpot",
                "createdate": "2025-01-03T23:38:47.008Z",
                "custom_notes": null,
                "email": "emailmaria@hubspot.com",
                "firstname": "Maria",
                "hs_object_id": "88918034480",
                "lastmodifieddate": "2025-01-03T23:38:59.001Z",
                "lastname": "Johnson (Sample Contact)"
            },
            "createdAt": "2025-01-03T23:38:47.008Z",
            "updatedAt": "2025-01-03T23:38:59.001Z",
            "archived": false
        }
    ]
}
```

This `resultSelector` builds an array of the `properties` objects.

```xmlui copy
<DataSource
  id="contacts"
  url="http://{DOMAIN}/{CORS_PROXY}/api.hubapi.com/crm/v3/objects/contacts?properties=firstname,lastname,email,company,custom_notes"
  resultSelector="results.map(item => item.properties )"
  headers='{{"Authorization":"Bearer not-a-real-token"}}'
```

This `List` uses the array.

```xmlui copy
<List data="{contacts}" title="Hubspot Contacts">
  <Card gap="0" width="20em">
    <Text fontWeight="bold">
      {$item.firstname} {$item.lastname}
    </Text>
    <Text>
      {$item.company}
    </Text>
    <Text>
      {$item.email}
    </Text>
    <Text>
      {$item.custom_notes}
    </Text>
  </Card>
</List>
```

This `resultSelector` filters the array of the `properties` objects to include only contacts with non-null `custom_notes`.

```xmlui copy
<DataSource
  id="contacts"
  resultSelector="results.filter(contact => contact.properties.custom_notes !== null).map(contact => contact.properties)"
  url="http://{DOMAIN}/{CORS_PROXY}/api.hubapi.com/crm/v3/objects/contacts?properties=firstname,lastname,email,company,custom_notes"
  headers='{{"Authorization":"Bearer not-a-real-token"}}'
  />
````

This `Table` uses the filtered array.

```xmlui copy
<Table title="HubSpot contacts" data="{contacts}">
  <Column bindTo="firstname" />
  <Column bindTo="lastname" />
  <Column bindTo="company" />
  <Column bindTo="email" />
  <Column bindTo="custom_notes" />
</Table>
```

### `structuralSharing` (default: "true") [#structuralsharing-default-true]

This property allows structural sharing. When turned on, `DataSource` will keep the original reference if nothing has changed in the data. If a subset has changed, `DataSource` will keep the unchanged parts and only replace the changed parts. If you do not need this behavior, set this property to `false`.

### `transformResult` [#transformresult]

Set an optional function to perform a final transformation of the response data. If this value is not set, the result is not transformed.

### `url` (required) [#url-required]

Set the URL.

## Events [#events]

### `error` [#error]

This event fires when a request results in an error.

### `loaded` [#loaded]

The component triggers this event when the fetch operation has been completed and the data is loaded. The event has two arguments. The first is the data loaded; the second indicates if the event is a result of a refetch.

## Exposed Methods [#exposed-methods]

### `inProgress` [#inprogress]

This property indicates if the data is being fetched.

**Signature**: `get inProgress(): boolean`

### `isRefetching` [#isrefetching]

This property indicates if the data is being re-fetched.

**Signature**: `get isRefetching(): boolean`

### `loaded` [#loaded]

This property indicates if the data has been loaded.

**Signature**: `get loaded(): boolean`

### `refetch` [#refetch]

This method requests the re-fetch of the data.

**Signature**: `refetch(): void`

### `value` [#value]

This property retrieves the data queried from the source after optional transformations.

**Signature**: `get value(): any`

## Styling [#styling]

This component does not have any styles.

```

--------------------------------------------------------------------------------
/xmlui/src/components/Tooltip/Tooltip.md:
--------------------------------------------------------------------------------

```markdown
%-DESC-START

## Using Tooltip

You rarely need to use the Tooltip component directly, as visual components support three properties, `tootip`, `tooltipMarkdown`, and `tooltipOptions` respectively. When you utilize the `tooltip` property with a visual component, hovering over that component displays the associated text.

### The `tooltip` property

```xmlui-pg display copy height="180px" /tooltip/ name="Example: using the tooltip property"
<App>
  <CHStack height="100px" verticalAlignment="center" >
    <Button
      label="Hover the mouse over me!"
      tooltip="I'm hovered!"
    >
    </Button>
  </CHStack>
</App>
```

### The `tooltipMarkdown` property

The `tooltipMarkdown` property allows you to use the tooltip with markdown syntax.

```xmlui-pg display copy /tooltipMarkdown/ name="Example: using the tooltipMarkdown property"
<App>
  <VStack height="80px" width="fit-content">
    <Card
      title="Tooltip with markdown"
      tooltipMarkdown="This *example* uses `toolTipMarkdown`"
      tooltipOptions="right"
    />
  </VStack>
</App>
```

### The `tooltipOptions` property

The tooltip provides several options (see the properties of this component), influencing its behavior and appearance. You can set the `tooltipOptions` property to define these options.

For example, the following example positions the tooltip to the right, making it appear somewhat distant from the component.

```xmlui-pg display copy height="180px" /tooltipOptions/ name="Example: using the tooltipOptions property"
<App>
  <CHStack height="100px" verticalAlignment="center" >
    <Button
      label="Hover the mouse over me!"
      tooltip="I'm hovered"
      tooltipOptions="right; sideOffset: 32"
    >
    </Button>
  </CHStack>
</App>
```

You can define `tooltipOptions` as a string or as an object. In the latter case, the object declares name and value pairs describing the visual options:

```xmlui-pg display copy height="180px" /tooltipOptions/ name="Example: tooltipOptions as an object"
<App>
  <CHStack height="100px" verticalAlignment="center" >
    <Button
      label="Hover the mouse over me!"
      tooltip="Use an object"
      tooltipOptions="{{ showArrow: false, side: 'bottom', align: 'start' }}"
    >
    </Button>
  </CHStack>
</App>
```

The string form of `tooltipOptions` is composed of names or name and value pairs separated by semicolons. The properties that allow enumerations (such as `side` or `align`) can be set with a name representing a single value. Properties with boolean values can use the property name to represent the `true` value, or the property name prefixed with an exclamation mark to signify a `false` value. Numeric values are separated from the property name by a colon, and they do not use units. Here are a few examples:

```xmlui-pg display copy height="300px" /tooltipOptions/ name="Example: tooltipOptions as a string"
<App>
  <VStack height="100px" horizontalAlignment="center" gap="3rem">
    <Card
      title="Tooltip to the left with 800ms delay"
      tooltip="I'm a Tooltip"
      tooltipOptions="left; delayDuration: 800; !showArrow" />
    <HStack>
      <Icon
        name="email"
        width="48px"
        height="48px"
        tooltipMarkdown="**Tooltip** to the bottom with no arrows, aligned left"
        tooltipOptions="bottom; !showArrow; start" />
      <Icon
        name="phone"
        width="48px"
        height="48px"
        tooltipMarkdown="*Tooltip* to the bottom with arrows, 28 pixels away"
        tooltipOptions="bottom; showArrow; sideOffset: 28" />
    </HStack>
  </VStack>
</App>
```

### Using the Tooltip component

Instead of using the tooltip-related properties, you can wrap the component into a `Tooltip`:

```xmlui-pg display copy height="260px" name="Example: Using the Tooltip component"
<App>
  <VStack height="100px" horizontalAlignment="center">
    <Tooltip side="bottom" markdown="This *example* uses a `Tooltip` component">
      <Stack>
        <Card title="Card 1: within a Tooltip" />
        <Card title="Card 2: within the same Tooltip" />
      </Stack>
    </Tooltip>
  </VStack>
</App>
```

### Using a Tooltip template

You can specify tooltips that you could not otherwise do with the `text` or `markdown` properties.

```xmlui-pg display copy height="200px" name="Example: Using a tooltipTemplate" /tooltipTemplate/
<App>
  <VStack height="100px" horizontalAlignment="center">
    <Tooltip side="bottom">
      <property name="tooltipTemplate">
        <HStack>
          <Stack width="24px" height="24px" backgroundColor="purple" />
          <H2>This is a tooltip</H2>
        </HStack>
      </property>
      <Card title="I have a templated Tooltip!" />
    </Tooltip>
  </VStack>
</App>
```

A `tooltipTemplate` may be able to use the `$tooltip` context variable.

```xmlui-pg display copy height="600px" name="Example: tooltipTemplate with $tooltip context variable"
<App
    var.starData="{[
      { star_date: '2025-02-11T00:00:00Z', xmlui_stars: 0, xmlui_test_server_stars: 0, xmlui_invoice_stars: 0, xmlui_mcp_stars: 0 },
      { star_date: '2025-07-18T00:00:00Z', xmlui_stars: 1, xmlui_test_server_stars: 0, xmlui_invoice_stars: 0, xmlui_mcp_stars: 0 },
      { star_date: '2025-07-19T00:00:00Z', xmlui_stars: 4, xmlui_test_server_stars: 1, xmlui_invoice_stars: 0, xmlui_mcp_stars: 0 },
      { star_date: '2025-07-20T00:00:00Z', xmlui_stars: 48, xmlui_test_server_stars: 5, xmlui_invoice_stars: 2, xmlui_mcp_stars: 1 },
      { star_date: '2025-07-21T00:00:00Z', xmlui_stars: 62, xmlui_test_server_stars: 8, xmlui_invoice_stars: 3, xmlui_mcp_stars: 2 },
      { star_date: '2025-07-22T00:00:00Z', xmlui_stars: 16, xmlui_test_server_stars: 3, xmlui_invoice_stars: 1, xmlui_mcp_stars: 1 },
      { star_date: '2025-07-23T00:00:00Z', xmlui_stars: 6, xmlui_test_server_stars: 2, xmlui_invoice_stars: 1, xmlui_mcp_stars: 0 },
      { star_date: '2025-07-24T00:00:00Z', xmlui_stars: 3, xmlui_test_server_stars: 1, xmlui_invoice_stars: 0, xmlui_mcp_stars: 1 },
      { star_date: '2025-07-25T00:00:00Z', xmlui_stars: 10, xmlui_test_server_stars: 2, xmlui_invoice_stars: 1, xmlui_mcp_stars: 1 },
      { star_date: '2025-07-26T00:00:00Z', xmlui_stars: 2, xmlui_test_server_stars: 1, xmlui_invoice_stars: 0, xmlui_mcp_stars: 0 },
      { star_date: '2025-07-27T00:00:00Z', xmlui_stars: 3, xmlui_test_server_stars: 1, xmlui_invoice_stars: 1, xmlui_mcp_stars: 0 },
      { star_date: '2025-07-28T00:00:00Z', xmlui_stars: 4, xmlui_test_server_stars: 1, xmlui_invoice_stars: 0, xmlui_mcp_stars: 1 },
      { star_date: '2025-07-29T00:00:00Z', xmlui_stars: 4, xmlui_test_server_stars: 2, xmlui_invoice_stars: 1, xmlui_mcp_stars: 0 },
      { star_date: '2025-07-30T00:00:00Z', xmlui_stars: 1, xmlui_test_server_stars: 0, xmlui_invoice_stars: 0, xmlui_mcp_stars: 1 },
      { star_date: '2025-07-31T00:00:00Z', xmlui_stars: 1, xmlui_test_server_stars: 1, xmlui_invoice_stars: 0, xmlui_mcp_stars: 0 },
      { star_date: '2025-08-01T00:00:00Z', xmlui_stars: 2, xmlui_test_server_stars: 0, xmlui_invoice_stars: 1, xmlui_mcp_stars: 0 },
      { star_date: '2025-08-05T00:00:00Z', xmlui_stars: 1, xmlui_test_server_stars: 1, xmlui_invoice_stars: 0, xmlui_mcp_stars: 0 },
      { star_date: '2025-08-07T00:00:00Z', xmlui_stars: 1, xmlui_test_server_stars: 0, xmlui_invoice_stars: 0, xmlui_mcp_stars: 1 },
      { star_date: '2025-08-08T00:00:00Z', xmlui_stars: 3, xmlui_test_server_stars: 1, xmlui_invoice_stars: 1, xmlui_mcp_stars: 0 },
      { star_date: '2025-08-12T00:00:00Z', xmlui_stars: 2, xmlui_test_server_stars: 1, xmlui_invoice_stars: 0, xmlui_mcp_stars: 1 },
      { star_date: '2025-08-14T00:00:00Z', xmlui_stars: 1, xmlui_test_server_stars: 0, xmlui_invoice_stars: 1, xmlui_mcp_stars: 0 },
      { star_date: '2025-08-15T00:00:00Z', xmlui_stars: 2, xmlui_test_server_stars: 1, xmlui_invoice_stars: 0, xmlui_mcp_stars: 0 },
      { star_date: '2025-08-18T00:00:00Z', xmlui_stars: 2, xmlui_test_server_stars: 0, xmlui_invoice_stars: 1, xmlui_mcp_stars: 1 },
      { star_date: '2025-08-19T00:00:00Z', xmlui_stars: 3, xmlui_test_server_stars: 1, xmlui_invoice_stars: 1, xmlui_mcp_stars: 0 },
      { star_date: '2025-08-20T00:00:00Z', xmlui_stars: 1, xmlui_test_server_stars: 0, xmlui_invoice_stars: 0, xmlui_mcp_stars: 1 }
    ]}"
  >

    <VStack padding="$space-4" gap="$space-4">
      <Text fontSize="$fontSize-xl" fontWeight="$fontWeight-semibold">
        XMLUI Stars Over Time
      </Text>

      <Card height="400px">
        <LineChart
          data="{starData}"
          yKeys="{['xmlui_stars', 'xmlui_test_server_stars', 'xmlui_invoice_stars', 'xmlui_mcp_stars']}"
          xKey="star_date"
          showLegend="true"
          tickFormatterX="{formatDateWithoutYear}">
          <property name="tooltipTemplate">
            <Theme
              border-cell-Table="none"
              padding-cell-Table="0">
              <VStack
                gap="0"
                width="16rem"
                borderRadius="$borderRadius"
                boxShadow="$boxShadow-md"
                backgroundColor="$color-surface-100">
                <Text>
                  {formatDate($tooltip.label)}
                </Text>
                <Table
                  lineHeight="$lineHeight-tight"
                  data="{$tooltip.payload}"
                  hideHeader="true"
                  noBottomBorder="true">
                  <Column width="3*">
                    <HStack gap="$space-2" verticalAlignment="center">
                      <Stack
                        width="8px"
                        height="8px"
                        backgroundColor="{$item.color}" />
                      <Text fontSize="$fontSize-smaller">
                        {$item.label}
                      </Text>
                    </HStack>
                  </Column>
                  <Column>
                    <Text fontSize="$fontSize-smaller">
                      {$item.value}
                    </Text>
                  </Column>
                </Table>
              </VStack>
            </Theme>
          </property>
        </LineChart>
      </Card>
    </VStack>
</App>
```


%-DESC-END
```

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

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

// --- This code snippet is required to collect the theme variables used in this module
$themeVars: ();
@function createThemeVar($componentVariable) {
  $themeVars: t.appendThemeVar($themeVars, $componentVariable) !global;
  @return t.getThemeVar($themeVars, $componentVariable);
}

$component: "Button";
$themeVars: t.composePaddingVars($themeVars, $component);
$themeVars: t.composePaddingVars($themeVars, "#{$component}-xs");
$themeVars: t.composePaddingVars($themeVars, "#{$component}-sm");
$themeVars: t.composePaddingVars($themeVars, "#{$component}-md");
$themeVars: t.composePaddingVars($themeVars, "#{$component}-lg");

$fontFamily-Button: createThemeVar('fontFamily-#{$component}');
$fontSize-Button: createThemeVar('fontSize-#{$component}');
$fontWeight-Button: createThemeVar('fontWeight-#{$component}');
$fontStyle-Button: createThemeVar('fontStyle-#{$component}');
$borderRadius-Button: createThemeVar('borderRadius-#{$component}');
$borderWidth-Button: createThemeVar('borderWidth-#{$component}');
$borderWidth-Button--hover: createThemeVar('borderWidth-#{$component}--hover');
$borderColor-Button: createThemeVar('borderColor-#{$component}');
$borderColor-Button--hover: createThemeVar('borderColor-#{$component}--hover');
$borderStyle-Button: createThemeVar('borderStyle-#{$component}');
$borderStyle-Button--hover: createThemeVar('borderStyle-#{$component}--hover');
$backgroundColor-Button: createThemeVar('backgroundColor-#{$component}');
$backgroundColor-Button--hover: createThemeVar('backgroundColor-#{$component}--hover');
$textColor-Button: createThemeVar('textColor-#{$component}');
$textColor-Button--hover: createThemeVar('textColor-#{$component}--hover');
$boxShadow-Button: createThemeVar('boxShadow-#{$component}');
$boxShadow-Button--hover: createThemeVar('boxShadow-#{$component}--hover');

$gap-Button: createThemeVar('gap-#{$component}');
$transition-Button: createThemeVar('transition-#{$component}');

// --- CSS properties of solid buttons with the specified color scheme
@mixin solid($colorScheme){
  font-family: createThemeVar('fontFamily-#{$component}-#{$colorScheme}-solid');
  font-size: createThemeVar('fontSize-#{$component}-#{$colorScheme}-solid');
  font-weight: createThemeVar('fontWeight-#{$component}-#{$colorScheme}-solid');
  border-radius: createThemeVar('borderRadius-#{$component}-#{$colorScheme}-solid');
  border-width: createThemeVar('borderWidth-#{$component}-#{$colorScheme}-solid');
  border-color: createThemeVar('borderColor-#{$component}-#{$colorScheme}-solid');
  border-style: createThemeVar('borderStyle-#{$component}-#{$colorScheme}-solid');
  background: createThemeVar('backgroundColor-#{$component}-#{$colorScheme}-solid');
  color: createThemeVar('textColor-#{$component}-#{$colorScheme}-solid');
  box-shadow: createThemeVar('boxShadow-#{$component}-#{$colorScheme}-solid');
  transition: createThemeVar('transition-#{$component}-#{$colorScheme}-solid');

  &:focus-visible {
    outline-width: createThemeVar('outlineWidth-#{$component}-#{$colorScheme}-solid--focus');
    outline-color: createThemeVar('outlineColor-#{$component}-#{$colorScheme}-solid--focus');
    outline-style: createThemeVar('outlineStyle-#{$component}-#{$colorScheme}-solid--focus');
    outline-offset: createThemeVar('outlineOffset-#{$component}-#{$colorScheme}-solid--focus');
  }

  &:not([disabled]) {
    &:hover {
      border-color: createThemeVar('borderColor-#{$component}-#{$colorScheme}-solid--hover');
      color: createThemeVar('textColor-#{$component}-#{$colorScheme}-solid--hover');
      background: createThemeVar('backgroundColor-#{$component}-#{$colorScheme}-solid--hover');
    }

    &:active {
      border-color: createThemeVar('borderColor-#{$component}-#{$colorScheme}-solid--active');
      color: createThemeVar('textColor-#{$component}-#{$colorScheme}-solid--active');
      box-shadow: createThemeVar('boxShadow-#{$component}-#{$colorScheme}-solid--active');
      background: createThemeVar('backgroundColor-#{$component}-#{$colorScheme}-solid--active');
    }
  }

  &:disabled {
    cursor: not-allowed;
    background: createThemeVar('backgroundColor-#{$component}--disabled');
    color: createThemeVar('textColor-#{$component}--disabled');
    border-color: createThemeVar('borderColor-#{$component}--disabled');
  }
}

// --- CSS properties of outlined buttons with the specified color scheme
@mixin outlined($colorScheme){
  font-family: createThemeVar('fontFamily-#{$component}-#{$colorScheme}-outlined');
  font-size: createThemeVar('fontSize-#{$component}-#{$colorScheme}-outlined');
  font-weight: createThemeVar('fontWeight-#{$component}-#{$colorScheme}-outlined');
  border-radius: createThemeVar('borderRadius-#{$component}-#{$colorScheme}-outlined');
  border-width: createThemeVar('borderWidth-#{$component}-#{$colorScheme}-outlined');
  border-color: createThemeVar('borderColor-#{$component}-#{$colorScheme}-outlined');
  border-style: createThemeVar('borderStyle-#{$component}-#{$colorScheme}-outlined');
  color: createThemeVar('textColor-#{$component}-#{$colorScheme}-outlined');
  box-shadow: createThemeVar('boxShadow-#{$component}-#{$colorScheme}-outlined');
  background: transparent;

  &:focus-visible {
    outline-width: createThemeVar('outlineWidth-#{$component}-#{$colorScheme}-outlined--focus');
    outline-color: createThemeVar('outlineColor-#{$component}-#{$colorScheme}-outlined--focus');
    outline-style: createThemeVar('outlineStyle-#{$component}-#{$colorScheme}-outlined--focus');
    outline-offset: createThemeVar('outlineOffset-#{$component}-#{$colorScheme}-outlined--focus');
  }

  &:not([disabled]) {
    &:hover {
      border-color: createThemeVar('borderColor-#{$component}-#{$colorScheme}-outlined--hover');
      background: createThemeVar('backgroundColor-#{$component}-#{$colorScheme}-outlined--hover');
      color: createThemeVar('textColor-#{$component}-#{$colorScheme}-outlined--hover');
    }

    &:active {
      border-color: createThemeVar('borderColor-#{$component}-#{$colorScheme}-outlined--active');
      background: createThemeVar('backgroundColor-#{$component}-#{$colorScheme}-outlined--active');
      color: createThemeVar('textColor-#{$component}-#{$colorScheme}-outlined--active');
    }
  }

  &:disabled {
    cursor: not-allowed;
    color: createThemeVar('textColor-#{$component}--disabled');
    border-color: createThemeVar('borderColor-#{$component}--disabled');
  }
}

// --- CSS properties of ghost buttons with the specified color scheme
@mixin ghost($colorScheme){
  font-family: createThemeVar('fontFamily-#{$component}-#{$colorScheme}-ghost');
  font-size: createThemeVar('fontSize-#{$component}-#{$colorScheme}-ghost');
  font-weight: createThemeVar('fontWeight-#{$component}-#{$colorScheme}-ghost');
  border-radius: createThemeVar('borderRadius-#{$component}-#{$colorScheme}-ghost');
  border-width: createThemeVar('borderWidth-#{$component}-#{$colorScheme}-ghost');
  border-color: transparent;
  border-style: solid;
  background: transparent;
  color: createThemeVar('textColor-#{$component}-#{$colorScheme}-ghost');

  &:focus-visible {
    outline-width: createThemeVar('outlineWidth-#{$component}-#{$colorScheme}-ghost--focus');
    outline-color: createThemeVar('outlineColor-#{$component}-#{$colorScheme}-ghost--focus');
    outline-style: createThemeVar('outlineStyle-#{$component}-#{$colorScheme}-ghost--focus');
    outline-offset: createThemeVar('outlineOffset-#{$component}-#{$colorScheme}-ghost--focus');
  }

  &:not([disabled]) {
    &:hover {
      background: createThemeVar('backgroundColor-#{$component}-#{$colorScheme}-ghost--hover');
      color: createThemeVar('textColor-#{$component}-#{$colorScheme}-ghost--hover');
    }

    &:active {
      background: createThemeVar('backgroundColor-#{$component}-#{$colorScheme}-ghost--active');
      color: createThemeVar('textColor-#{$component}-#{$colorScheme}-ghost--active');
    }
  }

  &:disabled {
    cursor: not-allowed;
    color: createThemeVar('textColor-#{$component}--disabled');
  }
}


@layer components{
  // --- CSS styles
  .button {
    width: createThemeVar("width-Button");
    height: createThemeVar("height-Button");
    line-height: normal;
    min-width: 0;
    padding: 0;
    margin: 0;
    border-style: solid;
    transition: $transition-Button;
    user-select: none;
    cursor: pointer;
    display: flex;
    gap: $gap-Button;
    justify-content: center;
    align-items: center;

    &.alignStart {
      justify-content: start;
    }

    &.alignEnd {
      justify-content: end;
    }

    * {
      color: inherit;
    }

    &.buttonHorizontal {
      flex-direction: row;
      &.xs {
        @include t.paddingVars($themeVars, "#{$component}-xs");
      }

      &.sm {
        @include t.paddingVars($themeVars, "#{$component}-sm");
      }

      &.md {
        @include t.paddingVars($themeVars, "#{$component}-md");
      }

      &.lg {
        @include t.paddingVars($themeVars, "#{$component}-lg");
      }
    }

    &.buttonVertical {
      flex-direction: column;
      gap: t.$space-1;
      width: fit-content;
      height: fit-content;

      &.xs {
        @include t.paddingVars($themeVars, "#{$component}-xs");
      }

      &.sm {
        @include t.paddingVars($themeVars, "#{$component}-sm");
      }

      &.md {
        @include t.paddingVars($themeVars, "#{$component}-md");
      }

      &.lg {
        @include t.paddingVars($themeVars, "#{$component}-lg");
      }
    }

    &.solidPrimary {
      @include solid('primary');
    }

    &.solidSecondary {
      @include solid('secondary');
    }

    &.solidAttention {
      @include solid('attention');
    }

    &.outlinedPrimary {
      @include outlined('primary');
    }

    &.outlinedSecondary {
      @include outlined('secondary');
    }

    &.outlinedAttention {
      @include outlined('attention');
    }

    &.ghostPrimary {
      @include ghost('primary');
    }

    &.ghostSecondary {
      @include ghost('secondary');
    }

    &.ghostAttention {
      @include ghost('attention');
    }
  }
}

// --- We export the theme variables to add them to the component renderer
:export{
  themeVars: t.json-stringify($themeVars)
}
```

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

```markdown
# Column [#column]

`Column` defines the structure and behavior of individual table columns within a [`Table`](/components/Table) component. Each Column controls data binding, header display, sorting capabilities, sizing, and can contain any XMLUI components for rich cell content.

**Key features:**
- **Data binding**: Use `bindTo` to automatically display object properties
- **Component embedding**: Place any component inside `Column`: `Button`, `Text`, `Icon`, etc.
- **Interactive behavior**: Enable/disable sorting and column resizing
- **Layout control**: Set width using pixels, star sizing (`*`, `2*`), or proportional values
- **Column pinning**: Pin columns to left or right edges for sticky behavior

**Context variables available during execution:**

- `$cell`: The specific cell value for this column
- `$colIndex`: Zero-based column index
- `$item`: The complete data row object being rendered
- `$itemIndex`: Zero-based row index
- `$row`: The complete data row object being rendered (the same as `$item`).
- `$rowIndex`: Zero-based row index (the same as `$itemIndex`).

## Properties [#properties]

### `bindTo` [#bindto]

Indicates the name of the current row item's property, the value of which to lay out in the column. If this property is not defined, the column is not sortable.

```xmlui copy {3}
<App>
  <Table data='{[...]}'>
    <Column bindTo="name" />
  </Table>
</App>
```

```xmlui-pg name="Example: bindTo"
<App>
  <Table data='{
    [
      {
        id: 0,
        name: "Apples",
        quantity: 5,
        unit: "pieces",
        category: "fruits",
        key: 5,
      },
      {
        id: 1,
        name: "Bananas",
        quantity: 6,
        unit: "pieces",
        category: "fruits",
        key: 4,
      },
      {
        id: 2,
        name: "Carrots",
        quantity: 100,
        unit: "grams",
        category: "vegetables",
        key: 3,
      },
      {
        id: 3,
        name: "Spinach",
        quantity: 1,
        unit: "bunch",
        category: "vegetables",
        key: 2,
      },
      {
        id: 4,
        name: "Milk",
        quantity: 10,
        unit: "liter",
        category: "dairy",
        key: 1,
      },
      {
        id: 5,
        name: "Cheese",
        quantity: 200,
        unit: "grams",
        category: "dairy",
        key: 0,
      },
    ]}'>
    <Column bindTo="name" />
  </Table>
</App>
```

### `canResize` (default: true) [#canresize-default-true]

This property indicates whether the user can resize the column. If set to `true`, the column can be resized by dragging the column border. If set to `false`, the column cannot be resized. Double-clicking the column border resets to the original size.

### `canSort` (default: true) [#cansort-default-true]

This property sets whether the user can sort by a column by clicking on its header (`true`) or not (`false`). If the `bindTo` property is not defined, the column is not sortable.

Click on either the `Name` or the `Quantity` column headers to order the data by that attribute.

```xmlui copy /canSort/
<App>
  <Table data='{[...]}'>
    <Column canSort="true" bindTo="name" />
    <Column canSort="true" bindTo="quantity" />
    <Column canSort="false" bindTo="unit" />
  </Table>
</App>
```

```xmlui-pg name="Example: canSort"
<App>
  <Table data='{
  [
    {
      id: 0,
      name: "Apples",
      quantity: 5,
      unit: "pieces",
      category: "fruits",
      key: 5,
    },
    {
      id: 1,
      name: "Bananas",
      quantity: 6,
      unit: "pieces",
      category: "fruits",
      key: 4,
    },
    {
      id: 2,
      name: "Carrots",
      quantity: 100,
      unit: "grams",
      category: "vegetables",
      key: 3,
    },
    {
      id: 3,
      name: "Spinach",
      quantity: 1,
      unit: "bunch",
      category: "vegetables",
      key: 2,
    },
    {
      id: 4,
      name: "Milk",
      quantity: 10,
      unit: "liter",
      category: "dairy",
      key: 1,
    },
    {
      id: 5,
      name: "Cheese",
      quantity: 200,
      unit: "grams",
      category: "dairy",
      key: 0,
    },
  ]}'>
    <Column canSort="true" bindTo="name" />
    <Column canSort="true" bindTo="quantity" />
    <Column canSort="false" bindTo="unit" />
  </Table>
</App>
```

### `header` [#header]

This property defines a label for a particular column. If not set, the `bindTo` property value is used for the label.

```xmlui copy {3-4}
<App>
  <Table data='{[...]}'>
    <Column header="Food Name" bindTo="name" />
    <Column header="Food Quantity" bindTo="quantity" />
    <Column bindTo="unit" />
  </Table>
</App>
```

```xmlui-pg name="Example: header"
<App>
  <Table data='{
  [
    {
      id: 0,
      name: "Apples",
      quantity: 5,
      unit: "pieces",
      category: "fruits",
      key: 5,
    },
    {
      id: 1,
      name: "Bananas",
      quantity: 6,
      unit: "pieces",
      category: "fruits",
      key: 4,
    },
    {
      id: 2,
      name: "Carrots",
      quantity: 100,
      unit: "grams",
      category: "vegetables",
      key: 3,
    },
    {
      id: 3,
      name: "Spinach",
      quantity: 1,
      unit: "bunch",
      category: "vegetables",
      key: 2,
    },
    {
      id: 4,
      name: "Milk",
      quantity: 10,
      unit: "liter",
      category: "dairy",
      key: 1,
    },
    {
      id: 5,
      name: "Cheese",
      quantity: 200,
      unit: "grams",
      category: "dairy",
      key: 0,
    },
  ]}'>
    <Column header="Food Name" bindTo="name" />
    <Column header="Food Quantity" bindTo="quantity" />
    <Column bindTo="unit" />
  </Table>
</App>
```

### `maxWidth` [#maxwidth]

Indicates the maximum width a particular column can have. Same rules apply as with [width](#width).

### `minWidth` [#minwidth]

Indicates the minimum width a particular column can have. Same rules apply as with [width](#width).

### `pinTo` [#pinto]

This property allows the column to be pinned to the `left` (left-to-right writing style) or `right` (left-to-right writing style) edge of the table. If the writing style is right-to-left, the locations are switched. If this property is not set, the column is not pinned to any edge.

Available values: `left`, `right`

>[!WARNING]
> By default, the background color of table rows is transparent. When using the `pinTo` property, you should set the background to an explicit (non-transparent) color; otherwise, the scrolled cells will be visible under the pinned columns.

```xmlui copy /pinTo="left"/ /pinTo="right"/
<App>
  <Theme backgroundColor-row-Table="$color-surface-0">
    <Table data='{[...]}' height="100%">
      <Column bindTo="id" width="50px" pinTo="left" />
      <Column bindTo="name" width="500px" />
      <Column bindTo="quantity" width="300px" />
      <Column bindTo="unit" width="300px"/>
      <Column bindTo="category" width="100px" pinTo="right"/>
    </Table>
  </Theme>
</App>
```
Scroll the table contents horizontally to see how the pinned columns are displayed.

```xmlui-pg name="Example: pinTo"
<App>
  <Theme backgroundColor-row-Table="$color-surface-0">
  <Table data='{
  [
    {
      id: 0,
      name: "Apples",
      quantity: 5,
      unit: "pieces",
      category: "fruits",
      key: 5,
    },
    {
      id: 1,
      name: "Bananas",
      quantity: 6,
      unit: "pieces",
      category: "fruits",
      key: 4,
    },
    {
      id: 2,
      name: "Carrots",
      quantity: 100,
      unit: "grams",
      category: "vegetables",
      key: 3,
    },
    {
      id: 3,
      name: "Spinach",
      quantity: 1,
      unit: "bunch",
      category: "vegetables",
      key: 2,
    },
    {
      id: 4,
      name: "Milk",
      quantity: 10,
      unit: "liter",
      category: "dairy",
      key: 1,
    },
    {
      id: 5,
      name: "Cheese",
      quantity: 200,
      unit: "grams",
      category: "dairy",
      key: 0,
    },
  ]}'
      height="100%">
    <Column bindTo="id" width="50px" pinTo="left" />
    <Column bindTo="name" width="500px" />
    <Column bindTo="quantity" width="300px" />
    <Column bindTo="unit" width="300px"/>
    <Column bindTo="category" width="100px" pinTo="right"/>
  </Table>
  </Theme>
</App>
```

### `width` [#width]

This property defines the width of the column. You can use a numeric value, a pixel value (such as `100px`), or a star size value (such as `*`, `2*`, etc.). You will get an error if you use any other unit (or value).If not defined, the component will use a width according to the column values and the available space.

The following example sets the second column to an absolute size (size pixels), while the first and third columns have star sizes:

```xmlui copy {4}
<App>
  <Table data='{[...]}'>
    <Column bindTo="name" canResize="true" width="3*" />
    <Column bindTo="quantity" width="100px" minWidth="50px" maxWidth="500px" />
    <Column bindTo="unit" width="*" />
  </Table>
</App>
```

Check what happens when you resize table columns:

```xmlui-pg name="Example: width"
<App>
  <Table data='{
  [
    {
      id: 0,
      name: "Apples",
      quantity: 5,
      unit: "pieces",
      category: "fruits",
      key: 5,
    },
    {
      id: 1,
      name: "Bananas",
      quantity: 6,
      unit: "pieces",
      category: "fruits",
      key: 4,
    },
    {
      id: 2,
      name: "Carrots",
      quantity: 100,
      unit: "grams",
      category: "vegetables",
      key: 3,
    },
    {
      id: 3,
      name: "Spinach",
      quantity: 1,
      unit: "bunch",
      category: "vegetables",
      key: 2,
    },
    {
      id: 4,
      name: "Milk",
      quantity: 10,
      unit: "liter",
      category: "dairy",
      key: 1,
    },
    {
      id: 5,
      name: "Cheese",
      quantity: 200,
      unit: "grams",
      category: "dairy",
      key: 0,
    },
  ]}'>
    <Column bindTo="name" canResize="true" width="3*" />
    <Column bindTo="quantity" width="100px" minWidth="50px" maxWidth="500px" />
    <Column bindTo="unit" width="*" />
  </Table>
</App>
```

## Events [#events]

This component does not have any events.

## Exposed Methods [#exposed-methods]

This component does not expose any methods.

## Styling [#styling]

Styling is done via the [`Table` component](/components/Table).

```

--------------------------------------------------------------------------------
/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;
}

```

