This is page 181 of 186. Use http://codebase.md/xmlui-org/xmlui/assets/img/%7BlogoUrl%7D?format=md&lines=true&page={x} to view the full context.

# Directory Structure

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

# Files

--------------------------------------------------------------------------------
/xmlui/conventions/create-xmlui-components.md:
--------------------------------------------------------------------------------

```markdown
   1 | # Creating XMLUI Components
   2 | 
   3 | This document outlines the conventions, patterns, and best practices for creating new XMLUI components.
   4 | 
   5 | ## Table of Contents
   6 | 
   7 | 1. [Component Structure](#component-structure)
   8 | 2. [Component Metadata](#component-metadata)
   9 | 3. [Component Parts Pattern](#component-parts-pattern)
  10 | 4. [Component Renderers](#component-renderers)
  11 | 5. [Theme and Styling](#theme-and-styling)
  12 | 6. [Component Implementation](#component-implementation)
  13 | 7. [Testing](#testing)
  14 | 8. [Component Implementation Patterns](#component-implementation-patterns)
  15 | 9. [Default Values Pattern](#default-values-pattern)
  16 | 10. [ForwardRef Pattern](#forwardref-pattern)
  17 | 11. [State Management Patterns](#state-management-patterns)
  18 | 12. [Event Handling Patterns](#event-handling-patterns)
  19 | 13. [API Registration and Programmatic Control Patterns](#api-registration-and-programmatic-control-patterns)
  20 | 14. [XMLUI Renderer Patterns](#xmlui-renderer-patterns)
  21 | 15. [Performance Patterns](#performance-patterns)
  22 | 
  23 | ## Component Structure
  24 | 
  25 | XMLUI components are built from four crucial concepts:
  26 | 
  27 | 1. **Native React Component**: The actual UI implementation using standard React patterns
  28 | 2. **Metadata**: Complete API description including props, events, APIs, and theme variables
  29 | 3. **Renderer Function**: Maps XMLUI markup to React component calls
  30 | 4. **Component Registration**: Makes the component available in XMLUI markup
  31 | 
  32 | ### Core Component Concepts
  33 | 
  34 | XMLUI components expose several key concepts that enable rich interactivity:
  35 | 
  36 | - **Properties**: Configuration values passed to components (e.g., `size`, `variant`, `disabled`)
  37 | - **Events**: User interactions that components can emit (e.g., `click`, `change`, `focus`)
  38 | - **Event Handlers**: Functions that respond to events, often updating application state
  39 | - **Exposed Methods**: Programmatic APIs that allow parent components to control child behavior (e.g., `setValue()`, `focus()`)
  40 | - **Context Variables**: Data that components expose to their children, accessible via `$variableName` syntax
  41 | 
  42 | ### Component Creation Conventions
  43 | 
  44 | When creating new XMLUI components, follow these strict conventions:
  45 | 
  46 | **File Structure:**
  47 | - **Never create `index.ts` files** when creating components
  48 | - **Never create example files** to demonstrate the component
  49 | - **Only create end-to-end tests and documentation when explicitly requested**
  50 | - **Do not add the React component to the xmlui folder's package.json file**
  51 | 
  52 | **Focus on Core Functionality:**
  53 | - Prioritize the component's core functionality and API design
  54 | - Ensure proper XMLUI integration and registration
  55 | - Examples and comprehensive documentation are secondary concerns unless specifically requested
  56 | 
  57 | ### File Organization
  58 | 
  59 | Each component should have its own directory under `src/components/` with the following structure:
  60 | 
  61 | ```
  62 | ComponentName/
  63 | ├── ComponentName.tsx              # Component definition (required)
  64 | ├── ComponentNameNative.tsx        # Native implementation (dual-file pattern)
  65 | └── ComponentName.module.scss      # Component styles (optional)
  66 | ```
  67 | 
  68 | **Key files:**
  69 | - **Component definition**: Always named exactly like the component (e.g., `Avatar.tsx`)
  70 | - **Native file**: Appended with "Native" suffix (e.g., `AvatarNative.tsx`)
  71 | - **SCSS module**: Always follows `.module.scss` pattern for scoped styles
  72 | 
  73 | **Important conventions:**
  74 | - **Never create `index.ts` files** when creating components - components should be imported directly from their main files
  75 | - **Never create example files** to demonstrate the component - examples should be in documentation or playground only
  76 | - **Create end-to-end tests and documentation only when explicitly requested** - focus on core functionality first
  77 | 
  78 | ### Standard Dual-File Pattern
  79 | 
  80 | Most XMLUI components use a dual-file pattern that separates concerns:
  81 | 
  82 | - **Component Definition** (`ComponentName.tsx`)
  83 |   - Contains component metadata using `createMetadata`
  84 |   - Defines the renderer function with `createComponentRenderer`
  85 |   - Specifies theme variables and their defaults
  86 |   - Maps XMLUI props to native component props
  87 | 
  88 | - **Native Component** (`ComponentNameNative.tsx`)
  89 |   - Pure React implementation using `forwardRef`
  90 |   - Contains actual rendering logic and component behavior
  91 |   - Defines TypeScript interfaces for props
  92 |   - Exports `defaultProps` object
  93 | 
  94 | > **Note**: For very simple components, the native implementation can be included directly in the component definition file instead of creating a separate `*Native.tsx` file.
  95 | 
  96 | ### Component Registration
  97 | 
  98 | Components must be registered in `ComponentProvider.tsx` to be available in XMLUI markup:
  99 | 
 100 | ```typescript
 101 | // Import the component renderer
 102 | import { avatarComponentRenderer } from "./Avatar/Avatar";
 103 | 
 104 | // Register in ComponentProvider class  
 105 | this.registerCoreComponent(avatarComponentRenderer);
 106 | ```
 107 | 
 108 | ## Component Metadata
 109 | 
 110 | Component metadata is a **fundamental and critical concept** in XMLUI. It serves as the single source of truth that describes a component's complete API surface, including properties, events, exposed methods, context variables, and theme variables. This metadata is not just documentation—it's actively used by:
 111 | 
 112 | - **XMLUI Documentation System**: Auto-generates component documentation
 113 | - **VS Code Extension**: Provides IntelliSense, auto-completion, and validation
 114 | - **Type Checking**: Validates component usage at build time  
 115 | - **Developer Tools**: Powers debugging and inspection features
 116 | - **Code Generation**: Enables automated tooling and scaffolding
 117 | 
 118 | ### Metadata Structure
 119 | 
 120 | Component metadata is defined using the `createMetadata` helper. Some components are non-visual and do not render any UI - these use the `nonVisual` metadata property set to `true`.
 121 | 
 122 | Component metadata is defined using the `createMetadata` helper:
 123 | 
 124 | ```typescript
 125 | import { createMetadata, d, dClick } from "../metadata-helpers";
 126 | 
 127 | const COMP = "ComponentName";
 128 | 
 129 | export const ComponentNameMd = createMetadata({
 130 |   status: "stable" | "experimental" | "deprecated",
 131 |   description: "Brief description of the component and its purpose",
 132 |   
 133 |   props: {
 134 |     propName: {
 135 |       description: "What this prop does",
 136 |       type: "string" | "number" | "boolean",
 137 |       availableValues: optionsArray, // For enum-like props
 138 |       defaultValue: defaultProps.propName,
 139 |       isRequired: false,
 140 |     },
 141 |   },
 142 |   
 143 |   events: {
 144 |     onClick: dClick(COMP),
 145 |     onCustomEvent: d("Description of custom event"),
 146 |   },
 147 |   
 148 |   apis: {
 149 |     setValue: {
 150 |       description: "API method description",
 151 |       signature: "setValue(value: string): void",
 152 |     },
 153 |   },
 154 |   
 155 |   contextVars: {
 156 |     // Variables exposed to child components
 157 |   },
 158 |   
 159 |   themeVars: parseScssVar(styles.themeVars),
 160 |   defaultThemeVars: {
 161 |     [`property-${COMP}`]: "defaultValue",
 162 |   },
 163 | });
 164 | ```
 165 | 
 166 | ### Metadata Helper Functions
 167 | 
 168 | - `d(description, availableValues?, valueType?, defaultValue?, isValid?, isRequired?)` - General property descriptor
 169 | - `dClick(componentName)` - Standard click event descriptor
 170 | - `dGotFocus(componentName)` - Focus event descriptor
 171 | - `dLostFocus(componentName)` - Blur event descriptor
 172 | - `dInternal(description?)` - Internal-only property descriptor
 173 | 
 174 | ## Component Parts Pattern
 175 | 
 176 | The **parts pattern** is a metadata-driven approach that allows referencing and styling nested sub-components within complex XMLUI components. This pattern adds metadata to components that enables targeting specific parts for testing, styling, and layout applications.
 177 | 
 178 | ### Parts Metadata Structure
 179 | 
 180 | Components that use the parts pattern define a `parts` object in their metadata, where each part has a descriptive name and description:
 181 | 
 182 | ```typescript
 183 | export const ComponentNameMd = createMetadata({
 184 |   // ... other metadata
 185 |   parts: {
 186 |     label: {
 187 |       description: "The label displayed for the component.",
 188 |     },
 189 |     input: {
 190 |       description: "The main input area.",
 191 |     },
 192 |     startAdornment: {
 193 |       description: "The adornment displayed at the start of the component.",
 194 |     },
 195 |     endAdornment: {
 196 |       description: "The adornment displayed at the end of the component.",
 197 |     },
 198 |   },
 199 |   defaultPart: "input", // Optional: specifies which part receives layout properties by default
 200 |   // ... rest of metadata
 201 | });
 202 | ```
 203 | 
 204 | ### Part Implementation in Native Components
 205 | 
 206 | Parts are implemented in native components by applying CSS classes that mark specific DOM elements as parts. This is done using the `partClassName` function from the parts infrastructure:
 207 | 
 208 | ```typescript
 209 | import { partClassName, PART_INPUT, PART_START_ADORNMENT, PART_END_ADORNMENT } from "../../components-core/parts";
 210 | 
 211 | export const ComponentNative = forwardRef(function ComponentNative(props, ref) {
 212 |   return (
 213 |     <div className={styles.container}>
 214 |       {/* Start adornment part */}
 215 |       {startAdornment && (
 216 |         <div className={classnames(partClassName(PART_START_ADORNMENT), styles.adornment)}>
 217 |           {startAdornment}
 218 |         </div>
 219 |       )}
 220 |       
 221 |       {/* Main input part */}
 222 |       <input
 223 |         className={classnames(partClassName(PART_INPUT), styles.input)}
 224 |         {...inputProps}
 225 |       />
 226 |       
 227 |       {/* End adornment part */}
 228 |       {endAdornment && (
 229 |         <div className={classnames(partClassName(PART_END_ADORNMENT), styles.adornment)}>
 230 |           {endAdornment}
 231 |         </div>
 232 |       )}
 233 |     </div>
 234 |   );
 235 | });
 236 | ```
 237 | 
 238 | ### Standard Part Names
 239 | 
 240 | XMLUI defines common part constants for consistency across components:
 241 | 
 242 | - `PART_LABEL` - For component labels
 243 | - `PART_INPUT` - For main input areas
 244 | - `PART_START_ADORNMENT` - For decorative elements at the start
 245 | - `PART_END_ADORNMENT` - For decorative elements at the end
 246 | 
 247 | ### Component Examples Using Parts
 248 | 
 249 | #### TextBox Component Parts
 250 | ```typescript
 251 | parts: {
 252 |   label: { description: "The label displayed for the text box." },
 253 |   startAdornment: { description: "The adornment displayed at the start of the text box." },
 254 |   endAdornment: { description: "The adornment displayed at the end of the text box." },
 255 |   input: { description: "The text box input area." }
 256 | },
 257 | defaultPart: "input"
 258 | ```
 259 | 
 260 | #### TimeInput Component Parts
 261 | ```typescript
 262 | parts: {
 263 |   hour: { description: "The hour input field." },
 264 |   minute: { description: "The minute input field." },
 265 |   second: { description: "The second input field." },
 266 |   ampm: { description: "The AM/PM indicator." },
 267 |   clearButton: { description: "The button to clear the time input." }
 268 | }
 269 | ```
 270 | 
 271 | #### Checkbox Component Parts
 272 | ```typescript
 273 | parts: {
 274 |   label: { description: "The label displayed for the checkbox." },
 275 |   input: { description: "The checkbox input area." }
 276 | }
 277 | ```
 278 | 
 279 | ### Benefits of the Parts Pattern
 280 | 
 281 | 1. **Testing**: Parts provide stable selectors for automated testing by generating predictable CSS classes like `_PART_input_`
 282 | 2. **Styling**: Theme variables and CSS can target specific parts of complex components
 283 | 3. **Layout**: Layout properties can be applied to specific parts rather than the entire component
 284 | 4. **Documentation**: Auto-generated documentation includes part descriptions for better developer understanding
 285 | 5. **Consistency**: Standardized part names create consistent patterns across the component library
 286 | 
 287 | ### When to Use Parts
 288 | 
 289 | Use the parts pattern for components that:
 290 | - Have multiple distinct visual elements that users might want to style separately
 291 | - Contain input elements alongside labels, adornments, or other decorative elements
 292 | - Have complex internal structure that benefits from targeted styling or testing
 293 | - Need fine-grained control over layout application to sub-elements
 294 | 
 295 | Simple components with a single visual element typically don't need the parts pattern.
 296 | 
 297 | ## Component Renderers
 298 | 
 299 | Component renderers are functions that bridge XMLUI markup and React components. They receive a `RendererContext` object containing all necessary information to render the component and return a React element.
 300 | 
 301 | ### Renderer Context
 302 | 
 303 | The `RendererContext` provides these key properties for accessing component data and functionality:
 304 | 
 305 | - **`node`**: The component definition containing props, children, and metadata
 306 | - **`state`**: The current state of the container in which the component is rendered
 307 | - **`appContext`**: The application context for binding expressions and component usage
 308 | - **`renderChild`**: Renders child components with optional layout context
 309 | - **`layoutContext`**: Information about the layout context in which the component is rendered
 310 | - **`uid`**: Unique identifier for the component instance
 311 | - **`updateState`**: Updates component's internal state using reducer pattern
 312 | - **`extractValue`**: Extracts and evaluates property values (handles binding expressions)
 313 | - **`extractResourceUrl`**: Converts logical resource URLs to physical URLs
 314 | - **`lookupEventHandler`**: Creates event handler functions from XMLUI event definitions  
 315 | - **`lookupAction`**: Obtains async action handlers by name with specified options
 316 | - **`lookupSyncCallback`**: Retrieves synchronous callback functions
 317 | - **`layoutCss`**: Pre-computed CSS properties for layout (position, size, etc.)
 318 | - **`registerComponentApi`**: Registers component methods for programmatic access
 319 | 
 320 | ### Value Extraction Patterns
 321 | 
 322 | The `extractValue` function handles different data types with specialized methods:
 323 | 
 324 | ```typescript
 325 | // Basic extraction (any type)
 326 | const value = extractValue(node.props.someProperty);
 327 | 
 328 | // Typed extraction with defaults
 329 | const size = extractValue.asOptionalString(node.props.size, "medium");
 330 | const enabled = extractValue.asOptionalBoolean(node.props.enabled, true);
 331 | const count = extractValue.asOptionalNumber(node.props.count, 0);
 332 | 
 333 | // Display text (handles spacing properly)
 334 | const label = extractValue.asDisplayText(node.props.label);
 335 | 
 336 | // CSS size values (with units)
 337 | const width = extractValue.asSize(node.props.width);
 338 | ```
 339 | 
 340 | ### Event Handler Patterns
 341 | 
 342 | Event handlers are created through `lookupEventHandler` and connected to React component events:
 343 | 
 344 | ```typescript
 345 | // Simple event handlers
 346 | onClick={lookupEventHandler("click")}
 347 | onFocus={lookupEventHandler("gotFocus")}
 348 | onBlur={lookupEventHandler("lostFocus")}
 349 | 
 350 | // Custom events with specific payloads
 351 | onDidChange={lookupEventHandler("didChange")}
 352 | onSelectionChanged={lookupEventHandler("selectionDidChange")}
 353 | ```
 354 | 
 355 | ### Renderer Examples
 356 | 
 357 | #### Complex Component Renderer with Children
 358 | ```typescript
 359 | export const buttonComponentRenderer = createComponentRenderer(
 360 |   "Button",
 361 |   ButtonMd,
 362 |   ({ node, extractValue, renderChild, lookupEventHandler, layoutCss }) => {
 363 |     const iconName = extractValue.asString(node.props.icon);
 364 |     const label = extractValue.asDisplayText(node.props.label);
 365 |     
 366 |     return (
 367 |       <Button
 368 |         variant={extractValue.asOptionalString(node.props.variant)}
 369 |         disabled={!extractValue.asOptionalBoolean(node.props.enabled, true)}
 370 |         icon={iconName && <Icon name={iconName} aria-hidden />}
 371 |         onClick={lookupEventHandler("click")}
 372 |         onFocus={lookupEventHandler("gotFocus")}
 373 |         style={layoutCss}
 374 |       >
 375 |         {renderChild(node.children, { type: "Stack", orientation: "horizontal" }) || label}
 376 |       </Button>
 377 |     );
 378 |   },
 379 | );
 380 | ```
 381 | 
 382 | #### Component with State and API Registration
 383 | ```typescript
 384 | export const colorPickerComponentRenderer = createComponentRenderer(
 385 |   "ColorPicker", 
 386 |   ColorPickerMd,
 387 |   ({ node, extractValue, state, updateState, registerComponentApi, lookupEventHandler, layoutCss }) => {
 388 |     return (
 389 |       <ColorPicker
 390 |         value={state.value}
 391 |         initialValue={extractValue(node.props.initialValue)}
 392 |         updateState={updateState}
 393 |         registerComponentApi={registerComponentApi}
 394 |         onDidChange={lookupEventHandler("didChange")}
 395 |         style={layoutCss}
 396 |         enabled={extractValue.asOptionalBoolean(node.props.enabled, true)}
 397 |       />
 398 |     );
 399 |   },
 400 | );
 401 | ```
 402 | 
 403 | ## Theme and Styling
 404 | 
 405 | Non-visual components do not use styling or theme variables.
 406 | 
 407 | Each visual component requires a SCSS module file with this structure:
 408 | 
 409 | ```scss
 410 | // ComponentName.module.scss
 411 | @use "../../components-core/theming/themes" as t;
 412 | 
 413 | // --- This code snippet is required to collect the theme variables used in this module
 414 | $themeVars: ();
 415 | @function createThemeVar($componentVariable) {
 416 |   $themeVars: t.appendThemeVar($themeVars, $componentVariable) !global;
 417 |   @return t.getThemeVar($themeVars, $componentVariable);
 418 | }
 419 | 
 420 | // Define theme variables
 421 | $backgroundColor-ComponentName: createThemeVar("backgroundColor-ComponentName");
 422 | $borderColor-ComponentName: createThemeVar("borderColor-ComponentName");
 423 | $textColor-ComponentName: createThemeVar("textColor-ComponentName");
 424 | 
 425 | // --- This part defines the CSS styles
 426 | .componentName {
 427 |   background-color: $backgroundColor-ComponentName;
 428 |   border-color: $borderColor-ComponentName;
 429 |   color: $textColor-ComponentName;
 430 |   
 431 |   // Component-specific styles
 432 |   
 433 |   &.variantClass {
 434 |     // Variant styles
 435 |   }
 436 | }
 437 | 
 438 | // --- We export the theme variables to add them to the component renderer
 439 | :export{
 440 |   themeVars: t.json-stringify($themeVars)
 441 | }
 442 | ```
 443 | 
 444 | This structure is important because it helps collect all theme variables a particular component supports for documentation purposes. The pattern uses the `createThemeVar()` function to define theme variables that can be customized through the design system, then uses those variables in CSS styles, and finally exports them for the component renderer.
 445 | 
 446 | ## Component Implementation
 447 | 
 448 | Follow this implementation flow for creating new XMLUI components:
 449 | 
 450 | 1. **Create the component metadata** - This information helps understand the component design and facilitates discussion
 451 | 2. **Create the renderer function and export it** - Use the native component and pass XMLUI component properties and events to it (the code won't build yet as no native component exists)
 452 | 3. **Create a rudimentary version of the native component** - Make the code compile with basic functionality
 453 | 4. **Add component registration** - At this point you can test the rudimentary component in XMLUI markup
 454 | 5. **Implement the native component in full** - Add complete functionality, styling, and behavior
 455 | 
 456 | **Note**: End-to-end tests and comprehensive documentation should only be created when explicitly requested. Focus on core functionality first.
 457 | 
 458 | ### Native Component Structure
 459 | 
 460 | Native components must follow these patterns:
 461 | 
 462 | ```typescript
 463 | import React, { forwardRef, useRef, useEffect } from "react";
 464 | import classnames from "classnames";
 465 | import styles from "./ComponentName.module.scss";
 466 | 
 467 | // Define props interface
 468 | type Props = {
 469 |   id?: string;
 470 |   // Component-specific props
 471 |   children?: React.ReactNode;
 472 |   style?: CSSProperties;
 473 |   // Event handlers
 474 |   onClick?: (event: React.MouseEvent) => void;
 475 |   // Accessibility props
 476 | } & React.HTMLAttributes<HTMLElement>;
 477 | 
 478 | // Define default props
 479 | export const defaultProps: Required<Pick<Props, "prop1" | "prop2">> = {
 480 |   prop1: "defaultValue",
 481 |   prop2: "anotherDefault",
 482 | };
 483 | 
 484 | // Component implementation with forwardRef
 485 | export const ComponentName = forwardRef(function ComponentName(
 486 |   {
 487 |     prop1 = defaultProps.prop1,
 488 |     prop2 = defaultProps.prop2,
 489 |     children,
 490 |     style,
 491 |     onClick,
 492 |     ...rest
 493 |   }: Props,
 494 |   ref: React.ForwardedRef<HTMLElement>,
 495 | ) {
 496 |   const innerRef = useRef<HTMLElement>(null);
 497 |   
 498 |   // Compose refs if needed
 499 |   const composedRef = ref ? composeRefs(ref, innerRef) : innerRef;
 500 |   
 501 |   // Component logic here
 502 |   
 503 |   return (
 504 |     <div
 505 |       ref={composedRef}
 506 |       className={classnames(styles.componentName, {
 507 |         [styles.variantClass]: condition,
 508 |       })}
 509 |       style={style}
 510 |       onClick={onClick}
 511 |       {...rest}
 512 |     >
 513 |       {children}
 514 |     </div>
 515 |   );
 516 | });
 517 | 
 518 | // Note: We do NOT use displayName in XMLUI components
 519 | // React.displayName is not used in our component convention
 520 | ```
 521 | 
 522 | **Key patterns**: Always use `forwardRef`, define clear TypeScript interfaces, provide sensible defaults via `defaultProps`, use scoped CSS modules, support standard HTML attributes, handle accessibility through proper ARIA attributes, and do **not** set `displayName` on components.
 523 | 
 524 | ## Testing
 525 | 
 526 | Component testing follows established patterns and conventions detailed in [testing-conventions.md](./testing-conventions.md). This includes component driver patterns, test structure, and best practices for ensuring component reliability and functionality.
 527 | 
 528 | ---
 529 | 
 530 | ## Component Implementation Patterns
 531 | 
 532 | *Note: This is a temporary list for detailed expansion later*
 533 | 
 534 | ### XMLUI Component Patterns
 535 | 
 536 | **Specialized Component Patterns:**
 537 | - Form components: Integration with FormContext, validation handling
 538 | - Data-driven components: List virtualization, table column management
 539 | - Interactive components: Complex state management, event propagation
 540 | - Container components: Layout management, child component orchestration
 541 | 
 542 | ### React Native Component Patterns
 543 | 
 544 | **Accessibility Patterns:**
 545 | - ARIA attribute management
 546 | - Focus management and trap patterns
 547 | - Screen reader optimization
 548 | - High contrast and reduced motion support
 549 | 
 550 | ---
 551 | 
 552 | ## Default Values Pattern
 553 | 
 554 | **Purpose**: Components need consistent, predictable default behavior while allowing customization. This pattern solves the problem of ensuring components work correctly when properties are omitted, reducing the need for consumers to specify every property explicitly.
 555 | 
 556 | **Implementation Pattern**:
 557 | 
 558 | 1. **Define defaults object in Native component**:
 559 | ```typescript
 560 | // In ComponentNative.tsx
 561 | export const defaultProps = {
 562 |   enabled: true,
 563 |   variant: "primary" as const,
 564 |   size: "md" as const,
 565 |   showIcon: false,
 566 |   // ... other defaults
 567 | };
 568 | ```
 569 | 
 570 | 2. **Apply defaults in Native component implementation**:
 571 | ```typescript
 572 | interface Props {
 573 |   enabled?: boolean;
 574 |   variant?: "primary" | "secondary" | "danger";
 575 |   size?: "sm" | "md" | "lg";
 576 |   showIcon?: boolean;
 577 | }
 578 | 
 579 | export const ComponentNative = ({
 580 |   enabled = defaultProps.enabled,
 581 |   variant = defaultProps.variant,
 582 |   size = defaultProps.size,
 583 |   showIcon = defaultProps.showIcon,
 584 |   ...rest
 585 | }: Props) => {
 586 |   // Component implementation uses the resolved defaults
 587 |   return (
 588 |     <div
 589 |       className={classnames(styles.component, {
 590 |         [styles.disabled]: !enabled,
 591 |         [styles[variant]]: variant,
 592 |         [styles[size]]: size,
 593 |       })}
 594 |       {...rest}
 595 |     />
 596 |   );
 597 | };
 598 | ```
 599 | 
 600 | 3. **Reference defaults in XMLUI metadata**:
 601 | ```typescript
 602 | export const ComponentMd = createMetadata({
 603 |   props: {
 604 |     enabled: dEnabled(defaultProps.enabled),
 605 |     variant: {
 606 |       description: "Visual style variant",
 607 |       availableValues: ["primary", "secondary", "danger"],
 608 |       defaultValue: defaultProps.variant,
 609 |       valueType: "string",
 610 |     },
 611 |     // ... other props with defaults
 612 |   },
 613 | });
 614 | ```
 615 | 
 616 | 4. **Pass values directly in renderer (no fallbacks needed)**:
 617 | ```typescript
 618 | export const componentRenderer = createComponentRenderer(
 619 |   COMP,
 620 |   ComponentMd,
 621 |   ({ node, extractValue }) => {
 622 |     return (
 623 |       <ComponentNative
 624 |         enabled={extractValue.asOptionalBoolean(node.props.enabled)}
 625 |         variant={extractValue(node.props.variant)}
 626 |         size={extractValue(node.props.size)}
 627 |         // Native component handles undefined values with its own defaults
 628 |       />
 629 |     );
 630 |   },
 631 | );
 632 | ```
 633 | 
 634 | **Key Benefits**:
 635 | - Consistent behavior across all components
 636 | - Native components work correctly when used directly by other XMLUI components
 637 | - Single source of truth for default values
 638 | - Eliminates duplication between renderer and native component
 639 | - Supports both XMLUI and direct React usage patterns seamlessly
 640 | 
 641 | ## ForwardRef Pattern
 642 | 
 643 | **Purpose**: React components need to expose DOM element references to parent components for imperative operations like focusing, scrolling, or measuring. The forwardRef pattern solves the problem of ref forwarding through component boundaries, enabling parent components to directly interact with child DOM elements and supporting imperative APIs.
 644 | 
 645 | **React API Overview**:
 646 | - **`forwardRef`**: A React function that enables a component to receive a `ref` from its parent and forward it to a child element or expose custom APIs
 647 | 
 648 | > **⚠️ Important - useImperativeHandle Antipattern**: The XMLUI team has determined that `useImperativeHandle` is an antipattern and **should NOT be used** in XMLUI components. All instances have been removed from the codebase. Instead, imperative APIs should be exposed through the XMLUI `registerComponentApi` mechanism, which provides better framework integration and more predictable behavior.
 649 | 
 650 | **Implementation Pattern**:
 651 | 
 652 | 1. **Basic forwardRef structure with typed ref**:
 653 | ```typescript
 654 | import React, { forwardRef } from "react";
 655 | 
 656 | interface Props {
 657 |   children?: React.ReactNode;
 658 |   className?: string;
 659 |   // ... other props
 660 | }
 661 | 
 662 | export const ComponentNative = forwardRef<HTMLDivElement, Props>(
 663 |   function ComponentNative({ children, className, ...rest }, ref) {
 664 |     return (
 665 |       <div ref={ref} className={className} {...rest}>
 666 |         {children}
 667 |       </div>
 668 |     );
 669 |   }
 670 | );
 671 | ```
 672 | 
 673 | 2. **ForwardRef with internal ref composition**:
 674 | ```typescript
 675 | import React, { forwardRef, useRef } from "react";
 676 | import { composeRefs } from "../../utils/ref-utils";
 677 | 
 678 | export const ComponentNative = forwardRef<HTMLDivElement, Props>(
 679 |   function ComponentNative({ children, ...rest }, ref) {
 680 |     const internalRef = useRef<HTMLDivElement>(null);
 681 |     const composedRef = composeRefs(ref, internalRef);
 682 |     
 683 |     // Use internalRef for component logic
 684 |     const handleClick = () => {
 685 |       internalRef.current?.focus();
 686 |     };
 687 |     
 688 |     return (
 689 |       <div ref={composedRef} onClick={handleClick} {...rest}>
 690 |         {children}
 691 |       </div>
 692 |     );
 693 |   }
 694 | );
 695 | ```
 696 | 
 697 | 3. **ForwardRef with imperative API exposure via registerComponentApi** (recommended pattern):
 698 | ```typescript
 699 | import React, { forwardRef, useRef, useState, useEffect } from "react";
 700 | 
 701 | interface Props {
 702 |   initialValue?: string;
 703 |   registerComponentApi?: (api: any) => void;
 704 |   updateState?: (state: any) => void;
 705 |   onDidChange?: () => void;
 706 | }
 707 | 
 708 | export const ComponentNative = forwardRef<HTMLInputElement, Props>(
 709 |   function ComponentNative({ initialValue, registerComponentApi, updateState, onDidChange, ...rest }, ref) {
 710 |     const elementRef = useRef<HTMLInputElement>(null);
 711 |     const [value, setValue] = useState(initialValue || "");
 712 |     
 713 |     // Compose refs to expose both DOM element and internal ref
 714 |     const composedRef = composeRefs(ref, elementRef);
 715 |     
 716 |     // Register imperative API using XMLUI's registerComponentApi pattern
 717 |     useEffect(() => {
 718 |       if (registerComponentApi) {
 719 |         registerComponentApi({
 720 |           focus: () => elementRef.current?.focus(),
 721 |           blur: () => elementRef.current?.blur(),
 722 |           scrollIntoView: () => elementRef.current?.scrollIntoView(),
 723 |           getValue: () => value,
 724 |           setValue: (newValue: string) => {
 725 |             setValue(newValue);
 726 |             updateState?.({ value: newValue });
 727 |             onDidChange?.();
 728 |           },
 729 |         });
 730 |       }
 731 |     }, [registerComponentApi, value, updateState, onDidChange]);
 732 |     
 733 |     return (
 734 |       <input
 735 |         ref={composedRef}
 736 |         value={value}
 737 |         onChange={(e) => {
 738 |           setValue(e.target.value);
 739 |           updateState?.({ value: e.target.value });
 740 |           onDidChange?.();
 741 |         }}
 742 |         {...rest}
 743 |       />
 744 |     );
 745 |   }
 746 | );
 747 | ```
 748 | 
 749 | 4. **Registration in XMLUI renderer with API exposure**:
 750 | ```typescript
 751 | export const componentRenderer = createComponentRenderer(
 752 |   COMP,
 753 |   ComponentMd,
 754 |   ({ node, extractValue, registerComponentApi, updateState, lookupEventHandler }) => {
 755 |     return (
 756 |       <ComponentNative
 757 |         initialValue={extractValue(node.props.initialValue)}
 758 |         registerComponentApi={registerComponentApi}
 759 |         updateState={updateState}
 760 |         onDidChange={lookupEventHandler("didChange")}
 761 |       />
 762 |     );
 763 |   },
 764 | );
 765 | ```
 766 | 
 767 | **Key Benefits**:
 768 | - Enables parent components to access child DOM elements directly
 769 | - Supports imperative APIs for programmatic component control through `registerComponentApi`
 770 | - Maintains clean separation between declarative props and imperative methods
 771 | - Allows XMLUI components to expose methods callable from event handlers
 772 | - Facilitates complex component interactions (focus management, animations, measurements)
 773 | - Essential for form components that need validation and value access
 774 | - Provides better framework integration compared to `useImperativeHandle` antipattern
 775 | 
 776 | ## State Management Patterns
 777 | 
 778 | **Purpose**: React components need different approaches to manage state depending on their complexity, interaction patterns, and integration requirements. These patterns solve various state-related challenges from simple local state to complex cross-component communication and XMLUI framework integration.
 779 | 
 780 | **React Hooks Overview**:
 781 | - **`useState`**: Manages component-local state with getter/setter pattern
 782 | - **`useRef`**: Creates mutable references that persist across renders without causing re-renders
 783 | - **`useMemo`**: Memoizes expensive calculations to prevent unnecessary recomputation
 784 | - **`useCallback`**: Memoizes functions to prevent unnecessary re-creation and child re-renders
 785 | - **`useEffect`**: Handles side effects, subscriptions, and cleanup operations
 786 | 
 787 | ### Controlled vs Uncontrolled Component Pattern
 788 | 
 789 | **Purpose**: Components need to handle user input and data flow in predictable ways, either allowing parent components to control the state (controlled) or managing it internally (uncontrolled).
 790 | 
 791 | **Implementation Pattern**:
 792 | 
 793 | ```typescript
 794 | // Uncontrolled component - manages its own state
 795 | export const UncontrolledComponent = ({ defaultValue, onChange }: Props) => {
 796 |   const [value, setValue] = useState(defaultValue || "");
 797 |   
 798 |   const handleChange = (newValue: string) => {
 799 |     setValue(newValue);
 800 |     onChange?.(newValue); // Notify parent but don't depend on it
 801 |   };
 802 |   
 803 |   return <input value={value} onChange={(e) => handleChange(e.target.value)} />;
 804 | };
 805 | 
 806 | // Controlled component - parent controls the state
 807 | export const ControlledComponent = ({ value, onChange }: Props) => {
 808 |   // No internal state - everything comes from props
 809 |   const handleChange = (newValue: string) => {
 810 |     onChange?.(newValue); // Parent must handle this
 811 |   };
 812 |   
 813 |   return <input value={value} onChange={(e) => handleChange(e.target.value)} />;
 814 | };
 815 | 
 816 | // Hybrid approach - supports both patterns
 817 | export const FlexibleComponent = ({ value, defaultValue, onChange }: Props) => {
 818 |   const [internalValue, setInternalValue] = useState(defaultValue || "");
 819 |   const isControlled = value !== undefined;
 820 |   const effectiveValue = isControlled ? value : internalValue;
 821 |   
 822 |   const handleChange = (newValue: string) => {
 823 |     if (!isControlled) {
 824 |       setInternalValue(newValue);
 825 |     }
 826 |     onChange?.(newValue);
 827 |   };
 828 |   
 829 |   return <input value={effectiveValue} onChange={(e) => handleChange(e.target.value)} />;
 830 | };
 831 | ```
 832 | 
 833 | ### Internal State with External Synchronization Pattern
 834 | 
 835 | **Purpose**: Components need to maintain internal state while staying synchronized with external data sources or parent component changes.
 836 | 
 837 | **Implementation Pattern**:
 838 | 
 839 | ```typescript
 840 | export const SynchronizedComponent = ({ externalValue, onValueChange }: Props) => {
 841 |   const [internalState, setInternalState] = useState({
 842 |     value: externalValue || "",
 843 |     isDirty: false,
 844 |     lastSyncedValue: externalValue || "",
 845 |   });
 846 |   
 847 |   // Sync with external changes
 848 |   useEffect(() => {
 849 |     if (externalValue !== internalState.lastSyncedValue) {
 850 |       setInternalState(prev => ({
 851 |         ...prev,
 852 |         value: externalValue || "",
 853 |         lastSyncedValue: externalValue || "",
 854 |         isDirty: false,
 855 |       }));
 856 |     }
 857 |   }, [externalValue, internalState.lastSyncedValue]);
 858 |   
 859 |   const handleInternalChange = (newValue: string) => {
 860 |     setInternalState(prev => ({
 861 |       ...prev,
 862 |       value: newValue,
 863 |       isDirty: newValue !== prev.lastSyncedValue,
 864 |     }));
 865 |     
 866 |     // Debounced external notification
 867 |     onValueChange?.(newValue);
 868 |   };
 869 |   
 870 |   return (
 871 |     <div>
 872 |       <input 
 873 |         value={internalState.value} 
 874 |         onChange={(e) => handleInternalChange(e.target.value)} 
 875 |       />
 876 |       {internalState.isDirty && <span>*</span>}
 877 |     </div>
 878 |   );
 879 | };
 880 | ```
 881 | 
 882 | ### Context Consumption for Shared State Pattern
 883 | 
 884 | **Purpose**: Components need access to shared state across component trees without prop drilling, such as themes, user authentication, or application-wide settings.
 885 | 
 886 | **Implementation Pattern**:
 887 | 
 888 | ```typescript
 889 | // Theme context example
 890 | const ThemeContext = createContext<{
 891 |   theme: 'light' | 'dark';
 892 |   toggleTheme: () => void;
 893 | }>({
 894 |   theme: 'light',
 895 |   toggleTheme: () => {},
 896 | });
 897 | 
 898 | export const ThemeProvider = ({ children }: { children: ReactNode }) => {
 899 |   const [theme, setTheme] = useState<'light' | 'dark'>('light');
 900 |   
 901 |   const toggleTheme = useCallback(() => {
 902 |     setTheme(prev => prev === 'light' ? 'dark' : 'light');
 903 |   }, []);
 904 |   
 905 |   const value = useMemo(() => ({ theme, toggleTheme }), [theme, toggleTheme]);
 906 |   
 907 |   return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
 908 | };
 909 | 
 910 | // Component consuming theme context
 911 | export const ThemedComponent = ({ children }: Props) => {
 912 |   const { theme, toggleTheme } = useContext(ThemeContext);
 913 |   
 914 |   return (
 915 |     <div className={`theme-${theme}`}>
 916 |       {children}
 917 |       <button onClick={toggleTheme}>Toggle Theme</button>
 918 |     </div>
 919 |   );
 920 | };
 921 | 
 922 | // Form context example for shared form state
 923 | const FormContext = createContext<{
 924 |   formData: Record<string, any>;
 925 |   updateField: (field: string, value: any) => void;
 926 |   errors: Record<string, string>;
 927 | }>({
 928 |   formData: {},
 929 |   updateField: () => {},
 930 |   errors: {},
 931 | });
 932 | 
 933 | export const FormFieldComponent = ({ fieldName }: { fieldName: string }) => {
 934 |   const { formData, updateField, errors } = useContext(FormContext);
 935 |   
 936 |   return (
 937 |     <div>
 938 |       <input
 939 |         value={formData[fieldName] || ''}
 940 |         onChange={(e) => updateField(fieldName, e.target.value)}
 941 |       />
 942 |       {errors[fieldName] && <span className="error">{errors[fieldName]}</span>}
 943 |     </div>
 944 |   );
 945 | };
 946 | ```
 947 | 
 948 | ### Effect Hooks for Side Effects and Cleanup Pattern
 949 | 
 950 | **Purpose**: Components need to handle side effects like data fetching, subscriptions, timers, and external API interactions while ensuring proper cleanup to prevent memory leaks.
 951 | 
 952 | **Implementation Pattern**:
 953 | 
 954 | ```typescript
 955 | export const EffectfulComponent = ({ url, pollingInterval }: Props) => {
 956 |   const [data, setData] = useState(null);
 957 |   const [loading, setLoading] = useState(false);
 958 |   const [error, setError] = useState(null);
 959 |   
 960 |   // Data fetching effect
 961 |   useEffect(() => {
 962 |     let isCancelled = false;
 963 |     
 964 |     const fetchData = async () => {
 965 |       setLoading(true);
 966 |       setError(null);
 967 |       
 968 |       try {
 969 |         const response = await fetch(url);
 970 |         const result = await response.json();
 971 |         
 972 |         if (!isCancelled) {
 973 |           setData(result);
 974 |         }
 975 |       } catch (err) {
 976 |         if (!isCancelled) {
 977 |           setError(err.message);
 978 |         }
 979 |       } finally {
 980 |         if (!isCancelled) {
 981 |           setLoading(false);
 982 |         }
 983 |       }
 984 |     };
 985 |     
 986 |     fetchData();
 987 |     
 988 |     // Cleanup function
 989 |     return () => {
 990 |       isCancelled = true;
 991 |     };
 992 |   }, [url]);
 993 |   
 994 |   // Polling effect with cleanup
 995 |   useEffect(() => {
 996 |     if (!pollingInterval) return;
 997 |     
 998 |     const interval = setInterval(() => {
 999 |       // Refetch data
1000 |       fetch(url)
1001 |         .then(res => res.json())
1002 |         .then(setData)
1003 |         .catch(setError);
1004 |     }, pollingInterval);
1005 |     
1006 |     return () => clearInterval(interval);
1007 |   }, [url, pollingInterval]);
1008 |   
1009 |   // Event listener effect
1010 |   useEffect(() => {
1011 |     const handleVisibilityChange = () => {
1012 |       if (document.visibilityState === 'visible') {
1013 |         // Refetch when tab becomes visible
1014 |         setData(null);
1015 |       }
1016 |     };
1017 |     
1018 |     document.addEventListener('visibilitychange', handleVisibilityChange);
1019 |     
1020 |     return () => {
1021 |       document.removeEventListener('visibilitychange', handleVisibilityChange);
1022 |     };
1023 |   }, []);
1024 |   
1025 |   if (loading) return <div>Loading...</div>;
1026 |   if (error) return <div>Error: {error}</div>;
1027 |   return <div>{JSON.stringify(data)}</div>;
1028 | };
1029 | ```
1030 | 
1031 | ### XMLUI State Management using updateState/state Reducer Pattern
1032 | 
1033 | **Purpose**: XMLUI components need to integrate with the framework's container-based state management system, enabling complex state sharing across component hierarchies and integration with XMLUI's binding expressions and event system.
1034 | 
1035 | **Implementation Pattern**:
1036 | 
1037 | ```typescript
1038 | // XMLUI component renderer using updateState/state pattern
1039 | export const xmluiInputComponentRenderer = createComponentRenderer(
1040 |   COMP,
1041 |   ComponentMd,
1042 |   ({ node, state, updateState, extractValue, lookupEventHandler, registerComponentApi }) => {
1043 |     // State is managed by XMLUI's container system
1044 |     const currentValue = state.value || extractValue(node.props.initialValue);
1045 |     
1046 |     return (
1047 |       <InputNative
1048 |         value={currentValue}
1049 |         updateState={updateState} // Pass XMLUI's state updater
1050 |         initialValue={extractValue(node.props.initialValue)}
1051 |         onDidChange={lookupEventHandler("didChange")}
1052 |         registerComponentApi={registerComponentApi}
1053 |         placeholder={extractValue(node.props.placeholder)}
1054 |       />
1055 |     );
1056 |   },
1057 | );
1058 | 
1059 | // Native component using XMLUI state management
1060 | export const InputNative = ({ 
1061 |   value, 
1062 |   updateState, 
1063 |   initialValue, 
1064 |   onDidChange,
1065 |   registerComponentApi 
1066 | }: Props) => {
1067 |   const [localValue, setLocalValue] = useState(value || initialValue || "");
1068 |   
1069 |   // Sync with XMLUI state changes
1070 |   useEffect(() => {
1071 |     if (value !== undefined && value !== localValue) {
1072 |       setLocalValue(value);
1073 |     }
1074 |   }, [value, localValue]);
1075 |   
1076 |   const handleChange = useCallback((newValue: string) => {
1077 |     setLocalValue(newValue);
1078 |     
1079 |     // Update XMLUI container state through reducer pattern
1080 |     updateState({ value: newValue });
1081 |     
1082 |     // Trigger XMLUI event handlers
1083 |     onDidChange?.();
1084 |   }, [updateState, onDidChange]);
1085 |   
1086 |   // Register imperative API with XMLUI
1087 |   useEffect(() => {
1088 |     registerComponentApi({
1089 |       setValue: (newValue: string) => {
1090 |         setLocalValue(newValue);
1091 |         updateState({ value: newValue });
1092 |       },
1093 |       getValue: () => localValue,
1094 |       focus: () => {
1095 |         // Focus implementation
1096 |       },
1097 |     });
1098 |   }, [registerComponentApi, localValue, updateState]);
1099 |   
1100 |   return (
1101 |     <input
1102 |       value={localValue}
1103 |       onChange={(e) => handleChange(e.target.value)}
1104 |     />
1105 |   );
1106 | };
1107 | 
1108 | // Complex state update patterns
1109 | export const ComplexStateComponent = ({ state, updateState }: Props) => {
1110 |   const handleComplexUpdate = () => {
1111 |     // Update multiple state properties atomically
1112 |     updateState({
1113 |       currentPage: 1,
1114 |       filters: { category: 'electronics', minPrice: 100 },
1115 |       sortBy: 'price',
1116 |       lastUpdated: Date.now(),
1117 |     });
1118 |   };
1119 |   
1120 |   const handleNestedUpdate = () => {
1121 |     // Update nested state properties
1122 |     updateState({
1123 |       'user.preferences.theme': 'dark',
1124 |       'user.preferences.notifications': true,
1125 |     });
1126 |   };
1127 |   
1128 |   return (
1129 |     <div>
1130 |       <button onClick={handleComplexUpdate}>Update Multiple Fields</button>
1131 |       <button onClick={handleNestedUpdate}>Update Nested Fields</button>
1132 |     </div>
1133 |   );
1134 | };
1135 | ```
1136 | 
1137 | **Key Benefits of Each Pattern**:
1138 | - **Controlled/Uncontrolled**: Clear data flow, predictable behavior, flexible usage patterns
1139 | - **External Synchronization**: Maintains UI responsiveness while staying in sync with external data
1140 | - **Context Consumption**: Eliminates prop drilling, centralizes shared state, improves maintainability
1141 | - **Effect Hooks**: Proper lifecycle management, memory leak prevention, external system integration
1142 | - **XMLUI State Management**: Framework integration, binding expression support, container hierarchy benefits, imperative API registration
1143 | 
1144 | ## Event Handling Patterns
1145 | 
1146 | **Purpose**: Components need robust, accessible, and performant event handling to respond to user interactions, manage complex input scenarios, and integrate with both React and XMLUI event systems. These patterns solve challenges around event propagation, accessibility, keyboard navigation, and framework integration.
1147 | 
1148 | ### Event Callback Prop Pattern
1149 | 
1150 | **Purpose**: Components need flexible event handling that supports optional callbacks while maintaining predictable behavior when handlers are not provided.
1151 | 
1152 | **Implementation Pattern**:
1153 | 
1154 | ```typescript
1155 | interface Props {
1156 |   onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
1157 |   onFocus?: (event: React.FocusEvent<HTMLButtonElement>) => void;
1158 |   onKeyDown?: (event: React.KeyboardEvent<HTMLButtonElement>) => void;
1159 |   onValueChange?: (value: string, event: React.ChangeEvent<HTMLInputElement>) => void;
1160 | }
1161 | 
1162 | export const EventHandlerComponent = ({
1163 |   onClick,
1164 |   onFocus,
1165 |   onKeyDown,
1166 |   onValueChange,
1167 |   children
1168 | }: Props) => {
1169 |   const [value, setValue] = useState("");
1170 | 
1171 |   const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
1172 |     // Internal logic
1173 |     console.log("Button clicked");
1174 |     
1175 |     // Call optional external handler
1176 |     onClick?.(event);
1177 |   };
1178 | 
1179 |   const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {
1180 |     // Handle specific keys internally
1181 |     if (event.key === 'Enter' || event.key === ' ') {
1182 |       event.preventDefault();
1183 |       handleClick(event as any);
1184 |     }
1185 |     
1186 |     // Call optional external handler
1187 |     onKeyDown?.(event);
1188 |   };
1189 | 
1190 |   const handleValueChange = (event: React.ChangeEvent<HTMLInputElement>) => {
1191 |     const newValue = event.target.value;
1192 |     setValue(newValue);
1193 |     
1194 |     // Pass both value and event to external handler
1195 |     onValueChange?.(newValue, event);
1196 |   };
1197 | 
1198 |   return (
1199 |     <div>
1200 |       <input
1201 |         value={value}
1202 |         onChange={handleValueChange}
1203 |         onFocus={onFocus}
1204 |       />
1205 |       <button
1206 |         onClick={handleClick}
1207 |         onKeyDown={handleKeyDown}
1208 |         onFocus={onFocus}
1209 |       >
1210 |         {children}
1211 |       </button>
1212 |     </div>
1213 |   );
1214 | };
1215 | ```
1216 | 
1217 | ### Event Object Creation and Propagation Pattern
1218 | 
1219 | **Purpose**: Components need to create custom event objects and control event propagation for complex interactions and framework integration.
1220 | 
1221 | **Implementation Pattern**:
1222 | 
1223 | ```typescript
1224 | // Custom event types
1225 | interface CustomChangeEvent {
1226 |   type: 'change';
1227 |   value: string;
1228 |   previousValue: string;
1229 |   isValid: boolean;
1230 |   timestamp: number;
1231 | }
1232 | 
1233 | interface CustomSelectionEvent {
1234 |   type: 'selection';
1235 |   selectedItems: string[];
1236 |   action: 'add' | 'remove' | 'clear';
1237 |   item?: string;
1238 | }
1239 | 
1240 | export const CustomEventComponent = ({
1241 |   onSelectionChange,
1242 |   onValidatedChange
1243 | }: {
1244 |   onSelectionChange?: (event: CustomSelectionEvent) => void;
1245 |   onValidatedChange?: (event: CustomChangeEvent) => void;
1246 | }) => {
1247 |   const [value, setValue] = useState("");
1248 |   const [selectedItems, setSelectedItems] = useState<string[]>([]);
1249 | 
1250 |   const createChangeEvent = (newValue: string, previousValue: string): CustomChangeEvent => ({
1251 |     type: 'change',
1252 |     value: newValue,
1253 |     previousValue,
1254 |     isValid: newValue.length >= 3,
1255 |     timestamp: Date.now(),
1256 |   });
1257 | 
1258 |   const handleValueChange = (newValue: string) => {
1259 |     const changeEvent = createChangeEvent(newValue, value);
1260 |     setValue(newValue);
1261 |     
1262 |     // Only trigger external handler if validation passes
1263 |     if (changeEvent.isValid) {
1264 |       onValidatedChange?.(changeEvent);
1265 |     }
1266 |   };
1267 | 
1268 |   const handleItemSelection = (item: string, action: 'add' | 'remove') => {
1269 |     let newSelection: string[];
1270 |     
1271 |     if (action === 'add') {
1272 |       newSelection = [...selectedItems, item];
1273 |     } else {
1274 |       newSelection = selectedItems.filter(i => i !== item);
1275 |     }
1276 |     
1277 |     setSelectedItems(newSelection);
1278 |     
1279 |     const selectionEvent: CustomSelectionEvent = {
1280 |       type: 'selection',
1281 |       selectedItems: newSelection,
1282 |       action,
1283 |       item,
1284 |     };
1285 |     
1286 |     onSelectionChange?.(selectionEvent);
1287 |   };
1288 | 
1289 |   return (
1290 |     <div>
1291 |       <input
1292 |         value={value}
1293 |         onChange={(e) => handleValueChange(e.target.value)}
1294 |         placeholder="Type at least 3 characters"
1295 |       />
1296 |       <div>
1297 |         {['apple', 'banana', 'cherry'].map(item => (
1298 |           <button
1299 |             key={item}
1300 |             onClick={() => handleItemSelection(
1301 |               item, 
1302 |               selectedItems.includes(item) ? 'remove' : 'add'
1303 |             )}
1304 |             className={selectedItems.includes(item) ? 'selected' : ''}
1305 |           >
1306 |             {item}
1307 |           </button>
1308 |         ))}
1309 |       </div>
1310 |     </div>
1311 |   );
1312 | };
1313 | ```
1314 | 
1315 | ### Keyboard Event Handling with Accessibility Pattern
1316 | 
1317 | **Purpose**: Components need comprehensive keyboard support for accessibility compliance and enhanced user experience, following ARIA patterns and keyboard navigation standards.
1318 | 
1319 | **Implementation Pattern**:
1320 | 
1321 | ```typescript
1322 | export const AccessibleComponent = ({
1323 |   items,
1324 |   onItemSelect,
1325 |   onEscape
1326 | }: {
1327 |   items: string[];
1328 |   onItemSelect?: (item: string) => void;
1329 |   onEscape?: () => void;
1330 | }) => {
1331 |   const [focusedIndex, setFocusedIndex] = useState(0);
1332 |   const [isOpen, setIsOpen] = useState(false);
1333 |   const listRef = useRef<HTMLUListElement>(null);
1334 |   const itemRefs = useRef<(HTMLLIElement | null)[]>([]);
1335 | 
1336 |   const handleKeyDown = (event: React.KeyboardEvent) => {
1337 |     switch (event.key) {
1338 |       case 'ArrowDown':
1339 |         event.preventDefault();
1340 |         setFocusedIndex(prev => 
1341 |           prev < items.length - 1 ? prev + 1 : 0
1342 |         );
1343 |         break;
1344 |         
1345 |       case 'ArrowUp':
1346 |         event.preventDefault();
1347 |         setFocusedIndex(prev => 
1348 |           prev > 0 ? prev - 1 : items.length - 1
1349 |         );
1350 |         break;
1351 |         
1352 |       case 'Enter':
1353 |       case ' ':
1354 |         event.preventDefault();
1355 |         if (isOpen && items[focusedIndex]) {
1356 |           onItemSelect?.(items[focusedIndex]);
1357 |           setIsOpen(false);
1358 |         } else {
1359 |           setIsOpen(true);
1360 |         }
1361 |         break;
1362 |         
1363 |       case 'Escape':
1364 |         event.preventDefault();
1365 |         setIsOpen(false);
1366 |         onEscape?.();
1367 |         break;
1368 |         
1369 |       case 'Home':
1370 |         event.preventDefault();
1371 |         setFocusedIndex(0);
1372 |         break;
1373 |         
1374 |       case 'End':
1375 |         event.preventDefault();
1376 |         setFocusedIndex(items.length - 1);
1377 |         break;
1378 |         
1379 |       case 'Tab':
1380 |         // Allow normal tab behavior
1381 |         setIsOpen(false);
1382 |         break;
1383 |         
1384 |       default:
1385 |         // Handle alphanumeric navigation
1386 |         if (event.key.length === 1) {
1387 |           const char = event.key.toLowerCase();
1388 |           const nextIndex = items.findIndex((item, index) => 
1389 |             index > focusedIndex && 
1390 |             item.toLowerCase().startsWith(char)
1391 |           );
1392 |           if (nextIndex !== -1) {
1393 |             setFocusedIndex(nextIndex);
1394 |           }
1395 |         }
1396 |         break;
1397 |     }
1398 |   };
1399 | 
1400 |   // Focus management
1401 |   useEffect(() => {
1402 |     if (isOpen && itemRefs.current[focusedIndex]) {
1403 |       itemRefs.current[focusedIndex]?.focus();
1404 |     }
1405 |   }, [focusedIndex, isOpen]);
1406 | 
1407 |   return (
1408 |     <div
1409 |       role="combobox"
1410 |       aria-expanded={isOpen}
1411 |       aria-haspopup="listbox"
1412 |       onKeyDown={handleKeyDown}
1413 |       tabIndex={0}
1414 |     >
1415 |       <button
1416 |         onClick={() => setIsOpen(!isOpen)}
1417 |         aria-label="Toggle dropdown"
1418 |       >
1419 |         Select Item
1420 |       </button>
1421 |       
1422 |       {isOpen && (
1423 |         <ul
1424 |           ref={listRef}
1425 |           role="listbox"
1426 |           aria-label="Available options"
1427 |         >
1428 |           {items.map((item, index) => (
1429 |             <li
1430 |               key={item}
1431 |               ref={el => itemRefs.current[index] = el}
1432 |               role="option"
1433 |               aria-selected={index === focusedIndex}
1434 |               tabIndex={-1}
1435 |               onClick={() => {
1436 |                 onItemSelect?.(item);
1437 |                 setIsOpen(false);
1438 |               }}
1439 |               onMouseEnter={() => setFocusedIndex(index)}
1440 |               className={index === focusedIndex ? 'focused' : ''}
1441 |             >
1442 |               {item}
1443 |             </li>
1444 |           ))}
1445 |         </ul>
1446 |       )}
1447 |     </div>
1448 |   );
1449 | };
1450 | ```
1451 | 
1452 | ### Mouse/Touch Interaction Pattern
1453 | 
1454 | **Purpose**: Components need to handle complex mouse and touch interactions including drag and drop, gestures, and multi-touch scenarios while maintaining performance.
1455 | 
1456 | **Implementation Pattern**:
1457 | 
1458 | ```typescript
1459 | export const InteractiveComponent = ({
1460 |   onDragComplete,
1461 |   onTap,
1462 |   onLongPress
1463 | }: {
1464 |   onDragComplete?: (startPos: { x: number; y: number }, endPos: { x: number; y: number }) => void;
1465 |   onTap?: () => void;
1466 |   onLongPress?: () => void;
1467 | }) => {
1468 |   const [dragState, setDragState] = useState<{
1469 |     isDragging: boolean;
1470 |     startPos: { x: number; y: number } | null;
1471 |     currentPos: { x: number; y: number } | null;
1472 |   }>({
1473 |     isDragging: false,
1474 |     startPos: null,
1475 |     currentPos: null,
1476 |   });
1477 | 
1478 |   const longPressTimerRef = useRef<NodeJS.Timeout>();
1479 |   const tapStartTimeRef = useRef<number>(0);
1480 | 
1481 |   const handleMouseDown = (event: React.MouseEvent) => {
1482 |     const pos = { x: event.clientX, y: event.clientY };
1483 |     setDragState({
1484 |       isDragging: false,
1485 |       startPos: pos,
1486 |       currentPos: pos,
1487 |     });
1488 | 
1489 |     tapStartTimeRef.current = Date.now();
1490 | 
1491 |     // Start long press timer
1492 |     longPressTimerRef.current = setTimeout(() => {
1493 |       onLongPress?.();
1494 |     }, 500);
1495 |   };
1496 | 
1497 |   const handleMouseMove = (event: React.MouseEvent) => {
1498 |     if (dragState.startPos) {
1499 |       const currentPos = { x: event.clientX, y: event.clientY };
1500 |       const distance = Math.sqrt(
1501 |         Math.pow(currentPos.x - dragState.startPos.x, 2) +
1502 |         Math.pow(currentPos.y - dragState.startPos.y, 2)
1503 |       );
1504 | 
1505 |       // Start dragging if moved more than 5 pixels
1506 |       if (distance > 5) {
1507 |         setDragState(prev => ({
1508 |           ...prev,
1509 |           isDragging: true,
1510 |           currentPos,
1511 |         }));
1512 | 
1513 |         // Cancel long press if dragging
1514 |         if (longPressTimerRef.current) {
1515 |           clearTimeout(longPressTimerRef.current);
1516 |         }
1517 |       }
1518 |     }
1519 |   };
1520 | 
1521 |   const handleMouseUp = (event: React.MouseEvent) => {
1522 |     const endPos = { x: event.clientX, y: event.clientY };
1523 | 
1524 |     // Clear long press timer
1525 |     if (longPressTimerRef.current) {
1526 |       clearTimeout(longPressTimerRef.current);
1527 |     }
1528 | 
1529 |     if (dragState.isDragging && dragState.startPos) {
1530 |       onDragComplete?.(dragState.startPos, endPos);
1531 |     } else if (dragState.startPos) {
1532 |       // Check if it's a tap (quick and didn't move much)
1533 |       const tapDuration = Date.now() - tapStartTimeRef.current;
1534 |       const distance = Math.sqrt(
1535 |         Math.pow(endPos.x - dragState.startPos.x, 2) +
1536 |         Math.pow(endPos.y - dragState.startPos.y, 2)
1537 |       );
1538 | 
1539 |       if (tapDuration < 500 && distance < 5) {
1540 |         onTap?.();
1541 |       }
1542 |     }
1543 | 
1544 |     setDragState({
1545 |       isDragging: false,
1546 |       startPos: null,
1547 |       currentPos: null,
1548 |     });
1549 |   };
1550 | 
1551 |   // Touch events for mobile support
1552 |   const handleTouchStart = (event: React.TouchEvent) => {
1553 |     const touch = event.touches[0];
1554 |     handleMouseDown({
1555 |       clientX: touch.clientX,
1556 |       clientY: touch.clientY,
1557 |     } as React.MouseEvent);
1558 |   };
1559 | 
1560 |   const handleTouchMove = (event: React.TouchEvent) => {
1561 |     event.preventDefault(); // Prevent scrolling
1562 |     const touch = event.touches[0];
1563 |     handleMouseMove({
1564 |       clientX: touch.clientX,
1565 |       clientY: touch.clientY,
1566 |     } as React.MouseEvent);
1567 |   };
1568 | 
1569 |   const handleTouchEnd = (event: React.TouchEvent) => {
1570 |     const touch = event.changedTouches[0];
1571 |     handleMouseUp({
1572 |       clientX: touch.clientX,
1573 |       clientY: touch.clientY,
1574 |     } as React.MouseEvent);
1575 |   };
1576 | 
1577 |   return (
1578 |     <div
1579 |       style={{
1580 |         width: 200,
1581 |         height: 200,
1582 |         backgroundColor: dragState.isDragging ? '#e0e0e0' : '#f0f0f0',
1583 |         border: '2px solid #ccc',
1584 |         cursor: dragState.isDragging ? 'grabbing' : 'grab',
1585 |         userSelect: 'none',
1586 |         position: 'relative',
1587 |       }}
1588 |       onMouseDown={handleMouseDown}
1589 |       onMouseMove={handleMouseMove}
1590 |       onMouseUp={handleMouseUp}
1591 |       onMouseLeave={handleMouseUp} // Handle mouse leaving component
1592 |       onTouchStart={handleTouchStart}
1593 |       onTouchMove={handleTouchMove}
1594 |       onTouchEnd={handleTouchEnd}
1595 |     >
1596 |       <div>Interactive Area</div>
1597 |       {dragState.isDragging && dragState.startPos && dragState.currentPos && (
1598 |         <div
1599 |           style={{
1600 |             position: 'absolute',
1601 |             left: Math.min(dragState.startPos.x, dragState.currentPos.x) - 200,
1602 |             top: Math.min(dragState.startPos.y, dragState.currentPos.y) - 200,
1603 |             width: Math.abs(dragState.currentPos.x - dragState.startPos.x),
1604 |             height: Math.abs(dragState.currentPos.y - dragState.startPos.y),
1605 |             border: '2px dashed #007acc',
1606 |             backgroundColor: 'rgba(0, 122, 204, 0.1)',
1607 |             pointerEvents: 'none',
1608 |           }}
1609 |         />
1610 |       )}
1611 |     </div>
1612 |   );
1613 | };
1614 | ```
1615 | 
1616 | **Key Benefits of Each Pattern**:
1617 | - **Event Callback Props**: Flexible, optional event handling with predictable defaults
1618 | - **Custom Event Objects**: Rich event data, controlled propagation, framework integration
1619 | - **Keyboard Accessibility**: WCAG compliance, enhanced UX, comprehensive navigation support
1620 | - **Mouse/Touch Interactions**: Cross-platform compatibility, gesture recognition, performance optimization
1621 | 
1622 | ## API Registration and Programmatic Control Patterns
1623 | 
1624 | **Purpose**: XMLUI components need to expose programmatic APIs that allow parent components and external systems to control behavior imperatively. This enables complex interactions like focus management, value manipulation, data refresh, and animation control beyond what declarative props can provide.
1625 | 
1626 | ### Basic API Registration Pattern
1627 | 
1628 | **Purpose**: Components need to expose simple methods for common operations like focus, blur, and value access that can be called from XMLUI event handlers or external JavaScript.
1629 | 
1630 | **Implementation Pattern**:
1631 | 
1632 | ```typescript
1633 | // Native component with imperative API
1634 | export const InputNative = forwardRef<HTMLInputElement, Props>(
1635 |   function InputNative({ registerComponentApi, updateState, onDidChange }, ref) {
1636 |     const inputRef = useRef<HTMLInputElement>(null);
1637 |     const [value, setValue] = useState("");
1638 | 
1639 |     // Register API methods with XMLUI framework
1640 |     useEffect(() => {
1641 |       if (registerComponentApi) {
1642 |         registerComponentApi({
1643 |           // Basic DOM operations
1644 |           focus: () => inputRef.current?.focus(),
1645 |           blur: () => inputRef.current?.blur(),
1646 |           
1647 |           // Value operations
1648 |           getValue: () => value,
1649 |           setValue: (newValue: string) => {
1650 |             setValue(newValue);
1651 |             updateState?.({ value: newValue });
1652 |             onDidChange?.();
1653 |           },
1654 |           
1655 |           // Validation operations
1656 |           isValid: () => value.length >= 3,
1657 |           validate: () => {
1658 |             const valid = value.length >= 3;
1659 |             updateState?.({ isValid: valid });
1660 |             return valid;
1661 |           },
1662 |         });
1663 |       }
1664 |     }, [registerComponentApi, value, updateState, onDidChange]);
1665 | 
1666 |     return (
1667 |       <input
1668 |         ref={inputRef}
1669 |         value={value}
1670 |         onChange={(e) => setValue(e.target.value)}
1671 |       />
1672 |     );
1673 |   }
1674 | );
1675 | 
1676 | // XMLUI renderer with API registration
1677 | export const inputComponentRenderer = createComponentRenderer(
1678 |   "Input",
1679 |   InputMd,
1680 |   ({ node, registerComponentApi, extractValue, updateState, lookupEventHandler }) => {
1681 |     return (
1682 |       <InputNative
1683 |         ref={(instance) => {
1684 |           // Forward imperative API to XMLUI
1685 |           if (instance && registerComponentApi) {
1686 |             registerComponentApi(instance);
1687 |           }
1688 |         }}
1689 |         registerComponentApi={registerComponentApi}
1690 |         updateState={updateState}
1691 |         onDidChange={lookupEventHandler("didChange")}
1692 |         placeholder={extractValue(node.props.placeholder)}
1693 |       />
1694 |     );
1695 |   },
1696 | );
1697 | ```
1698 | 
1699 | ### Async API Operations Pattern
1700 | 
1701 | **Purpose**: Components need to expose asynchronous operations like data fetching, file operations, or animations that return promises and can be awaited by calling code.
1702 | 
1703 | **Implementation Pattern**:
1704 | 
1705 | ```typescript
1706 | export const DataTableNative = forwardRef<DataTableAPI, Props>(
1707 |   function DataTableNative({ registerComponentApi, dataSource, updateState }) {
1708 |     const [data, setData] = useState([]);
1709 |     const [loading, setLoading] = useState(false);
1710 |     const [error, setError] = useState<string | null>(null);
1711 | 
1712 |     const refreshData = async (): Promise<void> => {
1713 |       setLoading(true);
1714 |       setError(null);
1715 |       
1716 |       try {
1717 |         const response = await fetch(dataSource);
1718 |         const newData = await response.json();
1719 |         setData(newData);
1720 |         updateState?.({ data: newData, lastRefresh: Date.now() });
1721 |       } catch (err) {
1722 |         const errorMessage = err instanceof Error ? err.message : 'Unknown error';
1723 |         setError(errorMessage);
1724 |         updateState?.({ error: errorMessage });
1725 |         throw err; // Re-throw for caller handling
1726 |       } finally {
1727 |         setLoading(false);
1728 |       }
1729 |     };
1730 | 
1731 |     const exportData = async (format: 'csv' | 'json' | 'xlsx'): Promise<Blob> => {
1732 |       switch (format) {
1733 |         case 'csv':
1734 |           const csvContent = data.map(row => 
1735 |             Object.values(row).join(',')
1736 |           ).join('\n');
1737 |           return new Blob([csvContent], { type: 'text/csv' });
1738 |           
1739 |         case 'json':
1740 |           return new Blob([JSON.stringify(data, null, 2)], { 
1741 |             type: 'application/json' 
1742 |           });
1743 |           
1744 |         case 'xlsx':
1745 |           // Simulate async Excel generation
1746 |           await new Promise(resolve => setTimeout(resolve, 1000));
1747 |           return new Blob(['Excel data'], { 
1748 |             type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' 
1749 |           });
1750 |           
1751 |         default:
1752 |           throw new Error(`Unsupported format: ${format}`);
1753 |       }
1754 |     };
1755 | 
1756 |     const searchData = async (query: string): Promise<any[]> => {
1757 |       // Simulate async search
1758 |       await new Promise(resolve => setTimeout(resolve, 300));
1759 |       
1760 |       const results = data.filter(item =>
1761 |         Object.values(item).some(value =>
1762 |           String(value).toLowerCase().includes(query.toLowerCase())
1763 |         )
1764 |       );
1765 |       
1766 |       updateState?.({ searchResults: results, searchQuery: query });
1767 |       return results;
1768 |     };
1769 | 
1770 |     // Register async API methods
1771 |     useEffect(() => {
1772 |       if (registerComponentApi) {
1773 |         registerComponentApi({
1774 |           // Async data operations
1775 |           refreshData,
1776 |           exportData,
1777 |           searchData,
1778 |           
1779 |           // Sync getters
1780 |           getData: () => data,
1781 |           getRowCount: () => data.length,
1782 |           isLoading: () => loading,
1783 |           hasError: () => error !== null,
1784 |           getError: () => error,
1785 |           
1786 |           // Selection operations
1787 |           selectRow: (index: number) => {
1788 |             updateState?.({ selectedRowIndex: index });
1789 |           },
1790 |           selectAll: () => {
1791 |             updateState?.({ selectedRows: data.map((_, i) => i) });
1792 |           },
1793 |           clearSelection: () => {
1794 |             updateState?.({ selectedRows: [], selectedRowIndex: -1 });
1795 |           },
1796 |         });
1797 |       }
1798 |     }, [registerComponentApi, data, loading, error, updateState]);
1799 | 
1800 |     return (
1801 |       <div className="data-table">
1802 |         {loading && <div>Loading...</div>}
1803 |         {error && <div className="error">Error: {error}</div>}
1804 |         <table>
1805 |           <tbody>
1806 |             {data.map((row, index) => (
1807 |               <tr key={index}>
1808 |                 {Object.values(row).map((value, colIndex) => (
1809 |                   <td key={colIndex}>{String(value)}</td>
1810 |                 ))}
1811 |               </tr>
1812 |             ))}
1813 |           </tbody>
1814 |         </table>
1815 |       </div>
1816 |     );
1817 |   }
1818 | );
1819 | ```
1820 | 
1821 | ### Complex State Management API Pattern
1822 | 
1823 | **Purpose**: Components with complex internal state need APIs that allow external control over multiple state aspects while maintaining internal consistency and validation.
1824 | 
1825 | **Implementation Pattern**:
1826 | 
1827 | ```typescript
1828 | interface FormState {
1829 |   values: Record<string, any>;
1830 |   errors: Record<string, string>;
1831 |   touched: Record<string, boolean>;
1832 |   isSubmitting: boolean;
1833 |   isDirty: boolean;
1834 | }
1835 | 
1836 | export const FormNative = forwardRef<FormAPI, Props>(
1837 |   function FormNative({ registerComponentApi, updateState, onValidationChange }) {
1838 |     const [formState, setFormState] = useState<FormState>({
1839 |       values: {},
1840 |       errors: {},
1841 |       touched: {},
1842 |       isSubmitting: false,
1843 |       isDirty: false,
1844 |     });
1845 | 
1846 |     const validators = useRef<Record<string, (value: any) => string | null>>({});
1847 | 
1848 |     const validateField = (fieldName: string, value: any): string | null => {
1849 |       const validator = validators.current[fieldName];
1850 |       return validator ? validator(value) : null;
1851 |     };
1852 | 
1853 |     const validateForm = (): Record<string, string> => {
1854 |       const errors: Record<string, string> = {};
1855 |       
1856 |       Object.keys(formState.values).forEach(fieldName => {
1857 |         const error = validateField(fieldName, formState.values[fieldName]);
1858 |         if (error) {
1859 |           errors[fieldName] = error;
1860 |         }
1861 |       });
1862 |       
1863 |       return errors;
1864 |     };
1865 | 
1866 |     const setFieldValue = (fieldName: string, value: any, shouldValidate = true) => {
1867 |       setFormState(prev => {
1868 |         const newValues = { ...prev.values, [fieldName]: value };
1869 |         const newErrors = { ...prev.errors };
1870 |         
1871 |         if (shouldValidate) {
1872 |           const error = validateField(fieldName, value);
1873 |           if (error) {
1874 |             newErrors[fieldName] = error;
1875 |           } else {
1876 |             delete newErrors[fieldName];
1877 |           }
1878 |         }
1879 |         
1880 |         const newState = {
1881 |           ...prev,
1882 |           values: newValues,
1883 |           errors: newErrors,
1884 |           isDirty: true,
1885 |         };
1886 |         
1887 |         // Update XMLUI state
1888 |         updateState?.({
1889 |           formValues: newValues,
1890 |           formErrors: newErrors,
1891 |           formIsDirty: true,
1892 |         });
1893 |         
1894 |         return newState;
1895 |       });
1896 |     };
1897 | 
1898 |     const resetForm = (newValues?: Record<string, any>) => {
1899 |       const resetState: FormState = {
1900 |         values: newValues || {},
1901 |         errors: {},
1902 |         touched: {},
1903 |         isSubmitting: false,
1904 |         isDirty: false,
1905 |       };
1906 |       
1907 |       setFormState(resetState);
1908 |       updateState?.({
1909 |         formValues: resetState.values,
1910 |         formErrors: resetState.errors,
1911 |         formIsDirty: false,
1912 |       });
1913 |     };
1914 | 
1915 |     const submitForm = async (): Promise<boolean> => {
1916 |       setFormState(prev => ({ ...prev, isSubmitting: true }));
1917 |       
1918 |       try {
1919 |         const errors = validateForm();
1920 |         
1921 |         if (Object.keys(errors).length > 0) {
1922 |           setFormState(prev => ({
1923 |             ...prev,
1924 |             errors,
1925 |             isSubmitting: false,
1926 |             touched: Object.keys(prev.values).reduce((acc, key) => ({
1927 |               ...acc,
1928 |               [key]: true,
1929 |             }), {}),
1930 |           }));
1931 |           
1932 |           onValidationChange?.(false, errors);
1933 |           return false;
1934 |         }
1935 |         
1936 |         // Form is valid, proceed with submission
1937 |         onValidationChange?.(true, {});
1938 |         return true;
1939 |         
1940 |       } catch (error) {
1941 |         setFormState(prev => ({ ...prev, isSubmitting: false }));
1942 |         throw error;
1943 |       }
1944 |     };
1945 | 
1946 |     // Register comprehensive form API
1947 |     useEffect(() => {
1948 |       if (registerComponentApi) {
1949 |         registerComponentApi({
1950 |           // Field operations
1951 |           setFieldValue,
1952 |           getFieldValue: (fieldName: string) => formState.values[fieldName],
1953 |           setFieldError: (fieldName: string, error: string) => {
1954 |             setFormState(prev => ({
1955 |               ...prev,
1956 |               errors: { ...prev.errors, [fieldName]: error },
1957 |             }));
1958 |           },
1959 |           clearFieldError: (fieldName: string) => {
1960 |             setFormState(prev => {
1961 |               const newErrors = { ...prev.errors };
1962 |               delete newErrors[fieldName];
1963 |               return { ...prev, errors: newErrors };
1964 |             });
1965 |           },
1966 |           
1967 |           // Validation operations
1968 |           validateField: (fieldName: string) => {
1969 |             const error = validateField(fieldName, formState.values[fieldName]);
1970 |             if (error) {
1971 |               setFormState(prev => ({
1972 |                 ...prev,
1973 |                 errors: { ...prev.errors, [fieldName]: error },
1974 |               }));
1975 |             }
1976 |             return !error;
1977 |           },
1978 |           validateForm: () => {
1979 |             const errors = validateForm();
1980 |             setFormState(prev => ({ ...prev, errors }));
1981 |             return Object.keys(errors).length === 0;
1982 |           },
1983 |           registerValidator: (fieldName: string, validator: (value: any) => string | null) => {
1984 |             validators.current[fieldName] = validator;
1985 |           },
1986 |           
1987 |           // Form operations
1988 |           submitForm,
1989 |           resetForm,
1990 |           setValues: (values: Record<string, any>) => {
1991 |             setFormState(prev => ({
1992 |               ...prev,
1993 |               values: { ...prev.values, ...values },
1994 |               isDirty: true,
1995 |             }));
1996 |           },
1997 |           
1998 |           // State getters
1999 |           getValues: () => formState.values,
2000 |           getErrors: () => formState.errors,
2001 |           isDirty: () => formState.isDirty,
2002 |           isSubmitting: () => formState.isSubmitting,
2003 |           isValid: () => Object.keys(formState.errors).length === 0,
2004 |         });
2005 |       }
2006 |     }, [registerComponentApi, formState, updateState, onValidationChange]);
2007 | 
2008 |     return (
2009 |       <form onSubmit={(e) => { e.preventDefault(); submitForm(); }}>
2010 |         {/* Form content will be rendered by child components */}
2011 |         <div className="form-content">
2012 |           {/* Child components access form state through context */}
2013 |         </div>
2014 |       </form>
2015 |     );
2016 |   }
2017 | );
2018 | ```
2019 | 
2020 | ### Animation and Media Control API Pattern
2021 | 
2022 | **Purpose**: Components that handle animations, media playback, or complex visual effects need APIs for controlling timing, playback state, and visual transitions.
2023 | 
2024 | **Implementation Pattern**:
2025 | 
2026 | ```typescript
2027 | export const VideoPlayerNative = forwardRef<VideoPlayerAPI, Props>(
2028 |   function VideoPlayerNative({ registerComponentApi, updateState, onPlaybackChange }) {
2029 |     const videoRef = useRef<HTMLVideoElement>(null);
2030 |     const [playerState, setPlayerState] = useState({
2031 |       isPlaying: false,
2032 |       currentTime: 0,
2033 |       duration: 0,
2034 |       volume: 1,
2035 |       playbackRate: 1,
2036 |       isFullscreen: false,
2037 |     });
2038 | 
2039 |     const play = async (): Promise<void> => {
2040 |       if (videoRef.current) {
2041 |         await videoRef.current.play();
2042 |         setPlayerState(prev => ({ ...prev, isPlaying: true }));
2043 |         updateState?.({ isPlaying: true });
2044 |         onPlaybackChange?.('play');
2045 |       }
2046 |     };
2047 | 
2048 |     const pause = (): void => {
2049 |       if (videoRef.current) {
2050 |         videoRef.current.pause();
2051 |         setPlayerState(prev => ({ ...prev, isPlaying: false }));
2052 |         updateState?.({ isPlaying: false });
2053 |         onPlaybackChange?.('pause');
2054 |       }
2055 |     };
2056 | 
2057 |     const seekTo = (timeInSeconds: number): void => {
2058 |       if (videoRef.current) {
2059 |         videoRef.current.currentTime = timeInSeconds;
2060 |         setPlayerState(prev => ({ ...prev, currentTime: timeInSeconds }));
2061 |         updateState?.({ currentTime: timeInSeconds });
2062 |       }
2063 |     };
2064 | 
2065 |     const setVolume = (volume: number): void => {
2066 |       const clampedVolume = Math.max(0, Math.min(1, volume));
2067 |       if (videoRef.current) {
2068 |         videoRef.current.volume = clampedVolume;
2069 |         setPlayerState(prev => ({ ...prev, volume: clampedVolume }));
2070 |         updateState?.({ volume: clampedVolume });
2071 |       }
2072 |     };
2073 | 
2074 |     const setPlaybackRate = (rate: number): void => {
2075 |       if (videoRef.current) {
2076 |         videoRef.current.playbackRate = rate;
2077 |         setPlayerState(prev => ({ ...prev, playbackRate: rate }));
2078 |         updateState?.({ playbackRate: rate });
2079 |       }
2080 |     };
2081 | 
2082 |     const toggleFullscreen = async (): Promise<void> => {
2083 |       if (!document.fullscreenElement) {
2084 |         await videoRef.current?.requestFullscreen();
2085 |         setPlayerState(prev => ({ ...prev, isFullscreen: true }));
2086 |       } else {
2087 |         await document.exitFullscreen();
2088 |         setPlayerState(prev => ({ ...prev, isFullscreen: false }));
2089 |       }
2090 |     };
2091 | 
2092 |     const captureFrame = (): string | null => {
2093 |       if (videoRef.current) {
2094 |         const canvas = document.createElement('canvas');
2095 |         const ctx = canvas.getContext('2d');
2096 |         if (ctx) {
2097 |           canvas.width = videoRef.current.videoWidth;
2098 |           canvas.height = videoRef.current.videoHeight;
2099 |           ctx.drawImage(videoRef.current, 0, 0);
2100 |           return canvas.toDataURL('image/png');
2101 |         }
2102 |       }
2103 |       return null;
2104 |     };
2105 | 
2106 |     // Register media control API
2107 |     useEffect(() => {
2108 |       if (registerComponentApi) {
2109 |         registerComponentApi({
2110 |           // Playback controls
2111 |           play,
2112 |           pause,
2113 |           stop: () => {
2114 |             pause();
2115 |             seekTo(0);
2116 |           },
2117 |           toggle: () => playerState.isPlaying ? pause() : play(),
2118 |           
2119 |           // Navigation controls
2120 |           seekTo,
2121 |           seekBy: (deltaSeconds: number) => {
2122 |             seekTo(playerState.currentTime + deltaSeconds);
2123 |           },
2124 |           seekToPercentage: (percentage: number) => {
2125 |             seekTo((percentage / 100) * playerState.duration);
2126 |           },
2127 |           
2128 |           // Audio controls
2129 |           setVolume,
2130 |           mute: () => setVolume(0),
2131 |           unmute: () => setVolume(1),
2132 |           adjustVolume: (delta: number) => {
2133 |             setVolume(playerState.volume + delta);
2134 |           },
2135 |           
2136 |           // Playback rate controls
2137 |           setPlaybackRate,
2138 |           setSpeed: setPlaybackRate, // Alias for common usage
2139 |           normalSpeed: () => setPlaybackRate(1),
2140 |           
2141 |           // Display controls
2142 |           toggleFullscreen,
2143 |           enterFullscreen: () => {
2144 |             if (!document.fullscreenElement) {
2145 |               toggleFullscreen();
2146 |             }
2147 |           },
2148 |           exitFullscreen: () => {
2149 |             if (document.fullscreenElement) {
2150 |               toggleFullscreen();
2151 |             }
2152 |           },
2153 |           
2154 |           // Utility functions
2155 |           captureFrame,
2156 |           getCurrentTime: () => playerState.currentTime,
2157 |           getDuration: () => playerState.duration,
2158 |           getVolume: () => playerState.volume,
2159 |           getPlaybackRate: () => playerState.playbackRate,
2160 |           isPlaying: () => playerState.isPlaying,
2161 |           isFullscreen: () => playerState.isFullscreen,
2162 |           
2163 |           // Advanced controls
2164 |           setCurrentTime: seekTo, // Alias for clarity
2165 |           getCurrentTimePercentage: () => 
2166 |             playerState.duration > 0 ? (playerState.currentTime / playerState.duration) * 100 : 0,
2167 |         });
2168 |       }
2169 |     }, [registerComponentApi, playerState, updateState, onPlaybackChange]);
2170 | 
2171 |     return (
2172 |       <video
2173 |         ref={videoRef}
2174 |         onTimeUpdate={(e) => {
2175 |           const currentTime = e.currentTarget.currentTime;
2176 |           setPlayerState(prev => ({ ...prev, currentTime }));
2177 |           updateState?.({ currentTime });
2178 |         }}
2179 |         onLoadedMetadata={(e) => {
2180 |           const duration = e.currentTarget.duration;
2181 |           setPlayerState(prev => ({ ...prev, duration }));
2182 |           updateState?.({ duration });
2183 |         }}
2184 |         controls
2185 |       />
2186 |     );
2187 |   }
2188 | );
2189 | ```
2190 | 
2191 | **Key Benefits of API Registration Patterns**:
2192 | - **Basic API Registration**: Simple imperative operations, consistent interface, framework integration
2193 | - **Async Operations**: Promise-based APIs, error handling, progress tracking, external system integration
2194 | - **Complex State Management**: Multi-faceted control, validation integration, state consistency, external synchronization
2195 | - **Animation/Media Control**: Real-time control, frame-accurate operations, hardware integration, performance optimization
2196 | 
2197 | ## XMLUI Renderer Patterns
2198 | 
2199 | **Purpose**: XMLUI renderer functions need consistent, efficient patterns for translating component markup into React elements while handling complex scenarios like child rendering, state management, and dynamic property passing. These patterns solve architectural challenges and ensure optimal performance across the component ecosystem.
2200 | 
2201 | ### Standard Component Renderer Structure Pattern
2202 | 
2203 | **Purpose**: All XMLUI components need consistent renderer structure for maintainability, debugging, and framework integration. This pattern provides a standardized template that handles common concerns and reduces boilerplate.
2204 | 
2205 | **Implementation Pattern**:
2206 | 
2207 | ```typescript
2208 | // Import dependencies
2209 | import { createComponentRenderer } from "../renderer-helpers";
2210 | import { ComponentNameMd } from "./ComponentNameMetadata";
2211 | import { ComponentNameNative } from "./ComponentNameNative";
2212 | 
2213 | // Component constant for consistency
2214 | const COMP = "ComponentName";
2215 | 
2216 | // Standard renderer structure
2217 | export const componentNameComponentRenderer = createComponentRenderer(
2218 |   COMP,                    // Component name (must match metadata)
2219 |   ComponentNameMd,         // Component metadata object
2220 |   ({                       // Destructured renderer context
2221 |     // Core context properties
2222 |     node,                  // Component definition with props/children
2223 |     extractValue,          // Value extraction with binding support
2224 |     renderChild,           // Child rendering function
2225 |     layoutCss,             // Pre-computed layout styles
2226 |     
2227 |     // State management
2228 |     state,                 // Current component state
2229 |     updateState,           // State update function
2230 |     
2231 |     // Event system
2232 |     lookupEventHandler,    // Event handler factory
2233 |     lookupAction,          // Async action lookup
2234 |     
2235 |     // API registration
2236 |     registerComponentApi,  // Component API registration
2237 |     
2238 |     // Context and utilities
2239 |     appContext,           // Application context
2240 |     uid,                  // Unique component identifier
2241 |     layoutContext,        // Layout context information
2242 |   }) => {
2243 |     
2244 |     // Extract and process props with proper defaults and typing
2245 |     const variant = extractValue.asOptionalString(node.props.variant, "primary");
2246 |     const enabled = extractValue.asOptionalBoolean(node.props.enabled, true);
2247 |     const label = extractValue.asDisplayText(node.props.label);
2248 |     const icon = extractValue.asString(node.props.icon);
2249 |     
2250 |     // Handle complex prop processing
2251 |     const processedProps = {
2252 |       variant,
2253 |       enabled,
2254 |       label,
2255 |       // Transform XMLUI props to native component props
2256 |       disabled: !enabled,
2257 |       showIcon: Boolean(icon),
2258 |       iconName: icon || undefined,
2259 |     };
2260 |     
2261 |     // Event handler creation with error boundaries
2262 |     const eventHandlers = {
2263 |       onClick: lookupEventHandler("click"),
2264 |       onFocus: lookupEventHandler("gotFocus"),
2265 |       onBlur: lookupEventHandler("lostFocus"),
2266 |       onValueChange: lookupEventHandler("didChange"),
2267 |     };
2268 |     
2269 |     // Conditional rendering logic
2270 |     if (!enabled && node.props.hideWhenDisabled) {
2271 |       return null;
2272 |     }
2273 |     
2274 |     // Return rendered component with all integrations
2275 |     return (
2276 |       <ComponentNameNative
2277 |         {...processedProps}
2278 |         {...eventHandlers}
2279 |         
2280 |         // Framework integration
2281 |         updateState={updateState}
2282 |         registerComponentApi={registerComponentApi}
2283 |         
2284 |         // Layout and styling
2285 |         style={layoutCss}
2286 |         className={extractValue.asString(node.props.className)}
2287 |         
2288 |         // Child content handling
2289 |         children={renderChild(node.children)}
2290 |         
2291 |         // Advanced props
2292 |         ref={(instance) => {
2293 |           if (instance && registerComponentApi) {
2294 |             registerComponentApi(instance);
2295 |           }
2296 |         }}
2297 |       />
2298 |     );
2299 |   },
2300 | );
2301 | 
2302 | // Export with consistent naming
2303 | export { componentNameComponentRenderer as componentNameRenderer };
2304 | ```
2305 | 
2306 | ### Child Rendering Patterns
2307 | 
2308 | **Purpose**: Components need different strategies for rendering child content depending on their role as containers, the type of children they accept, and the layout context they provide. This pattern optimizes performance and provides proper component composition.
2309 | 
2310 | **Implementation Pattern**:
2311 | 
2312 | ```typescript
2313 | // Pattern 1: Simple pass-through rendering
2314 | export const simpleContainerRenderer = createComponentRenderer(
2315 |   "SimpleContainer",
2316 |   SimpleContainerMd,
2317 |   ({ node, renderChild, layoutCss }) => {
2318 |     return (
2319 |       <div style={layoutCss} className="simple-container">
2320 |         {/* Direct child rendering - preserves all children as-is */}
2321 |         {renderChild(node.children)}
2322 |       </div>
2323 |     );
2324 |   },
2325 | );
2326 | 
2327 | // Pattern 2: Layout context rendering with specific arrangements
2328 | export const stackContainerRenderer = createComponentRenderer(
2329 |   "Stack",
2330 |   StackMd,
2331 |   ({ node, extractValue, renderChild, layoutCss }) => {
2332 |     const orientation = extractValue.asOptionalString(node.props.orientation, "vertical");
2333 |     const spacing = extractValue.asOptionalString(node.props.spacing, "medium");
2334 |     const alignment = extractValue.asOptionalString(node.props.alignment, "start");
2335 |     
2336 |     return (
2337 |       <div 
2338 |         style={layoutCss} 
2339 |         className={`stack stack-${orientation} spacing-${spacing} align-${alignment}`}
2340 |       >
2341 |         {/* Render children with layout context for optimal arrangement */}
2342 |         {renderChild(node.children, {
2343 |           type: "Stack",
2344 |           orientation,
2345 |           spacing,
2346 |           alignment,
2347 |           // Layout hints for child components
2348 |           itemAlignment: alignment,
2349 |           crossAxisAlignment: extractValue.asOptionalString(node.props.crossAxisAlignment),
2350 |         })}
2351 |       </div>
2352 |     );
2353 |   },
2354 | );
2355 | 
2356 | // Pattern 3: Conditional child rendering based on component state
2357 | export const expandableContainerRenderer = createComponentRenderer(
2358 |   "ExpandableContainer",
2359 |   ExpandableContainerMd,
2360 |   ({ node, extractValue, renderChild, state, layoutCss }) => {
2361 |     const isExpanded = state.expanded || extractValue.asOptionalBoolean(node.props.defaultExpanded, false);
2362 |     const renderMode = extractValue.asOptionalString(node.props.renderMode, "lazy");
2363 |     
2364 |     return (
2365 |       <div style={layoutCss} className="expandable-container">
2366 |         <div className="header">
2367 |           {extractValue.asDisplayText(node.props.title)}
2368 |         </div>
2369 |         
2370 |         {/* Conditional rendering with performance optimization */}
2371 |         {isExpanded && (
2372 |           <div className="content">
2373 |             {renderMode === "lazy" 
2374 |               ? renderChild(node.children) // Render only when expanded
2375 |               : null // Children rendered separately with visibility control
2376 |             }
2377 |           </div>
2378 |         )}
2379 |         
2380 |         {/* Always render but control visibility for "eager" mode */}
2381 |         {renderMode === "eager" && (
2382 |           <div className={`content ${!isExpanded ? 'hidden' : ''}`}>
2383 |             {renderChild(node.children)}
2384 |           </div>
2385 |         )}
2386 |       </div>
2387 |     );
2388 |   },
2389 | );
2390 | 
2391 | // Pattern 4: Selective child rendering with filtering
2392 | export const tabContainerRenderer = createComponentRenderer(
2393 |   "TabContainer",
2394 |   TabContainerMd,
2395 |   ({ node, extractValue, renderChild, state, layoutCss }) => {
2396 |     const activeTabIndex = state.activeTabIndex || extractValue.asOptionalNumber(node.props.defaultActiveTab, 0);
2397 |     
2398 |     // Filter children to only render tab panels
2399 |     const tabPanels = node.children?.filter(child => child.component === "TabPanel") || [];
2400 |     const activePanel = tabPanels[activeTabIndex];
2401 |     
2402 |     return (
2403 |       <div style={layoutCss} className="tab-container">
2404 |         <div className="tab-headers">
2405 |           {tabPanels.map((panel, index) => (
2406 |             <button
2407 |               key={panel.uid || index}
2408 |               className={`tab-header ${index === activeTabIndex ? 'active' : ''}`}
2409 |               onClick={() => updateState({ activeTabIndex: index })}
2410 |             >
2411 |               {extractValue.asDisplayText(panel.props.title)}
2412 |             </button>
2413 |           ))}
2414 |         </div>
2415 |         
2416 |         <div className="tab-content">
2417 |           {/* Render only the active tab panel for performance */}
2418 |           {activePanel && renderChild([activePanel])}
2419 |         </div>
2420 |       </div>
2421 |     );
2422 |   },
2423 | );
2424 | 
2425 | // Pattern 5: Hybrid rendering - mix of children and direct props
2426 | export const buttonWithContentRenderer = createComponentRenderer(
2427 |   "ButtonWithContent",
2428 |   ButtonWithContentMd,
2429 |   ({ node, extractValue, renderChild, lookupEventHandler, layoutCss }) => {
2430 |     const label = extractValue.asDisplayText(node.props.label);
2431 |     const hasChildren = node.children && node.children.length > 0;
2432 |     
2433 |     return (
2434 |       <button
2435 |         style={layoutCss}
2436 |         className="button-with-content"
2437 |         onClick={lookupEventHandler("click")}
2438 |       >
2439 |         {/* Prioritize children over label prop */}
2440 |         {hasChildren 
2441 |           ? renderChild(node.children, { 
2442 |               type: "ButtonContent", 
2443 |               inline: true,
2444 |               // Pass button context to children
2445 |               buttonVariant: extractValue.asOptionalString(node.props.variant),
2446 |               buttonSize: extractValue.asOptionalString(node.props.size),
2447 |             })
2448 |           : label || "Button"
2449 |         }
2450 |       </button>
2451 |     );
2452 |   },
2453 | );
2454 | 
2455 | // Pattern 6: Performance-optimized rendering with memoization
2456 | export const dataListRenderer = createComponentRenderer(
2457 |   "DataList",
2458 |   DataListMd,
2459 |   ({ node, extractValue, renderChild, state, layoutCss }) => {
2460 |     const data = state.data || extractValue(node.props.data) || [];
2461 |     const itemTemplate = node.children?.find(child => child.component === "ItemTemplate");
2462 |     const emptyTemplate = node.children?.find(child => child.component === "EmptyTemplate");
2463 |     
2464 |     // Memoize expensive rendering operations
2465 |     const renderedItems = useMemo(() => {
2466 |       if (!itemTemplate || data.length === 0) return null;
2467 |       
2468 |       return data.map((item, index) => {
2469 |         // Clone template with item data context
2470 |         const itemNode = {
2471 |           ...itemTemplate,
2472 |           uid: `${itemTemplate.uid}-${index}`,
2473 |           // Inject item data into template context
2474 |           props: {
2475 |             ...itemTemplate.props,
2476 |             $item: item,
2477 |             $index: index,
2478 |           },
2479 |         };
2480 |         
2481 |         return renderChild([itemNode]);
2482 |       });
2483 |     }, [data, itemTemplate, renderChild]);
2484 |     
2485 |     return (
2486 |       <div style={layoutCss} className="data-list">
2487 |         {data.length > 0 
2488 |           ? renderedItems
2489 |           : emptyTemplate && renderChild([emptyTemplate])
2490 |         }
2491 |       </div>
2492 |     );
2493 |   },
2494 | );
2495 | ```
2496 | 
2497 | ### Conditional Property Passing Pattern
2498 | 
2499 | **Purpose**: Components need dynamic behavior based on state, props, or context conditions. This pattern enables responsive component behavior while maintaining performance and preventing unnecessary re-renders.
2500 | 
2501 | **Implementation Pattern**:
2502 | 
2503 | ```typescript
2504 | // Pattern 1: State-based conditional props
2505 | export const dynamicInputRenderer = createComponentRenderer(
2506 |   "DynamicInput",
2507 |   DynamicInputMd,
2508 |   ({ node, extractValue, state, updateState, lookupEventHandler, layoutCss }) => {
2509 |     const inputType = extractValue.asOptionalString(node.props.type, "text");
2510 |     const isPassword = inputType === "password";
2511 |     const isReadOnly = state.readOnly || extractValue.asOptionalBoolean(node.props.readOnly, false);
2512 |     const hasError = Boolean(state.error);
2513 |     
2514 |     // Build dynamic props object
2515 |     const dynamicProps = {
2516 |       // Base props always present
2517 |       type: inputType,
2518 |       value: state.value || extractValue(node.props.value) || "",
2519 |       placeholder: extractValue.asString(node.props.placeholder),
2520 |       
2521 |       // Conditional props based on state and type
2522 |       ...(isPassword && {
2523 |         autoComplete: "current-password",
2524 |         spellCheck: false,
2525 |       }),
2526 |       
2527 |       ...(isReadOnly && {
2528 |         readOnly: true,
2529 |         tabIndex: -1,
2530 |       }),
2531 |       
2532 |       ...(hasError && {
2533 |         "aria-invalid": true,
2534 |         "aria-describedby": `${node.uid}-error`,
2535 |       }),
2536 |       
2537 |       // Performance optimization - only add expensive props when needed
2538 |       ...(extractValue.asOptionalBoolean(node.props.enableSpellCheck) && {
2539 |         spellCheck: true,
2540 |       }),
2541 |       
2542 |       // Conditional event handlers
2543 |       onChange: !isReadOnly ? lookupEventHandler("didChange") : undefined,
2544 |       onFocus: !isReadOnly ? lookupEventHandler("gotFocus") : undefined,
2545 |       onBlur: !isReadOnly ? lookupEventHandler("lostFocus") : undefined,
2546 |     };
2547 |     
2548 |     return (
2549 |       <div style={layoutCss} className="dynamic-input-container">
2550 |         <input
2551 |           {...dynamicProps}
2552 |           className={`input ${hasError ? 'error' : ''} ${isReadOnly ? 'readonly' : ''}`}
2553 |         />
2554 |         
2555 |         {/* Conditionally render error message */}
2556 |         {hasError && (
2557 |           <div id={`${node.uid}-error`} className="error-message">
2558 |             {state.error}
2559 |           </div>
2560 |         )}
2561 |         
2562 |         {/* Conditionally render password toggle */}
2563 |         {isPassword && !isReadOnly && (
2564 |           <button
2565 |             type="button"
2566 |             className="password-toggle"
2567 |             onClick={() => updateState({ showPassword: !state.showPassword })}
2568 |           >
2569 |             {state.showPassword ? "Hide" : "Show"}
2570 |           </button>
2571 |         )}
2572 |       </div>
2573 |     );
2574 |   },
2575 | );
2576 | 
2577 | // Pattern 2: Context-aware conditional rendering
2578 | export const responsiveCardRenderer = createComponentRenderer(
2579 |   "ResponsiveCard",
2580 |   ResponsiveCardMd,
2581 |   ({ node, extractValue, renderChild, layoutContext, appContext, layoutCss }) => {
2582 |     const variant = extractValue.asOptionalString(node.props.variant, "default");
2583 |     const size = extractValue.asOptionalString(node.props.size, "medium");
2584 |     
2585 |     // Determine rendering strategy based on context
2586 |     const isMobile = layoutContext?.breakpoint === "mobile" || appContext?.screenWidth < 768;
2587 |     const isInGrid = layoutContext?.type === "Grid";
2588 |     const isInStack = layoutContext?.type === "Stack";
2589 |     
2590 |     // Build conditional style and behavior props
2591 |     const conditionalProps = {
2592 |       // Base styling
2593 |       className: `card card-${variant} card-${size}`,
2594 |       
2595 |       // Context-aware modifications
2596 |       ...(isMobile && {
2597 |         className: `card card-${variant} card-${size} card-mobile`,
2598 |         // Simplified props for mobile
2599 |         showSecondaryActions: false,
2600 |         compactMode: true,
2601 |       }),
2602 |       
2603 |       ...(isInGrid && {
2604 |         // Grid-specific optimizations
2605 |         className: `card card-${variant} card-${size} card-in-grid`,
2606 |         aspectRatio: extractValue.asOptionalString(node.props.aspectRatio, "auto"),
2607 |       }),
2608 |       
2609 |       ...(isInStack && layoutContext.orientation === "horizontal" && {
2610 |         // Horizontal stack optimizations
2611 |         className: `card card-${variant} card-${size} card-horizontal`,
2612 |         layout: "horizontal",
2613 |       }),
2614 |     };
2615 |     
2616 |     // Conditional feature rendering based on capabilities
2617 |     const showAdvancedFeatures = !isMobile && appContext?.features?.advancedCardFeatures !== false;
2618 |     const showAnimations = appContext?.settings?.enableAnimations !== false;
2619 |     
2620 |     return (
2621 |       <div
2622 |         style={layoutCss}
2623 |         {...conditionalProps}
2624 |         {...(showAnimations && {
2625 |           className: `${conditionalProps.className} animated`,
2626 |         })}
2627 |       >
2628 |         {/* Always render main content */}
2629 |         <div className="card-content">
2630 |           {renderChild(node.children?.filter(child => 
2631 |             child.component !== "CardActions" && child.component !== "CardMenu"
2632 |           ))}
2633 |         </div>
2634 |         
2635 |         {/* Conditionally render advanced features */}
2636 |         {showAdvancedFeatures && (
2637 |           <>
2638 |             {node.children?.find(child => child.component === "CardActions") && (
2639 |               <div className="card-actions">
2640 |                 {renderChild(node.children.filter(child => child.component === "CardActions"))}
2641 |               </div>
2642 |             )}
2643 |             
2644 |             {node.children?.find(child => child.component === "CardMenu") && (
2645 |               <div className="card-menu">
2646 |                 {renderChild(node.children.filter(child => child.component === "CardMenu"))}
2647 |               </div>
2648 |             )}
2649 |           </>
2650 |         )}
2651 |       </div>
2652 |     );
2653 |   },
2654 | );
2655 | 
2656 | // Pattern 3: Performance-optimized conditional props with memoization
2657 | export const optimizedDataTableRenderer = createComponentRenderer(
2658 |   "OptimizedDataTable",
2659 |   OptimizedDataTableMd,
2660 |   ({ node, extractValue, state, renderChild, layoutCss }) => {
2661 |     const data = state.data || [];
2662 |     const columns = extractValue(node.props.columns) || [];
2663 |     const enableVirtualization = extractValue.asOptionalBoolean(node.props.enableVirtualization, data.length > 100);
2664 |     const enableSorting = extractValue.asOptionalBoolean(node.props.enableSorting, true);
2665 |     const enableFiltering = extractValue.asOptionalBoolean(node.props.enableFiltering, false);
2666 |     
2667 |     // Memoize expensive conditional props
2668 |     const tableProps = useMemo(() => ({
2669 |       // Base props
2670 |       data,
2671 |       columns,
2672 |       
2673 |       // Conditional feature props - only compute when needed
2674 |       ...(enableVirtualization && {
2675 |         virtualizer: {
2676 |           itemHeight: extractValue.asOptionalNumber(node.props.rowHeight, 40),
2677 |           overscan: extractValue.asOptionalNumber(node.props.overscan, 5),
2678 |         },
2679 |       }),
2680 |       
2681 |       ...(enableSorting && {
2682 |         sortConfig: {
2683 |           defaultSort: extractValue(node.props.defaultSort),
2684 |           multiSort: extractValue.asOptionalBoolean(node.props.multiSort, false),
2685 |         },
2686 |       }),
2687 |       
2688 |       ...(enableFiltering && {
2689 |         filterConfig: {
2690 |           globalFilter: state.globalFilter,
2691 |           columnFilters: state.columnFilters || {},
2692 |         },
2693 |       }),
2694 |       
2695 |       // Performance props based on data size
2696 |       ...(data.length > 1000 && {
2697 |         deferredRendering: true,
2698 |         batchSize: 50,
2699 |       }),
2700 |       
2701 |     }), [data, columns, enableVirtualization, enableSorting, enableFiltering, state]);
2702 |     
2703 |     // Conditional className based on features and state
2704 |     const tableClassName = [
2705 |       "data-table",
2706 |       enableVirtualization && "virtualized",
2707 |       enableSorting && "sortable",
2708 |       enableFiltering && "filterable",
2709 |       data.length > 1000 && "large-dataset",
2710 |       state.isLoading && "loading",
2711 |     ].filter(Boolean).join(" ");
2712 |     
2713 |     return (
2714 |       <div style={layoutCss} className="data-table-container">
2715 |         {/* Conditionally render filter UI */}
2716 |         {enableFiltering && (
2717 |           <div className="table-filters">
2718 |             {renderChild(node.children?.filter(child => child.component === "TableFilter"))}
2719 |           </div>
2720 |         )}
2721 |         
2722 |         <div className={tableClassName}>
2723 |           {/* Render table with conditional props */}
2724 |           <DataTableNative
2725 |             {...tableProps}
2726 |             updateState={updateState}
2727 |             registerComponentApi={registerComponentApi}
2728 |           />
2729 |         </div>
2730 |         
2731 |         {/* Conditionally render pagination for large datasets */}
2732 |         {data.length > 25 && (
2733 |           <div className="table-pagination">
2734 |             {renderChild(node.children?.filter(child => child.component === "TablePagination"))}
2735 |           </div>
2736 |         )}
2737 |       </div>
2738 |     );
2739 |   },
2740 | );
2741 | ```
2742 | 
2743 | **Key Benefits of Renderer Patterns**:
2744 | - **Standard Structure**: Consistent architecture, reduced boilerplate, easier maintenance, debugging support
2745 | - **Child Rendering**: Flexible composition, performance optimization, layout context awareness, selective rendering
2746 | - **Conditional Properties**: Dynamic behavior, performance optimization, context awareness, responsive design support
2747 | 
2748 | ## Performance Patterns
2749 | 
2750 | **Purpose**: React components need optimization strategies to handle large datasets, complex computations, and frequent updates without degrading user experience. These patterns solve performance bottlenecks through memoization, virtualization, lazy loading, and efficient update strategies.
2751 | 
2752 | ### Memoization with useMemo and useCallback Pattern
2753 | 
2754 | **Purpose**: Components need to prevent expensive recalculations and avoid unnecessary re-renders of child components by memoizing computed values and stable function references.
2755 | 
2756 | **Implementation Pattern**:
2757 | 
2758 | ```typescript
2759 | export const OptimizedDataProcessor = ({ 
2760 |   data, 
2761 |   filters, 
2762 |   sortConfig, 
2763 |   onDataChange,
2764 |   onSelectionChange 
2765 | }: Props) => {
2766 |   const [selectedItems, setSelectedItems] = useState<Set<string>>(new Set());
2767 |   const [searchQuery, setSearchQuery] = useState("");
2768 | 
2769 |   // Memoize expensive data transformations
2770 |   const filteredData = useMemo(() => {
2771 |     console.log("Computing filtered data..."); // Only logs when dependencies change
2772 |     
2773 |     return data.filter(item => {
2774 |       // Apply multiple filters
2775 |       const matchesSearch = searchQuery === "" || 
2776 |         item.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
2777 |         item.description.toLowerCase().includes(searchQuery.toLowerCase());
2778 |       
2779 |       const matchesCategory = !filters.category || 
2780 |         item.category === filters.category;
2781 |       
2782 |       const matchesDateRange = !filters.dateRange || 
2783 |         (item.date >= filters.dateRange.start && item.date <= filters.dateRange.end);
2784 |       
2785 |       return matchesSearch && matchesCategory && matchesDateRange;
2786 |     });
2787 |   }, [data, searchQuery, filters.category, filters.dateRange]);
2788 | 
2789 |   // Memoize expensive sorting operations
2790 |   const sortedData = useMemo(() => {
2791 |     console.log("Computing sorted data..."); // Only logs when dependencies change
2792 |     
2793 |     if (!sortConfig.field) return filteredData;
2794 |     
2795 |     return [...filteredData].sort((a, b) => {
2796 |       const aVal = a[sortConfig.field];
2797 |       const bVal = b[sortConfig.field];
2798 |       
2799 |       // Handle different data types
2800 |       if (typeof aVal === 'number' && typeof bVal === 'number') {
2801 |         return sortConfig.direction === 'asc' ? aVal - bVal : bVal - aVal;
2802 |       }
2803 |       
2804 |       if (aVal instanceof Date && bVal instanceof Date) {
2805 |         return sortConfig.direction === 'asc' 
2806 |           ? aVal.getTime() - bVal.getTime() 
2807 |           : bVal.getTime() - aVal.getTime();
2808 |       }
2809 |       
2810 |       // String comparison
2811 |       const result = String(aVal).localeCompare(String(bVal));
2812 |       return sortConfig.direction === 'asc' ? result : -result;
2813 |     });
2814 |   }, [filteredData, sortConfig.field, sortConfig.direction]);
2815 | 
2816 |   // Memoize computed statistics
2817 |   const statistics = useMemo(() => {
2818 |     return {
2819 |       total: data.length,
2820 |       filtered: filteredData.length,
2821 |       selected: selectedItems.size,
2822 |       categories: [...new Set(data.map(item => item.category))].length,
2823 |       averageValue: data.reduce((sum, item) => sum + (item.value || 0), 0) / data.length,
2824 |     };
2825 |   }, [data, filteredData.length, selectedItems.size]);
2826 | 
2827 |   // Memoize stable callback functions to prevent child re-renders
2828 |   const handleItemClick = useCallback((itemId: string) => {
2829 |     setSelectedItems(prev => {
2830 |       const newSelection = new Set(prev);
2831 |       if (newSelection.has(itemId)) {
2832 |         newSelection.delete(itemId);
2833 |       } else {
2834 |         newSelection.add(itemId);
2835 |       }
2836 |       
2837 |       // Notify parent with stable reference
2838 |       onSelectionChange?.(Array.from(newSelection));
2839 |       return newSelection;
2840 |     });
2841 |   }, [onSelectionChange]);
2842 | 
2843 |   const handleSelectAll = useCallback(() => {
2844 |     const allIds = sortedData.map(item => item.id);
2845 |     setSelectedItems(new Set(allIds));
2846 |     onSelectionChange?.(allIds);
2847 |   }, [sortedData, onSelectionChange]);
2848 | 
2849 |   const handleClearSelection = useCallback(() => {
2850 |     setSelectedItems(new Set());
2851 |     onSelectionChange?.([]);
2852 |   }, [onSelectionChange]);
2853 | 
2854 |   // Memoize search handler with debouncing
2855 |   const debouncedSearch = useCallback(
2856 |     debounce((query: string) => {
2857 |       setSearchQuery(query);
2858 |     }, 300),
2859 |     []
2860 |   );
2861 | 
2862 |   const handleSearchChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
2863 |     debouncedSearch(event.target.value);
2864 |   }, [debouncedSearch]);
2865 | 
2866 |   // Memoize expensive render functions
2867 |   const renderStatistics = useCallback(() => (
2868 |     <div className="statistics">
2869 |       <span>Total: {statistics.total}</span>
2870 |       <span>Filtered: {statistics.filtered}</span>
2871 |       <span>Selected: {statistics.selected}</span>
2872 |       <span>Categories: {statistics.categories}</span>
2873 |       <span>Average: {statistics.averageValue.toFixed(2)}</span>
2874 |     </div>
2875 |   ), [statistics]);
2876 | 
2877 |   return (
2878 |     <div className="optimized-data-processor">
2879 |       {/* Search input - uses memoized handler */}
2880 |       <input
2881 |         type="text"
2882 |         placeholder="Search..."
2883 |         onChange={handleSearchChange}
2884 |       />
2885 |       
2886 |       {/* Statistics - memoized component */}
2887 |       {renderStatistics()}
2888 |       
2889 |       {/* Action buttons - use memoized handlers */}
2890 |       <div className="actions">
2891 |         <button onClick={handleSelectAll}>Select All</button>
2892 |         <button onClick={handleClearSelection}>Clear Selection</button>
2893 |       </div>
2894 |       
2895 |       {/* Data list - only re-renders when sortedData changes */}
2896 |       <div className="data-list">
2897 |         {sortedData.map(item => (
2898 |           <MemoizedDataItem
2899 |             key={item.id}
2900 |             item={item}
2901 |             isSelected={selectedItems.has(item.id)}
2902 |             onClick={handleItemClick}
2903 |           />
2904 |         ))}
2905 |       </div>
2906 |     </div>
2907 |   );
2908 | };
2909 | 
2910 | // Memoized child component to prevent unnecessary re-renders
2911 | const MemoizedDataItem = React.memo(({ 
2912 |   item, 
2913 |   isSelected, 
2914 |   onClick 
2915 | }: {
2916 |   item: DataItem;
2917 |   isSelected: boolean;
2918 |   onClick: (id: string) => void;
2919 | }) => {
2920 |   const handleClick = useCallback(() => {
2921 |     onClick(item.id);
2922 |   }, [item.id, onClick]);
2923 | 
2924 |   return (
2925 |     <div 
2926 |       className={`data-item ${isSelected ? 'selected' : ''}`}
2927 |       onClick={handleClick}
2928 |     >
2929 |       <h3>{item.name}</h3>
2930 |       <p>{item.description}</p>
2931 |       <span>{item.category}</span>
2932 |     </div>
2933 |   );
2934 | });
2935 | ```
2936 | 
2937 | ### Lazy Loading and Code Splitting Pattern
2938 | 
2939 | **Purpose**: Components need to load content and code on-demand to reduce initial bundle size and improve perceived performance by deferring non-critical resources.
2940 | 
2941 | **Implementation Pattern**:
2942 | 
2943 | ```typescript
2944 | // Dynamic component import with lazy loading
2945 | const LazyChart = React.lazy(() => 
2946 |   import('./components/Chart').then(module => ({
2947 |     default: module.Chart
2948 |   }))
2949 | );
2950 | 
2951 | const LazyDataTable = React.lazy(() => 
2952 |   import('./components/DataTable').then(module => ({
2953 |     default: module.DataTable
2954 |   }))
2955 | );
2956 | 
2957 | const LazyImageEditor = React.lazy(() => 
2958 |   import('./components/ImageEditor').then(module => ({
2959 |     default: module.ImageEditor
2960 |   }))
2961 | );
2962 | 
2963 | export const LazyLoadingContainer = ({ 
2964 |   activeTab, 
2965 |   data, 
2966 |   onTabChange 
2967 | }: Props) => {
2968 |   const [loadedTabs, setLoadedTabs] = useState<Set<string>>(new Set(['overview']));
2969 |   const [imageCache, setImageCache] = useState<Map<string, string>>(new Map());
2970 |   
2971 |   // Track which tabs have been viewed for preloading
2972 |   const handleTabChange = useCallback((tabId: string) => {
2973 |     setLoadedTabs(prev => new Set([...prev, tabId]));
2974 |     onTabChange(tabId);
2975 |   }, [onTabChange]);
2976 | 
2977 |   // Preload next likely tab based on user behavior
2978 |   useEffect(() => {
2979 |     const preloadMap = {
2980 |       'overview': 'analytics',
2981 |       'analytics': 'reports',
2982 |       'reports': 'settings',
2983 |     };
2984 |     
2985 |     const nextTab = preloadMap[activeTab as keyof typeof preloadMap];
2986 |     if (nextTab && !loadedTabs.has(nextTab)) {
2987 |       // Preload after a delay
2988 |       const timer = setTimeout(() => {
2989 |         setLoadedTabs(prev => new Set([...prev, nextTab]));
2990 |       }, 2000);
2991 |       
2992 |       return () => clearTimeout(timer);
2993 |     }
2994 |   }, [activeTab, loadedTabs]);
2995 | 
2996 |   // Lazy image loading with intersection observer
2997 |   const LazyImage = useCallback(({ src, alt, ...props }: ImageProps) => {
2998 |     const [isLoaded, setIsLoaded] = useState(false);
2999 |     const [isInView, setIsInView] = useState(false);
3000 |     const imgRef = useRef<HTMLImageElement>(null);
3001 | 
3002 |     useEffect(() => {
3003 |       const observer = new IntersectionObserver(
3004 |         ([entry]) => {
3005 |           if (entry.isIntersecting) {
3006 |             setIsInView(true);
3007 |             observer.disconnect();
3008 |           }
3009 |         },
3010 |         { threshold: 0.1 }
3011 |       );
3012 | 
3013 |       if (imgRef.current) {
3014 |         observer.observe(imgRef.current);
3015 |       }
3016 | 
3017 |       return () => observer.disconnect();
3018 |     }, []);
3019 | 
3020 |     useEffect(() => {
3021 |       if (isInView && !isLoaded) {
3022 |         // Check cache first
3023 |         if (imageCache.has(src)) {
3024 |           setIsLoaded(true);
3025 |           return;
3026 |         }
3027 | 
3028 |         // Preload image
3029 |         const img = new Image();
3030 |         img.onload = () => {
3031 |           setImageCache(prev => new Map([...prev, [src, src]]));
3032 |           setIsLoaded(true);
3033 |         };
3034 |         img.src = src;
3035 |       }
3036 |     }, [isInView, isLoaded, src, imageCache]);
3037 | 
3038 |     return (
3039 |       <div ref={imgRef} className="lazy-image-container" {...props}>
3040 |         {isLoaded ? (
3041 |           <img src={src} alt={alt} className="lazy-image loaded" />
3042 |         ) : (
3043 |           <div className="lazy-image-placeholder">
3044 |             <div className="loading-spinner" />
3045 |           </div>
3046 |         )}
3047 |       </div>
3048 |     );
3049 |   }, [imageCache]);
3050 | 
3051 |   // Lazy content loading based on visibility
3052 |   const LazyContent = useCallback(({ 
3053 |     children, 
3054 |     fallback = <div>Loading...</div>,
3055 |     threshold = 0.1 
3056 |   }: LazyContentProps) => {
3057 |     const [shouldLoad, setShouldLoad] = useState(false);
3058 |     const containerRef = useRef<HTMLDivElement>(null);
3059 | 
3060 |     useEffect(() => {
3061 |       const observer = new IntersectionObserver(
3062 |         ([entry]) => {
3063 |           if (entry.isIntersecting) {
3064 |             setShouldLoad(true);
3065 |             observer.disconnect();
3066 |           }
3067 |         },
3068 |         { threshold }
3069 |       );
3070 | 
3071 |       if (containerRef.current) {
3072 |         observer.observe(containerRef.current);
3073 |       }
3074 | 
3075 |       return () => observer.disconnect();
3076 |     }, [threshold]);
3077 | 
3078 |     return (
3079 |       <div ref={containerRef}>
3080 |         {shouldLoad ? children : fallback}
3081 |       </div>
3082 |     );
3083 |   }, []);
3084 | 
3085 |   return (
3086 |     <div className="lazy-loading-container">
3087 |       <nav className="tabs">
3088 |         {['overview', 'analytics', 'reports', 'settings'].map(tab => (
3089 |           <button
3090 |             key={tab}
3091 |             className={`tab ${activeTab === tab ? 'active' : ''}`}
3092 |             onClick={() => handleTabChange(tab)}
3093 |           >
3094 |             {tab.charAt(0).toUpperCase() + tab.slice(1)}
3095 |             {!loadedTabs.has(tab) && <span className="loading-indicator" />}
3096 |           </button>
3097 |         ))}
3098 |       </nav>
3099 | 
3100 |       <div className="tab-content">
3101 |         {/* Always render overview immediately */}
3102 |         {activeTab === 'overview' && (
3103 |           <div className="overview-tab">
3104 |             <h2>Overview</h2>
3105 |             <p>Key metrics and summary information</p>
3106 |             
3107 |             {/* Lazy load images in overview */}
3108 |             <div className="image-gallery">
3109 |               {data.images?.map((img, index) => (
3110 |                 <LazyImage
3111 |                   key={index}
3112 |                   src={img.src}
3113 |                   alt={img.alt}
3114 |                   className="gallery-image"
3115 |                 />
3116 |               ))}
3117 |             </div>
3118 |           </div>
3119 |         )}
3120 | 
3121 |         {/* Lazy load analytics tab */}
3122 |         {activeTab === 'analytics' && (
3123 |           <Suspense fallback={<div className="loading">Loading Analytics...</div>}>
3124 |             <LazyContent>
3125 |               {loadedTabs.has('analytics') && (
3126 |                 <LazyChart 
3127 |                   data={data.analytics}
3128 |                   type="line"
3129 |                   animated={true}
3130 |                 />
3131 |               )}
3132 |             </LazyContent>
3133 |           </Suspense>
3134 |         )}
3135 | 
3136 |         {/* Lazy load reports tab */}
3137 |         {activeTab === 'reports' && (
3138 |           <Suspense fallback={<div className="loading">Loading Reports...</div>}>
3139 |             <LazyContent>
3140 |               {loadedTabs.has('reports') && (
3141 |                 <LazyDataTable 
3142 |                   data={data.reports}
3143 |                   pagination={true}
3144 |                   exportable={true}
3145 |                 />
3146 |               )}
3147 |             </LazyContent>
3148 |           </Suspense>
3149 |         )}
3150 | 
3151 |         {/* Lazy load settings tab */}
3152 |         {activeTab === 'settings' && (
3153 |           <Suspense fallback={<div className="loading">Loading Settings...</div>}>
3154 |             <LazyContent>
3155 |               {loadedTabs.has('settings') && (
3156 |                 <LazyImageEditor 
3157 |                   features={['crop', 'filter', 'adjust']}
3158 |                   onSave={handleImageSave}
3159 |                 />
3160 |               )}
3161 |             </LazyContent>
3162 |           </Suspense>
3163 |         )}
3164 |       </div>
3165 |     </div>
3166 |   );
3167 | };
3168 | ```
3169 | 
3170 | ### Debouncing for Expensive Operations Pattern
3171 | 
3172 | **Purpose**: Components need to optimize user input handling and expensive operations by reducing the frequency of execution through debouncing and throttling techniques.
3173 | 
3174 | **Implementation Pattern**:
3175 | 
3176 | ```typescript
3177 | export const OptimizedSearchComponent = ({ 
3178 |   onSearch, 
3179 |   onFilter, 
3180 |   onSort,
3181 |   searchDelay = 300,
3182 |   filterDelay = 500 
3183 | }: Props) => {
3184 |   const [searchQuery, setSearchQuery] = useState("");
3185 |   const [filters, setFilters] = useState<FilterState>({});
3186 |   const [sortConfig, setSortConfig] = useState<SortConfig>({});
3187 |   const [isSearching, setIsSearching] = useState(false);
3188 | 
3189 |   // Debounced search function
3190 |   const debouncedSearch = useMemo(
3191 |     () => debounce(async (query: string) => {
3192 |       setIsSearching(true);
3193 |       try {
3194 |         await onSearch(query);
3195 |       } finally {
3196 |         setIsSearching(false);
3197 |       }
3198 |     }, searchDelay),
3199 |     [onSearch, searchDelay]
3200 |   );
3201 | 
3202 |   // Debounced filter function with batching
3203 |   const debouncedFilter = useMemo(
3204 |     () => debounce((filterState: FilterState) => {
3205 |       onFilter(filterState);
3206 |     }, filterDelay),
3207 |     [onFilter, filterDelay]
3208 |   );
3209 | 
3210 |   // Throttled sort function to prevent rapid sorting
3211 |   const throttledSort = useMemo(
3212 |     () => throttle((config: SortConfig) => {
3213 |       onSort(config);
3214 |     }, 200),
3215 |     [onSort]
3216 |   );
3217 | 
3218 |   // Search input handler
3219 |   const handleSearchChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
3220 |     const query = event.target.value;
3221 |     setSearchQuery(query);
3222 |     
3223 |     // Cancel previous search and start new one
3224 |     debouncedSearch.cancel();
3225 |     debouncedSearch(query);
3226 |   }, [debouncedSearch]);
3227 | 
3228 |   // Filter change handler with batching
3229 |   const handleFilterChange = useCallback((filterKey: string, value: any) => {
3230 |     setFilters(prev => {
3231 |       const newFilters = { ...prev, [filterKey]: value };
3232 |       
3233 |       // Cancel previous filter operation
3234 |       debouncedFilter.cancel();
3235 |       debouncedFilter(newFilters);
3236 |       
3237 |       return newFilters;
3238 |     });
3239 |   }, [debouncedFilter]);
3240 | 
3241 |   // Sort change handler
3242 |   const handleSortChange = useCallback((field: string, direction: 'asc' | 'desc') => {
3243 |     const newConfig = { field, direction };
3244 |     setSortConfig(newConfig);
3245 |     throttledSort(newConfig);
3246 |   }, [throttledSort]);
3247 | 
3248 |   // Advanced debouncing with request cancellation
3249 |   const advancedDebouncedSearch = useMemo(() => {
3250 |     let currentController: AbortController | null = null;
3251 |     
3252 |     return debounce(async (query: string) => {
3253 |       // Cancel previous request
3254 |       if (currentController) {
3255 |         currentController.abort();
3256 |       }
3257 |       
3258 |       // Create new abort controller
3259 |       currentController = new AbortController();
3260 |       setIsSearching(true);
3261 |       
3262 |       try {
3263 |         const results = await fetch(`/api/search?q=${encodeURIComponent(query)}`, {
3264 |           signal: currentController.signal
3265 |         });
3266 |         
3267 |         if (!results.ok) throw new Error('Search failed');
3268 |         
3269 |         const data = await results.json();
3270 |         onSearch(data);
3271 |       } catch (error) {
3272 |         if (error.name !== 'AbortError') {
3273 |           console.error('Search error:', error);
3274 |         }
3275 |       } finally {
3276 |         if (currentController && !currentController.signal.aborted) {
3277 |           setIsSearching(false);
3278 |         }
3279 |         currentController = null;
3280 |       }
3281 |     }, searchDelay);
3282 |   }, [onSearch, searchDelay]);
3283 | 
3284 |   // Cleanup on unmount
3285 |   useEffect(() => {
3286 |     return () => {
3287 |       debouncedSearch.cancel();
3288 |       debouncedFilter.cancel();
3289 |       throttledSort.cancel();
3290 |       advancedDebouncedSearch.cancel();
3291 |     };
3292 |   }, [debouncedSearch, debouncedFilter, throttledSort, advancedDebouncedSearch]);
3293 | 
3294 |   // Auto-save with debouncing
3295 |   const [formData, setFormData] = useState({});
3296 |   const [lastSaved, setLastSaved] = useState<Date | null>(null);
3297 |   
3298 |   const debouncedAutoSave = useMemo(
3299 |     () => debounce(async (data: any) => {
3300 |       try {
3301 |         await fetch('/api/autosave', {
3302 |           method: 'POST',
3303 |           headers: { 'Content-Type': 'application/json' },
3304 |           body: JSON.stringify(data)
3305 |         });
3306 |         setLastSaved(new Date());
3307 |       } catch (error) {
3308 |         console.error('Auto-save failed:', error);
3309 |       }
3310 |     }, 2000),
3311 |     []
3312 |   );
3313 | 
3314 |   const handleFormDataChange = useCallback((field: string, value: any) => {
3315 |     setFormData(prev => {
3316 |       const newData = { ...prev, [field]: value };
3317 |       debouncedAutoSave(newData);
3318 |       return newData;
3319 |     });
3320 |   }, [debouncedAutoSave]);
3321 | 
3322 |   // Resize handler with throttling
3323 |   const [windowSize, setWindowSize] = useState({
3324 |     width: window.innerWidth,
3325 |     height: window.innerHeight
3326 |   });
3327 | 
3328 |   const throttledResize = useMemo(
3329 |     () => throttle(() => {
3330 |       setWindowSize({
3331 |         width: window.innerWidth,
3332 |         height: window.innerHeight
3333 |       });
3334 |     }, 100),
3335 |     []
3336 |   );
3337 | 
3338 |   useEffect(() => {
3339 |     window.addEventListener('resize', throttledResize);
3340 |     return () => {
3341 |       window.removeEventListener('resize', throttledResize);
3342 |       throttledResize.cancel();
3343 |     };
3344 |   }, [throttledResize]);
3345 | 
3346 |   return (
3347 |     <div className="optimized-search-component">
3348 |       {/* Search input with debouncing */}
3349 |       <div className="search-section">
3350 |         <input
3351 |           type="text"
3352 |           value={searchQuery}
3353 |           onChange={handleSearchChange}
3354 |           placeholder="Search..."
3355 |           className={isSearching ? 'searching' : ''}
3356 |         />
3357 |         {isSearching && <div className="search-spinner" />}
3358 |       </div>
3359 | 
3360 |       {/* Filter controls with debounced updates */}
3361 |       <div className="filter-section">
3362 |         <select 
3363 |           onChange={(e) => handleFilterChange('category', e.target.value)}
3364 |           value={filters.category || ''}
3365 |         >
3366 |           <option value="">All Categories</option>
3367 |           <option value="electronics">Electronics</option>
3368 |           <option value="books">Books</option>
3369 |           <option value="clothing">Clothing</option>
3370 |         </select>
3371 | 
3372 |         <input
3373 |           type="range"
3374 |           min="0"
3375 |           max="1000"
3376 |           value={filters.maxPrice || 1000}
3377 |           onChange={(e) => handleFilterChange('maxPrice', parseInt(e.target.value))}
3378 |         />
3379 |       </div>
3380 | 
3381 |       {/* Sort controls with throttling */}
3382 |       <div className="sort-section">
3383 |         <button onClick={() => handleSortChange('name', 'asc')}>
3384 |           Sort by Name ↑
3385 |         </button>
3386 |         <button onClick={() => handleSortChange('name', 'desc')}>
3387 |           Sort by Name ↓
3388 |         </button>
3389 |         <button onClick={() => handleSortChange('price', 'asc')}>
3390 |           Sort by Price ↑
3391 |         </button>
3392 |         <button onClick={() => handleSortChange('price', 'desc')}>
3393 |           Sort by Price ↓
3394 |         </button>
3395 |       </div>
3396 | 
3397 |       {/* Auto-save indicator */}
3398 |       <div className="auto-save-section">
3399 |         {lastSaved && (
3400 |           <span>Last saved: {lastSaved.toLocaleTimeString()}</span>
3401 |         )}
3402 |       </div>
3403 | 
3404 |       {/* Window size display (responsive testing) */}
3405 |       <div className="window-info">
3406 |         {windowSize.width} × {windowSize.height}
3407 |       </div>
3408 |     </div>
3409 |   );
3410 | };
3411 | 
3412 | // Utility functions
3413 | function debounce<T extends (...args: any[]) => any>(
3414 |   func: T,
3415 |   delay: number
3416 | ): T & { cancel: () => void } {
3417 |   let timeoutId: NodeJS.Timeout;
3418 |   
3419 |   const debounced = (...args: Parameters<T>) => {
3420 |     clearTimeout(timeoutId);
3421 |     timeoutId = setTimeout(() => func(...args), delay);
3422 |   };
3423 |   
3424 |   debounced.cancel = () => {
3425 |     clearTimeout(timeoutId);
3426 |   };
3427 |   
3428 |   return debounced as T & { cancel: () => void };
3429 | }
3430 | 
3431 | function throttle<T extends (...args: any[]) => any>(
3432 |   func: T,
3433 |   delay: number
3434 | ): T & { cancel: () => void } {
3435 |   let inThrottle: boolean;
3436 |   let timeoutId: NodeJS.Timeout;
3437 |   
3438 |   const throttled = (...args: Parameters<T>) => {
3439 |     if (!inThrottle) {
3440 |       func(...args);
3441 |       inThrottle = true;
3442 |       timeoutId = setTimeout(() => {
3443 |         inThrottle = false;
3444 |       }, delay);
3445 |     }
3446 |   };
3447 |   
3448 |   throttled.cancel = () => {
3449 |     clearTimeout(timeoutId);
3450 |     inThrottle = false;
3451 |   };
3452 |   
3453 |   return throttled as T & { cancel: () => void };
3454 | }
3455 | ```
3456 | 
3457 | **Key Benefits of Performance Patterns**:
3458 | - **Memoization**: Prevents expensive recalculations, reduces child re-renders, optimizes function stability, improves large dataset handling
3459 | - **Lazy Loading**: Reduces initial bundle size, improves perceived performance, loads content on-demand, supports code splitting
3460 | - **Debouncing**: Optimizes user input handling, reduces API calls, prevents excessive operations, includes request cancellation and auto-save features
```

