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

# Directory Structure

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

# Files

--------------------------------------------------------------------------------
/xmlui/dev-docs/react-fundamentals.md:
--------------------------------------------------------------------------------

```markdown
# React Fundamentals

This document is a concise reference for React patterns and hooks used in XMLUI. It assumes you're familiar with [React basics](https://react.dev/learn) and provides practical guidance for reading and maintaining XMLUI source code.

## React Hooks: Quick Overview

**What are hooks?** Functions that let you "hook into" React features from function components. They always start with `use` (e.g., `useState`, `useEffect`).

**Core hooks in XMLUI:**
- **`useState`** - Add local state to components
- **`useEffect`** - Run side effects (data fetching, subscriptions, DOM updates)
- **`useRef`** - Store mutable values that don't trigger re-renders
- **`useMemo`** - Cache expensive calculations
- **`useCallback`** - Cache function definitions
- **`useReducer`** - Manage complex state with reducer pattern
- **`useContext`** - Access context values from providers

**Two critical rules:**
1. Only call hooks at the top level (not in loops, conditions, or nested functions)
2. Only call hooks from React functions (components or custom hooks)

**Why?** React tracks hooks by call order. Breaking these rules causes state mismatches and bugs.

## Component Rendering Lifecycle

React components re-render whenever their state or props change. Understanding this cycle prevents performance issues and unexpected behavior.

**The 5-Phase Render Cycle:**

1. **Trigger** → Something requests a render:
   - Parent component re-renders
   - Props change
   - State changes (`useState`, `useReducer`)

2. **Render** → React calls your component function, which returns JSX

3. **Reconciliation** → React's diffing algorithm determines what changed in the virtual DOM

4. **Commit** → React updates the actual DOM with minimal changes

5. **Effects** → React runs effects in order:
   - `useLayoutEffect` (synchronous, blocks paint)
   - Browser paints the screen
   - `useEffect` (asynchronous, after paint)

**Key insight:** Re-rendering is cheap (just a function call), but DOM updates are expensive. React optimizes by batching and minimizing DOM changes.

**Common performance pitfalls:**
```tsx
// ❌ WRONG - Parent re-renders cause all children to re-render
function Parent() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <ExpensiveChild data={data} />  {/* Re-renders unnecessarily */}
      <button onClick={() => setCount(c => c + 1)}>Update</button>
    </div>
  );
}

// ✅ CORRECT - Memoize to prevent unnecessary re-renders
const MemoizedChild = React.memo(ExpensiveChild);

function Parent() {
  const [count, setCount] = useState(0);
  const data = useMemo(() => computeData(), []); // Stable reference
  return (
    <div>
      <MemoizedChild data={data} />  {/* Only re-renders when data changes */}
      <button onClick={() => setCount(c => c + 1)}>Update</button>
    </div>
  );
}
```

## Rules of Hooks

These rules are enforced by React and ESLint. Violating them causes hard-to-debug errors.

**Rule 1: Call hooks at the top level**
```tsx
// ❌ WRONG - Conditional hook
function Bad({ show }: Props) {
  if (show) {
    const [value, setValue] = useState(""); // Hook order changes!
  }
  return <div>...</div>;
}

// ✅ CORRECT - Hook always called
function Good({ show }: Props) {
  const [value, setValue] = useState("");
  if (!show) return null;
  return <div>{value}</div>;
}
```

**Rule 2: Only call from React functions**
```tsx
// ❌ WRONG - Hook in regular function
function getUser() {
  const [user, setUser] = useState(null); // Not allowed!
  return user;
}

// ✅ CORRECT - Hook in component or custom hook
function useUser() {
  const [user, setUser] = useState(null);
  return user;
}

function Component() {
  const user = useUser(); // OK
  return <div>{user?.name}</div>;
}
```

**Why these rules exist:** React stores hook state in a sequential array tied to each component instance. The array index depends on call order. Conditional hooks break this indexing, causing state to be assigned to the wrong hooks.

---

## React State Management Patterns

Fundamental patterns for managing state in React, from local component state to shared state across component trees.

### `useState` - Local State

**Syntax:** `const [state, setState] = useState(initialValue)`

```tsx
// Basic
const [count, setCount] = useState(0);

// Functional update (when new state depends on old)
setCount(prev => prev + 1);

// Lazy initialization (expensive initial state)
const [data, setData] = useState(() => expensiveComputation());

// Immutable updates
setUser(prev => ({ ...prev, name }));
setItems(prev => [...prev, newItem]);
```

**Use when:** State is local, updates are simple, no complex transitions.  
**Consider alternatives:** Multiple components → Context, complex logic → useReducer.

---

### `useReducer` - Complex State Logic

**Syntax:** `const [state, dispatch] = useReducer(reducer, initialState)`

```tsx
type Action = { type: 'increment' } | { type: 'decrement' } | { type: 'reset' };

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case 'increment': return { count: state.count + 1 };
    case 'decrement': return { count: state.count - 1 };
    case 'reset': return { count: 0 };
    default: return state;
  }
}

const [state, dispatch] = useReducer(reducer, { count: 0 });
dispatch({ type: 'increment' });
```

**With Immer (XMLUI pattern):**
```tsx
import produce from 'immer';

const reducer = produce((draft, action) => {
  switch (action.type) {
    case 'ADD_TODO':
      draft.todos.push(action.payload); // Direct mutation
      break;
  }
});
```

**Use when:** Multiple related state values, complex transitions, want to separate state logic.  
**Use useState when:** Simple independent values, straightforward updates.

---

### Context API - Avoid Prop Drilling

**Purpose:** Share state across component tree without passing props through every level.

**Pattern:** Create context → Provider component → Custom hook → Consume

```tsx
// 1. Create context
const AuthContext = createContext<AuthContext | null>(null);

// 2. Custom hook with validation
function useAuth() {
  const context = useContext(AuthContext);
  if (!context) throw new Error('useAuth must be used within AuthProvider');
  return context;
}

// 3. Provider component
function AuthProvider({ children }: Props) {
  const [user, setUser] = useState<User | null>(null);
  
  const value = useMemo(() => ({
    user,
    login: async (creds: Credentials) => { /* ... */ },
    logout: () => setUser(null),
  }), [user]);
  
  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

// 4. Consume anywhere in tree
function Component() {
  const { user, logout } = useAuth(); // No prop drilling!
  return <button onClick={logout}>{user.name}</button>;
}
```

**XMLUI Example:**
```tsx
// AppLayoutContext - Provides layout state to nested navigation
const AppLayoutContext = createContext<IAppLayoutContext | null>(null);

export const App = forwardRef(function App(props, ref) {
  const layoutContextValue = useMemo(() => ({
    layout,
    navPanelVisible,
    toggleDrawer,
  }), [layout, navPanelVisible, toggleDrawer]);
  
  return (
    <AppLayoutContext.Provider value={layoutContextValue}>
      {content}
    </AppLayoutContext.Provider>
  );
});

// NavLink accesses layout directly
export const NavLink = forwardRef(function NavLink(props, ref) {
  const { layout } = useAppLayoutContext();
  // No prop drilling!
});
```

**Use when:** Many nested components need access, >3 levels of prop drilling, global state (theme, auth).  
**Don't use when:** 1-2 levels of nesting (props fine), high-frequency updates (re-renders all consumers).

**Performance tip:** Split contexts by update frequency - separate user/theme/settings contexts instead of one combined context.

---

### State Lifting

**Pattern:** Move state to common ancestor to share between siblings.

```tsx
// ❌ WRONG - Siblings can't communicate
<Parent><InputA /><InputB /></Parent>

// ✅ CORRECT - Lift state to parent
function Parent() {
  const [value, setValue] = useState('');
  return (
    <>
      <InputA value={value} onChange={setValue} />
      <InputB value={value} />
    </>
  );
}
```

**XMLUI Pattern:** Container-based state flows down automatically:
```tsx
<Stack var.selectedId="{null}">
  <Button onClick={"{() => selectedId = 'item1'}" />
  <Display value="{selectedId}" />
</Stack>
```

**Use when:** Siblings need to coordinate, parent orchestrates behavior.  
**Don't use when:** State only used by one component, excessive prop drilling (use context).

---

### Controlled vs Uncontrolled Components

**Controlled:** Parent manages state via `value` prop.
```tsx
function Controlled({ value, onChange }: Props) {
  return <input value={value} onChange={e => onChange(e.target.value)} />;
}
```

**Uncontrolled:** Component manages own state via `initialValue`.
```tsx
function Uncontrolled({ initialValue = '', onDidChange }: Props) {
  const [value, setValue] = useState(initialValue);
  return <input value={value} onChange={e => { setValue(e.target.value); onDidChange?.(e.target.value); }} />;
}
```

**Hybrid (XMLUI pattern):** Support both modes.
```tsx
function Flexible({ value, initialValue = '', onDidChange }: Props) {
  const [localValue, setLocalValue] = useState(initialValue);
  
  useEffect(() => {
    if (value !== undefined) setLocalValue(value);
  }, [value]);
  
  const handleChange = (e) => {
    setLocalValue(e.target.value);
    onDidChange?.(e.target.value);
  };
  
  return <input value={localValue} onChange={handleChange} />;
}
```

**Use controlled:** Validate/format input, value affects other UI, programmatic changes.  
**Use uncontrolled:** Simple forms (read on submit), performance critical.  
**Use hybrid:** Reusable component libraries.

---

### Compound Components

**Purpose:** Components work together as cohesive unit, sharing state via context.

```tsx
const TabsContext = createContext<{
  activeTab: string;
  setActiveTab: (id: string) => void;
} | null>(null);

function Tabs({ children }: Props) {
  const [activeTab, setActiveTab] = useState('tab1');
  return (
    <TabsContext.Provider value={{ activeTab, setActiveTab }}>
      <div className="tabs">{children}</div>
    </TabsContext.Provider>
  );
}

function Tab({ id, children }: Props) {
  const { activeTab, setActiveTab } = useContext(TabsContext)!;
  return (
    <button
      className={activeTab === id ? 'active' : ''}
      onClick={() => setActiveTab(id)}
    >
      {children}
    </button>
  );
}

Tabs.Tab = Tab;
Tabs.Panel = TabPanel;

// Usage - Flexible composition
<Tabs>
  <Tabs.Tab id="tab1">First</Tabs.Tab>
  <Tabs.Tab id="tab2">Second</Tabs.Tab>
  <Tabs.Panel id="tab1">Content 1</Tabs.Panel>
  <Tabs.Panel id="tab2">Content 2</Tabs.Panel>
</Tabs>
```

**Use when:** Tightly coupled components (tabs, accordion), need flexible composition, building libraries.  
**Don't use when:** Simple parent-child, no shared state, prop drilling is simple.

---

### Advanced Patterns

**Provider Composition:**
```tsx
function AppProviders({ children }: Props) {
  return (
    <ThemeProvider>
      <AuthProvider>
        <RouterProvider>
          {children}
        </RouterProvider>
      </AuthProvider>
    </ThemeProvider>
  );
}
```

**Async Initialization:**
```tsx
function AuthProvider({ children }: Props) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    checkAuth().then(user => { setUser(user); setLoading(false); });
  }, []);
  
  if (loading) return <LoadingScreen />;
  return <AuthContext.Provider value={{ user }}>{children}</AuthContext.Provider>;
}
```

**Reducer with Immer (XMLUI):**
```tsx
// StateContainer reducer
export function createContainerReducer(debugView: IDebugViewContext) {
  return produce((state: ContainerState, action: ContainerAction) => {
    switch (action.type) {
      case ContainerActionKind.COMPONENT_STATE_CHANGED:
        state[uid] = { ...state[uid], ...action.payload.state };
        break;
    }
  });
}
```

---

## React Performance Optimization Patterns

This section covers React's performance optimization tools and patterns. **Always profile before optimizing**—premature optimization adds complexity without real benefits.

### Core Optimization Hooks

#### `useMemo` - Computation Caching

Cache expensive calculations between renders.

```tsx
const filtered = useMemo(() => 
  items.filter(item => item.includes(filter)), 
  [items, filter]
);
```

**Use when:** Computation is expensive (>10ms), creating objects/arrays for memoized children, or calculations in dependency arrays.  
**Don't use when:** Computation is cheap (<1ms), result used only once, or component rarely re-renders.

#### `useCallback` - Function Caching

Cache function definitions to prevent child re-renders.

```tsx
const handleClick = useCallback(() => {
  doSomething(value);
}, [value]);
```

**Use when:** Passing callbacks to memoized children or to dependency arrays.  
**Don't use when:** Function isn't passed to memoized components or deps arrays.

**Note:** `useCallback(fn, deps)` is equivalent to `useMemo(() => fn, deps)`.

#### `useTransition` - Non-Urgent Updates

Mark state updates as low-priority to keep UI responsive.

```tsx
const [isPending, startTransition] = useTransition();

