#
tokens: 43430/50000 2/1624 files (page 99/141)
lines: off (toggle) GitHub
raw markdown copy
This is page 99 of 141. Use http://codebase.md/xmlui-org/xmlui/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/src/components/DateInput/DateInputNative.tsx:
--------------------------------------------------------------------------------

```typescript
import React, { type CSSProperties } from "react";
import {
  forwardRef,
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from "react";
import classnames from "classnames";
import styles from "./DateInput.module.scss";
import { format, parse, isValid } from "date-fns";
import { PartialInput, type BlurDirection } from "../Input/PartialInput";
import { InputDivider } from "../Input/InputDivider";

import type { RegisterComponentApiFn, UpdateStateFn } from "../../abstractions/RendererDefs";
import { useEvent } from "../../components-core/utils/misc";
import type { ValidationStatus } from "../abstractions";
import { Adornment } from "../Input/InputAdornment";
import Icon from "../Icon/IconNative";

// Component part names
const PART_DAY = "day";
const PART_MONTH = "month";
const PART_YEAR = "year";
const PART_CLEAR_BUTTON = "clearButton";

// Date validation constants
const MIN_YEAR = 1900;
const MAX_YEAR = 2100;

// Browser compatibility checks
const isIEOrEdgeLegacy =
  typeof window !== "undefined" && /(MSIE|Trident\/|Edge\/)/.test(navigator.userAgent);

// Date format types
export const dateFormats = [
  "MM/dd/yyyy",
  "MM-dd-yyyy",
  "yyyy/MM/dd",
  "yyyy-MM-dd",
  "dd/MM/yyyy",
  "dd-MM-yyyy",
  "yyyyMMdd",
  "MMddyyyy",
] as const;

type DateFormat = (typeof dateFormats)[number];

export const DateInputModeValues = ["single", "range"] as const;
type DateInputMode = (typeof DateInputModeValues)[number];

export const enum WeekDays {
  Sunday = 0,
  Monday = 1,
  Tuesday = 2,
  Wednesday = 3,
  Thursday = 4,
  Friday = 5,
  Saturday = 6,
}

type Props = {
  id?: string;
  initialValue?: string;
  value?: string;
  enabled?: boolean;
  updateState?: UpdateStateFn;
  style?: CSSProperties;
  className?: string;
  onDidChange?: (newValue: string | null) => void;
  onFocus?: (ev: React.FocusEvent<HTMLDivElement>) => void;
  onBlur?: (ev: React.FocusEvent<HTMLDivElement>) => void;
  onInvalidChange?: () => void;
  validationStatus?: ValidationStatus;
  registerComponentApi?: RegisterComponentApiFn;
  mode?: DateInputMode;
  dateFormat?: DateFormat;
  showWeekNumber?: boolean;
  weekStartsOn?: WeekDays;
  minValue?: string;
  maxValue?: string;
  disabledDates?: any;
  inline?: boolean;
  clearable?: boolean;
  clearIcon?: string;
  clearToInitialValue?: boolean;
  required?: boolean;
  startText?: string;
  startIcon?: string;
  endText?: string;
  endIcon?: string;
  gap?: string;
  readOnly?: boolean;
  autoFocus?: boolean;
  emptyCharacter?: string;
};

export const defaultProps = {
  enabled: true,
  validationStatus: "none" as ValidationStatus,
  mode: "single" as DateInputMode,
  dateFormat: "MM/dd/yyyy" as DateFormat,
  showWeekNumber: false,
  weekStartsOn: WeekDays.Sunday,
  inline: true,
  clearable: false,
  clearToInitialValue: true,
  required: false,
  labelPosition: "top",
  readOnly: false,
  autoFocus: false,
  labelBreak: false,
  emptyCharacter: "-",
};

export const DateInput = forwardRef<HTMLDivElement, Props>(function DateInputNative(
  {
    id,
    initialValue,
    value: controlledValue,
    enabled = defaultProps.enabled,
    updateState,
    style,
    className,
    onDidChange,
    onFocus,
    onBlur,
    onInvalidChange,
    validationStatus = defaultProps.validationStatus,
    registerComponentApi,
    mode = defaultProps.mode,
    dateFormat = defaultProps.dateFormat,
    showWeekNumber = defaultProps.showWeekNumber,
    weekStartsOn = defaultProps.weekStartsOn,
    minValue,
    maxValue,
    disabledDates,
    inline = defaultProps.inline,
    clearable = defaultProps.clearable,
    clearIcon,
    clearToInitialValue = defaultProps.clearToInitialValue,
    required = defaultProps.required,
    startText,
    startIcon,
    endText,
    endIcon,
    gap,
    readOnly = defaultProps.readOnly,
    autoFocus = defaultProps.autoFocus,
    emptyCharacter = defaultProps.emptyCharacter,
    ...rest
  },
  ref,
) {
  const dateInputRef = useRef<HTMLDivElement>(null);

  // Refs for auto-tabbing between inputs
  const dayInputRef = useRef<HTMLInputElement>(null);
  const monthInputRef = useRef<HTMLInputElement>(null);
  const yearInputRef = useRef<HTMLInputElement>(null);

  // Process emptyCharacter according to requirements
  const processedEmptyCharacter = useMemo(() => {
    if (!emptyCharacter || emptyCharacter.length === 0) {
      return "-";
    }
    if (emptyCharacter.length > 1) {
      // Use proper unicode-aware character extraction
      const firstChar = [...emptyCharacter][0];
      return firstChar;
    }
    return emptyCharacter;
  }, [emptyCharacter]);

  // Stabilize initialValue to prevent unnecessary re-renders
  const stableInitialValue = useMemo(() => {
    return initialValue;
  }, [initialValue]);

  // Local state management - sync with value prop
  const [localValue, setLocalValue] = useState<string | null>(() => {
    const initial = controlledValue || stableInitialValue || null;
    return initial;
  });

  // Parse current value into individual components
  const [day, setDay] = useState<string | null>(null);
  const [month, setMonth] = useState<string | null>(null);
  const [year, setYear] = useState<string | null>(null);

  // Track whether the component currently has focus
  const [componentHasFocus, setComponentHasFocus] = useState(false);

  // State to track invalid status for visual feedback
  const [isDayCurrentlyInvalid, setIsDayCurrentlyInvalid] = useState(false);
  const [isMonthCurrentlyInvalid, setIsMonthCurrentlyInvalid] = useState(false);
  const [isYearCurrentlyInvalid, setIsYearCurrentlyInvalid] = useState(false);

  useEffect(() => {
    // Initialize XMLUI state with initial value on first mount
    if (updateState && stableInitialValue !== undefined && controlledValue === undefined) {
      updateState({ value: stableInitialValue }, { initial: true });
      return; // Don't sync on this first run, let the state update trigger a re-render
    }

    // Sync with controlled value - always sync when controlledValue changes
    const newLocalValue = controlledValue || null;
    setLocalValue(newLocalValue);
  }, [controlledValue, stableInitialValue, updateState]);

  // Get the order of date inputs based on the format
  const dateOrder = useMemo(() => {
    const format = dateFormat.toLowerCase();

    // Determine the order based on the format pattern
    if (format.startsWith("mm") || format.startsWith("m")) {
      if (format.includes("/dd/yyyy") || format.includes("-dd-yyyy")) {
        return ["month", "day", "year"]; // MM/dd/yyyy or MM-dd-yyyy
      } else {
        return ["month", "day", "year"]; // MMddyyyy
      }
    } else if (format.startsWith("yyyy")) {
      return ["year", "month", "day"]; // yyyy/MM/dd or yyyy-MM-dd
    } else if (format.startsWith("dd")) {
      return ["day", "month", "year"]; // dd/MM/yyyy or dd-MM-yyyy
    } else {
      return ["month", "day", "year"]; // fallback
    }
  }, [dateFormat]);

  // Parse value into individual components
  useEffect(() => {
    if (localValue) {
      const parsedValues = parseDateString(localValue, dateFormat);
      if (parsedValues) {
        setDay(parsedValues.day);
        setMonth(parsedValues.month);
        setYear(parsedValues.year);
      } else {
        setDay(null);
        setMonth(null);
        setYear(null);
      }
    } else {
      setDay(null);
      setMonth(null);
      setYear(null);
    }
  }, [localValue, dateFormat]);

  // Event handlers
  const handleChange = useEvent((newValue: string | null) => {
    // Update local state immediately for immediate UI feedback
    setLocalValue(newValue);

    // Also update the XMLUI state
    if (updateState) {
      updateState({ value: newValue });
    }
    onDidChange?.(newValue);
  });

  // Helper function to format the complete date value
  const formatDateValue = useCallback(
    (d: string | null, m: string | null, y: string | null): string | null => {
      if (!d || !m || !y) {
        return null;
      }

      // Create a date object and format it according to the dateFormat
      const dayNum = parseInt(d, 10);
      const monthNum = parseInt(m, 10);
      const yearNum = parseInt(y, 10);

      if (isNaN(dayNum) || isNaN(monthNum) || isNaN(yearNum)) {
        return null;
      }

      try {
        // Create date object (month is 0-indexed in Date constructor)
        const date = new Date(yearNum, monthNum - 1, dayNum);

        // Validate the date
        if (
          date.getFullYear() !== yearNum ||
          date.getMonth() !== monthNum - 1 ||
          date.getDate() !== dayNum
        ) {
          return null;
        }

        // Format using the specified format
        return format(date, dateFormat);
      } catch (error) {
        return null;
      }
    },
    [dateFormat],
  );

  // Generic handlers for input change and blur
  const createInputChangeHandler = useCallback(
    (
      field: "day" | "month" | "year",
      setValue: (value: string) => void,
      setInvalid: (invalid: boolean) => void,
      validateFn: (value: string) => boolean,
    ) =>
      (event: React.ChangeEvent<HTMLInputElement>) => {
        const newValue = event.target.value;
        setValue(newValue);
        // Update invalid state immediately for visual feedback
        const isInvalid = validateFn(newValue);
        setInvalid(isInvalid);

        // Clear day invalid state when any field changes, as the date combination might become valid
        if (!isInvalid) {
          setIsDayCurrentlyInvalid(false);
        }

        // Fire invalid event if the value is invalid
        if (isInvalid) {
          onInvalidChange?.();
        }
        // Don't format/normalize during typing - only on blur
      },
    [onInvalidChange],
  );

  const createInputBlurHandler = useCallback(
    (
      field: "day" | "month" | "year",
      setValue: (value: string) => void,
      setInvalid: (invalid: boolean) => void,
      normalizeFn: (value: string) => string | null,
    ) =>
      (direction: BlurDirection, event: React.FocusEvent<HTMLInputElement>) => {
        const currentValue = event.target.value;
        const normalizedValue = normalizeFn(currentValue);

        // Check if the current value was invalid (needed normalization or couldn't be normalized)
        const wasInvalid =
          currentValue !== "" && (normalizedValue === null || normalizedValue !== currentValue);

        if (normalizedValue !== null && normalizedValue !== currentValue) {
          setValue(normalizedValue);
          setInvalid(false); // Clear invalid state after normalization

          // Check if the complete date would be valid
          const dateValues = { day, month, year };
          dateValues[field] = normalizedValue;
          const dateString = formatDateValue(dateValues.day, dateValues.month, dateValues.year);

          if (dateString !== null) {
            // Valid complete date - update normally
            handleChange(dateString);
          } else {
            // Invalid date combination - mark the day as invalid if all fields are present
            if (dateValues.day && dateValues.month && dateValues.year) {
              setIsDayCurrentlyInvalid(true);
              onInvalidChange?.();
              // Don't call handleChange with null to avoid clearing the fields
            } else {
              // Incomplete date - call handleChange as normal (will be null)
              handleChange(dateString);
            }
          }
        } else if (normalizedValue === null && currentValue !== "") {
          // Reset to previous valid value or clear
          setValue("");
          setInvalid(false); // Clear invalid state
          // Always call handleChange to update the date value (likely to null)
          const dateValues = { day, month, year };
          dateValues[field] = "";
          const dateString = formatDateValue(dateValues.day, dateValues.month, dateValues.year);
          handleChange(dateString);
        } else if (normalizedValue !== null) {
          // Value didn't need normalization, but still update the complete date
          const dateValues = { day, month, year };
          dateValues[field] = normalizedValue;
          const dateString = formatDateValue(dateValues.day, dateValues.month, dateValues.year);

          if (dateString !== null) {
            // Valid complete date - update normally
            handleChange(dateString);
          } else {
            // Invalid date combination - mark the day as invalid if all fields are present
            if (dateValues.day && dateValues.month && dateValues.year) {
              setIsDayCurrentlyInvalid(true);
              onInvalidChange?.();
              // Don't call handleChange with null to avoid clearing the fields
            } else {
              // Incomplete date - call handleChange as normal (will be null)
              handleChange(dateString);
            }
          }
        }
      },
    [day, month, year, handleChange, onInvalidChange],
  );

  // Handle changes from individual inputs
  const handleDayChange = useMemo(
    () =>
      createInputChangeHandler("day", setDay, setIsDayCurrentlyInvalid, (value) =>
        isDayInvalid(value, month, year),
      ),
    [createInputChangeHandler, month, year],
  );

  const handleDayBlur = useMemo(
    () =>
      createInputBlurHandler("day", setDay, setIsDayCurrentlyInvalid, (value) =>
        normalizeDay(value, month, year),
      ),
    [createInputBlurHandler, month, year],
  );

  const handleMonthChange = useMemo(
    () => createInputChangeHandler("month", setMonth, setIsMonthCurrentlyInvalid, isMonthInvalid),
    [createInputChangeHandler],
  );

  const handleMonthBlur = useMemo(
    () => createInputBlurHandler("month", setMonth, setIsMonthCurrentlyInvalid, normalizeMonth),
    [createInputBlurHandler],
  );

  const handleYearChange = useMemo(
    () => createInputChangeHandler("year", setYear, setIsYearCurrentlyInvalid, isYearInvalid),
    [createInputChangeHandler],
  );

  const handleYearBlur = useMemo(
    () => createInputBlurHandler("year", setYear, setIsYearCurrentlyInvalid, normalizeYear),
    [createInputBlurHandler],
  );

  // Focus method
  const focus = useCallback(() => {
    const firstInput = dateInputRef.current?.querySelector("input") as HTMLInputElement;
    firstInput?.focus();
  }, []);

  // Custom focus handler that fires gotFocus when component gains focus
  const handleComponentFocus = useCallback(
    (event: React.FocusEvent<HTMLDivElement>) => {
      // If component didn't have focus before, fire gotFocus
      if (!componentHasFocus) {
        setComponentHasFocus(true);
        onFocus?.(event);
      }
    },
    [componentHasFocus, onFocus],
  );

  // Custom blur handler that only fires lostFocus when focus leaves the entire component
  const handleComponentBlur = useCallback(
    (event: React.FocusEvent<HTMLDivElement>) => {
      // Check if the new focus target is still within this DateInput component
      const relatedTarget = event.relatedTarget as HTMLElement;
      const currentTarget = event.currentTarget;

      // If there's no related target, or the related target is not within this component, fire lostFocus
      if (!relatedTarget || !currentTarget.contains(relatedTarget)) {
        setComponentHasFocus(false);
        onBlur?.(event);
      }
    },
    [onBlur],
  );

  // Arrow key navigation handler
  const createArrowKeyHandler = useCallback(() => {
    return (event: React.KeyboardEvent<HTMLInputElement>) => {
      const { key } = event;

      if (key === "ArrowRight") {
        event.preventDefault();
        const currentTarget = event.target as HTMLInputElement;

        // Determine next input based on current input
        if (currentTarget === monthInputRef.current && dayInputRef.current) {
          dayInputRef.current.focus();
          dayInputRef.current.select();
        } else if (currentTarget === dayInputRef.current && yearInputRef.current) {
          yearInputRef.current.focus();
          yearInputRef.current.select();
        }
      } else if (key === "ArrowLeft") {
        event.preventDefault();
        const currentTarget = event.target as HTMLInputElement;

        // Determine previous input based on current input
        if (currentTarget === dayInputRef.current && monthInputRef.current) {
          monthInputRef.current.focus();
          monthInputRef.current.select();
        } else if (currentTarget === yearInputRef.current && dayInputRef.current) {
          dayInputRef.current.focus();
          dayInputRef.current.select();
        }
      }
    };
  }, []);

  // Create the arrow key handler instance
  const handleArrowKeys = createArrowKeyHandler();

  const clear = useCallback(() => {
    // Reset to initial value if provided, otherwise null
    let valueToReset = clearToInitialValue
      ? stableInitialValue !== undefined
        ? stableInitialValue
        : null
      : null;

    if (valueToReset) {
      const parsedValues = parseDateString(valueToReset, dateFormat);
      if (parsedValues) {
        setDay(parsedValues.day);
        setMonth(parsedValues.month);
        setYear(parsedValues.year);
      } else {
        setDay(null);
        setMonth(null);
        setYear(null);
      }
    } else {
      // Clear all fields
      setDay(null);
      setMonth(null);
      setYear(null);
    }

    handleChange(valueToReset);

    // Focus the component after clearing
    setTimeout(() => {
      focus();
    }, 0);
  }, [stableInitialValue, handleChange, dateFormat, clearToInitialValue, focus]);

  function stopPropagation(event: React.FocusEvent) {
    event.stopPropagation();
  }

  const setValue = useEvent((newValue: string | null) => {
    handleChange(newValue);
  });

  // Function to get ISO formatted date value (YYYY-MM-DD)
  const getIsoValue = useCallback((): string | null => {
    if (!day || !month || !year) {
      return null;
    }

    // Convert to numbers
    const dayNum = parseInt(day, 10);
    const monthNum = parseInt(month, 10);
    const yearNum = parseInt(year, 10);

    if (isNaN(dayNum) || isNaN(monthNum) || isNaN(yearNum)) {
      return null;
    }

    try {
      // Create date object (month is 0-indexed in Date constructor)
      const date = new Date(yearNum, monthNum - 1, dayNum);

      // Validate the date
      if (
        date.getFullYear() !== yearNum ||
        date.getMonth() !== monthNum - 1 ||
        date.getDate() !== dayNum
      ) {
        return null;
      }

      // Format as ISO date string (YYYY-MM-DD)
      const year4 = yearNum.toString().padStart(4, "0");
      const month2 = monthNum.toString().padStart(2, "0");
      const day2 = dayNum.toString().padStart(2, "0");

      return `${year4}-${month2}-${day2}`;
    } catch (error) {
      return null;
    }
  }, [day, month, year]);

  // Component API registration
  useEffect(() => {
    if (registerComponentApi) {
      registerComponentApi({
        focus,
        setValue,
        isoValue: getIsoValue,
      });
    }
  }, [registerComponentApi, focus, setValue, getIsoValue]);

  // Custom clear icon
  const clearIconElement = useMemo(() => {
    if (clearIcon === null || clearIcon === "null") return null;
    if (clearIcon) return <Icon name={clearIcon} />;
    // Default clear icon
    return (
      <svg
        xmlns="http://www.w3.org/2000/svg"
        width={19}
        height={19}
        viewBox="0 0 19 19"
        stroke="currentColor"
        strokeWidth={2}
        aria-hidden="true"
        className={classnames(styles.clearButtonIcon, styles.buttonIcon)}
      >
        <line x1="4" x2="15" y1="4" y2="15" />
        <line x1="15" x2="4" y1="4" y2="15" />
      </svg>
    );
  }, [clearIcon]);

  // Adornments
  const startAdornment = useMemo(() => {
    if (startIcon || startText) {
      return <Adornment iconName={startIcon} text={startText} className={styles.adornment} />;
    }
    return null;
  }, [startIcon, startText]);

  const endAdornment = useMemo(() => {
    if (endIcon || endText) {
      return <Adornment iconName={endIcon} text={endText} className={styles.adornment} />;
    }
    return null;
  }, [endIcon, endText]);

  // Helper function to get input refs based on order
  const getInputRefs = useCallback(() => {
    const refs = {
      day: dayInputRef,
      month: monthInputRef,
      year: yearInputRef,
    };
    return dateOrder.map((field) => refs[field as keyof typeof refs]);
  }, [dateOrder]);

  // Helper function to create input components in the right order
  const createDateInputs = () => {
    const inputRefs = getInputRefs();

    return dateOrder.map((field, index) => {
      const nextRef = index < inputRefs.length - 1 ? inputRefs[index + 1] : undefined;
      // Pass id to the first input field only
      const inputId = index === 0 ? id : undefined;

      const getSeparator = () => {
        if (index === dateOrder.length - 1) return null;

        // Get separator based on format
        if (dateFormat.includes("/")) return "/";
        if (dateFormat.includes("-")) return "-";
        return "";
      };

      switch (field) {
        case "day":
          return (
            <React.Fragment key="day">
              <DayInput
                id={inputId}
                autoFocus={autoFocus && index === 0}
                disabled={!enabled}
                inputRef={dayInputRef}
                nextInputRef={nextRef}
                minValue={minValue}
                maxValue={maxValue}
                onChange={handleDayChange}
                onBlur={handleDayBlur}
                onKeyDown={handleArrowKeys}
                readOnly={readOnly}
                required={required}
                value={day}
                isInvalid={isDayCurrentlyInvalid}
                month={month}
                year={year}
                emptyCharacter={processedEmptyCharacter}
              />
              {getSeparator() && <InputDivider separator={getSeparator()} />}
            </React.Fragment>
          );
        case "month":
          return (
            <React.Fragment key="month">
              <MonthInput
                id={inputId}
                autoFocus={autoFocus && index === 0}
                disabled={!enabled}
                inputRef={monthInputRef}
                nextInputRef={nextRef}
                minValue={minValue}
                maxValue={maxValue}
                onChange={handleMonthChange}
                onBlur={handleMonthBlur}
                onKeyDown={handleArrowKeys}
                readOnly={readOnly}
                required={required}
                value={month}
                isInvalid={isMonthCurrentlyInvalid}
                emptyCharacter={processedEmptyCharacter}
              />
              {getSeparator() && <InputDivider separator={getSeparator()} />}
            </React.Fragment>
          );
        case "year":
          return (
            <React.Fragment key="year">
              <YearInput
                id={inputId}
                autoFocus={autoFocus && index === 0}
                disabled={!enabled}
                inputRef={yearInputRef}
                nextInputRef={nextRef}
                minValue={minValue}
                maxValue={maxValue}
                onChange={handleYearChange}
                onBlur={handleYearBlur}
                onKeyDown={handleArrowKeys}
                readOnly={readOnly}
                required={required}
                value={year}
                isInvalid={isYearCurrentlyInvalid}
                dateFormat={dateFormat}
                emptyCharacter={processedEmptyCharacter}
              />
              {getSeparator() && <InputDivider separator={getSeparator()} />}
            </React.Fragment>
          );
        default:
          return null;
      }
    });
  };

  return (
    <div
      ref={dateInputRef}
      className={classnames(
        styles.dateInputWrapper,
        {
          [styles.error]: validationStatus === "error",
          [styles.warning]: validationStatus === "warning",
          [styles.valid]: validationStatus === "valid",
          [styles.disabled]: !enabled,
          [styles.readOnly]: readOnly,
        },
        className,
      )}
      style={{ ...style, gap }}
      onFocusCapture={handleComponentFocus}
      onBlur={handleComponentBlur}
      data-validation-status={validationStatus}
      {...rest}
    >
      {startAdornment}
      <div className={styles.wrapper}>
        <div className={styles.inputGroup}>{createDateInputs()}</div>
        {clearable && (
          <button
            data-part-id={PART_CLEAR_BUTTON}
            className={classnames(
              styles.clearButton,
              styles.button,
            )}
            disabled={!enabled}
            onClick={clear}
            onFocus={stopPropagation}
            type="button"
          >
            {clearIconElement}
          </button>
        )}
      </div>
      {endAdornment}
    </div>
  );
});

// Input component types
type InputProps = {
  id?: string;
  ariaLabel?: string;
  autoFocus?: boolean;
  className?: string;
  disabled?: boolean;
  inputRef?: React.RefObject<HTMLInputElement | null>;
  max: number;
  min: number;
  name: string;
  nextInputRef?: React.RefObject<HTMLInputElement | null>; // For auto-tabbing to next input
  onChange?: (event: React.ChangeEvent<HTMLInputElement> & { target: HTMLInputElement }) => void;
  onBlur?: (event: React.FocusEvent<HTMLInputElement> & { target: HTMLInputElement }) => void;
  onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement> & { target: HTMLInputElement }) => void;
  onKeyUp?: (event: React.KeyboardEvent<HTMLInputElement> & { target: HTMLInputElement }) => void;
  placeholder?: string;
  readOnly?: boolean;
  required?: boolean;
  step?: number;
  value?: string | null;
  maxLength?: number;
  isInvalid?: boolean; // To prevent auto-tabbing when value is invalid
  validateFn?: (value: string) => boolean; // Function to validate the current input value
  onBeep?: () => void; // Function to handle beep sound and event
};

// Input component
function Input({
  id,
  ariaLabel,
  autoFocus,
  className,
  disabled,
  inputRef,
  max,
  min,
  name,
  nextInputRef, // For auto-tabbing to next input
  onChange,
  onBlur,
  onKeyDown,
  onKeyUp,
  placeholder,
  readOnly,
  required,
  step,
  value,
  maxLength = 2,
  isInvalid = false, // To prevent auto-tabbing when value is invalid
  validateFn, // Function to validate the current input value
  onBeep, // Function to handle beep sound and event
}: InputProps): React.ReactElement {
  // Handle input changes with auto-tabbing logic
  const handleInputChange = useCallback(
    (event: React.ChangeEvent<HTMLInputElement>) => {
      const newValue = event.target.value;

      // Call the original onChange handler
      if (onChange) {
        onChange(event);
      }

      // Auto-tab to next input if we have reached max length, value is numeric, and value is valid
      if (newValue.length === maxLength && /^\d+$/.test(newValue)) {
        // Check if the new value is valid before auto-tabbing
        const isValueInvalid = validateFn ? validateFn(newValue) : false;

        if (!isValueInvalid) {
          // Small delay to ensure the current input is properly updated
          setTimeout(() => {
            if (nextInputRef?.current) {
              // Tab to next input field
              nextInputRef.current.focus();
              nextInputRef.current.select();
            }
          }, 0);
        } else {
          // Input is ready for auto-tab but invalid - play beep sound and fire event
          onBeep?.();
        }
      }
    },
    [onChange, nextInputRef, maxLength, validateFn, onBeep],
  );

  return (
    <>
      <input
        id={id}
        aria-label={ariaLabel}
        autoComplete="off"
        // biome-ignore lint/a11y/noAutofocus: This is up to developers' decision
        autoFocus={autoFocus}
        className={classnames(styles.input, className)}
        data-input="true"
        disabled={disabled}
        inputMode="numeric"
        max={max}
        maxLength={maxLength}
        min={min}
        name={name}
        onChange={handleInputChange}
        onBlur={onBlur}
        onFocus={onFocus}
        onKeyDown={onKeyDown}
        onKeyUp={onKeyUp}
        placeholder={placeholder || "--"}
        readOnly={readOnly}
        // Assertion is needed for React 18 compatibility
        ref={inputRef as React.RefObject<HTMLInputElement>}
        required={required}
        step={step}
        type="text"
        value={value !== null ? value : ""}
      />
    </>
  );
}

// DayInput component
type DayInputProps = {
  minValue?: string;
  maxValue?: string;
  value?: string | null;
  isInvalid?: boolean;
  month?: string | null;
  year?: string | null;
  onBeep?: () => void;
  emptyCharacter?: string;
} & Omit<
  React.ComponentProps<typeof PartialInput>,
  | "max"
  | "min"
  | "name"
  | "value"
  | "maxLength"
  | "validateFn"
  | "emptyCharacter"
  | "placeholderLength"
>;

function DayInput({
  minValue,
  maxValue,
  value,
  isInvalid = false,
  month,
  year,
  onBeep,
  emptyCharacter = "-",
  ...otherProps
}: DayInputProps): React.ReactElement {
  // Calculate max days for the current month/year
  const maxDay = useMemo(() => {
    if (month && year) {
      const monthNum = parseInt(month, 10);
      const yearNum = parseInt(year, 10);
      if (!isNaN(monthNum) && !isNaN(yearNum)) {
        return new Date(yearNum, monthNum, 0).getDate();
      }
    }
    return 31; // Default to 31 if month/year not available
  }, [month, year]);

  return (
    <PartialInput
      data-part-id={PART_DAY}
      id={otherProps.id}
      value={value}
      emptyCharacter={emptyCharacter}
      placeholderLength={2}
      max={Math.min(maxDay, 31)}
      min={1}
      maxLength={2}
      validateFn={(val) => isDayInvalid(val, month, year)}
      onBeep={onBeep}
      onChange={otherProps.onChange}
      onBlur={(direction, event) => {
        // PartialInput provides direction, but current onBlur expects just event
        if (otherProps.onBlur) {
          // Provide both direction and event to match the expected signature
          otherProps.onBlur(direction, event);
        }
      }}
      onKeyDown={otherProps.onKeyDown}
      className={classnames(styles.input, styles.day)}
      invalidClassName={styles.invalid}
      disabled={otherProps.disabled}
      readOnly={otherProps.readOnly}
      required={otherProps.required}
      autoFocus={otherProps.autoFocus}
      inputRef={otherProps.inputRef}
      nextInputRef={otherProps.nextInputRef}
      name="day"
      ariaLabel={otherProps.ariaLabel}
      isInvalid={isInvalid}
    />
  );
}

// MonthInput component
type MonthInputProps = {
  minValue?: string;
  maxValue?: string;
  value?: string | null;
  isInvalid?: boolean;
  onBeep?: () => void;
  emptyCharacter?: string;
} & Omit<React.ComponentProps<typeof PartialInput>, "max" | "min" | "name" | "value" | "maxLength">;

function MonthInput({
  minValue,
  maxValue,
  value,
  isInvalid = false,
  onBeep,
  emptyCharacter = "-",
  ...otherProps
}: MonthInputProps): React.ReactElement {
  return (
    <PartialInput
      data-part-id={PART_MONTH}
      id={otherProps.id}
      max={12}
      min={1}
      name="month"
      value={value}
      invalidClassName={styles.invalid}
      isInvalid={isInvalid}
      validateFn={isMonthInvalid}
      onBeep={onBeep}
      onChange={otherProps.onChange}
      emptyCharacter={emptyCharacter}
      placeholderLength={2}
      className={classnames(styles.input, styles.month)}
      maxLength={2}
      disabled={otherProps.disabled}
      required={otherProps.required}
      onBlur={(direction, event) => {
        // PartialInput provides direction, but current onBlur expects just event
        if (otherProps.onBlur) {
          // Provide both direction and event to match the expected signature
          otherProps.onBlur(direction, event);
        }
      }}
      onKeyDown={otherProps.onKeyDown}
      readOnly={otherProps.readOnly}
      autoFocus={otherProps.autoFocus}
      inputRef={otherProps.inputRef}
      nextInputRef={otherProps.nextInputRef}
      ariaLabel={otherProps.ariaLabel}
    />
  );
}

// YearInput component
type YearInputProps = {
  minValue?: string;
  maxValue?: string;
  value?: string | null;
  isInvalid?: boolean;
  dateFormat?: DateFormat;
  onBeep?: () => void;
  emptyCharacter?: string;
} & Omit<React.ComponentProps<typeof PartialInput>, "max" | "min" | "name" | "value" | "maxLength">;

function YearInput({
  minValue,
  maxValue,
  value,
  isInvalid = false,
  dateFormat = "MM/dd/yyyy",
  onBeep,
  emptyCharacter = "-",
  ...otherProps
}: YearInputProps): React.ReactElement {
  // Always use 4-digit year format
  const maxLength = 4;

  const currentYear = new Date().getFullYear();
  const min = 1900;
  const max = currentYear + 100;

  const { className: originalClassName, ...restProps } = otherProps;

  return (
    <PartialInput
      data-part-id={PART_YEAR}
      id={otherProps.id}
      max={max}
      min={min}
      name="year"
      value={value}
      isInvalid={isInvalid}
      invalidClassName={styles.invalid}
      validateFn={isYearInvalid}
      onBeep={onBeep}
      emptyCharacter={emptyCharacter}
      placeholderLength={4}
      className={classnames(styles.input, styles.year, originalClassName)}
      maxLength={maxLength}
      onBlur={(direction, event) => {
        // PartialInput provides direction, but current onBlur expects just event
        if (otherProps.onBlur) {
          // Provide both direction and event to match the expected signature
          otherProps.onBlur(direction, event);
        }
      }}
      {...restProps}
    />
  );
}

// Input helper functions
function onFocus(event: React.FocusEvent<HTMLInputElement>) {
  const { target } = event;

  if (isIEOrEdgeLegacy) {
    requestAnimationFrame(() => target.select());
  } else {
    target.select();
  }
}

// Utility function to parse date string into components
function parseDateString(dateString: string, dateFormat: DateFormat) {
  // Handle non-string values gracefully by returning null (empty fields)
  if (typeof dateString !== 'string' || dateString === null || dateString === undefined) {
    return null;
  }

  try {
    // Try to parse the date using the specified format
    const parsedDate = parse(dateString, dateFormat, new Date());

    if (isValid(parsedDate)) {
      return {
        day: parsedDate.getDate().toString().padStart(2, "0"),
        month: (parsedDate.getMonth() + 1).toString().padStart(2, "0"),
        year: parsedDate.getFullYear().toString(),
      };
    }

    // Fallback: Try to parse as ISO date string
    const isoDate = new Date(dateString);
    if (!isNaN(isoDate.getTime())) {
      return {
        day: isoDate.getDate().toString().padStart(2, "0"),
        month: (isoDate.getMonth() + 1).toString().padStart(2, "0"),
        year: isoDate.getFullYear().toString(),
      };
    }

    return null;
  } catch (error) {
    return null;
  }
}

// Normalize functions
function normalizeDay(
  value: string | null,
  month: string | null,
  year: string | null,
): string | null {
  if (!value || value === "") return null;

  const num = parseInt(value, 10);
  if (isNaN(num)) return null;

  // Calculate max days for the current month/year
  let maxDay = 31;
  if (month && year) {
    const monthNum = parseInt(month, 10);
    const yearNum = parseInt(year, 10);
    if (!isNaN(monthNum) && !isNaN(yearNum)) {
      maxDay = new Date(yearNum, monthNum, 0).getDate();
    }
  }

  if (num >= 1 && num <= maxDay) {
    return num.toString().padStart(2, "0");
  } else {
    // Keep value % 10. In case of "0" use "01"
    const normalizedValue = num % 10;
    if (normalizedValue === 0) {
      return "01";
    } else {
      return normalizedValue.toString().padStart(2, "0");
    }
  }
}

function normalizeMonth(value: string | null): string | null {
  if (!value || value === "") return null;

  const num = parseInt(value, 10);
  if (isNaN(num)) return null;

  if (num >= 1 && num <= 12) {
    return num.toString().padStart(2, "0");
  } else {
    // Keep the last digit. Use "0" as the first digit. In case of "0" use "01"
    const lastDigit = num % 10;
    if (lastDigit === 0) {
      return "01";
    } else {
      return `0${lastDigit}`;
    }
  }
}

function normalizeYear(value: string | null): string | null {
  if (!value || value === "") return null;

  const num = parseInt(value, 10);
  if (isNaN(num)) return null;

  if (num >= MIN_YEAR && num <= MAX_YEAR) {
    return num.toString();
  } else {
    // Keep the last two year digits and use "20" as the first two digits if the resulting year is not in the future; otherwise, use "19" as the first two digits
    const lastTwoDigits = num % 100;
    const currentYear = new Date().getFullYear();
    const candidate20 = 2000 + lastTwoDigits;
    const candidate19 = 1900 + lastTwoDigits;

    // Use "20" if the resulting year is not in the future; otherwise, use "19"
    if (candidate20 <= currentYear) {
      return candidate20.toString();
    } else {
      return candidate19.toString();
    }
  }
}

// Validation functions
function isDayInvalid(value: string | null, month: string | null, year: string | null): boolean {
  if (!value || value === "") return false;

  const num = parseInt(value, 10);
  if (isNaN(num)) return true;

  // Calculate max days for the current month/year
  let maxDay = 31;
  if (month && year) {
    const monthNum = parseInt(month, 10);
    const yearNum = parseInt(year, 10);
    if (!isNaN(monthNum) && !isNaN(yearNum)) {
      maxDay = new Date(yearNum, monthNum, 0).getDate();
    }
  }

  return num < 1 || num > maxDay;
}

function isMonthInvalid(value: string | null): boolean {
  if (!value || value === "") return false;

  const num = parseInt(value, 10);
  if (isNaN(num)) return true;

  return num < 1 || num > 12;
}

function isYearInvalid(value: string | null): boolean {
  if (!value || value === "") return false;

  const num = parseInt(value, 10);
  if (isNaN(num)) return true;

  // Invalid if out of the minimum and maximum year range
  return num < MIN_YEAR || num > MAX_YEAR;
}

```

