This is page 40 of 141. Use http://codebase.md/xmlui-org/xmlui/mockApiDef.js?lines=false&page={x} to view the full context.
# Directory Structure
```
├── .changeset
│ ├── clean-onions-pick.md
│ ├── config.json
│ ├── curly-llamas-try.md
│ ├── loose-trains-sit.md
│ ├── moody-pans-poke.md
│ ├── puny-worms-make.md
│ ├── rare-cooks-write.md
│ ├── silver-llamas-cough.md
│ └── true-jeans-agree.md
├── .eslintrc.cjs
├── .github
│ ├── build-checklist.png
│ ├── ISSUE_TEMPLATE
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ └── workflows
│ ├── deploy-blog.yml
│ ├── deploy-docs-optimized.yml
│ ├── deploy-docs.yml
│ ├── prepare-versions.yml
│ ├── release-packages.yml
│ ├── run-all-tests.yml
│ └── run-smoke-tests.yml
├── .gitignore
├── .prettierrc.js
├── .vscode
│ ├── launch.json
│ └── settings.json
├── blog
│ ├── .gitignore
│ ├── .gitkeep
│ ├── CHANGELOG.md
│ ├── extensions.ts
│ ├── index.html
│ ├── index.ts
│ ├── package.json
│ ├── public
│ │ ├── blog
│ │ │ ├── images
│ │ │ │ ├── an-advanced-codefence.gif
│ │ │ │ ├── an-advanced-codefence.mp4
│ │ │ │ ├── blog-page-component.png
│ │ │ │ ├── blog-scrabble.png
│ │ │ │ ├── codefence-runner.png
│ │ │ │ ├── integrated-blog-search.png
│ │ │ │ ├── lorem-ipsum.png
│ │ │ │ ├── playground-checkbox-source.png
│ │ │ │ ├── playground.png
│ │ │ │ ├── use-xmlui-mcp-to-find-a-howto.png
│ │ │ │ └── xmlui-demo-gallery.png
│ │ │ ├── introducing-xmlui.md
│ │ │ ├── lorem-ipsum.md
│ │ │ ├── newest-post.md
│ │ │ ├── older-post.md
│ │ │ ├── xmlui-playground.md
│ │ │ └── xmlui-powered-blog.md
│ │ ├── mockServiceWorker.js
│ │ ├── resources
│ │ │ ├── favicon.ico
│ │ │ ├── files
│ │ │ │ └── for-download
│ │ │ │ └── xmlui
│ │ │ │ └── xmlui-standalone.umd.js
│ │ │ ├── github.svg
│ │ │ ├── llms.txt
│ │ │ ├── logo-dark.svg
│ │ │ ├── logo.svg
│ │ │ ├── pg-popout.svg
│ │ │ ├── rss.svg
│ │ │ └── xmlui-logo.svg
│ │ ├── serve.json
│ │ └── web.config
│ ├── scripts
│ │ ├── download-latest-xmlui.js
│ │ ├── generate-rss.js
│ │ ├── get-releases.js
│ │ └── utils.js
│ ├── src
│ │ ├── components
│ │ │ ├── BlogOverview.xmlui
│ │ │ ├── BlogPage.xmlui
│ │ │ └── PageNotFound.xmlui
│ │ ├── config.ts
│ │ ├── Main.xmlui
│ │ └── themes
│ │ └── blog-theme.ts
│ └── tsconfig.json
├── CONTRIBUTING.md
├── docs
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── ComponentRefLinks.txt
│ ├── content
│ │ ├── _meta.json
│ │ ├── components
│ │ │ ├── _meta.json
│ │ │ ├── _overview.md
│ │ │ ├── APICall.md
│ │ │ ├── App.md
│ │ │ ├── AppHeader.md
│ │ │ ├── AppState.md
│ │ │ ├── AutoComplete.md
│ │ │ ├── Avatar.md
│ │ │ ├── Backdrop.md
│ │ │ ├── Badge.md
│ │ │ ├── BarChart.md
│ │ │ ├── Bookmark.md
│ │ │ ├── Breakout.md
│ │ │ ├── Button.md
│ │ │ ├── Card.md
│ │ │ ├── Carousel.md
│ │ │ ├── ChangeListener.md
│ │ │ ├── Checkbox.md
│ │ │ ├── CHStack.md
│ │ │ ├── ColorPicker.md
│ │ │ ├── Column.md
│ │ │ ├── ContentSeparator.md
│ │ │ ├── CVStack.md
│ │ │ ├── DataSource.md
│ │ │ ├── DateInput.md
│ │ │ ├── DatePicker.md
│ │ │ ├── DonutChart.md
│ │ │ ├── DropdownMenu.md
│ │ │ ├── EmojiSelector.md
│ │ │ ├── ExpandableItem.md
│ │ │ ├── FileInput.md
│ │ │ ├── FileUploadDropZone.md
│ │ │ ├── FlowLayout.md
│ │ │ ├── Footer.md
│ │ │ ├── Form.md
│ │ │ ├── FormItem.md
│ │ │ ├── FormSection.md
│ │ │ ├── Fragment.md
│ │ │ ├── H1.md
│ │ │ ├── H2.md
│ │ │ ├── H3.md
│ │ │ ├── H4.md
│ │ │ ├── H5.md
│ │ │ ├── H6.md
│ │ │ ├── Heading.md
│ │ │ ├── HSplitter.md
│ │ │ ├── HStack.md
│ │ │ ├── Icon.md
│ │ │ ├── IFrame.md
│ │ │ ├── Image.md
│ │ │ ├── Items.md
│ │ │ ├── LabelList.md
│ │ │ ├── Legend.md
│ │ │ ├── LineChart.md
│ │ │ ├── Link.md
│ │ │ ├── List.md
│ │ │ ├── Logo.md
│ │ │ ├── Markdown.md
│ │ │ ├── MenuItem.md
│ │ │ ├── MenuSeparator.md
│ │ │ ├── ModalDialog.md
│ │ │ ├── NavGroup.md
│ │ │ ├── NavLink.md
│ │ │ ├── NavPanel.md
│ │ │ ├── NoResult.md
│ │ │ ├── NumberBox.md
│ │ │ ├── Option.md
│ │ │ ├── Page.md
│ │ │ ├── PageMetaTitle.md
│ │ │ ├── Pages.md
│ │ │ ├── Pagination.md
│ │ │ ├── PasswordInput.md
│ │ │ ├── PieChart.md
│ │ │ ├── ProgressBar.md
│ │ │ ├── Queue.md
│ │ │ ├── RadioGroup.md
│ │ │ ├── RealTimeAdapter.md
│ │ │ ├── Redirect.md
│ │ │ ├── Select.md
│ │ │ ├── Slider.md
│ │ │ ├── Slot.md
│ │ │ ├── SpaceFiller.md
│ │ │ ├── Spinner.md
│ │ │ ├── Splitter.md
│ │ │ ├── Stack.md
│ │ │ ├── StickyBox.md
│ │ │ ├── SubMenuItem.md
│ │ │ ├── Switch.md
│ │ │ ├── TabItem.md
│ │ │ ├── Table.md
│ │ │ ├── TableOfContents.md
│ │ │ ├── Tabs.md
│ │ │ ├── Text.md
│ │ │ ├── TextArea.md
│ │ │ ├── TextBox.md
│ │ │ ├── Theme.md
│ │ │ ├── TimeInput.md
│ │ │ ├── Timer.md
│ │ │ ├── ToneChangerButton.md
│ │ │ ├── ToneSwitch.md
│ │ │ ├── Tooltip.md
│ │ │ ├── Tree.md
│ │ │ ├── VSplitter.md
│ │ │ ├── VStack.md
│ │ │ ├── xmlui-animations
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ ├── Animation.md
│ │ │ │ ├── FadeAnimation.md
│ │ │ │ ├── FadeInAnimation.md
│ │ │ │ ├── FadeOutAnimation.md
│ │ │ │ ├── ScaleAnimation.md
│ │ │ │ └── SlideInAnimation.md
│ │ │ ├── xmlui-pdf
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ └── Pdf.md
│ │ │ ├── xmlui-spreadsheet
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ └── Spreadsheet.md
│ │ │ └── xmlui-website-blocks
│ │ │ ├── _meta.json
│ │ │ ├── _overview.md
│ │ │ ├── Carousel.md
│ │ │ ├── HelloMd.md
│ │ │ ├── HeroSection.md
│ │ │ └── ScrollToTop.md
│ │ └── extensions
│ │ ├── _meta.json
│ │ ├── xmlui-animations
│ │ │ ├── _meta.json
│ │ │ ├── _overview.md
│ │ │ ├── Animation.md
│ │ │ ├── FadeAnimation.md
│ │ │ ├── FadeInAnimation.md
│ │ │ ├── FadeOutAnimation.md
│ │ │ ├── ScaleAnimation.md
│ │ │ └── SlideInAnimation.md
│ │ └── xmlui-website-blocks
│ │ ├── _meta.json
│ │ ├── _overview.md
│ │ ├── Carousel.md
│ │ ├── HelloMd.md
│ │ ├── HeroSection.md
│ │ └── ScrollToTop.md
│ ├── extensions.ts
│ ├── index.html
│ ├── index.ts
│ ├── package.json
│ ├── public
│ │ ├── feed.rss
│ │ ├── mockServiceWorker.js
│ │ ├── pages
│ │ │ ├── _meta.json
│ │ │ ├── app-structure.md
│ │ │ ├── build-editor-component.md
│ │ │ ├── build-hello-world-component.md
│ │ │ ├── components-intro.md
│ │ │ ├── context-variables.md
│ │ │ ├── forms.md
│ │ │ ├── globals.md
│ │ │ ├── glossary.md
│ │ │ ├── helper-tags.md
│ │ │ ├── hosted-deployment.md
│ │ │ ├── howto
│ │ │ │ ├── assign-a-complex-json-literal-to-a-component-variable.md
│ │ │ │ ├── chain-a-refetch.md
│ │ │ │ ├── control-cache-invalidation.md
│ │ │ │ ├── debug-a-component.md
│ │ │ │ ├── delay-a-datasource-until-another-datasource-is-ready.md
│ │ │ │ ├── delegate-a-method.md
│ │ │ │ ├── do-custom-form-validation.md
│ │ │ │ ├── expose-a-method-from-a-component.md
│ │ │ │ ├── filter-and-transform-data-from-an-api.md
│ │ │ │ ├── group-items-in-list-by-a-property.md
│ │ │ │ ├── handle-background-operations.md
│ │ │ │ ├── hide-an-element-until-its-datasource-is-ready.md
│ │ │ │ ├── make-a-set-of-equal-width-cards.md
│ │ │ │ ├── make-a-table-responsive.md
│ │ │ │ ├── make-navpanel-width-responsive.md
│ │ │ │ ├── modify-a-value-reported-in-a-column.md
│ │ │ │ ├── paginate-a-list.md
│ │ │ │ ├── pass-data-to-a-modal-dialog.md
│ │ │ │ ├── react-to-button-click-not-keystrokes.md
│ │ │ │ ├── set-the-initial-value-of-a-select-from-fetched-data.md
│ │ │ │ ├── share-a-modaldialog-across-components.md
│ │ │ │ ├── sync-selections-between-table-and-list-views.md
│ │ │ │ ├── update-ui-optimistically.md
│ │ │ │ ├── use-built-in-form-validation.md
│ │ │ │ └── use-the-same-modaldialog-to-add-or-edit.md
│ │ │ ├── howto.md
│ │ │ ├── intro.md
│ │ │ ├── layout.md
│ │ │ ├── markup.md
│ │ │ ├── mcp.md
│ │ │ ├── modal-dialogs.md
│ │ │ ├── news-and-reviews.md
│ │ │ ├── reactive-intro.md
│ │ │ ├── refactoring.md
│ │ │ ├── routing-and-links.md
│ │ │ ├── samples
│ │ │ │ ├── color-palette.xmlui
│ │ │ │ ├── color-values.xmlui
│ │ │ │ ├── shadow-sizes.xmlui
│ │ │ │ ├── spacing-sizes.xmlui
│ │ │ │ ├── swatch.xmlui
│ │ │ │ ├── theme-gallery-brief.xmlui
│ │ │ │ └── theme-gallery.xmlui
│ │ │ ├── scoping.md
│ │ │ ├── scripting.md
│ │ │ ├── styles-and-themes
│ │ │ │ ├── common-units.md
│ │ │ │ ├── layout-props.md
│ │ │ │ ├── theme-variable-defaults.md
│ │ │ │ ├── theme-variables.md
│ │ │ │ └── themes.md
│ │ │ ├── template-properties.md
│ │ │ ├── test.md
│ │ │ ├── tutorial-01.md
│ │ │ ├── tutorial-02.md
│ │ │ ├── tutorial-03.md
│ │ │ ├── tutorial-04.md
│ │ │ ├── tutorial-05.md
│ │ │ ├── tutorial-06.md
│ │ │ ├── tutorial-07.md
│ │ │ ├── tutorial-08.md
│ │ │ ├── tutorial-09.md
│ │ │ ├── tutorial-10.md
│ │ │ ├── tutorial-11.md
│ │ │ ├── tutorial-12.md
│ │ │ ├── universal-properties.md
│ │ │ ├── user-defined-components.md
│ │ │ ├── vscode.md
│ │ │ ├── working-with-markdown.md
│ │ │ ├── working-with-text.md
│ │ │ ├── xmlui-animations
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ ├── Animation.md
│ │ │ │ ├── FadeAnimation.md
│ │ │ │ ├── FadeInAnimation.md
│ │ │ │ ├── FadeOutAnimation.md
│ │ │ │ ├── ScaleAnimation.md
│ │ │ │ └── SlideInAnimation.md
│ │ │ ├── xmlui-charts
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ ├── BarChart.md
│ │ │ │ ├── DonutChart.md
│ │ │ │ ├── LabelList.md
│ │ │ │ ├── Legend.md
│ │ │ │ ├── LineChart.md
│ │ │ │ └── PieChart.md
│ │ │ ├── xmlui-pdf
│ │ │ │ ├── _meta.json
│ │ │ │ ├── _overview.md
│ │ │ │ └── Pdf.md
│ │ │ └── xmlui-spreadsheet
│ │ │ ├── _meta.json
│ │ │ ├── _overview.md
│ │ │ └── Spreadsheet.md
│ │ ├── resources
│ │ │ ├── devdocs
│ │ │ │ ├── debug-proxy-object-2.png
│ │ │ │ ├── debug-proxy-object.png
│ │ │ │ ├── table_editor_01.png
│ │ │ │ ├── table_editor_02.png
│ │ │ │ ├── table_editor_03.png
│ │ │ │ ├── table_editor_04.png
│ │ │ │ ├── table_editor_05.png
│ │ │ │ ├── table_editor_06.png
│ │ │ │ ├── table_editor_07.png
│ │ │ │ ├── table_editor_08.png
│ │ │ │ ├── table_editor_09.png
│ │ │ │ ├── table_editor_10.png
│ │ │ │ ├── table_editor_11.png
│ │ │ │ ├── table-editor-01.png
│ │ │ │ ├── table-editor-02.png
│ │ │ │ ├── table-editor-03.png
│ │ │ │ ├── table-editor-04.png
│ │ │ │ ├── table-editor-06.png
│ │ │ │ ├── table-editor-07.png
│ │ │ │ ├── table-editor-08.png
│ │ │ │ ├── table-editor-09.png
│ │ │ │ └── xmlui-rendering-of-tiptap-markdown.png
│ │ │ ├── favicon.ico
│ │ │ ├── files
│ │ │ │ ├── clients.json
│ │ │ │ ├── daily-revenue.json
│ │ │ │ ├── dashboard-stats.json
│ │ │ │ ├── demo.xmlui
│ │ │ │ ├── demo.xmlui.xs
│ │ │ │ ├── downloads
│ │ │ │ │ └── downloads.json
│ │ │ │ ├── for-download
│ │ │ │ │ ├── index-with-api.html
│ │ │ │ │ ├── index.html
│ │ │ │ │ ├── mockApi.js
│ │ │ │ │ ├── start-darwin.sh
│ │ │ │ │ ├── start-linux.sh
│ │ │ │ │ ├── start.bat
│ │ │ │ │ └── xmlui
│ │ │ │ │ └── xmlui-standalone.umd.js
│ │ │ │ ├── getting-started
│ │ │ │ │ ├── cl-tutorial-final.zip
│ │ │ │ │ ├── cl-tutorial.zip
│ │ │ │ │ ├── cl-tutorial2.zip
│ │ │ │ │ ├── cl-tutorial3.zip
│ │ │ │ │ ├── cl-tutorial4.zip
│ │ │ │ │ ├── cl-tutorial5.zip
│ │ │ │ │ ├── cl-tutorial6.zip
│ │ │ │ │ ├── getting-started.zip
│ │ │ │ │ ├── hello-xmlui.zip
│ │ │ │ │ ├── xmlui-empty.zip
│ │ │ │ │ └── xmlui-starter.zip
│ │ │ │ ├── howto
│ │ │ │ │ └── component-icons
│ │ │ │ │ └── up-arrow.svg
│ │ │ │ ├── invoices.json
│ │ │ │ ├── monthly-status.json
│ │ │ │ ├── news-and-reviews.json
│ │ │ │ ├── products.json
│ │ │ │ ├── releases.json
│ │ │ │ ├── tutorials
│ │ │ │ │ ├── datasource
│ │ │ │ │ │ └── api.ts
│ │ │ │ │ └── p2do
│ │ │ │ │ ├── api.ts
│ │ │ │ │ └── todo-logo.svg
│ │ │ │ └── xmlui.json
│ │ │ ├── github.svg
│ │ │ ├── images
│ │ │ │ ├── apiaction-tutorial
│ │ │ │ │ ├── add-success.png
│ │ │ │ │ ├── apiaction-param.png
│ │ │ │ │ ├── change-completed.png
│ │ │ │ │ ├── change-in-progress.png
│ │ │ │ │ ├── confirm-delete.png
│ │ │ │ │ ├── data-error.png
│ │ │ │ │ ├── data-progress.png
│ │ │ │ │ ├── data-success.png
│ │ │ │ │ ├── display-1.png
│ │ │ │ │ ├── item-deleted.png
│ │ │ │ │ ├── item-updated.png
│ │ │ │ │ ├── missing-api-key.png
│ │ │ │ │ ├── new-item-added.png
│ │ │ │ │ └── test-message.png
│ │ │ │ ├── chat-api
│ │ │ │ │ └── domain-model.svg
│ │ │ │ ├── components
│ │ │ │ │ ├── image
│ │ │ │ │ │ └── breakfast.jpg
│ │ │ │ │ ├── markdown
│ │ │ │ │ │ └── colors.png
│ │ │ │ │ └── modal
│ │ │ │ │ ├── deep_link_dialog_1.jpg
│ │ │ │ │ └── deep_link_dialog_2.jpg
│ │ │ │ ├── create-apps
│ │ │ │ │ ├── collapsed-vertical.png
│ │ │ │ │ ├── using-forms-warning-dialog.png
│ │ │ │ │ └── using-forms.png
│ │ │ │ ├── datasource-tutorial
│ │ │ │ │ ├── data-with-header.png
│ │ │ │ │ ├── filtered-data.png
│ │ │ │ │ ├── filtered-items.png
│ │ │ │ │ ├── initial-page-items.png
│ │ │ │ │ ├── list-items.png
│ │ │ │ │ ├── next-page-items.png
│ │ │ │ │ ├── no-data.png
│ │ │ │ │ ├── pagination-1.jpg
│ │ │ │ │ ├── pagination-1.png
│ │ │ │ │ ├── polling-1.png
│ │ │ │ │ ├── refetch-data.png
│ │ │ │ │ ├── slow-loading.png
│ │ │ │ │ ├── test-message.png
│ │ │ │ │ ├── Thumbs.db
│ │ │ │ │ ├── unconventional-data.png
│ │ │ │ │ └── unfiltered-items.png
│ │ │ │ ├── flower.jpg
│ │ │ │ ├── get-started
│ │ │ │ │ ├── add-new-contact.png
│ │ │ │ │ ├── app-modified.png
│ │ │ │ │ ├── app-start.png
│ │ │ │ │ ├── app-with-boxes.png
│ │ │ │ │ ├── app-with-toast.png
│ │ │ │ │ ├── boilerplate-structure.png
│ │ │ │ │ ├── cl-initial.png
│ │ │ │ │ ├── cl-start.png
│ │ │ │ │ ├── contact-counts.png
│ │ │ │ │ ├── contact-dialog-title.png
│ │ │ │ │ ├── contact-dialog.png
│ │ │ │ │ ├── contact-menus.png
│ │ │ │ │ ├── contact-predicates.png
│ │ │ │ │ ├── context-menu.png
│ │ │ │ │ ├── dashboard-numbers.png
│ │ │ │ │ ├── default-contact-list.png
│ │ │ │ │ ├── delete-contact.png
│ │ │ │ │ ├── delete-task.png
│ │ │ │ │ ├── detailed-template.png
│ │ │ │ │ ├── edit-contact-details.png
│ │ │ │ │ ├── edited-contact-saved.png
│ │ │ │ │ ├── empty-sections.png
│ │ │ │ │ ├── filter-completed.png
│ │ │ │ │ ├── fullwidth-desktop.png
│ │ │ │ │ ├── fullwidth-mobile.png
│ │ │ │ │ ├── initial-table.png
│ │ │ │ │ ├── items-and-badges.png
│ │ │ │ │ ├── loading-message.png
│ │ │ │ │ ├── new-contact-button.png
│ │ │ │ │ ├── new-contact-saved.png
│ │ │ │ │ ├── no-empty-sections.png
│ │ │ │ │ ├── personal-todo-initial.png
│ │ │ │ │ ├── piechart.png
│ │ │ │ │ ├── review-today.png
│ │ │ │ │ ├── rudimentary-dashboard.png
│ │ │ │ │ ├── section-collapsed.png
│ │ │ │ │ ├── sectioned-items.png
│ │ │ │ │ ├── sections-ordered.png
│ │ │ │ │ ├── spacex-list-with-links.png
│ │ │ │ │ ├── spacex-list.png
│ │ │ │ │ ├── start-personal-todo-1.png
│ │ │ │ │ ├── submit-new-contact.png
│ │ │ │ │ ├── submit-new-task.png
│ │ │ │ │ ├── syntax-highlighting.png
│ │ │ │ │ ├── table-with-badge.png
│ │ │ │ │ ├── template-with-card.png
│ │ │ │ │ ├── test-emulated-api.png
│ │ │ │ │ ├── Thumbs.db
│ │ │ │ │ ├── todo-logo.png
│ │ │ │ │ └── xmlui-tools.png
│ │ │ │ ├── HelloApp.png
│ │ │ │ ├── HelloApp2.png
│ │ │ │ ├── logos
│ │ │ │ │ ├── xmlui1.svg
│ │ │ │ │ ├── xmlui2.svg
│ │ │ │ │ ├── xmlui3.svg
│ │ │ │ │ ├── xmlui4.svg
│ │ │ │ │ ├── xmlui5.svg
│ │ │ │ │ ├── xmlui6.svg
│ │ │ │ │ └── xmlui7.svg
│ │ │ │ ├── pdf
│ │ │ │ │ └── dummy-pdf.jpg
│ │ │ │ ├── rendering-engine
│ │ │ │ │ ├── AppEngine-flow.svg
│ │ │ │ │ ├── Component.svg
│ │ │ │ │ ├── CompoundComponent.svg
│ │ │ │ │ ├── RootComponent.svg
│ │ │ │ │ └── tree-with-containers.svg
│ │ │ │ ├── reviewers-guide
│ │ │ │ │ ├── AppEngine-flow.svg
│ │ │ │ │ └── incbutton-in-action.png
│ │ │ │ ├── tools
│ │ │ │ │ └── boilerplate-structure.png
│ │ │ │ ├── try.svg
│ │ │ │ ├── tutorial
│ │ │ │ │ ├── app-chat-history.png
│ │ │ │ │ ├── app-content-placeholder.png
│ │ │ │ │ ├── app-header-and-content.png
│ │ │ │ │ ├── app-links-channel-selected.png
│ │ │ │ │ ├── app-links-click.png
│ │ │ │ │ ├── app-navigation.png
│ │ │ │ │ ├── finished-ex01.png
│ │ │ │ │ ├── finished-ex02.png
│ │ │ │ │ ├── hello.png
│ │ │ │ │ ├── splash-screen-advanced.png
│ │ │ │ │ ├── splash-screen-after-click.png
│ │ │ │ │ ├── splash-screen-centered.png
│ │ │ │ │ ├── splash-screen-events.png
│ │ │ │ │ ├── splash-screen-expression.png
│ │ │ │ │ ├── splash-screen-reuse-after.png
│ │ │ │ │ ├── splash-screen-reuse-before.png
│ │ │ │ │ └── splash-screen.png
│ │ │ │ └── tutorial-01.png
│ │ │ ├── llms.txt
│ │ │ ├── logo-dark.svg
│ │ │ ├── logo.svg
│ │ │ ├── pg-popout.svg
│ │ │ └── xmlui-logo.svg
│ │ ├── serve.json
│ │ └── web.config
│ ├── scripts
│ │ ├── download-latest-xmlui.js
│ │ ├── generate-rss.js
│ │ ├── get-releases.js
│ │ └── utils.js
│ ├── src
│ │ ├── components
│ │ │ ├── BlogOverview.xmlui
│ │ │ ├── BlogPage.xmlui
│ │ │ ├── Boxes.xmlui
│ │ │ ├── Breadcrumb.xmlui
│ │ │ ├── ChangeLog.xmlui
│ │ │ ├── ColorPalette.xmlui
│ │ │ ├── DocumentLinks.xmlui
│ │ │ ├── DocumentPage.xmlui
│ │ │ ├── DocumentPageNoTOC.xmlui
│ │ │ ├── Icons.xmlui
│ │ │ ├── IncButton.xmlui
│ │ │ ├── IncButton2.xmlui
│ │ │ ├── NameValue.xmlui
│ │ │ ├── PageNotFound.xmlui
│ │ │ ├── PaletteItem.xmlui
│ │ │ ├── Palettes.xmlui
│ │ │ ├── SectionHeader.xmlui
│ │ │ ├── TBD.xmlui
│ │ │ ├── Test.xmlui
│ │ │ ├── ThemesIntro.xmlui
│ │ │ ├── ThousandThemes.xmlui
│ │ │ ├── TubeStops.xmlui
│ │ │ ├── TubeStops.xmlui.xs
│ │ │ └── TwoColumnCode.xmlui
│ │ ├── config.ts
│ │ ├── Main.xmlui
│ │ └── themes
│ │ ├── docs-theme.ts
│ │ ├── earthtone.ts
│ │ ├── xmlui-gray-on-default.ts
│ │ ├── xmlui-green-on-default.ts
│ │ └── xmlui-orange-on-default.ts
│ └── tsconfig.json
├── LICENSE
├── package-lock.json
├── package.json
├── packages
│ ├── tsconfig.json
│ ├── xmlui-animations
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── Animation.tsx
│ │ ├── AnimationNative.tsx
│ │ ├── FadeAnimation.tsx
│ │ ├── FadeInAnimation.tsx
│ │ ├── FadeOutAnimation.tsx
│ │ ├── index.tsx
│ │ ├── ScaleAnimation.tsx
│ │ └── SlideInAnimation.tsx
│ ├── xmlui-devtools
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── devtools
│ │ │ │ ├── DevTools.tsx
│ │ │ │ ├── DevToolsNative.module.scss
│ │ │ │ ├── DevToolsNative.tsx
│ │ │ │ ├── ModalDialog.module.scss
│ │ │ │ ├── ModalDialog.tsx
│ │ │ │ ├── ModalVisibilityContext.tsx
│ │ │ │ ├── Tooltip.module.scss
│ │ │ │ ├── Tooltip.tsx
│ │ │ │ └── utils.ts
│ │ │ ├── editor
│ │ │ │ └── Editor.tsx
│ │ │ └── index.tsx
│ │ └── vite.config-overrides.ts
│ ├── xmlui-hello-world
│ │ ├── .gitignore
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── HelloWorld.module.scss
│ │ ├── HelloWorld.tsx
│ │ ├── HelloWorldNative.tsx
│ │ └── index.tsx
│ ├── xmlui-os-frames
│ │ ├── .gitignore
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── index.tsx
│ │ ├── IPhoneFrame.module.scss
│ │ ├── IPhoneFrame.tsx
│ │ ├── MacOSAppFrame.module.scss
│ │ ├── MacOSAppFrame.tsx
│ │ ├── WindowsAppFrame.module.scss
│ │ └── WindowsAppFrame.tsx
│ ├── xmlui-pdf
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ ├── components
│ │ │ │ └── Pdf.xmlui
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── index.tsx
│ │ ├── LazyPdfNative.tsx
│ │ ├── Pdf.module.scss
│ │ └── Pdf.tsx
│ ├── xmlui-playground
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── hooks
│ │ │ ├── usePlayground.ts
│ │ │ └── useToast.ts
│ │ ├── index.tsx
│ │ ├── playground
│ │ │ ├── Box.module.scss
│ │ │ ├── Box.tsx
│ │ │ ├── CodeSelector.tsx
│ │ │ ├── ConfirmationDialog.module.scss
│ │ │ ├── ConfirmationDialog.tsx
│ │ │ ├── Editor.tsx
│ │ │ ├── Header.module.scss
│ │ │ ├── Header.tsx
│ │ │ ├── Playground.tsx
│ │ │ ├── PlaygroundContent.module.scss
│ │ │ ├── PlaygroundContent.tsx
│ │ │ ├── PlaygroundNative.module.scss
│ │ │ ├── PlaygroundNative.tsx
│ │ │ ├── Preview.module.scss
│ │ │ ├── Preview.tsx
│ │ │ ├── Select.module.scss
│ │ │ ├── StandalonePlayground.tsx
│ │ │ ├── StandalonePlaygroundNative.module.scss
│ │ │ ├── StandalonePlaygroundNative.tsx
│ │ │ ├── ThemeSwitcher.module.scss
│ │ │ ├── ThemeSwitcher.tsx
│ │ │ ├── ToneSwitcher.tsx
│ │ │ ├── Tooltip.module.scss
│ │ │ ├── Tooltip.tsx
│ │ │ └── utils.ts
│ │ ├── providers
│ │ │ ├── Toast.module.scss
│ │ │ └── ToastProvider.tsx
│ │ ├── state
│ │ │ └── store.ts
│ │ ├── themes
│ │ │ └── theme.ts
│ │ └── utils
│ │ └── helpers.ts
│ ├── xmlui-search
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── index.tsx
│ │ ├── Search.module.scss
│ │ └── Search.tsx
│ ├── xmlui-spreadsheet
│ │ ├── .gitignore
│ │ ├── demo
│ │ │ └── Main.xmlui
│ │ ├── index.html
│ │ ├── index.ts
│ │ ├── meta
│ │ │ └── componentsMetadata.ts
│ │ ├── package.json
│ │ └── src
│ │ ├── index.tsx
│ │ ├── Spreadsheet.tsx
│ │ └── SpreadsheetNative.tsx
│ └── xmlui-website-blocks
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── demo
│ │ ├── components
│ │ │ ├── HeroBackgroundBreakoutPage.xmlui
│ │ │ ├── HeroBackgroundsPage.xmlui
│ │ │ ├── HeroContentsPage.xmlui
│ │ │ ├── HeroTextAlignPage.xmlui
│ │ │ ├── HeroTextPage.xmlui
│ │ │ └── HeroTonesPage.xmlui
│ │ ├── Main.xmlui
│ │ └── themes
│ │ └── default.ts
│ ├── index.html
│ ├── index.ts
│ ├── meta
│ │ └── componentsMetadata.ts
│ ├── package.json
│ ├── public
│ │ └── resources
│ │ ├── building.jpg
│ │ └── xmlui-logo.svg
│ └── src
│ ├── Carousel
│ │ ├── Carousel.module.scss
│ │ ├── Carousel.tsx
│ │ ├── CarouselContext.tsx
│ │ └── CarouselNative.tsx
│ ├── FancyButton
│ │ ├── FancyButton.module.scss
│ │ ├── FancyButton.tsx
│ │ └── FancyButton.xmlui
│ ├── Hello
│ │ ├── Hello.tsx
│ │ ├── Hello.xmlui
│ │ └── Hello.xmlui.xs
│ ├── HeroSection
│ │ ├── HeroSection.module.scss
│ │ ├── HeroSection.spec.ts
│ │ ├── HeroSection.tsx
│ │ └── HeroSectionNative.tsx
│ ├── index.tsx
│ ├── ScrollToTop
│ │ ├── ScrollToTop.module.scss
│ │ ├── ScrollToTop.tsx
│ │ └── ScrollToTopNative.tsx
│ └── vite-env.d.ts
├── playwright.config.ts
├── README.md
├── tools
│ ├── codefence
│ │ └── xmlui-code-fence-docs.md
│ ├── create-app
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── create-app.ts
│ │ ├── helpers
│ │ │ ├── copy.ts
│ │ │ ├── get-pkg-manager.ts
│ │ │ ├── git.ts
│ │ │ ├── install.ts
│ │ │ ├── is-folder-empty.ts
│ │ │ ├── is-writeable.ts
│ │ │ ├── make-dir.ts
│ │ │ └── validate-pkg.ts
│ │ ├── index.ts
│ │ ├── package.json
│ │ ├── templates
│ │ │ ├── default
│ │ │ │ └── ts
│ │ │ │ ├── gitignore
│ │ │ │ ├── index.html
│ │ │ │ ├── index.ts
│ │ │ │ ├── public
│ │ │ │ │ ├── mockServiceWorker.js
│ │ │ │ │ ├── resources
│ │ │ │ │ │ ├── favicon.ico
│ │ │ │ │ │ └── xmlui-logo.svg
│ │ │ │ │ └── serve.json
│ │ │ │ └── src
│ │ │ │ ├── components
│ │ │ │ │ ├── ApiAware.xmlui
│ │ │ │ │ ├── Home.xmlui
│ │ │ │ │ ├── IncButton.xmlui
│ │ │ │ │ └── PagePanel.xmlui
│ │ │ │ ├── config.ts
│ │ │ │ └── Main.xmlui
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── tsconfig.json
│ ├── create-xmlui-hello-world
│ │ ├── index.js
│ │ └── package.json
│ └── vscode
│ ├── .gitignore
│ ├── .vscode
│ │ ├── launch.json
│ │ └── tasks.json
│ ├── .vscodeignore
│ ├── build.sh
│ ├── CHANGELOG.md
│ ├── esbuild.js
│ ├── eslint.config.mjs
│ ├── formatter-docs.md
│ ├── generate-test-sample.sh
│ ├── LICENSE.md
│ ├── package-lock.json
│ ├── package.json
│ ├── README.md
│ ├── resources
│ │ ├── xmlui-logo.png
│ │ └── xmlui-markup-syntax-highlighting.png
│ ├── src
│ │ ├── extension.ts
│ │ └── server.ts
│ ├── syntaxes
│ │ └── xmlui.tmLanguage.json
│ ├── test-samples
│ │ └── sample.xmlui
│ ├── tsconfig.json
│ └── tsconfig.tsbuildinfo
├── turbo.json
└── xmlui
├── .gitignore
├── bin
│ ├── bootstrap.cjs
│ ├── bootstrap.js
│ ├── build-lib.ts
│ ├── build.ts
│ ├── index.ts
│ ├── preview.ts
│ ├── start.ts
│ ├── vite-xmlui-plugin.ts
│ └── viteConfig.ts
├── CHANGELOG.md
├── conventions
│ ├── component-qa-checklist.md
│ ├── copilot-conventions.md
│ ├── create-xmlui-components.md
│ ├── mermaid.md
│ ├── testing-conventions.md
│ └── xmlui-in-a-nutshell.md
├── dev-docs
│ ├── accessibility.md
│ ├── build-system.md
│ ├── build-xmlui.md
│ ├── component-behaviors.md
│ ├── components-with-options.md
│ ├── containers.md
│ ├── data-operations.md
│ ├── glossary.md
│ ├── index.md
│ ├── next
│ │ ├── component-dev-guide.md
│ │ ├── configuration-management-enhancement-summary.md
│ │ ├── documentation-scripts-refactoring-complete-summary.md
│ │ ├── documentation-scripts-refactoring-plan.md
│ │ ├── duplicate-pattern-extraction-summary.md
│ │ ├── error-handling-standardization-summary.md
│ │ ├── generating-component-reference.md
│ │ ├── index.md
│ │ ├── logging-consistency-implementation-summary.md
│ │ ├── project-build.md
│ │ ├── project-structure.md
│ │ ├── theme-context.md
│ │ ├── tiptap-design-considerations.md
│ │ ├── working-with-code.md
│ │ ├── xmlui-runtime-architecture
│ │ └── xmlui-wcag-accessibility-report.md
│ ├── react-fundamentals.md
│ ├── release-method.md
│ ├── standalone-app.md
│ ├── ud-components.md
│ └── xmlui-repo.md
├── package.json
├── scripts
│ ├── coverage-only.js
│ ├── e2e-test-summary.js
│ ├── generate-docs
│ │ ├── build-downloads-map.mjs
│ │ ├── build-pages-map.mjs
│ │ ├── components-config.json
│ │ ├── configuration-management.mjs
│ │ ├── constants.mjs
│ │ ├── create-theme-files.mjs
│ │ ├── DocsGenerator.mjs
│ │ ├── error-handling.mjs
│ │ ├── extensions-config.json
│ │ ├── folders.mjs
│ │ ├── generate-summary-files.mjs
│ │ ├── get-docs.mjs
│ │ ├── input-handler.mjs
│ │ ├── logger.mjs
│ │ ├── logging-standards.mjs
│ │ ├── MetadataProcessor.mjs
│ │ ├── pattern-utilities.mjs
│ │ └── utils.mjs
│ ├── get-langserver-metadata.js
│ ├── inline-links.mjs
│ └── README-e2e-summary.md
├── src
│ ├── abstractions
│ │ ├── _conventions.md
│ │ ├── ActionDefs.ts
│ │ ├── AppContextDefs.ts
│ │ ├── ComponentDefs.ts
│ │ ├── ContainerDefs.ts
│ │ ├── ExtensionDefs.ts
│ │ ├── FunctionDefs.ts
│ │ ├── RendererDefs.ts
│ │ ├── scripting
│ │ │ ├── BlockScope.ts
│ │ │ ├── Compilation.ts
│ │ │ ├── LogicalThread.ts
│ │ │ ├── LoopScope.ts
│ │ │ ├── modules.ts
│ │ │ ├── ScriptParserError.ts
│ │ │ ├── Token.ts
│ │ │ ├── TryScope.ts
│ │ │ └── TryScopeExp.ts
│ │ └── ThemingDefs.ts
│ ├── components
│ │ ├── _conventions.md
│ │ ├── abstractions.ts
│ │ ├── Accordion
│ │ │ ├── Accordion.md
│ │ │ ├── Accordion.module.scss
│ │ │ ├── Accordion.spec.ts
│ │ │ ├── Accordion.tsx
│ │ │ ├── AccordionContext.tsx
│ │ │ ├── AccordionItem.tsx
│ │ │ ├── AccordionItemNative.tsx
│ │ │ └── AccordionNative.tsx
│ │ ├── Animation
│ │ │ └── AnimationNative.tsx
│ │ ├── APICall
│ │ │ ├── APICall.md
│ │ │ ├── APICall.spec.ts
│ │ │ ├── APICall.tsx
│ │ │ └── APICallNative.tsx
│ │ ├── App
│ │ │ ├── App.md
│ │ │ ├── App.module.scss
│ │ │ ├── App.spec.ts
│ │ │ ├── App.tsx
│ │ │ ├── AppLayoutContext.ts
│ │ │ ├── AppNative.tsx
│ │ │ ├── AppStateContext.ts
│ │ │ ├── doc-resources
│ │ │ │ ├── condensed-sticky.xmlui
│ │ │ │ ├── condensed.xmlui
│ │ │ │ ├── horizontal-sticky.xmlui
│ │ │ │ ├── horizontal.xmlui
│ │ │ │ ├── vertical-full-header.xmlui
│ │ │ │ ├── vertical-sticky.xmlui
│ │ │ │ └── vertical.xmlui
│ │ │ ├── IndexerContext.ts
│ │ │ ├── LinkInfoContext.ts
│ │ │ ├── SearchContext.tsx
│ │ │ ├── Sheet.module.scss
│ │ │ └── Sheet.tsx
│ │ ├── AppHeader
│ │ │ ├── AppHeader.md
│ │ │ ├── AppHeader.module.scss
│ │ │ ├── AppHeader.spec.ts
│ │ │ ├── AppHeader.tsx
│ │ │ └── AppHeaderNative.tsx
│ │ ├── AppState
│ │ │ ├── AppState.md
│ │ │ ├── AppState.spec.ts
│ │ │ ├── AppState.tsx
│ │ │ └── AppStateNative.tsx
│ │ ├── AutoComplete
│ │ │ ├── AutoComplete.md
│ │ │ ├── AutoComplete.module.scss
│ │ │ ├── AutoComplete.spec.ts
│ │ │ ├── AutoComplete.tsx
│ │ │ ├── AutoCompleteContext.tsx
│ │ │ └── AutoCompleteNative.tsx
│ │ ├── Avatar
│ │ │ ├── Avatar.md
│ │ │ ├── Avatar.module.scss
│ │ │ ├── Avatar.spec.ts
│ │ │ ├── Avatar.tsx
│ │ │ └── AvatarNative.tsx
│ │ ├── Backdrop
│ │ │ ├── Backdrop.md
│ │ │ ├── Backdrop.module.scss
│ │ │ ├── Backdrop.spec.ts
│ │ │ ├── Backdrop.tsx
│ │ │ └── BackdropNative.tsx
│ │ ├── Badge
│ │ │ ├── Badge.md
│ │ │ ├── Badge.module.scss
│ │ │ ├── Badge.spec.ts
│ │ │ ├── Badge.tsx
│ │ │ └── BadgeNative.tsx
│ │ ├── Bookmark
│ │ │ ├── Bookmark.md
│ │ │ ├── Bookmark.module.scss
│ │ │ ├── Bookmark.spec.ts
│ │ │ ├── Bookmark.tsx
│ │ │ └── BookmarkNative.tsx
│ │ ├── Breakout
│ │ │ ├── Breakout.module.scss
│ │ │ ├── Breakout.spec.ts
│ │ │ ├── Breakout.tsx
│ │ │ └── BreakoutNative.tsx
│ │ ├── Button
│ │ │ ├── Button-style.spec.ts
│ │ │ ├── Button.md
│ │ │ ├── Button.module.scss
│ │ │ ├── Button.spec.ts
│ │ │ ├── Button.tsx
│ │ │ └── ButtonNative.tsx
│ │ ├── Card
│ │ │ ├── Card.md
│ │ │ ├── Card.module.scss
│ │ │ ├── Card.spec.ts
│ │ │ ├── Card.tsx
│ │ │ └── CardNative.tsx
│ │ ├── Carousel
│ │ │ ├── Carousel.md
│ │ │ ├── Carousel.module.scss
│ │ │ ├── Carousel.spec.ts
│ │ │ ├── Carousel.tsx
│ │ │ ├── CarouselContext.tsx
│ │ │ ├── CarouselItem.tsx
│ │ │ ├── CarouselItemNative.tsx
│ │ │ └── CarouselNative.tsx
│ │ ├── ChangeListener
│ │ │ ├── ChangeListener.md
│ │ │ ├── ChangeListener.spec.ts
│ │ │ ├── ChangeListener.tsx
│ │ │ └── ChangeListenerNative.tsx
│ │ ├── chart-color-schemes.ts
│ │ ├── Charts
│ │ │ ├── AreaChart
│ │ │ │ ├── AreaChart.md
│ │ │ │ ├── AreaChart.spec.ts
│ │ │ │ ├── AreaChart.tsx
│ │ │ │ └── AreaChartNative.tsx
│ │ │ ├── BarChart
│ │ │ │ ├── BarChart.md
│ │ │ │ ├── BarChart.module.scss
│ │ │ │ ├── BarChart.spec.ts
│ │ │ │ ├── BarChart.tsx
│ │ │ │ └── BarChartNative.tsx
│ │ │ ├── DonutChart
│ │ │ │ ├── DonutChart.spec.ts
│ │ │ │ └── DonutChart.tsx
│ │ │ ├── LabelList
│ │ │ │ ├── LabelList.spec.ts
│ │ │ │ ├── LabelList.tsx
│ │ │ │ ├── LabelListNative.module.scss
│ │ │ │ └── LabelListNative.tsx
│ │ │ ├── Legend
│ │ │ │ ├── Legend.spec.ts
│ │ │ │ ├── Legend.tsx
│ │ │ │ └── LegendNative.tsx
│ │ │ ├── LineChart
│ │ │ │ ├── LineChart.md
│ │ │ │ ├── LineChart.module.scss
│ │ │ │ ├── LineChart.spec.ts
│ │ │ │ ├── LineChart.tsx
│ │ │ │ └── LineChartNative.tsx
│ │ │ ├── PieChart
│ │ │ │ ├── PieChart.md
│ │ │ │ ├── PieChart.spec.ts
│ │ │ │ ├── PieChart.tsx
│ │ │ │ ├── PieChartNative.module.scss
│ │ │ │ └── PieChartNative.tsx
│ │ │ ├── RadarChart
│ │ │ │ ├── RadarChart.md
│ │ │ │ ├── RadarChart.spec.ts
│ │ │ │ ├── RadarChart.tsx
│ │ │ │ └── RadarChartNative.tsx
│ │ │ ├── Tooltip
│ │ │ │ ├── TooltipContent.module.scss
│ │ │ │ ├── TooltipContent.spec.ts
│ │ │ │ └── TooltipContent.tsx
│ │ │ └── utils
│ │ │ ├── abstractions.ts
│ │ │ └── ChartProvider.tsx
│ │ ├── Checkbox
│ │ │ ├── Checkbox.md
│ │ │ ├── Checkbox.spec.ts
│ │ │ └── Checkbox.tsx
│ │ ├── CodeBlock
│ │ │ ├── CodeBlock.module.scss
│ │ │ ├── CodeBlock.spec.ts
│ │ │ ├── CodeBlock.tsx
│ │ │ ├── CodeBlockNative.tsx
│ │ │ └── highlight-code.ts
│ │ ├── collectedComponentMetadata.ts
│ │ ├── ColorPicker
│ │ │ ├── ColorPicker.md
│ │ │ ├── ColorPicker.module.scss
│ │ │ ├── ColorPicker.spec.ts
│ │ │ ├── ColorPicker.tsx
│ │ │ └── ColorPickerNative.tsx
│ │ ├── Column
│ │ │ ├── Column.md
│ │ │ ├── Column.tsx
│ │ │ ├── ColumnNative.tsx
│ │ │ ├── doc-resources
│ │ │ │ └── list-component-data.js
│ │ │ └── TableContext.tsx
│ │ ├── component-utils.ts
│ │ ├── ComponentProvider.tsx
│ │ ├── ComponentRegistryContext.tsx
│ │ ├── container-helpers.tsx
│ │ ├── ContentSeparator
│ │ │ ├── ContentSeparator.md
│ │ │ ├── ContentSeparator.module.scss
│ │ │ ├── ContentSeparator.spec.ts
│ │ │ ├── ContentSeparator.tsx
│ │ │ └── ContentSeparatorNative.tsx
│ │ ├── DataSource
│ │ │ ├── DataSource.md
│ │ │ └── DataSource.tsx
│ │ ├── DateInput
│ │ │ ├── DateInput.md
│ │ │ ├── DateInput.module.scss
│ │ │ ├── DateInput.spec.ts
│ │ │ ├── DateInput.tsx
│ │ │ └── DateInputNative.tsx
│ │ ├── DatePicker
│ │ │ ├── DatePicker.md
│ │ │ ├── DatePicker.module.scss
│ │ │ ├── DatePicker.spec.ts
│ │ │ ├── DatePicker.tsx
│ │ │ └── DatePickerNative.tsx
│ │ ├── DropdownMenu
│ │ │ ├── DropdownMenu.md
│ │ │ ├── DropdownMenu.module.scss
│ │ │ ├── DropdownMenu.spec.ts
│ │ │ ├── DropdownMenu.tsx
│ │ │ ├── DropdownMenuNative.tsx
│ │ │ ├── MenuItem.md
│ │ │ └── SubMenuItem.md
│ │ ├── EmojiSelector
│ │ │ ├── EmojiSelector.md
│ │ │ ├── EmojiSelector.spec.ts
│ │ │ ├── EmojiSelector.tsx
│ │ │ └── EmojiSelectorNative.tsx
│ │ ├── ExpandableItem
│ │ │ ├── ExpandableItem.module.scss
│ │ │ ├── ExpandableItem.spec.ts
│ │ │ ├── ExpandableItem.tsx
│ │ │ └── ExpandableItemNative.tsx
│ │ ├── FileInput
│ │ │ ├── FileInput.md
│ │ │ ├── FileInput.module.scss
│ │ │ ├── FileInput.spec.ts
│ │ │ ├── FileInput.tsx
│ │ │ └── FileInputNative.tsx
│ │ ├── FileUploadDropZone
│ │ │ ├── FileUploadDropZone.md
│ │ │ ├── FileUploadDropZone.module.scss
│ │ │ ├── FileUploadDropZone.spec.ts
│ │ │ ├── FileUploadDropZone.tsx
│ │ │ └── FileUploadDropZoneNative.tsx
│ │ ├── FlowLayout
│ │ │ ├── FlowLayout.md
│ │ │ ├── FlowLayout.module.scss
│ │ │ ├── FlowLayout.spec.ts
│ │ │ ├── FlowLayout.spec.ts-snapshots
│ │ │ │ └── Edge-cases-boxShadow-is-not-clipped-1-non-smoke-darwin.png
│ │ │ ├── FlowLayout.tsx
│ │ │ └── FlowLayoutNative.tsx
│ │ ├── Footer
│ │ │ ├── Footer.md
│ │ │ ├── Footer.module.scss
│ │ │ ├── Footer.spec.ts
│ │ │ ├── Footer.tsx
│ │ │ └── FooterNative.tsx
│ │ ├── Form
│ │ │ ├── Form.md
│ │ │ ├── Form.module.scss
│ │ │ ├── Form.spec.ts
│ │ │ ├── Form.tsx
│ │ │ ├── formActions.ts
│ │ │ ├── FormContext.ts
│ │ │ └── FormNative.tsx
│ │ ├── FormItem
│ │ │ ├── FormItem.md
│ │ │ ├── FormItem.module.scss
│ │ │ ├── FormItem.spec.ts
│ │ │ ├── FormItem.tsx
│ │ │ ├── FormItemNative.tsx
│ │ │ ├── HelperText.module.scss
│ │ │ ├── HelperText.tsx
│ │ │ ├── ItemWithLabel.tsx
│ │ │ └── Validations.ts
│ │ ├── FormSection
│ │ │ ├── FormSection.md
│ │ │ ├── FormSection.ts
│ │ │ └── FormSection.xmlui
│ │ ├── Fragment
│ │ │ ├── Fragment.spec.ts
│ │ │ └── Fragment.tsx
│ │ ├── Heading
│ │ │ ├── abstractions.ts
│ │ │ ├── H1.md
│ │ │ ├── H1.spec.ts
│ │ │ ├── H2.md
│ │ │ ├── H2.spec.ts
│ │ │ ├── H3.md
│ │ │ ├── H3.spec.ts
│ │ │ ├── H4.md
│ │ │ ├── H4.spec.ts
│ │ │ ├── H5.md
│ │ │ ├── H5.spec.ts
│ │ │ ├── H6.md
│ │ │ ├── H6.spec.ts
│ │ │ ├── Heading.md
│ │ │ ├── Heading.module.scss
│ │ │ ├── Heading.spec.ts
│ │ │ ├── Heading.tsx
│ │ │ └── HeadingNative.tsx
│ │ ├── HoverCard
│ │ │ ├── HoverCard.tsx
│ │ │ └── HovercardNative.tsx
│ │ ├── HtmlTags
│ │ │ ├── HtmlTags.module.scss
│ │ │ ├── HtmlTags.spec.ts
│ │ │ └── HtmlTags.tsx
│ │ ├── Icon
│ │ │ ├── AdmonitionDanger.tsx
│ │ │ ├── AdmonitionInfo.tsx
│ │ │ ├── AdmonitionNote.tsx
│ │ │ ├── AdmonitionTip.tsx
│ │ │ ├── AdmonitionWarning.tsx
│ │ │ ├── ApiIcon.tsx
│ │ │ ├── ArrowDropDown.module.scss
│ │ │ ├── ArrowDropDown.tsx
│ │ │ ├── ArrowDropUp.module.scss
│ │ │ ├── ArrowDropUp.tsx
│ │ │ ├── ArrowLeft.module.scss
│ │ │ ├── ArrowLeft.tsx
│ │ │ ├── ArrowRight.module.scss
│ │ │ ├── ArrowRight.tsx
│ │ │ ├── Attach.tsx
│ │ │ ├── Binding.module.scss
│ │ │ ├── Binding.tsx
│ │ │ ├── BoardIcon.tsx
│ │ │ ├── BoxIcon.tsx
│ │ │ ├── CheckIcon.tsx
│ │ │ ├── ChevronDownIcon.tsx
│ │ │ ├── ChevronLeft.tsx
│ │ │ ├── ChevronRight.tsx
│ │ │ ├── ChevronUpIcon.tsx
│ │ │ ├── CodeFileIcon.tsx
│ │ │ ├── CodeSandbox.tsx
│ │ │ ├── CompactListIcon.tsx
│ │ │ ├── ContentCopyIcon.tsx
│ │ │ ├── DarkToLightIcon.tsx
│ │ │ ├── DatabaseIcon.module.scss
│ │ │ ├── DatabaseIcon.tsx
│ │ │ ├── DocFileIcon.tsx
│ │ │ ├── DocIcon.tsx
│ │ │ ├── DotMenuHorizontalIcon.tsx
│ │ │ ├── DotMenuIcon.tsx
│ │ │ ├── EmailIcon.tsx
│ │ │ ├── EmptyFolderIcon.tsx
│ │ │ ├── ErrorIcon.tsx
│ │ │ ├── ExpressionIcon.tsx
│ │ │ ├── FillPlusCricleIcon.tsx
│ │ │ ├── FilterIcon.tsx
│ │ │ ├── FolderIcon.tsx
│ │ │ ├── GlobeIcon.tsx
│ │ │ ├── HomeIcon.tsx
│ │ │ ├── HyperLinkIcon.tsx
│ │ │ ├── Icon.md
│ │ │ ├── Icon.module.scss
│ │ │ ├── Icon.spec.ts
│ │ │ ├── Icon.tsx
│ │ │ ├── IconNative.tsx
│ │ │ ├── ImageFileIcon.tsx
│ │ │ ├── Inspect.tsx
│ │ │ ├── LightToDark.tsx
│ │ │ ├── LinkIcon.tsx
│ │ │ ├── ListIcon.tsx
│ │ │ ├── LooseListIcon.tsx
│ │ │ ├── MoonIcon.tsx
│ │ │ ├── MoreOptionsIcon.tsx
│ │ │ ├── NoSortIcon.tsx
│ │ │ ├── PDFIcon.tsx
│ │ │ ├── PenIcon.tsx
│ │ │ ├── PhoneIcon.tsx
│ │ │ ├── PhotoIcon.tsx
│ │ │ ├── PlusIcon.tsx
│ │ │ ├── SearchIcon.tsx
│ │ │ ├── ShareIcon.tsx
│ │ │ ├── SortAscendingIcon.tsx
│ │ │ ├── SortDescendingIcon.tsx
│ │ │ ├── StarsIcon.tsx
│ │ │ ├── SunIcon.tsx
│ │ │ ├── svg
│ │ │ │ ├── admonition_danger.svg
│ │ │ │ ├── admonition_info.svg
│ │ │ │ ├── admonition_note.svg
│ │ │ │ ├── admonition_tip.svg
│ │ │ │ ├── admonition_warning.svg
│ │ │ │ ├── api.svg
│ │ │ │ ├── arrow-dropdown.svg
│ │ │ │ ├── arrow-left.svg
│ │ │ │ ├── arrow-right.svg
│ │ │ │ ├── arrow-up.svg
│ │ │ │ ├── attach.svg
│ │ │ │ ├── binding.svg
│ │ │ │ ├── box.svg
│ │ │ │ ├── bulb.svg
│ │ │ │ ├── code-file.svg
│ │ │ │ ├── code-sandbox.svg
│ │ │ │ ├── dark_to_light.svg
│ │ │ │ ├── database.svg
│ │ │ │ ├── doc.svg
│ │ │ │ ├── empty-folder.svg
│ │ │ │ ├── expression.svg
│ │ │ │ ├── eye-closed.svg
│ │ │ │ ├── eye-dark.svg
│ │ │ │ ├── eye.svg
│ │ │ │ ├── file-text.svg
│ │ │ │ ├── filter.svg
│ │ │ │ ├── folder.svg
│ │ │ │ ├── img.svg
│ │ │ │ ├── inspect.svg
│ │ │ │ ├── light_to_dark.svg
│ │ │ │ ├── moon.svg
│ │ │ │ ├── pdf.svg
│ │ │ │ ├── photo.svg
│ │ │ │ ├── share.svg
│ │ │ │ ├── stars.svg
│ │ │ │ ├── sun.svg
│ │ │ │ ├── trending-down.svg
│ │ │ │ ├── trending-level.svg
│ │ │ │ ├── trending-up.svg
│ │ │ │ ├── txt.svg
│ │ │ │ ├── unknown-file.svg
│ │ │ │ ├── unlink.svg
│ │ │ │ └── xls.svg
│ │ │ ├── TableDeleteColumnIcon.tsx
│ │ │ ├── TableDeleteRowIcon.tsx
│ │ │ ├── TableInsertColumnIcon.tsx
│ │ │ ├── TableInsertRowIcon.tsx
│ │ │ ├── TrashIcon.tsx
│ │ │ ├── TrendingDownIcon.tsx
│ │ │ ├── TrendingLevelIcon.tsx
│ │ │ ├── TrendingUpIcon.tsx
│ │ │ ├── TxtIcon.tsx
│ │ │ ├── UnknownFileIcon.tsx
│ │ │ ├── UnlinkIcon.tsx
│ │ │ ├── UserIcon.tsx
│ │ │ ├── WarningIcon.tsx
│ │ │ └── XlsIcon.tsx
│ │ ├── IconProvider.tsx
│ │ ├── IconRegistryContext.tsx
│ │ ├── IFrame
│ │ │ ├── IFrame.md
│ │ │ ├── IFrame.module.scss
│ │ │ ├── IFrame.spec.ts
│ │ │ ├── IFrame.tsx
│ │ │ └── IFrameNative.tsx
│ │ ├── Image
│ │ │ ├── Image.md
│ │ │ ├── Image.module.scss
│ │ │ ├── Image.spec.ts
│ │ │ ├── Image.tsx
│ │ │ └── ImageNative.tsx
│ │ ├── Input
│ │ │ ├── index.ts
│ │ │ ├── InputAdornment.module.scss
│ │ │ ├── InputAdornment.tsx
│ │ │ ├── InputDivider.module.scss
│ │ │ ├── InputDivider.tsx
│ │ │ ├── InputLabel.module.scss
│ │ │ ├── InputLabel.tsx
│ │ │ ├── PartialInput.module.scss
│ │ │ └── PartialInput.tsx
│ │ ├── InspectButton
│ │ │ ├── InspectButton.module.scss
│ │ │ └── InspectButton.tsx
│ │ ├── Items
│ │ │ ├── Items.md
│ │ │ ├── Items.spec.ts
│ │ │ ├── Items.tsx
│ │ │ └── ItemsNative.tsx
│ │ ├── Link
│ │ │ ├── Link.md
│ │ │ ├── Link.module.scss
│ │ │ ├── Link.spec.ts
│ │ │ ├── Link.tsx
│ │ │ └── LinkNative.tsx
│ │ ├── List
│ │ │ ├── doc-resources
│ │ │ │ └── list-component-data.js
│ │ │ ├── List.md
│ │ │ ├── List.module.scss
│ │ │ ├── List.spec.ts
│ │ │ ├── List.tsx
│ │ │ └── ListNative.tsx
│ │ ├── Logo
│ │ │ ├── doc-resources
│ │ │ │ └── xmlui-logo.svg
│ │ │ ├── Logo.md
│ │ │ ├── Logo.tsx
│ │ │ └── LogoNative.tsx
│ │ ├── Markdown
│ │ │ ├── CodeText.module.scss
│ │ │ ├── CodeText.tsx
│ │ │ ├── Markdown.md
│ │ │ ├── Markdown.module.scss
│ │ │ ├── Markdown.spec.ts
│ │ │ ├── Markdown.tsx
│ │ │ ├── MarkdownNative.tsx
│ │ │ ├── parse-binding-expr.ts
│ │ │ └── utils.ts
│ │ ├── metadata-helpers.ts
│ │ ├── ModalDialog
│ │ │ ├── ConfirmationModalContextProvider.tsx
│ │ │ ├── Dialog.module.scss
│ │ │ ├── Dialog.tsx
│ │ │ ├── ModalDialog.md
│ │ │ ├── ModalDialog.module.scss
│ │ │ ├── ModalDialog.spec.ts
│ │ │ ├── ModalDialog.tsx
│ │ │ ├── ModalDialogNative.tsx
│ │ │ └── ModalVisibilityContext.tsx
│ │ ├── NavGroup
│ │ │ ├── NavGroup.md
│ │ │ ├── NavGroup.module.scss
│ │ │ ├── NavGroup.spec.ts
│ │ │ ├── NavGroup.tsx
│ │ │ ├── NavGroupContext.ts
│ │ │ └── NavGroupNative.tsx
│ │ ├── NavLink
│ │ │ ├── NavLink.md
│ │ │ ├── NavLink.module.scss
│ │ │ ├── NavLink.spec.ts
│ │ │ ├── NavLink.tsx
│ │ │ └── NavLinkNative.tsx
│ │ ├── NavPanel
│ │ │ ├── NavPanel.md
│ │ │ ├── NavPanel.module.scss
│ │ │ ├── NavPanel.spec.ts
│ │ │ ├── NavPanel.tsx
│ │ │ └── NavPanelNative.tsx
│ │ ├── NestedApp
│ │ │ ├── AppWithCodeView.module.scss
│ │ │ ├── AppWithCodeView.tsx
│ │ │ ├── AppWithCodeViewNative.tsx
│ │ │ ├── defaultProps.tsx
│ │ │ ├── logo.svg
│ │ │ ├── NestedApp.module.scss
│ │ │ ├── NestedApp.tsx
│ │ │ ├── NestedAppNative.tsx
│ │ │ ├── Tooltip.module.scss
│ │ │ ├── Tooltip.tsx
│ │ │ └── utils.ts
│ │ ├── NoResult
│ │ │ ├── NoResult.md
│ │ │ ├── NoResult.module.scss
│ │ │ ├── NoResult.spec.ts
│ │ │ ├── NoResult.tsx
│ │ │ └── NoResultNative.tsx
│ │ ├── NumberBox
│ │ │ ├── numberbox-abstractions.ts
│ │ │ ├── NumberBox.md
│ │ │ ├── NumberBox.module.scss
│ │ │ ├── NumberBox.spec.ts
│ │ │ ├── NumberBox.tsx
│ │ │ └── NumberBoxNative.tsx
│ │ ├── Option
│ │ │ ├── Option.md
│ │ │ ├── Option.spec.ts
│ │ │ ├── Option.tsx
│ │ │ ├── OptionNative.tsx
│ │ │ └── OptionTypeProvider.tsx
│ │ ├── PageMetaTitle
│ │ │ ├── PageMetaTilteNative.tsx
│ │ │ ├── PageMetaTitle.md
│ │ │ ├── PageMetaTitle.spec.ts
│ │ │ └── PageMetaTitle.tsx
│ │ ├── Pages
│ │ │ ├── Page.md
│ │ │ ├── Pages.md
│ │ │ ├── Pages.module.scss
│ │ │ ├── Pages.tsx
│ │ │ └── PagesNative.tsx
│ │ ├── Pagination
│ │ │ ├── Pagination.md
│ │ │ ├── Pagination.module.scss
│ │ │ ├── Pagination.spec.ts
│ │ │ ├── Pagination.tsx
│ │ │ └── PaginationNative.tsx
│ │ ├── PositionedContainer
│ │ │ ├── PositionedContainer.module.scss
│ │ │ ├── PositionedContainer.tsx
│ │ │ └── PositionedContainerNative.tsx
│ │ ├── ProfileMenu
│ │ │ ├── ProfileMenu.module.scss
│ │ │ └── ProfileMenu.tsx
│ │ ├── ProgressBar
│ │ │ ├── ProgressBar.md
│ │ │ ├── ProgressBar.module.scss
│ │ │ ├── ProgressBar.spec.ts
│ │ │ ├── ProgressBar.tsx
│ │ │ └── ProgressBarNative.tsx
│ │ ├── Queue
│ │ │ ├── Queue.md
│ │ │ ├── Queue.spec.ts
│ │ │ ├── Queue.tsx
│ │ │ ├── queueActions.ts
│ │ │ └── QueueNative.tsx
│ │ ├── RadioGroup
│ │ │ ├── RadioGroup.md
│ │ │ ├── RadioGroup.module.scss
│ │ │ ├── RadioGroup.spec.ts
│ │ │ ├── RadioGroup.tsx
│ │ │ ├── RadioGroupNative.tsx
│ │ │ ├── RadioItem.tsx
│ │ │ └── RadioItemNative.tsx
│ │ ├── RealTimeAdapter
│ │ │ ├── RealTimeAdapter.tsx
│ │ │ └── RealTimeAdapterNative.tsx
│ │ ├── Redirect
│ │ │ ├── Redirect.md
│ │ │ ├── Redirect.spec.ts
│ │ │ └── Redirect.tsx
│ │ ├── ResponsiveBar
│ │ │ ├── README.md
│ │ │ ├── ResponsiveBar.md
│ │ │ ├── ResponsiveBar.module.scss
│ │ │ ├── ResponsiveBar.spec.ts
│ │ │ ├── ResponsiveBar.tsx
│ │ │ └── ResponsiveBarNative.tsx
│ │ ├── Select
│ │ │ ├── HiddenOption.tsx
│ │ │ ├── OptionContext.ts
│ │ │ ├── Select.md
│ │ │ ├── Select.module.scss
│ │ │ ├── Select.spec.ts
│ │ │ ├── Select.tsx
│ │ │ ├── SelectContext.tsx
│ │ │ └── SelectNative.tsx
│ │ ├── SelectionStore
│ │ │ ├── SelectionStore.md
│ │ │ ├── SelectionStore.tsx
│ │ │ └── SelectionStoreNative.tsx
│ │ ├── Slider
│ │ │ ├── Slider.md
│ │ │ ├── Slider.module.scss
│ │ │ ├── Slider.spec.ts
│ │ │ ├── Slider.tsx
│ │ │ └── SliderNative.tsx
│ │ ├── Slot
│ │ │ ├── Slot.md
│ │ │ ├── Slot.spec.ts
│ │ │ └── Slot.ts
│ │ ├── SlotItem.tsx
│ │ ├── SpaceFiller
│ │ │ ├── SpaceFiller.md
│ │ │ ├── SpaceFiller.module.scss
│ │ │ ├── SpaceFiller.spec.ts
│ │ │ ├── SpaceFiller.tsx
│ │ │ └── SpaceFillerNative.tsx
│ │ ├── Spinner
│ │ │ ├── Spinner.md
│ │ │ ├── Spinner.module.scss
│ │ │ ├── Spinner.spec.ts
│ │ │ ├── Spinner.tsx
│ │ │ └── SpinnerNative.tsx
│ │ ├── Splitter
│ │ │ ├── HSplitter.md
│ │ │ ├── HSplitter.spec.ts
│ │ │ ├── Splitter.md
│ │ │ ├── Splitter.module.scss
│ │ │ ├── Splitter.spec.ts
│ │ │ ├── Splitter.tsx
│ │ │ ├── SplitterNative.tsx
│ │ │ ├── utils.ts
│ │ │ ├── VSplitter.md
│ │ │ └── VSplitter.spec.ts
│ │ ├── Stack
│ │ │ ├── CHStack.md
│ │ │ ├── CHStack.spec.ts
│ │ │ ├── CVStack.md
│ │ │ ├── CVStack.spec.ts
│ │ │ ├── HStack.md
│ │ │ ├── HStack.spec.ts
│ │ │ ├── Stack.md
│ │ │ ├── Stack.module.scss
│ │ │ ├── Stack.spec.ts
│ │ │ ├── Stack.tsx
│ │ │ ├── StackNative.tsx
│ │ │ ├── VStack.md
│ │ │ └── VStack.spec.ts
│ │ ├── StickyBox
│ │ │ ├── StickyBox.md
│ │ │ ├── StickyBox.module.scss
│ │ │ ├── StickyBox.tsx
│ │ │ └── StickyBoxNative.tsx
│ │ ├── Switch
│ │ │ ├── Switch.md
│ │ │ ├── Switch.spec.ts
│ │ │ └── Switch.tsx
│ │ ├── Table
│ │ │ ├── doc-resources
│ │ │ │ └── list-component-data.js
│ │ │ ├── react-table-config.d.ts
│ │ │ ├── Table.md
│ │ │ ├── Table.module.scss
│ │ │ ├── Table.spec.ts
│ │ │ ├── Table.tsx
│ │ │ ├── TableNative.tsx
│ │ │ └── useRowSelection.tsx
│ │ ├── TableOfContents
│ │ │ ├── TableOfContents.module.scss
│ │ │ ├── TableOfContents.spec.ts
│ │ │ ├── TableOfContents.tsx
│ │ │ └── TableOfContentsNative.tsx
│ │ ├── Tabs
│ │ │ ├── TabContext.tsx
│ │ │ ├── TabItem.md
│ │ │ ├── TabItem.tsx
│ │ │ ├── TabItemNative.tsx
│ │ │ ├── Tabs.md
│ │ │ ├── Tabs.module.scss
│ │ │ ├── Tabs.spec.ts
│ │ │ ├── Tabs.tsx
│ │ │ └── TabsNative.tsx
│ │ ├── Text
│ │ │ ├── Text.md
│ │ │ ├── Text.module.scss
│ │ │ ├── Text.spec.ts
│ │ │ ├── Text.tsx
│ │ │ └── TextNative.tsx
│ │ ├── TextArea
│ │ │ ├── TextArea.md
│ │ │ ├── TextArea.module.scss
│ │ │ ├── TextArea.spec.ts
│ │ │ ├── TextArea.tsx
│ │ │ ├── TextAreaNative.tsx
│ │ │ ├── TextAreaResizable.tsx
│ │ │ └── useComposedRef.ts
│ │ ├── TextBox
│ │ │ ├── TextBox.md
│ │ │ ├── TextBox.module.scss
│ │ │ ├── TextBox.spec.ts
│ │ │ ├── TextBox.tsx
│ │ │ └── TextBoxNative.tsx
│ │ ├── Theme
│ │ │ ├── NotificationToast.tsx
│ │ │ ├── Theme.md
│ │ │ ├── Theme.module.scss
│ │ │ ├── Theme.spec.ts
│ │ │ ├── Theme.tsx
│ │ │ └── ThemeNative.tsx
│ │ ├── TimeInput
│ │ │ ├── TimeInput.md
│ │ │ ├── TimeInput.module.scss
│ │ │ ├── TimeInput.spec.ts
│ │ │ ├── TimeInput.tsx
│ │ │ ├── TimeInputNative.tsx
│ │ │ └── utils.ts
│ │ ├── Timer
│ │ │ ├── Timer.md
│ │ │ ├── Timer.spec.ts
│ │ │ ├── Timer.tsx
│ │ │ └── TimerNative.tsx
│ │ ├── Toggle
│ │ │ ├── Toggle.module.scss
│ │ │ └── Toggle.tsx
│ │ ├── ToneChangerButton
│ │ │ ├── ToneChangerButton.md
│ │ │ ├── ToneChangerButton.spec.ts
│ │ │ └── ToneChangerButton.tsx
│ │ ├── ToneSwitch
│ │ │ ├── ToneSwitch.md
│ │ │ ├── ToneSwitch.module.scss
│ │ │ ├── ToneSwitch.spec.ts
│ │ │ ├── ToneSwitch.tsx
│ │ │ └── ToneSwitchNative.tsx
│ │ ├── Tooltip
│ │ │ ├── Tooltip.md
│ │ │ ├── Tooltip.module.scss
│ │ │ ├── Tooltip.spec.ts
│ │ │ ├── Tooltip.tsx
│ │ │ └── TooltipNative.tsx
│ │ ├── Tree
│ │ │ ├── testData.ts
│ │ │ ├── Tree-dynamic.spec.ts
│ │ │ ├── Tree-icons.spec.ts
│ │ │ ├── Tree.md
│ │ │ ├── Tree.spec.ts
│ │ │ ├── TreeComponent.module.scss
│ │ │ ├── TreeComponent.tsx
│ │ │ └── TreeNative.tsx
│ │ ├── TreeDisplay
│ │ │ ├── TreeDisplay.md
│ │ │ ├── TreeDisplay.module.scss
│ │ │ ├── TreeDisplay.tsx
│ │ │ └── TreeDisplayNative.tsx
│ │ ├── ValidationSummary
│ │ │ ├── ValidationSummary.module.scss
│ │ │ └── ValidationSummary.tsx
│ │ └── VisuallyHidden.tsx
│ ├── components-core
│ │ ├── abstractions
│ │ │ ├── ComponentRenderer.ts
│ │ │ ├── LoaderRenderer.ts
│ │ │ ├── standalone.ts
│ │ │ └── treeAbstractions.ts
│ │ ├── action
│ │ │ ├── actions.ts
│ │ │ ├── APICall.tsx
│ │ │ ├── FileDownloadAction.tsx
│ │ │ ├── FileUploadAction.tsx
│ │ │ ├── NavigateAction.tsx
│ │ │ └── TimedAction.tsx
│ │ ├── ApiBoundComponent.tsx
│ │ ├── appContext
│ │ │ ├── date-functions.ts
│ │ │ ├── math-function.ts
│ │ │ └── misc-utils.ts
│ │ ├── AppContext.tsx
│ │ ├── behaviors
│ │ │ ├── Behavior.tsx
│ │ │ └── CoreBehaviors.tsx
│ │ ├── component-hooks.ts
│ │ ├── ComponentDecorator.tsx
│ │ ├── ComponentViewer.tsx
│ │ ├── CompoundComponent.tsx
│ │ ├── constants.ts
│ │ ├── DebugViewProvider.tsx
│ │ ├── descriptorHelper.ts
│ │ ├── devtools
│ │ │ ├── InspectorDialog.module.scss
│ │ │ ├── InspectorDialog.tsx
│ │ │ └── InspectorDialogVisibilityContext.tsx
│ │ ├── EngineError.ts
│ │ ├── event-handlers.ts
│ │ ├── InspectorButton.module.scss
│ │ ├── InspectorContext.tsx
│ │ ├── interception
│ │ │ ├── abstractions.ts
│ │ │ ├── ApiInterceptor.ts
│ │ │ ├── ApiInterceptorProvider.tsx
│ │ │ ├── apiInterceptorWorker.ts
│ │ │ ├── Backend.ts
│ │ │ ├── Errors.ts
│ │ │ ├── IndexedDb.ts
│ │ │ ├── initMock.ts
│ │ │ ├── InMemoryDb.ts
│ │ │ ├── ReadonlyCollection.ts
│ │ │ └── useApiInterceptorContext.tsx
│ │ ├── loader
│ │ │ ├── ApiLoader.tsx
│ │ │ ├── DataLoader.tsx
│ │ │ ├── ExternalDataLoader.tsx
│ │ │ ├── Loader.tsx
│ │ │ ├── MockLoaderRenderer.tsx
│ │ │ └── PageableLoader.tsx
│ │ ├── LoaderComponent.tsx
│ │ ├── markup-check.ts
│ │ ├── parts.ts
│ │ ├── renderers.ts
│ │ ├── rendering
│ │ │ ├── AppContent.tsx
│ │ │ ├── AppRoot.tsx
│ │ │ ├── AppWrapper.tsx
│ │ │ ├── buildProxy.ts
│ │ │ ├── collectFnVarDeps.ts
│ │ │ ├── ComponentAdapter.tsx
│ │ │ ├── ComponentWrapper.tsx
│ │ │ ├── Container.tsx
│ │ │ ├── containers.ts
│ │ │ ├── ContainerWrapper.tsx
│ │ │ ├── ErrorBoundary.module.scss
│ │ │ ├── ErrorBoundary.tsx
│ │ │ ├── InvalidComponent.module.scss
│ │ │ ├── InvalidComponent.tsx
│ │ │ ├── nodeUtils.ts
│ │ │ ├── reducer.ts
│ │ │ ├── renderChild.tsx
│ │ │ ├── StandaloneComponent.tsx
│ │ │ ├── StateContainer.tsx
│ │ │ ├── UnknownComponent.module.scss
│ │ │ ├── UnknownComponent.tsx
│ │ │ └── valueExtractor.ts
│ │ ├── reportEngineError.ts
│ │ ├── RestApiProxy.ts
│ │ ├── script-runner
│ │ │ ├── asyncProxy.ts
│ │ │ ├── AttributeValueParser.ts
│ │ │ ├── bannedFunctions.ts
│ │ │ ├── BindingTreeEvaluationContext.ts
│ │ │ ├── eval-tree-async.ts
│ │ │ ├── eval-tree-common.ts
│ │ │ ├── eval-tree-sync.ts
│ │ │ ├── ParameterParser.ts
│ │ │ ├── process-statement-async.ts
│ │ │ ├── process-statement-common.ts
│ │ │ ├── process-statement-sync.ts
│ │ │ ├── ScriptingSourceTree.ts
│ │ │ ├── simplify-expression.ts
│ │ │ ├── statement-queue.ts
│ │ │ └── visitors.ts
│ │ ├── StandaloneApp.tsx
│ │ ├── StandaloneExtensionManager.ts
│ │ ├── TableOfContentsContext.tsx
│ │ ├── theming
│ │ │ ├── _themes.scss
│ │ │ ├── component-layout-resolver.ts
│ │ │ ├── extendThemeUtils.ts
│ │ │ ├── hvar.ts
│ │ │ ├── layout-resolver.ts
│ │ │ ├── parse-layout-props.ts
│ │ │ ├── StyleContext.tsx
│ │ │ ├── StyleRegistry.ts
│ │ │ ├── ThemeContext.tsx
│ │ │ ├── ThemeProvider.tsx
│ │ │ ├── themes
│ │ │ │ ├── base-utils.ts
│ │ │ │ ├── palette.ts
│ │ │ │ ├── root.ts
│ │ │ │ ├── solid.ts
│ │ │ │ ├── theme-colors.ts
│ │ │ │ └── xmlui.ts
│ │ │ ├── themeVars.module.scss
│ │ │ ├── themeVars.ts
│ │ │ ├── transformThemeVars.ts
│ │ │ └── utils.ts
│ │ ├── utils
│ │ │ ├── actionUtils.ts
│ │ │ ├── audio-utils.ts
│ │ │ ├── base64-utils.ts
│ │ │ ├── compound-utils.ts
│ │ │ ├── css-utils.ts
│ │ │ ├── DataLoaderQueryKeyGenerator.ts
│ │ │ ├── date-utils.ts
│ │ │ ├── extractParam.ts
│ │ │ ├── hooks.tsx
│ │ │ ├── LruCache.ts
│ │ │ ├── mergeProps.ts
│ │ │ ├── misc.ts
│ │ │ ├── request-params.ts
│ │ │ ├── statementUtils.ts
│ │ │ └── treeUtils.ts
│ │ └── xmlui-parser.ts
│ ├── index-standalone.ts
│ ├── index.scss
│ ├── index.ts
│ ├── language-server
│ │ ├── server-common.ts
│ │ ├── server-web-worker.ts
│ │ ├── server.ts
│ │ ├── services
│ │ │ ├── common
│ │ │ │ ├── docs-generation.ts
│ │ │ │ ├── lsp-utils.ts
│ │ │ │ ├── metadata-utils.ts
│ │ │ │ └── syntax-node-utilities.ts
│ │ │ ├── completion.ts
│ │ │ ├── diagnostic.ts
│ │ │ ├── format.ts
│ │ │ └── hover.ts
│ │ └── xmlui-metadata-generated.js
│ ├── logging
│ │ ├── LoggerContext.tsx
│ │ ├── LoggerInitializer.tsx
│ │ ├── LoggerService.ts
│ │ └── xmlui.ts
│ ├── logo.svg
│ ├── parsers
│ │ ├── common
│ │ │ ├── GenericToken.ts
│ │ │ ├── InputStream.ts
│ │ │ └── utils.ts
│ │ ├── scripting
│ │ │ ├── code-behind-collect.ts
│ │ │ ├── Lexer.ts
│ │ │ ├── modules.ts
│ │ │ ├── Parser.ts
│ │ │ ├── ParserError.ts
│ │ │ ├── ScriptingNodeTypes.ts
│ │ │ ├── TokenTrait.ts
│ │ │ ├── TokenType.ts
│ │ │ └── tree-visitor.ts
│ │ ├── style-parser
│ │ │ ├── errors.ts
│ │ │ ├── source-tree.ts
│ │ │ ├── StyleInputStream.ts
│ │ │ ├── StyleLexer.ts
│ │ │ ├── StyleParser.ts
│ │ │ └── tokens.ts
│ │ └── xmlui-parser
│ │ ├── CharacterCodes.ts
│ │ ├── diagnostics.ts
│ │ ├── fileExtensions.ts
│ │ ├── index.ts
│ │ ├── lint.ts
│ │ ├── parser.ts
│ │ ├── ParserError.ts
│ │ ├── scanner.ts
│ │ ├── syntax-kind.ts
│ │ ├── syntax-node.ts
│ │ ├── transform.ts
│ │ ├── utils.ts
│ │ ├── xmlui-serializer.ts
│ │ └── xmlui-tree.ts
│ ├── react-app-env.d.ts
│ ├── syntax
│ │ ├── monaco
│ │ │ ├── grammar.monacoLanguage.ts
│ │ │ ├── index.ts
│ │ │ ├── xmlui-dark.ts
│ │ │ ├── xmlui-light.ts
│ │ │ └── xmluiscript.monacoLanguage.ts
│ │ └── textMate
│ │ ├── index.ts
│ │ ├── xmlui-dark.json
│ │ ├── xmlui-light.json
│ │ ├── xmlui.json
│ │ └── xmlui.tmLanguage.json
│ ├── testing
│ │ ├── assertions.ts
│ │ ├── component-test-helpers.ts
│ │ ├── ComponentDrivers.ts
│ │ ├── drivers
│ │ │ ├── DateInputDriver.ts
│ │ │ ├── index.ts
│ │ │ ├── ModalDialogDriver.ts
│ │ │ ├── NumberBoxDriver.ts
│ │ │ ├── TextBoxDriver.ts
│ │ │ ├── TimeInputDriver.ts
│ │ │ ├── TimerDriver.ts
│ │ │ └── TreeDriver.ts
│ │ ├── fixtures.ts
│ │ ├── index.ts
│ │ ├── infrastructure
│ │ │ ├── index.html
│ │ │ ├── main.tsx
│ │ │ ├── public
│ │ │ │ ├── mockServiceWorker.js
│ │ │ │ ├── resources
│ │ │ │ │ ├── bell.svg
│ │ │ │ │ ├── box.svg
│ │ │ │ │ ├── doc.svg
│ │ │ │ │ ├── eye.svg
│ │ │ │ │ ├── flower-640x480.jpg
│ │ │ │ │ ├── sun.svg
│ │ │ │ │ ├── test-image-100x100.jpg
│ │ │ │ │ └── txt.svg
│ │ │ │ └── serve.json
│ │ │ └── TestBed.tsx
│ │ └── themed-app-test-helpers.ts
│ └── vite-env.d.ts
├── tests
│ ├── components
│ │ ├── CodeBlock
│ │ │ └── hightlight-code.test.ts
│ │ ├── playground-pattern.test.ts
│ │ └── Tree
│ │ └── Tree-states.test.ts
│ ├── components-core
│ │ ├── abstractions
│ │ │ └── treeAbstractions.test.ts
│ │ ├── container
│ │ │ └── buildProxy.test.ts
│ │ ├── interception
│ │ │ ├── orderBy.test.ts
│ │ │ ├── ReadOnlyCollection.test.ts
│ │ │ └── request-param-converter.test.ts
│ │ ├── scripts-runner
│ │ │ ├── AttributeValueParser.test.ts
│ │ │ ├── eval-tree-arrow-async.test.ts
│ │ │ ├── eval-tree-arrow.test.ts
│ │ │ ├── eval-tree-func-decl-async.test.ts
│ │ │ ├── eval-tree-func-decl.test.ts
│ │ │ ├── eval-tree-pre-post.test.ts
│ │ │ ├── eval-tree-regression.test.ts
│ │ │ ├── eval-tree.test.ts
│ │ │ ├── function-proxy.test.ts
│ │ │ ├── parser-regression.test.ts
│ │ │ ├── process-event.test.ts
│ │ │ ├── process-function.test.ts
│ │ │ ├── process-implicit-context.test.ts
│ │ │ ├── process-statement-asgn.test.ts
│ │ │ ├── process-statement-destruct.test.ts
│ │ │ ├── process-statement-regs.test.ts
│ │ │ ├── process-statement-sync.test.ts
│ │ │ ├── process-statement.test.ts
│ │ │ ├── process-switch-sync.test.ts
│ │ │ ├── process-switch.test.ts
│ │ │ ├── process-try-sync.test.ts
│ │ │ ├── process-try.test.ts
│ │ │ └── test-helpers.ts
│ │ ├── test-metadata-handler.ts
│ │ ├── theming
│ │ │ ├── border-segments.test.ts
│ │ │ ├── component-layout.resolver.test.ts
│ │ │ ├── layout-property-parser.test.ts
│ │ │ ├── layout-resolver.test.ts
│ │ │ ├── layout-resolver2.test.ts
│ │ │ ├── layout-vp-override.test.ts
│ │ │ └── padding-segments.test.ts
│ │ └── utils
│ │ ├── date-utils.test.ts
│ │ ├── format-human-elapsed-time.test.ts
│ │ └── LruCache.test.ts
│ ├── language-server
│ │ ├── completion.test.ts
│ │ ├── format.test.ts
│ │ ├── hover.test.ts
│ │ └── mockData.ts
│ └── parsers
│ ├── common
│ │ └── input-stream.test.ts
│ ├── markdown
│ │ └── parse-binding-expression.test.ts
│ ├── parameter-parser.test.ts
│ ├── paremeter-parser.test.ts
│ ├── scripting
│ │ ├── eval-tree-arrow.test.ts
│ │ ├── eval-tree-pre-post.test.ts
│ │ ├── eval-tree.test.ts
│ │ ├── function-proxy.test.ts
│ │ ├── lexer-literals.test.ts
│ │ ├── lexer-misc.test.ts
│ │ ├── module-parse.test.ts
│ │ ├── parser-arrow.test.ts
│ │ ├── parser-assignments.test.ts
│ │ ├── parser-binary.test.ts
│ │ ├── parser-destructuring.test.ts
│ │ ├── parser-errors.test.ts
│ │ ├── parser-expressions.test.ts
│ │ ├── parser-function.test.ts
│ │ ├── parser-literals.test.ts
│ │ ├── parser-primary.test.ts
│ │ ├── parser-regex.test.ts
│ │ ├── parser-statements.test.ts
│ │ ├── parser-unary.test.ts
│ │ ├── process-event.test.ts
│ │ ├── process-implicit-context.test.ts
│ │ ├── process-statement-asgn.test.ts
│ │ ├── process-statement-destruct.test.ts
│ │ ├── process-statement-regs.test.ts
│ │ ├── process-statement-sync.test.ts
│ │ ├── process-statement.test.ts
│ │ ├── process-switch-sync.test.ts
│ │ ├── process-switch.test.ts
│ │ ├── process-try-sync.test.ts
│ │ ├── process-try.test.ts
│ │ ├── simplify-expression.test.ts
│ │ ├── statement-hooks.test.ts
│ │ └── test-helpers.ts
│ ├── style-parser
│ │ ├── generateHvarChain.test.ts
│ │ ├── parseHVar.test.ts
│ │ ├── parser.test.ts
│ │ └── tokens.test.ts
│ └── xmlui
│ ├── lint.test.ts
│ ├── parser.test.ts
│ ├── scanner.test.ts
│ ├── transform.attr.test.ts
│ ├── transform.circular.test.ts
│ ├── transform.element.test.ts
│ ├── transform.errors.test.ts
│ ├── transform.escape.test.ts
│ ├── transform.regression.test.ts
│ ├── transform.script.test.ts
│ ├── transform.test.ts
│ └── xmlui.ts
├── tests-e2e
│ ├── api-bound-component-regression.spec.ts
│ ├── api-call-as-extracted-component.spec.ts
│ ├── assign-to-object-or-array-regression.spec.ts
│ ├── binding-regression.spec.ts
│ ├── children-as-template-context-vars.spec.ts
│ ├── compound-component.spec.ts
│ ├── context-vars-regression.spec.ts
│ ├── data-bindings.spec.ts
│ ├── datasource-and-api-usage-in-var.spec.ts
│ ├── datasource-direct-binding.spec.ts
│ ├── datasource-onLoaded-regression.spec.ts
│ ├── modify-array-item-regression.spec.ts
│ ├── namespaces.spec.ts
│ ├── push-to-array-regression.spec.ts
│ ├── screen-breakpoints.spec.ts
│ ├── scripting.spec.ts
│ ├── state-scope-in-pages.spec.ts
│ └── state-var-scopes.spec.ts
├── tsconfig.bin.json
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── vitest.config.ts
```
# Files
--------------------------------------------------------------------------------
/xmlui/src/components/DropdownMenu/DropdownMenu.tsx:
--------------------------------------------------------------------------------
```typescript
import styles from "./DropdownMenu.module.scss";
import { createComponentRenderer } from "../../components-core/renderers";
import { parseScssVar } from "../../components-core/theming/themeVars";
import { alignmentOptionMd, buttonThemeMd, buttonVariantMd, iconPositionMd } from "../abstractions";
import { createMetadata, d, dClick, dEnabled, dLabel, dTriggerTemplate } from "../metadata-helpers";
import { Icon } from "../Icon/IconNative";
import {
defaultDropdownMenuProps,
defaultMenuItemProps,
DropdownMenu,
MenuItem,
MenuSeparator,
SubMenuItem,
} from "./DropdownMenuNative";
const DDMCOMP = "DropdownMenu";
export const DropdownMenuMd = createMetadata({
status: "stable",
description:
"`DropdownMenu` provides a space-efficient way to present multiple options or " +
"actions through a collapsible interface. When clicked, the trigger button reveals " +
"a menu that can include items, separators, and nested submenus, making it ideal " +
"for navigation, action lists, or any situation requiring many options without " +
"permanent screen space.",
props: {
label: dLabel(),
triggerTemplate: dTriggerTemplate(DDMCOMP),
alignment: {
description:
"This property allows you to determine the alignment of the dropdown panel with " +
"the displayed menu items.",
valueType: "string",
availableValues: alignmentOptionMd,
defaultValue: defaultDropdownMenuProps.alignment,
},
enabled: dEnabled(),
triggerButtonVariant: {
description:
`This property defines the theme variant of the \`Button\` as the dropdown menu's trigger. ` +
`It has no effect when a custom trigger is defined with \`triggerTemplate\`.`,
valueType: "string",
availableValues: buttonVariantMd,
defaultValue: defaultDropdownMenuProps.triggerButtonVariant,
},
triggerButtonThemeColor: {
description:
`This property defines the theme color of the \`Button\` as the dropdown menu's trigger. ` +
`It has no effect when a custom trigger is defined with \`triggerTemplate\`.`,
valueType: "string",
availableValues: buttonThemeMd,
defaultValue: defaultDropdownMenuProps.triggerButtonThemeColor,
},
triggerButtonIcon: {
description:
`This property defines the icon to display on the trigger button. You can change the default icon ` +
`for all ${DDMCOMP} instances with the "icon.triggerButton:DropdownMenu" declaration in the app ` +
`configuration file.`,
defaultValue: defaultDropdownMenuProps.triggerButtonIcon,
valueType: "string",
},
triggerButtonIconPosition: {
description: `This property defines the position of the icon on the trigger button.`,
defaultValue: defaultDropdownMenuProps.triggerButtonIconPosition,
valueType: "string",
availableValues: iconPositionMd,
},
},
events: {
willOpen: d(
`This event fires when the \`${DDMCOMP}\` component is about to be opened. ` +
`You can prevent opening the menu by returning \`false\` from the event handler. ` +
`Otherwise, the menu will open at the end of the event handler like normal.`,
),
},
apis: {
close: {
description: `This method command closes the dropdown.`,
signature: "close(): void",
},
open: {
description: `This method command opens the dropdown.`,
signature: "open(): void",
},
},
themeVars: parseScssVar(styles.themeVars),
limitThemeVarsToComponent: true,
defaultThemeVars: {
[`backgroundColor-${DDMCOMP}`]: "$color-surface-raised",
[`minWidth-${DDMCOMP}`]: "160px",
[`boxShadow-${DDMCOMP}`]: "$boxShadow-xl",
[`borderStyle-${DDMCOMP}-content`]: "solid",
[`borderRadius-${DDMCOMP}`]: "$borderRadius",
},
});
export const dropdownMenuComponentRenderer = createComponentRenderer(
DDMCOMP,
DropdownMenuMd,
({ node, extractValue, renderChild, registerComponentApi, className, lookupEventHandler }) => {
return (
<DropdownMenu
triggerTemplate={renderChild(node.props?.triggerTemplate)}
label={extractValue(node.props?.label)}
registerComponentApi={registerComponentApi}
onWillOpen={lookupEventHandler("willOpen")}
className={className}
alignment={extractValue(node.props?.alignment)}
disabled={!extractValue.asOptionalBoolean(node.props.enabled, true)}
triggerButtonThemeColor={extractValue(node.props.triggerButtonThemeColor)}
triggerButtonVariant={extractValue(node.props.triggerButtonVariant)}
triggerButtonIcon={extractValue(node.props.triggerButtonIcon)}
triggerButtonIconPosition={extractValue(node.props.triggerButtonIconPosition)}
>
{renderChild(node.children)}
</DropdownMenu>
);
},
);
const MICOMP = "MenuItem";
export const MenuItemMd = createMetadata({
status: "stable",
description:
"`MenuItem` represents individual clickable items within dropdown menus and other " +
"menu components. Each menu item can display text, icons, and respond to clicks " +
"with either navigation or custom actions, making it the building block for " +
"interactive menu systems.",
docFolder: DDMCOMP,
props: {
iconPosition: {
description: `This property allows you to determine the position of the icon displayed in the menu item.`,
valueType: "string",
availableValues: iconPositionMd,
defaultValue: defaultMenuItemProps.iconPosition,
},
icon: {
description: `This property names an optional icon to display with the menu item. You can use component-specific icons in the format "iconName:MenuItem".`,
valueType: "string",
},
label: dLabel(),
to: {
description:
`This property defines the URL of the menu item. If this property is defined (and the \`click\` ` +
`event does not have an event handler), clicking the menu item navigates to this link.`,
valueType: "string",
},
active: {
description: `This property indicates if the specified menu item is active.`,
valueType: "boolean",
defaultValue: defaultMenuItemProps.active,
},
enabled: dEnabled(),
},
events: {
click: dClick(MICOMP),
},
themeVars: parseScssVar(styles.themeVars),
limitThemeVarsToComponent: true,
defaultThemeVars: {
[`backgroundColor-${MICOMP}`]: "$backgroundColor-dropdown-item",
[`color-${MICOMP}`]: "$textColor-primary",
[`color-${MICOMP}--disabled`]: "$textColor--disabled",
[`fontFamily-${MICOMP}`]: "$fontFamily",
[`fontSize-${MICOMP}`]: "$fontSize-sm",
[`paddingVertical-${MICOMP}`]: "$space-2",
[`paddingHorizontal-${MICOMP}`]: "$space-3",
[`backgroundColor-${MICOMP}--hover`]: "$backgroundColor-dropdown-item--hover",
[`color-${MICOMP}--hover`]: "inherit",
[`gap-${MICOMP}`]: "$space-2",
[`color-${MICOMP}--active`]: "$color-primary",
[`backgroundColor-${MICOMP}--active`]: "$backgroundColor-dropdown-item--active",
light: {},
dark: {},
},
});
export const menuItemRenderer = createComponentRenderer(
MICOMP,
MenuItemMd,
({ node, renderChild, lookupEventHandler, lookupAction, extractValue, className }) => {
const clickEventHandler = lookupEventHandler("click");
let clickHandler;
const to = extractValue(node.props.to);
if (!clickEventHandler && to?.trim()) {
const navigateAction = lookupAction("navigate", { signError: false });
clickHandler = () => {
navigateAction?.({ pathname: to });
};
}
return (
<MenuItem
onClick={clickHandler}
label={extractValue(node.props?.label)}
className={className}
iconPosition={extractValue(node.props.iconPosition)}
icon={
node.props?.icon && (
<Icon name={extractValue(node.props.icon)} fallback={extractValue(node.props.icon)} />
)
}
active={extractValue.asOptionalBoolean(node.props.active, false)}
enabled={extractValue.asOptionalBoolean(node.props.enabled, true)}
>
{renderChild(node.children)}
</MenuItem>
);
},
);
const SMCOMP = "SubMenuItem";
export const SubMenuItemMd = createMetadata({
status: "stable",
description:
"`SubMenuItem` creates hierarchical menu structures by acting as both a menu " +
"item and a container for nested menu items. When clicked or hovered, it reveals " +
"a submenu containing additional [MenuItem](/components/MenuItem), " +
"[MenuSeparator](/components/MenuSeparator), or other " +
"[SubMenuItem](/components/SubMenuItems) components, enabling complex multi-level " +
"navigation and action organization.",
docFolder: DDMCOMP,
props: {
label: dLabel(),
triggerTemplate: dTriggerTemplate(SMCOMP),
},
});
export const subMenuItemRenderer = createComponentRenderer(
SMCOMP,
SubMenuItemMd,
({ node, renderChild, extractValue }) => {
return (
<SubMenuItem
label={extractValue(node.props?.label)}
triggerTemplate={renderChild(node.props?.triggerTemplate)}
>
{renderChild(node.children)}
</SubMenuItem>
);
},
);
const MSEP = "MenuSeparator";
export const MenuSeparatorMd = createMetadata({
status: "stable",
description:
"`MenuSeparator` displays a separator line between menu items to group related " +
"menu options within `DropdownMenu`.",
docFolder: DDMCOMP,
themeVars: parseScssVar(styles.themeVars),
limitThemeVarsToComponent: true,
defaultThemeVars: {
[`marginTop-${MSEP}`]: "$space-1",
[`marginBottom-${MSEP}`]: "$space-1",
[`width-${MSEP}`]: "100%",
[`height-${MSEP}`]: "1px",
[`color-${MSEP}`]: "$borderColor-dropdown-item",
[`marginHorizontal-${MSEP}`]: "12px",
},
});
export const menuSeparatorRenderer = createComponentRenderer(MSEP, MenuSeparatorMd, () => {
return <MenuSeparator />;
});
```
--------------------------------------------------------------------------------
/xmlui/src/components/Charts/LineChart/LineChartNative.tsx:
--------------------------------------------------------------------------------
```typescript
import {
Line,
LineChart as RLineChart,
XAxis,
ResponsiveContainer,
Tooltip,
Legend as RLegend,
YAxis,
} from "recharts";
import type { ForwardedRef, ReactNode } from "react";
import type React from "react";
import { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from "react";
import ChartProvider, { useChartContextValue } from "../utils/ChartProvider";
import { TooltipContent } from "../Tooltip/TooltipContent";
import { useTheme } from "../../../components-core/theming/ThemeContext";
import classnames from "classnames";
import styles from "./LineChart.module.scss";
export type LineChartProps = {
data: any[];
dataKeys: string[];
nameKey: string;
style?: React.CSSProperties;
hideTickX?: boolean;
hideTickY?: boolean;
className?: string;
hideX?: boolean;
hideY?: boolean;
hideTooltip?: boolean;
tickFormatterX?: (value: any) => any;
tickFormatterY?: (value: any) => any;
children?: ReactNode;
showLegend?: boolean;
marginTop?: number;
marginRight?: number;
marginBottom?: number;
marginLeft?: number;
tooltipRenderer?: (tooltipData: any) => ReactNode;
};
export const defaultProps: Pick<
LineChartProps,
| "hideX"
| "hideY"
| "hideTooltip"
| "showLegend"
| "tickFormatterX"
| "tickFormatterY"
| "hideTickX"
| "hideTickY"
> = {
hideTickX: false,
hideTickY: false,
hideX: false,
hideY: false,
hideTooltip: false,
showLegend: false,
tickFormatterX: (value) => value,
tickFormatterY: (value) => value,
};
const defaultChartParams = {
chartWidth: 800,
};
export const LineChart = forwardRef(function LineChart(
{
data,
dataKeys = [],
nameKey,
style,
className,
hideX = defaultProps.hideX,
hideY = defaultProps.hideY,
hideTickX = defaultProps.hideTickX,
hideTickY = defaultProps.hideTickY,
hideTooltip = defaultProps.hideTooltip,
tickFormatterX = defaultProps.tickFormatterX,
tickFormatterY = defaultProps.tickFormatterY,
children,
showLegend = defaultProps.showLegend,
tooltipRenderer,
}: LineChartProps,
forwardedRef: ForwardedRef<HTMLDivElement>,
) {
const { getThemeVar } = useTheme();
const colorValues = useMemo(() => {
return [
getThemeVar("color-primary-500"),
getThemeVar("color-primary-300"),
getThemeVar("color-success-500"),
getThemeVar("color-success-300"),
getThemeVar("color-warn-500"),
getThemeVar("color-warn-300"),
getThemeVar("color-danger-500"),
getThemeVar("color-danger-300"),
getThemeVar("color-info-500"),
getThemeVar("color-info-300"),
getThemeVar("color-secondary-500"),
getThemeVar("color-secondary-300"),
getThemeVar("color-primary-600"),
getThemeVar("color-primary-400"),
getThemeVar("color-success-600"),
getThemeVar("color-success-400"),
getThemeVar("color-warn-600"),
getThemeVar("color-warn-400"),
getThemeVar("color-danger-600"),
getThemeVar("color-danger-400"),
getThemeVar("color-info-600"),
getThemeVar("color-info-400"),
getThemeVar("color-secondary-600"),
getThemeVar("color-secondary-400"),
getThemeVar("color-primary-900"),
getThemeVar("color-primary-700"),
getThemeVar("color-success-900"),
getThemeVar("color-success-700"),
getThemeVar("color-warn-900"),
getThemeVar("color-warn-700"),
getThemeVar("color-danger-900"),
getThemeVar("color-danger-700"),
getThemeVar("color-info-900"),
getThemeVar("color-info-700"),
getThemeVar("color-secondary-900"),
getThemeVar("color-secondary-700"),
];
}, [getThemeVar]);
const chartContextValue = useChartContextValue({ nameKey, dataKeys });
const containerRef = useRef<HTMLDivElement>(null);
const labelsRef = useRef<HTMLDivElement>(null);
const [interval, setIntervalState] = useState(0);
const [tickAngle, setTickAngle] = useState(0);
const [tickAnchor, setTickAnchor] = useState<"end" | "middle">("middle");
const [chartMargin, setChartMargin] = useState({ left: 30, right: 30, top: 10, bottom: 60 });
const [xAxisHeight, setXAxisHeight] = useState(50);
const [miniMode, setMiniMode] = useState(false);
const fontSize = 12;
const safeData = Array.isArray(data) ? data : [];
const safeTooltipRenderer = useCallback(
(props: any) => {
if (!tooltipRenderer) return <TooltipContent {...props} />;
const payloadArray: Array<{ label: string; value: any; color: string }> = [];
if (props.payload && props.payload.length > 0 && props.payload[0].payload) {
const originalPayload = props.payload[0].payload;
// Transform dataKeys into array of objects with label, value, and color
dataKeys.forEach((dataKey, index) => {
if (dataKey in originalPayload) {
payloadArray.push({
label: dataKey,
value: originalPayload[dataKey],
color: colorValues[index] || colorValues[0],
});
}
});
}
// Extract tooltip data from Recharts props
const tooltipData = {
label: props.label,
payload: payloadArray,
active: props.active,
};
return tooltipRenderer(tooltipData);
},
[tooltipRenderer, dataKeys, colorValues],
);
useEffect(() => {
const calc = () => {
const width = containerRef.current?.offsetWidth || defaultChartParams.chartWidth;
const spans = labelsRef.current?.querySelectorAll("span") || [];
const maxWidth = Array.from(spans).reduce((mx, s) => Math.max(mx, s.offsetWidth), 50);
let angle = 0;
let anchor: "end" | "middle" = "middle";
let rad = 0;
let minTickSpacing = maxWidth + 8;
let leftMargin = Math.max(8, Math.ceil(maxWidth / 3));
let rightMargin = Math.max(8, Math.ceil(maxWidth / 3));
let xAxisH = Math.ceil(fontSize * 1.2);
let maxTicks = Math.max(1, Math.floor(width / minTickSpacing));
let skip = Math.max(0, Math.ceil(safeData.length / maxTicks) - 1);
if (skip > 0) {
angle = -60;
anchor = "end";
rad = (Math.abs(angle) * Math.PI) / 180;
minTickSpacing = Math.ceil(maxWidth * Math.cos(rad)) + 2;
maxTicks = Math.max(1, Math.floor(width / minTickSpacing));
skip = Math.max(0, Math.ceil(safeData.length / maxTicks) - 1);
leftMargin = Math.max(8, Math.ceil((maxWidth * Math.cos(rad)) / 1.8));
rightMargin = Math.max(8, Math.ceil((maxWidth * Math.cos(rad)) / 1.8));
xAxisH = Math.ceil(Math.abs(maxWidth * Math.sin(rad)) + Math.abs(fontSize * Math.cos(rad)));
}
setIntervalState(skip);
setTickAngle(angle);
setTickAnchor(anchor);
setChartMargin({ left: leftMargin, right: rightMargin, top: 10, bottom: xAxisH });
setXAxisHeight(Math.ceil(fontSize));
const containerHeight = containerRef.current?.offsetHeight || 0;
const neededHeight = 10 + xAxisHeight + 10 + 32;
setMiniMode(neededHeight > containerHeight);
};
calc();
window.addEventListener("resize", calc);
return () => window.removeEventListener("resize", calc);
}, [data, nameKey, xAxisHeight, safeData.length, fontSize]);
// The stroke width of the lines
const strokeWidth = getThemeVar("width-line-LineChart");
return (
<ChartProvider value={chartContextValue}>
{children}
<div
ref={labelsRef}
style={{ position: "absolute", visibility: "hidden", height: 0, overflow: "hidden" }}
>
{safeData.length > 0 && nameKey
? safeData
.map((d) => d?.[nameKey])
.map((label, idx) => (
<span key={idx} style={{ fontSize: 12, whiteSpace: "nowrap" }}>
{label}
</span>
))
: null}
</div>
<div
ref={forwardedRef}
className={classnames(className, styles.wrapper)}
style={{ flexGrow: 1, ...style }}
>
<ResponsiveContainer
ref={containerRef}
width="100%"
height="100%"
minWidth={60}
minHeight={30}
debounce={100}
>
<RLineChart
accessibilityLayer
data={data}
margin={miniMode ? { left: 0, right: 0, top: 0, bottom: 0 } : chartMargin}
>
<XAxis
interval={interval}
tickLine={false}
dataKey={nameKey}
angle={tickAngle}
textAnchor={tickAnchor}
tick={miniMode ? false : !hideTickX && { fill: "currentColor", fontSize }}
tickFormatter={miniMode ? undefined : tickFormatterX}
height={miniMode || hideX ? 0 : xAxisHeight}
hide={miniMode || hideX}
/>
<YAxis
hide={miniMode || hideY}
tickLine={false}
tickFormatter={miniMode ? undefined : tickFormatterY}
tick={miniMode ? false : !hideTickY && { fill: "currentColor", fontSize }}
domain={[(dataMin: number) => dataMin * 0.95, (dataMax: number) => dataMax * 1.05]}
/>
{!miniMode && !hideTooltip && <Tooltip content={safeTooltipRenderer} />}
{dataKeys.map((dataKey, i) => (
<Line
key={dataKey}
type="monotone"
dataKey={dataKey}
name={dataKey}
stroke={colorValues[i]}
strokeWidth={strokeWidth}
dot={false}
/>
))}
{showLegend && (
<RLegend
wrapperStyle={{
bottom: 0,
left: 0,
right: 0,
margin: "0 auto",
width: "100%",
textAlign: "center",
}}
/>
)}
</RLineChart>
</ResponsiveContainer>
</div>
</ChartProvider>
);
});
```
--------------------------------------------------------------------------------
/xmlui/src/components-core/InspectorContext.tsx:
--------------------------------------------------------------------------------
```typescript
import {
createContext,
type ReactNode,
useCallback,
useContext,
useEffect,
useId,
useMemo,
useRef,
useState,
} from "react";
import type { ComponentDef } from "../abstractions/ComponentDefs";
import { usePopper } from "react-popper";
import { createPortal } from "react-dom";
import { useTheme } from "./theming/ThemeContext";
import classnames from "classnames";
import { Button } from "../components/Button/ButtonNative";
import styles from "./InspectorButton.module.scss";
import type { ProjectCompilation } from "../abstractions/scripting/Compilation";
import { InspectorDialog } from "./devtools/InspectorDialog";
import AppWithCodeViewNative from "../components/NestedApp/AppWithCodeViewNative";
import { XmlUiHelper } from "../parsers/xmlui-parser";
import { useAppContext } from "./AppContext";
// --- The context object that is used to store the inspector information.
interface IInspectorContext {
// --- The list of source files for the components.
sources?: Record<string, string>;
attach: (node: ComponentDef, uid: symbol, inspectId: string) => void;
detach: (uid: symbol, inspectId: string) => void;
refresh: (inspectId: string) => void;
devToolsEnabled?: boolean;
setIsOpen: (isOpen: boolean) => void;
isOpen: boolean;
inspectedNode: any;
projectCompilation: ProjectCompilation | undefined;
setInspectMode: (inspectMode: (prev: any) => boolean) => void;
inspectMode: boolean;
mockApi: any;
clickPosition: { x: number; y: number };
}
// --- The context object that is used to store the inspector information.
export const InspectorContext = createContext<IInspectorContext | null>(null);
export function InspectorProvider({
children,
sources,
projectCompilation,
mockApi,
}: {
children: ReactNode;
sources?: Record<string, string>;
projectCompilation?: ProjectCompilation;
mockApi?: any;
}) {
const [inspectable, setInspectable] = useState<Record<string, any>>({});
const [inspectedNode, setInspectedNode] = useState<ComponentDef | null>(null);
const [showCode, setShowCode] = useState(false);
const [inspectMode, setInspectMode] = useState(false);
const [clickPosition, setClickPosition] = useState<{ x: number; y: number }>({
x: 0,
y: 0,
});
const contextValue: IInspectorContext = useMemo(() => {
return {
sources,
attach: (node, uid, inspectId) => {
setInspectable((prev) => {
return {
...prev,
[inspectId]: {
node,
uid,
inspectId,
key: 0,
},
};
});
},
refresh: (inspectId) => {
setInspectable((prev) => {
return {
...prev,
[inspectId]: {
...prev[inspectId],
key: prev[inspectId].key + 1,
},
};
});
},
detach: (uid, inspectId) => {
setInspectable((prev) => {
const ret = { ...prev };
delete ret[inspectId];
return ret;
});
},
inspectedNode,
setIsOpen: setShowCode,
isOpen: showCode,
devToolsEnabled: showCode,
projectCompilation: projectCompilation,
setInspectMode,
inspectMode,
mockApi,
clickPosition,
};
}, [
sources,
inspectedNode,
showCode,
clickPosition,
setShowCode,
projectCompilation,
inspectMode,
mockApi,
]);
return (
<InspectorContext.Provider value={contextValue}>
{children}
{process.env.VITE_USER_COMPONENTS_Inspect !== "false" &&
inspectable &&
Object.values(inspectable).map((item: any) => {
return (
<InspectButton
inspectedNode={inspectedNode}
setShowCode={setShowCode}
setClickPosition={setClickPosition}
key={item.inspectId + +"-" + item.key}
inspectId={item.inspectId}
node={item.node}
setInspectedNode={setInspectedNode}
inspectMode={inspectMode}
/>
);
})}
</InspectorContext.Provider>
);
}
function InspectButton({
inspectId,
node,
inspectedNode,
setInspectedNode,
setShowCode,
inspectMode,
setClickPosition,
}: {
inspectId: string;
node: ComponentDef;
inspectedNode: any;
setInspectedNode: (node: any) => void;
setShowCode: (show: any) => void;
inspectMode: boolean;
setClickPosition?: (position: { x: number; y: number }) => void;
}) {
const { root } = useTheme();
const [referenceElement, setReferenceElement] = useState<HTMLElement | null>(null);
const [popperElement, setPopperElement] = useState<HTMLButtonElement | null>(null);
const { styles: popperStyles, attributes } = usePopper(referenceElement, popperElement, {
placement: "top-end",
modifiers: [
{
name: "offset",
options: {
offset: [-4, -18],
},
},
{
name: "flip",
enabled: false,
// options: {
// fallbackPlacements: ['top', 'right'],
// },
},
],
});
const [visible, setVisible] = useState(false);
const timeoutRef = useRef<number | null>(null);
const hoverRef = useRef<boolean>(false);
useEffect(() => {
if (!referenceElement) {
return;
}
if (inspectedNode?.inspectId === inspectId) {
referenceElement.classList.add(styles.inspectedNode);
} else {
referenceElement.classList.remove(styles.inspectedNode);
}
}, [inspectId, inspectedNode, referenceElement]);
useEffect(() => {
if (inspectedNode) {
setShowCode(true);
} else {
setShowCode(false);
}
}, [inspectedNode]);
useEffect(() => {
const htmlElement = document.querySelector(`[data-inspectId="${inspectId}"]`) as HTMLElement;
if (!htmlElement) {
return;
}
setReferenceElement(htmlElement);
if (inspectMode) {
htmlElement.classList.add(styles.inspectableNode);
const overlay = document.createElement("div");
overlay.classList.add(styles.inspectOverlay);
htmlElement.appendChild(overlay);
overlay.addEventListener("click", () => {
setInspectedNode((prev) => {
if (prev?.inspectId === inspectId) {
return null;
}
return { ...node, inspectId };
});
});
}
if (!inspectMode) {
htmlElement.classList.remove(styles.inspectableNode);
setInspectedNode(null);
setShowCode(false);
const overlay = htmlElement.querySelector(`.${styles.inspectOverlay}`);
if (overlay) {
overlay.remove();
}
htmlElement.classList.remove(styles.inspectedNode);
}
function mouseenter() {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
setVisible(true);
}
function mouseleave() {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
if (hoverRef.current) {
return;
}
timeoutRef.current = window.setTimeout(() => {
setVisible(false);
}, 100);
}
htmlElement.addEventListener("mouseenter", mouseenter);
htmlElement.addEventListener("mouseleave", mouseleave);
return () => {
htmlElement.removeEventListener("mouseenter", mouseenter);
htmlElement.removeEventListener("mouseleave", mouseleave);
};
}, [inspectId, node, inspectMode, setShowCode, setInspectedNode]);
return (
<>
{inspectMode
? null
: visible &&
!!root &&
createPortal(
<Button
variant={"outlined"}
className={classnames(styles.wrapper, "_debug-inspect-button")}
ref={(el) => setPopperElement(el)}
style={{ ...popperStyles.popper, padding: 0 }}
{...attributes.popper}
onMouseEnter={() => {
hoverRef.current = true;
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
timeoutRef.current = null;
}
}}
onMouseLeave={() => {
hoverRef.current = false;
setVisible(false);
}}
onClick={() => {
setInspectedNode(node);
setShowCode(true);
setClickPosition({
x: popperElement?.getBoundingClientRect().left || 0,
y: popperElement?.getBoundingClientRect().top || 0,
});
}}
>
Show code
</Button>,
root,
)}
</>
);
}
export function useDevTools() {
const context = useContext(InspectorContext);
if (!context) {
throw new Error("useDevTools must be used within an InspectorProvider");
}
return {
projectCompilation: context.projectCompilation,
inspectedNode: context.inspectedNode,
sources: context.sources,
isOpen: context.isOpen,
setIsOpen: context.setIsOpen,
devToolsEnabled: context.devToolsEnabled,
mockApi: context.mockApi,
clickPosition: context.clickPosition,
};
}
export function useInspectMode() {
const context = useContext(InspectorContext);
return {
setInspectMode: context?.setInspectMode,
inspectMode: context?.inspectMode,
};
}
export function useInspector(node: ComponentDef, uid: symbol) {
const context = useContext(InspectorContext);
const inspectValue = (node.props as any)?.inspect;
const shouldInspect = inspectValue === true || inspectValue === "true";
const inspectId = useId();
const refreshInspection = useCallback(() => {
context?.refresh(inspectId);
}, [context, inspectId]);
useEffect(() => {
if (shouldInspect) {
context?.attach(node, uid, inspectId);
}
return () => {
context?.detach(uid, inspectId);
};
}, [context, inspectId, node, shouldInspect, uid]);
if (shouldInspect && context) {
return {
refreshInspection,
inspectId,
};
}
return {};
}
```
--------------------------------------------------------------------------------
/docs/content/components/DataSource.md:
--------------------------------------------------------------------------------
```markdown
# DataSource [#datasource]
`DataSource` fetches and caches data from API endpoints, versus [`APICall`](/components/APICall) which creates, updates or deletes data.
**Key characteristics:**
- **Conditional loading**: Use `when` property to prevent fetching until dependent data is ready
- **Built-in caching**: Prevents unnecessary requests and provides instant data access
- **Polling support**: Automatically refetch data at specified intervals
- **Data transformation**: Process and filter responses before components use the data
## Preventing the `DataSource` from Executing [#preventing-the-datasource-from-executing]
Prevent the `DataSource` from executing until the specified condition in the `when` attribute is true.
```xmlui
<DataSource
id="userProfile"
url="/api/users/{selectedUserId}/profile"
when="{selectedUserId}" />
```
## Structural Sharing [#structural-sharing]
`DataSource` uses a technique called "structural sharing" to ensure that as many data references as possible will be kept intact and not cause extra UI refresh. If data is fetched from an API endpoint, you'll usually get a completely new reference by json parsing the response. However, `DataSource` will keep the original reference if *nothing* has changed in the data. If a subset has changed, `DataSource` will keep the unchanged parts and only replace the changed parts.
When you initiate the refetching of data (e.g., with the `refetch` method or setting the `pollIntervalInSeconds` property) and you retrieve data structurally equal with the cached data instance, `DataSource` will not fire the `loaded` event.
By default, structural sharing is turned on. If you do not need this behavior, set the `structuralSharing` property to `false`.
## Properties [#properties]
### `body` [#body]
Set the optional request body. The object you pass is serialized as a JSON string.
### `completedNotificationMessage` [#completednotificationmessage]
Set the message to display when the data fetch completes.If the property value is not set, no completion message is displayed.
This property customizes the success message displayed in a toast after the finished API invocation. The `$result` context variable can refer to the response body. For example, you can use the following code snippet to display the first 100 characters in the completed operation's response body:
```xmlui copy
<DataSource
id="ds"
url="/api/shopping-list"
completedNotificationMessage="Result: {JSON.stringify($result).substring(0, 100)}" />
```
### `errorNotificationMessage` [#errornotificationmessage]
Set the message to display when the there is an error. You can use the `$error` context value in an expression to refer to the original error message.
This property customizes the message displayed in a toast when the API invocation results in an error. The `$error.statusCode` context variable can refer to the response's status code, while `$error. details` to the response body. For example, you can use the following code snippet to display the status code and the details:
```xmlui copy
<DataSource
id="ds"
method="post"
url="/api/shopping-list"
errorNotificationMessage="${error.statusCode}, {JSON.stringify($error.details)}" />
```
### `headers` [#headers]
Set request headers. Pass an object whose keys are header names and values are header values.
### `id` (required) [#id-required]
Set the ID used by other components to access the retrieved data in the `value`property of a `DataSource`, or status info in the `loaded` and `error` properties.When no `id` is set, the component cannot be used programmatically.
### `inProgressNotificationMessage` [#inprogressnotificationmessage]
Set the message to display when the data fetch is in progress. If the property value is not set, no progress message is displayed.
### `method` (default: "get") [#method-default-get]
Set the HTTP method.
Available values: `get` **(default)**, `post`, `put`, `delete`, `patch`, `head`, `options`, `trace`, `connect`
### `nextPageSelector` [#nextpageselector]
When using `DataSource` with paging, the response may contain information about the previous and next page. This property defines the selector that extracts the next page information from the response deserialized to an object.
### `pollIntervalInSeconds` [#pollintervalinseconds]
Set the interval for periodic data fetching. If the data changes on refresh, XMLUI will re-render components that refer directly or indirectly to the `DataSource`. If not set or set to zero, the component does not poll for data.
### `prevPageSelector` [#prevpageselector]
When using `DataSource` with paging, the response may contain information about the previous and next page. This property defines the selector that extracts the previous page information from the response deserialized to an object.
### `queryParams` [#queryparams]
Append optional key-value pairs to the URL.
### `rawBody` [#rawbody]
Set the request body with no serialization. Use it to send a payload that has already been serialized to a JSON string.
### `resultSelector` [#resultselector]
Set an optional object key to extract a subset of the response data. If this value is not set, the entire response body is considered the result.
The selector can be a simple dot notation path (e.g., `value.results`) or a JavaScript expression that processes the data (e.g., `results.filter(item => item.type === 'active')`). The selector has access to standard JavaScript functions like `map` and `filter`, and operates on the full response body.
Here is a sample response from the HubSpot API.
```json
{
"results": [
{
"id": "88903258744",
"properties": {
"company": "HubSpot",
"createdate": "2025-01-03T23:38:47.449Z",
"custom_notes": "Nice guy!",
"email": "[email protected]",
"firstname": "Brian",
"hs_object_id": "88903258744",
"lastmodifieddate": "2025-02-18T23:13:34.759Z",
"lastname": "Halligan (Sample Contact)"
},
"createdAt": "2025-01-03T23:38:47.449Z",
"updatedAt": "2025-02-18T23:13:34.759Z",
"archived": false
},
{
"id": "88918034480",
"properties": {
"company": "HubSpot",
"createdate": "2025-01-03T23:38:47.008Z",
"custom_notes": null,
"email": "[email protected]",
"firstname": "Maria",
"hs_object_id": "88918034480",
"lastmodifieddate": "2025-01-03T23:38:59.001Z",
"lastname": "Johnson (Sample Contact)"
},
"createdAt": "2025-01-03T23:38:47.008Z",
"updatedAt": "2025-01-03T23:38:59.001Z",
"archived": false
}
]
}
```
This `resultSelector` builds an array of the `properties` objects.
```xmlui copy
<DataSource
id="contacts"
url="http://{DOMAIN}/{CORS_PROXY}/api.hubapi.com/crm/v3/objects/contacts?properties=firstname,lastname,email,company,custom_notes"
resultSelector="results.map(item => item.properties )"
headers='{{"Authorization":"Bearer not-a-real-token"}}'
```
This `List` uses the array.
```xmlui copy
<List data="{contacts}" title="Hubspot Contacts">
<Card gap="0" width="20em">
<Text fontWeight="bold">
{$item.firstname} {$item.lastname}
</Text>
<Text>
{$item.company}
</Text>
<Text>
{$item.email}
</Text>
<Text>
{$item.custom_notes}
</Text>
</Card>
</List>
```
This `resultSelector` filters the array of the `properties` objects to include only contacts with non-null `custom_notes`.
```xmlui copy
<DataSource
id="contacts"
resultSelector="results.filter(contact => contact.properties.custom_notes !== null).map(contact => contact.properties)"
url="http://{DOMAIN}/{CORS_PROXY}/api.hubapi.com/crm/v3/objects/contacts?properties=firstname,lastname,email,company,custom_notes"
headers='{{"Authorization":"Bearer not-a-real-token"}}'
/>
````
This `Table` uses the filtered array.
```xmlui copy
<Table title="HubSpot contacts" data="{contacts}">
<Column bindTo="firstname" />
<Column bindTo="lastname" />
<Column bindTo="company" />
<Column bindTo="email" />
<Column bindTo="custom_notes" />
</Table>
```
### `structuralSharing` (default: "true") [#structuralsharing-default-true]
This property allows structural sharing. When turned on, `DataSource` will keep the original reference if nothing has changed in the data. If a subset has changed, `DataSource` will keep the unchanged parts and only replace the changed parts. If you do not need this behavior, set this property to `false`.
### `transformResult` [#transformresult]
Set an optional function to perform a final transformation of the response data. If this value is not set, the result is not transformed.
### `url` (required) [#url-required]
Set the URL.
## Events [#events]
### `error` [#error]
This event fires when a request results in an error.
### `loaded` [#loaded]
The component triggers this event when the fetch operation has been completed and the data is loaded. The event has two arguments. The first is the data loaded; the second indicates if the event is a result of a refetch.
## Exposed Methods [#exposed-methods]
### `inProgress` [#inprogress]
This property indicates if the data is being fetched.
**Signature**: `get inProgress(): boolean`
### `isRefetching` [#isrefetching]
This property indicates if the data is being re-fetched.
**Signature**: `get isRefetching(): boolean`
### `loaded` [#loaded]
This property indicates if the data has been loaded.
**Signature**: `get loaded(): boolean`
### `refetch` [#refetch]
This method requests the re-fetch of the data.
**Signature**: `refetch(): void`
### `value` [#value]
This property retrieves the data queried from the source after optional transformations.
**Signature**: `get value(): any`
## Styling [#styling]
This component does not have any styles.
```
--------------------------------------------------------------------------------
/docs/content/components/RadioGroup.md:
--------------------------------------------------------------------------------
```markdown
# RadioGroup [#radiogroup]
`RadioGroup` creates a mutually exclusive selection interface where users can choose only one option from a group of radio buttons. It manages the selection state and ensures that selecting one option automatically deselects all others in the group.
Radio options store their values as strings. Numbers and booleans are converted to strings when assigned, while objects, functions and arrays default to an empty string unless resolved via binding expressions.
**Key features:**
- **Exclusive selection**: Only one option can be selected at a time within the group
- **Form integration**: Built-in validation states and seamless form compatibility
- **Flexible layout**: Contains [Option](/components/Option) that can be arranged in any layout structure
- **State management**: Automatically handles selection state and change events
- **Accessibility support**: Proper keyboard navigation and screen reader compatibility
- **Validation indicators**: Visual feedback for error, warning, and valid states
`RadioGroup` is often used in forms. See [this guide](/forms) for details.
## Properties [#properties]
### `autoFocus` (default: false) [#autofocus-default-false]
If this property is set to `true`, the component gets the focus automatically when displayed.
### `enabled` (default: true) [#enabled-default-true]
This boolean property value indicates whether the component responds to user events (`true`) or not (`false`).
This property indicates whether the input accepts user actions (`true`) or not (`false`). The default value is `true`.
```xmlui-pg copy display name="Example: enabled"
<App>
<RadioGroup initialValue="first" enabled="false">
<HStack padding="$space-normal">
<Option label="First Item" value="first"/>
<Option label="Second Item" value="second"/>
<Option label="Third Item" value="third"/>
</HStack>
</RadioGroup>
</App>
```
### `initialValue` (default: "") [#initialvalue-default-]
This property sets the component's initial value.
This property defines the initial value of the selected option within the group.
```xmlui-pg copy display name="Example: initialValue"
<App>
<RadioGroup initialValue="first">
<HStack padding="$space-normal">
<Option label="First Item" value="first"/>
<Option label="Second Item" value="second"/>
<Option label="Third Item" value="third"/>
</HStack>
</RadioGroup>
</App>
```
### `readOnly` (default: false) [#readonly-default-false]
Set this property to `true` to disallow changing the component value.
### `required` (default: false) [#required-default-false]
Set this property to `true` to indicate it must have a value before submitting the containing form.
### `validationStatus` (default: "none") [#validationstatus-default-none]
This property allows you to set the validation status of the input component.
Available values:
| Value | Description |
| --- | --- |
| `valid` | Visual indicator for an input that is accepted |
| `warning` | Visual indicator for an input that produced a warning |
| `error` | Visual indicator for an input that produced an error |
This prop is used to visually indicate status changes reacting to form field validation.
| Value | Description |
| :-------- | :---------------------------------------------------- |
| `valid` | Visual indicator for an input that is accepted |
| `warning` | Visual indicator for an input that produced a warning |
| `error` | Visual indicator for an input that produced an error |
```xmlui-pg copy display name="Example: validationStatus"
<App>
<HStack>
<RadioGroup initialValue="first" validationStatus="error">
<Option label="First Item" value="first"/>
<Option label="Second Item" value="second"/>
</RadioGroup>
<RadioGroup initialValue="first" validationStatus="warning">
<Option label="First Item" value="first"/>
<Option label="Second Item" value="second"/>
</RadioGroup>
<RadioGroup initialValue="first" validationStatus="valid">
<Option label="First Item" value="first"/>
<Option label="Second Item" value="second"/>
</RadioGroup>
</HStack>
</App>
```
## Events [#events]
### `didChange` [#didchange]
This event is triggered when value of RadioGroup has changed.
This event is triggered after the user has changed the field value. The following example uses this event to display the selected option's value:
```xmlui-pg
---app copy display name="Example: didChange"
<App var.field="">
<RadioGroup initialValue="{field}" onDidChange="(val) => field = val">
<Option label="First Item" value="first"/>
<Option label="Second Item" value="second"/>
</RadioGroup>
<Text value="{field}" />
</App>
---desc
Select one of the available options and see how the `Text` underneath it is updated in parallel:
```
### `gotFocus` [#gotfocus]
This event is triggered when the RadioGroup has received the focus.
### `lostFocus` [#lostfocus]
This event is triggered when the RadioGroup has lost the focus.
## Exposed Methods [#exposed-methods]
This component does not expose any methods.
## Styling [#styling]
`RadioGroup` is a component that governs its children and stores the selected value. It does not support styling; however, you can style the options within the group. When you set the theme variables for the group's options, use the `RadioGroupOption` name.
### Theme Variables [#theme-variables]
| Variable | Default Value (Light) | Default Value (Dark) |
| --- | --- | --- |
| [backgroundColor](../styles-and-themes/common-units/#color)-checked-RadioGroupOption | $color-primary-500 | $color-primary-500 |
| [backgroundColor](../styles-and-themes/common-units/#color)-checked-RadioGroupOption | $color-primary-500 | $color-primary-500 |
| [backgroundColor](../styles-and-themes/common-units/#color)-checked-RadioGroupOption--disabled | $textColor--disabled | $textColor--disabled |
| [backgroundColor](../styles-and-themes/common-units/#color)-checked-RadioGroupOption--disabled | $textColor--disabled | $textColor--disabled |
| [backgroundColor](../styles-and-themes/common-units/#color)-RadioGroupOption--disabled | $backgroundColor--disabled | $backgroundColor--disabled |
| [backgroundColor](../styles-and-themes/common-units/#color)-RadioGroupOption-default | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-checked-RadioGroupOption | $color-primary-500 | $color-primary-500 |
| [borderColor](../styles-and-themes/common-units/#color)-checked-RadioGroupOption | $color-primary-500 | $color-primary-500 |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption--disabled | *none* | *none* |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption-default | $color-surface-500 | $color-surface-500 |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption-default | $color-surface-500 | $color-surface-500 |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption-default--active | $color-primary-500 | $color-primary-500 |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption-default--active | $color-primary-500 | $color-primary-500 |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption-default--hover | $color-surface-700 | $color-surface-700 |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption-default--hover | $color-surface-700 | $color-surface-700 |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption-error | $borderColor-Input-default--error | $borderColor-Input-default--error |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption-error | $borderColor-Input-default--error | $borderColor-Input-default--error |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption-success | $borderColor-Input-default--success | $borderColor-Input-default--success |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption-success | $borderColor-Input-default--success | $borderColor-Input-default--success |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption-warning | $borderColor-Input-default--warning | $borderColor-Input-default--warning |
| [borderColor](../styles-and-themes/common-units/#color)-RadioGroupOption-warning | $borderColor-Input-default--warning | $borderColor-Input-default--warning |
| [borderWidth](../styles-and-themes/common-units/#size)-RadioGroupOption | 1px | 1px |
| [borderWidth](../styles-and-themes/common-units/#size)-RadioGroupOption-validation | 2px | 2px |
| [color](../styles-and-themes/common-units/#color)-RadioGroupOption--disabled | *none* | *none* |
| [fontSize](../styles-and-themes/common-units/#size)-RadioGroupOption | $fontSize-sm | $fontSize-sm |
| [fontSize](../styles-and-themes/common-units/#size)-RadioGroupOption | $fontSize-sm | $fontSize-sm |
| [fontWeight](../styles-and-themes/common-units/#fontWeight)-RadioGroupOption | $fontWeight-bold | $fontWeight-bold |
| [fontWeight](../styles-and-themes/common-units/#fontWeight)-RadioGroupOption | $fontWeight-bold | $fontWeight-bold |
| [gap](../styles-and-themes/common-units/#size)-RadioGroupOption | $space-1_5 | $space-1_5 |
| [outlineColor](../styles-and-themes/common-units/#color)-RadioGroupOption--focus | *none* | *none* |
| [outlineOffset](../styles-and-themes/common-units/#size)-RadioGroupOption--focus | *none* | *none* |
| [outlineStyle](../styles-and-themes/common-units/#border)-RadioGroupOption--focus | *none* | *none* |
| [outlineWidth](../styles-and-themes/common-units/#size)-RadioGroupOption--focus | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-RadioGroupOption-default | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-RadioGroupOption-error | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-RadioGroupOption-success | *none* | *none* |
| [textColor](../styles-and-themes/common-units/#color)-RadioGroupOption-warning | *none* | *none* |
```
--------------------------------------------------------------------------------
/xmlui/src/components/Tooltip/Tooltip.md:
--------------------------------------------------------------------------------
```markdown
%-DESC-START
## Using Tooltip
You rarely need to use the Tooltip component directly, as visual components support three properties, `tootip`, `tooltipMarkdown`, and `tooltipOptions` respectively. When you utilize the `tooltip` property with a visual component, hovering over that component displays the associated text.
### The `tooltip` property
```xmlui-pg display copy height="180px" /tooltip/ name="Example: using the tooltip property"
<App>
<CHStack height="100px" verticalAlignment="center" >
<Button
label="Hover the mouse over me!"
tooltip="I'm hovered!"
>
</Button>
</CHStack>
</App>
```
### The `tooltipMarkdown` property
The `tooltipMarkdown` property allows you to use the tooltip with markdown syntax.
```xmlui-pg display copy /tooltipMarkdown/ name="Example: using the tooltipMarkdown property"
<App>
<VStack height="80px" width="fit-content">
<Card
title="Tooltip with markdown"
tooltipMarkdown="This *example* uses `toolTipMarkdown`"
tooltipOptions="right"
/>
</VStack>
</App>
```
### The `tooltipOptions` property
The tooltip provides several options (see the properties of this component), influencing its behavior and appearance. You can set the `tooltipOptions` property to define these options.
For example, the following example positions the tooltip to the right, making it appear somewhat distant from the component.
```xmlui-pg display copy height="180px" /tooltipOptions/ name="Example: using the tooltipOptions property"
<App>
<CHStack height="100px" verticalAlignment="center" >
<Button
label="Hover the mouse over me!"
tooltip="I'm hovered"
tooltipOptions="right; sideOffset: 32"
>
</Button>
</CHStack>
</App>
```
You can define `tooltipOptions` as a string or as an object. In the latter case, the object declares name and value pairs describing the visual options:
```xmlui-pg display copy height="180px" /tooltipOptions/ name="Example: tooltipOptions as an object"
<App>
<CHStack height="100px" verticalAlignment="center" >
<Button
label="Hover the mouse over me!"
tooltip="Use an object"
tooltipOptions="{{ showArrow: false, side: 'bottom', align: 'start' }}"
>
</Button>
</CHStack>
</App>
```
The string form of `tooltipOptions` is composed of names or name and value pairs separated by semicolons. The properties that allow enumerations (such as `side` or `align`) can be set with a name representing a single value. Properties with boolean values can use the property name to represent the `true` value, or the property name prefixed with an exclamation mark to signify a `false` value. Numeric values are separated from the property name by a colon, and they do not use units. Here are a few examples:
```xmlui-pg display copy height="300px" /tooltipOptions/ name="Example: tooltipOptions as a string"
<App>
<VStack height="100px" horizontalAlignment="center" gap="3rem">
<Card
title="Tooltip to the left with 800ms delay"
tooltip="I'm a Tooltip"
tooltipOptions="left; delayDuration: 800; !showArrow" />
<HStack>
<Icon
name="email"
width="48px"
height="48px"
tooltipMarkdown="**Tooltip** to the bottom with no arrows, aligned left"
tooltipOptions="bottom; !showArrow; start" />
<Icon
name="phone"
width="48px"
height="48px"
tooltipMarkdown="*Tooltip* to the bottom with arrows, 28 pixels away"
tooltipOptions="bottom; showArrow; sideOffset: 28" />
</HStack>
</VStack>
</App>
```
### Using the Tooltip component
Instead of using the tooltip-related properties, you can wrap the component into a `Tooltip`:
```xmlui-pg display copy height="260px" name="Example: Using the Tooltip component"
<App>
<VStack height="100px" horizontalAlignment="center">
<Tooltip side="bottom" markdown="This *example* uses a `Tooltip` component">
<Stack>
<Card title="Card 1: within a Tooltip" />
<Card title="Card 2: within the same Tooltip" />
</Stack>
</Tooltip>
</VStack>
</App>
```
### Using a Tooltip template
You can specify tooltips that you could not otherwise do with the `text` or `markdown` properties.
```xmlui-pg display copy height="200px" name="Example: Using a tooltipTemplate" /tooltipTemplate/
<App>
<VStack height="100px" horizontalAlignment="center">
<Tooltip side="bottom">
<property name="tooltipTemplate">
<HStack>
<Stack width="24px" height="24px" backgroundColor="purple" />
<H2>This is a tooltip</H2>
</HStack>
</property>
<Card title="I have a templated Tooltip!" />
</Tooltip>
</VStack>
</App>
```
A `tooltipTemplate` may be able to use the `$tooltip` context variable.
```xmlui-pg display copy height="600px" name="Example: tooltipTemplate with $tooltip context variable"
<App
var.starData="{[
{ star_date: '2025-02-11T00:00:00Z', xmlui_stars: 0, xmlui_test_server_stars: 0, xmlui_invoice_stars: 0, xmlui_mcp_stars: 0 },
{ star_date: '2025-07-18T00:00:00Z', xmlui_stars: 1, xmlui_test_server_stars: 0, xmlui_invoice_stars: 0, xmlui_mcp_stars: 0 },
{ star_date: '2025-07-19T00:00:00Z', xmlui_stars: 4, xmlui_test_server_stars: 1, xmlui_invoice_stars: 0, xmlui_mcp_stars: 0 },
{ star_date: '2025-07-20T00:00:00Z', xmlui_stars: 48, xmlui_test_server_stars: 5, xmlui_invoice_stars: 2, xmlui_mcp_stars: 1 },
{ star_date: '2025-07-21T00:00:00Z', xmlui_stars: 62, xmlui_test_server_stars: 8, xmlui_invoice_stars: 3, xmlui_mcp_stars: 2 },
{ star_date: '2025-07-22T00:00:00Z', xmlui_stars: 16, xmlui_test_server_stars: 3, xmlui_invoice_stars: 1, xmlui_mcp_stars: 1 },
{ star_date: '2025-07-23T00:00:00Z', xmlui_stars: 6, xmlui_test_server_stars: 2, xmlui_invoice_stars: 1, xmlui_mcp_stars: 0 },
{ star_date: '2025-07-24T00:00:00Z', xmlui_stars: 3, xmlui_test_server_stars: 1, xmlui_invoice_stars: 0, xmlui_mcp_stars: 1 },
{ star_date: '2025-07-25T00:00:00Z', xmlui_stars: 10, xmlui_test_server_stars: 2, xmlui_invoice_stars: 1, xmlui_mcp_stars: 1 },
{ star_date: '2025-07-26T00:00:00Z', xmlui_stars: 2, xmlui_test_server_stars: 1, xmlui_invoice_stars: 0, xmlui_mcp_stars: 0 },
{ star_date: '2025-07-27T00:00:00Z', xmlui_stars: 3, xmlui_test_server_stars: 1, xmlui_invoice_stars: 1, xmlui_mcp_stars: 0 },
{ star_date: '2025-07-28T00:00:00Z', xmlui_stars: 4, xmlui_test_server_stars: 1, xmlui_invoice_stars: 0, xmlui_mcp_stars: 1 },
{ star_date: '2025-07-29T00:00:00Z', xmlui_stars: 4, xmlui_test_server_stars: 2, xmlui_invoice_stars: 1, xmlui_mcp_stars: 0 },
{ star_date: '2025-07-30T00:00:00Z', xmlui_stars: 1, xmlui_test_server_stars: 0, xmlui_invoice_stars: 0, xmlui_mcp_stars: 1 },
{ star_date: '2025-07-31T00:00:00Z', xmlui_stars: 1, xmlui_test_server_stars: 1, xmlui_invoice_stars: 0, xmlui_mcp_stars: 0 },
{ star_date: '2025-08-01T00:00:00Z', xmlui_stars: 2, xmlui_test_server_stars: 0, xmlui_invoice_stars: 1, xmlui_mcp_stars: 0 },
{ star_date: '2025-08-05T00:00:00Z', xmlui_stars: 1, xmlui_test_server_stars: 1, xmlui_invoice_stars: 0, xmlui_mcp_stars: 0 },
{ star_date: '2025-08-07T00:00:00Z', xmlui_stars: 1, xmlui_test_server_stars: 0, xmlui_invoice_stars: 0, xmlui_mcp_stars: 1 },
{ star_date: '2025-08-08T00:00:00Z', xmlui_stars: 3, xmlui_test_server_stars: 1, xmlui_invoice_stars: 1, xmlui_mcp_stars: 0 },
{ star_date: '2025-08-12T00:00:00Z', xmlui_stars: 2, xmlui_test_server_stars: 1, xmlui_invoice_stars: 0, xmlui_mcp_stars: 1 },
{ star_date: '2025-08-14T00:00:00Z', xmlui_stars: 1, xmlui_test_server_stars: 0, xmlui_invoice_stars: 1, xmlui_mcp_stars: 0 },
{ star_date: '2025-08-15T00:00:00Z', xmlui_stars: 2, xmlui_test_server_stars: 1, xmlui_invoice_stars: 0, xmlui_mcp_stars: 0 },
{ star_date: '2025-08-18T00:00:00Z', xmlui_stars: 2, xmlui_test_server_stars: 0, xmlui_invoice_stars: 1, xmlui_mcp_stars: 1 },
{ star_date: '2025-08-19T00:00:00Z', xmlui_stars: 3, xmlui_test_server_stars: 1, xmlui_invoice_stars: 1, xmlui_mcp_stars: 0 },
{ star_date: '2025-08-20T00:00:00Z', xmlui_stars: 1, xmlui_test_server_stars: 0, xmlui_invoice_stars: 0, xmlui_mcp_stars: 1 }
]}"
>
<VStack padding="$space-4" gap="$space-4">
<Text fontSize="$fontSize-xl" fontWeight="$fontWeight-semibold">
XMLUI Stars Over Time
</Text>
<Card height="400px">
<LineChart
data="{starData}"
yKeys="{['xmlui_stars', 'xmlui_test_server_stars', 'xmlui_invoice_stars', 'xmlui_mcp_stars']}"
xKey="star_date"
showLegend="true"
tickFormatterX="{formatDateWithoutYear}">
<property name="tooltipTemplate">
<Theme
border-cell-Table="none"
padding-cell-Table="0">
<VStack
gap="0"
width="16rem"
borderRadius="$borderRadius"
boxShadow="$boxShadow-md"
backgroundColor="$color-surface-100">
<Text>
{formatDate($tooltip.label)}
</Text>
<Table
lineHeight="$lineHeight-tight"
data="{$tooltip.payload}"
hideHeader="true"
noBottomBorder="true">
<Column width="3*">
<HStack gap="$space-2" verticalAlignment="center">
<Stack
width="8px"
height="8px"
backgroundColor="{$item.color}" />
<Text fontSize="$fontSize-smaller">
{$item.label}
</Text>
</HStack>
</Column>
<Column>
<Text fontSize="$fontSize-smaller">
{$item.value}
</Text>
</Column>
</Table>
</VStack>
</Theme>
</property>
</LineChart>
</Card>
</VStack>
</App>
```
%-DESC-END
```
--------------------------------------------------------------------------------
/tools/vscode/CHANGELOG.md:
--------------------------------------------------------------------------------
```markdown
# xmlui-vscode
## 0.11.0
### Patch Changes
- Updated dependencies [fe503eb]
- Updated dependencies [06bb966]
- Updated dependencies [19145d2]
- Updated dependencies [e6b5810]
- Updated dependencies [db94656]
- Updated dependencies [fe503eb]
- Updated dependencies [82ddbe7]
- Updated dependencies [5109dce]
- Updated dependencies [75b701b]
- [email protected]
## 0.10.26
### Patch Changes
- Updated dependencies [e1b8d58]
- Updated dependencies [1ad832c]
- [email protected]
## 0.10.25
### Patch Changes
- Updated dependencies [e7c503e]
- Updated dependencies [5fe3052]
- Updated dependencies [5fe3052]
- Updated dependencies [250647b]
- [email protected]
## 0.10.24
### Patch Changes
- Updated dependencies [3e361c4]
- Updated dependencies [3e361c4]
- [email protected]
## 0.10.23
### Patch Changes
- Updated dependencies [bf18444]
- Updated dependencies [6d3bb89]
- Updated dependencies [89c69af]
- Updated dependencies [4cfebf0]
- Updated dependencies [145cd68]
- [email protected]
## 0.10.22
### Patch Changes
- Updated dependencies [501f60a]
- Updated dependencies [1020f1c]
- [email protected]
## 0.10.21
### Patch Changes
- Updated dependencies [6fd4d62]
- [email protected]
## 0.10.20
### Patch Changes
- Updated dependencies [26eac90]
- Updated dependencies [f53edff]
- Updated dependencies [1840916]
- Updated dependencies [c6be7a3]
- Updated dependencies [6aaefaf]
- Updated dependencies [28d2585]
- Updated dependencies [e29a231]
- Updated dependencies [22162c0]
- Updated dependencies [e90232b]
- [email protected]
## 0.10.19
### Patch Changes
- Updated dependencies [facb257]
- Updated dependencies [6084c14]
- Updated dependencies [e1fa9d7]
- [email protected]
## 0.10.18
### Patch Changes
- Updated dependencies [202f2b2]
- Updated dependencies [6650ee8]
- Updated dependencies [da98994]
- Updated dependencies [8394663]
- [email protected]
## 0.10.17
### Patch Changes
- Updated dependencies [07dae0b]
- [email protected]
## 0.10.16
### Patch Changes
- Updated dependencies [0ba6612]
- Updated dependencies [7b78052]
- Updated dependencies [314b429]
- Updated dependencies [a1dea8f]
- Updated dependencies [cff754c]
- [email protected]
## 0.10.15
### Patch Changes
- Updated dependencies [3c8ad14]
- Updated dependencies [5502fea]
- Updated dependencies [e08f0ba]
- Updated dependencies [5502fea]
- Updated dependencies [db618b5]
- Updated dependencies [a795b3d]
- Updated dependencies [5851c02]
- [email protected]
## 0.10.14
### Patch Changes
- Updated dependencies [618049b]
- Updated dependencies [215a142]
- Updated dependencies [65b52e1]
- Updated dependencies [0cc2178]
- Updated dependencies [53d4ed9]
- [email protected]
## 0.10.13
### Patch Changes
- Updated dependencies [9401ee0]
- Updated dependencies [eb62858]
- Updated dependencies [eb62858]
- Updated dependencies [eb62858]
- Updated dependencies [eb62858]
- Updated dependencies [eb62858]
- Updated dependencies [eb62858]
- Updated dependencies [243b7fa]
- Updated dependencies [eb62858]
- [email protected]
## 0.10.12
### Patch Changes
- Updated dependencies [f12a042]
- Updated dependencies [8731eb8]
- Updated dependencies [eb6454f]
- Updated dependencies [1210852]
- [email protected]
## 0.10.11
### Patch Changes
- Updated dependencies [8c76c8d]
- Updated dependencies [d56c3e5]
- Updated dependencies [e42d367]
- Updated dependencies [f539526]
- Updated dependencies [19ce234]
- Updated dependencies [455b6c0]
- Updated dependencies [e90dc73]
- Updated dependencies [819b563]
- Updated dependencies [b57dfa2]
- Updated dependencies [9dd0f97]
- Updated dependencies [19ce234]
- Updated dependencies [898346d]
- Updated dependencies [705dd04]
- [email protected]
## 0.10.10
### Patch Changes
- Updated dependencies [fff80c5]
- [email protected]
## 0.10.9
### Patch Changes
- Updated dependencies [879c09d]
- Updated dependencies [3ad8514]
- Updated dependencies [0c69245]
- Updated dependencies [4ad31fc]
- Updated dependencies [c99f184]
- Updated dependencies [5032e4a]
- Updated dependencies [2394f36]
- [email protected]
## 0.10.8
### Patch Changes
- Updated dependencies [a4d62c4]
- Updated dependencies [7ed2918]
- [email protected]
## 0.10.7
### Patch Changes
- Updated dependencies [664ea4f]
- Updated dependencies [a739a26]
- Updated dependencies [bdb54dd]
- Updated dependencies [81724c6]
- [email protected]
## 0.10.6
### Patch Changes
- Updated dependencies [6464ec8]
- [email protected]
## 0.10.5
### Patch Changes
- Updated dependencies [d38351d]
- [email protected]
## 0.10.4
### Patch Changes
- Updated dependencies [43fd8c5]
- Updated dependencies [1df8e5d]
- Updated dependencies [0d5d9d1]
- Updated dependencies [3def673]
- Updated dependencies [428ebea]
- Updated dependencies [a12ce66]
- [email protected]
## 0.10.3
### Patch Changes
- Updated dependencies [2e512bb]
- Updated dependencies [46d1d18]
- Updated dependencies [6bc9ed1]
- Updated dependencies [0b1f983]
- Updated dependencies [a2637f3]
- Updated dependencies [eb4d592]
- [email protected]
## 0.10.2
### Patch Changes
- Updated dependencies [ff14e15]
- Updated dependencies [1451a94]
- [email protected]
## 0.10.1
### Patch Changes
- Updated dependencies [442416b]
- Updated dependencies [a018431]
- Updated dependencies [33cb547]
- Updated dependencies [b5d7537]
- [email protected]
## 0.10.0
### Patch Changes
- Updated dependencies [6d0ce52]
- Updated dependencies [8c98f33]
- Updated dependencies [ef86593]
- Updated dependencies [da5f4e7]
- Updated dependencies [47c7a2d]
- Updated dependencies [740f904]
- Updated dependencies [5009c52]
- Updated dependencies [000a311]
- Updated dependencies [eb8b958]
- Updated dependencies [2f5ec32]
- [email protected]
## 0.9.101
### Patch Changes
- Updated dependencies [791b0be]
- [email protected]
## 0.9.100
### Patch Changes
- Updated dependencies [2dbf6d2]
- [email protected]
## 0.9.99
### Patch Changes
- Updated dependencies [e5a09fb]
- Updated dependencies [36360f6]
- [email protected]
## 0.9.98
### Patch Changes
- Updated dependencies [ff781f3]
- Updated dependencies [377f0f2]
- Updated dependencies [ce0ff76]
- Updated dependencies [208768a]
- [email protected]
## 0.9.97
### Patch Changes
- Updated dependencies [f7e8019]
- [email protected]
## 0.9.96
### Patch Changes
- Updated dependencies [3196156]
- Updated dependencies [cfee78a]
- Updated dependencies [f51002a]
- Updated dependencies [3fa52d9]
- [email protected]
## 0.9.95
### Patch Changes
- Updated dependencies [af6a7a0]
- Updated dependencies [69a2a8f]
- Updated dependencies [29c68fe]
- [email protected]
## 0.9.94
### Patch Changes
- Updated dependencies [1d9365c]
- [email protected]
## 0.9.93
### Patch Changes
- Updated dependencies [af17117]
- Updated dependencies [44da3d9]
- Updated dependencies [b7a6b9a]
- Updated dependencies [bc95844]
- Updated dependencies [52d94a2]
- Updated dependencies [6629ce5]
- Updated dependencies [0254471]
- Updated dependencies [3318cfb]
- [email protected]
## 0.9.92
### Patch Changes
- Updated dependencies [347cda1]
- [email protected]
## 0.9.91
### Patch Changes
- Updated dependencies [6a7d779]
- [email protected]
## 0.9.90
### Patch Changes
- Updated dependencies [4b57f7e]
- [email protected]
## 0.9.89
### Patch Changes
- Updated dependencies [2968eb9]
- Updated dependencies [94f4eb5]
- Updated dependencies [8364c03]
- [email protected]
## 0.9.88
### Patch Changes
- d4235e9: feat: layout properties displayed later in completion list
- Updated dependencies [b79d7d8]
- [email protected]
## 0.9.87
### Patch Changes
- Updated dependencies [33846c2]
- [email protected]
## 0.9.86
### Patch Changes
- Updated dependencies [48af60d]
- [email protected]
## 0.9.85
### Patch Changes
- Updated dependencies [ee8d6ad]
- Updated dependencies [9ca7572]
- Updated dependencies [6944d2f]
- Updated dependencies [c0c10e7]
- Updated dependencies [cbe1ef2]
- [email protected]
## 0.9.84
### Patch Changes
- Updated dependencies [c54abf3]
- [email protected]
## 0.9.83
### Patch Changes
- Updated dependencies [8e3d6a3]
- Updated dependencies [8644010]
- [email protected]
## 0.9.82
### Patch Changes
- Updated dependencies [3bc29ae]
- Updated dependencies [1101bf5]
- Updated dependencies [cd8db58]
- Updated dependencies [13beb58]
- Updated dependencies [79c1d8a]
- [email protected]
## 0.9.81
### Patch Changes
- Updated dependencies [59680b7]
- [email protected]
## 0.9.80
### Patch Changes
- Updated dependencies [4598566]
- Updated dependencies [14e6a7d]
- Updated dependencies [cf05bd2]
- [email protected]
## 0.9.79
### Patch Changes
- Updated dependencies [ad21a31]
- [email protected]
## 0.9.78
### Patch Changes
- Updated dependencies [94a68f0]
- Updated dependencies [94a68f0]
- Updated dependencies [163a45c]
- Updated dependencies [7ce528b]
- Updated dependencies [c6eb9a8]
- [email protected]
## 0.9.77
### Patch Changes
- Updated dependencies [c867f38]
- [email protected]
## 0.9.76
### Patch Changes
- 15bf622: fix: add escaped \{ to textmate syntax, eliminate double extraction of props in FormItem causing bugs with escaped open curly brace being parsed as start of binding expression.
- Updated dependencies [aa08a8c]
- Updated dependencies [15bf622]
- Updated dependencies [5761868]
- [email protected]
## 0.9.75
### Patch Changes
- 2edefdd: feat: ensure xmlui-vscode is versioned with xmlui
- Updated dependencies [c876be8]
- [email protected]
## 0.1.2
### Patch Changes
- 2e808fa: Add custom xmlui formatter to better handle formatting erroneous syntax, long lines, and xmlui specific syntax, like backtick quoted strings, key-only attributes, etc...
- Updated dependencies [96273bf]
- Updated dependencies [1a81bcf]
- [email protected]
## 0.1.1
### Patch Changes
- e964286: Add formating to language server and fix error recovery when tag name is erroneous
- Updated dependencies [de8d63c]
- Updated dependencies [bd6d1b4]
- Updated dependencies [db5a5f4]
- Updated dependencies [69b4402]
- [email protected]
## 0.0.5
### Patch Changes
- 42416ba: test change for CI #2
- Updated dependencies [42416ba]
- [email protected]
## 0.0.3
### Patch Changes
- e43b92a: another test change
## 0.0.2
### Patch Changes
- 3be75a4: test release for CI
- Updated dependencies [8d662f3]
- [email protected]
```
--------------------------------------------------------------------------------
/xmlui/src/components/Button/Button.module.scss:
--------------------------------------------------------------------------------
```scss
@use "../../components-core/theming/themes" as t;
// --- This code snippet is required to collect the theme variables used in this module
$themeVars: ();
@function createThemeVar($componentVariable) {
$themeVars: t.appendThemeVar($themeVars, $componentVariable) !global;
@return t.getThemeVar($themeVars, $componentVariable);
}
$component: "Button";
$themeVars: t.composePaddingVars($themeVars, $component);
$themeVars: t.composePaddingVars($themeVars, "#{$component}-xs");
$themeVars: t.composePaddingVars($themeVars, "#{$component}-sm");
$themeVars: t.composePaddingVars($themeVars, "#{$component}-md");
$themeVars: t.composePaddingVars($themeVars, "#{$component}-lg");
$fontFamily-Button: createThemeVar('fontFamily-#{$component}');
$fontSize-Button: createThemeVar('fontSize-#{$component}');
$fontWeight-Button: createThemeVar('fontWeight-#{$component}');
$fontStyle-Button: createThemeVar('fontStyle-#{$component}');
$borderRadius-Button: createThemeVar('borderRadius-#{$component}');
$borderWidth-Button: createThemeVar('borderWidth-#{$component}');
$borderWidth-Button--hover: createThemeVar('borderWidth-#{$component}--hover');
$borderColor-Button: createThemeVar('borderColor-#{$component}');
$borderColor-Button--hover: createThemeVar('borderColor-#{$component}--hover');
$borderStyle-Button: createThemeVar('borderStyle-#{$component}');
$borderStyle-Button--hover: createThemeVar('borderStyle-#{$component}--hover');
$backgroundColor-Button: createThemeVar('backgroundColor-#{$component}');
$backgroundColor-Button--hover: createThemeVar('backgroundColor-#{$component}--hover');
$textColor-Button: createThemeVar('textColor-#{$component}');
$textColor-Button--hover: createThemeVar('textColor-#{$component}--hover');
$boxShadow-Button: createThemeVar('boxShadow-#{$component}');
$boxShadow-Button--hover: createThemeVar('boxShadow-#{$component}--hover');
$gap-Button: createThemeVar('gap-#{$component}');
$transition-Button: createThemeVar('transition-#{$component}');
// --- CSS properties of solid buttons with the specified color scheme
@mixin solid($colorScheme){
font-family: createThemeVar('fontFamily-#{$component}-#{$colorScheme}-solid');
font-size: createThemeVar('fontSize-#{$component}-#{$colorScheme}-solid');
font-weight: createThemeVar('fontWeight-#{$component}-#{$colorScheme}-solid');
border-radius: createThemeVar('borderRadius-#{$component}-#{$colorScheme}-solid');
border-width: createThemeVar('borderWidth-#{$component}-#{$colorScheme}-solid');
border-color: createThemeVar('borderColor-#{$component}-#{$colorScheme}-solid');
border-style: createThemeVar('borderStyle-#{$component}-#{$colorScheme}-solid');
background: createThemeVar('backgroundColor-#{$component}-#{$colorScheme}-solid');
color: createThemeVar('textColor-#{$component}-#{$colorScheme}-solid');
box-shadow: createThemeVar('boxShadow-#{$component}-#{$colorScheme}-solid');
transition: createThemeVar('transition-#{$component}-#{$colorScheme}-solid');
&:focus-visible {
outline-width: createThemeVar('outlineWidth-#{$component}-#{$colorScheme}-solid--focus');
outline-color: createThemeVar('outlineColor-#{$component}-#{$colorScheme}-solid--focus');
outline-style: createThemeVar('outlineStyle-#{$component}-#{$colorScheme}-solid--focus');
outline-offset: createThemeVar('outlineOffset-#{$component}-#{$colorScheme}-solid--focus');
}
&:not([disabled]) {
&:hover {
border-color: createThemeVar('borderColor-#{$component}-#{$colorScheme}-solid--hover');
color: createThemeVar('textColor-#{$component}-#{$colorScheme}-solid--hover');
background: createThemeVar('backgroundColor-#{$component}-#{$colorScheme}-solid--hover');
}
&:active {
border-color: createThemeVar('borderColor-#{$component}-#{$colorScheme}-solid--active');
color: createThemeVar('textColor-#{$component}-#{$colorScheme}-solid--active');
box-shadow: createThemeVar('boxShadow-#{$component}-#{$colorScheme}-solid--active');
background: createThemeVar('backgroundColor-#{$component}-#{$colorScheme}-solid--active');
}
}
&:disabled {
cursor: not-allowed;
background: createThemeVar('backgroundColor-#{$component}--disabled');
color: createThemeVar('textColor-#{$component}--disabled');
border-color: createThemeVar('borderColor-#{$component}--disabled');
}
}
// --- CSS properties of outlined buttons with the specified color scheme
@mixin outlined($colorScheme){
font-family: createThemeVar('fontFamily-#{$component}-#{$colorScheme}-outlined');
font-size: createThemeVar('fontSize-#{$component}-#{$colorScheme}-outlined');
font-weight: createThemeVar('fontWeight-#{$component}-#{$colorScheme}-outlined');
border-radius: createThemeVar('borderRadius-#{$component}-#{$colorScheme}-outlined');
border-width: createThemeVar('borderWidth-#{$component}-#{$colorScheme}-outlined');
border-color: createThemeVar('borderColor-#{$component}-#{$colorScheme}-outlined');
border-style: createThemeVar('borderStyle-#{$component}-#{$colorScheme}-outlined');
color: createThemeVar('textColor-#{$component}-#{$colorScheme}-outlined');
box-shadow: createThemeVar('boxShadow-#{$component}-#{$colorScheme}-outlined');
background: transparent;
&:focus-visible {
outline-width: createThemeVar('outlineWidth-#{$component}-#{$colorScheme}-outlined--focus');
outline-color: createThemeVar('outlineColor-#{$component}-#{$colorScheme}-outlined--focus');
outline-style: createThemeVar('outlineStyle-#{$component}-#{$colorScheme}-outlined--focus');
outline-offset: createThemeVar('outlineOffset-#{$component}-#{$colorScheme}-outlined--focus');
}
&:not([disabled]) {
&:hover {
border-color: createThemeVar('borderColor-#{$component}-#{$colorScheme}-outlined--hover');
background: createThemeVar('backgroundColor-#{$component}-#{$colorScheme}-outlined--hover');
color: createThemeVar('textColor-#{$component}-#{$colorScheme}-outlined--hover');
}
&:active {
border-color: createThemeVar('borderColor-#{$component}-#{$colorScheme}-outlined--active');
background: createThemeVar('backgroundColor-#{$component}-#{$colorScheme}-outlined--active');
color: createThemeVar('textColor-#{$component}-#{$colorScheme}-outlined--active');
}
}
&:disabled {
cursor: not-allowed;
color: createThemeVar('textColor-#{$component}--disabled');
border-color: createThemeVar('borderColor-#{$component}--disabled');
}
}
// --- CSS properties of ghost buttons with the specified color scheme
@mixin ghost($colorScheme){
font-family: createThemeVar('fontFamily-#{$component}-#{$colorScheme}-ghost');
font-size: createThemeVar('fontSize-#{$component}-#{$colorScheme}-ghost');
font-weight: createThemeVar('fontWeight-#{$component}-#{$colorScheme}-ghost');
border-radius: createThemeVar('borderRadius-#{$component}-#{$colorScheme}-ghost');
border-width: createThemeVar('borderWidth-#{$component}-#{$colorScheme}-ghost');
border-color: transparent;
border-style: solid;
background: transparent;
color: createThemeVar('textColor-#{$component}-#{$colorScheme}-ghost');
&:focus-visible {
outline-width: createThemeVar('outlineWidth-#{$component}-#{$colorScheme}-ghost--focus');
outline-color: createThemeVar('outlineColor-#{$component}-#{$colorScheme}-ghost--focus');
outline-style: createThemeVar('outlineStyle-#{$component}-#{$colorScheme}-ghost--focus');
outline-offset: createThemeVar('outlineOffset-#{$component}-#{$colorScheme}-ghost--focus');
}
&:not([disabled]) {
&:hover {
background: createThemeVar('backgroundColor-#{$component}-#{$colorScheme}-ghost--hover');
color: createThemeVar('textColor-#{$component}-#{$colorScheme}-ghost--hover');
}
&:active {
background: createThemeVar('backgroundColor-#{$component}-#{$colorScheme}-ghost--active');
color: createThemeVar('textColor-#{$component}-#{$colorScheme}-ghost--active');
}
}
&:disabled {
cursor: not-allowed;
color: createThemeVar('textColor-#{$component}--disabled');
}
}
@layer components{
// --- CSS styles
.button {
width: createThemeVar("width-Button");
height: createThemeVar("height-Button");
line-height: normal;
min-width: 0;
padding: 0;
margin: 0;
border-style: solid;
transition: $transition-Button;
user-select: none;
cursor: pointer;
display: flex;
gap: $gap-Button;
justify-content: center;
align-items: center;
&.alignStart {
justify-content: start;
}
&.alignEnd {
justify-content: end;
}
* {
color: inherit;
}
&.buttonHorizontal {
flex-direction: row;
&.xs {
@include t.paddingVars($themeVars, "#{$component}-xs");
}
&.sm {
@include t.paddingVars($themeVars, "#{$component}-sm");
}
&.md {
@include t.paddingVars($themeVars, "#{$component}-md");
}
&.lg {
@include t.paddingVars($themeVars, "#{$component}-lg");
}
}
&.buttonVertical {
flex-direction: column;
gap: t.$space-1;
width: fit-content;
height: fit-content;
&.xs {
@include t.paddingVars($themeVars, "#{$component}-xs");
}
&.sm {
@include t.paddingVars($themeVars, "#{$component}-sm");
}
&.md {
@include t.paddingVars($themeVars, "#{$component}-md");
}
&.lg {
@include t.paddingVars($themeVars, "#{$component}-lg");
}
}
&.solidPrimary {
@include solid('primary');
}
&.solidSecondary {
@include solid('secondary');
}
&.solidAttention {
@include solid('attention');
}
&.outlinedPrimary {
@include outlined('primary');
}
&.outlinedSecondary {
@include outlined('secondary');
}
&.outlinedAttention {
@include outlined('attention');
}
&.ghostPrimary {
@include ghost('primary');
}
&.ghostSecondary {
@include ghost('secondary');
}
&.ghostAttention {
@include ghost('attention');
}
}
}
// --- We export the theme variables to add them to the component renderer
:export{
themeVars: t.json-stringify($themeVars)
}
```