startTransition(() => {
  setExpensiveState(newValue); // Won't block UI
});
```

**Use when:** Updating expensive state that doesn't need immediate feedback (filtering large lists, complex calculations).

#### `memo` - Component Memoization

Prevent re-renders when props haven't changed.

```tsx
const MemoChild = memo(function MemoChild({ data }: Props) {
  return <div>{data.value}</div>;
});
```

**Use when:** Component renders frequently with same props, has expensive rendering, or is in large lists.  
**Don't use when:** Component rarely re-renders, props change every render, or rendering is cheap.

**Important:** `memo` only works if props are stable. Use `useMemo`/`useCallback` for object/function props.

---

### Memoization Strategy Pattern

**Principle:** `memo` + `useMemo` + `useCallback` work together. `memo` prevents re-renders, but only if props stay stable. Use `useMemo`/`useCallback` to keep props stable.

#### The Memoization Cascade

```tsx
// ❌ ANTI-PATTERN - memo without stable props
const Child = memo(({ data, onClick }: Props) => <div onClick={onClick}>{data.value}</div>);

function Parent() {
  return <Child data={{ value: 123 }} onClick={() => {}} />; // New refs every render!
}

// ✅ CORRECT - memo with stable props
function Parent() {
  const data = useMemo(() => ({ value: 123 }), []);
  const onClick = useCallback(() => console.log('clicked'), []);
  return <Child data={data} onClick={onClick} />;
}
```

#### Decision Tree

1. **Performance problem?** No → Don't optimize. Yes → Step 2.
2. **What's the cause?**
   - Parent re-renders often → Use `memo()` on child
   - Expensive computation → Use `useMemo()` on calculation  
   - New function props → Use `useCallback()` on function
3. **Passing objects/arrays/functions to memoized component?** Yes → Memoize those too.

#### Common Patterns

```tsx
// Pattern 1: Context values
const contextValue = useMemo(() => ({
  state,
  setState,
  isLoading: state.status === 'loading',
}), [state]);

// Pattern 2: Event handlers with deps
const handleSearch = useCallback(() => {
  if (query.length >= minLength) onSearch(query);
}, [query, minLength, onSearch]);

// Pattern 3: Expensive selectors
const filteredData = useMemo(() => {
  return data.filter(item => item.name.includes(filter)).sort((a, b) => a.name.localeCompare(b.name));
}, [data, filter]);

// Pattern 4: Derived state
const summary = useMemo(() => ({
  total: items.reduce((sum, item) => sum + item.price * item.quantity, 0),
  itemCount: items.reduce((sum, item) => sum + item.quantity, 0),
}), [items]);
```

#### Anti-Patterns

```tsx
// ❌ Over-memoization
const greeting = useMemo(() => `Hello, ${name}`, [name]); // Too simple!

// ❌ Incomplete chain
<MemoChild config={{ theme: 'dark' }} />; // New object defeats memo

// ❌ Unstable dependencies
useMemo(() => formatUser(user), [user]); // user object recreated every render
// ✅ Fix: useMemo(() => formatUser(user), [user.id, user.name]);
```

#### Checklist

**✅ DO memoize:**
- Components rendering frequently with same props
- Expensive computations (>10ms)
- Objects/arrays/functions passed to memoized children
- Context values

**❌ DON'T memoize:**
- Cheap operations (<1ms)
- Values that change every render
- Without profiling first

---

### Virtualization Pattern

**Purpose:** Render only visible items in large lists by using "windowing." Instead of rendering 10,000 items, render only ~10 visible items.

**Libraries:** XMLUI uses two based on component needs:
- **virtua** (Tree, List) - Chat interfaces, reverse scrolling, auto-sizing, fixed-size lists
- **@tanstack/react-virtual** (Table) - Dynamic measurements, flexible

**Library Comparison:**

| Feature | virtua | @tanstack/react-virtual |
|---------|--------|------------------------|
| **Bundle Size** | ~6KB | ~4KB |
| **API** | Render props | Hooks |
| **Dynamic heights** | Automatic | Automatic |
| **Reverse scroll** | ✅ Built-in | Manual |
| **Auto-sizing** | ✅ Built-in | Manual |
| **XMLUI Usage** | Tree, List | Table |

**virtua Example (XMLUI List):**

```tsx
import { Virtualizer } from 'virtua';

function ChatList({ messages }: Props) {
  return (
    <Virtualizer count={messages.length}>
      {(index) => {
        const msg = messages[index];
        return (
          <div key={msg.id}>
            <div>{msg.author}</div>
            <div>{msg.content}</div>
          </div>
        );
      }}
    </Virtualizer>
  );
}
```

**@tanstack/react-virtual Example:**

```tsx
import { useVirtualizer } from '@tanstack/react-virtual';

function DataTable({ rows }: Props) {
  const tableRef = useRef<HTMLDivElement>(null);
  
  const rowVirtualizer = useVirtualizer({
    count: rows.length,
    getScrollElement: () => tableRef.current,
    estimateSize: () => 30,
    overscan: 5,
  });
  
  return (
    <div ref={tableRef} style={{ height: '400px', overflow: 'auto' }}>
      {rowVirtualizer.getVirtualItems().map((virtualRow) => (
        <div
          key={virtualRow.index}
          ref={(el) => rowVirtualizer.measureElement(el)}
          style={{ transform: `translateY(${virtualRow.start}px)` }}
        >
          {rows[virtualRow.index].content}
        </div>
      ))}
    </div>
  );
}
```

**Critical Rules:**
1. **Memoize row components** - Use `React.memo()`
2. **Apply transform/style** - Required for positioning (@tanstack)
3. **Memoize data** - Prevent row re-renders
4. **Handle scroll container** - Each library handles sizing differently

**Performance Impact:**

| Items | Normal | Virtualized | Improvement |
|-------|--------|-------------|-------------|
| 100 | 50ms | 10ms | 5x faster |
| 1,000 | 500ms | 10ms | 50x faster |
| 10,000 | 5s | 10ms | 500x faster |

**When to Use:**
- ✅ >100 items
- ✅ Uniform item sizes
- ✅ Scrollable datasets
- ❌ <100 items (overhead not worth it)
- ❌ Already paginated
- ❌ Complex/unpredictable heights

---

### Rate Limiting: Debouncing and Throttling

**Purpose:** Control the frequency of expensive operations during high-frequency events (user input, scrolling, resizing).

**Key Difference:**
- **Debouncing**: Wait until activity **stops** (search, autosave)
- **Throttling**: Execute at **regular intervals** during activity (scroll, mousemove)

```tsx
// User types "search" continuously

// DEBOUNCING: Executes ONCE after user stops typing
// Timeline: [type...type...type...STOP] → Execute

// THROTTLING: Executes EVERY 200ms while typing  
// Timeline: Execute → [200ms] → Execute → [200ms] → Execute...
```

#### Debouncing Solutions

**1. useDeferredValue (React 18+) - Recommended**

```tsx
function Search() {
  const [query, setQuery] = useState('');
  const deferredQuery = useDeferredValue(query);
  
  const results = useMemo(() => {
    if (deferredQuery.length < 2) return [];
    return performSearch(deferredQuery);
  }, [deferredQuery]);
  
  return (
    <>
      <input value={query} onChange={e => setQuery(e.target.value)} />
      <ResultsList results={results} />
    </>
  );
}
```

**2. Custom useDebounce Hook**

```tsx
function useDebounce<T>(value: T, delay: number = 500): T {
  const [debouncedValue, setDebouncedValue] = useState<T>(value);
  
  useEffect(() => {
    const timer = setTimeout(() => setDebouncedValue(value), delay);
    return () => clearTimeout(timer);
  }, [value, delay]);
  
  return debouncedValue;
}

// Usage
const debouncedQuery = useDebounce(query, 300);
```

**3. Lodash debounce**

```tsx
const debouncedSave = useMemo(
  () => debounce((text: string) => saveToServer(text), 1000),
  []
);

useEffect(() => {
  return () => debouncedSave.cancel();
}, [debouncedSave]);
```

#### Throttling Solutions

**1. Custom useThrottle Hook**

```tsx
function useThrottle<T extends (...args: any[]) => any>(
  callback: T,
  delay: number = 200
): T {
  const lastRun = useRef(Date.now());
  
  return useCallback((...args: Parameters<T>) => {
    const now = Date.now();
    if (now - lastRun.current >= delay) {
      lastRun.current = now;
      return callback(...args);
    }
  }, [callback, delay]) as T;
}

// Usage
const handleScroll = useThrottle(() => {
  setScrollPos(window.scrollY);
}, 200);
```

**2. Lodash throttle**

```tsx
const throttledScroll = useMemo(
  () => throttle(() => {
    updateScrollPosition();
  }, 200, {
    leading: true,   // Execute on first call
    trailing: true   // Execute after interval ends
  }),
  []
);

