This is page 12 of 140. Use http://codebase.md/xmlui-org/xmlui/xmlui/0.9.23.js?format=md&lines=false&page={x} to view the full context.

# Directory Structure

```
├── .changeset
│   └── config.json
├── .eslintrc.cjs
├── .github
│   ├── build-checklist.png
│   ├── ISSUE_TEMPLATE
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   └── workflows
│       ├── deploy-blog.yml
│       ├── deploy-docs-optimized.yml
│       ├── deploy-docs.yml
│       ├── prepare-versions.yml
│       ├── release-packages.yml
│       ├── run-all-tests.yml
│       └── run-smoke-tests.yml
├── .gitignore
├── .prettierrc.js
├── .vscode
│   ├── launch.json
│   └── settings.json
├── blog
│   ├── .gitignore
│   ├── .gitkeep
│   ├── CHANGELOG.md
│   ├── extensions.ts
│   ├── index.html
│   ├── index.ts
│   ├── layout-changes.md
│   ├── package.json
│   ├── public
│   │   ├── blog
│   │   │   ├── images
│   │   │   │   ├── blog-page-component.png
│   │   │   │   ├── blog-scrabble.png
│   │   │   │   ├── integrated-blog-search.png
│   │   │   │   └── lorem-ipsum.png
│   │   │   ├── lorem-ipsum.md
│   │   │   ├── newest-post.md
│   │   │   ├── older-post.md
│   │   │   └── welcome-to-the-xmlui-blog.md
│   │   ├── mockServiceWorker.js
│   │   ├── netlify.toml
│   │   ├── resources
│   │   │   ├── favicon.ico
│   │   │   ├── files
│   │   │   │   └── for-download
│   │   │   │       └── xmlui
│   │   │   │           └── xmlui-standalone.umd.js
│   │   │   ├── github.svg
│   │   │   ├── 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
│   │   │   ├── Debug.xmlui
│   │   │   ├── Headlines.xmlui
│   │   │   └── PageNotFound.xmlui
│   │   ├── config.ts
│   │   ├── Main.xmlui
│   │   └── themes
│   │       └── blog-theme.ts
│   └── tsconfig.json
├── CONTRIBUTING.md
├── docs
│   ├── .gitignore
│   ├── CHANGELOG.md
│   ├── ComponentRefLinks.txt
│   ├── content
│   │   ├── _meta.json
│   │   ├── components
│   │   │   ├── _meta.json
│   │   │   ├── _overview.md
│   │   │   ├── APICall.md
│   │   │   ├── App.md
│   │   │   ├── AppHeader.md
│   │   │   ├── AppState.md
│   │   │   ├── AutoComplete.md
│   │   │   ├── Avatar.md
│   │   │   ├── Backdrop.md
│   │   │   ├── Badge.md
│   │   │   ├── BarChart.md
│   │   │   ├── Bookmark.md
│   │   │   ├── Breakout.md
│   │   │   ├── Button.md
│   │   │   ├── Card.md
│   │   │   ├── Carousel.md
│   │   │   ├── ChangeListener.md
│   │   │   ├── Checkbox.md
│   │   │   ├── CHStack.md
│   │   │   ├── ColorPicker.md
│   │   │   ├── Column.md
│   │   │   ├── ContentSeparator.md
│   │   │   ├── CVStack.md
│   │   │   ├── DataSource.md
│   │   │   ├── DateInput.md
│   │   │   ├── DatePicker.md
│   │   │   ├── DonutChart.md
│   │   │   ├── DropdownMenu.md
│   │   │   ├── EmojiSelector.md
│   │   │   ├── ExpandableItem.md
│   │   │   ├── FileInput.md
│   │   │   ├── FileUploadDropZone.md
│   │   │   ├── FlowLayout.md
│   │   │   ├── Footer.md
│   │   │   ├── Form.md
│   │   │   ├── FormItem.md
│   │   │   ├── FormSection.md
│   │   │   ├── Fragment.md
│   │   │   ├── H1.md
│   │   │   ├── H2.md
│   │   │   ├── H3.md
│   │   │   ├── H4.md
│   │   │   ├── H5.md
│   │   │   ├── H6.md
│   │   │   ├── Heading.md
│   │   │   ├── HSplitter.md
│   │   │   ├── HStack.md
│   │   │   ├── Icon.md
│   │   │   ├── IFrame.md
│   │   │   ├── Image.md
│   │   │   ├── Items.md
│   │   │   ├── LabelList.md
│   │   │   ├── Legend.md
│   │   │   ├── LineChart.md
│   │   │   ├── Link.md
│   │   │   ├── List.md
│   │   │   ├── Logo.md
│   │   │   ├── Markdown.md
│   │   │   ├── MenuItem.md
│   │   │   ├── MenuSeparator.md
│   │   │   ├── ModalDialog.md
│   │   │   ├── NavGroup.md
│   │   │   ├── NavLink.md
│   │   │   ├── NavPanel.md
│   │   │   ├── NoResult.md
│   │   │   ├── NumberBox.md
│   │   │   ├── Option.md
│   │   │   ├── Page.md
│   │   │   ├── PageMetaTitle.md
│   │   │   ├── Pages.md
│   │   │   ├── Pagination.md
│   │   │   ├── PasswordInput.md
│   │   │   ├── PieChart.md
│   │   │   ├── ProgressBar.md
│   │   │   ├── Queue.md
│   │   │   ├── RadioGroup.md
│   │   │   ├── RealTimeAdapter.md
│   │   │   ├── Redirect.md
│   │   │   ├── Select.md
│   │   │   ├── Slider.md
│   │   │   ├── Slot.md
│   │   │   ├── SpaceFiller.md
│   │   │   ├── Spinner.md
│   │   │   ├── Splitter.md
│   │   │   ├── Stack.md
│   │   │   ├── StickyBox.md
│   │   │   ├── SubMenuItem.md
│   │   │   ├── Switch.md
│   │   │   ├── TabItem.md
│   │   │   ├── Table.md
│   │   │   ├── TableOfContents.md
│   │   │   ├── Tabs.md
│   │   │   ├── Text.md
│   │   │   ├── TextArea.md
│   │   │   ├── TextBox.md
│   │   │   ├── Theme.md
│   │   │   ├── TimeInput.md
│   │   │   ├── Timer.md
│   │   │   ├── ToneChangerButton.md
│   │   │   ├── ToneSwitch.md
│   │   │   ├── Tooltip.md
│   │   │   ├── Tree.md
│   │   │   ├── VSplitter.md
│   │   │   ├── VStack.md
│   │   │   ├── xmlui-animations
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   ├── Animation.md
│   │   │   │   ├── FadeAnimation.md
│   │   │   │   ├── FadeInAnimation.md
│   │   │   │   ├── FadeOutAnimation.md
│   │   │   │   ├── ScaleAnimation.md
│   │   │   │   └── SlideInAnimation.md
│   │   │   ├── xmlui-pdf
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   └── Pdf.md
│   │   │   ├── xmlui-spreadsheet
│   │   │   │   ├── _meta.json
│   │   │   │   ├── _overview.md
│   │   │   │   └── Spreadsheet.md
│   │   │   └── xmlui-website-blocks
│   │   │       ├── _meta.json
│   │   │       ├── _overview.md
│   │   │       ├── Carousel.md
│   │   │       ├── HelloMd.md
│   │   │       ├── HeroSection.md
│   │   │       └── ScrollToTop.md
│   │   └── extensions
│   │       ├── _meta.json
│   │       ├── xmlui-animations
│   │       │   ├── _meta.json
│   │       │   ├── _overview.md
│   │       │   ├── Animation.md
│   │       │   ├── FadeAnimation.md
│   │       │   ├── FadeInAnimation.md
│   │       │   ├── FadeOutAnimation.md
│   │       │   ├── ScaleAnimation.md
│   │       │   └── SlideInAnimation.md
│   │       └── xmlui-website-blocks
│   │           ├── _meta.json
│   │           ├── _overview.md
│   │           ├── Carousel.md
│   │           ├── HelloMd.md
│   │           ├── HeroSection.md
│   │           └── ScrollToTop.md
│   ├── extensions.ts
│   ├── index.html
│   ├── index.ts
│   ├── package.json
│   ├── public
│   │   ├── feed.rss
│   │   ├── mockServiceWorker.js
│   │   ├── pages
│   │   │   ├── _meta.json
│   │   │   ├── app-structure.md
│   │   │   ├── build-editor-component.md
│   │   │   ├── build-hello-world-component.md
│   │   │   ├── components-intro.md
│   │   │   ├── context-variables.md
│   │   │   ├── forms.md
│   │   │   ├── globals.md
│   │   │   ├── glossary.md
│   │   │   ├── helper-tags.md
│   │   │   ├── hosted-deployment.md
│   │   │   ├── howto
│   │   │   │   ├── assign-a-complex-json-literal-to-a-component-variable.md
│   │   │   │   ├── chain-a-refetch.md
│   │   │   │   ├── 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
│   ├── 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
│   │   └── tsconfig.json
│   ├── 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
│   │   ├── tsconfig.json
│   │   └── 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
│   │   └── tsconfig.json
│   ├── 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
│   │   └── tsconfig.json
│   ├── 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
│   │   └── tsconfig.json
│   ├── xmlui-playground
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   ├── src
│   │   │   ├── hooks
│   │   │   │   ├── usePlayground.ts
│   │   │   │   └── useToast.ts
│   │   │   ├── index.tsx
│   │   │   ├── playground
│   │   │   │   ├── Box.module.scss
│   │   │   │   ├── Box.tsx
│   │   │   │   ├── CodeSelector.tsx
│   │   │   │   ├── ConfirmationDialog.module.scss
│   │   │   │   ├── ConfirmationDialog.tsx
│   │   │   │   ├── Editor.tsx
│   │   │   │   ├── Header.module.scss
│   │   │   │   ├── Header.tsx
│   │   │   │   ├── Playground.tsx
│   │   │   │   ├── PlaygroundContent.module.scss
│   │   │   │   ├── PlaygroundContent.tsx
│   │   │   │   ├── PlaygroundNative.module.scss
│   │   │   │   ├── PlaygroundNative.tsx
│   │   │   │   ├── Preview.module.scss
│   │   │   │   ├── Preview.tsx
│   │   │   │   ├── Select.module.scss
│   │   │   │   ├── StandalonePlayground.tsx
│   │   │   │   ├── StandalonePlaygroundNative.module.scss
│   │   │   │   ├── StandalonePlaygroundNative.tsx
│   │   │   │   ├── ThemeSwitcher.module.scss
│   │   │   │   ├── ThemeSwitcher.tsx
│   │   │   │   ├── ToneSwitcher.tsx
│   │   │   │   ├── Tooltip.module.scss
│   │   │   │   ├── Tooltip.tsx
│   │   │   │   └── utils.ts
│   │   │   ├── providers
│   │   │   │   ├── Toast.module.scss
│   │   │   │   └── ToastProvider.tsx
│   │   │   ├── state
│   │   │   │   └── store.ts
│   │   │   ├── themes
│   │   │   │   └── theme.ts
│   │   │   └── utils
│   │   │       └── helpers.ts
│   │   └── tsconfig.json
│   ├── 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
│   │   └── tsconfig.json
│   ├── xmlui-spreadsheet
│   │   ├── .gitignore
│   │   ├── demo
│   │   │   └── Main.xmlui
│   │   ├── index.html
│   │   ├── index.ts
│   │   ├── meta
│   │   │   └── componentsMetadata.ts
│   │   ├── package.json
│   │   ├── src
│   │   │   ├── index.tsx
│   │   │   ├── Spreadsheet.tsx
│   │   │   └── SpreadsheetNative.tsx
│   │   └── tsconfig.json
│   └── 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.tsx
│       │   │   └── HeroSectionNative.tsx
│       │   ├── index.tsx
│       │   ├── ScrollToTop
│       │   │   ├── ScrollToTop.module.scss
│       │   │   ├── ScrollToTop.tsx
│       │   │   └── ScrollToTopNative.tsx
│       │   └── vite-env.d.ts
│       └── tsconfig.json
├── 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.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
    │   ├── containers.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
    │   ├── state-management.md
    │   ├── ud-components.md
    │   └── xmlui-repo.md
    ├── package.json
    ├── playwright.config.ts
    ├── scripts
    │   ├── coverage-only.js
    │   ├── e2e-test-summary.js
    │   ├── generate-docs
    │   │   ├── build-downloads-map.mjs
    │   │   ├── build-pages-map.mjs
    │   │   ├── components-config.json
    │   │   ├── configuration-management.mjs
    │   │   ├── constants.mjs
    │   │   ├── create-theme-files.mjs
    │   │   ├── DocsGenerator.mjs
    │   │   ├── error-handling.mjs
    │   │   ├── extensions-config.json
    │   │   ├── folders.mjs
    │   │   ├── generate-summary-files.mjs
    │   │   ├── get-docs.mjs
    │   │   ├── input-handler.mjs
    │   │   ├── logger.mjs
    │   │   ├── logging-standards.mjs
    │   │   ├── MetadataProcessor.mjs
    │   │   ├── pattern-utilities.mjs
    │   │   └── utils.mjs
    │   ├── get-langserver-metadata.mjs
    │   ├── inline-links.mjs
    │   └── README-e2e-summary.md
    ├── src
    │   ├── abstractions
    │   │   ├── _conventions.md
    │   │   ├── ActionDefs.ts
    │   │   ├── AppContextDefs.ts
    │   │   ├── ComponentDefs.ts
    │   │   ├── ContainerDefs.ts
    │   │   ├── ExtensionDefs.ts
    │   │   ├── FunctionDefs.ts
    │   │   ├── RendererDefs.ts
    │   │   ├── scripting
    │   │   │   ├── BlockScope.ts
    │   │   │   ├── Compilation.ts
    │   │   │   ├── LogicalThread.ts
    │   │   │   ├── LoopScope.ts
    │   │   │   ├── modules.ts
    │   │   │   ├── ScriptParserError.ts
    │   │   │   ├── Token.ts
    │   │   │   ├── TryScope.ts
    │   │   │   └── TryScopeExp.ts
    │   │   └── ThemingDefs.ts
    │   ├── components
    │   │   ├── _conventions.md
    │   │   ├── abstractions.ts
    │   │   ├── Accordion
    │   │   │   ├── Accordion.md
    │   │   │   ├── Accordion.module.scss
    │   │   │   ├── Accordion.spec.ts
    │   │   │   ├── Accordion.tsx
    │   │   │   ├── AccordionContext.tsx
    │   │   │   ├── AccordionItem.tsx
    │   │   │   ├── AccordionItemNative.tsx
    │   │   │   └── AccordionNative.tsx
    │   │   ├── Animation
    │   │   │   └── AnimationNative.tsx
    │   │   ├── APICall
    │   │   │   ├── APICall.md
    │   │   │   ├── APICall.spec.ts
    │   │   │   ├── APICall.tsx
    │   │   │   └── APICallNative.tsx
    │   │   ├── App
    │   │   │   ├── App.md
    │   │   │   ├── App.module.scss
    │   │   │   ├── App.spec.ts
    │   │   │   ├── App.tsx
    │   │   │   ├── AppLayoutContext.ts
    │   │   │   ├── AppNative.tsx
    │   │   │   ├── AppStateContext.ts
    │   │   │   ├── doc-resources
    │   │   │   │   ├── condensed-sticky.xmlui
    │   │   │   │   ├── condensed.xmlui
    │   │   │   │   ├── horizontal-sticky.xmlui
    │   │   │   │   ├── horizontal.xmlui
    │   │   │   │   ├── vertical-full-header.xmlui
    │   │   │   │   ├── vertical-sticky.xmlui
    │   │   │   │   └── vertical.xmlui
    │   │   │   ├── IndexerContext.ts
    │   │   │   ├── LinkInfoContext.ts
    │   │   │   ├── SearchContext.tsx
    │   │   │   ├── Sheet.module.scss
    │   │   │   └── Sheet.tsx
    │   │   ├── AppHeader
    │   │   │   ├── AppHeader.md
    │   │   │   ├── AppHeader.module.scss
    │   │   │   ├── AppHeader.spec.ts
    │   │   │   ├── AppHeader.tsx
    │   │   │   └── AppHeaderNative.tsx
    │   │   ├── AppState
    │   │   │   ├── AppState.md
    │   │   │   ├── AppState.spec.ts
    │   │   │   ├── AppState.tsx
    │   │   │   └── AppStateNative.tsx
    │   │   ├── AutoComplete
    │   │   │   ├── AutoComplete.md
    │   │   │   ├── AutoComplete.module.scss
    │   │   │   ├── AutoComplete.spec.ts
    │   │   │   ├── AutoComplete.tsx
    │   │   │   ├── AutoCompleteContext.tsx
    │   │   │   └── AutoCompleteNative.tsx
    │   │   ├── Avatar
    │   │   │   ├── Avatar.md
    │   │   │   ├── Avatar.module.scss
    │   │   │   ├── Avatar.spec.ts
    │   │   │   ├── Avatar.tsx
    │   │   │   └── AvatarNative.tsx
    │   │   ├── Backdrop
    │   │   │   ├── Backdrop.md
    │   │   │   ├── Backdrop.module.scss
    │   │   │   ├── Backdrop.spec.ts
    │   │   │   ├── Backdrop.tsx
    │   │   │   └── BackdropNative.tsx
    │   │   ├── Badge
    │   │   │   ├── Badge.md
    │   │   │   ├── Badge.module.scss
    │   │   │   ├── Badge.spec.ts
    │   │   │   ├── Badge.tsx
    │   │   │   └── BadgeNative.tsx
    │   │   ├── Bookmark
    │   │   │   ├── Bookmark.md
    │   │   │   ├── Bookmark.module.scss
    │   │   │   ├── Bookmark.spec.ts
    │   │   │   ├── Bookmark.tsx
    │   │   │   └── BookmarkNative.tsx
    │   │   ├── Breakout
    │   │   │   ├── Breakout.module.scss
    │   │   │   ├── Breakout.spec.ts
    │   │   │   ├── Breakout.tsx
    │   │   │   └── BreakoutNative.tsx
    │   │   ├── Button
    │   │   │   ├── Button-style.spec.ts
    │   │   │   ├── Button.md
    │   │   │   ├── Button.module.scss
    │   │   │   ├── Button.spec.ts
    │   │   │   ├── Button.tsx
    │   │   │   └── ButtonNative.tsx
    │   │   ├── Card
    │   │   │   ├── Card.md
    │   │   │   ├── Card.module.scss
    │   │   │   ├── Card.spec.ts
    │   │   │   ├── Card.tsx
    │   │   │   └── CardNative.tsx
    │   │   ├── Carousel
    │   │   │   ├── Carousel.md
    │   │   │   ├── Carousel.module.scss
    │   │   │   ├── Carousel.spec.ts
    │   │   │   ├── Carousel.tsx
    │   │   │   ├── CarouselContext.tsx
    │   │   │   ├── CarouselItem.tsx
    │   │   │   ├── CarouselItemNative.tsx
    │   │   │   └── CarouselNative.tsx
    │   │   ├── ChangeListener
    │   │   │   ├── ChangeListener.md
    │   │   │   ├── ChangeListener.spec.ts
    │   │   │   ├── ChangeListener.tsx
    │   │   │   └── ChangeListenerNative.tsx
    │   │   ├── chart-color-schemes.ts
    │   │   ├── Charts
    │   │   │   ├── AreaChart
    │   │   │   │   ├── AreaChart.md
    │   │   │   │   ├── AreaChart.spec.ts
    │   │   │   │   ├── AreaChart.tsx
    │   │   │   │   └── AreaChartNative.tsx
    │   │   │   ├── BarChart
    │   │   │   │   ├── BarChart.md
    │   │   │   │   ├── BarChart.module.scss
    │   │   │   │   ├── BarChart.spec.ts
    │   │   │   │   ├── BarChart.tsx
    │   │   │   │   └── BarChartNative.tsx
    │   │   │   ├── DonutChart
    │   │   │   │   ├── DonutChart.spec.ts
    │   │   │   │   └── DonutChart.tsx
    │   │   │   ├── LabelList
    │   │   │   │   ├── LabelList.spec.ts
    │   │   │   │   ├── LabelList.tsx
    │   │   │   │   ├── LabelListNative.module.scss
    │   │   │   │   └── LabelListNative.tsx
    │   │   │   ├── Legend
    │   │   │   │   ├── Legend.spec.ts
    │   │   │   │   ├── Legend.tsx
    │   │   │   │   └── LegendNative.tsx
    │   │   │   ├── LineChart
    │   │   │   │   ├── LineChart.md
    │   │   │   │   ├── LineChart.module.scss
    │   │   │   │   ├── LineChart.spec.ts
    │   │   │   │   ├── LineChart.tsx
    │   │   │   │   └── LineChartNative.tsx
    │   │   │   ├── PieChart
    │   │   │   │   ├── PieChart.md
    │   │   │   │   ├── PieChart.spec.ts
    │   │   │   │   ├── PieChart.tsx
    │   │   │   │   ├── PieChartNative.module.scss
    │   │   │   │   └── PieChartNative.tsx
    │   │   │   ├── RadarChart
    │   │   │   │   ├── RadarChart.md
    │   │   │   │   ├── RadarChart.spec.ts
    │   │   │   │   ├── RadarChart.tsx
    │   │   │   │   └── RadarChartNative.tsx
    │   │   │   ├── Tooltip
    │   │   │   │   ├── TooltipContent.module.scss
    │   │   │   │   ├── TooltipContent.spec.ts
    │   │   │   │   └── TooltipContent.tsx
    │   │   │   └── utils
    │   │   │       ├── abstractions.ts
    │   │   │       └── ChartProvider.tsx
    │   │   ├── Checkbox
    │   │   │   ├── Checkbox.md
    │   │   │   ├── Checkbox.spec.ts
    │   │   │   └── Checkbox.tsx
    │   │   ├── CodeBlock
    │   │   │   ├── CodeBlock.module.scss
    │   │   │   ├── CodeBlock.spec.ts
    │   │   │   ├── CodeBlock.tsx
    │   │   │   ├── CodeBlockNative.tsx
    │   │   │   └── highlight-code.ts
    │   │   ├── collectedComponentMetadata.ts
    │   │   ├── ColorPicker
    │   │   │   ├── ColorPicker.md
    │   │   │   ├── ColorPicker.module.scss
    │   │   │   ├── ColorPicker.spec.ts
    │   │   │   ├── ColorPicker.tsx
    │   │   │   └── ColorPickerNative.tsx
    │   │   ├── Column
    │   │   │   ├── Column.md
    │   │   │   ├── Column.tsx
    │   │   │   ├── ColumnNative.tsx
    │   │   │   ├── doc-resources
    │   │   │   │   └── list-component-data.js
    │   │   │   └── TableContext.tsx
    │   │   ├── component-utils.ts
    │   │   ├── ComponentProvider.tsx
    │   │   ├── ComponentRegistryContext.tsx
    │   │   ├── container-helpers.tsx
    │   │   ├── ContentSeparator
    │   │   │   ├── ContentSeparator.md
    │   │   │   ├── ContentSeparator.module.scss
    │   │   │   ├── ContentSeparator.spec.ts
    │   │   │   ├── ContentSeparator.tsx
    │   │   │   └── ContentSeparatorNative.tsx
    │   │   ├── DataSource
    │   │   │   ├── DataSource.md
    │   │   │   └── DataSource.tsx
    │   │   ├── DateInput
    │   │   │   ├── DateInput.md
    │   │   │   ├── DateInput.module.scss
    │   │   │   ├── DateInput.spec.ts
    │   │   │   ├── DateInput.tsx
    │   │   │   └── DateInputNative.tsx
    │   │   ├── DatePicker
    │   │   │   ├── DatePicker.md
    │   │   │   ├── DatePicker.module.scss
    │   │   │   ├── DatePicker.spec.ts
    │   │   │   ├── DatePicker.tsx
    │   │   │   └── DatePickerNative.tsx
    │   │   ├── DropdownMenu
    │   │   │   ├── DropdownMenu.md
    │   │   │   ├── DropdownMenu.module.scss
    │   │   │   ├── DropdownMenu.spec.ts
    │   │   │   ├── DropdownMenu.tsx
    │   │   │   ├── DropdownMenuNative.tsx
    │   │   │   ├── MenuItem.md
    │   │   │   └── SubMenuItem.md
    │   │   ├── EmojiSelector
    │   │   │   ├── EmojiSelector.md
    │   │   │   ├── EmojiSelector.spec.ts
    │   │   │   ├── EmojiSelector.tsx
    │   │   │   └── EmojiSelectorNative.tsx
    │   │   ├── ExpandableItem
    │   │   │   ├── ExpandableItem.module.scss
    │   │   │   ├── ExpandableItem.spec.ts
    │   │   │   ├── ExpandableItem.tsx
    │   │   │   └── ExpandableItemNative.tsx
    │   │   ├── FileInput
    │   │   │   ├── FileInput.md
    │   │   │   ├── FileInput.module.scss
    │   │   │   ├── FileInput.spec.ts
    │   │   │   ├── FileInput.tsx
    │   │   │   └── FileInputNative.tsx
    │   │   ├── FileUploadDropZone
    │   │   │   ├── FileUploadDropZone.md
    │   │   │   ├── FileUploadDropZone.module.scss
    │   │   │   ├── FileUploadDropZone.spec.ts
    │   │   │   ├── FileUploadDropZone.tsx
    │   │   │   └── FileUploadDropZoneNative.tsx
    │   │   ├── FlowLayout
    │   │   │   ├── FlowLayout.md
    │   │   │   ├── FlowLayout.module.scss
    │   │   │   ├── FlowLayout.spec.ts
    │   │   │   ├── FlowLayout.spec.ts-snapshots
    │   │   │   │   └── Edge-cases-boxShadow-is-not-clipped-1-non-smoke-darwin.png
    │   │   │   ├── FlowLayout.tsx
    │   │   │   └── FlowLayoutNative.tsx
    │   │   ├── Footer
    │   │   │   ├── Footer.md
    │   │   │   ├── Footer.module.scss
    │   │   │   ├── Footer.spec.ts
    │   │   │   ├── Footer.tsx
    │   │   │   └── FooterNative.tsx
    │   │   ├── Form
    │   │   │   ├── Form.md
    │   │   │   ├── Form.module.scss
    │   │   │   ├── Form.spec.ts
    │   │   │   ├── Form.tsx
    │   │   │   ├── formActions.ts
    │   │   │   ├── FormContext.ts
    │   │   │   └── FormNative.tsx
    │   │   ├── FormItem
    │   │   │   ├── FormItem.md
    │   │   │   ├── FormItem.module.scss
    │   │   │   ├── FormItem.spec.ts
    │   │   │   ├── FormItem.tsx
    │   │   │   ├── FormItemNative.tsx
    │   │   │   ├── HelperText.module.scss
    │   │   │   ├── HelperText.tsx
    │   │   │   ├── ItemWithLabel.tsx
    │   │   │   └── Validations.ts
    │   │   ├── FormSection
    │   │   │   ├── FormSection.md
    │   │   │   ├── FormSection.ts
    │   │   │   └── FormSection.xmlui
    │   │   ├── Fragment
    │   │   │   ├── Fragment.spec.ts
    │   │   │   └── Fragment.tsx
    │   │   ├── Heading
    │   │   │   ├── abstractions.ts
    │   │   │   ├── H1.md
    │   │   │   ├── H1.spec.ts
    │   │   │   ├── H2.md
    │   │   │   ├── H2.spec.ts
    │   │   │   ├── H3.md
    │   │   │   ├── H3.spec.ts
    │   │   │   ├── H4.md
    │   │   │   ├── H4.spec.ts
    │   │   │   ├── H5.md
    │   │   │   ├── H5.spec.ts
    │   │   │   ├── H6.md
    │   │   │   ├── H6.spec.ts
    │   │   │   ├── Heading.md
    │   │   │   ├── Heading.module.scss
    │   │   │   ├── Heading.spec.ts
    │   │   │   ├── Heading.tsx
    │   │   │   └── HeadingNative.tsx
    │   │   ├── HoverCard
    │   │   │   ├── HoverCard.tsx
    │   │   │   └── HovercardNative.tsx
    │   │   ├── HtmlTags
    │   │   │   ├── HtmlTags.module.scss
    │   │   │   ├── HtmlTags.spec.ts
    │   │   │   └── HtmlTags.tsx
    │   │   ├── Icon
    │   │   │   ├── AdmonitionDanger.tsx
    │   │   │   ├── AdmonitionInfo.tsx
    │   │   │   ├── AdmonitionNote.tsx
    │   │   │   ├── AdmonitionTip.tsx
    │   │   │   ├── AdmonitionWarning.tsx
    │   │   │   ├── ApiIcon.tsx
    │   │   │   ├── ArrowDropDown.module.scss
    │   │   │   ├── ArrowDropDown.tsx
    │   │   │   ├── ArrowDropUp.module.scss
    │   │   │   ├── ArrowDropUp.tsx
    │   │   │   ├── ArrowLeft.module.scss
    │   │   │   ├── ArrowLeft.tsx
    │   │   │   ├── ArrowRight.module.scss
    │   │   │   ├── ArrowRight.tsx
    │   │   │   ├── Attach.tsx
    │   │   │   ├── Binding.module.scss
    │   │   │   ├── Binding.tsx
    │   │   │   ├── BoardIcon.tsx
    │   │   │   ├── BoxIcon.tsx
    │   │   │   ├── CheckIcon.tsx
    │   │   │   ├── ChevronDownIcon.tsx
    │   │   │   ├── ChevronLeft.tsx
    │   │   │   ├── ChevronRight.tsx
    │   │   │   ├── ChevronUpIcon.tsx
    │   │   │   ├── CodeFileIcon.tsx
    │   │   │   ├── CodeSandbox.tsx
    │   │   │   ├── CompactListIcon.tsx
    │   │   │   ├── ContentCopyIcon.tsx
    │   │   │   ├── DarkToLightIcon.tsx
    │   │   │   ├── DatabaseIcon.module.scss
    │   │   │   ├── DatabaseIcon.tsx
    │   │   │   ├── DocFileIcon.tsx
    │   │   │   ├── DocIcon.tsx
    │   │   │   ├── DotMenuHorizontalIcon.tsx
    │   │   │   ├── DotMenuIcon.tsx
    │   │   │   ├── EmailIcon.tsx
    │   │   │   ├── EmptyFolderIcon.tsx
    │   │   │   ├── ErrorIcon.tsx
    │   │   │   ├── ExpressionIcon.tsx
    │   │   │   ├── FillPlusCricleIcon.tsx
    │   │   │   ├── FilterIcon.tsx
    │   │   │   ├── FolderIcon.tsx
    │   │   │   ├── GlobeIcon.tsx
    │   │   │   ├── HomeIcon.tsx
    │   │   │   ├── HyperLinkIcon.tsx
    │   │   │   ├── Icon.md
    │   │   │   ├── Icon.module.scss
    │   │   │   ├── Icon.spec.ts
    │   │   │   ├── Icon.tsx
    │   │   │   ├── IconNative.tsx
    │   │   │   ├── ImageFileIcon.tsx
    │   │   │   ├── Inspect.tsx
    │   │   │   ├── LightToDark.tsx
    │   │   │   ├── LinkIcon.tsx
    │   │   │   ├── ListIcon.tsx
    │   │   │   ├── LooseListIcon.tsx
    │   │   │   ├── MoonIcon.tsx
    │   │   │   ├── MoreOptionsIcon.tsx
    │   │   │   ├── NoSortIcon.tsx
    │   │   │   ├── PDFIcon.tsx
    │   │   │   ├── PenIcon.tsx
    │   │   │   ├── PhoneIcon.tsx
    │   │   │   ├── PhotoIcon.tsx
    │   │   │   ├── PlusIcon.tsx
    │   │   │   ├── SearchIcon.tsx
    │   │   │   ├── ShareIcon.tsx
    │   │   │   ├── SortAscendingIcon.tsx
    │   │   │   ├── SortDescendingIcon.tsx
    │   │   │   ├── StarsIcon.tsx
    │   │   │   ├── SunIcon.tsx
    │   │   │   ├── svg
    │   │   │   │   ├── admonition_danger.svg
    │   │   │   │   ├── admonition_info.svg
    │   │   │   │   ├── admonition_note.svg
    │   │   │   │   ├── admonition_tip.svg
    │   │   │   │   ├── admonition_warning.svg
    │   │   │   │   ├── api.svg
    │   │   │   │   ├── arrow-dropdown.svg
    │   │   │   │   ├── arrow-left.svg
    │   │   │   │   ├── arrow-right.svg
    │   │   │   │   ├── arrow-up.svg
    │   │   │   │   ├── attach.svg
    │   │   │   │   ├── binding.svg
    │   │   │   │   ├── box.svg
    │   │   │   │   ├── bulb.svg
    │   │   │   │   ├── code-file.svg
    │   │   │   │   ├── code-sandbox.svg
    │   │   │   │   ├── dark_to_light.svg
    │   │   │   │   ├── database.svg
    │   │   │   │   ├── doc.svg
    │   │   │   │   ├── empty-folder.svg
    │   │   │   │   ├── expression.svg
    │   │   │   │   ├── eye-closed.svg
    │   │   │   │   ├── eye-dark.svg
    │   │   │   │   ├── eye.svg
    │   │   │   │   ├── file-text.svg
    │   │   │   │   ├── filter.svg
    │   │   │   │   ├── folder.svg
    │   │   │   │   ├── img.svg
    │   │   │   │   ├── inspect.svg
    │   │   │   │   ├── light_to_dark.svg
    │   │   │   │   ├── moon.svg
    │   │   │   │   ├── pdf.svg
    │   │   │   │   ├── photo.svg
    │   │   │   │   ├── share.svg
    │   │   │   │   ├── stars.svg
    │   │   │   │   ├── sun.svg
    │   │   │   │   ├── trending-down.svg
    │   │   │   │   ├── trending-level.svg
    │   │   │   │   ├── trending-up.svg
    │   │   │   │   ├── txt.svg
    │   │   │   │   ├── unknown-file.svg
    │   │   │   │   ├── unlink.svg
    │   │   │   │   └── xls.svg
    │   │   │   ├── TableDeleteColumnIcon.tsx
    │   │   │   ├── TableDeleteRowIcon.tsx
    │   │   │   ├── TableInsertColumnIcon.tsx
    │   │   │   ├── TableInsertRowIcon.tsx
    │   │   │   ├── TrashIcon.tsx
    │   │   │   ├── TrendingDownIcon.tsx
    │   │   │   ├── TrendingLevelIcon.tsx
    │   │   │   ├── TrendingUpIcon.tsx
    │   │   │   ├── TxtIcon.tsx
    │   │   │   ├── UnknownFileIcon.tsx
    │   │   │   ├── UnlinkIcon.tsx
    │   │   │   ├── UserIcon.tsx
    │   │   │   ├── WarningIcon.tsx
    │   │   │   └── XlsIcon.tsx
    │   │   ├── IconProvider.tsx
    │   │   ├── IconRegistryContext.tsx
    │   │   ├── IFrame
    │   │   │   ├── IFrame.md
    │   │   │   ├── IFrame.module.scss
    │   │   │   ├── IFrame.spec.ts
    │   │   │   ├── IFrame.tsx
    │   │   │   └── IFrameNative.tsx
    │   │   ├── Image
    │   │   │   ├── Image.md
    │   │   │   ├── Image.module.scss
    │   │   │   ├── Image.spec.ts
    │   │   │   ├── Image.tsx
    │   │   │   └── ImageNative.tsx
    │   │   ├── Input
    │   │   │   ├── index.ts
    │   │   │   ├── InputAdornment.module.scss
    │   │   │   ├── InputAdornment.tsx
    │   │   │   ├── InputDivider.module.scss
    │   │   │   ├── InputDivider.tsx
    │   │   │   ├── InputLabel.module.scss
    │   │   │   ├── InputLabel.tsx
    │   │   │   ├── PartialInput.module.scss
    │   │   │   └── PartialInput.tsx
    │   │   ├── InspectButton
    │   │   │   ├── InspectButton.module.scss
    │   │   │   └── InspectButton.tsx
    │   │   ├── Items
    │   │   │   ├── Items.md
    │   │   │   ├── Items.spec.ts
    │   │   │   ├── Items.tsx
    │   │   │   └── ItemsNative.tsx
    │   │   ├── Link
    │   │   │   ├── Link.md
    │   │   │   ├── Link.module.scss
    │   │   │   ├── Link.spec.ts
    │   │   │   ├── Link.tsx
    │   │   │   └── LinkNative.tsx
    │   │   ├── List
    │   │   │   ├── doc-resources
    │   │   │   │   └── list-component-data.js
    │   │   │   ├── List.md
    │   │   │   ├── List.module.scss
    │   │   │   ├── List.spec.ts
    │   │   │   ├── List.tsx
    │   │   │   └── ListNative.tsx
    │   │   ├── Logo
    │   │   │   ├── doc-resources
    │   │   │   │   └── xmlui-logo.svg
    │   │   │   ├── Logo.md
    │   │   │   ├── Logo.tsx
    │   │   │   └── LogoNative.tsx
    │   │   ├── Markdown
    │   │   │   ├── CodeText.module.scss
    │   │   │   ├── CodeText.tsx
    │   │   │   ├── Markdown.md
    │   │   │   ├── Markdown.module.scss
    │   │   │   ├── Markdown.spec.ts
    │   │   │   ├── Markdown.tsx
    │   │   │   ├── MarkdownNative.tsx
    │   │   │   ├── parse-binding-expr.ts
    │   │   │   └── utils.ts
    │   │   ├── metadata-helpers.ts
    │   │   ├── ModalDialog
    │   │   │   ├── ConfirmationModalContextProvider.tsx
    │   │   │   ├── Dialog.module.scss
    │   │   │   ├── Dialog.tsx
    │   │   │   ├── ModalDialog.md
    │   │   │   ├── ModalDialog.module.scss
    │   │   │   ├── ModalDialog.spec.ts
    │   │   │   ├── ModalDialog.tsx
    │   │   │   ├── ModalDialogNative.tsx
    │   │   │   └── ModalVisibilityContext.tsx
    │   │   ├── NavGroup
    │   │   │   ├── NavGroup.md
    │   │   │   ├── NavGroup.module.scss
    │   │   │   ├── NavGroup.spec.ts
    │   │   │   ├── NavGroup.tsx
    │   │   │   ├── NavGroupContext.ts
    │   │   │   └── NavGroupNative.tsx
    │   │   ├── NavLink
    │   │   │   ├── NavLink.md
    │   │   │   ├── NavLink.module.scss
    │   │   │   ├── NavLink.spec.ts
    │   │   │   ├── NavLink.tsx
    │   │   │   └── NavLinkNative.tsx
    │   │   ├── NavPanel
    │   │   │   ├── NavPanel.md
    │   │   │   ├── NavPanel.module.scss
    │   │   │   ├── NavPanel.spec.ts
    │   │   │   ├── NavPanel.tsx
    │   │   │   └── NavPanelNative.tsx
    │   │   ├── NestedApp
    │   │   │   ├── AppWithCodeView.module.scss
    │   │   │   ├── AppWithCodeView.tsx
    │   │   │   ├── AppWithCodeViewNative.tsx
    │   │   │   ├── defaultProps.tsx
    │   │   │   ├── logo.svg
    │   │   │   ├── NestedApp.module.scss
    │   │   │   ├── NestedApp.tsx
    │   │   │   ├── NestedAppNative.tsx
    │   │   │   ├── Tooltip.module.scss
    │   │   │   ├── Tooltip.tsx
    │   │   │   └── utils.ts
    │   │   ├── NoResult
    │   │   │   ├── NoResult.md
    │   │   │   ├── NoResult.module.scss
    │   │   │   ├── NoResult.spec.ts
    │   │   │   ├── NoResult.tsx
    │   │   │   └── NoResultNative.tsx
    │   │   ├── NumberBox
    │   │   │   ├── numberbox-abstractions.ts
    │   │   │   ├── NumberBox.md
    │   │   │   ├── NumberBox.module.scss
    │   │   │   ├── NumberBox.spec.ts
    │   │   │   ├── NumberBox.tsx
    │   │   │   └── NumberBoxNative.tsx
    │   │   ├── Option
    │   │   │   ├── Option.md
    │   │   │   ├── Option.spec.ts
    │   │   │   ├── Option.tsx
    │   │   │   ├── OptionNative.tsx
    │   │   │   └── OptionTypeProvider.tsx
    │   │   ├── PageMetaTitle
    │   │   │   ├── PageMetaTilteNative.tsx
    │   │   │   ├── PageMetaTitle.md
    │   │   │   ├── PageMetaTitle.spec.ts
    │   │   │   └── PageMetaTitle.tsx
    │   │   ├── Pages
    │   │   │   ├── Page.md
    │   │   │   ├── Pages.md
    │   │   │   ├── Pages.module.scss
    │   │   │   ├── Pages.tsx
    │   │   │   └── PagesNative.tsx
    │   │   ├── Pagination
    │   │   │   ├── Pagination.md
    │   │   │   ├── Pagination.module.scss
    │   │   │   ├── Pagination.spec.ts
    │   │   │   ├── Pagination.tsx
    │   │   │   └── PaginationNative.tsx
    │   │   ├── PositionedContainer
    │   │   │   ├── PositionedContainer.module.scss
    │   │   │   ├── PositionedContainer.tsx
    │   │   │   └── PositionedContainerNative.tsx
    │   │   ├── ProfileMenu
    │   │   │   ├── ProfileMenu.module.scss
    │   │   │   └── ProfileMenu.tsx
    │   │   ├── ProgressBar
    │   │   │   ├── ProgressBar.md
    │   │   │   ├── ProgressBar.module.scss
    │   │   │   ├── ProgressBar.spec.ts
    │   │   │   ├── ProgressBar.tsx
    │   │   │   └── ProgressBarNative.tsx
    │   │   ├── Queue
    │   │   │   ├── Queue.md
    │   │   │   ├── Queue.spec.ts
    │   │   │   ├── Queue.tsx
    │   │   │   ├── queueActions.ts
    │   │   │   └── QueueNative.tsx
    │   │   ├── RadioGroup
    │   │   │   ├── RadioGroup.md
    │   │   │   ├── RadioGroup.module.scss
    │   │   │   ├── RadioGroup.spec.ts
    │   │   │   ├── RadioGroup.tsx
    │   │   │   ├── RadioGroupNative.tsx
    │   │   │   ├── RadioItem.tsx
    │   │   │   └── RadioItemNative.tsx
    │   │   ├── RealTimeAdapter
    │   │   │   ├── RealTimeAdapter.tsx
    │   │   │   └── RealTimeAdapterNative.tsx
    │   │   ├── Redirect
    │   │   │   ├── Redirect.md
    │   │   │   ├── Redirect.spec.ts
    │   │   │   └── Redirect.tsx
    │   │   ├── ResponsiveBar
    │   │   │   ├── README.md
    │   │   │   ├── ResponsiveBar.md
    │   │   │   ├── ResponsiveBar.module.scss
    │   │   │   ├── ResponsiveBar.spec.ts
    │   │   │   ├── ResponsiveBar.tsx
    │   │   │   └── ResponsiveBarNative.tsx
    │   │   ├── Select
    │   │   │   ├── HiddenOption.tsx
    │   │   │   ├── MultiSelectOption.tsx
    │   │   │   ├── OptionContext.ts
    │   │   │   ├── Select.md
    │   │   │   ├── Select.module.scss
    │   │   │   ├── Select.spec.ts
    │   │   │   ├── Select.tsx
    │   │   │   ├── SelectContext.tsx
    │   │   │   ├── SelectNative.tsx
    │   │   │   ├── SelectOption.tsx
    │   │   │   └── SimpleSelect.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
    │   │   │   ├── 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.mjs
    │   ├── 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
    │   │   │   ├── ModalDialogDriver.ts
    │   │   │   ├── NumberBoxDriver.ts
    │   │   │   ├── TextBoxDriver.ts
    │   │   │   ├── TimeInputDriver.ts
    │   │   │   ├── TimerDriver.ts
    │   │   │   └── TreeDriver.ts
    │   │   ├── fixtures.ts
    │   │   ├── infrastructure
    │   │   │   ├── index.html
    │   │   │   ├── main.tsx
    │   │   │   ├── public
    │   │   │   │   ├── mockServiceWorker.js
    │   │   │   │   ├── resources
    │   │   │   │   │   ├── bell.svg
    │   │   │   │   │   ├── box.svg
    │   │   │   │   │   ├── doc.svg
    │   │   │   │   │   ├── eye.svg
    │   │   │   │   │   ├── flower-640x480.jpg
    │   │   │   │   │   ├── sun.svg
    │   │   │   │   │   ├── test-image-100x100.jpg
    │   │   │   │   │   └── txt.svg
    │   │   │   │   └── serve.json
    │   │   │   └── TestBed.tsx
    │   │   └── themed-app-test-helpers.ts
    │   └── vite-env.d.ts
    ├── tests
    │   ├── components
    │   │   ├── CodeBlock
    │   │   │   └── hightlight-code.test.ts
    │   │   ├── playground-pattern.test.ts
    │   │   └── Tree
    │   │       └── Tree-states.test.ts
    │   ├── components-core
    │   │   ├── abstractions
    │   │   │   └── treeAbstractions.test.ts
    │   │   ├── container
    │   │   │   └── buildProxy.test.ts
    │   │   ├── interception
    │   │   │   ├── orderBy.test.ts
    │   │   │   ├── ReadOnlyCollection.test.ts
    │   │   │   └── request-param-converter.test.ts
    │   │   ├── scripts-runner
    │   │   │   ├── AttributeValueParser.test.ts
    │   │   │   ├── eval-tree-arrow-async.test.ts
    │   │   │   ├── eval-tree-arrow.test.ts
    │   │   │   ├── eval-tree-func-decl-async.test.ts
    │   │   │   ├── eval-tree-func-decl.test.ts
    │   │   │   ├── eval-tree-pre-post.test.ts
    │   │   │   ├── eval-tree-regression.test.ts
    │   │   │   ├── eval-tree.test.ts
    │   │   │   ├── function-proxy.test.ts
    │   │   │   ├── parser-regression.test.ts
    │   │   │   ├── process-event.test.ts
    │   │   │   ├── process-function.test.ts
    │   │   │   ├── process-implicit-context.test.ts
    │   │   │   ├── process-statement-asgn.test.ts
    │   │   │   ├── process-statement-destruct.test.ts
    │   │   │   ├── process-statement-regs.test.ts
    │   │   │   ├── process-statement-sync.test.ts
    │   │   │   ├── process-statement.test.ts
    │   │   │   ├── process-switch-sync.test.ts
    │   │   │   ├── process-switch.test.ts
    │   │   │   ├── process-try-sync.test.ts
    │   │   │   ├── process-try.test.ts
    │   │   │   └── test-helpers.ts
    │   │   ├── test-metadata-handler.ts
    │   │   ├── theming
    │   │   │   ├── border-segments.test.ts
    │   │   │   ├── component-layout.resolver.test.ts
    │   │   │   ├── layout-property-parser.test.ts
    │   │   │   ├── layout-resolver.test.ts
    │   │   │   ├── layout-resolver2.test.ts
    │   │   │   ├── layout-vp-override.test.ts
    │   │   │   └── padding-segments.test.ts
    │   │   └── utils
    │   │       ├── date-utils.test.ts
    │   │       ├── format-human-elapsed-time.test.ts
    │   │       └── LruCache.test.ts
    │   ├── language-server
    │   │   ├── completion.test.ts
    │   │   ├── format.test.ts
    │   │   ├── hover.test.ts
    │   │   └── mockData.ts
    │   └── parsers
    │       ├── common
    │       │   └── input-stream.test.ts
    │       ├── markdown
    │       │   └── parse-binding-expression.test.ts
    │       ├── parameter-parser.test.ts
    │       ├── paremeter-parser.test.ts
    │       ├── scripting
    │       │   ├── eval-tree-arrow.test.ts
    │       │   ├── eval-tree-pre-post.test.ts
    │       │   ├── eval-tree.test.ts
    │       │   ├── function-proxy.test.ts
    │       │   ├── lexer-literals.test.ts
    │       │   ├── lexer-misc.test.ts
    │       │   ├── module-parse.test.ts
    │       │   ├── parser-arrow.test.ts
    │       │   ├── parser-assignments.test.ts
    │       │   ├── parser-binary.test.ts
    │       │   ├── parser-destructuring.test.ts
    │       │   ├── parser-errors.test.ts
    │       │   ├── parser-expressions.test.ts
    │       │   ├── parser-function.test.ts
    │       │   ├── parser-literals.test.ts
    │       │   ├── parser-primary.test.ts
    │       │   ├── parser-regex.test.ts
    │       │   ├── parser-statements.test.ts
    │       │   ├── parser-unary.test.ts
    │       │   ├── process-event.test.ts
    │       │   ├── process-implicit-context.test.ts
    │       │   ├── process-statement-asgn.test.ts
    │       │   ├── process-statement-destruct.test.ts
    │       │   ├── process-statement-regs.test.ts
    │       │   ├── process-statement-sync.test.ts
    │       │   ├── process-statement.test.ts
    │       │   ├── process-switch-sync.test.ts
    │       │   ├── process-switch.test.ts
    │       │   ├── process-try-sync.test.ts
    │       │   ├── process-try.test.ts
    │       │   ├── simplify-expression.test.ts
    │       │   ├── statement-hooks.test.ts
    │       │   └── test-helpers.ts
    │       ├── style-parser
    │       │   ├── generateHvarChain.test.ts
    │       │   ├── parseHVar.test.ts
    │       │   ├── parser.test.ts
    │       │   └── tokens.test.ts
    │       └── xmlui
    │           ├── lint.test.ts
    │           ├── parser.test.ts
    │           ├── scanner.test.ts
    │           ├── transform.attr.test.ts
    │           ├── transform.circular.test.ts
    │           ├── transform.element.test.ts
    │           ├── transform.errors.test.ts
    │           ├── transform.escape.test.ts
    │           ├── transform.regression.test.ts
    │           ├── transform.script.test.ts
    │           ├── transform.test.ts
    │           └── xmlui.ts
    ├── tests-e2e
    │   ├── api-bound-component-regression.spec.ts
    │   ├── api-call-as-extracted-component.spec.ts
    │   ├── assign-to-object-or-array-regression.spec.ts
    │   ├── binding-regression.spec.ts
    │   ├── children-as-template-context-vars.spec.ts
    │   ├── compound-component.spec.ts
    │   ├── context-vars-regression.spec.ts
    │   ├── data-bindings.spec.ts
    │   ├── datasource-and-api-usage-in-var.spec.ts
    │   ├── datasource-direct-binding.spec.ts
    │   ├── datasource-onLoaded-regression.spec.ts
    │   ├── modify-array-item-regression.spec.ts
    │   ├── namespaces.spec.ts
    │   ├── push-to-array-regression.spec.ts
    │   ├── screen-breakpoints.spec.ts
    │   ├── scripting.spec.ts
    │   ├── state-scope-in-pages.spec.ts
    │   └── state-var-scopes.spec.ts
    ├── tsconfig.bin.json
    ├── tsconfig.json
    ├── tsconfig.node.json
    ├── vite.config.ts
    └── vitest.config.ts
```

