@cube-dev/ui-kit 0.67.0 → 0.69.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 +28 -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 +36 -29
- 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 +16 -26
- package/es/components/actions/CommandMenu/index.js +1 -1
- package/es/components/actions/CommandMenu/styled.js +8 -16
- package/es/components/actions/Menu/Menu.js +18 -13
- package/es/components/actions/Menu/MenuItem.js +2 -1
- package/es/components/actions/Menu/MenuSection.js +1 -1
- package/es/components/actions/Menu/MenuTrigger.js +1 -1
- package/es/components/actions/Menu/context.js +1 -1
- package/es/components/actions/Menu/index.js +1 -1
- package/es/components/actions/Menu/styled.js +49 -24
- package/es/components/actions/index.js +1 -1
- package/es/components/actions/use-action.js +1 -1
- package/es/components/actions/use-anchored-menu.js +1 -1
- package/es/components/actions/use-context-menu.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 +1 -1
- 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 +2 -2
- 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 +1 -1
- 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/FilterListBox/FilterListBox.js +584 -0
- package/es/components/fields/FilterListBox/index.js +10 -0
- package/es/components/fields/FilterPicker/FilterPicker.js +426 -0
- package/es/components/fields/FilterPicker/index.js +10 -0
- 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 +325 -238
- 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 +3 -3
- package/es/components/fields/SearchInput/index.js +1 -1
- package/es/components/fields/Select/Select.js +23 -14
- 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 +4 -4
- 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 +2 -2
- 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 +26 -11
- package/es/components/fields/TextInput/index.js +1 -1
- package/es/components/fields/TextInputMapper/TextInputMapper.js +7 -7
- package/es/components/fields/TextInputMapper/index.js +1 -1
- package/es/components/fields/index.js +3 -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 +5 -2
- 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 -2
- package/es/components/navigation/Link/Link.js +1 -1
- package/es/components/organisms/FileTabs/FileTabs.js +1 -2
- 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 +2 -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/index.js +1 -1
- package/es/components/overlays/Dialog/use-dialog-container.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 +2 -2
- package/es/components/overlays/NewNotifications/NotificationView/NotificationCloseButton.js +1 -2
- 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/ChartKPIIcon.js +12 -0
- 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 +2 -1
- package/es/icons/wrap-icon.js +1 -1
- package/es/index.js +1 -1
- 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 +4 -1
- package/es/tasty/utils/warnings.js +1 -1
- package/es/tokens.js +20 -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 +2 -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/sharedStore.js +1 -1
- package/es/utils/react/useCombinedRefs.js +1 -1
- package/es/utils/react/useControlledFocusVisible.js +42 -0
- package/es/utils/react/useEventBus.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 +1 -1
- 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 +2 -1
- package/types/components/actions/Button/Button.d.ts +20 -13
- package/types/components/actions/CommandMenu/CommandMenu.d.ts +1 -1
- package/types/components/actions/Menu/Menu.d.ts +4 -1
- package/types/components/actions/Menu/MenuItem.d.ts +1 -1
- package/types/components/actions/Menu/styled.d.ts +1 -0
- package/types/components/fields/ComboBox/ComboBox.d.ts +1 -1
- package/types/components/fields/FilterListBox/FilterListBox.d.ts +51 -0
- package/types/components/fields/FilterListBox/index.d.ts +1 -0
- package/types/components/fields/FilterPicker/FilterPicker.d.ts +55 -0
- package/types/components/fields/FilterPicker/index.d.ts +1 -0
- package/types/components/fields/ListBox/ListBox.d.ts +48 -22
- package/types/components/fields/Select/Select.d.ts +7 -1
- package/types/components/fields/TextInput/TextInputBase.d.ts +1 -1
- package/types/components/fields/TextInputMapper/TextInputMapper.d.ts +2 -0
- package/types/components/fields/index.d.ts +2 -0
- package/types/icons/ChartKPIIcon.d.ts +4 -0
- package/types/icons/index.d.ts +1 -0
- package/types/shared/form.d.ts +2 -0
- package/types/tasty/utils/styles.d.ts +1 -0
- package/types/tokens.d.ts +17 -0
- package/types/utils/react/index.d.ts +2 -0
- package/types/utils/react/useControlledFocusVisible.d.ts +10 -0
@@ -1,30 +1,36 @@
|
|
1
1
|
/**
|
2
2
|
* @license MIT
|
3
3
|
* author: Cube Dev Team
|
4
|
-
* @cube-dev/ui-kit v0.
|
4
|
+
* @cube-dev/ui-kit v0.69.0
|
5
5
|
* Released under the MIT license.
|
6
6
|
*/
|
7
7
|
|
8
8
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
9
|
-
import {
|
10
|
-
import {
|
9
|
+
import { useHover } from '@react-aria/interactions';
|
10
|
+
import { useVirtualizer } from '@tanstack/react-virtual';
|
11
|
+
import { forwardRef, useEffect, useMemo, useRef, } from 'react';
|
12
|
+
import { useKeyboard, useListBox, useListBoxSection, useOption, } from 'react-aria';
|
11
13
|
import { Section as BaseSection, Item, useListState } from 'react-stately';
|
12
|
-
import {
|
14
|
+
import { useWarn } from '../../../_internal/hooks/use-warn';
|
15
|
+
import { CheckIcon } from '../../../icons';
|
13
16
|
import { useProviderProps } from '../../../provider';
|
14
17
|
import { BASE_STYLES, COLOR_STYLES, extractStyles, OUTER_STYLES, tasty, } from '../../../tasty';
|
15
|
-
import {
|
18
|
+
import { SIZES } from '../../../tokens';
|
19
|
+
import { mergeProps, useCombinedRefs } from '../../../utils/react';
|
16
20
|
import { useFocus } from '../../../utils/react/interactions';
|
17
|
-
|
21
|
+
// Import Menu styled components for header and footer
|
22
|
+
import { StyledDivider, StyledFooter, StyledHeader, StyledSectionHeading, } from '../../actions/Menu/styled';
|
18
23
|
import { useFieldProps, useFormProps, wrapWithField } from '../../form';
|
19
|
-
import { DEFAULT_INPUT_STYLES, INPUT_WRAPPER_STYLES, } from '../TextInput/TextInputBase';
|
20
24
|
const ListBoxWrapperElement = tasty({
|
25
|
+
qa: 'ListBox',
|
21
26
|
styles: {
|
22
|
-
display: '
|
27
|
+
display: 'grid',
|
28
|
+
gridColumns: '1sf',
|
29
|
+
gridRows: 'max-content 1sf max-content',
|
23
30
|
flow: 'column',
|
24
31
|
gap: 0,
|
25
32
|
position: 'relative',
|
26
|
-
radius:
|
27
|
-
fill: '#white',
|
33
|
+
radius: '1cr',
|
28
34
|
color: '#dark-02',
|
29
35
|
transition: 'theme',
|
30
36
|
outline: {
|
@@ -38,31 +44,31 @@ const ListBoxWrapperElement = tasty({
|
|
38
44
|
valid: '#success-text.50',
|
39
45
|
invalid: '#danger-text.50',
|
40
46
|
disabled: true,
|
47
|
+
'popover | searchable': false,
|
41
48
|
},
|
42
49
|
},
|
43
50
|
});
|
44
|
-
const SearchWrapperElement = tasty({
|
45
|
-
styles: {
|
46
|
-
...INPUT_WRAPPER_STYLES,
|
47
|
-
border: '#clear',
|
48
|
-
radius: '1r top',
|
49
|
-
borderBottom: '1bw solid #border',
|
50
|
-
},
|
51
|
-
});
|
52
|
-
const SearchInputElement = tasty({
|
53
|
-
as: 'input',
|
54
|
-
styles: DEFAULT_INPUT_STYLES,
|
55
|
-
});
|
56
51
|
const ListElement = tasty({
|
57
52
|
as: 'ul',
|
58
53
|
styles: {
|
59
|
-
display: '
|
60
|
-
|
61
|
-
flow: 'column',
|
62
|
-
margin: '0',
|
63
|
-
padding: '.5x',
|
54
|
+
display: 'block',
|
55
|
+
padding: 0,
|
64
56
|
listStyle: 'none',
|
65
|
-
|
57
|
+
boxSizing: 'border-box',
|
58
|
+
margin: {
|
59
|
+
'': '.5x .5x 0 .5x',
|
60
|
+
sections: '0 .5x',
|
61
|
+
},
|
62
|
+
height: 'max-content',
|
63
|
+
},
|
64
|
+
});
|
65
|
+
// NEW: dedicated scroll container for ListBox
|
66
|
+
const ListBoxScrollElement = tasty({
|
67
|
+
as: 'div',
|
68
|
+
styles: {
|
69
|
+
display: 'grid',
|
70
|
+
gridColumns: '1sf',
|
71
|
+
gridRows: '1sf',
|
66
72
|
overflow: 'auto',
|
67
73
|
scrollbar: 'styled',
|
68
74
|
},
|
@@ -71,13 +77,25 @@ const OptionElement = tasty({
|
|
71
77
|
as: 'li',
|
72
78
|
styles: {
|
73
79
|
display: 'flex',
|
74
|
-
flow: '
|
75
|
-
|
76
|
-
|
80
|
+
flow: 'row',
|
81
|
+
placeItems: 'center start',
|
82
|
+
gap: '.75x',
|
83
|
+
padding: '.5x 1x',
|
84
|
+
margin: {
|
85
|
+
'': '0 0 1bw 0',
|
86
|
+
':last-of-type': '0',
|
87
|
+
},
|
88
|
+
height: {
|
89
|
+
'': 'min @size-md',
|
90
|
+
'[data-size="large"]': 'min @size-lg',
|
91
|
+
},
|
92
|
+
boxSizing: 'border-box',
|
77
93
|
radius: '1r',
|
78
|
-
cursor:
|
94
|
+
cursor: {
|
95
|
+
'': 'default',
|
96
|
+
disabled: 'not-allowed',
|
97
|
+
},
|
79
98
|
transition: 'theme',
|
80
|
-
outline: 0,
|
81
99
|
border: 0,
|
82
100
|
userSelect: 'none',
|
83
101
|
color: {
|
@@ -89,23 +107,75 @@ const OptionElement = tasty({
|
|
89
107
|
},
|
90
108
|
fill: {
|
91
109
|
'': '#clear',
|
92
|
-
focused: '#dark.03',
|
93
|
-
selected: '#dark.
|
94
|
-
'selected & focused': '#dark.
|
95
|
-
|
110
|
+
'hovered | focused': '#dark.03',
|
111
|
+
selected: '#dark.09',
|
112
|
+
'selected & (hovered | focused)': '#dark.12',
|
113
|
+
'selected & hovered & focused': '#dark.15',
|
114
|
+
pressed: '#dark.09',
|
96
115
|
valid: '#success-bg',
|
97
116
|
invalid: '#danger-bg',
|
98
117
|
disabled: '#clear',
|
99
118
|
},
|
119
|
+
outline: 0,
|
120
|
+
backgroundClip: 'padding-box',
|
121
|
+
CheckboxWrapper: {
|
122
|
+
cursor: 'pointer',
|
123
|
+
padding: '.75x',
|
124
|
+
margin: '-.75x',
|
125
|
+
},
|
126
|
+
Checkbox: {
|
127
|
+
display: 'grid',
|
128
|
+
placeItems: 'center',
|
129
|
+
radius: '.5r',
|
130
|
+
width: '(2x - 2bw)',
|
131
|
+
height: '(2x - 2bw)',
|
132
|
+
flexShrink: 0,
|
133
|
+
transition: 'theme',
|
134
|
+
opacity: {
|
135
|
+
'': 0,
|
136
|
+
'selected | :hover | focused': 1,
|
137
|
+
},
|
138
|
+
fill: {
|
139
|
+
'': '#white',
|
140
|
+
selected: '#purple-text',
|
141
|
+
'invalid & !selected': '#white',
|
142
|
+
'invalid & selected': '#danger',
|
143
|
+
disabled: '#dark.12',
|
144
|
+
},
|
145
|
+
color: {
|
146
|
+
'': '#white',
|
147
|
+
'disabled & !selected': '#clear',
|
148
|
+
},
|
149
|
+
border: {
|
150
|
+
'': '#dark.30',
|
151
|
+
invalid: '#danger',
|
152
|
+
'disabled | (selected & !invalid)': '#clear',
|
153
|
+
},
|
154
|
+
},
|
155
|
+
Content: {
|
156
|
+
display: 'flex',
|
157
|
+
flow: 'column',
|
158
|
+
gap: '.25x',
|
159
|
+
flex: 1,
|
160
|
+
width: 'max 100%',
|
161
|
+
},
|
100
162
|
Label: {
|
101
163
|
preset: 't3',
|
102
164
|
color: 'inherit',
|
165
|
+
overflow: 'hidden',
|
166
|
+
textOverflow: 'ellipsis',
|
167
|
+
whiteSpace: 'nowrap',
|
168
|
+
width: 'max 100%',
|
103
169
|
},
|
104
170
|
Description: {
|
105
171
|
preset: 't4',
|
106
172
|
color: {
|
107
173
|
'': '#dark-03',
|
108
174
|
},
|
175
|
+
overflow: 'hidden',
|
176
|
+
textOverflow: 'ellipsis',
|
177
|
+
whiteSpace: 'nowrap',
|
178
|
+
width: 'max 100%',
|
109
179
|
},
|
110
180
|
},
|
111
181
|
});
|
@@ -113,35 +183,24 @@ const SectionWrapperElement = tasty({
|
|
113
183
|
as: 'li',
|
114
184
|
styles: {
|
115
185
|
display: 'block',
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
preset: 't4 strong',
|
121
|
-
color: '#dark-03',
|
122
|
-
padding: '.5x 1x .25x',
|
123
|
-
userSelect: 'none',
|
186
|
+
padding: {
|
187
|
+
'': 0,
|
188
|
+
':last-of-type': '0 0 .5x 0',
|
189
|
+
},
|
124
190
|
},
|
125
191
|
});
|
126
192
|
const SectionListElement = tasty({
|
193
|
+
qa: 'ListBoxSectionList',
|
127
194
|
as: 'ul',
|
128
195
|
styles: {
|
129
196
|
display: 'flex',
|
130
|
-
gap: '
|
197
|
+
gap: '0',
|
131
198
|
flow: 'column',
|
132
199
|
margin: '0',
|
133
200
|
padding: '0',
|
134
201
|
listStyle: 'none',
|
135
202
|
},
|
136
203
|
});
|
137
|
-
const DividerElement = tasty({
|
138
|
-
as: 'li',
|
139
|
-
styles: {
|
140
|
-
height: '1bw',
|
141
|
-
fill: '#border',
|
142
|
-
margin: '.5x 0',
|
143
|
-
},
|
144
|
-
});
|
145
204
|
const PROP_STYLES = [...BASE_STYLES, ...OUTER_STYLES, ...COLOR_STYLES];
|
146
205
|
export const ListBox = forwardRef(function ListBox(props, ref) {
|
147
206
|
props = useProviderProps(props);
|
@@ -150,84 +209,23 @@ export const ListBox = forwardRef(function ListBox(props, ref) {
|
|
150
209
|
valuePropsMapper: ({ value, onChange }) => {
|
151
210
|
const fieldProps = {};
|
152
211
|
if (props.selectionMode === 'multiple') {
|
153
|
-
fieldProps.selectedKeys =
|
154
|
-
? value
|
155
|
-
: value
|
156
|
-
? [value]
|
157
|
-
: [];
|
212
|
+
fieldProps.selectedKeys = value || [];
|
158
213
|
}
|
159
214
|
else {
|
160
215
|
fieldProps.selectedKey = value ?? null;
|
161
216
|
}
|
162
217
|
fieldProps.onSelectionChange = (key) => {
|
163
218
|
if (props.selectionMode === 'multiple') {
|
164
|
-
|
165
|
-
onChange(key);
|
166
|
-
}
|
167
|
-
else if (key instanceof Set) {
|
168
|
-
onChange(Array.from(key));
|
169
|
-
}
|
170
|
-
else {
|
171
|
-
onChange(key ? [key] : []);
|
172
|
-
}
|
219
|
+
onChange(key ? (Array.isArray(key) ? key : [key]) : []);
|
173
220
|
}
|
174
221
|
else {
|
175
|
-
|
176
|
-
onChange(key.size === 0 ? null : Array.from(key)[0]);
|
177
|
-
}
|
178
|
-
else {
|
179
|
-
onChange(key);
|
180
|
-
}
|
222
|
+
onChange(Array.isArray(key) ? key[0] : key);
|
181
223
|
}
|
182
224
|
};
|
183
225
|
return fieldProps;
|
184
226
|
},
|
185
227
|
});
|
186
|
-
let { qa, label, extra, labelStyles, isRequired, necessityIndicator, validationState, isDisabled,
|
187
|
-
const [searchValue, setSearchValue] = useState('');
|
188
|
-
const { contains } = useFilter({ sensitivity: 'base' });
|
189
|
-
// Choose the text filter function: user-provided `filter` prop (if any)
|
190
|
-
// or the default `contains` helper from `useFilter`.
|
191
|
-
const textFilterFn = useMemo(() => filter || contains, [filter, contains]);
|
192
|
-
// Collection-level filter function expected by `useListState`.
|
193
|
-
// It converts the text filter (textValue, searchValue) ⟶ boolean
|
194
|
-
// into the shape `(nodes) => Iterable<Node<T>>`.
|
195
|
-
// The current `searchValue` is captured in the closure – every re-render
|
196
|
-
// produces a new function so React Stately updates the collection when the
|
197
|
-
// search term changes.
|
198
|
-
const collectionFilter = useCallback((nodes) => {
|
199
|
-
const term = searchValue.trim();
|
200
|
-
// If there is no search term, return nodes untouched to avoid
|
201
|
-
// unnecessary object allocations.
|
202
|
-
if (!term) {
|
203
|
-
return nodes;
|
204
|
-
}
|
205
|
-
// Recursive helper to filter sections and items.
|
206
|
-
const filterNodes = (iter) => {
|
207
|
-
const result = [];
|
208
|
-
for (const node of iter) {
|
209
|
-
if (node.type === 'section') {
|
210
|
-
const filteredChildren = filterNodes(node.childNodes);
|
211
|
-
if (filteredChildren.length) {
|
212
|
-
// Preserve the original node but replace `childNodes` with the
|
213
|
-
// filtered iterable so that React-Stately can still traverse it.
|
214
|
-
result.push({
|
215
|
-
...node,
|
216
|
-
childNodes: filteredChildren,
|
217
|
-
});
|
218
|
-
}
|
219
|
-
}
|
220
|
-
else {
|
221
|
-
const text = node.textValue ?? String(node.rendered ?? '');
|
222
|
-
if (textFilterFn(text, term)) {
|
223
|
-
result.push(node);
|
224
|
-
}
|
225
|
-
}
|
226
|
-
}
|
227
|
-
return result;
|
228
|
-
};
|
229
|
-
return filterNodes(nodes);
|
230
|
-
}, [searchValue, textFilterFn]);
|
228
|
+
let { qa, label, extra, labelStyles, isRequired, necessityIndicator, validationState, isDisabled, listStyles, optionStyles, sectionStyles, headingStyles, listRef, message, description, styles, mods: externalMods, size = 'medium', labelSuffix, selectedKey, defaultSelectedKey, selectedKeys, defaultSelectedKeys, shouldUseVirtualFocus, onSelectionChange, stateRef, focusOnHover, header, footer, headerStyles, footerStyles, escapeKeyBehavior, onEscape, isCheckable, onOptionClick, ...otherProps } = props;
|
231
229
|
// Wrap onSelectionChange to prevent selection when disabled and handle React Aria's Set format
|
232
230
|
const externalSelectionHandler = onSelectionChange || props.onChange;
|
233
231
|
const wrappedOnSelectionChange = useMemo(() => {
|
@@ -259,7 +257,6 @@ export const ListBox = forwardRef(function ListBox(props, ref) {
|
|
259
257
|
// Prepare props for useListState with correct selection props
|
260
258
|
const listStateProps = {
|
261
259
|
...props,
|
262
|
-
filter: collectionFilter,
|
263
260
|
onSelectionChange: wrappedOnSelectionChange,
|
264
261
|
isDisabled,
|
265
262
|
selectionMode: props.selectionMode || 'single',
|
@@ -267,14 +264,10 @@ export const ListBox = forwardRef(function ListBox(props, ref) {
|
|
267
264
|
// Set selection props based on mode
|
268
265
|
if (listStateProps.selectionMode === 'multiple') {
|
269
266
|
if (selectedKeys !== undefined) {
|
270
|
-
listStateProps.selectedKeys =
|
271
|
-
selectedKeys === 'all' ? 'all' : new Set(selectedKeys);
|
267
|
+
listStateProps.selectedKeys = new Set(selectedKeys);
|
272
268
|
}
|
273
269
|
if (defaultSelectedKeys !== undefined) {
|
274
|
-
listStateProps.defaultSelectedKeys =
|
275
|
-
defaultSelectedKeys === 'all'
|
276
|
-
? 'all'
|
277
|
-
: new Set(defaultSelectedKeys);
|
270
|
+
listStateProps.defaultSelectedKeys = new Set(defaultSelectedKeys);
|
278
271
|
}
|
279
272
|
// Remove single-selection props if any
|
280
273
|
delete listStateProps.selectedKey;
|
@@ -295,170 +288,264 @@ export const ListBox = forwardRef(function ListBox(props, ref) {
|
|
295
288
|
delete listStateProps.selectedKey;
|
296
289
|
delete listStateProps.defaultSelectedKey;
|
297
290
|
}
|
298
|
-
const listState = useListState(
|
291
|
+
const listState = useListState({
|
292
|
+
...listStateProps,
|
293
|
+
});
|
294
|
+
// Track whether the last focus change was due to keyboard navigation
|
295
|
+
const lastFocusSourceRef = useRef('other');
|
296
|
+
// Expose the list state instance via the provided ref (if any)
|
297
|
+
if (stateRef) {
|
298
|
+
stateRef.current = {
|
299
|
+
...listState,
|
300
|
+
lastFocusSourceRef,
|
301
|
+
};
|
302
|
+
}
|
303
|
+
// Warn if isCheckable is false in single selection mode
|
304
|
+
useWarn(isCheckable === false && props.selectionMode === 'single', {
|
305
|
+
key: ['listbox-checkable-single-mode'],
|
306
|
+
args: [
|
307
|
+
'CubeUIKit: isCheckable=false is not recommended in single selection mode as it may confuse users about selection behavior.',
|
308
|
+
],
|
309
|
+
});
|
310
|
+
// Custom keyboard handling to prevent selection clearing on Escape while allowing overlay dismiss
|
311
|
+
const { keyboardProps } = useKeyboard({
|
312
|
+
onKeyDown: (e) => {
|
313
|
+
// Mark focus changes from keyboard navigation
|
314
|
+
if (e.key === 'ArrowDown' ||
|
315
|
+
e.key === 'ArrowUp' ||
|
316
|
+
e.key === 'Home' ||
|
317
|
+
e.key === 'End' ||
|
318
|
+
e.key === 'PageUp' ||
|
319
|
+
e.key === 'PageDown') {
|
320
|
+
lastFocusSourceRef.current = 'keyboard';
|
321
|
+
}
|
322
|
+
if (e.key === 'Escape' && onEscape) {
|
323
|
+
// Don't prevent default - let the overlay system handle closing
|
324
|
+
// But we'll call onEscape to potentially override the default selection clearing
|
325
|
+
onEscape();
|
326
|
+
}
|
327
|
+
},
|
328
|
+
});
|
299
329
|
styles = extractStyles(otherProps, PROP_STYLES, styles);
|
300
330
|
ref = useCombinedRefs(ref);
|
301
|
-
searchInputRef = useCombinedRefs(searchInputRef);
|
302
331
|
listRef = useCombinedRefs(listRef);
|
303
332
|
const { listBoxProps } = useListBox({
|
304
333
|
...props,
|
305
334
|
'aria-label': props['aria-label'] || label?.toString(),
|
306
335
|
isDisabled,
|
307
|
-
shouldUseVirtualFocus:
|
336
|
+
shouldUseVirtualFocus: shouldUseVirtualFocus ?? false,
|
308
337
|
shouldFocusWrap: true,
|
338
|
+
escapeKeyBehavior: onEscape ? 'none' : 'clearSelection',
|
309
339
|
}, listState, listRef);
|
310
340
|
const { isFocused, focusProps } = useFocus({ isDisabled });
|
311
341
|
const isInvalid = validationState === 'invalid';
|
312
|
-
//
|
313
|
-
const
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
342
|
+
// ----- Virtualization logic -----
|
343
|
+
const itemsArray = useMemo(() => [...listState.collection], [listState.collection]);
|
344
|
+
const hasSections = useMemo(() => itemsArray.some((i) => i.type === 'section'), [itemsArray]);
|
345
|
+
const shouldVirtualize = !hasSections;
|
346
|
+
// Use ref to ensure estimateSize always accesses current itemsArray
|
347
|
+
const itemsArrayRef = useRef(itemsArray);
|
348
|
+
itemsArrayRef.current = itemsArray;
|
349
|
+
// Scroll container ref for virtualization
|
350
|
+
const scrollRef = useRef(null);
|
351
|
+
const rowVirtualizer = useVirtualizer({
|
352
|
+
count: shouldVirtualize ? itemsArray.length : 0,
|
353
|
+
getScrollElement: () => scrollRef.current,
|
354
|
+
estimateSize: (index) => {
|
355
|
+
const currentItem = itemsArrayRef.current[index];
|
356
|
+
if (currentItem?.props?.description) {
|
357
|
+
return SIZES.XL + 1;
|
358
|
+
}
|
359
|
+
return size === 'large' ? SIZES.XL + 1 : SIZES.MD + 1;
|
360
|
+
},
|
361
|
+
measureElement: (el) => {
|
362
|
+
return el.offsetHeight + 1;
|
363
|
+
},
|
364
|
+
overscan: 10,
|
365
|
+
});
|
366
|
+
// Trigger remeasurement when items change (for filtering scenarios)
|
367
|
+
useEffect(() => {
|
368
|
+
if (shouldVirtualize) {
|
369
|
+
rowVirtualizer.measure();
|
370
|
+
}
|
371
|
+
}, [shouldVirtualize, itemsArray, rowVirtualizer]);
|
372
|
+
// Keep focused item visible when virtualizing, but only for keyboard navigation
|
373
|
+
useEffect(() => {
|
374
|
+
if (!shouldVirtualize)
|
375
|
+
return;
|
376
|
+
const focusedKey = listState.selectionManager.focusedKey;
|
377
|
+
if (focusedKey != null) {
|
378
|
+
const idx = itemsArrayRef.current.findIndex((it) => it.key === focusedKey);
|
379
|
+
if (idx !== -1) {
|
380
|
+
// Check if the focused item is actually visible in the current viewport
|
381
|
+
// (not just rendered due to overscan)
|
382
|
+
const scrollElement = scrollRef.current;
|
383
|
+
if (scrollElement) {
|
384
|
+
const scrollTop = scrollElement.scrollTop;
|
385
|
+
const viewportHeight = scrollElement.clientHeight;
|
386
|
+
const viewportBottom = scrollTop + viewportHeight;
|
387
|
+
// Find the virtual item for this index
|
388
|
+
const virtualItems = rowVirtualizer.getVirtualItems();
|
389
|
+
const virtualItem = virtualItems.find((item) => item.index === idx);
|
390
|
+
let isAlreadyVisible = false;
|
391
|
+
if (virtualItem) {
|
392
|
+
const itemTop = virtualItem.start;
|
393
|
+
const itemBottom = virtualItem.start + virtualItem.size;
|
394
|
+
// Check if the item is fully visible in the viewport
|
395
|
+
// We should scroll if the item is partially hidden
|
396
|
+
isAlreadyVisible =
|
397
|
+
itemTop >= scrollTop && itemBottom <= viewportBottom;
|
349
398
|
}
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
const direction = isArrowDown ? 'forward' : 'backward';
|
354
|
-
if (currentKey == null) {
|
355
|
-
// No current focus, find first/last selectable item
|
356
|
-
nextKey = findFirstLastSelectableKey(direction);
|
357
|
-
}
|
358
|
-
else {
|
359
|
-
// Find next selectable item from current position
|
360
|
-
const candidateKey = direction === 'forward'
|
361
|
-
? collection.getKeyAfter(currentKey)
|
362
|
-
: collection.getKeyBefore(currentKey);
|
363
|
-
nextKey = findNextSelectableKey(candidateKey, direction);
|
364
|
-
// If no next key found and focus wrapping is enabled, wrap to first/last selectable item
|
365
|
-
if (nextKey == null) {
|
366
|
-
nextKey = findFirstLastSelectableKey(direction);
|
399
|
+
// Only scroll if the item is not already visible AND the focus change was due to keyboard navigation
|
400
|
+
if (!isAlreadyVisible && lastFocusSourceRef.current === 'keyboard') {
|
401
|
+
rowVirtualizer.scrollToIndex(idx, { align: 'auto' });
|
367
402
|
}
|
368
403
|
}
|
369
|
-
if (nextKey != null) {
|
370
|
-
selectionManager.setFocusedKey(nextKey);
|
371
|
-
}
|
372
|
-
}
|
373
|
-
else if (e.key === 'Enter' || (e.key === ' ' && !searchValue.trim())) {
|
374
|
-
const focusedKey = listState.selectionManager.focusedKey;
|
375
|
-
if (focusedKey != null) {
|
376
|
-
e.preventDefault();
|
377
|
-
// Use the SelectionManager's select method which handles all selection logic
|
378
|
-
// including single vs multiple selection modes and modifier keys
|
379
|
-
listState.selectionManager.select(focusedKey, e);
|
380
|
-
}
|
381
404
|
}
|
382
|
-
}
|
383
|
-
});
|
405
|
+
}
|
406
|
+
}, [shouldVirtualize, listState.selectionManager.focusedKey, itemsArray]);
|
407
|
+
// Merge React Aria listbox props with custom keyboard props so both sets of
|
408
|
+
// event handlers (e.g. Arrow navigation *and* our Escape handler) are
|
409
|
+
// preserved.
|
410
|
+
const mergedListBoxProps = mergeProps(listBoxProps, keyboardProps);
|
384
411
|
const mods = useMemo(() => ({
|
385
412
|
invalid: isInvalid,
|
386
413
|
valid: validationState === 'valid',
|
387
414
|
disabled: isDisabled,
|
388
415
|
focused: isFocused,
|
389
|
-
|
390
|
-
|
416
|
+
header: !!header,
|
417
|
+
footer: !!footer,
|
418
|
+
...externalMods,
|
391
419
|
}), [
|
392
420
|
isInvalid,
|
393
421
|
validationState,
|
394
422
|
isDisabled,
|
395
423
|
isFocused,
|
396
|
-
|
397
|
-
|
424
|
+
header,
|
425
|
+
footer,
|
426
|
+
externalMods,
|
398
427
|
]);
|
399
|
-
const
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
setSearchValue(value);
|
404
|
-
}, ...keyboardProps, ...modAttrs(mods) }), _jsx("div", { "data-element": "Prefix", children: _jsx("div", { "data-element": "InputIcon", children: isLoading ? _jsx(LoadingIcon, {}) : _jsx(SearchIcon, {}) }) })] })) : null;
|
405
|
-
const listBoxField = (_jsxs(ListBoxWrapperElement, { ref: ref, qa: qa || 'ListBox', ...modAttrs(mods), styles: styles, ...focusProps, children: [searchInput, _jsx(ListElement, { ...listBoxProps, ref: listRef, styles: listStyles, "aria-disabled": isDisabled || undefined, ...(!isSearchable ? keyboardProps : {}), children: (() => {
|
406
|
-
const renderedItems = [];
|
407
|
-
let isFirstSection = true;
|
408
|
-
for (const item of listState.collection) {
|
409
|
-
if (item.type === 'section') {
|
410
|
-
if (!isFirstSection) {
|
411
|
-
renderedItems.push(_jsx(DividerElement, { role: "separator", "aria-orientation": "horizontal" }, `divider-${String(item.key)}`));
|
412
|
-
}
|
413
|
-
renderedItems.push(_jsx(ListBoxSection, { item: item, state: listState, optionStyles: optionStyles, headingStyles: headingStyles, sectionStyles: sectionStyles, isParentDisabled: isDisabled, validationState: validationState }, item.key));
|
414
|
-
isFirstSection = false;
|
415
|
-
}
|
416
|
-
else {
|
417
|
-
renderedItems.push(_jsx(Option, { item: item, state: listState, styles: optionStyles, isParentDisabled: isDisabled, validationState: validationState }, item.key));
|
428
|
+
const listBoxField = (_jsxs(ListBoxWrapperElement, { ref: ref, qa: qa || 'ListBox', mods: mods, styles: styles, children: [header ? (_jsx(StyledHeader, { styles: headerStyles, "data-size": size, children: header })) : (_jsx("div", { role: "presentation" })), _jsx(ListBoxScrollElement, { ref: scrollRef, mods: mods, ...focusProps, children: _jsx(ListElement, { ...mergedListBoxProps, ref: listRef, styles: listStyles, "aria-disabled": isDisabled || undefined, mods: { sections: hasSections }, style: shouldVirtualize
|
429
|
+
? {
|
430
|
+
position: 'relative',
|
431
|
+
height: `${rowVirtualizer.getTotalSize() + 3}px`,
|
418
432
|
}
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
433
|
+
: undefined, children: shouldVirtualize
|
434
|
+
? rowVirtualizer.getVirtualItems().map((virtualItem) => {
|
435
|
+
const item = itemsArray[virtualItem.index];
|
436
|
+
return (_jsx(Option, { size: size, item: item, state: listState, styles: optionStyles, isParentDisabled: isDisabled, validationState: validationState, focusOnHover: focusOnHover, isCheckable: isCheckable,
|
437
|
+
// We don't need to measure the element here, because the height is already set by the virtualizer
|
438
|
+
// This is a workaround to avoid glitches when selecting/deselecting items
|
439
|
+
virtualRef: rowVirtualizer.measureElement, virtualStyle: {
|
440
|
+
position: 'absolute',
|
441
|
+
top: 0,
|
442
|
+
left: 0,
|
443
|
+
right: 0,
|
444
|
+
transform: `translateY(${virtualItem.start}px)`,
|
445
|
+
}, virtualIndex: virtualItem.index, lastFocusSourceRef: lastFocusSourceRef, onOptionClick: onOptionClick }, virtualItem.key));
|
446
|
+
})
|
447
|
+
: (() => {
|
448
|
+
const renderedItems = [];
|
449
|
+
let isFirstSection = true;
|
450
|
+
for (const item of listState.collection) {
|
451
|
+
if (item.type === 'section') {
|
452
|
+
if (!isFirstSection) {
|
453
|
+
renderedItems.push(_jsx(StyledDivider, { role: "separator", "aria-orientation": "horizontal" }, `divider-${String(item.key)}`));
|
454
|
+
}
|
455
|
+
renderedItems.push(_jsx(ListBoxSection, { item: item, state: listState, optionStyles: optionStyles, headingStyles: headingStyles, sectionStyles: sectionStyles, isParentDisabled: isDisabled, validationState: validationState, focusOnHover: focusOnHover, isCheckable: isCheckable, size: size, lastFocusSourceRef: lastFocusSourceRef, onOptionClick: onOptionClick }, item.key));
|
456
|
+
isFirstSection = false;
|
457
|
+
}
|
458
|
+
else {
|
459
|
+
renderedItems.push(_jsx(Option, { size: size, item: item, state: listState, styles: optionStyles, isParentDisabled: isDisabled, validationState: validationState, focusOnHover: focusOnHover, isCheckable: isCheckable, lastFocusSourceRef: lastFocusSourceRef, onOptionClick: onOptionClick }, item.key));
|
460
|
+
}
|
461
|
+
}
|
462
|
+
return renderedItems;
|
463
|
+
})() }) }), footer ? (_jsx(StyledFooter, { styles: footerStyles, "data-size": size, children: footer })) : (_jsx("div", { role: "presentation" }))] }));
|
428
464
|
return wrapWithField(listBoxField, ref, mergeProps({ ...props, styles: undefined }, {}));
|
429
465
|
});
|
430
|
-
function Option({ item, state, styles, isParentDisabled, validationState }) {
|
431
|
-
const
|
466
|
+
function Option({ size = 'medium', item, state, styles, isParentDisabled, validationState, focusOnHover = false, isCheckable, onOptionClick, virtualStyle, virtualRef, virtualIndex, lastFocusSourceRef, }) {
|
467
|
+
const localRef = useRef(null);
|
468
|
+
// Merge local ref with react-virtual measure ref when provided
|
469
|
+
const combinedRef = useCombinedRefs(localRef, virtualRef);
|
432
470
|
const isDisabled = isParentDisabled || state.disabledKeys.has(item.key);
|
433
471
|
const isSelected = state.selectionManager.isSelected(item.key);
|
434
472
|
const isFocused = state.selectionManager.focusedKey === item.key;
|
473
|
+
const { hoverProps, isHovered } = useHover({ isDisabled });
|
435
474
|
const { optionProps, isPressed } = useOption({
|
436
475
|
key: item.key,
|
437
476
|
isDisabled,
|
438
477
|
isSelected,
|
439
478
|
shouldSelectOnPressUp: true,
|
440
|
-
shouldFocusOnHover:
|
441
|
-
}, state,
|
479
|
+
shouldFocusOnHover: focusOnHover,
|
480
|
+
}, state, combinedRef);
|
442
481
|
const description = item?.props?.description;
|
443
|
-
|
482
|
+
// Custom click handler for the entire option
|
483
|
+
const handleOptionClick = (e) => {
|
484
|
+
// Mark focus changes from mouse clicks
|
485
|
+
if (lastFocusSourceRef) {
|
486
|
+
lastFocusSourceRef.current = 'mouse';
|
487
|
+
}
|
488
|
+
// If there's an onOptionClick callback and this is checkable in multiple mode,
|
489
|
+
// we need to distinguish between checkbox and content clicks
|
490
|
+
if (onOptionClick &&
|
491
|
+
isCheckable &&
|
492
|
+
state.selectionManager.selectionMode === 'multiple') {
|
493
|
+
// Check if the click target is within the checkbox area
|
494
|
+
const clickTarget = e.target;
|
495
|
+
const checkboxElement = localRef.current?.querySelector('[data-element="CheckboxWrapper"]');
|
496
|
+
if (checkboxElement &&
|
497
|
+
(checkboxElement === clickTarget ||
|
498
|
+
checkboxElement.contains(clickTarget))) {
|
499
|
+
// Checkbox area clicked - only toggle, don't call onOptionClick
|
500
|
+
// Let React Aria handle the selection
|
501
|
+
optionProps.onClick?.(e);
|
502
|
+
// Set focus to the clicked item
|
503
|
+
state.selectionManager.setFocusedKey(item.key);
|
504
|
+
}
|
505
|
+
else {
|
506
|
+
// Content area clicked - toggle and trigger callback
|
507
|
+
// Let React Aria handle the selection first
|
508
|
+
optionProps.onClick?.(e);
|
509
|
+
// Set focus to the clicked item
|
510
|
+
state.selectionManager.setFocusedKey(item.key);
|
511
|
+
// Then call the callback (which will close the popover in FilterPicker)
|
512
|
+
if (onOptionClick) {
|
513
|
+
onOptionClick(item.key);
|
514
|
+
}
|
515
|
+
}
|
516
|
+
}
|
517
|
+
else {
|
518
|
+
// Normal behavior - let React Aria handle it
|
519
|
+
optionProps.onClick?.(e);
|
520
|
+
// Set focus to the clicked item
|
521
|
+
state.selectionManager.setFocusedKey(item.key);
|
522
|
+
// Call onOptionClick if provided
|
523
|
+
if (onOptionClick) {
|
524
|
+
onOptionClick(item.key);
|
525
|
+
}
|
526
|
+
}
|
527
|
+
};
|
528
|
+
return (_jsxs(OptionElement, { id: `ListBoxItem-${String(item.key)}`, ...mergeProps(optionProps, hoverProps), ref: combinedRef, style: virtualStyle, "data-size": size, "data-index": virtualIndex, mods: {
|
444
529
|
selected: isSelected,
|
445
530
|
focused: isFocused,
|
446
531
|
disabled: isDisabled,
|
447
532
|
pressed: isPressed,
|
448
533
|
valid: isSelected && validationState === 'valid',
|
449
534
|
invalid: isSelected && validationState === 'invalid',
|
450
|
-
|
535
|
+
checkable: isCheckable,
|
536
|
+
hovered: isHovered, // We'll treat focus as hover for the checkbox visibility
|
537
|
+
}, styles: styles, onClick: handleOptionClick, children: [isCheckable && state.selectionManager.selectionMode === 'multiple' && (_jsx("div", { "data-element": "CheckboxWrapper", children: _jsx("div", { "data-element": "Checkbox", children: _jsx(CheckIcon, { size: 12, stroke: 3 }) }) })), _jsxs("div", { "data-element": "Content", children: [_jsx("div", { "data-element": "Label", children: item.rendered }), description ? (_jsx("div", { "data-element": "Description", children: description })) : null] })] }));
|
451
538
|
}
|
452
539
|
function ListBoxSection(props) {
|
453
|
-
const { item, state, optionStyles, headingStyles, sectionStyles, isParentDisabled, validationState, } = props;
|
540
|
+
const { item, state, optionStyles, headingStyles, sectionStyles, isParentDisabled, validationState, focusOnHover, isCheckable, onOptionClick, lastFocusSourceRef, } = props;
|
454
541
|
const heading = item.rendered;
|
455
542
|
const { itemProps, headingProps, groupProps } = useListBoxSection({
|
456
543
|
heading,
|
457
544
|
'aria-label': item['aria-label'],
|
458
545
|
});
|
459
|
-
return (_jsxs(SectionWrapperElement, { ...itemProps, styles: sectionStyles, children: [heading && (_jsx(
|
546
|
+
return (_jsxs(SectionWrapperElement, { ...itemProps, styles: sectionStyles, children: [heading && (_jsx(StyledSectionHeading, { ...headingProps, styles: headingStyles, children: heading })), _jsx(SectionListElement, { ...groupProps, children: [...item.childNodes]
|
460
547
|
.filter((node) => state.collection.getItem(node.key))
|
461
|
-
.map((node) => (_jsx(Option, { item: node, state: state, styles: optionStyles, isParentDisabled: isParentDisabled, validationState: validationState }, node.key))) })] }));
|
548
|
+
.map((node) => (_jsx(Option, { size: props.size, item: node, state: state, styles: optionStyles, isParentDisabled: isParentDisabled, validationState: validationState, focusOnHover: focusOnHover, isCheckable: isCheckable, lastFocusSourceRef: lastFocusSourceRef, onOptionClick: onOptionClick }, node.key))) })] }));
|
462
549
|
}
|
463
550
|
const ListBoxSectionComponent = Object.assign(BaseSection, {
|
464
551
|
displayName: 'Section',
|