useEffect(() => {
  return () => throttledScroll.cancel();
}, [throttledScroll]);
```

#### XMLUI Examples

**Debounced Search (Search.tsx):**
```tsx
function Search({ data, limit }: Props) {
  const [inputValue, setInputValue] = useState("");
  const debouncedValue = useDeferredValue(inputValue);
  
  const results = useMemo(() => {
    if (debouncedValue.length <= 1) return [];
    return fuse.search(debouncedValue, { limit });
  }, [debouncedValue, limit]);
  
  return (
    <>
      <input value={inputValue} onChange={e => setInputValue(e.target.value)} />
      <SearchResults results={results} />
    </>
  );
}
```

**Throttled Change Listener (ChangeListenerNative.tsx):**
```tsx
function ChangeListener({ listenTo, onChange, throttleWaitInMs = 0 }: Props) {
  const throttledOnChange = useMemo(() => {
    if (throttleWaitInMs !== 0 && onChange) {
      return throttle(onChange, throttleWaitInMs, { leading: true });
    }
    return onChange;
  }, [onChange, throttleWaitInMs]);
  
  useEffect(() => {
    if (throttledOnChange) {
      throttledOnChange({ prevValue, newValue: listenTo });
    }
  }, [listenTo, throttledOnChange]);
}
```

**Async Throttle for Validation (misc.ts):**
```tsx
function asyncThrottle<F extends (...args: any[]) => Promise<any>>(
  func: F,
  wait?: number,
  options?: ThrottleSettings
) {
  const throttled = throttle(
    (resolve, reject, args: Parameters<F>) => {
      void func(...args).then(resolve).catch(reject);
    },
    wait,
    options
  );
  
  return (...args: Parameters<F>): ReturnType<F> =>
    new Promise((resolve, reject) => {
      throttled(resolve, reject, args);
    }) as ReturnType<F>;
}
```

#### Decision Guide

| Scenario | Solution | Timing |
|----------|----------|--------|
| Search input | Debounce | 300ms |
| Form validation | Debounce | 500ms |
| Autosave | Debounce | 1000ms |
| Scroll position | Throttle | 100-200ms |
| Window resize | Throttle | 200-300ms |
| Mouse tracking | Throttle | 50-100ms |
| API rate limiting | Throttle | 500-1000ms |

#### Performance Impact

| Operation | Without | With (300ms) | Improvement |
|-----------|---------|--------------|-------------|
| Search (6 chars typed) | 6 API calls | 1 API call | 83% reduction |
| Scroll (1s) | ~60 events | 5 events | 92% reduction |
| Window resize | ~30 events | 5 events | 83% reduction |

#### Critical Rules

**1. Always memoize** rate-limited functions:
```tsx
// ❌ WRONG - Creates new function every render
const handle = debounce(() => search(), 500);

// ✅ CORRECT - Memoized
const handle = useMemo(() => debounce(() => search(), 500), []);
```

**2. Always cleanup**:
```tsx
useEffect(() => {
  return () => debouncedFn.cancel();
}, [debouncedFn]);
```

**3. Don't rate-limit UI state** - only side effects:
```tsx
// ❌ WRONG - UI lags
const handleChange = debounce((e) => setValue(e.target.value), 300);

// ✅ CORRECT - Immediate UI, debounced side effect
const handleChange = (e) => {
  setValue(e.target.value); // Instant
  debouncedSearch(e.target.value); // Delayed
};
```

**4. Choose appropriate delays**:
- Search: 300ms
- Autosave: 1000ms  
- Scroll/resize: 100-200ms
- Mousemove: 50ms

#### When to Use

**Debouncing:**
- ✅ Search, autosave, validation
- ✅ Wait for user to finish action
- ❌ Don't use for immediate feedback

**Throttling:**
- ✅ Scroll, resize, mousemove
- ✅ Execute during continuous activity
- ❌ Don't use when only final value matters

#### Resources

- [useDeferredValue](https://react.dev/reference/react/useDeferredValue) - React 18 docs
- [lodash.debounce](https://lodash.com/docs/#debounce) - Debounce docs
- [lodash.throttle](https://lodash.com/docs/#throttle) - Throttle docs
- [XMLUI Search](packages/xmlui-search/src/Search.tsx) - Production example

---

## React Event Handling Patterns

Patterns for handling user interactions efficiently and correctly in React applications.

### Event Delegation Pattern

**Purpose:** Handle events for multiple children at parent level instead of attaching handlers to each child.

**Benefits:**
- Fewer event listeners (better memory usage)
- Works with dynamically added/removed children
- Simplifies event handler management

```tsx
// ❌ ANTI-PATTERN - Handler on every item
function List({ items }: Props) {
  return (
    <ul>
      {items.map(item => (
        <li key={item.id} onClick={() => handleClick(item.id)}>
          {item.name}
        </li>
      ))}
    </ul>
  );
}

// ✅ CORRECT - Single handler on parent
function List({ items }: Props) {
  const handleClick = (e: React.MouseEvent<HTMLUListElement>) => {
    const target = e.target as HTMLElement;
    const li = target.closest('li');
    if (li) {
      const itemId = li.dataset.id;
      console.log('Clicked item:', itemId);
    }
  };
  
  return (
    <ul onClick={handleClick}>
      {items.map(item => (
        <li key={item.id} data-id={item.id}>
          {item.name}
        </li>
      ))}
    </ul>
  );
}
```

**XMLUI Example (Tree component):**
```tsx
function Tree({ items }: Props) {
  // Single click handler for entire tree
  const handleTreeClick = useCallback((e: React.MouseEvent) => {
    const target = e.target as HTMLElement;
    const treeItem = target.closest('[data-tree-item]');
    
    if (treeItem) {
      const itemId = treeItem.getAttribute('data-item-id');
      const action = target.getAttribute('data-action');
      
      if (action === 'expand') {
        toggleExpand(itemId);
      } else if (action === 'select') {
        selectItem(itemId);
      }
    }
  }, [toggleExpand, selectItem]);
  
  return (
    <div className="tree" onClick={handleTreeClick}>
      {renderTreeItems(items)}
    </div>
  );
}
```

**When to use:**
- Lists with many items (>50)
- Dynamic children (added/removed frequently)
- Multiple event types on same children
- Performance-critical rendering

**When NOT to use:**
- Few items (<10) - overhead not worth it
- Need precise event target info
- Event handler logic is complex per-item

---

### Synthetic Event Pattern

**Purpose:** React wraps native browser events in `SyntheticEvent` for cross-browser consistency.

**Key differences from native events:**

| Feature | Native Event | Synthetic Event |
|---------|-------------|-----------------|
| **Type** | Browser-specific | Unified React type |
| **Pooling (React 16)** | No | Yes (reused) |
| **Pooling (React 17+)** | No | No (deprecated) |
| **Properties** | Browser-specific | Normalized |
| **Access after handler** | ✅ Always available | ⚠️ Nullified (React 16 only) |

**Basic usage:**
```tsx
function Input() {
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    // e is SyntheticEvent, not native Event
    console.log(e.target.value); // ✅ Works
    console.log(e.currentTarget); // ✅ Works
    
    // Access native event if needed
    const nativeEvent = e.nativeEvent;
  };
  
  return <input onChange={handleChange} />;
}
```

**Event pooling (React 16 only):**
```tsx
// ❌ WRONG - Async access (React 16)
function Bad() {
  const handleClick = (e: React.MouseEvent) => {
    setTimeout(() => {
      console.log(e.target); // null in React 16!
    }, 1000);
  };
  return <button onClick={handleClick}>Click</button>;
}

// ✅ CORRECT - Persist event (React 16)
function Good() {
  const handleClick = (e: React.MouseEvent) => {
    e.persist(); // Keep event alive
    setTimeout(() => {
      console.log(e.target); // ✅ Works
    }, 1000);
  };
  return <button onClick={handleClick}>Click</button>;
}

// ✅ BETTER - Extract values (React 16 & 17+)
function Better() {
  const handleClick = (e: React.MouseEvent) => {
    const target = e.target; // Capture immediately
    setTimeout(() => {
      console.log(target); // ✅ Works in all versions
    }, 1000);
  };
  return <button onClick={handleClick}>Click</button>;
}
```

**Note:** React 17+ removed event pooling, so `e.persist()` is no longer needed.

**Common event types:**
```tsx
// Mouse events
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {};
const handleDoubleClick = (e: React.MouseEvent) => {};

// Keyboard events
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
  if (e.key === 'Enter') submitForm();
};

// Form events
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {};
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
  e.preventDefault();
};

// Focus events
const handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {};
const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {};

// Clipboard events
const handleCopy = (e: React.ClipboardEvent) => {};
const handlePaste = (e: React.ClipboardEvent) => {
  const text = e.clipboardData.getData('text');
};

// Drag events
const handleDragStart = (e: React.DragEvent) => {};
const handleDrop = (e: React.DragEvent) => {
  e.preventDefault();
  const data = e.dataTransfer.getData('text');
};
```

**Accessing native event:**
```tsx
function Component() {
  const handleClick = (e: React.MouseEvent) => {
    // React synthetic event
    console.log(e.currentTarget); // Element handler is attached to
    console.log(e.target); // Element that triggered event
    
    // Native browser event
    const nativeEvent = e.nativeEvent;
    console.log(nativeEvent); // MouseEvent object
  };
  
  return <button onClick={handleClick}>Click</button>;
}
```

---

### Event Callback Composition Pattern

**Purpose:** Combine multiple event handlers into a single handler, useful for library components that accept user callbacks.

**Pattern 1: Sequential execution**
```tsx
function composeHandlers<E>(...handlers: Array<((e: E) => void) | undefined>) {
  return (event: E) => {
    handlers.forEach(handler => {
      if (handler) {
        handler(event);
      }
    });
  };
}

// Usage
function Button({ onClick, onClickInternal }: Props) {
  const handleClick = composeHandlers(onClickInternal, onClick);
  return <button onClick={handleClick}>Click</button>;
}
```

**Pattern 2: Conditional execution (stop on preventDefault)**
```tsx
function composeEventHandlers<E extends React.SyntheticEvent>(
  internalHandler?: (e: E) => void,
  externalHandler?: (e: E) => void
) {
  return (event: E) => {
    internalHandler?.(event);
    
    // If internal handler called preventDefault, stop
    if (!event.defaultPrevented) {
      externalHandler?.(event);
    }
  };
}

// Usage - XMLUI pattern
function Select({ onChange, onDidChange }: Props) {
  const handleInternalChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
    // Internal logic (validation, state updates)
    validateValue(e.target.value);
    
    // Prevent external handler if validation fails
    if (!isValid) {
      e.preventDefault();
    }
  };
  
  const handleChange = composeEventHandlers(handleInternalChange, onChange);
  
  return <select onChange={handleChange}>...</select>;
}
```

**Pattern 3: Merge handlers from props**
```tsx
function mergeEventHandlers<T extends React.SyntheticEvent>(
  ours: ((e: T) => void) | undefined,
  theirs: ((e: T) => void) | undefined
): ((e: T) => void) | undefined {
  if (!ours) return theirs;
  if (!theirs) return ours;
  
  return (event: T) => {
    ours(event);
    if (!event.defaultPrevented) {
      theirs(event);
    }
  };
}