# Files

--------------------------------------------------------------------------------
/xmlui/tests/parsers/scripting/parser-primary.test.ts:
--------------------------------------------------------------------------------

```typescript
import { describe, expect, it } from "vitest";

import { Parser } from "../../../src/parsers/scripting/Parser";
import {
  Identifier,
  T_BINARY_EXPRESSION,
  T_CALCULATED_MEMBER_ACCESS_EXPRESSION,
  T_CONDITIONAL_EXPRESSION,
  T_FUNCTION_INVOCATION_EXPRESSION,
  T_IDENTIFIER,
  T_LITERAL,
  T_MEMBER_ACCESS_EXPRESSION,
  T_SEQUENCE_EXPRESSION,
  T_UNARY_EXPRESSION,
} from "../../../src/components-core/script-runner/ScriptingSourceTree";

describe("Parser - primary expressions", () => {
  it("null", () => {
    // --- Arrange
    const wParser = new Parser("null");

    // --- Act
    const expr = wParser.parseExpr();

    // --- Assert
    expect(expr).not.equal(null);
    if (!expr) return;
    expect(expr.type).equal(T_LITERAL);
  });

  it("undefined", () => {
    // --- Arrange
    const wParser = new Parser("undefined");

    // --- Act
    const expr = wParser.parseExpr();

    // --- Assert
    expect(expr).not.equal(null);
    if (!expr) return;
    expect(expr.type).equal(T_LITERAL);
  });

  const identifierCases = [
    { src: "$id", exp: "$id" },
    { src: "ident", exp: "ident" },
    { src: "_alma$123", exp: "_alma$123" },
  ];

  identifierCases.forEach((c) => {
    it(`Identifier: ${c.src}`, () => {
      // --- Arrange
      const wParser = new Parser(c.src);

      // --- Act
      const expr = wParser.parseExpr();

      // --- Assert
      expect(expr).not.equal(null);
      if (!expr) return;
      expect(expr.type).equal(T_IDENTIFIER);
      const literal = expr as Identifier;
      expect(literal.name).equal(c.exp);
    });
  });

  const parenthesizedCases = [
    { src: "(123)", exp: T_LITERAL },
    { src: "(a+b)", exp: T_BINARY_EXPRESSION },
    { src: "(a ? b : c)", exp: T_CONDITIONAL_EXPRESSION },
    { src: "(!a)", exp: T_UNARY_EXPRESSION },
    { src: "(a)", exp: T_IDENTIFIER },
    { src: "(a, b)", exp: T_SEQUENCE_EXPRESSION },
    { src: "(c(a, b))", exp: T_FUNCTION_INVOCATION_EXPRESSION },
    { src: "(a.b)", exp: T_MEMBER_ACCESS_EXPRESSION },
    { src: "(a[b])", exp: T_CALCULATED_MEMBER_ACCESS_EXPRESSION },
  ];
  parenthesizedCases.forEach((c) => {
    it(`Parenthesized expression: ${c.src}`, () => {
      // --- Arrange
      const wParser = new Parser(c.src);

      // --- Act
      const expr = wParser.parseExpr();

      // --- Assert
      expect(expr).not.equal(null);
      if (!expr) return;
      expect(expr.type).equal(c.exp);
      expect(expr.parenthesized).equal(1);
    });
  });

  it(`Parenthesized expression`, () => {
    // --- Arrange
    const wParser = new Parser("(c(a, b))");

    // --- Act
    const expr = wParser.parseExpr();

    // --- Assert
    expect(expr).not.equal(null);
    if (!expr) return;
    expect(expr.type).equal(T_FUNCTION_INVOCATION_EXPRESSION);
    expect(expr.parenthesized).equal(1);
  });
});

```

