#
tokens: 43760/50000 2/1624 files (page 101/141)
lines: off (toggle) GitHub
raw markdown copy
This is page 101 of 141. Use http://codebase.md/xmlui-org/xmlui/mockApiDef.js?lines=false&page={x} to view the full context.

# Directory Structure

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

# Files

--------------------------------------------------------------------------------
/xmlui/conventions/copilot-conventions.md:
--------------------------------------------------------------------------------

```markdown
# XMLUI Coding Conventions

## Default Values Convention

### Overview

XMLUI components follow a specific pattern for handling default values to ensure consistency between the component metadata and their React Native implementations. The convention ensures that default values are defined in a single location and referenced throughout the codebase, preventing duplication and inconsistencies.

### Convention Rules

1. **Define Default Values in Native Component**:
   - Default values should be defined in a `defaultProps` object in the Native component implementation file (e.g., `ComponentNameNative.tsx`).
   - The `defaultProps` object should explicitly type which properties it's defining defaults for using TypeScript's `Pick` type.

2. **Reference Default Values in Component Implementation**:
   - When destructuring props in the component implementation, reference the `defaultProps` values as defaults.
   - Example: `{ propName = defaultProps.propName } = props`

3. **Reference Default Values in Component Metadata**:
   - In the component metadata file (e.g., `ComponentName.tsx`), import the `defaultProps` from the Native component.
   - Use these default values in the component metadata's `defaultValue` fields.
   - Example: `defaultValue: defaultProps.propName`

4. **Resolution of Inconsistencies**:
   - If inconsistencies are found between metadata and implementation, the XMLUI (metadata) default value prevails.
   - Update the implementation to match the metadata default value.

### Example Implementation

#### ComponentNameNative.tsx
```typescript
type Props = {
  size?: string;
  color?: string;
  // other props...
};

export const defaultProps: Pick<Props, "size" | "color"> = {
  size: "medium",
  color: "primary",
};

export const ComponentName = forwardRef(function ComponentName(
  { 
    size = defaultProps.size,
    color = defaultProps.color,
    // other props with defaults...
  }: Props,
  forwardedRef: ForwardedRef<HTMLDivElement>
) {
  // Component implementation...
});
```

#### ComponentName.tsx
```typescript
import { createMetadata } from "../../abstractions/ComponentDefs";
import { ComponentName, defaultProps } from "./ComponentNameNative";

export const ComponentNameMd = createMetadata({
  props: {
    size: {
      description: "The size of the component",
      valueType: "string",
      defaultValue: defaultProps.size,
    },
    color: {
      description: "The color of the component",
      valueType: "string", 
      defaultValue: defaultProps.color,
    },
    // other props...
  },
  // other metadata...
});

