@cube-dev/ui-kit 0.157.3 → 0.159.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/dist/CHANGELOG.md +155 -0
- package/dist/_internal/hooks/use-chained-callback.js +1 -1
- package/dist/_internal/hooks/use-debounced-value.js +1 -1
- package/dist/_internal/hooks/use-deprecation-warning.js +1 -1
- package/dist/_internal/hooks/use-event.js +1 -1
- package/dist/_internal/hooks/use-is-first-render.js +1 -1
- package/dist/_internal/hooks/use-sync-ref.js +1 -1
- package/dist/_internal/hooks/use-timer/timer.js +1 -1
- package/dist/_internal/hooks/use-timer/use-timer.js +1 -1
- package/dist/_internal/hooks/use-warn.js +1 -1
- package/dist/components/Block.js +1 -1
- package/dist/components/CollectionItem.js +1 -1
- package/dist/components/GlobalStyles.js +1 -1
- package/dist/components/GridProvider.js +1 -1
- package/dist/components/HiddenInput.js +1 -1
- package/dist/components/Root.js +1 -1
- package/dist/components/actions/Action/Action.js +1 -1
- package/dist/components/actions/Banner/Banner.js +1 -1
- package/dist/components/actions/Button/Button.js +10 -4
- package/dist/components/actions/Button/Button.js.map +1 -1
- package/dist/components/actions/ButtonGroup/ButtonGroup.js +1 -1
- package/dist/components/actions/ButtonSplit/ButtonSplit.js +1 -1
- package/dist/components/actions/ButtonSplit/context.js +1 -1
- package/dist/components/actions/CommandMenu/CommandMenu.js +1 -1
- package/dist/components/actions/CommandMenu/styled.js +1 -1
- package/dist/components/actions/ItemAction/ItemAction.js +1 -1
- package/dist/components/actions/ItemActionContext.js +1 -1
- package/dist/components/actions/ItemButton/ItemButton.js +1 -1
- package/dist/components/actions/Link/Link.js +1 -1
- package/dist/components/actions/Menu/Menu.js +1 -1
- package/dist/components/actions/Menu/MenuItem.js +1 -1
- package/dist/components/actions/Menu/MenuSection.js +1 -1
- package/dist/components/actions/Menu/MenuTrigger.js +1 -1
- package/dist/components/actions/Menu/SubMenuTrigger.js +1 -1
- package/dist/components/actions/Menu/SubmenuTriggerContext.js +1 -1
- package/dist/components/actions/Menu/context.js +1 -1
- package/dist/components/actions/Menu/styled.js +1 -1
- package/dist/components/actions/index.js +1 -1
- package/dist/components/actions/use-action.js +1 -1
- package/dist/components/actions/use-anchored-menu.js +1 -1
- package/dist/components/actions/use-context-menu.js +1 -1
- package/dist/components/content/ActiveZone/ActiveZone.js +1 -1
- package/dist/components/content/Alert/Alert.js +1 -1
- package/dist/components/content/Alert/use-alert.js +1 -1
- package/dist/components/content/Avatar/Avatar.js +1 -1
- package/dist/components/content/Badge/Badge.js +1 -1
- package/dist/components/content/Card/Card.js +1 -1
- package/dist/components/content/Content.js +1 -1
- package/dist/components/content/CopyPasteBlock/CopyPasteBlock.js +1 -1
- package/dist/components/content/CopySnippet/CopySnippet.js +1 -1
- package/dist/components/content/Disclosure/Disclosure.js +1 -1
- package/dist/components/content/Divider.js +1 -1
- package/dist/components/content/Footer.js +1 -1
- package/dist/components/content/Header.js +1 -1
- package/dist/components/content/HotKeys/HotKeys.js +1 -1
- package/dist/components/content/InfoBadge/InfoBadge.js +1 -1
- package/dist/components/content/InlineInput/InlineInput.js +1 -1
- package/dist/components/content/Item/Item.d.ts +7 -0
- package/dist/components/content/Item/Item.js +13 -6
- package/dist/components/content/Item/Item.js.map +1 -1
- package/dist/components/content/ItemBadge/ItemBadge.js +1 -1
- package/dist/components/content/ItemCard/ItemCard.js +1 -1
- package/dist/components/content/Layout/GridLayout.js +1 -1
- package/dist/components/content/Layout/Layout.js +1 -1
- package/dist/components/content/Layout/LayoutBlock.js +1 -1
- package/dist/components/content/Layout/LayoutCenter.js +1 -1
- package/dist/components/content/Layout/LayoutContainer.js +1 -1
- package/dist/components/content/Layout/LayoutContent.js +1 -1
- package/dist/components/content/Layout/LayoutContext.js +1 -1
- package/dist/components/content/Layout/LayoutFlex.js +1 -1
- package/dist/components/content/Layout/LayoutFooter.js +1 -1
- package/dist/components/content/Layout/LayoutGrid.js +1 -1
- package/dist/components/content/Layout/LayoutHeader.js +1 -1
- package/dist/components/content/Layout/LayoutPane.js +1 -1
- package/dist/components/content/Layout/LayoutPanel.js +1 -1
- package/dist/components/content/Layout/LayoutPanelHeader.js +1 -1
- package/dist/components/content/Layout/LayoutToolbar.js +1 -1
- package/dist/components/content/Layout/hooks/useTinyScrollbar.js +1 -1
- package/dist/components/content/Layout/index.js +1 -1
- package/dist/components/content/Layout/utils.js +1 -1
- package/dist/components/content/Paragraph.js +1 -1
- package/dist/components/content/Placeholder/Placeholder.js +1 -1
- package/dist/components/content/PrismCode/PrismCode.js +1 -1
- package/dist/components/content/PrismCode/prismSetup.js +1 -1
- package/dist/components/content/PrismDiffCode/PrismDiffCode.js +1 -1
- package/dist/components/content/Result/Result.js +1 -1
- package/dist/components/content/Skeleton/Skeleton.js +1 -1
- package/dist/components/content/Tag/Tag.js +1 -1
- package/dist/components/content/Text.d.ts +14 -14
- package/dist/components/content/Text.js +1 -1
- package/dist/components/content/TextItem/TextItem.js +1 -1
- package/dist/components/content/Title.js +1 -1
- package/dist/components/content/Tree/Tree.js +1 -1
- package/dist/components/content/Tree/TreeNode.js +1 -1
- package/dist/components/content/Tree/styled.js +1 -1
- package/dist/components/content/Tree/tree-index.js +1 -1
- package/dist/components/content/Tree/use-checkbox-tree.js +1 -1
- package/dist/components/content/Tree/use-load-data.js +1 -1
- package/dist/components/content/highlightText.js +1 -1
- package/dist/components/content/use-auto-tooltip.js +41 -32
- package/dist/components/content/use-auto-tooltip.js.map +1 -1
- package/dist/components/data/DataTable/DataTable.js +82 -24
- package/dist/components/data/DataTable/DataTable.js.map +1 -1
- package/dist/components/data/DataTable/types.d.ts +56 -1
- package/dist/components/data/ItemTable/ItemTable.js +13 -5
- package/dist/components/data/ItemTable/ItemTable.js.map +1 -1
- package/dist/components/data/ItemTable/ItemTableBulkBar.js +3 -7
- package/dist/components/data/ItemTable/ItemTableBulkBar.js.map +1 -1
- package/dist/components/data/ItemTable/ItemTableDragPreview.js +1 -1
- package/dist/components/data/ItemTable/ItemTableFooter.js +1 -1
- package/dist/components/data/ItemTable/ItemTableToolbar.js +1 -1
- package/dist/components/data/ItemTable/types.d.ts +19 -0
- package/dist/components/data/TableBase/ColumnResizer.js +1 -1
- package/dist/components/data/TableBase/RowCollection.js +5 -3
- package/dist/components/data/TableBase/RowCollection.js.map +1 -1
- package/dist/components/data/TableBase/TableHeaderCell.js +115 -0
- package/dist/components/data/TableBase/TableHeaderCell.js.map +1 -0
- package/dist/components/data/TableBase/TableRow.js +1 -1
- package/dist/components/data/TableBase/TableView.js +195 -33
- package/dist/components/data/TableBase/TableView.js.map +1 -1
- package/dist/components/data/TableBase/column-menu.d.ts +36 -0
- package/dist/components/data/TableBase/column-menu.js +104 -0
- package/dist/components/data/TableBase/column-menu.js.map +1 -0
- package/dist/components/data/TableBase/column-tint.js +168 -0
- package/dist/components/data/TableBase/column-tint.js.map +1 -0
- package/dist/components/data/TableBase/index.d.ts +3 -2
- package/dist/components/data/TableBase/row-menu.js +11 -6
- package/dist/components/data/TableBase/row-menu.js.map +1 -1
- package/dist/components/data/TableBase/styled.js +45 -16
- package/dist/components/data/TableBase/styled.js.map +1 -1
- package/dist/components/data/TableBase/types.d.ts +104 -6
- package/dist/components/data/TableBase/types.js +1 -1
- package/dist/components/data/TableBase/types.js.map +1 -1
- package/dist/components/data/TableBase/use-cell-selection.js +0 -0
- package/dist/components/data/TableBase/use-column-order.js +100 -0
- package/dist/components/data/TableBase/use-column-order.js.map +1 -0
- package/dist/components/data/TableBase/use-container-width.js +1 -1
- package/dist/components/data/TableBase/use-row-move-animation.js +1 -1
- package/dist/components/data/TableBase/use-scrollability.js +1 -1
- package/dist/components/data/TableBase/use-table-columns.js +24 -2
- package/dist/components/data/TableBase/use-table-columns.js.map +1 -1
- package/dist/components/data/TableBase/use-table-search.js +1 -1
- package/dist/components/data/TableBase/use-table-selection.js +1 -1
- package/dist/components/data/TableBase/use-table-sort.js +20 -1
- package/dist/components/data/TableBase/use-table-sort.js.map +1 -1
- package/dist/components/data/TableBase/use-table-sorts.js +40 -1
- package/dist/components/data/TableBase/use-table-sorts.js.map +1 -1
- package/dist/components/data/TableBase/use-table-storage.d.ts +1 -1
- package/dist/components/data/TableBase/use-table-storage.js +6 -2
- package/dist/components/data/TableBase/use-table-storage.js.map +1 -1
- package/dist/components/data/index.d.ts +2 -1
- package/dist/components/fields/Checkbox/Checkbox.js +1 -1
- package/dist/components/fields/Checkbox/CheckboxGroup.js +1 -1
- package/dist/components/fields/Checkbox/context.js +1 -1
- package/dist/components/fields/ColorInput/ColorInput.js +1 -1
- package/dist/components/fields/ColorPicker/ColorPicker.js +1 -1
- package/dist/components/fields/ColorSwatchGroup/ColorSwatchGroup.js +1 -1
- package/dist/components/fields/ComboBox/ComboBox.js +1 -1
- package/dist/components/fields/CommandTextArea/CommandTextArea.js +1 -1
- package/dist/components/fields/CommandTextArea/caretPosition.js +1 -1
- package/dist/components/fields/CommandTextArea/useCaretAnchor.js +1 -1
- package/dist/components/fields/DatePicker/DateInput.js +1 -1
- package/dist/components/fields/DatePicker/DateInputBase.js +1 -1
- package/dist/components/fields/DatePicker/DatePicker.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerButton.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerElement.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerInput.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerSegment.js +1 -1
- package/dist/components/fields/DatePicker/DateRangePicker.js +1 -1
- package/dist/components/fields/DatePicker/DateRangeSeparatedPicker.js +1 -1
- package/dist/components/fields/DatePicker/MonthPicker.js +1 -1
- package/dist/components/fields/DatePicker/PeriodPicker.js +1 -1
- package/dist/components/fields/DatePicker/QuarterPicker.js +1 -1
- package/dist/components/fields/DatePicker/TimeInput.js +1 -1
- package/dist/components/fields/DatePicker/WeekPicker.js +1 -1
- package/dist/components/fields/DatePicker/YearPicker.js +1 -1
- package/dist/components/fields/DatePicker/parseDate.js +1 -1
- package/dist/components/fields/DatePicker/period.js +1 -1
- package/dist/components/fields/DatePicker/props.js +1 -1
- package/dist/components/fields/DatePicker/utils.js +1 -1
- package/dist/components/fields/FileInput/FileInput.js +1 -1
- package/dist/components/fields/FilterListBox/FilterListBox.js +1 -1
- package/dist/components/fields/FilterPicker/FilterPicker.js +1 -1
- package/dist/components/fields/Input/Input.js +1 -1
- package/dist/components/fields/ListBox/DraggableListBox.js +1 -1
- package/dist/components/fields/ListBox/ListBox.js +1 -1
- package/dist/components/fields/ListBoxPopover/ListBoxPopover.js +1 -1
- package/dist/components/fields/ListBoxPopover/listNavigation.js +1 -1
- package/dist/components/fields/ListBoxPopover/useCompositeFocus.js +1 -1
- package/dist/components/fields/NumberInput/NumberInput.js +1 -1
- package/dist/components/fields/NumberInput/StepButton.js +1 -1
- package/dist/components/fields/PasswordInput/PasswordInput.js +1 -1
- package/dist/components/fields/Picker/Picker.js +1 -1
- package/dist/components/fields/RadioGroup/Radio.js +1 -1
- package/dist/components/fields/RadioGroup/RadioGroup.js +1 -1
- package/dist/components/fields/RadioGroup/context.js +1 -1
- package/dist/components/fields/SearchComboBox/SearchComboBox.js +1 -1
- package/dist/components/fields/SearchInput/SearchInput.js +1 -1
- package/dist/components/fields/Select/Select.js +1 -1
- package/dist/components/fields/Slider/Gradation.js +1 -1
- package/dist/components/fields/Slider/HueSlider.js +1 -1
- package/dist/components/fields/Slider/RangeSlider.js +1 -1
- package/dist/components/fields/Slider/Slider.js +1 -1
- package/dist/components/fields/Slider/SliderBase.js +1 -1
- package/dist/components/fields/Slider/SliderThumb.js +1 -1
- package/dist/components/fields/Slider/SliderTrack.js +1 -1
- package/dist/components/fields/Slider/elements.js +1 -1
- package/dist/components/fields/Slider/index.js +1 -1
- package/dist/components/fields/Switch/Switch.js +1 -1
- package/dist/components/fields/TextArea/TextArea.js +1 -1
- package/dist/components/fields/TextInput/TextInput.js +1 -1
- package/dist/components/fields/TextInput/TextInputBase.js +1 -1
- package/dist/components/fields/TextInputMapper/TextInputMapper.js +1 -1
- package/dist/components/fields/color/ColorPanel.js +1 -1
- package/dist/components/fields/color/ColorSwatch.js +1 -1
- package/dist/components/fields/color/channels.js +1 -1
- package/dist/components/fields/color/color.js +1 -1
- package/dist/components/fields/color/context.js +1 -1
- package/dist/components/form/FieldWrapper/FieldWrapper.js +1 -1
- package/dist/components/form/Form/Field.js +1 -1
- package/dist/components/form/Form/Form.js +1 -1
- package/dist/components/form/Form/ResetButton/ResetButton.js +1 -1
- package/dist/components/form/Form/SubmitButton/SubmitButton.js +1 -1
- package/dist/components/form/Form/SubmitError.js +1 -1
- package/dist/components/form/Form/index.js +1 -1
- package/dist/components/form/Form/use-field/use-field-props.js +1 -1
- package/dist/components/form/Form/use-field/use-field.js +1 -1
- package/dist/components/form/Form/use-form.js +1 -1
- package/dist/components/form/Form/validation.js +1 -1
- package/dist/components/form/Label.js +1 -1
- package/dist/components/form/validation/ValidationIndicator.js +1 -1
- package/dist/components/form/validation/resolve-validation-props.js +1 -1
- package/dist/components/form/validation/use-validation-props.js +1 -1
- package/dist/components/form/wrapper.js +1 -1
- package/dist/components/helpers/DisplayTransition/DisplayTransition.js +1 -1
- package/dist/components/helpers/IconSwitch/IconSwitch.js +1 -1
- package/dist/components/layout/Board/Board.js +1 -1
- package/dist/components/layout/Board/BoardProvider.js +1 -1
- package/dist/components/layout/Board/BoardResponsive.js +1 -1
- package/dist/components/layout/Board/Widget.js +1 -1
- package/dist/components/layout/Board/WidgetHost.js +1 -1
- package/dist/components/layout/Board/board-context.js +1 -1
- package/dist/components/layout/Board/board-store.js +1 -1
- package/dist/components/layout/Board/grid-core/calculate.js +1 -1
- package/dist/components/layout/Board/grid-core/collision.js +1 -1
- package/dist/components/layout/Board/grid-core/compactors.js +1 -1
- package/dist/components/layout/Board/grid-core/constraints.js +1 -1
- package/dist/components/layout/Board/grid-core/group-move.js +1 -1
- package/dist/components/layout/Board/grid-core/layout.js +1 -1
- package/dist/components/layout/Board/grid-core/sort.js +1 -1
- package/dist/components/layout/Board/index.js +1 -1
- package/dist/components/layout/Board/responsive-utils.js +1 -1
- package/dist/components/layout/Board/use-board-layout.js +1 -1
- package/dist/components/layout/Board/use-board-registry.js +1 -1
- package/dist/components/layout/Board/use-board-select-modifier-key.js +1 -1
- package/dist/components/layout/Board/use-board-selection.js +1 -1
- package/dist/components/layout/Flex.js +1 -1
- package/dist/components/layout/Flow.js +1 -1
- package/dist/components/layout/Grid.js +1 -1
- package/dist/components/layout/Panel.js +1 -1
- package/dist/components/layout/Prefix.js +1 -1
- package/dist/components/layout/ResizablePanel.js +1 -1
- package/dist/components/layout/Space.js +1 -1
- package/dist/components/layout/Suffix.js +1 -1
- package/dist/components/navigation/Pagination/Pagination.js +1 -1
- package/dist/components/navigation/Pagination/use-pagination.js +1 -1
- package/dist/components/navigation/Tabs/DraggableTabList.js +1 -1
- package/dist/components/navigation/Tabs/TabButton.js +1 -1
- package/dist/components/navigation/Tabs/TabDropIndicator.js +1 -1
- package/dist/components/navigation/Tabs/TabPanel.js +1 -1
- package/dist/components/navigation/Tabs/TabPicker.js +1 -1
- package/dist/components/navigation/Tabs/Tabs.js +1 -1
- package/dist/components/navigation/Tabs/TabsAction.js +1 -1
- package/dist/components/navigation/Tabs/TabsContext.js +1 -1
- package/dist/components/navigation/Tabs/popover-placement.js +1 -1
- package/dist/components/navigation/Tabs/styled.js +1 -1
- package/dist/components/navigation/Tabs/types.js +1 -1
- package/dist/components/navigation/Tabs/use-tab-editing.js +1 -1
- package/dist/components/navigation/Tabs/use-tab-indicator.js +1 -1
- package/dist/components/organisms/StatsCard/StatsCard.js +1 -1
- package/dist/components/other/Calendar/Calendar.js +1 -1
- package/dist/components/other/Calendar/CalendarCell.js +1 -1
- package/dist/components/other/Calendar/CalendarGrid.js +1 -1
- package/dist/components/other/Calendar/PeriodCalendar.js +1 -1
- package/dist/components/other/Calendar/RangeCalendar.js +1 -1
- package/dist/components/other/CubeLogo/CubeLogo.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialog.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialogApiProvider.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialogZone.js +1 -1
- package/dist/components/overlays/Dialog/Dialog.js +1 -1
- package/dist/components/overlays/Dialog/DialogContainer.js +1 -1
- package/dist/components/overlays/Dialog/DialogForm.js +1 -1
- package/dist/components/overlays/Dialog/DialogTrigger.js +1 -1
- package/dist/components/overlays/Dialog/context.js +1 -1
- package/dist/components/overlays/Dialog/use-dialog-container.js +1 -1
- package/dist/components/overlays/Modal/Modal.js +1 -1
- package/dist/components/overlays/Modal/OpenTransitionContext.js +1 -1
- package/dist/components/overlays/Modal/Overlay.js +1 -1
- package/dist/components/overlays/Modal/Popover.js +1 -1
- package/dist/components/overlays/Modal/Tray.js +1 -1
- package/dist/components/overlays/Modal/Underlay.js +1 -1
- package/dist/components/overlays/Notifications/Notification.js +1 -1
- package/dist/components/overlays/Notifications/NotificationAction.js +1 -1
- package/dist/components/overlays/Notifications/NotificationCard.js +1 -1
- package/dist/components/overlays/Notifications/NotificationContext.js +1 -1
- package/dist/components/overlays/Notifications/NotificationItem.js +1 -1
- package/dist/components/overlays/Notifications/OverlayContainer.js +1 -1
- package/dist/components/overlays/Notifications/OverlayProvider.js +1 -1
- package/dist/components/overlays/Notifications/PersistentNotificationsList.js +1 -1
- package/dist/components/overlays/Notifications/dismissed-storage.js +1 -1
- package/dist/components/overlays/Notifications/format-relative-time.js +1 -1
- package/dist/components/overlays/Notifications/index.js +1 -1
- package/dist/components/overlays/Notifications/use-notification-state.js +1 -1
- package/dist/components/overlays/Notifications/use-notifications.js +1 -1
- package/dist/components/overlays/Notifications/use-overlay-timers.js +1 -1
- package/dist/components/overlays/Notifications/use-persistent-notifications.js +1 -1
- package/dist/components/overlays/Notifications/use-persistent-state.js +1 -1
- package/dist/components/overlays/Notifications/use-toast-state.js +1 -1
- package/dist/components/overlays/Toast/ToastItem.js +1 -1
- package/dist/components/overlays/Toast/index.js +1 -1
- package/dist/components/overlays/Toast/useProgressToast.js +1 -1
- package/dist/components/overlays/Toast/useToast.js +1 -1
- package/dist/components/overlays/Tooltip/Tooltip.js +1 -1
- package/dist/components/overlays/Tooltip/TooltipProvider.js +1 -1
- package/dist/components/overlays/Tooltip/TooltipTrigger.js +1 -1
- package/dist/components/overlays/Tooltip/context.js +1 -1
- package/dist/components/portal/Portal.js +1 -1
- package/dist/components/portal/PortalProvider.js +1 -1
- package/dist/components/portal/usePortal.js +1 -1
- package/dist/components/shared/DraggableCollection.js +1 -1
- package/dist/components/shared/InvalidIcon.js +1 -1
- package/dist/components/shared/ValidIcon.js +1 -1
- package/dist/components/status/LoadingAnimation/LoadingAnimation.js +1 -1
- package/dist/components/status/Spin/Cube.js +1 -1
- package/dist/components/status/Spin/InternalSpinner.js +1 -1
- package/dist/components/status/Spin/Spin.js +1 -1
- package/dist/components/status/Spin/SpinsContainer.js +1 -1
- package/dist/data/item-themes.js +1 -1
- package/dist/data/themes.js +1 -1
- package/dist/eslint-plugin/defaults.generated.js +13 -1
- package/dist/eslint-plugin/defaults.generated.js.map +1 -1
- package/dist/eslint-plugin/index.js +1 -1
- package/dist/eslint-plugin/rules/no-redundant-default-prop.js +1 -1
- package/dist/i18n/I18nProvider.js +1 -1
- package/dist/i18n/createFormatter.js +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/instance.js +1 -1
- package/dist/i18n/locales/de-DE/uikit.js +5 -1
- package/dist/i18n/locales/en-US/uikit.js +5 -1
- package/dist/i18n/locales/en-US/uikit.json.d.ts +4 -0
- package/dist/i18n/locales/es-ES/uikit.js +5 -1
- package/dist/i18n/locales/es-MX/uikit.js +5 -1
- package/dist/i18n/locales/fr-FR/uikit.js +5 -1
- package/dist/i18n/locales/it-IT/uikit.js +5 -1
- package/dist/i18n/locales/ja-JP/uikit.js +5 -1
- package/dist/i18n/locales/nb-NO/uikit.js +5 -1
- package/dist/i18n/locales/pt-BR/uikit.js +5 -1
- package/dist/i18n/locales/pt-PT/uikit.js +5 -1
- package/dist/i18n/locales/sv-SE/uikit.js +5 -1
- package/dist/i18n/locales/vi-VN/uikit.js +5 -1
- package/dist/i18n/locales.js +1 -1
- package/dist/i18n/useFormatter.js +1 -1
- package/dist/i18n/useI18n.js +1 -1
- package/dist/icons/AdjustmentsHorizontalIcon.js +1 -1
- package/dist/icons/AdjustmentsIcon.js +1 -1
- package/dist/icons/AiIcon.js +1 -1
- package/dist/icons/AreaChartIcon.js +1 -1
- package/dist/icons/ArrowNarrowDownIcon.d.ts +12 -0
- package/dist/icons/ArrowNarrowDownIcon.js +11 -0
- package/dist/icons/ArrowNarrowDownIcon.js.map +1 -0
- package/dist/icons/ArrowNarrowUpIcon.d.ts +12 -0
- package/dist/icons/ArrowNarrowUpIcon.js +11 -0
- package/dist/icons/ArrowNarrowUpIcon.js.map +1 -0
- package/dist/icons/BackwardIcon.js +1 -1
- package/dist/icons/BarChartIcon.js +1 -1
- package/dist/icons/BellFilledIcon.js +1 -1
- package/dist/icons/BellIcon.js +1 -1
- package/dist/icons/BooleanIcon.js +1 -1
- package/dist/icons/CalendarEditIcon.js +1 -1
- package/dist/icons/CalendarIcon.js +1 -1
- package/dist/icons/CaretDownIcon.js +1 -1
- package/dist/icons/CaretUpIcon.js +1 -1
- package/dist/icons/ChartAreaStackedIcon.js +1 -1
- package/dist/icons/ChartAreaStackedPercentageIcon.js +1 -1
- package/dist/icons/ChartBarGroupedHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarGroupedIcon.js +1 -1
- package/dist/icons/ChartBarHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarLineIcon.js +1 -1
- package/dist/icons/ChartBarStackedHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarStackedIcon.js +1 -1
- package/dist/icons/ChartBarStackedPercentageHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarStackedPercentageIcon.js +1 -1
- package/dist/icons/ChartBoxPlot2Icon.js +1 -1
- package/dist/icons/ChartBoxPlotIcon.js +1 -1
- package/dist/icons/ChartBubbleIcon.js +1 -1
- package/dist/icons/ChartDonut2Icon.js +1 -1
- package/dist/icons/ChartFunnelIcon.js +1 -1
- package/dist/icons/ChartHeatmapIcon.js +1 -1
- package/dist/icons/ChartKPIIcon.js +1 -1
- package/dist/icons/ChartPie2Icon.js +1 -1
- package/dist/icons/ChartScatterIcon.js +1 -1
- package/dist/icons/CheckCircleFilledIcon.js +1 -1
- package/dist/icons/CheckCircleIcon.js +1 -1
- package/dist/icons/CheckIcon.js +1 -1
- package/dist/icons/CircleFilledIcon.js +1 -1
- package/dist/icons/ClearIcon.js +1 -1
- package/dist/icons/CloseCircleFilledIcon.js +1 -1
- package/dist/icons/CloseCircleIcon.js +1 -1
- package/dist/icons/CloseIcon.js +1 -1
- package/dist/icons/CodeIcon.js +1 -1
- package/dist/icons/ColumnTotalIcon.js +1 -1
- package/dist/icons/CopyIcon.js +1 -1
- package/dist/icons/CountIcon.js +1 -1
- package/dist/icons/CubeIcon.js +1 -1
- package/dist/icons/CubePauseIcon.js +1 -1
- package/dist/icons/CubePlayIcon.js +1 -1
- package/dist/icons/CurrencyDollarIcon.js +1 -1
- package/dist/icons/DangerIcon.js +1 -1
- package/dist/icons/DashboardIcon.js +1 -1
- package/dist/icons/DatabaseIcon.js +1 -1
- package/dist/icons/DecimalDecreaseIcon.js +1 -1
- package/dist/icons/DecimalIncreaseIcon.js +1 -1
- package/dist/icons/DirectionIcon.js +1 -1
- package/dist/icons/DonutIcon.js +1 -1
- package/dist/icons/DownIcon.js +1 -1
- package/dist/icons/EditIcon.js +1 -1
- package/dist/icons/ExclamationCircleFilledIcon.js +1 -1
- package/dist/icons/ExclamationCircleIcon.js +1 -1
- package/dist/icons/ExclamationIcon.js +1 -1
- package/dist/icons/EyeIcon.js +1 -1
- package/dist/icons/EyeInvisibleIcon.js +1 -1
- package/dist/icons/FilterIcon.js +1 -1
- package/dist/icons/FolderFilledIcon.js +1 -1
- package/dist/icons/FolderIcon.js +1 -1
- package/dist/icons/FolderOpenFilledIcon.js +1 -1
- package/dist/icons/FolderOpenIcon.js +1 -1
- package/dist/icons/ForwardIcon.js +1 -1
- package/dist/icons/GripVerticalIcon.js +1 -1
- package/dist/icons/HierarchyIcon.js +1 -1
- package/dist/icons/HierarchyOpenIcon.js +1 -1
- package/dist/icons/Icon.js +1 -1
- package/dist/icons/InfoCircleIcon.js +1 -1
- package/dist/icons/InfoIcon.js +1 -1
- package/dist/icons/KeyIcon.js +1 -1
- package/dist/icons/LeftIcon.js +1 -1
- package/dist/icons/LineChartIcon.js +1 -1
- package/dist/icons/LoadingIcon.js +1 -1
- package/dist/icons/LockFilledIcon.js +1 -1
- package/dist/icons/LockIcon.js +1 -1
- package/dist/icons/MoreIcon.js +1 -1
- package/dist/icons/NotAllowedIcon.js +1 -1
- package/dist/icons/Number123Icon.js +1 -1
- package/dist/icons/NumberIcon.js +1 -1
- package/dist/icons/PauseCircleFilledIcon.js +1 -1
- package/dist/icons/PauseCircleIcon.js +1 -1
- package/dist/icons/PauseIcon.js +1 -1
- package/dist/icons/PercentageIcon.js +1 -1
- package/dist/icons/PieChartIcon.js +1 -1
- package/dist/icons/PipetteIcon.js +1 -1
- package/dist/icons/PlayCircleIcon.js +1 -1
- package/dist/icons/PlayIcon.js +1 -1
- package/dist/icons/PlusIcon.js +1 -1
- package/dist/icons/ProgressBarIcon.js +1 -1
- package/dist/icons/ReloadIcon.js +1 -1
- package/dist/icons/ReportIcon.js +1 -1
- package/dist/icons/ReturnIcon.js +1 -1
- package/dist/icons/RightIcon.js +1 -1
- package/dist/icons/RowTotalsIcon.js +1 -1
- package/dist/icons/SchemeIcon.js +1 -1
- package/dist/icons/SearchIcon.js +1 -1
- package/dist/icons/SemanticQueryIcon.js +1 -1
- package/dist/icons/SettingsIcon.js +1 -1
- package/dist/icons/ShieldFilledIcon.js +1 -1
- package/dist/icons/ShieldIcon.js +1 -1
- package/dist/icons/SlashIcon.js +1 -1
- package/dist/icons/SparklesIcon.js +1 -1
- package/dist/icons/SqlIcon.js +1 -1
- package/dist/icons/StatsIcon.js +1 -1
- package/dist/icons/StopIcon.js +1 -1
- package/dist/icons/StringIcon.js +1 -1
- package/dist/icons/SubtotalsIcon.js +1 -1
- package/dist/icons/SwitchIcon.js +1 -1
- package/dist/icons/TableIcon.js +1 -1
- package/dist/icons/ThumbsDownIcon.js +1 -1
- package/dist/icons/ThumbsUpIcon.js +1 -1
- package/dist/icons/ThunderboltCrossedIcon.js +1 -1
- package/dist/icons/ThunderboltFilledIcon.js +1 -1
- package/dist/icons/ThunderboltIcon.js +1 -1
- package/dist/icons/TimeIcon.js +1 -1
- package/dist/icons/TrashIcon.js +1 -1
- package/dist/icons/UnlockIcon.js +1 -1
- package/dist/icons/UpIcon.js +1 -1
- package/dist/icons/UserGroupIcon.js +1 -1
- package/dist/icons/UserIcon.js +1 -1
- package/dist/icons/UserLockIcon.js +1 -1
- package/dist/icons/ViewIcon.js +1 -1
- package/dist/icons/WarningFilledIcon.js +1 -1
- package/dist/icons/WarningIcon.js +1 -1
- package/dist/icons/index.d.ts +2 -0
- package/dist/icons/wrap-icon.js +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/provider.js +1 -1
- package/dist/providers/TrackingProvider.js +1 -1
- package/dist/providers/navigationAdapter.default.js +1 -1
- package/dist/tokens/base.js +1 -1
- package/dist/tokens/color-theme.d.ts +86 -0
- package/dist/tokens/color-theme.js +156 -0
- package/dist/tokens/color-theme.js.map +1 -0
- package/dist/tokens/colors.js +1 -1
- package/dist/tokens/index.d.ts +1 -0
- package/dist/tokens/index.js +2 -1
- package/dist/tokens/index.js.map +1 -1
- package/dist/tokens/layout.js +1 -1
- package/dist/tokens/lazy-styles.js +1 -1
- package/dist/tokens/palette-config.d.ts +1 -1
- package/dist/tokens/palette-config.js +17 -5
- package/dist/tokens/palette-config.js.map +1 -1
- package/dist/tokens/palette.d.ts +1 -1
- package/dist/tokens/palette.js +44 -2
- package/dist/tokens/palette.js.map +1 -1
- package/dist/tokens/shadows.js +1 -1
- package/dist/tokens/sizes.js +1 -1
- package/dist/tokens/spacing.js +1 -1
- package/dist/tokens/typography.js +1 -1
- package/dist/utils/ResizeSensor.js +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/is-dev-env.js +1 -1
- package/dist/utils/modules.js +1 -1
- package/dist/utils/promise.js +1 -1
- package/dist/utils/raf.js +1 -1
- package/dist/utils/random.js +1 -1
- package/dist/utils/range.js +1 -1
- package/dist/utils/react/RenderCache.js +1 -1
- package/dist/utils/react/Slots.js +1 -1
- package/dist/utils/react/chain.js +1 -1
- package/dist/utils/react/disabledProps.d.ts +49 -0
- package/dist/utils/react/disabledProps.js +82 -0
- package/dist/utils/react/disabledProps.js.map +1 -0
- package/dist/utils/react/forwardRefWithGenerics.js +1 -1
- package/dist/utils/react/index.d.ts +1 -0
- package/dist/utils/react/index.js +2 -1
- package/dist/utils/react/interactions.js +1 -1
- package/dist/utils/react/isTextOnly.js +1 -1
- package/dist/utils/react/mapProps.js +1 -1
- package/dist/utils/react/mergeProps.js +1 -1
- package/dist/utils/react/nullableValue.js +1 -1
- package/dist/utils/react/resolveIcon.js +1 -1
- package/dist/utils/react/sharedStore.js +1 -1
- package/dist/utils/react/useBufferedValue.js +1 -1
- package/dist/utils/react/useCombinedRefs.js +1 -1
- package/dist/utils/react/useControlledFocusVisible.js +1 -1
- package/dist/utils/react/useEventBus.js +1 -1
- package/dist/utils/react/useId.js +1 -1
- package/dist/utils/react/useIsDarwin.js +1 -1
- package/dist/utils/react/useKeySymbols.js +1 -1
- package/dist/utils/react/useLayoutEffect.js +1 -1
- package/dist/utils/react/useLocalStorage.js +1 -1
- package/dist/utils/react/useMergeStyles.js +1 -1
- package/dist/utils/react/usePopoverSync.js +1 -1
- package/dist/utils/react/useQaProps.js +1 -1
- package/dist/utils/react/useViewportSize.js +1 -1
- package/dist/utils/react/wrapNodeIfPlain.js +1 -1
- package/dist/utils/selection.js +1 -1
- package/dist/utils/styles.js +1 -1
- package/dist/utils/tree.js +1 -1
- package/dist/utils/warnings.js +1 -1
- package/dist/version.js +2 -2
- package/docs/Theming.md +20 -13
- package/docs/components/actions/Button.md +17 -0
- package/docs/components/content/Item.md +8 -1
- package/docs/components/data/DataTable.md +118 -2
- package/docs/components/data/ItemTable.md +37 -5
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataTable.js","names":[],"sources":["../../../../src/components/data/DataTable/DataTable.tsx"],"sourcesContent":["import { useControlledState } from '@react-stately/utils';\nimport { CONTAINER_STYLES } from '@tenphi/tasty';\nimport { forwardRef, useMemo, useRef, useState } from 'react';\n\nimport { useEvent } from '../../../_internal/hooks';\nimport { useI18n } from '../../../i18n';\nimport { useCombinedRefs } from '../../../utils/react';\nimport { extractStyles } from '../../../utils/styles';\nimport { clampPage, getPageInfo } from '../../navigation/Pagination';\nimport { ItemTableFooter } from '../ItemTable/ItemTableFooter';\nimport { TableView } from '../TableBase/TableView';\nimport { selectionRowKey } from '../TableBase/types';\nimport { useCellSelection } from '../TableBase/use-cell-selection';\nimport { useContainerWidth } from '../TableBase/use-container-width';\nimport { useTableColumns } from '../TableBase/use-table-columns';\nimport { ROW_NUMBER_COLUMN_KEY } from '../TableBase/use-table-selection';\nimport { useTableSorts } from '../TableBase/use-table-sorts';\nimport { useTableStorage } from '../TableBase/use-table-storage';\n\nimport type { Key } from '@react-types/shared';\nimport type { ForwardedRef, ReactElement } from 'react';\nimport type { CubeTableRowSection } from '../TableBase/types';\nimport type { CubeDataTableColumn, CubeDataTableProps } from './types';\n\n/** Wide enough for five digits at the dense default. */\nconst ROW_NUMBER_WIDTH = 56;\n\nconst EMPTY_WIDTHS: Record<string, number> = {};\n\nfunction defaultGetRowKey<T>(rowKey: string) {\n return (row: T, index: number): Key => {\n const value = (row as any)?.[rowKey];\n\n return value == null ? index : (value as Key);\n };\n}\n\n/**\n * A grid for query results.\n *\n * The same engine as `ItemTable` — one `TableView`, one column layout, one\n * value pipeline — with the defaults an analytical grid wants rather than a\n * list's: denser type, banded rows, resizable columns, multi-column sort, and\n * rows pinned for totals.\n *\n * It knows nothing about Cube. Measures, dimensions, pivots and drill-downs\n * reach it as ordinary columns, `render` output and `column.header.menu`\n * content, which is what keeps the ~34 kB of Cloud's column-header menu in\n * Cloud.\n */\nfunction DataTable<T = any>(\n props: CubeDataTableProps<T>,\n ref: ForwardedRef<HTMLDivElement>,\n) {\n const {\n data,\n columns,\n rowKey = 'id',\n getRowKey,\n pinnedTopRows,\n pinnedBottomRows,\n isLoading = false,\n loadingIndicator = 'overlay',\n skeletonRowCount,\n error,\n emptyLabel,\n noResultsLabel,\n isFiltered,\n shape = 'plain',\n // Denser than `ItemTable`'s `medium`: a result grid is read as a block, and\n // more rows on screen is the point of it.\n size = 'small',\n rowHeight,\n headerHeight,\n isStriped = true,\n isHeaderHidden,\n isHeaderSticky,\n showRowNumbers = false,\n sortMode,\n sorts: sortsProp,\n defaultSorts,\n onSortsChange,\n paginationMode = 'client',\n page: pageProp,\n defaultPage,\n onPageChange,\n pageSize: pageSizeProp,\n defaultPageSize = 100,\n onPageSizeChange,\n pageSizeOptions,\n total: totalProp,\n totalPages,\n hasNextPage,\n summary = true,\n autoHidePagination = true,\n footerStart,\n footerCenter,\n footerEnd,\n cellSelectionMode = 'range',\n isCellSelectable,\n selectedCellRange,\n defaultSelectedCellRange,\n onCellRangeChange,\n isRowMoveAnimated,\n isResizable = true,\n columnWidths: columnWidthsProp,\n defaultColumnWidths,\n onColumnResize,\n isVirtualized,\n virtualizeThreshold,\n overscan,\n getRowProps,\n storageKey,\n styles,\n headerStyles,\n headerCellStyles,\n bodyStyles,\n rowStyles,\n cellStyles,\n footerStyles,\n ariaLabel,\n qa,\n mods,\n ...rest\n } = props;\n\n const localRef = useRef<HTMLDivElement>(null);\n const rootRef = useCombinedRefs(ref, localRef);\n const [scrollerEl, setScrollerEl] = useState<HTMLElement | null>(null);\n const containerWidth = useContainerWidth(scrollerEl);\n\n const storage = useTableStorage(storageKey);\n\n /**\n * `dataType` is presentational, so it is folded into the column here rather\n * than reaching the renderer: `number` right-aligns and takes tabular figures\n * so digits line up down the column.\n */\n const resolvedColumns = useMemo(\n () =>\n columns.map((column) => {\n const isNumeric = column.dataType === 'number';\n\n return {\n ...column,\n align: column.align ?? (isNumeric ? 'end' : 'start'),\n cellStyles: isNumeric\n ? {\n fontVariantNumeric: 'tabular-nums',\n ...(typeof column.cellStyles === 'object'\n ? column.cellStyles\n : null),\n }\n : column.cellStyles,\n } as CubeDataTableColumn<T>;\n }),\n [columns],\n );\n\n const {\n sorts,\n sortedRows,\n toggleSort,\n mode: resolvedSortMode,\n } = useTableSorts<T>({\n columns: resolvedColumns,\n rows: data,\n mode: sortMode,\n sorts: sortsProp,\n defaultSorts,\n onSortsChange,\n });\n\n const [pageSize, setPageSizeState] = useControlledState<number>(\n pageSizeProp as number,\n (pageSizeProp === undefined && storage.has('pageSize')\n ? storage.initial.pageSize ?? defaultPageSize\n : defaultPageSize) as number,\n onPageSizeChange as (value: number) => void,\n );\n const [page, setPageState] = useControlledState<number>(\n pageProp as number,\n defaultPage ?? 1,\n onPageChange as (value: number) => void,\n );\n\n const isPaginated = paginationMode !== 'off';\n const isServerPaginated = paginationMode === 'server';\n const total = isServerPaginated ? totalProp ?? 0 : sortedRows.length;\n\n const pageInfo = getPageInfo({\n page,\n pageSize,\n total,\n totalPages: isServerPaginated ? totalPages : undefined,\n });\n\n const setPage = useEvent((next: number) =>\n setPageState(clampPage(next, pageInfo.totalPages)),\n );\n const setPageSize = useEvent((next: number) => {\n setPageSizeState(next);\n setPageState(1);\n\n if (pageSizeProp === undefined) storage.write({ pageSize: next });\n });\n\n const visibleRows =\n paginationMode === 'client'\n ? sortedRows.slice(\n (pageInfo.page - 1) * pageSize,\n pageInfo.page * pageSize,\n )\n : sortedRows;\n\n const [ownColumnWidths, setOwnColumnWidths] = useState<\n Record<string, number>\n >(\n () =>\n (columnWidthsProp === undefined && storage.has('columnWidths')\n ? storage.initial.columnWidths ?? defaultColumnWidths\n : defaultColumnWidths) ?? EMPTY_WIDTHS,\n );\n const [draftColumnWidths, setDraftColumnWidths] = useState<Record<\n string,\n number\n > | null>(null);\n const draftRef = useRef<Record<string, number> | null>(null);\n\n const baseColumnWidths = columnWidthsProp ?? ownColumnWidths;\n const columnWidths = draftColumnWidths ?? baseColumnWidths;\n\n const handleColumnResize = useEvent((key: string, width: number) => {\n draftRef.current = {\n ...(draftRef.current ?? baseColumnWidths),\n [key]: Math.round(width),\n };\n setDraftColumnWidths(draftRef.current);\n });\n\n const handleColumnResizeEnd = useEvent((key: string) => {\n const next = draftRef.current ?? baseColumnWidths;\n\n if (columnWidthsProp === undefined) {\n setOwnColumnWidths(next);\n storage.write({ columnWidths: next });\n }\n\n onColumnResize?.(key, next[key], next);\n draftRef.current = null;\n setDraftColumnWidths(null);\n });\n\n const leadingColumns = useMemo(\n () =>\n showRowNumbers\n ? [{ key: ROW_NUMBER_COLUMN_KEY, width: ROW_NUMBER_WIDTH }]\n : undefined,\n [showRowNumbers],\n );\n\n const layout = useTableColumns<T>({\n columns: resolvedColumns,\n containerWidth,\n columnWidths,\n leadingColumns,\n });\n\n const { t } = useI18n();\n\n const resolvedGetRowKey = useMemo(\n () => getRowKey ?? defaultGetRowKey<T>(rowKey),\n [getRowKey, rowKey],\n );\n\n // Every row a range can reach, in the order they appear on screen. Pinned rows\n // are in it: a total is a figure like any other, and having to copy it\n // separately from the column it sums is the wrong trade.\n //\n // The keys are built here rather than inside the hook so they cannot disagree\n // with the ones the renderer stamps — a pinned row is keyed by its own index\n // within its group, exactly as `renderPinnedRow` keys it.\n const selectionRows = useMemo(\n () => [\n ...(pinnedTopRows ?? []),\n ...visibleRows,\n ...(pinnedBottomRows ?? []),\n ],\n [pinnedTopRows, visibleRows, pinnedBottomRows],\n );\n const selectionRowKeys = useMemo(\n () => [\n // Section-qualified, matching what the renderer stamps: the same record\n // is routinely pinned at both edges, and one flat key space collapsed the\n // two into whichever came first.\n ...(pinnedTopRows ?? []).map((row, index) =>\n selectionRowKey('pinnedTop', resolvedGetRowKey(row, index)),\n ),\n ...visibleRows.map(resolvedGetRowKey),\n ...(pinnedBottomRows ?? []).map((row, index) =>\n selectionRowKey('pinnedBottom', resolvedGetRowKey(row, index)),\n ),\n ],\n [pinnedTopRows, visibleRows, pinnedBottomRows, resolvedGetRowKey],\n );\n\n // The hook works in one flat row order; the section a row belongs to is a\n // property of where it sits in that order, so it is resolved here rather than\n // asking the consumer to track it.\n const resolveCellSelectable = useEvent(\n (row: T, rowKey: Key, columnKey: string) => {\n if (!isCellSelectable) return true;\n\n const index = selectionRowKeys.indexOf(rowKey);\n const topCount = pinnedTopRows?.length ?? 0;\n const section: CubeTableRowSection =\n index < topCount\n ? 'pinnedTop'\n : index < topCount + visibleRows.length\n ? 'body'\n : 'pinnedBottom';\n\n return isCellSelectable({ row, rowKey, columnKey, section });\n },\n );\n\n const cellSelection = useCellSelection<T>({\n mode: cellSelectionMode,\n columns: layout.columns,\n rows: selectionRows,\n rowKeys: selectionRowKeys,\n isCellSelectable: isCellSelectable ? resolveCellSelectable : undefined,\n range: selectedCellRange,\n defaultRange: defaultSelectedCellRange,\n onRangeChange: onCellRangeChange,\n });\n\n // Same as `ItemTable`: style props (`height`, `maxHeight`, `margin`, …) land\n // on the root frame. `height` is the one that matters — there is no\n // page-scroll mode, so bounding the grid is what turns the body into a\n // scroller, pins the header, and lets virtualization engage at all.\n const rootStyles = { ...extractStyles(props, CONTAINER_STYLES), ...styles };\n\n const smallestPageSize = pageSizeOptions?.length\n ? Math.min(...pageSizeOptions)\n : pageSize;\n\n const showPagination =\n isPaginated &&\n !(\n autoHidePagination &&\n !hasNextPage &&\n pageInfo.totalPages <= 1 &&\n total <= smallestPageSize\n );\n\n const hasFooter =\n showPagination ||\n footerStart != null ||\n footerCenter != null ||\n footerEnd != null;\n\n return (\n <TableView<T>\n {...rest}\n rootRef={rootRef}\n qa={qa || 'DataTable'}\n rows={visibleRows}\n pinnedTopRows={pinnedTopRows}\n pinnedBottomRows={pinnedBottomRows}\n // Continuous across pages: row 101 is row 101, not row 1 of page two.\n //\n // Server mode counts too — the page and its size are known there just the\n // same, and `rows` is that page. Only `'off'` starts at 1, because then\n // there is no page to be on.\n rowNumberOffset={\n paginationMode === 'off' ? 0 : (pageInfo.page - 1) * pageSize\n }\n // The same offset drives `aria-rowindex`, which is document-absolute by\n // contract — a screen reader on page 3 should hear \"row 51 of 240\", not\n // \"row 1 of 25\".\n rowIndexOffset={\n paginationMode === 'off' ? 0 : (pageInfo.page - 1) * pageSize\n }\n totalRowCount={total}\n layout={layout}\n // Always on, unlike `ItemTable`. A result grid is read down a column, and\n // once the values are wide and right-aligned the rule is what keeps a\n // figure attached to its column — which is why Cloud's ag-grid theme sets\n // `columnBorder` for `DataTable` and not for the list grids.\n hasColumnDividers\n cellSelection={cellSelection}\n getRowKey={resolvedGetRowKey}\n onScrollerRef={setScrollerEl}\n isLoading={isLoading}\n loadingIndicator={loadingIndicator}\n skeletonRowCount={skeletonRowCount}\n error={error}\n // Same localized fallbacks as `ItemTable`: a grid that has finished\n // loading and shows an unexplained blank rectangle reads as broken.\n emptyLabel={emptyLabel ?? t('itemTable.noItems', 'No items')}\n noResultsLabel={\n noResultsLabel ?? t('itemTable.noResults', 'No results found')\n }\n isFiltered={isFiltered}\n shape={shape}\n size={size}\n rowHeight={rowHeight}\n headerHeight={headerHeight}\n isStriped={isStriped}\n isRowMoveAnimated={isRowMoveAnimated}\n isHeaderHidden={isHeaderHidden}\n isHeaderSticky={isHeaderSticky}\n // The header shows the column name at body size — a result grid has no\n // room for the uppercase caption a list header uses.\n // `t4` throughout: a result grid is read as a block, and one step down\n // from the list preset fits noticeably more on screen without losing\n // legibility. The header takes the medium weight of the same step.\n contentPreset=\"t4\"\n headerPreset=\"t4m\"\n sortMode={resolvedSortMode}\n sorts={sorts}\n onColumnSort={toggleSort}\n isVirtualized={isVirtualized}\n virtualizeThreshold={virtualizeThreshold}\n overscan={overscan}\n isResizable={isResizable}\n onColumnResize={handleColumnResize}\n onColumnResizeEnd={handleColumnResizeEnd}\n getRowProps={getRowProps}\n ariaLabel={ariaLabel}\n styles={rootStyles}\n headerStyles={headerStyles}\n headerCellStyles={headerCellStyles}\n bodyStyles={bodyStyles}\n rowStyles={rowStyles}\n cellStyles={cellStyles}\n mods={mods}\n footer={\n hasFooter ? (\n <ItemTableFooter\n start={footerStart}\n center={footerCenter}\n end={footerEnd}\n styles={footerStyles}\n pagination={\n showPagination\n ? {\n page: pageInfo.page,\n pageSize,\n total,\n totalPages: pageInfo.totalPages,\n pageSizeOptions,\n summary,\n hasNextPage,\n onPageChange: setPage,\n onPageSizeChange: setPageSize,\n }\n : undefined\n }\n />\n ) : null\n }\n />\n );\n}\n\nconst _DataTable = forwardRef(DataTable) as unknown as (<T = any>(\n props: CubeDataTableProps<T> & { ref?: ForwardedRef<HTMLDivElement> },\n) => ReactElement) & { displayName?: string };\n\n_DataTable.displayName = 'DataTable';\n\nexport { _DataTable as DataTable };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DataTable.js","names":[],"sources":["../../../../src/components/data/DataTable/DataTable.tsx"],"sourcesContent":["import { SelectionManager } from '@react-stately/selection';\nimport { useControlledState } from '@react-stately/utils';\nimport { CONTAINER_STYLES } from '@tenphi/tasty';\nimport { forwardRef, useMemo, useRef, useState } from 'react';\nimport { useMultipleSelectionState } from 'react-stately';\n\nimport { useEvent } from '../../../_internal/hooks';\nimport { useI18n } from '../../../i18n';\nimport { useCombinedRefs } from '../../../utils/react';\nimport { extractStyles } from '../../../utils/styles';\nimport { clampPage, getPageInfo } from '../../navigation/Pagination';\nimport { DraggableCollection } from '../../shared/DraggableCollection';\nimport { ItemTableFooter } from '../ItemTable/ItemTableFooter';\nimport { RowCollection } from '../TableBase/RowCollection';\nimport { TableView } from '../TableBase/TableView';\nimport { selectionRowKey } from '../TableBase/types';\nimport { useCellSelection } from '../TableBase/use-cell-selection';\nimport {\n getDraggableColumnKeys,\n isColumnDraggable,\n useColumnOrder,\n} from '../TableBase/use-column-order';\nimport { useContainerWidth } from '../TableBase/use-container-width';\nimport {\n freezeColumnWidths,\n useTableColumns,\n} from '../TableBase/use-table-columns';\nimport { ROW_NUMBER_COLUMN_KEY } from '../TableBase/use-table-selection';\nimport { useTableSorts } from '../TableBase/use-table-sorts';\nimport { useTableStorage } from '../TableBase/use-table-storage';\n\nimport type { Key } from '@react-types/shared';\nimport type { ForwardedRef, ReactElement } from 'react';\nimport type {\n CubeTableColumnLayout,\n CubeTableRowSection,\n} from '../TableBase/types';\nimport type { CubeDataTableColumn, CubeDataTableProps } from './types';\n\n/** Wide enough for five digits at the dense default. */\nconst ROW_NUMBER_WIDTH = 56;\n\nconst EMPTY_WIDTHS: Record<string, number> = {};\n\nfunction defaultGetRowKey<T>(rowKey: string) {\n return (row: T, index: number): Key => {\n const value = (row as any)?.[rowKey];\n\n return value == null ? index : (value as Key);\n };\n}\n\n/**\n * A grid for query results.\n *\n * The same engine as `ItemTable` — one `TableView`, one column layout, one\n * value pipeline — with the defaults an analytical grid wants rather than a\n * list's: denser type, banded rows, resizable columns, multi-column sort, and\n * rows pinned for totals.\n *\n * It knows nothing about Cube. Measures, dimensions, pivots and drill-downs\n * reach it as ordinary columns, `render` output and `column.header.menu`\n * content, which is what keeps the ~34 kB of Cloud's column-header menu in\n * Cloud.\n */\nfunction DataTable<T = any>(\n props: CubeDataTableProps<T>,\n ref: ForwardedRef<HTMLDivElement>,\n) {\n const {\n data,\n columns,\n rowKey = 'id',\n getRowKey,\n pinnedTopRows,\n pinnedBottomRows,\n isLoading = false,\n loadingIndicator = 'overlay',\n skeletonRowCount,\n error,\n emptyLabel,\n noResultsLabel,\n isFiltered,\n shape = 'plain',\n // Denser than `ItemTable`'s `medium`: a result grid is read as a block, and\n // more rows on screen is the point of it.\n size = 'small',\n rowSize,\n rowHeight,\n headerHeight,\n isStriped = true,\n isHeaderHidden,\n isHeaderSticky,\n showRowNumbers = false,\n sortMode,\n sorts: sortsProp,\n defaultSorts,\n onSortsChange,\n paginationMode = 'client',\n page: pageProp,\n defaultPage,\n onPageChange,\n pageSize: pageSizeProp,\n defaultPageSize = 100,\n onPageSizeChange,\n pageSizeOptions,\n total: totalProp,\n totalPages,\n hasNextPage,\n summary = true,\n autoHidePagination = true,\n footerStart,\n footerCenter,\n footerEnd,\n cellSelectionMode = 'range',\n isCellSelectable,\n selectedCellRange,\n defaultSelectedCellRange,\n onCellRangeChange,\n isRowMoveAnimated,\n isResizable = true,\n columnWidths: columnWidthsProp,\n defaultColumnWidths,\n onColumnResize,\n isColumnReorderable = false,\n columnOrder,\n defaultColumnOrder,\n onColumnOrderChange,\n columnContextMenu,\n onColumnMenuAction,\n columnMenuTriggerProps,\n columnMenuProps,\n isVirtualized,\n virtualizeThreshold,\n overscan,\n getRowProps,\n storageKey,\n styles,\n headerStyles,\n headerCellStyles,\n bodyStyles,\n rowStyles,\n cellStyles,\n footerStyles,\n ariaLabel,\n qa,\n mods,\n ...rest\n } = props;\n\n const localRef = useRef<HTMLDivElement>(null);\n const rootRef = useCombinedRefs(ref, localRef);\n const [scrollerEl, setScrollerEl] = useState<HTMLElement | null>(null);\n const containerWidth = useContainerWidth(scrollerEl);\n\n const storage = useTableStorage(storageKey);\n\n /**\n * `dataType` is presentational, so it is folded into the column here rather\n * than reaching the renderer: `number` right-aligns and takes tabular figures\n * so digits line up down the column.\n */\n const resolvedColumns = useMemo(\n () =>\n columns.map((column) => {\n const isNumeric = column.dataType === 'number';\n\n return {\n ...column,\n align: column.align ?? (isNumeric ? 'end' : 'start'),\n cellStyles: isNumeric\n ? {\n fontVariantNumeric: 'tabular-nums',\n ...(typeof column.cellStyles === 'object'\n ? column.cellStyles\n : null),\n }\n : column.cellStyles,\n } as CubeDataTableColumn<T>;\n }),\n [columns],\n );\n\n // Applied to the SOURCE columns, before `useTableColumns`, so hidden-column\n // filtering, structural injection and pinned hoisting all still happen\n // downstream and `columnOrder` can never fight `pin`.\n const columnOrderState = useColumnOrder<T>({\n columns: resolvedColumns,\n columnOrder,\n defaultColumnOrder,\n onColumnOrderChange,\n storage,\n });\n const orderedColumns = columnOrderState.columns;\n\n const {\n sorts,\n sortedRows,\n toggleSort,\n setColumnSort,\n mode: resolvedSortMode,\n } = useTableSorts<T>({\n columns: orderedColumns,\n rows: data,\n mode: sortMode,\n sorts: sortsProp,\n defaultSorts,\n onSortsChange,\n });\n\n const [pageSize, setPageSizeState] = useControlledState<number>(\n pageSizeProp as number,\n (pageSizeProp === undefined && storage.has('pageSize')\n ? storage.initial.pageSize ?? defaultPageSize\n : defaultPageSize) as number,\n onPageSizeChange as (value: number) => void,\n );\n const [page, setPageState] = useControlledState<number>(\n pageProp as number,\n defaultPage ?? 1,\n onPageChange as (value: number) => void,\n );\n\n const isPaginated = paginationMode !== 'off';\n const isServerPaginated = paginationMode === 'server';\n const total = isServerPaginated ? totalProp ?? 0 : sortedRows.length;\n\n const pageInfo = getPageInfo({\n page,\n pageSize,\n total,\n totalPages: isServerPaginated ? totalPages : undefined,\n });\n\n const setPage = useEvent((next: number) =>\n setPageState(clampPage(next, pageInfo.totalPages)),\n );\n const setPageSize = useEvent((next: number) => {\n setPageSizeState(next);\n setPageState(1);\n\n if (pageSizeProp === undefined) storage.write({ pageSize: next });\n });\n\n const visibleRows =\n paginationMode === 'client'\n ? sortedRows.slice(\n (pageInfo.page - 1) * pageSize,\n pageInfo.page * pageSize,\n )\n : sortedRows;\n\n const [ownColumnWidths, setOwnColumnWidths] = useState<\n Record<string, number>\n >(\n () =>\n (columnWidthsProp === undefined && storage.has('columnWidths')\n ? storage.initial.columnWidths ?? defaultColumnWidths\n : defaultColumnWidths) ?? EMPTY_WIDTHS,\n );\n const [draftColumnWidths, setDraftColumnWidths] = useState<Record<\n string,\n number\n > | null>(null);\n const draftRef = useRef<Record<string, number> | null>(null);\n\n const baseColumnWidths = columnWidthsProp ?? ownColumnWidths;\n const columnWidths = draftColumnWidths ?? baseColumnWidths;\n\n /**\n * The resolved widths, for the freeze below. A ref because `layout` is\n * computed *after* this handler is defined, and `useEvent` only reads it when\n * the drag actually runs.\n */\n const layoutRef = useRef<CubeTableColumnLayout<T> | null>(null);\n\n const handleColumnResize = useEvent((key: string, width: number) => {\n // First move of a drag freezes every column, so this changes exactly one\n // width instead of re-splitting the flex pool. See `freezeColumnWidths`.\n const base =\n draftRef.current ??\n freezeColumnWidths(layoutRef.current, baseColumnWidths);\n\n draftRef.current = { ...base, [key]: Math.round(width) };\n setDraftColumnWidths(draftRef.current);\n });\n\n const handleColumnResizeEnd = useEvent((key: string) => {\n const next = draftRef.current ?? baseColumnWidths;\n\n if (columnWidthsProp === undefined) {\n setOwnColumnWidths(next);\n storage.write({ columnWidths: next });\n }\n\n onColumnResize?.(key, next[key], next);\n draftRef.current = null;\n setDraftColumnWidths(null);\n });\n\n const leadingColumns = useMemo(\n () =>\n showRowNumbers\n ? [{ key: ROW_NUMBER_COLUMN_KEY, width: ROW_NUMBER_WIDTH }]\n : undefined,\n [showRowNumbers],\n );\n\n const layout = useTableColumns<T>({\n columns: orderedColumns,\n containerWidth,\n columnWidths,\n leadingColumns,\n });\n\n layoutRef.current = layout;\n\n const { t } = useI18n();\n\n const resolvedGetRowKey = useMemo(\n () => getRowKey ?? defaultGetRowKey<T>(rowKey),\n [getRowKey, rowKey],\n );\n\n // Every row a range can reach, in the order they appear on screen. Pinned rows\n // are in it: a total is a figure like any other, and having to copy it\n // separately from the column it sums is the wrong trade.\n //\n // The keys are built here rather than inside the hook so they cannot disagree\n // with the ones the renderer stamps — a pinned row is keyed by its own index\n // within its group, exactly as `renderPinnedRow` keys it.\n const selectionRows = useMemo(\n () => [\n ...(pinnedTopRows ?? []),\n ...visibleRows,\n ...(pinnedBottomRows ?? []),\n ],\n [pinnedTopRows, visibleRows, pinnedBottomRows],\n );\n const selectionRowKeys = useMemo(\n () => [\n // Section-qualified, matching what the renderer stamps: the same record\n // is routinely pinned at both edges, and one flat key space collapsed the\n // two into whichever came first.\n ...(pinnedTopRows ?? []).map((row, index) =>\n selectionRowKey('pinnedTop', resolvedGetRowKey(row, index)),\n ),\n ...visibleRows.map(resolvedGetRowKey),\n ...(pinnedBottomRows ?? []).map((row, index) =>\n selectionRowKey('pinnedBottom', resolvedGetRowKey(row, index)),\n ),\n ],\n [pinnedTopRows, visibleRows, pinnedBottomRows, resolvedGetRowKey],\n );\n\n // The hook works in one flat row order; the section a row belongs to is a\n // property of where it sits in that order, so it is resolved here rather than\n // asking the consumer to track it.\n const resolveCellSelectable = useEvent(\n (row: T, rowKey: Key, columnKey: string) => {\n if (!isCellSelectable) return true;\n\n const index = selectionRowKeys.indexOf(rowKey);\n const topCount = pinnedTopRows?.length ?? 0;\n const section: CubeTableRowSection =\n index < topCount\n ? 'pinnedTop'\n : index < topCount + visibleRows.length\n ? 'body'\n : 'pinnedBottom';\n\n return isCellSelectable({ row, rowKey, columnKey, section });\n },\n );\n\n const cellSelection = useCellSelection<T>({\n mode: cellSelectionMode,\n columns: layout.columns,\n rows: selectionRows,\n rowKeys: selectionRowKeys,\n isCellSelectable: isCellSelectable ? resolveCellSelectable : undefined,\n range: selectedCellRange,\n defaultRange: defaultSelectedCellRange,\n onRangeChange: onCellRangeChange,\n });\n\n // Same as `ItemTable`: style props (`height`, `maxHeight`, `margin`, …) land\n // on the root frame. `height` is the one that matters — there is no\n // page-scroll mode, so bounding the grid is what turns the body into a\n // scroller, pins the header, and lets virtualization engage at all.\n const rootStyles = { ...extractStyles(props, CONTAINER_STYLES), ...styles };\n\n const smallestPageSize = pageSizeOptions?.length\n ? Math.min(...pageSizeOptions)\n : pageSize;\n\n const showPagination =\n isPaginated &&\n !(\n autoHidePagination &&\n !hasNextPage &&\n pageInfo.totalPages <= 1 &&\n total <= smallestPageSize\n );\n\n const hasFooter =\n showPagination ||\n footerStart != null ||\n footerCenter != null ||\n footerEnd != null;\n\n /* ── column reordering ────────────────────────────────────────────────── */\n\n const headRowRef = useRef<HTMLTableRowElement>(null);\n const draggableColumnKeys = useMemo(\n () => getDraggableColumnKeys(layout.columns, isColumnReorderable),\n [layout.columns, isColumnReorderable],\n );\n const columnCollection = useMemo(\n () =>\n new RowCollection(\n layout.columns.filter((column) =>\n isColumnDraggable(column, isColumnReorderable),\n ),\n (column) => column.key,\n new Set(),\n // The drag announcements read this — otherwise a screen reader hears\n // \"Insert between and \".\n (column) =>\n typeof column.title === 'string' ? column.title : column.key,\n ),\n [layout.columns, isColumnReorderable],\n );\n /**\n * `'single'`, not `'none'`.\n *\n * `useDraggableItem` only deletes its own `onClick` — the one that would\n * hijack a screen-reader click away from the sort — when the selection mode is\n * not `'none'`, and only then does it attach the keyboard drag description.\n * Nothing is ever actually selected here.\n */\n const columnSelectionState = useMultipleSelectionState({\n selectionMode: 'single',\n disabledBehavior: 'all',\n });\n const columnSelectionManager = useMemo(\n () => new SelectionManager(columnCollection, columnSelectionState),\n [columnCollection, columnSelectionState],\n );\n const handleColumnFocus = useEvent((columnKey: string | null) => {\n columnSelectionManager.setFocusedKey(columnKey);\n });\n\n // One draggable column cannot be reordered, so the machinery stays unmounted\n // and the header keeps its exact DOM.\n const isColumnDragEnabled =\n isColumnReorderable && draggableColumnKeys.length > 1;\n\n const renderTable = (\n columnDragState?: any,\n columnDropState?: any,\n headCollectionProps?: Record<string, any>,\n ) => (\n <TableView<T>\n {...rest}\n rootRef={rootRef}\n qa={qa || 'DataTable'}\n rows={visibleRows}\n pinnedTopRows={pinnedTopRows}\n pinnedBottomRows={pinnedBottomRows}\n // Continuous across pages: row 101 is row 101, not row 1 of page two.\n //\n // Server mode counts too — the page and its size are known there just the\n // same, and `rows` is that page. Only `'off'` starts at 1, because then\n // there is no page to be on.\n rowNumberOffset={\n paginationMode === 'off' ? 0 : (pageInfo.page - 1) * pageSize\n }\n // The same offset drives `aria-rowindex`, which is document-absolute by\n // contract — a screen reader on page 3 should hear \"row 51 of 240\", not\n // \"row 1 of 25\".\n rowIndexOffset={\n paginationMode === 'off' ? 0 : (pageInfo.page - 1) * pageSize\n }\n totalRowCount={total}\n layout={layout}\n // Always on, unlike `ItemTable`. A result grid is read down a column, and\n // once the values are wide and right-aligned the rule is what keeps a\n // figure attached to its column — which is why Cloud's ag-grid theme sets\n // `columnBorder` for `DataTable` and not for the list grids.\n hasColumnDividers\n cellSelection={cellSelection}\n getRowKey={resolvedGetRowKey}\n onScrollerRef={setScrollerEl}\n isLoading={isLoading}\n loadingIndicator={loadingIndicator}\n skeletonRowCount={skeletonRowCount}\n error={error}\n // Same localized fallbacks as `ItemTable`: a grid that has finished\n // loading and shows an unexplained blank rectangle reads as broken.\n emptyLabel={emptyLabel ?? t('itemTable.noItems', 'No items')}\n noResultsLabel={\n noResultsLabel ?? t('itemTable.noResults', 'No results found')\n }\n isFiltered={isFiltered}\n shape={shape}\n size={size}\n rowSize={rowSize}\n rowHeight={rowHeight}\n headerHeight={headerHeight}\n isStriped={isStriped}\n isRowMoveAnimated={isRowMoveAnimated}\n isHeaderHidden={isHeaderHidden}\n isHeaderSticky={isHeaderSticky}\n // The header shows the column name at body size — a result grid has no\n // room for the uppercase caption a list header uses.\n // `t4` throughout: a result grid is read as a block, and one step down\n // from the list preset fits noticeably more on screen without losing\n // legibility. The header takes the medium weight of the same step.\n contentPreset=\"t4\"\n headerPreset=\"t4m\"\n sortMode={resolvedSortMode}\n sorts={sorts}\n onColumnSort={toggleSort}\n onColumnSortChange={setColumnSort}\n columnContextMenu={columnContextMenu}\n onColumnMenuAction={onColumnMenuAction}\n columnMenuTriggerProps={columnMenuTriggerProps}\n columnMenuProps={columnMenuProps}\n isVirtualized={isVirtualized}\n virtualizeThreshold={virtualizeThreshold}\n overscan={overscan}\n isResizable={isResizable}\n onColumnResize={handleColumnResize}\n onColumnResizeEnd={handleColumnResizeEnd}\n getRowProps={getRowProps}\n ariaLabel={ariaLabel}\n styles={rootStyles}\n headerStyles={headerStyles}\n headerCellStyles={headerCellStyles}\n bodyStyles={bodyStyles}\n rowStyles={rowStyles}\n cellStyles={cellStyles}\n mods={mods}\n isColumnReorderable={isColumnDragEnabled}\n columnDragState={columnDragState}\n columnDropState={columnDropState}\n headCollectionProps={headCollectionProps}\n headRowRef={headRowRef}\n onColumnFocus={handleColumnFocus}\n footer={\n hasFooter ? (\n <ItemTableFooter\n start={footerStart}\n center={footerCenter}\n end={footerEnd}\n styles={footerStyles}\n pagination={\n showPagination\n ? {\n page: pageInfo.page,\n pageSize,\n total,\n totalPages: pageInfo.totalPages,\n pageSizeOptions,\n summary,\n hasNextPage,\n onPageChange: setPage,\n onPageSizeChange: setPageSize,\n }\n : undefined\n }\n />\n ) : null\n }\n />\n );\n\n return isColumnDragEnabled ? (\n <DraggableCollection\n state={{\n collection: columnCollection as any,\n selectionManager: columnSelectionManager as any,\n disabledKeys: new Set(),\n }}\n // The element that DIRECTLY contains the header cells. React Aria's\n // `ListDropTargetDelegate` resolves a drop by measuring `[data-key]`\n // descendants of this element, so pointing it anywhere else leaves every\n // drop unresolvable — the column lifts but never lands.\n listRef={headRowRef}\n orderedKeys={draggableColumnKeys}\n orientation=\"horizontal\"\n onReorder={columnOrderState.reorder}\n >\n {(dragState, dropState, collectionProps) =>\n renderTable(dragState, dropState, collectionProps)\n }\n </DraggableCollection>\n ) : (\n renderTable()\n );\n}\n\nconst _DataTable = forwardRef(DataTable) as unknown as (<T = any>(\n props: CubeDataTableProps<T> & { ref?: ForwardedRef<HTMLDivElement> },\n) => ReactElement) & { displayName?: string };\n\n_DataTable.displayName = 'DataTable';\n\nexport { _DataTable as DataTable };\n"],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import { SizeName } from "../../../tokens/sizes.js";
|
|
|
3
3
|
import { CubeTablePageInfo } from "../../navigation/Pagination/types.js";
|
|
4
4
|
import "../../navigation/Pagination/index.js";
|
|
5
5
|
import "../../../tokens/index.js";
|
|
6
|
-
import { CubeTableCellRange, CubeTableColumn, CubeTableLoadingIndicator, CubeTableRowContext, CubeTableRowSection, CubeTableSort } from "../TableBase/types.js";
|
|
6
|
+
import { CubeTableCellRange, CubeTableColumn, CubeTableLoadingIndicator, CubeTableRowContext, CubeTableRowSection, CubeTableRowSize, CubeTableSort } from "../TableBase/types.js";
|
|
7
7
|
import { BaseProps, ContainerStyleProps, Styles } from "@tenphi/tasty";
|
|
8
8
|
import { ReactNode } from "react";
|
|
9
9
|
import { Key as Key$1 } from "@react-types/shared";
|
|
@@ -46,6 +46,18 @@ interface CubeDataTableProps<T = any> extends BaseProps, ContainerStyleProps {
|
|
|
46
46
|
shape?: 'plain' | 'card';
|
|
47
47
|
/** @default 'small' — an analytical grid packs more rows than a list. */
|
|
48
48
|
size?: SizeName;
|
|
49
|
+
/**
|
|
50
|
+
* Row height as a named step: `small` 28px, `medium` 32px, `large` 40px.
|
|
51
|
+
*
|
|
52
|
+
* Only the rows — the header keeps whatever `size` gives it, so a denser body
|
|
53
|
+
* does not drag the header down with it. `rowHeight` wins when both are set.
|
|
54
|
+
*
|
|
55
|
+
* Unset, the row height comes from `size` as before, which at this table's
|
|
56
|
+
* default (`size="small"`) is the same 32px `medium` gives. They diverge only
|
|
57
|
+
* if you also move `size`: `size="large"` alone is 48px rows.
|
|
58
|
+
*/
|
|
59
|
+
rowSize?: CubeTableRowSize;
|
|
60
|
+
/** An exact height in px, when none of the named steps is the answer. */
|
|
49
61
|
rowHeight?: number;
|
|
50
62
|
headerHeight?: number;
|
|
51
63
|
/** @default true — banding is what makes a wide row readable across. */
|
|
@@ -124,6 +136,49 @@ interface CubeDataTableProps<T = any> extends BaseProps, ContainerStyleProps {
|
|
|
124
136
|
columnWidths?: Record<string, number>;
|
|
125
137
|
defaultColumnWidths?: Record<string, number>;
|
|
126
138
|
onColumnResize?: (columnKey: string, width: number, all: Record<string, number>) => void;
|
|
139
|
+
/**
|
|
140
|
+
* Drag column headers sideways to reorder them.
|
|
141
|
+
*
|
|
142
|
+
* Named for the axis: `ItemTable`'s `isReorderable` already means ROW
|
|
143
|
+
* reordering, and the two are different features.
|
|
144
|
+
*
|
|
145
|
+
* Structural and pinned columns stay put. `pin` is already the ordering
|
|
146
|
+
* authority for a pinned column, and a sticky `<th>` cannot be hit-tested
|
|
147
|
+
* reliably under horizontal scroll.
|
|
148
|
+
*
|
|
149
|
+
* @default false
|
|
150
|
+
*/
|
|
151
|
+
isColumnReorderable?: boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Controlled order, as column keys. Works with or without dragging, so a
|
|
154
|
+
* column manager elsewhere in the page can drive it on its own.
|
|
155
|
+
*
|
|
156
|
+
* Stale keys are ignored, and a column missing from the list lands after the
|
|
157
|
+
* neighbour it had in `columns` rather than at the end.
|
|
158
|
+
*/
|
|
159
|
+
columnOrder?: string[];
|
|
160
|
+
defaultColumnOrder?: string[];
|
|
161
|
+
/** The FULL key list, including hidden and pinned columns. */
|
|
162
|
+
onColumnOrderChange?: (order: string[]) => void;
|
|
163
|
+
/**
|
|
164
|
+
* Where a column's `header.menu` is exposed.
|
|
165
|
+
*
|
|
166
|
+
* - `true` — a `⋮` trigger in the header, plus right-click and Shift+F10.
|
|
167
|
+
* - `'context-only'` — right-click and Shift+F10 only, no trigger.
|
|
168
|
+
* - `false` — suppressed entirely.
|
|
169
|
+
*
|
|
170
|
+
* @default true
|
|
171
|
+
*/
|
|
172
|
+
columnContextMenu?: boolean | 'context-only';
|
|
173
|
+
/**
|
|
174
|
+
* The key of the pressed `Menu.Item`, as written — no `.$` prefix.
|
|
175
|
+
*
|
|
176
|
+
* Fires for the reserved sort keys too (`sort-asc`, `sort-desc`,
|
|
177
|
+
* `clear-sort`), after the table has already applied them.
|
|
178
|
+
*/
|
|
179
|
+
onColumnMenuAction?: (action: string, columnKey: string) => void;
|
|
180
|
+
columnMenuTriggerProps?: Record<string, any>;
|
|
181
|
+
columnMenuProps?: Record<string, any>;
|
|
127
182
|
isVirtualized?: boolean | 'auto';
|
|
128
183
|
virtualizeThreshold?: number;
|
|
129
184
|
overscan?: number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.159.0 | Cube Dev Team */
|
|
2
2
|
import { extractStyles } from "../../../utils/styles.js";
|
|
3
3
|
import { useCombinedRefs } from "../../../utils/react/useCombinedRefs.js";
|
|
4
4
|
import { useEvent } from "../../../_internal/hooks/use-event.js";
|
|
@@ -7,7 +7,7 @@ import { DraggableCollection } from "../../shared/DraggableCollection.js";
|
|
|
7
7
|
import { clampPage, getPageInfo } from "../../navigation/Pagination/use-pagination.js";
|
|
8
8
|
import { ItemTableFooter } from "./ItemTableFooter.js";
|
|
9
9
|
import { ROW_MENU_COLUMN_KEY, ROW_MENU_COLUMN_WIDTH } from "../TableBase/row-menu.js";
|
|
10
|
-
import { useTableColumns } from "../TableBase/use-table-columns.js";
|
|
10
|
+
import { freezeColumnWidths, useTableColumns } from "../TableBase/use-table-columns.js";
|
|
11
11
|
import { SELECTION_COLUMN_KEY, SELECTION_COLUMN_WIDTH, useTableSelection } from "../TableBase/use-table-selection.js";
|
|
12
12
|
import { TableView } from "../TableBase/TableView.js";
|
|
13
13
|
import { useContainerWidth } from "../TableBase/use-container-width.js";
|
|
@@ -32,7 +32,7 @@ function defaultGetRowKey(rowKey) {
|
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
function ItemTable(props, ref) {
|
|
35
|
-
const { data, columns, rowKey = "id", getRowKey, isLoading = false, loadingIndicator = "overlay", selectionMode, bulkActions, rowLink, onRowAction, rowMenu, rowContextMenu = false, onRowMenuAction, rowMenuTriggerProps, bulkBarPlacement = "floating", bulkBarStyles, selectedKeys: selectedKeysProp, defaultSelectedKeys, onSelectionChange, selectAllMode = "page", isRowSelectable, selectionTooltip, disabledKeys, skeletonRowCount = 6, emptyLabel, noResultsLabel, error, isFiltered, toolbar, isSearchable = false, searchMode = "client", searchPlaceholder, searchValue: searchValueProp, defaultSearchValue, onSearchChange, searchDelay = 500, searchFilter, filters, actions, onRefresh, paginationMode = "client", pageSize: pageSizeProp, defaultPageSize = 50, autoHidePagination = true, onLoadMore, hasMore, isLoadingMore, loadMoreMargin, storageKey, persist, isReorderable = false, onReorder, dropOnRow, getItemDragInfo, isResizable = false, columnWidths: columnWidthsProp, defaultColumnWidths, onColumnResize, onPageSizeChange, pageSizeOptions = [
|
|
35
|
+
const { data, columns, rowKey = "id", getRowKey, isLoading = false, loadingIndicator = "overlay", selectionMode, bulkActions, rowLink, onRowAction, rowMenu, rowContextMenu = false, onRowMenuAction, rowMenuTriggerProps, bulkBarPlacement = "floating", bulkBarStyles, selectedKeys: selectedKeysProp, defaultSelectedKeys, onSelectionChange, selectAllMode = "page", isRowSelectable, selectionTooltip, disabledKeys, skeletonRowCount = 6, emptyLabel, noResultsLabel, error, isFiltered, toolbar, isSearchable = false, searchMode = "client", searchPlaceholder, searchValue: searchValueProp, defaultSearchValue, onSearchChange, searchDelay = 500, searchFilter, filters, actions, onRefresh, paginationMode = "client", pageSize: pageSizeProp, defaultPageSize = 50, autoHidePagination = true, onLoadMore, hasMore, isLoadingMore, loadMoreMargin, storageKey, persist, isReorderable = false, onReorder, dropOnRow, getItemDragInfo, isResizable = false, columnWidths: columnWidthsProp, defaultColumnWidths, onColumnResize, columnContextMenu, onColumnMenuAction, columnMenuTriggerProps, columnMenuProps, onPageSizeChange, pageSizeOptions = [
|
|
36
36
|
10,
|
|
37
37
|
20,
|
|
38
38
|
50,
|
|
@@ -58,7 +58,7 @@ function ItemTable(props, ref) {
|
|
|
58
58
|
filter: searchFilter
|
|
59
59
|
});
|
|
60
60
|
const storage = useTableStorage(storageKey, persist);
|
|
61
|
-
const { sort, sortedRows, toggleSort, mode: resolvedSortMode } = useTableSort({
|
|
61
|
+
const { sort, sortedRows, toggleSort, setColumnSort, mode: resolvedSortMode } = useTableSort({
|
|
62
62
|
columns,
|
|
63
63
|
rows: searchedRows,
|
|
64
64
|
mode: sortMode,
|
|
@@ -138,9 +138,11 @@ function ItemTable(props, ref) {
|
|
|
138
138
|
const draftColumnWidthsRef = useRef(null);
|
|
139
139
|
const baseColumnWidths = columnWidthsProp ?? ownColumnWidths;
|
|
140
140
|
const columnWidths = draftColumnWidths ?? baseColumnWidths;
|
|
141
|
+
/** `layout` is computed below; `useEvent` only reads this when a drag runs. */
|
|
142
|
+
const layoutRef = useRef(null);
|
|
141
143
|
const handleColumnResize = useEvent((key, width) => {
|
|
142
144
|
draftColumnWidthsRef.current = {
|
|
143
|
-
...draftColumnWidthsRef.current ?? baseColumnWidths,
|
|
145
|
+
...draftColumnWidthsRef.current ?? freezeColumnWidths(layoutRef.current, baseColumnWidths),
|
|
144
146
|
[key]: Math.round(width)
|
|
145
147
|
};
|
|
146
148
|
setDraftColumnWidths(draftColumnWidthsRef.current);
|
|
@@ -162,6 +164,7 @@ function ItemTable(props, ref) {
|
|
|
162
164
|
leadingColumns,
|
|
163
165
|
trailingColumns
|
|
164
166
|
});
|
|
167
|
+
layoutRef.current = layout;
|
|
165
168
|
const bulkBar = bulkActions != null && bulkActions.length > 0 && selection.selectedCount > 0 ? /* @__PURE__ */ jsx(ItemTableBulkBar, {
|
|
166
169
|
actions: bulkActions,
|
|
167
170
|
placement: bulkBarPlacement,
|
|
@@ -273,6 +276,11 @@ function ItemTable(props, ref) {
|
|
|
273
276
|
sortMode: resolvedSortMode,
|
|
274
277
|
sort,
|
|
275
278
|
onColumnSort: toggleSort,
|
|
279
|
+
onColumnSortChange: setColumnSort,
|
|
280
|
+
columnContextMenu,
|
|
281
|
+
onColumnMenuAction,
|
|
282
|
+
columnMenuTriggerProps,
|
|
283
|
+
columnMenuProps,
|
|
276
284
|
getRowProps,
|
|
277
285
|
ariaLabel,
|
|
278
286
|
styles: rootStyles,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ItemTable.js","names":[],"sources":["../../../../src/components/data/ItemTable/ItemTable.tsx"],"sourcesContent":["import { useControlledState } from '@react-stately/utils';\nimport { CONTAINER_STYLES } from '@tenphi/tasty';\nimport { forwardRef, useMemo, useRef, useState } from 'react';\n\nimport { useEvent } from '../../../_internal/hooks';\nimport { useI18n } from '../../../i18n';\nimport { useCombinedRefs } from '../../../utils/react';\nimport { extractStyles } from '../../../utils/styles';\nimport { clampPage, getPageInfo } from '../../navigation/Pagination';\nimport { DraggableCollection } from '../../shared/DraggableCollection';\nimport {\n ROW_MENU_COLUMN_KEY,\n ROW_MENU_COLUMN_WIDTH,\n} from '../TableBase/row-menu';\nimport { TableView } from '../TableBase/TableView';\nimport { useContainerWidth } from '../TableBase/use-container-width';\nimport { useTableColumns } from '../TableBase/use-table-columns';\nimport { useTableSearch } from '../TableBase/use-table-search';\nimport {\n SELECTION_COLUMN_KEY,\n SELECTION_COLUMN_WIDTH,\n useTableSelection,\n} from '../TableBase/use-table-selection';\nimport { useTableSort } from '../TableBase/use-table-sort';\nimport { useTableStorage } from '../TableBase/use-table-storage';\n\nimport { ItemTableBulkBar } from './ItemTableBulkBar';\nimport { ItemTableDragPreview } from './ItemTableDragPreview';\nimport { ItemTableFooter } from './ItemTableFooter';\nimport {\n ItemTableChromeProvider,\n ItemTableSearch,\n ItemTableToolbar,\n} from './ItemTableToolbar';\n\nimport type { Key } from '@react-types/shared';\nimport type { ForwardedRef, ReactElement, ReactNode } from 'react';\nimport type { CubeTableRowContext, CubeTableSort } from '../TableBase/types';\nimport type { CubeItemTableProps } from './types';\n\n/** Stable identity, so the uncontrolled default does not change every render. */\nconst EMPTY_WIDTHS: Record<string, number> = {};\n\nfunction defaultGetRowKey<T>(rowKey: string) {\n return (row: T, index: number): Key => {\n const value = (row as any)?.[rowKey];\n\n return value == null ? index : (value as Key);\n };\n}\n\nfunction ItemTable<T = any>(\n props: CubeItemTableProps<T>,\n ref: ForwardedRef<HTMLDivElement>,\n): ReactElement {\n const {\n data,\n columns,\n rowKey = 'id',\n getRowKey,\n isLoading = false,\n loadingIndicator = 'overlay',\n selectionMode,\n bulkActions,\n rowLink,\n onRowAction,\n rowMenu,\n rowContextMenu = false,\n onRowMenuAction,\n rowMenuTriggerProps,\n bulkBarPlacement = 'floating',\n bulkBarStyles,\n selectedKeys: selectedKeysProp,\n defaultSelectedKeys,\n onSelectionChange,\n selectAllMode = 'page',\n isRowSelectable,\n selectionTooltip,\n disabledKeys,\n skeletonRowCount = 6,\n emptyLabel,\n noResultsLabel,\n error,\n isFiltered,\n toolbar,\n isSearchable = false,\n searchMode = 'client',\n searchPlaceholder,\n searchValue: searchValueProp,\n defaultSearchValue,\n onSearchChange,\n searchDelay = 500,\n searchFilter,\n filters,\n actions,\n onRefresh,\n paginationMode = 'client',\n pageSize: pageSizeProp,\n defaultPageSize = 50,\n autoHidePagination = true,\n onLoadMore,\n hasMore,\n isLoadingMore,\n loadMoreMargin,\n storageKey,\n persist,\n isReorderable = false,\n onReorder,\n dropOnRow,\n getItemDragInfo,\n isResizable = false,\n columnWidths: columnWidthsProp,\n defaultColumnWidths,\n onColumnResize,\n onPageSizeChange,\n pageSizeOptions = [10, 20, 50, 100, 500],\n page: pageProp,\n defaultPage,\n onPageChange,\n total: totalProp,\n totalPages,\n hasNextPage,\n summary = true,\n footer,\n footerStart,\n footerCenter,\n footerEnd,\n sortMode,\n sort: sortProp,\n defaultSort,\n onSortChange,\n shape = 'plain',\n size = 'medium',\n rowHeight,\n headerHeight,\n isStriped = false,\n isHeaderHidden = false,\n isHeaderSticky = true,\n isVirtualized = 'auto',\n virtualizeThreshold = 50,\n overscan = 20,\n getRowProps,\n ariaLabel,\n qa,\n mods,\n styles,\n headerStyles,\n headerCellStyles,\n headerPreset = 'c3',\n toolbarStyles,\n searchStyles,\n footerStyles,\n bodyStyles,\n rowStyles,\n cellStyles,\n isRowMoveAnimated,\n } = props;\n\n const { t } = useI18n();\n\n const localRef = useRef<HTMLDivElement>(null);\n const rootRef = useCombinedRefs(ref, localRef);\n\n // Held in state, not a ref: the virtualized path's scroller is created by\n // Virtuoso and arrives through a callback, and the column layout has to\n // re-derive once it does.\n const [scrollerEl, setScrollerEl] = useState<HTMLDivElement | null>(null);\n const containerWidth = useContainerWidth(scrollerEl);\n\n // Style props (`height`, `maxHeight`, `margin`, …) land on the root frame.\n // `height` matters most: there is no page-scroll mode, so bounding the table\n // is what turns the body into a scroller and pins the header.\n const rootStyles = { ...extractStyles(props, CONTAINER_STYLES), ...styles };\n\n const {\n searchValue,\n setSearchValue,\n searchedRows,\n isFiltered: isSearching,\n } = useTableSearch<T>({\n columns,\n rows: data,\n mode: searchMode,\n value: searchValueProp,\n defaultValue: defaultSearchValue,\n onChange: onSearchChange,\n delay: searchDelay,\n filter: searchFilter,\n });\n\n const storage = useTableStorage(storageKey, persist);\n\n const {\n sort,\n sortedRows,\n toggleSort,\n mode: resolvedSortMode,\n } = useTableSort<T>({\n columns,\n rows: searchedRows,\n mode: sortMode,\n sort: sortProp,\n // Only restore what the table owns: a controlled `sort` belongs to the page,\n // and overriding it here would fight the page's own source of truth.\n defaultSort:\n sortProp === undefined && storage.has('sort')\n ? storage.initial.sort ?? defaultSort\n : defaultSort,\n onSortChange: useEvent((next: CubeTableSort | null) => {\n if (sortProp === undefined) storage.write({ sort: next });\n onSortChange?.(next);\n }),\n });\n\n // Search → sort → paginate. Paging last, so a page always reflects the rows\n // the user is actually looking at.\n //\n // Deliberately not `usePagination`: that hook owns an in-memory array, and in\n // server mode `data` is a single page. Deriving the bounds from it would clamp\n // the page to 1 and swallow every page change.\n const [pageSize, setPageSizeState] = useControlledState<number>(\n pageSizeProp as number,\n pageSizeProp === undefined && storage.has('pageSize')\n ? storage.initial.pageSize ?? defaultPageSize\n : defaultPageSize,\n onPageSizeChange as (value: number) => void,\n );\n const [page, setPageState] = useControlledState<number>(\n pageProp as number,\n defaultPage ?? 1,\n onPageChange as (value: number) => void,\n );\n\n const isInfinite = paginationMode === 'infinite';\n // Infinite scroll replaces the page control rather than adding to it.\n const isPaginated = paginationMode !== 'off' && !isInfinite;\n const isServerPaginated = paginationMode === 'server';\n const total = isServerPaginated ? totalProp ?? 0 : sortedRows.length;\n\n const pageInfo = getPageInfo({\n page,\n pageSize,\n total,\n totalPages: isServerPaginated ? totalPages : undefined,\n });\n\n const setPage = useEvent((next: number) =>\n setPageState(clampPage(next, pageInfo.totalPages)),\n );\n const setPageSize = useEvent((next: number) => {\n setPageSizeState(next);\n\n if (pageSizeProp === undefined) storage.write({ pageSize: next });\n\n // The old page index points at different rows under a new page size, so\n // staying on it would silently move the user.\n setPageState(1);\n });\n\n const visibleRows =\n paginationMode === 'client'\n ? sortedRows.slice(\n (pageInfo.page - 1) * pageSize,\n pageInfo.page * pageSize,\n )\n : sortedRows;\n\n const resolvedGetRowKey = useMemo(\n () => getRowKey ?? defaultGetRowKey<T>(rowKey),\n [getRowKey, rowKey],\n );\n\n // A bulk action with no way to select rows is a contradiction, so supplying\n // any implies multiple selection unless the consumer says otherwise.\n const resolvedSelectionMode =\n selectionMode ?? (bulkActions?.length ? 'multiple' : 'none');\n\n const selection = useTableSelection<T>({\n rows: visibleRows,\n // The wider set the header checkbox can reach under\n // `selectAllMode=\"filtered\"`. In server mode the client only ever holds one\n // page, so the two coincide.\n filteredRows: paginationMode === 'client' ? sortedRows : visibleRows,\n getRowKey: resolvedGetRowKey,\n selectionMode: resolvedSelectionMode,\n selectedKeys: selectedKeysProp,\n defaultSelectedKeys,\n onSelectionChange,\n selectAllMode,\n isRowSelectable,\n disabledKeys,\n });\n\n // A `ReactNode` menu applies to every row; a function decides per row. The\n // renderer only ever sees the function form.\n const resolveRowMenu = useMemo(\n () =>\n rowMenu == null\n ? undefined\n : typeof rowMenu === 'function'\n ? (rowMenu as (\n row: T,\n ctx: CubeTableRowContext<T>,\n ) => ReactNode | null)\n : () => rowMenu as ReactNode,\n [rowMenu],\n );\n\n const trailingColumns = useMemo(\n () =>\n resolveRowMenu && rowContextMenu === true\n ? [\n {\n key: ROW_MENU_COLUMN_KEY,\n width:\n ROW_MENU_COLUMN_WIDTH[size] ?? ROW_MENU_COLUMN_WIDTH.medium,\n align: 'center' as const,\n },\n ]\n : undefined,\n [resolveRowMenu, rowContextMenu, size],\n );\n\n const leadingColumns = useMemo(\n () =>\n selection.isEnabled\n ? [\n {\n key: SELECTION_COLUMN_KEY,\n width:\n SELECTION_COLUMN_WIDTH[size] ?? SELECTION_COLUMN_WIDTH.medium,\n align: 'center' as const,\n },\n ]\n : undefined,\n [selection.isEnabled, size],\n );\n\n /**\n * Column widths, in three layers.\n *\n * The draft exists because a resize has to be visible *while* it happens, and\n * a controlled `columnWidths` cannot be: the consumer only learns the new\n * width from `onColumnResize`, which fires when the gesture ends. Without a\n * draft a controlled table simply would not move under the pointer.\n */\n const [ownColumnWidths, setOwnColumnWidths] = useState<\n Record<string, number>\n >(\n () =>\n (columnWidthsProp === undefined && storage.has('columnWidths')\n ? storage.initial.columnWidths ?? defaultColumnWidths\n : defaultColumnWidths) ?? EMPTY_WIDTHS,\n );\n const [draftColumnWidths, setDraftColumnWidths] = useState<Record<\n string,\n number\n > | null>(null);\n\n /**\n * The same draft, in a ref.\n *\n * A keyboard resize runs `useMove`'s whole start → move → end cycle inside\n * one key press, so the end handler would read the state from before the\n * move. The ref is what it actually settles on; the state exists only to\n * trigger the render.\n */\n const draftColumnWidthsRef = useRef<Record<string, number> | null>(null);\n\n const baseColumnWidths = columnWidthsProp ?? ownColumnWidths;\n const columnWidths = draftColumnWidths ?? baseColumnWidths;\n\n const handleColumnResize = useEvent((key: string, width: number) => {\n draftColumnWidthsRef.current = {\n ...(draftColumnWidthsRef.current ?? baseColumnWidths),\n [key]: Math.round(width),\n };\n setDraftColumnWidths(draftColumnWidthsRef.current);\n });\n\n // Once at the end: a callback per pixel would be unusable, and persisting\n // every frame would hammer `localStorage`.\n const handleColumnResizeEnd = useEvent((key: string) => {\n const next = draftColumnWidthsRef.current ?? baseColumnWidths;\n\n if (columnWidthsProp === undefined) {\n setOwnColumnWidths(next);\n storage.write({ columnWidths: next });\n }\n\n onColumnResize?.(key, next[key], next);\n\n // The prop (or `ownColumnWidths`) is the source of truth again. A\n // controlled consumer that ignores the callback reverts, which is what\n // being controlled means.\n draftColumnWidthsRef.current = null;\n setDraftColumnWidths(null);\n });\n\n const layout = useTableColumns<T>({\n columns,\n containerWidth,\n columnWidths,\n leadingColumns,\n trailingColumns,\n });\n\n const hasBulkSelection =\n bulkActions != null &&\n bulkActions.length > 0 &&\n selection.selectedCount > 0;\n\n const bulkBar = hasBulkSelection ? (\n <ItemTableBulkBar<T>\n actions={bulkActions!}\n placement={bulkBarPlacement}\n styles={bulkBarStyles}\n />\n ) : null;\n\n const isBulkBarInToolbar = bulkBar != null && bulkBarPlacement === 'toolbar';\n\n const hasToolbar =\n toolbar !== undefined ||\n isSearchable ||\n filters != null ||\n actions != null ||\n onRefresh != null ||\n isBulkBarInToolbar;\n\n const toolbarNode = hasToolbar\n ? toolbar ?? (\n <ItemTableToolbar\n isSearchable={isSearchable}\n filters={filters}\n // The bar takes the actions group rather than sitting beside it: the\n // two compete for the same space, and while rows are selected the\n // bulk actions are what the user is reaching for.\n actions={isBulkBarInToolbar ? bulkBar : actions}\n isLoading={isLoading}\n styles={toolbarStyles}\n searchStyles={searchStyles}\n onRefresh={onRefresh}\n />\n )\n : null;\n\n /**\n * Pagination that cannot do anything is noise: one page of five rows still\n * renders \"1–5 of 5\", a page-size selector whose every option shows the same\n * five rows, and a solitary \"1\" button.\n *\n * \"Cannot do anything\" is both conditions together — a single page *and* a\n * total that even the smallest page size would not split. A 15-row single\n * page stays, because choosing \"10 / page\" would genuinely paginate it.\n */\n const smallestPageSize = pageSizeOptions?.length\n ? Math.min(...pageSizeOptions)\n : pageSize;\n\n const isPaginationUseless =\n autoHidePagination &&\n !hasNextPage &&\n pageInfo.totalPages <= 1 &&\n total <= smallestPageSize;\n\n const showPagination = isPaginated && !isPaginationUseless;\n\n const hasFooter =\n footer !== undefined ||\n showPagination ||\n footerStart != null ||\n footerCenter != null ||\n footerEnd != null;\n\n const footerNode = hasFooter\n ? footer ?? (\n <ItemTableFooter\n start={footerStart}\n center={footerCenter}\n end={footerEnd}\n styles={footerStyles}\n pagination={\n showPagination\n ? {\n page: pageInfo.page,\n pageSize,\n total,\n totalPages: pageInfo.totalPages,\n pageSizeOptions,\n summary,\n hasNextPage,\n onPageChange: setPage,\n onPageSizeChange: setPageSize,\n }\n : undefined\n }\n />\n )\n : null;\n\n const bodyRef = useRef<HTMLTableSectionElement>(null);\n\n const rowKeys = useMemo(\n () =>\n visibleRows.map((row, index) => String(resolvedGetRowKey(row, index))),\n [visibleRows, resolvedGetRowKey],\n );\n\n const handleReorder = useEvent((nextKeys: string[]) => {\n const byKey = new Map(\n visibleRows.map((row, index) => [\n String(resolvedGetRowKey(row, index)),\n row,\n ]),\n );\n\n onReorder?.(\n nextKeys,\n nextKeys\n .map((key) => byKey.get(key))\n .filter((row): row is T => row !== undefined),\n );\n });\n\n /**\n * `DraggableCollection` owns the React Aria drag/drop hooks and hands the two\n * states down. It is only mounted when reordering is on, so a plain table\n * pays nothing for it.\n *\n * `RowCollection` and the `SelectionManager` from `useTableSelection` satisfy\n * its structural `state` contract unchanged — both exist even when selection\n * itself is off.\n */\n const renderTable = (\n dragState?: any,\n dropState?: any,\n collectionProps?: Record<string, any>,\n ) => (\n <TableView<T>\n rootRef={rootRef}\n dragState={dragState}\n dropState={dropState}\n collectionProps={collectionProps}\n bodyRef={bodyRef}\n qa={qa || 'ItemTable'}\n rows={visibleRows}\n // `aria-rowindex` is document-absolute by contract: on page 3 a screen\n // reader should hear \"row 51 of 240\", not \"row 1 of 25\". Infinite scroll\n // never offsets — every loaded row is already in `visibleRows`.\n // `isPaginated` already excludes infinite scroll, where every loaded row\n // is in `visibleRows` and there is no page to offset by.\n rowIndexOffset={isPaginated ? (pageInfo.page - 1) * pageSize : 0}\n totalRowCount={total}\n getRowKey={resolvedGetRowKey}\n layout={layout}\n onScrollerRef={setScrollerEl}\n size={size}\n shape={shape}\n rowHeight={rowHeight}\n headerHeight={headerHeight}\n isHeaderHidden={isHeaderHidden}\n isHeaderSticky={isHeaderSticky}\n isVirtualized={isVirtualized}\n virtualizeThreshold={virtualizeThreshold}\n overscan={overscan}\n isStriped={isStriped}\n isRowMoveAnimated={isRowMoveAnimated}\n isLoading={isLoading}\n loadingIndicator={loadingIndicator}\n selection={selection}\n selectionTooltip={selectionTooltip}\n rowLink={rowLink}\n onRowAction={onRowAction}\n onLoadMore={isInfinite ? onLoadMore : undefined}\n hasMore={hasMore}\n isLoadingMore={isLoadingMore}\n loadMoreMargin={loadMoreMargin}\n isReorderable={isDragEnabled}\n isResizable={isResizable}\n onColumnResize={handleColumnResize}\n onColumnResizeEnd={handleColumnResizeEnd}\n rowMenu={resolveRowMenu}\n rowContextMenu={rowContextMenu}\n onRowMenuAction={onRowMenuAction}\n rowMenuTriggerProps={rowMenuTriggerProps}\n skeletonRowCount={skeletonRowCount}\n emptyLabel={emptyLabel ?? t('itemTable.noItems', 'No items')}\n noResultsLabel={\n noResultsLabel ?? t('itemTable.noResults', 'No results found')\n }\n error={error}\n toolbar={toolbarNode}\n footer={footerNode}\n isFiltered={isFiltered ?? isSearching}\n sortMode={resolvedSortMode}\n sort={sort}\n onColumnSort={toggleSort}\n getRowProps={getRowProps}\n ariaLabel={ariaLabel}\n styles={rootStyles}\n headerStyles={headerStyles}\n headerCellStyles={headerCellStyles}\n headerPreset={headerPreset}\n bodyStyles={bodyStyles}\n rowStyles={rowStyles}\n cellStyles={cellStyles}\n mods={mods}\n overlay={bulkBarPlacement === 'floating' ? bulkBar : null}\n />\n );\n\n const rowByKeyForDrop = useMemo(() => {\n const map = new Map<string, T>();\n\n visibleRows.forEach((row, index) =>\n map.set(String(resolvedGetRowKey(row, index)), row),\n );\n\n return map;\n }, [visibleRows, resolvedGetRowKey]);\n\n const handleItemDrop = useEvent((targetKey: Key, draggedKeys: Key[]) => {\n if (!dropOnRow) return;\n\n const target = rowByKeyForDrop.get(String(targetKey));\n\n if (!target) return;\n\n const dragged = draggedKeys\n .map((key) => rowByKeyForDrop.get(String(key)))\n // A row cannot be dropped on itself.\n .filter((row): row is T => row !== undefined && row !== target);\n\n if (!dragged.length) return;\n if (dropOnRow.isAllowed && !dropOnRow.isAllowed(dragged, target)) return;\n\n void dropOnRow.onDrop(dragged, target);\n });\n\n const renderDragPreview = useEvent((keys: Key[]) => (\n <ItemTableDragPreview<T>\n rows={keys\n .map((key) => rowByKeyForDrop.get(String(key)))\n .filter((row): row is T => row !== undefined)}\n getItemDragInfo={getItemDragInfo!}\n />\n ));\n\n const shouldAcceptItemDrop = useEvent((targetKey: Key) => {\n const target = rowByKeyForDrop.get(String(targetKey));\n\n return target != null && (dropOnRow?.isTarget(target) ?? false);\n });\n\n // Dropping onto a row and reordering both need the drag machinery.\n const isDragEnabled = isReorderable || dropOnRow != null;\n\n const table = isDragEnabled ? (\n <DraggableCollection\n state={{\n collection: selection.collection,\n selectionManager: selection.selectionManager as any,\n disabledKeys: new Set(disabledKeys ?? []),\n }}\n // The element that directly contains the rows. React Aria's\n // `ListDropTargetDelegate` measures the drop position from this element's\n // children, so pointing it at the table root would leave every drop\n // unresolvable — the row lifts but never lands.\n listRef={bodyRef}\n orderedKeys={rowKeys}\n orientation=\"vertical\"\n onReorder={isReorderable ? handleReorder : undefined}\n onItemDrop={dropOnRow ? handleItemDrop : undefined}\n shouldAcceptItemDrop={dropOnRow ? shouldAcceptItemDrop : undefined}\n renderPreview={getItemDragInfo ? renderDragPreview : undefined}\n >\n {(dragState, dropState, collectionProps) =>\n renderTable(dragState, dropState, collectionProps)\n }\n </DraggableCollection>\n ) : (\n renderTable()\n );\n\n // The provider always wraps, so `ItemTable.Search` works from a custom\n // `toolbar` as well as from the built-in one.\n return (\n <ItemTableChromeProvider\n value={{\n searchValue,\n setSearchValue,\n searchPlaceholder,\n isLoading,\n onRefresh,\n selectedKeys: selection.selectedKeys,\n selectedRows: selection.selectedRows,\n selectedCount: selection.selectedCount,\n clearSelection: selection.clearSelection,\n }}\n >\n {table}\n </ItemTableChromeProvider>\n );\n}\n\nconst _ItemTable = Object.assign(\n forwardRef(ItemTable) as unknown as (<T = any>(\n props: CubeItemTableProps<T> & { ref?: ForwardedRef<HTMLDivElement> },\n ) => ReactElement) & { displayName?: string },\n {\n /** The table's search input, bound to the table's own state. */\n Search: ItemTableSearch,\n /** The default toolbar row, for rebuilding it around extra content. */\n Toolbar: ItemTableToolbar,\n /** The selection action bar, for placing it outside the default chrome. */\n BulkBar: ItemTableBulkBar,\n },\n);\n\n_ItemTable.displayName = 'ItemTable';\n\nexport { _ItemTable as ItemTable };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ItemTable.js","names":[],"sources":["../../../../src/components/data/ItemTable/ItemTable.tsx"],"sourcesContent":["import { useControlledState } from '@react-stately/utils';\nimport { CONTAINER_STYLES } from '@tenphi/tasty';\nimport { forwardRef, useMemo, useRef, useState } from 'react';\n\nimport { useEvent } from '../../../_internal/hooks';\nimport { useI18n } from '../../../i18n';\nimport { useCombinedRefs } from '../../../utils/react';\nimport { extractStyles } from '../../../utils/styles';\nimport { clampPage, getPageInfo } from '../../navigation/Pagination';\nimport { DraggableCollection } from '../../shared/DraggableCollection';\nimport {\n ROW_MENU_COLUMN_KEY,\n ROW_MENU_COLUMN_WIDTH,\n} from '../TableBase/row-menu';\nimport { TableView } from '../TableBase/TableView';\nimport { useContainerWidth } from '../TableBase/use-container-width';\nimport {\n freezeColumnWidths,\n useTableColumns,\n} from '../TableBase/use-table-columns';\nimport { useTableSearch } from '../TableBase/use-table-search';\nimport {\n SELECTION_COLUMN_KEY,\n SELECTION_COLUMN_WIDTH,\n useTableSelection,\n} from '../TableBase/use-table-selection';\nimport { useTableSort } from '../TableBase/use-table-sort';\nimport { useTableStorage } from '../TableBase/use-table-storage';\n\nimport { ItemTableBulkBar } from './ItemTableBulkBar';\nimport { ItemTableDragPreview } from './ItemTableDragPreview';\nimport { ItemTableFooter } from './ItemTableFooter';\nimport {\n ItemTableChromeProvider,\n ItemTableSearch,\n ItemTableToolbar,\n} from './ItemTableToolbar';\n\nimport type { Key } from '@react-types/shared';\nimport type { ForwardedRef, ReactElement, ReactNode } from 'react';\nimport type {\n CubeTableColumnLayout,\n CubeTableRowContext,\n CubeTableSort,\n} from '../TableBase/types';\nimport type { CubeItemTableProps } from './types';\n\n/** Stable identity, so the uncontrolled default does not change every render. */\nconst EMPTY_WIDTHS: Record<string, number> = {};\n\nfunction defaultGetRowKey<T>(rowKey: string) {\n return (row: T, index: number): Key => {\n const value = (row as any)?.[rowKey];\n\n return value == null ? index : (value as Key);\n };\n}\n\nfunction ItemTable<T = any>(\n props: CubeItemTableProps<T>,\n ref: ForwardedRef<HTMLDivElement>,\n): ReactElement {\n const {\n data,\n columns,\n rowKey = 'id',\n getRowKey,\n isLoading = false,\n loadingIndicator = 'overlay',\n selectionMode,\n bulkActions,\n rowLink,\n onRowAction,\n rowMenu,\n rowContextMenu = false,\n onRowMenuAction,\n rowMenuTriggerProps,\n bulkBarPlacement = 'floating',\n bulkBarStyles,\n selectedKeys: selectedKeysProp,\n defaultSelectedKeys,\n onSelectionChange,\n selectAllMode = 'page',\n isRowSelectable,\n selectionTooltip,\n disabledKeys,\n skeletonRowCount = 6,\n emptyLabel,\n noResultsLabel,\n error,\n isFiltered,\n toolbar,\n isSearchable = false,\n searchMode = 'client',\n searchPlaceholder,\n searchValue: searchValueProp,\n defaultSearchValue,\n onSearchChange,\n searchDelay = 500,\n searchFilter,\n filters,\n actions,\n onRefresh,\n paginationMode = 'client',\n pageSize: pageSizeProp,\n defaultPageSize = 50,\n autoHidePagination = true,\n onLoadMore,\n hasMore,\n isLoadingMore,\n loadMoreMargin,\n storageKey,\n persist,\n isReorderable = false,\n onReorder,\n dropOnRow,\n getItemDragInfo,\n isResizable = false,\n columnWidths: columnWidthsProp,\n defaultColumnWidths,\n onColumnResize,\n columnContextMenu,\n onColumnMenuAction,\n columnMenuTriggerProps,\n columnMenuProps,\n onPageSizeChange,\n pageSizeOptions = [10, 20, 50, 100, 500],\n page: pageProp,\n defaultPage,\n onPageChange,\n total: totalProp,\n totalPages,\n hasNextPage,\n summary = true,\n footer,\n footerStart,\n footerCenter,\n footerEnd,\n sortMode,\n sort: sortProp,\n defaultSort,\n onSortChange,\n shape = 'plain',\n size = 'medium',\n rowHeight,\n headerHeight,\n isStriped = false,\n isHeaderHidden = false,\n isHeaderSticky = true,\n isVirtualized = 'auto',\n virtualizeThreshold = 50,\n overscan = 20,\n getRowProps,\n ariaLabel,\n qa,\n mods,\n styles,\n headerStyles,\n headerCellStyles,\n headerPreset = 'c3',\n toolbarStyles,\n searchStyles,\n footerStyles,\n bodyStyles,\n rowStyles,\n cellStyles,\n isRowMoveAnimated,\n } = props;\n\n const { t } = useI18n();\n\n const localRef = useRef<HTMLDivElement>(null);\n const rootRef = useCombinedRefs(ref, localRef);\n\n // Held in state, not a ref: the virtualized path's scroller is created by\n // Virtuoso and arrives through a callback, and the column layout has to\n // re-derive once it does.\n const [scrollerEl, setScrollerEl] = useState<HTMLDivElement | null>(null);\n const containerWidth = useContainerWidth(scrollerEl);\n\n // Style props (`height`, `maxHeight`, `margin`, …) land on the root frame.\n // `height` matters most: there is no page-scroll mode, so bounding the table\n // is what turns the body into a scroller and pins the header.\n const rootStyles = { ...extractStyles(props, CONTAINER_STYLES), ...styles };\n\n const {\n searchValue,\n setSearchValue,\n searchedRows,\n isFiltered: isSearching,\n } = useTableSearch<T>({\n columns,\n rows: data,\n mode: searchMode,\n value: searchValueProp,\n defaultValue: defaultSearchValue,\n onChange: onSearchChange,\n delay: searchDelay,\n filter: searchFilter,\n });\n\n const storage = useTableStorage(storageKey, persist);\n\n const {\n sort,\n sortedRows,\n toggleSort,\n setColumnSort,\n mode: resolvedSortMode,\n } = useTableSort<T>({\n columns,\n rows: searchedRows,\n mode: sortMode,\n sort: sortProp,\n // Only restore what the table owns: a controlled `sort` belongs to the page,\n // and overriding it here would fight the page's own source of truth.\n defaultSort:\n sortProp === undefined && storage.has('sort')\n ? storage.initial.sort ?? defaultSort\n : defaultSort,\n onSortChange: useEvent((next: CubeTableSort | null) => {\n if (sortProp === undefined) storage.write({ sort: next });\n onSortChange?.(next);\n }),\n });\n\n // Search → sort → paginate. Paging last, so a page always reflects the rows\n // the user is actually looking at.\n //\n // Deliberately not `usePagination`: that hook owns an in-memory array, and in\n // server mode `data` is a single page. Deriving the bounds from it would clamp\n // the page to 1 and swallow every page change.\n const [pageSize, setPageSizeState] = useControlledState<number>(\n pageSizeProp as number,\n pageSizeProp === undefined && storage.has('pageSize')\n ? storage.initial.pageSize ?? defaultPageSize\n : defaultPageSize,\n onPageSizeChange as (value: number) => void,\n );\n const [page, setPageState] = useControlledState<number>(\n pageProp as number,\n defaultPage ?? 1,\n onPageChange as (value: number) => void,\n );\n\n const isInfinite = paginationMode === 'infinite';\n // Infinite scroll replaces the page control rather than adding to it.\n const isPaginated = paginationMode !== 'off' && !isInfinite;\n const isServerPaginated = paginationMode === 'server';\n const total = isServerPaginated ? totalProp ?? 0 : sortedRows.length;\n\n const pageInfo = getPageInfo({\n page,\n pageSize,\n total,\n totalPages: isServerPaginated ? totalPages : undefined,\n });\n\n const setPage = useEvent((next: number) =>\n setPageState(clampPage(next, pageInfo.totalPages)),\n );\n const setPageSize = useEvent((next: number) => {\n setPageSizeState(next);\n\n if (pageSizeProp === undefined) storage.write({ pageSize: next });\n\n // The old page index points at different rows under a new page size, so\n // staying on it would silently move the user.\n setPageState(1);\n });\n\n const visibleRows =\n paginationMode === 'client'\n ? sortedRows.slice(\n (pageInfo.page - 1) * pageSize,\n pageInfo.page * pageSize,\n )\n : sortedRows;\n\n const resolvedGetRowKey = useMemo(\n () => getRowKey ?? defaultGetRowKey<T>(rowKey),\n [getRowKey, rowKey],\n );\n\n // A bulk action with no way to select rows is a contradiction, so supplying\n // any implies multiple selection unless the consumer says otherwise.\n const resolvedSelectionMode =\n selectionMode ?? (bulkActions?.length ? 'multiple' : 'none');\n\n const selection = useTableSelection<T>({\n rows: visibleRows,\n // The wider set the header checkbox can reach under\n // `selectAllMode=\"filtered\"`. In server mode the client only ever holds one\n // page, so the two coincide.\n filteredRows: paginationMode === 'client' ? sortedRows : visibleRows,\n getRowKey: resolvedGetRowKey,\n selectionMode: resolvedSelectionMode,\n selectedKeys: selectedKeysProp,\n defaultSelectedKeys,\n onSelectionChange,\n selectAllMode,\n isRowSelectable,\n disabledKeys,\n });\n\n // A `ReactNode` menu applies to every row; a function decides per row. The\n // renderer only ever sees the function form.\n const resolveRowMenu = useMemo(\n () =>\n rowMenu == null\n ? undefined\n : typeof rowMenu === 'function'\n ? (rowMenu as (\n row: T,\n ctx: CubeTableRowContext<T>,\n ) => ReactNode | null)\n : () => rowMenu as ReactNode,\n [rowMenu],\n );\n\n const trailingColumns = useMemo(\n () =>\n resolveRowMenu && rowContextMenu === true\n ? [\n {\n key: ROW_MENU_COLUMN_KEY,\n width:\n ROW_MENU_COLUMN_WIDTH[size] ?? ROW_MENU_COLUMN_WIDTH.medium,\n align: 'center' as const,\n },\n ]\n : undefined,\n [resolveRowMenu, rowContextMenu, size],\n );\n\n const leadingColumns = useMemo(\n () =>\n selection.isEnabled\n ? [\n {\n key: SELECTION_COLUMN_KEY,\n width:\n SELECTION_COLUMN_WIDTH[size] ?? SELECTION_COLUMN_WIDTH.medium,\n align: 'center' as const,\n },\n ]\n : undefined,\n [selection.isEnabled, size],\n );\n\n /**\n * Column widths, in three layers.\n *\n * The draft exists because a resize has to be visible *while* it happens, and\n * a controlled `columnWidths` cannot be: the consumer only learns the new\n * width from `onColumnResize`, which fires when the gesture ends. Without a\n * draft a controlled table simply would not move under the pointer.\n */\n const [ownColumnWidths, setOwnColumnWidths] = useState<\n Record<string, number>\n >(\n () =>\n (columnWidthsProp === undefined && storage.has('columnWidths')\n ? storage.initial.columnWidths ?? defaultColumnWidths\n : defaultColumnWidths) ?? EMPTY_WIDTHS,\n );\n const [draftColumnWidths, setDraftColumnWidths] = useState<Record<\n string,\n number\n > | null>(null);\n\n /**\n * The same draft, in a ref.\n *\n * A keyboard resize runs `useMove`'s whole start → move → end cycle inside\n * one key press, so the end handler would read the state from before the\n * move. The ref is what it actually settles on; the state exists only to\n * trigger the render.\n */\n const draftColumnWidthsRef = useRef<Record<string, number> | null>(null);\n\n const baseColumnWidths = columnWidthsProp ?? ownColumnWidths;\n const columnWidths = draftColumnWidths ?? baseColumnWidths;\n\n /** `layout` is computed below; `useEvent` only reads this when a drag runs. */\n const layoutRef = useRef<CubeTableColumnLayout<T> | null>(null);\n\n const handleColumnResize = useEvent((key: string, width: number) => {\n // First move of a drag freezes every column, so this changes exactly one\n // width instead of re-splitting the flex pool. See `freezeColumnWidths`.\n const base =\n draftColumnWidthsRef.current ??\n freezeColumnWidths(layoutRef.current, baseColumnWidths);\n\n draftColumnWidthsRef.current = { ...base, [key]: Math.round(width) };\n setDraftColumnWidths(draftColumnWidthsRef.current);\n });\n\n // Once at the end: a callback per pixel would be unusable, and persisting\n // every frame would hammer `localStorage`.\n const handleColumnResizeEnd = useEvent((key: string) => {\n const next = draftColumnWidthsRef.current ?? baseColumnWidths;\n\n if (columnWidthsProp === undefined) {\n setOwnColumnWidths(next);\n storage.write({ columnWidths: next });\n }\n\n onColumnResize?.(key, next[key], next);\n\n // The prop (or `ownColumnWidths`) is the source of truth again. A\n // controlled consumer that ignores the callback reverts, which is what\n // being controlled means.\n draftColumnWidthsRef.current = null;\n setDraftColumnWidths(null);\n });\n\n const layout = useTableColumns<T>({\n columns,\n containerWidth,\n columnWidths,\n leadingColumns,\n trailingColumns,\n });\n\n layoutRef.current = layout;\n\n const hasBulkSelection =\n bulkActions != null &&\n bulkActions.length > 0 &&\n selection.selectedCount > 0;\n\n const bulkBar = hasBulkSelection ? (\n <ItemTableBulkBar<T>\n actions={bulkActions!}\n placement={bulkBarPlacement}\n styles={bulkBarStyles}\n />\n ) : null;\n\n const isBulkBarInToolbar = bulkBar != null && bulkBarPlacement === 'toolbar';\n\n const hasToolbar =\n toolbar !== undefined ||\n isSearchable ||\n filters != null ||\n actions != null ||\n onRefresh != null ||\n isBulkBarInToolbar;\n\n const toolbarNode = hasToolbar\n ? toolbar ?? (\n <ItemTableToolbar\n isSearchable={isSearchable}\n filters={filters}\n // The bar takes the actions group rather than sitting beside it: the\n // two compete for the same space, and while rows are selected the\n // bulk actions are what the user is reaching for.\n actions={isBulkBarInToolbar ? bulkBar : actions}\n isLoading={isLoading}\n styles={toolbarStyles}\n searchStyles={searchStyles}\n onRefresh={onRefresh}\n />\n )\n : null;\n\n /**\n * Pagination that cannot do anything is noise: one page of five rows still\n * renders \"1–5 of 5\", a page-size selector whose every option shows the same\n * five rows, and a solitary \"1\" button.\n *\n * \"Cannot do anything\" is both conditions together — a single page *and* a\n * total that even the smallest page size would not split. A 15-row single\n * page stays, because choosing \"10 / page\" would genuinely paginate it.\n */\n const smallestPageSize = pageSizeOptions?.length\n ? Math.min(...pageSizeOptions)\n : pageSize;\n\n const isPaginationUseless =\n autoHidePagination &&\n !hasNextPage &&\n pageInfo.totalPages <= 1 &&\n total <= smallestPageSize;\n\n const showPagination = isPaginated && !isPaginationUseless;\n\n const hasFooter =\n footer !== undefined ||\n showPagination ||\n footerStart != null ||\n footerCenter != null ||\n footerEnd != null;\n\n const footerNode = hasFooter\n ? footer ?? (\n <ItemTableFooter\n start={footerStart}\n center={footerCenter}\n end={footerEnd}\n styles={footerStyles}\n pagination={\n showPagination\n ? {\n page: pageInfo.page,\n pageSize,\n total,\n totalPages: pageInfo.totalPages,\n pageSizeOptions,\n summary,\n hasNextPage,\n onPageChange: setPage,\n onPageSizeChange: setPageSize,\n }\n : undefined\n }\n />\n )\n : null;\n\n const bodyRef = useRef<HTMLTableSectionElement>(null);\n\n const rowKeys = useMemo(\n () =>\n visibleRows.map((row, index) => String(resolvedGetRowKey(row, index))),\n [visibleRows, resolvedGetRowKey],\n );\n\n const handleReorder = useEvent((nextKeys: string[]) => {\n const byKey = new Map(\n visibleRows.map((row, index) => [\n String(resolvedGetRowKey(row, index)),\n row,\n ]),\n );\n\n onReorder?.(\n nextKeys,\n nextKeys\n .map((key) => byKey.get(key))\n .filter((row): row is T => row !== undefined),\n );\n });\n\n /**\n * `DraggableCollection` owns the React Aria drag/drop hooks and hands the two\n * states down. It is only mounted when reordering is on, so a plain table\n * pays nothing for it.\n *\n * `RowCollection` and the `SelectionManager` from `useTableSelection` satisfy\n * its structural `state` contract unchanged — both exist even when selection\n * itself is off.\n */\n const renderTable = (\n dragState?: any,\n dropState?: any,\n collectionProps?: Record<string, any>,\n ) => (\n <TableView<T>\n rootRef={rootRef}\n dragState={dragState}\n dropState={dropState}\n collectionProps={collectionProps}\n bodyRef={bodyRef}\n qa={qa || 'ItemTable'}\n rows={visibleRows}\n // `aria-rowindex` is document-absolute by contract: on page 3 a screen\n // reader should hear \"row 51 of 240\", not \"row 1 of 25\". Infinite scroll\n // never offsets — every loaded row is already in `visibleRows`.\n // `isPaginated` already excludes infinite scroll, where every loaded row\n // is in `visibleRows` and there is no page to offset by.\n rowIndexOffset={isPaginated ? (pageInfo.page - 1) * pageSize : 0}\n totalRowCount={total}\n getRowKey={resolvedGetRowKey}\n layout={layout}\n onScrollerRef={setScrollerEl}\n size={size}\n shape={shape}\n rowHeight={rowHeight}\n headerHeight={headerHeight}\n isHeaderHidden={isHeaderHidden}\n isHeaderSticky={isHeaderSticky}\n isVirtualized={isVirtualized}\n virtualizeThreshold={virtualizeThreshold}\n overscan={overscan}\n isStriped={isStriped}\n isRowMoveAnimated={isRowMoveAnimated}\n isLoading={isLoading}\n loadingIndicator={loadingIndicator}\n selection={selection}\n selectionTooltip={selectionTooltip}\n rowLink={rowLink}\n onRowAction={onRowAction}\n onLoadMore={isInfinite ? onLoadMore : undefined}\n hasMore={hasMore}\n isLoadingMore={isLoadingMore}\n loadMoreMargin={loadMoreMargin}\n isReorderable={isDragEnabled}\n isResizable={isResizable}\n onColumnResize={handleColumnResize}\n onColumnResizeEnd={handleColumnResizeEnd}\n rowMenu={resolveRowMenu}\n rowContextMenu={rowContextMenu}\n onRowMenuAction={onRowMenuAction}\n rowMenuTriggerProps={rowMenuTriggerProps}\n skeletonRowCount={skeletonRowCount}\n emptyLabel={emptyLabel ?? t('itemTable.noItems', 'No items')}\n noResultsLabel={\n noResultsLabel ?? t('itemTable.noResults', 'No results found')\n }\n error={error}\n toolbar={toolbarNode}\n footer={footerNode}\n isFiltered={isFiltered ?? isSearching}\n sortMode={resolvedSortMode}\n sort={sort}\n onColumnSort={toggleSort}\n onColumnSortChange={setColumnSort}\n columnContextMenu={columnContextMenu}\n onColumnMenuAction={onColumnMenuAction}\n columnMenuTriggerProps={columnMenuTriggerProps}\n columnMenuProps={columnMenuProps}\n getRowProps={getRowProps}\n ariaLabel={ariaLabel}\n styles={rootStyles}\n headerStyles={headerStyles}\n headerCellStyles={headerCellStyles}\n headerPreset={headerPreset}\n bodyStyles={bodyStyles}\n rowStyles={rowStyles}\n cellStyles={cellStyles}\n mods={mods}\n overlay={bulkBarPlacement === 'floating' ? bulkBar : null}\n />\n );\n\n const rowByKeyForDrop = useMemo(() => {\n const map = new Map<string, T>();\n\n visibleRows.forEach((row, index) =>\n map.set(String(resolvedGetRowKey(row, index)), row),\n );\n\n return map;\n }, [visibleRows, resolvedGetRowKey]);\n\n const handleItemDrop = useEvent((targetKey: Key, draggedKeys: Key[]) => {\n if (!dropOnRow) return;\n\n const target = rowByKeyForDrop.get(String(targetKey));\n\n if (!target) return;\n\n const dragged = draggedKeys\n .map((key) => rowByKeyForDrop.get(String(key)))\n // A row cannot be dropped on itself.\n .filter((row): row is T => row !== undefined && row !== target);\n\n if (!dragged.length) return;\n if (dropOnRow.isAllowed && !dropOnRow.isAllowed(dragged, target)) return;\n\n void dropOnRow.onDrop(dragged, target);\n });\n\n const renderDragPreview = useEvent((keys: Key[]) => (\n <ItemTableDragPreview<T>\n rows={keys\n .map((key) => rowByKeyForDrop.get(String(key)))\n .filter((row): row is T => row !== undefined)}\n getItemDragInfo={getItemDragInfo!}\n />\n ));\n\n const shouldAcceptItemDrop = useEvent((targetKey: Key) => {\n const target = rowByKeyForDrop.get(String(targetKey));\n\n return target != null && (dropOnRow?.isTarget(target) ?? false);\n });\n\n // Dropping onto a row and reordering both need the drag machinery.\n const isDragEnabled = isReorderable || dropOnRow != null;\n\n const table = isDragEnabled ? (\n <DraggableCollection\n state={{\n collection: selection.collection,\n selectionManager: selection.selectionManager as any,\n disabledKeys: new Set(disabledKeys ?? []),\n }}\n // The element that directly contains the rows. React Aria's\n // `ListDropTargetDelegate` measures the drop position from this element's\n // children, so pointing it at the table root would leave every drop\n // unresolvable — the row lifts but never lands.\n listRef={bodyRef}\n orderedKeys={rowKeys}\n orientation=\"vertical\"\n onReorder={isReorderable ? handleReorder : undefined}\n onItemDrop={dropOnRow ? handleItemDrop : undefined}\n shouldAcceptItemDrop={dropOnRow ? shouldAcceptItemDrop : undefined}\n renderPreview={getItemDragInfo ? renderDragPreview : undefined}\n >\n {(dragState, dropState, collectionProps) =>\n renderTable(dragState, dropState, collectionProps)\n }\n </DraggableCollection>\n ) : (\n renderTable()\n );\n\n // The provider always wraps, so `ItemTable.Search` works from a custom\n // `toolbar` as well as from the built-in one.\n return (\n <ItemTableChromeProvider\n value={{\n searchValue,\n setSearchValue,\n searchPlaceholder,\n isLoading,\n onRefresh,\n selectedKeys: selection.selectedKeys,\n selectedRows: selection.selectedRows,\n selectedCount: selection.selectedCount,\n clearSelection: selection.clearSelection,\n }}\n >\n {table}\n </ItemTableChromeProvider>\n );\n}\n\nconst _ItemTable = Object.assign(\n forwardRef(ItemTable) as unknown as (<T = any>(\n props: CubeItemTableProps<T> & { ref?: ForwardedRef<HTMLDivElement> },\n ) => ReactElement) & { displayName?: string },\n {\n /** The table's search input, bound to the table's own state. */\n Search: ItemTableSearch,\n /** The default toolbar row, for rebuilding it around extra content. */\n Toolbar: ItemTableToolbar,\n /** The selection action bar, for placing it outside the default chrome. */\n BulkBar: ItemTableBulkBar,\n },\n);\n\n_ItemTable.displayName = 'ItemTable';\n\nexport { _ItemTable as ItemTable };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,MAAM,eAAuC,EAAE;AAE/C,SAAS,iBAAoB,QAAgB;AAC3C,SAAQ,KAAQ,UAAuB;EACrC,MAAM,QAAS,MAAc;AAE7B,SAAO,SAAS,OAAO,QAAS;;;AAIpC,SAAS,UACP,OACA,KACc;CACd,MAAM,EACJ,MACA,SACA,SAAS,MACT,WACA,YAAY,OACZ,mBAAmB,WACnB,eACA,aACA,SACA,aACA,SACA,iBAAiB,OACjB,iBACA,qBACA,mBAAmB,YACnB,eACA,cAAc,kBACd,qBACA,mBACA,gBAAgB,QAChB,iBACA,kBACA,cACA,mBAAmB,GACnB,YACA,gBACA,OACA,YACA,SACA,eAAe,OACf,aAAa,UACb,mBACA,aAAa,iBACb,oBACA,gBACA,cAAc,KACd,cACA,SACA,SACA,WACA,iBAAiB,UACjB,UAAU,cACV,kBAAkB,IAClB,qBAAqB,MACrB,YACA,SACA,eACA,gBACA,YACA,SACA,gBAAgB,OAChB,WACA,WACA,iBACA,cAAc,OACd,cAAc,kBACd,qBACA,gBACA,mBACA,oBACA,wBACA,iBACA,kBACA,kBAAkB;EAAC;EAAI;EAAI;EAAI;EAAK;EAAI,EACxC,MAAM,UACN,aACA,cACA,OAAO,WACP,YACA,aACA,UAAU,MACV,QACA,aACA,cACA,WACA,UACA,MAAM,UACN,aACA,cACA,QAAQ,SACR,OAAO,UACP,WACA,cACA,YAAY,OACZ,iBAAiB,OACjB,iBAAiB,MACjB,gBAAgB,QAChB,sBAAsB,IACtB,WAAW,IACX,aACA,WACA,IACA,MACA,QACA,cACA,kBACA,eAAe,MACf,eACA,cACA,cACA,YACA,WACA,YACA,sBACE;CAEJ,MAAM,EAAE,MAAM,SAAS;CAGvB,MAAM,UAAU,gBAAgB,KADf,OAAuB,KAAK,CACC;CAK9C,MAAM,CAAC,YAAY,iBAAiB,SAAgC,KAAK;CACzE,MAAM,iBAAiB,kBAAkB,WAAW;CAKpD,MAAM,aAAa;EAAE,GAAG,cAAc,OAAO,iBAAiB;EAAE,GAAG;EAAQ;CAE3E,MAAM,EACJ,aACA,gBACA,cACA,YAAY,gBACV,eAAkB;EACpB;EACA,MAAM;EACN,MAAM;EACN,OAAO;EACP,cAAc;EACd,UAAU;EACV,OAAO;EACP,QAAQ;EACT,CAAC;CAEF,MAAM,UAAU,gBAAgB,YAAY,QAAQ;CAEpD,MAAM,EACJ,MACA,YACA,YACA,eACA,MAAM,qBACJ,aAAgB;EAClB;EACA,MAAM;EACN,MAAM;EACN,MAAM;EAGN,aACE,aAAa,UAAa,QAAQ,IAAI,OAAO,GACzC,QAAQ,QAAQ,QAAQ,cACxB;EACN,cAAc,UAAU,SAA+B;AACrD,OAAI,aAAa,OAAW,SAAQ,MAAM,EAAE,MAAM,MAAM,CAAC;AACzD,kBAAe,KAAK;IACpB;EACH,CAAC;CAQF,MAAM,CAAC,UAAU,oBAAoB,mBACnC,cACA,iBAAiB,UAAa,QAAQ,IAAI,WAAW,GACjD,QAAQ,QAAQ,YAAY,kBAC5B,iBACJ,iBACD;CACD,MAAM,CAAC,MAAM,gBAAgB,mBAC3B,UACA,eAAe,GACf,aACD;CAED,MAAM,aAAa,mBAAmB;CAEtC,MAAM,cAAc,mBAAmB,SAAS,CAAC;CACjD,MAAM,oBAAoB,mBAAmB;CAC7C,MAAM,QAAQ,oBAAoB,aAAa,IAAI,WAAW;CAE9D,MAAM,WAAW,YAAY;EAC3B;EACA;EACA;EACA,YAAY,oBAAoB,aAAa;EAC9C,CAAC;CAEF,MAAM,UAAU,UAAU,SACxB,aAAa,UAAU,MAAM,SAAS,WAAW,CAAC,CACnD;CACD,MAAM,cAAc,UAAU,SAAiB;AAC7C,mBAAiB,KAAK;AAEtB,MAAI,iBAAiB,OAAW,SAAQ,MAAM,EAAE,UAAU,MAAM,CAAC;AAIjE,eAAa,EAAE;GACf;CAEF,MAAM,cACJ,mBAAmB,WACf,WAAW,OACR,SAAS,OAAO,KAAK,UACtB,SAAS,OAAO,SACjB,GACD;CAEN,MAAM,oBAAoB,cAClB,aAAa,iBAAoB,OAAO,EAC9C,CAAC,WAAW,OAAO,CACpB;CAID,MAAM,wBACJ,kBAAkB,aAAa,SAAS,aAAa;CAEvD,MAAM,YAAY,kBAAqB;EACrC,MAAM;EAIN,cAAc,mBAAmB,WAAW,aAAa;EACzD,WAAW;EACX,eAAe;EACf,cAAc;EACd;EACA;EACA;EACA;EACA;EACD,CAAC;CAIF,MAAM,iBAAiB,cAEnB,WAAW,OACP,SACA,OAAO,YAAY,aAChB,gBAIK,SACd,CAAC,QAAQ,CACV;CAED,MAAM,kBAAkB,cAEpB,kBAAkB,mBAAmB,OACjC,CACE;EACE,KAAK;EACL,OACE,sBAAsB,SAAS,sBAAsB;EACvD,OAAO;EACR,CACF,GACD,QACN;EAAC;EAAgB;EAAgB;EAAK,CACvC;CAED,MAAM,iBAAiB,cAEnB,UAAU,YACN,CACE;EACE,KAAK;EACL,OACE,uBAAuB,SAAS,uBAAuB;EACzD,OAAO;EACR,CACF,GACD,QACN,CAAC,UAAU,WAAW,KAAK,CAC5B;;;;;;;;;CAUD,MAAM,CAAC,iBAAiB,sBAAsB,gBAIzC,qBAAqB,UAAa,QAAQ,IAAI,eAAe,GAC1D,QAAQ,QAAQ,gBAAgB,sBAChC,wBAAwB,aAC/B;CACD,MAAM,CAAC,mBAAmB,wBAAwB,SAGxC,KAAK;;;;;;;;;CAUf,MAAM,uBAAuB,OAAsC,KAAK;CAExE,MAAM,mBAAmB,oBAAoB;CAC7C,MAAM,eAAe,qBAAqB;;CAG1C,MAAM,YAAY,OAAwC,KAAK;CAE/D,MAAM,qBAAqB,UAAU,KAAa,UAAkB;AAOlE,uBAAqB,UAAU;GAAE,GAH/B,qBAAqB,WACrB,mBAAmB,UAAU,SAAS,iBAAiB;IAEd,MAAM,KAAK,MAAM,MAAM;GAAE;AACpE,uBAAqB,qBAAqB,QAAQ;GAClD;CAIF,MAAM,wBAAwB,UAAU,QAAgB;EACtD,MAAM,OAAO,qBAAqB,WAAW;AAE7C,MAAI,qBAAqB,QAAW;AAClC,sBAAmB,KAAK;AACxB,WAAQ,MAAM,EAAE,cAAc,MAAM,CAAC;;AAGvC,mBAAiB,KAAK,KAAK,MAAM,KAAK;AAKtC,uBAAqB,UAAU;AAC/B,uBAAqB,KAAK;GAC1B;CAEF,MAAM,SAAS,gBAAmB;EAChC;EACA;EACA;EACA;EACA;EACD,CAAC;AAEF,WAAU,UAAU;CAOpB,MAAM,UAJJ,eAAe,QACf,YAAY,SAAS,KACrB,UAAU,gBAAgB,IAG1B,oBAAC;EACC,SAAS;EACT,WAAW;EACX,QAAQ;GACR,GACA;CAEJ,MAAM,qBAAqB,WAAW,QAAQ,qBAAqB;CAUnE,MAAM,cAPJ,YAAY,UACZ,gBACA,WAAW,QACX,WAAW,QACX,aAAa,QACb,qBAGE,WACE,oBAAC;EACe;EACL;EAIT,SAAS,qBAAqB,UAAU;EAC7B;EACX,QAAQ;EACM;EACH;GACX,GAEJ;;;;;;;;;;CAWJ,MAAM,mBAAmB,iBAAiB,SACtC,KAAK,IAAI,GAAG,gBAAgB,GAC5B;CAEJ,MAAM,sBACJ,sBACA,CAAC,eACD,SAAS,cAAc,KACvB,SAAS;CAEX,MAAM,iBAAiB,eAAe,CAAC;CASvC,MAAM,aANJ,WAAW,UACX,kBACA,eAAe,QACf,gBAAgB,QAChB,aAAa,OAGX,UACE,oBAAC;EACC,OAAO;EACP,QAAQ;EACR,KAAK;EACL,QAAQ;EACR,YACE,iBACI;GACE,MAAM,SAAS;GACf;GACA;GACA,YAAY,SAAS;GACrB;GACA;GACA;GACA,cAAc;GACd,kBAAkB;GACnB,GACD;GAEN,GAEJ;CAEJ,MAAM,UAAU,OAAgC,KAAK;CAErD,MAAM,UAAU,cAEZ,YAAY,KAAK,KAAK,UAAU,OAAO,kBAAkB,KAAK,MAAM,CAAC,CAAC,EACxE,CAAC,aAAa,kBAAkB,CACjC;CAED,MAAM,gBAAgB,UAAU,aAAuB;EACrD,MAAM,QAAQ,IAAI,IAChB,YAAY,KAAK,KAAK,UAAU,CAC9B,OAAO,kBAAkB,KAAK,MAAM,CAAC,EACrC,IACD,CAAC,CACH;AAED,cACE,UACA,SACG,KAAK,QAAQ,MAAM,IAAI,IAAI,CAAC,CAC5B,QAAQ,QAAkB,QAAQ,OAAU,CAChD;GACD;;;;;;;;;;CAWF,MAAM,eACJ,WACA,WACA,oBAEA,oBAAC;EACU;EACE;EACA;EACM;EACR;EACT,IAAI,MAAM;EACV,MAAM;EAMN,gBAAgB,eAAe,SAAS,OAAO,KAAK,WAAW;EAC/D,eAAe;EACf,WAAW;EACH;EACR,eAAe;EACT;EACC;EACI;EACG;EACE;EACA;EACD;EACM;EACX;EACC;EACQ;EACR;EACO;EACP;EACO;EACT;EACI;EACb,YAAY,aAAa,aAAa;EAC7B;EACM;EACC;EAChB,eAAe;EACF;EACb,gBAAgB;EAChB,mBAAmB;EACnB,SAAS;EACO;EACC;EACI;EACH;EAClB,YAAY,cAAc,EAAE,qBAAqB,WAAW;EAC5D,gBACE,kBAAkB,EAAE,uBAAuB,mBAAmB;EAEzD;EACP,SAAS;EACT,QAAQ;EACR,YAAY,cAAc;EAC1B,UAAU;EACJ;EACN,cAAc;EACd,oBAAoB;EACD;EACC;EACI;EACP;EACJ;EACF;EACX,QAAQ;EACM;EACI;EACJ;EACF;EACD;EACC;EACN;EACN,SAAS,qBAAqB,aAAa,UAAU;GACrD;CAGJ,MAAM,kBAAkB,cAAc;EACpC,MAAM,sBAAM,IAAI,KAAgB;AAEhC,cAAY,SAAS,KAAK,UACxB,IAAI,IAAI,OAAO,kBAAkB,KAAK,MAAM,CAAC,EAAE,IAAI,CACpD;AAED,SAAO;IACN,CAAC,aAAa,kBAAkB,CAAC;CAEpC,MAAM,iBAAiB,UAAU,WAAgB,gBAAuB;AACtE,MAAI,CAAC,UAAW;EAEhB,MAAM,SAAS,gBAAgB,IAAI,OAAO,UAAU,CAAC;AAErD,MAAI,CAAC,OAAQ;EAEb,MAAM,UAAU,YACb,KAAK,QAAQ,gBAAgB,IAAI,OAAO,IAAI,CAAC,CAAC,CAE9C,QAAQ,QAAkB,QAAQ,UAAa,QAAQ,OAAO;AAEjE,MAAI,CAAC,QAAQ,OAAQ;AACrB,MAAI,UAAU,aAAa,CAAC,UAAU,UAAU,SAAS,OAAO,CAAE;AAElE,EAAK,UAAU,OAAO,SAAS,OAAO;GACtC;CAEF,MAAM,oBAAoB,UAAU,SAClC,oBAAC;EACC,MAAM,KACH,KAAK,QAAQ,gBAAgB,IAAI,OAAO,IAAI,CAAC,CAAC,CAC9C,QAAQ,QAAkB,QAAQ,OAAU;EAC9B;GACjB,CACF;CAEF,MAAM,uBAAuB,UAAU,cAAmB;EACxD,MAAM,SAAS,gBAAgB,IAAI,OAAO,UAAU,CAAC;AAErD,SAAO,UAAU,SAAS,WAAW,SAAS,OAAO,IAAI;GACzD;CAGF,MAAM,gBAAgB,iBAAiB,aAAa;CAEpD,MAAM,QAAQ,gBACZ,oBAAC;EACC,OAAO;GACL,YAAY,UAAU;GACtB,kBAAkB,UAAU;GAC5B,cAAc,IAAI,IAAI,gBAAgB,EAAE,CAAC;GAC1C;EAKD,SAAS;EACT,aAAa;EACb,aAAY;EACZ,WAAW,gBAAgB,gBAAgB;EAC3C,YAAY,YAAY,iBAAiB;EACzC,sBAAsB,YAAY,uBAAuB;EACzD,eAAe,kBAAkB,oBAAoB;aAEnD,WAAW,WAAW,oBACtB,YAAY,WAAW,WAAW,gBAAgB;GAEhC,GAEtB,aAAa;AAKf,QACE,oBAAC;EACC,OAAO;GACL;GACA;GACA;GACA;GACA;GACA,cAAc,UAAU;GACxB,cAAc,UAAU;GACxB,eAAe,UAAU;GACzB,gBAAgB,UAAU;GAC3B;YAEA;GACuB;;AAI9B,MAAM,aAAa,OAAO,OACxB,WAAW,UAAU,EAGrB;CAEE,QAAQ;CAER,SAAS;CAET,SAAS;CACV,CACF;AAED,WAAW,cAAc"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.159.0 | Cube Dev Team */
|
|
2
2
|
import { useEvent } from "../../../_internal/hooks/use-event.js";
|
|
3
3
|
import { _Text } from "../../content/Text.js";
|
|
4
|
-
import { TooltipProvider } from "../../overlays/Tooltip/TooltipProvider.js";
|
|
5
4
|
import { useI18n } from "../../../i18n/useI18n.js";
|
|
6
5
|
import { CloseIcon } from "../../../icons/CloseIcon.js";
|
|
7
6
|
import { Button } from "../../actions/index.js";
|
|
@@ -100,20 +99,17 @@ function ItemTableBulkBar(props) {
|
|
|
100
99
|
}),
|
|
101
100
|
actions.map((action) => {
|
|
102
101
|
const isDisabled = action.isDisabled?.(selectedRows) ?? false;
|
|
103
|
-
|
|
102
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
104
103
|
size: "small",
|
|
105
104
|
type: action.type ?? "outline",
|
|
106
105
|
theme: action.theme,
|
|
107
106
|
icon: action.icon,
|
|
108
107
|
isDisabled,
|
|
109
108
|
isLoading: loadingKeys[action.key],
|
|
109
|
+
tooltip: isDisabled && action.disabledTooltip ? action.disabledTooltip : void 0,
|
|
110
110
|
onPress: () => run(action),
|
|
111
111
|
children: action.label
|
|
112
112
|
}, action.key);
|
|
113
|
-
return isDisabled && action.disabledTooltip ? /* @__PURE__ */ jsx(TooltipProvider, {
|
|
114
|
-
title: action.disabledTooltip,
|
|
115
|
-
children: button
|
|
116
|
-
}, action.key) : button;
|
|
117
113
|
}),
|
|
118
114
|
/* @__PURE__ */ jsx(Button, {
|
|
119
115
|
size: "small",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ItemTableBulkBar.js","names":["Text"],"sources":["../../../../src/components/data/ItemTable/ItemTableBulkBar.tsx"],"sourcesContent":["import { tasty } from '@tenphi/tasty';\nimport { useState } from 'react';\n\nimport { useEvent } from '../../../_internal/hooks';\nimport { useI18n } from '../../../i18n';\nimport { CloseIcon } from '../../../icons';\nimport { Button } from '../../actions';\nimport { Text } from '../../content/Text';\
|
|
1
|
+
{"version":3,"file":"ItemTableBulkBar.js","names":["Text"],"sources":["../../../../src/components/data/ItemTable/ItemTableBulkBar.tsx"],"sourcesContent":["import { tasty } from '@tenphi/tasty';\nimport { useState } from 'react';\n\nimport { useEvent } from '../../../_internal/hooks';\nimport { useI18n } from '../../../i18n';\nimport { CloseIcon } from '../../../icons';\nimport { Button } from '../../actions';\nimport { Text } from '../../content/Text';\n\nimport { useItemTableChrome } from './ItemTableToolbar';\n\nimport type { Styles } from '@tenphi/tasty';\nimport type { CubeTableBulkAction } from './types';\n\nconst BarElement = tasty({\n qa: 'ItemTableBulkBar',\n as: 'div',\n styles: {\n display: 'flex',\n flow: 'row',\n gap: '1x',\n placeItems: 'center',\n boxSizing: 'border-box',\n\n /**\n * `floating` lifts the bar out of the grid and centres it over the body, so\n * it never changes the table's height — a bar that pushed the rows down\n * would move the very row the user is about to click.\n */\n position: { '': 'static', floating: 'absolute' },\n inset: { '': 'auto', floating: 'auto auto 2x 50%' },\n translate: { '': false, floating: '-50% 0' },\n zIndex: { '': 'auto', floating: 10 },\n // A raised surface rather than an inverted \"toast\": `#dark` flips to a light\n // colour under the dark theme, which would put white text on a light bar.\n fill: { '': '#clear', floating: '#surface' },\n color: '#surface-text',\n border: { '': false, floating: true },\n radius: { '': 0, floating: '1cr' },\n shadow: { '': false, floating: '0 1x 3x #shadow' },\n padding: { '': 0, floating: '1x 1.5x' },\n width: { '': 'auto', floating: 'max (100% - 4x)' },\n },\n});\n\nexport interface ItemTableBulkBarProps<T = any> {\n actions: CubeTableBulkAction<T>[];\n /** @default 'floating' */\n placement?: 'floating' | 'toolbar';\n styles?: Styles;\n}\n\n/**\n * The action bar shown while rows are selected.\n *\n * Reads the selection from context rather than props, so a consumer rebuilding\n * the toolbar can drop `<ItemTable.BulkBar>` wherever it likes and still have\n * one owner of the selection.\n */\nexport function ItemTableBulkBar<T = any>(props: ItemTableBulkBarProps<T>) {\n const { actions, placement = 'floating', styles } = props;\n const { t } = useI18n();\n const chrome = useItemTableChrome('ItemTable.BulkBar');\n const { selectedRows, selectedCount, clearSelection } = chrome;\n\n // Per-action, so one slow request cannot disable the others.\n const [loadingKeys, setLoadingKeys] = useState<Record<string, boolean>>({});\n\n const run = useEvent(async (action: CubeTableBulkAction<T>) => {\n const setLoading = (value: boolean) =>\n setLoadingKeys((current) => ({ ...current, [action.key]: value }));\n\n try {\n await action.onAction(selectedRows as T[], { setLoading });\n\n // Deselecting is the default because the rows an action just deleted or\n // moved are usually gone; an action that only reads keeps the selection\n // by opting out.\n if (action.deselectAfter !== false) clearSelection();\n } finally {\n setLoading(false);\n }\n });\n\n if (selectedCount === 0) return null;\n\n return (\n <BarElement\n role=\"toolbar\"\n aria-label={t('itemTable.bulkActions', 'Bulk actions')}\n styles={styles}\n mods={{ floating: placement === 'floating' }}\n >\n <Text nowrap>\n {t('itemTable.selectedCount', '{{count}} selected', {\n count: selectedCount,\n })}\n </Text>\n\n {actions.map((action) => {\n const isDisabled = action.isDisabled?.(selectedRows as T[]) ?? false;\n\n return (\n <Button\n key={action.key}\n size=\"small\"\n type={action.type ?? 'outline'}\n theme={action.theme}\n icon={action.icon}\n isDisabled={isDisabled}\n isLoading={loadingKeys[action.key]}\n // The button's own prop rather than a wrapping `TooltipProvider`:\n // that is what lets it stay hoverable while disabled, which is the\n // only state this tooltip is shown in.\n tooltip={\n isDisabled && action.disabledTooltip\n ? action.disabledTooltip\n : undefined\n }\n onPress={() => run(action)}\n >\n {action.label}\n </Button>\n );\n })}\n\n <Button\n size=\"small\"\n type=\"clear\"\n icon={<CloseIcon />}\n aria-label={t('itemTable.clearSelection', 'Clear selection')}\n onPress={clearSelection}\n />\n </BarElement>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAcA,MAAM,aAAa,MAAM;CACvB,IAAI;CACJ,IAAI;CACJ,QAAQ;EACN,SAAS;EACT,MAAM;EACN,KAAK;EACL,YAAY;EACZ,WAAW;EAOX,UAAU;GAAE,IAAI;GAAU,UAAU;GAAY;EAChD,OAAO;GAAE,IAAI;GAAQ,UAAU;GAAoB;EACnD,WAAW;GAAE,IAAI;GAAO,UAAU;GAAU;EAC5C,QAAQ;GAAE,IAAI;GAAQ,UAAU;GAAI;EAGpC,MAAM;GAAE,IAAI;GAAU,UAAU;GAAY;EAC5C,OAAO;EACP,QAAQ;GAAE,IAAI;GAAO,UAAU;GAAM;EACrC,QAAQ;GAAE,IAAI;GAAG,UAAU;GAAO;EAClC,QAAQ;GAAE,IAAI;GAAO,UAAU;GAAmB;EAClD,SAAS;GAAE,IAAI;GAAG,UAAU;GAAW;EACvC,OAAO;GAAE,IAAI;GAAQ,UAAU;GAAmB;EACnD;CACF,CAAC;;;;;;;;AAgBF,SAAgB,iBAA0B,OAAiC;CACzE,MAAM,EAAE,SAAS,YAAY,YAAY,WAAW;CACpD,MAAM,EAAE,MAAM,SAAS;CAEvB,MAAM,EAAE,cAAc,eAAe,mBADtB,mBAAmB,oBAAoB;CAItD,MAAM,CAAC,aAAa,kBAAkB,SAAkC,EAAE,CAAC;CAE3E,MAAM,MAAM,SAAS,OAAO,WAAmC;EAC7D,MAAM,cAAc,UAClB,gBAAgB,aAAa;GAAE,GAAG;IAAU,OAAO,MAAM;GAAO,EAAE;AAEpE,MAAI;AACF,SAAM,OAAO,SAAS,cAAqB,EAAE,YAAY,CAAC;AAK1D,OAAI,OAAO,kBAAkB,MAAO,iBAAgB;YAC5C;AACR,cAAW,MAAM;;GAEnB;AAEF,KAAI,kBAAkB,EAAG,QAAO;AAEhC,QACE,qBAAC;EACC,MAAK;EACL,cAAY,EAAE,yBAAyB,eAAe;EAC9C;EACR,MAAM,EAAE,UAAU,cAAc,YAAY;;GAE5C,oBAACA;IAAK;cACH,EAAE,2BAA2B,sBAAsB,EAClD,OAAO,eACR,CAAC;KACG;GAEN,QAAQ,KAAK,WAAW;IACvB,MAAM,aAAa,OAAO,aAAa,aAAoB,IAAI;AAE/D,WACE,oBAAC;KAEC,MAAK;KACL,MAAM,OAAO,QAAQ;KACrB,OAAO,OAAO;KACd,MAAM,OAAO;KACD;KACZ,WAAW,YAAY,OAAO;KAI9B,SACE,cAAc,OAAO,kBACjB,OAAO,kBACP;KAEN,eAAe,IAAI,OAAO;eAEzB,OAAO;OAjBH,OAAO,IAkBL;KAEX;GAEF,oBAAC;IACC,MAAK;IACL,MAAK;IACL,MAAM,oBAAC,cAAY;IACnB,cAAY,EAAE,4BAA4B,kBAAkB;IAC5D,SAAS;KACT;;GACS"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.159.0 | Cube Dev Team */
|
|
2
2
|
import { _Text } from "../../content/Text.js";
|
|
3
3
|
import { useI18n } from "../../../i18n/useI18n.js";
|
|
4
4
|
import { tasty } from "@tenphi/tasty";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.159.0 | Cube Dev Team */
|
|
2
2
|
import { _Pagination } from "../../navigation/Pagination/Pagination.js";
|
|
3
3
|
import { tasty } from "@tenphi/tasty";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.159.0 | Cube Dev Team */
|
|
2
2
|
import { useI18n } from "../../../i18n/useI18n.js";
|
|
3
3
|
import { ReloadIcon } from "../../../icons/ReloadIcon.js";
|
|
4
4
|
import { Button } from "../../actions/index.js";
|
|
@@ -279,6 +279,25 @@ interface CubeItemTableProps<T = any> extends BaseProps, ContainerStyleProps {
|
|
|
279
279
|
defaultColumnWidths?: Record<string, number>;
|
|
280
280
|
/** Fires once the drag or key press finishes, not on every pixel. */
|
|
281
281
|
onColumnResize?: (columnKey: string, width: number, all: Record<string, number>) => void;
|
|
282
|
+
/**
|
|
283
|
+
* Where a column's `header.menu` is exposed.
|
|
284
|
+
*
|
|
285
|
+
* - `true` — a `⋮` trigger in the header, plus right-click and Shift+F10.
|
|
286
|
+
* - `'context-only'` — right-click and Shift+F10 only, no trigger.
|
|
287
|
+
* - `false` — suppressed entirely.
|
|
288
|
+
*
|
|
289
|
+
* @default true
|
|
290
|
+
*/
|
|
291
|
+
columnContextMenu?: boolean | 'context-only';
|
|
292
|
+
/**
|
|
293
|
+
* The key of the pressed `Menu.Item`, as written — no `.$` prefix.
|
|
294
|
+
*
|
|
295
|
+
* Fires for the reserved sort keys too (`sort-asc`, `sort-desc`,
|
|
296
|
+
* `clear-sort`), after the table has already applied them.
|
|
297
|
+
*/
|
|
298
|
+
onColumnMenuAction?: (action: string, columnKey: string) => void;
|
|
299
|
+
columnMenuTriggerProps?: Record<string, any>;
|
|
300
|
+
columnMenuProps?: Record<string, any>;
|
|
282
301
|
/**
|
|
283
302
|
* Persists the table's own state under `cube-ui-kit:table:${storageKey}`.
|
|
284
303
|
* Controlled state is never stored — it belongs to the page.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.159.0 | Cube Dev Team */
|
|
2
2
|
import { mergeProps as mergeProps$1 } from "../../../utils/react/mergeProps.js";
|
|
3
3
|
import { useEvent } from "../../../_internal/hooks/use-event.js";
|
|
4
4
|
import { useRef } from "react";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.159.0 | Cube Dev Team */
|
|
2
2
|
//#region src/components/data/TableBase/RowCollection.ts
|
|
3
3
|
/**
|
|
4
4
|
* A `Collection<Node<T>>` over a plain row array.
|
|
@@ -20,10 +20,12 @@ var RowCollection = class {
|
|
|
20
20
|
indexByKey;
|
|
21
21
|
nodeCache = /* @__PURE__ */ new Map();
|
|
22
22
|
disabledKeys;
|
|
23
|
-
|
|
23
|
+
getItemText;
|
|
24
|
+
constructor(rows, getKey, disabledKeys = /* @__PURE__ */ new Set(), getItemText) {
|
|
24
25
|
this.rows = rows;
|
|
25
26
|
this.keys = rows.map(getKey);
|
|
26
27
|
this.disabledKeys = disabledKeys;
|
|
28
|
+
this.getItemText = getItemText;
|
|
27
29
|
this.indexByKey = /* @__PURE__ */ new Map();
|
|
28
30
|
this.keys.forEach((key, index) => {
|
|
29
31
|
if (!this.indexByKey.has(key)) this.indexByKey.set(key, index);
|
|
@@ -48,7 +50,7 @@ var RowCollection = class {
|
|
|
48
50
|
hasChildNodes: false,
|
|
49
51
|
childNodes: [],
|
|
50
52
|
rendered: null,
|
|
51
|
-
textValue: "",
|
|
53
|
+
textValue: this.getItemText?.(this.rows[index]) ?? "",
|
|
52
54
|
index,
|
|
53
55
|
"aria-label": void 0,
|
|
54
56
|
parentKey: null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RowCollection.js","names":[],"sources":["../../../../src/components/data/TableBase/RowCollection.ts"],"sourcesContent":["import type { Collection, Key, Node } from '@react-types/shared';\n\n/**\n * A `Collection<Node<T>>` over a plain row array.\n *\n * React Aria's selection primitives — `SelectionManager`, `useSelectableItem`,\n * `useSelectableCollection` — need a collection, but the only thing they ask of\n * it is key order and lookup. `useTableState` would build a `Node` per header\n * row, per column, per body row *and per cell*, which a table whose page size\n * goes to 500 (and whose \"Load all results\" removes the cap entirely) cannot\n * afford.\n *\n * So the array is the collection. Nodes are built lazily on `getItem` and\n * memoized, which means a 100k-row table allocates nodes only for the handful\n * of keys selection actually touches.\n */\nexport class RowCollection<T> implements Collection<Node<T>> {\n private rows: readonly T[];\n private keys: Key[];\n private indexByKey: Map<Key, number>;\n private nodeCache = new Map<Key, Node<T>>();\n private disabledKeys: Set<Key>;\n\n constructor(\n rows: readonly T[],\n getKey: (row: T, index: number) => Key,\n disabledKeys: Set<Key> = new Set(),\n ) {\n this.rows = rows;\n this.keys = rows.map(getKey);\n this.disabledKeys = disabledKeys;\n this.indexByKey = new Map();\n\n // A duplicate key would make selection ambiguous — two rows would answer to\n // the same identity. First occurrence wins, matching how React resolves a\n // duplicated `key`.\n this.keys.forEach((key, index) => {\n if (!this.indexByKey.has(key)) this.indexByKey.set(key, index);\n });\n }\n\n get size() {\n return this.rows.length;\n }\n\n getKeys() {\n return this.keys;\n }\n\n getItem(key: Key): Node<T> | null {\n const index = this.indexByKey.get(key);\n\n if (index == null) return null;\n\n const cached = this.nodeCache.get(key);\n\n if (cached) return cached;\n\n const node: Node<T> = {\n type: 'item',\n key,\n value: this.rows[index],\n level: 0,\n hasChildNodes: false,\n childNodes: [],\n rendered: null,\n textValue: '',\n index,\n // `SelectionManager` reads this to decide whether a key can be selected\n // at all, before `disabledBehavior` is even considered.\n 'aria-label': undefined,\n parentKey: null,\n prevKey: index > 0 ? this.keys[index - 1] : null,\n nextKey: index < this.keys.length - 1 ? this.keys[index + 1] : null,\n } as Node<T>;\n\n this.nodeCache.set(key, node);\n\n return node;\n }\n\n at(index: number): Node<T> | null {\n const key = this.keys[index];\n\n return key == null ? null : this.getItem(key);\n }\n\n getKeyBefore(key: Key): Key | null {\n const index = this.indexByKey.get(key);\n\n return index == null || index === 0 ? null : this.keys[index - 1];\n }\n\n getKeyAfter(key: Key): Key | null {\n const index = this.indexByKey.get(key);\n\n return index == null || index >= this.keys.length - 1\n ? null\n : this.keys[index + 1];\n }\n\n getFirstKey(): Key | null {\n return this.keys[0] ?? null;\n }\n\n getLastKey(): Key | null {\n return this.keys[this.keys.length - 1] ?? null;\n }\n\n getChildren(): Iterable<Node<T>> {\n return [];\n }\n\n /** Not part of `Collection`, but selection asks about it constantly. */\n isDisabled(key: Key) {\n return this.disabledKeys.has(key);\n }\n\n indexOf(key: Key): number {\n return this.indexByKey.get(key) ?? -1;\n }\n\n *[Symbol.iterator](): Iterator<Node<T>> {\n for (const key of this.keys) {\n const node = this.getItem(key);\n\n if (node) yield node;\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,IAAa,gBAAb,MAA6D;CAC3D,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ,4BAAY,IAAI,KAAmB;CAC3C,AAAQ;CAER,YACE,MACA,QACA,+BAAyB,IAAI,KAAK,
|
|
1
|
+
{"version":3,"file":"RowCollection.js","names":[],"sources":["../../../../src/components/data/TableBase/RowCollection.ts"],"sourcesContent":["import type { Collection, Key, Node } from '@react-types/shared';\n\n/**\n * A `Collection<Node<T>>` over a plain row array.\n *\n * React Aria's selection primitives — `SelectionManager`, `useSelectableItem`,\n * `useSelectableCollection` — need a collection, but the only thing they ask of\n * it is key order and lookup. `useTableState` would build a `Node` per header\n * row, per column, per body row *and per cell*, which a table whose page size\n * goes to 500 (and whose \"Load all results\" removes the cap entirely) cannot\n * afford.\n *\n * So the array is the collection. Nodes are built lazily on `getItem` and\n * memoized, which means a 100k-row table allocates nodes only for the handful\n * of keys selection actually touches.\n */\nexport class RowCollection<T> implements Collection<Node<T>> {\n private rows: readonly T[];\n private keys: Key[];\n private indexByKey: Map<Key, number>;\n private nodeCache = new Map<Key, Node<T>>();\n private disabledKeys: Set<Key>;\n\n private getItemText?: (row: T) => string;\n\n constructor(\n rows: readonly T[],\n getKey: (row: T, index: number) => Key,\n disabledKeys: Set<Key> = new Set(),\n /**\n * The item's accessible name, for screen-reader drag announcements.\n *\n * Without it `useDropIndicator` says \"Insert between and \" — React Aria\n * builds that string from `node.textValue`. Optional because selection, the\n * original caller, never reads it.\n */\n getItemText?: (row: T) => string,\n ) {\n this.rows = rows;\n this.keys = rows.map(getKey);\n this.disabledKeys = disabledKeys;\n this.getItemText = getItemText;\n this.indexByKey = new Map();\n\n // A duplicate key would make selection ambiguous — two rows would answer to\n // the same identity. First occurrence wins, matching how React resolves a\n // duplicated `key`.\n this.keys.forEach((key, index) => {\n if (!this.indexByKey.has(key)) this.indexByKey.set(key, index);\n });\n }\n\n get size() {\n return this.rows.length;\n }\n\n getKeys() {\n return this.keys;\n }\n\n getItem(key: Key): Node<T> | null {\n const index = this.indexByKey.get(key);\n\n if (index == null) return null;\n\n const cached = this.nodeCache.get(key);\n\n if (cached) return cached;\n\n const node: Node<T> = {\n type: 'item',\n key,\n value: this.rows[index],\n level: 0,\n hasChildNodes: false,\n childNodes: [],\n rendered: null,\n textValue: this.getItemText?.(this.rows[index]) ?? '',\n index,\n // `SelectionManager` reads this to decide whether a key can be selected\n // at all, before `disabledBehavior` is even considered.\n 'aria-label': undefined,\n parentKey: null,\n prevKey: index > 0 ? this.keys[index - 1] : null,\n nextKey: index < this.keys.length - 1 ? this.keys[index + 1] : null,\n } as Node<T>;\n\n this.nodeCache.set(key, node);\n\n return node;\n }\n\n at(index: number): Node<T> | null {\n const key = this.keys[index];\n\n return key == null ? null : this.getItem(key);\n }\n\n getKeyBefore(key: Key): Key | null {\n const index = this.indexByKey.get(key);\n\n return index == null || index === 0 ? null : this.keys[index - 1];\n }\n\n getKeyAfter(key: Key): Key | null {\n const index = this.indexByKey.get(key);\n\n return index == null || index >= this.keys.length - 1\n ? null\n : this.keys[index + 1];\n }\n\n getFirstKey(): Key | null {\n return this.keys[0] ?? null;\n }\n\n getLastKey(): Key | null {\n return this.keys[this.keys.length - 1] ?? null;\n }\n\n getChildren(): Iterable<Node<T>> {\n return [];\n }\n\n /** Not part of `Collection`, but selection asks about it constantly. */\n isDisabled(key: Key) {\n return this.disabledKeys.has(key);\n }\n\n indexOf(key: Key): number {\n return this.indexByKey.get(key) ?? -1;\n }\n\n *[Symbol.iterator](): Iterator<Node<T>> {\n for (const key of this.keys) {\n const node = this.getItem(key);\n\n if (node) yield node;\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,IAAa,gBAAb,MAA6D;CAC3D,AAAQ;CACR,AAAQ;CACR,AAAQ;CACR,AAAQ,4BAAY,IAAI,KAAmB;CAC3C,AAAQ;CAER,AAAQ;CAER,YACE,MACA,QACA,+BAAyB,IAAI,KAAK,EAQlC,aACA;AACA,OAAK,OAAO;AACZ,OAAK,OAAO,KAAK,IAAI,OAAO;AAC5B,OAAK,eAAe;AACpB,OAAK,cAAc;AACnB,OAAK,6BAAa,IAAI,KAAK;AAK3B,OAAK,KAAK,SAAS,KAAK,UAAU;AAChC,OAAI,CAAC,KAAK,WAAW,IAAI,IAAI,CAAE,MAAK,WAAW,IAAI,KAAK,MAAM;IAC9D;;CAGJ,IAAI,OAAO;AACT,SAAO,KAAK,KAAK;;CAGnB,UAAU;AACR,SAAO,KAAK;;CAGd,QAAQ,KAA0B;EAChC,MAAM,QAAQ,KAAK,WAAW,IAAI,IAAI;AAEtC,MAAI,SAAS,KAAM,QAAO;EAE1B,MAAM,SAAS,KAAK,UAAU,IAAI,IAAI;AAEtC,MAAI,OAAQ,QAAO;EAEnB,MAAM,OAAgB;GACpB,MAAM;GACN;GACA,OAAO,KAAK,KAAK;GACjB,OAAO;GACP,eAAe;GACf,YAAY,EAAE;GACd,UAAU;GACV,WAAW,KAAK,cAAc,KAAK,KAAK,OAAO,IAAI;GACnD;GAGA,cAAc;GACd,WAAW;GACX,SAAS,QAAQ,IAAI,KAAK,KAAK,QAAQ,KAAK;GAC5C,SAAS,QAAQ,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,QAAQ,KAAK;GAChE;AAED,OAAK,UAAU,IAAI,KAAK,KAAK;AAE7B,SAAO;;CAGT,GAAG,OAA+B;EAChC,MAAM,MAAM,KAAK,KAAK;AAEtB,SAAO,OAAO,OAAO,OAAO,KAAK,QAAQ,IAAI;;CAG/C,aAAa,KAAsB;EACjC,MAAM,QAAQ,KAAK,WAAW,IAAI,IAAI;AAEtC,SAAO,SAAS,QAAQ,UAAU,IAAI,OAAO,KAAK,KAAK,QAAQ;;CAGjE,YAAY,KAAsB;EAChC,MAAM,QAAQ,KAAK,WAAW,IAAI,IAAI;AAEtC,SAAO,SAAS,QAAQ,SAAS,KAAK,KAAK,SAAS,IAChD,OACA,KAAK,KAAK,QAAQ;;CAGxB,cAA0B;AACxB,SAAO,KAAK,KAAK,MAAM;;CAGzB,aAAyB;AACvB,SAAO,KAAK,KAAK,KAAK,KAAK,SAAS,MAAM;;CAG5C,cAAiC;AAC/B,SAAO,EAAE;;;CAIX,WAAW,KAAU;AACnB,SAAO,KAAK,aAAa,IAAI,IAAI;;CAGnC,QAAQ,KAAkB;AACxB,SAAO,KAAK,WAAW,IAAI,IAAI,IAAI;;CAGrC,EAAE,OAAO,YAA+B;AACtC,OAAK,MAAM,OAAO,KAAK,MAAM;GAC3B,MAAM,OAAO,KAAK,QAAQ,IAAI;AAE9B,OAAI,KAAM,OAAM"}
|