--------------------------------------------------------------------------------
/docs/public/pages/tutorial-11.md:
--------------------------------------------------------------------------------

```markdown
# Import

The `ImportProducts` component uses [FileInput](/components/FileInput) to acquire a CSV file, [Table](/components/Table) to display records as selectable rows, and [Queue](/components/Queue) to import selected rows.

## Using FileInput

To exercise XMLUI Invoice's import feature when running the demo app, you'll use `FileInput` to navigate to `products.csv` in the app's root folder.

```xmlui
<FileInput
  id="fileInput"
  acceptsFileType="{['.csv']}"
  onDidChange="{ (val) => {
    parsedCsv = window.parseCsv(val[0]).map((item, idx) => {
      return {...item, id: idx};
    });
  }}"
/>
```

## Avoiding duplication

The table that displays imported products makes rows selectable, so you can import only a subset of what's in the CSV file.

It uses `rowDisabledPredicate` to disable a row if the name of any existing product matches the name of the product in the current row. The function `isDuplicate` also enables highlighting duplicate rows.

```xmlui /isDuplicate/
<Table
  id="productsFromCsv"
  data="{ parsedCsv }"
  rowsSelectable="true"
  rowDisabledPredicate="{(row) => isDuplicate(row.name)}"
>
  <Column header="Name">
    <Text color="{isDuplicate($item.name)
        ? '$color-danger-500' : '$textColor-primary'}"
    >
      {$item.name} {isDuplicate($item.name) ? '(duplicate)' : ''}
    </Text>
  </Column>
  <Column bindTo="description"/>
  <Column bindTo="price"/>