export const componentNameComponentRenderer = createComponentRenderer(
  "ComponentName",
  ComponentNameMd,
  ({ node, extractValue, layoutCss }) => {
    return (
      <ComponentName
        size={extractValue(node.props.size)}
        color={extractValue(node.props.color)}
        style={layoutCss}
      >
        {/* component content */}
      </ComponentName>
    );
  }
);
```

### Common Mistakes to Avoid

1. **Duplicate Default Definitions**:
   - Don't define default values both in `defaultProps` and inline in the component.
   
2. **Inconsistent Types**:
   - Ensure the type of default values is the same in both metadata and implementation (e.g., `"0.1"` string vs `0.1` number).

3. **Setting `defaultProps` on ComponentMetadata**:
   - The `ComponentMetadata` type doesn't have a `defaultProps` property, so avoid lines like:
   ```typescript
   // Do NOT do this as it causes TypeScript errors
   ComponentNameMd.defaultProps = defaultProps;
   ```

4. **Incomplete Default Props Coverage**:
   - Make sure all props with default values follow this convention, not just some of them.

By following these conventions, we ensure that default values are consistently defined and referenced throughout the XMLUI codebase, making maintenance easier and reducing the likelihood of bugs related to default values.

## GitHub Copilot Conventions

### Conversation Context Summary

When GitHub Copilot summarizes the conversation context for the XMLUI project, it should include the following:

1. **Include Conventions File**:
   - Always read the content of the `/Users/dotneteer/source/xmlui/xmlui/conventions/copilot-conventions.md` file into the context summary.
   - This ensures that all conventions are available to Copilot when continuing work on the project.

2. **Maintain Record of Components Processed**:
   - Keep track of which components have been analyzed and modified.
   - List the component file paths that have been worked on.

3. **Record Code Changes**:
   - Summarize the nature of changes made to components.
   - Include specific details about what default prop patterns were implemented or fixed.

4. **Track Inconsistencies Found**:
   - Document any inconsistencies found between component metadata and implementations.
   - Note how these inconsistencies were resolved.

5. **Note Pending Work**:
   - Maintain a list of components or tasks still pending review or updates.

This convention ensures continuity in long-running tasks and helps maintain a consistent approach to code modifications across the XMLUI project.

## Layout Properties Convention

### Overview

XMLUI has a comprehensive system for handling layout properties that affect component styling and positioning. These properties need to be consistently defined, documented, and integrated throughout the codebase. This convention ensures that any new layout property is properly added to all relevant parts of the system.

### Convention Rules

1. **Layout Property Definition**:
   - All layout properties must be added to the `layoutOptionKeys` array in `descriptorHelper.ts`.
   - Properties should be added in alphabetical order within their logical grouping.

2. **Layout Resolver Integration**:
   - Add the property to the `LayoutProps` type definition in `layout-resolver.ts`.
   - Include the property in the `layoutPatterns` object with appropriate pattern validation.
   - Group properties logically (Dimensions, Typography, Animations, etc.) with clear comments.

3. **Documentation Requirements**:
   - Each layout property requires documentation in two places:
     - `layout-props.md`: A concise definition with a link to detailed documentation.
     - `common-units.md`: Detailed explanation of allowed values, examples, and visual demos.

4. **Theme Keyword Links**:
   - Add the property to the `themeKeywordLinks` object in `MetadataProcessor.mjs`.
   - Link format: `"propertyName": "[propertyName](../styles-and-themes/common-units/#anchor-name)"`.
   - Ensure the anchor name exists in the common-units.md file.

### Implementation Process

When adding a new layout property, follow these steps:

1. **Update Type Definitions**:
   ```typescript
   // In layout-resolver.ts
   export type LayoutProps = {
     // ...existing properties
     
     // Add new property in appropriate section with comment
     newProperty?: string | number;
   };
   ```

2. **Update Layout Patterns**:
   ```typescript
   // In layout-resolver.ts - layoutPatterns object
   const layoutPatterns: Record<keyof LayoutProps, RegExp[]> = {
     // ...existing patterns
     
     // Add new property (with validation patterns if needed)
     newProperty: [],
   };
   ```

3. **Update Property Keys**:
   ```typescript
   // In descriptorHelper.ts
   export const layoutOptionKeys = [
     // ...existing keys
     "newProperty",
   ];
   ```

4. **Add Documentation in `layout-props.md`**:
   ```markdown
   ## `newProperty`

   This property [describes what it does](/styles-and-themes/common-units#anchor-name).
   ```

5. **Add Detailed Documentation in `common-units.md`**:
   ```markdown
   ## New Property Values [#anchor-name]

   This value [detailed description of what it does and how it works]...
   
   | Value | Description |
   | ----- | ----------- |
   | `value1` | Description of value1 |
   | `value2` | Description of value2 |
   
   ```xmlui-pg name="Example name"
   <App>
     // Example showing the property in use
   </App>
   ```
   ```

6. **Add Theme Keyword Link**:
   ```javascript
   // In MetadataProcessor.mjs - themeKeywordLinks object
   const themeKeywordLinks = {
     // ...existing links
     newProperty: "[newProperty](../styles-and-themes/common-units/#anchor-name)",
   };
   ```

### Common Patterns for Layout Properties

1. **Size Properties**:
   - Support standard CSS units (`px`, `rem`, `em`, `%`, etc.)
   - May support special values like `auto`, `inherit`, etc.
   - Anchor: `#size`

2. **Color Properties**:
   - Support color names, hex values, rgb/rgba, hsl/hsla
   - May support theme variables with `$` prefix
   - Anchor: `#color`

3. **Style Properties**:
   - Usually support enumerated string values (`solid`, `dashed`, etc.)
   - Document all possible values in a table
   - Create property-specific anchor (e.g., `#border-style`)

4. **Animation Properties**:
   - Document component parts (duration, timing function, etc.)
   - Include examples with visual demonstrations
   - Anchor: specific to property (e.g., `#transition`)

5. **Text and Typography Properties**:
   - Group related properties together in documentation
   - Include visual examples showing differences
   - Anchors: specific to property (e.g., `#text-align`, `#word-spacing`)

### Example Implementation

#### Adding the `transition` Layout Property

1. **Update Layout Properties Type**:
   ```typescript
   // In layout-resolver.ts
   export type LayoutProps = {
     // ...existing properties
     
     // --- Animation
     transition?: string;
   };
   ```

2. **Update Layout Patterns**:
   ```typescript
   // In layout-resolver.ts - layoutPatterns object
   const layoutPatterns: Record<keyof LayoutProps, RegExp[]> = {
     // ...existing patterns
     
     // --- Animation
     transition: [],
   };
   ```

3. **Update Property Keys**:
   ```typescript
   // In descriptorHelper.ts
   export const layoutOptionKeys = [
     // ...existing keys
     "transition",
   ];
   ```

4. **Add Property Documentation in `layout-props.md`**:
   ```markdown
   ## `transition`

   This property is a shorthand for [transition effects](/styles-and-themes/common-units#transition) that specify the CSS property to which a transition effect should be applied, the duration and timing of the transition, and any delay.
   ```

5. **Add Detailed Documentation in `common-units.md`** (simplified example):
   ```markdown
   ## Transition Values [#transition]

   This value specifies the CSS property to animate, the duration, timing function, and delay...
   
   | Timing Function Values | Description |
   | --------------------- | ----------- |
   | `ease`                | Starts slow, becomes fast, then ends slowly... |
   
   ```xmlui-pg name="Transition examples"
   <App>
     // Examples showing transitions
   </App>
   ```
   ```

6. **Add Theme Keyword Link**:
   ```javascript
   // In MetadataProcessor.mjs - themeKeywordLinks object
   const themeKeywordLinks = {
     // ...existing links
     transition: "[transition](../styles-and-themes/common-units/#transition)",
   };
   ```

By following these conventions, we ensure consistent implementation and documentation of layout properties across the XMLUI codebase, making the system more maintainable and easier to extend.

## End-to-End Testing Convention

### Overview

XMLUI components require comprehensive end-to-end testing using Playwright to ensure reliability, accessibility, and performance. This convention establishes patterns for creating thorough test suites that cover all aspects of component behavior, from basic functionality to edge cases and performance optimizations.

### Component Test Location Map

| Component Type | Component Location | Test File Location |
| -------------- | ----------------- | ----------------- |
| Standard Components | `/xmlui/src/components/ComponentName/ComponentName.tsx` | `/xmlui/src/components/ComponentName/ComponentName.spec.ts` |
| Container Components | `/xmlui/src/components/Container/Container.tsx` | `/xmlui/src/components/Container/Container.spec.ts` |
| Form Components | `/xmlui/src/components/FormControl/FormControl.tsx` | `/xmlui/src/components/FormControl/FormControl.spec.ts` |

**Critical Rules for Test Creation:**
1. ✅ ALL component tests MUST be placed in the same folder as the component itself
2. ✅ ALL newly created tests MUST use the `.skip` modifier
3. ✅ Each skipped test MUST include the comment: `// TODO: review these Copilot-created tests`
4. ❌ NEVER place tests in the global test directory (`/tests/tests/`)
5. ❌ NEVER create non-skipped tests for new components

### Convention Rules

1. **Test Structure and Organization**:
   - Tests should be organized into logical sections with clear comments and separators.
   - Use descriptive test names that clearly indicate what behavior is being tested.
   - Group related tests together (e.g., "Size Property Tests", "Edge Cases and Name Processing").

2. **Comprehensive Test Coverage**:
   - **Basic Functionality**: Core component behavior and prop handling
   - **Accessibility**: ARIA attributes, keyboard navigation, screen reader compatibility
   - **Visual States**: Different visual configurations and state transitions
   - **Edge Cases**: Null/undefined props, empty values, special characters
   - **Performance**: Memoization, rapid prop changes, memory stability
   - **Integration**: Component behavior in different layout contexts

3. **Test Implementation Patterns**:
   - Use `initTestBed` for component setup with proper XMLUI markup
   - Create driver instances for component interaction
   - Use `expect.poll()` for async state verification
   - Implement proper cleanup and isolation between tests

4. **Accessibility Testing Requirements**:
   - Verify correct ARIA attributes (`aria-label`, `role`)
   - Test keyboard navigation and focus management
   - Ensure proper alt text for images
   - Validate screen reader compatibility

5. **Performance Testing Patterns**:
   - Test memoization behavior through functional verification
   - Verify efficient prop change handling
   - Test memory stability with multiple component instances
   - Ensure smooth state transitions

### Test Categories and Implementation

#### 1. Basic Functionality Tests
```typescript
test("component renders with basic props", async ({ initTestBed, createComponentDriver }) => {
  await initTestBed(`<ComponentName prop="value"/>`, {});
  const driver = await createComponentDriver();
  
  await expect(driver.component).toBeVisible();
  await expect(driver.component).toContainText("Expected Content");
});
```

#### 2. Accessibility Tests
```typescript
test("component has correct accessibility attributes", async ({ initTestBed, createComponentDriver }) => {
  await initTestBed(`<ComponentName name="Test User"/>`, {});
  const driver = await createComponentDriver();
  
  await expect(driver.component).toHaveAttribute('aria-label', 'Expected Label');
  await expect(driver.component).toHaveAttribute('role', 'expected-role');
});

test("component is keyboard accessible when interactive", async ({ initTestBed, createComponentDriver }) => {
  const { testStateDriver } = await initTestBed(`
    <ComponentName 
      name="Test User"
      onClick="testState = 'keyboard-activated'"
    />
  `, {});
  
  const driver = await createComponentDriver();
  
  await driver.component.focus();
  await expect(driver.component).toBeFocused();
  
  await driver.component.press('Enter');
  await expect.poll(testStateDriver.testState).toEqual('keyboard-activated');
});
```

#### 3. Visual State Tests
```typescript
test("component handles different visual states", async ({ initTestBed, createComponentDriver }) => {
  // Test initial state
  await initTestBed(`<ComponentName state="initial"/>`, {});
  const driver1 = await createComponentDriver();
  await expect(driver1.component).toHaveClass(/initial-state/);
  
  // Test changed state
  await initTestBed(`<ComponentName state="changed"/>`, {});
  const driver2 = await createComponentDriver();
  await expect(driver2.component).toHaveClass(/changed-state/);
});
```

#### 4. Edge Case Tests
```typescript
test("component handles null and undefined props gracefully", async ({ initTestBed, createComponentDriver }) => {
  // Test with undefined props
  await initTestBed(`<ComponentName/>`, {});
  const driver1 = await createComponentDriver();
  await expect(driver1.component).toBeVisible();
  
  // Test with empty string props
  await initTestBed(`<ComponentName prop=""/>`, {});
  const driver2 = await createComponentDriver();
  await expect(driver2.component).toBeVisible();
});

test("component handles special characters correctly", async ({ initTestBed, createComponentDriver }) => {
  await initTestBed(`<ComponentName name="José María"/>`, {});
  const driver = await createComponentDriver();
  await expect(driver.component).toBeVisible();
  // Test specific behavior with special characters
});
```

#### 5. Performance Tests
```typescript
test("component memoization prevents unnecessary re-renders", async ({ initTestBed, createComponentDriver }) => {
  const { testStateDriver } = await initTestBed(`
    <ComponentName 
      name="Test User"
      onClick="testState = ++testState || 1"
    />
  `, {});
  
  const driver = await createComponentDriver();
  
  // Test that memoization works through stable behavior
  await driver.component.click();
  await expect.poll(testStateDriver.testState).toEqual(1);
  
  await driver.component.click();
  await expect.poll(testStateDriver.testState).toEqual(2);
  
  // Component should maintain consistent behavior
  await expect(driver.component).toBeVisible();
});

test("component handles rapid prop changes efficiently", async ({ initTestBed, createComponentDriver }) => {
  // Test multiple rapid prop changes
  await initTestBed(`<ComponentName prop="value1"/>`, {});
  const driver1 = await createComponentDriver();
  await expect(driver1.component).toBeVisible();
  
  await initTestBed(`<ComponentName prop="value2"/>`, {});
  const driver2 = await createComponentDriver();
  await expect(driver2.component).toBeVisible();
  
  // Verify final state is correct
  await expect(driver2.component).toContainText("Expected Final Content");
});
```

#### 6. Integration Tests
```typescript
test("component works correctly in different layout contexts", async ({ initTestBed, createComponentDriver }) => {
  await initTestBed(`<ComponentName name="Layout Test"/>`, {});
  const driver = await createComponentDriver();
  
  // Test basic layout integration
  await expect(driver.component).toBeVisible();
  
  // Test bounding box and dimensions
  const boundingBox = await driver.component.boundingBox();
  expect(boundingBox).not.toBeNull();
  expect(boundingBox!.width).toBeGreaterThan(0);
  expect(boundingBox!.height).toBeGreaterThan(0);
});
```

### Component-Specific Testing Considerations

#### Container Components (like Accordion)
1. **Expansion State Testing**:
   ```typescript
   test("component expands and collapses correctly", async ({ initTestBed, createAccordionDriver }) => {
     await initTestBed(`<Accordion><AccordionItem header="Test">Content</AccordionItem></Accordion>`, {});
     const driver = await createAccordionDriver();
     
     // Test initial collapsed state
     let content = driver.component.locator(".accordion-content");
     await expect(content).not.toBeVisible();
     
     // Click to expand
     const header = driver.component.locator(".accordion-header");
     await header.click();
     
     // Test expanded state
     await expect(content).toBeVisible();
     
     // Click to collapse
     await header.click();
     
     // Test collapsed state again
     await expect(content).not.toBeVisible();
   });
   ```

2. **Multiple Item Testing**:
   ```typescript
   test("multiple items can expand independently", async ({ initTestBed, createAccordionDriver }) => {
     await initTestBed(`
       <Accordion>
         <AccordionItem header="Item 1">Content 1</AccordionItem>
         <AccordionItem header="Item 2">Content 2</AccordionItem>
       </Accordion>
     `, {});
     
     const driver = await createAccordionDriver();
     const headers = driver.component.locator(".accordion-header").all();
     
     // Expand first item
     await (await headers)[0].click();
     
     // Verify first expanded, second collapsed
     let contents = driver.component.locator(".accordion-content").all();
     await expect((await contents)[0]).toBeVisible();
     await expect((await contents)[1]).not.toBeVisible();
   });
   ```

3. **Component API Testing**:
   ```typescript
   test("component API methods work correctly", async ({ initTestBed, createAccordionDriver, page }) => {
     const { testStateDriver } = await initTestBed(`
       <Accordion ref="accordionRef">
         <AccordionItem header="API Test">Content</AccordionItem>
       </Accordion>
       <Button id="expandBtn" onClick="accordionRef.expand('0'); testState = 'expanded'">Expand</Button>
     `, {});
     
     const driver = await createAccordionDriver();
     
     // Test API method
     await page.locator("#expandBtn").click();
     await expect.poll(testStateDriver.testState).toEqual('expanded');
     
     // Verify component state changed
     const content = driver.component.locator(".accordion-content");
     await expect(content).toBeVisible();
   });
   ```

4. **Icon Rendering Testing**:
   ```typescript
   test("component displays custom icons", async ({ initTestBed, createAccordionDriver }) => {
     await initTestBed(`
       <Accordion collapsedIcon="plus" expandedIcon="minus">
         <AccordionItem header="Custom Icons">Content</AccordionItem>
       </Accordion>
     `, {});
     
     const driver = await createAccordionDriver();
     
     // Check collapsed icon
     const icon = driver.component.locator(".chevron");
     await expect(icon).toHaveAttribute("data-icon-name", "plus");
     
     // Expand and check expanded icon
     const header = driver.component.locator(".accordion-header");
     await header.click();
     await expect(icon).toHaveAttribute("data-icon-name", "minus");
   });
   ```

#### Components With Custom Templates

1. **Custom Template Rendering**:
   ```typescript
   test("component renders custom templates correctly", async ({ initTestBed, createComponentDriver }) => {
     await initTestBed(`
       <ComponentName headerTemplate={
         <div>
           <Icon name="star" />
           <Text fontWeight="bold">Custom Template</Text>
         </div>
       }>
         Content
       </ComponentName>
     `, {});
     
     const driver = await createComponentDriver();
     
     // Verify template elements rendered correctly
     await expect(driver.component.locator("svg[data-icon-name='star']")).toBeVisible();
     await expect(driver.component.locator("text=Custom Template")).toBeVisible();
   });
   ```

#### Testing Theme Variables

1. **Theme Variable Application Testing**:
   ```typescript
   test("applies theme variables to specific element parts", async ({ initTestBed, createComponentDriver }) => {
     await initTestBed(`<ComponentName />`, {
       testThemeVars: {
         "backgroundColor-header-ComponentName": "rgb(255, 0, 0)",
         "color-content-ComponentName": "rgb(0, 255, 0)",
       },
     });
     
     const driver = await createComponentDriver();
     
     // Check styles applied to specific component parts
     await expect(driver.component.locator(".header")).toHaveCSS("background-color", "rgb(255, 0, 0)");
     await expect(driver.component.locator(".content")).toHaveCSS("color", "rgb(0, 255, 0)");
   });
   ```

2. **Border and Padding Theme Variables**:
   ```typescript
   test("applies border and padding theme variables correctly", async ({ initTestBed, createComponentDriver }) => {
     await initTestBed(`<ComponentName />`, {
       testThemeVars: {
         "border-ComponentName": "1px solid rgb(255, 0, 0)",
         "padding-ComponentName": "10px",
       },
     });
     
     const driver = await createComponentDriver();
     
     // Check border properties
     await expect(driver.component).toHaveCSS("border-width", "1px");
     await expect(driver.component).toHaveCSS("border-style", "solid");
     await expect(driver.component).toHaveCSS("border-color", "rgb(255, 0, 0)");
     
     // Check padding
     await expect(driver.component).toHaveCSS("padding", "10px");
   });
   ```

3. **Border Side-Specific Theme Variables**:
   ```typescript
   test("prioritizes specific border sides over general border", async ({ initTestBed, createComponentDriver }) => {
     await initTestBed(`<ComponentName />`, {
       testThemeVars: {
         "border-ComponentName": "1px solid rgb(0, 0, 0)",
         "borderLeft-ComponentName": "2px dashed rgb(255, 0, 0)",
       },
     });
     
     const driver = await createComponentDriver();
     
     // Check general borders applied to most sides
     await expect(driver.component).toHaveCSS("border-top-width", "1px");
     await expect(driver.component).toHaveCSS("border-right-width", "1px");
     await expect(driver.component).toHaveCSS("border-bottom-width", "1px");
     
     // Check specific side override
     await expect(driver.component).toHaveCSS("border-left-width", "2px");
     await expect(driver.component).toHaveCSS("border-left-style", "dashed");
     await expect(driver.component).toHaveCSS("border-left-color", "rgb(255, 0, 0)");
   });
   ```

### Test Name and Organization Patterns

1. **Naming Components Tests by Feature**:
   - Avoid: `"test component with value X"`
   - Prefer: `"renders with size=small correctly"`

2. **Naming Pattern for Behavior Tests**:
   - `"{verb} {feature} {when/with} {condition}"`
   - Examples: 
     - `"expands when header is clicked"`
     - `"applies red background with danger prop"`
     - `"renders placeholder when value is empty"`

3. **Naming Pattern for Property Tests**:
   - `"prioritizes {specific-prop} over {general-prop}"`
   - `"applies {style} to {component-part} with {theme-var}"`
   - Examples:
     - `"prioritizes borderLeftWidth over borderWidth"`
     - `"applies padding to all sides with padding theme var"`

4. **Test Organization Patterns**:
   ```typescript
   // =============================================================================
   // BASIC FUNCTIONALITY TESTS
   // =============================================================================
   
   test("renders with basic props", async () => {});
   test("updates display when props change", async () => {});
   
   // =============================================================================
   // ACCESSIBILITY TESTS
   // =============================================================================
   
   test("has correct accessibility attributes", async () => {});
   test("is keyboard accessible when interactive", async () => {});
   
   // =============================================================================
   // VISUAL STATE TESTS
   // =============================================================================
   
   test("applies theme variables correctly", async () => {});
   test("handles different visual states", async () => {});
   
   // =============================================================================
   // EDGE CASE TESTS
   // =============================================================================
   
   test("handles null and undefined props gracefully", async () => {});
   test("handles special characters correctly", async () => {});
   
   // =============================================================================
   // PERFORMANCE TESTS
   // =============================================================================
   
   test("memoization prevents unnecessary re-renders", async () => {});
   
   // =============================================================================
   // INTEGRATION TESTS
   // =============================================================================
   
   test("works correctly in different layout contexts", async () => {});
   ```

By following these conventions, XMLUI components will have comprehensive, reliable, and maintainable end-to-end test suites that ensure quality and performance across all scenarios.

### Skipped Test Creation Convention

When creating skeleton tests for components, follow these guidelines to ensure consistency and maintainability across the test suite. These tests provide a roadmap for future implementation while maintaining a clear structure.

#### Convention Rules (CRITICAL)

1. **Test Structure Organization**:
   - Organize existing tests into appropriate categories (Basic Functionality, Accessibility, etc.)
   - Maintain clear section separators with consistent formatting
   - Keep related tests grouped together within their sections

2. **Test Naming Conventions**:
   - Rename existing tests to follow naming conventions (as described in Test Name and Organization Patterns)
   - Use descriptive, action-oriented names that clearly indicate what's being tested
   - Be specific about the behavior or prop being verified

3. **Skipped Test Creation** (MANDATORY):
   - ✅ ALL newly created tests MUST be skipped using the `.skip` modifier
   - ✅ ALWAYS include the standard TODO comment: `// TODO: review these Copilot-created tests`
   - ✅ Implement a complete test body that follows test patterns for that category
   - ❌ NEVER create non-skipped tests when adding skeleton tests to components

4. **Complete Implementation**:
   - Even in skipped tests, provide a complete implementation
   - Include proper assertions that verify the expected behavior
   - Structure the test to provide a clear example of how it should work when enabled

#### Implementation Process

1. **Organize Tests by Category**:
   ```typescript
   // =============================================================================
   // BASIC FUNCTIONALITY TESTS
   // =============================================================================

   // (Basic tests here)

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

   // (Accessibility tests here)
   ```

2. **Rename Existing Tests with Clear Patterns**:
   - Before: `test("component test", async () => {...})`
   - After: `test("renders with size={size} correctly", async () => {...})`

3. **Add Skipped Tests with TODO Comments**:
   ```typescript
   test.skip("component applies correct theme variables", async ({ initTestBed, createComponentDriver }) => {
     // TODO: review these Copilot-created tests
     
     await initTestBed(`<ComponentName />`, {
       testThemeVars: {
         "backgroundColor-ComponentName": "rgb(255, 0, 0)",
       },
     });
     
     const driver = await createComponentDriver();
     await expect(driver.component).toHaveCSS("background-color", "rgb(255, 0, 0)");
   });
   ```

4. **Implement Complete Test Bodies**:
   ```typescript
   test.skip("handles keyboard navigation correctly", async ({ initTestBed, createComponentDriver }) => {
     // TODO: review these Copilot-created tests
     
     const { testStateDriver } = await initTestBed(`
       <ComponentName 
         onKeyDown="testState = 'key-pressed'"
       />
     `, {});
     
     const driver = await createComponentDriver();
     
     // Focus the component
     await driver.component.focus();
     await expect(driver.component).toBeFocused();
     
     // Test keyboard interaction
     await driver.component.press('Enter');
     await expect.poll(testStateDriver.testState).toEqual('key-pressed');
   });
   ```

#### Example Test Suite with Skipped Tests

```typescript
import { test, expect } from '@playwright/test';

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

test("renders with default props", async ({ initTestBed, createComponentDriver }) => {
  await initTestBed(`<ComponentName />`, {});
  const driver = await createComponentDriver();
  await expect(driver.component).toBeVisible();
});

test.skip("updates display when prop changes", async ({ initTestBed, createComponentDriver }) => {
  // TODO: review these Copilot-created tests
  
  // Test with initial prop
  await initTestBed(`<ComponentName value="initial" />`, {});
  let driver = await createComponentDriver();
  await expect(driver.component).toContainText("initial");
  
  // Test with updated prop
  await initTestBed(`<ComponentName value="updated" />`, {});
  driver = await createComponentDriver();
  await expect(driver.component).toContainText("updated");
});

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

test.skip("has correct accessibility attributes", async ({ initTestBed, createComponentDriver }) => {
  // TODO: review these Copilot-created tests
  
  await initTestBed(`<ComponentName label="Accessible Component" />`, {});
  const driver = await createComponentDriver();
  
  await expect(driver.component).toHaveAttribute('role', 'button');
  await expect(driver.component).toHaveAttribute('aria-label', 'Accessible Component');
  await expect(driver.component).toHaveAttribute('tabindex', '0');
});
```

### Best Practices for Skipped Tests

1. **Clear Reasoning**: The skipped test should clearly indicate why it's important to implement later
2. **Full Implementation**: Implement the complete test body, not just a placeholder
3. **Readable Examples**: Make the test easy to understand for developers who will enable it later
4. **Descriptive Names**: Use clear test names that explain exactly what behavior is being tested
5. **Proper Isolation**: Each skipped test should be independent of other tests
6. **Comprehensive Coverage**: Create skipped tests for all important functionality, even if it's not implemented yet

### Common Mistakes to Avoid

1. **Empty Test Bodies**: Don't create skipped tests without implementing the test body
2. **Missing Comments**: Always include the TODO comment explaining these are Copilot-created tests
3. **Vague Names**: Avoid generic test names like "test component behavior"
4. **Untestable Assertions**: Don't make assertions that can't be tested with the current implementation
5. **Incomplete Categories**: Make sure all required test categories (accessibility, etc.) are represented

By following these conventions for skipped tests, you create a valuable roadmap for future test implementation while maintaining a clear and organized test structure. This approach helps ensure comprehensive test coverage even when all tests aren't immediately ready to run.

### Test File Location Conventions (CRITICAL)

When creating component tests, follow these location conventions:

1. **Component-Level Test Location** (MANDATORY):
   - ✅ Test files MUST be located in the same directory as the component being tested
   - ✅ Use the naming convention `ComponentName.spec.ts` for test files
   - ✅ Example: For a component defined in `/components/Button/Button.tsx`, the test MUST be at `/components/Button/Button.spec.ts`
   - ❌ NEVER place test files in the global test directory (`/tests/tests/`)

2. **Test Import Paths**:
   - Import test utilities from the testing directory:
     ```typescript
     import { expect, test } from "../../testing/fixtures";
     import { getStyles } from "../../testing/component-test-helpers";
     ```
   - Adjust import paths based on the relative location of the component and testing utilities

3. **Component Driver Parameters**:
   - Use the appropriate fixture parameters based on component needs:
     ```typescript
     test.skip("basic test", async ({ initTestBed, createComponentDriver }) => {
       // For components with component drivers
     });
     ```

4. **Test Execution Context**:
   - Tests should be executed from the component's directory
   - Run specific component tests with: `npx playwright test ComponentName.spec.ts`
   - Test runners will automatically locate tests in the component directories

This location convention ensures tests are closely associated with their components, making the codebase easier to maintain and navigate. It also simplifies the process of finding and updating tests when component implementations change.

### Test Execution and Verification

### Proper Test File Structure Example

Below is an example of a correctly structured skeleton test file for a component. Note that ALL tests are marked with `.skip` and include the required TODO comment:

```typescript
import { test, expect } from "../../testing/fixtures";
import { getStyles } from "../../testing/component-test-helpers";

// Constants for testing
const RED = "rgb(255, 0, 0)";
const GREEN = "rgb(0, 255, 0)";

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

test.skip("component renders with basic props", async ({ initTestBed, createComponentDriver }) => {
  // TODO: review these Copilot-created tests
  
  await initTestBed(`<ComponentName prop="value"/>`);
  const driver = await createComponentDriver();
  
  await expect(driver.component).toBeVisible();
  await expect(driver.component).toContainText("Expected Content");
});

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

test.skip("component has correct accessibility attributes", async ({ initTestBed, createComponentDriver }) => {
  // TODO: review these Copilot-created tests
  
  await initTestBed(`<ComponentName label="Accessible Label"/>`);
  const driver = await createComponentDriver();
  
  await expect(driver.component).toHaveAttribute('role', 'button');
  await expect(driver.component).toHaveAttribute('aria-label', 'Accessible Label');
});

// =============================================================================
// VISUAL STATE TESTS
// =============================================================================

test.skip("component applies theme variables correctly", async ({ initTestBed, createComponentDriver }) => {
  // TODO: review these Copilot-created tests
  
  await initTestBed(`<ComponentName />`, {
    testThemeVars: {
      "backgroundColor-ComponentName": RED,
    },
  });
  
  const driver = await createComponentDriver();
  await expect(driver.component).toHaveCSS("background-color", RED);
});

// All remaining test categories follow the same pattern...
```

This example shows the proper structure with:
1. Correct imports from the testing directory
2. Section separators for test categories
3. ALL tests marked with `.skip`
4. Required TODO comment in each test
5. Proper test implementation following the patterns

```

--------------------------------------------------------------------------------
/xmlui/src/parsers/xmlui-parser/transform.ts:
--------------------------------------------------------------------------------

```typescript
import type { ComponentDef, CompoundComponentDef } from "../../abstractions/ComponentDefs";
import { collectCodeBehindFromSource } from "../scripting/code-behind-collect";
import { Node } from "./syntax-node";
import type { ErrorCodes } from "./ParserError";
import { SyntaxKind } from "./syntax-kind";
import { ParserError, errorMessages } from "./ParserError";
import { Parser } from "../scripting/Parser";
import { CharacterCodes } from "./CharacterCodes";
import type { GetText } from "./parser";
import type { ParsedEventValue } from "../../abstractions/scripting/Compilation";

export const COMPOUND_COMP_ID = "Component";
export const UCRegex = /^[A-Z]/;
export const onPrefixRegex = /^on[A-Z]/;
const propAttrs = ["name", "value"];

const CDATA_PREFIX_LEN = 9;
const CDATA_POSTFIX_LEN = 3;
const COMPONENT_NAMESPACE_SCHEME = "component-ns";
const APP_NS_KEY = "app-ns";
const APP_NS_VALUE = "#app-ns";
const CORE_NS_KEY = "core-ns";
export const CORE_NAMESPACE_VALUE = "#xmlui-core-ns";

/** Nodes which got modified or added during transformation keep their own text,
 * since they are not present in the original source text */
interface TransformNode extends Node {
  text?: string;
}

const HelperNode = {
  property: "property",
  event: "event",
  variable: "variable",
  loaders: "loaders",
  uses: "uses",
  method: "method",
  item: "item",
  field: "field",
} as const;

let lastParseId = 0;

export function nodeToComponentDef(
  node: Node,
  originalGetText: GetText,
  fileId: string | number,
): ComponentDef | CompoundComponentDef | null {
  const getText = (node: TransformNode) => {
    return node.text ?? originalGetText(node);
  };

  const element = getTopLvlElement(node, getText);
  const preppedElement = prepNode(element);
  const usesStack: Map<string, string>[] = [];
  const namespaceStack: Map<string, string>[] = [];
  return transformTopLvlElement(usesStack, preppedElement);

  function transformTopLvlElement(
    usesStack: Map<string, string>[],
    node: Node,
  ): ComponentDef | CompoundComponentDef | null {
    const name = getNamespaceResolvedComponentName(node, getText, namespaceStack);

    if (name === COMPOUND_COMP_ID) {
      return collectCompoundComponent(node);
    }

    let component: ComponentDef = {
      type: name,
      debug: {
        source: {
          start: node.start,
          end: node.end,
          fileId,
        },
      },
    };

    // --- Done
    collectTraits(usesStack, component, node);
    return component;
  }

  function transformInnerElement(
    usesStack: Map<string, string>[],
    node: Node,
  ): ComponentDef | CompoundComponentDef | null {
    const name = getNamespaceResolvedComponentName(node, getText, namespaceStack);

    if (name === COMPOUND_COMP_ID) {
      reportError("T006");
    }

    let component: ComponentDef = {
      type: name,
      debug: {
        source: {
          start: node.start,
          end: node.end,
          fileId,
        },
      },
    };

    // --- Done
    collectTraits(usesStack, component, node);
    return component;
  }

  function collectCompoundComponent(node: Node) {
    const attrs = getAttributes(node).map(segmentAttr);
    // --- Validate component name
    const compoundName = attrs.find((attr) => attr.name === "name");
    if (!compoundName) {
      reportError("T003");
    }
    if (!UCRegex.test(compoundName.value)) {
      reportError("T004");
    }

    const codeBehind = attrs.find((attr) => attr.name === "codeBehind");

    // --- Get "method" attributes
    let api: Record<string, any> | undefined;
    const apiAttrs = attrs.filter((attr) => attr.startSegment === "method");
    if (apiAttrs.length > 0) {
      api = {};
      apiAttrs.forEach((attr) => {
        api![attr.name] = attr.value;
      });
    }

    // --- Get var attributes
    let vars: Record<string, any> | undefined;
    const varsAttrs = attrs.filter((attr) => attr.startSegment === "var");
    if (varsAttrs.length > 0) {
      vars = {};
      varsAttrs.forEach((attr) => {
        vars![attr.name] = attr.value;
      });
    }

    const children = getChildNodes(node);

    // --- Get the single component definition
    const nestedComponents = children.filter(
      (child) =>
        child.kind === SyntaxKind.ElementNode && !(getComponentName(child, getText) in HelperNode),
    );
    if (nestedComponents.length === 0) {
      nestedComponents.push(createTextNodeElement(""));
    }

    const nonVarHelperNodes: Node[] = [];
    const nestedVars: Node[] = [];
    for (let child of children) {
      if (child.kind === SyntaxKind.ElementNode) {
        const childName = getComponentName(child, getText);
        if (childName === HelperNode.variable) {
          nestedVars.push(child);
        } else if (childName in HelperNode) {
          nonVarHelperNodes.push(child);
        }
      }
    }

    // --- Should we wrap with a Fragment?
    let element: Node;
    if (nestedComponents.length > 1 || nestedVars.length > 0) {
      element = wrapWithFragment([...nestedVars, ...nestedComponents]);
    } else {
      element = nestedComponents[0];
    }

    namespaceStack.push(new Map());
    // --- Get collect namespace attributes
    const nsAttrs = attrs
      .filter((attr) => attr.namespace === "xmlns")
      .forEach((attr) => {
        addToNamespaces(namespaceStack, element, attr.unsegmentedName, attr.value);
      });

    let nestedComponent: ComponentDef = transformInnerElement(usesStack, element)! as ComponentDef;
    namespaceStack.pop();

    const component: CompoundComponentDef = {
      name: compoundName.value,
      component: nestedComponent,
      debug: {
        source: {
          start: node.start,
          end: node.end,
          fileId,
        },
      },
    };

    if (api) {
      component.api = api;
    }
    if (vars) {
      nestedComponent.vars = { ...nestedComponent.vars, ...vars };
    }
    if (codeBehind) {
      component.codeBehind = codeBehind.value;
    }

    nestedComponent.debug = {
      source: {
        start: element.start,
        end: element.end,
        fileId,
      },
    };

    const nodeClone: Node = withNewChildNodes(node, nonVarHelperNodes);
    collectTraits(usesStack, component, nodeClone);
    return component;
  }

  /**
   * Collects component traits from attributes and child elements
   * @param comp Component definition
   * @param element Component element
   */
  function collectTraits(
    usesStack: Map<string, string>[],
    comp: ComponentDef | CompoundComponentDef,
    element: Node,
  ): void {
    const isCompound = !isComponent(comp);

    const attributes = getAttributes(element);

    namespaceStack.push(new Map());
    // --- Process attributes
    attributes.forEach((attr: Node) => {
      // --- Process the attribute
      collectAttribute(comp, attr);
    });
    const childNodes = getChildNodes(element);

    // --- Process child nodes
    childNodes.forEach((child: Node) => {
      if (child.kind === SyntaxKind.Script) {
        if (getAttributes(child).length > 0) {
          reportError("T022");
        }
        const scriptText = getText(child);
        const scriptContent = scriptText.slice(
          scriptText.indexOf(">") + 1,
          scriptText.lastIndexOf("</"),
        );

        comp.script ??= "";
        if (comp.script.length > 0) {
          comp.script += "\n";
        }
        comp.script += scriptContent;
        return;
      }

      // --- Single text element, consider it a child name
      if (child.kind === SyntaxKind.TextNode && !isCompound) {
        comp.children = mergeValue(comp.children, getText(child));
        return;
      }

      const childName = getComponentName(child, getText);
      if (isCompound && child.kind === SyntaxKind.ElementNode && !(childName in HelperNode)) {
        // --- This is the single nested component definition of a compound component,
        // --- it is already processed
        return;
      }

      // --- Element name starts with an uppercase letter
      if (!(childName in HelperNode) && !isCompound) {
        // if (UCRegex.test(childName) && !isCompound) {
        // --- This must be a child component
        // maybe here or in the transformInnerElement function, after the compound comp check
        const childComponent = transformInnerElement(usesStack, child);
        if (childComponent) {
          if (!comp.children) {
            comp.children = [childComponent as ComponentDef];
          } else {
            if (typeof comp.children === "string") {
              comp.children = [comp.children as any, childComponent];
            } else if (Array.isArray(comp.children)) {
              comp.children.push(childComponent as any);
            }
          }
        }
        return;
      }

      // --- Element with a lowercase start letter, it must be some traits of the host component
      switch (childName) {
        case "property":
          collectElementHelper(
            usesStack,
            comp,
            child,

            (name) => (isComponent(comp) ? comp.props?.[name] : undefined),
            (name, value) => {
              if (!isComponent(comp)) return;
              comp.props ??= {};
              comp.props[name] = value;
            },
          );
          return;

        case "event":
          collectElementHelper(
            usesStack,
            comp,
            child,

            (name) => (isComponent(comp) ? comp.events?.[name] : undefined),
            (name, value) => {
              if (!isComponent(comp)) return;
              comp.events ??= {};
              comp.events[name] = parseEvent(value);
            },
            (name) => {
              if (onPrefixRegex.test(name)) {
                reportError("T008", name);
              }
            },
          );
          return;

        case HelperNode.variable:
          collectElementHelper(
            usesStack,
            comp,
            child,

            (name) => (isComponent(comp) ? comp.vars?.[name] : undefined),
            (name, value) => {
              if (!isComponent(comp)) return;
              comp.vars ??= {};
              comp.vars[name] = value;
            },
          );
          return;

        case "loaders":
          collectLoadersElements(usesStack, comp, child);
          return;

        case "uses":
          collectUsesElements(comp, child);
          return;

        case "method":
          collectElementHelper(
            usesStack,
            comp,
            child,

            (name) => (isComponent(comp) ? comp.api?.[name] : undefined),
            (name, value) => {
              comp.api ??= {};
              comp.api[name] = value;
            },
          );
          return;

        default:
          reportError("T009", childName);
          return;
      }
    });

    namespaceStack.pop();

    if (!comp.script || comp.script.trim().length === 0) {
      // --- No (or whitespace only) script
      return;
    }

    // --- Run the parse and collect on scripts
    const parser = new Parser(comp.script);
    try {
      // --- We parse the module file to catch parsing errors
      parser.parseStatements();
      comp.scriptCollected = collectCodeBehindFromSource("Main", comp.script);
    } catch (err) {
      if (parser.errors && parser.errors.length > 0) {
        const errMsg = parser.errors[0];
        throw new ParserError(`${errMsg.text} [${errMsg.line}: ${errMsg.column}]`, errMsg.code);
      } else {
        comp.scriptError = err;
      }
    }

    // --- We may have module parsing/execution errors
    const moduleErrors = comp.scriptCollected?.moduleErrors ?? {};
    if (Object.keys(moduleErrors).length > 0) {
      comp.scriptError = moduleErrors;
    }
  }

  function collectAttribute(comp: ComponentDef | CompoundComponentDef, attr: Node) {
    const { namespace, startSegment, name, value, unsegmentedName: nsKey } = segmentAttr(attr);

    if (namespace === "xmlns") {
      return addToNamespaces(namespaceStack, comp, nsKey, value);
    }

    const isCompound = !isComponent(comp);
    // --- Handle single-word attributes
    if (isCompound) {
      if (startSegment && startSegment !== "method" && startSegment !== "var") {
        reportError("T021");
        return;
      }

      if (name === "name" && !startSegment) {
        // --- We already processed name
        return;
      }

      if (name === "codeBehind" && !startSegment) {
        // --- We already processed codeBehind
        return;
      }

      // --- Compound components do not have any other attributable props
      if (!startSegment && name) {
        reportError("T021", name);
      }
      return;
    }

    // --- Recognize special attributes by component definition type
    switch (name) {
      case "id":
        comp.uid = value;
        return;
      case "testId":
        comp.testId = value;
        return;
      case "when":
        comp.when = value;
        return;
      case "uses":
        comp.uses = splitUsesValue(value);
        return;
      default:
        if (startSegment === "var") {
          comp.vars ??= {};
          comp.vars[name] = value;
        } else if (startSegment === "method") {
          comp.api ??= {};
          comp.api[name] = value;
        } else if (startSegment === "event") {
          comp.events ??= {};
          comp.events[name] = parseEvent(value);
        } else if (onPrefixRegex.test(name)) {
          comp.events ??= {};
          const eventName = name[2].toLowerCase() + name.substring(3);
          comp.events[eventName] = parseEvent(value);
        } else {
          comp.props ??= {};
          comp.props[name] = value;
        }
        return;
    }
  }

  function collectObjectOrArray(usesStack: Map<string, string>[], children?: Node[]): any {
    let result: any = null;

    // --- No children, it's a null object
    if (!children) return result;
    let nestedElementType: string | null = null;

    children.forEach((child) => {
      if (child.kind === SyntaxKind.TextNode) {
        result = mergeValue(result, getText(child));
        return;
      }

      if (child.kind !== SyntaxKind.ElementNode) return;
      const childName = getComponentName(child, getText);
      // --- The only element names we accept are "field" or "item"
      if (childName !== "field" && childName !== "item") {
        reportError("T016");
        return;
      }

      if (childName === "field") {
        if (!nestedElementType) {
          // --- First nested element is "field", so we have an object
          nestedElementType = childName;
          result = {};
        } else if (nestedElementType !== childName) {
          reportError("T017");
          return;
        }
      } else if (childName === "item") {
        if (!nestedElementType) {
          // --- First nested element is "item", so we have an array
          nestedElementType = childName;
          result = [];
        } else if (nestedElementType !== childName) {
          reportError("T017");
          return;
        }
      }

      // --- Get the field value
      let valueInfo = collectValue(usesStack, child, childName === "field");
      if (!valueInfo) {
        return null;
      }

      // --- Does the field have a value?
      if (nestedElementType === "field") {
        result[valueInfo.name!] = valueInfo.value;
      } else {
        result.push(valueInfo.value);
      }
    });
    return result;
  }

  function collectValue(
    usesStack: Map<string, string>[],
    element: Node,
    allowName = true,
  ): { name?: string; value: any } | null {
    const elementName = getComponentName(element, getText);
    // --- Accept only "name", "value"
    const childNodes = getChildNodes(element);
    const nestedComponents = childNodes.filter(
      (c) => c.kind === SyntaxKind.ElementNode && UCRegex.test(getComponentName(c, getText)),
    );
    const nestedElements = childNodes.filter(
      (c) => c.kind === SyntaxKind.ElementNode && !UCRegex.test(getComponentName(c, getText)),
    );
    const attributes = getAttributes(element).map(segmentAttr);

    const attrProps = attributes.filter((attr) => propAttrs.indexOf(attr.name) >= 0);
    if (attributes.length > attrProps.length) {
      reportError("T011", elementName);
      return null;
    }

    // --- Validate the "name" usage
    const nameAttr = attrProps.find((attr) => attr.name === "name");
    if (allowName) {
      if (!nameAttr?.value) {
        reportError("T012", elementName);
        return null;
      }
    } else {
      if (nameAttr) {
        reportError("T018", elementName);
        return null;
      }
    }
    const name = nameAttr?.value;

    // --- Get the value attribute
    const valueAttr = attrProps.find((attr) => attr.name === "value");
    if (valueAttr && valueAttr.value === undefined) {
      reportError("T019", elementName);
      return null;
    }

    // --- Let's handle a special case, when the value is a component definition
    if (name && nestedComponents.length >= 1) {
      if (nestedElements.length > 0) {
        reportError("T020");
        return null;
      }
      // --- We expect a component definition here!
      const nestedComps = nestedComponents.map((nc) => transformInnerElement(usesStack, nc));
      return {
        name,
        value: nestedComps.length === 1 ? nestedComps[0] : nestedComps,
      };
    }

    // --- At this point, all attributes are ok, let's get the value.
    let value = valueAttr?.value;

    if (value === null) {
      return null;
    }

    if (typeof value === "string") {
      return { name, value };
    }

    return { name, value: collectObjectOrArray(usesStack, childNodes) };
  }

  function collectLoadersElements(
    usesStack: Map<string, string>[],
    comp: ComponentDef | CompoundComponentDef,
    loaders: Node,
  ): void {
    if (!isComponent(comp)) {
      reportError("T009", "loaders");
      return;
    }

    const children = getChildNodes(loaders);
    //todo: this check seems not necesarry
    if (children.length === 0) {
      comp.loaders ??= [];
    }

    const hasAttribute = loaders.children?.some((c) => c.kind === SyntaxKind.AttributeListNode);
    if (hasAttribute) {
      reportError("T014", "attributes");
      return;
    }

    children.forEach((loader) => {
      // --- Test is not supported
      if (loader.kind === SyntaxKind.TextNode) {
        reportError("T010", "loader");
        return;
      }

      // todo: is this needed?
      // --- Just for the sake of being sure...
      // if (loader.type !== "Element") return;

      const loaderDef = transformInnerElement(usesStack, loader) as ComponentDef;

      // --- Get the uid value
      if (!loaderDef.uid) {
        reportError("T013");
        return;
      }

      // --- Check props that a loader must not have
      if ((loaderDef as any).vars) {
        reportError("T014", "vars");
        return;
      }

      if ((loaderDef as any).loaders) {
        reportError("T014", "loaders");
        return;
      }

      if ((loaderDef as any).uses) {
        reportError("T014", "uses");
        return;
      }

      // --- Store this loader
      comp.loaders ??= [];
      comp.loaders.push(loaderDef);
    });
  }

  function collectElementHelper(
    usesStack: Map<string, string>[],
    comp: ComponentDef | CompoundComponentDef,
    child: Node,
    getter: (name: string) => any,
    setter: (name: string, value: string) => void,
    nameValidator?: (name: string) => void,
  ): void {
    // --- Compound component do not have a uses

    // --- Get the value
    const valueInfo = collectValue(usesStack, child);
    if (!valueInfo) {
      return;
    }

    // --- Extra name validation, if required so
    nameValidator?.(valueInfo?.name ?? "");

    const name = valueInfo.name!;
    const value = valueInfo.value;
    if (valueInfo?.value !== undefined) {
      setter(name, mergeValue(getter(name), value));
    } else {
      // --- Consider the value to be null; check optional child items
      const children = getChildNodes(child);
      const itemValue = collectObjectOrArray(usesStack, children);
      let updatedValue = getter(name);
      updatedValue = mergeValue(updatedValue, itemValue);
      setter(name, updatedValue);
    }
  }

  function collectUsesElements(comp: ComponentDef | CompoundComponentDef, usesNode: Node): void {
    // --- Compound component do not have a uses
    if (!isComponent(comp)) {
      reportError("T009", "uses");
      return;
    }

    const attributes = getAttributes(usesNode).map(segmentAttr);
    const valueAttr = attributes.find((attr) => attr.name === "value");
    if (!valueAttr?.value || attributes.length !== 1) {
      reportError("T015", "uses");
      return;
    }

    // --- Extract the value
    const usesValues = splitUsesValue(valueAttr.value);
    if (comp.uses) {
      comp.uses.push(...usesValues);
    } else {
      comp.uses = usesValues;
    }
  }

  function segmentAttr(attr: Node): {
    namespace?: string;
    startSegment?: string;
    name?: string;
    value: string;
    unsegmentedName: string;
  } {
    let key = attr.children![0];
    const hasNamespace = key.children!.length === 3;
    let namespace: undefined | string;
    if (hasNamespace) {
      namespace = getText(key.children![0]);
    }
    let unsegmentedName = getText(key.children![key.children!.length - 1]);
    const segments = unsegmentedName.split(".");
    if (segments.length > 2) {
      reportError("T007", attr, key);
    }

    let name: string | undefined;
    let startSegment: string | undefined;

    if (segments.length === 2) {
      startSegment = segments[0];
      name = segments[1];
      if (name.trim() === "") {
        reportError("T007", attr, name);
      }
    } else {
      //TODO: remove asigning name when name === unsegmentedName. It is there for backwards compat
      name = unsegmentedName;
    }
    const valueText = getText(attr.children![2]);
    const value = valueText.substring(1, valueText.length - 1);
    return { namespace, startSegment, name, value, unsegmentedName };
  }

  function parseEscapeCharactersInAttrValues(attrs: Node[]) {
    for (let attr of attrs) {
      const attrValue = attr.children![attr.children!.length - 1] as TransformNode;
      const escapedText = tryEscapeEntities(getText(attrValue));
      if (escapedText !== null) {
        attrValue.text = escapedText;
      }
    }
  }

  function prepNode(node: Node): Node {
    const childNodes: TransformNode[] = getChildNodes(node);
    const tagName = getComponentName(node, getText);
    const hasComponentName = !(tagName in HelperNode);
    const shouldUseTextNodeElement = hasComponentName || tagName === "property";
    const shouldCollapseWhitespace = tagName !== "event" && tagName !== "method";
    const attrs = getAttributes(node);

    desugarKeyOnlyAttrs(attrs);
    parseEscapeCharactersInAttrValues(attrs);
    parseEscapeCharactersInContent(childNodes);

    mergeConsecutiveTexts(childNodes, shouldCollapseWhitespace);
    let shouldUseCData = false;
    let hasScriptChild = false;

    for (let i = 0; i < childNodes.length; ++i) {
      const child = childNodes[i];
      let newChild: TransformNode;

      if (child.kind == SyntaxKind.Script) {
        hasScriptChild = true;
        continue;
      }
      if (child.kind === SyntaxKind.ElementNode) {
        newChild = prepNode(child);
        childNodes[i] = newChild;
        continue;
      }

      let textValue = getText(child);

      if (child.kind === SyntaxKind.StringLiteral) {
        textValue = textValue.slice(1, -1);
      } else if (child.kind === SyntaxKind.CData) {
        shouldUseCData = true;
      } else if (child.kind === SyntaxKind.TextNode) {
      }

      if (shouldUseTextNodeElement) {
        if (shouldUseCData) {
          newChild = createTextNodeCDataElement(textValue);
        } else {
          newChild = createTextNodeElement(textValue);
        }
      } else {
        newChild = {
          kind: SyntaxKind.TextNode,
          text: textValue,
        } as TransformNode;
      }
      childNodes[i] = newChild;
    }

    const helperNodes = [];
    const otherNodes = [];
    let hasComponentChild = false;
    for (const child of childNodes) {
      if (child.kind === SyntaxKind.ElementNode) {
        let compName: string = getComponentName(child, getText) ?? undefined;
        if (compName in HelperNode) {
          helperNodes.push(child);
          continue;
        }
        hasComponentChild = true;
      }
      otherNodes.push(child);
    }

    if (hasScriptChild && hasComponentChild) {
      const fragment = wrapWithFragment(otherNodes);
      helperNodes.push(fragment);
      return withNewChildNodes(node, helperNodes);
    }

    return node;
  }

  function collapseWhitespace(childNodes: TransformNode[]) {
    for (let i = 0; i < childNodes.length; ++i) {
      if (
        childNodes[i].kind === SyntaxKind.StringLiteral ||
        childNodes[i].kind === SyntaxKind.TextNode
      ) {
        //the union is the same as \s , but took \u00a0 (non breaking space) out
        //source https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions/Cheatsheet
        const allSubsequentWsExceptNonBreakingSpace =
          /[\f\n\r\t\v\u0020\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/g;
        childNodes[i].text = getText(childNodes[i]).replace(
          allSubsequentWsExceptNonBreakingSpace,
          " ",
        );
      }
    }
  }

  function stripCDataWrapper(childNodes: TransformNode[]) {
    for (let i = 0; i < childNodes.length; ++i) {
      if (childNodes[i].kind === SyntaxKind.CData) {
        childNodes[i].text = getText(childNodes[i]).slice(CDATA_PREFIX_LEN, -CDATA_POSTFIX_LEN);
      }
    }
  }

  function parseEscapeCharactersInContent(childNodes: TransformNode[]) {
    for (let node of childNodes) {
      if (node.kind === SyntaxKind.StringLiteral || node.kind === SyntaxKind.TextNode) {
        const escapedText = tryEscapeEntities(getText(node));
        if (escapedText !== null) {
          node.text = escapedText;
        }
      }
    }
  }

  function tryEscapeEntities(text: string): string | null {
    let newText = "";
    let startOfSubstr = 0;
    for (let i = 0; i < text.length; ++i) {
      if (text.charCodeAt(i) === CharacterCodes.ampersand) {
        switch (text.charCodeAt(i + 1)) {
          //&a
          case CharacterCodes.a:
            switch (text.charCodeAt(i + 2)) {
              //am
              case CharacterCodes.m:
                //amp;
                if (
                  text.charCodeAt(i + 3) === CharacterCodes.p &&
                  text.charCodeAt(i + 4) === CharacterCodes.semicolon
                ) {
                  newText = newText + text.substring(startOfSubstr, i) + "&";
                  i += 4;
                  startOfSubstr = i + 1;
                }
                break;
              //ap
              case CharacterCodes.p:
                //apos;
                if (
                  text.charCodeAt(i + 3) === CharacterCodes.o &&
                  text.charCodeAt(i + 4) === CharacterCodes.s &&
                  text.charCodeAt(i + 5) === CharacterCodes.semicolon
                ) {
                  newText = newText + text.substring(startOfSubstr, i) + "'";
                  i += 5;
                  startOfSubstr = i + 1;
                }
                break;
            }
            break;
          //&g
          case CharacterCodes.g:
            //\gt;
            if (
              text.charCodeAt(i + 2) === CharacterCodes.t &&
              text.charCodeAt(i + 3) === CharacterCodes.semicolon
            ) {
              newText = newText + text.substring(startOfSubstr, i) + ">";
              i += 3;
              startOfSubstr = i + 1;
            }
            break;
          //&l
          case CharacterCodes.l:
            //&lt;
            if (
              text.charCodeAt(i + 2) === CharacterCodes.t &&
              text.charCodeAt(i + 3) === CharacterCodes.semicolon
            ) {
              newText = newText + text.substring(startOfSubstr, i) + "<";
              i += 3;
              startOfSubstr = i + 1;
            }
            break;
          //&q
          case CharacterCodes.q:
            //&quot;
            if (
              text.charCodeAt(i + 2) === CharacterCodes.u &&
              text.charCodeAt(i + 3) === CharacterCodes.o &&
              text.charCodeAt(i + 4) === CharacterCodes.t &&
              text.charCodeAt(i + 5) === CharacterCodes.semicolon
            ) {
              newText = newText + text.substring(startOfSubstr, i) + '"';
              i += 5;
              startOfSubstr = i + 1;
            }
            break;
          //&n
          case CharacterCodes.n:
            //&nbsp;
            if (
              text.charCodeAt(i + 2) === CharacterCodes.b &&
              text.charCodeAt(i + 3) === CharacterCodes.s &&
              text.charCodeAt(i + 4) === CharacterCodes.p &&
              text.charCodeAt(i + 5) === CharacterCodes.semicolon
            ) {
              newText = newText + text.substring(startOfSubstr, i) + "\xa0";
              i += 5;
              startOfSubstr = i + 1;
            }
            break;
        }
      }
    }
    if (startOfSubstr === 0) {
      return null;
    }
    newText += text.substring(startOfSubstr);
    return newText;
  }

  function mergeConsecutiveTexts(childNodes: TransformNode[], shouldCollapseWs: boolean) {
    if (shouldCollapseWs) {
      collapseWhitespace(childNodes);
    }
    stripCDataWrapper(childNodes);

    for (let i = childNodes.length - 1; i > 0; --i) {
      const node = childNodes[i - 1];
      const nextNode = childNodes[i];

      if (node.kind === SyntaxKind.StringLiteral && nextNode.kind === SyntaxKind.CData) {
        childNodes[i - 1] = {
          kind: SyntaxKind.CData,
          text: getText(node).slice(1, -1) + getText(nextNode),
        } as TransformNode;
        childNodes.pop();
      } else if (node.kind === SyntaxKind.CData && nextNode.kind === SyntaxKind.StringLiteral) {
        childNodes[i - 1] = {
          kind: SyntaxKind.CData,
          text: getText(node) + getText(nextNode).slice(1, -1),
        } as TransformNode;
        childNodes.pop();
      } else if (node.kind === SyntaxKind.CData && nextNode.kind === SyntaxKind.TextNode) {
        childNodes[i - 1] = {
          kind: SyntaxKind.CData,
          text: getText(node) + getText(nextNode),
        } as TransformNode;
        childNodes.pop();
      } else if (node.kind === SyntaxKind.CData && nextNode.kind === SyntaxKind.CData) {
        childNodes[i - 1] = {
          kind: SyntaxKind.CData,
          text: getText(node) + getText(nextNode),
        } as TransformNode;
        childNodes.pop();
      } else if (node.kind === SyntaxKind.TextNode && nextNode.kind === SyntaxKind.TextNode) {
        if (getText(node).endsWith(" ") && getText(nextNode).startsWith(" ")) {
          node.text = getText(node).trimEnd();
        }
        childNodes[i - 1] = {
          kind: SyntaxKind.TextNode,
          text: getText(node) + getText(nextNode),
        } as TransformNode;
        childNodes.pop();
      } else if (node.kind === SyntaxKind.TextNode && nextNode.kind === SyntaxKind.CData) {
        childNodes[i - 1] = {
          kind: SyntaxKind.CData,
          text: getText(node) + getText(nextNode),
        } as TransformNode;
        childNodes.pop();
      }
    }
  }

  function parseEvent(value: any): any {
    if (typeof value !== "string") {
      // --- It must be a component definition in the event code
      return value;
    }

    // --- Parse the event code
    const parser = new Parser(value);
    try {
      const statements = parser.parseStatements();
      return {
        __PARSED: true,
        statements,
        parseId: ++lastParseId,
        // TODO: retrieve the event source code only in dev mode
        source: value,
      } as ParsedEventValue;
    } catch {
      if (parser.errors.length > 0) {
        const errMsg = parser.errors[0];
        throw new ParserError(`${errMsg.text} [${errMsg.line}: ${errMsg.column}]`, errMsg.code);
      }
    }
  }
}

function createTextNodeCDataElement(textValue: string): Node {
  return {
    kind: SyntaxKind.ElementNode,
    children: [
      { kind: SyntaxKind.OpenNodeStart },
      {
        kind: SyntaxKind.TagNameNode,
        children: [{ kind: SyntaxKind.Identifier, text: "TextNodeCData" }],
      },
      {
        kind: SyntaxKind.AttributeListNode,
        children: [
          {
            kind: SyntaxKind.AttributeNode,
            children: [
              {
                kind: SyntaxKind.AttributeKeyNode,
                children: [{ kind: SyntaxKind.Identifier, text: "value" }],
              },
              { kind: SyntaxKind.Equal },
              { kind: SyntaxKind.Identifier, text: `"${textValue}"` },
            ],
          },
        ],
      },
      { kind: SyntaxKind.NodeClose },
    ],
  } as Node;
}

function createTextNodeElement(textValue: string): Node {
  return {
    kind: SyntaxKind.ElementNode,
    children: [
      { kind: SyntaxKind.OpenNodeStart },
      {
        kind: SyntaxKind.TagNameNode,
        children: [{ kind: SyntaxKind.Identifier, text: "TextNode" }],
      },
      {
        kind: SyntaxKind.AttributeListNode,
        children: [
          {
            kind: SyntaxKind.AttributeNode,
            children: [
              {
                kind: SyntaxKind.AttributeKeyNode,
                children: [{ kind: SyntaxKind.Identifier, text: "value" }],
              },
              { kind: SyntaxKind.Equal },
              { kind: SyntaxKind.Identifier, text: `"${textValue}"` },
            ],
          },
        ],
      },
      { kind: SyntaxKind.NodeClose },
    ],
  } as Node;
}

/**
 * Reports the specified error
 * @param errorCode Error code
 * @param options Error message options
 */
function reportError(errorCode: ErrorCodes, ...options: any[]): void {
  let errorText: string = errorMessages[errorCode] ?? "Unknown error";
  if (options) {
    options.forEach((o, idx) => (errorText = replace(errorText, `{${idx}}`, o.toString())));
  }
  throw new ParserError(errorText, errorCode);

  function replace(input: string, placeholder: string, replacement: string): string {
    do {
      input = input.replace(placeholder, replacement);
    } while (input.includes(placeholder));
    return input;
  }
}

function isComponent(obj: ComponentDef | CompoundComponentDef): obj is ComponentDef {
  return (obj as any).type;
}

function mergeValue(oldValue: any, itemValue: any): any {
  if (oldValue) {
    if (Array.isArray(oldValue)) {
      if (typeof oldValue === "string") {
        return [oldValue, itemValue];
      } else {
        oldValue.push(itemValue);
        return oldValue;
      }
    } else {
      return [oldValue, itemValue];
    }
  } else {
    return itemValue;
  }
}

function wrapWithFragment(wrappedChildren: Node[]): TransformNode {
  const nameNode = {
    kind: SyntaxKind.TagNameNode,
    children: [{ kind: SyntaxKind.Identifier, text: "Fragment" }],
  };
  return {
    kind: SyntaxKind.ElementNode,
    start: wrappedChildren[0].start,
    pos: wrappedChildren[0].pos,
    end: wrappedChildren[wrappedChildren.length - 1].end,
    children: [
      { kind: SyntaxKind.OpenNodeStart },
      nameNode,
      { kind: SyntaxKind.NodeEnd },
      { kind: SyntaxKind.ContentListNode, children: wrappedChildren },
      { kind: SyntaxKind.CloseNodeStart },
      nameNode,
      { kind: SyntaxKind.NodeEnd },
    ],
  } as TransformNode;
}

function getAttributes(node: Node): Node[] {
  return node.children?.find((c) => c.kind === SyntaxKind.AttributeListNode)?.children ?? [];
}

function getChildNodes(node: Node): Node[] {
  return node.children?.find((c) => c.kind === SyntaxKind.ContentListNode)?.children ?? [];
}

function withNewChildNodes(node: Node, newChildren: Node[]) {
  const childrenListIdx = node.children?.findIndex((c) => c.kind === SyntaxKind.ContentListNode);
  if (childrenListIdx === undefined || childrenListIdx === -1) {
    return node;
  }
  const contentListChild = node.children![childrenListIdx];
  return new Node(node.kind, node.pos ?? 0, node.end ?? 0, node.triviaBefore, [
    ...node.children!.slice(0, childrenListIdx),
    new Node(
      contentListChild.kind,
      contentListChild.pos ?? 0,
      contentListChild.end ?? 0,
      undefined,
      newChildren,
    ),
    ...node.children!.slice(childrenListIdx),
  ]);
}

function desugarKeyOnlyAttrs(attrs: Node[]) {
  for (let attr of attrs) {
    if (attr.children?.length === 1) {
      const eq = {
        kind: SyntaxKind.Equal,
      } as Node;
      const value = {
        kind: SyntaxKind.StringLiteral,
        text: '"true"',
      } as TransformNode;
      attr.children!.push(eq, value);
    }
  }
}

function addToNamespaces(
  namespaceStack: Map<string, string>[],
  comp: any,
  nsKey: string,
  value: string,
) {
  let nsCommaSeparated = value.split(":");
  if (nsCommaSeparated.length > 2) {
    return reportError("T028", value, "Namespace cannot contain multiple ':' (colon).");
  }

  let nsValue = value;
  if (nsCommaSeparated.length === 2) {
    if (nsCommaSeparated[0] != COMPONENT_NAMESPACE_SCHEME) {
      return reportError("T029", value, COMPONENT_NAMESPACE_SCHEME);
    }
    nsValue = nsCommaSeparated[1];
  }

  if (nsValue.includes("#")) {
    return reportError("T028", nsValue, "Namespace cannot contain character '#'.");
  }

  switch (nsValue) {
    case COMPONENT_NAMESPACE_SCHEME:
      nsValue = nsKey;
      break;
    case APP_NS_KEY:
      nsValue = APP_NS_VALUE;
      break;
    case CORE_NS_KEY:
      nsValue = CORE_NAMESPACE_VALUE;
      break;
  }

  const compNamespaces = namespaceStack[namespaceStack.length - 1];
  if (compNamespaces.has(nsKey)) {
    return reportError("T025", nsKey);
  }
  compNamespaces.set(nsKey, nsValue);
}

function getTopLvlElement(node: Node, getText: GetText): Node {
  // --- Check that the nodes contains exactly only a single component root element before the EoF token
  if (node.children!.length !== 2) {
    reportError("T001");
  }

  // --- Ensure it's a component
  const element = node.children![0];
  if (element.kind !== SyntaxKind.ElementNode) {
    reportError("T001");
  }
  return element;
}

function getComponentName(node: Node, getText: GetText) {
  const nameTokens = node.children!.find((c) => c.kind === SyntaxKind.TagNameNode)!.children!;
  const name = getText(nameTokens.at(-1));
  return name;
}

function getNamespaceResolvedComponentName(
  node: Node,
  getText: GetText,
  namespaceStack: Map<string, string>[],
) {
  const nameTokens = node.children!.find((c) => c.kind === SyntaxKind.TagNameNode)!.children!;
  const name = getText(nameTokens.at(-1));

  if (nameTokens.length === 1) {
    return name;
  }

  const namespace = getText(nameTokens[0]);

  if (namespaceStack.length === 0) {
    reportError("T026");
  }

  let resolvedNamespace = undefined;
  for (let i = namespaceStack.length - 1; i >= 0; --i) {
    resolvedNamespace = namespaceStack[i].get(namespace);
    if (resolvedNamespace !== undefined) {
      break;
    }
  }
  if (resolvedNamespace === undefined) {
    reportError("T027", namespace);
  }

  return resolvedNamespace + "." + name;
}

/**
 * @param name - The name of the event in camelCase, with "on" prefix.
 */
export function stripOnPrefix(name: string) {
  return name[2].toLowerCase() + name.substring(3);
}

function splitUsesValue(value: string) {
  return value.split(",").map((v) => v.trim());
}

```
Page 101/141FirstPrevNextLast