#
tokens: 68561/50000 1/1643 files (page 176/179)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 176 of 179. Use http://codebase.md/xmlui-org/xmlui/xmlui/mockApiDef.js?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .changeset
│   ├── cold-items-taste.md
│   ├── config.json
│   ├── empty-spiders-dress.md
│   ├── shy-windows-allow.md
│   ├── sour-coins-read.md
│   ├── tame-zebras-invite.md
│   ├── three-ideas-invent.md
│   ├── twenty-jeans-watch.md
│   └── warm-spies-melt.md
├── .eslintrc.cjs
├── .github
│   ├── build-checklist.png
│   ├── ISSUE_TEMPLATE
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   └── workflows
│       ├── 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
    │   ├── actions.md
    │   ├── AppRoot.md
    │   ├── component-apis.md
    │   ├── component-rendering.md
    │   ├── component-review-checklist.md
    │   ├── containers.md
    │   ├── data-sources.md
    │   ├── e2e-summary.md
    │   ├── expression-evaluation.md
    │   ├── glossary.md
    │   ├── helper-components.md
    │   ├── index.md
    │   ├── loaders.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
    │   ├── rendering-fundamentals.md
    │   ├── reusable-components.md
    │   ├── standalone-apps.md
    │   ├── state-management.md
    │   └── xmlui-extensibility.xlsx
    ├── 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/src/components/Tree/Tree.spec.ts:
--------------------------------------------------------------------------------

