@cube-dev/ui-kit 0.65.1 → 0.66.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/CHANGELOG.md +8 -0
- package/es/_internal/hooks/index.js +1 -1
- package/es/_internal/hooks/use-chained-callback.js +1 -1
- package/es/_internal/hooks/use-debounced-value.js +1 -1
- package/es/_internal/hooks/use-deprecation-warning.js +1 -1
- package/es/_internal/hooks/use-effect-once.js +1 -1
- package/es/_internal/hooks/use-event.js +1 -1
- package/es/_internal/hooks/use-is-first-render.js +1 -1
- package/es/_internal/hooks/use-sync-ref.js +1 -1
- package/es/_internal/hooks/use-timer/index.js +1 -1
- package/es/_internal/hooks/use-timer/timer.js +1 -1
- package/es/_internal/hooks/use-timer/use-timer.js +1 -1
- package/es/_internal/hooks/use-update-effect.js +1 -1
- package/es/_internal/hooks/use-warn.js +1 -1
- package/es/_internal/index.js +1 -1
- package/es/components/Block.js +1 -1
- package/es/components/GlobalStyles.js +1 -1
- package/es/components/GridProvider.js +1 -1
- package/es/components/HiddenInput.js +1 -1
- package/es/components/OpenTrasition.js +1 -1
- package/es/components/Root.js +1 -1
- package/es/components/actions/Action/Action.js +1 -1
- package/es/components/actions/Button/Button.js +1 -1
- package/es/components/actions/Button/index.js +1 -1
- package/es/components/actions/ButtonGroup/ButtonGroup.js +1 -1
- package/es/components/actions/CommandMenu/CommandMenu.js +457 -0
- package/es/components/actions/CommandMenu/index.js +11 -0
- package/es/components/actions/CommandMenu/styled.js +110 -0
- package/es/components/{pickers → actions}/Menu/Menu.js +34 -8
- package/es/components/{pickers → actions}/Menu/MenuItem.js +10 -7
- package/es/components/{pickers → actions}/Menu/MenuSection.js +3 -3
- package/es/components/{pickers → actions}/Menu/MenuTrigger.js +2 -1
- package/es/components/{pickers → actions}/Menu/context.js +1 -1
- package/es/components/actions/Menu/index.js +17 -0
- package/es/components/{pickers → actions}/Menu/styled.js +31 -14
- package/es/components/actions/index.js +3 -1
- package/es/components/actions/use-action.js +1 -1
- package/es/components/content/ActiveZone/ActiveZone.js +1 -1
- package/es/components/content/Alert/Alert.js +1 -1
- package/es/components/content/Alert/index.js +1 -1
- package/es/components/content/Alert/types.js +1 -1
- package/es/components/content/Alert/use-alert.js +1 -1
- package/es/components/content/Avatar/Avatar.js +1 -1
- package/es/components/content/Badge/Badge.js +1 -1
- package/es/components/content/Card/Card.js +1 -1
- package/es/components/content/Content.js +1 -1
- package/es/components/content/CopyPasteBlock/CopyPasteBlock.js +1 -1
- package/es/components/content/CopyPasteBlock/index.js +1 -1
- package/es/components/content/CopySnippet/CopySnippet.js +1 -1
- package/es/components/content/CopySnippet/index.js +1 -1
- package/es/components/content/Divider.js +1 -1
- package/es/components/content/Footer.js +1 -1
- package/es/components/content/Header.js +1 -1
- package/es/components/content/HotKeys/HotKeys.js +14 -4
- package/es/components/content/HotKeys/index.js +1 -1
- package/es/components/content/Paragraph.js +1 -1
- package/es/components/content/Placeholder/Placeholder.js +1 -1
- package/es/components/content/PrismCode/PrismCode.js +1 -1
- package/es/components/content/PrismCode/prismSetup.js +1 -1
- package/es/components/content/PrismDiffCode/PrismDiffCode.js +1 -1
- package/es/components/content/Result/Result.js +1 -1
- package/es/components/content/Skeleton/Skeleton.js +1 -1
- package/es/components/content/Tag/Tag.js +1 -1
- package/es/components/content/Text.js +1 -1
- package/es/components/content/Title.js +1 -1
- package/es/components/fields/Checkbox/Checkbox.js +1 -1
- package/es/components/fields/Checkbox/CheckboxGroup.js +1 -1
- package/es/components/fields/Checkbox/context.js +1 -1
- package/es/components/fields/Checkbox/index.js +1 -1
- package/es/components/fields/ComboBox/ComboBox.js +3 -2
- package/es/components/fields/ComboBox/index.js +1 -1
- package/es/components/fields/DatePicker/DateInput.js +1 -1
- package/es/components/fields/DatePicker/DateInputBase.js +1 -1
- package/es/components/fields/DatePicker/DatePicker.js +1 -1
- package/es/components/fields/DatePicker/DatePickerButton.js +1 -1
- package/es/components/fields/DatePicker/DatePickerElement.js +1 -1
- package/es/components/fields/DatePicker/DatePickerInput.js +1 -1
- package/es/components/fields/DatePicker/DatePickerSegment.js +1 -1
- package/es/components/fields/DatePicker/DateRangePicker.js +1 -1
- package/es/components/fields/DatePicker/DateRangeSeparatedPicker.js +1 -1
- package/es/components/fields/DatePicker/TimeInput.js +1 -1
- package/es/components/fields/DatePicker/index.js +1 -1
- package/es/components/fields/DatePicker/intl.js +1 -1
- package/es/components/fields/DatePicker/parseDate.js +1 -1
- package/es/components/fields/DatePicker/props.js +1 -1
- package/es/components/fields/DatePicker/types.js +1 -1
- package/es/components/fields/DatePicker/utils.js +1 -1
- package/es/components/fields/FileInput/FileInput.js +1 -1
- package/es/components/fields/Input/Input.js +1 -1
- package/es/components/fields/Input/index.js +1 -1
- package/es/components/fields/ListBox/ListBox.js +1 -1
- package/es/components/fields/ListBox/index.js +1 -1
- package/es/components/fields/NumberInput/NumberInput.js +1 -1
- package/es/components/fields/NumberInput/StepButton.js +1 -1
- package/es/components/fields/PasswordInput/PasswordInput.js +1 -1
- package/es/components/fields/RadioGroup/Radio.js +1 -1
- package/es/components/fields/RadioGroup/RadioGroup.js +1 -1
- package/es/components/fields/RadioGroup/context.js +1 -1
- package/es/components/fields/RadioGroup/index.js +1 -1
- package/es/components/fields/SearchInput/SearchInput.js +1 -1
- package/es/components/fields/SearchInput/index.js +1 -1
- package/es/components/fields/Select/Select.js +19 -11
- package/es/components/fields/Select/index.js +1 -1
- package/es/components/fields/Slider/Gradation.js +1 -1
- package/es/components/fields/Slider/Header.js +1 -1
- package/es/components/fields/Slider/RangeSlider.js +1 -1
- package/es/components/fields/Slider/Slider.js +1 -1
- package/es/components/fields/Slider/SliderBase.js +1 -1
- package/es/components/fields/Slider/SliderInput.js +1 -1
- package/es/components/fields/Slider/SliderThumb.js +1 -1
- package/es/components/fields/Slider/SliderTrack.js +1 -1
- package/es/components/fields/Slider/elements.js +1 -1
- package/es/components/fields/Slider/index.js +1 -1
- package/es/components/fields/Slider/types.js +1 -1
- package/es/components/fields/Switch/Switch.js +1 -1
- package/es/components/fields/Switch/index.js +1 -1
- package/es/components/fields/TextArea/TextArea.js +1 -1
- package/es/components/fields/TextArea/index.js +1 -1
- package/es/components/fields/TextInput/TextInput.js +1 -1
- package/es/components/fields/TextInput/TextInputBase.js +1 -1
- package/es/components/fields/TextInput/index.js +1 -1
- package/es/components/fields/TextInputMapper/TextInputMapper.js +1 -1
- package/es/components/fields/TextInputMapper/index.js +1 -1
- package/es/components/fields/index.js +1 -1
- package/es/components/form/FieldWrapper/FieldWrapper.js +1 -1
- package/es/components/form/FieldWrapper/extract-field-wrapper-props.js +1 -1
- package/es/components/form/FieldWrapper/index.js +1 -1
- package/es/components/form/FieldWrapper/types.js +1 -1
- package/es/components/form/Form/Field.js +1 -1
- package/es/components/form/Form/Form.js +1 -1
- package/es/components/form/Form/ResetButton/ResetButton.js +1 -1
- package/es/components/form/Form/ResetButton/index.js +1 -1
- package/es/components/form/Form/SubmitButton/SubmitButton.js +1 -1
- package/es/components/form/Form/SubmitButton/index.js +1 -1
- package/es/components/form/Form/SubmitError.js +1 -1
- package/es/components/form/Form/index.js +1 -1
- package/es/components/form/Form/types.js +1 -1
- package/es/components/form/Form/use-field/index.js +1 -1
- package/es/components/form/Form/use-field/types.js +1 -1
- package/es/components/form/Form/use-field/use-field-props.js +1 -1
- package/es/components/form/Form/use-field/use-field.js +1 -1
- package/es/components/form/Form/use-form.js +1 -1
- package/es/components/form/Form/validation.js +1 -1
- package/es/components/form/Label.js +1 -1
- package/es/components/form/index.js +1 -1
- package/es/components/form/wrapper.js +1 -1
- package/es/components/layout/Flex.js +1 -1
- package/es/components/layout/Flow.js +1 -1
- package/es/components/layout/Grid.js +1 -1
- package/es/components/layout/Panel.js +1 -1
- package/es/components/layout/Prefix.js +1 -1
- package/es/components/layout/ResizablePanel.js +1 -1
- package/es/components/layout/Space.js +1 -1
- package/es/components/layout/Suffix.js +1 -1
- package/es/components/navigation/LegacyTabs/LegacyTabs.js +1 -1
- package/es/components/navigation/Link/Link.js +1 -1
- package/es/components/organisms/FileTabs/FileTabs.js +1 -1
- package/es/components/organisms/Modal/Modal.js +1 -1
- package/es/components/organisms/StatsCard/StatsCard.js +1 -1
- package/es/components/other/Base64Upload/Base64Upload.js +1 -1
- package/es/components/other/Calendar/Calendar.js +1 -1
- package/es/components/other/Calendar/CalendarCell.js +1 -1
- package/es/components/other/Calendar/CalendarGrid.js +1 -1
- package/es/components/other/Calendar/RangeCalendar.js +1 -1
- package/es/components/other/CloudLogo/CloudLogo.js +1 -1
- package/es/components/overlays/AlertDialog/AlertDialog.js +1 -1
- package/es/components/overlays/AlertDialog/AlertDialogApiProvider.js +1 -1
- package/es/components/overlays/AlertDialog/AlertDialogZone.js +1 -1
- package/es/components/overlays/AlertDialog/index.js +1 -1
- package/es/components/overlays/AlertDialog/types.js +1 -1
- package/es/components/overlays/Dialog/Dialog.js +1 -1
- package/es/components/overlays/Dialog/DialogContainer.js +1 -1
- package/es/components/overlays/Dialog/DialogForm.js +1 -1
- package/es/components/overlays/Dialog/DialogTrigger.js +1 -1
- package/es/components/overlays/Dialog/context.js +1 -1
- package/es/components/overlays/Dialog/dialog-container.js +1 -1
- package/es/components/overlays/Dialog/index.js +1 -1
- package/es/components/overlays/Modal/Modal.js +1 -1
- package/es/components/overlays/Modal/OpenTransition.js +1 -1
- package/es/components/overlays/Modal/Overlay.js +1 -1
- package/es/components/overlays/Modal/Popover.js +1 -1
- package/es/components/overlays/Modal/Tray.js +1 -1
- package/es/components/overlays/Modal/Underlay.js +1 -1
- package/es/components/overlays/Modal/index.js +1 -1
- package/es/components/overlays/Modal/types.js +1 -1
- package/es/components/overlays/NewNotifications/Bar/FloatingNotification.js +1 -1
- package/es/components/overlays/NewNotifications/Bar/NotificationsBar.js +1 -1
- package/es/components/overlays/NewNotifications/Bar/TransitionComponent.js +1 -1
- package/es/components/overlays/NewNotifications/Bar/index.js +1 -1
- package/es/components/overlays/NewNotifications/Dialog/NotificationsDialogTrigger.js +1 -1
- package/es/components/overlays/NewNotifications/Dialog/index.js +1 -1
- package/es/components/overlays/NewNotifications/Notification.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/NotificationAction.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/NotificationCloseButton.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/NotificationDescription.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/NotificationFooter.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/NotificationHeader.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/NotificationIcon.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/NotificationProvider.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/NotificationView.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/index.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationView/types.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationsContext/NotificationsContext.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationsContext/NotificationsProvider.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationsContext/index.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationsContext/use-notifications.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationsList/NotificationsList.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationsList/NotificationsListItem.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationsList/index.js +1 -1
- package/es/components/overlays/NewNotifications/NotificationsList/types.js +1 -1
- package/es/components/overlays/NewNotifications/hooks/index.js +1 -1
- package/es/components/overlays/NewNotifications/hooks/types.js +1 -1
- package/es/components/overlays/NewNotifications/hooks/use-notification-list-item.js +1 -1
- package/es/components/overlays/NewNotifications/hooks/use-notifications-api.js +1 -1
- package/es/components/overlays/NewNotifications/hooks/use-notifications-list.js +1 -1
- package/es/components/overlays/NewNotifications/hooks/use-notifications-observer.js +1 -1
- package/es/components/overlays/NewNotifications/index.js +1 -1
- package/es/components/overlays/NewNotifications/types.js +1 -1
- package/es/components/overlays/Notification/Notification.js +1 -1
- package/es/components/overlays/OverlayWrapper.js +1 -1
- package/es/components/overlays/Toasts/Toast.js +1 -1
- package/es/components/overlays/Toasts/index.js +1 -1
- package/es/components/overlays/Toasts/types.js +1 -1
- package/es/components/overlays/Toasts/use-toasts-api.js +1 -1
- package/es/components/overlays/Tooltip/Tooltip.js +1 -1
- package/es/components/overlays/Tooltip/TooltipProvider.js +1 -1
- package/es/components/overlays/Tooltip/TooltipTrigger.js +1 -1
- package/es/components/overlays/Tooltip/context.js +1 -1
- package/es/components/overlays/Tooltip/index.js +1 -1
- package/es/components/portal/Portal.js +1 -1
- package/es/components/portal/PortalProvider.js +1 -1
- package/es/components/portal/index.js +1 -1
- package/es/components/portal/storybook/templates/CustomRoot.js +1 -1
- package/es/components/portal/storybook/templates/PortalOrder.js +1 -1
- package/es/components/portal/storybook/templates/basic.js +1 -1
- package/es/components/portal/storybook/templates/index.js +1 -1
- package/es/components/portal/types.js +1 -1
- package/es/components/portal/usePortal.js +1 -1
- package/es/components/shared/InvalidIcon.js +1 -1
- package/es/components/shared/ValidIcon.js +1 -1
- package/es/components/status/LoadingAnimation/LoadingAnimation.js +1 -1
- package/es/components/status/LoadingAnimation/index.js +1 -1
- package/es/components/status/Spin/Cube.js +1 -1
- package/es/components/status/Spin/InternalSpinner.js +1 -1
- package/es/components/status/Spin/Spin.js +1 -1
- package/es/components/status/Spin/SpinsContainer.js +1 -1
- package/es/components/status/Spin/index.js +1 -1
- package/es/components/status/Spin/types.js +1 -1
- package/es/components/status/index.js +1 -1
- package/es/data/themes.js +1 -1
- package/es/icons/AdjustmentsHorizontalIcon.js +1 -1
- package/es/icons/AdjustmentsIcon.js +1 -1
- package/es/icons/AiIcon.js +1 -1
- package/es/icons/AreaChartIcon.js +1 -1
- package/es/icons/BackwardIcon.js +1 -1
- package/es/icons/BarChartIcon.js +1 -1
- package/es/icons/BellFilledIcon.js +1 -1
- package/es/icons/BellIcon.js +1 -1
- package/es/icons/BooleanIcon.js +1 -1
- package/es/icons/CalendarEditIcon.js +1 -1
- package/es/icons/CalendarIcon.js +1 -1
- package/es/icons/CaretDownIcon.js +1 -1
- package/es/icons/CaretUpIcon.js +1 -1
- package/es/icons/ChartAreaStackedIcon.js +1 -1
- package/es/icons/ChartAreaStackedPercentageIcon.js +1 -1
- package/es/icons/ChartBarGroupedHorizontalIcon.js +1 -1
- package/es/icons/ChartBarGroupedIcon.js +1 -1
- package/es/icons/ChartBarHorizontalIcon.js +1 -1
- package/es/icons/ChartBarLineIcon.js +1 -1
- package/es/icons/ChartBarStackedHorizontalIcon.js +1 -1
- package/es/icons/ChartBarStackedIcon.js +1 -1
- package/es/icons/ChartBarStackedPercentageHorizontalIcon.js +1 -1
- package/es/icons/ChartBarStackedPercentageIcon.js +1 -1
- package/es/icons/ChartBoxPlot2Icon.js +1 -1
- package/es/icons/ChartBoxPlotIcon.js +1 -1
- package/es/icons/ChartBubbleIcon.js +1 -1
- package/es/icons/ChartDonut2Icon.js +1 -1
- package/es/icons/ChartFunnelIcon.js +1 -1
- package/es/icons/ChartPie2Icon.js +1 -1
- package/es/icons/ChartScatterIcon.js +1 -1
- package/es/icons/CheckCircleFilledIcon.js +1 -1
- package/es/icons/CheckCircleIcon.js +1 -1
- package/es/icons/CheckIcon.js +1 -1
- package/es/icons/CircleFilledIcon.js +1 -1
- package/es/icons/ClearIcon.js +1 -1
- package/es/icons/CloseCircleFilledIcon.js +1 -1
- package/es/icons/CloseCircleIcon.js +1 -1
- package/es/icons/CloseIcon.js +1 -1
- package/es/icons/CodeIcon.js +1 -1
- package/es/icons/CopyIcon.js +1 -1
- package/es/icons/CountIcon.js +1 -1
- package/es/icons/CubeIcon.js +1 -1
- package/es/icons/DangerIcon.js +1 -1
- package/es/icons/DashboardIcon.js +1 -1
- package/es/icons/DatabaseIcon.js +1 -1
- package/es/icons/DirectionIcon.js +1 -1
- package/es/icons/DonutIcon.js +1 -1
- package/es/icons/DownIcon.js +1 -1
- package/es/icons/EditIcon.js +1 -1
- package/es/icons/ExclamationCircleFilledIcon.js +1 -1
- package/es/icons/ExclamationCircleIcon.js +1 -1
- package/es/icons/ExclamationIcon.js +1 -1
- package/es/icons/EyeIcon.js +1 -1
- package/es/icons/EyeInvisibleIcon.js +1 -1
- package/es/icons/FilterIcon.js +1 -1
- package/es/icons/FolderFilledIcon.js +1 -1
- package/es/icons/FolderIcon.js +1 -1
- package/es/icons/FolderOpenFilledIcon.js +1 -1
- package/es/icons/FolderOpenIcon.js +1 -1
- package/es/icons/ForwardIcon.js +1 -1
- package/es/icons/HierarchyIcon.js +1 -1
- package/es/icons/Icon.js +1 -1
- package/es/icons/InfoCircleIcon.js +1 -1
- package/es/icons/InfoIcon.js +1 -1
- package/es/icons/KeyIcon.js +1 -1
- package/es/icons/LeftIcon.js +1 -1
- package/es/icons/LineChartIcon.js +1 -1
- package/es/icons/LoadingIcon.js +1 -1
- package/es/icons/LockFilledIcon.js +1 -1
- package/es/icons/LockIcon.js +1 -1
- package/es/icons/MoreIcon.js +1 -1
- package/es/icons/NotAllowedIcon.js +1 -1
- package/es/icons/NumberIcon.js +1 -1
- package/es/icons/PauseCircleFilledIcon.js +1 -1
- package/es/icons/PauseCircleIcon.js +1 -1
- package/es/icons/PauseIcon.js +1 -1
- package/es/icons/PieChartIcon.js +1 -1
- package/es/icons/PlayCircleIcon.js +1 -1
- package/es/icons/PlayIcon.js +1 -1
- package/es/icons/PlusIcon.js +1 -1
- package/es/icons/ReloadIcon.js +1 -1
- package/es/icons/ReportIcon.js +1 -1
- package/es/icons/ReturnIcon.js +1 -1
- package/es/icons/RightIcon.js +1 -1
- package/es/icons/SchemeIcon.js +1 -1
- package/es/icons/SearchIcon.js +1 -1
- package/es/icons/SettingsIcon.js +1 -1
- package/es/icons/ShieldFilledIcon.js +1 -1
- package/es/icons/ShieldIcon.js +1 -1
- package/es/icons/SlashIcon.js +1 -1
- package/es/icons/SparklesIcon.js +1 -1
- package/es/icons/SqlIcon.js +1 -1
- package/es/icons/StatsIcon.js +1 -1
- package/es/icons/StopIcon.js +1 -1
- package/es/icons/StringIcon.js +1 -1
- package/es/icons/SwitchIcon.js +1 -1
- package/es/icons/TableIcon.js +1 -1
- package/es/icons/ThumbsDownIcon.js +1 -1
- package/es/icons/ThumbsUpIcon.js +1 -1
- package/es/icons/ThunderboltCrossedIcon.js +1 -1
- package/es/icons/ThunderboltFilledIcon.js +1 -1
- package/es/icons/ThunderboltIcon.js +1 -1
- package/es/icons/TimeIcon.js +1 -1
- package/es/icons/UnlockIcon.js +1 -1
- package/es/icons/UpIcon.js +1 -1
- package/es/icons/UserGroupIcon.js +1 -1
- package/es/icons/UserIcon.js +1 -1
- package/es/icons/UserLockIcon.js +1 -1
- package/es/icons/ViewIcon.js +1 -1
- package/es/icons/WarningFilledIcon.js +1 -1
- package/es/icons/WarningIcon.js +1 -1
- package/es/icons/add-new-icon.js +1 -1
- package/es/icons/index.js +1 -1
- package/es/icons/wrap-icon.js +1 -1
- package/es/index.js +4 -3
- package/es/provider.js +1 -1
- package/es/providers/TrackingProvider.js +1 -1
- package/es/services/notification.js +1 -1
- package/es/shared/form.js +1 -1
- package/es/shared/index.js +1 -1
- package/es/stories/Form.legacy-stories.js +1 -1
- package/es/stories/FormFieldArgs.js +1 -1
- package/es/stories/Layout.stories.js +1 -1
- package/es/stories/Tasty.stories.js +1 -1
- package/es/stories/components/ConfirmDeletionDialogForm.js +1 -1
- package/es/stories/components/DialogFormApp.js +1 -1
- package/es/stories/components/StyledButton.js +1 -1
- package/es/stories/lists/baseProps.js +1 -1
- package/es/tasty/index.js +1 -1
- package/es/tasty/providers/BreakpointsProvider.js +1 -1
- package/es/tasty/styles/align.js +1 -1
- package/es/tasty/styles/border.js +1 -1
- package/es/tasty/styles/boxShadow.combinator.js +1 -1
- package/es/tasty/styles/color.js +1 -1
- package/es/tasty/styles/createStyle.js +1 -1
- package/es/tasty/styles/dimension.js +1 -1
- package/es/tasty/styles/display.js +1 -1
- package/es/tasty/styles/fade.js +1 -1
- package/es/tasty/styles/fill.js +1 -1
- package/es/tasty/styles/flow.js +1 -1
- package/es/tasty/styles/font.js +1 -1
- package/es/tasty/styles/fontStyle.js +1 -1
- package/es/tasty/styles/gap.js +1 -1
- package/es/tasty/styles/groupRadius.js +1 -1
- package/es/tasty/styles/height.js +1 -1
- package/es/tasty/styles/index.js +1 -1
- package/es/tasty/styles/inset.js +1 -1
- package/es/tasty/styles/justify.js +1 -1
- package/es/tasty/styles/list.js +1 -1
- package/es/tasty/styles/margin.js +1 -1
- package/es/tasty/styles/marginBlock.js +1 -1
- package/es/tasty/styles/marginInline.js +1 -1
- package/es/tasty/styles/outline.js +1 -1
- package/es/tasty/styles/padding.js +1 -1
- package/es/tasty/styles/paddingBlock.js +1 -1
- package/es/tasty/styles/paddingInline.js +1 -1
- package/es/tasty/styles/place.js +1 -1
- package/es/tasty/styles/predefined.js +1 -1
- package/es/tasty/styles/preset.js +1 -1
- package/es/tasty/styles/radius.js +1 -1
- package/es/tasty/styles/reset.js +1 -1
- package/es/tasty/styles/scrollbar.js +1 -1
- package/es/tasty/styles/shadow.js +1 -1
- package/es/tasty/styles/styledScrollbar.js +1 -1
- package/es/tasty/styles/transition.js +1 -1
- package/es/tasty/styles/types.js +1 -1
- package/es/tasty/styles/width.js +1 -1
- package/es/tasty/tasty.js +1 -1
- package/es/tasty/types.js +1 -1
- package/es/tasty/utils/cache-wrapper.js +1 -1
- package/es/tasty/utils/case-converter.js +1 -1
- package/es/tasty/utils/colors.js +1 -1
- package/es/tasty/utils/dotize.js +1 -1
- package/es/tasty/utils/filterBaseProps.js +1 -1
- package/es/tasty/utils/getDisplayName.js +1 -1
- package/es/tasty/utils/getModCombinations.js +1 -1
- package/es/tasty/utils/mergeStyles.js +1 -1
- package/es/tasty/utils/modAttrs.js +1 -1
- package/es/tasty/utils/renderStyles.js +1 -1
- package/es/tasty/utils/responsive.js +1 -1
- package/es/tasty/utils/string.js +1 -1
- package/es/tasty/utils/styles.js +1 -1
- package/es/tasty/utils/warnings.js +1 -1
- package/es/tokens.js +1 -1
- package/es/type-checks.js +1 -1
- package/es/utils/ResizeSensor.js +1 -1
- package/es/utils/modules.js +1 -1
- package/es/utils/promise.js +1 -1
- package/es/utils/random.js +1 -1
- package/es/utils/range.js +1 -1
- package/es/utils/react/Slots.js +1 -1
- package/es/utils/react/chain.js +1 -1
- package/es/utils/react/index.js +1 -1
- package/es/utils/react/interactions.js +1 -1
- package/es/utils/react/isTextOnly.js +1 -1
- package/es/utils/react/mapProps.js +1 -1
- package/es/utils/react/mergeProps.js +1 -1
- package/es/utils/react/nullableValue.js +1 -1
- package/es/utils/react/useCombinedRefs.js +1 -1
- package/es/utils/react/useId.js +1 -1
- package/es/utils/react/useIsDarwin.js +1 -1
- package/es/utils/react/useKeySymbols.js +8 -8
- package/es/utils/react/useLayoutEffect.js +1 -1
- package/es/utils/react/useQaProps.js +1 -1
- package/es/utils/react/useViewportSize.js +1 -1
- package/es/utils/react/wrapNodeIfPlain.js +1 -1
- package/es/utils/transitions.js +1 -1
- package/es/utils/tree.js +1 -1
- package/es/utils/warnings.js +1 -1
- package/es/version.js +2 -2
- package/package.json +1 -1
- package/types/components/actions/CommandMenu/CommandMenu.d.ts +38 -0
- package/types/components/actions/CommandMenu/index.d.ts +2 -0
- package/types/components/actions/CommandMenu/styled.d.ts +5 -0
- package/types/components/{pickers → actions}/Menu/Menu.d.ts +12 -3
- package/types/components/{pickers → actions}/Menu/MenuItem.d.ts +1 -0
- package/types/components/{pickers → actions}/Menu/MenuSection.d.ts +1 -0
- package/types/components/{pickers → actions}/Menu/context.d.ts +4 -0
- package/types/components/actions/Menu/index.d.ts +7 -0
- package/types/components/{pickers → actions}/Menu/styled.d.ts +432 -0
- package/types/components/actions/index.d.ts +2 -0
- package/types/components/content/HotKeys/HotKeys.d.ts +3 -3
- package/types/components/fields/ComboBox/ComboBox.d.ts +1 -1
- package/types/components/fields/Select/Select.d.ts +3 -2
- package/types/components/status/Spin/Cube.d.ts +1 -1
- package/types/components/status/Spin/SpinsContainer.d.ts +1 -1
- package/types/index.d.ts +6 -4
- package/es/components/pickers/Menu/MenuButton.js +0 -96
- package/types/components/pickers/Menu/MenuButton.d.ts +0 -14
- /package/types/components/{pickers → actions}/Menu/MenuTrigger.d.ts +0 -0
@@ -0,0 +1,457 @@
|
|
1
|
+
/**
|
2
|
+
* @license MIT
|
3
|
+
* author: Cube Dev Team
|
4
|
+
* @cube-dev/ui-kit v0.66.0
|
5
|
+
* Released under the MIT license.
|
6
|
+
*/
|
7
|
+
|
8
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
9
|
+
import { useSyncRef } from '@react-aria/utils';
|
10
|
+
import { useDOMRef } from '@react-spectrum/utils';
|
11
|
+
import React, { useCallback, useMemo, useRef, useState, } from 'react';
|
12
|
+
import { useFilter, useMenu } from 'react-aria';
|
13
|
+
// Import Item and Section from Menu for CommandMenu compound component
|
14
|
+
import { Item, Section, useTreeState } from 'react-stately';
|
15
|
+
import { LoadingIcon } from '../../../icons';
|
16
|
+
import { CONTAINER_STYLES, extractStyles, filterBaseProps, } from '../../../tasty';
|
17
|
+
import { mergeProps } from '../../../utils/react';
|
18
|
+
import { useDialogContext } from '../../overlays/Dialog/context';
|
19
|
+
import { TooltipProvider } from '../../overlays/Tooltip/TooltipProvider';
|
20
|
+
import { useMenuContext } from '../Menu';
|
21
|
+
import { MenuItem } from '../Menu/MenuItem';
|
22
|
+
import { MenuSection } from '../Menu/MenuSection';
|
23
|
+
import { MenuTrigger } from '../Menu/MenuTrigger';
|
24
|
+
import { StyledDivider, StyledFooter, StyledHeader, StyledMenu, } from '../Menu/styled';
|
25
|
+
import { StyledCommandMenu, StyledEmptyState, StyledLoadingWrapper, StyledMenuWrapper, StyledSearchInput, } from './styled';
|
26
|
+
function CommandMenuBase(props, ref) {
|
27
|
+
const { searchPlaceholder = 'Search commands...', searchValue: controlledSearchValue, onSearchChange, filter: customFilter, emptyLabel = 'No commands found', searchInputStyles, headerStyles, footerStyles, isLoading = false, shouldFilter = true, autoFocus = true, size = 'small', qa, styles, selectedKeys, defaultSelectedKeys, onSelectionChange, header, footer, ...restMenuProps } = props;
|
28
|
+
const domRef = useDOMRef(ref);
|
29
|
+
const searchInputRef = useRef(null);
|
30
|
+
const contextProps = useMenuContext();
|
31
|
+
const dialogContext = useDialogContext();
|
32
|
+
// Convert string[] to Set<Key> for React Aria compatibility
|
33
|
+
const ariaSelectedKeys = selectedKeys ? new Set(selectedKeys) : undefined;
|
34
|
+
const ariaDefaultSelectedKeys = defaultSelectedKeys
|
35
|
+
? new Set(defaultSelectedKeys)
|
36
|
+
: undefined;
|
37
|
+
const handleSelectionChange = onSelectionChange
|
38
|
+
? (keys) => {
|
39
|
+
if (keys === 'all') {
|
40
|
+
// Handle 'all' selection case - collect all available keys
|
41
|
+
const allKeys = Array.from(treeState.collection.getKeys()).map((key) => String(key));
|
42
|
+
onSelectionChange(allKeys);
|
43
|
+
}
|
44
|
+
else if (keys instanceof Set) {
|
45
|
+
onSelectionChange(Array.from(keys).map((key) => String(key)));
|
46
|
+
}
|
47
|
+
else {
|
48
|
+
onSelectionChange([]);
|
49
|
+
}
|
50
|
+
}
|
51
|
+
: undefined;
|
52
|
+
const completeProps = mergeProps(contextProps, restMenuProps, {
|
53
|
+
selectedKeys: ariaSelectedKeys,
|
54
|
+
defaultSelectedKeys: ariaDefaultSelectedKeys,
|
55
|
+
onSelectionChange: handleSelectionChange,
|
56
|
+
});
|
57
|
+
// Search state management
|
58
|
+
const [internalSearchValue, setInternalSearchValue] = useState('');
|
59
|
+
const searchValue = controlledSearchValue ?? internalSearchValue;
|
60
|
+
const handleSearchChange = useCallback((value) => {
|
61
|
+
if (controlledSearchValue === undefined) {
|
62
|
+
setInternalSearchValue(value);
|
63
|
+
}
|
64
|
+
onSearchChange?.(value);
|
65
|
+
}, [controlledSearchValue, onSearchChange]);
|
66
|
+
// Filter setup
|
67
|
+
const { contains } = useFilter({ sensitivity: 'base' });
|
68
|
+
const textFilterFn = useMemo(() => customFilter || contains, [customFilter, contains]);
|
69
|
+
// Enhanced filter function that supports keywords and forceMount
|
70
|
+
const enhancedFilter = useCallback((textValue, inputValue, item) => {
|
71
|
+
// Always show force-mounted items
|
72
|
+
if (item?.forceMount) {
|
73
|
+
return true;
|
74
|
+
}
|
75
|
+
// If shouldFilter is false, show all items
|
76
|
+
if (!shouldFilter) {
|
77
|
+
return true;
|
78
|
+
}
|
79
|
+
// Split input value into individual words and filter out empty strings
|
80
|
+
const searchWords = inputValue
|
81
|
+
.trim()
|
82
|
+
.toLowerCase()
|
83
|
+
.split(/\s+/)
|
84
|
+
.filter((word) => word.length > 0);
|
85
|
+
// If no search words, show all items
|
86
|
+
if (searchWords.length === 0) {
|
87
|
+
return true;
|
88
|
+
}
|
89
|
+
// Collect all searchable text for this item
|
90
|
+
const searchableTexts = [];
|
91
|
+
// Add main text value
|
92
|
+
searchableTexts.push(textValue.toLowerCase());
|
93
|
+
// Add keywords if available
|
94
|
+
if (item?.keywords && Array.isArray(item.keywords)) {
|
95
|
+
searchableTexts.push(...item.keywords.map((keyword) => keyword.toLowerCase()));
|
96
|
+
}
|
97
|
+
// Check if ALL search words match at least one of the searchable texts
|
98
|
+
return searchWords.every((searchWord) => searchableTexts.some((text) => text.includes(searchWord)));
|
99
|
+
}, [shouldFilter]);
|
100
|
+
// Collection filter for React Stately
|
101
|
+
const collectionFilter = useCallback((nodes) => {
|
102
|
+
const term = searchValue.trim();
|
103
|
+
// If no search term, return all nodes
|
104
|
+
if (!term) {
|
105
|
+
return nodes;
|
106
|
+
}
|
107
|
+
// Split search term into words for multi-word filtering
|
108
|
+
const searchWords = term
|
109
|
+
.toLowerCase()
|
110
|
+
.split(/\s+/)
|
111
|
+
.filter((word) => word.length > 0);
|
112
|
+
// If no valid search words, return all nodes
|
113
|
+
if (searchWords.length === 0) {
|
114
|
+
return nodes;
|
115
|
+
}
|
116
|
+
// Recursive helper to filter sections and items
|
117
|
+
const filterNodes = (iter) => {
|
118
|
+
const result = [];
|
119
|
+
for (const node of iter) {
|
120
|
+
if (node.type === 'section') {
|
121
|
+
const filteredChildren = filterNodes(node.childNodes);
|
122
|
+
if (filteredChildren.length) {
|
123
|
+
result.push({
|
124
|
+
...node,
|
125
|
+
childNodes: filteredChildren,
|
126
|
+
});
|
127
|
+
}
|
128
|
+
}
|
129
|
+
else {
|
130
|
+
const text = node.textValue ?? String(node.rendered ?? '');
|
131
|
+
if (enhancedFilter(text, term, node.props)) {
|
132
|
+
result.push(node);
|
133
|
+
}
|
134
|
+
}
|
135
|
+
}
|
136
|
+
return result;
|
137
|
+
};
|
138
|
+
return filterNodes(nodes);
|
139
|
+
}, [searchValue, enhancedFilter]);
|
140
|
+
// Create tree state with filter for both keyboard navigation and rendering
|
141
|
+
const treeStateProps = {
|
142
|
+
...completeProps,
|
143
|
+
filter: collectionFilter,
|
144
|
+
shouldUseVirtualFocus: true, // Always use virtual focus for CommandMenu
|
145
|
+
};
|
146
|
+
const treeState = useTreeState(treeStateProps);
|
147
|
+
const collectionItems = [...treeState.collection];
|
148
|
+
const hasSections = collectionItems.some((item) => item.type === 'section');
|
149
|
+
// Track focused key for aria-activedescendant
|
150
|
+
const [focusedKey, setFocusedKey] = React.useState(null);
|
151
|
+
// Apply filtering to collection items for rendering and empty state checks
|
152
|
+
const filteredCollectionItems = useMemo(() => {
|
153
|
+
const term = searchValue.trim();
|
154
|
+
if (!term) {
|
155
|
+
return collectionItems;
|
156
|
+
}
|
157
|
+
// Split search term into words for multi-word filtering
|
158
|
+
const searchWords = term
|
159
|
+
.toLowerCase()
|
160
|
+
.split(/\s+/)
|
161
|
+
.filter((word) => word.length > 0);
|
162
|
+
// If no valid search words, return all items
|
163
|
+
if (searchWords.length === 0) {
|
164
|
+
return collectionItems;
|
165
|
+
}
|
166
|
+
const filterNodes = (items) => {
|
167
|
+
const result = [];
|
168
|
+
[...items].forEach((item) => {
|
169
|
+
if (item.type === 'section') {
|
170
|
+
const filteredChildren = filterNodes(item.childNodes);
|
171
|
+
if (filteredChildren.length) {
|
172
|
+
result.push({
|
173
|
+
...item,
|
174
|
+
childNodes: filteredChildren,
|
175
|
+
});
|
176
|
+
}
|
177
|
+
}
|
178
|
+
else {
|
179
|
+
const text = item.textValue ?? String(item.rendered ?? '');
|
180
|
+
if (enhancedFilter(text, term, item.props)) {
|
181
|
+
result.push(item);
|
182
|
+
}
|
183
|
+
}
|
184
|
+
});
|
185
|
+
return result;
|
186
|
+
};
|
187
|
+
return filterNodes(collectionItems);
|
188
|
+
}, [collectionItems, searchValue, enhancedFilter]);
|
189
|
+
const hasFilteredItems = filteredCollectionItems.length > 0;
|
190
|
+
const viewHasSections = filteredCollectionItems.some((item) => item.type === 'section');
|
191
|
+
// Helper function to find the first selectable item from filtered results
|
192
|
+
const findFirstSelectableItem = useCallback(() => {
|
193
|
+
// Use the filtered collection items instead of the full tree state collection
|
194
|
+
for (const item of filteredCollectionItems) {
|
195
|
+
if (item &&
|
196
|
+
item.type === 'item' &&
|
197
|
+
!treeState.selectionManager.isDisabled(item.key)) {
|
198
|
+
return item.key;
|
199
|
+
}
|
200
|
+
}
|
201
|
+
return null;
|
202
|
+
}, [filteredCollectionItems, treeState.selectionManager]);
|
203
|
+
// Create a ref for the menu container
|
204
|
+
const menuRef = useRef(null);
|
205
|
+
// Use menu hook for accessibility
|
206
|
+
const { menuProps } = useMenu({
|
207
|
+
...completeProps,
|
208
|
+
'aria-label': 'Command palette menu',
|
209
|
+
filter: collectionFilter,
|
210
|
+
shouldUseVirtualFocus: true,
|
211
|
+
}, treeState, menuRef);
|
212
|
+
// Manual rendering of menu items (similar to Menu component)
|
213
|
+
const renderedItems = useMemo(() => {
|
214
|
+
const items = [];
|
215
|
+
let isFirstSection = true;
|
216
|
+
filteredCollectionItems.forEach((item) => {
|
217
|
+
if (item.type === 'section') {
|
218
|
+
if (!isFirstSection) {
|
219
|
+
items.push(_jsx(StyledDivider, { role: "separator", "aria-orientation": "horizontal" }, `divider-${String(item.key)}`));
|
220
|
+
}
|
221
|
+
items.push(_jsx(MenuSection, { item: item, state: treeState, styles: completeProps.sectionStyles, itemStyles: completeProps.itemStyles, headingStyles: completeProps.sectionHeadingStyles, selectionIcon: completeProps.selectionIcon, size: size }, item.key));
|
222
|
+
isFirstSection = false;
|
223
|
+
return;
|
224
|
+
}
|
225
|
+
let menuItem = (_jsx(MenuItem, { item: item, state: treeState, styles: completeProps.itemStyles, selectionIcon: completeProps.selectionIcon, size: size, onAction: item.onAction }, item.key));
|
226
|
+
// Apply tooltip wrapper if tooltip property is provided
|
227
|
+
if (item.props.tooltip) {
|
228
|
+
const tooltipProps = typeof item.props.tooltip === 'string'
|
229
|
+
? { title: item.props.tooltip }
|
230
|
+
: item.props.tooltip;
|
231
|
+
menuItem = (_jsx(TooltipProvider, { activeWrap: true, placement: "right", ...tooltipProps, children: menuItem }, item.key));
|
232
|
+
}
|
233
|
+
// Apply custom wrapper if provided
|
234
|
+
if (item.props.wrapper) {
|
235
|
+
menuItem = item.props.wrapper(menuItem);
|
236
|
+
}
|
237
|
+
// Ensure every child has a stable key, even if the wrapper component didn't set one.
|
238
|
+
items.push(React.cloneElement(menuItem, { key: item.key }));
|
239
|
+
});
|
240
|
+
return items;
|
241
|
+
}, [
|
242
|
+
filteredCollectionItems,
|
243
|
+
treeState,
|
244
|
+
completeProps.sectionStyles,
|
245
|
+
completeProps.itemStyles,
|
246
|
+
completeProps.selectionIcon,
|
247
|
+
completeProps.sectionHeadingStyles,
|
248
|
+
]);
|
249
|
+
// Auto-focus search input
|
250
|
+
React.useEffect(() => {
|
251
|
+
if (autoFocus && searchInputRef.current) {
|
252
|
+
// Use a small timeout to ensure the element is visible and focusable
|
253
|
+
// This is especially important when the CommandMenu is opened in a popover
|
254
|
+
const timeoutId = setTimeout(() => {
|
255
|
+
if (searchInputRef.current) {
|
256
|
+
searchInputRef.current.focus();
|
257
|
+
}
|
258
|
+
}, 0);
|
259
|
+
return () => clearTimeout(timeoutId);
|
260
|
+
}
|
261
|
+
}, [autoFocus]);
|
262
|
+
// Also focus when the component becomes visible (for trigger/popover usage)
|
263
|
+
React.useEffect(() => {
|
264
|
+
// Check if autoFocus is enabled and we're in a trigger context
|
265
|
+
if (autoFocus && contextProps.autoFocus && searchInputRef.current) {
|
266
|
+
// Use a small timeout to ensure the popover is fully rendered
|
267
|
+
const timeoutId = setTimeout(() => {
|
268
|
+
if (searchInputRef.current) {
|
269
|
+
searchInputRef.current.focus();
|
270
|
+
}
|
271
|
+
}, 50); // Slightly longer timeout for popover context
|
272
|
+
return () => clearTimeout(timeoutId);
|
273
|
+
}
|
274
|
+
}, [autoFocus, contextProps.autoFocus]);
|
275
|
+
// Auto-focus first item when search value changes (but not on initial render)
|
276
|
+
React.useEffect(() => {
|
277
|
+
// Only auto-focus when search value changes, not on initial mount
|
278
|
+
if (searchValue.trim() !== '') {
|
279
|
+
const firstSelectableKey = findFirstSelectableItem();
|
280
|
+
if (firstSelectableKey && hasFilteredItems) {
|
281
|
+
// Focus the first item in the selection manager
|
282
|
+
treeState.selectionManager.setFocusedKey(firstSelectableKey);
|
283
|
+
setFocusedKey(firstSelectableKey);
|
284
|
+
}
|
285
|
+
else {
|
286
|
+
// Clear focus if no items are available
|
287
|
+
treeState.selectionManager.setFocusedKey(null);
|
288
|
+
setFocusedKey(null);
|
289
|
+
}
|
290
|
+
}
|
291
|
+
}, [
|
292
|
+
searchValue,
|
293
|
+
findFirstSelectableItem,
|
294
|
+
hasFilteredItems,
|
295
|
+
treeState.selectionManager,
|
296
|
+
]);
|
297
|
+
// Extract styles
|
298
|
+
const extractedStyles = useMemo(() => extractStyles(props, CONTAINER_STYLES), [props]);
|
299
|
+
// Determine if we should show empty state based on actual filtered collection
|
300
|
+
const hasSearchTerm = searchValue.trim().length > 0;
|
301
|
+
const showEmptyState = hasSearchTerm && !hasFilteredItems && !isLoading;
|
302
|
+
// Sync refs
|
303
|
+
useSyncRef(contextProps, menuRef);
|
304
|
+
const mods = useMemo(() => {
|
305
|
+
// Determine mods based on dialog context and menu context
|
306
|
+
let popoverMod = completeProps.mods?.popover || dialogContext?.type === 'popover';
|
307
|
+
let trayMod = completeProps.mods?.tray || dialogContext?.type === 'tray';
|
308
|
+
let modalMod = dialogContext?.type === 'modal';
|
309
|
+
return {
|
310
|
+
sections: viewHasSections,
|
311
|
+
footer: !!footer,
|
312
|
+
header: !!header,
|
313
|
+
popover: popoverMod,
|
314
|
+
tray: trayMod,
|
315
|
+
modal: modalMod,
|
316
|
+
};
|
317
|
+
}, [
|
318
|
+
viewHasSections,
|
319
|
+
footer,
|
320
|
+
header,
|
321
|
+
completeProps.mods,
|
322
|
+
dialogContext?.type,
|
323
|
+
]);
|
324
|
+
return (_jsxs(StyledCommandMenu, { ...filterBaseProps(props), ref: domRef, qa: qa || 'CommandMenu', "data-size": size, mods: mods, styles: mergeProps(extractedStyles, styles), children: [header && (_jsx(StyledHeader, { role: "presentation", styles: headerStyles, children: header })), _jsx(StyledSearchInput, { ref: searchInputRef, type: "search", placeholder: searchPlaceholder, value: searchValue, styles: searchInputStyles, "data-size": size, "aria-controls": `${qa || 'CommandMenu'}-menu`, role: "combobox", "aria-expanded": "true", "aria-haspopup": "listbox", "aria-activedescendant": focusedKey != null
|
325
|
+
? `${qa || 'CommandMenu'}-menu-option-${focusedKey}`
|
326
|
+
: undefined, onChange: (e) => handleSearchChange(e.target.value), onKeyDown: (e) => {
|
327
|
+
if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
|
328
|
+
e.preventDefault();
|
329
|
+
const isArrowDown = e.key === 'ArrowDown';
|
330
|
+
const { selectionManager, collection } = treeState;
|
331
|
+
const currentKey = selectionManager.focusedKey;
|
332
|
+
// Helper function to find next selectable key in a direction
|
333
|
+
const findNextSelectableKey = (startKey, direction) => {
|
334
|
+
if (startKey == null) {
|
335
|
+
return null;
|
336
|
+
}
|
337
|
+
// First check if the startKey itself is selectable
|
338
|
+
const startNode = collection.getItem(startKey);
|
339
|
+
if (startNode &&
|
340
|
+
startNode.type === 'item' &&
|
341
|
+
!selectionManager.isDisabled(startKey)) {
|
342
|
+
return startKey;
|
343
|
+
}
|
344
|
+
// If startKey is not selectable, find the next selectable key
|
345
|
+
let keys = [...collection.getKeys()];
|
346
|
+
if (direction === 'backward') {
|
347
|
+
keys = keys.reverse();
|
348
|
+
}
|
349
|
+
let startIndex = keys.indexOf(startKey);
|
350
|
+
if (startIndex === -1) {
|
351
|
+
return null;
|
352
|
+
}
|
353
|
+
for (let i = startIndex + 1; i < keys.length; i++) {
|
354
|
+
const key = keys[i];
|
355
|
+
const node = collection.getItem(key);
|
356
|
+
if (node &&
|
357
|
+
node.type === 'item' &&
|
358
|
+
!selectionManager.isDisabled(key)) {
|
359
|
+
return key;
|
360
|
+
}
|
361
|
+
}
|
362
|
+
return null;
|
363
|
+
};
|
364
|
+
// Helper function to find first or last selectable key
|
365
|
+
const findFirstLastSelectableKey = (direction) => {
|
366
|
+
const keys = [...collection.getKeys()];
|
367
|
+
const keysToCheck = direction === 'forward' ? keys : keys.reverse();
|
368
|
+
for (const key of keysToCheck) {
|
369
|
+
const node = collection.getItem(key);
|
370
|
+
if (node &&
|
371
|
+
node.type === 'item' &&
|
372
|
+
!selectionManager.isDisabled(key)) {
|
373
|
+
return key;
|
374
|
+
}
|
375
|
+
}
|
376
|
+
return null;
|
377
|
+
};
|
378
|
+
let nextKey;
|
379
|
+
const direction = isArrowDown ? 'forward' : 'backward';
|
380
|
+
if (currentKey == null) {
|
381
|
+
// No current focus, start from the first/last item
|
382
|
+
nextKey = findFirstLastSelectableKey(direction);
|
383
|
+
}
|
384
|
+
else {
|
385
|
+
// Find next selectable item from current position
|
386
|
+
const candidateKey = direction === 'forward'
|
387
|
+
? collection.getKeyAfter(currentKey)
|
388
|
+
: collection.getKeyBefore(currentKey);
|
389
|
+
nextKey = findNextSelectableKey(candidateKey, direction);
|
390
|
+
// If no next key found and focus wrapping is enabled, wrap to first/last selectable item
|
391
|
+
if (nextKey == null) {
|
392
|
+
nextKey = findFirstLastSelectableKey(direction);
|
393
|
+
}
|
394
|
+
}
|
395
|
+
if (nextKey != null) {
|
396
|
+
selectionManager.setFocusedKey(nextKey);
|
397
|
+
setFocusedKey(nextKey);
|
398
|
+
}
|
399
|
+
}
|
400
|
+
else if (e.key === 'Enter' ||
|
401
|
+
(e.key === ' ' && !searchValue.trim())) {
|
402
|
+
const currentFocusedKey = focusedKey || treeState.selectionManager.focusedKey;
|
403
|
+
if (currentFocusedKey != null) {
|
404
|
+
e.preventDefault();
|
405
|
+
// Trigger action for the focused item (like Menu does)
|
406
|
+
// First check if there's a selection mode, if so, handle selection
|
407
|
+
if (treeState.selectionManager.selectionMode !== 'none') {
|
408
|
+
treeState.selectionManager.select(currentFocusedKey, e);
|
409
|
+
}
|
410
|
+
else {
|
411
|
+
// Default behavior: trigger action
|
412
|
+
const node = treeState.collection.getItem(currentFocusedKey);
|
413
|
+
if (node) {
|
414
|
+
// Call the tree state's action handler
|
415
|
+
const onAction = completeProps.onAction;
|
416
|
+
if (onAction) {
|
417
|
+
onAction(currentFocusedKey);
|
418
|
+
}
|
419
|
+
// Also call the item's individual onAction if it exists
|
420
|
+
if (node.props?.onAction) {
|
421
|
+
node.props.onAction(currentFocusedKey);
|
422
|
+
}
|
423
|
+
}
|
424
|
+
}
|
425
|
+
// Close the menu if we're in a trigger context and closeOnSelect is enabled (default behavior)
|
426
|
+
const { onClose, closeOnSelect } = contextProps;
|
427
|
+
if (onClose && closeOnSelect !== false) {
|
428
|
+
onClose();
|
429
|
+
}
|
430
|
+
}
|
431
|
+
}
|
432
|
+
else if (e.key === 'Escape') {
|
433
|
+
if (searchValue) {
|
434
|
+
e.preventDefault();
|
435
|
+
handleSearchChange('');
|
436
|
+
}
|
437
|
+
}
|
438
|
+
} }), isLoading && (_jsx(StyledLoadingWrapper, { children: _jsx(LoadingIcon, { role: "progressbar", "aria-label": "Loading commands", "aria-hidden": false }) })), !isLoading && !showEmptyState && (_jsx(StyledMenuWrapper, { children: _jsx(StyledMenu, { ...menuProps, ref: menuRef, id: `${qa || 'CommandMenu'}-menu`, "aria-label": "Command menu", qa: "Menu", "data-size": size, mods: mods, styles: {
|
439
|
+
border: 'none',
|
440
|
+
boxShadow: 'none',
|
441
|
+
radius: 0,
|
442
|
+
padding: '0.5x',
|
443
|
+
}, children: renderedItems }) })), !isLoading && showEmptyState && (_jsx(StyledEmptyState, { children: emptyLabel })), footer && (_jsx(StyledFooter, { role: "presentation", styles: footerStyles, children: footer }))] }));
|
444
|
+
}
|
445
|
+
// forwardRef doesn't support generic parameters, so cast the result to the correct type
|
446
|
+
const _CommandMenu = React.forwardRef(CommandMenuBase);
|
447
|
+
// Attach Trigger alias from MenuTrigger for consistent API
|
448
|
+
// Also attach Item and Section for compound component pattern
|
449
|
+
const __CommandMenu = Object.assign(_CommandMenu, {
|
450
|
+
Trigger: MenuTrigger,
|
451
|
+
Item,
|
452
|
+
Section,
|
453
|
+
displayName: 'CommandMenu',
|
454
|
+
});
|
455
|
+
export { __CommandMenu as CommandMenu };
|
456
|
+
|
457
|
+
|
@@ -0,0 +1,110 @@
|
|
1
|
+
/**
|
2
|
+
* @license MIT
|
3
|
+
* author: Cube Dev Team
|
4
|
+
* @cube-dev/ui-kit v0.66.0
|
5
|
+
* Released under the MIT license.
|
6
|
+
*/
|
7
|
+
|
8
|
+
import { tasty } from '../../../tasty';
|
9
|
+
export const StyledCommandMenu = tasty({
|
10
|
+
qa: 'CommandMenu',
|
11
|
+
styles: {
|
12
|
+
display: 'grid',
|
13
|
+
flow: 'row',
|
14
|
+
gridColumns: 'minmax(0, 1fr)',
|
15
|
+
gridRows: {
|
16
|
+
'': 'max-content minmax(0, 1fr)',
|
17
|
+
header: 'max-content max-content minmax(0, 1fr)',
|
18
|
+
footer: 'max-content minmax(0, 1fr) max-content max-content',
|
19
|
+
'header & footer': 'max-content max-content minmax(0, 1fr) max-content max-content',
|
20
|
+
},
|
21
|
+
placeContent: 'stretch',
|
22
|
+
placeItems: 'stretch',
|
23
|
+
fill: '#white',
|
24
|
+
border: '#border',
|
25
|
+
radius: '(1cr + 1bw)',
|
26
|
+
shadow: {
|
27
|
+
'': false,
|
28
|
+
'popover | tray': '0px 5px 15px #dark.05',
|
29
|
+
},
|
30
|
+
overflow: 'hidden',
|
31
|
+
width: '20x 50x',
|
32
|
+
height: {
|
33
|
+
'': 'initial',
|
34
|
+
popover: 'initial max-content (50vh - 4x)',
|
35
|
+
tray: 'initial max-content (100vh - 4x)',
|
36
|
+
},
|
37
|
+
},
|
38
|
+
});
|
39
|
+
export const StyledSearchInput = tasty({
|
40
|
+
qa: 'SearchInput',
|
41
|
+
as: 'input',
|
42
|
+
styles: {
|
43
|
+
display: 'flex',
|
44
|
+
width: '100%',
|
45
|
+
color: '#dark',
|
46
|
+
fill: '#white',
|
47
|
+
border: '#border bottom',
|
48
|
+
outline: 'none',
|
49
|
+
transition: 'theme',
|
50
|
+
radius: 0,
|
51
|
+
padding: '@vertical-padding @right-padding @vertical-padding @left-padding',
|
52
|
+
textAlign: 'left',
|
53
|
+
reset: 'input',
|
54
|
+
preset: 't3',
|
55
|
+
margin: 0,
|
56
|
+
boxSizing: 'border-box',
|
57
|
+
userSelect: 'auto',
|
58
|
+
'@vertical-padding': {
|
59
|
+
'': '(.75x - 1bw)',
|
60
|
+
'[data-size="medium"]': '(1.25x - 1bw)',
|
61
|
+
},
|
62
|
+
'@left-padding': {
|
63
|
+
'': '1x',
|
64
|
+
'[data-size="medium"]': '1x',
|
65
|
+
},
|
66
|
+
'@right-padding': {
|
67
|
+
'': '1x',
|
68
|
+
'[data-size="medium"]': '1x',
|
69
|
+
},
|
70
|
+
'&::placeholder': {
|
71
|
+
color: '#dark-03',
|
72
|
+
},
|
73
|
+
},
|
74
|
+
});
|
75
|
+
export const StyledLoadingWrapper = tasty({
|
76
|
+
qa: 'LoadingWrapper',
|
77
|
+
styles: {
|
78
|
+
display: 'flex',
|
79
|
+
padding: '2x',
|
80
|
+
placeContent: 'center',
|
81
|
+
placeItems: 'center',
|
82
|
+
color: '#dark-03',
|
83
|
+
},
|
84
|
+
});
|
85
|
+
export const StyledEmptyState = tasty({
|
86
|
+
qa: 'EmptyState',
|
87
|
+
styles: {
|
88
|
+
display: 'flex',
|
89
|
+
padding: '2x',
|
90
|
+
placeContent: 'center',
|
91
|
+
placeItems: 'center',
|
92
|
+
color: '#dark-03',
|
93
|
+
preset: 't3',
|
94
|
+
},
|
95
|
+
});
|
96
|
+
export const StyledMenuWrapper = tasty({
|
97
|
+
qa: 'MenuWrapper',
|
98
|
+
styles: {
|
99
|
+
display: 'grid',
|
100
|
+
flow: 'row',
|
101
|
+
gridColumns: 'minmax(0, 1fr)',
|
102
|
+
placeContent: 'stretch',
|
103
|
+
placeItems: 'stretch',
|
104
|
+
width: '100%',
|
105
|
+
overflow: 'auto',
|
106
|
+
scrollbar: 'styled',
|
107
|
+
},
|
108
|
+
});
|
109
|
+
|
110
|
+
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @license MIT
|
3
3
|
* author: Cube Dev Team
|
4
|
-
* @cube-dev/ui-kit v0.
|
4
|
+
* @cube-dev/ui-kit v0.66.0
|
5
5
|
* Released under the MIT license.
|
6
6
|
*/
|
7
7
|
|
@@ -17,26 +17,52 @@ import { TooltipProvider, } from '../../overlays/Tooltip/TooltipProvider';
|
|
17
17
|
import { useMenuContext } from './context';
|
18
18
|
import { MenuItem } from './MenuItem';
|
19
19
|
import { MenuSection } from './MenuSection';
|
20
|
-
import { StyledDivider, StyledHeader, StyledMenu } from './styled';
|
20
|
+
import { StyledDivider, StyledFooter, StyledHeader, StyledMenu, } from './styled';
|
21
21
|
function Menu(props, ref) {
|
22
|
-
const { header, footer, itemStyles, sectionStyles, sectionHeadingStyles, selectionIcon, qa, ...rest } = props;
|
22
|
+
const { header, footer, itemStyles, sectionStyles, sectionHeadingStyles, selectionIcon, size = 'small', qa, selectedKeys, defaultSelectedKeys, onSelectionChange, ...rest } = props;
|
23
23
|
const domRef = useDOMRef(ref);
|
24
24
|
const contextProps = useMenuContext();
|
25
|
-
|
25
|
+
// Convert string[] to Set<Key> for React Aria compatibility
|
26
|
+
const ariaSelectedKeys = selectedKeys ? new Set(selectedKeys) : undefined;
|
27
|
+
const ariaDefaultSelectedKeys = defaultSelectedKeys
|
28
|
+
? new Set(defaultSelectedKeys)
|
29
|
+
: undefined;
|
30
|
+
const handleSelectionChange = onSelectionChange
|
31
|
+
? (keys) => {
|
32
|
+
if (keys === 'all') {
|
33
|
+
// Handle 'all' selection case - collect all available keys
|
34
|
+
const allKeys = Array.from(state.collection.getKeys()).map((key) => String(key));
|
35
|
+
onSelectionChange(allKeys);
|
36
|
+
}
|
37
|
+
else if (keys instanceof Set) {
|
38
|
+
onSelectionChange(Array.from(keys).map((key) => String(key)));
|
39
|
+
}
|
40
|
+
else {
|
41
|
+
onSelectionChange([]);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
: undefined;
|
45
|
+
const completeProps = mergeProps(contextProps, rest, {
|
46
|
+
selectedKeys: ariaSelectedKeys,
|
47
|
+
defaultSelectedKeys: ariaDefaultSelectedKeys,
|
48
|
+
onSelectionChange: handleSelectionChange,
|
49
|
+
});
|
26
50
|
// Props used for collection building.
|
27
51
|
const treeProps = completeProps;
|
28
52
|
const state = useTreeState(treeProps);
|
29
53
|
const collectionItems = [...state.collection];
|
30
54
|
const hasSections = collectionItems.some((item) => item.type === 'section');
|
31
|
-
const { menuProps } = useMenu(
|
55
|
+
const { menuProps } = useMenu(completeProps, state, domRef);
|
32
56
|
const styles = useMemo(() => extractStyles(completeProps, CONTAINER_STYLES), [completeProps]);
|
33
57
|
const defaultProps = {
|
34
58
|
qa,
|
35
59
|
styles,
|
60
|
+
'data-size': size,
|
36
61
|
mods: {
|
37
62
|
sections: hasSections,
|
38
63
|
footer: !!footer,
|
39
64
|
header: !!header,
|
65
|
+
popover: completeProps.mods?.popover,
|
40
66
|
},
|
41
67
|
};
|
42
68
|
// Sync the ref stored in the context object with the DOM ref returned by useDOMRef.
|
@@ -51,11 +77,11 @@ function Menu(props, ref) {
|
|
51
77
|
if (!isFirstSection) {
|
52
78
|
items.push(_jsx(StyledDivider, { role: "separator", "aria-orientation": "horizontal" }, `divider-${String(item.key)}`));
|
53
79
|
}
|
54
|
-
items.push(_jsx(MenuSection, { item: item, state: state, styles: sectionStyles, itemStyles: itemStyles, headingStyles: sectionHeadingStyles, selectionIcon: selectionIcon }, item.key));
|
80
|
+
items.push(_jsx(MenuSection, { item: item, state: state, styles: sectionStyles, itemStyles: itemStyles, headingStyles: sectionHeadingStyles, selectionIcon: selectionIcon, size: size }, item.key));
|
55
81
|
isFirstSection = false;
|
56
82
|
return;
|
57
83
|
}
|
58
|
-
let menuItem = (_jsx(MenuItem, { item: item, state: state, styles: itemStyles, selectionIcon: selectionIcon, onAction: item.onAction }, item.key));
|
84
|
+
let menuItem = (_jsx(MenuItem, { item: item, state: state, styles: itemStyles, selectionIcon: selectionIcon, size: size, onAction: item.onAction }, item.key));
|
59
85
|
// Apply tooltip wrapper if tooltip property is provided
|
60
86
|
if (item.props.tooltip) {
|
61
87
|
const tooltipProps = typeof item.props.tooltip === 'string'
|
@@ -79,7 +105,7 @@ function Menu(props, ref) {
|
|
79
105
|
selectionIcon,
|
80
106
|
sectionHeadingStyles,
|
81
107
|
]);
|
82
|
-
return (_jsxs(StyledMenu, { ...mergeProps(defaultProps, menuProps, filterBaseProps(completeProps)), ref: domRef, role: menuProps.role ?? 'menu', children: [header && _jsx(StyledHeader, { role: "presentation", children: header }), renderedItems] }));
|
108
|
+
return (_jsxs(StyledMenu, { ...mergeProps(defaultProps, menuProps, filterBaseProps(completeProps)), ref: domRef, role: menuProps.role ?? 'menu', children: [header && _jsx(StyledHeader, { role: "presentation", children: header }), renderedItems, footer && _jsx(StyledFooter, { role: "presentation", children: footer })] }));
|
83
109
|
}
|
84
110
|
// forwardRef doesn't support generic parameters, so cast the result to the correct type
|
85
111
|
// https://stackoverflow.com/questions/58469229/react-with-typescript-generics-while-using-react-forwardref
|