--------------------------------------------------------------------------------
/xmlui/dev-docs/ud-components.md:
--------------------------------------------------------------------------------

```markdown
# User-Defined Component Architecture

This document explains XMLUI's user-defined component infrastructure - the rendering mechanisms that enable developers to create reusable components in `.xmlui` files with template composition through slots and children transposition. It covers the architectural foundations, the slot transposition mechanism, the role of ComponentAdapter and supporting components, and implementation details for framework developers working on the XMLUI core.

## What Are User-Defined Components?

**User-defined components** are reusable component definitions created by application developers using XMLUI markup in `.xmlui` files. They encapsulate visual structure, behavior, and state management patterns into named components that can be used throughout an application just like framework-provided components.

A user-defined component is declared with the `<Component>` tag and must have a unique name starting with an uppercase letter. The component name must match the filename (e.g., `ActionBar.xmlui` contains `<Component name="ActionBar">`). Components support properties, events, methods, variables, and slots for template composition.

> **Note**: In built mode, xmlui can work with components where their name does not match the file name. However, those components won't work with buildless mode.

**Key Characteristics:**

- **Declarative Definition** - Components defined entirely in XMLUI markup without requiring JavaScript/TypeScript code
- **Property Passing** - Parent components pass data through properties accessed via `$props` context variable
- **Event Emission** - Components notify parents of state changes through custom events using `emitEvent()`
- **Template Composition** - Slots enable parent components to inject custom markup into predefined component regions
- **Encapsulation** - Components maintain their own state, methods, and internal structure
- **Reusability** - Once defined, components can be used throughout the application like any framework component

## Architectural Overview

### The Compound Component Pattern

User-defined components are implemented as **compound components** - they consist of two interconnected parts:

1. **Component Interface** - The properties, events, and children the parent component provides
2. **Component Implementation** - The internal markup, state, and logic defined in the `.xmlui` file

**Example Component Definition:**

```xml
<Component name="ContactCard">
  <Card width="20%">
    <Text>Name: { $props.name} </Text>
    <Text>Phone: { $props.value} </Text>
    <Slot />
  </Card>