</Table>
```

We define `isDuplicate()` using a `<script>` [helper tag](/helper-tags).

```xmlui
<Component name="ImportProducts">
  <script>
    function isDuplicate(name) {
      return existingProducts.value.some(p => p.name === name);
    }
  </script>
  <!-- ... -->
</Component>
```

## Using Queue

The API doesn't support batch update so we use `Queue` to iterate over the selected rows and make an [APICall](/components/APICall) for each.

```xmlui /pluralize/
<Queue id="importQueue" clearAfterFinish="true">
  <property name="progressFeedback">
    <Text value="Importing {
      pluralize(importQueue.getQueuedItems().length, 'product', 'products')
    }"/>
  </property>
  <property name="resultFeedback">
    <Text value="Imported {pluralize($completedItems.length,
      'product', 'products')}"
    />
  </property>
  <event name="process">
    <APICall
      url="/api/products"
      method="post"
      body="{$param.item}"
    />
  </event>
  <event name="complete" value="productsFromCsv.clearSelection()"/>
</Queue>
```

> [!INFO] `pluralize` is a [global helper function](/globals#pluralize).

The import button uses the queue's `enqueueItems` method to populate the queue with the result of the table's `getSelectedItems` method.

```xmlui
<Button
  label="Import"
  onClick="{ importQueue.enqueueItems(productsFromCsv.getSelectedItems())}"
  enabled="{productsFromCsv.getSelectedItems().length}"
/>
```

```

--------------------------------------------------------------------------------
/xmlui/src/components/Image/Image.tsx:
--------------------------------------------------------------------------------

```typescript
import styles from "./Image.module.scss";

import { parseScssVar } from "../../components-core/theming/themeVars";
import { createComponentRenderer } from "../../components-core/renderers";
import { createMetadata, d, dClick, dInternal } from "../metadata-helpers";
import { Image, defaultProps } from "./ImageNative";

const COMP = "Image";

export const ImageMd = createMetadata({
  status: "stable",
  description:
    "`Image` displays pictures from URLs or local sources with built-in responsive " +
    "sizing, aspect ratio control, and accessibility features. It handles different " +
    "image formats and provides options for lazy loading and click interactions.",
  props: {
    src: d(
      "This property is used to indicate the source (path) of the image to display. " +
        "When not defined, no image is displayed.",
    ),
    data: d(
      `This property contains the binary data that represents the image.`,
    ),
    alt: d(`This optional property specifies an alternate text for the image.`),
    fit: {
      description:
        "This property sets how the image content should be resized to fit its container.",
      type: "string",
      defaultValue: defaultProps.fit,
    },
    lazyLoad: {
      description:
        `Lazy loading instructs the browser to load the image only when it is imminently needed ` +
        `(e.g. user scrolls to it).`,
      type: "boolean",
      defaultValue: defaultProps.lazyLoad,
    },
    aspectRatio: d(
      "This property sets a preferred aspect ratio for the image, which will be used in " +
        "calculating auto sizes and other layout functions. If this value is not used, the " +
        'original aspect ratio is kept. The value can be a number of a string (such as "16/9").',
    ),
    inline: {
      description: `When set to true, the image will be displayed as an inline element instead of a block element.`,
      type: "boolean",
      defaultValue: defaultProps.inline,
    },
    animation: dInternal(`The optional animation object to be applied to the component`),
  },
  events: {
    click: dClick(COMP),
  },
  themeVars: parseScssVar(styles.themeVars),
});

export const imageComponentRenderer = createComponentRenderer(
  COMP,
  ImageMd,
  ({ node, extractValue, className, extractResourceUrl }) => {
    return (
      <Image
        src={node.props.src ? extractResourceUrl(node.props.src) : undefined}
        imageData={extractValue(node.props.data)}
        alt={extractValue(node.props.alt)}
        fit={extractValue(node.props.fit)}
        lazyLoad={extractValue.asOptionalBoolean(node.props.lazyLoad)}
        inline={extractValue.asOptionalBoolean(node.props.inline)}
        aspectRatio={extractValue(node.props.aspectRatio)}
        className={className}
        animation={extractValue(node.props.animation)}
      />
    );
  },
);

```

--------------------------------------------------------------------------------
/xmlui/src/components-core/rendering/buildProxy.ts:
--------------------------------------------------------------------------------

```typescript
// The type of action we can use with a proxy
export type ProxyAction = "set" | "unset";

// Proxy operation callback parameters
export type ProxyCallbackArgs = {
  action: ProxyAction;
  path: string;
  pathArray: (string | symbol)[];
  target: string;
  newValue?: any;
  previousValue?: any;
};

/**
 * Use this function to build a JavaScript proxy for localContext objects. The 
 * responsibility of the proxy is to collect the changes within the localContext 
 * so that we can refresh the UI according to them.
 */
export function buildProxy(
  proxyTarget: any,
  callback: (changeInfo: ProxyCallbackArgs) => void,
  tree: Array<string | symbol> = [],
): any {
  // --- We identify a particular (deep) localContext property by its full path; 
  // --- this function creates the path
  const getPath = (prop: string | symbol) => tree.concat(prop).join(".");

  const proxiedValues = new WeakMap();
  // --- Create the proxy object for `proxyTarget`
  return new Proxy(proxyTarget, {
    get: function (target, prop, receiver) {
      const value = Reflect.get(target, prop, receiver);

      // --- Create proxies only for writable objects and arrays, except arrow 
      // --- function expressions.
      if (
        value &&
        !value._ARROW_EXPR_ &&
        !Object.isFrozen(value) &&
        typeof value === "object" &&
        ["Array", "Object"].includes(value.constructor.name)
      ) {
        // --- Just to make sure that accessing the proxied objects' field gets 
        // --- the same reference every time. e.g. this wouldn't be true otherwise: 
        // --- proxiedObject['field'] === proxiedObject['field']
        if (!proxiedValues.has(value)) {
          proxiedValues.set(value, buildProxy(value, callback, tree.concat(prop)));
        }
        return proxiedValues.get(value);
      }

      // --- Do not create a proxy for other objects
      return value;
    },

    set: function (target, prop, value, receiver) {
      // --- Invoke the callback function to sign any change in the proxied object
      callback({
        action: "set",
        path: getPath(prop),
        pathArray: tree.concat(prop),
        target,
        newValue: value,
        previousValue: Reflect.get(target, prop, receiver),
      });

      // --- Execute the change.
      // --- Note, any error raised in the callback will prevent from changing the property value
      return Reflect.set(target, prop, value, receiver);
    },

    deleteProperty: function (target, prop) {
      // --- Invoke the callback function to delete a property
      callback({ action: "unset", path: getPath(prop), pathArray: tree.concat(prop), target });

      // --- Execute the change
      // --- Note, any error raised in the callback will prevent from deleting the property value
      return Reflect.deleteProperty(target, prop);
    },
  });
}

```

--------------------------------------------------------------------------------
/packages/xmlui-animations/src/ScaleAnimation.tsx:
--------------------------------------------------------------------------------

```typescript
import { createComponentRenderer, createMetadata } from "xmlui";
import { Animation, defaultProps } from "./AnimationNative";

const COMP = "ScaleAnimation";

const defaultAnimationValues = {
  from: 0,
  to: 1,
};

export const ScaleAnimationMd = createMetadata({
  status: "experimental",
  description: `The \`${COMP}\` component represents an animation that scales the content.`,
  docFolder: "src",
  props: {
    from: {
      description: "The initial scale of the content.",
      valueType: "number",
      defaultValue: defaultAnimationValues.from,
    },
    to: {
      description: "The final scale of the content.",
      valueType: "number",
      defaultValue: defaultAnimationValues.to,
    },
    duration: {
      description: "The duration of the animation in milliseconds.",
      valueType: "number",
    },
    animateWhenInView: {
      description: "Indicates whether the animation should start when the component is in view.",
      valueType: "boolean",
    },
    reverse: {
      description: `Indicates whether the animation should run in reverse`,
      defaultValue: defaultProps.reverse,
      valueType: "boolean",
    },
    loop: {
      description: `Indicates whether the animation should loop`,
      defaultValue: defaultProps.loop,
      valueType: "boolean",
    },
    delay: {
      description: `The delay before the animation starts in milliseconds`,
      defaultValue: defaultProps.delay,
      valueType: "number",
    },
  },
  events: {
    started: { description: `Event fired when the animation starts` },
    stopped: { description: `Event fired when the animation stops` },
  },
  apis: {
    start: { description: `Starts the animation` },
    stop: { description: `Stops the animation` },
  },
});

export const scaleAnimationRenderer = createComponentRenderer(
  COMP,
  ScaleAnimationMd,
  ({ node, renderChild, extractValue, registerComponentApi, lookupEventHandler }) => {
    return (
      <Animation
        registerComponentApi={registerComponentApi}
        animation={{
          from: {
            transform: `scale(${extractValue.asOptionalNumber(node.props?.from, defaultAnimationValues.from)})`,
          },
          to: {
            transform: `scale(${extractValue.asOptionalNumber(node.props?.to, defaultAnimationValues.to)})`,
          },
        }}
        duration={extractValue.asOptionalNumber(node.props.duration)}
        onStop={lookupEventHandler("stopped")}
        onStart={lookupEventHandler("started")}
        animateWhenInView={extractValue.asOptionalBoolean(node.props.animateWhenInView)}
        reverse={extractValue.asOptionalBoolean(node.props.reverse)}
        loop={extractValue.asOptionalBoolean(node.props.loop)}
        delay={extractValue.asOptionalNumber(node.props.delay)}
      >
        {renderChild(node.children)}
      </Animation>
    );
  },
);

```

--------------------------------------------------------------------------------
/.github/workflows/deploy-docs-optimized.yml:
--------------------------------------------------------------------------------

```yaml
name: Deploy docs (optimized)

on:
  workflow_dispatch:
    inputs:
      max_releases:
        description: "Maximum number of releases to include in docs"
        type: number
        required: false
        default: 10

permissions:
  contents: write
  pull-requests: write

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    env:
      NODE_OPTIONS: "--max-old-space-size=8192"
      TURBO_UI: "false"

    steps:
      - name: 1. Generate a token from the GitHub App 🤖
        id: generate_token
        uses: tibdex/github-app-token@v2
        with:
          app_id: ${{ secrets.APP_ID }}
          private_key: ${{ secrets.APP_PRIVATE_KEY }}
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: "npm"
          registry-url: https://registry.npmjs.org/

      - name: Cache for Turbo
        uses: rharkor/caching-for-turbo@v2.3.1

      - run: npm ci --prefer-offline

      - name: 4. Configure Git to use the App's token 🔑
        # The token generated in the first step is used here for authentication.
        run: git config --global url."https://x-access-token:${{ steps.generate_token.outputs.token }}@github.com/".insteadOf "https://github.com/"
      - name: 5. DEBUG - Attempt to clone the private repo
        # This step will give a clear error if authentication is the problem
        run: git clone https://github.com/xmlui-org/xmlui-optimizer.git
      - name: 5. Install optimizer's dependencies
        run: npm install
        working-directory: ./xmlui-optimizer
      - name: DEBUG - install xmlui-optimizer
        # This step will give a clear error if authentication is the problem
        run: npm install ./xmlui-optimizer

      - run: cd docs && npm run release-ci-optimized
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          DOCS_XMLUI_MAX_RELEASES_LENGTH: ${{ github.event.inputs.max_releases }}

      - name: "Run Azure webapp deploy action using publish profile credentials"
        uses: azure/webapps-deploy@v2
        with:
          package: "docs/ui-optimized.zip"
          app-name: xmlui-docs
          publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE_XMLUI_DOCS }}
      - name: Create Pull Request for generated releases.json
        uses: peter-evans/create-pull-request@v7
        with:
          add-paths: "docs/public/resources/files/releases.json"
          commit-message: "chore: update generated releases.json"
          title: "docs: Update generated releases.json"
          body: "This PR was automatically opened by the **Deploy docs (optimized)** workflow, which generates the `releases.json` file with data about the latest releases."
          branch: "automated/update-releases"
          delete-branch: true # Clean up the temp branch after merge
          labels: automated

