@commercetools/nimbus-mcp 0.1.0 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -14
- package/data/docs/route-manifest.json +10998 -0
- package/data/docs/routes/components-accessibility-visually-hidden.json +388 -0
- package/data/docs/routes/components-accessibility.json +34 -0
- package/data/docs/routes/components-buttons-button.json +715 -0
- package/data/docs/routes/components-buttons-icon-button.json +852 -0
- package/data/docs/routes/components-buttons-icon-toggle-button.json +594 -0
- package/data/docs/routes/components-buttons-split-button.json +670 -0
- package/data/docs/routes/components-buttons-toggle-button-group.json +722 -0
- package/data/docs/routes/components-buttons-toggle-button.json +689 -0
- package/data/docs/routes/components-buttons.json +36 -0
- package/data/docs/routes/components-data-display-badge.json +555 -0
- package/data/docs/routes/components-data-display-card.json +338 -0
- package/data/docs/routes/components-data-display-data-table.json +855 -0
- package/data/docs/routes/components-data-display-draggable-list.json +596 -0
- package/data/docs/routes/components-data-display-table.json +472 -0
- package/data/docs/routes/components-data-display-tag-group.json +535 -0
- package/data/docs/routes/components-data-display.json +34 -0
- package/data/docs/routes/components-feedback-alert.json +696 -0
- package/data/docs/routes/components-feedback-dialog.json +682 -0
- package/data/docs/routes/components-feedback-drawer.json +600 -0
- package/data/docs/routes/components-feedback-loading-spinner.json +415 -0
- package/data/docs/routes/components-feedback-progress-bar.json +661 -0
- package/data/docs/routes/components-feedback-toast.json +1040 -0
- package/data/docs/routes/components-feedback-tooltip.json +510 -0
- package/data/docs/routes/components-feedback.json +34 -0
- package/data/docs/routes/components-forms-field-errors.json +557 -0
- package/data/docs/routes/components-forms-form-field.json +848 -0
- package/data/docs/routes/components-forms-group.json +427 -0
- package/data/docs/routes/components-forms-localized-field.json +770 -0
- package/data/docs/routes/components-forms.json +37 -0
- package/data/docs/routes/components-inputs-calendar.json +611 -0
- package/data/docs/routes/components-inputs-checkbox.json +774 -0
- package/data/docs/routes/components-inputs-combo-box.json +761 -0
- package/data/docs/routes/components-inputs-date-input.json +628 -0
- package/data/docs/routes/components-inputs-date-picker.json +709 -0
- package/data/docs/routes/components-inputs-date-range-picker.json +599 -0
- package/data/docs/routes/components-inputs-money-input.json +721 -0
- package/data/docs/routes/components-inputs-multiline-text-input.json +611 -0
- package/data/docs/routes/components-inputs-number-input.json +647 -0
- package/data/docs/routes/components-inputs-password-input.json +576 -0
- package/data/docs/routes/components-inputs-radio-input.json +583 -0
- package/data/docs/routes/components-inputs-range-calendar.json +607 -0
- package/data/docs/routes/components-inputs-rich-text-input.json +599 -0
- package/data/docs/routes/components-inputs-scoped-search-input.json +570 -0
- package/data/docs/routes/components-inputs-search-input.json +588 -0
- package/data/docs/routes/components-inputs-select-input.json +960 -0
- package/data/docs/routes/components-inputs-switch.json +720 -0
- package/data/docs/routes/components-inputs-text-input.json +566 -0
- package/data/docs/routes/components-inputs-time-input.json +775 -0
- package/data/docs/routes/components-inputs.json +34 -0
- package/data/docs/routes/components-layout-box.json +501 -0
- package/data/docs/routes/components-layout-defaultpage.json +748 -0
- package/data/docs/routes/components-layout-flex.json +587 -0
- package/data/docs/routes/components-layout-grid.json +393 -0
- package/data/docs/routes/components-layout-modalpage.json +716 -0
- package/data/docs/routes/components-layout-pagecontent.json +673 -0
- package/data/docs/routes/components-layout-scrollarea.json +428 -0
- package/data/docs/routes/components-layout-separator.json +461 -0
- package/data/docs/routes/components-layout-simple-grid.json +519 -0
- package/data/docs/routes/components-layout-spacer.json +573 -0
- package/data/docs/routes/components-layout-stack.json +481 -0
- package/data/docs/routes/components-layout.json +34 -0
- package/data/docs/routes/components-media-avatar.json +427 -0
- package/data/docs/routes/components-media-icon.json +663 -0
- package/data/docs/routes/components-media-image.json +511 -0
- package/data/docs/routes/components-media-inline-svg.json +586 -0
- package/data/docs/routes/components-media.json +34 -0
- package/data/docs/routes/components-navigation-accordion.json +643 -0
- package/data/docs/routes/components-navigation-collapsible-motion.json +628 -0
- package/data/docs/routes/components-navigation-link.json +554 -0
- package/data/docs/routes/components-navigation-menu.json +546 -0
- package/data/docs/routes/components-navigation-pagination.json +502 -0
- package/data/docs/routes/components-navigation-steps.json +629 -0
- package/data/docs/routes/components-navigation-tabnav.json +546 -0
- package/data/docs/routes/components-navigation-tabs.json +635 -0
- package/data/docs/routes/components-navigation-toolbar.json +549 -0
- package/data/docs/routes/components-navigation.json +34 -0
- package/data/docs/routes/components-typography-code.json +39 -0
- package/data/docs/routes/components-typography-heading.json +402 -0
- package/data/docs/routes/components-typography-kbd.json +399 -0
- package/data/docs/routes/components-typography-list.json +593 -0
- package/data/docs/routes/components-typography-text.json +444 -0
- package/data/docs/routes/components-typography.json +34 -0
- package/data/docs/routes/components-utilities-nimbus-i18n-provider.json +295 -0
- package/data/docs/routes/components-utilities-nimbus-provider.json +663 -0
- package/data/docs/routes/components-utilities.json +34 -0
- package/data/docs/routes/components.json +33 -0
- package/data/docs/routes/home-contribute-adrs-adr0001-consumer-component-apis.json +314 -0
- package/data/docs/routes/home-contribute-adrs-adr0002-compound-component-extraction.json +160 -0
- package/data/docs/routes/home-contribute-adrs-adr0003-component-lifecycle-states.json +460 -0
- package/data/docs/routes/home-contribute-adrs.json +205 -0
- package/data/docs/routes/home-contribute-development-setup.json +213 -0
- package/data/docs/routes/home-contribute-stats.json +36 -0
- package/data/docs/routes/home-contribute.json +36 -0
- package/data/docs/routes/home-design-tokens-aspect-ratios.json +36 -0
- package/data/docs/routes/home-design-tokens-borders.json +35 -0
- package/data/docs/routes/home-design-tokens-colors.json +157 -0
- package/data/docs/routes/home-design-tokens-other-animations.json +119 -0
- package/data/docs/routes/home-design-tokens-other-blurs.json +36 -0
- package/data/docs/routes/home-design-tokens-other-breakpoints.json +61 -0
- package/data/docs/routes/home-design-tokens-other-cursors.json +36 -0
- package/data/docs/routes/home-design-tokens-other-z-indices.json +39 -0
- package/data/docs/routes/home-design-tokens-other.json +35 -0
- package/data/docs/routes/home-design-tokens-radii.json +59 -0
- package/data/docs/routes/home-design-tokens-shadows.json +57 -0
- package/data/docs/routes/home-design-tokens-sizes.json +137 -0
- package/data/docs/routes/home-design-tokens-spacing.json +36 -0
- package/data/docs/routes/home-design-tokens-typography.json +184 -0
- package/data/docs/routes/home-design-tokens.json +34 -0
- package/data/docs/routes/home-getting-started-core-concepts.json +301 -0
- package/data/docs/routes/home-getting-started-installation.json +621 -0
- package/data/docs/routes/home-getting-started-mcp-server-overview.json +139 -0
- package/data/docs/routes/home-getting-started-mcp-server-setup.json +316 -0
- package/data/docs/routes/home-getting-started-release-process.json +294 -0
- package/data/docs/routes/home-getting-started-testing-setup.json +296 -0
- package/data/docs/routes/home-playground-markdown.json +638 -0
- package/data/docs/routes/home-playground-toc.json +169 -0
- package/data/docs/routes/home-playground.json +34 -0
- package/data/docs/routes/home-style-props-background.json +236 -0
- package/data/docs/routes/home-style-props-border.json +310 -0
- package/data/docs/routes/home-style-props-display.json +120 -0
- package/data/docs/routes/home-style-props-effects.json +116 -0
- package/data/docs/routes/home-style-props-filters.json +396 -0
- package/data/docs/routes/home-style-props-flex-and-grid.json +496 -0
- package/data/docs/routes/home-style-props-interactivity.json +356 -0
- package/data/docs/routes/home-style-props-layout.json +422 -0
- package/data/docs/routes/home-style-props-list.json +116 -0
- package/data/docs/routes/home-style-props-sizing.json +244 -0
- package/data/docs/routes/home-style-props-spacing.json +228 -0
- package/data/docs/routes/home-style-props-svg.json +96 -0
- package/data/docs/routes/home-style-props-tables.json +116 -0
- package/data/docs/routes/home-style-props-transforms.json +216 -0
- package/data/docs/routes/home-style-props-transitions.json +216 -0
- package/data/docs/routes/home-style-props-typography.json +536 -0
- package/data/docs/routes/home-style-props.json +33 -0
- package/data/docs/routes/home.json +32 -0
- package/data/docs/routes/hooks-usecopytoclipboard.json +76 -0
- package/data/docs/routes/hooks-usehotkeys.json +117 -0
- package/data/docs/routes/hooks.json +33 -0
- package/data/docs/routes/icons.json +32 -0
- package/data/docs/routes/patterns-fields-date-range-picker-field.json +393 -0
- package/data/docs/routes/patterns-fields-money-input-field.json +415 -0
- package/data/docs/routes/patterns-fields-multiline-text-input-field.json +404 -0
- package/data/docs/routes/patterns-fields-number-input-field.json +470 -0
- package/data/docs/routes/patterns-fields-password-input-field.json +319 -0
- package/data/docs/routes/patterns-fields-search-input-field.json +382 -0
- package/data/docs/routes/patterns-fields-text-input-field.json +404 -0
- package/data/docs/routes/patterns-fields.json +78 -0
- package/data/docs/routes/patterns.json +34 -0
- package/data/docs/search-index.json +1 -0
- package/data/docs/types/Accordion.json +12 -0
- package/data/docs/types/AccordionContent.json +286 -0
- package/data/docs/types/AccordionHeader.json +891 -0
- package/data/docs/types/AccordionHeaderRightContent.json +27 -0
- package/data/docs/types/AccordionItem.json +242 -0
- package/data/docs/types/AccordionRoot.json +162 -0
- package/data/docs/types/Alert.json +12 -0
- package/data/docs/types/AlertActions.json +11 -0
- package/data/docs/types/AlertDescription.json +118 -0
- package/data/docs/types/AlertDismissButton.json +937 -0
- package/data/docs/types/AlertRoot.json +42 -0
- package/data/docs/types/AlertTitle.json +118 -0
- package/data/docs/types/Avatar.json +125 -0
- package/data/docs/types/Badge.json +64 -0
- package/data/docs/types/Body.json +67 -0
- package/data/docs/types/Box.json +85 -0
- package/data/docs/types/Button.json +1015 -0
- package/data/docs/types/Calendar.json +565 -0
- package/data/docs/types/Caption.json +67 -0
- package/data/docs/types/Card.json +12 -0
- package/data/docs/types/CardContent.json +27 -0
- package/data/docs/types/CardHeader.json +27 -0
- package/data/docs/types/CardRoot.json +106 -0
- package/data/docs/types/Cell.json +227 -0
- package/data/docs/types/Checkbox.json +897 -0
- package/data/docs/types/Code.json +112 -0
- package/data/docs/types/CollapsibleMotionContent.json +35 -0
- package/data/docs/types/CollapsibleMotionRoot.json +99 -0
- package/data/docs/types/CollapsibleMotionTrigger.json +71 -0
- package/data/docs/types/Column.json +101 -0
- package/data/docs/types/ColumnGroup.json +101 -0
- package/data/docs/types/ColumnHeader.json +193 -0
- package/data/docs/types/ComboBoxListBox.json +751 -0
- package/data/docs/types/ComboBoxOption.json +672 -0
- package/data/docs/types/ComboBoxPopover.json +786 -0
- package/data/docs/types/ComboBoxRoot.json +747 -0
- package/data/docs/types/ComboBoxSection.json +277 -0
- package/data/docs/types/ComboBoxTrigger.json +70 -0
- package/data/docs/types/Content.json +33 -0
- package/data/docs/types/DataTable.json +596 -0
- package/data/docs/types/DataTableBody.json +223 -0
- package/data/docs/types/DataTableFooter.json +27 -0
- package/data/docs/types/DataTableHeader.json +269 -0
- package/data/docs/types/DataTableManager.json +11 -0
- package/data/docs/types/DataTableRoot.json +590 -0
- package/data/docs/types/DataTableTable.json +271 -0
- package/data/docs/types/DateInput.json +792 -0
- package/data/docs/types/DatePicker.json +700 -0
- package/data/docs/types/DateRangePicker.json +936 -0
- package/data/docs/types/DateRangePickerField.json +1047 -0
- package/data/docs/types/DefaultPage.json +12 -0
- package/data/docs/types/DefaultPageActions.json +27 -0
- package/data/docs/types/DefaultPageBackLink.json +213 -0
- package/data/docs/types/DefaultPageContent.json +27 -0
- package/data/docs/types/DefaultPageFooter.json +27 -0
- package/data/docs/types/DefaultPageHeader.json +27 -0
- package/data/docs/types/DefaultPageRoot.json +106 -0
- package/data/docs/types/DefaultPageSubtitle.json +27 -0
- package/data/docs/types/DefaultPageTabNav.json +28 -0
- package/data/docs/types/DefaultPageTitle.json +27 -0
- package/data/docs/types/DialogBody.json +27 -0
- package/data/docs/types/DialogCloseTrigger.json +939 -0
- package/data/docs/types/DialogContent.json +27 -0
- package/data/docs/types/DialogFooter.json +27 -0
- package/data/docs/types/DialogHeader.json +27 -0
- package/data/docs/types/DialogRoot.json +138 -0
- package/data/docs/types/DialogTitle.json +27 -0
- package/data/docs/types/DialogTrigger.json +80 -0
- package/data/docs/types/DraggableList.json +12 -0
- package/data/docs/types/DraggableListField.json +894 -0
- package/data/docs/types/DraggableListItem.json +574 -0
- package/data/docs/types/DraggableListRoot.json +745 -0
- package/data/docs/types/Drawer.json +12 -0
- package/data/docs/types/DrawerBody.json +27 -0
- package/data/docs/types/DrawerCloseTrigger.json +939 -0
- package/data/docs/types/DrawerContent.json +27 -0
- package/data/docs/types/DrawerFooter.json +27 -0
- package/data/docs/types/DrawerHeader.json +27 -0
- package/data/docs/types/DrawerRoot.json +142 -0
- package/data/docs/types/DrawerTitle.json +27 -0
- package/data/docs/types/DrawerTrigger.json +80 -0
- package/data/docs/types/FieldErrors.getBuiltInMessage.json +11 -0
- package/data/docs/types/FieldErrors.getCustomMessage.json +9 -0
- package/data/docs/types/FieldErrors.json +109 -0
- package/data/docs/types/Flex.json +238 -0
- package/data/docs/types/Footer.json +67 -0
- package/data/docs/types/FormFieldDescription.json +11 -0
- package/data/docs/types/FormFieldError.json +11 -0
- package/data/docs/types/FormFieldInfoBox.json +27 -0
- package/data/docs/types/FormFieldInput.json +11 -0
- package/data/docs/types/FormFieldLabel.json +11 -0
- package/data/docs/types/FormFieldRoot.json +148 -0
- package/data/docs/types/Grid.json +253 -0
- package/data/docs/types/GridProps.json +11 -0
- package/data/docs/types/Group.json +143 -0
- package/data/docs/types/Header.json +67 -0
- package/data/docs/types/Heading.json +109 -0
- package/data/docs/types/Icon.json +112 -0
- package/data/docs/types/IconButton.json +1019 -0
- package/data/docs/types/IconToggleButton.json +787 -0
- package/data/docs/types/Image.json +373 -0
- package/data/docs/types/Indicator.json +67 -0
- package/data/docs/types/InlineSvg.json +98 -0
- package/data/docs/types/Item.json +67 -0
- package/data/docs/types/Kbd.json +118 -0
- package/data/docs/types/Link.json +380 -0
- package/data/docs/types/List.json +12 -0
- package/data/docs/types/ListIndicator.json +70 -0
- package/data/docs/types/ListItem.json +70 -0
- package/data/docs/types/ListRoot.json +124 -0
- package/data/docs/types/LoadingSpinner.json +87 -0
- package/data/docs/types/LocalizedField.json +460 -0
- package/data/docs/types/LocalizedStringFormatter.json +9 -0
- package/data/docs/types/MakeElementFocusable.json +196 -0
- package/data/docs/types/MenuContent.json +111 -0
- package/data/docs/types/MenuItem.json +671 -0
- package/data/docs/types/MenuRoot.json +670 -0
- package/data/docs/types/MenuSection.json +364 -0
- package/data/docs/types/MenuSubmenu.json +111 -0
- package/data/docs/types/MenuSubmenuTrigger.json +67 -0
- package/data/docs/types/MenuTrigger.json +906 -0
- package/data/docs/types/ModalPage.json +12 -0
- package/data/docs/types/ModalPageActions.json +27 -0
- package/data/docs/types/ModalPageContent.json +27 -0
- package/data/docs/types/ModalPageFooter.json +27 -0
- package/data/docs/types/ModalPageHeader.json +27 -0
- package/data/docs/types/ModalPageRoot.json +87 -0
- package/data/docs/types/ModalPageSubtitle.json +27 -0
- package/data/docs/types/ModalPageTabNav.json +28 -0
- package/data/docs/types/ModalPageTitle.json +27 -0
- package/data/docs/types/ModalPageTopBar.json +57 -0
- package/data/docs/types/MoneyInput.isEmpty.json +40 -0
- package/data/docs/types/MoneyInput.json +282 -0
- package/data/docs/types/MoneyInputField.json +379 -0
- package/data/docs/types/MoneyInputFieldProps.json +9 -0
- package/data/docs/types/MultilineTextInput.json +1194 -0
- package/data/docs/types/MultilineTextInputField.json +1269 -0
- package/data/docs/types/MultilineTextInputFieldProps.json +9 -0
- package/data/docs/types/NimbusI18nProvider.json +42 -0
- package/data/docs/types/NimbusI18nProviderProps.json +9 -0
- package/data/docs/types/NimbusProvider.json +270 -0
- package/data/docs/types/NumberInput.json +952 -0
- package/data/docs/types/NumberInputField.json +1004 -0
- package/data/docs/types/NumberInputFieldProps.json +9 -0
- package/data/docs/types/PageContent.json +11 -0
- package/data/docs/types/PageContentColumn.json +99 -0
- package/data/docs/types/PageContentRoot.json +114 -0
- package/data/docs/types/Pagination.json +159 -0
- package/data/docs/types/PasswordInput.json +1120 -0
- package/data/docs/types/PasswordInputField.json +1216 -0
- package/data/docs/types/PasswordInputFieldProps.json +9 -0
- package/data/docs/types/ProgressBar.json +280 -0
- package/data/docs/types/RadioInputOption.json +550 -0
- package/data/docs/types/RadioInputRoot.json +514 -0
- package/data/docs/types/RangeCalendar.json +618 -0
- package/data/docs/types/RichTextInput.json +134 -0
- package/data/docs/types/Root.json +122 -0
- package/data/docs/types/Row.json +67 -0
- package/data/docs/types/ScopedSearchInput.isEmpty.json +40 -0
- package/data/docs/types/ScopedSearchInput.json +253 -0
- package/data/docs/types/ScrollArea.json +179 -0
- package/data/docs/types/ScrollAreaElementIds.json +9 -0
- package/data/docs/types/ScrollAreaProps.json +9 -0
- package/data/docs/types/SearchInput.json +1165 -0
- package/data/docs/types/SearchInputField.json +1240 -0
- package/data/docs/types/Select.json +12 -0
- package/data/docs/types/SelectOption.json +572 -0
- package/data/docs/types/SelectOptionGroup.json +215 -0
- package/data/docs/types/SelectOptions.json +693 -0
- package/data/docs/types/SelectRoot.json +926 -0
- package/data/docs/types/Separator.json +65 -0
- package/data/docs/types/SimpleGrid.json +291 -0
- package/data/docs/types/Spacer.json +27 -0
- package/data/docs/types/SpacerProps.json +9 -0
- package/data/docs/types/SplitButton.json +203 -0
- package/data/docs/types/Stack.json +144 -0
- package/data/docs/types/Steps.json +12 -0
- package/data/docs/types/StepsChangeDetails.json +9 -0
- package/data/docs/types/StepsCompletedContent.json +28 -0
- package/data/docs/types/StepsCompletedContentProps.json +9 -0
- package/data/docs/types/StepsContent.json +43 -0
- package/data/docs/types/StepsContentProps.json +9 -0
- package/data/docs/types/StepsDescription.json +28 -0
- package/data/docs/types/StepsDescriptionProps.json +9 -0
- package/data/docs/types/StepsIndicator.json +28 -0
- package/data/docs/types/StepsIndicatorProps.json +9 -0
- package/data/docs/types/StepsItem.json +43 -0
- package/data/docs/types/StepsItemProps.json +9 -0
- package/data/docs/types/StepsList.json +28 -0
- package/data/docs/types/StepsListProps.json +9 -0
- package/data/docs/types/StepsNextTrigger.json +62 -0
- package/data/docs/types/StepsNextTriggerProps.json +9 -0
- package/data/docs/types/StepsNumber.json +28 -0
- package/data/docs/types/StepsNumberProps.json +9 -0
- package/data/docs/types/StepsPrevTrigger.json +62 -0
- package/data/docs/types/StepsPrevTriggerProps.json +9 -0
- package/data/docs/types/StepsRoot.json +183 -0
- package/data/docs/types/StepsRootProps.json +11 -0
- package/data/docs/types/StepsSeparator.json +28 -0
- package/data/docs/types/StepsSeparatorProps.json +9 -0
- package/data/docs/types/StepsStatus.json +57 -0
- package/data/docs/types/StepsStatusProps.json +9 -0
- package/data/docs/types/StepsTitle.json +28 -0
- package/data/docs/types/StepsTitleProps.json +9 -0
- package/data/docs/types/StepsTrigger.json +47 -0
- package/data/docs/types/StepsTriggerProps.json +9 -0
- package/data/docs/types/Switch.json +371 -0
- package/data/docs/types/TabListProps.json +9 -0
- package/data/docs/types/TabNav.json +12 -0
- package/data/docs/types/TabNavItem.json +300 -0
- package/data/docs/types/TabNavItemProps.json +9 -0
- package/data/docs/types/TabNavProps.json +9 -0
- package/data/docs/types/TabNavRoot.json +80 -0
- package/data/docs/types/TabPanelProps.json +9 -0
- package/data/docs/types/TabPanelsProps.json +9 -0
- package/data/docs/types/TabProps.json +9 -0
- package/data/docs/types/Table.json +9 -0
- package/data/docs/types/TableBody.json +67 -0
- package/data/docs/types/TableBodyProps.json +9 -0
- package/data/docs/types/TableCaption.json +67 -0
- package/data/docs/types/TableCaptionProps.json +9 -0
- package/data/docs/types/TableCell.json +227 -0
- package/data/docs/types/TableCellProps.json +9 -0
- package/data/docs/types/TableColumn.json +101 -0
- package/data/docs/types/TableColumnGroup.json +101 -0
- package/data/docs/types/TableColumnGroupProps.json +9 -0
- package/data/docs/types/TableColumnHeader.json +193 -0
- package/data/docs/types/TableColumnHeaderProps.json +9 -0
- package/data/docs/types/TableColumnProps.json +9 -0
- package/data/docs/types/TableFooter.json +67 -0
- package/data/docs/types/TableFooterProps.json +9 -0
- package/data/docs/types/TableHeader.json +67 -0
- package/data/docs/types/TableHeaderProps.json +9 -0
- package/data/docs/types/TableRoot.json +365 -0
- package/data/docs/types/TableRootProps.json +12 -0
- package/data/docs/types/TableRow.json +67 -0
- package/data/docs/types/TableRowProps.json +9 -0
- package/data/docs/types/TableScrollArea.json +82 -0
- package/data/docs/types/TableScrollAreaProps.json +9 -0
- package/data/docs/types/Tabs.json +12 -0
- package/data/docs/types/TabsList.json +110 -0
- package/data/docs/types/TabsPanel.json +112 -0
- package/data/docs/types/TabsPanels.json +108 -0
- package/data/docs/types/TabsRoot.json +211 -0
- package/data/docs/types/TabsTab.json +174 -0
- package/data/docs/types/TagGroup.json +12 -0
- package/data/docs/types/TagGroupRoot.json +306 -0
- package/data/docs/types/TagGroupTag.json +595 -0
- package/data/docs/types/TagGroupTagList.json +166 -0
- package/data/docs/types/Text.json +119 -0
- package/data/docs/types/TextInput.json +1156 -0
- package/data/docs/types/TextInputField.json +1263 -0
- package/data/docs/types/TimeInput.json +752 -0
- package/data/docs/types/ToastAction.json +9 -0
- package/data/docs/types/ToastManagerApi.json +9 -0
- package/data/docs/types/ToastOptions.json +9 -0
- package/data/docs/types/ToastOutlet.json +12 -0
- package/data/docs/types/ToastPlacement.json +9 -0
- package/data/docs/types/ToastPromiseOptions.json +9 -0
- package/data/docs/types/ToastType.json +9 -0
- package/data/docs/types/ToastVariant.json +9 -0
- package/data/docs/types/ToggleButton.json +789 -0
- package/data/docs/types/ToggleButtonGroup.json +9 -0
- package/data/docs/types/ToggleButtonGroupButton.json +331 -0
- package/data/docs/types/ToggleButtonGroupRoot.json +269 -0
- package/data/docs/types/Toolbar.json +176 -0
- package/data/docs/types/Tooltip.json +12 -0
- package/data/docs/types/TooltipContent.json +372 -0
- package/data/docs/types/TooltipRoot.json +179 -0
- package/data/docs/types/Trigger.json +69 -0
- package/data/docs/types/VisuallyHidden.json +93 -0
- package/data/docs/types/__object.json +12 -0
- package/data/docs/types/filters.json +11 -0
- package/data/docs/types/manifest.json +280 -0
- package/data/docs/types/toast.json +234 -0
- package/data/docs/types/useColorMode.json +13 -0
- package/data/docs/types/useColorModeValue.json +13 -0
- package/data/docs/types/useColorScheme.json +12 -0
- package/data/docs/types/useLocalizedStringFormatter.json +14 -0
- package/data/icons.json +21940 -0
- package/data/tokens.json +40061 -0
- package/dist/index.js +2516 -17
- package/package.json +25 -6
- package/dist/data-loader.d.ts +0 -102
- package/dist/data-loader.js +0 -104
- package/dist/index.d.ts +0 -13
- package/dist/server.d.ts +0 -9
- package/dist/server.js +0 -22
- package/dist/server.spec.d.ts +0 -1
- package/dist/server.spec.js +0 -69
- package/dist/tools/list-components.d.ts +0 -9
- package/dist/tools/list-components.js +0 -42
- package/dist/types.d.ts +0 -28
- package/dist/types.js +0 -4
- package/src/data-loader.ts +0 -226
- package/src/index.ts +0 -29
- package/src/server.spec.ts +0 -86
- package/src/server.ts +0 -28
- package/src/tools/list-components.ts +0 -49
- package/src/types.ts +0 -31
- package/tsconfig.json +0 -14
- package/vitest.config.ts +0 -9
|
@@ -0,0 +1,682 @@
|
|
|
1
|
+
{
|
|
2
|
+
"meta": {
|
|
3
|
+
"id": "Components-Dialog",
|
|
4
|
+
"title": "Dialog",
|
|
5
|
+
"exportName": "Dialog",
|
|
6
|
+
"description": "A foundational dialog component for overlays that require user attention and interaction. Built with React Aria Components for accessibility and WCAG 2.1 AA compliance.",
|
|
7
|
+
"lifecycleState": "Stable",
|
|
8
|
+
"order": 999,
|
|
9
|
+
"repoPath": "packages/nimbus/src/components/dialog/dialog.mdx",
|
|
10
|
+
"menu": [
|
|
11
|
+
"Components",
|
|
12
|
+
"Feedback",
|
|
13
|
+
"Dialog"
|
|
14
|
+
],
|
|
15
|
+
"route": "components/feedback/dialog",
|
|
16
|
+
"tags": [
|
|
17
|
+
"component",
|
|
18
|
+
"overlay",
|
|
19
|
+
"dialog",
|
|
20
|
+
"modal",
|
|
21
|
+
"interactive"
|
|
22
|
+
],
|
|
23
|
+
"toc": [
|
|
24
|
+
{
|
|
25
|
+
"value": "Overview",
|
|
26
|
+
"href": "#overview",
|
|
27
|
+
"depth": 2,
|
|
28
|
+
"numbering": [
|
|
29
|
+
1,
|
|
30
|
+
1
|
|
31
|
+
],
|
|
32
|
+
"parent": "root"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"value": "Key features",
|
|
36
|
+
"href": "#key-features",
|
|
37
|
+
"depth": 3,
|
|
38
|
+
"numbering": [
|
|
39
|
+
1,
|
|
40
|
+
1,
|
|
41
|
+
1
|
|
42
|
+
],
|
|
43
|
+
"parent": "root"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"value": "Resources",
|
|
47
|
+
"href": "#resources",
|
|
48
|
+
"depth": 3,
|
|
49
|
+
"numbering": [
|
|
50
|
+
1,
|
|
51
|
+
1,
|
|
52
|
+
2
|
|
53
|
+
],
|
|
54
|
+
"parent": "root"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"value": "Variables",
|
|
58
|
+
"href": "#variables",
|
|
59
|
+
"depth": 2,
|
|
60
|
+
"numbering": [
|
|
61
|
+
1,
|
|
62
|
+
2
|
|
63
|
+
],
|
|
64
|
+
"parent": "root"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"value": "Basic Usage",
|
|
68
|
+
"href": "#basic-usage",
|
|
69
|
+
"depth": 3,
|
|
70
|
+
"numbering": [
|
|
71
|
+
1,
|
|
72
|
+
2,
|
|
73
|
+
1
|
|
74
|
+
],
|
|
75
|
+
"parent": "root"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"value": "Size",
|
|
79
|
+
"href": "#size",
|
|
80
|
+
"depth": 3,
|
|
81
|
+
"numbering": [
|
|
82
|
+
1,
|
|
83
|
+
2,
|
|
84
|
+
2
|
|
85
|
+
],
|
|
86
|
+
"parent": "root"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"value": "Placement Options",
|
|
90
|
+
"href": "#placement-options",
|
|
91
|
+
"depth": 3,
|
|
92
|
+
"numbering": [
|
|
93
|
+
1,
|
|
94
|
+
2,
|
|
95
|
+
3
|
|
96
|
+
],
|
|
97
|
+
"parent": "root"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"value": "Scroll Behavior",
|
|
101
|
+
"href": "#scroll-behavior",
|
|
102
|
+
"depth": 3,
|
|
103
|
+
"numbering": [
|
|
104
|
+
1,
|
|
105
|
+
2,
|
|
106
|
+
4
|
|
107
|
+
],
|
|
108
|
+
"parent": "root"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"value": "Controlled State",
|
|
112
|
+
"href": "#controlled-state",
|
|
113
|
+
"depth": 3,
|
|
114
|
+
"numbering": [
|
|
115
|
+
1,
|
|
116
|
+
2,
|
|
117
|
+
5
|
|
118
|
+
],
|
|
119
|
+
"parent": "root"
|
|
120
|
+
}
|
|
121
|
+
],
|
|
122
|
+
"figmaLink": "https://www.figma.com/design/gHbAJGfcrCv7f2bgzUQgHq/NIMBUS-Guidelines?node-id=1695-45519&m",
|
|
123
|
+
"layout": "app-frame",
|
|
124
|
+
"tabs": [
|
|
125
|
+
{
|
|
126
|
+
"key": "overview",
|
|
127
|
+
"title": "Overview",
|
|
128
|
+
"order": 0
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"key": "guidelines",
|
|
132
|
+
"title": "Guidelines",
|
|
133
|
+
"order": 2
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"key": "dev",
|
|
137
|
+
"title": "Implementation",
|
|
138
|
+
"order": 3
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"key": "a11y",
|
|
142
|
+
"title": "Accessibility",
|
|
143
|
+
"order": 4
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
},
|
|
147
|
+
"mdx": "\n## Overview\n\nDialogs are overlay windows that appear on top of the main content to display\nimportant information, gather user input, or require user decisions. They\ntemporarily disable the main interface until the user completes an action or\ndismisses the dialog.\n\n### Key features\n\n- **Accessibility First**: Built with React Aria Components for WCAG 2.1 AA\n compliance\n- **Flexible Positioning**: Support for center, top, and bottom placements\n- **Responsive Sizing**: Multiple size variants from xs to full-screen\n- **Smooth Animations**: Customizable motion presets for entrance/exit\n- **Focus Management**: Automatic focus trapping and restoration\n- **Keyboard Navigation**: Full keyboard support including Escape to close\n- **Scroll Handling**: Options for inside or outside scrolling behavior\n\n### Resources\n\nDeep dive into implementation details and access the Nimbus design library.\n\n[React Aria Dialog Docs](https://react-spectrum.adobe.com/react-aria/Dialog.html)\n[ARIA Dialog Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/)\n[Figma Design Library](https://www.figma.com/design/gHbAJGfcrCv7f2bgzUQgHq/NIMBUS-Guidelines?node-id=1695-45519&m)\n\n## Variables\n\nGet familiar with the features.\n\n### Basic Usage\n\n```jsx live\nconst App = () => (\n <Dialog.Root>\n <Dialog.Trigger>Anything can be a trigger</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Dialog Title</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n This is a basic dialog with default settings. It includes a backdrop,\n title, description, and close button for a complete experience.\n </Dialog.Body>\n <Dialog.Footer>\n <Button variant=\"outline\" slot=\"close\">\n Cancel\n </Button>\n <Button>Save</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n);\n```\n\n### Size\n\nControl the dialog width by applying `width` prop on the Content component, it's\na regular style-prop, so you can use all size-tokens but also custom values.\n\n```jsx live\nconst App = () => (\n <Dialog.Root>\n <Dialog.Trigger asChild>\n <Button>Open Large Dialog</Button>\n </Dialog.Trigger>\n <Dialog.Content width=\"3xl\">\n <Dialog.Header>\n <Dialog.Title>Large Dialog</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n This dialog uses a custom width. You can change the width by adjusting\n the width prop on Dialog.Root to values like \"xs\", \"sm\", \"md\", \"lg\",\n \"xl\", or \"full\", but also raw css values.\n </Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n);\n```\n\n### Placement Options\n\nPosition the dialog at different locations using the `placement` prop:\n\n```jsx live\nconst App = () => {\n const placements = [\n {\n value: \"center\",\n label: \"Center (default)\",\n description: \"Centered in the viewport, works well for most use cases\",\n },\n {\n value: \"top\",\n label: \"Top\",\n description: \"Appears at the top, useful for notifications or alerts\",\n },\n {\n value: \"bottom\",\n label: \"Bottom\",\n description:\n \"Appears at the bottom, good for mobile-friendly sheets or action panels\",\n },\n ];\n\n return (\n <Stack direction=\"row\" gap=\"400\">\n {placements.map((placement) => (\n <Dialog.Root key={placement.value} placement={placement.value}>\n <Dialog.Trigger asChild>\n <Button>{placement.label}</Button>\n </Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>{placement.label} Placement</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>{placement.description}</Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n ))}\n </Stack>\n );\n};\n```\n\n### Scroll Behavior\n\nHandle long content with different scrolling approaches using the\n`scrollBehavior` prop:\n\n```jsx live\nconst App = () => {\n const scrollBehaviors = [\n {\n value: \"outside\",\n label: \"Outside (default)\",\n description: \"Default scroll behavior, entire dialog scrolls\",\n },\n {\n value: \"inside\",\n label: \"Inside\",\n description: \"Contained scrolling within the dialog body\",\n },\n ];\n\n return (\n <Stack direction=\"row\" gap=\"400\">\n {scrollBehaviors.map((behavior) => (\n <Dialog.Root key={behavior.value} scrollBehavior={behavior.value}>\n <Dialog.Trigger asChild>\n <Button>{behavior.label}</Button>\n </Dialog.Trigger>\n <Dialog.Content width=\"sm\">\n <Dialog.Header>\n <Dialog.Title>{behavior.label} Scrolling</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n <Stack>\n <Text>{behavior.description}</Text>\n {Array.from({ length: 20 }, (_, i) => (\n <Text key={i}>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed\n do eiusmod tempor incididunt ut labore et dolore magna\n aliqua.\n </Text>\n ))}\n </Stack>\n </Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n ))}\n </Stack>\n );\n};\n```\n\n### Controlled State\n\nUse external state to control the dialog programmatically:\n\n```jsx live\nconst App = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n\n return (\n <Stack>\n <Button onClick={() => setIsOpen(true)}>Open Controlled Dialog</Button>\n\n <Text>Dialog is currently: {isOpen ? \"open\" : \"closed\"}</Text>\n\n <Dialog.Root isOpen={isOpen} onOpenChange={setIsOpen}>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Controlled Dialog</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n This dialog's state is controlled by the parent component. You can\n open/close it programmatically or through user interaction.\n </Dialog.Body>\n <Dialog.Footer>\n <Button variant=\"outline\" onClick={() => setIsOpen(false)}>\n Cancel\n </Button>\n <Button onClick={() => setIsOpen(false)}>Save</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n </Stack>\n );\n};\n```\n",
|
|
148
|
+
"views": {
|
|
149
|
+
"overview": {
|
|
150
|
+
"mdx": "\n## Overview\n\nDialogs are overlay windows that appear on top of the main content to display\nimportant information, gather user input, or require user decisions. They\ntemporarily disable the main interface until the user completes an action or\ndismisses the dialog.\n\n### Key features\n\n- **Accessibility First**: Built with React Aria Components for WCAG 2.1 AA\n compliance\n- **Flexible Positioning**: Support for center, top, and bottom placements\n- **Responsive Sizing**: Multiple size variants from xs to full-screen\n- **Smooth Animations**: Customizable motion presets for entrance/exit\n- **Focus Management**: Automatic focus trapping and restoration\n- **Keyboard Navigation**: Full keyboard support including Escape to close\n- **Scroll Handling**: Options for inside or outside scrolling behavior\n\n### Resources\n\nDeep dive into implementation details and access the Nimbus design library.\n\n[React Aria Dialog Docs](https://react-spectrum.adobe.com/react-aria/Dialog.html)\n[ARIA Dialog Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/)\n[Figma Design Library](https://www.figma.com/design/gHbAJGfcrCv7f2bgzUQgHq/NIMBUS-Guidelines?node-id=1695-45519&m)\n\n## Variables\n\nGet familiar with the features.\n\n### Basic Usage\n\n```jsx live\nconst App = () => (\n <Dialog.Root>\n <Dialog.Trigger>Anything can be a trigger</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Dialog Title</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n This is a basic dialog with default settings. It includes a backdrop,\n title, description, and close button for a complete experience.\n </Dialog.Body>\n <Dialog.Footer>\n <Button variant=\"outline\" slot=\"close\">\n Cancel\n </Button>\n <Button>Save</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n);\n```\n\n### Size\n\nControl the dialog width by applying `width` prop on the Content component, it's\na regular style-prop, so you can use all size-tokens but also custom values.\n\n```jsx live\nconst App = () => (\n <Dialog.Root>\n <Dialog.Trigger asChild>\n <Button>Open Large Dialog</Button>\n </Dialog.Trigger>\n <Dialog.Content width=\"3xl\">\n <Dialog.Header>\n <Dialog.Title>Large Dialog</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n This dialog uses a custom width. You can change the width by adjusting\n the width prop on Dialog.Root to values like \"xs\", \"sm\", \"md\", \"lg\",\n \"xl\", or \"full\", but also raw css values.\n </Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n);\n```\n\n### Placement Options\n\nPosition the dialog at different locations using the `placement` prop:\n\n```jsx live\nconst App = () => {\n const placements = [\n {\n value: \"center\",\n label: \"Center (default)\",\n description: \"Centered in the viewport, works well for most use cases\",\n },\n {\n value: \"top\",\n label: \"Top\",\n description: \"Appears at the top, useful for notifications or alerts\",\n },\n {\n value: \"bottom\",\n label: \"Bottom\",\n description:\n \"Appears at the bottom, good for mobile-friendly sheets or action panels\",\n },\n ];\n\n return (\n <Stack direction=\"row\" gap=\"400\">\n {placements.map((placement) => (\n <Dialog.Root key={placement.value} placement={placement.value}>\n <Dialog.Trigger asChild>\n <Button>{placement.label}</Button>\n </Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>{placement.label} Placement</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>{placement.description}</Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n ))}\n </Stack>\n );\n};\n```\n\n### Scroll Behavior\n\nHandle long content with different scrolling approaches using the\n`scrollBehavior` prop:\n\n```jsx live\nconst App = () => {\n const scrollBehaviors = [\n {\n value: \"outside\",\n label: \"Outside (default)\",\n description: \"Default scroll behavior, entire dialog scrolls\",\n },\n {\n value: \"inside\",\n label: \"Inside\",\n description: \"Contained scrolling within the dialog body\",\n },\n ];\n\n return (\n <Stack direction=\"row\" gap=\"400\">\n {scrollBehaviors.map((behavior) => (\n <Dialog.Root key={behavior.value} scrollBehavior={behavior.value}>\n <Dialog.Trigger asChild>\n <Button>{behavior.label}</Button>\n </Dialog.Trigger>\n <Dialog.Content width=\"sm\">\n <Dialog.Header>\n <Dialog.Title>{behavior.label} Scrolling</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n <Stack>\n <Text>{behavior.description}</Text>\n {Array.from({ length: 20 }, (_, i) => (\n <Text key={i}>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed\n do eiusmod tempor incididunt ut labore et dolore magna\n aliqua.\n </Text>\n ))}\n </Stack>\n </Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n ))}\n </Stack>\n );\n};\n```\n\n### Controlled State\n\nUse external state to control the dialog programmatically:\n\n```jsx live\nconst App = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n\n return (\n <Stack>\n <Button onClick={() => setIsOpen(true)}>Open Controlled Dialog</Button>\n\n <Text>Dialog is currently: {isOpen ? \"open\" : \"closed\"}</Text>\n\n <Dialog.Root isOpen={isOpen} onOpenChange={setIsOpen}>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Controlled Dialog</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n This dialog's state is controlled by the parent component. You can\n open/close it programmatically or through user interaction.\n </Dialog.Body>\n <Dialog.Footer>\n <Button variant=\"outline\" onClick={() => setIsOpen(false)}>\n Cancel\n </Button>\n <Button onClick={() => setIsOpen(false)}>Save</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n </Stack>\n );\n};\n```\n",
|
|
151
|
+
"toc": [
|
|
152
|
+
{
|
|
153
|
+
"value": "Overview",
|
|
154
|
+
"href": "#overview",
|
|
155
|
+
"depth": 2,
|
|
156
|
+
"numbering": [
|
|
157
|
+
1,
|
|
158
|
+
1
|
|
159
|
+
],
|
|
160
|
+
"parent": "root"
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"value": "Key features",
|
|
164
|
+
"href": "#key-features",
|
|
165
|
+
"depth": 3,
|
|
166
|
+
"numbering": [
|
|
167
|
+
1,
|
|
168
|
+
1,
|
|
169
|
+
1
|
|
170
|
+
],
|
|
171
|
+
"parent": "root"
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"value": "Resources",
|
|
175
|
+
"href": "#resources",
|
|
176
|
+
"depth": 3,
|
|
177
|
+
"numbering": [
|
|
178
|
+
1,
|
|
179
|
+
1,
|
|
180
|
+
2
|
|
181
|
+
],
|
|
182
|
+
"parent": "root"
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"value": "Variables",
|
|
186
|
+
"href": "#variables",
|
|
187
|
+
"depth": 2,
|
|
188
|
+
"numbering": [
|
|
189
|
+
1,
|
|
190
|
+
2
|
|
191
|
+
],
|
|
192
|
+
"parent": "root"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"value": "Basic Usage",
|
|
196
|
+
"href": "#basic-usage",
|
|
197
|
+
"depth": 3,
|
|
198
|
+
"numbering": [
|
|
199
|
+
1,
|
|
200
|
+
2,
|
|
201
|
+
1
|
|
202
|
+
],
|
|
203
|
+
"parent": "root"
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
"value": "Size",
|
|
207
|
+
"href": "#size",
|
|
208
|
+
"depth": 3,
|
|
209
|
+
"numbering": [
|
|
210
|
+
1,
|
|
211
|
+
2,
|
|
212
|
+
2
|
|
213
|
+
],
|
|
214
|
+
"parent": "root"
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"value": "Placement Options",
|
|
218
|
+
"href": "#placement-options",
|
|
219
|
+
"depth": 3,
|
|
220
|
+
"numbering": [
|
|
221
|
+
1,
|
|
222
|
+
2,
|
|
223
|
+
3
|
|
224
|
+
],
|
|
225
|
+
"parent": "root"
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
"value": "Scroll Behavior",
|
|
229
|
+
"href": "#scroll-behavior",
|
|
230
|
+
"depth": 3,
|
|
231
|
+
"numbering": [
|
|
232
|
+
1,
|
|
233
|
+
2,
|
|
234
|
+
4
|
|
235
|
+
],
|
|
236
|
+
"parent": "root"
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"value": "Controlled State",
|
|
240
|
+
"href": "#controlled-state",
|
|
241
|
+
"depth": 3,
|
|
242
|
+
"numbering": [
|
|
243
|
+
1,
|
|
244
|
+
2,
|
|
245
|
+
5
|
|
246
|
+
],
|
|
247
|
+
"parent": "root"
|
|
248
|
+
}
|
|
249
|
+
]
|
|
250
|
+
},
|
|
251
|
+
"a11y": {
|
|
252
|
+
"mdx": "\n## Accessibility\n\nAccessibility ensures that digital content and functionality are usable by\neveryone, including people with disabilities, by addressing visual, auditory,\ncognitive, and physical limitations.\n\n```jsx live\nconst App = () => (\n <Dialog.Root>\n <Dialog.Trigger>\n <Button>Open dialog</Button>\n </Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Dialog Title</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n This is a basic dialog with default settings. It includes a backdrop,\n title, description, and close button for a complete experience.\n </Dialog.Body>\n <Dialog.Footer>\n <Button variant=\"outline\" slot=\"close\">Cancel</Button>\n <Button>Save</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n)\n```\n\n### Accessibility standards\n\n- **Keyboard navigation:** Tab moves focus to next focusable element within\n dialog, Shift + Tab moves to previous element, Escape closes the dialog\n (unless disabled), Enter/Space activates focused button or trigger.\n- **Role identification:** Dialog has `dialog` role with proper labeling.\n- **Focus management:** Focus moves to dialog on open and returns to trigger on\n close.\n- **Focus containment:** Tab navigation stays within dialog boundaries.\n- **Accessible names:** Title and description properly associate with dialog.\n- **State announcements:** Screen readers announce when dialog opens/closes.\n- **Info and relationships:** Proper semantic structure with header, body, and\n footer.\n- **Contrast:** All text meets minimum contrast requirements.\n- **Non-text contrast:** Focus indicators and UI components meet contrast\n standards.\n- **No keyboard trap:** Focus contained but escapable via Escape key.\n- **Focus order:** Logical focus progression through dialog elements.\n- **Focus visible:** Clear focus indicators on all interactive elements.\n- **On focus:** No unexpected context changes when focusing elements.\n- **On input:** Predictable behavior for all user interactions.\n- **Labels or instructions:** Clear labeling and instructions where needed.\n- **Name, role, value:** Proper semantic markup and ARIA attributes.\n- **Status messages:** Appropriate announcements for state changes.\n\n### Resources\n\n- [W3C ARIA Authoring Practices Guide (APG) - Dialog](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/)\n",
|
|
253
|
+
"toc": [
|
|
254
|
+
{
|
|
255
|
+
"value": "Accessibility",
|
|
256
|
+
"href": "#accessibility",
|
|
257
|
+
"depth": 2,
|
|
258
|
+
"numbering": [
|
|
259
|
+
1,
|
|
260
|
+
1
|
|
261
|
+
],
|
|
262
|
+
"parent": "root"
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"value": "Accessibility standards",
|
|
266
|
+
"href": "#accessibility-standards",
|
|
267
|
+
"depth": 3,
|
|
268
|
+
"numbering": [
|
|
269
|
+
1,
|
|
270
|
+
1,
|
|
271
|
+
1
|
|
272
|
+
],
|
|
273
|
+
"parent": "root"
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"value": "Resources",
|
|
277
|
+
"href": "#resources",
|
|
278
|
+
"depth": 3,
|
|
279
|
+
"numbering": [
|
|
280
|
+
1,
|
|
281
|
+
1,
|
|
282
|
+
2
|
|
283
|
+
],
|
|
284
|
+
"parent": "root"
|
|
285
|
+
}
|
|
286
|
+
]
|
|
287
|
+
},
|
|
288
|
+
"dev": {
|
|
289
|
+
"mdx": "\n## Getting started\n\n### Import\n\n```tsx\nimport { Dialog, type DialogRootProps } from '@commercetools/nimbus';\n```\n\n### Basic usage\n\nThe Dialog component uses a compound component pattern. You must wrap all parts in `Dialog.Root`. The component handles focus management, keyboard navigation, and portal rendering automatically.\n\n```jsx live-dev\nconst App = () => (\n <Dialog.Root>\n <Dialog.Trigger>Open Dialog</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Dialog Title</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n <Text>This is the dialog content. It automatically handles focus management and keyboard navigation.</Text>\n </Dialog.Body>\n <Dialog.Footer>\n <Button slot=\"close\" variant=\"outline\">Cancel</Button>\n <Button variant=\"solid\">Confirm</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n)\n```\n\n## Usage examples\n\n### Placement options\n\nThe `placement` prop on `Dialog.Root` controls where the dialog appears in the viewport. Three options are available: `center` (default), `top`, and `bottom`.\n\n```jsx live-dev\nconst App = () => (\n <Stack direction=\"row\" gap=\"400\" flexWrap=\"wrap\">\n <Dialog.Root placement=\"center\">\n <Dialog.Trigger>Center (Default)</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Center Placement</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n <Text>The dialog is centered vertically and horizontally in the viewport.</Text>\n </Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n\n <Dialog.Root placement=\"top\">\n <Dialog.Trigger>Top Placement</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Top Placement</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n <Text>The dialog appears near the top of the viewport with margin spacing.</Text>\n </Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n\n <Dialog.Root placement=\"bottom\">\n <Dialog.Trigger>Bottom Placement</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Bottom Placement</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n <Text>The dialog appears near the bottom of the viewport with margin spacing.</Text>\n </Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n </Stack>\n)\n```\n\n### Scroll behavior\n\nThe `scrollBehavior` prop determines how overflow content is handled. Use `outside` (default) for page-level scrolling or `inside` to confine scrolling to the dialog body.\n\n```jsx live-dev\nconst App = () => {\n const longContent = Array.from({ length: 60 }, (_, i) => (\n <Text key={i}>Line {i + 1} of long content that will cause overflow.</Text>\n ));\n\n return (\n <Stack direction=\"row\" gap=\"400\">\n <Dialog.Root scrollBehavior=\"outside\">\n <Dialog.Trigger>Outside (Default)</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Scroll Outside</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n <Stack direction=\"column\" gap=\"200\">\n <Text fontWeight=\"600\">The entire modal scrolls when content overflows.</Text>\n {longContent}\n </Stack>\n </Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n\n <Dialog.Root scrollBehavior=\"inside\">\n <Dialog.Trigger>Inside Body</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Scroll Inside Body</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n <Stack direction=\"column\" gap=\"200\">\n <Text fontWeight=\"600\">Only the body scrolls; header and footer remain fixed.</Text>\n {longContent}\n </Stack>\n </Dialog.Body>\n <Dialog.Footer>\n <Button slot=\"close\">Close</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n </Stack>\n );\n}\n```\n\n### Uncontrolled mode\n\nThe dialog manages its own open/close state internally without requiring external state management. Use the `defaultOpen` prop if you need the dialog to start open on mount (though this is rarely needed in practice).\n\n```jsx live-dev\nconst App = () => (\n <Dialog.Root>\n <Dialog.Trigger>Open Dialog</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Uncontrolled Dialog</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n <Text>\n This dialog manages its own state. The parent component doesn't need to track whether it's open or closed.\n You can set defaultOpen={'{true}'} on Dialog.Root if you need it to start open on mount.\n </Text>\n </Dialog.Body>\n <Dialog.Footer>\n <Button slot=\"close\" variant=\"outline\">Cancel</Button>\n <Button slot=\"close\">Save</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n)\n```\n\n### Controlled mode\n\nUse `isOpen` and `onOpenChange` to control the dialog state externally. This is essential when you need to open the dialog programmatically or track state changes.\n\n```jsx live-dev\nconst App = () => {\n const [isOpen, setIsOpen] = useState<DialogRootProps[\"isOpen\"]>(false);\n\n return (\n <Stack direction=\"column\" gap=\"400\" alignItems=\"flex-start\">\n <Button onPress={() => setIsOpen(true)}>Open Dialog</Button>\n\n <Text>Dialog state: <Code>{isOpen ? 'Open' : 'Closed'}</Code></Text>\n\n <Dialog.Root isOpen={isOpen} onOpenChange={setIsOpen}>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Controlled Dialog</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n <Text>This dialog's state is controlled externally.</Text>\n </Dialog.Body>\n <Dialog.Footer>\n <Button slot=\"close\" variant=\"outline\">Cancel</Button>\n <Button onPress={() => setIsOpen(false)}>Confirm</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n </Stack>\n );\n}\n```\n\n### Dismissal behavior\n\nControl how users can close the dialog using three props: `isDismissable`, `isKeyboardDismissDisabled`, and `shouldCloseOnInteractOutside`. These work together to create the right dismissal behavior for your use case.\n\n#### Default\n\nBy default, dialogs can only be closed with the Escape key or close buttons. Clicking the backdrop does nothing. This is the standard behavior for most dialogs.\n\n```jsx live-dev\nconst App = () => (\n <Dialog.Root>\n <Dialog.Trigger>Default Behavior</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Default Dismissal</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n <Stack direction=\"column\" gap=\"200\">\n <Text fontWeight=\"600\">Can be closed by:</Text>\n <Text>✓ Escape key</Text>\n <Text>✓ Close button</Text>\n <Text>✗ Clicking backdrop (does nothing)</Text>\n </Stack>\n </Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n)\n```\n\n#### Dismissable Dialogs\n\nUse `isDismissable={true}` for non-critical dialogs like notifications or informational content where users should be able to quickly dismiss by clicking outside.\n\n```jsx live-dev\nconst App = () => (\n <Dialog.Root isDismissable>\n <Dialog.Trigger>Dismissible Notification</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Quick Notification</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n <Stack direction=\"column\" gap=\"200\">\n <Text>Use isDismissable={'{true}'} for non-critical dialogs.</Text>\n <Text fontWeight=\"600\">Can be closed by:</Text>\n <Text>✓ Escape key</Text>\n <Text>✓ Close button</Text>\n <Text>✓ Clicking backdrop</Text>\n </Stack>\n </Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n)\n```\n\n#### Critical Confirmations\n\nUse `isKeyboardDismissDisabled={true}` for critical confirmations where you need to ensure users explicitly choose an action rather than accidentally dismissing.\n\n```jsx live-dev\nconst App = () => (\n <Dialog.Root isKeyboardDismissDisabled>\n <Dialog.Trigger>Critical Action</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Confirm Deletion</Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>\n <Stack direction=\"column\" gap=\"200\">\n <Text>Use isKeyboardDismissDisabled={'{true}'} for critical confirmations.</Text>\n <Text fontWeight=\"600\">Can be closed by:</Text>\n <Text>✓ Close button only</Text>\n <Text>✗ Escape key (disabled)</Text>\n <Text>✗ Clicking backdrop (does nothing)</Text>\n </Stack>\n </Dialog.Body>\n <Dialog.Footer>\n <Button slot=\"close\" variant=\"outline\">Cancel</Button>\n <Button colorPalette=\"critical\">Delete</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n)\n```\n\n#### Conditional dismissal\n\nCombine `isDismissable` with `isKeyboardDismissDisabled` & `shouldCloseOnInteractOutside` to implement custom logic, such as protecting unsaved form changes.\nThis example prevents backdrop and keyboard dismissal when there are unsaved changes.\n\n```jsx live-dev\nconst App = () => {\n const [formData, setFormData] = useState('');\n const [lastAction, setLastAction] = useState('');\n\n const hasUnsavedChanges = formData.length > 0;\n\n const canBeClosed = () => {\n if (hasUnsavedChanges) {\n setLastAction('Prevented - unsaved changes detected');\n alert('Unsaved changes detected');\n return false;\n }\n setLastAction('Allowed - no unsaved changes');\n return true;\n }\n\n return (\n <Stack direction=\"column\" gap=\"400\">\n <Text fontSize=\"sm\" color=\"fg.muted\">\n Last dismissal attempt: {lastAction || 'None'}\n </Text>\n\n <Dialog.Root\n isDismissable\n isKeyboardDismissDisabled={hasUnsavedChanges}\n shouldCloseOnInteractOutside={canBeClosed}\n >\n <Dialog.Trigger>Form with Protection</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Edit Profile</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n <Stack direction=\"column\" gap=\"400\">\n <Text>\n Combines isDismissable with shouldCloseOnInteractOutside to protect unsaved work.\n Try typing, then clicking outside.\n </Text>\n <TextInput\n placeholder=\"Your name\"\n value={formData}\n onChange={(value) => setFormData(value)}\n />\n <Text fontSize=\"sm\">\n Unsaved changes: <Code>{hasUnsavedChanges ? 'Yes' : 'No'}</Code>\n </Text>\n </Stack>\n </Dialog.Body>\n <Dialog.Footer>\n <Button\n slot=\"close\"\n variant=\"outline\"\n onPress={() => setFormData('')}\n >\n Cancel\n </Button>\n <Button onPress={() => {\n setFormData('');\n setLastAction('Saved and closed');\n }}>\n Save\n </Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n </Stack>\n );\n}\n```\n\n### Flexible composition\n\nThe dialog parts are composable. You can omit optional parts based on your needs. These real-world examples demonstrate when and why to use different compositions.\n\n#### Order cancellation with full context\n\nUse the complete structure (header, body, footer) when users need detailed information before making a decision. This e-commerce example shows refund implications before confirming cancellation.\n\n```jsx live-dev\nconst App = () => {\n const [isCancelling, setIsCancelling] = useState(false);\n const [isOpen, setIsOpen] = useState<DialogRootProps[\"isOpen\"]>(false);\n\n const handleCancel = () => {\n setIsCancelling(true);\n // Simulate API call\n setTimeout(() => {\n setIsCancelling(false);\n setIsOpen(false);\n alert('Order #12345 has been cancelled. Refund will be processed in 3-5 business days.');\n }, 1500);\n };\n\n return (\n <Dialog.Root isOpen={isOpen} onOpenChange={setIsOpen}>\n <Dialog.Trigger>Cancel Order</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Cancel Order #12345</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n <Stack direction=\"column\" gap=\"400\">\n <Text>\n Are you sure you want to cancel this order? This action will:\n </Text>\n <Stack direction=\"column\" gap=\"200\" paddingLeft=\"400\">\n <Text>• Process a full refund to your original payment method</Text>\n <Text>• Stop the shipment if it hasn't been dispatched</Text>\n <Text>• Send a cancellation confirmation email</Text>\n </Stack>\n <Text fontSize=\"sm\" color=\"fg.muted\">\n Refunds typically take 3-5 business days to appear in your account.\n </Text>\n </Stack>\n </Dialog.Body>\n <Dialog.Footer>\n <Button slot=\"close\" variant=\"outline\" isDisabled={isCancelling}>\n Keep Order\n </Button>\n <Button\n colorPalette=\"critical\"\n onPress={handleCancel}\n isLoading={isCancelling}\n >\n Cancel Order\n </Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n```\n\n#### Feature announcement without footer\n\nOmit the footer when actions are embedded in the body content or when only dismissal is needed. This pattern works well for informational dialogs with inline calls-to-action.\n\n```jsx live-dev\nconst App = () => (\n <Dialog.Root>\n <Dialog.Trigger>What's New</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>New Dashboard Available</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n <Stack direction=\"column\" gap=\"400\">\n <Text>\n We've redesigned the analytics dashboard with enhanced data visualization,\n real-time updates, and customizable widgets.\n </Text>\n <Stack direction=\"column\" gap=\"200\">\n <Text fontWeight=\"600\">Key improvements:</Text>\n <Text>• Interactive charts with drill-down capabilities</Text>\n <Text>• Custom date range filtering</Text>\n <Text>• Export reports in multiple formats</Text>\n </Stack>\n <Button variant=\"solid\" width=\"full\">\n Explore New Dashboard\n </Button>\n </Stack>\n </Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n)\n```\n\n#### Processing state without actions\n\nOmit the footer entirely when showing non-interruptible processes. Users can't take action until the operation completes, so only the header and progress information are needed.\n\n```jsx live-dev\nconst App = () => {\n const [isOpen, setIsOpen] = useState<DialogRootProps[\"isOpen\"]>(false);\n const [progress, setProgress] = useState(0);\n const [deletedCount, setDeletedCount] = useState(0);\n const totalItems = 247;\n\n const startDeletion = () => {\n setIsOpen(true);\n setProgress(0);\n setDeletedCount(0);\n\n // Simulate progressive deletion\n const interval = setInterval(() => {\n setProgress((prev) => {\n const newProgress = prev + 5;\n if (newProgress >= 100) {\n clearInterval(interval);\n setTimeout(() => {\n setIsOpen(false);\n alert(`Successfully deleted ${totalItems} products`);\n }, 500);\n return 100;\n }\n return newProgress;\n });\n setDeletedCount((prev) => Math.min(prev + 12, totalItems));\n }, 200);\n };\n\n return (\n <Stack direction=\"column\" gap=\"400\">\n <Button onPress={startDeletion}>Delete 247 Products</Button>\n <Dialog.Root\n isOpen={isOpen}\n onOpenChange={setIsOpen}\n isDismissable={false}\n isKeyboardDismissDisabled\n >\n <Dialog.Content width=\"sm\">\n <Dialog.Header>\n <Dialog.Title>Deleting Products</Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>\n <Stack direction=\"column\" gap=\"400\">\n <Text>\n Please wait while we delete the selected products. This may take a moment.\n </Text>\n <Stack direction=\"column\" gap=\"200\">\n <Text fontSize=\"sm\" color=\"fg.muted\">\n {deletedCount} of {totalItems} products deleted\n </Text>\n <Box\n width=\"full\"\n height=\"8px\"\n backgroundColor=\"neutral.3\"\n borderRadius=\"full\"\n overflow=\"hidden\"\n >\n <Box\n height=\"full\"\n width={`${progress}%`}\n backgroundColor=\"primary.9\"\n transition=\"width 0.2s\"\n />\n </Box>\n </Stack>\n </Stack>\n </Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n </Stack>\n );\n}\n```\n\n## Component requirements\n\n## Accessibility\n\nThe `Dialog` component is built with React Aria Components and follows WCAG 2.1 AA guidelines:\n\n- **Role**: The dialog content has `role=\"dialog\"` and is properly labeled using either `Dialog.Title` or an `aria-label` prop on `Dialog.Root`.\n- **Focus Management**: When opened, focus moves to the first focusable element inside the dialog. When closed, focus returns to the trigger element.\n- **Keyboard Navigation**:\n - `Escape` - Closes the dialog (unless `isKeyboardDismissDisabled` is true)\n - `Tab` - Moves focus through interactive elements within the dialog\n - Focus is trapped within the dialog while open\n- **Labeling**: The `Dialog.Title` component automatically provides the accessible name. If you don't use `Dialog.Title`, provide an `aria-label` on `Dialog.Root`.\n- **Backdrop**: Clicking outside the dialog closes it by default (controlled by `isDismissable`).\n\nIf your use case requires tracking and analytics for this component, it is good practice to add a **persistent**, **unique** id to the component:\n\n```tsx\nconst PERSISTENT_ID = \"confirm-delete-dialog\";\n\nexport const DeleteConfirmation = () => (\n <Dialog.Root id={PERSISTENT_ID}>\n <Dialog.Trigger>Delete Item</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Title>Confirm Deletion</Dialog.Title>\n </Dialog.Content>\n </Dialog.Root>\n);\n```\n\n### Composition constraints\n\nThe `Dialog` component uses specific layout slots for proper rendering:\n\n- Keep sub-components (`Header`, `Body`, `Footer`, `Title`, `CloseTrigger`) as direct children of `Dialog.Content`.\n- `Dialog.Title` should be placed inside `Dialog.Header` for proper layout.\n- `Dialog.CloseTrigger` can be placed anywhere but is typically in `Dialog.Header`.\n- You can use layout components *inside* `Dialog.Body` or `Dialog.Footer` to organize content within those sections.\n- The `Dialog.Content` is portaled to the document body by React Aria, so it renders outside your component tree.\n\n## Common patterns\n\n### Confirmation dialogs\n\nUse dialogs to confirm destructive actions. Make the intent clear with appropriate button variants.\n\n```jsx live-dev\nconst App = () => {\n const [isDeleting, setIsDeleting] = useState(false);\n const [isOpen, setIsOpen] = useState<DialogRootProps[\"isOpen\"]>(false);\n\n const handleDelete = () => {\n setIsDeleting(true);\n // Simulate async delete operation\n setTimeout(() => {\n setIsDeleting(false);\n setIsOpen(false);\n alert('Item deleted successfully');\n }, 1500);\n };\n\n return (\n <Dialog.Root isOpen={isOpen} onOpenChange={setIsOpen}>\n <Dialog.Trigger>Delete Item</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>Confirm Deletion</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n <Text>\n Are you sure you want to delete this item? This action cannot be undone.\n </Text>\n </Dialog.Body>\n <Dialog.Footer>\n <Button slot=\"close\" variant=\"outline\" isDisabled={isDeleting}>\n Cancel\n </Button>\n <Button\n colorPalette=\"critical\"\n onPress={handleDelete}\n isLoading={isDeleting}\n >\n Delete\n </Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n```\n\n### Form dialogs\n\nDialogs can contain forms for data entry. Use controlled mode to handle form submission and validation.\n\n```jsx live-dev\nconst App = () => {\n const [isOpen, setIsOpen] = useState<DialogRootProps[\"isOpen\"]>(false);\n const [formData, setFormData] = useState({ name: '', email: '' });\n const [isSaving, setIsSaving] = useState(false);\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n setIsSaving(true);\n // Simulate async save\n setTimeout(() => {\n setIsSaving(false);\n setIsOpen(false);\n alert(`Saved: ${formData.name} (${formData.email})`);\n setFormData({ name: '', email: '' });\n }, 1500);\n };\n\n return (\n <Dialog.Root isOpen={isOpen} onOpenChange={setIsOpen}>\n <Dialog.Trigger>Add User</Dialog.Trigger>\n <Dialog.Content>\n <form onSubmit={handleSubmit}>\n <Dialog.Header>\n <Dialog.Title>Create New User</Dialog.Title>\n <Dialog.CloseTrigger />\n </Dialog.Header>\n <Dialog.Body>\n <Stack direction=\"column\" gap=\"400\">\n <FormField.Root>\n <FormField.Label>Name</FormField.Label>\n <FormField.Input>\n <TextInput\n value={formData.name}\n onChange={(value) => setFormData({ ...formData, name: value })}\n required\n />\n </FormField.Input>\n </FormField.Root>\n\n <FormField.Root>\n <FormField.Label>Email</FormField.Label>\n <FormField.Input>\n <TextInput\n type=\"email\"\n value={formData.email}\n onChange={(value) => setFormData({ ...formData, email: value })}\n required\n />\n </FormField.Input>\n </FormField.Root>\n </Stack>\n </Dialog.Body>\n <Dialog.Footer>\n <Button\n slot=\"close\"\n variant=\"outline\"\n isDisabled={isSaving}\n onPress={() => setFormData({ name: '', email: '' })}\n >\n Cancel\n </Button>\n <Button type=\"submit\" isLoading={isSaving}>\n Create User\n </Button>\n </Dialog.Footer>\n </form>\n </Dialog.Content>\n </Dialog.Root>\n );\n}\n```\n\n### Alert dialogs\n\nFor important messages that require acknowledgment. Consider making these non-dismissable to ensure users see the message.\n\n```jsx live-dev\nconst App = () => (\n <Dialog.Root isDismissable={false}>\n <Dialog.Trigger>Show Alert</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Header>\n <Dialog.Title>System Maintenance</Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>\n <Stack direction=\"column\" gap=\"300\">\n <Text>\n The system will undergo scheduled maintenance on Saturday at 2:00 AM UTC.\n During this time, the service will be unavailable for approximately 30 minutes.\n </Text>\n <Text fontWeight=\"600\">\n Please save your work and plan accordingly.\n </Text>\n </Stack>\n </Dialog.Body>\n <Dialog.Footer>\n <Button slot=\"close\">I Understand</Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n)\n```\n### Keyboard navigation\n\n| Key | Action |\n|-----|--------|\n| `Tab` | Move focus to next focusable element within dialog |\n| `Shift + Tab` | Move focus to previous focusable element within dialog |\n| `Escape` | Close the dialog (unless disabled) |\n| `Enter/Space` | Activate focused button or trigger |\n\n## API reference\n\n<PropsTable id=\"Dialog\" />\n\n## Testing your implementation\n\nThese examples demonstrate how to test your implementation when using Dialog within your application. As the component's internal functionality is already tested by Nimbus, these patterns help you verify your integration and application-specific logic.\n\n### Basic Rendering Tests\n\nVerify the dialog renders with expected elements\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen, waitFor } from \"@testing-library/react\";\nimport { userEvent } from \"@testing-library/user-event\";\nimport { useState } from \"react\";\nimport {\n Dialog,\n Button,\n TextInput,\n NimbusProvider,\n} from \"@commercetools/nimbus\";\n\ndescribe(\"Dialog - Basic rendering\", () => {\n it(\"renders trigger button\", () => {\n render(\n <NimbusProvider>\n <Dialog.Root>\n <Dialog.Trigger>Open Dialog</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Body>Content</Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n </NimbusProvider>\n );\n\n expect(\n screen.getByRole(\"button\", { name: \"Open Dialog\" })\n ).toBeInTheDocument();\n });\n});\n```\n\n### Opening and Closing Interaction Tests\n\nTest opening and closing the dialog\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen, waitFor } from \"@testing-library/react\";\nimport { userEvent } from \"@testing-library/user-event\";\nimport { useState } from \"react\";\nimport {\n Dialog,\n Button,\n TextInput,\n NimbusProvider,\n} from \"@commercetools/nimbus\";\n\ndescribe(\"Dialog - Opening and closing\", () => {\n it(\"opens dialog when trigger is clicked\", async () => {\n const user = userEvent.setup();\n\n render(\n <NimbusProvider>\n <Dialog.Root>\n <Dialog.Trigger>Open</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Title>Test Dialog</Dialog.Title>\n <Dialog.Body>Dialog content</Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n </NimbusProvider>\n );\n\n await user.click(screen.getByRole(\"button\", { name: \"Open\" }));\n\n await waitFor(() => {\n expect(screen.getByRole(\"dialog\")).toBeInTheDocument();\n expect(screen.getByText(\"Dialog content\")).toBeInTheDocument();\n });\n });\n\n it(\"closes dialog when close trigger is clicked\", async () => {\n const user = userEvent.setup();\n\n render(\n <NimbusProvider>\n <Dialog.Root>\n <Dialog.Trigger>Open</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Title>Test Dialog</Dialog.Title>\n <Dialog.Body>Content</Dialog.Body>\n <Dialog.CloseTrigger />\n </Dialog.Content>\n </Dialog.Root>\n </NimbusProvider>\n );\n\n // Open dialog\n await user.click(screen.getByRole(\"button\", { name: \"Open\" }));\n await waitFor(() => expect(screen.getByRole(\"dialog\")).toBeInTheDocument());\n\n // Close dialog\n await user.click(screen.getByRole(\"button\", { name: \"Close dialog\" }));\n\n await waitFor(() => {\n expect(screen.queryByRole(\"dialog\")).not.toBeInTheDocument();\n });\n });\n});\n```\n\n### Controlled Mode Tests\n\nTest controlled component behavior\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen, waitFor } from \"@testing-library/react\";\nimport { userEvent } from \"@testing-library/user-event\";\nimport { useState } from \"react\";\nimport {\n Dialog,\n Button,\n TextInput,\n NimbusProvider,\n} from \"@commercetools/nimbus\";\n\ndescribe(\"Dialog - Controlled mode\", () => {\n const ControlledDialog = () => {\n const [isOpen, setIsOpen] = useState(false);\n\n return (\n <NimbusProvider>\n <Button onPress={() => setIsOpen(true)}>Open External</Button>\n <Dialog.Root isOpen={isOpen} onOpenChange={setIsOpen}>\n <Dialog.Content>\n <Dialog.Title>Controlled Dialog</Dialog.Title>\n <Dialog.Body>Content</Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n </NimbusProvider>\n );\n };\n\n it(\"opens dialog via external control\", async () => {\n const user = userEvent.setup();\n render(<ControlledDialog />);\n\n await user.click(screen.getByRole(\"button\", { name: \"Open External\" }));\n\n await waitFor(() => {\n expect(screen.getByRole(\"dialog\")).toBeInTheDocument();\n });\n });\n});\n```\n\n### Form Submission Tests\n\nTest form handling within dialogs\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen, waitFor } from \"@testing-library/react\";\nimport { userEvent } from \"@testing-library/user-event\";\nimport { useState } from \"react\";\nimport {\n Dialog,\n Button,\n TextInput,\n NimbusProvider,\n} from \"@commercetools/nimbus\";\n\ndescribe(\"Dialog - Form submission\", () => {\n const FormDialog = ({\n onSubmit,\n }: {\n onSubmit: (data: { name: string }) => void;\n }) => {\n const [name, setName] = useState(\"\");\n\n return (\n <NimbusProvider>\n <Dialog.Root>\n <Dialog.Trigger>Add User</Dialog.Trigger>\n <Dialog.Content>\n <form\n onSubmit={(e) => {\n e.preventDefault();\n onSubmit({ name });\n }}\n >\n <Dialog.Header>\n <Dialog.Title>Create User</Dialog.Title>\n </Dialog.Header>\n <Dialog.Body>\n <TextInput\n aria-label=\"Name\"\n placeholder=\"Name\"\n value={name}\n onChange={(value) => setName(value)}\n />\n </Dialog.Body>\n <Dialog.Footer>\n <Button type=\"submit\">Create</Button>\n </Dialog.Footer>\n </form>\n </Dialog.Content>\n </Dialog.Root>\n </NimbusProvider>\n );\n };\n\n it(\"submits form with entered data\", async () => {\n const user = userEvent.setup();\n const handleSubmit = vi.fn();\n\n render(<FormDialog onSubmit={handleSubmit} />);\n\n // Open dialog\n await user.click(screen.getByRole(\"button\", { name: \"Add User\" }));\n await waitFor(() => expect(screen.getByRole(\"dialog\")).toBeInTheDocument());\n\n // Fill form\n await user.type(screen.getByPlaceholderText(\"Name\"), \"John Doe\");\n\n // Submit\n await user.click(screen.getByRole(\"button\", { name: \"Create\" }));\n\n expect(handleSubmit).toHaveBeenCalledWith({ name: \"John Doe\" });\n });\n});\n```\n\n### Keyboard Navigation Tests\n\nTest keyboard interactions\n\n```tsx\nimport { describe, it, expect, vi } from \"vitest\";\nimport { render, screen, waitFor } from \"@testing-library/react\";\nimport { userEvent } from \"@testing-library/user-event\";\nimport { useState } from \"react\";\nimport {\n Dialog,\n Button,\n TextInput,\n NimbusProvider,\n} from \"@commercetools/nimbus\";\n\ndescribe(\"Dialog - Keyboard navigation\", () => {\n it(\"closes dialog when Escape is pressed\", async () => {\n const user = userEvent.setup();\n\n render(\n <NimbusProvider>\n <Dialog.Root>\n <Dialog.Trigger>Open</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Title>Test Dialog</Dialog.Title>\n <Dialog.Body>Content</Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n </NimbusProvider>\n );\n\n // Open dialog\n await user.click(screen.getByRole(\"button\", { name: \"Open\" }));\n await waitFor(() => expect(screen.getByRole(\"dialog\")).toBeInTheDocument());\n\n // Press Escape\n await user.keyboard(\"{Escape}\");\n\n await waitFor(() => {\n expect(screen.queryByRole(\"dialog\")).not.toBeInTheDocument();\n });\n });\n\n it(\"does not close when Escape is disabled\", async () => {\n const user = userEvent.setup();\n\n render(\n <NimbusProvider>\n <Dialog.Root isKeyboardDismissDisabled>\n <Dialog.Trigger>Open</Dialog.Trigger>\n <Dialog.Content>\n <Dialog.Title>Test Dialog</Dialog.Title>\n <Dialog.Body>Content</Dialog.Body>\n </Dialog.Content>\n </Dialog.Root>\n </NimbusProvider>\n );\n\n await user.click(screen.getByRole(\"button\", { name: \"Open\" }));\n await waitFor(() => expect(screen.getByRole(\"dialog\")).toBeInTheDocument());\n\n await user.keyboard(\"{Escape}\");\n\n // Dialog should still be open\n expect(screen.getByRole(\"dialog\")).toBeInTheDocument();\n });\n});\n```\n\n\n## Resources\n\n- [Dialog Storybook](https://nimbus-storybook.vercel.app/?path=/docs/components-overlay-dialog--docs)\n- [React Aria Dialog Documentation](https://react-spectrum.adobe.com/react-aria/Dialog.html)\n- [ARIA Dialog Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/)\n",
|
|
290
|
+
"toc": [
|
|
291
|
+
{
|
|
292
|
+
"value": "Getting started",
|
|
293
|
+
"href": "#getting-started",
|
|
294
|
+
"depth": 2,
|
|
295
|
+
"numbering": [
|
|
296
|
+
1,
|
|
297
|
+
1
|
|
298
|
+
],
|
|
299
|
+
"parent": "root"
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
"value": "Import",
|
|
303
|
+
"href": "#import",
|
|
304
|
+
"depth": 3,
|
|
305
|
+
"numbering": [
|
|
306
|
+
1,
|
|
307
|
+
1,
|
|
308
|
+
1
|
|
309
|
+
],
|
|
310
|
+
"parent": "root"
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"value": "Basic usage",
|
|
314
|
+
"href": "#basic-usage",
|
|
315
|
+
"depth": 3,
|
|
316
|
+
"numbering": [
|
|
317
|
+
1,
|
|
318
|
+
1,
|
|
319
|
+
2
|
|
320
|
+
],
|
|
321
|
+
"parent": "root"
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
"value": "Usage examples",
|
|
325
|
+
"href": "#usage-examples",
|
|
326
|
+
"depth": 2,
|
|
327
|
+
"numbering": [
|
|
328
|
+
1,
|
|
329
|
+
2
|
|
330
|
+
],
|
|
331
|
+
"parent": "root"
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
"value": "Placement options",
|
|
335
|
+
"href": "#placement-options",
|
|
336
|
+
"depth": 3,
|
|
337
|
+
"numbering": [
|
|
338
|
+
1,
|
|
339
|
+
2,
|
|
340
|
+
1
|
|
341
|
+
],
|
|
342
|
+
"parent": "root"
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
"value": "Scroll behavior",
|
|
346
|
+
"href": "#scroll-behavior",
|
|
347
|
+
"depth": 3,
|
|
348
|
+
"numbering": [
|
|
349
|
+
1,
|
|
350
|
+
2,
|
|
351
|
+
2
|
|
352
|
+
],
|
|
353
|
+
"parent": "root"
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
"value": "Uncontrolled mode",
|
|
357
|
+
"href": "#uncontrolled-mode",
|
|
358
|
+
"depth": 3,
|
|
359
|
+
"numbering": [
|
|
360
|
+
1,
|
|
361
|
+
2,
|
|
362
|
+
3
|
|
363
|
+
],
|
|
364
|
+
"parent": "root"
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
"value": "Controlled mode",
|
|
368
|
+
"href": "#controlled-mode",
|
|
369
|
+
"depth": 3,
|
|
370
|
+
"numbering": [
|
|
371
|
+
1,
|
|
372
|
+
2,
|
|
373
|
+
4
|
|
374
|
+
],
|
|
375
|
+
"parent": "root"
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
"value": "Dismissal behavior",
|
|
379
|
+
"href": "#dismissal-behavior",
|
|
380
|
+
"depth": 3,
|
|
381
|
+
"numbering": [
|
|
382
|
+
1,
|
|
383
|
+
2,
|
|
384
|
+
5
|
|
385
|
+
],
|
|
386
|
+
"parent": "root"
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
"value": "Default",
|
|
390
|
+
"href": "#default",
|
|
391
|
+
"depth": 4,
|
|
392
|
+
"numbering": [
|
|
393
|
+
1,
|
|
394
|
+
2,
|
|
395
|
+
5,
|
|
396
|
+
1
|
|
397
|
+
],
|
|
398
|
+
"parent": "root"
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
"value": "Dismissable Dialogs",
|
|
402
|
+
"href": "#dismissable-dialogs",
|
|
403
|
+
"depth": 4,
|
|
404
|
+
"numbering": [
|
|
405
|
+
1,
|
|
406
|
+
2,
|
|
407
|
+
5,
|
|
408
|
+
2
|
|
409
|
+
],
|
|
410
|
+
"parent": "root"
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
"value": "Critical Confirmations",
|
|
414
|
+
"href": "#critical-confirmations",
|
|
415
|
+
"depth": 4,
|
|
416
|
+
"numbering": [
|
|
417
|
+
1,
|
|
418
|
+
2,
|
|
419
|
+
5,
|
|
420
|
+
3
|
|
421
|
+
],
|
|
422
|
+
"parent": "root"
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
"value": "Conditional dismissal",
|
|
426
|
+
"href": "#conditional-dismissal",
|
|
427
|
+
"depth": 4,
|
|
428
|
+
"numbering": [
|
|
429
|
+
1,
|
|
430
|
+
2,
|
|
431
|
+
5,
|
|
432
|
+
4
|
|
433
|
+
],
|
|
434
|
+
"parent": "root"
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
"value": "Flexible composition",
|
|
438
|
+
"href": "#flexible-composition",
|
|
439
|
+
"depth": 3,
|
|
440
|
+
"numbering": [
|
|
441
|
+
1,
|
|
442
|
+
2,
|
|
443
|
+
6
|
|
444
|
+
],
|
|
445
|
+
"parent": "root"
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
"value": "Order cancellation with full context",
|
|
449
|
+
"href": "#order-cancellation-with-full-context",
|
|
450
|
+
"depth": 4,
|
|
451
|
+
"numbering": [
|
|
452
|
+
1,
|
|
453
|
+
2,
|
|
454
|
+
6,
|
|
455
|
+
1
|
|
456
|
+
],
|
|
457
|
+
"parent": "root"
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
"value": "Feature announcement without footer",
|
|
461
|
+
"href": "#feature-announcement-without-footer",
|
|
462
|
+
"depth": 4,
|
|
463
|
+
"numbering": [
|
|
464
|
+
1,
|
|
465
|
+
2,
|
|
466
|
+
6,
|
|
467
|
+
2
|
|
468
|
+
],
|
|
469
|
+
"parent": "root"
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
"value": "Processing state without actions",
|
|
473
|
+
"href": "#processing-state-without-actions",
|
|
474
|
+
"depth": 4,
|
|
475
|
+
"numbering": [
|
|
476
|
+
1,
|
|
477
|
+
2,
|
|
478
|
+
6,
|
|
479
|
+
3
|
|
480
|
+
],
|
|
481
|
+
"parent": "root"
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
"value": "Component requirements",
|
|
485
|
+
"href": "#component-requirements",
|
|
486
|
+
"depth": 2,
|
|
487
|
+
"numbering": [
|
|
488
|
+
1,
|
|
489
|
+
3
|
|
490
|
+
],
|
|
491
|
+
"parent": "root"
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
"value": "Accessibility",
|
|
495
|
+
"href": "#accessibility",
|
|
496
|
+
"depth": 2,
|
|
497
|
+
"numbering": [
|
|
498
|
+
1,
|
|
499
|
+
4
|
|
500
|
+
],
|
|
501
|
+
"parent": "root"
|
|
502
|
+
},
|
|
503
|
+
{
|
|
504
|
+
"value": "Composition constraints",
|
|
505
|
+
"href": "#composition-constraints",
|
|
506
|
+
"depth": 3,
|
|
507
|
+
"numbering": [
|
|
508
|
+
1,
|
|
509
|
+
4,
|
|
510
|
+
1
|
|
511
|
+
],
|
|
512
|
+
"parent": "root"
|
|
513
|
+
},
|
|
514
|
+
{
|
|
515
|
+
"value": "Common patterns",
|
|
516
|
+
"href": "#common-patterns",
|
|
517
|
+
"depth": 2,
|
|
518
|
+
"numbering": [
|
|
519
|
+
1,
|
|
520
|
+
5
|
|
521
|
+
],
|
|
522
|
+
"parent": "root"
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
"value": "Confirmation dialogs",
|
|
526
|
+
"href": "#confirmation-dialogs",
|
|
527
|
+
"depth": 3,
|
|
528
|
+
"numbering": [
|
|
529
|
+
1,
|
|
530
|
+
5,
|
|
531
|
+
1
|
|
532
|
+
],
|
|
533
|
+
"parent": "root"
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
"value": "Form dialogs",
|
|
537
|
+
"href": "#form-dialogs",
|
|
538
|
+
"depth": 3,
|
|
539
|
+
"numbering": [
|
|
540
|
+
1,
|
|
541
|
+
5,
|
|
542
|
+
2
|
|
543
|
+
],
|
|
544
|
+
"parent": "root"
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
"value": "Alert dialogs",
|
|
548
|
+
"href": "#alert-dialogs",
|
|
549
|
+
"depth": 3,
|
|
550
|
+
"numbering": [
|
|
551
|
+
1,
|
|
552
|
+
5,
|
|
553
|
+
3
|
|
554
|
+
],
|
|
555
|
+
"parent": "root"
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
"value": "Keyboard navigation",
|
|
559
|
+
"href": "#keyboard-navigation",
|
|
560
|
+
"depth": 3,
|
|
561
|
+
"numbering": [
|
|
562
|
+
1,
|
|
563
|
+
5,
|
|
564
|
+
4
|
|
565
|
+
],
|
|
566
|
+
"parent": "root"
|
|
567
|
+
},
|
|
568
|
+
{
|
|
569
|
+
"value": "API reference",
|
|
570
|
+
"href": "#api-reference",
|
|
571
|
+
"depth": 2,
|
|
572
|
+
"numbering": [
|
|
573
|
+
1,
|
|
574
|
+
6
|
|
575
|
+
],
|
|
576
|
+
"parent": "root"
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
"value": "Testing your implementation",
|
|
580
|
+
"href": "#testing-your-implementation",
|
|
581
|
+
"depth": 2,
|
|
582
|
+
"numbering": [
|
|
583
|
+
1,
|
|
584
|
+
7
|
|
585
|
+
],
|
|
586
|
+
"parent": "root"
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
"value": "Basic Rendering Tests",
|
|
590
|
+
"href": "#basic-rendering-tests",
|
|
591
|
+
"depth": 3,
|
|
592
|
+
"numbering": [
|
|
593
|
+
1,
|
|
594
|
+
7,
|
|
595
|
+
1
|
|
596
|
+
],
|
|
597
|
+
"parent": "root"
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
"value": "Opening and Closing Interaction Tests",
|
|
601
|
+
"href": "#opening-and-closing-interaction-tests",
|
|
602
|
+
"depth": 3,
|
|
603
|
+
"numbering": [
|
|
604
|
+
1,
|
|
605
|
+
7,
|
|
606
|
+
2
|
|
607
|
+
],
|
|
608
|
+
"parent": "root"
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
"value": "Controlled Mode Tests",
|
|
612
|
+
"href": "#controlled-mode-tests",
|
|
613
|
+
"depth": 3,
|
|
614
|
+
"numbering": [
|
|
615
|
+
1,
|
|
616
|
+
7,
|
|
617
|
+
3
|
|
618
|
+
],
|
|
619
|
+
"parent": "root"
|
|
620
|
+
},
|
|
621
|
+
{
|
|
622
|
+
"value": "Form Submission Tests",
|
|
623
|
+
"href": "#form-submission-tests",
|
|
624
|
+
"depth": 3,
|
|
625
|
+
"numbering": [
|
|
626
|
+
1,
|
|
627
|
+
7,
|
|
628
|
+
4
|
|
629
|
+
],
|
|
630
|
+
"parent": "root"
|
|
631
|
+
},
|
|
632
|
+
{
|
|
633
|
+
"value": "Keyboard Navigation Tests",
|
|
634
|
+
"href": "#keyboard-navigation-tests",
|
|
635
|
+
"depth": 3,
|
|
636
|
+
"numbering": [
|
|
637
|
+
1,
|
|
638
|
+
7,
|
|
639
|
+
5
|
|
640
|
+
],
|
|
641
|
+
"parent": "root"
|
|
642
|
+
},
|
|
643
|
+
{
|
|
644
|
+
"value": "Resources",
|
|
645
|
+
"href": "#resources",
|
|
646
|
+
"depth": 2,
|
|
647
|
+
"numbering": [
|
|
648
|
+
1,
|
|
649
|
+
8
|
|
650
|
+
],
|
|
651
|
+
"parent": "root"
|
|
652
|
+
}
|
|
653
|
+
]
|
|
654
|
+
},
|
|
655
|
+
"guidelines": {
|
|
656
|
+
"mdx": "\n## Guidelines\n\nUse dialogs strategically to enhance user workflow without disrupting the\nexperience.\n\n### Best practices\n\n- **Use dialogs sparingly**: Only when you need to interrupt the user's flow for\n critical actions\n- **Keep content focused**: Dialogs should have a single, clear purpose\n- **Provide clear actions**: Always include obvious ways to proceed or dismiss\n- **Make dismissal easy**: Support Escape key, close buttons, and click-outside\n behavior\n- **Maintain focus flow**: Focus should move logically through interactive\n elements\n- **Size appropriately**: Choose sizes that fit your content without\n overwhelming the viewport\n- **Consider mobile**: Ensure dialogs work well on small screens\n\n> [!TIP]\\\n> When to use\n\n- **Confirming destructive actions**: Delete confirmations and critical warnings\n- **Collecting focused input**: Forms, settings, and data entry that requires\n attention\n- **Displaying critical alerts**: Important information that requires immediate\n user attention\n- **Showing detailed information**: Content that doesn't require navigation to a\n new page\n- **Authentication flows**: Login, signup, and security-related interactions\n\n> [!CAUTION]\\\n> When not to use\n\n- **Complex multi-step workflows**: Use pages instead for lengthy processes\n- **Non-critical information**: Use inline content for supplementary information\n- **Navigation**: Use proper routing instead of dialogs for moving between\n sections\n- **Content that needs to be referenced**: Avoid for information users need\n while working elsewhere\n",
|
|
657
|
+
"toc": [
|
|
658
|
+
{
|
|
659
|
+
"value": "Guidelines",
|
|
660
|
+
"href": "#guidelines",
|
|
661
|
+
"depth": 2,
|
|
662
|
+
"numbering": [
|
|
663
|
+
1,
|
|
664
|
+
1
|
|
665
|
+
],
|
|
666
|
+
"parent": "root"
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
"value": "Best practices",
|
|
670
|
+
"href": "#best-practices",
|
|
671
|
+
"depth": 3,
|
|
672
|
+
"numbering": [
|
|
673
|
+
1,
|
|
674
|
+
1,
|
|
675
|
+
1
|
|
676
|
+
],
|
|
677
|
+
"parent": "root"
|
|
678
|
+
}
|
|
679
|
+
]
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}
|