</Component>
```

**Parent Usage:**

```xml
<App>
  <ContactCard name="Mary" value="123">
    <Button icon="phone" label="Click Me to Call" />
  </ContactCard>
</App>
```

This example defines a reusable ContactCard component that reads properties passed by its parent (available inside the component as `$props.name` and `$props.value`) and renders them inside a Card. The `<Slot />` is a default slot: any children provided by the parent (the Button in this case) are transposed into that location when the component is rendered.

### Component Rendering Flow

User-defined components follow a distinct rendering path compared to framework-provided components. The key architectural difference is that user-defined components are **compound components** - they have both a component definition (what the parent sees) and an internal implementation (what renders).

**High-Level Flow:**

1. Parent component uses a user-defined component (e.g., `<ContactCard>`)
2. ComponentAdapter receives the component definition
3. ComponentRegistry identifies it as a compound component
4. CompoundComponent wraps the internal implementation
5. Container provides scope for `$props`, vars, and methods
6. Slot components transpose parent content
7. SlotItem renders content with context variables

This architecture enables template composition - parent components provide markup fragments that render within the compound component's layout, with access to data pushed from the compound component through slot properties.


### Slot-Based Template Composition

Slots are placeholder components within user-defined components that mark where parent-provided content should render. XMLUI supports two types of slots:

**Default (Unnamed) Slots** receive all children passed to the component:

```xml
<Component name="Panel">
  <Card>
    <Slot />
  </Card>