```

--------------------------------------------------------------------------------
/docs/public/pages/howto/make-a-table-responsive.md:
--------------------------------------------------------------------------------

```markdown
# Make a Table responsive

```xmlui-pg noHeader
---app
<App>
  <ResponsiveTable />
</App>
---comp display
<Component name="ResponsiveTable" var.people="{[
  { name: 'Alice Johnson', email: 'alice@company.com', department: 'Engineering', status: 'active', salary: '95k' },
  { name: 'Bob Smith', email: 'bob@company.com', department: 'Marketing', status: 'active', salary: '88k' },
  { name: 'Carol Davis', email: 'carol@company.com', department: 'Sales', status: 'inactive', salary: '110k' },
  { name: 'David Wilson', email: 'david@company.com', department: 'Engineering', status: 'active', salary: '105k' },
  { name: 'Eva Brown', email: 'eva@company.com', department: 'HR', status: 'active', salary: '75k' }
]}">
  <VStack>
    <HStack>
      <Text size="lg">Responsive People Table</Text>
      <Badge value="Current: {mediaSize.size}" color="blue" />
    </HStack>
    <Text size="sm" color="gray">Resize your browser window to see columns progressively hide</Text>

    <Table data="{people}">
      <!-- Essential: Avatar - always show -->
      <Column header="" width="50px">
        <Avatar
          name="{$item.name}"
          size="xs"
          color="blue"
        />
      </Column>

      <!-- Essential: Name - always show -->
      <Column header="Name" bindTo="name" width="150px">
        <Text>{$item.name}</Text>
      </Column>

      <!-- Priority: Email - hide on xs screens -->
      <Column header="Email" bindTo="email" when="{mediaSize.size !== 'xs'}" width="200px">
        <Text size="sm" color="gray">{$item.email}</Text>
      </Column>

      <!-- Secondary: Department - hide on xs/sm screens -->
      <Column header="Department" bindTo="department" when="{mediaSize.size !== 'xs' && mediaSize.size !== 'sm'}" width="120px" />

      <!-- Tertiary: Status - only show on md+ screens -->
      <Column header="Status" bindTo="status" when="{mediaSize.size === 'md' || mediaSize.size === 'lg' || mediaSize.size === 'xl' || mediaSize.size === 'xxl'}" width="80px">
        <Badge
          value="{$item.status}"
          color="{status === 'active' ? 'green' : 'gray'}"
          variant="pill"
        />
      </Column>

      <!-- Low Priority: Salary - only show on lg+ screens -->
      <Column header="Salary" bindTo="salary" when="{mediaSize.size === 'lg' || mediaSize.size === 'xl' || mediaSize.size === 'xxl'}" width="100px">
        <Text size="sm" weight="medium">${$item.salary}</Text>
      </Column>
    </Table>

    <VStack gap="sm" margin="md">
      <Text size="sm" weight="bold">Column Visibility by Screen Size:</Text>
      <Text size="xs" color="gray">xs: Avatar + Name only</Text>
      <Text size="xs" color="gray">sm: + Email</Text>
      <Text size="xs" color="gray">md: + Department + Status</Text>
      <Text size="xs" color="gray">lg+: + Salary</Text>
    </VStack>
  </VStack>
</Component>
```


```

--------------------------------------------------------------------------------
/xmlui/src/components/Icon/svg/pdf.svg:
--------------------------------------------------------------------------------

```
<svg viewBox="0 0 22 28" fill="none" xmlns="http://www.w3.org/2000/svg">
  <g clip-path="url(#clip0_1813_15242)">
    <path
      d="M21.788 7.38281L16.3739 5.74219L14.827 0H3.22546C2.37112 0 1.67859 0.734508 1.67859 1.64062V26.3594C1.67859 27.2655 2.37112 28 3.22546 28H20.2411C21.0954 28 21.788 27.2655 21.788 26.3594V7.38281Z"
      fill="#EDEDED"/>
    <path
      d="M21.7879 7.38281V26.3594C21.7879 27.2655 21.0954 28 20.2411 28H11.8571V0H14.827L16.3739 5.74219L21.7879 7.38281Z"
      fill="#EDEDED"/>
    <path
      d="M21.788 7.38281H16.3739C15.5231 7.38281 14.827 6.64453 14.827 5.74219V0C15.0281 0 15.2292 0.0820312 15.3684 0.246148L21.5559 6.80865C21.7106 6.95625 21.788 7.16953 21.788 7.38281Z"
      fill="#BDBDBD"/>
    <path
      d="M20.5333 22.4259C20.5333 22.925 20.1483 23.3333 19.6778 23.3333H0.855556C0.385 23.3333 0 22.925 0 22.4259V13.3519C0 12.8528 0.385 12.4445 0.855556 12.4445H19.6778C20.1483 12.4445 20.5333 12.8528 20.5333 13.3519V22.4259Z"
      fill="#FF3E3E"/>
    <path
      d="M4.25304 17.732V16.448H4.98504C5.09304 16.448 5.19704 16.456 5.29704 16.472C5.39704 16.488 5.48504 16.52 5.56104 16.568C5.63704 16.612 5.69704 16.676 5.74104 16.76C5.78904 16.844 5.81304 16.954 5.81304 17.09C5.81304 17.226 5.78904 17.336 5.74104 17.42C5.69704 17.504 5.63704 17.57 5.56104 17.618C5.48504 17.662 5.39704 17.692 5.29704 17.708C5.19704 17.724 5.09304 17.732 4.98504 17.732H4.25304ZM3.31104 15.716V20H4.25304V18.464H5.24304C5.51104 18.464 5.73904 18.426 5.92704 18.35C6.11504 18.27 6.26704 18.166 6.38304 18.038C6.50304 17.91 6.58904 17.764 6.64104 17.6C6.69704 17.432 6.72504 17.262 6.72504 17.09C6.72504 16.914 6.69704 16.744 6.64104 16.58C6.58904 16.416 6.50304 16.27 6.38304 16.142C6.26704 16.014 6.11504 15.912 5.92704 15.836C5.73904 15.756 5.51104 15.716 5.24304 15.716H3.31104Z"
      fill="white"/>
    <path
      d="M8.85499 19.208V16.508H9.52699C9.75899 16.508 9.95299 16.542 10.109 16.61C10.269 16.674 10.397 16.768 10.493 16.892C10.589 17.016 10.657 17.166 10.697 17.342C10.741 17.514 10.763 17.708 10.763 17.924C10.763 18.16 10.733 18.36 10.673 18.524C10.613 18.688 10.533 18.822 10.433 18.926C10.333 19.026 10.219 19.098 10.091 19.142C9.96299 19.186 9.83099 19.208 9.69499 19.208H8.85499ZM7.91299 15.716V20H9.76099C10.089 20 10.373 19.946 10.613 19.838C10.857 19.726 11.059 19.574 11.219 19.382C11.383 19.19 11.505 18.962 11.585 18.698C11.665 18.434 11.705 18.146 11.705 17.834C11.705 17.478 11.655 17.168 11.555 16.904C11.459 16.64 11.323 16.42 11.147 16.244C10.975 16.068 10.769 15.936 10.529 15.848C10.293 15.76 10.037 15.716 9.76099 15.716H7.91299Z"
      fill="white"/>
    <path d="M12.9603 15.716V20H13.9023V18.23H15.6963V17.498H13.9023V16.508H15.9723V15.716H12.9603Z" fill="white"/>
  </g>
  <defs>
    <clipPath id="clip0_1813_15242">
      <rect width="22" height="28" fill="white"/>
    </clipPath>
  </defs>
</svg>
```

--------------------------------------------------------------------------------
/xmlui/src/components/App/AppLayoutContext.ts:
--------------------------------------------------------------------------------

```typescript
import { createContext, useContext } from "react";

import type { ComponentDef, PropertyValueDescription } from "../../abstractions/ComponentDefs";

const appLayoutNames = [
  "vertical",
  "vertical-sticky",
  "vertical-full-header",
  "condensed",
  "condensed-sticky",
  "horizontal",
  "horizontal-sticky",
] as const;
export const appLayoutMd: readonly PropertyValueDescription[] = [
  {
    value: "vertical",
    description:
      "This layout puts the navigation bar on the left side and displays its items vertically. The main content is aligned to the right (including the header and the footer), and its content is a single scroll container; every part of it moves as you scroll the page. This layout does not display the logo in the app header.",
  },
  {
    value: "vertical-sticky",
    description:
      "Similar to `vertical`, the header and the navigation bar dock to the top of the main content's viewport, while the footer sticks to the bottom. This layout does not display the logo in the app header.",
  },
  {
    value: "vertical-full-header",
    description:
      "Similar to `vertical-sticky`. However, the header and the navigation bar dock to the top of the app's window, while the footer sticks to the bottom.",
  },
  {
    value: "condensed",
    description:
      "Similar to `horizontal`. However, the header and the navigation bar are in a single header block. (default)",
  },
  {
    value: "condensed-sticky",
    description: "However, the header and the navigation bar are in a single header block.",
  },
  {
    value: "horizontal",
    description:
      "This layout stacks the layout sections in a single column in this order: header, navigation bar, main content, and footer. The application is a single scroll container; every part moves as you scroll the page.",
  },
  {
    value: "horizontal-sticky",
    description:
      "Similar to `horizontal`, the header and the navigation bar dock to the top of the viewport, while the footer sticks to the bottom.",
  },
] as const;

export const appLayouts: string[] = [...appLayoutNames];
export type AppLayoutType = (typeof appLayoutNames)[number];

export interface IAppLayoutContext {
  layout: AppLayoutType;
  navPanelVisible: boolean;
  drawerVisible: boolean;
  showDrawer: () => void;
  hideDrawer: () => void;
  toggleDrawer: () => void;
  hasRegisteredNavPanel: boolean;
  hasRegisteredHeader: boolean;
  navPanelDef?: ComponentDef;
  logoContentDef?: ComponentDef;
  logo?: string;
  logoDark?: string;
  logoLight?: string;
  registerSubNavPanelSlot?: (slot: HTMLElement) => void;
  subNavPanelSlot?: HTMLElement;
  scrollWholePage?: boolean;
  isFullVerticalWidth?: boolean;
  isNested?: boolean;
}

export const AppLayoutContext = createContext<IAppLayoutContext | null>(null);

export function useAppLayoutContext() {
  return useContext(AppLayoutContext);
}

```

--------------------------------------------------------------------------------
/.github/workflows/run-all-tests.yml:
--------------------------------------------------------------------------------

```yaml
name: All Tests (nightly run)

concurrency: # Concurrency ensures that only a single job or workflow using the same concurrency group will run at a time.
  group: component-e2e-testing-nightly
  cancel-in-progress: true

on:
  workflow_dispatch:
  schedule:
    - cron: "39 1 * * *"
jobs:
  check-commit:
    runs-on: ubuntu-latest
    env:
      NODE_OPTIONS: "--max-old-space-size=8192"
    outputs:
      should_test: ${{ steps.check.outputs.should_test }}
    steps:
      - uses: actions/checkout@v4
      - id: check
        name: Determine if the commit has been tested already
        run: |
          # Always run tests if triggered by workflow_dispatch
          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
            echo "Workflow dispatch triggered, always run tests"
            echo "should_test=true" >> $GITHUB_OUTPUT
            exit 0
          fi

          current_time_epoch=$(date +%s)
          last_commit_time_epoch=$(git log -1 --format=%ct)
          one_day_epoch=$((60 * 60 * 24))
          threshold_time=$((last_commit_time_epoch + one_day_epoch))

          if [ $current_time_epoch -gt $threshold_time ]; then
              echo "Last commit is older than 24 hours, skipping tests"
              echo "should_test=false" >> $GITHUB_OUTPUT
          else
              echo "Last commit is within the last 24 hours, will not skip tests"
              echo "should_test=true" >> $GITHUB_OUTPUT
          fi
  test:
    needs: check-commit
    if: needs.check-commit.outputs.should_test == 'true'
    timeout-minutes: 60
    runs-on: ubuntu-latest
    env:
      NODE_OPTIONS: "--max-old-space-size=8192"
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: "npm"
      - name: Install node dependencies
        run: npm ci --prefer-offline
      - name: Cache for Turbo
        uses: rharkor/caching-for-turbo@v2.3.1
      - name: Store Playwright's Version
        run: |
          PLAYWRIGHT_VERSION=$(npm ls @playwright/test | grep @playwright | sed 's/.*@//' | sort | head -n 1)
          echo "Playwright's Version: $PLAYWRIGHT_VERSION"
          echo "PLAYWRIGHT_VERSION=$PLAYWRIGHT_VERSION" >> $GITHUB_ENV
      - name: Cache Playwright Browsers for Playwright's Version
        id: cache-playwright-browsers
        uses: actions/cache@v4
        with:
          path: ~/.cache/ms-playwright
          key: playwright-browsers-${{ env.PLAYWRIGHT_VERSION }}
      - name: Install Playwright Browsers
        if: steps.cache-playwright-browsers.outputs.cache-hit != 'true'
        run: npx playwright install --with-deps
      - name: run some tests
        run: npm run test-xmlui
      - uses: actions/upload-artifact@v4
        with:
          name: playwright-report
          path: xmlui/playwright-report/
          retention-days: 30

```

--------------------------------------------------------------------------------
/xmlui/tests/parsers/common/input-stream.test.ts:
--------------------------------------------------------------------------------

```typescript
import { describe, expect, it } from "vitest";
import { InputStream } from "../../../src/parsers/common/InputStream";

describe("InputStream", () => {
  it("Builds from string", () => {
    // --- Act
    const is = new InputStream("hello");

    // --- Assert
    expect(is.position).equal(0);
    expect(is.line).equal(1);
    expect(is.column).equal(0);
    expect(is.source).equal("hello");
  });

  it("Peek #1", () => {
    // --- Arrange
    const is = new InputStream("hello");

    // --- Act
    const ch = is.peek();

    // --- Assert
    expect(ch).equal("h");
    expect(is.position).equal(0);
    expect(is.line).equal(1);
    expect(is.column).equal(0);
  });

  it("Peek #3", () => {
    // --- Arrange
    const is = new InputStream("hello");
    is.get();
    is.get();

    // --- Act
    const ch = is.peek();

    // --- Assert
    expect(ch).equal("l");
    expect(is.position).equal(2);
    expect(is.line).equal(1);
    expect(is.column).equal(2);
  });

  it("Peek #5", () => {
    // --- Arrange
    const is = new InputStream("hello");
    is.get();
    is.get();
    is.get();
    is.get();
    is.get();

    // --- Act
    const ch = is.peek();

    // --- Assert
    expect(ch).equal(null);
    expect(is.position).equal(5);
    expect(is.line).equal(1);
    expect(is.column).equal(5);
  });

  it("Peek with new line #1", () => {
    // --- Arrange
    const is = new InputStream("he\nllo");
    is.get();
    is.get();

    // --- Act
    const ch = is.peek();

    // --- Assert
    expect(ch).equal("\n");
    expect(is.position).equal(2);
    expect(is.line).equal(1);
    expect(is.column).equal(2);
  });

  it("Get #1", () => {
    // --- Arrange
    const is = new InputStream("hello");

    // --- Act
    const ch = is.get();

    // --- Assert
    expect(ch).equal("h");
    expect(is.position).equal(1);
    expect(is.line).equal(1);
    expect(is.column).equal(1);
  });

  it("Get #3", () => {
    // --- Arrange
    const is = new InputStream("hello");
    is.get();
    is.get();

    // --- Act
    const ch = is.get();

    // --- Assert
    expect(ch).equal("l");
    expect(is.position).equal(3);
    expect(is.line).equal(1);
    expect(is.column).equal(3);
  });

  it("Get #5", () => {
    // --- Arrange
    const is = new InputStream("hello");
    is.get();
    is.get();
    is.get();
    is.get();
    is.get();

    // --- Act
    const ch = is.get();

    // --- Assert
    expect(ch).equal(null);
    expect(is.position).equal(5);
    expect(is.line).equal(1);
    expect(is.column).equal(5);
  });

  it("Get with new line #1", () => {
    // --- Arrange
    const is = new InputStream("he\nllo");
    is.get();
    is.get();

    // --- Act
    const ch = is.get();

    // --- Assert
    expect(ch).equal("\n");
    expect(is.position).equal(3);
    expect(is.line).equal(2);
    expect(is.column).equal(0);
  });
});

```

--------------------------------------------------------------------------------
/xmlui/src/components/Heading/H1.spec.ts:
--------------------------------------------------------------------------------

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

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

test.describe("Basic Functionality", () => {
  test("renders as h1 level heading", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H1 testId="h1">Test Heading</H1>`);

    const driver = await createHeadingDriver("h1");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Test Heading");
    await expect(driver.component).toHaveRole("heading");
    
    // Verify it renders as h1 HTML element
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h1");
  });

  test("renders with value property", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H1 testId="h1" value="Value Property Text" />`);

    const driver = await createHeadingDriver("h1");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Value Property Text");
    await expect(driver.component).toHaveRole("heading");
    
    // Verify it renders as h1 HTML element
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h1");
  });

  test("is equivalent to Heading with level='h1'", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`
      <Fragment>
        <Heading testId="heading" level="h1">Heading Content</Heading>
        <H1 testId="h1">H1 Content</H1>
      </Fragment>
    `);

    const headingDriver = await createHeadingDriver("heading");
    const h1Driver = await createHeadingDriver("h1");
    
    // Both should render as h1 elements
    const headingTagName = await headingDriver.getComponentTagName();
    const h1TagName = await h1Driver.getComponentTagName();
    
    expect(headingTagName.toLowerCase()).toBe("h1");
    expect(h1TagName.toLowerCase()).toBe("h1");
    expect(headingTagName).toEqual(h1TagName);
    
    // Both should have heading role
    await expect(headingDriver.component).toHaveRole("heading");
    await expect(h1Driver.component).toHaveRole("heading");
  });

  test("ignores level property when provided", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H1 testId="h1" level="h3">Should be H1</H1>`);

    const driver = await createHeadingDriver("h1");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Should be H1");
    await expect(driver.component).toHaveRole("heading");
    
    // Should always be h1 despite level="h3" prop (this is the expected behavior)
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h1");
  });
});

