#
tokens: 49643/50000 32/1629 files (page 11/186)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 11 of 186. Use http://codebase.md/xmlui-org/xmlui/main.tsx?lines=true&page={x} to view the full context.

# Directory Structure

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

# Files

--------------------------------------------------------------------------------
/xmlui/tests-e2e/state-var-scopes.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { test, expect } from "../src/testing/fixtures";
 2 | 
 3 | test("vars shadowing works", async ({ initTestBed, page }) => {
 4 |   await initTestBed(`
 5 |     <Stack var.x="x in outer stack" var.y="y in outer stack">
 6 |       <Stack var.y="y in inner stack">
 7 |         <Button testId="button" onClick="y = 123">change y in inner stack</Button>
 8 |         <Text testId="y_in_inner_stack">{y}</Text>
 9 |       </Stack>
10 |       <Text testId="y_in_outer_stack">{y}</Text>
11 |     </Stack>
12 |   `);
13 |   await page.getByTestId("button").click();
14 |   await expect(page.getByTestId("y_in_inner_stack")).toHaveText("123");
15 |   await expect(page.getByTestId("y_in_outer_stack")).toHaveText("y in outer stack");
16 | });
17 | 
18 | test("inner input is available in the file (implicit containers because of vars)", async ({
19 |   initTestBed,
20 |   page,
21 | }) => {
22 |   await initTestBed(`
23 |     <Fragment>
24 |       <Stack var.x="x in outer stack" var.y="y in outer stack">
25 |         <Stack var.y="y in inner stack">
26 |           <TextBox id="textbox"/>
27 |         </Stack>
28 |       </Stack>
29 |       <Text testId="textbox_value_outside">{textbox.value}</Text>
30 |     </Fragment>
31 |   `);
32 |   await page.getByTestId("textbox").getByRole("textbox").fill("textbox-value");
33 |   await expect(page.getByTestId("textbox_value_outside")).toHaveText("textbox-value");
34 | });
35 | 
36 | test("inner datasource is available in the file (implicit containers because of vars)", async ({
37 |   initTestBed,
38 |   page,
39 | }) => {
40 |   await initTestBed(
41 |     `
42 |     <Fragment>
43 |       <Stack var.x="x in outer stack" var.y="y in outer stack">
44 |         <Stack var.y="y in inner stack">
45 |           <DataSource url="/data1" id="explicitDataSource"/>
46 |         </Stack>
47 |       </Stack>
48 |       <Text testId="datasource_value_outside">{explicitDataSource.value}</Text>
49 |     </Fragment>
50 |     `,
51 |     {
52 |       apiInterceptor: {
53 |         operations: {
54 |           "load-api-data1": {
55 |             url: "/data1",
56 |             method: "get",
57 |             handler: `()=>{
58 |             return 'data1';
59 |           }`,
60 |           },
61 |         },
62 |       },
63 |     },
64 |   );
65 |   await expect(page.getByTestId("datasource_value_outside")).toHaveText("data1");
66 | });
67 | 
```

--------------------------------------------------------------------------------
/docs/public/pages/intro.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Introduction
 2 | 
 3 | XMLUI is a framework for building user interfaces declaratively, with XML markup and flexible theming. XMLUI apps are:
 4 | 
 5 | - **Easy to create**. Build on the web platform with little or no knowledge of React or CSS.
 6 | - **Clean and modern**. Enjoy themes that look great out of the box and are easy to modify. Create experiences that meet expectations for modern web apps.
 7 | - **Connected**. Read and write APIs with little or no scripting.
 8 | - **Modular**. Use a comprehensive suite of [components](/components/_overview) that you can extend with — again! — little or no scripting.
 9 | - **Easy to deploy**. Just drop a handful of files onto a static webserver.
10 | 
11 | This paragraph is static text displayed by XMLUI's [Markdown](/components/Markdown) component.
12 | 
13 | This list is a live report on the status of London's tube stations.
14 | 
15 | ```xmlui-pg name="London Tube Status"
16 | <App>
17 |   <List data="https://api.tfl.gov.uk/line/mode/tube/status">
18 |      <Text>{$item.name}: {$item.lineStatuses[0].statusSeverityDescription}</Text>
19 |   </List>
20 | </App>
21 | ```
22 | 
23 | When you reload the page you'll see fresh data.
24 | 
25 | > [!INFO]
26 | > You can use the ![](/resources/pg-popout.svg) icon to open live elements, like the London Tube Status report, in a playground where you read and edit the XMLUI markup.
27 | 
28 | This is the XMLUI markup you'll see in the playground.
29 | 
30 | ```xmlui
31 | <List data="https://api.tfl.gov.uk/line/mode/tube/status">
32 |   <Text>{$item.name}: {$item.lineStatuses[0].statusSeverityDescription}</Text>
33 | </List>
34 | ```
35 | 
36 | The [List](/components/List) component fetches JSON from a <a href="https://api.tfl.gov.uk/line/mode/tube/status" target="_blank">REST endpoint</a>, iterates through the array of objects returned from the API, and updates the [context variable](context-variables) called `$item` for each object. The [Text](/components/Text) component uses JavaScript dot notation and array indexing to extract station names and statuses from each `$item`.
37 | 
38 | In this case the URL is static. In the next chapter you'll see how a data URL can vary to deliver changing data in response to UI interaction.
39 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/Stack/StackNative.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import { type CSSProperties, forwardRef, type ReactNode, type Ref } from "react";
 2 | import classnames from "classnames";
 3 | 
 4 | import styles from "./Stack.module.scss";
 5 | 
 6 | import { useContentAlignment } from "../../components-core/component-hooks";
 7 | import { useOnMount } from "../../components-core/utils/hooks";
 8 | 
 9 | export const DEFAULT_ORIENTATION = "vertical";
10 | 
11 | export const defaultProps = {
12 |   orientation: DEFAULT_ORIENTATION,
13 |   reverse: false,
14 |   hoverContainer: false,
15 |   visibleOnHover: false,
16 | };
17 | 
18 | type Props = {
19 |   children: ReactNode;
20 |   orientation?: string;
21 |   uid?: string;
22 |   horizontalAlignment?: string;
23 |   verticalAlignment?: string;
24 |   style?: CSSProperties;
25 |   className?: string;
26 |   reverse?: boolean;
27 |   hoverContainer?: boolean;
28 |   visibleOnHover?: boolean;
29 |   onClick?: any;
30 |   onMount?: any;
31 | };
32 | 
33 | // =====================================================================================================================
34 | // Stack React component
35 | 
36 | export const Stack = forwardRef(function Stack(
37 |   {
38 |     uid,
39 |     children,
40 |     orientation = defaultProps.orientation,
41 |     horizontalAlignment,
42 |     verticalAlignment,
43 |     style,
44 |     reverse = defaultProps.reverse,
45 |     hoverContainer = defaultProps.hoverContainer,
46 |     visibleOnHover = defaultProps.visibleOnHover,
47 |     onClick,
48 |     onMount,
49 |     className,
50 |     ...rest
51 |   }: Props,
52 |   ref: Ref<any>,
53 | ) {
54 |   useOnMount(onMount);
55 |   const { horizontal, vertical } = useContentAlignment(
56 |     orientation,
57 |     horizontalAlignment,
58 |     verticalAlignment,
59 |   );
60 |   return (
61 |     <div
62 |       {...rest}
63 |       onClick={onClick}
64 |       ref={ref}
65 |       style={style}
66 |       className={classnames(
67 |         className,
68 |         styles.base,
69 |         {
70 |           [styles.vertical]: orientation === "vertical",
71 |           [styles.horizontal]: orientation === "horizontal",
72 |           [styles.reverse]: reverse,
73 |           [styles.hoverContainer]: hoverContainer,
74 |           "display-on-hover": visibleOnHover,
75 |           [styles.handlesClick]: !!onClick,
76 |         },
77 |         horizontal ?? "",
78 |         vertical ?? "",
79 |       )}
80 |     >
81 |       {children}
82 |     </div>
83 |   );
84 | });
85 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components-core/theming/themeVars.ts:
--------------------------------------------------------------------------------

```typescript
 1 | /**
 2 |  * The sole purpose of this module is to provide an object with the available keys of theme SCSS variables and the
 3 |  * prefix of the theme.
 4 |  */
 5 | import themeVars from "./themeVars.module.scss";
 6 | 
 7 | /**
 8 |  * This function extracts CSS variables from the specified SCSS input. It uses a hack to convert the CSS input to JSON
 9 |  * and then calls a JSON parser to create the desired object.
10 |  * @param scssStr The scss input
11 |  */
12 | export function parseScssVar(scssStr: any) {
13 |   if (!scssStr || typeof scssStr !== typeof "") {
14 |     return scssStr;
15 |   }
16 | 
17 |   // Lists and maps are surrounded by single quotes, e.g. "'[ \"string in list\", 5, \"5px\" ]'"
18 |   // Remove them if they exist so they can be parsed correctly.
19 |   let jsValue = scssStr.replace(/(^['"])|(['"]$)/g, "");
20 | 
21 |   try {
22 |     // JSON-formatted string from within SCSS file
23 |     return JSON.parse(jsValue);
24 |   } catch (errorParsingJsonGeneratedInUtilScssFile) {
25 |     try {
26 |       // Value was likely an SCSS literal string; attempt parsing it manually.
27 |       // Example: inspect($my-map) => '(num: 10, numWithUnits: 5px, str: hello, color: #fff, "keyAsStr": false, other: null)'
28 |       return JSON.parse(
29 |         scssStr
30 |           .replace("(", "{")
31 |           .replace(")", "}")
32 |           // JSON values: convert any collection of word characters followed by a comma or bracket to a string
33 |           .replace(/: ?([^,}]+)([,}])/g, ': "$1"$2')
34 |           // JSON keys: space/bracket/comma as first character, not already a string, anything not colon or
35 |           // space (rules out JSON values), ended by colon
36 |           .replace(/([\s{,])(?!")([^:\s]+)+:/g, '$1"$2":'),
37 |       );
38 |     } catch (errorParsingScssStringLiteral) {
39 |       return jsValue;
40 |     }
41 |   }
42 | }
43 | 
44 | let keyPrefix = parseScssVar(themeVars.keyPrefix) || "";
45 | let vars = parseScssVar(themeVars.themeVars);
46 | 
47 | /**
48 |  * Export the desired SCSS variables and prefix
49 |  */
50 | const theme = {
51 |   keyPrefix: keyPrefix,
52 |   themeVars: vars,
53 | };
54 | 
55 | export function getVarKey(varName: string) {
56 |   if (keyPrefix) {
57 |     return `--${keyPrefix}-${varName}`;
58 |   }
59 |   return `--${varName}`;
60 | }
61 | 
62 | export default theme;
63 | 
```

--------------------------------------------------------------------------------
/packages/xmlui-playground/src/providers/ToastProvider.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import { createContext, useState, type ReactNode } from "react";
 2 | import { noop } from "lodash-es";
 3 | import * as RadixToast from "@radix-ui/react-toast";
 4 | import styles from "./Toast.module.scss";
 5 | import { MdOutlineClose } from "react-icons/md";
 6 | import classnames from "classnames";
 7 | 
 8 | type ToastMessage = {
 9 |   type: "success" | "warning" | "error" | "info";
10 |   title?: string;
11 |   description: string;
12 | };
13 | 
14 | type ToastContextDefinition = {
15 |   toastMessage: ToastMessage | null;
16 |   showToast: (toastMessage: ToastMessage) => void;
17 | };
18 | 
19 | export const ToastContext = createContext<ToastContextDefinition>({
20 |   toastMessage: null,
21 |   showToast: noop,
22 | });
23 | 
24 | type ToastProviderProps = {
25 |   children: ReactNode;
26 | };
27 | 
28 | export const ToastProvider = ({ children }: ToastProviderProps) => {
29 |   const [toastMessage, setToastMessage] = useState<ToastMessage | null>(null);
30 |   const [open, setOpen] = useState(false);
31 | 
32 |   const showToast = (toastMessage: ToastMessage) => {
33 |     setToastMessage(toastMessage);
34 |     setOpen(true);
35 |   };
36 | 
37 |   return (
38 |     <ToastContext.Provider value={{ toastMessage, showToast }}>
39 |       <RadixToast.Provider swipeDirection="right">
40 |         {children}
41 |         <RadixToast.Root
42 |           open={open}
43 |           onOpenChange={setOpen}
44 |           className={classnames(styles.ToastRoot, {
45 |             [styles.success]: toastMessage?.type === "success",
46 |             [styles.warning]: toastMessage?.type === "warning",
47 |             [styles.error]: toastMessage?.type === "error",
48 |           })}
49 |         >
50 |           <RadixToast.Close className={styles.ToastClose}>
51 |             <MdOutlineClose />
52 |           </RadixToast.Close>
53 |           {toastMessage?.title && (
54 |             <RadixToast.Title className={styles.ToastTitle}>{toastMessage?.title}</RadixToast.Title>
55 |           )}
56 |           <RadixToast.Description className={styles.ToastDescription} asChild>
57 |             <div>{toastMessage?.description}</div>
58 |           </RadixToast.Description>
59 |         </RadixToast.Root>
60 |         <RadixToast.Viewport className={styles.ToastViewport} />
61 |       </RadixToast.Provider>
62 |     </ToastContext.Provider>
63 |   );
64 | };
65 | 
```

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

```typescript
 1 | import { createComponentRenderer } from "../../components-core/renderers";
 2 | import styles from "./Icon.module.scss";
 3 | import { parseScssVar } from "../../components-core/theming/themeVars";
 4 | import Icon from "./IconNative";
 5 | import { createMetadata, d } from "../metadata-helpers";
 6 | 
 7 | const COMP = "Icon";
 8 | 
 9 | export const IconMd = createMetadata({
10 |   status: "stable",
11 |   description:
12 |     "`Icon` displays scalable vector icons from XMLUI's built-in icon registry " +
13 |     "using simple name references. Icons are commonly used in buttons, navigation " +
14 |     "elements, and status indicators.",
15 |   props: {
16 |     name: d(
17 |       "This string property specifies the name of the icon to display. All icons have " +
18 |         "unique, case-sensitive names identifying them. If the icon name is not set, the " +
19 |         "`fallback` value is used.",
20 |     ),
21 |     size: {
22 |       description:
23 |         `This property defines the size of the \`${COMP}\`. Note that setting the \`height\` and/or ` +
24 |         `the \`width\` of the component will override this property. You can use az explicit size ` +
25 |         "value (e.g., 32px) or one of these predefined values: `xs`, `sm`, `md`, `lg`.",
26 |       availableValues: ["xs", "sm", "md", "lg"],
27 |     },
28 |     fallback: d(
29 |       "This optional property provides a way to handle situations when the icon with the provided " +
30 |         "[icon name](#name) name does not exist. If the icon cannot be found, no icon is displayed.",
31 |     ),
32 |   },
33 |   events: {
34 |     click: d("This event is triggered when the icon is clicked."),
35 |   },
36 | 
37 |   themeVars: parseScssVar(styles.themeVars),
38 |   defaultThemeVars: {
39 |     [`size-${COMP}`]: "1.2em",
40 |   },
41 | });
42 | 
43 | export const iconComponentRenderer = createComponentRenderer(
44 |   COMP,
45 |   IconMd,
46 |   ({ node, extractValue, className, lookupEventHandler }) => {
47 |     return (
48 |       <Icon
49 |         name={extractValue.asOptionalString(node.props.name)}
50 |         size={extractValue(node.props.size)}
51 |         className={className}
52 |         fallback={extractValue.asOptionalString(node.props.fallback)}
53 |         onClick={lookupEventHandler("click")}
54 |       />
55 |     );
56 |   },
57 | );
58 | 
```

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

```markdown
 1 | # Spinner [#spinner]
 2 | 
 3 | `Spinner` is an animated indicator that represents an action in progress with no deterministic progress value.
 4 | 
 5 | While it is visible, the action is yet to be completed; on completion, the UI logic may opt to remove the component.
 6 | 
 7 | ## Using the `Spinner` [#using-the-spinner]
 8 | 
 9 | ```xmlui-pg copy display name="Example: using Spinner"
10 | <App>
11 |   <Spinner />
12 | </App>
13 | ```
14 | 
15 | >[!INFO]
16 | > `Spinner` ignores the `width`, `minWidth`, `maxWidth`, `height`, `minHeight`, and `maxHeight` properties. If you want to change its size, use the `size-Spinner` theme variable (see details is the [Styling](#styling) section).
17 | 
18 | ## Properties [#properties]
19 | 
20 | ### `delay` (default: 400) [#delay-default-400]
21 | 
22 | The delay in milliseconds before the spinner is displayed.
23 | 
24 | Use the buttons to toggle between the two `Spinners`.
25 | 
26 | ```xmlui-pg copy {8-9} display name="Example: delay"
27 | <App>
28 |   <variable name="noDelay" value="{true}" />
29 |   <variable name="yesDelay" value="{false}" />
30 |   <HStack gap="$space-0_5">
31 |     <Button label="No delay" onClick="noDelay = true; yesDelay = false;" />
32 |     <Button label="1000 ms delay" onClick="noDelay = false; yesDelay = true;" />
33 |   </HStack>
34 |   <Spinner when="{noDelay}" delay="0" />
35 |   <Spinner when="{yesDelay}" delay="1000" />
36 | </App>
37 | ```
38 | 
39 | ### `fullScreen` (default: false) [#fullscreen-default-false]
40 | 
41 | If set to `true`, the component will be rendered in a full screen container.
42 | 
43 | ```xmlui-pg copy display name="Example: fullScreen" height="200px"
44 | <App>
45 |   <Spinner fullScreen="true" />
46 | </App>
47 | ```
48 | 
49 | ## Events [#events]
50 | 
51 | This component does not have any events.
52 | 
53 | ## Exposed Methods [#exposed-methods]
54 | 
55 | This component does not expose any methods.
56 | 
57 | ## Styling [#styling]
58 | 
59 | ### Theme Variables [#theme-variables]
60 | 
61 | | Variable | Default Value (Light) | Default Value (Dark) |
62 | | --- | --- | --- |
63 | | [borderColor](../styles-and-themes/common-units/#color)-Spinner | $color-surface-400 | $color-surface-400 |
64 | | [size](../styles-and-themes/common-units/#size)-Spinner | $space-10 | $space-10 |
65 | | [thickness](../styles-and-themes/common-units/#size)-Spinner | $space-0_5 | $space-0_5 |
66 | 
```

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

```typescript
 1 | import type { ThemeTone } from "../../abstractions/ThemingDefs";
 2 | import { createComponentRenderer } from "../../components-core/renderers";
 3 | import { createMetadata, d } from "../metadata-helpers";
 4 | import { Theme, defaultProps } from "./ThemeNative";
 5 | 
 6 | const COMP = "Theme";
 7 | 
 8 | export const ThemeMd = createMetadata({
 9 |   status: "stable",
10 |   description:
11 |     "`Theme` creates styling contexts to customize the appearance of nested " +
12 |     "components without using CSS.",
13 |   allowArbitraryProps: true,
14 |   props: {
15 |     themeId: d(`This property specifies which theme to use by setting the theme's id.`),
16 |     tone: {
17 |       description: "This property allows the setting of the current theme's tone.",
18 |       availableValues: ["light", "dark"],
19 |       valueType: "string",
20 |       defaultValue: "light",
21 |     },
22 |     root: d(
23 |       `This property indicates whether the component is at the root of the application.`,
24 |       undefined,
25 |       "boolean",
26 |       defaultProps.root,
27 |     ),
28 |     applyIf: d(
29 |       `This property controls whether the theme wrapper is applied. When true (default), the theme wraps the children. When false, children are rendered unwrapped.`,
30 |       undefined,
31 |       "boolean",
32 |       true,
33 |     ),
34 |   },
35 |   opaque: true,
36 | });
37 | 
38 | export const themeComponentRenderer = createComponentRenderer(
39 |   COMP,
40 |   ThemeMd,
41 |   ({ node, extractValue, renderChild, layoutContext, appContext }) => {
42 |     const { tone, ...restProps } = node.props;
43 |     const toastDuration = appContext?.appGlobals?.notifications?.duration;
44 |     let themeTone = extractValue.asOptionalString(tone);
45 |     if (themeTone && themeTone !== "dark") {
46 |       themeTone = "light";
47 |     }
48 |     return (
49 |       <Theme
50 |         id={extractValue.asOptionalString(node.props.themeId)}
51 |         isRoot={extractValue.asOptionalBoolean(node.props.root)}
52 |         applyIf={extractValue.asOptionalBoolean(node.props.applyIf)}
53 |         layoutContext={layoutContext}
54 |         renderChild={renderChild}
55 |         tone={themeTone as ThemeTone}
56 |         toastDuration={toastDuration}
57 |         themeVars={extractValue(restProps)}
58 |         node={node}
59 |       />
60 |     );
61 |   },
62 | );
63 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/Charts/Tooltip/TooltipContent.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import type React from "react";
 2 | import { forwardRef } from "react";
 3 | import styles from "./TooltipContent.module.scss";
 4 | import classnames from "classnames";
 5 | import type { Tooltip as RTooltip } from "recharts";
 6 | 
 7 | export const TooltipContent = forwardRef<
 8 |   HTMLDivElement,
 9 |   React.ComponentProps<typeof RTooltip> &
10 |     React.ComponentProps<"div"> & {
11 |       hideLabel?: boolean;
12 |       hideIndicator?: boolean;
13 |       indicator?: "line" | "dot" | "dashed";
14 |       nameKey?: string;
15 |       labelKey?: string;
16 |     }
17 | >(function ({ active, payload, indicator = "dot", hideLabel = false, label, color }, ref) {
18 |   if (active && payload && payload.length) {
19 |     const nestLabel = payload.length === 1 && indicator !== "dot";
20 |     return (
21 |       <div className={styles.tooltipContainer} ref={ref}>
22 |         {!hideLabel && <p className="label">{label}</p>}
23 | 
24 |         <div className={styles.gridGap}>
25 |           {payload?.map((item: any, index: any) => {
26 |             const indicatorColor = color || item.payload?.fill || item.color;
27 |             return (
28 |               <div key={index} className={styles.itemContainer}>
29 |                 <div
30 |                   className={classnames(styles.indicator, {
31 |                     [styles.dot]: indicator === "dot",
32 |                     [styles.line]: indicator === "line",
33 |                     [styles.dashed]: indicator === "dashed",
34 |                     [styles.nestDashed]: nestLabel && indicator === "dashed",
35 |                   })}
36 |                   style={{ backgroundColor: indicatorColor, borderColor: indicatorColor }}
37 |                 />
38 |                 <div className={styles.valueContainer}>
39 |                   <div className={styles.labelGrid}>
40 |                     <span className={styles.mutedText}>{item.name}</span>
41 |                   </div>
42 |                   {item.value && (
43 |                     <span className={styles.valueText}>{item.value.toLocaleString()}</span>
44 |                   )}
45 |                 </div>
46 |               </div>
47 |             );
48 |           })}
49 |         </div>
50 |       </div>
51 |     );
52 |   }
53 | 
54 |   return null;
55 | });
56 | 
57 | TooltipContent.displayName = "TooltipContent";
58 | 
```

--------------------------------------------------------------------------------
/blog/public/web.config:
--------------------------------------------------------------------------------

```
 1 | <?xml version="1.0" encoding="utf-8" ?>
 2 | <configuration>
 3 |     <system.webServer>
 4 |        <staticContent>
 5 |             <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="365.00:00:00" />
 6 | 
 7 |             <mimeMap fileExtension=".json" mimeType="application/json" />
 8 |             <mimeMap fileExtension=".rss" mimeType="application/rss+xml" />
 9 |             <mimeMap fileExtension=".ts" mimeType="application/x-typescript" />
10 |             <mimeMap fileExtension=".xmlui" mimeType="application/xmlui" />
11 |             <mimeMap fileExtension=".xmlui.xs" mimeType="application/xmlui-xs" />
12 |             <mimeMap fileExtension="woff" mimeType="application/font-woff" />
13 |             <mimeMap fileExtension="woff2" mimeType="application/font-woff2" />
14 |             <mimeMap fileExtension="md" mimeType="text/markdown" />
15 |        </staticContent>
16 |        <rewrite>
17 |             <rules>
18 |                 <rule name="RewriteHTML" stopProcessing="true">
19 |                     <match url="^([^.]+)$" />
20 |                     <conditions>
21 |                         <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
22 |                         <add input="{REQUEST_FILENAME}.html" matchType="IsFile" />
23 |                     </conditions>
24 |                     <action type="Rewrite" url="{R:1}.html" />
25 |                 </rule>
26 |                 <remove name="pushState" />
27 |                 <rule name="pushState" stopProcessing="true">
28 |                     <match url=".*" />
29 |                     <conditions logicalGrouping="MatchAll">
30 |                         <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
31 |                         <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
32 |                     </conditions>
33 |                     <action type="Rewrite" url="/" />
34 |                 </rule>
35 |                 <rule name="Playground" stopProcessing="true">
36 |                     <match url="^playground$" />
37 |                     <action type="Rewrite" url="/playground" />
38 |                 </rule>
39 |             </rules>
40 |        </rewrite>
41 |     </system.webServer>
42 | </configuration>
43 | 
```

--------------------------------------------------------------------------------
/docs/public/web.config:
--------------------------------------------------------------------------------

```
 1 | <?xml version="1.0" encoding="utf-8" ?>
 2 | <configuration>
 3 |     <system.webServer>
 4 |        <staticContent>
 5 |             <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="365.00:00:00" />
 6 | 
 7 |             <mimeMap fileExtension=".json" mimeType="application/json" />
 8 |             <mimeMap fileExtension=".rss" mimeType="application/rss+xml" />
 9 |             <mimeMap fileExtension=".ts" mimeType="application/x-typescript" />
10 |             <mimeMap fileExtension=".xmlui" mimeType="application/xmlui" />
11 |             <mimeMap fileExtension=".xmlui.xs" mimeType="application/xmlui-xs" />
12 |             <mimeMap fileExtension="woff" mimeType="application/font-woff" />
13 |             <mimeMap fileExtension="woff2" mimeType="application/font-woff2" />
14 |             <mimeMap fileExtension="md" mimeType="text/markdown" />
15 |        </staticContent>
16 |        <rewrite>
17 |             <rules>
18 |                 <rule name="RewriteHTML" stopProcessing="true">
19 |                     <match url="^([^.]+)$" />
20 |                     <conditions>
21 |                         <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
22 |                         <add input="{REQUEST_FILENAME}.html" matchType="IsFile" />
23 |                     </conditions>
24 |                     <action type="Rewrite" url="{R:1}.html" />
25 |                 </rule>
26 |                 <remove name="pushState" />
27 |                 <rule name="pushState" stopProcessing="true">
28 |                     <match url=".*" />
29 |                     <conditions logicalGrouping="MatchAll">
30 |                         <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
31 |                         <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
32 |                     </conditions>
33 |                     <action type="Rewrite" url="/" />
34 |                 </rule>
35 |                 <rule name="Playground" stopProcessing="true">
36 |                     <match url="^playground$" />
37 |                     <action type="Rewrite" url="/playground" />
38 |                 </rule>
39 |             </rules>
40 |        </rewrite>
41 |     </system.webServer>
42 | </configuration>
43 | 
```

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

```typescript
 1 | import { describe, expect, it } from "vitest";
 2 | import { handleHoverCore } from "../../src/language-server/services/hover";
 3 | import { createXmlUiParser } from "../../src/parsers/xmlui-parser";
 4 | import { mockMetadataProvider } from "./mockData";
 5 | import { MarkupContent } from "vscode-languageserver";
 6 | 
 7 | describe("Hover", () => {
 8 |   it("documents component description", () => {
 9 |     const docs = hoverAtPoundSign("<Butt#on />").value;
10 |     const expected = mockMetadataProvider.getComponent("Button").getMetadata().description;
11 | 
12 |     expect(docs).toContain(expected);
13 |   });
14 | 
15 |   it("documents prop description", () => {
16 |     const docs = hoverAtPoundSign("<Button lab#el='Hello' />").value;
17 |     const expected = mockMetadataProvider.getComponent("Button").getAttr("label").description;
18 | 
19 |     expect(docs).toContain(expected);
20 |   });
21 | 
22 |   it("documents event description", () => {
23 |     const docs = hoverAtPoundSign("<Button onCl#ick='Hello' />").value;
24 |     const expected = mockMetadataProvider.getComponent("Button").getAttr("onClick").description;
25 | 
26 |     expect(docs).toContain(expected);
27 |   });
28 | 
29 |   it("documents implicit prop description", () => {
30 |     const docs = hoverAtPoundSign("<Button dat#a='Hello' />").value;
31 |     const expected = mockMetadataProvider.getComponent("Button").getAttr("data").description;
32 | 
33 |     expect(docs).toContain(expected);
34 |   });
35 | 
36 |   it("documents layout prop description", () => {
37 |     const docs = hoverAtPoundSign("<Button wid#th='Hello' />").value;
38 |     const expected = mockMetadataProvider.getComponent("Button").getAttr("width").description;
39 | 
40 |     expect(docs).toContain(expected);
41 |   });
42 | });
43 | 
44 | function hoverAtPoundSign(source: string) {
45 |   const cursorIndicator = "#";
46 |   const position = source.indexOf(cursorIndicator);
47 |   if (position === -1) {
48 |     throw new Error(`No '${cursorIndicator}' found in the tested source to denote the position of the cursor.`);
49 |   }
50 |   source = source.replace(cursorIndicator, "");
51 |   const parser = createXmlUiParser(source)
52 | 
53 |   const { node } = parser.parse()
54 | 
55 |   return handleHoverCore({ getText: parser.getText, node, metaByComp: mockMetadataProvider }, position)
56 | }
57 | 
```

--------------------------------------------------------------------------------
/docs/public/resources/files/monthly-status.json:
--------------------------------------------------------------------------------

```json
1 | [{"month":"2022-06","paid_revenue":2243.97,"sent_revenue":0},{"month":"2022-07","paid_revenue":815,"sent_revenue":0},{"month":"2022-08","paid_revenue":2285,"sent_revenue":0},{"month":"2022-09","paid_revenue":1050,"sent_revenue":0},{"month":"2022-10","paid_revenue":1585,"sent_revenue":0},{"month":"2022-11","paid_revenue":473.81,"sent_revenue":660},{"month":"2022-12","paid_revenue":180,"sent_revenue":852.86},{"month":"2023-01","paid_revenue":1587.75,"sent_revenue":0},{"month":"2023-02","paid_revenue":845.05,"sent_revenue":0},{"month":"2023-03","paid_revenue":1419.54,"sent_revenue":0},{"month":"2023-04","paid_revenue":1000,"sent_revenue":0},{"month":"2023-05","paid_revenue":2301.41,"sent_revenue":0},{"month":"2023-06","paid_revenue":360,"sent_revenue":0},{"month":"2023-07","paid_revenue":1912.34,"sent_revenue":0},{"month":"2023-08","paid_revenue":1556.49,"sent_revenue":0},{"month":"2023-09","paid_revenue":1296.89,"sent_revenue":0},{"month":"2023-10","paid_revenue":1272.01,"sent_revenue":0},{"month":"2023-11","paid_revenue":1445,"sent_revenue":0},{"month":"2023-12","paid_revenue":108.3,"sent_revenue":0},{"month":"2024-01","paid_revenue":70,"sent_revenue":0},{"month":"2024-02","paid_revenue":4039.41,"sent_revenue":0},{"month":"2024-03","paid_revenue":1754.33,"sent_revenue":0},{"month":"2024-04","paid_revenue":1243.81,"sent_revenue":0},{"month":"2024-05","paid_revenue":568.57,"sent_revenue":0},{"month":"2024-06","paid_revenue":2818.28,"sent_revenue":0},{"month":"2024-07","paid_revenue":2818.69,"sent_revenue":0},{"month":"2024-08","paid_revenue":1226.97,"sent_revenue":0},{"month":"2024-09","paid_revenue":680,"sent_revenue":0},{"month":"2024-10","paid_revenue":940,"sent_revenue":0},{"month":"2024-11","paid_revenue":1208.35,"sent_revenue":0},{"month":"2024-12","paid_revenue":2475,"sent_revenue":0},{"month":"2025-01","paid_revenue":162.45,"sent_revenue":0},{"month":"2025-02","paid_revenue":882.73,"sent_revenue":555.04},{"month":"2025-03","paid_revenue":0,"sent_revenue":810},{"month":"2025-04","paid_revenue":700,"sent_revenue":0},{"month":"2025-05","paid_revenue":0,"sent_revenue":625}]
2 | 
```

--------------------------------------------------------------------------------
/xmlui/tests-e2e/namespaces.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { SKIP_REASON } from "../src/testing/component-test-helpers";
 2 | import { expect, test } from "../src/testing/fixtures";
 3 | 
 4 | test("core button renders without namespace", async ({ page, initTestBed }) => {
 5 |   await initTestBed(`<App><Button testId="button">CORE</Button></App>`, {
 6 |     components: [
 7 |       `
 8 |       <Component name="Button">
 9 |         <Text>COMPOUND COMPONENT</Text>
10 |       </Component>
11 |     `,
12 |     ],
13 |   });
14 |   await expect(page.getByTestId("button")).toHaveText("CORE");
15 | });
16 | 
17 | test("core button renders with XMLUI namespace", async ({ page, initTestBed }) => {
18 |   await initTestBed(
19 |     `
20 |     <App xmlns:XMLUI="core-ns">
21 |       <XMLUI:Button testId="button">CORE</XMLUI:Button>
22 |     </App>`,
23 |     {
24 |       components: [
25 |         `
26 |       <Component name="Button">
27 |         <Text>COMPOUND COMPONENT</Text>
28 |       </Component>
29 |     `,
30 |       ],
31 |     },
32 |   );
33 |   await expect(page.getByTestId("button")).toHaveText("CORE");
34 | });
35 | 
36 | test("compound component button renders with app-ns namespace", async ({ page, initTestBed }) => {
37 |   await initTestBed(
38 |     `
39 |     <App xmlns:My="app-ns">
40 |       <My:Button testId="button">CORE</My:Button>
41 |     </App>`,
42 |     {
43 |       components: [
44 |         `
45 |       <Component name="Button">
46 |         <Text>COMPOUND COMPONENT</Text>
47 |       </Component>
48 |     `,
49 |       ],
50 |     },
51 |   );
52 |   await expect(page.getByTestId("button")).toHaveText("COMPOUND COMPONENT");
53 | });
54 | 
55 | test("compound component renders without namespace (no name-conflict with core component)", async ({
56 |   page,
57 |   initTestBed,
58 | }) => {
59 |   await initTestBed(
60 |     `
61 |     <App>
62 |       <MyButton testId="button">CORE</MyButton>
63 |     </App>`,
64 |     {
65 |       components: [
66 |         `
67 |       <Component name="MyButton">
68 |         <Text>COMPOUND COMPONENT</Text>
69 |       </Component>
70 |     `,
71 |       ],
72 |     },
73 |   );
74 |   await expect(page.getByTestId("button")).toHaveText("COMPOUND COMPONENT");
75 | });
76 | 
77 | test("extension doesn't render without namespace", async ({ page, initTestBed }) => {
78 |   await initTestBed(`
79 |     <App>
80 |       <TestComponent testId="testComp">EXTENSION CONTENT</TestComponent>
81 |     </App>`);
82 |   await expect(page.getByTestId("testComp")).not.toBeVisible();
83 | });
84 | 
```

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

```
 1 | <svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
 2 | <path d="M7 5.15039H28C28.4694 5.15039 28.8496 5.53056 28.8496 6V26.6445C28.8496 26.8769 28.755 27.0994 28.5869 27.2598L24.0205 31.6152C23.8625 31.766 23.652 31.8496 23.4336 31.8496H7C6.53056 31.8496 6.15039 31.4694 6.15039 31V6C6.15039 5.53056 6.53056 5.15039 7 5.15039Z" fill="#FEFEFE" stroke="#666666" stroke-width="0.3"/>
 3 | <path d="M26.0982 12.5596H8.58191V13.083H26.0982V12.5596Z" fill="#666666"/>
 4 | <path d="M26.0982 15.3857H8.58191V15.9092H26.0982V15.3857Z" fill="#666666"/>
 5 | <path d="M26.0982 18.2109H8.58191V18.7344H26.0982V18.2109Z" fill="#666666"/>
 6 | <path d="M26.0982 21.0039H8.58191V21.5273H26.0982V21.0039Z" fill="#666666"/>
 7 | <path d="M26.0982 23.8291H8.58191V24.3525H26.0982V23.8291Z" fill="#666666"/>
 8 | <path d="M16.8516 27.0947H8.58191V27.6181H16.8516V27.0947Z" fill="#666666"/>
 9 | <path d="M23.9056 32.3591L29 27.2646H23.9056V32.3591Z" fill="#F4F2F2"/>
10 | <path d="M21 9H14V10H21V9Z" fill="#535353"/>
11 | <path d="M23.9339 14.783L22.4576 13.9355L21.6053 15.4034L23.0816 16.2508L23.9339 14.783Z" fill="#E0E1E2"/>
12 | <path d="M25.6385 11.8475L24.8948 11.4206C24.7937 11.3625 24.6837 11.3307 24.5715 11.3222C24.5154 11.318 24.4589 11.3196 24.4026 11.3276C24.1208 11.3654 23.8457 11.5452 23.6789 11.8325L22.4576 13.9357L23.9339 14.7831L25.6385 11.8475Z" fill="#E85738"/>
13 | <path d="M24.9268 17.3103L23.0815 16.251L18.1808 24.6911L20.0261 25.7504L24.9268 17.3103Z" fill="#F2C91D"/>
14 | <path d="M25.7791 15.8425L23.9338 14.7832L23.0815 16.251L24.9268 17.3104L25.7791 15.8425Z" fill="#C4C4C4"/>
15 | <path d="M25.7791 15.8427L27.0003 13.7395C27.1671 13.4522 27.1541 13.107 26.9975 12.8174C26.9664 12.7598 26.9289 12.7036 26.8866 12.6514C26.8012 12.5465 26.6944 12.4539 26.568 12.3813L25.6384 11.8477L23.9338 14.7833L25.7791 15.8427Z" fill="#B13218"/>
16 | <path d="M20.0261 25.7505L16.7046 23.8438L16.6607 27.7328L20.0261 25.7505Z" fill="#FDEDD9"/>
17 | <path d="M17.8536 26.95L16.7465 26.3145L16.6608 27.7331L17.8536 26.95Z" fill="#4C4C4C"/>
18 | <path d="M23.0816 16.2508L21.6053 15.4033L16.7046 23.8434L18.1808 24.6909L23.0816 16.2508Z" fill="#FFD93C"/>
19 | </svg>
20 | 
```

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

```typescript
 1 | import { createComponentRenderer } from "../../components-core/renderers";
 2 | import { MemoizedItem } from "../container-helpers";
 3 | import { createMetadata, d, dComponent, dInternal } from "../metadata-helpers";
 4 | import { Items, defaultProps } from "./ItemsNative";
 5 | 
 6 | const COMP = "Items";
 7 | 
 8 | export const ItemsMd = createMetadata({
 9 |   status: "stable",
10 |   description:
11 |     "`Items` renders data arrays without built-in layout or styling, providing " +
12 |     "a lightweight alternative to `List`. Unlike `List`, it provides no " +
13 |     "virtualization, grouping, or visual formatting — just pure data iteration.",
14 |   props: {
15 |     items: dInternal(`This property contains the list of data items this component renders.`),
16 |     data: d(
17 |       `This property contains the list of data items (obtained from a data source) this component renders.`,
18 |     ),
19 |     reverse: {
20 |       description:
21 |         "This property reverses the order in which data is mapped to template components.",
22 |       type: "boolean",
23 |       defaultValue: defaultProps.reverse,
24 |     },
25 |     itemTemplate: dComponent("The component template to display a single item"),
26 |   },
27 |   childrenAsTemplate: "itemTemplate",
28 |   contextVars: {
29 |     $item: dComponent("Current data item being rendered"),
30 |     $itemIndex: dComponent(
31 |       "Zero-based index of current item",
32 |     ),
33 |     $isFirst: dComponent("Boolean indicating if this is the first item"),
34 |     $isLast: dComponent("Boolean indicating if this is the last item"),
35 |   },
36 |   opaque: true,
37 | });
38 | 
39 | export const itemsComponentRenderer = createComponentRenderer(COMP, ItemsMd, (rendererContext) => {
40 |   const { node, renderChild, extractValue, layoutContext } = rendererContext;
41 |   return (
42 |     <Items
43 |       items={extractValue(node.props.items) || extractValue(node.props.data)}
44 |       reverse={extractValue(node.props.reverse)}
45 |       renderItem={(contextVars, key) => {
46 |         return (
47 |           <MemoizedItem
48 |             key={key}
49 |             contextVars={contextVars}
50 |             node={node.props.itemTemplate}
51 |             renderChild={renderChild}
52 |             layoutContext={layoutContext}
53 |           />
54 |         );
55 |       }}
56 |     />
57 |   );
58 | });
59 | 
```

--------------------------------------------------------------------------------
/xmlui/tests/parsers/xmlui/transform.test.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { describe, expect, it, assert } from "vitest";
 2 | import type { ComponentDef, CompoundComponentDef } from "../../../src/abstractions/ComponentDefs";
 3 | import { transformSource } from "./xmlui";
 4 | 
 5 | describe("Xmlui transform", () => {
 6 |   it("Empty code results in error", () => {
 7 |     try {
 8 |       transformSource("");
 9 |       assert.fail("Exception expected");
10 |     } catch (err) {
11 |       expect(err.toString().includes("T001")).equal(true);
12 |     }
13 |   });
14 | 
15 |   it("Empty component #1", () => {
16 |     const cd = transformSource("<Stack />") as ComponentDef;
17 |     expect(cd.type).equal("Stack");
18 |   });
19 | 
20 |   it("Empty component #2", () => {
21 |     const cd = transformSource("<!-- This is a stack --><Stack />") as ComponentDef;
22 |     expect(cd.type).equal("Stack");
23 |   });
24 | 
25 |   it("Compound component needs a name #1", () => {
26 |     try {
27 |       transformSource("<Component><Stack/></Component>");
28 |       assert.fail("Exception expected");
29 |     } catch (err) {
30 |       expect(err.toString().includes("T003")).equal(true);
31 |     }
32 |   });
33 | 
34 |   it("Compound component needs a name #2", () => {
35 |     try {
36 |       transformSource("<Component name='haho'><Stack/></Component>");
37 |       assert.fail("Exception expected");
38 |     } catch (err) {
39 |       expect(err.toString().includes("T004")).equal(true);
40 |     }
41 |   });
42 | 
43 |   it("Compound component needs a component child #1", () => {
44 |     const cd = transformSource("<Component name='MyComp'><!-- comment--></Component>") as CompoundComponentDef;
45 |     expect((cd.component).type).equal("TextNode");
46 |     expect(((cd.component).props as any).value).equal("");
47 |   });
48 | 
49 |   it("Compound component needs a component child #2", () => {
50 |     const cd = transformSource("<Component name='MyComp'></Component>") as CompoundComponentDef;
51 |     expect((cd.component).type).equal("TextNode");
52 |     expect(((cd.component).props as any).value).equal("");
53 |   });
54 | 
55 |   it("Compound component cannot nest another one", () => {
56 |     try {
57 |       transformSource("<Component name='MyComp'><Component name='Other'/></Component>");
58 |       assert.fail("Exception expected");
59 |     } catch (err) {
60 |       expect(err.toString().includes("T006")).equal(true);
61 |     }
62 |   });
63 | });
64 | 
```

--------------------------------------------------------------------------------
/blog/scripts/download-latest-xmlui.js:
--------------------------------------------------------------------------------

```javascript
 1 | #!/usr/bin/env node
 2 | 
 3 | const fs = require("fs").promises;
 4 | const path = require("path");
 5 | const axios = require("axios");
 6 | const { sortByVersion, XMLUI_STANDALONE_PATTERN } = require("./utils.js");
 7 | 
 8 | const getLatestAssetUrl = async () => {
 9 |   try {
10 |     const per_page = 100;
11 |     const max_releases = 100;
12 | 
13 |     const url = `https://api.github.com/repos/xmlui-org/xmlui/releases?per_page=${per_page}`;
14 | 
15 |     const res = await fetch(url);
16 | 
17 |     if (!res.ok) {
18 |       throw new Error(`GitHub API error: ${res.status} ${res.statusText}`);
19 |     }
20 | 
21 |     /** @type {Array<any>} */
22 |     const releases = await res.json();
23 | 
24 |     const xmluiReleases = releases
25 |       .filter((r) => r?.tag_name?.startsWith("xmlui@"))
26 |       .sort(sortByVersion);
27 | 
28 |     const releasesToProcess = xmluiReleases.slice(0, max_releases);
29 | 
30 |     for (const release of releasesToProcess) {
31 |       const xmluiStandaloneAsset = (release.assets || []).find((asset) =>
32 |         XMLUI_STANDALONE_PATTERN.test(asset.name),
33 |       );
34 |       return xmluiStandaloneAsset.browser_download_url;
35 |     }
36 |     throw new Error("No matching standalone asset found in the latest releases");
37 |   } catch (e) {
38 |     console.error("Error fetching latest release", e);
39 |     throw e;
40 |   }
41 | };
42 | 
43 | async function downloadFile(url) {
44 |   try {
45 |     const response = await axios.get(url, {
46 |       responseType: "arraybuffer",
47 |       maxRedirects: 5,
48 |     });
49 |     return response.data;
50 |   } catch (error) {
51 |     console.log(error.message);
52 |   }
53 | }
54 | 
55 | (async () => {
56 |   try {
57 |     const rootDir = path.resolve(__dirname, "..");
58 |     const buildPublicDir = path.join(rootDir, "/public/resources/files/for-download/xmlui");
59 |     const browser_download_url = await getLatestAssetUrl();
60 | 
61 |     if (!browser_download_url) {
62 |       throw new Error("Missing browser_download_url");
63 |     }
64 | 
65 |     const filename = "xmlui-standalone.umd.js";
66 |     const outputPath = path.join(buildPublicDir, filename);
67 | 
68 |     const fileBuffer = await downloadFile(browser_download_url);
69 | 
70 |     await fs.mkdir(buildPublicDir, { recursive: true });
71 |     await fs.writeFile(outputPath, fileBuffer);
72 |   } catch (err) {
73 |     console.error(err.message);
74 |     process.exit(1);
75 |   }
76 | })();
77 | 
```

--------------------------------------------------------------------------------
/docs/scripts/download-latest-xmlui.js:
--------------------------------------------------------------------------------

```javascript
 1 | #!/usr/bin/env node
 2 | 
 3 | const fs = require("fs").promises;
 4 | const path = require("path");
 5 | const axios = require("axios");
 6 | const { sortByVersion, XMLUI_STANDALONE_PATTERN } = require("./utils.js");
 7 | 
 8 | const getLatestAssetUrl = async () => {
 9 |   try {
10 |     const per_page = 100;
11 |     const max_releases = 100;
12 | 
13 |     const url = `https://api.github.com/repos/xmlui-org/xmlui/releases?per_page=${per_page}`;
14 | 
15 |     const res = await fetch(url);
16 | 
17 |     if (!res.ok) {
18 |       throw new Error(`GitHub API error: ${res.status} ${res.statusText}`);
19 |     }
20 | 
21 |     /** @type {Array<any>} */
22 |     const releases = await res.json();
23 | 
24 |     const xmluiReleases = releases
25 |       .filter((r) => r?.tag_name?.startsWith("xmlui@"))
26 |       .sort(sortByVersion);
27 | 
28 |     const releasesToProcess = xmluiReleases.slice(0, max_releases);
29 | 
30 |     for (const release of releasesToProcess) {
31 |       const xmluiStandaloneAsset = (release.assets || []).find((asset) =>
32 |         XMLUI_STANDALONE_PATTERN.test(asset.name),
33 |       );
34 |       return xmluiStandaloneAsset.browser_download_url;
35 |     }
36 |     throw new Error("No matching standalone asset found in the latest releases");
37 |   } catch (e) {
38 |     console.error("Error fetching latest release", e);
39 |     throw e;
40 |   }
41 | };
42 | 
43 | async function downloadFile(url) {
44 |   try {
45 |     const response = await axios.get(url, {
46 |       responseType: "arraybuffer",
47 |       maxRedirects: 5,
48 |     });
49 |     return response.data;
50 |   } catch (error) {
51 |     console.log(error.message);
52 |   }
53 | }
54 | 
55 | (async () => {
56 |   try {
57 |     const rootDir = path.resolve(__dirname, "..");
58 |     const buildPublicDir = path.join(rootDir, "/public/resources/files/for-download/xmlui");
59 |     const browser_download_url = await getLatestAssetUrl();
60 | 
61 |     if (!browser_download_url) {
62 |       throw new Error("Missing browser_download_url");
63 |     }
64 | 
65 |     const filename = "xmlui-standalone.umd.js";
66 |     const outputPath = path.join(buildPublicDir, filename);
67 | 
68 |     const fileBuffer = await downloadFile(browser_download_url);
69 | 
70 |     await fs.mkdir(buildPublicDir, { recursive: true });
71 |     await fs.writeFile(outputPath, fileBuffer);
72 |   } catch (err) {
73 |     console.error(err.message);
74 |     process.exit(1);
75 |   }
76 | })();
77 | 
```

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

```markdown
 1 | # Redirect [#redirect]
 2 | 
 3 | `Redirect` immediately redirects the browser to the URL in its `to` property when it gets visible (its `when` property gets `true`). It works only within [App](/components/App), not externally.
 4 | 
 5 | ## Using `Redirect` [#using-redirect]
 6 | 
 7 | The following app demonstrates two different patterns for using `Redirect`.
 8 | 
 9 | 1. When you navigate to the "Redirect #1" page, it immediately redirects the app to the "Accounts" page. By default, the  `when` property of `Redirect` (and any other component) is "true", so redirection immediately happens.
10 | 2. The "Redirect #2" page expects you to click the button before redirecting. The button click sets the `when` property of `Redirect` to true, and redirection happens at that moment.
11 | 
12 | ```xmlui-pg copy {14, 20} display name="Example: providing children" height="170px"
13 | <App>
14 |   <NavPanel>
15 |     <NavLink to="/">Home</NavLink>
16 |     <NavLink to="/accounts">Accounts</NavLink>
17 |     <NavLink to="/products">Products</NavLink>
18 |     <NavLink to="/redirect1">Redirect #1</NavLink>
19 |     <NavLink to="/redirect2">Redirect #2</NavLink>
20 |   </NavPanel>
21 |   <Pages>
22 |     <Page url="/">Home</Page>
23 |     <Page url="/accounts">Accounts</Page>
24 |     <Page url="/products">Products</Page>
25 |     <Page url="/redirect1">
26 |       <Redirect to="/accounts" />
27 |       Redirecting to Accounts...
28 |     </Page>
29 |     <Page url="/redirect2">
30 |       <Fragment var.clicked="{false}">
31 |         <Button label="Click to redirect" onClick="clicked = true"/>
32 |         <Redirect when="{clicked}" to="/accounts" />
33 |         Redirecting to Accounts...
34 |       </Fragment>
35 |     </Page>
36 |   </Pages>
37 | </App>
38 | ```
39 | 
40 | ## Properties [#properties]
41 | 
42 | ### `replace` (default: false) [#replace-default-false]
43 | 
44 | This boolean property indicates whether the redirect should replace the current history entry or create a new one.
45 | 
46 | ### `to` (default: "") [#to-default-]
47 | 
48 | This property defines the URL to which this component is about to redirect requests.
49 | 
50 | ## Events [#events]
51 | 
52 | This component does not have any events.
53 | 
54 | ## Exposed Methods [#exposed-methods]
55 | 
56 | This component does not expose any methods.
57 | 
58 | ## Styling [#styling]
59 | 
60 | This component does not have any styles.
61 | 
```

--------------------------------------------------------------------------------
/xmlui/scripts/generate-docs/build-downloads-map.mjs:
--------------------------------------------------------------------------------

```
 1 | import { writeFileSync, statSync } from "fs";
 2 | import { basename, extname } from "path";
 3 | import { gatherAndRemoveDuplicates, toNormalizedUpperCase, traverseDirectory } from "./utils.mjs";
 4 | import { createScopedLogger } from "./logging-standards.mjs";
 5 | import { DOWNLOADS_MAP_CONFIG } from "./constants.mjs";
 6 | import { 
 7 |   generateExportStatements, 
 8 |   processDuplicatesWithLogging 
 9 | } from "./pattern-utilities.mjs";
10 | 
11 | const baseUrlCutoff = DOWNLOADS_MAP_CONFIG.BASE_URL_CUTOFF;
12 | const includedFileExtensions = DOWNLOADS_MAP_CONFIG.INCLUDED_FILE_EXTENSIONS;
13 | 
14 | /**
15 |  * Creates a file containing download link constants for downloadable files.
16 |  * @param {string} downloadsFolder The path to the downloads folder (use UNIX delimiters)
17 |  * @param {string} outFilePathAndName The path and name of the output file (use UNIX delimiters)
18 |  */
19 | export function buildDownloadsMap(downloadsFolder, outFilePathAndName) {
20 |   const logger = createScopedLogger("DownloadsMapBuilder");
21 |   logger.operationStart("building downloads map");
22 |   const downloads = [];
23 |   traverseDirectory({ name: "", path: downloadsFolder }, (item, _) => {
24 |     /**
25 |      * name: the folder's/file's name (eg. "hello-app-engine")
26 |      * path: the path to the root of the given folder from the project root (eg. "src/apps/1_basic/samples/hello-app-engine")
27 |      * parent: parent node
28 |      * children: children file/folder names
29 |      */
30 |     if (statSync(item.path).isDirectory()) {
31 |       // Node is a folder
32 |     } else {
33 |       // Node is a file
34 |       if (includedFileExtensions.includes(extname(item.name))) {
35 |         const relativePath = item.path.split(baseUrlCutoff)[1];
36 |         downloads.push({
37 |           id: toNormalizedUpperCase(basename(relativePath, extname(relativePath))),
38 |           path: relativePath,
39 |         });
40 |       }
41 |     }
42 |   });
43 | 
44 |   const { filtered, duplicates } = gatherAndRemoveDuplicates(downloads);
45 |   
46 |   // Process duplicates with standardized logging
47 |   processDuplicatesWithLogging(duplicates, logger, "download IDs and paths");
48 | 
49 |   // Generate export statements using utility
50 |   const outStr = generateExportStatements(filtered);
51 | 
52 |   writeFileSync(outFilePathAndName, outStr);
53 | }
54 | 
```

--------------------------------------------------------------------------------
/docs/public/pages/howto/share-a-modaldialog-across-components.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Share a ModalDialog across components
 2 | 
 3 | ```xmlui-pg
 4 | ---app
 5 | <App>
 6 |   <Test />
 7 | </App>
 8 | ---api
 9 | {
10 |   "apiUrl": "/api",
11 |   "initialize": "$state.items = [
12 |     { id: 1, title: 'Mountain View' },
13 |     { id: 2, title: 'City Lights' },
14 |     { id: 3, title: 'Ocean Sunset' }
15 |   ]",
16 |   "operations": {
17 |     "get-items": {
18 |       "url": "/items",
19 |       "method": "get",
20 |       "handler": "return $state.items"
21 |     }
22 |   }
23 | }
24 | ---comp display /settings/ /settingsDialog/ /appSettings/
25 | <Component name="Test">
26 | 
27 |   <AppState id="settings" bucket="appSettings" initialValue="{{
28 |     itemSize: 'medium',
29 |     showDetails: true
30 |   }}" />
31 | 
32 |   <!-- Settings modal defined at App level - accessible to all components -->
33 |   <ModalDialog id="settingsDialog" title="Settings">
34 |     <SettingsPanel />
35 |   </ModalDialog>
36 | 
37 |   <DataSource id="items" url="/api/items" />
38 | 
39 |   <AppHeader title="Demo App">
40 |     <property name="profileMenuTemplate">
41 |       <Icon name="cog" onClick="settingsDialog.open()" />
42 |     </property>
43 |   </AppHeader>
44 | 
45 |   <VStack>
46 |     <HStack>
47 |       <Text>Items ({settings.value.itemSize} size)</Text>
48 |       <Button
49 |         label="Settings"
50 |         size="sm"
51 |         onClick="settingsDialog.open()"
52 |       />
53 |     </HStack>
54 | 
55 |     <List data="{items}">
56 |       <Card>
57 |         <VStack>
58 |           <Text>{$item.title}</Text>
59 |           <Fragment when="{settings.value.showDetails}">
60 |             <Text variant="caption">ID: {$item.id}</Text>
61 |           </Fragment>
62 |         </VStack>
63 |       </Card>
64 |     </List>
65 |   </VStack>
66 | 
67 | </Component>
68 | ---comp display /settings/ /settingsDialog/ /appSettings/
69 | <Component name="SettingsPanel">
70 |   <AppState id="settings" bucket="appSettings" />
71 | 
72 |   <VStack>
73 | 
74 |     <Select
75 |       label="Item Size"
76 |       initialValue="{settings.value.itemSize}"
77 |       onDidChange="(value) => settings.update({ itemSize: value })"
78 |     >
79 |       <Option value="small" label="Small" />
80 |       <Option value="medium" label="Medium" />
81 |       <Option value="large" label="Large" />
82 |     </Select>
83 | 
84 |     <Switch
85 |       label="Show details"
86 |       initialValue="{settings.value.showDetails}"
87 |       onDidChange="(value) => settings.update({ showDetails: value })"
88 |     />
89 | 
90 |   </VStack>
91 | </Component>
92 | ```
93 | 
```

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

```typescript
 1 | import { createComponentRenderer } from "../../components-core/renderers";
 2 | import { createMetadata } from "../metadata-helpers";
 3 | import { Bookmark, defaultProps } from "./BookmarkNative";
 4 | 
 5 | const COMP = "Bookmark";
 6 | 
 7 | export const BookmarkMd = createMetadata({
 8 |   status: "stable",
 9 |   description:
10 |     "As its name suggests, this component places a bookmark into its parent component's view. The " +
11 |     "component has an \`id\` that you can use in links to navigate (scroll to) the bookmark's location.",
12 |   opaque: true,
13 |   props: {
14 |     id: {
15 |       description:
16 |         "The unique identifier of the bookmark. You can use this identifier in links " +
17 |         "to navigate to this component's location. If this identifier is not set, you cannot " +
18 |         "programmatically visit this bookmark.",
19 |       valueType: "string",
20 |     },
21 |     level: {
22 |       description:
23 |         "The level of the bookmark. The level is used to determine the bookmark's " +
24 |         "position in the table of contents.",
25 |       valueType: "number",
26 |       defaultValue: defaultProps.level,
27 |     },
28 |     title: {
29 |       description:
30 |         "Defines the text to display the bookmark in the table of contents. If this property is " +
31 |         "empty, the text falls back to the value of \`id\`.",
32 |       valueType: "string",
33 |     },
34 |     omitFromToc: {
35 |       description: "If true, this bookmark will be excluded from the table of contents.",
36 |       valueType: "boolean",
37 |       defaultValue: defaultProps.omitFromToc,
38 |     },
39 |   },
40 |   apis: {
41 |     scrollIntoView: {
42 |       signature: "scrollIntoView()",
43 |       description: "Scrolls the bookmark into view.",
44 |     },
45 |   },
46 | });
47 | 
48 | export const bookmarkComponentRenderer = createComponentRenderer(
49 |   COMP,
50 |   BookmarkMd,
51 |   (rendererContext) => {
52 |     const { node, renderChild, extractValue, layoutContext } = rendererContext;
53 | 
54 |     return (
55 |       <Bookmark
56 |         uid={extractValue(node.uid)}
57 |         level={extractValue(node.props.level)}
58 |         title={extractValue(node.props.title)}
59 |         omitFromToc={extractValue.asOptionalBoolean(node.props.omitFromToc)}
60 |       >
61 |         {renderChild(node.children, layoutContext)}
62 |       </Bookmark>
63 |     );
64 |   },
65 | );
66 | 
```

--------------------------------------------------------------------------------
/xmlui/tests-e2e/api-call-as-extracted-component.spec.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { expect, test } from "../src/testing/fixtures";
 2 | import { initApp } from "../src/testing/themed-app-test-helpers";
 3 | 
 4 | test("api call as an extracted component get called", async ({ page }) => {
 5 |   await initApp(page, {
 6 |     entryPoint: `
 7 |     <Fragment>
 8 |         <APICall 
 9 |            id="apiCall"
10 |            url="/postUrl"
11 |            method="post"
12 |            body="{$param}"
13 |         />
14 |         <Form onSubmit="(body)=>apiCall.execute(body)">
15 |             <FormItem bindTo="name" testId="nameInput"/>
16 |         </Form>
17 |     </Fragment>
18 |     `,
19 |     apiInterceptor: {
20 |       operations: {
21 |         "postUrl": {
22 |           url: "/postUrl",
23 |           method: "post",
24 |           handler: `()=>{
25 |             return $requestBody;
26 |           }`,
27 |         }
28 |       },
29 |     },
30 |   });
31 | 
32 | 
33 |   const responsePromise = page.waitForResponse((response) => response.url().includes("/postUrl"));
34 | 
35 |   await page.getByTestId("nameInput").getByRole("textbox").fill("John");
36 |   await page.locator("button[type='submit']").click();
37 | 
38 | 
39 |   const response = await responsePromise;
40 |   const responseBody = await response.json();
41 |   expect(responseBody).toEqual({
42 |     name: "John"
43 |   });
44 | });
45 | 
46 | 
47 | test("api call as an extracted component get called (function reference + default body)", async ({ page }) => {
48 |   await initApp(page, {
49 |     entryPoint: `
50 |     <Fragment>
51 |         <APICall 
52 |            id="apiCall"
53 |            url="/postUrl"
54 |            method="post"
55 |         />
56 |         <Form onSubmit="apiCall.execute">
57 |             <FormItem bindTo="name" testId="nameInput"/>
58 |         </Form>
59 |     </Fragment>
60 |     `,
61 |     apiInterceptor: {
62 |       operations: {
63 |         "postUrl": {
64 |           url: "/postUrl",
65 |           method: "post",
66 |           handler: `()=>{
67 |             return $requestBody;
68 |           }`,
69 |         }
70 |       },
71 |     },
72 |   });
73 | 
74 | 
75 |   const responsePromise = page.waitForResponse((response) => response.url().includes("/postUrl"));
76 | 
77 |   await page.getByTestId("nameInput").getByRole("textbox").fill("John");
78 |   await page.locator("button[type='submit']").click();
79 | 
80 |   const response = await responsePromise;
81 |   const responseBody = await response.json();
82 |   expect(responseBody).toEqual({
83 |     name: "John"
84 |   });
85 | });
86 | 
```

--------------------------------------------------------------------------------
/docs/public/pages/howto/control-cache-invalidation.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Control cache invalidation
 2 | 
 3 | By default, when an `APICall` executes successfully, it invalidates ALL DataSource caches, causing them to refetch. Use the `invalidates` property to control this behavior for better performance.
 4 | 
 5 | ```xmlui-pg name="Update user - refreshes user list"
 6 | ---app display {16}
 7 | <App>
 8 |   <DataSource
 9 |     id="users"
10 |     url="/api/users"
11 |   />
12 | 
13 |   <DataSource
14 |     id="stats"
15 |     url="/api/stats"
16 |   />
17 | 
18 |   <APICall
19 |     id="updateUser"
20 |     method="put"
21 |     url="/api/users/{$param}"
22 |     invalidates="{['/api/users']}"
23 |     completedNotificationMessage="User updated!"
24 |   />
25 | 
26 |   <VStack>
27 |     <Text>Users (will refresh)</Text>
28 | 
29 |     <Items data="{users}">
30 |       <Card>
31 |         <HStack>
32 |           <VStack>
33 |             <Text>{$item.name}</Text>
34 |             <Text>Role: {$item.role}</Text>
35 |           </VStack>
36 |           <Button
37 |             onClick="updateUser.execute($item.id)"
38 |             enabled="{$item.role !== 'admin'}">
39 |             Promote to Admin
40 |           </Button>
41 |         </HStack>
42 |       </Card>
43 |     </Items>
44 | 
45 |     <Text>Stats (won't refresh)</Text>
46 |     <Text>Total requests: {stats.value.totalRequests}</Text>
47 |     <Text>Stats fetched: {stats.value.lastUpdate} time(s)</Text>
48 |   </VStack>
49 | </App>
50 | ---api
51 | {
52 |   "apiUrl": "/api",
53 |   "initialize": "
54 |     $state.users = [
55 |       { id: '1', name: 'Alice', role: 'viewer' },
56 |       { id: '2', name: 'Bob', role: 'viewer' }
57 |     ];
58 |     $state.stats = { totalRequests: 42, lastUpdate: 0 };
59 |   ",
60 |   "operations": {
61 |     "get-users": {
62 |       "url": "/users",
63 |       "method": "get",
64 |       "handler": "return [...$state.users]"
65 |     },
66 |     "get-stats": {
67 |       "url": "/stats",
68 |       "method": "get",
69 |       "handler": "
70 |         $state.stats.lastUpdate++;
71 |         return { ...$state.stats };
72 |       "
73 |     },
74 |     "update-user": {
75 |       "url": "/users/:id",
76 |       "method": "put",
77 |       "pathParamTypes": { "id": "string" },
78 |       "handler": "
79 |         const user = $state.users.find(u => u.id === $pathParams.id);
80 |         if (user) {
81 |           user.role = 'admin';
82 |         }
83 |       "
84 |     }
85 |   }
86 | }
87 | ```
88 | 
89 | When an API mutation doesn't affect other displayed data, use `invalidates="{[]}"` to prevent unnecessary refetches.
90 | 
91 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components-core/reportEngineError.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { ScriptParseError, StatementExecutionError, ThrowStatementError } from "./EngineError";
 2 | 
 3 | type ErrorInfo = {
 4 |   error: Error;
 5 |   helperMessage?: string;
 6 |   colors?: string[];
 7 | };
 8 | 
 9 | const appErrors: ErrorInfo[] = [];
10 | 
11 | /**
12 |  * Get all errors collected during the last run
13 |  */
14 | export function getAppErrors(): ErrorInfo[] {
15 |   return appErrors;
16 | }
17 | 
18 | /**
19 |  * Use this function to reset the errors raised by the execution engine
20 |  */
21 | export function resetErrors(): void {
22 |   appErrors.length = 0;
23 | }
24 | 
25 | /**
26 |  * Use this function to report an error
27 |  * @param error Error or string describing the error to report
28 |  * @param errorToThrow The error to throw
29 |  */
30 | export function reportEngineError(error: Error | string, errorToThrow?: any): void {
31 |   // --- Wrap a string into an error
32 |   if (typeof error === "string") {
33 |     error = new Error(error);
34 |   }
35 | 
36 |   let helperMessage = "";
37 |   let colors: string[] = [];
38 | 
39 |   // --- Error-specific helper messages
40 |   if (error instanceof ScriptParseError) {
41 |     let pos = (error?.position ?? 0) - 1;
42 |     if (error.source) {
43 |       while (pos < error.source.length - 1 && error.source[pos] === " ") {
44 |         pos++;
45 |       }
46 |       helperMessage += `%c${error.message}%c\n\n`;
47 |       helperMessage += `${error.source.substring(0, pos)}%c${error.source[pos]}%c${
48 |         error.source.substring(pos + 1) ?? ""
49 |       }\n\n`;
50 |     }
51 |     helperMessage += `%cThe error handler associated with the parsed code did not run.%c`;
52 |     colors = ["color: red", "color: inherited", "color: red", "color: inherited", "color: orange", "color: inherited"];
53 |   } else if (error instanceof StatementExecutionError) {
54 |     helperMessage += `%cError while executing code: ${error.message}%c`;
55 |     if (error.source) {
56 |       helperMessage += `\n\n${error.source}`;
57 |     }
58 |     colors = ["color: red", "color: inherited"];
59 |   } else if (error instanceof ThrowStatementError) {
60 |     helperMessage += `A 'throw' statement executed:\n\n%c${error.message}%c\n\n${error.errorObject}`;
61 |     colors = ["color: red", "color: inherited"];
62 |   }
63 | 
64 |   if (helperMessage) {
65 |     console.log(helperMessage, ...colors);
66 |   }
67 |   appErrors.push({ error, helperMessage, colors });
68 |   throw errorToThrow ?? error;
69 | }
70 | 
```

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

```markdown
 1 | %-DESC-START
 2 | 
 3 | **Key features:**
 4 | - **Value and label separation**: Define what gets stored (value) separately from what users see (label)
 5 | - **Automatic fallbacks**: Uses label as value or value as label when only one is provided
 6 | - **Custom templates**: Support for rich content via optionTemplate property or child components
 7 | - **State management**: Built-in enabled/disabled states for individual options
 8 | - **Data integration**: Works seamlessly with Items components for dynamic option lists
 9 | 
10 | ## Using `Option`
11 | 
12 | ### With `AutoComplete`
13 | 
14 | ```xmlui-pg copy {4-6} display name="Example: Option in a AutoComplete" height="275px"
15 | <App>
16 |   <Text value="Selected ID: {myComp.value}"/>
17 |   <AutoComplete id="myComp">
18 |     <Option label="John, Smith" value="john" />
19 |     <Option label="Jane, Clint" value="jane" disabled="true" />
20 |     <Option label="Herbert, Frank" value="herbert" />
21 |   </AutoComplete>
22 | </App>
23 | ```
24 | 
25 | ### With `Select`
26 | 
27 | ```xmlui-pg copy {4-6} display name="Example: Option in a Select" height="275px"
28 | <App>
29 |   <Text value="Selected ID: {mySelect.value}"/>
30 |   <Select id="mySelect">
31 |     <Option label="John, Smith" value="john" />
32 |     <Option label="Jane, Clint" value="jane" />
33 |     <Option label="Herbert, Frank" value="herbert" />
34 |   </Select>
35 | </App>
36 | ```
37 | 
38 | %-DESC-END
39 | 
40 | %-PROP-START label
41 | 
42 | >[!INFO]
43 | > If `Option` does not define any of the `label` or `value` properties, the option will not be rendered.
44 | 
45 | ```xmlui-pg copy display name="Example: Using label" height="275px"
46 | <App>
47 |   <Text value="Selected ID: {mySelect.value}"/>
48 |   <Select id="mySelect">
49 |     <Option />
50 |     <Option label="Vanilla" value="van"/>
51 |     <Option label="Chocolate" value="choc" />
52 |     <Option value="pist" />
53 |   </Select>
54 | </App>
55 | ```
56 | 
57 | %-PROP-END
58 | 
59 | %-PROP-START value
60 | 
61 | >[!INFO]
62 | > If `Option` does not define any of the `label` or `value` properties, the option will not be rendered.
63 | 
64 | ```xmlui-pg copy display name="Example: Using value" height="275px"
65 | <App>
66 |   <Text value="Selected ID: {mySelect.value}"/>
67 |   <Select id="mySelect">
68 |     <Option />
69 |     <Option label="Vanilla" />
70 |     <Option label="Chocolate" value="chocolate" />
71 |     <Option label="Pistachio" value="pistachio" />
72 |   </Select>
73 | </App>
74 | ```
75 | 
76 | %-PROP-END
77 | 
```

--------------------------------------------------------------------------------
/docs/public/pages/xmlui-charts/BarChart.md:
--------------------------------------------------------------------------------

```markdown
 1 | # BarChart [#barchart]
 2 | 
 3 | >[!WARNING]
 4 | > This component is in an **experimental** state; you can use it in your app. However, we may modify it, and it may even have breaking changes in the future.The `BarChart` component represents a bar chart.Accepts a `LabelLst` component as a child to parametrize display labels.
 5 | 
 6 | ## Properties
 7 | 
 8 | ### `data`
 9 | 
10 | This property is used to provide the component with data to display.The data needs to be an array of objects.
11 | 
12 | ### `dataKeys`
13 | 
14 | This property specifies the keys in the data objects that should be used for rendering the bars.E.g. 'id' or 'key'.
15 | 
16 | ### `hideTickX (default: false)`
17 | 
18 | Controls the visibility of the X-axis ticks. If set to `true`, tick labels on the X-axis will be hidden.
19 | 
20 | ### `hideTickY (default: false)`
21 | 
22 | Controls the visibility of the Y-axis ticks. If set to `true`, tick labels on the Y-axis will be hidden.
23 | 
24 | ### `hideX (default: false)`
25 | 
26 | Determines whether the X-axis should be hidden. If set to `true`, the axis will not be rendered.
27 | 
28 | ### `hideY (default: false)`
29 | 
30 | Determines whether the Y-axis should be hidden. If set to `true`, the axis will not be rendered.
31 | 
32 | ### `layout (default: "vertical")`
33 | 
34 | This property determines the orientation of the bar chart. The `vertical` variant specifies the horizontal axis as the primary and lays out the bars from left to right. The `horizontal` variant specifies the vertical axis as the primary and has the bars spread from top to bottom.
35 | 
36 | Available values: `horizontal`, `vertical` **(default)**
37 | 
38 | ### `nameKey`
39 | 
40 | Specifies the key in the data objects that will be used to label the different data series.
41 | 
42 | ### `showLegend (default: false)`
43 | 
44 | Determines whether the legend should be displayed.
45 | 
46 | ### `stacked (default: false)`
47 | 
48 | This property determines how the bars are laid out.If set to `true`, bars with the same category will be stacked on top of each other rather than placed side by side.
49 | 
50 | ### `tickFormatter`
51 | 
52 | A function that formats the axis tick labels. It receives a tick value and returns a formatted string.
53 | 
54 | ## Events
55 | 
56 | This component does not have any events.
57 | 
58 | ## Exposed Methods
59 | 
60 | This component does not expose any methods.
61 | 
62 | ## Styling
63 | 
64 | This component does not have any styles.
65 | 
```

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

```markdown
 1 | # Logo [#logo]
 2 | 
 3 | `Logo` displays your application's brand symbol by automatically loading logo images defined in the app manifest. While logos are typically configured using App-level properties (`logo`, `logo-dark`), this component provides direct control when you need custom logo placement or templating.
 4 | 
 5 | Most apps use `logo="path/to/logo.svg"` on the App component rather than using `<Logo>` directly. Use this component when you need custom logo positioning or want to combine logos with other elements in a `logoTemplate`.
 6 | 
 7 | ## Using Logo [#using-logo]
 8 | 
 9 | The framework checks the application manifest for a logo resource (SVG file).
10 | If found, it loads and displays it in the Logo component.
11 | 
12 | This is a sample manifest that shows a logo definition:
13 | 
14 | ```json copy {5}
15 | {
16 |   "name": "Tutorial",
17 |   "version": "0.0.1",
18 |   "resources": {
19 |     "logo": "resources/xmlui-logo.svg",
20 |     "favicon": "resources/favicon.ico"
21 |   }
22 | }
23 | ```
24 | 
25 | In the following example, you can see a custom logo definition in the `AppHeader` via templating.
26 | There is a `Heading` with the title text "MyApp" before the logo.
27 | It also uses the `Logo` component within the template definition:
28 | 
29 | ```xmlui-pg
30 | ---app copy display name="Example: using Logo" {6} height="200px"
31 | <App layout="horizontal">
32 |   <AppHeader>
33 |     <property name="logoTemplate">
34 |        <Fragment>
35 |          <Heading level="h2" value="MyApp"/>
36 |          <Logo/>
37 |        </Fragment>
38 |     </property>
39 |   </AppHeader>
40 |   <NavPanel>
41 |     <NavLink label="Home" to="/" icon="home"/>
42 |   </NavPanel>
43 |   <Pages fallbackPath="/">
44 |     <Page url="/">
45 |       <CHStack>
46 |         (Sample content)
47 |       </CHStack>
48 |     </Page>
49 |   </Pages>
50 | </App>
51 | ---desc
52 | The markup displays the app's logo:
53 | ```
54 | 
55 | ## Properties [#properties]
56 | 
57 | ### `alt` (default: "Logo") [#alt-default-logo]
58 | 
59 | Alternative text for the logo image for accessibility.
60 | 
61 | ### `inline` (default: false) [#inline-default-false]
62 | 
63 | When set to true, the image will be displayed as an inline element instead of a block element.
64 | 
65 | ## Events [#events]
66 | 
67 | This component does not have any events.
68 | 
69 | ## Exposed Methods [#exposed-methods]
70 | 
71 | This component does not expose any methods.
72 | 
73 | ## Styling [#styling]
74 | 
75 | This component does not have any styles.
76 | 
```

--------------------------------------------------------------------------------
/xmlui/src/components/NestedApp/logo.svg:
--------------------------------------------------------------------------------

```
1 | <svg width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
2 |     <path d="M9.04674 19.3954C8.2739 19.3954 7.60226 19.2265 7.03199 18.8887C6.47443 18.5384 6.0435 18.0505 5.73938 17.425C5.43526 16.7869 5.2832 16.0362 5.2832 15.173V9.89961C5.2832 9.7745 5.32771 9.66815 5.41637 9.58059C5.50502 9.493 5.61275 9.44922 5.73938 9.44922H7.41222C7.55157 9.44922 7.6593 9.493 7.73524 9.58059C7.8239 9.66815 7.86841 9.7745 7.86841 9.89961V15.0604C7.86841 16.6117 8.55895 17.3874 9.94021 17.3874C10.5991 17.3874 11.1187 17.181 11.4988 16.7681C11.8917 16.3553 12.0881 15.786 12.0881 15.0604V9.89961C12.0881 9.7745 12.1325 9.66815 12.2211 9.58059C12.3098 9.493 12.4175 9.44922 12.5443 9.44922H14.217C14.3436 9.44922 14.4513 9.493 14.54 9.58059C14.6288 9.66815 14.6732 9.7745 14.6732 9.89961V18.7574C14.6732 18.8825 14.6288 18.9888 14.54 19.0764C14.4513 19.164 14.3436 19.2078 14.217 19.2078H12.6773C12.538 19.2078 12.4239 19.164 12.3352 19.0764C12.2591 18.9888 12.2211 18.8825 12.2211 18.7574V17.988C11.879 18.4258 11.4545 18.7699 10.9476 19.0201C10.4407 19.2703 9.80704 19.3954 9.04674 19.3954Z" fill="#3367CC"/>
3 |     <path d="M17.6397 19.2104C17.5129 19.2104 17.4052 19.1666 17.3165 19.079C17.2279 18.9914 17.1835 18.8851 17.1835 18.76V9.90221C17.1835 9.7771 17.2279 9.67075 17.3165 9.58319C17.4052 9.4956 17.5129 9.45182 17.6397 9.45182H19.2174C19.3567 9.45182 19.4644 9.4956 19.5404 9.58319C19.6292 9.67075 19.6736 9.7771 19.6736 9.90221V18.76C19.6736 18.8851 19.6292 18.9914 19.5404 19.079C19.4644 19.1666 19.3567 19.2104 19.2174 19.2104H17.6397ZM17.5636 7.8379C17.4243 7.8379 17.3102 7.80038 17.2215 7.72531C17.1454 7.63773 17.1074 7.52514 17.1074 7.38751V6.03633C17.1074 5.91122 17.1454 5.80487 17.2215 5.71731C17.3102 5.62972 17.4243 5.58594 17.5636 5.58594H19.2933C19.4327 5.58594 19.5467 5.62972 19.6354 5.71731C19.7242 5.80487 19.7686 5.91122 19.7686 6.03633V7.38751C19.7686 7.52514 19.7242 7.63773 19.6354 7.72531C19.5467 7.80038 19.4327 7.8379 19.2933 7.8379H17.5636Z" fill="#3367CC"/>
4 |     <path fill-rule="evenodd" clip-rule="evenodd" d="M23.0215 2.81748H2.53486V23.044H23.0215V2.81748ZM2.18164 2.46875V23.3927H23.3747V2.46875H2.18164Z" fill="#3367CC"/>
5 | </svg>
6 | 
```

--------------------------------------------------------------------------------
/tools/create-app/templates/index.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { install } from "../helpers/install";
 2 | import { copy } from "../helpers/copy";
 3 | import os from "os";
 4 | import fs from "fs/promises";
 5 | import path from "path";
 6 | import { bold, cyan } from "picocolors";
 7 | import pkg from '../package.json'
 8 | 
 9 | import type { InstallTemplateArgs } from "./types";
10 | 
11 | /**
12 |  * Install a UI Engine internal template to a given `root` directory.
13 |  */
14 | export const installTemplate = async ({ appName, root, packageManager, template, useGit }: InstallTemplateArgs) => {
15 |   console.log(bold(`Using ${packageManager}.`));
16 | 
17 |   /**
18 |    * Copy the template files to the target directory.
19 |    */
20 |   console.log("\nInitializing project with template:", template, "\n");
21 |   const templatePath = path.join(__dirname, template, "ts");
22 |   const copySource = ["**"];
23 | 
24 |   if (!useGit) {
25 |     copySource.push("!gitignore");
26 |   }
27 |   await copy(copySource, root, {
28 |     parents: true,
29 |     cwd: templatePath,
30 |     rename(name) {
31 |       switch (name) {
32 |         case "gitignore":
33 |         case "eslintrc.json": {
34 |           return `.${name}`;
35 |         }
36 |         // README.md is ignored by webpack-asset-relocator-loader used by ncc:
37 |         // https://github.com/vercel/webpack-asset-relocator-loader/blob/e9308683d47ff507253e37c9bcbb99474603192b/src/asset-relocator.js#L227
38 |         case "README-template.md": {
39 |           return "README.md";
40 |         }
41 |         default: {
42 |           return name;
43 |         }
44 |       }
45 |     },
46 |   });
47 | 
48 |   /** Create a package.json for the new project and write it to disk. */
49 |   const packageJson: any = {
50 |     name: appName,
51 |     version: "0.1.0",
52 |     private: true,
53 |     scripts: {
54 |       start: "xmlui start",
55 |       build: "xmlui build",
56 |       preview: "xmlui preview",
57 |       "build-prod": "npm run build -- --prod",
58 |       "release-ci": "npm run build-prod && xmlui zip-dist",
59 |     },
60 |     /**
61 |      * Default dependencies.
62 |      */
63 |     dependencies: {
64 |       "xmlui": pkg.version,
65 |     },
66 |   };
67 | 
68 |   await fs.writeFile(path.join(root, "package.json"), JSON.stringify(packageJson, null, 2) + os.EOL);
69 | 
70 |   console.log("\nInstalling dependencies:");
71 |   for (const dependency in packageJson.dependencies) console.log(`- ${cyan(dependency)}`);
72 | 
73 |   console.log();
74 | 
75 |   await install(packageManager);
76 | };
77 | 
78 | export * from "./types";
79 | 
```

--------------------------------------------------------------------------------
/xmlui/tests/components-core/utils/LruCache.test.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { beforeEach, describe, expect, it } from "vitest";
 2 | import { LRUCache } from "../../../src/components-core/utils/LruCache";
 3 | 
 4 | describe("LRUCache", () => {
 5 |   let lru: LRUCache;
 6 |   beforeEach(() => {
 7 |     lru = new LRUCache(5);
 8 |   });
 9 | 
10 |   it.skip("puts most recently added item to front of list", () => {
11 |     // note: can't test using lru.get() as that will mess up ordering
12 |     //       reach into the internals directly instead
13 |     lru.set("nick", "nick val 1");
14 |     expect(lru!.list!.head!.value).to.equal("nick val 1");
15 |     lru.set("char", "char val 1");
16 |     expect(lru.list!.head!.value).to.equal("char val 1");
17 |     lru.set("nick", "nick val 2");
18 |     expect(lru.list!.head!.value).to.equal("nick val 2");
19 |   });
20 | 
21 |   it("puts most recently accessed item to front of list", () => {
22 |     // note: can't test using lru.get() as that will mess up ordering
23 |     //       reach into the internals directly instead
24 |     lru.set("nick", "nick val 1");
25 |     lru.set("char", "char val 1");
26 |     lru.set("brow", "brow val 1");
27 |     lru.set("lane", "lane val 1");
28 |     lru.get("nick");
29 |     expect(lru.list!.head!.value).to.equal("nick val 1");
30 |     lru.get("char");
31 |     expect(lru.list!.head!.value).to.equal("char val 1");
32 |     lru.get("lane");
33 |     expect(lru.list!.head!.value).to.equal("lane val 1");
34 |     lru.get("brow");
35 |     expect(lru.list!.head!.value).to.equal("brow val 1");
36 |     lru.get("brow");
37 |     expect(lru.list!.head!.value).to.equal("brow val 1");
38 |   });
39 | 
40 |   it.skip("keeps track of size correctly", () => {
41 |     lru.set("nick", "nick val 1");
42 |     expect(lru.list.size).to.equal(1);
43 |     lru.set("char", "char val 1");
44 |     expect(lru.list.size).to.equal(2);
45 |     lru.set("char", "char val 2");
46 |     expect(lru.list.size).to.equal(2);
47 | 
48 |     lru.set("bowie", "bowie val 1");
49 |     lru.set("david", "david val 1");
50 |     lru.set("dobrick", "dobrick val 1");
51 |     expect(lru.list.size).to.equal(5);
52 |   });
53 | 
54 |   it("evicts the last item in list when max size is reached", () => {
55 |     lru.set("nick", 1);
56 |     lru.set("bob", 2);
57 |     lru.set("dylan", 3);
58 |     lru.set("jonny", 4);
59 |     lru.set("depth", 5);
60 |     lru.set("shtick", 6);
61 |     expect(lru.get("nick")).to.equal(undefined);
62 |     expect(lru.get("bob")).not.to.equal(undefined);
63 |   });
64 | });
65 | 
```
Page 11/186FirstPrevNextLast