</Component>

<!-- Usage -->
<Panel>
  <Text>This content goes into the default slot</Text>
</Panel>
```

**Named Slots** receive specific template fragments from the parent using the `<property>` syntax:

```xml
<Component name="Dialog">
  <Card>
    <Slot name="headerTemplate">
      <H3>Default Header</H3>
    </Slot>
    <Slot />
    <Slot name="actionsTemplate">
      <Button label="OK" />
    </Slot>
  </Card>
</Component>

<!-- Usage -->
<Dialog>
  <property name="headerTemplate">
    <H2>Custom Header</H2>
  </property>
  <Text>Main dialog content</Text>
  <property name="actionsTemplate">
    <Button label="Cancel" />
    <Button label="Confirm" />
  </property>
</Dialog>
```

Named slots must end with `"Template"` suffix - this is a framework requirement enforced in `slotRenderer()` and `renderChild()`.

### Slot Properties: Data Flow from Component to Parent

Slots enable bidirectional data flow - not only can parents inject content into components, but components can push data back to the parent's slot content through **slot properties**.

**How Slot Properties Work:**

1. The compound component declares properties on the `<Slot>` element
2. These properties are evaluated in the component's scope with access to component state
3. The properties are transformed into context variables prefixed with `$` in the slot content
4. The parent's slot content can access these context variables

**Example - List Component Passing Item Data:**

```xml
<Component name="ItemList">
  <variable name="items" value="{['Apple', 'Banana', 'Cherry']}" />
  
  <VStack>
    <Items data="{items}">
      <Slot 
        name="itemTemplate" 
        item="{$item}" 
        index="{$index}"
        isLast="{$isLast}">
        <!-- Default template if parent doesn't provide one -->
        <Text>{$item}</Text>
      </Slot>
    </Items>
  </VStack>