// Usage - Wrapper component
function Wrapper({ children, onClick }: Props) {
  const internalClick = (e: React.MouseEvent) => {
    console.log('Wrapper clicked');
  };
  
  return cloneElement(children, {
    onClick: mergeEventHandlers(internalClick, children.props.onClick),
  });
}
```

**XMLUI Example (Container component):**
```tsx
function Container({ children, ...props }: Props, ref: Ref<HTMLElement>) {
  const renderedChild = renderChild(children);
  
  if (ref && renderedChild && isValidElement(renderedChild)) {
    // Merge event handlers from both Container and child
    const mergedProps = {
      ...renderedChild.props,
      onClick: composeEventHandlers(props.onClick, renderedChild.props.onClick),
      onKeyDown: composeEventHandlers(props.onKeyDown, renderedChild.props.onKeyDown),
      ref: composeRefs(ref, (renderedChild as any).ref),
    };
    
    return cloneElement(renderedChild, mergedProps);
  }
  
  return renderedChild;
}
```

**Pattern 4: Callback with additional args**
```tsx
function withArgs<E, T>(
  handler: ((e: E, ...args: T[]) => void) | undefined,
  ...args: T[]
) {
  if (!handler) return undefined;
  
  return (event: E) => {
    handler(event, ...args);
  };
}

// Usage
function List({ items, onItemClick }: Props) {
  return (
    <ul>
      {items.map(item => (
        <li key={item.id} onClick={withArgs(onItemClick, item.id)}>
          {item.name}
        </li>
      ))}
    </ul>
  );
}
```

**When to compose handlers:**
- Building reusable component libraries
- Wrapper components that add behavior
- Components with internal + external handlers
- Need to call parent handler conditionally

**Best practices:**
- Always check if handler exists before calling
- Respect `preventDefault()` and `stopPropagation()`
- Execute internal handlers first
- Document composition order clearly

---

## React Lifecycle and Effect Patterns

Patterns for managing side effects, synchronization, and component lifecycle in React applications.

### `useEffect` - Side Effects and Lifecycle

**Purpose:** Run side effects after render (data fetching, subscriptions, DOM manipulation).

**Syntax:** `useEffect(() => { /* effect */ return () => { /* cleanup */ } }, [dependencies])`

**Basic usage:**
```tsx
function UserProfile({ userId }: Props) {
  const [user, setUser] = useState(null);
  
  useEffect(() => {
    // Effect runs after render
    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(data => setUser(data));
  }, [userId]); // Re-run when userId changes
  
  return <div>{user?.name}</div>;
}
```

**With async/await:**
```tsx
useEffect(() => {
  // Can't make callback async directly, use IIFE
  (async () => {
    const res = await fetch(`/api/users/${userId}`);
    const data = await res.json();
    setUser(data);
  })();
}, [userId]);
```

**Use when:** Data fetching, subscriptions, event listeners, DOM manipulation, integrating with non-React libraries.  
**Avoid when:** Computing derived values (use `useMemo`), handling events (use handlers), initializing state (use initializer).

---

### Effect Cleanup Pattern

**Purpose:** Properly clean up subscriptions, timers, and event listeners to prevent memory leaks.

**Pattern: Always return cleanup function for subscriptions**
```tsx
function Chat({ roomId }: Props) {
  useEffect(() => {
    const connection = createConnection(roomId);
    connection.connect();
    
    // ✅ Cleanup runs before next effect and on unmount
    return () => {
      connection.disconnect();
    };
  }, [roomId]);
  
  return <div>Connected to {roomId}</div>;
}
```

**Pattern: Cancel async operations**
```tsx
function DataComponent({ url }: Props) {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    let cancelled = false;
    
    fetch(url)
      .then(res => res.json())
      .then(data => {
        if (!cancelled) setData(data);
      });
    
    // ✅ Prevent state updates after unmount
    return () => { cancelled = true; };
  }, [url]);
  
  return <div>{JSON.stringify(data)}</div>;
}
```

**Pattern: Remove event listeners**
```tsx
function WindowSize() {
  const [size, setSize] = useState({ width: 0, height: 0 });
  
  useEffect(() => {
    const handleResize = () => {
      setSize({ width: window.innerWidth, height: window.innerHeight });
    };
    
    window.addEventListener('resize', handleResize);
    handleResize(); // Initial size
    
    // ✅ Always remove listeners
    return () => window.removeEventListener('resize', handleResize);
  }, []);
  
  return <div>{size.width} x {size.height}</div>;
}
```

**Pattern: Clear timers and intervals**
```tsx
function Timer() {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    const interval = setInterval(() => {
      setCount(c => c + 1);
    }, 1000);
    
    // ✅ Clear interval on unmount
    return () => clearInterval(interval);
  }, []);
  
  return <div>{count}s</div>;
}
```

**Pattern: Unsubscribe from external stores**
```tsx
function ExternalStore({ store }: Props) {
  const [value, setValue] = useState(store.getValue());
  
  useEffect(() => {
    const unsubscribe = store.subscribe(newValue => {
      setValue(newValue);
    });
    
    // ✅ Unsubscribe when component unmounts
    return unsubscribe;
  }, [store]);
  
  return <div>{value}</div>;
}
```

**Critical rules:**
- Return cleanup for subscriptions, listeners, timers
- Use cancellation flags for async operations
- Cleanup runs before next effect and on unmount
- Don't forget to remove event listeners

---

### Effect Dependencies Pattern

**Purpose:** Correctly manage dependency arrays to avoid stale closures and unnecessary re-runs.

**Anti-pattern: Missing dependencies (stale closure bug)**
```tsx
// ❌ WRONG - Stale closure
function Counter() {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    setInterval(() => {
      console.log(count); // Always logs 0!
    }, 1000);
  }, []); // Missing count
  
  return <button onClick={() => setCount(count + 1)}>Increment</button>;
}

// ✅ CORRECT - Use functional update
useEffect(() => {
  setInterval(() => {
    setCount(c => c + 1); // Uses latest value
  }, 1000);
}, []); // No dependencies needed
```

**Anti-pattern: Object/array in dependencies**
```tsx
// ❌ WRONG - Object recreated every render
function Component({ config }: Props) {
  useEffect(() => {
    fetchData(config);
  }, [config]); // Runs every render if config is new object
}

// ✅ CORRECT - Destructure primitive values
useEffect(() => {
  fetchData(config);
}, [config.id, config.filter]); // Only re-run when these change
```

**Pattern: Empty array = run once on mount**
```tsx
useEffect(() => {
  // Initialization logic
  initializeApp();
  
  return () => {
    // Cleanup on unmount
    cleanupApp();
  };
}, []); // Runs once on mount, cleanup on unmount
```

**Pattern: No array = run after every render**
```tsx
useEffect(() => {
  // Runs after every render (rarely needed)
  updateDocumentTitle(`Page - ${count}`);
}); // No dependency array
```

**Pattern: Avoid callback dependencies with useRef**
```tsx
function Component({ callback }: Props) {
  const callbackRef = useRef(callback);
  
  // Keep ref updated
  useEffect(() => {
    callbackRef.current = callback;
  }, [callback]);
  
  useEffect(() => {
    const interval = setInterval(() => {
      // ✅ Always uses latest callback
      callbackRef.current();
    }, 1000);
    
    return () => clearInterval(interval);
  }, []); // No callback in deps
}
```

**Common mistakes:**
```tsx
// ❌ Wrong - Missing dependencies
useEffect(() => {
  doSomething(prop); // prop not in deps
}, []);

// ❌ Wrong - Object identity
useEffect(() => {
  fetchData(user);
}, [user]); // user object changes every render

// ❌ Wrong - Function identity
useEffect(() => {
  callback();
}, [callback]); // callback recreated every render

// ✅ Correct - Destructure objects
useEffect(() => {
  fetchData({ id: user.id, name: user.name });
}, [user.id, user.name]);

// ✅ Correct - Memoize callbacks
const memoizedCallback = useCallback(callback, [dep]);
useEffect(() => {
  memoizedCallback();
}, [memoizedCallback]);
```

**ESLint rule:** Always enable `react-hooks/exhaustive-deps` to catch dependency issues.

---

### Layout Effect Pattern

**Purpose:** Run effects synchronously after DOM mutations but before browser paint to prevent visual flickering.

**When to use `useLayoutEffect`:**

**Pattern: DOM measurements before paint**
```tsx
function Tooltip() {
  const [position, setPosition] = useState({ x: 0, y: 0 });
  const ref = useRef<HTMLDivElement>(null);
  
  // ✅ CORRECT - Measure before paint
  useLayoutEffect(() => {
    if (ref.current) {
      const rect = ref.current.getBoundingClientRect();
      setPosition({
        x: rect.left + rect.width / 2,
        y: rect.top - 10,
      });
    }
  }, []);
  
  return <div ref={ref} style={{ left: position.x, top: position.y }}>Tooltip</div>;
}

// ❌ WRONG - useEffect causes visible flicker
useEffect(() => {
  // DOM measurements happen AFTER paint
  // User sees element jump from old to new position
}, []);
```

**Pattern: Synchronize scroll position**
```tsx
function ScrollSync({ targetRef }: Props) {
  useLayoutEffect(() => {
    if (targetRef.current) {
      // ✅ Scroll before paint, no flicker
      targetRef.current.scrollTop = savedPosition;
    }
  }, [targetRef, savedPosition]);
}
```

**Pattern: Prevent layout shift**
```tsx
function AutoResizeTextarea({ value }: Props) {
  const ref = useRef<HTMLTextAreaElement>(null);
  
  useLayoutEffect(() => {
    if (ref.current) {
      // ✅ Adjust height before paint
      ref.current.style.height = 'auto';
      ref.current.style.height = `${ref.current.scrollHeight}px`;
    }
  }, [value]);
  
  return <textarea ref={ref} value={value} />;
}
```

**Pattern: Third-party DOM library integration**
```tsx
function Chart({ data }: Props) {
  const containerRef = useRef<HTMLDivElement>(null);
  
  useLayoutEffect(() => {
    if (containerRef.current) {
      // ✅ Initialize library before paint
      const chart = new ChartLibrary(containerRef.current);
      chart.render(data);
      
      return () => chart.destroy();
    }
  }, [data]);
  
  return <div ref={containerRef} />;
}
```

**Comparison: useEffect vs useLayoutEffect**

| Aspect | `useEffect` | `useLayoutEffect` |
|--------|------------|-------------------|
| **Timing** | After paint (async) | Before paint (sync) |
| **Blocks rendering** | ❌ No | ✅ Yes |
| **Use for** | Data fetching, subscriptions | DOM measurements, preventing flicker |
| **Performance** | Better (non-blocking) | Worse (blocks paint) |
| **SSR** | ✅ Works | ⚠️ Warning (no DOM on server) |

**When to use each:**
- **useEffect**: 99% of cases - data fetching, subscriptions, analytics
- **useLayoutEffect**: DOM measurements, scroll sync, preventing visual flicker

**Warning:** `useLayoutEffect` blocks visual updates. Only use when you need synchronous DOM access before paint.

**SSR consideration:**
```tsx
// ⚠️ useLayoutEffect doesn't run on server
useLayoutEffect(() => {
  // This code only runs in browser
  measureDOM();
}, []);