```

--------------------------------------------------------------------------------
/xmlui/src/components/Heading/H2.spec.ts:
--------------------------------------------------------------------------------

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

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

test.describe("Basic Functionality", () => {
  test("renders as h2 level heading", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H2 testId="h2">Test Heading</H2>`);

    const driver = await createHeadingDriver("h2");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Test Heading");
    await expect(driver.component).toHaveRole("heading");
    
    // Verify it renders as h2 HTML element
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h2");
  });

  test("renders with value property", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H2 testId="h2" value="Value Property Text" />`);

    const driver = await createHeadingDriver("h2");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Value Property Text");
    await expect(driver.component).toHaveRole("heading");
    
    // Verify it renders as h2 HTML element
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h2");
  });

  test("is equivalent to Heading with level='h2'", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`
      <Fragment>
        <Heading testId="heading" level="h2">Heading Content</Heading>
        <H2 testId="h2">H2 Content</H2>
      </Fragment>
    `);

    const headingDriver = await createHeadingDriver("heading");
    const h2Driver = await createHeadingDriver("h2");
    
    // Both should render as h2 elements
    const headingTagName = await headingDriver.getComponentTagName();
    const h2TagName = await h2Driver.getComponentTagName();
    
    expect(headingTagName.toLowerCase()).toBe("h2");
    expect(h2TagName.toLowerCase()).toBe("h2");
    expect(headingTagName).toEqual(h2TagName);
    
    // Both should have heading role
    await expect(headingDriver.component).toHaveRole("heading");
    await expect(h2Driver.component).toHaveRole("heading");
  });

  test("ignores level property when provided", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H2 testId="h2" level="h4">Should be H2</H2>`);

    const driver = await createHeadingDriver("h2");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Should be H2");
    await expect(driver.component).toHaveRole("heading");
    
    // Should always be h2 despite level="h4" prop (this is the expected behavior)
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h2");
  });
});

```

--------------------------------------------------------------------------------
/xmlui/src/components/Heading/H3.spec.ts:
--------------------------------------------------------------------------------

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

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

test.describe("Basic Functionality", () => {
  test("renders as h3 level heading", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H3 testId="h3">Test Heading</H3>`);

    const driver = await createHeadingDriver("h3");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Test Heading");
    await expect(driver.component).toHaveRole("heading");
    
    // Verify it renders as h3 HTML element
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h3");
  });

  test("renders with value property", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H3 testId="h3" value="Value Property Text" />`);

    const driver = await createHeadingDriver("h3");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Value Property Text");
    await expect(driver.component).toHaveRole("heading");
    
    // Verify it renders as h3 HTML element
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h3");
  });

  test("is equivalent to Heading with level='h3'", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`
      <Fragment>
        <Heading testId="heading" level="h3">Heading Content</Heading>
        <H3 testId="h3">H3 Content</H3>
      </Fragment>
    `);

    const headingDriver = await createHeadingDriver("heading");
    const h3Driver = await createHeadingDriver("h3");
    
    // Both should render as h3 elements
    const headingTagName = await headingDriver.getComponentTagName();
    const h3TagName = await h3Driver.getComponentTagName();
    
    expect(headingTagName.toLowerCase()).toBe("h3");
    expect(h3TagName.toLowerCase()).toBe("h3");
    expect(headingTagName).toEqual(h3TagName);
    
    // Both should have heading role
    await expect(headingDriver.component).toHaveRole("heading");
    await expect(h3Driver.component).toHaveRole("heading");
  });

  test("ignores level property when provided", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H3 testId="h3" level="h1">Should be H3</H3>`);

    const driver = await createHeadingDriver("h3");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Should be H3");
    await expect(driver.component).toHaveRole("heading");
    
    // Should always be h3 despite level="h1" prop (this is the expected behavior)
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h3");
  });
});

```

--------------------------------------------------------------------------------
/xmlui/src/components/Heading/H4.spec.ts:
--------------------------------------------------------------------------------

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

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

test.describe("Basic Functionality", () => {
  test("renders as h4 level heading", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H4 testId="h4">Test Heading</H4>`);

    const driver = await createHeadingDriver("h4");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Test Heading");
    await expect(driver.component).toHaveRole("heading");
    
    // Verify it renders as h4 HTML element
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h4");
  });

  test("renders with value property", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H4 testId="h4" value="Value Property Text" />`);

    const driver = await createHeadingDriver("h4");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Value Property Text");
    await expect(driver.component).toHaveRole("heading");
    
    // Verify it renders as h4 HTML element
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h4");
  });

  test("is equivalent to Heading with level='h4'", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`
      <Fragment>
        <Heading testId="heading" level="h4">Heading Content</Heading>
        <H4 testId="h4">H4 Content</H4>
      </Fragment>
    `);

    const headingDriver = await createHeadingDriver("heading");
    const h4Driver = await createHeadingDriver("h4");
    
    // Both should render as h4 elements
    const headingTagName = await headingDriver.getComponentTagName();
    const h4TagName = await h4Driver.getComponentTagName();
    
    expect(headingTagName.toLowerCase()).toBe("h4");
    expect(h4TagName.toLowerCase()).toBe("h4");
    expect(headingTagName).toEqual(h4TagName);
    
    // Both should have heading role
    await expect(headingDriver.component).toHaveRole("heading");
    await expect(h4Driver.component).toHaveRole("heading");
  });

  test("ignores level property when provided", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H4 testId="h4" level="h1">Should be H4</H4>`);

    const driver = await createHeadingDriver("h4");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Should be H4");
    await expect(driver.component).toHaveRole("heading");
    
    // Should always be h4 despite level="h1" prop (this is the expected behavior)
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h4");
  });
});

```

--------------------------------------------------------------------------------
/xmlui/src/components/Heading/H5.spec.ts:
--------------------------------------------------------------------------------

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

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

test.describe("Basic Functionality", () => {
  test("renders as h5 level heading", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H5 testId="h5">Test Heading</H5>`);

    const driver = await createHeadingDriver("h5");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Test Heading");
    await expect(driver.component).toHaveRole("heading");
    
    // Verify it renders as h5 HTML element
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h5");
  });

  test("renders with value property", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H5 testId="h5" value="Value Property Text" />`);

    const driver = await createHeadingDriver("h5");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Value Property Text");
    await expect(driver.component).toHaveRole("heading");
    
    // Verify it renders as h5 HTML element
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h5");
  });

  test("is equivalent to Heading with level='h5'", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`
      <Fragment>
        <Heading testId="heading" level="h5">Heading Content</Heading>
        <H5 testId="h5">H5 Content</H5>
      </Fragment>
    `);

    const headingDriver = await createHeadingDriver("heading");
    const h5Driver = await createHeadingDriver("h5");
    
    // Both should render as h5 elements
    const headingTagName = await headingDriver.getComponentTagName();
    const h5TagName = await h5Driver.getComponentTagName();
    
    expect(headingTagName.toLowerCase()).toBe("h5");
    expect(h5TagName.toLowerCase()).toBe("h5");
    expect(headingTagName).toEqual(h5TagName);
    
    // Both should have heading role
    await expect(headingDriver.component).toHaveRole("heading");
    await expect(h5Driver.component).toHaveRole("heading");
  });

  test("ignores level property when provided", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H5 testId="h5" level="h1">Should be H5</H5>`);

    const driver = await createHeadingDriver("h5");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Should be H5");
    await expect(driver.component).toHaveRole("heading");
    
    // Should always be h5 despite level="h1" prop (this is the expected behavior)
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h5");
  });
});

```

--------------------------------------------------------------------------------
/xmlui/src/components/Heading/H6.spec.ts:
--------------------------------------------------------------------------------

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

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

test.describe("Basic Functionality", () => {
  test("renders as h6 level heading", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H6 testId="h6">Test Heading</H6>`);

    const driver = await createHeadingDriver("h6");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Test Heading");
    await expect(driver.component).toHaveRole("heading");
    
    // Verify it renders as h6 HTML element
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h6");
  });

  test("renders with value property", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H6 testId="h6" value="Value Property Text" />`);

    const driver = await createHeadingDriver("h6");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Value Property Text");
    await expect(driver.component).toHaveRole("heading");
    
    // Verify it renders as h6 HTML element
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h6");
  });

  test("is equivalent to Heading with level='h6'", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`
      <Fragment>
        <Heading testId="heading" level="h6">Heading Content</Heading>
        <H6 testId="h6">H6 Content</H6>
      </Fragment>
    `);

    const headingDriver = await createHeadingDriver("heading");
    const h6Driver = await createHeadingDriver("h6");
    
    // Both should render as h6 elements
    const headingTagName = await headingDriver.getComponentTagName();
    const h6TagName = await h6Driver.getComponentTagName();
    
    expect(headingTagName.toLowerCase()).toBe("h6");
    expect(h6TagName.toLowerCase()).toBe("h6");
    expect(headingTagName).toEqual(h6TagName);
    
    // Both should have heading role
    await expect(headingDriver.component).toHaveRole("heading");
    await expect(h6Driver.component).toHaveRole("heading");
  });

  test("ignores level property when provided", async ({ initTestBed, createHeadingDriver }) => {
    await initTestBed(`<H6 testId="h6" level="h1">Should be H6</H6>`);

    const driver = await createHeadingDriver("h6");
    
    await expect(driver.component).toBeVisible();
    await expect(driver.component).toContainText("Should be H6");
    await expect(driver.component).toHaveRole("heading");
    
    // Should always be h6 despite level="h1" prop (this is the expected behavior)
    const tagName = await driver.getComponentTagName();
    expect(tagName.toLowerCase()).toBe("h6");
  });
});

```

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

```typescript
import { InspectorDialog } from "./devtools/InspectorDialog";
import AppWithCodeViewNative from "../components/NestedApp/AppWithCodeViewNative";
import React, { useMemo } from "react";
import { useDevTools } from "./InspectorContext";
import { Tooltip } from "../components/NestedApp/Tooltip";
import styles from "../components/NestedApp/NestedApp.module.scss";
import { AiOutlineClose } from "react-icons/ai";
import { useAppContext } from "./AppContext";

export const ComponentViewer = () => {
  const { mockApi, setIsOpen, isOpen, inspectedNode, clickPosition, projectCompilation, sources } =
    useDevTools();

  const { appGlobals } = useAppContext();

  const components = useMemo<string[]>(() => {
    if (!projectCompilation) {
      return [];
    }
    return projectCompilation.components.map((component) => {
      return component.markupSource;
    });
  }, [projectCompilation]);

  const value = useMemo(() => {
    const compSrc = inspectedNode?.debug?.source;

    if (!compSrc) {
      return "";
    }
    if (!sources) {
      return "";
    }
    const { start, end, fileId } = compSrc;
    const slicedSrc = sources[fileId].slice(start, end);

    let dropEmptyLines = true;
    const prunedLines: Array<string> = [];
    let trimBeginCount: number | undefined = undefined;
    slicedSrc.split("\n").forEach((line) => {
      if (line.trim() === "" && dropEmptyLines) {
        //drop empty lines from the beginning
        return;
      } else {
        dropEmptyLines = false;
        prunedLines.push(line);
        const startingWhiteSpaces = line.search(/\S|$/);
        if (
          line.trim() !== "" &&
          (trimBeginCount === undefined || startingWhiteSpaces < trimBeginCount)
        ) {
          trimBeginCount = startingWhiteSpaces;
        }
      }
    });
    return prunedLines
      .map((line) => line.slice(trimBeginCount).replace(/inspect="true"/g, ""))
      .join("\n");
  }, [inspectedNode, sources]);

  return process.env.VITE_USER_COMPONENTS_Inspect !== "false" &&
    isOpen &&
    inspectedNode !== null ? (
    <InspectorDialog isOpen={isOpen} setIsOpen={setIsOpen} clickPosition={clickPosition}>
      <AppWithCodeViewNative
        height={"500px"}
        allowPlaygroundPopup
        initiallyShowCode={appGlobals?.initiallyShowCode ?? true}
        splitView={true}
        controlsWidth={"120px"}
        closeButton={
          <Tooltip
            trigger={
              <button
                className={styles.headerButton}
                onClick={() => {
                  setIsOpen(false);
                }}
              >
                <AiOutlineClose />
              </button>
            }
            label="Close"
          />
        }
        markdown={`\`\`\`xmlui
${value}
\`\`\``}
        api={mockApi}
        app={value}
        components={components}
      />
    </InspectorDialog>
  ) : null;
};

```

--------------------------------------------------------------------------------
/xmlui/src/components-core/devtools/InspectorDialog.module.scss:
--------------------------------------------------------------------------------

```scss
@use "xmlui/themes.scss" as t;

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

// --- Theme vars for paddings
$themeVars: t.composePaddingVars($themeVars, $component);
$themeVars: t.composePaddingVars($themeVars, "overlay-#{$component}");
$padding-ModalDialog: createThemeVar("padding-#{$component}");
$backgroundColor-ModalDialog: createThemeVar("Dialog:backgroundColor-#{$component}");
$backgroundColor-overlay-ModalDialog: createThemeVar("Dialog:backgroundColor-overlay-#{$component}");
$borderRadius-ModalDialog: createThemeVar("Dialog:borderRadius-#{$component}");
$fontFamily-ModalDialog: createThemeVar("Dialog:fontFamily-#{$component}");
$textColor-ModalDialog: createThemeVar("Dialog:textColor-#{$component}");
$minWidth-ModalDialog: createThemeVar("Dialog:minWidth-#{$component}");
$maxWidth-ModalDialog: createThemeVar("Dialog:maxWidth-#{$component}");
$marginBottom-title-ModalDialog: createThemeVar("Dialog:marginBottom-title-#{$component}");


.overlay {
  position: fixed;
  overflow-y: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  inset: 0;
  background-color: $backgroundColor-overlay-ModalDialog;
  padding: t.$space-4;
}

.overlayBg {
  background-color: $backgroundColor-overlay-ModalDialog;
  position: fixed;
  inset: 0;
}

.contentWrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
}

.content {
  border-radius: $borderRadius-ModalDialog;
  font-family: $fontFamily-ModalDialog;
  color: $textColor-ModalDialog;
  width: 90vw;
  max-width: 960px;
  min-width: 240px;
  isolation: isolate;
  position: relative;
  display: flex;
  flex-direction: column;
  max-height: 80vh;
  overflow-y: auto;
}

.content:focus {
  outline: none;
}

.dialogTitle {
  flex: 1;
  margin-bottom: $marginBottom-title-ModalDialog;
  font-size: t.$fontSize-2xl;
}

.innerContent {
  display: flex;
  flex-direction: column;
  min-height: 0;
  gap: var(--stack-gap-default);
  flex: 1;
}

.closeButton {
  position: absolute;
  right: 0.5rem;
  top: 0.4rem;
}

.actions {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
}

.header {
  padding: t.$space-2;
  justify-content: space-between;
  display: flex;
  flex-direction: row;
  border-bottom: 1px solid t.$borderColor;
}

@media (max-width: 70em) {
  .dialog, .content {
    max-width: 90%;
  }
}