</Component>

<!-- Parent Usage -->
<ItemList>
  <property name="itemTemplate">
    <Card padding="sm">
      <Text variant="strong">#{$index + 1}: {$item}</Text>
      <ContentSeparator when="{!$isLast}" />
    </Card>
  </property>
</ItemList>
```

In this example:
- The `ItemList` component uses the `<Items>` component to iterate over the `items` array
- For each item, it renders a `<Slot>` with properties: `item`, `index`, and `isLast`
- These properties become context variables `$item`, `$index`, and `$isLast` in the parent's template
- The parent's `itemTemplate` uses these variables to render custom markup, with `ContentSeparator` conditionally displayed based on `$isLast`

**Scope Behavior:**

Slot properties create a unique scoping pattern:
- Slot properties are evaluated in the **component's scope** (with access to component variables and state)
- The extracted values are passed as context variables to the slot content
- The slot content renders in the **parent's scope** (with access to parent variables and IDs)
- Context variables from slot properties are available only within that specific slot content

This pattern enables powerful composition scenarios like data tables with custom cell renderers, lists with custom item templates, and dialogs with custom header/footer templates.

## Implementation Details

### ComponentAdapter: The Routing Layer

`ComponentAdapter` is the central component in XMLUI's rendering pipeline that transforms component definitions into React elements. It handles special routing and slot transposition for user-defined components.

**Key Responsibilities:**

1. **Component Registry Lookup** - Determines if a component is compound (user-defined) or primitive (framework)
2. **Slot Detection and Routing** - Detects `type === "Slot"` and routes to `slotRenderer()`
3. **Renderer Context Assembly** - Prepares renderer context with state, value extraction, event handlers, and layout
4. **Behavior Application** - Applies behaviors (tooltip, animation, label) but skips them for compound components
5. **Test Decoration** - Adds test IDs and inspection attributes for development tooling

**Compound Component Detection:**

```typescript
const { renderer, descriptor, isCompoundComponent } =
  componentRegistry.lookupComponentRenderer(safeNode.type) || {};