```typescript
   1 | import { SKIP_REASON } from "../../testing/component-test-helpers";
   2 | import { expect, test } from "../../testing/fixtures";
   3 | 
   4 | import {
   5 |   apiStyleData,
   6 |   apiStyleHierarchy,
   7 |   customDynamicTreeData,
   8 |   customFieldsData1,
   9 |   customFieldsData2,
  10 |   customFieldsHierarchy1,
  11 |   customFieldsHierarchy2,
  12 |   customIconFieldData,
  13 |   customIconFieldHierarchy,
  14 |   databaseStyleData,
  15 |   databaseStyleHierarchy,
  16 |   dataWithStateIcons,
  17 |   dynamicFlatData,
  18 |   dynamicTreeData,
  19 |   flatDataWithIcons,
  20 |   flatTreeData,
  21 |   hierarchyDataWithIcons,
  22 |   hierarchyTreeData,
  23 |   hierarchyWithStateIcons,
  24 |   multiBranchTreeData,
  25 | } from "./testData";
  26 | 
  27 | // =============================================================================
  28 | // BASIC FUNCTIONALITY TESTS
  29 | // =============================================================================
  30 | 
  31 | test.describe("Basic Functionality", () => {
  32 |   test("component renders with default props", async ({ initTestBed, createTreeDriver }) => {
  33 |     await initTestBed(`
  34 |         <VStack height="400px">
  35 |           <Tree testId="tree" dataFormat="flat" data='{${JSON.stringify(flatTreeData)}}'>
  36 |             <property name="itemTemplate">
  37 |               <HStack testId="{$item.id}" verticalAlignment="center">
  38 |                 <Icon name="folder" />
  39 |                 <Text value="{$item.name}" />
  40 |               </HStack>
  41 |             </property>
  42 |           </Tree>
  43 |         </VStack>
  44 |       `);
  45 |     const tree = await createTreeDriver("tree");
  46 |     await expect(tree.component).toBeVisible();
  47 |     await expect(tree.getByTestId("1")).toBeVisible();
  48 |     await expect(tree.getByTestId("2")).not.toBeVisible();
  49 |     await expect(tree.getByTestId("3")).not.toBeVisible();
  50 |     await expect(tree.getByTestId("4")).not.toBeVisible();
  51 |   });
  52 | 
  53 |   test("displays flat data format correctly", async ({ initTestBed, createTreeDriver }) => {
  54 |     await initTestBed(`
  55 |         <VStack height="400px">
  56 |           <Tree testId="tree" dataFormat="flat" defaultExpanded="all"
  57 |             data='{${JSON.stringify(flatTreeData)}}'>
  58 |             <property name="itemTemplate">
  59 |               <HStack testId="{$item.id}:{$item.depth}" verticalAlignment="center">
  60 |                 <Icon name="folder" />
  61 |                 <Text value="{$item.name}" />
  62 |               </HStack>
  63 |             </property>
  64 |           </Tree>
  65 |         </VStack>
  66 |       `);
  67 |     const tree = await createTreeDriver("tree");
  68 |     await expect(tree.component).toBeVisible();
  69 |     await expect(tree.getByTestId("1:0")).toBeVisible();
  70 |     await expect(tree.getByTestId("2:1")).toBeVisible();
  71 |     await expect(tree.getByTestId("3:1")).toBeVisible();
  72 |     await expect(tree.getByTestId("4:2")).toBeVisible();
  73 |   });
  74 | 
  75 |   test("displays hierarchy data format correctly", async ({ initTestBed, createTreeDriver }) => {
  76 |     await initTestBed(`
  77 |         <VStack height="400px">
  78 |           <Tree testId="tree" dataFormat="hierarchy" defaultExpanded="all"
  79 |             data='{${JSON.stringify(hierarchyTreeData)}}'>
  80 |             <property name="itemTemplate">
  81 |               <HStack testId="{$item.id}:{$item.depth}" verticalAlignment="center">
  82 |                 <Icon name="folder" />
  83 |                 <Text id="{$item.id}" value="{$item.name}" />
  84 |               </HStack>
  85 |             </property>
  86 |           </Tree>
  87 |         </VStack>
  88 |       `);
  89 |     const tree = await createTreeDriver("tree");
  90 |     await expect(tree.component).toBeVisible();
  91 |     await expect(tree.getByTestId("1:0")).toBeVisible();
  92 |     await expect(tree.getByTestId("2:1")).toBeVisible();
  93 |     await expect(tree.getByTestId("3:1")).toBeVisible();
  94 |     await expect(tree.getByTestId("4:2")).toBeVisible();
  95 |   });
  96 | 
  97 |   test("uses flat as default data format when dataFormat is not specified", async ({
  98 |     initTestBed,
  99 |     createTreeDriver,
 100 |   }) => {
 101 |     await initTestBed(`
 102 |         <VStack height="400px">
 103 |           <Tree testId="tree" defaultExpanded="all"
 104 |             data='{${JSON.stringify(flatTreeData)}}'>
 105 |             <property name="itemTemplate">
 106 |               <HStack testId="{$item.id}:{$item.depth}" verticalAlignment="center">
 107 |                 <Icon name="folder" />
 108 |                 <Text id="{$item.id}" value="{$item.name}" />
 109 |               </HStack>
 110 |             </property>
 111 |           </Tree>
 112 |         </VStack>
 113 |       `);
 114 |     const tree = await createTreeDriver("tree");
 115 |     await expect(tree.component).toBeVisible();
 116 |     await expect(tree.getByTestId("1:0")).toBeVisible();
 117 |     await expect(tree.getByTestId("2:1")).toBeVisible();
 118 |     await expect(tree.getByTestId("3:1")).toBeVisible();
 119 |     await expect(tree.getByTestId("4:2")).toBeVisible();
 120 |   });
 121 | 
 122 |   test("handles custom idField, nameField, and parentIdField mapping", async ({
 123 |     initTestBed,
 124 |     createTreeDriver,
 125 |   }) => {
 126 |     await initTestBed(`
 127 |         <VStack height="400px">
 128 |           <Tree testId="tree" 
 129 |             dataFormat="flat" 
 130 |             defaultExpanded="all"
 131 |             idField="nodeId"
 132 |             nameField="title"
 133 |             parentIdField="parent"
 134 |             data='{${JSON.stringify(customFieldsData1)}}'>
 135 |             <property name="itemTemplate">
 136 |               <HStack testId="{$item.nodeId}:{$item.depth}" verticalAlignment="center">
 137 |                 <Icon name="folder" />
 138 |                 <Text value="{$item.title}" />
 139 |               </HStack>
 140 |             </property>
 141 |           </Tree>
 142 |         </VStack>
 143 |       `);
 144 |     const tree = await createTreeDriver("tree");
 145 |     await expect(tree.component).toBeVisible();
 146 |     await expect(tree.getByTestId("A1:0")).toBeVisible();
 147 |     await expect(tree.getByTestId("A2:1")).toBeVisible();
 148 |     await expect(tree.getByTestId("A3:1")).toBeVisible();
 149 |     await expect(tree.getByTestId("A4:2")).toBeVisible();
 150 |   });
 151 | 
 152 |   test("handles alternative field names (id, displayName, parentId)", async ({
 153 |     initTestBed,
 154 |     createTreeDriver,
 155 |   }) => {
 156 |     await initTestBed(`
 157 |         <VStack height="400px">
 158 |           <Tree testId="tree" 
 159 |             dataFormat="flat" 
 160 |             defaultExpanded="all"
 161 |             idField="id"
 162 |             nameField="displayName"
 163 |             parentIdField="parentId"
 164 |             data='{${JSON.stringify(customFieldsData2)}}'>
 165 |             <property name="itemTemplate">
 166 |               <HStack testId="{$item.id}:{$item.depth}" verticalAlignment="center">
 167 |                 <Icon name="folder" />
 168 |                 <Text value="{$item.displayName}" />
 169 |               </HStack>
 170 |             </property>
 171 |           </Tree>
 172 |         </VStack>
 173 |       `);
 174 |     const tree = await createTreeDriver("tree");
 175 |     await expect(tree.component).toBeVisible();
 176 |     await expect(tree.getByTestId("100:0")).toBeVisible();
 177 |     await expect(tree.getByTestId("101:1")).toBeVisible();
 178 |     await expect(tree.getByTestId("102:1")).toBeVisible();
 179 |     await expect(tree.getByTestId("103:2")).toBeVisible();
 180 |   });
 181 | 
 182 |   test("handles database-style field names (pk, label, parent_id)", async ({
 183 |     initTestBed,
 184 |     createTreeDriver,
 185 |   }) => {
 186 |     await initTestBed(`
 187 |         <VStack height="400px">
 188 |           <Tree testId="tree" 
 189 |             dataFormat="flat" 
 190 |             defaultExpanded="all"
 191 |             idField="pk"
 192 |             nameField="label"
 193 |             parentIdField="parent_id"
 194 |             data='{${JSON.stringify(databaseStyleData)}}'>
 195 |             <property name="itemTemplate">
 196 |               <HStack testId="{$item.pk}:{$item.depth}" verticalAlignment="center">
 197 |                 <Icon name="folder" />
 198 |                 <Text value="{$item.label}" />
 199 |               </HStack>
 200 |             </property>
 201 |           </Tree>
 202 |         </VStack>
 203 |       `);
 204 |     const tree = await createTreeDriver("tree");
 205 |     await expect(tree.component).toBeVisible();
 206 |     await expect(tree.getByTestId("root-1:0")).toBeVisible();
 207 |     await expect(tree.getByTestId("child-1:1")).toBeVisible();
 208 |     await expect(tree.getByTestId("child-2:1")).toBeVisible();
 209 |     await expect(tree.getByTestId("grandchild-1:2")).toBeVisible();
 210 |   });
 211 | 
 212 |   test("handles API-style field names (key, text, parentKey)", async ({
 213 |     initTestBed,
 214 |     createTreeDriver,
 215 |   }) => {
 216 |     await initTestBed(`
 217 |         <VStack height="400px">
 218 |           <Tree testId="tree" 
 219 |             dataFormat="flat" 
 220 |             defaultExpanded="all"
 221 |             idField="key"
 222 |             nameField="text"
 223 |             parentIdField="parentKey"
 224 |             data='{${JSON.stringify(apiStyleData)}}'>
 225 |             <property name="itemTemplate">
 226 |               <HStack testId="{$item.key}:{$item.depth}" verticalAlignment="center">
 227 |                 <Icon name="folder" />
 228 |                 <Text value="{$item.text}" />
 229 |               </HStack>
 230 |             </property>
 231 |           </Tree>
 232 |         </VStack>
 233 |       `);
 234 |     const tree = await createTreeDriver("tree");
 235 |     await expect(tree.component).toBeVisible();
 236 |     await expect(tree.getByTestId("item1:0")).toBeVisible();
 237 |     await expect(tree.getByTestId("item2:1")).toBeVisible();
 238 |     await expect(tree.getByTestId("item3:1")).toBeVisible();
 239 |     await expect(tree.getByTestId("item4:2")).toBeVisible();
 240 |   });
 241 | 
 242 |   test("handles iconField mapping with default icon field name", async ({
 243 |     initTestBed,
 244 |     createTreeDriver,
 245 |   }) => {
 246 |     await initTestBed(`
 247 |         <VStack height="400px">
 248 |           <Tree testId="tree" 
 249 |             dataFormat="flat" 
 250 |             defaultExpanded="all"
 251 |             data='{${JSON.stringify(flatDataWithIcons)}}'>
 252 |             <property name="itemTemplate">
 253 |               <HStack testId="{$item.id}:icon:{$item.icon}" verticalAlignment="center">
 254 |                 <Text testId="icon:{$item.icon}" value="[{$item.icon}]" />
 255 |                 <Text value="{$item.name}" />
 256 |               </HStack>
 257 |             </property>
 258 |           </Tree>
 259 |         </VStack>
 260 |       `);
 261 |     const tree = await createTreeDriver("tree");
 262 |     await expect(tree.component).toBeVisible();
 263 |     await expect(tree.getByTestId("1:icon:folder")).toBeVisible();
 264 |     await expect(tree.getByTestId("2:icon:file-pdf")).toBeVisible();
 265 |     await expect(tree.getByTestId("3:icon:folder")).toBeVisible();
 266 |     await expect(tree.getByTestId("4:icon:file-image")).toBeVisible();
 267 |     // Verify individual icon markers
 268 |     await expect(tree.getByTestId("icon:folder")).toBeVisible();
 269 |     await expect(tree.getByTestId("icon:file-pdf")).toBeVisible();
 270 |     await expect(tree.getByTestId("icon:file-image")).toBeVisible();
 271 |   });
 272 | 
 273 |   test("handles custom iconField mapping", async ({ initTestBed, createTreeDriver }) => {
 274 |     await initTestBed(`
 275 |         <VStack height="400px">
 276 |           <Tree testId="tree" 
 277 |             dataFormat="flat" 
 278 |             defaultExpanded="all"
 279 |             idField="nodeId"
 280 |             nameField="title"
 281 |             iconField="iconType"
 282 |             parentIdField="parent"
 283 |             data='{${JSON.stringify(customIconFieldData)}}'>
 284 |             <property name="itemTemplate">
 285 |               <HStack testId="{$item.nodeId}:icon:{$item.iconType}" verticalAlignment="center">
 286 |                 <Text testId="icon-type:{$item.iconType}" value="[{$item.iconType}]" />
 287 |                 <Text value="{$item.title}" />
 288 |               </HStack>
 289 |             </property>
 290 |           </Tree>
 291 |         </VStack>
 292 |       `);
 293 |     const tree = await createTreeDriver("tree");
 294 |     await expect(tree.component).toBeVisible();
 295 |     await expect(tree.getByTestId("A1:icon:project-folder")).toBeVisible();
 296 |     await expect(tree.getByTestId("A2:icon:code-folder")).toBeVisible();
 297 |     await expect(tree.getByTestId("A3:icon:typescript-file")).toBeVisible();
 298 |     await expect(tree.getByTestId("A4:icon:typescript-file")).toBeVisible();
 299 |     // Verify individual icon type markers
 300 |     await expect(tree.getByTestId("icon-type:project-folder")).toBeVisible();
 301 |     await expect(tree.getByTestId("icon-type:code-folder")).toBeVisible();
 302 |     await expect(tree.getByTestId("icon-type:typescript-file")).toBeVisible();
 303 |   });
 304 | 
 305 |   test("handles iconExpandedField and iconCollapsedField mapping", async ({
 306 |     initTestBed,
 307 |     createTreeDriver,
 308 |   }) => {
 309 |     await initTestBed(`
 310 |         <VStack height="400px">
 311 |           <Tree testId="tree" 
 312 |             dataFormat="flat" 
 313 |             iconField="icon"
 314 |             iconExpandedField="iconExpanded"
 315 |             iconCollapsedField="iconCollapsed"
 316 |             data='{${JSON.stringify(dataWithStateIcons)}}'>
 317 |             <property name="itemTemplate">
 318 |               <HStack testId="{$item.id}:icon:{$item.icon}:expanded:{$item.iconExpanded}:collapsed:{$item.iconCollapsed}" verticalAlignment="center">
 319 |                 <Text testId="state-icon:{$isExpanded ? $item.iconExpanded : $item.iconCollapsed}" value="[{$isExpanded ? $item.iconExpanded || $item.icon : $item.iconCollapsed || $item.icon}]" />
 320 |                 <Text value="{$item.name}" />
 321 |               </HStack>
 322 |             </property>
 323 |           </Tree>
 324 |         </VStack>
 325 |       `);
 326 |     const tree = await createTreeDriver("tree");
 327 |     await expect(tree.component).toBeVisible();
 328 |     await expect(
 329 |       tree.getByTestId("1:icon:folder:expanded:folder-open:collapsed:folder-closed"),
 330 |     ).toBeVisible();
 331 |     await expect(
 332 |       tree.getByTestId("2:icon:folder:expanded:folder-open:collapsed:folder-closed"),
 333 |     ).not.toBeVisible(); // Should be collapsed initially
 334 |     await expect(
 335 |       tree.getByTestId("3:icon:file-text:expanded:undefined:collapsed:undefined"),
 336 |     ).not.toBeVisible(); // Should be nested and collapsed
 337 |     // Verify collapsed state icons are shown initially (since defaultExpanded is not set)
 338 |     await expect(tree.getByTestId("state-icon:folder-closed")).toBeVisible();
 339 |   });
 340 | 
 341 |   test("handles missing icon fields gracefully", async ({ initTestBed, createTreeDriver }) => {
 342 |     await initTestBed(`
 343 |         <VStack height="400px">
 344 |           <Tree testId="tree" 
 345 |             dataFormat="flat" 
 346 |             defaultExpanded="all"
 347 |             iconField="nonExistentIcon"
 348 |             data='{${JSON.stringify(flatTreeData)}}'>
 349 |             <property name="itemTemplate">
 350 |               <HStack testId="{$item.id}:icon:{$item.nonExistentIcon || 'no-icon'}" verticalAlignment="center">
 351 |                 <Text testId="fallback-icon:{$item.nonExistentIcon || 'default'}" value="[{$item.nonExistentIcon || 'default'}]" />
 352 |                 <Text value="{$item.name}" />
 353 |               </HStack>
 354 |             </property>
 355 |           </Tree>
 356 |         </VStack>
 357 |       `);
 358 |     const tree = await createTreeDriver("tree");
 359 |     await expect(tree.component).toBeVisible();
 360 |     await expect(tree.getByTestId("1:icon:no-icon")).toBeVisible();
 361 |     await expect(tree.getByTestId("2:icon:no-icon")).toBeVisible();
 362 |     await expect(tree.getByTestId("3:icon:no-icon")).toBeVisible();
 363 |     await expect(tree.getByTestId("4:icon:no-icon")).toBeVisible();
 364 |     // Verify fallback icons
 365 |     await expect(tree.getByTestId("fallback-icon:default")).toBeVisible();
 366 |   });
 367 | 
 368 |   // Selectable Field Mapping Tests
 369 |   test("handles default selectableField mapping (all nodes selectable by default)", async ({
 370 |     initTestBed,
 371 |     createTreeDriver,
 372 |   }) => {
 373 |     await initTestBed(`
 374 |         <VStack height="400px">
 375 |           <Tree testId="tree" 
 376 |             dataFormat="flat" 
 377 |             defaultExpanded="all"
 378 |             data='{${JSON.stringify(flatTreeData)}}'>
 379 |             <property name="itemTemplate">
 380 |               <HStack testId="{$item.id}:selectable:{$item.selectable}" verticalAlignment="center">
 381 |                 <Text value="{$item.name} (Selectable: {$item.selectable})" />
 382 |               </HStack>
 383 |             </property>
 384 |           </Tree>
 385 |         </VStack>
 386 |       `);
 387 |     const tree = await createTreeDriver("tree");
 388 |     await expect(tree.component).toBeVisible();
 389 |     // All nodes should be selectable by default (true)
 390 |     await expect(tree.getByTestId("1:selectable:true")).toBeVisible();
 391 |     await expect(tree.getByTestId("2:selectable:true")).toBeVisible();
 392 |     await expect(tree.getByTestId("3:selectable:true")).toBeVisible();
 393 |     await expect(tree.getByTestId("4:selectable:true")).toBeVisible();
 394 |   });
 395 | 
 396 |   test("handles custom selectableField mapping with mixed selectable states", async ({
 397 |     initTestBed,
 398 |     createTreeDriver,
 399 |   }) => {
 400 |     const customSelectableData = [
 401 |       { id: "1", name: "Root Item 1", parentId: null, isSelectable: true },
 402 |       { id: "2", name: "Child Item 1.1", parentId: "1", isSelectable: false },
 403 |       { id: "3", name: "Child Item 1.2", parentId: "1", isSelectable: true },
 404 |       { id: "4", name: "Grandchild Item 1.1.1", parentId: "2", isSelectable: false },
 405 |       { id: "5", name: "Another Child", parentId: "1", isSelectable: true },
 406 |     ];
 407 | 
 408 |     await initTestBed(`
 409 |         <VStack height="400px">
 410 |           <Tree testId="tree" 
 411 |             dataFormat="flat" 
 412 |             defaultExpanded="all"
 413 |             selectableField="isSelectable"
 414 |             data='{${JSON.stringify(customSelectableData)}}'>
 415 |             <property name="itemTemplate">
 416 |               <HStack testId="{$item.id}:selectable:{$item.selectable}" verticalAlignment="center">
 417 |                 <Text value="{$item.name} - Selectable: {$item.selectable}" />
 418 |               </HStack>
 419 |             </property>
 420 |           </Tree>
 421 |         </VStack>
 422 |       `);
 423 |     const tree = await createTreeDriver("tree");
 424 |     await expect(tree.component).toBeVisible();
 425 | 
 426 |     // Verify mapped selectable states
 427 |     await expect(tree.getByTestId("1:selectable:true")).toBeVisible(); // Root selectable
 428 |     await expect(tree.getByTestId("2:selectable:false")).toBeVisible(); // Child not selectable
 429 |     await expect(tree.getByTestId("3:selectable:true")).toBeVisible(); // Child selectable
 430 |     await expect(tree.getByTestId("4:selectable:false")).toBeVisible(); // Grandchild not selectable
 431 |     await expect(tree.getByTestId("5:selectable:true")).toBeVisible(); // Another child selectable
 432 |   });
 433 | 
 434 |   test("handles selectableField with fallback to true when field is missing", async ({
 435 |     initTestBed,
 436 |     createTreeDriver,
 437 |   }) => {
 438 |     const partialSelectableData = [
 439 |       { id: "1", name: "Root Item 1", parentId: null, canSelect: true },
 440 |       { id: "2", name: "Child Item 1.1", parentId: "1" }, // Missing canSelect field
 441 |       { id: "3", name: "Child Item 1.2", parentId: "1", canSelect: false },
 442 |       { id: "4", name: "Grandchild Item 1.1.1", parentId: "2" }, // Missing canSelect field
 443 |     ];
 444 | 
 445 |     await initTestBed(`
 446 |         <VStack height="400px">
 447 |           <Tree testId="tree" 
 448 |             dataFormat="flat" 
 449 |             defaultExpanded="all"
 450 |             selectableField="canSelect"
 451 |             data='{${JSON.stringify(partialSelectableData)}}'>
 452 |             <property name="itemTemplate">
 453 |               <HStack testId="{$item.id}:selectable:{$item.selectable}" verticalAlignment="center">
 454 |                 <Text value="{$item.name} - Selectable: {$item.selectable}" />
 455 |               </HStack>
 456 |             </property>
 457 |           </Tree>
 458 |         </VStack>
 459 |       `);
 460 |     const tree = await createTreeDriver("tree");
 461 |     await expect(tree.component).toBeVisible();
 462 | 
 463 |     // Verify fallback behavior: missing field defaults to true
 464 |     await expect(tree.getByTestId("1:selectable:true")).toBeVisible(); // Explicitly true
 465 |     await expect(tree.getByTestId("2:selectable:true")).toBeVisible(); // Missing field, defaults to true
 466 |     await expect(tree.getByTestId("3:selectable:false")).toBeVisible(); // Explicitly false
 467 |     await expect(tree.getByTestId("4:selectable:true")).toBeVisible(); // Missing field, defaults to true
 468 |   });
 469 | 
 470 |   test("handles selectableField in hierarchy data format", async ({
 471 |     initTestBed,
 472 |     createTreeDriver,
 473 |   }) => {
 474 |     const hierarchySelectableData = [
 475 |       {
 476 |         id: "A1",
 477 |         title: "Project",
 478 |         allowSelection: true,
 479 |         children: [
 480 |           {
 481 |             id: "A2",
 482 |             title: "Source",
 483 |             allowSelection: false,
 484 |             children: [{ id: "A3", title: "App.tsx", allowSelection: true }],
 485 |           },
 486 |           { id: "A4", title: "Tests", allowSelection: true },
 487 |         ],
 488 |       },
 489 |     ];
 490 | 
 491 |     await initTestBed(`
 492 |         <VStack height="400px">
 493 |           <Tree testId="tree" 
 494 |             dataFormat="hierarchy" 
 495 |             defaultExpanded="all"
 496 |             idField="id"
 497 |             nameField="title"
 498 |             selectableField="allowSelection"
 499 |             childrenField="children"
 500 |             data='{${JSON.stringify(hierarchySelectableData)}}'>
 501 |             <property name="itemTemplate">
 502 |               <HStack testId="{$item.id}:selectable:{$item.selectable}" verticalAlignment="center">
 503 |                 <Text value="{$item.title} - Selectable: {$item.selectable}" />
 504 |               </HStack>
 505 |             </property>
 506 |           </Tree>
 507 |         </VStack>
 508 |       `);
 509 |     const tree = await createTreeDriver("tree");
 510 |     await expect(tree.component).toBeVisible();
 511 | 
 512 |     // Verify hierarchy with selectableField mapping
 513 |     await expect(tree.getByTestId("A1:selectable:true")).toBeVisible(); // Project selectable
 514 |     await expect(tree.getByTestId("A2:selectable:false")).toBeVisible(); // Source not selectable
 515 |     await expect(tree.getByTestId("A3:selectable:true")).toBeVisible(); // App.tsx selectable
 516 |     await expect(tree.getByTestId("A4:selectable:true")).toBeVisible(); // Tests selectable
 517 |   });
 518 | 
 519 |   test("validates selectableField affects actual selection behavior", async ({
 520 |     initTestBed,
 521 |     createTreeDriver,
 522 |   }) => {
 523 |     const selectableBehaviorData = [
 524 |       { id: "1", name: "Selectable Root", parentId: null, canClick: true },
 525 |       { id: "2", name: "Non-Selectable Child", parentId: "1", canClick: false },
 526 |       { id: "3", name: "Selectable Child", parentId: "1", canClick: true },
 527 |     ];
 528 | 
 529 |     await initTestBed(`
 530 |         <VStack height="400px">
 531 |           <Tree testId="tree" 
 532 |             dataFormat="flat" 
 533 |             defaultExpanded="all"
 534 |             selectableField="canClick"
 535 |             data='{${JSON.stringify(selectableBehaviorData)}}'>
 536 |             <property name="itemTemplate">
 537 |               <HStack testId="{$item.id}" verticalAlignment="center">
 538 |                 <Text value="{$item.name} ({$item.selectable ? 'Clickable' : 'Not Clickable'})" />
 539 |               </HStack>
 540 |             </property>
 541 |           </Tree>
 542 |         </VStack>
 543 |       `);
 544 |     const tree = await createTreeDriver("tree");
 545 |     await expect(tree.component).toBeVisible();
 546 | 
 547 |     // Verify all nodes are visible
 548 |     await expect(tree.getByTestId("1")).toBeVisible();
 549 |     await expect(tree.getByTestId("2")).toBeVisible();
 550 |     await expect(tree.getByTestId("3")).toBeVisible();
 551 | 
 552 |     // Test selection behavior: selectable nodes should be clickable for selection
 553 |     // This verifies that the selectable property is correctly mapped and used internally
 554 |     const selectableNode = tree.getByTestId("1");
 555 |     const nonSelectableNode = tree.getByTestId("2");
 556 |     const anotherSelectableNode = tree.getByTestId("3");
 557 | 
 558 |     // Click on selectable nodes - should work
 559 |     await selectableNode.click();
 560 |     // Note: Detailed selection behavior testing would require checking internal state
 561 |     // which might be tested in other selection-focused test cases
 562 | 
 563 |     await anotherSelectableNode.click();
 564 |     // The actual selection assertion would depend on visible selection styling
 565 |     // or other indicators that would be tested in selection-specific tests
 566 |   });
 567 | 
 568 |   // Hierarchical Data Format Field Mapping Tests
 569 |   test("handles custom idField, nameField, and childrenField mapping for hierarchy data", async ({
 570 |     initTestBed,
 571 |     createTreeDriver,
 572 |   }) => {
 573 |     await initTestBed(`
 574 |         <VStack height="400px">
 575 |           <Tree testId="tree" 
 576 |             dataFormat="hierarchy" 
 577 |             defaultExpanded="all"
 578 |             idField="nodeId"
 579 |             nameField="title"
 580 |             childrenField="items"
 581 |             data='{${JSON.stringify(customFieldsHierarchy1)}}'>
 582 |             <property name="itemTemplate">
 583 |               <HStack testId="{$item.nodeId}:{$item.depth}" verticalAlignment="center">
 584 |                 <Icon name="folder" />
 585 |                 <Text value="{$item.title}" />
 586 |               </HStack>
 587 |             </property>
 588 |           </Tree>
 589 |         </VStack>
 590 |       `);
 591 |     const tree = await createTreeDriver("tree");
 592 |     await expect(tree.component).toBeVisible();
 593 |     await expect(tree.getByTestId("A1:0")).toBeVisible();
 594 |     await expect(tree.getByTestId("A2:1")).toBeVisible();
 595 |     await expect(tree.getByTestId("A3:1")).toBeVisible();
 596 |     await expect(tree.getByTestId("A4:2")).toBeVisible();
 597 |   });
 598 | 
 599 |   test("handles alternative hierarchy field names (id, displayName, subNodes)", async ({
 600 |     initTestBed,
 601 |     createTreeDriver,
 602 |   }) => {
 603 |     await initTestBed(`
 604 |         <VStack height="400px">
 605 |           <Tree testId="tree" 
 606 |             dataFormat="hierarchy" 
 607 |             defaultExpanded="all"
 608 |             idField="id"
 609 |             nameField="displayName"
 610 |             childrenField="subNodes"
 611 |             data='{${JSON.stringify(customFieldsHierarchy2)}}'>
 612 |             <property name="itemTemplate">
 613 |               <HStack testId="{$item.id}:{$item.depth}" verticalAlignment="center">
 614 |                 <Icon name="folder" />
 615 |                 <Text value="{$item.displayName}" />
 616 |               </HStack>
 617 |             </property>
 618 |           </Tree>
 619 |         </VStack>
 620 |       `);
 621 |     const tree = await createTreeDriver("tree");
 622 |     await expect(tree.component).toBeVisible();
 623 |     await expect(tree.getByTestId("100:0")).toBeVisible();
 624 |     await expect(tree.getByTestId("101:1")).toBeVisible();
 625 |     await expect(tree.getByTestId("102:1")).toBeVisible();
 626 |     await expect(tree.getByTestId("103:2")).toBeVisible();
 627 |   });
 628 | 
 629 |   test("handles database-style hierarchy field names (pk, label, nested_items)", async ({
 630 |     initTestBed,
 631 |     createTreeDriver,
 632 |   }) => {
 633 |     await initTestBed(`
 634 |         <VStack height="400px">
 635 |           <Tree testId="tree" 
 636 |             dataFormat="hierarchy" 
 637 |             defaultExpanded="all"
 638 |             idField="pk"
 639 |             nameField="label"
 640 |             childrenField="nested_items"
 641 |             data='{${JSON.stringify(databaseStyleHierarchy)}}'>
 642 |             <property name="itemTemplate">
 643 |               <HStack testId="{$item.pk}:{$item.depth}" verticalAlignment="center">
 644 |                 <Icon name="folder" />
 645 |                 <Text value="{$item.label}" />
 646 |               </HStack>
 647 |             </property>
 648 |           </Tree>
 649 |         </VStack>
 650 |       `);
 651 |     const tree = await createTreeDriver("tree");
 652 |     await expect(tree.component).toBeVisible();
 653 |     await expect(tree.getByTestId("root-1:0")).toBeVisible();
 654 |     await expect(tree.getByTestId("child-1:1")).toBeVisible();
 655 |     await expect(tree.getByTestId("child-2:1")).toBeVisible();
 656 |     await expect(tree.getByTestId("grandchild-1:2")).toBeVisible();
 657 |   });
 658 | 
 659 |   test("handles API-style hierarchy field names (key, text, nodes)", async ({
 660 |     initTestBed,
 661 |     createTreeDriver,
 662 |   }) => {
 663 |     await initTestBed(`
 664 |         <VStack height="400px">
 665 |           <Tree testId="tree" 
 666 |             dataFormat="hierarchy" 
 667 |             defaultExpanded="all"
 668 |             idField="key"
 669 |             nameField="text"
 670 |             childrenField="nodes"
 671 |             data='{${JSON.stringify(apiStyleHierarchy)}}'>
 672 |             <property name="itemTemplate">
 673 |               <HStack testId="{$item.key}:{$item.depth}" verticalAlignment="center">
 674 |                 <Icon name="folder" />
 675 |                 <Text value="{$item.text}" />
 676 |               </HStack>
 677 |             </property>
 678 |           </Tree>
 679 |         </VStack>
 680 |       `);
 681 |     const tree = await createTreeDriver("tree");
 682 |     await expect(tree.component).toBeVisible();
 683 |     await expect(tree.getByTestId("item1:0")).toBeVisible();
 684 |     await expect(tree.getByTestId("item2:1")).toBeVisible();
 685 |     await expect(tree.getByTestId("item3:1")).toBeVisible();
 686 |     await expect(tree.getByTestId("item4:2")).toBeVisible();
 687 |   });
 688 | 
 689 |   test("handles iconField mapping in hierarchy data with default field name", async ({
 690 |     initTestBed,
 691 |     createTreeDriver,
 692 |   }) => {
 693 |     await initTestBed(`
 694 |         <VStack height="400px">
 695 |           <Tree testId="tree" 
 696 |             dataFormat="hierarchy" 
 697 |             defaultExpanded="all"
 698 |             data='{${JSON.stringify(hierarchyDataWithIcons)}}'>
 699 |             <property name="itemTemplate">
 700 |               <HStack testId="{$item.id}:icon:{$item.icon}" verticalAlignment="center">
 701 |                 <Text testId="hierarchy-icon:{$item.icon}" value="[{$item.icon}]" />
 702 |                 <Text value="{$item.name}" />
 703 |               </HStack>
 704 |             </property>
 705 |           </Tree>
 706 |         </VStack>
 707 |       `);
 708 |     const tree = await createTreeDriver("tree");
 709 |     await expect(tree.component).toBeVisible();
 710 |     await expect(tree.getByTestId("1:icon:folder")).toBeVisible();
 711 |     await expect(tree.getByTestId("2:icon:file-pdf")).toBeVisible();
 712 |     await expect(tree.getByTestId("3:icon:folder")).toBeVisible();
 713 |     await expect(tree.getByTestId("4:icon:file-image")).toBeVisible();
 714 |     // Verify individual icon markers
 715 |     await expect(tree.getByTestId("hierarchy-icon:folder")).toBeVisible();
 716 |     await expect(tree.getByTestId("hierarchy-icon:file-pdf")).toBeVisible();
 717 |     await expect(tree.getByTestId("hierarchy-icon:file-image")).toBeVisible();
 718 |   });
 719 | 
 720 |   test("handles custom iconField mapping in hierarchy data", async ({
 721 |     initTestBed,
 722 |     createTreeDriver,
 723 |   }) => {
 724 |     await initTestBed(`
 725 |         <VStack height="400px">
 726 |           <Tree testId="tree" 
 727 |             dataFormat="hierarchy" 
 728 |             defaultExpanded="all"
 729 |             idField="nodeId"
 730 |             nameField="title"
 731 |             iconField="iconType"
 732 |             childrenField="items"
 733 |             data='{${JSON.stringify(customIconFieldHierarchy)}}'>
 734 |             <property name="itemTemplate">
 735 |               <HStack testId="{$item.nodeId}:icon:{$item.iconType}" verticalAlignment="center">
 736 |                 <Text testId="hierarchy-icon-type:{$item.iconType}" value="[{$item.iconType}]" />
 737 |                 <Text value="{$item.title}" />
 738 |               </HStack>
 739 |             </property>
 740 |           </Tree>
 741 |         </VStack>
 742 |       `);
 743 |     const tree = await createTreeDriver("tree");
 744 |     await expect(tree.component).toBeVisible();
 745 |     await expect(tree.getByTestId("A1:icon:project-folder")).toBeVisible();
 746 |     await expect(tree.getByTestId("A2:icon:code-folder")).toBeVisible();
 747 |     await expect(tree.getByTestId("A3:icon:typescript-file")).toBeVisible();
 748 |     await expect(tree.getByTestId("A4:icon:typescript-file")).toBeVisible();
 749 |     // Verify individual icon type markers
 750 |     await expect(tree.getByTestId("hierarchy-icon-type:project-folder")).toBeVisible();
 751 |     await expect(tree.getByTestId("hierarchy-icon-type:code-folder")).toBeVisible();
 752 |     await expect(tree.getByTestId("hierarchy-icon-type:typescript-file")).toBeVisible();
 753 |   });
 754 | 
 755 |   test("handles iconExpandedField and iconCollapsedField in hierarchy data", async ({
 756 |     initTestBed,
 757 |     createTreeDriver,
 758 |   }) => {
 759 |     await initTestBed(`
 760 |         <VStack height="400px">
 761 |           <Tree testId="tree" 
 762 |             dataFormat="hierarchy" 
 763 |             iconField="icon"
 764 |             iconExpandedField="iconExpanded"
 765 |             iconCollapsedField="iconCollapsed"
 766 |             data='{${JSON.stringify(hierarchyWithStateIcons)}}'>
 767 |             <property name="itemTemplate">
 768 |               <HStack testId="{$item.id}:icon:{$item.icon}:expanded:{$item.iconExpanded}:collapsed:{$item.iconCollapsed}" verticalAlignment="center">
 769 |                 <Text testId="hierarchy-state-icon:{$isExpanded ? $item.iconExpanded : $item.iconCollapsed}" value="[{$isExpanded ? $item.iconExpanded || $item.icon : $item.iconCollapsed || $item.icon}]" />
 770 |                 <Text value="{$item.name}" />
 771 |               </HStack>
 772 |             </property>
 773 |           </Tree>
 774 |         </VStack>
 775 |       `);
 776 |     const tree = await createTreeDriver("tree");
 777 |     await expect(tree.component).toBeVisible();
 778 |     await expect(
 779 |       tree.getByTestId("1:icon:folder:expanded:folder-open:collapsed:folder-closed"),
 780 |     ).toBeVisible();
 781 |     await expect(
 782 |       tree.getByTestId("2:icon:folder:expanded:folder-open:collapsed:folder-closed"),
 783 |     ).not.toBeVisible(); // Should be collapsed initially
 784 |     await expect(
 785 |       tree.getByTestId("3:icon:file-text:expanded:undefined:collapsed:undefined"),
 786 |     ).not.toBeVisible(); // Should be nested and collapsed
 787 |     // Verify collapsed state icons are shown initially (since defaultExpanded is not set)
 788 |     await expect(tree.getByTestId("hierarchy-state-icon:folder-closed")).toBeVisible();
 789 |   });
 790 | 
 791 |   test("handles missing icon fields gracefully in hierarchy data", async ({
 792 |     initTestBed,
 793 |     createTreeDriver,
 794 |   }) => {
 795 |     await initTestBed(`
 796 |         <VStack height="400px">
 797 |           <Tree testId="tree" 
 798 |             dataFormat="hierarchy" 
 799 |             defaultExpanded="all"
 800 |             iconField="nonExistentIcon"
 801 |             data='{${JSON.stringify(hierarchyTreeData)}}'>
 802 |             <property name="itemTemplate">
 803 |               <HStack testId="{$item.id}:icon:{$item.nonExistentIcon || 'no-icon'}" verticalAlignment="center">
 804 |                 <Text testId="hierarchy-fallback-icon:{$item.nonExistentIcon || 'default'}" value="[{$item.nonExistentIcon || 'default'}]" />
 805 |                 <Text value="{$item.name}" />
 806 |               </HStack>
 807 |             </property>
 808 |           </Tree>
 809 |         </VStack>
 810 |       `);
 811 |     const tree = await createTreeDriver("tree");
 812 |     await expect(tree.component).toBeVisible();
 813 |     await expect(tree.getByTestId("1:icon:no-icon")).toBeVisible();
 814 |     await expect(tree.getByTestId("2:icon:no-icon")).toBeVisible();
 815 |     await expect(tree.getByTestId("3:icon:no-icon")).toBeVisible();
 816 |     await expect(tree.getByTestId("4:icon:no-icon")).toBeVisible();
 817 |     // Verify fallback icons
 818 |     await expect(tree.getByTestId("hierarchy-fallback-icon:default")).toBeVisible();
 819 |   });
 820 | 
 821 |   // =============================================================================
 822 |   // $ITEM CONTEXT PROPERTIES TESTS
 823 |   // =============================================================================
 824 | 
 825 |   test("passes all core $item properties correctly to item template", async ({
 826 |     initTestBed,
 827 |     createTreeDriver,
 828 |   }) => {
 829 |     await initTestBed(`
 830 |         <VStack height="400px">
 831 |           <Tree testId="tree" 
 832 |             dataFormat="flat" 
 833 |             defaultExpanded="all"
 834 |             data='{${JSON.stringify(flatTreeData)}}'>
 835 |             <property name="itemTemplate">
 836 |               <HStack testId="{$item.key}:props:name:{$item.name}|depth:{$item.depth}" verticalAlignment="center">
 837 |                 <Text value="{$item.name} (ID: {$item.id}, Key: {$item.key}, Depth: {$item.depth})" />
 838 |               </HStack>
 839 |             </property>
 840 |           </Tree>
 841 |         </VStack>
 842 |       `);
 843 |     const tree = await createTreeDriver("tree");
 844 |     await expect(tree.component).toBeVisible();
 845 |     // Verify core properties for different items
 846 |     await expect(tree.getByTestId("1:props:name:Root Item 1|depth:0")).toBeVisible();
 847 |     await expect(tree.getByTestId("2:props:name:Child Item 1.1|depth:1")).toBeVisible();
 848 |     await expect(tree.getByTestId("3:props:name:Child Item 1.2|depth:1")).toBeVisible();
 849 |     await expect(tree.getByTestId("4:props:name:Grandchild Item 1.1.1|depth:2")).toBeVisible();
 850 |   });
 851 | 
 852 |   test("passes original source data properties via $item spread", async ({
 853 |     initTestBed,
 854 |     createTreeDriver,
 855 |   }) => {
 856 |     const dataWithExtraProps = [
 857 |       {
 858 |         id: 1,
 859 |         name: "Root",
 860 |         category: "folder",
 861 |         size: "large",
 862 |         customField: "value1",
 863 |         parentId: null,
 864 |       },
 865 |       { id: 2, name: "Child", category: "file", size: "small", customField: "value2", parentId: 1 },
 866 |     ];
 867 | 
 868 |     await initTestBed(`
 869 |         <VStack height="400px">
 870 |           <Tree testId="tree" 
 871 |             dataFormat="flat" 
 872 |             defaultExpanded="all"
 873 |             data='{${JSON.stringify(dataWithExtraProps)}}'>
 874 |             <property name="itemTemplate">
 875 |               <HStack testId="{$item.id}:extra:{$item.category}:{$item.size}:{$item.customField}" verticalAlignment="center">
 876 |                 <Text value="{$item.name} - {$item.category} ({$item.size}) [{$item.customField}]" />
 877 |               </HStack>
 878 |             </property>
 879 |           </Tree>
 880 |         </VStack>
 881 |       `);
 882 |     const tree = await createTreeDriver("tree");
 883 |     await expect(tree.component).toBeVisible();
 884 |     await expect(tree.getByTestId("1:extra:folder:large:value1")).toBeVisible();
 885 |     await expect(tree.getByTestId("2:extra:file:small:value2")).toBeVisible();
 886 |   });
 887 | 
 888 |   test("passes icon properties correctly via $item", async ({ initTestBed, createTreeDriver }) => {
 889 |     await initTestBed(`
 890 |         <VStack height="400px">
 891 |           <Tree testId="tree" 
 892 |             dataFormat="flat" 
 893 |             defaultExpanded="all"
 894 |             data='{${JSON.stringify(flatDataWithIcons)}}'>
 895 |             <property name="itemTemplate">
 896 |               <HStack testId="{$item.key}:icon:{$item.icon}" verticalAlignment="center">
 897 |                 <Text value="{$item.name} [{$item.icon}]" />
 898 |               </HStack>
 899 |             </property>
 900 |           </Tree>
 901 |         </VStack>
 902 |       `);
 903 |     const tree = await createTreeDriver("tree");
 904 |     await expect(tree.component).toBeVisible();
 905 |     await expect(tree.getByTestId("1:icon:folder")).toBeVisible();
 906 |     await expect(tree.getByTestId("2:icon:file-pdf")).toBeVisible();
 907 |     await expect(tree.getByTestId("3:icon:folder")).toBeVisible();
 908 |     await expect(tree.getByTestId("4:icon:file-image")).toBeVisible();
 909 |   });
 910 | 
 911 |   test("passes TreeNode internal properties via $item spread", async ({
 912 |     initTestBed,
 913 |     createTreeDriver,
 914 |   }) => {
 915 |     await initTestBed(`
 916 |         <VStack height="400px">
 917 |           <Tree testId="tree" 
 918 |             dataFormat="flat" 
 919 |             defaultExpanded="all"
 920 |             data='{${JSON.stringify(flatTreeData)}}'>
 921 |             <property name="itemTemplate">
 922 |               <HStack testId="{$item.key}:internal:selectable:{$item.selectable}" verticalAlignment="center">
 923 |                 <Text value="{$item.name} (Selectable: {$item.selectable})" />
 924 |               </HStack>
 925 |             </property>
 926 |           </Tree>
 927 |         </VStack>
 928 |       `);
 929 |     const tree = await createTreeDriver("tree");
 930 |     await expect(tree.component).toBeVisible();
 931 |     await expect(tree.getByTestId("1:internal:selectable:true")).toBeVisible();
 932 |     await expect(tree.getByTestId("2:internal:selectable:true")).toBeVisible();
 933 |     await expect(tree.getByTestId("3:internal:selectable:true")).toBeVisible();
 934 |     await expect(tree.getByTestId("4:internal:selectable:true")).toBeVisible();
 935 |   });
 936 | 
 937 |   test("passes custom field mapped properties correctly in hierarchy format", async ({
 938 |     initTestBed,
 939 |     createTreeDriver,
 940 |   }) => {
 941 |     await initTestBed(`
 942 |         <VStack height="400px">
 943 |           <Tree testId="tree" 
 944 |             dataFormat="hierarchy" 
 945 |             defaultExpanded="all"
 946 |             idField="nodeId"
 947 |             nameField="title"
 948 |             iconField="iconType"
 949 |             childrenField="items"
 950 |             data='{${JSON.stringify(customIconFieldHierarchy)}}'>
 951 |             <property name="itemTemplate">
 952 |               <HStack testId="{$item.nodeId}:mapped:name:{$item.name}|title:{$item.title}|iconType:{$item.iconType}" verticalAlignment="center">
 953 |                 <Text value="Mapped: {$item.name} | Original: {$item.title} | Icon: {$item.iconType}" />
 954 |               </HStack>
 955 |             </property>
 956 |           </Tree>
 957 |         </VStack>
 958 |       `);
 959 |     const tree = await createTreeDriver("tree");
 960 |     await expect(tree.component).toBeVisible();
 961 |     await expect(
 962 |       tree.getByTestId("A1:mapped:name:Project|title:Project|iconType:project-folder"),
 963 |     ).toBeVisible();
 964 |     await expect(
 965 |       tree.getByTestId("A2:mapped:name:Source|title:Source|iconType:code-folder"),
 966 |     ).toBeVisible();
 967 |     await expect(
 968 |       tree.getByTestId("A3:mapped:name:App.tsx|title:App.tsx|iconType:typescript-file"),
 969 |     ).toBeVisible();
 970 |   });
 971 | 
 972 |   test("validates $item properties maintain referential integrity across re-renders", async ({
 973 |     initTestBed,
 974 |     createTreeDriver,
 975 |   }) => {
 976 |     await initTestBed(`
 977 |         <VStack height="400px">
 978 |           <Tree testId="tree" 
 979 |             dataFormat="flat" 
 980 |             defaultExpanded="all"
 981 |             data='{${JSON.stringify(flatTreeData)}}'>
 982 |             <property name="itemTemplate">
 983 |               <HStack testId="{$item.key}:integrity:name:{$item.name}" verticalAlignment="center">
 984 |                 <Text value="{$item.name}" />
 985 |               </HStack>
 986 |             </property>
 987 |           </Tree>
 988 |         </VStack>
 989 |       `);
 990 |     const tree = await createTreeDriver("tree");
 991 |     await expect(tree.component).toBeVisible();
 992 |     // Verify that basic properties are accessible and consistent
 993 |     await expect(tree.getByTestId("1:integrity:name:Root Item 1")).toBeVisible();
 994 |     await expect(tree.getByTestId("2:integrity:name:Child Item 1.1")).toBeVisible();
 995 |     await expect(tree.getByTestId("3:integrity:name:Child Item 1.2")).toBeVisible();
 996 |     await expect(tree.getByTestId("4:integrity:name:Grandchild Item 1.1.1")).toBeVisible();
 997 |   });
 998 | 
 999 |   // =============================================================================
1000 |   // SELECTION MANAGEMENT TESTS
1001 |   // =============================================================================
1002 | 
1003 |   test.describe("Selection Management", () => {
1004 |     test("handles selectedValue property with visual feedback", async ({
1005 |       initTestBed,
1006 |       createTreeDriver,
1007 |     }) => {
1008 |       const SELECTED_BG_COLOR = "rgb(255, 100, 100)";
1009 |       const SELECTED_TEXT_COLOR = "rgb(255, 255, 255)";
1010 |       await initTestBed(
1011 |         `
1012 |         <VStack height="400px">
1013 |           <Tree testId="tree" 
1014 |             dataFormat="flat"
1015 |             defaultExpanded="all"
1016 |             selectedValue="{2}"
1017 |             data='{${JSON.stringify(flatTreeData)}}'>
1018 |             <property name="itemTemplate">
1019 |               <HStack testId="{$item.id}" verticalAlignment="center">
1020 |                 <Text value="{$item.name}" />
1021 |               </HStack>
1022 |             </property>
1023 |           </Tree>
1024 |         </VStack>
1025 |         `,
1026 |         {
1027 |           testThemeVars: {
1028 |             "backgroundColor-Tree-row--selected": SELECTED_BG_COLOR,
1029 |             "textColor-Tree--selected": SELECTED_TEXT_COLOR,
1030 |           },
1031 |         },
1032 |       );
1033 | 
1034 |       const tree = await createTreeDriver("tree");
1035 | 
1036 |       // Get row wrappers directly using getNodeWrapperByMarker
1037 |       const selectedRowWrapper = tree.getNodeWrapperByTestId("2");
1038 |       const item1RowWrapper = tree.getNodeWrapperByTestId("1");
1039 |       const item3RowWrapper = tree.getNodeWrapperByTestId("3");
1040 |       const item4RowWrapper = tree.getNodeWrapperByTestId("4");
1041 | 
1042 |       await expect(selectedRowWrapper).toBeVisible();
1043 | 
1044 |       // Test selected item has correct styling
1045 |       await expect(selectedRowWrapper).toHaveCSS("background-color", SELECTED_BG_COLOR);
1046 |       await expect(selectedRowWrapper).toHaveCSS("color", SELECTED_TEXT_COLOR);
1047 |       await expect(selectedRowWrapper).toHaveClass(/selected/);
1048 | 
1049 |       // Test non-selected items don't have selected styling
1050 |       await expect(item1RowWrapper).not.toHaveCSS("background-color", SELECTED_BG_COLOR);
1051 |       await expect(item3RowWrapper).not.toHaveCSS("background-color", SELECTED_BG_COLOR);
1052 |       await expect(item4RowWrapper).not.toHaveCSS("background-color", SELECTED_BG_COLOR);
1053 |       await expect(item1RowWrapper).not.toHaveClass(/selected/);
1054 |       await expect(item3RowWrapper).not.toHaveClass(/selected/);
1055 |       await expect(item4RowWrapper).not.toHaveClass(/selected/);
1056 |     });
1057 | 
1058 |     test("handles selection with different selectedValue types", async ({
1059 |       initTestBed,
1060 |       createTreeDriver,
1061 |     }) => {
1062 |       const SELECTED_BG_COLOR = "rgb(200, 100, 255)";
1063 |       const SELECTED_TEXT_COLOR = "rgb(255, 255, 255)";
1064 | 
1065 |       await initTestBed(
1066 |         `
1067 |         <VStack height="400px">
1068 |           <Tree testId="tree" 
1069 |             dataFormat="flat"
1070 |             defaultExpanded="all"
1071 |             selectedValue="{3}"
1072 |             data='{${JSON.stringify(flatTreeData)}}'>
1073 |             <property name="itemTemplate">
1074 |               <HStack testId="{$item.id}" verticalAlignment="center">
1075 |                 <Text value="{$item.name}" />
1076 |               </HStack>
1077 |             </property>
1078 |           </Tree>
1079 |         </VStack>
1080 |         `,
1081 |         {
1082 |           testThemeVars: {
1083 |             "backgroundColor-Tree-row--selected": SELECTED_BG_COLOR,
1084 |             "textColor-Tree--selected": SELECTED_TEXT_COLOR,
1085 |           },
1086 |         },
1087 |       );
1088 | 
1089 |       const tree = await createTreeDriver("tree");
1090 | 
1091 |       // Get row wrappers directly using getNodeWrapperByMarker
1092 |       const item1RowWrapper = tree.getNodeWrapperByTestId("1");
1093 |       const item2RowWrapper = tree.getNodeWrapperByTestId("2");
1094 |       const item3RowWrapper = tree.getNodeWrapperByTestId("3");
1095 |       const item4RowWrapper = tree.getNodeWrapperByTestId("4");
1096 | 
1097 |       await expect(item1RowWrapper).toBeVisible();
1098 | 
1099 |       // Item 3 should be selected (with proper string comparison handling)
1100 |       await expect(item3RowWrapper).toHaveCSS("background-color", SELECTED_BG_COLOR);
1101 |       await expect(item3RowWrapper).toHaveCSS("color", SELECTED_TEXT_COLOR);
1102 |       await expect(item3RowWrapper).toHaveClass(/selected/);
1103 | 
1104 |       // Other items should not be selected
1105 |       await expect(item1RowWrapper).not.toHaveCSS("background-color", SELECTED_BG_COLOR);
1106 |       await expect(item2RowWrapper).not.toHaveCSS("background-color", SELECTED_BG_COLOR);
1107 |       await expect(item4RowWrapper).not.toHaveCSS("background-color", SELECTED_BG_COLOR);
1108 | 
1109 |       // Verify class names are correctly applied
1110 |       await expect(item1RowWrapper).not.toHaveClass(/selected/);
1111 |       await expect(item2RowWrapper).not.toHaveClass(/selected/);
1112 |       await expect(item4RowWrapper).not.toHaveClass(/selected/);
1113 |     });
1114 | 
1115 |     test("handles selection with type mismatch tolerance", async ({
1116 |       initTestBed,
1117 |       createTreeDriver,
1118 |     }) => {
1119 |       const SELECTED_BG_COLOR = "rgb(100, 200, 50)";
1120 |       const SELECTED_TEXT_COLOR = "rgb(255, 255, 255)";
1121 |       await initTestBed(
1122 |         `
1123 |         <VStack height="400px">
1124 |           <Tree testId="tree" 
1125 |             dataFormat="flat"
1126 |             defaultExpanded="all"
1127 |             selectedValue="{2}"
1128 |             data='{${JSON.stringify(flatTreeData)}}'>
1129 |             <property name="itemTemplate">
1130 |               <HStack testId="{$item.id}" verticalAlignment="center">
1131 |                 <Text value="{$item.name}" />
1132 |               </HStack>
1133 |             </property>
1134 |           </Tree>
1135 |         </VStack>
1136 |         `,
1137 |         {
1138 |           testThemeVars: {
1139 |             "backgroundColor-Tree-row--selected": SELECTED_BG_COLOR,
1140 |             "textColor-Tree--selected": SELECTED_TEXT_COLOR,
1141 |           },
1142 |         },
1143 |       );
1144 | 
1145 |       const tree = await createTreeDriver("tree");
1146 | 
1147 |       // Get row wrapper directly using getNodeWrapperByMarker
1148 |       const selectedRowWrapper = tree.getNodeWrapperByTestId("2");
1149 | 
1150 |       await expect(selectedRowWrapper).toBeVisible();
1151 | 
1152 |       // Verify selection styling is applied correctly despite type mismatch (selectedValue: number vs itemKey: number)
1153 |       await expect(selectedRowWrapper).toHaveCSS("background-color", SELECTED_BG_COLOR);
1154 |       await expect(selectedRowWrapper).toHaveCSS("color", SELECTED_TEXT_COLOR);
1155 |       await expect(selectedRowWrapper).toHaveClass(/selected/);
1156 |     });
1157 | 
1158 |     test("selection state overrides hover state styling", async ({
1159 |       initTestBed,
1160 |       createTreeDriver,
1161 |     }) => {
1162 |       const SELECTED_BG_COLOR = "rgb(200, 0, 0)";
1163 |       const SELECTED_TEXT_COLOR = "rgb(255, 255, 255)";
1164 |       const HOVER_BG_COLOR = "rgb(0, 0, 200)";
1165 |       const HOVER_TEXT_COLOR = "rgb(255, 255, 0)";
1166 |       await initTestBed(
1167 |         `
1168 |         <VStack height="400px">
1169 |           <Tree testId="tree" 
1170 |             dataFormat="flat"
1171 |             defaultExpanded="all"
1172 |             selectedValue="{2}"
1173 |             data='{${JSON.stringify(flatTreeData)}}'>
1174 |             <property name="itemTemplate">
1175 |               <HStack testId="{$item.id}" verticalAlignment="center">
1176 |                 <Text value="{$item.name}" />
1177 |               </HStack>
1178 |             </property>
1179 |           </Tree>
1180 |         </VStack>
1181 |         `,
1182 |         {
1183 |           testThemeVars: {
1184 |             "backgroundColor-Tree-row--selected": SELECTED_BG_COLOR,
1185 |             "textColor-Tree--selected": SELECTED_TEXT_COLOR,
1186 |             "backgroundColor-Tree-row--hover": HOVER_BG_COLOR,
1187 |             "textColor-Tree--hover": HOVER_TEXT_COLOR,
1188 |           },
1189 |         },
1190 |       );
1191 | 
1192 |       const tree = await createTreeDriver("tree");
1193 | 
1194 |       // Get row wrappers directly using getNodeWrapperByMarker
1195 |       const selectedRowWrapper = tree.getNodeWrapperByTestId("2");
1196 |       const item1RowWrapper = tree.getNodeWrapperByTestId("1");
1197 |       const item3RowWrapper = tree.getNodeWrapperByTestId("3");
1198 | 
1199 |       await expect(selectedRowWrapper).toBeVisible();
1200 | 
1201 |       // Hover over the selected item - selection should override hover
1202 |       await selectedRowWrapper.hover();
1203 |       await expect(selectedRowWrapper).toHaveCSS("background-color", SELECTED_BG_COLOR);
1204 |       await expect(selectedRowWrapper).toHaveCSS("color", SELECTED_TEXT_COLOR);
1205 | 
1206 |       // Hover over non-selected items - should show hover state
1207 |       await item1RowWrapper.hover();
1208 |       await expect(item1RowWrapper).toHaveCSS("background-color", HOVER_BG_COLOR);
1209 |       await expect(item1RowWrapper).toHaveCSS("color", HOVER_TEXT_COLOR);
1210 | 
1211 |       await item3RowWrapper.hover();
1212 |       await expect(item3RowWrapper).toHaveCSS("background-color", HOVER_BG_COLOR);
1213 |       await expect(item3RowWrapper).toHaveCSS("color", HOVER_TEXT_COLOR);
1214 | 
1215 |       // Verify selected item maintains selection styling even after hovering other items
1216 |       await expect(selectedRowWrapper).toHaveCSS("background-color", SELECTED_BG_COLOR);
1217 |       await expect(selectedRowWrapper).toHaveCSS("color", SELECTED_TEXT_COLOR);
1218 |     });
1219 | 
1220 |     test("supports interactive selection changes", async ({ initTestBed, createTreeDriver }) => {
1221 |       const SELECTED_BG_COLOR = "rgb(200, 100, 255)";
1222 |       const SELECTED_TEXT_COLOR = "rgb(255, 255, 255)";
1223 |       const FOCUS_OUTLINE_COLOR = "rgb(255, 100, 100)";
1224 | 
1225 |       await initTestBed(
1226 |         `
1227 |         <VStack height="400px">
1228 |           <Tree testId="tree" 
1229 |             dataFormat="flat"
1230 |             defaultExpanded="all"
1231 |             selectedValue="{2}"
1232 |             data='{${JSON.stringify(flatTreeData)}}'>
1233 |             <property name="itemTemplate">
1234 |               <HStack testId="{$item.id}" verticalAlignment="center">
1235 |                 <Text value="{$item.name}" />
1236 |               </HStack>
1237 |             </property>
1238 |           </Tree>
1239 |         </VStack>
1240 |         `,
1241 |         {
1242 |           testThemeVars: {
1243 |             "backgroundColor-Tree-row--selected": SELECTED_BG_COLOR,
1244 |             "textColor-Tree--selected": SELECTED_TEXT_COLOR,
1245 |             "outlineColor-Tree--focus": FOCUS_OUTLINE_COLOR,
1246 |           },
1247 |         },
1248 |       );
1249 | 
1250 |       const tree = await createTreeDriver("tree");
1251 |       await tree.component.focus();
1252 | 
1253 |       // Get row wrappers directly using getNodeWrapperByMarker
1254 |       const item1RowWrapper = tree.getNodeWrapperByTestId("1");
1255 |       const item2RowWrapper = tree.getNodeWrapperByTestId("2");
1256 | 
1257 |       await expect(item1RowWrapper).toBeVisible();
1258 | 
1259 |       // Item 2 should be initially selected
1260 |       await expect(item2RowWrapper).toHaveCSS("background-color", SELECTED_BG_COLOR);
1261 |       await expect(item2RowWrapper).toHaveCSS("color", SELECTED_TEXT_COLOR);
1262 |       await expect(item2RowWrapper).toHaveClass(/selected/);
1263 | 
1264 |       // Click on item 1 to change selection
1265 |       await tree.getByTestId("1").click();
1266 | 
1267 |       // Item 1 should now be selected
1268 |       await expect(item1RowWrapper).toHaveCSS("background-color", SELECTED_BG_COLOR);
1269 |       await expect(item1RowWrapper).toHaveCSS("color", SELECTED_TEXT_COLOR);
1270 |       await expect(item1RowWrapper).toHaveClass(/selected/);
1271 | 
1272 |       // Item 2 should no longer be selected
1273 |       await expect(item2RowWrapper).not.toHaveCSS("background-color", SELECTED_BG_COLOR);
1274 |       await expect(item2RowWrapper).not.toHaveClass(/selected/);
1275 | 
1276 |       // Verify the tree container maintains focus
1277 |       await expect(tree.component).toBeFocused();
1278 |     });
1279 | 
1280 |     test("handles null/undefined selection gracefully", async ({
1281 |       initTestBed,
1282 |       createTreeDriver,
1283 |     }) => {
1284 |       const SELECTED_BG_COLOR = "rgb(255, 0, 0)";
1285 |       await initTestBed(
1286 |         `
1287 |         <VStack height="400px">
1288 |           <Tree testId="tree" 
1289 |             dataFormat="flat"
1290 |             defaultExpanded="all"
1291 |             selectedValue="{null}"
1292 |             data='{${JSON.stringify(flatTreeData)}}'>
1293 |             <property name="itemTemplate">
1294 |               <HStack testId="{$item.id}" verticalAlignment="center">
1295 |                 <Text value="{$item.name}" />
1296 |               </HStack>
1297 |             </property>
1298 |           </Tree>
1299 |         </VStack>
1300 |         `,
1301 |         {
1302 |           testThemeVars: {
1303 |             "backgroundColor-Tree-row--selected": SELECTED_BG_COLOR,
1304 |           },
1305 |         },
1306 |       );
1307 | 
1308 |       const tree = await createTreeDriver("tree");
1309 | 
1310 |       // Get row wrappers to test no selection highlighting
1311 |       const rowWrapper1 = tree.getNodeWrapperByTestId("1");
1312 |       const rowWrapper2 = tree.getNodeWrapperByTestId("2");
1313 |       const rowWrapper3 = tree.getNodeWrapperByTestId("3");
1314 |       const rowWrapper4 = tree.getNodeWrapperByTestId("4");
1315 | 
1316 |       await expect(rowWrapper1).toBeVisible();
1317 | 
1318 |       // Verify no items are selected when selectedValue is null
1319 |       await expect(rowWrapper1).not.toHaveCSS("background-color", SELECTED_BG_COLOR);
1320 |       await expect(rowWrapper2).not.toHaveCSS("background-color", SELECTED_BG_COLOR);
1321 |       await expect(rowWrapper3).not.toHaveCSS("background-color", SELECTED_BG_COLOR);
1322 |       await expect(rowWrapper4).not.toHaveCSS("background-color", SELECTED_BG_COLOR);
1323 | 
1324 |       // Verify no items have selected class
1325 |       await expect(rowWrapper1).not.toHaveClass(/selected/);
1326 |       await expect(rowWrapper2).not.toHaveClass(/selected/);
1327 |       await expect(rowWrapper3).not.toHaveClass(/selected/);
1328 |       await expect(rowWrapper4).not.toHaveClass(/selected/);
1329 | 
1330 |       // Verify tree is still functional - can select items by clicking
1331 |       await tree.getByTestId("2").click();
1332 |       await expect(rowWrapper2).toHaveCSS("background-color", SELECTED_BG_COLOR);
1333 |       await expect(rowWrapper2).toHaveClass(/selected/);
1334 |     });
1335 | 
1336 |     test("handles invalid selection values gracefully", async ({
1337 |       initTestBed,
1338 |       createTreeDriver,
1339 |     }) => {
1340 |       const SELECTED_BG_COLOR = "rgb(0, 255, 0)";
1341 |       await initTestBed(
1342 |         `
1343 |         <VStack height="400px">
1344 |           <Tree testId="tree" 
1345 |             dataFormat="flat"
1346 |             defaultExpanded="all"
1347 |             selectedValue="999"
1348 |             data='{${JSON.stringify(flatTreeData)}}'>
1349 |             <property name="itemTemplate">
1350 |               <HStack testId="{$item.id}" verticalAlignment="center">
1351 |                 <Text value="{$item.name}" />
1352 |               </HStack>
1353 |             </property>
1354 |           </Tree>
1355 |         </VStack>
1356 |         `,
1357 |         {
1358 |           testThemeVars: {
1359 |             "backgroundColor-Tree-row--selected": SELECTED_BG_COLOR,
1360 |           },
1361 |         },
1362 |       );
1363 | 
1364 |       const tree = await createTreeDriver("tree");
1365 | 
1366 |       // Get row wrappers to test no selection highlighting
1367 |       const rowWrapper1 = tree.getNodeWrapperByTestId("1");
1368 |       const rowWrapper2 = tree.getNodeWrapperByTestId("2");
1369 |       const rowWrapper3 = tree.getNodeWrapperByTestId("3");
1370 |       const rowWrapper4 = tree.getNodeWrapperByTestId("4");
1371 | 
1372 |       await expect(rowWrapper1).toBeVisible();
1373 | 
1374 |       // Verify component doesn't crash with invalid selectedValue and no items are selected
1375 |       await expect(rowWrapper1).not.toHaveCSS("background-color", SELECTED_BG_COLOR);
1376 |       await expect(rowWrapper2).not.toHaveCSS("background-color", SELECTED_BG_COLOR);
1377 |       await expect(rowWrapper3).not.toHaveCSS("background-color", SELECTED_BG_COLOR);
1378 |       await expect(rowWrapper4).not.toHaveCSS("background-color", SELECTED_BG_COLOR);
1379 | 
1380 |       // Verify no items have selected class
1381 |       await expect(rowWrapper1).not.toHaveClass(/selected/);
1382 |       await expect(rowWrapper2).not.toHaveClass(/selected/);
1383 |       await expect(rowWrapper3).not.toHaveClass(/selected/);
1384 |       await expect(rowWrapper4).not.toHaveClass(/selected/);
1385 | 
1386 |       // Verify tree is still functional - can select valid items by clicking
1387 |       await tree.getByTestId("3").click();
1388 |       await expect(rowWrapper3).toHaveCSS("background-color", SELECTED_BG_COLOR);
1389 |       await expect(rowWrapper3).toHaveClass(/selected/);
1390 |     });
1391 | 
1392 |     // =============================================================================
1393 |     // FOCUS MANAGEMENT SUB-TESTS
1394 |     // =============================================================================
1395 | 
1396 |     test("supports keyboard focus navigation with visual feedback", async ({
1397 |       initTestBed,
1398 |       createTreeDriver,
1399 |       page,
1400 |     }) => {
1401 |       const FOCUS_OUTLINE_COLOR = "rgb(255, 0, 255)";
1402 |       const FOCUS_OUTLINE_WIDTH = "3px";
1403 |       await initTestBed(
1404 |         `
1405 |         <VStack height="400px">
1406 |           <Tree testId="tree" 
1407 |             dataFormat="flat"
1408 |             defaultExpanded="all"
1409 |             data='{${JSON.stringify(flatTreeData)}}'>
1410 |             <property name="itemTemplate">
1411 |               <HStack testId="{$item.id}" verticalAlignment="center">
1412 |                 <Text value="{$item.name}" />
1413 |               </HStack>
1414 |             </property>
1415 |           </Tree>
1416 |         </VStack>
1417 |         `,
1418 |         {
1419 |           testThemeVars: {
1420 |             "outlineColor-Tree--focus": FOCUS_OUTLINE_COLOR,
1421 |             "outlineWidth-Tree--focus": FOCUS_OUTLINE_WIDTH,
1422 |           },
1423 |         },
1424 |       );
1425 | 
1426 |       const tree = await createTreeDriver("tree");
1427 | 
1428 |       await expect(tree.getByTestId("1")).toBeVisible();
1429 | 
1430 |       // Focus the tree to trigger focus styling
1431 |       await tree.component.focus();
1432 | 
1433 |       // Use keyboard navigation to trigger focus on an item
1434 |       await page.keyboard.press("ArrowDown");
1435 | 
1436 |       // The second item should be focused now
1437 |       const focusedItem = tree.getNodeWrapperByTestId("2");
1438 |       await expect(focusedItem).toBeVisible();
1439 | 
1440 |       // Check that focus outline uses custom theme variables
1441 |       // Focus styling uses inset box-shadow with the outline color
1442 |       await expect(focusedItem).toHaveCSS(
1443 |         "box-shadow",
1444 |         `${FOCUS_OUTLINE_COLOR} 0px 0px 0px 2px inset`,
1445 |       );
1446 | 
1447 |       // Also verify the focused item has the correct CSS class
1448 |       await expect(focusedItem).toHaveClass(/focused/);
1449 | 
1450 |       // Verify box-shadow contains the custom focus outline color
1451 |       const boxShadowValue = await focusedItem.evaluate((el) => getComputedStyle(el).boxShadow);
1452 |       expect(boxShadowValue).toContain(FOCUS_OUTLINE_COLOR);
1453 | 
1454 |       // Test that focus can move to different items
1455 |       await page.keyboard.press("ArrowDown");
1456 |       const nextFocusedItem = tree.getNodeWrapperByTestId("4"); // Should be the grandchild
1457 |       await expect(nextFocusedItem).toHaveClass(/focused/);
1458 |       await expect(nextFocusedItem).toHaveCSS(
1459 |         "box-shadow",
1460 |         `${FOCUS_OUTLINE_COLOR} 0px 0px 0px 2px inset`,
1461 |       );
1462 | 
1463 |       // Previous item should no longer be focused
1464 |       await expect(focusedItem).not.toHaveClass(/focused/);
1465 | 
1466 |       // Navigate back up
1467 |       await page.keyboard.press("ArrowUp");
1468 |       await expect(focusedItem).toHaveClass(/focused/);
1469 |       await expect(nextFocusedItem).not.toHaveClass(/focused/);
1470 |     });
1471 | 
1472 |     test("focus styling supports comprehensive theme variables", async ({
1473 |       initTestBed,
1474 |       createTreeDriver,
1475 |       page,
1476 |     }) => {
1477 |       const FOCUS_OUTLINE_COLOR = "rgb(0, 255, 0)";
1478 |       const FOCUS_OUTLINE_WIDTH = "4px";
1479 |       const FOCUS_OUTLINE_STYLE = "solid";
1480 |       const FOCUS_OUTLINE_OFFSET = "2px";
1481 | 
1482 |       await initTestBed(
1483 |         `
1484 |         <VStack height="400px">
1485 |           <Tree testId="tree" 
1486 |             dataFormat="flat"
1487 |             defaultExpanded="all"
1488 |             data='{${JSON.stringify(flatTreeData)}}'>
1489 |             <property name="itemTemplate">
1490 |               <HStack testId="{$item.id}" verticalAlignment="center">
1491 |                 <Text value="{$item.name}" />
1492 |               </HStack>
1493 |             </property>
1494 |           </Tree>
1495 |         </VStack>
1496 |         `,
1497 |         {
1498 |           testThemeVars: {
1499 |             "outlineColor-Tree--focus": FOCUS_OUTLINE_COLOR,
1500 |             "outlineWidth-Tree--focus": FOCUS_OUTLINE_WIDTH,
1501 |             "outlineStyle-Tree--focus": FOCUS_OUTLINE_STYLE,
1502 |             "outlineOffset-Tree--focus": FOCUS_OUTLINE_OFFSET,
1503 |           },
1504 |         },
1505 |       );
1506 | 
1507 |       const tree = await createTreeDriver("tree");
1508 | 
1509 |       await expect(tree.getNodeWrapperByTestId("1")).toBeVisible();
1510 | 
1511 |       // Focus the tree and navigate to an item
1512 |       await tree.component.focus();
1513 |       await page.keyboard.press("ArrowDown", {delay: 100});
1514 | 
1515 |       // Test focused item has all custom theme variables applied
1516 |       const focusedItem = tree.getNodeWrapperByTestId("2");
1517 |       await expect(focusedItem).toHaveClass(/focused/);
1518 | 
1519 |       // Verify the focus outline uses all custom theme variables
1520 |       // Note: In the current implementation, focus uses inset box-shadow rather than outline
1521 |       // but the theme variables should still be available for potential outline styling
1522 |       const boxShadowValue = await focusedItem.evaluate((el) => getComputedStyle(el).boxShadow);
1523 |       expect(boxShadowValue).toContain("0, 255, 0"); // Check for green color components
1524 |     });
1525 | 
1526 |     test("combined selection and focus states work together", async ({
1527 |       initTestBed,
1528 |       createTreeDriver,
1529 |       page,
1530 |     }) => {
1531 |       const SELECTED_BG_COLOR = "rgb(255, 50, 50)";
1532 |       const SELECTED_TEXT_COLOR = "rgb(255, 255, 255)";
1533 |       const HOVER_BG_COLOR = "rgb(50, 255, 50)";
1534 |       const HOVER_TEXT_COLOR = "rgb(0, 0, 0)";
1535 |       const DEFAULT_TEXT_COLOR = "rgb(100, 100, 100)";
1536 |       const FOCUS_OUTLINE_COLOR = "rgb(50, 50, 255)";
1537 | 
1538 |       await initTestBed(
1539 |         `
1540 |         <VStack height="400px">
1541 |           <Tree testId="tree" 
1542 |             dataFormat="flat"
1543 |             defaultExpanded="all"
1544 |             selectedValue="{3}"
1545 |             data='{${JSON.stringify(flatTreeData)}}'>
1546 |             <property name="itemTemplate">
1547 |               <HStack testId="{$item.id}" verticalAlignment="center">
1548 |                 <Text value="{$item.name}" />
1549 |               </HStack>
1550 |             </property>
1551 |           </Tree>
1552 |         </VStack>
1553 |         `,
1554 |         {
1555 |           testThemeVars: {
1556 |             "backgroundColor-Tree-row--selected": SELECTED_BG_COLOR,
1557 |             "textColor-Tree--selected": SELECTED_TEXT_COLOR,
1558 |             "backgroundColor-Tree-row--hover": HOVER_BG_COLOR,
1559 |             "textColor-Tree--hover": HOVER_TEXT_COLOR,
1560 |             "textColor-Tree": DEFAULT_TEXT_COLOR,
1561 |             "outlineColor-Tree--focus": FOCUS_OUTLINE_COLOR,
1562 |           },
1563 |         },
1564 |       );
1565 | 
1566 |       const tree = await createTreeDriver("tree");
1567 | 
1568 |       // Test all theme variables work correctly in isolation and combination
1569 |       const selectedRowWrapper = tree.getNodeWrapperByTestId("3");
1570 |       const normalRowWrapper = tree.getNodeWrapperByTestId("1");
1571 |       const hoverRowWrapper = tree.getNodeWrapperByTestId("2");
1572 | 
1573 |       await expect(selectedRowWrapper).toBeVisible();
1574 | 
1575 |       // Test selected item styling
1576 |       await expect(selectedRowWrapper).toHaveCSS("background-color", SELECTED_BG_COLOR);
1577 |       await expect(selectedRowWrapper).toHaveCSS("color", SELECTED_TEXT_COLOR);
1578 |       await expect(selectedRowWrapper).toHaveClass(/selected/);
1579 | 
1580 |       // Test default text color on normal items
1581 |       await expect(normalRowWrapper).toHaveCSS("color", DEFAULT_TEXT_COLOR);
1582 |       await expect(normalRowWrapper).not.toHaveClass(/selected/);
1583 | 
1584 |       // Test hover styling on non-selected item
1585 |       await hoverRowWrapper.hover();
1586 |       await expect(hoverRowWrapper).toHaveCSS("background-color", HOVER_BG_COLOR);
1587 |       await expect(hoverRowWrapper).toHaveCSS("color", HOVER_TEXT_COLOR);
1588 | 
1589 |       // Test hover on selected item (selection should override)
1590 |       await selectedRowWrapper.hover();
1591 |       await expect(selectedRowWrapper).toHaveCSS("background-color", SELECTED_BG_COLOR);
1592 |       await expect(selectedRowWrapper).toHaveCSS("color", SELECTED_TEXT_COLOR);
1593 | 
1594 |       // Test focus styling - ensure we can detect focus
1595 |       await tree.component.focus();
1596 |       // Give some time for focus to be applied
1597 |       await page.waitForTimeout(100);
1598 | 
1599 |       // Check if any item has focus, or skip focus-specific checks for this comprehensive test
1600 |       // The focus behavior is already tested in the dedicated focus tests
1601 |       const anyFocusedElement = page.locator('[data-test-id="tree"] .focused');
1602 |       const hasFocusedElement = (await anyFocusedElement.count()) > 0;
1603 | 
1604 |       if (hasFocusedElement) {
1605 |         // If we have focused elements, verify the color
1606 |         const focusedElement = anyFocusedElement.first();
1607 |         const finalBoxShadowValue = await focusedElement.evaluate(
1608 |           (el) => getComputedStyle(el).boxShadow,
1609 |         );
1610 |         expect(finalBoxShadowValue).toContain("50, 50, 255");
1611 |       }
1612 |       // If no focused element, skip focus-specific validation since focus behavior varies
1613 | 
1614 |       // Verify all theme variables are working simultaneously
1615 |       // Selected item maintains selection while tree has focus
1616 |       await expect(selectedRowWrapper).toHaveCSS("background-color", SELECTED_BG_COLOR);
1617 |       await expect(selectedRowWrapper).toHaveCSS("color", SELECTED_TEXT_COLOR);
1618 |     });
1619 | 
1620 |     test("applies selection and focus with multiple theme configurations", async ({
1621 |       initTestBed,
1622 |       createTreeDriver,
1623 |       page,
1624 |     }) => {
1625 |       const SELECTED_BG_COLOR = "rgb(50, 100, 200)";
1626 |       const SELECTED_TEXT_COLOR = "rgb(255, 255, 255)";
1627 |       const FOCUS_OUTLINE_COLOR = "rgb(255, 165, 0)";
1628 |       const DEFAULT_TEXT_COLOR = "rgb(64, 64, 64)";
1629 | 
1630 |       await initTestBed(
1631 |         `
1632 |         <VStack height="400px">
1633 |           <Tree testId="tree" 
1634 |             dataFormat="flat"
1635 |             defaultExpanded="all"
1636 |             selectedValue="{2}"
1637 |             data='{${JSON.stringify(flatTreeData)}}'>
1638 |             <property name="itemTemplate">
1639 |               <HStack testId="{$item.id}" verticalAlignment="center">
1640 |                 <Text value="{$item.name}" />
1641 |               </HStack>
1642 |             </property>
1643 |           </Tree>
1644 |         </VStack>
1645 |         `,
1646 |         {
1647 |           testThemeVars: {
1648 |             "backgroundColor-Tree-row--selected": SELECTED_BG_COLOR,
1649 |             "textColor-Tree--selected": SELECTED_TEXT_COLOR,
1650 |             "outlineColor-Tree--focus": FOCUS_OUTLINE_COLOR,
1651 |             "textColor-Tree": DEFAULT_TEXT_COLOR,
1652 |           },
1653 |         },
1654 |       );
1655 | 
1656 |       const tree = await createTreeDriver("tree");
1657 | 
1658 |       // Get row wrappers directly using getNodeWrapperByMarker
1659 |       const selectedRowWrapper = tree.getNodeWrapperByTestId("2");
1660 |       const nonSelectedRowWrapper = tree.getNodeWrapperByTestId("1");
1661 | 
1662 |       await expect(selectedRowWrapper).toBeVisible();
1663 | 
1664 |       // Test selection theme variables
1665 |       await expect(selectedRowWrapper).toHaveCSS("background-color", SELECTED_BG_COLOR);
1666 |       await expect(selectedRowWrapper).toHaveCSS("color", SELECTED_TEXT_COLOR);
1667 | 
1668 |       // Test default text color on non-selected items
1669 |       await expect(nonSelectedRowWrapper).toHaveCSS("color", DEFAULT_TEXT_COLOR);
1670 | 
1671 |       // Focus the tree and navigate to trigger focus styling
1672 |       await tree.component.focus();
1673 |       await page.keyboard.press("ArrowDown");
1674 | 
1675 |       // Check if any item received focus (focus behavior can be timing-dependent in tests)
1676 |       const focusedItem = page.locator('[data-test-id="tree"] .focused');
1677 |       const focusedItemCount = await focusedItem.count();
1678 | 
1679 |       if (focusedItemCount > 0) {
1680 |         // If we have focused elements, verify the focus styling uses custom theme variables
1681 |         await expect(focusedItem.first()).toBeVisible();
1682 |         await expect(focusedItem.first()).toHaveCSS(
1683 |           "box-shadow",
1684 |           `${FOCUS_OUTLINE_COLOR} 0px 0px 0px 2px inset`,
1685 |         );
1686 |       }
1687 |       // If no focused element found, skip focus-specific validation as focus behavior is tested elsewhere
1688 |     });
1689 |   });
1690 | 
1691 |   // =============================================================================
1692 |   // EXPANSION STATE TESTS
1693 |   // =============================================================================
1694 | 
1695 |   test.describe("Expansion States", () => {
1696 |     test("handles defaultExpanded none", async ({ initTestBed, createTreeDriver }) => {
1697 |       await initTestBed(`
1698 |         <VStack height="400px">
1699 |           <Tree testId="tree" 
1700 |             dataFormat="flat" 
1701 |             defaultExpanded="none"
1702 |             data='{${JSON.stringify(flatTreeData)}}'>
1703 |             <property name="itemTemplate">
1704 |               <HStack testId="{$item.id}:{$item.name}:depth:{$item.depth}" verticalAlignment="center">
1705 |                 <Text value="{$item.name} (depth: {$item.depth})" />
1706 |               </HStack>
1707 |             </property>
1708 |           </Tree>
1709 |         </VStack>
1710 |       `);
1711 |       const tree = await createTreeDriver("tree");
1712 |       await expect(tree.component).toBeVisible();
1713 | 
1714 |       // Only root level (depth 0) should be visible with defaultExpanded="none"
1715 |       await expect(tree.getByTestId("1:Root Item 1:depth:0")).toBeVisible();
1716 | 
1717 |       // Child nodes (depth 1+) should NOT be visible initially
1718 |       await expect(tree.getByTestId("2:Child Item 1.1:depth:1")).not.toBeVisible();
1719 |       await expect(tree.getByTestId("3:Child Item 1.2:depth:1")).not.toBeVisible();
1720 |       await expect(tree.getByTestId("4:Grandchild Item 1.1.1:depth:2")).not.toBeVisible();
1721 |     });
1722 | 
1723 |     test("handles defaultExpanded all", async ({ initTestBed, createTreeDriver }) => {
1724 |       await initTestBed(`
1725 |         <VStack height="400px">
1726 |           <Tree testId="tree" 
1727 |             dataFormat="flat" 
1728 |             defaultExpanded="all"
1729 |             data='{${JSON.stringify(flatTreeData)}}'>
1730 |             <property name="itemTemplate">
1731 |               <HStack testId="{$item.id}:{$item.name}:depth:{$item.depth}" verticalAlignment="center">
1732 |                 <Text value="{$item.name} (depth: {$item.depth})" />
1733 |               </HStack>
1734 |             </property>
1735 |           </Tree>
1736 |         </VStack>
1737 |       `);
1738 |       const tree = await createTreeDriver("tree");
1739 |       await expect(tree.component).toBeVisible();
1740 | 
1741 |       // All nodes at all depths should be visible with defaultExpanded="all"
1742 |       await expect(tree.getByTestId("1:Root Item 1:depth:0")).toBeVisible();
1743 |       await expect(tree.getByTestId("2:Child Item 1.1:depth:1")).toBeVisible();
1744 |       await expect(tree.getByTestId("3:Child Item 1.2:depth:1")).toBeVisible();
1745 |       await expect(tree.getByTestId("4:Grandchild Item 1.1.1:depth:2")).toBeVisible();
1746 |     });
1747 | 
1748 |     test("handles defaultExpanded first-level", async ({ initTestBed, createTreeDriver }) => {
1749 |       await initTestBed(`
1750 |         <VStack height="400px">
1751 |           <Tree testId="tree" 
1752 |             dataFormat="flat" 
1753 |             defaultExpanded="first-level"
1754 |             data='{${JSON.stringify(flatTreeData)}}'>
1755 |             <property name="itemTemplate">
1756 |               <HStack testId="{$item.id}:{$item.name}:depth:{$item.depth}" verticalAlignment="center">
1757 |                 <Text value="{$item.name} (depth: {$item.depth})" />
1758 |               </HStack>
1759 |             </property>
1760 |           </Tree>
1761 |         </VStack>
1762 |       `);
1763 |       const tree = await createTreeDriver("tree");
1764 |       await expect(tree.component).toBeVisible();
1765 | 
1766 |       // Root level (depth 0) and first level (depth 1) should be visible
1767 |       await expect(tree.getByTestId("1:Root Item 1:depth:0")).toBeVisible();
1768 |       await expect(tree.getByTestId("2:Child Item 1.1:depth:1")).toBeVisible();
1769 |       await expect(tree.getByTestId("3:Child Item 1.2:depth:1")).toBeVisible();
1770 | 
1771 |       // Second level and deeper (depth 2+) should NOT be visible
1772 |       await expect(tree.getByTestId("4:Grandchild Item 1.1.1:depth:2")).not.toBeVisible();
1773 |     });
1774 | 
1775 |     test("handles defaultExpanded with array of string IDs - expands specific nodes making all children visible", async ({
1776 |       initTestBed,
1777 |       createTreeDriver,
1778 |     }) => {
1779 |       await initTestBed(`
1780 |         <VStack height="400px">
1781 |           <Tree testId="tree" 
1782 |             dataFormat="flat" 
1783 |             idField="pk"
1784 |             nameField="label"
1785 |             parentIdField="parent_id"
1786 |             defaultExpanded='{["root-1", "child-1"]}'
1787 |             data='{${JSON.stringify(databaseStyleData)}}'>
1788 |             <property name="itemTemplate">
1789 |               <HStack testId="{$item.pk}:{$item.label}:depth:{$item.depth}:expanded" verticalAlignment="center">
1790 |                 <Text value="{$item.label} (ID: {$item.pk}, Depth: {$item.depth})" />
1791 |               </HStack>
1792 |             </property>
1793 |           </Tree>
1794 |         </VStack>
1795 |       `);
1796 |       const tree = await createTreeDriver("tree");
1797 |       await expect(tree.component).toBeVisible();
1798 | 
1799 |       // When defaultExpanded=["root-1", "child-1"], these specific nodes should be expanded:
1800 | 
1801 |       // 1. Root node "root-1" is expanded → its direct children become visible
1802 |       await expect(tree.getByTestId("root-1:Root Item 1:depth:0:expanded")).toBeVisible();
1803 |       await expect(tree.getByTestId("child-1:Child Item 1.1:depth:1:expanded")).toBeVisible();
1804 |       await expect(tree.getByTestId("child-2:Child Item 1.2:depth:1:expanded")).toBeVisible();
1805 | 
1806 |       // 2. Child node "child-1" is also expanded → its children become visible
1807 |       await expect(
1808 |         tree.getByTestId("grandchild-1:Grandchild Item 1.1.1:depth:2:expanded"),
1809 |       ).toBeVisible();
1810 | 
1811 |       // Verify expansion behavior: each ID in the array expands that specific node,
1812 |       // making its direct children visible. If a child is also in the expansion array,
1813 |       // it will also be expanded, showing its children recursively.
1814 |     });
1815 | 
1816 |     test("handles defaultExpanded array with nodes from different parent branches", async ({
1817 |       initTestBed,
1818 |       createTreeDriver,
1819 |     }) => {
1820 |       await initTestBed(`
1821 |         <VStack height="400px">
1822 |           <Tree testId="tree" 
1823 |             dataFormat="flat" 
1824 |             defaultExpanded='{["doc-root", "proj-web", "media-images"]}'
1825 |             data='{${JSON.stringify(multiBranchTreeData)}}'>
1826 |             <property name="itemTemplate">
1827 |               <HStack testId="{$item.id}:{$item.name}:depth:{$item.depth}" verticalAlignment="center">
1828 |                 <Text value="{$item.name} (ID: {$item.id}, Depth: {$item.depth})" />
1829 |               </HStack>
1830 |             </property>
1831 |           </Tree>
1832 |         </VStack>
1833 |       `);
1834 |       const tree = await createTreeDriver("tree");
1835 |       await expect(tree.component).toBeVisible();
1836 | 
1837 |       // Branch A: "doc-root" is expanded → its direct children are visible
1838 |       await expect(tree.getByTestId("doc-root:Documents:depth:0")).toBeVisible();
1839 |       await expect(tree.getByTestId("doc-reports:Reports:depth:1")).toBeVisible();
1840 |       await expect(tree.getByTestId("doc-invoices:Invoices:depth:1")).toBeVisible();
1841 |       // But grandchildren of doc-root should NOT be visible (doc-reports not expanded)
1842 |       await expect(tree.getByTestId("doc-q1-report:Q1 Report.pdf:depth:2")).not.toBeVisible();
1843 |       await expect(tree.getByTestId("doc-inv-001:Invoice-001.pdf:depth:2")).not.toBeVisible();
1844 | 
1845 |       // Branch B: "proj-root" is auto-expanded because "proj-web" is in defaultExpanded
1846 |       await expect(tree.getByTestId("proj-root:Projects:depth:0")).toBeVisible();
1847 |       await expect(tree.getByTestId("proj-web:Web Apps:depth:1")).toBeVisible(); // Now visible due to auto-expansion
1848 |       await expect(tree.getByTestId("proj-mobile:Mobile Apps:depth:1")).toBeVisible(); // Also visible due to parent expansion
1849 |       // proj-web is expanded → its children are visible
1850 |       await expect(tree.getByTestId("proj-ecommerce:E-commerce Site:depth:2")).toBeVisible();
1851 |       await expect(tree.getByTestId("proj-dashboard:Admin Dashboard:depth:2")).toBeVisible();
1852 |       // proj-mobile is NOT expanded → its children remain hidden
1853 |       await expect(tree.getByTestId("proj-ios-app:iOS Shopping App:depth:2")).not.toBeVisible();
1854 | 
1855 |       // Branch C: "media-root" is auto-expanded because "media-images" is in defaultExpanded
1856 |       await expect(tree.getByTestId("media-root:Media:depth:0")).toBeVisible();
1857 |       await expect(tree.getByTestId("media-images:Images:depth:1")).toBeVisible(); // Now visible due to auto-expansion
1858 |       await expect(tree.getByTestId("media-videos:Videos:depth:1")).toBeVisible(); // Also visible due to parent expansion
1859 |       // media-images is expanded → its children are visible
1860 |       await expect(tree.getByTestId("media-profile-pic:profile.jpg:depth:2")).toBeVisible();
1861 |       await expect(tree.getByTestId("media-banner:banner.png:depth:2")).toBeVisible();
1862 | 
1863 |       // This test validates that defaultExpanded array automatically expands parent paths:
1864 |       // 1. Each ID in defaultExpanded array is expanded AND its full parent path is auto-expanded
1865 |       // 2. Auto-expansion ensures target nodes are visible by expanding their parents
1866 |       // 3. Multiple independent branches can have different expansion states
1867 |       // 4. Only specifically targeted nodes (plus necessary parents) are expanded
1868 |     });
1869 | 
1870 |     test("handles defaultExpanded array expanding multiple independent root branches", async ({
1871 |       initTestBed,
1872 |       createTreeDriver,
1873 |     }) => {
1874 |       await initTestBed(`
1875 |         <VStack height="400px">
1876 |           <Tree testId="tree" 
1877 |             dataFormat="flat" 
1878 |             defaultExpanded='{["doc-root", "proj-root", "doc-reports", "proj-web"]}'
1879 |             data='{${JSON.stringify(multiBranchTreeData)}}'>
1880 |             <property name="itemTemplate">
1881 |               <HStack testId="{$item.id}:{$item.name}:depth:{$item.depth}" verticalAlignment="center">
1882 |                 <Text value="{$item.name} (ID: {$item.id}, Depth: {$item.depth})" />
1883 |               </HStack>
1884 |             </property>
1885 |           </Tree>
1886 |         </VStack>
1887 |       `);
1888 |       const tree = await createTreeDriver("tree");
1889 |       await expect(tree.component).toBeVisible();
1890 | 
1891 |       // Branch A: "doc-root" expanded → children visible, "doc-reports" also expanded → grandchildren visible
1892 |       await expect(tree.getByTestId("doc-root:Documents:depth:0")).toBeVisible();
1893 |       await expect(tree.getByTestId("doc-reports:Reports:depth:1")).toBeVisible();
1894 |       await expect(tree.getByTestId("doc-invoices:Invoices:depth:1")).toBeVisible();
1895 |       // doc-reports is expanded → its children are visible
1896 |       await expect(tree.getByTestId("doc-q1-report:Q1 Report.pdf:depth:2")).toBeVisible();
1897 |       await expect(tree.getByTestId("doc-q2-report:Q2 Report.pdf:depth:2")).toBeVisible();
1898 |       // doc-invoices is NOT expanded → its children are hidden
1899 |       await expect(tree.getByTestId("doc-inv-001:Invoice-001.pdf:depth:2")).not.toBeVisible();
1900 | 
1901 |       // Branch B: "proj-root" expanded → children visible, "proj-web" also expanded → grandchildren visible
1902 |       await expect(tree.getByTestId("proj-root:Projects:depth:0")).toBeVisible();
1903 |       await expect(tree.getByTestId("proj-web:Web Apps:depth:1")).toBeVisible();
1904 |       await expect(tree.getByTestId("proj-mobile:Mobile Apps:depth:1")).toBeVisible();
1905 |       // proj-web is expanded → its children are visible
1906 |       await expect(tree.getByTestId("proj-ecommerce:E-commerce Site:depth:2")).toBeVisible();
1907 |       await expect(tree.getByTestId("proj-dashboard:Admin Dashboard:depth:2")).toBeVisible();
1908 |       // proj-mobile is NOT expanded → its children are hidden
1909 |       await expect(tree.getByTestId("proj-ios-app:iOS Shopping App:depth:2")).not.toBeVisible();
1910 | 
1911 |       // Branch C: "media-root" is NOT in defaultExpanded → children remain hidden
1912 |       await expect(tree.getByTestId("media-root:Media:depth:0")).toBeVisible();
1913 |       await expect(tree.getByTestId("media-images:Images:depth:1")).not.toBeVisible();
1914 |       await expect(tree.getByTestId("media-videos:Videos:depth:1")).not.toBeVisible();
1915 | 
1916 |       // This test validates complete multi-branch expansion:
1917 |       // 1. Multiple root branches can be independently expanded
1918 |       // 2. Sub-nodes within expanded branches can also be selectively expanded
1919 |       // 3. Each expansion is isolated - expanding one branch doesn't affect others
1920 |       // 4. Deep nesting works correctly with selective expansion at each level
1921 |     });
1922 | 
1923 |     test("auto-expands parent paths for defaultExpanded array to ensure target nodes are visible", async ({
1924 |       initTestBed,
1925 |       createTreeDriver,
1926 |     }) => {
1927 |       await initTestBed(`
1928 |         <VStack height="400px">
1929 |           <Tree testId="tree" 
1930 |             dataFormat="flat" 
1931 |             defaultExpanded='{["proj-web", "media-images"]}'
1932 |             data='{${JSON.stringify(multiBranchTreeData)}}'>
1933 |             <property name="itemTemplate">
1934 |               <HStack testId="{$item.id}:{$item.name}:depth:{$item.depth}" verticalAlignment="center">
1935 |                 <Text value="{$item.name} (ID: {$item.id}, Depth: {$item.depth})" />
1936 |               </HStack>
1937 |             </property>
1938 |           </Tree>
1939 |         </VStack>
1940 |       `);
1941 |       const tree = await createTreeDriver("tree");
1942 |       await expect(tree.component).toBeVisible();
1943 | 
1944 |       // The key behavior: even though we only specified "proj-web" and "media-images" in defaultExpanded,
1945 |       // their parent paths should be automatically expanded to make them visible
1946 | 
1947 |       // Branch A: "doc-root" is NOT in defaultExpanded → should remain collapsed
1948 |       await expect(tree.getByTestId("doc-root:Documents:depth:0")).toBeVisible();
1949 |       await expect(tree.getByTestId("doc-reports:Reports:depth:1")).not.toBeVisible();
1950 |       await expect(tree.getByTestId("doc-invoices:Invoices:depth:1")).not.toBeVisible();
1951 | 
1952 |       // Branch B: "proj-web" is in defaultExpanded → parent "proj-root" should auto-expand to make it visible
1953 |       await expect(tree.getByTestId("proj-root:Projects:depth:0")).toBeVisible();
1954 |       await expect(tree.getByTestId("proj-web:Web Apps:depth:1")).toBeVisible(); // Target node should be visible
1955 |       await expect(tree.getByTestId("proj-mobile:Mobile Apps:depth:1")).toBeVisible(); // Sibling visible due to parent expansion
1956 |       // proj-web is expanded → its children should be visible
1957 |       await expect(tree.getByTestId("proj-ecommerce:E-commerce Site:depth:2")).toBeVisible();
1958 |       await expect(tree.getByTestId("proj-dashboard:Admin Dashboard:depth:2")).toBeVisible();
1959 |       // proj-mobile is NOT expanded → its children remain hidden
1960 |       await expect(tree.getByTestId("proj-ios-app:iOS Shopping App:depth:2")).not.toBeVisible();
1961 | 
1962 |       // Branch C: "media-images" is in defaultExpanded → parent "media-root" should auto-expand
1963 |       await expect(tree.getByTestId("media-root:Media:depth:0")).toBeVisible();
1964 |       await expect(tree.getByTestId("media-images:Images:depth:1")).toBeVisible(); // Target node should be visible
1965 |       await expect(tree.getByTestId("media-videos:Videos:depth:1")).toBeVisible(); // Sibling visible due to parent expansion
1966 |       // media-images is expanded → its children should be visible
1967 |       await expect(tree.getByTestId("media-profile-pic:profile.jpg:depth:2")).toBeVisible();
1968 |       await expect(tree.getByTestId("media-banner:banner.png:depth:2")).toBeVisible();
1969 | 
1970 |       // This test validates the auto-expansion behavior:
1971 |       // 1. When a node ID is in defaultExpanded, all its parent nodes are automatically expanded
1972 |       // 2. This ensures the target node is visible and can display its expanded state
1973 |       // 3. Parent expansion makes sibling nodes visible but doesn't expand them
1974 |       // 4. Only the specifically targeted nodes (plus their parents) are expanded
1975 |     });
1976 | 
1977 |     test.skip(
1978 |       "handles expandedValues property",
1979 |       SKIP_REASON.TO_BE_IMPLEMENTED(),
1980 |       async ({ initTestBed, page }) => {
1981 |         // TODO: Test controlled expansion state with expandedValues prop
1982 |         // TODO: Verify expansion state synchronization with external control
1983 |         await initTestBed(`
1984 |         <Tree 
1985 |           testId="tree" 
1986 |           data="{flatTreeData}" 
1987 |           dataFormat="flat"
1988 |           expandedValues="{[1]}"
1989 |         />
1990 |       `);
1991 |       },
1992 |     );
1993 | 
1994 |     test.skip(
1995 |       "supports expansion toggle by chevron click",
1996 |       SKIP_REASON.TO_BE_IMPLEMENTED(),
1997 |       async ({ initTestBed, page }) => {
1998 |         // TODO: Test clicking expand/collapse chevron toggles node expansion
1999 |         // TODO: Verify child nodes become visible/hidden appropriately
2000 |         await initTestBed(`
2001 |         <Tree 
2002 |           testId="tree" 
2003 |           data="{flatTreeData}" 
2004 |           dataFormat="flat"
2005 |         />
2006 |       `);
2007 |       },
2008 |     );
2009 | 
2010 |     test.skip(
2011 |       "supports expansion toggle by item click when enabled",
2012 |       SKIP_REASON.TO_BE_IMPLEMENTED(),
2013 |       async ({ initTestBed, page }) => {
2014 |         // TODO: Test itemClickExpands prop enables expansion on full item click
2015 |         // TODO: Verify clicking anywhere on item (not just chevron) toggles expansion
2016 |         await initTestBed(`
2017 |         <Tree 
2018 |           testId="tree" 
2019 |           data="{flatTreeData}" 
2020 |           dataFormat="flat"
2021 |           itemClickExpands="true"
2022 |         />
2023 |       `);
2024 |       },
2025 |     );
2026 | 
2027 |     test.skip(
2028 |       "handles autoExpandToSelection",
2029 |       SKIP_REASON.TO_BE_IMPLEMENTED(),
2030 |       async ({ initTestBed, page }) => {
2031 |         // TODO: Test automatic expansion of path to selected item
2032 |         // TODO: Verify all parent nodes of selected item are expanded
2033 |         await initTestBed(`
2034 |         <Tree 
2035 |           testId="tree" 
2036 |           data="{flatTreeData}" 
2037 |           dataFormat="flat"
2038 |           selectedValue="4"
2039 |           autoExpandToSelection="true"
2040 |         />
2041 |       `);
2042 |       },
2043 |     );
2044 |   });
2045 | });
2046 | 
2047 | // =============================================================================
2048 | // EVENTS TESTS
2049 | // =============================================================================
2050 | 
2051 | test.describe("Events", () => {
2052 |   test.describe("selectionDidChange Event", () => {
2053 |     test("fires when user clicks on a selectable node", async ({
2054 |       initTestBed,
2055 |       createTreeDriver,
2056 |     }) => {
2057 |       const { testStateDriver } = await initTestBed(`
2058 |         <VStack height="400px">
2059 |           <Tree testId="tree" 
2060 |             dataFormat="flat" 
2061 |             data='{${JSON.stringify(flatTreeData)}}'
2062 |             onSelectionDidChange="event => testState = event">
2063 |             <property name="itemTemplate">
2064 |               <HStack testId="{$item.id}">
2065 |                 <Text value="{$item.name}" />
2066 |               </HStack>
2067 |             </property>
2068 |           </Tree>
2069 |         </VStack>
2070 |       `);
2071 | 
2072 |       const tree = await createTreeDriver("tree");
2073 | 
2074 |       // Click on the first item
2075 |       await tree.getByTestId("1").click();
2076 | 
2077 |       // Verify selectionDidChange event was fired with correct data
2078 |       await expect.poll(() => testStateDriver.testState()).toBeDefined();
2079 |       const event = await testStateDriver.testState();
2080 |       expect(event.newNode).toBeDefined();
2081 |       expect(event.newNode.id).toBe(1);
2082 |       expect(event.newNode.displayName).toBe("Root Item 1");
2083 |       expect(event.previousNode).toBeNull();
2084 |     });
2085 | 
2086 |     test("fires with previous node when selection changes", async ({
2087 |       initTestBed,
2088 |       createTreeDriver,
2089 |     }) => {
2090 |       const { testStateDriver } = await initTestBed(`
2091 |         <VStack height="400px">
2092 |           <Tree testId="tree" 
2093 |             dataFormat="flat" 
2094 |             defaultExpanded="all"
2095 |             data='{${JSON.stringify(flatTreeData)}}'
2096 |             onSelectionDidChange="event => testState = event">
2097 |             <property name="itemTemplate">
2098 |               <HStack testId="{$item.id}">
2099 |                 <Text value="{$item.name}" />
2100 |               </HStack>
2101 |             </property>
2102 |           </Tree>
2103 |         </VStack>
2104 |       `);
2105 | 
2106 |       const tree = await createTreeDriver("tree");
2107 | 
2108 |       // First selection
2109 |       await tree.getByTestId("1").click();
2110 | 
2111 |       // Second selection
2112 |       await tree.getByTestId("2").click();
2113 | 
2114 |       // Verify event has both previous and new node
2115 |       await expect.poll(() => testStateDriver.testState()?.then((s) => s?.newNode?.id)).toBe(2);
2116 |       const event = await testStateDriver.testState();
2117 |       expect(event.previousNode.id).toBe(1);
2118 |     });
2119 |   });
2120 | 
2121 |   test.describe("nodeDidExpand Event", () => {
2122 |     test("fires after successful node expansion", async ({ initTestBed, createTreeDriver }) => {
2123 |       const { testStateDriver } = await initTestBed(`
2124 |         <VStack height="400px">
2125 |           <Tree testId="tree" 
2126 |             dataFormat="hierarchy"
2127 |             itemClickExpands="true"
2128 |             data='{${JSON.stringify(hierarchyTreeData)}}'
2129 |             onNodeDidExpand="node => testState = node">
2130 |             <property name="itemTemplate">
2131 |               <HStack testId="{$item.id}">
2132 |                 <Text value="{$item.name}" />
2133 |               </HStack>
2134 |             </property>
2135 |           </Tree>
2136 |         </VStack>
2137 |       `);
2138 | 
2139 |       const tree = await createTreeDriver("tree");
2140 | 
2141 |       // Click to expand first node
2142 |       await tree.getByTestId("1").click();
2143 | 
2144 |       // Verify nodeDidExpand event fired
2145 |       await expect.poll(() => testStateDriver.testState().then((s) => s?.id)).toBe(1);
2146 | 
2147 |       // Verify child is now visible
2148 |       await expect(tree.getByTestId("2")).toBeVisible();
2149 |     });
2150 |   });
2151 | 
2152 |   test.describe("nodeDidCollapse Event", () => {
2153 |     test("fires after successful node collapse", async ({ initTestBed, createTreeDriver }) => {
2154 |       const { testStateDriver } = await initTestBed(`
2155 |         <VStack height="400px">
2156 |           <Tree testId="tree" 
2157 |             dataFormat="hierarchy" 
2158 |             itemClickExpands="true"
2159 |             defaultExpanded="all"
2160 |             data='{${JSON.stringify(hierarchyTreeData)}}'
2161 |             onNodeDidCollapse="node => testState = node">
2162 |             <property name="itemTemplate">
2163 |               <HStack testId="{$item.id}">
2164 |                 <Text value="{$item.name}" />
2165 |               </HStack>
2166 |             </property>
2167 |           </Tree>
2168 |         </VStack>
2169 |       `);
2170 | 
2171 |       const tree = await createTreeDriver("tree");
2172 | 
2173 |       // First, verify child is visible (node starts expanded)
2174 |       await expect(tree.getByTestId("2")).toBeVisible();
2175 | 
2176 |       // Click to collapse expanded node
2177 |       await tree.getByTestId("1").click();
2178 | 
2179 |       // Verify nodeDidCollapse fired with correct node
2180 |       await expect.poll(() => testStateDriver.testState().then((s) => s?.id)).toBe(1);
2181 | 
2182 |       // Verify child is no longer visible
2183 |       await expect(tree.getByTestId("2")).not.toBeVisible();
2184 |     });
2185 | 
2186 |     // Note: Additional collapse tests can be added when TreeDriver supports programmatic collapse operations
2187 |   });
2188 | 
2189 |   // =============================================================================
2190 |   // KEYBOARD EVENT TESTS
2191 |   // =============================================================================
2192 | 
2193 |   test.describe("Keyboard Events", () => {
2194 |     test.describe("selectionDidChange Event via Keyboard", () => {
2195 |       test("fires when Enter key is pressed on a selectable node", async ({
2196 |         initTestBed,
2197 |         createTreeDriver,
2198 |       }) => {
2199 |         const { testStateDriver } = await initTestBed(`
2200 |           <VStack height="400px">
2201 |             <Tree testId="tree" 
2202 |               dataFormat="flat" 
2203 |               data='{${JSON.stringify(flatTreeData)}}'
2204 |               onSelectionDidChange="event => testState = event">
2205 |               <property name="itemTemplate">
2206 |                 <HStack testId="{$item.id}">
2207 |                   <Text value="{$item.name}" />
2208 |                 </HStack>
2209 |               </property>
2210 |             </Tree>
2211 |           </VStack>
2212 |         `);
2213 | 
2214 |         const tree = await createTreeDriver("tree");
2215 | 
2216 |         // Focus the tree and navigate to first item
2217 |         await tree.component.focus();
2218 | 
2219 |         // Press Enter to select the focused node
2220 |         await tree.component.press("Enter");
2221 | 
2222 |         // Verify selectionDidChange event was fired with correct data
2223 |         await expect.poll(() => testStateDriver.testState()).toBeDefined();
2224 |         const event = await testStateDriver.testState();
2225 |         expect(event.newNode).toBeDefined();
2226 |         expect(event.newNode.id).toBe(1);
2227 |         expect(event.newNode.displayName).toBe("Root Item 1");
2228 |         expect(event.previousNode).toBeNull();
2229 |       });
2230 | 
2231 |       test("fires when Space key is pressed on a selectable node", async ({
2232 |         initTestBed,
2233 |         createTreeDriver,
2234 |       }) => {
2235 |         const { testStateDriver } = await initTestBed(`
2236 |           <VStack height="400px">
2237 |             <Tree testId="tree" 
2238 |               dataFormat="flat" 
2239 |               data='{${JSON.stringify(flatTreeData)}}'
2240 |               onSelectionDidChange="event => testState = event">
2241 |               <property name="itemTemplate">
2242 |                 <HStack testId="{$item.id}">
2243 |                   <Text value="{$item.name}" />
2244 |                 </HStack>
2245 |               </property>
2246 |             </Tree>
2247 |           </VStack>
2248 |         `);
2249 | 
2250 |         const tree = await createTreeDriver("tree");
2251 | 
2252 |         // Focus the tree (this starts focus on first item)
2253 |         await tree.component.focus();
2254 | 
2255 |         // Press Space to select the currently focused node (should be first node)
2256 |         await tree.component.press("Space");
2257 | 
2258 |         // Verify selectionDidChange event was fired with correct data
2259 |         await expect.poll(() => testStateDriver.testState()).toBeDefined();
2260 |         const event = await testStateDriver.testState();
2261 |         expect(event.newNode).toBeDefined();
2262 |         expect(event.newNode.id).toBe(1); // Should be first node since we didn't navigate
2263 |         expect(event.newNode.displayName).toBe("Root Item 1");
2264 |         expect(event.previousNode).toBeNull();
2265 |       });
2266 | 
2267 |       test("fires with previous node when selection changes via keyboard", async ({
2268 |         initTestBed,
2269 |         createTreeDriver,
2270 |       }) => {
2271 |         const { testStateDriver } = await initTestBed(`
2272 |           <VStack height="400px">
2273 |             <Tree testId="tree" 
2274 |               dataFormat="flat" 
2275 |               defaultExpanded="all"
2276 |               data='{${JSON.stringify(flatTreeData)}}'
2277 |               onSelectionDidChange="event => testState = event">
2278 |               <property name="itemTemplate">
2279 |                 <HStack testId="{$item.id}">
2280 |                   <Text value="{$item.name}" />
2281 |                 </HStack>
2282 |               </property>
2283 |             </Tree>
2284 |           </VStack>
2285 |         `);
2286 | 
2287 |         const tree = await createTreeDriver("tree");
2288 | 
2289 |         // Click to select first node (using mouse to establish baseline)
2290 |         await tree.getByTestId("1").click();
2291 | 
2292 |         // Now use keyboard to navigate and select second node
2293 |         await tree.component.focus();
2294 |         await tree.component.press("ArrowDown"); // Navigate to second node
2295 |         await tree.component.press("Enter"); // Select it
2296 | 
2297 |         // Verify event has both previous and new node
2298 |         await expect.poll(() => testStateDriver.testState()?.then((s) => s?.newNode?.id)).toBe(2);
2299 |         const event = await testStateDriver.testState();
2300 |         expect(event.previousNode.id).toBe(1);
2301 |         expect(event.newNode.id).toBe(2);
2302 |       });
2303 |     });
2304 | 
2305 |     test.describe("nodeDidExpand Event via Keyboard", () => {
2306 |       test("fires when Right arrow key expands a collapsed node", async ({
2307 |         initTestBed,
2308 |         createTreeDriver,
2309 |       }) => {
2310 |         const { testStateDriver } = await initTestBed(`
2311 |           <VStack height="400px">
2312 |             <Tree testId="tree" 
2313 |               dataFormat="hierarchy"
2314 |               data='{${JSON.stringify(hierarchyTreeData)}}'
2315 |               onNodeDidExpand="node => testState = node">
2316 |               <property name="itemTemplate">
2317 |                 <HStack testId="{$item.id}">
2318 |                   <Text value="{$item.name}" />
2319 |                 </HStack>
2320 |               </property>
2321 |             </Tree>
2322 |           </VStack>
2323 |         `);
2324 | 
2325 |         const tree = await createTreeDriver("tree");
2326 | 
2327 |         // Focus the tree (first node should be focused)
2328 |         await tree.component.focus();
2329 | 
2330 |         // Press Right arrow to expand the first node
2331 |         await tree.component.press("ArrowRight");
2332 | 
2333 |         // Verify nodeDidExpand event fired
2334 |         await expect.poll(() => testStateDriver.testState().then((s) => s?.id)).toBe(1);
2335 | 
2336 |         // Verify child is now visible
2337 |         await expect(tree.getByTestId("2")).toBeVisible();
2338 |       });
2339 | 
2340 |       test("fires when Enter key expands a collapsed node with children", async ({
2341 |         initTestBed,
2342 |         createTreeDriver,
2343 |       }) => {
2344 |         const { testStateDriver } = await initTestBed(`
2345 |           <VStack height="400px">
2346 |             <Tree testId="tree" 
2347 |               dataFormat="hierarchy"
2348 |               data='{${JSON.stringify(hierarchyTreeData)}}'
2349 |               onNodeDidExpand="node => testState = node">
2350 |               <property name="itemTemplate">
2351 |                 <HStack testId="{$item.id}">
2352 |                   <Text value="{$item.name}" />
2353 |                 </HStack>
2354 |               </property>
2355 |             </Tree>
2356 |           </VStack>
2357 |         `);
2358 | 
2359 |         const tree = await createTreeDriver("tree");
2360 | 
2361 |         // Focus the tree and press Enter to expand first node
2362 |         await tree.component.focus();
2363 |         await tree.component.press("Enter");
2364 | 
2365 |         // Verify nodeDidExpand event fired
2366 |         await expect.poll(() => testStateDriver.testState().then((s) => s?.id)).toBe(1);
2367 | 
2368 |         // Verify child is now visible
2369 |         await expect(tree.getByTestId("2")).toBeVisible();
2370 |       });
2371 | 
2372 |       test("only Enter key expands nodes - Space only selects", async ({
2373 |         initTestBed,
2374 |         createTreeDriver,
2375 |       }) => {
2376 |         const { testStateDriver } = await initTestBed(`
2377 |           <VStack height="400px" var.selectionFired="false">
2378 |             <Tree testId="tree" 
2379 |               dataFormat="hierarchy"
2380 |               data='{${JSON.stringify(hierarchyTreeData)}}'
2381 |               onNodeDidExpand="node => testState = node"
2382 |               onSelectionDidChange="event => selectionFired = true">
2383 |               <property name="itemTemplate">
2384 |                 <HStack testId="{$item.id}">
2385 |                   <Text value="{$item.name}" />
2386 |                 </HStack>
2387 |               </property>
2388 |             </Tree>
2389 |           </VStack>
2390 |         `);
2391 | 
2392 |         const tree = await createTreeDriver("tree");
2393 | 
2394 |         // Focus the tree and press Space - should only trigger selection, not expansion
2395 |         await tree.component.focus();
2396 |         await tree.component.press("Space");
2397 | 
2398 |         // Wait a bit to ensure no expansion event fires
2399 |         await tree.component.waitFor({ timeout: 1000 });
2400 | 
2401 |         // Verify no expansion event fired (testState should remain null)
2402 |         const expandState = await testStateDriver.testState();
2403 |         expect(expandState).toBeNull();
2404 | 
2405 |         // Verify children are still not visible
2406 |         await expect(tree.getByTestId("2")).not.toBeVisible();
2407 |       });
2408 |     });
2409 | 
2410 |     test.describe("nodeDidCollapse Event via Keyboard", () => {
2411 |       test("fires when Left arrow key collapses an expanded node", async ({
2412 |         initTestBed,
2413 |         createTreeDriver,
2414 |       }) => {
2415 |         const { testStateDriver } = await initTestBed(`
2416 |           <VStack height="400px">
2417 |             <Tree testId="tree" 
2418 |               dataFormat="hierarchy" 
2419 |               defaultExpanded="all"
2420 |               data='{${JSON.stringify(hierarchyTreeData)}}'
2421 |               onNodeDidCollapse="node => testState = node">
2422 |               <property name="itemTemplate">
2423 |                 <HStack testId="{$item.id}">
2424 |                   <Text value="{$item.name}" />
2425 |                 </HStack>
2426 |               </property>
2427 |             </Tree>
2428 |           </VStack>
2429 |         `);
2430 | 
2431 |         const tree = await createTreeDriver("tree");
2432 | 
2433 |         // Verify child is initially visible (node starts expanded)
2434 |         await expect(tree.getByTestId("2")).toBeVisible();
2435 | 
2436 |         // Focus the tree and press Left arrow to collapse the first node
2437 |         await tree.component.focus();
2438 |         await tree.component.press("ArrowLeft");
2439 | 
2440 |         // Verify nodeDidCollapse fired with correct node
2441 |         await expect.poll(() => testStateDriver.testState().then((s) => s?.id)).toBe(1);
2442 | 
2443 |         // Verify child is no longer visible
2444 |         await expect(tree.getByTestId("2")).not.toBeVisible();
2445 |       });
2446 | 
2447 |       test("fires when Left arrow navigates from child to parent and collapses parent", async ({
2448 |         initTestBed,
2449 |         createTreeDriver,
2450 |       }) => {
2451 |         const { testStateDriver } = await initTestBed(`
2452 |           <VStack height="400px">
2453 |             <Tree testId="tree" 
2454 |               dataFormat="hierarchy" 
2455 |               defaultExpanded="all"
2456 |               data='{${JSON.stringify(hierarchyTreeData)}}'
2457 |               onNodeDidCollapse="node => testState = node">
2458 |               <property name="itemTemplate">
2459 |                 <HStack testId="{$item.id}">
2460 |                   <Text value="{$item.name}" />
2461 |                 </HStack>
2462 |               </property>
2463 |             </Tree>
2464 |           </VStack>
2465 |         `);
2466 | 
2467 |         const tree = await createTreeDriver("tree");
2468 | 
2469 |         // Verify child is initially visible (node starts expanded)
2470 |         await expect(tree.getByTestId("2")).toBeVisible();
2471 |         await tree.component.focus();
2472 |         await tree.component.press("ArrowDown"); // Move to child node
2473 |         await tree.component.press("ArrowLeft"); // Navigate to parent
2474 | 
2475 |         // Then collapse the parent by pressing Left again
2476 |         await tree.component.press("ArrowLeft");
2477 | 
2478 |         // Verify nodeDidCollapse fired with correct node
2479 |         await expect.poll(() => testStateDriver.testState().then((s) => s?.id)).toBe(1);
2480 | 
2481 |         // Verify child is no longer visible
2482 |         await expect(tree.getByTestId("2")).not.toBeVisible();
2483 |       });
2484 |     });
2485 | 
2486 |     test.describe("Complex Keyboard Event Scenarios", () => {
2487 |       test("fires multiple events during keyboard navigation session", async ({
2488 |         initTestBed,
2489 |         createTreeDriver,
2490 |       }) => {
2491 |         const { testStateDriver } = await initTestBed(`
2492 |           <VStack height="400px" var.eventCount="0" var.lastEvent="">
2493 |             <Tree testId="tree" 
2494 |               dataFormat="hierarchy"
2495 |               data='{${JSON.stringify(hierarchyTreeData)}}'
2496 |               onSelectionDidChange="event => { eventCount++; lastEvent = 'selection:' + event.newNode?.id; testState = { count: eventCount, last: lastEvent }; }"
2497 |               onNodeDidExpand="node => { eventCount++; lastEvent = 'expand:' + node.id; testState = { count: eventCount, last: lastEvent }; }"
2498 |               onNodeDidCollapse="node => { eventCount++; lastEvent = 'collapse:' + node.id; testState = { count: eventCount, last: lastEvent }; }">
2499 |               <property name="itemTemplate">
2500 |                 <HStack testId="{$item.id}">
2501 |                   <Text value="{$item.name}" />
2502 |                 </HStack>
2503 |               </property>
2504 |             </Tree>
2505 |           </VStack>
2506 |         `);
2507 | 
2508 |         const tree = await createTreeDriver("tree");
2509 | 
2510 |         // Simple keyboard interaction sequence
2511 |         await tree.component.focus();
2512 | 
2513 |         // 1. Select and expand first node (Enter does both)
2514 |         await tree.component.press("Enter");
2515 | 
2516 |         // 2. Navigate to child and select it
2517 |         await tree.component.press("ArrowDown");
2518 |         await tree.component.press("Space"); // Select child (Space only selects)
2519 | 
2520 |         // Verify we have multiple events (using poll for async events)
2521 |         await expect.poll(() => testStateDriver.testState().then((s) => s?.count)).toBe(2);
2522 |         const result = await testStateDriver.testState();
2523 | 
2524 |         // Check that we captured events (last event should be selection)
2525 |         expect(result.last).toMatch(/selection:\d+/);
2526 |       });
2527 | 
2528 |       test("handles rapid keyboard interactions without missing events", async ({
2529 |         initTestBed,
2530 |         createTreeDriver,
2531 |       }) => {
2532 |         const { testStateDriver } = await initTestBed(`
2533 |           <VStack height="400px" var.expandCount="0">
2534 |             <Tree testId="tree" 
2535 |               dataFormat="hierarchy"
2536 |               data='{${JSON.stringify(hierarchyTreeData)}}'
2537 |               onNodeDidExpand="node => { expandCount++; testState = expandCount; }">
2538 |               <property name="itemTemplate">
2539 |                 <HStack testId="{$item.id}">
2540 |                   <Text value="{$item.name}" />
2541 |                 </HStack>
2542 |               </property>
2543 |             </Tree>
2544 |           </VStack>
2545 |         `);
2546 | 
2547 |         const tree = await createTreeDriver("tree");
2548 |         await tree.component.focus();
2549 | 
2550 |         // Rapid expand/collapse sequence
2551 |         await tree.component.press("ArrowRight"); // Expand
2552 |         await tree.component.press("ArrowLeft"); // Collapse
2553 |         await tree.component.press("ArrowRight"); // Expand again
2554 |         await tree.component.press("ArrowLeft"); // Collapse again
2555 |         await tree.component.press("ArrowRight"); // Expand third time
2556 | 
2557 |         // Verify all expansion events were captured
2558 |         await expect.poll(() => testStateDriver.testState()).toBe(3);
2559 |       });
2560 |     });
2561 |   });
2562 | 
2563 |   // =============================================================================
2564 |   // API EVENT TESTS
2565 |   // =============================================================================
2566 | 
2567 |   test.describe("API Events", () => {
2568 |     test.describe("nodeDidExpand Event via API", () => {
2569 |       test("fires when expandNode() API method is called", async ({
2570 |         initTestBed,
2571 |         createTreeDriver,
2572 |         createButtonDriver,
2573 |       }) => {
2574 |         const { testStateDriver } = await initTestBed(`
2575 |           <Fragment>
2576 |             <VStack height="400px">
2577 |               <Tree id="treeApi" testId="tree"
2578 |                 dataFormat="hierarchy"
2579 |                 defaultExpanded="none"
2580 |                 data='{${JSON.stringify(hierarchyTreeData)}}'
2581 |                 onNodeDidExpand="node => testState = node">
2582 |                 <property name="itemTemplate">
2583 |                   <HStack testId="{$item.id}">
2584 |                     <Text value="{$item.name}" />
2585 |                   </HStack>
2586 |                 </property>
2587 |               </Tree>
2588 |             </VStack>
2589 |             <Button testId="expand-btn" label="Expand Node 1" onClick="
2590 |               treeApi.expandNode(1);
2591 |             " />
2592 |           </Fragment>
2593 |         `);
2594 | 
2595 |         const tree = await createTreeDriver("tree");
2596 |         const expandButton = await createButtonDriver("expand-btn");
2597 | 
2598 |         // Initially, child should not be visible
2599 |         await expect(tree.getByTestId("2")).not.toBeVisible();
2600 | 
2601 |         // Trigger API expansion
2602 |         await expandButton.click();
2603 | 
2604 |         // Verify nodeDidExpand event fired
2605 |         await expect.poll(() => testStateDriver.testState().then((s) => s?.id)).toBe(1);
2606 | 
2607 |         // Verify child is now visible
2608 |         await expect(tree.getByTestId("2")).toBeVisible();
2609 |       });
2610 | 
2611 |       test("fires for expandAll() API method", async ({
2612 |         page,
2613 |         initTestBed,
2614 |         createTreeDriver,
2615 |         createButtonDriver,
2616 |       }) => {
2617 |         await initTestBed(`
2618 |           <Fragment>
2619 |             <VStack height="400px" var.expandEvents="[]">
2620 |               <Text testId="eventsText">{expandEvents}</Text>
2621 |               <Tree id="treeApi" testId="tree"
2622 |                 dataFormat="hierarchy"
2623 |                 defaultExpanded="none"
2624 |                 data='{${JSON.stringify(hierarchyTreeData)}}'
2625 |                 onNodeDidExpand="node => {expandEvents.push(node.id)}"
2626 |               >
2627 |                 <property name="itemTemplate">
2628 |                   <HStack testId="{$item.id}">
2629 |                     <Text value="{$item.name}" />
2630 |                   </HStack>
2631 |                 </property>
2632 |               </Tree>
2633 |             </VStack>
2634 |             <Button testId="expand-all-btn" label="Expand All" onClick="
2635 |               treeApi.expandAll();
2636 |             " />
2637 |           </Fragment>
2638 |         `);
2639 | 
2640 |         const tree = await createTreeDriver("tree");
2641 |         const expandAllButton = await createButtonDriver("expand-all-btn");
2642 | 
2643 |         // Trigger API expand all
2644 |         await expandAllButton.click();
2645 | 
2646 |         const eventsText = page.getByTestId("eventsText");
2647 | 
2648 |         // expandAll() does not fire individual nodeDidExpand events
2649 |         // This is the correct behavior - mass operations should not fire individual events
2650 |         await expect(eventsText).toHaveText("[]");
2651 | 
2652 |         // But verify the visual result is correct - all nodes should be visible
2653 |         await expect(tree.getByTestId("2")).toBeVisible();
2654 |         await expect(tree.getByTestId("4")).toBeVisible();
2655 |       });
2656 | 
2657 |       test("fires for expandToLevel() API method", async ({
2658 |         page,
2659 |         initTestBed,
2660 |         createTreeDriver,
2661 |         createButtonDriver,
2662 |       }) => {
2663 |         await initTestBed(`
2664 |           <Fragment>
2665 |             <VStack height="400px" var.expandEvents="[]">
2666 |               <Text testId="eventsText">{expandEvents}</Text>
2667 |               <Tree id="treeApi" testId="tree"
2668 |                 dataFormat="hierarchy"
2669 |                 defaultExpanded="none"
2670 |                 data='{${JSON.stringify(hierarchyTreeData)}}'
2671 |                 onNodeDidExpand="node => {expandEvents.push(node.id)}"
2672 |               >
2673 |                 <property name="itemTemplate">
2674 |                   <HStack testId="{$item.id}">
2675 |                     <Text value="{$item.name}" />
2676 |                   </HStack>
2677 |                 </property>
2678 |               </Tree>
2679 |             </VStack>
2680 |             <Button testId="expand-level-btn" label="Expand to Level 1" onClick="
2681 |               treeApi.expandToLevel(1);
2682 |             " />
2683 |           </Fragment>
2684 |         `);
2685 | 
2686 |         const tree = await createTreeDriver("tree");
2687 |         const expandLevelButton = await createButtonDriver("expand-level-btn");
2688 | 
2689 |         // Trigger API expand to level
2690 |         await expandLevelButton.click();
2691 | 
2692 |         const eventsText = page.getByTestId("eventsText");
2693 | 
2694 |         // expandToLevel() does not fire individual nodeDidExpand events
2695 |         // This is the correct behavior - mass operations should not fire individual events
2696 |         await expect(eventsText).toHaveText("[]");
2697 | 
2698 |         // But verify the visual result is correct - level 1 nodes should be visible
2699 |         await expect(tree.getByTestId("2")).toBeVisible();
2700 |       });
2701 |     });
2702 | 
2703 |     test.describe("nodeDidCollapse Event via API", () => {
2704 |       test("fires when collapseNode() API method is called", async ({
2705 |         initTestBed,
2706 |         createTreeDriver,
2707 |         createButtonDriver,
2708 |       }) => {
2709 |         const { testStateDriver } = await initTestBed(`
2710 |           <Fragment>
2711 |             <VStack height="400px">
2712 |               <Tree id="treeApi" testId="tree"
2713 |                 dataFormat="hierarchy"
2714 |                 defaultExpanded="all"
2715 |                 data='{${JSON.stringify(hierarchyTreeData)}}'
2716 |                 onNodeDidCollapse="node => testState = node">
2717 |                 <property name="itemTemplate">
2718 |                   <HStack testId="{$item.id}">
2719 |                     <Text value="{$item.name}" />
2720 |                   </HStack>
2721 |                 </property>
2722 |               </Tree>
2723 |             </VStack>
2724 |             <Button testId="collapse-btn" label="Collapse Node 1" onClick="
2725 |               treeApi.collapseNode(1);
2726 |             " />
2727 |           </Fragment>
2728 |         `);
2729 | 
2730 |         const tree = await createTreeDriver("tree");
2731 |         const collapseButton = await createButtonDriver("collapse-btn");
2732 | 
2733 |         // Initially, child should be visible (starts expanded)
2734 |         await expect(tree.getByTestId("2")).toBeVisible();
2735 | 
2736 |         // Trigger API collapse
2737 |         await collapseButton.click();
2738 | 
2739 |         // Verify nodeDidCollapse event fired
2740 |         await expect.poll(() => testStateDriver.testState().then((s) => s?.id)).toBe(1);
2741 | 
2742 |         // Verify child is no longer visible
2743 |         await expect(tree.getByTestId("2")).not.toBeVisible();
2744 |       });
2745 | 
2746 |       test("fires for collapseAll() API method", async ({
2747 |         page,
2748 |         initTestBed,
2749 |         createTreeDriver,
2750 |         createButtonDriver,
2751 |       }) => {
2752 |         await initTestBed(`
2753 |           <Fragment>
2754 |             <VStack height="400px" var.collapseEvents="[]">
2755 |               <Text testId="eventsText">{collapseEvents}</Text>
2756 |               <Tree id="treeApi" testId="tree"
2757 |                 dataFormat="hierarchy"
2758 |                 defaultExpanded="all"
2759 |                 data='{${JSON.stringify(hierarchyTreeData)}}'
2760 |                 onNodeDidCollapse="node => {collapseEvents.push(node.id)}"
2761 |               >
2762 |                 <property name="itemTemplate">
2763 |                   <HStack testId="{$item.id}">
2764 |                     <Text value="{$item.name}" />
2765 |                   </HStack>
2766 |                 </property>
2767 |               </Tree>
2768 |             </VStack>
2769 |             <Button testId="collapse-all-btn" label="Collapse All" onClick="
2770 |               treeApi.collapseAll();
2771 |             " />
2772 |           </Fragment>
2773 |         `);
2774 | 
2775 |         const tree = await createTreeDriver("tree");
2776 |         const collapseAllButton = await createButtonDriver("collapse-all-btn");
2777 | 
2778 |         // Initially, children should be visible (starts expanded)
2779 |         await expect(tree.getByTestId("2")).toBeVisible();
2780 | 
2781 |         // Trigger API collapse all
2782 |         await collapseAllButton.click();
2783 | 
2784 |         const eventsText = page.getByTestId("eventsText");
2785 | 
2786 |         // collapseAll() does not fire individual nodeDidCollapse events
2787 |         // This is the correct behavior - mass operations should not fire individual events
2788 |         await expect(eventsText).toHaveText("[]");
2789 | 
2790 |         // But verify the visual result is correct - children should no longer be visible
2791 |         await expect(tree.getByTestId("2")).not.toBeVisible();
2792 |       });
2793 |     });
2794 | 
2795 |     test.describe("selectionDidChange Event via API", () => {
2796 |       test("fires when selectNode() API method is called", async ({
2797 |         initTestBed,
2798 |         createTreeDriver,
2799 |         createButtonDriver,
2800 |       }) => {
2801 |         const { testStateDriver } = await initTestBed(`
2802 |           <Fragment>
2803 |             <VStack height="400px">
2804 |               <Tree id="treeApi" testId="tree"
2805 |                 dataFormat="flat"
2806 |                 data='{${JSON.stringify(flatTreeData)}}'
2807 |                 onSelectionDidChange="event => testState = event">
2808 |                 <property name="itemTemplate">
2809 |                   <HStack testId="{$item.id}">
2810 |                     <Text value="{$item.name}" />
2811 |                   </HStack>
2812 |                 </property>
2813 |               </Tree>
2814 |             </VStack>
2815 |             <Button testId="select-btn" label="Select Node 2" onClick="
2816 |               treeApi.selectNode(2);
2817 |             " />
2818 |           </Fragment>
2819 |         `);
2820 | 
2821 |         const tree = await createTreeDriver("tree");
2822 |         const selectButton = await createButtonDriver("select-btn");
2823 | 
2824 |         // Trigger API selection
2825 |         await selectButton.click();
2826 | 
2827 |         // Verify selectionDidChange event fired
2828 |         await expect.poll(() => testStateDriver.testState()).toBeDefined();
2829 |         const event = await testStateDriver.testState();
2830 |         expect(event.newNode).toBeDefined();
2831 |         expect(event.newNode.id).toBe(2);
2832 |         expect(event.newNode.displayName).toBe("Child Item 1.1");
2833 |         expect(event.previousNode).toBeNull();
2834 |       });
2835 | 
2836 |       test("fires with previous node when changing selection via API", async ({
2837 |         page,
2838 |         initTestBed,
2839 |         createTreeDriver,
2840 |         createButtonDriver,
2841 |       }) => {
2842 |         await initTestBed(`
2843 |           <Fragment>
2844 |             <VStack height="400px" var.selectionEvents="{[]}">
2845 |               <Text testId="eventsText">{JSON.stringify(selectionEvents)}</Text>
2846 |               <Tree id="treeApi" testId="tree"
2847 |                 dataFormat="flat"
2848 |                 defaultExpanded="all"
2849 |                 data='{${JSON.stringify(flatTreeData)}}'
2850 |                 onSelectionDidChange="event => {selectionEvents.push({prev: event.previousNode?.id || null, new: event.newNode?.id || null});}"
2851 |               >
2852 |                 <property name="itemTemplate">
2853 |                   <HStack testId="{$item.id}">
2854 |                     <Text value="{$item.name}" />
2855 |                   </HStack>
2856 |                 </property>
2857 |               </Tree>
2858 |             </VStack>
2859 |             <Button testId="select-first-btn" label="Select First" onClick="treeApi.selectNode(1);" />
2860 |             <Button testId="select-second-btn" label="Select Second" onClick="treeApi.selectNode(2);" />
2861 |           </Fragment>
2862 |         `);
2863 | 
2864 |         const tree = await createTreeDriver("tree");
2865 |         const selectFirstButton = await createButtonDriver("select-first-btn");
2866 |         const selectSecondButton = await createButtonDriver("select-second-btn");
2867 | 
2868 |         // First selection
2869 |         await selectFirstButton.click();
2870 | 
2871 |         // Second selection
2872 |         await selectSecondButton.click();
2873 | 
2874 |         const eventsText = page.getByTestId("eventsText");
2875 | 
2876 |         // Verify we have both selection events with correct previous/new node IDs
2877 |         await expect(eventsText).toHaveText('[{"prev":null,"new":1},{"prev":1,"new":2}]');
2878 |       });
2879 | 
2880 |       test("fires when clearSelection() API method is called", async ({
2881 |         initTestBed,
2882 |         createTreeDriver,
2883 |         createButtonDriver,
2884 |       }) => {
2885 |         const { testStateDriver } = await initTestBed(`
2886 |           <Fragment>
2887 |             <VStack height="400px">
2888 |               <Tree id="treeApi" testId="tree"
2889 |                 dataFormat="flat"
2890 |                 selectedValue="1"
2891 |                 data='{${JSON.stringify(flatTreeData)}}'
2892 |                 onSelectionDidChange="event => testState = event">
2893 |                 <property name="itemTemplate">
2894 |                   <HStack testId="{$item.id}">
2895 |                     <Text value="{$item.name}" />
2896 |                   </HStack>
2897 |                 </property>
2898 |               </Tree>
2899 |             </VStack>
2900 |             <Button testId="clear-btn" label="Clear Selection" onClick="
2901 |               treeApi.clearSelection();
2902 |             " />
2903 |           </Fragment>
2904 |         `);
2905 | 
2906 |         const tree = await createTreeDriver("tree");
2907 |         const clearButton = await createButtonDriver("clear-btn");
2908 | 
2909 |         // Trigger API clear selection
2910 |         await clearButton.click();
2911 | 
2912 |         // Verify selectionDidChange event fired with null newNode
2913 |         await expect.poll(() => testStateDriver.testState()).toBeDefined();
2914 |         const event = await testStateDriver.testState();
2915 |         expect(event.newNode).toBeNull();
2916 |         expect(event.previousNode).toBeDefined();
2917 |         expect(event.previousNode.id).toBe(1);
2918 |       });
2919 |     });
2920 |   });
2921 | });
2922 | 
2923 | // =============================================================================
2924 | // ACCESSIBILITY TESTS
2925 | // =============================================================================
2926 | 
2927 | test.describe("Accessibility", () => {
2928 |   test("has proper ARIA attributes", async ({ initTestBed, createTreeDriver }) => {
2929 |     await initTestBed(`
2930 |       <VStack height="400px">
2931 |         <Tree testId="tree" 
2932 |           dataFormat="flat" 
2933 |           defaultExpanded="all"
2934 |           data='{${JSON.stringify(flatTreeData)}}'>
2935 |           <property name="itemTemplate">
2936 |             <HStack testId="{$item.id}:aria" verticalAlignment="center">
2937 |               <Text value="{$item.name}" />
2938 |             </HStack>
2939 |           </property>
2940 |         </Tree>
2941 |       </VStack>
2942 |     `);
2943 | 
2944 |     const tree = await createTreeDriver("tree");
2945 | 
2946 |     // Test main tree container ARIA attributes
2947 |     await expect(tree.component).toHaveAttribute("role", "tree");
2948 |     await expect(tree.component).toHaveAttribute("aria-label", "Tree navigation");
2949 |     await expect(tree.component).toHaveAttribute("aria-multiselectable", "false");
2950 | 
2951 |     // Test tree items have proper ARIA attributes
2952 |     // Find treeitems by their role attribute
2953 |     const treeItems = tree.component.locator('[role="treeitem"]');
2954 | 
2955 |     // Test first tree item (should be expanded due to defaultExpanded="all")
2956 |     const firstTreeItem = treeItems.first();
2957 |     await expect(firstTreeItem).toHaveAttribute("role", "treeitem");
2958 |     await expect(firstTreeItem).toHaveAttribute("aria-level", "1");
2959 |     await expect(firstTreeItem).toHaveAttribute("aria-expanded", "true");
2960 |     await expect(firstTreeItem).toHaveAttribute("aria-selected", "false");
2961 |     await expect(firstTreeItem).toHaveAttribute("aria-label", "Root Item 1");
2962 | 
2963 |     // Test that we have the expected number of tree items (4 total in flatTreeData)
2964 |     await expect(treeItems).toHaveCount(4);
2965 | 
2966 |     // Test second tree item (Child Item 1.1)
2967 |     const secondTreeItem = treeItems.nth(1);
2968 |     await expect(secondTreeItem).toHaveAttribute("aria-level", "2");
2969 |     await expect(secondTreeItem).toHaveAttribute("aria-label", "Child Item 1.1");
2970 | 
2971 |     // Test third tree item (Grandchild Item 1.1.1)
2972 |     const thirdTreeItem = treeItems.nth(2);
2973 |     await expect(thirdTreeItem).toHaveAttribute("aria-level", "3");
2974 |     await expect(thirdTreeItem).toHaveAttribute("aria-label", "Grandchild Item 1.1.1");
2975 | 
2976 |     // Test fourth tree item (Child Item 1.2)
2977 |     const fourthTreeItem = treeItems.nth(3);
2978 |     await expect(fourthTreeItem).toHaveAttribute("aria-level", "2");
2979 |     await expect(fourthTreeItem).toHaveAttribute("aria-label", "Child Item 1.2");
2980 |   });
2981 | 
2982 |   test("supports keyboard navigation", async ({ initTestBed, createTreeDriver }) => {
2983 |     await initTestBed(`
2984 |       <VStack height="400px">
2985 |         <Tree testId="tree" 
2986 |           dataFormat="flat" 
2987 |           data='{${JSON.stringify(flatTreeData)}}'>
2988 |           <property name="itemTemplate">
2989 |             <HStack testId="{$item.id}:keyboard" verticalAlignment="center">
2990 |               <Text value="{$item.name}" />
2991 |             </HStack>
2992 |           </property>
2993 |         </Tree>
2994 |       </VStack>
2995 |     `);
2996 | 
2997 |     const tree = await createTreeDriver("tree");
2998 | 
2999 |     // Focus the tree
3000 |     await tree.component.focus();
3001 | 
3002 |     // Test Arrow Down navigation
3003 |     await tree.component.press("ArrowDown");
3004 |     // First item should be focused after initial focus + ArrowDown
3005 | 
3006 |     // Test Arrow Up navigation
3007 |     await tree.component.press("ArrowUp");
3008 |     // Should stay at first item (can't go up from first)
3009 | 
3010 |     // Navigate down to second item
3011 |     await tree.component.press("ArrowDown");
3012 | 
3013 |     // Test Enter for selection/expansion
3014 |     await tree.component.press("Enter");
3015 | 
3016 |     // Test Arrow Right for expansion (if has children)
3017 |     await tree.component.press("ArrowRight");
3018 | 
3019 |     // Test Arrow Left for collapse/parent navigation
3020 |     await tree.component.press("ArrowLeft");
3021 | 
3022 |     // Test Home key
3023 |     await tree.component.press("Home");
3024 | 
3025 |     // Test End key
3026 |     await tree.component.press("End");
3027 | 
3028 |     // Test Space for selection
3029 |     await tree.component.press(" ");
3030 | 
3031 |     // Verify tree is still visible and functional after keyboard interactions
3032 |     await expect(tree.getByTestId("1:keyboard")).toBeVisible();
3033 |   });
3034 | 
3035 |   test("supports itemClickExpands behavior", async ({ initTestBed, createTreeDriver }) => {
3036 |     await initTestBed(`
3037 |       <VStack height="400px">
3038 |         <Tree testId="tree" 
3039 |           dataFormat="flat" 
3040 |           itemClickExpands="true"
3041 |           data='{${JSON.stringify(flatTreeData)}}'>
3042 |           <property name="itemTemplate">
3043 |             <HStack testId="{$item.id}:expand-click" verticalAlignment="center">
3044 |               <Text value="{$item.name}" />
3045 |             </HStack>
3046 |           </property>
3047 |         </Tree>
3048 |       </VStack>
3049 |     `);
3050 | 
3051 |     const tree = await createTreeDriver("tree");
3052 | 
3053 |     // Initially, only root item should be visible (tree starts collapsed)
3054 |     await expect(tree.getByTestId("1:expand-click")).toBeVisible();
3055 |     await expect(tree.getByTestId("2:expand-click")).not.toBeVisible();
3056 | 
3057 |     // Click on the root item (not the expand/collapse icon) to expand it
3058 |     await tree.getByTestId("1:expand-click").click();
3059 | 
3060 |     // After clicking, children should be visible
3061 |     await expect(tree.getByTestId("2:expand-click")).toBeVisible();
3062 |     await expect(tree.getByTestId("3:expand-click")).toBeVisible();
3063 | 
3064 |     // Click on child item that has its own children
3065 |     await tree.getByTestId("2:expand-click").click();
3066 | 
3067 |     // Grandchild should become visible
3068 |     await expect(tree.getByTestId("4:expand-click")).toBeVisible();
3069 | 
3070 |     // Click again to collapse
3071 |     await tree.getByTestId("2:expand-click").click();
3072 | 
3073 |     // Grandchild should be hidden
3074 |     await expect(tree.getByTestId("4:expand-click")).not.toBeVisible();
3075 |   });
3076 | 
3077 |   test("works with screen readers", async ({ initTestBed, createTreeDriver }) => {
3078 |     await initTestBed(`
3079 |       <VStack height="400px">
3080 |         <Tree testId="tree" 
3081 |           dataFormat="flat" 
3082 |           defaultExpanded="all"
3083 |           data='{${JSON.stringify(flatTreeData)}}'>
3084 |           <property name="itemTemplate">
3085 |             <HStack testId="{$item.id}:screen-reader" verticalAlignment="center">
3086 |               <Text value="{$item.name}" />
3087 |             </HStack>
3088 |           </property>
3089 |         </Tree>
3090 |       </VStack>
3091 |     `);
3092 | 
3093 |     const tree = await createTreeDriver("tree");
3094 | 
3095 |     // Test semantic structure that screen readers depend on
3096 |     await expect(tree.component).toHaveAttribute("role", "tree");
3097 | 
3098 |     // Verify all tree items have proper semantic markup
3099 |     const treeItems = tree.component.locator('[role="treeitem"]');
3100 |     await expect(treeItems).toHaveCount(4);
3101 | 
3102 |     // Test each item has required accessibility information
3103 |     for (let i = 0; i < 4; i++) {
3104 |       const item = treeItems.nth(i);
3105 | 
3106 |       // Each item must have a level for screen reader navigation
3107 |       await expect(item).toHaveAttribute("aria-level");
3108 | 
3109 |       // Each item must have a label for screen reader announcement
3110 |       await expect(item).toHaveAttribute("aria-label");
3111 | 
3112 |       // Each item must have selection state
3113 |       await expect(item).toHaveAttribute("aria-selected");
3114 |     }
3115 | 
3116 |     // Test hierarchical relationships are properly communicated
3117 |     const rootItem = treeItems.first();
3118 |     await expect(rootItem).toHaveAttribute("aria-level", "1");
3119 |     await expect(rootItem).toHaveAttribute("aria-expanded", "true");
3120 | 
3121 |     // Test child items have correct level hierarchy
3122 |     const childItem = treeItems.nth(1);
3123 |     await expect(childItem).toHaveAttribute("aria-level", "2");
3124 | 
3125 |     // Test grandchild has deeper level
3126 |     const grandchildItem = treeItems.nth(2);
3127 |     await expect(grandchildItem).toHaveAttribute("aria-level", "3");
3128 | 
3129 |     // Test that all items have selection state (even if not selected)
3130 |     const allItems = tree.component.locator('[aria-selected="false"]');
3131 |     await expect(allItems).toHaveCount(4); // All items should be unselected initially
3132 | 
3133 |     // Test expansion states are properly communicated
3134 |     const expandedItems = tree.component.locator('[aria-expanded="true"]');
3135 |     await expect(expandedItems).toHaveCount(2); // Root and Child Item 1.1 (which has a grandchild)
3136 | 
3137 |     // Test that tree is focusable for keyboard navigation
3138 |     await expect(tree.component).toHaveAttribute("tabindex", "0");
3139 | 
3140 |     // Verify semantic structure is maintained for screen reader navigation
3141 |     await expect(tree.component).toHaveAttribute("role", "tree");
3142 |     await expect(treeItems.first()).toHaveAttribute("role", "treeitem");
3143 | 
3144 |     // Test that all required accessibility information is present
3145 |     // This ensures screen readers can properly announce tree structure
3146 |     const firstItem = treeItems.first();
3147 |     await expect(firstItem).toHaveAttribute("aria-level");
3148 |     await expect(firstItem).toHaveAttribute("aria-label");
3149 |     await expect(firstItem).toHaveAttribute("aria-expanded");
3150 |     await expect(firstItem).toHaveAttribute("aria-selected");
3151 |   });
3152 | });
3153 | 
3154 | // =============================================================================
3155 | // PERFORMANCE TESTS
3156 | // =============================================================================
3157 | 
3158 | test.describe("Performance", () => {
3159 |   test("handles large datasets efficiently", async ({ initTestBed, createTreeDriver }) => {
3160 |     // Generate a large dataset with 1000+ items in a hierarchical structure
3161 |     const generateLargeDataset = (numItems = 1000) => {
3162 |       const data = [];
3163 |       let id = 1;
3164 | 
3165 |       // Create root items (10% of total)
3166 |       const numRoots = Math.ceil(numItems * 0.1);
3167 |       for (let i = 0; i < numRoots; i++) {
3168 |         data.push({
3169 |           id: id++,
3170 |           name: `Root Item ${i + 1}`,
3171 |           parentId: null,
3172 |         });
3173 |       }
3174 | 
3175 |       // Create child items distributed under roots
3176 |       const itemsPerRoot = Math.floor((numItems - numRoots) / numRoots);
3177 |       for (let rootIndex = 0; rootIndex < numRoots; rootIndex++) {
3178 |         const rootId = rootIndex + 1;
3179 | 
3180 |         for (let j = 0; j < itemsPerRoot && id <= numItems; j++) {
3181 |           data.push({
3182 |             id: id++,
3183 |             name: `Child Item ${rootId}.${j + 1}`,
3184 |             parentId: rootId,
3185 |           });
3186 |         }
3187 |       }
3188 | 
3189 |       return data;
3190 |     };
3191 | 
3192 |     const largeDataset = generateLargeDataset(1000);
3193 | 
3194 |     const startTime = performance.now();
3195 | 
3196 |     await initTestBed(`
3197 |       <VStack height="400px">
3198 |         <Tree testId="tree" 
3199 |           dataFormat="flat" 
3200 |           data='{${JSON.stringify(largeDataset)}}'>
3201 |           <property name="itemTemplate">
3202 |             <HStack testId="{$item.id}:perf" verticalAlignment="center">
3203 |               <Text value="{$item.name}" />
3204 |             </HStack>
3205 |           </property>
3206 |         </Tree>
3207 |       </VStack>
3208 |     `);
3209 | 
3210 |     const tree = await createTreeDriver("tree");
3211 | 
3212 |     // Verify tree renders
3213 |     await expect(tree.component).toBeVisible();
3214 | 
3215 |     const renderTime = performance.now() - startTime;
3216 | 
3217 |     // Should render large dataset within reasonable time (< 5 seconds)
3218 |     expect(renderTime).toBeLessThan(5000);
3219 | 
3220 |     // Test that only root items are initially visible (virtualization working)
3221 |     await expect(tree.getByTestId("1:perf")).toBeVisible();
3222 |     await expect(tree.getByTestId("2:perf")).toBeVisible();
3223 | 
3224 |     // Verify scrolling performance - scroll to end of visible items
3225 |     const scrollStartTime = performance.now();
3226 |     await tree.component.press("End"); // Scroll to last visible item
3227 |     const scrollTime = performance.now() - scrollStartTime;
3228 | 
3229 |     // Scrolling should be fast (< 1 second)
3230 |     expect(scrollTime).toBeLessThan(1000);
3231 | 
3232 |     // Test expansion performance
3233 |     const expandStartTime = performance.now();
3234 |     await tree.getByTestId("1:perf").click(); // Expand first root item
3235 |     const expandTime = performance.now() - expandStartTime;
3236 | 
3237 |     // Expansion should be fast (< 500ms)
3238 |     expect(expandTime).toBeLessThan(500);
3239 |   });
3240 | 
3241 |   test("maintains smooth scrolling with virtualization", async ({
3242 |     initTestBed,
3243 |     createTreeDriver,
3244 |   }) => {
3245 |     // Create a dataset specifically for scroll testing
3246 |     const scrollTestData = [];
3247 |     for (let i = 1; i <= 500; i++) {
3248 |       scrollTestData.push({
3249 |         id: i,
3250 |         name: `Scroll Item ${i}`,
3251 |         parentId: null,
3252 |       });
3253 |     }
3254 | 
3255 |     await initTestBed(`
3256 |       <VStack height="300px">
3257 |         <Tree testId="scroll-tree" 
3258 |           dataFormat="flat" 
3259 |           data='{${JSON.stringify(scrollTestData)}}'>
3260 |           <property name="itemTemplate">
3261 |             <HStack testId="{$item.id}:scroll">
3262 |               <Text value="{$item.name}" />
3263 |             </HStack>
3264 |           </property>
3265 |         </Tree>
3266 |       </VStack>
3267 |     `);
3268 | 
3269 |     const tree = await createTreeDriver("scroll-tree");
3270 | 
3271 |     // Verify tree is visible
3272 |     await expect(tree.component).toBeVisible();
3273 |     await expect(tree.getByTestId("1:scroll")).toBeVisible();
3274 | 
3275 |     // Test keyboard scrolling performance
3276 |     await tree.component.focus();
3277 | 
3278 |     // Scroll down 50 times rapidly
3279 |     const rapidScrollStartTime = performance.now();
3280 |     for (let i = 0; i < 50; i++) {
3281 |       await tree.component.press("ArrowDown");
3282 |     }
3283 |     const rapidScrollTime = performance.now() - rapidScrollStartTime;
3284 | 
3285 |     // Rapid keyboard scrolling should remain responsive (< 2 seconds)
3286 |     expect(rapidScrollTime).toBeLessThan(2000);
3287 | 
3288 |     // Verify we can reach different parts of the large list
3289 |     await tree.component.press("Home"); // Go to start
3290 |     await expect(tree.getByTestId("1:scroll")).toBeVisible();
3291 | 
3292 |     await tree.component.press("End"); // Go to end
3293 |     // Should be able to navigate to end without timeout
3294 |   });
3295 | });
3296 | 
3297 | // =============================================================================
3298 | // THEME VARIABLES TESTS
3299 | // =============================================================================
3300 | 
3301 | test.describe("Theme Variables", () => {
3302 |   test("applies custom tree text color theme variable", async ({
3303 |     initTestBed,
3304 |     createTreeDriver,
3305 |   }) => {
3306 |     const TEXT_COLOR = "rgb(128, 0, 128)";
3307 |     await initTestBed(
3308 |       `
3309 |       <VStack height="400px">
3310 |         <Tree testId="tree" 
3311 |           dataFormat="flat"
3312 |           defaultExpanded="all"
3313 |           data='{${JSON.stringify(flatTreeData)}}'>
3314 |           <property name="itemTemplate">
3315 |             <HStack testId="{$item.id}" verticalAlignment="center">
3316 |               <Text value="{$item.name}" />
3317 |             </HStack>
3318 |           </property>
3319 |         </Tree>
3320 |       </VStack>
3321 |       `,
3322 |       {
3323 |         testThemeVars: {
3324 |           "textColor-Tree": TEXT_COLOR,
3325 |         },
3326 |       },
3327 |     );
3328 | 
3329 |     const tree = await createTreeDriver("tree");
3330 | 
3331 |     // Get row wrappers directly using getNodeWrapperByMarker
3332 |     const rowWrapper1 = tree.getNodeWrapperByTestId("1");
3333 |     const rowWrapper2 = tree.getNodeWrapperByTestId("2");
3334 |     const rowWrapper3 = tree.getNodeWrapperByTestId("3");
3335 |     const rowWrapper4 = tree.getNodeWrapperByTestId("4");
3336 | 
3337 |     await expect(rowWrapper1).toBeVisible();
3338 | 
3339 |     // Test all items have correct default text color
3340 |     await expect(rowWrapper1).toHaveCSS("color", TEXT_COLOR);
3341 |     await expect(rowWrapper2).toHaveCSS("color", TEXT_COLOR);
3342 |     await expect(rowWrapper3).toHaveCSS("color", TEXT_COLOR);
3343 |     await expect(rowWrapper4).toHaveCSS("color", TEXT_COLOR);
3344 |   });
3345 | 
3346 |   test("applies custom hover state theme variables", async ({
3347 |     initTestBed,
3348 |     createTreeDriver,
3349 |     page,
3350 |   }) => {
3351 |     const HOVER_BG_COLOR = "rgb(255, 255, 0)";
3352 |     const HOVER_TEXT_COLOR = "rgb(0, 0, 255)";
3353 |     await initTestBed(
3354 |       `
3355 |       <VStack height="400px">
3356 |         <Tree testId="tree" 
3357 |           dataFormat="flat"
3358 |           defaultExpanded="all"
3359 |           data='{${JSON.stringify(flatTreeData)}}'>
3360 |           <property name="itemTemplate">
3361 |             <HStack testId="{$item.id}" verticalAlignment="center">
3362 |               <Text value="{$item.name}" />
3363 |             </HStack>
3364 |           </property>
3365 |         </Tree>
3366 |       </VStack>
3367 |       `,
3368 |       {
3369 |         testThemeVars: {
3370 |           "backgroundColor-Tree-row--hover": HOVER_BG_COLOR,
3371 |           "textColor-Tree--hover": HOVER_TEXT_COLOR,
3372 |         },
3373 |       },
3374 |     );
3375 | 
3376 |     const tree = await createTreeDriver("tree");
3377 | 
3378 |     // Get row wrappers directly using getNodeWrapperByMarker
3379 |     const rowWrapper1 = tree.getNodeWrapperByTestId("1");
3380 |     const rowWrapper2 = tree.getNodeWrapperByTestId("2");
3381 |     const rowWrapper3 = tree.getNodeWrapperByTestId("3");
3382 | 
3383 |     await expect(rowWrapper1).toBeVisible();
3384 | 
3385 |     // Test hover on first item
3386 |     await rowWrapper1.hover();
3387 |     await expect(rowWrapper1).toHaveCSS("background-color", HOVER_BG_COLOR);
3388 |     await expect(rowWrapper1).toHaveCSS("color", HOVER_TEXT_COLOR);
3389 | 
3390 |     // Test hover on second item
3391 |     await rowWrapper2.hover();
3392 |     await expect(rowWrapper2).toHaveCSS("background-color", HOVER_BG_COLOR);
3393 |     await expect(rowWrapper2).toHaveCSS("color", HOVER_TEXT_COLOR);
3394 | 
3395 |     // Test hover on third item
3396 |     await rowWrapper3.hover();
3397 |     await expect(rowWrapper3).toHaveCSS("background-color", HOVER_BG_COLOR);
3398 |     await expect(rowWrapper3).toHaveCSS("color", HOVER_TEXT_COLOR);
3399 |   });
3400 | });
3401 | 
3402 | // =============================================================================
3403 | // EDGE CASES TESTS
3404 | // =============================================================================
3405 | 
3406 | test.describe("Edge Cases", () => {
3407 |   test("handles null/undefined data gracefully", async ({ initTestBed, createTreeDriver }) => {
3408 |     await initTestBed(`
3409 |       <VStack height="200px">
3410 |         <Tree 
3411 |           testId="tree" 
3412 |           data="{null}" 
3413 |           dataFormat="flat"
3414 |         />
3415 |       </VStack>
3416 |     `);
3417 |     const tree = await createTreeDriver("tree");
3418 |     await expect(tree.component).toBeVisible();
3419 |   });
3420 | 
3421 |   test("handles malformed data gracefully", async ({ initTestBed, createTreeDriver }) => {
3422 |     const malformedData = [
3423 |       { id: 1, name: "Valid Item" },
3424 |       { /* missing id */ name: "Invalid Item" },
3425 |       null,
3426 |       undefined,
3427 |     ];
3428 | 
3429 |     await initTestBed(`
3430 |       <VStack height="200px">
3431 |         <Tree 
3432 |           testId="tree" 
3433 |           data='{${JSON.stringify(malformedData)}}' 
3434 |           dataFormat="flat"
3435 |         />
3436 |       </VStack>
3437 |     `);
3438 |     const tree = await createTreeDriver("tree");
3439 |     await expect(tree.component).toBeVisible();
3440 |   });
3441 | 
3442 |   test("handles circular references in hierarchy data", async ({
3443 |     initTestBed,
3444 |     createTreeDriver,
3445 |   }) => {
3446 |     const circularData = [
3447 |       { id: 1, name: "Item 1", parentId: 2 },
3448 |       { id: 2, name: "Item 2", parentId: 1 },
3449 |     ];
3450 | 
3451 |     await initTestBed(`
3452 |       <VStack height="200px">
3453 |         <Tree 
3454 |           testId="tree" 
3455 |           data='{${JSON.stringify(circularData)}}' 
3456 |           dataFormat="flat"
3457 |         />
3458 |       </VStack>
3459 |     `);
3460 |     const tree = await createTreeDriver("tree");
3461 |     await expect(tree.component).toBeVisible();
3462 |   });
3463 | 
3464 |   test("handles duplicate IDs gracefully", async ({ initTestBed, createTreeDriver }) => {
3465 |     const duplicateIdData = [
3466 |       { id: 1, name: "Item 1" },
3467 |       { id: 1, name: "Duplicate Item 1" },
3468 |       { id: 2, name: "Item 2" },
3469 |     ];
3470 | 
3471 |     await initTestBed(`
3472 |       <VStack height="200px">
3473 |       <Tree 
3474 |           testId="tree" 
3475 |           data='{${JSON.stringify(duplicateIdData)}}' 
3476 |           dataFormat="flat"
3477 |         />
3478 |       </VStack>
3479 |     `);
3480 |     const tree = await createTreeDriver("tree");
3481 |     await expect(tree.component).toBeVisible();
3482 |   });
3483 | 
3484 |   test("handles orphaned nodes in flat data", async ({ initTestBed, createTreeDriver }) => {
3485 |     const orphanedData = [
3486 |       { id: 1, name: "Root Item" },
3487 |       { id: 2, name: "Orphaned Item", parentId: 999 }, // non-existent parent
3488 |     ];
3489 | 
3490 |     await initTestBed(`
3491 |       <VStack height="200px">
3492 |         <Tree 
3493 |           testId="tree" 
3494 |           data='{${JSON.stringify(orphanedData)}}' 
3495 |           dataFormat="flat"
3496 |         />
3497 |       </VStack>
3498 |     `);
3499 |     const tree = await createTreeDriver("tree");
3500 |     await expect(tree.component).toBeVisible();
3501 |   });
3502 | 
3503 |   test("handles deeply nested data structures", async ({ initTestBed, createTreeDriver }) => {
3504 |     const deepData = Array.from({ length: 100 }, (_, i) => ({
3505 |       id: i + 1,
3506 |       name: `Level ${i + 1}`,
3507 |       parentId: i === 0 ? null : i,
3508 |     }));
3509 | 
3510 |     await initTestBed(`
3511 |       <VStack height="200px">
3512 |         <Tree 
3513 |           testId="tree" 
3514 |           data='{${JSON.stringify(deepData)}}' 
3515 |           dataFormat="flat"
3516 |           selectedValue="{100}"
3517 |         />
3518 |       </VStack>
3519 |     `);
3520 |     const tree = await createTreeDriver("tree");
3521 |     await expect(tree.component).toBeVisible();
3522 |   });
3523 | 
3524 |   test("handles invalid dataFormat values", async ({ initTestBed, createTreeDriver }) => {
3525 |     const orphanedData = [
3526 |       { id: 1, name: "Root Item" },
3527 |       { id: 2, name: "Orphaned Item", parentId: 999 }, // non-existent parent
3528 |     ];
3529 | 
3530 |     await initTestBed(`
3531 |       <VStack height="200px">
3532 |         <Tree 
3533 |           testId="tree" 
3534 |           data='{${JSON.stringify(orphanedData)}}' 
3535 |           dataFormat="invalid-format"
3536 |         />
3537 |       </VStack>
3538 |     `);
3539 |     const tree = await createTreeDriver("tree");
3540 |     await expect(tree.component).toBeVisible();
3541 |   });
3542 | });
3543 | 
3544 | 
```
Page 176/179FirstPrevNextLast