// ✅ Better: Use useEffect for SSR-compatible code
useEffect(() => {
  measureDOM();
}, []);
```

---

### Insertion Effect Pattern

**Purpose:** Insert styles into DOM before layout effects run. Used by CSS-in-JS libraries.

**Syntax:** `useInsertionEffect(() => { /* insert styles */ }, [dependencies])`

**Effect execution order:**
1. `useInsertionEffect` - Insert styles
2. `useLayoutEffect` - Measure layout (reads styles)
3. Browser paints
4. `useEffect` - Other side effects

**Pattern: CSS-in-JS style injection**
```tsx
function useCSS(rule: string) {
  useInsertionEffect(() => {
    // ✅ Inject styles before layout reads
    const style = document.createElement('style');
    style.textContent = rule;
    document.head.appendChild(style);
    
    return () => document.head.removeChild(style);
  }, [rule]);
}

// Usage
function Button({ color }: Props) {
  useCSS(`
    .button-${color} {
      background: ${color};
      border: 1px solid ${darken(color)};
    }
  `);
  
  return <button className={`button-${color}`}>Click</button>;
}
```

**Pattern: Dynamic theme injection (XMLUI)**
```tsx
function ThemeProvider({ theme, children }: Props) {
  useInsertionEffect(() => {
    // ✅ Insert theme CSS before components measure
    const styleElement = document.createElement('style');
    styleElement.id = 'theme-styles';
    styleElement.textContent = generateThemeCSS(theme);
    document.head.appendChild(styleElement);
    
    return () => {
      document.getElementById('theme-styles')?.remove();
    };
  }, [theme]);
  
  return children;
}
```

**Pattern: Critical CSS injection**
```tsx
function useCriticalCSS(css: string) {
  useInsertionEffect(() => {
    // ✅ Inject before any layout calculations
    const style = document.createElement('style');
    style.setAttribute('data-critical', 'true');
    style.textContent = css;
    document.head.insertBefore(style, document.head.firstChild);
    
    return () => style.remove();
  }, [css]);
}
```

**When to use:**
- Building CSS-in-JS libraries
- Dynamic style generation
- Theme system implementation
- Critical CSS injection

**When NOT to use:**
- Regular application code (use `useEffect`)
- Static stylesheets (use `<link>` tags)
- Non-style DOM manipulation

**Note:** Rarely used directly in application code. Primarily for library authors. XMLUI uses this in `StyleContext` for theme style injection.

**Comparison with other effects:**

```tsx
// ❌ WRONG - useEffect runs too late
useEffect(() => {
  injectStyles(); // Styles added after layout measured
}, []);

// ❌ WRONG - useLayoutEffect causes double layout
useLayoutEffect(() => {
  injectStyles(); // Layout measured, then styles added, then re-measured
}, []);

// ✅ CORRECT - useInsertionEffect runs first
useInsertionEffect(() => {
  injectStyles(); // Styles ready before any layout measurement
}, []);
```

---

### Effect Best Practices Summary

**1. Always clean up:**
```tsx
useEffect(() => {
  const subscription = subscribe();
  return () => subscription.unsubscribe(); // ✅ Cleanup
}, []);
```

**2. Handle dependencies correctly:**
```tsx
// ✅ Include all dependencies
useEffect(() => {
  doSomething(prop, state);
}, [prop, state]);

// ✅ Or use functional updates
useEffect(() => {
  setState(prev => prev + 1);
}, []); // No state dependency needed
```

**3. Choose the right effect hook:**
- `useEffect` - Default choice (async, after paint)
- `useLayoutEffect` - DOM measurements, prevent flicker (sync, before paint)
- `useInsertionEffect` - CSS-in-JS only (before layout)

**4. Avoid common pitfalls:**
```tsx
// ❌ Don't use objects in deps
useEffect(() => {}, [config]); // Runs every render

// ✅ Destructure primitive values
useEffect(() => {}, [config.id, config.name]);

// ❌ Don't make effect callback async
useEffect(async () => {}, []); // Type error

// ✅ Use IIFE for async
useEffect(() => {
  (async () => await fetch())();
}, []);
```

**5. Profile before optimizing:**
- Most effects are cheap
- Don't prematurely optimize with `useLayoutEffect`
- Measure actual performance impact

---

## `useRef` - Persistent Mutable References

**Purpose:** Store mutable values that persist across renders without triggering re-renders.

**Syntax:** `const ref = useRef(initialValue)`

### DOM References

```tsx
function TextInput() {
  const inputRef = useRef<HTMLInputElement>(null);
  
  const focusInput = () => {
    inputRef.current?.focus();
  };
  
  return (
    <div>
      <input ref={inputRef} />
      <button onClick={focusInput}>Focus</button>
    </div>
  );
}
```

### Storing Mutable Values

```tsx
function Timer() {
  const [count, setCount] = useState(0);
  const intervalRef = useRef<NodeJS.Timeout>();
  
  useEffect(() => {
    intervalRef.current = setInterval(() => {
      setCount(c => c + 1);
    }, 1000);
    
    return () => clearInterval(intervalRef.current);
  }, []);
  
  const stop = () => {
    clearInterval(intervalRef.current);
  };
  
  return (
    <div>
      {count} seconds
      <button onClick={stop}>Stop</button>
    </div>
  );
}
```

### Avoiding Stale Closures

```tsx
function Component({ callback }: Props) {
  const callbackRef = useRef(callback);
  
  // Keep ref updated with latest callback
  useEffect(() => {
    callbackRef.current = callback;
  }, [callback]);
  
  useEffect(() => {
    const interval = setInterval(() => {
      // Always uses latest callback
      callbackRef.current();
    }, 1000);
    
    return () => clearInterval(interval);
  }, []); // No callback dependency needed
  
  return <div>Running...</div>;
}
```

### Common Patterns in XMLUI

**Previous Value Tracking:**
```tsx
function usePrevious<T>(value: T): T | undefined {
  const ref = useRef<T>();
  
  useEffect(() => {
    ref.current = value;
  }, [value]);
  
  return ref.current;
}

function Component({ count }: Props) {
  const prevCount = usePrevious(count);
  
  return <div>Now: {count}, Before: {prevCount}</div>;
}
```

### Key Differences: useState vs useRef

| Feature | `useState` | `useRef` |
|---------|-----------|---------|
| Triggers re-render | ✅ Yes | ❌ No |
| Persists across renders | ✅ Yes | ✅ Yes |
| Use for UI state | ✅ Yes | ❌ No |
| Use for DOM access | ❌ No | ✅ Yes |
| Use for mutable timers/intervals | ❌ No | ✅ Yes |

---

## `useId` - Unique ID Generation

**Purpose:** Generate stable unique IDs for accessibility attributes.

**Syntax:** `const id = useId()`

### Basic Usage

```tsx
function FormField({ label }: Props) {
  const id = useId();
  
  return (
    <div>
      <label htmlFor={id}>{label}</label>
      <input id={id} />
    </div>
  );
}
```

### Multiple IDs

```tsx
function ComplexForm() {
  const id = useId();
  
  return (
    <div>
      <label htmlFor={`${id}-name`}>Name</label>
      <input id={`${id}-name`} aria-describedby={`${id}-name-hint`} />
      <span id={`${id}-name-hint`}>Enter your full name</span>
      
      <label htmlFor={`${id}-email`}>Email</label>
      <input id={`${id}-email`} />
    </div>
  );
}
```

**Why not just use a counter?** `useId` generates IDs that are stable across server and client rendering, preventing hydration mismatches.

---

## `forwardRef` - Ref Forwarding to Child Components

**Purpose:** Allow parent components to access DOM nodes or component instances of child components by forwarding refs through component boundaries.

**Syntax:** `const Component = forwardRef((props, ref) => { ... })`

### Basic Usage

```tsx
const TextInput = forwardRef<HTMLInputElement, Props>(
  function TextInput({ label, ...props }, forwardedRef) {
    return (
      <div>
        <label>{label}</label>
        <input ref={forwardedRef} {...props} />
      </div>
    );
  }
);