```

Returns:
- `renderer` - Rendering function (for compound components: `CompoundComponentHolder`)
- `descriptor` - Component metadata (props, events, visual/nonvisual, etc.)
- `isCompoundComponent` - Boolean flag for user-defined components

**Critical Behavioral Difference:**

ComponentAdapter skips behavior application for compound components:

```typescript
const behaviors = componentRegistry.getBehaviors();
if (!isCompoundComponent) {
  for (const behavior of behaviors) {
    if (behavior.canAttach(rendererContext.node, descriptor)) {
      renderedNode = behavior.attach(rendererContext, renderedNode, descriptor);
    }
  }
}
```

This prevents behaviors from wrapping the compound component's internal structure. Behaviors attach only to the outermost visual element controlled by the component's internal implementation.

### slotRenderer(): The Transposition Function

`slotRenderer()` is a specialized renderer within ComponentAdapter that handles Slot component rendering. It implements the core transposition mechanism - taking content from the parent and rendering it in the compound component's location.

**Function Signature:**

```typescript
function slotRenderer(
  { node, extractValue, renderChild, lookupAction, layoutContext }: RendererContext<any>,
  parentRenderContext?: ParentRenderContext,
): ReactNode
```

**Parameters:**

- `node` - Slot component definition with slot name and properties
- `extractValue` - Evaluates property expressions for slot properties
- `renderChild` - Renders child components for default slot content
- `lookupAction` - Resolves action expressions for arrow function slot props
- `layoutContext` - Current layout context (horizontal/vertical stack, etc.)
- `parentRenderContext` - Parent component context with children and templates

**Processing Logic:**

```typescript
// 1. Extract slot name (if named slot)
const templateName = extractValue.asOptionalString(node.props.name);

// 2. Validate slot name ends with "Template"
if (templateName && !templateName.endsWith("Template")) {
  return <InvalidComponent errors={[...]} />;
}

// 3. Extract slot properties (all props except "name")
// Note: The "name" property identifies which parent template to use for transposition
// and is not passed as a slot property to the rendered content
let slotProps: any = null;
if (!isEmpty(node.props)) {
  slotProps = {};
  Object.keys(node.props).forEach((key) => {
    if (key !== "name") {
      let extractedValue = extractValue(node.props[key], true);
      // Handle arrow function properties
      if (extractedValue?._ARROW_EXPR_) {
        extractedValue = lookupAction(extractedValue);
      }
      slotProps[key] = extractedValue;
    }
  });
}

// 4. Determine content source based on slot type and parent context
if (parentRenderContext) {
  if (templateName === undefined) {
    // Default slot - use parent's children
    if (!slotProps) {
      return parentRenderContext.renderChild(parentRenderContext.children, layoutContext);
    } else {
      return <SlotItem 
        node={parentRenderContext.children}
        renderChild={parentRenderContext.renderChild}
        slotProps={slotProps}
        layoutContext={layoutContext}
      />;
    }
  } else {
    // Named slot - use parent's template property
    if (parentRenderContext.props[templateName]) {
      return <SlotItem 
        node={parentRenderContext.props[templateName]}
        renderChild={parentRenderContext.renderChild}
        slotProps={slotProps}
        layoutContext={layoutContext}
      />;
    }
  }
}

// 5. No parent content - render default slot children
if (node.children && node.children.length > 0) {
  return <SlotItem 
    node={node.children}
    renderChild={renderChild}
    slotProps={slotProps ?? EMPTY_OBJECT}
    layoutContext={layoutContext}
  />;
}

return undefined;
```

**Decision Tree:**

The function follows this logic to determine what to render:

1. **Named Slot with Parent Template** → Render parent's template property with slot props
2. **Named Slot without Parent Template** → Render default slot children with slot props
3. **Default Slot with Parent Children** → Render parent's children (with or without slot props)
4. **Default Slot without Parent Children** → Render default slot children
5. **No Content Available** → Return undefined (renders nothing)

**Slot Properties Handling:**

All properties on the Slot element (except `name`) become slot properties:

```xml
<Slot name="itemTemplate" item="{$item}" index="{$index}" color="red" />
```

Results in `slotProps`:

```javascript
{
  item: extractValue($item),      // Evaluates to current item value
  index: extractValue($index),    // Evaluates to current index value
  color: "red"                    // Static string value
}
```

These props are passed to `SlotItem` which transforms them into context variables (`$item`, `$index`, `$color`) available in the slot content.

**Arrow Function Properties:**

Slot properties can be arrow functions that execute in the component's scope:

```xml
<Slot 
  name="itemTemplate" 
  item="{$item}"
  displayName="() => $item.toUpperCase()" />
```

The `slotRenderer` detects arrow function expressions via the `_ARROW_EXPR_` marker and resolves them using `lookupAction()` before passing to `SlotItem`.

### SlotItem: The Context Variable Wrapper

`SlotItem` is a React component that wraps slot content in a Container with context variables derived from slot properties. It implements the transformation that makes slot properties accessible as context variables in the parent's template markup.

**Component Signature:**

```typescript
type SlotItemProps = {
  node: ComponentDef | Array<ComponentDef>;
  slotProps?: any;
  renderChild: RenderChildFn;
  layoutContext?: LayoutContext;
};

export const SlotItem = memo(({ node, renderChild, layoutContext, slotProps = EMPTY_OBJECT }: SlotItemProps) => {
  // ... implementation
});
```

**Transformation Process:**

```typescript
// 1. Memoize slot props to prevent unnecessary re-renders
const shallowMemoedSlotProps = useShallowCompareMemoize(slotProps);

// 2. Transform slot properties into context variables
const nodeWithItem = useMemo(() => {
  const templateProps = {};
  Object.entries(shallowMemoedSlotProps).forEach(([key, value]) => {
    templateProps["$" + key] = value;  // Prefix with $
  });

  // 3. Create Container with context variables
  return {
    type: "Container",
    contextVars: templateProps,
    children: Array.isArray(node) ? node : [node],
  } as ContainerWrapperDef;
}, [node, shallowMemoedSlotProps]);

// 4. Render containerized slot content
return <>{renderChild(nodeWithItem, layoutContext)}</>;
```

**Key Operations:**

1. **Property Prefixing** - Each slot prop key is prefixed with `$` to create a context variable
   - `item` → `$item`
   - `index` → `$index`
   - `isSelected` → `$isSelected`

2. **Container Creation** - Wraps slot content in a Container component definition with `contextVars`
   - The Container creates a new state scope
   - Context variables are available to all components within the slot content
   - State isolation prevents slot content from interfering with component or parent state

3. **Rendering Delegation** - Calls `renderChild()` with the containerized node
   - Routes through ComponentWrapper → ContainerWrapper → ComponentAdapter
   - ContainerWrapper provides the context variable scope
   - Slot content components can access `$item`, `$index`, etc. through the value extractor

**Memoization Strategy:**

SlotItem uses multiple memoization levels to optimize performance:
- `React.memo` - Prevents re-rendering when props haven't changed
- `useShallowCompareMemoize` - Creates stable references using shallow equality
- `useMemo` - Recomputes containerized node only when slot props or content changes

This prevents unnecessary re-renders when compound components re-render but slot properties remain unchanged.

**Example Data Flow:**

```xml
<!-- Compound Component -->
<Slot name="itemTemplate" item="{currentItem}" index="{i}" />

<!-- SlotItem receives -->
{
  node: [/* parent's template definition */],
  slotProps: { item: "Apple", index: 0 },
  renderChild: parentRenderChild,
  layoutContext: { ... }
}

<!-- SlotItem transforms to -->
{
  type: "Container",
  contextVars: { $item: "Apple", $index: 0 },
  children: [/* parent's template definition */]
}

<!-- Parent template can access -->
<Text>{$item}</Text>  <!-- Renders "Apple" -->
<Text>#{$index}</Text> <!-- Renders "#0" -->
```

### CompoundComponent: The Implementation Bridge

`CompoundComponent` is the React component that bridges user-defined component definitions with their internal implementations. It manages property resolution, event emission, state updates, and parent render context assembly for slot transposition.

**Component Signature:**

```typescript
type CompoundComponentProps = {
  compound: ComponentDef;           // Internal component implementation
  api?: Record<string, string>;     // Component API method mappings
  scriptCollected?: CollectedDeclarations;  // Collected script declarations
} & RendererContext;                // Full renderer context
```

**Responsibilities:**

1. **Property Resolution** - Extracts and evaluates all properties passed to the component
2. **Container Assembly** - Wraps internal implementation in Container with vars, loaders, methods
3. **Event Emission** - Provides `emitEvent()` function for component-to-parent communication
4. **Parent Context Creation** - Assembles parent render context for slot transposition
5. **Scope Isolation** - Ensures component implementation has access to `$props`, vars, and methods

**Property Resolution:**

```typescript
const resolvedPropsInner = useMemo(() => {
  const resolvedProps: any = {};
  if (node.props) {
    Object.entries(node.props).forEach(([key, value]) => {
      const extractedProp = extractValue(value, true);
      if (extractedProp?._ARROW_EXPR_) {
        // Arrow functions are called synchronously
        resolvedProps[key] = lookupSyncCallback(extractedProp);
      } else {
        resolvedProps[key] = extractedProp;
      }
    });
  }
  return resolvedProps;
}, [extractValue, lookupSyncCallback, node.props]);