@media (max-width: 50em) {
  .dialog, .content {
    width: 100%;
    max-width: calc(100% - #{t.$space-6});
    min-width: 0 !important;
  }
}

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

```

--------------------------------------------------------------------------------
/xmlui/src/components-core/action/FileDownloadAction.tsx:
--------------------------------------------------------------------------------

```typescript
import type { ComponentDef } from "../../abstractions/ComponentDefs";
import type { ActionExecutionContext } from "../../abstractions/ActionDefs";
import type { ApiActionOptions, DownloadOperationDef } from "../RestApiProxy";
import RestApiProxy from "../RestApiProxy";

import { createAction } from "./actions";

export interface DownloadActionComponent extends ComponentDef {
  props: DownloadOperationDef;
}

async function download(
  { state, appContext }: ActionExecutionContext,
  {
    params,
    url,
    queryParams,
    method,
    rawBody,
    body,
    fileName,
    headers,
  }: {
    params: any;
  } & DownloadOperationDef,
  { resolveBindingExpressions }: ApiActionOptions = {}
) {
  const context = { ...params, ...state };
  const operation: DownloadOperationDef = {
    url,
    queryParams,
    method,
    rawBody,
    body,
    fileName,
    headers,
  };

  const api = new RestApiProxy(appContext);
  const _url = api.resolveUrl({ operation, params: context, resolveBindingExpressions });

  if (
    (operation.method && (operation.method as string).toLowerCase() !== "get") ||
    Object.keys(appContext.appGlobals?.headers || {}).length !== 0 || //if we have any headers for the api, we can't use the iframe trick
    appContext.apiInterceptorContext.isMocked(_url) //if we mock this url, the mock can't work in an iframe, so we must fall back to download it with the restApiProxy
  ) {
    const file: File = await api.execute({
      operation,
      params: context,
      parseOptions: {
        asFile: true,
      },
      resolveBindingExpressions,
    });
    downloadWithAnchor(file);
  } else {
    downloadInIframe(_url);
  }
}

//we use a hidden iframe trick here,
// we set the iframe source as the download url, this way the browser will ask to download the file, and show a progress bar
// (we could use an anchor tag with a download attribute, but in this case we can't show progress )
// we can use it if we don't have to add extra headers to the request in order to download a file (pre-signed urls, or public urls)
function downloadInIframe(fileUrl: string) {
  const iframe = document.createElement("iframe");
  iframe.style.display = "none";
  iframe.hidden = true;
  iframe.name = fileUrl;
  iframe.id = `download-iframe_${fileUrl}`;
  iframe.src = fileUrl;
  document.body.appendChild(iframe);
  setTimeout(() => {
    iframe.remove();
  }, 20000);
}

// we can use it if we do have to add extra headers to the request in order to download a file (urls require authentication)
function downloadWithAnchor(file: File) {
  const url = window.URL.createObjectURL(file);
  const a = document.createElement("a");
  a.style.display = "none";
  a.href = url;
  // the filename you want
  a.download = file.name;
  document.body.appendChild(a);
  a.click();
  window.URL.revokeObjectURL(url);
}

export const downloadAction = createAction("download", download);

```

--------------------------------------------------------------------------------
/xmlui/scripts/inline-links.mjs:
--------------------------------------------------------------------------------

```
import * as fs from "fs";
import * as path from "path";

const includedFileExtensions = [".mdx", ".md"];

// Read the file contents
const fileContent = fs.readFileSync("../docs/meta/pages.js", "utf-8");

// Match lines like: export const NAME = "value";
const regex = /export const (\w+)\s*=\s*["'`](.*?)["'`];/g;

const constants = {};
let match;
while ((match = regex.exec(fileContent)) !== null) {
  const [, key, value] = match;
  constants[key] = value;
}

inlineLinks("../docs/pages");

function inlineLinks(pagesFolder) {
  traverseDirectory({ name: "", path: pagesFolder }, (item, _) => {
    /**
     * name: the folder's/file's name (eg. "hello-app-engine")
     * path: the path to the root of the given folder from the project root (eg. "src/apps/1_basic/samples/hello-app-engine")
     * parent: parent node
     * children: children file/folder names
     */
    if (fs.statSync(item.path).isDirectory()) {
      // Node is a folder
    } else {
      // Node is a file
      if (includedFileExtensions.includes(path.extname(item.name))) {
        console.log(item.name);
        const mdxContent = fs.readFileSync(item.path, "utf-8");
        
        const regex = /<SmartLink\s+href=\{([^}]+)\}>/g;
        const newMdxContent = mdxContent.replace(regex, (_, hrefExpr) => {
          return `<SmartLink href="${constants[hrefExpr] || ''}">`;
        });

        fs.writeFileSync(item.path, newMdxContent);
      }
    }
  });
}

/**
 * Recursive function that traverses a given folder and applies an optional function on
 * each of the folders/files found inside.
 */
export function traverseDirectory(node, visitor, level = 0) {
  level++;
  const dirContents = fs.readdirSync(node.path);
  if (!node.children) node.children = dirContents;
  for (const itemName of dirContents) {
    const itemPath = [winPathToPosix(node.path), itemName].join(path.posix.sep);
    const itemIsDir = fs.statSync(itemPath).isDirectory();
    const childNode = {
      name: itemName,
      path: itemPath,
      parent: node,
    };
    visitor && visitor(childNode, level);
    if (itemIsDir) {
      traverseDirectory(childNode, visitor, level);
    }
  }
}

/**
 * Multi-liner (commented and compatible with really old javascript versions)
 * Source: https://stackoverflow.com/a/62732509
 */
export function winPathToPosix(windowsPath) {
  // handle the edge-case of Window's long file names
  // See: https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#short-vs-long-names
  windowsPath = windowsPath.replace(/^\\\\\?\\/, "");

  // convert the separators, valid since both \ and / can't be in a windows filename
  windowsPath = windowsPath.replace(/\\/g, "/");

  // compress any // or /// to be just /, which is a safe oper under POSIX
  // and prevents accidental errors caused by manually doing path1+path2
  windowsPath = windowsPath.replace(/\/\/+/g, "/");

  return windowsPath;
}

```

--------------------------------------------------------------------------------
/xmlui/src/components/Stack/VStack.spec.ts:
--------------------------------------------------------------------------------

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

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

test.describe("Basic Functionality", () => {
  test("renders items vertically", async ({ initTestBed, page }) => {
    await initTestBed(`
      <VStack testId="vstack">
        <Stack testId="item1" height="32px" width="32px" backgroundColor="red" />
        <Stack testId="item2" height="32px" width="32px" backgroundColor="blue" />
        <Stack testId="item3" height="32px" width="32px" backgroundColor="green" />
      </VStack>
    `);

    const vstack = page.getByTestId("vstack");
    const item1 = page.getByTestId("item1");
    const item2 = page.getByTestId("item2");
    const item3 = page.getByTestId("item3");

    await expect(vstack).toBeVisible();
    await expect(item1).toBeVisible();
    await expect(item2).toBeVisible();
    await expect(item3).toBeVisible();

    // Get bounding boxes to verify vertical layout
    const item1Box = await item1.boundingBox();
    const item2Box = await item2.boundingBox();
    const item3Box = await item3.boundingBox();

    // Verify items are stacked vertically (item2 should be below item1, item3 below item2)
    expect(item2Box!.y).toBeGreaterThan(item1Box!.y + item1Box!.height - 1); // -1 for floating point tolerance
    expect(item3Box!.y).toBeGreaterThan(item2Box!.y + item2Box!.height - 1); // -1 for floating point tolerance

    // Verify items are horizontally aligned (should start at roughly the same x position)
    expect(Math.abs(item1Box!.x - item2Box!.x)).toBeLessThan(1);
    expect(Math.abs(item2Box!.x - item3Box!.x)).toBeLessThan(1);
  });

  test("renders empty VStack", async ({ initTestBed, page }) => {
    await initTestBed(`<VStack testId="vstack"></VStack>`);
    
    const vstack = page.getByTestId("vstack");
    await expect(vstack).toBeAttached();
    await expect(vstack).toBeEmpty();
  });

  test("ignores orientation property", async ({ initTestBed, page }) => {
    await initTestBed(`
      <VStack testId="vstack" orientation="horizontal">
        <Stack testId="item1" height="32px" width="32px" backgroundColor="red" />
        <Stack testId="item2" height="32px" width="32px" backgroundColor="blue" />
      </VStack>
    `);

    const item1 = page.getByTestId("item1");
    const item2 = page.getByTestId("item2");

    await expect(item1).toBeVisible();
    await expect(item2).toBeVisible();

    // Get bounding boxes to verify still renders vertically despite orientation="horizontal"
    const item1Box = await item1.boundingBox();
    const item2Box = await item2.boundingBox();

    // Verify items are still stacked vertically (orientation prop should be ignored)
    expect(item2Box!.y).toBeGreaterThan(item1Box!.y + item1Box!.height - 1);
  });
});

```

--------------------------------------------------------------------------------
/xmlui/src/components/Option/Option.tsx:
--------------------------------------------------------------------------------

```typescript
import { createComponentRenderer } from "../../components-core/renderers";
import { MemoizedItem } from "../container-helpers";
import { createMetadata, d } from "../metadata-helpers";
import { OptionNative, defaultProps } from "./OptionNative";

const COMP = "Option";

export const OptionMd = createMetadata({
  status: "stable",
  description:
    "`Option` defines selectable items for choice-based components, providing both " +
    "the underlying value and display text for selection interfaces. It serves as " +
    "a non-visual data structure that describes individual choices within " +
    "[Select](/components/Select), [AutoComplete](/components/AutoComplete), " +
    "and other selection components.",
  props: {
    label: d(
      `This property defines the text to display for the option. If \`label\` is not defined, ` +
      `\`Option\` will use the \`value\` as the label.`,
    ),
    value: d(
      "This property defines the value of the option. If `value` is not defined, " +
      "`Option` will use the `label` as the value. If neither is defined, " +
      "the option is not displayed.",
    ),
    enabled: {
      description: "This boolean property indicates whether the option is enabled or disabled.",
      valueType: "boolean",
      defaultValue: defaultProps.enabled,
    },
    keywords: d(
      "An array of keywords that can be used for searching and filtering the option. " +
      "These keywords are not displayed but help users find the option through search.",
    ),
  },
});

export const optionComponentRenderer = createComponentRenderer(
  COMP,
  OptionMd,
  ({ node, extractValue, className, renderChild, layoutContext }) => {
    const label = extractValue.asOptionalString(node.props.label);
    let value = extractValue(node.props.value);
    if (label === undefined && value === undefined) {
      return null;
    }

    const hasTextNodeChild = node.children?.length === 1 && (node.children[0].type === "TextNode" || node.children[0].type === "TextNodeCData");
    const textNodeChild = hasTextNodeChild ? renderChild(node.children) as string : undefined;

    return (
      <OptionNative
        label={label || textNodeChild}
        value={value !== undefined && value !== "" ? value : label}
        enabled={extractValue.asOptionalBoolean(node.props.enabled)}
        keywords={extractValue.asOptionalStringArray(node.props.keywords)}
        className={className}
        optionRenderer={
          node.children?.length > 0
            ? !hasTextNodeChild ? (contextVars) => (
              <MemoizedItem
                node={node.children}
                renderChild={renderChild}
                contextVars={contextVars}
                layoutContext={layoutContext}
              />
            ) : undefined
            : undefined
        }
      >
        {!hasTextNodeChild && renderChild(node.children)}
      </OptionNative>
    );
  },
);

```

--------------------------------------------------------------------------------
/docs/public/pages/howto/paginate-a-list.md:
--------------------------------------------------------------------------------

```markdown
# Paginate a List

XMLUI provides a `Pagination` component that can be used to display visual controls for the pagination feature, no matter whether it is handled inside or outside of a layout component requiring that feature.

The [`Table`](./table) component provides out-of-the-box support for pagination,
so you can access pagination options via the following properties: `isPaginated`, `pageSize`, `pageSizeOptions`, `paginationControlsLocation`.

```xmlui noHeader copy
<Table
  data="/api/endpoint"
  isPaginated
  pageSize="10"
  pageSizeOptions="{[5, 10, 20, 30]}"
  paginationControlsLocation="both"
>
    ...
</Table>
```

Other components, such as the `List`, can be hooked up with pagination using a `DataSource` combined with the `Pagination` component. This pattern works as a more generic solution where either the component does not have pagination implemented in the component itself, or you wish to use custom pagination logic.

In this case the `DataSource` component does the heavy lifting by querying the page index, the previous and next page IDs. This can be done using variables and query parameters.

```xmlui-pg
---app display
<App var.pageSize="{5}" var.currentPage="{0}" var.before="{0}" var.after="{pageSize-1}">
  <DataSource id="pagination_ds" url="/api/pagination_items" queryParams="{{ from: before, to: after }}" />
  <Pagination
    itemCount="20"
    pageSize="{pageSize}"
    pageIndex="{currentPage}"
    onPageDidChange="(page, size, total) => {
      currentPage = page;
      before = page * size;
      after = before + size - 1;
    }"
  />
  <List data="{pagination_ds}" />
</App>
---api
{
  "apiUrl": "/api",
  "initialize": "$state.pagination_items = [{ id: 1, name: 'Laptop Pro', price: 1299 },{ id: 2, name: 'Wireless Mouse', price: 29 },{ id: 3, name: 'Mechanical Keyboard', price: 149 },{ id: 4, name: '4K Monitor', price: 399 },{ id: 5, name: 'USB-C Hub', price: 79 },{ id: 6, name: 'Bluetooth Headphones', price: 199 },{ id: 7, name: 'Webcam HD', price: 89 },{ id: 8, name: 'Standing Desk', price: 299 },{ id: 9, name: 'Ergonomic Chair', price: 249 },{ id: 10, name: 'Desk Lamp', price: 45 },{ id: 11, name: 'Cable Organizer', price: 15 },{ id: 12, name: 'Mouse Pad', price: 12 },{ id: 13, name: 'Laptop Stand', price: 35 },{ id: 14, name: 'External SSD', price: 129 },{ id: 15, name: 'Wireless Charger', price: 59 },{ id: 16, name: 'Smart Speaker', price: 99 },{ id: 17, name: 'Fitness Tracker', price: 199 },{ id: 18, name: 'Tablet Pro', price: 799 },{ id: 19, name: 'Gaming Mouse', price: 89 },{ id: 20, name: 'Noise Cancelling Headphones', price: 349 }]",
  "operations": {
    "get-pagination-items": {
      "url": "/pagination_items",
      "method": "get",
      "queryParams": {
        "from": "integer",
        "to": "integer"
      },
      "handler": "$state.pagination_items.slice(Number($queryParams.from), Number($queryParams.to) + 1);"
    }
  }
}
```

```

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

```markdown
# FormSection [#formsection]

`FormSection` groups elements within a `Form`. Child components are placed in a [FlowLayout](/components/FlowLayout).

## Properties [#properties]

### `columnGap` (default: "3rem") [#columngap-default-3rem]

The gap between columns of items within the section.

```xmlui-pg copy display name="Example: columnGap"
<Form padding="1rem">
  <FormSection columnGap="1rem">
    <FormItem width="50%" label="Name" bindTo="" />
    <FormItem width="50%" label="Occupation" bindTo="" />
  </FormSection>
</Form>
```

### `heading` [#heading]

The heading text to be displayed at the top of the form section.

```xmlui-pg copy display name="Example: heading"
<Form padding="1rem">
  <FormSection heading="Basic Heading">
    <FormItem label="Input Field" bindTo="" />
  </FormSection>
</Form>
```

### `headingLevel` (default: "h3") [#headinglevel-default-h3]

The semantic and visual level of the heading.

Available values: `h1`, `h2`, `h3` **(default)**, `h4`, `h5`, `h6`

```xmlui-pg copy display name="Example: headingLevel"
<Form padding="1rem">
  <FormSection heading="Basic Heading" headingLevel="h1">
    <FormItem label="Input Field" bindTo="" />
  </FormSection>
</Form>
```

### `headingWeight` (default: "bold") [#headingweight-default-bold]

The font weight of the heading.

The default weight is `bold`.

```xmlui-pg copy display name="Example: headingWeight"
<Form padding="1rem">
  <FormSection heading="Basic Heading" headingWeight="normal">
    <FormItem label="Input Field" bindTo="" />
  </FormSection>
</Form>
```

### `info` [#info]

Informational text displayed below the heading.

```xmlui-pg copy display name="Example: info"
<Form padding="1rem">
  <FormSection info="This is some information about a particular section.">
    <FormItem label="Input Field" bindTo="" />
  </FormSection>
</Form>
```

### `infoFontSize` (default: "0.8rem") [#infofontsize-default-0-8rem]

The font size of the informational text.

```xmlui-pg copy {4} display name="Example: infoFontSize"
<Form padding="1rem">
  <FormSection
    info="This is some information about a particular section."
    infoFontSize="18px"
  >
    <FormItem label="Input Field" bindTo="" />
  </FormSection>
</Form>
```

### `paddingTop` (default: "$space-normal") [#paddingtop-default-space-normal]

The top padding of the FlowLayout where the section's children are placed.

### `rowGap` (default: "$space-normal") [#rowgap-default-space-normal]

The gap between rows of items within the section.

```xmlui-pg copy display name="Example: rowGap"
<Form padding="1rem">
  <FormSection rowGap="2rem">
    <FormItem label="Name" bindTo="" />
    <FormItem label="Occupation" bindTo="" />
  </FormSection>
</Form>
```

## Events [#events]

This component does not have any events.

## Exposed Methods [#exposed-methods]

This component does not expose any methods.

## Styling [#styling]

This component does not have any styles.

```

--------------------------------------------------------------------------------
/packages/xmlui-devtools/src/devtools/ModalDialog.module.scss:
--------------------------------------------------------------------------------

```scss
@use "xmlui/themes.scss" as t;

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

// --- Theme vars for paddings
$themeVars: t.composePaddingVars($themeVars, $component);
$themeVars: t.composePaddingVars($themeVars, "overlay-#{$component}");
$padding-ModalDialog: createThemeVar("padding-#{$component}");
$backgroundColor-ModalDialog: createThemeVar("Dialog:backgroundColor-#{$component}");
$backgroundColor-overlay-ModalDialog: createThemeVar("Dialog:backgroundColor-overlay-#{$component}");
$borderRadius-ModalDialog: createThemeVar("Dialog:borderRadius-#{$component}");
$fontFamily-ModalDialog: createThemeVar("Dialog:fontFamily-#{$component}");
$textColor-ModalDialog: createThemeVar("Dialog:textColor-#{$component}");
$minWidth-ModalDialog: createThemeVar("Dialog:minWidth-#{$component}");
$maxWidth-ModalDialog: createThemeVar("Dialog:maxWidth-#{$component}");
$marginBottom-title-ModalDialog: createThemeVar("Dialog:marginBottom-title-#{$component}");