// Parent can now access the input element
function Form() {
  const inputRef = useRef<HTMLInputElement>(null);
  
  const focusInput = () => {
    inputRef.current?.focus();
  };
  
  return (
    <div>
      <TextInput ref={inputRef} label="Name" />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
}
```

### TypeScript Generic Syntax

```tsx
// Explicitly type both the ref and props
const Component = forwardRef<RefType, PropsType>(
  function Component(props, ref) {
    return <div ref={ref}>...</div>;
  }
);

// Example with HTMLDivElement
const Card = forwardRef<HTMLDivElement, CardProps>(
  function Card({ children, className }, ref) {
    return (
      <div ref={ref} className={className}>
        {children}
      </div>
    );
  }
);
```

**Why explicit typing matters:**

Without generic syntax, TypeScript infers types from the function signature, which can lead to several issues:

```tsx
// ❌ WRONG - Without explicit generics
const Input = forwardRef(function Input(props: Props, ref) {
  // TypeScript infers ref as: ForwardedRef<unknown>
  // This means:
  // 1. No autocomplete for ref.current properties
  // 2. No type checking when assigning ref to JSX elements
  // 3. Parent components can pass wrong ref type without errors
  return <input ref={ref} />; // Type error: ref might not be compatible!
});

// Usage - TypeScript won't catch this error:
const divRef = useRef<HTMLDivElement>(null);
<Input ref={divRef} /> // Should error but doesn't - expecting HTMLInputElement!

// ✅ CORRECT - With explicit generics
const Input = forwardRef<HTMLInputElement, Props>(
  function Input(props, ref) {
    // TypeScript knows ref is: ForwardedRef<HTMLInputElement>
    // Benefits:
    // 1. Autocomplete works: ref.current?.focus()
    // 2. Type checking ensures ref matches JSX element
    // 3. Parent must pass correct ref type
    return <input ref={ref} />; // Type safe!
  }
);

// Usage - TypeScript catches the error:
const divRef = useRef<HTMLDivElement>(null);
<Input ref={divRef} /> // ❌ Type error: expected RefObject<HTMLInputElement>
```

**Key problems without explicit generics:**
1. **Loss of type safety** - Parent can pass incompatible ref types
2. **No IntelliSense** - No autocomplete for `ref.current` properties
3. **Runtime errors** - Type mismatches only discovered at runtime
4. **Harder refactoring** - Changes to ref type don't propagate to consumers

**Best practice:** Always specify both generic parameters explicitly in XMLUI components.

### Composing Multiple Refs

**The Problem:** Components often need to manage multiple refs pointing to the same DOM element:
1. **Internal ref** - Component's own logic (measurements, animations, focus)
2. **Forwarded ref** - Parent needs access to the DOM element
3. **Third-party refs** - Integration with libraries (Popper, Radix UI, etc.)

**The Solution:** Use `composeRefs` from `@radix-ui/react-compose-refs` to merge multiple refs into one.

**Why you need to compose refs:**

| Use Case | Example | Reason |
|----------|---------|--------|
| **Internal logic + parent access** | Auto-resize textarea | Component measures scrollHeight, parent needs focus() |
| **Library integration** | Popover/Tooltip | Popper needs ref for positioning, parent needs ref for control |
| **Wrapper components** | Container with single child | Parent ref applies to child, child has own ref |
| **Multiple behaviors** | Draggable element | Drag library needs ref, resize observer needs ref, parent needs ref |

**Key differences: Inner vs Forwarded refs:**

| Aspect | Inner Ref | Forwarded Ref |
|--------|-----------|---------------|
| **Created by** | Component itself with `useRef()` | Parent component |
| **Purpose** | Internal component logic | Parent needs DOM access |
| **Type** | Always `RefObject<T>` | Can be `RefObject<T>`, `RefCallback<T>`, or `null` |
| **Guaranteed to exist** | Yes - always has `.current` property | No - parent might not pass a ref |
| **When to use** | Component needs DOM access for its own behavior | Expose DOM element to parent |

**Example 1: Internal + Forwarded (most common in XMLUI):**

```tsx
import { composeRefs } from "@radix-ui/react-compose-refs";

function TextArea({ value, onChange }: Props, forwardedRef: Ref<HTMLTextAreaElement>) {
  // Inner ref: Component creates and owns this for auto-resize logic
  const innerRef = useRef<HTMLTextAreaElement>(null);
  
  // Compose both refs - textarea element needs both
  const composedRef = forwardedRef 
    ? composeRefs(innerRef, forwardedRef) 
    : innerRef;
  
  useEffect(() => {
    // ✅ CORRECT: Use innerRef for internal logic
    // It's guaranteed to exist and have .current property
    if (innerRef.current) {
      innerRef.current.style.height = 'auto';
      innerRef.current.style.height = `${innerRef.current.scrollHeight}px`;
    }
    
    // ❌ WRONG: Don't use forwardedRef directly
    // if (forwardedRef?.current) { ... } // Type error: Ref<T> might be a callback!
  }, [value]);
  
  return <textarea ref={composedRef} value={value} onChange={onChange} />;
}

export const AutoResizeTextArea = forwardRef(TextArea);

// Parent usage:
function Form() {
  const textareaRef = useRef<HTMLTextAreaElement>(null);
  
  const focusTextarea = () => {
    textareaRef.current?.focus(); // Parent can access via forwarded ref
  };
  
  return <AutoResizeTextArea ref={textareaRef} />; // Component auto-resizes via inner ref
}
```

**Example 2: Library Integration (Popper + Forwarded):**

```tsx
function Select({ options }: Props, forwardedRef: Ref<HTMLButtonElement>) {
  // Popper library needs a ref for positioning
  const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(null);
  
  // Compose library ref setter with forwarded ref
  const composedRef = forwardedRef 
    ? composeRefs(setReferenceElement, forwardedRef) 
    : setReferenceElement;
  
  return (
    <>
      <button ref={composedRef}>Select</button>
      <Popper referenceElement={referenceElement}>
        {/* Dropdown content */}
      </Popper>
    </>
  );
}

export const SelectComponent = forwardRef(Select);
```

**Example 3: Wrapper Component (Parent + Child refs):**

```tsx
function Container({ children }: Props, ref: Ref<HTMLElement>) {
  const renderedChild = renderChild(children);
  
  // If single child, compose parent's ref with child's existing ref
  if (isValidElement(renderedChild)) {
    return cloneElement(renderedChild, {
      ref: composeRefs(ref, (renderedChild as any).ref),
    });
  }
  
  return renderedChild;
}

export const ContainerComponent = forwardRef(Container);
```

**Example 4: Multiple Behaviors (Drag + Resize + Forward):**

```tsx
function DraggablePanel(props: Props, forwardedRef: Ref<HTMLDivElement>) {
  const dragRef = useRef<HTMLDivElement>(null);
  const resizeObserverRef = useRef<HTMLDivElement>(null);
  
  // Compose all three refs
  const composedRef = composeRefs(
    dragRef,
    resizeObserverRef,
    forwardedRef || null
  );
  
  useDragLogic(dragRef);
  useResizeObserver(resizeObserverRef);
  
  return <div ref={composedRef}>Draggable and resizable</div>;
}
```

**When to compose refs:**
- Component needs internal ref AND parent needs access
- Integrating with libraries that require refs (Popper, React DnD, etc.)
- Wrapping components that need to forward refs to children
- Multiple hooks/effects need refs to the same element

**How `composeRefs` works:**
- Accepts multiple refs (RefObjects, callbacks, or null)
- Returns a single callback ref that updates all provided refs
- Handles both RefObject (sets `.current`) and callback refs (calls function)
- Safely ignores `null`/`undefined` refs

### When to Use forwardRef

**Use `forwardRef` when:**
- Building reusable components that wrap DOM elements
- Parent needs direct DOM access (focus, scroll, measurements)
- Integrating with third-party libraries requiring refs
- Creating form components that need imperative control

**Don't use `forwardRef` when:**
- Component doesn't wrap a single DOM element
- Refs aren't needed by parent components
- You can solve the problem with callbacks/props instead

### Common Mistakes

```tsx
// ❌ WRONG - Forgetting to attach ref to DOM element
const Bad = forwardRef((props, ref) => {
  return <div>{props.children}</div>; // ref is ignored!
});

// ✅ CORRECT - Always attach ref to actual DOM element
const Good = forwardRef((props, ref) => {
  return <div ref={ref}>{props.children}</div>;
});

// ❌ WRONG - Attaching ref to component (won't work)
const AlsoBad = forwardRef((props, ref) => {
  return <CustomComponent ref={ref} />; // CustomComponent must also use forwardRef
});

// ✅ CORRECT - Forward through nested components
const CustomComponent = forwardRef((props, ref) => {
  return <div ref={ref}>...</div>;
});

const AlsoGood = forwardRef((props, ref) => {
  return <CustomComponent ref={ref} />; // Works because CustomComponent forwards
});
```

---

## `createPortal` - Render Outside Hierarchy

**Purpose:** Render children into a DOM node outside the parent component's hierarchy.

**Syntax:** `createPortal(children, domNode, key?)`

### Basic Usage

```tsx
import { createPortal } from 'react-dom';

function Modal({ isOpen, children }: Props) {
  if (!isOpen) return null;
  
  // Render into document.body instead of parent component
  return createPortal(
    <div className="modal-overlay">
      <div className="modal-content">
        {children}
      </div>
    </div>,
    document.body
  );
}

// Usage
function App() {
  return (
    <div className="app">
      <Modal isOpen={true}>
        <h1>This renders in document.body, not .app!</h1>
      </Modal>
    </div>
  );
}
```

### Common Use Cases

**1. Tooltips/Popovers (avoid z-index issues):**
```tsx
function Tooltip({ targetRef, content }: Props) {
  return createPortal(
    <div className="tooltip" style={calculatePosition(targetRef)}>
      {content}
    </div>,
    document.body
  );
}
```

**2. Notifications/Toasts:**
```tsx
function NotificationToast() {
  const [shouldRender, setShouldRender] = useState(false);
  
  useEffect(() => {
    setShouldRender(true);
  }, []);
  
  if (!shouldRender) return null;
  
  return createPortal(
    <Toaster position="top-right">
      {(t) => <ToastBar toast={t} />}
    </Toaster>,
    document.body
  );
}
```

**3. Modal Dialogs:**
```tsx
function ModalDialog({ isOpen, children }: Props) {
  if (!isOpen) return null;
  
  return createPortal(
    <div className="modal-backdrop">
      <div className="modal-dialog">
        {children}
      </div>
    </div>,
    document.getElementById('modal-root') || document.body
  );
}
```

**4. Full-Screen Overlays:**
```tsx
function FullScreenOverlay({ show, children }: Props) {
  if (!show) return null;
  
  return createPortal(
    <div className="fullscreen-overlay">
      {children}
    </div>,
    document.body
  );
}
```

### Event Bubbling Still Works

```tsx
// Event bubbling works despite DOM hierarchy
function Parent() {
  const handleClick = () => {
    console.log('Clicked!'); // This fires even though button is portaled
  };
  
  return (
    <div onClick={handleClick}>
      <PortaledButton />
    </div>
  );
}

function PortaledButton() {
  return createPortal(
    <button>Click me</button>,
    document.body
  );
}
```

### Common Pattern in XMLUI

```tsx
// App component portals theme styles
function App({ children }: Props) {
  return (
    <>
      {children}
      {createPortal(
        <style>{themeCSS}</style>,
        document.head
      )}
    </>
  );
}

// Inspector portals debugging UI
function Inspector() {
  return createPortal(
    <div className="inspector-panel">
      {/* Debug tools */}
    </div>,
    document.body
  );
}
```

### When to Use createPortal

**Use `createPortal` when:**
- Modals, dialogs, and overlays
- Tooltips and popovers
- Notifications and toasts
- Avoiding parent overflow/z-index issues
- Rendering into different parts of DOM (head, body)

**Don't use when:**
- Normal component rendering is sufficient
- No CSS stacking or overflow issues
- Adds unnecessary complexity

---

## `Fragment` - Grouping Without DOM Nodes

**Purpose:** Group multiple elements without adding extra nodes to the DOM.

**Syntax:** `<Fragment>...</Fragment>` or `<>...</>`

### Basic Usage

```tsx
// ❌ WRONG - Adds unnecessary div wrapper
function List() {
  return (
    <div>
      <li>Item 1</li>
      <li>Item 2</li>
    </div>
  );
}

// ✅ CORRECT - No extra DOM node
function List() {
  return (
    <>
      <li>Item 1</li>
      <li>Item 2</li>
    </>
  );
}
```

### Short vs Long Syntax

```tsx
// Short syntax <> - Use for most cases
function Component() {
  return (
    <>
      <Header />
      <Content />
    </>
  );
}

// Long syntax <Fragment> - Required when you need a key
function List({ items }: Props) {
  return (
    <ul>
      {items.map(item => (
        <Fragment key={item.id}>
          <li>{item.name}</li>
          <li>{item.description}</li>
        </Fragment>
      ))}
    </ul>
  );
}
```

**Limitations of short syntax:**
- ❌ Cannot add `key` prop (use `<Fragment key={...}>` instead)
- ❌ Cannot add any other props (only `key` is allowed on Fragment)
- ✅ Use short syntax everywhere else (cleaner, less verbose)

### Common Use Cases

**1. Returning Multiple Elements:**
```tsx
function Header() {
  return (
    <>
      <h1>Title</h1>
      <nav>Navigation</nav>
    </>
  );
}
```

**2. Conditional Rendering:**
```tsx
function Component({ showExtra }: Props) {
  return (
    <div>
      <h1>Always shown</h1>
      {showExtra && (
        <>
          <p>Extra content</p>
          <button>Extra button</button>
        </>
      )}
    </div>
  );
}
```

**3. Table Rows:**
```tsx
function TableRows({ data }: Props) {
  return (
    <>
      {data.map(row => (
        <Fragment key={row.id}>
          <tr>
            <td>{row.name}</td>
            <td>{row.value}</td>
          </tr>
          {row.hasDetails && (
            <tr>
              <td colSpan={2}>{row.details}</td>
            </tr>
          )}
        </Fragment>
      ))}
    </>
  );
}
```

**4. Avoiding Invalid HTML:**
```tsx
// ❌ WRONG - div inside p is invalid HTML
function Text() {
  return (
    <p>
      <div>This is invalid!</div>
    </p>
  );
}

// ✅ CORRECT - Fragment doesn't create DOM node
function Text() {
  return (
    <p>
      <>
        <span>This is valid!</span>
      </>
    </p>
  );
}
```

### When to Use Fragment

**Use `Fragment` when:**
- Component must return multiple elements
- Avoiding wrapper divs that break CSS (flexbox, grid)
- Keeping HTML semantically valid
- Conditional rendering of multiple elements

**Don't use when:**
- Single element (no need to wrap)
- Wrapper div doesn't cause issues
- Need to attach events or refs (Fragment can't have them)

---

## `cloneElement` - Clone and Modify React Elements

**Purpose:** Clone a React element and override its props, refs, or children.

**Syntax:** `cloneElement(element, props?, ...children?)`

### Basic Usage

```tsx
import { cloneElement, isValidElement } from 'react';

function Container({ children }: Props) {
  if (!isValidElement(children)) {
    return children;
  }
  
  // Clone child and add extra props
  return cloneElement(children, {
    className: 'container-child',
    style: { padding: '10px' },
  });
}

// Usage
<Container>
  <div>Original</div> {/* Becomes <div className="container-child" style={{padding: '10px'}}>Original</div> */}
</Container>
```

### Adding Props to Children

```tsx
function Animation({ children, duration = 300 }: Props) {
  if (!isValidElement(children)) {
    return children;
  }
  
  // Add animation props to child
  return cloneElement(children, {
    style: {
      ...children.props.style,
      transition: `all ${duration}ms`,
    },
  });
}
```

### Forwarding Refs Through Clone

```tsx
function Wrapper({ children, ...rest }: Props, forwardedRef: Ref<any>) {
  if (!isValidElement(children)) {
    return children;
  }
  
  // Clone and forward ref + other props
  return cloneElement(children, {
    ...rest,
    ref: forwardedRef,
  });
}

export const WrapperComponent = forwardRef(Wrapper);
```

### Common Pattern in XMLUI

**Container with single child ref forwarding:**
```tsx
function Container({ children }: Props, ref: Ref<HTMLElement>) {
  const renderedChild = renderChild(children);
  
  // If single valid child, compose refs and merge props
  if (ref && renderedChild && isValidElement(renderedChild)) {
    return cloneElement(renderedChild, {
      ref: composeRefs(ref, (renderedChild as any).ref),
      ...mergeProps(renderedChild.props, rest),
    });
  }
  
  return renderedChild;
}
```

**Form field with label integration:**
```tsx
function ItemWithLabel({ children, label }: Props) {
  const id = useId();
  
  return (
    <div>
      <label htmlFor={id}>{label}</label>
      {cloneElement(children as ReactElement, {
        id,
        'aria-labelledby': id,
      })}
    </div>
  );
}
```

### When to Use cloneElement

**Use `cloneElement` when:**
- Wrapping components need to add props to children
- Forwarding refs through wrapper components
- Adding common behavior to arbitrary children
- Integrating with child elements you don't control

**Don't use when:**
- You can pass props directly (prefer explicit props)
- You need to modify deeply nested children (use context instead)
- Children are not React elements (check with `isValidElement` first)

### Common Mistakes

```tsx
// ❌ WRONG - Not checking if child is valid element
function Bad({ children }: Props) {
  return cloneElement(children, { className: 'bad' }); // Crashes if children is string/number
}

// ✅ CORRECT - Always validate first (see isValidElement section)
function Good({ children }: Props) {
  if (!isValidElement(children)) {
    return children;
  }
  return cloneElement(children, { className: 'good' });
}

// ❌ WRONG - Overriding all existing props
return cloneElement(child, { style: { color: 'red' } }); // Loses child's existing style

// ✅ CORRECT - Merge with existing props
return cloneElement(child, {
  style: { ...child.props.style, color: 'red' },
});
```

---

## `isValidElement` - Type Check for React Elements

**Purpose:** Check if a value is a valid React element (created with JSX or `createElement`). Always use before `cloneElement`.

**Syntax:** `isValidElement(value)`

### Basic Usage

```tsx
import { isValidElement } from 'react';

function processChild(child: React.ReactNode) {
  // child could be anything: string, number, element, array, etc.
  
  if (isValidElement(child)) {
    // TypeScript now knows child is ReactElement
    console.log(child.props); // ✅ OK - access props safely
    console.log(child.type);  // ✅ OK - access type safely
    return child;
  }
  
  // Not an element - return as is
  return child;
}
```

### Common Pattern in XMLUI

**Conditional element wrapping:**
```tsx
function ConditionalWrapper({ condition, children }: Props) {
  if (!condition) {
    return children;
  }
  
  // Only wrap if child is valid element
  return isValidElement(children) 
    ? <div className="wrapper">{children}</div>
    : children;
}
```

### What isValidElement Checks

```tsx
isValidElement(<div />);              // ✅ true - JSX element
isValidElement(React.createElement('div')); // ✅ true - created element
isValidElement(<Component />);        // ✅ true - component element
isValidElement('hello');              // ❌ false - string
isValidElement(123);                  // ❌ false - number
isValidElement(null);                 // ❌ false - null
isValidElement(undefined);            // ❌ false - undefined
isValidElement([<div key="1" />]);    // ❌ false - array of elements
```

### When to Use isValidElement

**Use `isValidElement` when:**
- Before calling `cloneElement` (required to avoid crashes)
- Type narrowing for TypeScript (ReactNode → ReactElement)
- Validating `children` prop type
- Conditional element manipulation

**Note:** See `cloneElement` section for examples of using these two functions together.

---

## `flushSync` - Synchronous State Updates

**Purpose:** Force React to flush state updates synchronously, bypassing automatic batching.

**Syntax:** `flushSync(() => { /* state updates */ })`

**Warning:** Use sparingly - breaks React's batching optimization and can hurt performance.

### Basic Usage

```tsx
import { flushSync } from 'react-dom';

function Form() {
  const [value, setValue] = useState('');
  
  const handleSubmit = () => {
    // Normal: state updates are batched
    setValue('');
    setError(null);
    // Both updates happen together
    
    // With flushSync: update happens immediately
    flushSync(() => {
      setValue('');
    });
    // DOM is updated here, before next line
    inputRef.current?.focus();
  };
}
```

### When DOM Must Update Immediately

```tsx
function Table({ data }: Props) {
  const [selectedRow, setSelectedRow] = useState(0);
  const rowRef = useRef<HTMLTableRowElement>(null);
  
  const selectRow = (index: number) => {
    // Must update DOM before scrolling
    flushSync(() => {
      setSelectedRow(index);
    });
    
    // DOM is updated, can now scroll
    rowRef.current?.scrollIntoView();
  };
}
```

### Common Pattern in XMLUI

**Form reset with focus:**
```tsx
function Form({ onSubmit }: Props) {
  const doReset = () => {
    // Reset all fields
  };
  
  const handleSuccess = () => {
    const prevFocused = document.activeElement;
    
    // Force synchronous reset before restoring focus
    flushSync(() => {
      doReset();
    });
    
    // DOM is reset, restore focus
    if (prevFocused && typeof (prevFocused as HTMLElement).focus === 'function') {
      (prevFocused as HTMLElement).focus();
    }
  };
}
```

**Table with immediate scroll:**
```tsx
function DataTable({ data }: Props) {
  const handleSort = (column: string) => {
    // Update sort synchronously before scrolling
    flushSync(() => {
      setSortColumn(column);
      setSortedData(sortData(data, column));
    });
    
    // Table is re-rendered, can scroll to top
    tableRef.current?.scrollTo(0, 0);
  };
}
```

### Why flushSync Exists

```tsx
// ❌ Problem: Without flushSync
function Component() {
  const [text, setText] = useState('');
  
  const update = () => {
    setText('new value');
    // DOM not updated yet!
    inputRef.current?.focus(); // Focuses old state
  };
}

// ✅ Solution: With flushSync
function Component() {
  const [text, setText] = useState('');
  
  const update = () => {
    flushSync(() => {
      setText('new value');
    });
    // DOM is updated
    inputRef.current?.focus(); // Focuses new state
  };
}
```

### When to Use flushSync

**Use `flushSync` when:**
- Need DOM measurements after state change
- Synchronizing with third-party libraries
- Scrolling after state update
- Focus management after state change

**Don't use when:**
- Normal state updates (let React batch)
- Performance-critical code paths
- You can solve it with `useLayoutEffect`
- Inside render (not allowed)

**Performance impact:**
```tsx
// ❌ BAD - Multiple flushSync calls
data.forEach(item => {
  flushSync(() => {
    processItem(item); // Forces re-render each time
  });
});

// ✅ GOOD - Single batch update
const processedItems = data.map(processItem);
flushSync(() => {
  setItems(processedItems); // Single re-render
});
```

---

## `createRoot` - React 18 Root API

**Purpose:** Create a root to render React components into a DOM container (React 18+).

**Syntax:** `const root = createRoot(container); root.render(<App />)`

### Basic Usage

```tsx
import { createRoot } from 'react-dom/client';

// Old way (React 17)
ReactDOM.render(<App />, document.getElementById('root'));

// New way (React 18+)
const root = createRoot(document.getElementById('root')!);
root.render(<App />);
```

### With TypeScript

```tsx
import { createRoot } from 'react-dom/client';

const container = document.getElementById('root');
if (!container) {
  throw new Error('Root element not found');
}

const root = createRoot(container);
root.render(<App />);
```

### Unmounting

```tsx
const root = createRoot(container);
root.render(<App />);

// Later: unmount
root.unmount();
```

### Common Pattern in XMLUI

**Standalone app rendering:**
```tsx
function renderStandaloneApp(rootElement: HTMLElement) {
  let contentRoot: Root;
  
  if (!contentRoot) {
    contentRoot = createRoot(rootElement);
  }
  
  contentRoot.render(
    <StrictMode>
      <App />
    </StrictMode>
  );
  
  return contentRoot;
}
```

**Shadow DOM rendering:**
```tsx
function NestedApp({ children }: Props) {
  const shadowRef = useRef<ShadowRoot>(null);
  const contentRootRef = useRef<Root | null>(null);
  
  useEffect(() => {
    if (shadowRef.current && !contentRootRef.current) {
      // Create root in shadow DOM
      contentRootRef.current = createRoot(shadowRef.current);
      contentRootRef.current.render(<NestedContent />);
    }
    
    return () => {
      contentRootRef.current?.unmount();
    };
  }, []);
}
```

### Benefits of createRoot (React 18)

1. **Automatic batching** - All updates batched, even in promises/setTimeout
2. **Concurrent features** - Enables `useTransition`, `useDeferredValue`, etc.
3. **Improved hydration** - Better SSR support
4. **Suspense improvements** - Better streaming SSR

### When to Use createRoot

**Use `createRoot` when:**
- Starting a new React 18+ application
- Rendering React into a DOM container
- Creating multiple roots in one app
- Rendering into shadow DOM

**Migration from React 17:**
```tsx
// React 17
import ReactDOM from 'react-dom';
ReactDOM.render(<App />, container);
ReactDOM.unmountComponentAtNode(container);

// React 18
import { createRoot } from 'react-dom/client';
const root = createRoot(container);
root.render(<App />);
root.unmount();
```

---

## React Accessibility Patterns

### ARIA Attributes Pattern

**Key ARIA attributes:** `role`, `aria-label`, `aria-labelledby`, `aria-describedby`, `aria-hidden`, `aria-live`, `aria-expanded`, `aria-selected`, `aria-disabled`, `aria-current`

**Common patterns:**

```tsx
// Icon button with accessible label
<button onClick={onClick} aria-label="Close dialog">
  <Icon name="close" aria-hidden="true" />
</button>

// Form field with error/help text
function FormField({ label, error, helpText }: Props) {
  const id = useId();
  return (
    <>
      <label htmlFor={id}>{label}</label>
      <input id={id} aria-describedby={`${id}-desc`} aria-invalid={!!error} />
      <span id={`${id}-desc`} role={error ? "alert" : undefined}>
        {error || helpText}
      </span>
    </>
  );
}

// Accordion/expandable section
<button aria-expanded={isOpen} aria-controls={contentId}>
  {title}
</button>
<div id={contentId} hidden={!isOpen} role="region">
  {children}
</div>

// Live region for announcements
<div role="status" aria-live="polite" aria-atomic="true">
  {message}
</div>

// Modal dialog
<div role="dialog" aria-modal="true" aria-labelledby={titleId}>
  <h2 id={titleId}>{title}</h2>
  {children}
</div>

// Tab navigation
<div role="tablist">
  <button role="tab" aria-selected={isActive} aria-controls={panelId}>
    {label}
  </button>
</div>
<div role="tabpanel" id={panelId} aria-labelledby={tabId}>
  {content}
</div>
```

**Rules:** Use semantic HTML first, add ARIA only when needed, keep attributes in sync with state, test with screen readers.

---

### Focus Management Pattern

**Common scenarios:** Auto-focus on mount, focus traps in modals, focus restoration, roving tab index.

```tsx
// Auto-focus first element in dialog
function Dialog({ isOpen }: Props) {
  const buttonRef = useRef<HTMLButtonElement>(null);
  
  useEffect(() => {
    if (isOpen) buttonRef.current?.focus();
  }, [isOpen]);
  
  return <button ref={buttonRef}>Close</button>;
}

// Focus trap + restoration in modal
function Modal({ isOpen, onClose, children }: Props) {
  const modalRef = useRef<HTMLDivElement>(null);
  const restoreFocusRef = useRef<HTMLElement | null>(null);
  
  useEffect(() => {
    if (!isOpen) return;
    
    restoreFocusRef.current = document.activeElement as HTMLElement;
    modalRef.current?.querySelector<HTMLElement>('button')?.focus();
    
    return () => restoreFocusRef.current?.focus();
  }, [isOpen]);
  
  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Escape') onClose();
    
    // Trap Tab key
    if (e.key === 'Tab') {
      const focusable = modalRef.current?.querySelectorAll<HTMLElement>(
        'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
      );
      if (!focusable?.length) return;
      
      const first = focusable[0];
      const last = focusable[focusable.length - 1];
      
      if (e.shiftKey && document.activeElement === first) {
        e.preventDefault();
        last.focus();
      } else if (!e.shiftKey && document.activeElement === last) {
        e.preventDefault();
        first.focus();
      }
    }
  };
  
  return (
    <div ref={modalRef} role="dialog" aria-modal="true" onKeyDown={handleKeyDown}>
      {children}
    </div>
  );
}