const resolvedProps = useShallowCompareMemoize(resolvedPropsInner);
```

Properties are evaluated using the parent's value extractor, which means expressions like `<MyComponent count={parentVar + 1} />` are evaluated in the parent's scope. The resolved values become available in the component implementation via `$props.count`.

**Container Assembly:**

```typescript
const containerNode: ContainerWrapperDef = useMemo(() => {
  const { loaders, vars, functions, scriptError, ...rest } = compound;
  return {
    type: "Container",
    uses: EMPTY_ARRAY,
    api,
    scriptCollected,
    loaders: loaders,
    vars,
    functions: functions,
    scriptError: scriptError,
    containerUid: uid,
    props: {
      debug: (compound.props as any)?.debug,
    },
    children: [rest],
  };
}, [api, compound, scriptCollected, uid]);
```

The internal component implementation is wrapped in a Container that provides:
- `loaders` - DataSource and other loader components defined at component level
- `vars` - Variables declared with `<variable>` tags or in `<script>` tags
- `functions` - Methods declared with `<script>` tags
- `scriptCollected` - Collected script declarations from `.xmlui.xs` code-behind files
- `api` - Component API method mappings for external access (declared with `<method>` tags)

**Implicit Variables Injection:**

```typescript
const vars = useMemo(() => {
  return {
    $props: resolvedProps,
    ...containerNode.vars,
    emitEvent,
    hasEventHandler,
    updateState,
  };
}, [containerNode.vars, emitEvent, hasEventHandler, resolvedProps, updateState]);
```

CompoundComponent injects several implicit variables into the component's scope:
- `$props` - Object containing all resolved property values
- `emitEvent` - Function to fire custom events to parent
- `hasEventHandler` - Function to check if parent registered an event handler
- `updateState` - Function to programmatically update component state

These variables are available throughout the component implementation without explicit declaration.

**Event Emission:**

```typescript
const emitEvent = useEvent((eventName, ...args) => {
  const handler = lookupEventHandler(eventName);
  if (handler) {
    return handler(...args);
  }
});
```

The `emitEvent()` function allows component implementations to notify parents of state changes:

```xml
<Component name="Counter">
  <variable name="count" value="{0}" />
  <Button 
    label="Increment: {count}" 
    onClick="count++; emitEvent('valueChanged', count)" />
</Component>

<!-- Parent usage -->
<Counter onValueChanged="(newValue) => console.log('Count is now', newValue)" />
```

When the button is clicked, `emitEvent('valueChanged', count)` looks up the parent's `onValueChanged` handler and calls it with the current count value.

> **Note**: The `emitEvent` function signature is `emitEvent(eventName: string, ...args: any[])`. The event name is automatically prefixed with "on" and converted to camelCase when looking up the parent's handler. For example, `emitEvent('valueChanged', data)` looks for the `onValueChanged` property in the parent.

**Parent Render Context Assembly:**

```typescript
const hasTemplateProps = useMemo(() => {
  return Object.entries(node.props).some(([key, value]) => {
    return (
      key.endsWith("Template") ||
      (isObject(value) && (value as any).type !== undefined) ||
      (isArray(value) && (value as any)[0]?.type !== undefined)
    );
  });
}, [node.props]);

const memoedParentRenderContext = useMemo(() => {
  if (!hasTemplateProps && (!node.children || node.children.length === 0)) {
    return undefined;
  }
  return {
    renderChild,
    props: node.props,
    children: node.children,
  };
}, [hasTemplateProps, node.children, node.props, renderChild]);
```

CompoundComponent analyzes the parent's usage to determine if it needs to create a parent render context:

**Parent render context is created when:**
- The parent provides template properties (ending with "Template")
- The parent provides children for default slot transposition

**Parent render context is not created when:**
- No template properties are passed and no children are provided

The parent render context is passed down through `renderChild()` and becomes available in `slotRenderer()` for slot transposition.

**Detection Logic:**

The `hasTemplateProps` check uses a heuristic to identify template properties:
- Property name ends with "Template" (named slot convention)
- Property value is an object with a `type` field (component definition)
- Property value is an array with a first element that has a `type` field (array of component definitions)

This detection enables CompoundComponent to optimize - if no templates or children are passed, it skips parent render context creation entirely.

**Rendering Delegation:**

```typescript
const ret = renderChild(nodeWithPropsAndEvents, safeLayoutContext, memoedParentRenderContext);
```

CompoundComponent delegates to `renderChild()` with:
- `nodeWithPropsAndEvents` - The containerized component implementation with injected vars
- `safeLayoutContext` - Layout context with `wrapChild` removed (wrapping already happened)
- `memoedParentRenderContext` - Parent context for slot transposition (or undefined)

This delegation routes through ComponentWrapper → ContainerWrapper → ComponentAdapter, which renders the component's internal markup and handles any Slot components via `slotRenderer()`.

### Parent Render Context Structure

The parent render context is a critical data structure that enables slot transposition by carrying information from the parent component to the compound component's internal Slot elements.

**Type Definition:**

```typescript
export type ParentRenderContext = {
  renderChild: RenderChildFn;
  props: Record<string, any>;
  children?: Array<ComponentDef>;
};
```

**Properties:**

- **renderChild** - The parent component's render function
  - Used to render slot content in the parent's scope
  - Ensures parent variables, IDs, and context are accessible in slot content
  - Preserves correct event handler bindings to parent actions

- **props** - All properties passed to the compound component
  - Includes template properties (e.g., `headerTemplate`, `itemTemplate`)
  - Includes regular properties (accessed via `$props` in component implementation)
  - Template properties contain component definitions to render in named slots

- **children** - Array of child component definitions
  - Represents the default children passed between component tags
  - Used for default (unnamed) slot transposition
  - Optional - undefined if no children provided

**Flow Through Rendering Pipeline:**

1. **Parent Component Usage**
   ```xml
   <MyComponent header="Title">
     <property name="headerTemplate">
       <H2>{$processedHeader}</H2>
     </property>
     <Button label="Click me" />
   </MyComponent>
   ```

2. **Parent Render Context Assembly** - CompoundComponent assembles:
   ```ts
   {
     renderChild: parentRenderChild,
     props: {
       header: "Title",
       headerTemplate: [{ type: "H2", children: [...] }]
     },
     children: [{ type: "Button", props: { label: "Click me" } }]
   }
   ```

3. **Context Propagation** - Passed to `renderChild` as third parameter

4. **Rendering Flow** - Flows through ComponentWrapper → ComponentAdapter

5. **Slot Detection** - Available in slotRenderer when Slot is encountered

6. **Content Resolution** - slotRenderer uses:
   - `parentRenderContext.props[templateName]` for named slots
   - `parentRenderContext.children` for default slot
   - `parentRenderContext.renderChild` to render content

**Scope Preservation:**

The parent render context preserves the parent's rendering scope, which is critical for correct slot behavior:

```xml
<!-- Parent Component -->
<App var.userName="Alice">
  <MyDialog>
    <property name="headerTemplate">
      <Text>Welcome, {userName}!</Text>
    </property>
  </MyDialog>
</App>

<!-- MyDialog Component -->
<Component name="MyDialog">
  <Card>
    <Slot name="headerTemplate" />
  </Card>