.overlay {
  position: fixed;
  overflow-y: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  inset: 0;
  padding: t.$space-4;
}

.overlayBg {
  background-color: $backgroundColor-overlay-ModalDialog;
  position: fixed;
  inset: 0;
}

.contentWrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
}

.content {
  background-color: $backgroundColor-ModalDialog;
  border-radius: $borderRadius-ModalDialog;
  font-family: $fontFamily-ModalDialog;
  color: $textColor-ModalDialog;
  box-shadow: t.$boxShadow-spread;
  width: 90vw;
  max-width: 960px;
  min-width: 240px;
  isolation: isolate;
  position: relative;
  display: flex;
  flex-direction: column;
  max-height: 80vh;
  overflow-y: auto;
}

.content:focus {
  outline: none;
}

.dialogTitle {
  flex: 1;
  margin-bottom: $marginBottom-title-ModalDialog;
  font-size: t.$fontSize-2xl;
}

.innerContent {
  display: flex;
  flex-direction: column;
  min-height: 0;
  gap: var(--stack-gap-default);
  flex: 1;
}

.closeButton {
  position: absolute;
  right: 0.5rem;
  top: 0.4rem;
}

.actions {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
}

.header {
  padding: t.$space-2;
  justify-content: space-between;
  display: flex;
  flex-direction: row;
  border-bottom: 1px solid t.$borderColor;
}

@media (max-width: 70em) {
  .dialog, .content {
    max-width: 90%;
  }
}

@media (max-width: 50em) {
  .dialog, .content {
    width: 100%;
    max-width: calc(100% - #{t.$space-6});
    min-width: 0 !important;
  }
}

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

```

--------------------------------------------------------------------------------
/xmlui/src/components/Stack/HStack.spec.ts:
--------------------------------------------------------------------------------

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

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

test.describe("Basic Functionality", () => {
  test("renders items horizontally", async ({ initTestBed, page }) => {
    await initTestBed(`
      <HStack testId="hstack">
        <Stack testId="item1" height="32px" width="32px" backgroundColor="red" />
        <Stack testId="item2" height="32px" width="32px" backgroundColor="blue" />
        <Stack testId="item3" height="32px" width="32px" backgroundColor="green" />
      </HStack>
    `);

    const hstack = page.getByTestId("hstack");
    const item1 = page.getByTestId("item1");
    const item2 = page.getByTestId("item2");
    const item3 = page.getByTestId("item3");

    await expect(hstack).toBeVisible();
    await expect(item1).toBeVisible();
    await expect(item2).toBeVisible();
    await expect(item3).toBeVisible();

    // Get bounding boxes to verify horizontal layout
    const item1Box = await item1.boundingBox();
    const item2Box = await item2.boundingBox();
    const item3Box = await item3.boundingBox();

    // Verify items are stacked horizontally (item2 should be to the right of item1, item3 to the right of item2)
    expect(item2Box!.x).toBeGreaterThan(item1Box!.x + item1Box!.width - 1); // -1 for floating point tolerance
    expect(item3Box!.x).toBeGreaterThan(item2Box!.x + item2Box!.width - 1); // -1 for floating point tolerance

    // Verify items are vertically aligned (should start at roughly the same y position)
    expect(Math.abs(item1Box!.y - item2Box!.y)).toBeLessThan(1);
    expect(Math.abs(item2Box!.y - item3Box!.y)).toBeLessThan(1);
  });

  test("renders empty HStack", async ({ initTestBed, page }) => {
    await initTestBed(`<HStack testId="hstack"></HStack>`);
    
    const hstack = page.getByTestId("hstack");
    await expect(hstack).toBeAttached();
    await expect(hstack).toBeEmpty();
  });

  test("ignores orientation property", async ({ initTestBed, page }) => {
    await initTestBed(`
      <HStack testId="hstack" orientation="vertical">
        <Stack testId="item1" height="32px" width="32px" backgroundColor="red" />
        <Stack testId="item2" height="32px" width="32px" backgroundColor="blue" />
      </HStack>
    `);

    const item1 = page.getByTestId("item1");
    const item2 = page.getByTestId("item2");

    await expect(item1).toBeVisible();
    await expect(item2).toBeVisible();

    // Get bounding boxes to verify still renders horizontally despite orientation="vertical"
    const item1Box = await item1.boundingBox();
    const item2Box = await item2.boundingBox();

    // Verify items are still stacked horizontally (orientation prop should be ignored)
    expect(item2Box!.x).toBeGreaterThan(item1Box!.x + item1Box!.width - 1);
  });
});

```

--------------------------------------------------------------------------------
/xmlui/bin/vite-xmlui-plugin.ts:
--------------------------------------------------------------------------------

```typescript
import { dataToEsm } from "@rollup/pluginutils";
import type { Plugin } from "vite";
import {
  collectCodeBehindFromSource,
  removeCodeBehindTokensFromTree,
} from "../src/parsers/scripting/code-behind-collect";
import {
  codeBehindFileExtension,
  componentFileExtension,
  moduleFileExtension,
} from "../src/parsers/xmlui-parser/fileExtensions";
import { Parser } from "../src/parsers/scripting/Parser";
import * as fs from "fs";
import * as path from "path";
import { errReportComponent, xmlUiMarkupToComponent } from "../src/components-core/xmlui-parser";

export type PluginOptions = {
  // --- Add plugin options here.
};

const xmluiExtension = new RegExp(`.${componentFileExtension}$`);
const xmluiScriptExtension = new RegExp(`.${codeBehindFileExtension}$`);
const moduleScriptExtension = new RegExp(`.${moduleFileExtension}$`);

/**
 * Transform XMLUI files to JS objects.
 */
export default function viteXmluiPlugin(pluginOptions: PluginOptions = {}): Plugin {
  let itemIndex = 0;
  return {
    name: "vite:transform-xmlui",

    async transform(code: string, id: string, options) {
      const moduleNameResolver = (moduleName: string) => {
        return path.resolve(path.dirname(id), moduleName);
      };

      if (xmluiExtension.test(id)) {
        const fileId = "" + itemIndex++;
        let { component, errors, erroneousCompoundComponentName } = xmlUiMarkupToComponent(
          code,
          fileId,
        );
        if (errors.length > 0) {
          component = errReportComponent(errors, id, erroneousCompoundComponentName);
        }
        const file = {
          component,
          src: code,
          file: fileId,
        };

        return {
          code: dataToEsm(file),
          map: { mappings: "" },
        };
      }

      const hasXmluiScriptExtension = xmluiScriptExtension.test(id);
      const hasModuleScriptExtension = moduleScriptExtension.test(id);
      if (hasXmluiScriptExtension || hasModuleScriptExtension) {
        // --- We parse the module file to catch parsing errors

        const parser = new Parser(code);
        parser.parseStatements();
        const moduleName = hasXmluiScriptExtension
          ? id.substring(0, id.length - (codeBehindFileExtension.length + 1))
          : id.substring(0, id.length - (moduleFileExtension.length + 1));

        const codeBehind = collectCodeBehindFromSource(moduleNameResolver(moduleName), code);
        removeCodeBehindTokensFromTree(codeBehind);

        // TODO: Add error handling.
        // Check, if codeBehind.moduleErrors is not empty (Record<string, ModuleErrors[]>); each module
        // should be checked for errors and warnings. If there are errors, throw an error.

        return {
          code: dataToEsm({...codeBehind, src: code}),
          map: { mappings: "" },
        };
      }
      return null;
    },
    // async generateBundle(opts, bundle, isWrite){
    //   console.log('generate bundle', opts);
    // }
  };
}

```

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

```typescript
import { useCallback } from "react";

import type {
  LoaderErrorFn,
  LoaderInProgressChangedFn,
  LoaderLoadedFn,
} from "../abstractions/LoaderRenderer";
import type { ComponentDef } from "../../abstractions/ComponentDefs";
import type { ContainerState } from "../rendering/ContainerWrapper";
import { removeNullProperties } from "../utils/misc";
import { extractParam } from "../utils/extractParam";
import { createLoaderRenderer } from "../renderers";
import { useAppContext } from "../AppContext";
import { Loader } from "./Loader";
import { createMetadata, d } from "../../components/metadata-helpers";

/**
 * Properties of the API loader component
 */
type ApiLoaderProps = {
  loader: ApiLoaderDef;
  loaderInProgressChanged: LoaderInProgressChangedFn;
  loaderIsRefetchingChanged: LoaderInProgressChangedFn;
  loaderLoaded: LoaderLoadedFn;
  loaderError: LoaderErrorFn;
  state: ContainerState;
  doNotRemoveNulls?: boolean;
  structuralSharing?: boolean;
};

/**
 * Represents a non-displayed React component, which handles the specified API loader
 */
function ApiLoader({
  loader,
  loaderInProgressChanged,
  loaderIsRefetchingChanged,
  loaderLoaded,
  loaderError,
  state,
  doNotRemoveNulls,
  structuralSharing = true,
}: ApiLoaderProps) {
  const appContext = useAppContext();

  const url = extractParam(state, loader.props.url, appContext);
  const loadable = !!url;

  const doLoad = useCallback(async () => {
    if (!loadable) {
      return;
    }
    const response = await fetch(url);
    if (loader.props.raw) {
      return await response.text();
    }
    const responseObj = await response.json();
    if (!doNotRemoveNulls) {
      removeNullProperties(responseObj);
    }
    return responseObj;
  }, [doNotRemoveNulls, loadable, loader.props.raw, url]);

  return (
    <Loader
      state={state}
      loader={loader}
      loaderInProgressChanged={loaderInProgressChanged}
      loaderIsRefetchingChanged={loaderIsRefetchingChanged}
      loaderLoaded={loaderLoaded}
      loaderError={loaderError}
      loaderFn={doLoad}
      structuralSharing={structuralSharing}
    />
  );
}

const ApiLoaderMd = createMetadata({
  status: "stable",
  description: `Represents a loader that calls an API through an HTTP/HTTPS GET request`,
  props: {
    url: d("URL segment to use in the GET request"),
    raw: d("If true, the loader returns the raw text response instead of parsing it as JSON"),
  },
});

type ApiLoaderDef = ComponentDef<typeof ApiLoaderMd>;

export const apiLoaderRenderer = createLoaderRenderer(
  "ApiLoader",
  ({ loader, state, loaderInProgressChanged, loaderIsRefetchingChanged, loaderLoaded, loaderError }) => {
    return (
      <ApiLoader
        loader={loader}
        state={state}
        loaderInProgressChanged={loaderInProgressChanged}
        loaderIsRefetchingChanged={loaderIsRefetchingChanged}
        loaderLoaded={loaderLoaded}
        loaderError={loaderError}
      />
    );
  },
  ApiLoaderMd,
);

```

--------------------------------------------------------------------------------
/xmlui/src/components/ToneChangerButton/ToneChangerButton.tsx:
--------------------------------------------------------------------------------

```typescript
import { useThemes } from "../../components-core/theming/ThemeContext";
import { createComponentRenderer } from "../../components-core/renderers";
import { Button } from "../Button/ButtonNative";
import { Icon } from "../Icon/IconNative";
import { createMetadata, dClick } from "../metadata-helpers";
import { noop } from "lodash-es";

const COMP = "ToneChangerButton";
const LIGHT_TO_DARK_ICON = "lightToDark:ToneChangerButton";
const DARK_TO_LIGHT_ICON = "darkToLight:ToneChangerButton";

export const defaultProps = {
  lightToDarkIcon: LIGHT_TO_DARK_ICON,
  darkToLightIcon: DARK_TO_LIGHT_ICON,
  onClick: noop,
};

export const ToneChangerButtonMd = createMetadata({
  status: "stable",
  description: "`ToneChangerButton` enables the user to switch between light and dark modes.",
  props: {
    lightToDarkIcon: {
      description:
        `The icon displayed when the theme is in light mode and will switch to dark. You can change ` +
        `the default icon for all ${COMP} instances with the "icon.lightToDark:ToneChangerButton" ` +
        `declaration in the app configuration file.`,
      defaultValue: defaultProps.lightToDarkIcon,
    },
    darkToLightIcon: {
      description:
        `The icon displayed when the theme is in dark mode and will switch to light. You can change ` +
        `the default icon for all ${COMP} instances with the "icon.darkToLight:ToneChangerButton" ` +
        `declaration in the app configuration file.`,
      defaultValue: defaultProps.darkToLightIcon,
    },
  },
  events: {
    click: dClick(COMP),
  },
});

export function ToneChangerButton({
  lightToDarkIcon = defaultProps.lightToDarkIcon,
  darkToLightIcon = defaultProps.darkToLightIcon,
  onClick = defaultProps.onClick,
}) {
  const { activeThemeTone, setActiveThemeTone } = useThemes();

  // Use the direct icon name as both the main icon and the fallback
  // This ensures we always have a working icon
  const iconName = activeThemeTone === "light" ? lightToDarkIcon : darkToLightIcon;
  const fallbackIcon = activeThemeTone === "light" ? "lightToDark" : "darkToLight";

  return (
    <Button
      variant="ghost"
      style={{ flexShrink: 0 }}
      icon={<Icon name={iconName} fallback={fallbackIcon} />}
      onClick={() => {
        if (activeThemeTone === "light") {
          setActiveThemeTone("dark");
          onClick?.("dark");
        } else {
          setActiveThemeTone("light");
          onClick?.("light");
        }
      }}
    />
  );
}

/**
 * Define the renderer for the ToneChangerButton component
 */
export const toneChangerButtonComponentRenderer = createComponentRenderer(
  COMP,
  ToneChangerButtonMd,
  ({ node, extractValue, lookupEventHandler }) => {
    return (
      <ToneChangerButton
        onClick={lookupEventHandler("click")}
        lightToDarkIcon={extractValue.asOptionalString(node.props.lightToDarkIcon)}
        darkToLightIcon={extractValue.asOptionalString(node.props.darkToLightIcon)}
      />
    );
  },
);

```

--------------------------------------------------------------------------------
/xmlui/src/components/Pages/PagesNative.tsx:
--------------------------------------------------------------------------------

```typescript
import type { CSSProperties, ReactNode } from "react";
import { useMemo } from "react";
import { Navigate, Route, Routes, useParams } from "@remix-run/react";
import classnames from "classnames";

import type { ComponentDef } from "../../abstractions/ComponentDefs";
import type { LayoutContext, RenderChildFn, ValueExtractor } from "../../abstractions/RendererDefs";
import { EMPTY_ARRAY, EMPTY_OBJECT } from "../../components-core/constants";
import type { PageMd } from "./Pages";
import styles from "./Pages.module.scss";

// Default props for Pages component
export const defaultProps = {
  fallbackPath: "/",
};

// --- We need this component to make sure all the child routes are wrapped in a
// --- container and  this way they can access the routeParams
type RouteWrapperProps = {
  childRoute?: ComponentDef | Array<ComponentDef>;
  renderChild: RenderChildFn;
  layoutContext?: LayoutContext;
  style?: CSSProperties;
  className?: string;
  uid?: string;
};

export function RouteWrapper({
  childRoute = EMPTY_ARRAY,
  renderChild,
  layoutContext,
  style,
  className,
  uid,
}: RouteWrapperProps) {
  const params = useParams();

  //we need to wrap the child route in a container to make sure the route params are available.
  // we do this wrapping by providing an empty object to vars.
  // this way it becomes an 'implicit' container (vars/state inside this container is propagated to the parent)
  const wrappedWithContainer = useMemo(() => {
    if (Array.isArray(childRoute)) {
      return {
        type: "Fragment",
        uid,
        vars: EMPTY_OBJECT,
        children: childRoute,
      };
    }
    return {
      type: "Fragment",
      uid,
      vars: EMPTY_OBJECT,
      children: [childRoute],
    };
  }, [childRoute, uid]);

  return (
    <div
      key={JSON.stringify(params)}
      className={classnames(className, styles.wrapper, "xmlui-page-root")}
      style={style}
    >
      {renderChild(wrappedWithContainer, layoutContext)}
    </div>
  );
}

type PageComponentDef = ComponentDef<typeof PageMd>;

type PagesProps = {
  fallbackPath?: string;
  node?: ComponentDef;
  renderChild: RenderChildFn;
  extractValue: ValueExtractor;
  children?: ReactNode;
  className?: ReactNode;
};

export function Pages({
  node,
  renderChild,
  extractValue,
  fallbackPath = defaultProps.fallbackPath,
}: PagesProps) {
  const routes: Array<PageComponentDef> = [];
  const restChildren: Array<ComponentDef> = [];
  node.children?.forEach((child) => {
    if (child.type === "Page") {
      routes.push(child as PageComponentDef);
    } else {
      restChildren.push(child);
    }
  });
  return (
    <>
      <Routes>
        {routes.map((child, i) => {
          return (
            <Route path={extractValue(child.props.url)} key={i} element={renderChild(child)} />
          );
        })}
        {fallbackPath && <Route path="*" element={<Navigate to={fallbackPath} replace  />} />}
      </Routes>
      {renderChild(restChildren)}
    </>
  );
}

```