// Focus after delete action
function DeleteButton({ itemId, onDelete }: Props) {
  const handleDelete = () => {
    const current = document.getElementById(`item-${itemId}`);
    const next = (current?.nextElementSibling || current?.previousElementSibling)
      ?.querySelector('button') as HTMLElement;
    
    onDelete(itemId);
    setTimeout(() => next?.focus(), 0);
  };
  
  return <button onClick={handleDelete}>Delete</button>;
}

// Roving tab index for lists
function RadioGroup({ options, value, onChange }: Props) {
  const [focusedIndex, setFocusedIndex] = useState(0);
  
  const handleKeyDown = (e: React.KeyboardEvent, index: number) => {
    let newIndex = index;
    if (e.key === 'ArrowDown') newIndex = (index + 1) % options.length;
    if (e.key === 'ArrowUp') newIndex = index === 0 ? options.length - 1 : index - 1;
    if (e.key === 'Home') newIndex = 0;
    if (e.key === 'End') newIndex = options.length - 1;
    
    if (newIndex !== index) {
      e.preventDefault();
      setFocusedIndex(newIndex);
    }
  };
  
  return (
    <div role="radiogroup">
      {options.map((opt, i) => (
        <div
          key={opt.id}
          role="radio"
          aria-checked={value === opt.id}
          tabIndex={focusedIndex === i ? 0 : -1}
          onClick={() => onChange(opt.id)}
          onKeyDown={(e) => handleKeyDown(e, i)}
          onFocus={() => setFocusedIndex(i)}
        >
          {opt.label}
        </div>
      ))}
    </div>
  );
}
```

**Rules:** Always restore focus when closing modals, trap focus within modal contexts, use `focus-visible` for keyboard-only indicators, test thoroughly.

---

### Keyboard Navigation Pattern

**Standard keyboard shortcuts:** Escape (close), Tab/Shift+Tab (navigate), Arrow keys (move focus), Enter/Space (activate), Home/End (first/last).

```tsx
// Dropdown with full keyboard support
function Dropdown({ trigger, items, onSelect }: Props) {
  const [isOpen, setIsOpen] = useState(false);
  const [focusedIndex, setFocusedIndex] = useState(0);
  const itemsRef = useRef<(HTMLButtonElement | null)[]>([]);
  
  const handleKeyDown = (e: React.KeyboardEvent) => {
    switch (e.key) {
      case 'ArrowDown':
        e.preventDefault();
        if (!isOpen) {
          setIsOpen(true);
        } else {
          const next = (focusedIndex + 1) % items.length;
          setFocusedIndex(next);
          itemsRef.current[next]?.focus();
        }
        break;
      case 'ArrowUp':
        e.preventDefault();
        if (isOpen) {
          const prev = focusedIndex === 0 ? items.length - 1 : focusedIndex - 1;
          setFocusedIndex(prev);
          itemsRef.current[prev]?.focus();
        }
        break;
      case 'Escape':
        e.preventDefault();
        setIsOpen(false);
        break;
      case 'Enter':
      case ' ':
        e.preventDefault();
        if (isOpen) {
          onSelect(items[focusedIndex]);
          setIsOpen(false);
        } else {
          setIsOpen(true);
        }
        break;
    }
  };
  
  return (
    <div onKeyDown={handleKeyDown}>
      <button onClick={() => setIsOpen(!isOpen)} aria-expanded={isOpen}>
        {trigger}
      </button>
      {isOpen && (
        <ul role="menu">
          {items.map((item, i) => (
            <li key={item.id} role="none">
              <button
                ref={el => itemsRef.current[i] = el}
                role="menuitem"
                onClick={() => { onSelect(item); setIsOpen(false); }}
                onFocus={() => setFocusedIndex(i)}
              >
                {item.label}
              </button>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

// Global keyboard shortcuts hook
function useKeyboardShortcuts(shortcuts: Record<string, () => void>) {
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      const keys: string[] = [];
      if (e.ctrlKey || e.metaKey) keys.push('Ctrl');
      if (e.shiftKey) keys.push('Shift');
      if (e.altKey) keys.push('Alt');
      keys.push(e.key.toUpperCase());
      
      const handler = shortcuts[keys.join('+')];
      if (handler) {
        e.preventDefault();
        handler();
      }
    };
    
    document.addEventListener('keydown', handleKeyDown);
    return () => document.removeEventListener('keydown', handleKeyDown);
  }, [shortcuts]);
}

// Usage: Editor with shortcuts
function Editor() {
  useKeyboardShortcuts({
    'Ctrl+S': handleSave,
    'Ctrl+Z': handleUndo,
    'Ctrl+Shift+Z': handleRedo,
  });
  return <div>Editor</div>;
}

// Data table with arrow key navigation
function DataTable({ columns, rows }: Props) {
  const [focusedCell, setFocusedCell] = useState({ row: 0, col: 0 });
  const cellRefs = useRef<(HTMLTableCellElement | null)[][]>([]);
  
  const handleKeyDown = (e: React.KeyboardEvent, rowIndex: number, colIndex: number) => {
    let newRow = rowIndex, newCol = colIndex;
    
    if (e.key === 'ArrowUp') newRow = Math.max(0, rowIndex - 1);
    if (e.key === 'ArrowDown') newRow = Math.min(rows.length - 1, rowIndex + 1);
    if (e.key === 'ArrowLeft') newCol = Math.max(0, colIndex - 1);
    if (e.key === 'ArrowRight') newCol = Math.min(columns.length - 1, colIndex + 1);
    if (e.key === 'Home') newCol = 0;
    if (e.key === 'End') newCol = columns.length - 1;
    
    if (newRow !== rowIndex || newCol !== colIndex) {
      e.preventDefault();
      setFocusedCell({ row: newRow, col: newCol });
      cellRefs.current[newRow]?.[newCol]?.focus();
    }
  };
  
  return (
    <table>
      <tbody>
        {rows.map((row, ri) => (
          <tr key={row.id}>
            {columns.map((col, ci) => (
              <td
                key={col.id}
                ref={el => {
                  if (!cellRefs.current[ri]) cellRefs.current[ri] = [];
                  cellRefs.current[ri][ci] = el;
                }}
                tabIndex={focusedCell.row === ri && focusedCell.col === ci ? 0 : -1}
                onKeyDown={e => handleKeyDown(e, ri, ci)}
                onFocus={() => setFocusedCell({ row: ri, col: ci })}
              >
                {row[col.id]}
              </td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  );
}
```

**Rules:** Support standard shortcuts (Escape, Tab, Arrows), don't override browser/OS shortcuts, provide visible focus feedback, test keyboard-only navigation.

---

### Accessibility Best Practices Summary

**Key principles:**
- Use semantic HTML first (`<button>`, `<nav>`, `<main>`)
- Add ARIA only when semantic HTML isn't enough
- All interactive elements must be keyboard accessible
- Provide visible focus indicators (use `:focus-visible`)
- Keep ARIA attributes in sync with visual state
- Restore focus after closing modals/dialogs
- Test with screen readers and keyboard only

**Testing checklist:**
- [ ] Navigate entire app with keyboard only
- [ ] Focus indicators visible and high contrast
- [ ] Screen reader announces all content correctly
- [ ] Color not the only state indicator
- [ ] Text contrast ≥ 4.5:1 for normal text
- [ ] Interactive elements have accessible names
- [ ] Form fields have associated labels
- [ ] Error messages are announced

**Tools:** [axe DevTools](https://www.deque.com/axe/devtools/), [WAVE](https://wave.webaim.org/), [Lighthouse](https://developers.google.com/web/tools/lighthouse), screen readers (NVDA, JAWS, VoiceOver)

```
Page 130/138FirstPrevNextLast