</Component>
```

When the headerTemplate renders:
- `parentRenderContext.renderChild` is the App's renderChild function
- The expression `{userName}` evaluates in App's scope (where `userName` variable exists)
- The Text component renders "Welcome, Alice!" even though it's physically inside MyDialog's markup

Without parent render context preservation, the template would render in MyDialog's scope and `{userName}` would be undefined.

### Rendering Pipeline for User-Defined Components

**Complete Flow:**

1. **Parent Component References User-Defined Component**
   ```xml
   <ActionBar header="Menu">
     <Button label="Save" />
     <Button label="Cancel" />
   </ActionBar>
   ```

2. **ComponentWrapper** receives component definition
3. **ComponentWrapper** routes to ComponentAdapter
4. **ComponentAdapter** queries ComponentRegistry
   - Receives: renderer, descriptor, isCompoundComponent=true
   - Renderer is CompoundComponentHolder
5. **ComponentAdapter** prepares RendererContext
   - Assembles state, extractValue, lookupEventHandler, etc.
   - Skips behavior application (isCompoundComponent=true)
6. **ComponentAdapter** calls CompoundComponentHolder(rendererContext)
7. **CompoundComponentHolder** wraps in CompoundComponent
8. **CompoundComponent** resolves properties
   - Extracts "Menu" from header property
   - Creates resolvedProps: { header: "Menu" }
9. **CompoundComponent** assembles Container for implementation
   - Injects $props, emitEvent, hasEventHandler, vars, methods
10. **CompoundComponent** creates parent render context
    - props: { header: "Menu" }
    - children: [Button, Button]
    - renderChild: parent's renderChild function
11. **CompoundComponent** calls renderChild(containerNode, layoutContext, parentRenderContext)
12. **renderChild** routes through ComponentWrapper → ContainerWrapper → ComponentAdapter
13. **ComponentAdapter** renders component's internal Card, HStack, H3, Slot
14. **ComponentAdapter** encounters Slot component (type === "Slot")
15. **ComponentAdapter** calls slotRenderer(rendererContext, parentRenderContext)
16. **slotRenderer** determines slot type (default, unnamed)
17. **slotRenderer** extracts slot properties (if any)
18. **slotRenderer** retrieves content from parentRenderContext.children
19. **slotRenderer** delegates to SlotItem
20. **SlotItem** transforms slot props to context variables and creates Container with contextVars
21. **SlotItem** calls parentRenderContext.renderChild(containerizedNode)
22. **Parent's renderChild** renders Button components in parent's scope
23. **Buttons** render with access to parent's variables, IDs, event handlers
24. **Full component tree** assembled and returned to parent

**Key Transition Points:**

- **Steps 1-5**: Standard component rendering setup
- **Steps 6-11**: CompoundComponent-specific processing (property resolution, parent context assembly)
- **Steps 12-13**: Rendering component's internal implementation
- **Steps 14-19**: Slot transposition triggered
- **Steps 20-23**: SlotItem scope transformation and parent content rendering

**Scope Transitions:**

The rendering pipeline involves three distinct scopes:

1. **Parent Scope** (Steps 1-5, 22-24)
   - Parent's variables, IDs, state accessible
   - Parent's renderChild function active
   - Parent's event handlers bound

2. **Component Scope** (Steps 6-13)
   - Component's variables, methods, state accessible
   - `$props` contains resolved parent properties
   - Component's renderChild function active
   - Internal implementation rendering

3. **Slot Content Scope** (Steps 19-23)
   - Parent's scope restored via parentRenderContext.renderChild
   - Slot properties available as `$` context variables
   - Hybrid scope: parent variables + slot-provided context variables

This scope management ensures that:
- Component implementations can access their own state and `$props`
- Slot content can access parent variables and IDs
- Slot properties from component flow into parent's template as context variables

## Advanced Patterns

### Conditional Slots

Slots can be conditionally rendered based on component state or properties:

```xml
<Component name="CollapsiblePanel">
  <variable name="isExpanded" value="{$props.defaultExpanded ?? false}" />
  
  <Card>
    <HStack>
      <Slot name="headerTemplate">
        <H3>{$props.title}</H3>
      </Slot>
      <Button 
        label="{isExpanded ? '−' : '+'}"
        onClick="isExpanded = !isExpanded" />
    </HStack>
    
    <Slot when="{isExpanded}"/>
  </Card>
</Component>
```

The default slot only renders when `isExpanded` is true. The `when` attribute of `Slot` controls slot rendering based on component state.

### Default Content with Slot Properties

Slots can provide both default content and slot properties:

```xml
<Component name="StatusBadge">
  <variable name="statusColor" value="{getColorForStatus($props.status)}" />
  <variable name="statusIcon" value="{getIconForStatus($props.status)}" />
  
  <Slot 
    color="{statusColor}"
    icon="{statusIcon}"
    status="{$props.status}">
    <!-- Default rendering if parent doesn't provide template -->
    <HStack>
      <Icon name="{statusIcon}" color="{statusColor}" />
      <Text color="{statusColor}">{$props.status}</Text>
    </HStack>
  </Slot>
</Component>

<!-- Simple usage - uses default rendering -->
<StatusBadge status="active" />

<!-- Custom rendering - uses slot properties -->
<StatusBadge status="active">
  <Badge variant="solid" colorScheme="{$color}">
    <Icon name="{$icon}" />
    <Text>{$status.toUpperCase()}</Text>
  </Badge>
</StatusBadge>
```

This pattern allows components to provide sensible defaults while enabling parent customization when needed.

## Common Patterns and Best Practices

### Component Naming Conventions

**Component Names:**
- Must start with uppercase letter (e.g., `MyComponent`, not `myComponent`)
- Use PascalCase for multi-word names (e.g., `ActionBar`, `UserProfile`)
- Match filename exactly (e.g., `ActionBar.xmlui` contains `<Component name="ActionBar">`)

**Slot Names:**
- Must end with `Template` suffix for named slots (e.g., `headerTemplate`, `itemTemplate`)
- Use camelCase for consistency (e.g., `headerTemplate`, not `HeaderTemplate`)
- Be descriptive of content purpose (e.g., `emptyStateTemplate`, not `template1`)

**Property Names:**
- Use camelCase (e.g., `userName`, `isVisible`, `onItemSelected`)
- Prefix event properties with `on` (e.g., `onValueChanged`, `onSubmit`)
- Keep names concise but descriptive

### State Management

Keep component state internal and communicate changes through events:

```xml
<Component name="SearchBox">
  <variable name="query" value="{$props.initialQuery ?? ''}" />
  <variable name="results" value="{[]}" />
  
  <VStack>
    <TextBox 
      value="{query}"
      onValueChanged="query = $event; search()" />
    
    <method name="search">
      const newResults = await searchAPI(query);
      results = newResults;
      emitEvent('searchCompleted', { query, results: newResults });
    </method>
    
    <Items data="{results}">
      <Slot name="resultTemplate" result="{$item}" index="{$index}">
        <Text>{$result.title}</Text>
      </Slot>
    </Items>
  </VStack>
</Component>
```

The component manages internal state (`query`, `results`) and notifies parent of changes via `emitEvent()`.

### Slot Default Content

Always provide meaningful default content for slots:

```xml
<Component name="Card">
  <Card>
    <Slot name="headerTemplate">
      <H3>{$props.title ?? 'Untitled'}</H3>
    </Slot>
    
    <Slot>
      <Text color="gray.500">No content provided</Text>
    </Slot>
    
    <Slot name="actionsTemplate">
      <Button label="Close" onClick="$this.close()" />
    </Slot>
  </Card>
</Component>
```

Default content provides fallback rendering when parents don't provide custom templates, making components more robust and self-documenting.

## Implementation Notes for Framework Developers

### Performance Considerations

**Memoization Strategy:**

- CompoundComponent uses `useShallowCompareMemoize` for resolved props to prevent re-renders when prop objects are recreated but values haven't changed
- SlotItem uses `React.memo` and shallow comparison for slot props to avoid re-rendering when compound component re-renders but slot data is stable
- Parent render context is memoized to prevent recreation on every render

**Rendering Optimization:**

- Parent render context is only created when templates or children are present
- `hasTemplateProps` check uses heuristics to detect template properties efficiently
- Slot renderer short-circuits when no parent context and no default content

**State Isolation:**

- Each compound component instance gets unique `uid` for state isolation
- Container wrapping ensures component state doesn't pollute parent or global state
- Slot content renders in isolated Container scope with context variables

**Slot Name Validation:**

Named slots must end with "Template" suffix. The `slotRenderer` function validates this and renders an `InvalidComponent` with error message if violated:

```typescript
if (templateName && !templateName.endsWith("Template")) {
  return (
    <InvalidComponent
      node={node}
      errors={[
        `Slot name '${templateName}' is not valid. ` +
          "A named slot should use a name ending with 'Template'.",
      ]}
    />
  );
}
```

This validation prevents common mistakes and provides clear error messages during development.

### Extensibility Points

**Custom Component Registration:**

External packages can register user-defined components through the `ContributesDefinition` mechanism:

```typescript
export default {
  namespace: "MyPackage",
  components: [
    {
      name: "MyComponent",
      component: compoundDefinition,
      metadata: componentMetadata,
    }
  ],
};
```

## Summary

User-defined components in XMLUI provide a powerful declarative component model built on slot-based template composition. The architecture centers on three key mechanisms:

1. **CompoundComponent** manages the bridge between component interface and implementation, resolving properties, providing event emission, and assembling parent render context.

2. **slotRenderer** implements the core transposition logic, determining what content to render in each slot based on parent-provided templates, children, and default content.

3. **SlotItem** transforms slot properties into context variables, enabling bidirectional data flow between compound components and parent templates.

ComponentAdapter orchestrates the rendering pipeline, routing compound components through CompoundComponent, detecting Slot components, and delegating to slotRenderer for transposition. The parent render context structure preserves scope boundaries, ensuring slot content renders in the parent's scope with access to both parent variables and component-provided context variables.

This architecture enables composition patterns like nested slots, conditional slots, slot properties with arrow functions, and default content with slot properties. The memoization strategy optimizes performance by preventing unnecessary re-renders, while error handling provides graceful degradation and clear feedback during development.

For framework developers working on XMLUI core, understanding the slot transposition mechanism, parent render context flow, and scope management is essential for maintaining and extending the user-defined component infrastructure.

```
Page 99/141FirstPrevNextLast