@cube-dev/ui-kit 0.102.0 → 0.104.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 +24 -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/CollectionItem.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 +16 -2
- 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 +1 -1
- package/es/components/actions/CommandMenu/index.js +1 -1
- package/es/components/actions/CommandMenu/styled.js +1 -1
- package/es/components/actions/ItemAction/ItemAction.js +20 -3
- package/es/components/actions/ItemAction/index.js +1 -1
- package/es/components/actions/ItemActionContext.js +1 -1
- package/es/components/actions/ItemButton/ItemButton.js +1 -1
- package/es/components/actions/ItemButton/index.js +1 -1
- package/es/components/actions/Link/Link.js +1 -1
- package/es/components/actions/Menu/Menu.js +1 -1
- package/es/components/actions/Menu/MenuItem.js +1 -1
- package/es/components/actions/Menu/MenuSection.js +1 -1
- package/es/components/actions/Menu/MenuTrigger.js +1 -1
- package/es/components/actions/Menu/SubMenuTrigger.js +1 -1
- package/es/components/actions/Menu/SubmenuTriggerContext.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 +1 -1
- 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/Disclosure/Disclosure.js +1 -1
- package/es/components/content/Disclosure/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/Item/Item.js +30 -9
- package/es/components/content/Item/index.js +1 -1
- package/es/components/content/ItemBadge/ItemBadge.js +1 -1
- package/es/components/content/ItemBadge/index.js +1 -1
- package/es/components/content/Layout/GridLayout.js +1 -1
- package/es/components/content/Layout/Layout.js +1 -1
- package/es/components/content/Layout/LayoutBlock.js +1 -1
- package/es/components/content/Layout/LayoutCenter.js +1 -1
- package/es/components/content/Layout/LayoutContainer.js +1 -1
- package/es/components/content/Layout/LayoutContent.js +1 -1
- package/es/components/content/Layout/LayoutContext.js +1 -1
- package/es/components/content/Layout/LayoutFlex.js +1 -1
- package/es/components/content/Layout/LayoutFooter.js +1 -1
- package/es/components/content/Layout/LayoutGrid.js +1 -1
- package/es/components/content/Layout/LayoutHeader.js +1 -1
- package/es/components/content/Layout/LayoutPane.js +1 -1
- package/es/components/content/Layout/LayoutPanel.js +1 -1
- package/es/components/content/Layout/LayoutPanelHeader.js +1 -1
- package/es/components/content/Layout/LayoutToolbar.js +1 -1
- package/es/components/content/Layout/hooks/useTinyScrollbar.js +1 -1
- package/es/components/content/Layout/index.js +1 -1
- package/es/components/content/Layout/utils.js +1 -1
- package/es/components/content/List/SectionHeading.js +1 -1
- package/es/components/content/List/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/TextItem/TextItem.js +1 -1
- package/es/components/content/TextItem/index.js +1 -1
- package/es/components/content/Title.js +1 -1
- package/es/components/content/highlightText.js +1 -1
- package/es/components/content/use-auto-tooltip.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 +1 -1
- package/es/components/fields/FilterListBox/index.js +1 -1
- package/es/components/fields/FilterPicker/FilterPicker.js +3 -3
- package/es/components/fields/FilterPicker/index.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/Picker/Picker.js +3 -3
- package/es/components/fields/Picker/index.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 +1 -1
- 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/helpers/DisplayTransition/DisplayTransition.js +1 -1
- package/es/components/helpers/DisplayTransition/index.js +1 -1
- package/es/components/helpers/IconSwitch/IconSwitch.js +1 -1
- package/es/components/helpers/index.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/Tabs/DraggableTabList.js +101 -0
- package/es/components/navigation/Tabs/EditableTitle.js +116 -0
- package/es/components/navigation/Tabs/TabButton.js +320 -0
- package/es/components/navigation/Tabs/TabDropIndicator.js +34 -0
- package/es/components/navigation/Tabs/TabPanel.js +128 -0
- package/es/components/navigation/Tabs/TabPicker.js +46 -0
- package/es/components/navigation/Tabs/Tabs.js +212 -707
- package/es/components/navigation/Tabs/TabsAction.js +70 -0
- package/es/components/navigation/Tabs/TabsContext.js +36 -0
- package/es/components/navigation/Tabs/index.js +2 -2
- package/es/components/navigation/Tabs/styled.js +354 -0
- package/es/components/navigation/Tabs/types.js +17 -0
- package/es/components/navigation/Tabs/use-tab-editing.js +61 -0
- package/es/components/navigation/Tabs/use-tab-indicator.js +77 -0
- package/es/components/navigation/index.js +1 -1
- package/es/components/organisms/FileTabs/FileTabs.js +1 -1
- package/es/components/organisms/StatsCard/StatsCard.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/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/NotificationsDialogContext.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/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/item-themes.js +249 -5
- 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/ChartHeatmapIcon.js +1 -1
- package/es/icons/ChartKPIIcon.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/ColumnTotalIcon.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/CubePauseIcon.js +1 -1
- package/es/icons/CubePlayIcon.js +1 -1
- package/es/icons/CurrencyDollarIcon.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/DecimalDecreaseIcon.js +1 -1
- package/es/icons/DecimalIncreaseIcon.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/HierarchyOpenIcon.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/Number123Icon.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/PercentageIcon.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/ProgressBarIcon.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/RowTotalsIcon.js +1 -1
- package/es/icons/SchemeIcon.js +1 -1
- package/es/icons/SearchIcon.js +1 -1
- package/es/icons/SemanticQueryIcon.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/SubtotalsIcon.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/TrashIcon.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/index.js +1 -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/providers/navigation.types.js +1 -1
- package/es/providers/navigationAdapter.default.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/SimpleLayout.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/stories/playground/PlaygroundEditor.js +1 -1
- package/es/stories/playground/PlaygroundLayout.js +1 -1
- package/es/stories/playground/PlaygroundOutput.js +1 -1
- package/es/stories/playground/PlaygroundPreview.js +1 -1
- package/es/stories/playground/components/Button.js +1 -1
- package/es/stories/playground/components/Card.js +1 -1
- package/es/stories/playground/components/ScrollProgress.js +1 -1
- package/es/stories/playground/examples.js +1 -1
- package/es/tasty/chunks/cacheKey.js +1 -1
- package/es/tasty/chunks/definitions.js +1 -1
- package/es/tasty/chunks/index.js +1 -1
- package/es/tasty/chunks/renderChunk.js +1 -1
- package/es/tasty/config.js +1 -1
- package/es/tasty/debug.js +1 -1
- package/es/tasty/hooks/index.js +1 -1
- package/es/tasty/hooks/useGlobalStyles.js +1 -1
- package/es/tasty/hooks/useKeyframes.js +1 -1
- package/es/tasty/hooks/useProperty.js +1 -1
- package/es/tasty/hooks/useRawCSS.js +1 -1
- package/es/tasty/hooks/useStyles.js +1 -1
- package/es/tasty/index.js +1 -1
- package/es/tasty/injector/index.js +1 -1
- package/es/tasty/injector/injector.js +1 -1
- package/es/tasty/injector/sheet-manager.js +1 -1
- package/es/tasty/injector/types.js +1 -1
- package/es/tasty/keyframes/index.js +1 -1
- package/es/tasty/parser/classify.js +1 -1
- package/es/tasty/parser/const.js +1 -1
- package/es/tasty/parser/lru.js +1 -1
- package/es/tasty/parser/parser.js +1 -1
- package/es/tasty/parser/tokenizer.js +1 -1
- package/es/tasty/parser/types.js +1 -1
- package/es/tasty/pipeline/conditions.js +1 -1
- package/es/tasty/pipeline/exclusive.js +1 -1
- package/es/tasty/pipeline/index.js +1 -1
- package/es/tasty/pipeline/materialize.js +1 -1
- package/es/tasty/pipeline/parseStateKey.js +1 -1
- package/es/tasty/pipeline/simplify.js +1 -1
- package/es/tasty/plugins/index.js +1 -1
- package/es/tasty/plugins/okhsl-plugin.js +1 -1
- package/es/tasty/plugins/types.js +1 -1
- package/es/tasty/properties/index.js +1 -1
- package/es/tasty/states/index.js +1 -1
- package/es/tasty/static/index.js +1 -1
- package/es/tasty/static/tastyStatic.js +1 -1
- package/es/tasty/static/types.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/gap.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 +6 -5
- package/es/tasty/styles/justify.js +1 -1
- package/es/tasty/styles/list.js +1 -1
- package/es/tasty/styles/margin.js +6 -5
- package/es/tasty/styles/outline.js +1 -1
- package/es/tasty/styles/padding.js +6 -5
- 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/filter-base-props.js +1 -1
- package/es/tasty/utils/get-display-name.js +1 -1
- package/es/tasty/utils/hsl-to-rgb.js +1 -1
- package/es/tasty/utils/is-dev-env.js +1 -1
- package/es/tasty/utils/merge-styles.js +1 -1
- package/es/tasty/utils/mod-attrs.js +1 -1
- package/es/tasty/utils/okhsl-to-rgb.js +1 -1
- package/es/tasty/utils/process-tokens.js +1 -1
- package/es/tasty/utils/rgb-to-okhsl.js +1 -1
- package/es/tasty/utils/string.js +1 -1
- package/es/tasty/utils/styles.js +1 -1
- package/es/tasty/utils/typography.js +1 -1
- package/es/tasty/utils/warnings.js +1 -1
- package/es/tasty/zero/babel.js +1 -1
- package/es/tasty/zero/css-writer.js +1 -1
- package/es/tasty/zero/extractor.js +1 -1
- package/es/tasty/zero/index.js +1 -1
- package/es/tasty/zero/next.js +1 -1
- package/es/tokens/base.js +1 -1
- package/es/tokens/colors.js +11 -1
- package/es/tokens/index.js +1 -1
- package/es/tokens/layout.js +1 -1
- package/es/tokens/shadows.js +1 -1
- package/es/tokens/sizes.js +1 -1
- package/es/tokens/spacing.js +1 -1
- package/es/tokens/typography.js +1 -1
- package/es/utils/ResizeSensor.js +1 -1
- package/es/utils/index.js +1 -1
- package/es/utils/modules.js +1 -1
- package/es/utils/promise.js +1 -1
- package/es/utils/raf.js +1 -1
- package/es/utils/random.js +1 -1
- package/es/utils/range.js +1 -1
- package/es/utils/react/RenderCache.js +1 -1
- package/es/utils/react/Slots.js +1 -1
- package/es/utils/react/chain.js +1 -1
- package/es/utils/react/forwardRefWithGenerics.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/resolveIcon.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 +1 -1
- 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/useLocalStorage.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/tree.js +1 -1
- package/es/utils/warnings.js +1 -1
- package/es/version.js +2 -2
- package/package.json +2 -2
- package/types/components/actions/Button/Button.d.ts +1 -1
- package/types/components/actions/ItemAction/ItemAction.d.ts +2 -2
- package/types/components/navigation/Tabs/DraggableTabList.d.ts +23 -0
- package/types/components/navigation/Tabs/EditableTitle.d.ts +24 -0
- package/types/components/navigation/Tabs/TabButton.d.ts +22 -0
- package/types/components/navigation/Tabs/TabDropIndicator.d.ts +17 -0
- package/types/components/navigation/Tabs/TabPanel.d.ts +49 -0
- package/types/components/navigation/Tabs/TabPicker.d.ts +23 -0
- package/types/components/navigation/Tabs/Tabs.d.ts +6 -189
- package/types/components/navigation/Tabs/TabsAction.d.ts +38 -0
- package/types/components/navigation/Tabs/TabsContext.d.ts +57 -0
- package/types/components/navigation/Tabs/index.d.ts +3 -2
- package/types/components/navigation/Tabs/styled.d.ts +5927 -0
- package/types/components/navigation/Tabs/types.d.ts +261 -0
- package/types/components/navigation/Tabs/use-tab-editing.d.ts +30 -0
- package/types/components/navigation/Tabs/use-tab-indicator.d.ts +20 -0
- package/types/data/item-themes.d.ts +15 -1
- package/types/tokens/colors.d.ts +2 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license MIT
|
|
3
|
+
* author: Cube Dev Team
|
|
4
|
+
* @cube-dev/ui-kit v0.104.0
|
|
5
|
+
* Released under the MIT license.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
9
|
+
import { Children, cloneElement, isValidElement, useEffect, useLayoutEffect, useMemo, useRef, useState, } from 'react';
|
|
10
|
+
import { useDraggableItem, useFocus, useFocusVisible, useHover, useTab, } from 'react-aria';
|
|
11
|
+
import { useEvent } from '../../../_internal/hooks/index.js';
|
|
12
|
+
import { CloseIcon, MoreIcon } from '../../../icons/index.js';
|
|
13
|
+
import { mergeProps } from '../../../utils/react/index.js';
|
|
14
|
+
import { ItemAction } from '../../actions/ItemAction/index.js';
|
|
15
|
+
import { ItemActionProvider } from '../../actions/ItemActionContext.js';
|
|
16
|
+
import { Menu, MenuTrigger } from '../../actions/Menu/index.js';
|
|
17
|
+
import { useContextMenu } from '../../actions/use-context-menu.js';
|
|
18
|
+
import { EditableTitle } from './EditableTitle.js';
|
|
19
|
+
import { TabContainer, TabElement } from './styled.js';
|
|
20
|
+
import { TabDropIndicator } from './TabDropIndicator.js';
|
|
21
|
+
import { useTabsContext } from './TabsContext.js';
|
|
22
|
+
import { RADIO_SIZE_MAP } from './types.js';
|
|
23
|
+
// =============================================================================
|
|
24
|
+
// Event handlers for actions to prevent event propagation to tab button
|
|
25
|
+
// =============================================================================
|
|
26
|
+
const ACTIONS_EVENT_HANDLERS = {
|
|
27
|
+
onClick: (e) => e.stopPropagation(),
|
|
28
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
29
|
+
onPointerUp: (e) => e.stopPropagation(),
|
|
30
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
31
|
+
onMouseUp: (e) => e.stopPropagation(),
|
|
32
|
+
onKeyDown: (e) => {
|
|
33
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
34
|
+
e.stopPropagation();
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Extracts the raw key from a React element, stripping the ".$" prefix
|
|
40
|
+
* that React adds via Children.map/toArray.
|
|
41
|
+
*/
|
|
42
|
+
function getRawKey(element) {
|
|
43
|
+
if (element.key == null)
|
|
44
|
+
return null;
|
|
45
|
+
const keyStr = String(element.key);
|
|
46
|
+
return keyStr.startsWith('.$') ? keyStr.slice(2) : keyStr;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Process menu items for predefined action keys (rename, delete).
|
|
50
|
+
* Auto-adds labels and disables items when requirements aren't met.
|
|
51
|
+
*/
|
|
52
|
+
function processMenuItems(children, effectiveIsEditable, isDeletable) {
|
|
53
|
+
return Children.toArray(children).map((child) => {
|
|
54
|
+
if (!isValidElement(child))
|
|
55
|
+
return child;
|
|
56
|
+
const childKey = getRawKey(child);
|
|
57
|
+
const childProps = child.props;
|
|
58
|
+
// Handle predefined action keys
|
|
59
|
+
if (childKey === 'rename') {
|
|
60
|
+
return cloneElement(child, {
|
|
61
|
+
children: childProps.children ?? 'Rename',
|
|
62
|
+
isDisabled: childProps.isDisabled ?? !effectiveIsEditable,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (childKey === 'delete') {
|
|
66
|
+
return cloneElement(child, {
|
|
67
|
+
children: childProps.children ?? 'Delete',
|
|
68
|
+
theme: childProps.theme ?? 'danger',
|
|
69
|
+
isDisabled: childProps.isDisabled ?? !isDeletable,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
// Recursively process Menu.Section children
|
|
73
|
+
if (childProps.children && typeof childProps.children !== 'string') {
|
|
74
|
+
return cloneElement(child, {
|
|
75
|
+
children: processMenuItems(childProps.children, effectiveIsEditable, isDeletable),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return child;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Check if menu children is empty (null, undefined, or empty fragment)
|
|
83
|
+
*/
|
|
84
|
+
function isMenuEmpty(menu) {
|
|
85
|
+
if (menu === null || menu === undefined)
|
|
86
|
+
return true;
|
|
87
|
+
const children = Children.toArray(menu);
|
|
88
|
+
return children.length === 0;
|
|
89
|
+
}
|
|
90
|
+
// =============================================================================
|
|
91
|
+
// TabButton Component
|
|
92
|
+
// =============================================================================
|
|
93
|
+
/**
|
|
94
|
+
* Individual tab button component.
|
|
95
|
+
*
|
|
96
|
+
* Uses TabsContext to access shared props, dramatically reducing prop drilling.
|
|
97
|
+
* Handles:
|
|
98
|
+
* - Tab selection and keyboard navigation
|
|
99
|
+
* - Inline title editing
|
|
100
|
+
* - Menu and context menu
|
|
101
|
+
* - Drag-and-drop reordering
|
|
102
|
+
* - Focus and hover states
|
|
103
|
+
*/
|
|
104
|
+
export function TabButton({ item, tabData, isLastTab }) {
|
|
105
|
+
// Get shared context
|
|
106
|
+
const { state, type, size, showActionsOnHover: parentShowActionsOnHover, isEditable: parentIsEditable, menu: parentMenu, menuTriggerProps: parentMenuTriggerProps, menuProps: parentMenuProps, contextMenu: parentContextMenu, onAction: parentOnAction, onDelete, dragState, dropState, editingKey, editValue, setEditValue, startEditing, submitEditing, cancelEditing, } = useTabsContext();
|
|
107
|
+
const ref = useRef(null);
|
|
108
|
+
const containerRef = useRef(null);
|
|
109
|
+
const actionsRef = useRef(null);
|
|
110
|
+
const { tabProps } = useTab({ key: item.key }, state, ref);
|
|
111
|
+
// Measure actions width for proper space allocation in Item
|
|
112
|
+
const [actionsWidth, setActionsWidth] = useState(0);
|
|
113
|
+
// Drag-and-drop support - only enable when both states are provided
|
|
114
|
+
const isDraggable = !!dragState && !!dropState;
|
|
115
|
+
// useDraggableItem must be called unconditionally (Rules of Hooks)
|
|
116
|
+
// When dragState is undefined, we pass a minimal mock state to satisfy the hook
|
|
117
|
+
const mockDragState = useMemo(() => ({
|
|
118
|
+
collection: state.collection,
|
|
119
|
+
selectionManager: state.selectionManager,
|
|
120
|
+
isDragging: () => false,
|
|
121
|
+
getKeysForDrag: () => new Set(),
|
|
122
|
+
isDisabled: false,
|
|
123
|
+
startDrag: () => { },
|
|
124
|
+
endDrag: () => { },
|
|
125
|
+
}), [state.collection, state.selectionManager]);
|
|
126
|
+
const dragResult = useDraggableItem({ key: item.key }, dragState ?? mockDragState);
|
|
127
|
+
const effectiveDragProps = isDraggable ? dragResult.dragProps : {};
|
|
128
|
+
const isDragging = isDraggable && dragResult.isDragging;
|
|
129
|
+
// Controlled state for menu trigger (enables keyboard opening with Shift+F10)
|
|
130
|
+
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
|
131
|
+
// Hover, focus, and focus-visible state handling
|
|
132
|
+
const { hoverProps, isHovered } = useHover({});
|
|
133
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
134
|
+
const { focusProps } = useFocus({ onFocusChange: setIsFocused });
|
|
135
|
+
const { isFocusVisible } = useFocusVisible();
|
|
136
|
+
// Suppress focus-visible when restoring focus after editing
|
|
137
|
+
const [suppressFocusVisible, setSuppressFocusVisible] = useState(false);
|
|
138
|
+
const effectiveFocusVisible = isFocusVisible && !suppressFocusVisible;
|
|
139
|
+
const isActive = state.selectedKey === item.key;
|
|
140
|
+
const isDisabled = state.disabledKeys.has(item.key);
|
|
141
|
+
const isDeletable = !!onDelete;
|
|
142
|
+
const isEditing = editingKey === item.key;
|
|
143
|
+
// Compute effective values - Tab-level overrides Tabs-level
|
|
144
|
+
const effectiveIsEditable = tabData.isEditable ?? parentIsEditable ?? false;
|
|
145
|
+
const effectiveMenu = tabData.menu === null ? null : tabData.menu ?? parentMenu;
|
|
146
|
+
const effectiveMenuTriggerProps = {
|
|
147
|
+
...parentMenuTriggerProps,
|
|
148
|
+
...tabData.menuTriggerProps,
|
|
149
|
+
};
|
|
150
|
+
const effectiveMenuProps = {
|
|
151
|
+
...parentMenuProps,
|
|
152
|
+
...tabData.menuProps,
|
|
153
|
+
};
|
|
154
|
+
const effectiveContextMenu = tabData.contextMenu ?? parentContextMenu ?? false;
|
|
155
|
+
const effectiveType = tabData.type ?? type ?? 'default';
|
|
156
|
+
// Delete button shown only if onDelete is set AND no menu
|
|
157
|
+
const showDeleteButton = isDeletable && isMenuEmpty(effectiveMenu);
|
|
158
|
+
// Process menu items for auto-labels and disabled states
|
|
159
|
+
const processedMenu = effectiveMenu && !isMenuEmpty(effectiveMenu)
|
|
160
|
+
? processMenuItems(effectiveMenu, effectiveIsEditable, isDeletable)
|
|
161
|
+
: null;
|
|
162
|
+
const handleDelete = useEvent(() => {
|
|
163
|
+
onDelete?.(item.key);
|
|
164
|
+
});
|
|
165
|
+
const handleStartEditing = useEvent(() => {
|
|
166
|
+
if (!effectiveIsEditable || isDisabled)
|
|
167
|
+
return;
|
|
168
|
+
const titleText = typeof tabData.title === 'string' ? tabData.title : String(item.key);
|
|
169
|
+
startEditing(item.key, titleText);
|
|
170
|
+
});
|
|
171
|
+
const handleSubmitEditing = useEvent(() => {
|
|
172
|
+
submitEditing(item.key, editValue, tabData.onTitleChange);
|
|
173
|
+
// Suppress focus-visible and restore focus to the tab button after editing
|
|
174
|
+
setSuppressFocusVisible(true);
|
|
175
|
+
requestAnimationFrame(() => {
|
|
176
|
+
ref.current?.focus();
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
const handleCancelEditing = useEvent(() => {
|
|
180
|
+
cancelEditing();
|
|
181
|
+
// Suppress focus-visible and restore focus to the tab button after editing
|
|
182
|
+
setSuppressFocusVisible(true);
|
|
183
|
+
requestAnimationFrame(() => {
|
|
184
|
+
ref.current?.focus();
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
const handleEditValueChange = useEvent((value) => {
|
|
188
|
+
setEditValue(value);
|
|
189
|
+
});
|
|
190
|
+
// Handle menu actions - predefined actions first, then callbacks
|
|
191
|
+
const handleMenuAction = useEvent((action) => {
|
|
192
|
+
// Strip the ".$" prefix that React adds via Children.toArray/map
|
|
193
|
+
const actionStr = String(action);
|
|
194
|
+
const normalizedAction = actionStr.startsWith('.$')
|
|
195
|
+
? actionStr.slice(2)
|
|
196
|
+
: actionStr;
|
|
197
|
+
// Handle predefined actions first (only if requirements are met)
|
|
198
|
+
if (normalizedAction === 'rename' && effectiveIsEditable) {
|
|
199
|
+
handleStartEditing();
|
|
200
|
+
}
|
|
201
|
+
if (normalizedAction === 'delete' && isDeletable) {
|
|
202
|
+
onDelete?.(item.key);
|
|
203
|
+
}
|
|
204
|
+
// Call Tab-level onAction first (with normalized action)
|
|
205
|
+
tabData.onAction?.(normalizedAction);
|
|
206
|
+
// Then call Tabs-level onAction with tab key (with normalized action)
|
|
207
|
+
parentOnAction?.(normalizedAction, item.key);
|
|
208
|
+
});
|
|
209
|
+
// Keyboard handler for accessibility shortcuts (WAI-ARIA Tabs Pattern)
|
|
210
|
+
const handleKeyDown = useEvent((e) => {
|
|
211
|
+
// Reset focus-visible suppression on any keyboard interaction
|
|
212
|
+
if (suppressFocusVisible) {
|
|
213
|
+
setSuppressFocusVisible(false);
|
|
214
|
+
}
|
|
215
|
+
// F2 to start editing (standard rename shortcut)
|
|
216
|
+
if (e.key === 'F2' && effectiveIsEditable && !isDisabled) {
|
|
217
|
+
e.preventDefault();
|
|
218
|
+
e.stopPropagation();
|
|
219
|
+
handleStartEditing();
|
|
220
|
+
}
|
|
221
|
+
// Shift+F10 opens the menu (standard context menu shortcut)
|
|
222
|
+
if (e.key === 'F10' && e.shiftKey && processedMenu) {
|
|
223
|
+
e.preventDefault();
|
|
224
|
+
e.stopPropagation();
|
|
225
|
+
setIsMenuOpen(true);
|
|
226
|
+
}
|
|
227
|
+
// Delete key for direct tab deletion (ARIA Tabs pattern optional feature)
|
|
228
|
+
// Skip when editing to allow normal text editing operations
|
|
229
|
+
if ((e.key === 'Delete' || e.key === 'Backspace') &&
|
|
230
|
+
isDeletable &&
|
|
231
|
+
!isEditing) {
|
|
232
|
+
e.preventDefault();
|
|
233
|
+
onDelete?.(item.key);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
const mods = useMemo(() => ({
|
|
237
|
+
type: effectiveType,
|
|
238
|
+
active: isActive,
|
|
239
|
+
deletable: isDeletable,
|
|
240
|
+
disabled: isDisabled,
|
|
241
|
+
editing: isEditing,
|
|
242
|
+
hovered: isHovered,
|
|
243
|
+
focused: isFocused,
|
|
244
|
+
'focus-visible': effectiveFocusVisible,
|
|
245
|
+
draggable: isDraggable,
|
|
246
|
+
dragging: isDragging,
|
|
247
|
+
}), [
|
|
248
|
+
effectiveType,
|
|
249
|
+
isActive,
|
|
250
|
+
isDeletable,
|
|
251
|
+
isDisabled,
|
|
252
|
+
isEditing,
|
|
253
|
+
isHovered,
|
|
254
|
+
isFocused,
|
|
255
|
+
effectiveFocusVisible,
|
|
256
|
+
isDraggable,
|
|
257
|
+
isDragging,
|
|
258
|
+
]);
|
|
259
|
+
// Scroll active tab into view
|
|
260
|
+
useEffect(() => {
|
|
261
|
+
if (ref.current && isActive) {
|
|
262
|
+
ref.current.scrollIntoView?.({ block: 'nearest', inline: 'nearest' });
|
|
263
|
+
}
|
|
264
|
+
}, [isActive]);
|
|
265
|
+
// Build menu element
|
|
266
|
+
const menuElement = processedMenu ? (_jsx(Menu, { ...effectiveMenuProps, onAction: handleMenuAction, children: processedMenu })) : null;
|
|
267
|
+
// Use the useContextMenu hook for context menu handling
|
|
268
|
+
const contextMenu = useContextMenu(Menu, { placement: 'bottom start' }, {
|
|
269
|
+
...effectiveMenuProps,
|
|
270
|
+
onAction: handleMenuAction,
|
|
271
|
+
children: processedMenu,
|
|
272
|
+
});
|
|
273
|
+
// Build menu trigger action with controlled state for keyboard accessibility
|
|
274
|
+
const menuAction = menuElement ? (_jsxs(MenuTrigger, { isOpen: isMenuOpen, onOpenChange: setIsMenuOpen, children: [_jsx(ItemAction, { tabIndex: -1, icon: _jsx(MoreIcon, {}), ...effectiveMenuTriggerProps }), menuElement] })) : null;
|
|
275
|
+
// Build delete button (only shown when no menu)
|
|
276
|
+
const deleteAction = showDeleteButton ? (_jsx(ItemAction, { tabIndex: -1, icon: _jsx(CloseIcon, {}), tooltip: "Delete tab", onPress: handleDelete })) : null;
|
|
277
|
+
// Order: custom actions → menu trigger → delete button
|
|
278
|
+
const actions = tabData.actions || menuAction || deleteAction ? (_jsxs(_Fragment, { children: [tabData.actions, menuAction, deleteAction] })) : undefined;
|
|
279
|
+
// Measure actions width to pass to Item for proper space allocation
|
|
280
|
+
useLayoutEffect(() => {
|
|
281
|
+
if (actions && actionsRef.current) {
|
|
282
|
+
const width = Math.round(actionsRef.current.offsetWidth);
|
|
283
|
+
if (width !== actionsWidth) {
|
|
284
|
+
setActionsWidth(width);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}, [actions, actionsWidth]);
|
|
288
|
+
// Determine effective size
|
|
289
|
+
const effectiveSize = tabData.size ?? size ?? 'medium';
|
|
290
|
+
const itemSize = effectiveType === 'radio'
|
|
291
|
+
? RADIO_SIZE_MAP[effectiveSize === 'large' ? 'large' : 'medium']
|
|
292
|
+
: effectiveSize;
|
|
293
|
+
// Determine Item type prop
|
|
294
|
+
const itemType = effectiveType === 'default' ? (isActive ? 'clear' : 'neutral') : 'neutral';
|
|
295
|
+
// Determine shape - file type uses sharp edges
|
|
296
|
+
const isFileType = effectiveType === 'file';
|
|
297
|
+
const itemShape = isFileType ? 'sharp' : undefined;
|
|
298
|
+
// Determine showActionsOnHover - tab-level overrides parent-level
|
|
299
|
+
const effectiveShowActionsOnHover = tabData.showActionsOnHover ?? parentShowActionsOnHover;
|
|
300
|
+
// Render title with editing support if editable
|
|
301
|
+
const titleContent = effectiveIsEditable ? (_jsx(EditableTitle, { title: tabData.title, isEditing: isEditing, editValue: isEditing ? editValue : '', onEditValueChange: handleEditValueChange, onStartEditing: handleStartEditing, onSubmit: handleSubmitEditing, onCancel: handleCancelEditing })) : (tabData.title);
|
|
302
|
+
// Extract tab-specific props and pass through the rest (style props) to the Item
|
|
303
|
+
const { title: _title, content: _content, key: _key, isDisabled: _isDisabled, prerender: _prerender, keepMounted: _keepMounted, size: _size, type: _type, actions: _actions, showActionsOnHover: _showActionsOnHover, isEditable: _isEditable, onTitleChange: _onTitleChange, menu: _menu, menuTriggerProps: _menuTriggerProps, menuProps: _menuProps, contextMenu: _contextMenu, onAction: _onAction, qa, qaVal, styles, ...itemStyleProps } = tabData;
|
|
304
|
+
// Use the hook's targetRef when context menu is enabled
|
|
305
|
+
const effectiveContainerRef = effectiveContextMenu && processedMenu
|
|
306
|
+
? contextMenu.targetRef
|
|
307
|
+
: containerRef;
|
|
308
|
+
// ARIA: indicate popup menu presence
|
|
309
|
+
const ariaProps = processedMenu ? { 'aria-haspopup': 'menu' } : {};
|
|
310
|
+
// Mods for TabContainer
|
|
311
|
+
const containerMods = {
|
|
312
|
+
...mods,
|
|
313
|
+
'show-actions-on-hover': effectiveShowActionsOnHover,
|
|
314
|
+
};
|
|
315
|
+
return (_jsxs(TabContainer, { ref: effectiveContainerRef, "data-size": itemSize, mods: containerMods, tokens: { '$actions-width': `${actionsWidth}px` }, ...effectiveDragProps, children: [isDraggable && dropState && (_jsx(TabDropIndicator, { target: { type: 'item', key: item.key, dropPosition: 'before' }, dropState: dropState, position: "before" })), _jsx(TabElement, { preserveActionsSpace: true, showActionsOnHover: effectiveShowActionsOnHover, as: "button", ...mergeProps(tabProps, hoverProps, focusProps, {
|
|
316
|
+
onKeyDown: handleKeyDown,
|
|
317
|
+
}), ...ariaProps, ...itemStyleProps, ref: ref, qa: qa ?? `Tab-${String(item.key)}`, qaVal: qaVal, styles: styles, mods: mods, isSelected: isActive, isDisabled: isDisabled, size: itemSize, type: itemType, shape: itemShape, actions: actions ? true : undefined, children: titleContent }), actions && (_jsx("div", { ref: actionsRef, "data-element": "Actions", ...ACTIONS_EVENT_HANDLERS, children: _jsx(ItemActionProvider, { type: itemType, theme: "default", isDisabled: isDisabled, children: actions }) })), effectiveContextMenu && processedMenu && contextMenu.rendered, isDraggable && dropState && isLastTab && (_jsx(TabDropIndicator, { target: { type: 'item', key: item.key, dropPosition: 'after' }, dropState: dropState, position: "after" }))] }));
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license MIT
|
|
3
|
+
* author: Cube Dev Team
|
|
4
|
+
* @cube-dev/ui-kit v0.104.0
|
|
5
|
+
* Released under the MIT license.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
+
import { useRef } from 'react';
|
|
10
|
+
import { useDropIndicator } from 'react-aria';
|
|
11
|
+
import { DropIndicatorElement } from './styled.js';
|
|
12
|
+
// =============================================================================
|
|
13
|
+
// Component
|
|
14
|
+
// =============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Visual drop indicator for drag-and-drop tab reordering.
|
|
17
|
+
*
|
|
18
|
+
* Renders a vertical line showing where the dragged tab will be dropped.
|
|
19
|
+
* Only visible when the drop target is active.
|
|
20
|
+
*/
|
|
21
|
+
export function TabDropIndicator({ target, dropState, position, }) {
|
|
22
|
+
const ref = useRef(null);
|
|
23
|
+
const { dropIndicatorProps, isHidden, isDropTarget } = useDropIndicator({ target }, dropState, ref);
|
|
24
|
+
if (isHidden) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return (_jsx(DropIndicatorElement, { ref: ref, role: "option", ...dropIndicatorProps, mods: {
|
|
28
|
+
'drop-target': isDropTarget,
|
|
29
|
+
after: position === 'after',
|
|
30
|
+
before: position === 'before',
|
|
31
|
+
} }));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license MIT
|
|
3
|
+
* author: Cube Dev Team
|
|
4
|
+
* @cube-dev/ui-kit v0.104.0
|
|
5
|
+
* Released under the MIT license.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
9
|
+
import { useEffect, useMemo, useRef } from 'react';
|
|
10
|
+
import { useTabPanel } from 'react-aria';
|
|
11
|
+
import { TabPanelElement } from './styled.js';
|
|
12
|
+
// =============================================================================
|
|
13
|
+
// Panel Rendering Utilities
|
|
14
|
+
// =============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Determines if a panel should be rendered based on prerender/keepMounted settings.
|
|
17
|
+
*/
|
|
18
|
+
export function shouldRenderPanel(isActive, wasVisited, effectivePrerender, effectiveKeepMounted) {
|
|
19
|
+
return (!!effectivePrerender || isActive || (!!effectiveKeepMounted && wasVisited));
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Renders a single tab panel with proper ARIA attributes.
|
|
23
|
+
*/
|
|
24
|
+
export function TabPanelRenderer({ tabKey, state, content, prerender, keepMounted, tabPrerender, tabKeepMounted, visitedKeys, panelStyles, qa, qaVal, }) {
|
|
25
|
+
const ref = useRef(null);
|
|
26
|
+
const { tabPanelProps } = useTabPanel({ key: tabKey }, state, ref);
|
|
27
|
+
const isActive = state.selectedKey === tabKey;
|
|
28
|
+
// Determine effective prerender/keepMounted (tab-level overrides global)
|
|
29
|
+
const effectivePrerender = tabPrerender ?? prerender;
|
|
30
|
+
const effectiveKeepMounted = tabKeepMounted ?? keepMounted;
|
|
31
|
+
// Determine if panel should render
|
|
32
|
+
if (!shouldRenderPanel(isActive, visitedKeys.has(tabKey), effectivePrerender, effectiveKeepMounted)) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return (_jsx(TabPanelElement, { ...tabPanelProps, ref: ref, qa: qa ?? 'TabPanel', qaVal: qaVal ?? String(tabKey), styles: panelStyles, style: {
|
|
36
|
+
display: isActive ? 'contents' : 'none',
|
|
37
|
+
}, children: content }));
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Renders panels with content caching for `renderPanel`.
|
|
41
|
+
*
|
|
42
|
+
* Core principle: `renderPanel` is only called when the tab is active
|
|
43
|
+
* (or once on mount for `prerender`). Inactive panels use cached content.
|
|
44
|
+
*
|
|
45
|
+
* Caching behavior:
|
|
46
|
+
* - `keepMounted=true`: Cache content after first activation, reuse while inactive
|
|
47
|
+
* - `prerender=true`: Call `renderPanel` once on mount, reuse until active again
|
|
48
|
+
* - `panelCacheKeys`: Adds cache-key-based invalidation (lazy - only when active)
|
|
49
|
+
* - No caching props: Only active panel is rendered, unmount when inactive
|
|
50
|
+
*/
|
|
51
|
+
export function CachedPanelRenderer({ parsedTabs, explicitPanels, state, renderPanel, panelCacheKeys, prerender, keepMounted, visitedKeys, }) {
|
|
52
|
+
// Cache for rendered content - stores { content, cacheKey } per panel
|
|
53
|
+
const contentCacheRef = useRef(new Map());
|
|
54
|
+
/** Get the cache key for a panel. Returns undefined if not defined. */
|
|
55
|
+
const getCacheKey = (key) => panelCacheKeys?.[key];
|
|
56
|
+
/** Check if a panel has a defined (non-undefined) cache key. */
|
|
57
|
+
const hasCacheKey = (key) => panelCacheKeys != null &&
|
|
58
|
+
key in panelCacheKeys &&
|
|
59
|
+
panelCacheKeys[key] !== undefined;
|
|
60
|
+
/**
|
|
61
|
+
* Determine if we should call renderPanel for this tab.
|
|
62
|
+
*/
|
|
63
|
+
const shouldCallRenderPanel = (tabKey, isActive) => {
|
|
64
|
+
const cached = contentCacheRef.current.get(tabKey);
|
|
65
|
+
// No cache exists - always need to populate on first render
|
|
66
|
+
if (!cached) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
// Cache exists
|
|
70
|
+
if (isActive) {
|
|
71
|
+
// If panelCacheKeys has an entry for this panel, use cache-key-based invalidation
|
|
72
|
+
if (hasCacheKey(tabKey)) {
|
|
73
|
+
const currentCacheKey = getCacheKey(tabKey);
|
|
74
|
+
return cached.cacheKey !== currentCacheKey;
|
|
75
|
+
}
|
|
76
|
+
// No panelCacheKeys entry = always re-render when active
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
// Inactive with cache - use cache
|
|
80
|
+
return false;
|
|
81
|
+
};
|
|
82
|
+
// Clean up cache entries for removed tabs
|
|
83
|
+
const currentTabKeys = useMemo(() => new Set(parsedTabs.map((t) => t.key)), [parsedTabs]);
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
for (const key of contentCacheRef.current.keys()) {
|
|
86
|
+
if (!currentTabKeys.has(key)) {
|
|
87
|
+
contentCacheRef.current.delete(key);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}, [currentTabKeys]);
|
|
91
|
+
return (_jsx(_Fragment, { children: parsedTabs.map((tab) => {
|
|
92
|
+
const explicitPanel = explicitPanels.get(tab.key);
|
|
93
|
+
const tabPrerender = explicitPanel?.prerender ?? tab.prerender;
|
|
94
|
+
const tabKeepMounted = explicitPanel?.keepMounted ?? tab.keepMounted;
|
|
95
|
+
const effectivePrerender = tabPrerender ?? prerender;
|
|
96
|
+
const effectiveKeepMounted = tabKeepMounted ?? keepMounted;
|
|
97
|
+
const isActive = state.selectedKey === tab.key;
|
|
98
|
+
const wasVisited = visitedKeys.has(tab.key);
|
|
99
|
+
// Determine if panel should be in DOM (visibility)
|
|
100
|
+
if (!shouldRenderPanel(isActive, wasVisited, effectivePrerender, effectiveKeepMounted)) {
|
|
101
|
+
// Panel not in DOM - clear cache if no caching strategy
|
|
102
|
+
if (!effectiveKeepMounted && !effectivePrerender) {
|
|
103
|
+
contentCacheRef.current.delete(tab.key);
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
// Determine if we need to call renderPanel
|
|
108
|
+
let content;
|
|
109
|
+
const needsRender = shouldCallRenderPanel(tab.key, isActive);
|
|
110
|
+
if (needsRender) {
|
|
111
|
+
// Call renderPanel and cache the result
|
|
112
|
+
content = renderPanel(tab.key);
|
|
113
|
+
const currentCacheKey = getCacheKey(tab.key);
|
|
114
|
+
contentCacheRef.current.set(tab.key, {
|
|
115
|
+
content,
|
|
116
|
+
cacheKey: currentCacheKey,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
// Use cached content
|
|
121
|
+
const cached = contentCacheRef.current.get(tab.key);
|
|
122
|
+
content = cached?.content ?? null;
|
|
123
|
+
}
|
|
124
|
+
return (_jsx(TabPanelRenderer, { tabKey: tab.key, state: state, content: content, prerender: prerender, keepMounted: keepMounted, tabPrerender: tabPrerender, tabKeepMounted: tabKeepMounted, visitedKeys: visitedKeys, panelStyles: explicitPanel?.styles, qa: explicitPanel?.qa, qaVal: explicitPanel?.qaVal }, tab.key));
|
|
125
|
+
}) }));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license MIT
|
|
3
|
+
* author: Cube Dev Team
|
|
4
|
+
* @cube-dev/ui-kit v0.104.0
|
|
5
|
+
* Released under the MIT license.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
+
import { MoreIcon, TrashIcon } from '../../../icons/index.js';
|
|
10
|
+
import { ItemAction } from '../../actions/ItemAction/index.js';
|
|
11
|
+
import { FilterPicker } from '../../fields/FilterPicker/FilterPicker.js';
|
|
12
|
+
// =============================================================================
|
|
13
|
+
// Component
|
|
14
|
+
// =============================================================================
|
|
15
|
+
/**
|
|
16
|
+
* Tab picker component that displays a dropdown menu of all tabs.
|
|
17
|
+
*
|
|
18
|
+
* Used in the Tabs suffix area when tabs overflow to provide quick navigation
|
|
19
|
+
* to any tab without scrolling.
|
|
20
|
+
*/
|
|
21
|
+
export function TabPicker({ tabs, selectedKey, onSelect, onDelete, size, type = 'default', }) {
|
|
22
|
+
const isDeletable = !!onDelete;
|
|
23
|
+
// Map TabSize to FilterPicker size (xsmall -> small)
|
|
24
|
+
const pickerSize = size === 'xsmall' ? 'small' : size;
|
|
25
|
+
// Only show border divider for file type
|
|
26
|
+
const showBorderDivider = type === 'file';
|
|
27
|
+
return (_jsx(FilterPicker, { selectionMode: "single", selectedKey: selectedKey, renderSummary: false, icon: _jsx(MoreIcon, {}), rightIcon: null, shape: "sharp", type: "neutral", size: pickerSize,
|
|
28
|
+
// Apply border to wrapper (FilterPickerWrapper) so :first-child evaluates
|
|
29
|
+
// relative to Suffix container, not the internal DialogTrigger
|
|
30
|
+
styles: {
|
|
31
|
+
border: showBorderDivider
|
|
32
|
+
? {
|
|
33
|
+
'': 0,
|
|
34
|
+
'!:first-child': 'left',
|
|
35
|
+
}
|
|
36
|
+
: 0,
|
|
37
|
+
}, triggerStyles: { border: 0 }, "aria-label": "Select tab", onSelectionChange: (key) => {
|
|
38
|
+
if (key != null) {
|
|
39
|
+
onSelect(key);
|
|
40
|
+
}
|
|
41
|
+
}, children: tabs.map((tab) => (_jsx(FilterPicker.Item, { textValue: typeof tab.title === 'string' ? tab.title : String(tab.key), showActionsOnHover: isDeletable, actions: isDeletable ? (_jsx(ItemAction, { icon: _jsx(TrashIcon, {}), theme: "danger", "aria-label": "Delete tab", onPress: () => {
|
|
42
|
+
onDelete(tab.key);
|
|
43
|
+
} })) : undefined, children: tab.title }, tab.key))) }));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|