@cube-dev/ui-kit 0.164.0 → 0.165.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 +17 -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.d.ts +0 -1
- package/dist/components/actions/Button/Button.js +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.js +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 +1 -1
- package/dist/components/data/DataTable/DataTable.js +140 -21
- package/dist/components/data/DataTable/DataTable.js.map +1 -1
- package/dist/components/data/DataTable/index.d.ts +1 -1
- package/dist/components/data/DataTable/types.d.ts +19 -4
- package/dist/components/data/ItemTable/ItemTable.js +169 -25
- package/dist/components/data/ItemTable/ItemTable.js.map +1 -1
- package/dist/components/data/ItemTable/ItemTableBulkBar.js +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 +7 -2
- package/dist/components/data/TableBase/ColumnResizer.js +1 -1
- package/dist/components/data/TableBase/RowCollection.js +1 -1
- package/dist/components/data/TableBase/TableHeaderCell.js +1 -1
- package/dist/components/data/TableBase/TableRow.js +30 -5
- package/dist/components/data/TableBase/TableRow.js.map +1 -1
- package/dist/components/data/TableBase/TableView.d.ts +2 -1
- package/dist/components/data/TableBase/TableView.js +299 -75
- package/dist/components/data/TableBase/TableView.js.map +1 -1
- package/dist/components/data/TableBase/column-menu.js +1 -1
- package/dist/components/data/TableBase/column-tint.js +1 -1
- package/dist/components/data/TableBase/index.d.ts +1 -1
- package/dist/components/data/TableBase/row-menu.js +1 -1
- package/dist/components/data/TableBase/styled.d.ts +1 -2
- package/dist/components/data/TableBase/styled.js +75 -2
- package/dist/components/data/TableBase/styled.js.map +1 -1
- package/dist/components/data/TableBase/table-tree.js +129 -0
- package/dist/components/data/TableBase/table-tree.js.map +1 -0
- package/dist/components/data/TableBase/types.d.ts +46 -1
- 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.d.ts +0 -1
- package/dist/components/data/TableBase/use-cell-selection.js +0 -0
- package/dist/components/data/TableBase/use-column-order.js +1 -1
- 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 +1 -1
- package/dist/components/data/TableBase/use-table-search.js +4 -4
- package/dist/components/data/TableBase/use-table-search.js.map +1 -1
- package/dist/components/data/TableBase/use-table-selection.js +124 -24
- package/dist/components/data/TableBase/use-table-selection.js.map +1 -1
- package/dist/components/data/TableBase/use-table-sort.js +1 -1
- package/dist/components/data/TableBase/use-table-sorts.js +1 -1
- package/dist/components/data/TableBase/use-table-storage.js +1 -1
- package/dist/components/data/TableBase/use-table-tree-state.js +107 -0
- package/dist/components/data/TableBase/use-table-tree-state.js.map +1 -0
- package/dist/components/data/index.d.ts +2 -2
- 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/ColorSwatch/ColorSwatch.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 +8 -25
- package/dist/components/fields/CommandTextArea/CommandTextArea.js.map +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/index.d.ts +0 -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 +10 -29
- package/dist/components/fields/TextArea/TextArea.js.map +1 -1
- package/dist/components/fields/TextInput/TextInput.js +1 -1
- package/dist/components/fields/TextInput/TextInputBase.js +1 -1
- package/dist/components/fields/TextInput/useAutoSizeTextArea.js +146 -0
- package/dist/components/fields/TextInput/useAutoSizeTextArea.js.map +1 -0
- package/dist/components/fields/TextInputMapper/TextInputMapper.js +1 -1
- package/dist/components/fields/color/ColorPanel.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.d.ts +8 -5
- package/dist/components/layout/Board/Board.js +1 -1
- package/dist/components/layout/Board/Board.js.map +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-modes.js +7 -4
- package/dist/components/layout/Board/grid-core/collision-modes.js.map +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/grid-core/types.d.ts +6 -4
- 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 +90 -48
- package/dist/components/layout/Board/use-board-registry.js.map +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/CalendarHeader.js +1 -1
- package/dist/components/other/Calendar/CalendarPanel.js +1 -1
- package/dist/components/other/Calendar/PeriodCalendar.js +1 -1
- package/dist/components/other/Calendar/PeriodGrid.js +1 -1
- package/dist/components/other/Calendar/RangeCalendar.js +1 -1
- package/dist/components/other/Calendar/styled.js +1 -1
- package/dist/components/other/CubeLogo/CubeLogo.js +1 -1
- package/dist/components/other/NoDataIcon/NoDataIcon.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.d.ts +1 -2
- package/dist/components/overlays/Modal/Modal.js +1 -1
- package/dist/components/overlays/Modal/OpenTransitionContext.js +1 -1
- package/dist/components/overlays/Modal/Overlay.d.ts +0 -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/Modal/types.d.ts +0 -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.d.ts +0 -2
- 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/index.d.ts +0 -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 +2 -1
- package/dist/i18n/locales/en-US/uikit.js +2 -1
- package/dist/i18n/locales/en-US/uikit.json.d.ts +1 -0
- package/dist/i18n/locales/es-ES/uikit.js +2 -1
- package/dist/i18n/locales/es-MX/uikit.js +2 -1
- package/dist/i18n/locales/fr-FR/uikit.js +2 -1
- package/dist/i18n/locales/it-IT/uikit.js +2 -1
- package/dist/i18n/locales/ja-JP/uikit.js +2 -1
- package/dist/i18n/locales/nb-NO/uikit.js +2 -1
- package/dist/i18n/locales/pt-BR/uikit.js +2 -1
- package/dist/i18n/locales/pt-PT/uikit.js +2 -1
- package/dist/i18n/locales/sv-SE/uikit.js +2 -1
- package/dist/i18n/locales/vi-VN/uikit.js +2 -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.js +1 -1
- package/dist/icons/ArrowNarrowUpIcon.js +1 -1
- 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/wrap-icon.js +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/probe/canonicalize.js +1 -1
- package/dist/probe/css.js +1 -1
- package/dist/probe/index.js +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-seed.js +1 -1
- package/dist/tokens/color-theme.js +1 -1
- package/dist/tokens/colors.js +1 -1
- package/dist/tokens/index.js +1 -1
- package/dist/tokens/layout.js +1 -1
- package/dist/tokens/lazy-styles.js +1 -1
- package/dist/tokens/palette-config.js +1 -1
- package/dist/tokens/palette.js +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/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.js +1 -1
- package/dist/utils/react/forwardRefWithGenerics.js +1 -1
- package/dist/utils/react/index.js +1 -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 +3 -3
- package/docs/Introduction.md +85 -97
- package/docs/Usage.md +26 -0
- package/docs/components/data/DataTable.md +110 -11
- package/docs/components/data/ItemTable.md +63 -1
- package/docs/components/layout/Board.md +6 -5
- package/docs/tasty/configuration.md +10 -6
- package/docs/tasty/dsl.md +99 -2
- package/docs/tasty/styles.md +3 -1
- package/package.json +2 -2
- package/dist/components/fields/ListBoxPopover/useCompositeFocus.d.ts +0 -2
- package/dist/components/portal/PortalProvider.d.ts +0 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
/** @license MIT | @cube-dev/ui-kit v0.
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.165.0 | Cube Dev Team */
|
|
2
2
|
import { _Item } from "../../content/Item/Item.js";
|
|
3
|
+
import { Action } from "../../actions/Action/Action.js";
|
|
3
4
|
import { keyframes, tasty } from "@tenphi/tasty";
|
|
4
5
|
|
|
5
6
|
//#region src/components/data/TableBase/styled.ts
|
|
@@ -209,6 +210,26 @@ const TableElement = tasty({
|
|
|
209
210
|
"#row-text": "#dark-03",
|
|
210
211
|
$dim: 1
|
|
211
212
|
},
|
|
213
|
+
HeaderGroupCell: {
|
|
214
|
+
$: "> Scroller > Table > Head > HeadRow >",
|
|
215
|
+
...CELL_STYLES,
|
|
216
|
+
padding: 0,
|
|
217
|
+
paddingInline: 0,
|
|
218
|
+
height: "($header-height + 1bw)",
|
|
219
|
+
preset: "t3m",
|
|
220
|
+
border: "1bw #border bottom, $column-divider #border right",
|
|
221
|
+
fill: "#surface-3",
|
|
222
|
+
userSelect: "none",
|
|
223
|
+
position: {
|
|
224
|
+
"": "relative",
|
|
225
|
+
"@own(pin=start | pin=end)": "sticky"
|
|
226
|
+
},
|
|
227
|
+
overflow: "hidden",
|
|
228
|
+
zIndex: {
|
|
229
|
+
"": "auto",
|
|
230
|
+
"@own(pin=start | pin=end)": 3
|
|
231
|
+
}
|
|
232
|
+
},
|
|
212
233
|
HeaderCell: {
|
|
213
234
|
$: "> Scroller > Table > Head > HeadRow >",
|
|
214
235
|
...CELL_STYLES,
|
|
@@ -364,6 +385,29 @@ const TableElement = tasty({
|
|
|
364
385
|
placeItems: "center",
|
|
365
386
|
height: "100%"
|
|
366
387
|
},
|
|
388
|
+
TreeContent: {
|
|
389
|
+
$: "> Scroller > Table > Body > Row > Cell >",
|
|
390
|
+
display: "flex",
|
|
391
|
+
alignItems: "center",
|
|
392
|
+
gap: ".5x",
|
|
393
|
+
minWidth: 0,
|
|
394
|
+
padding: "left ($tree-indent * 2x)",
|
|
395
|
+
"$tree-indent": "($tree-level, 0)"
|
|
396
|
+
},
|
|
397
|
+
TreeValue: {
|
|
398
|
+
$: "> Scroller > Table > Body > Row > Cell > TreeContent >",
|
|
399
|
+
flexGrow: 1,
|
|
400
|
+
flexShrink: 1,
|
|
401
|
+
flexBasis: 0,
|
|
402
|
+
minWidth: 0,
|
|
403
|
+
overflow: "hidden"
|
|
404
|
+
},
|
|
405
|
+
TreeToggle: {
|
|
406
|
+
$: "> Scroller > Table > Body > Row > Cell > TreeContent >",
|
|
407
|
+
flexGrow: 0,
|
|
408
|
+
flexShrink: 0,
|
|
409
|
+
flexBasis: "auto"
|
|
410
|
+
},
|
|
367
411
|
SelectionBox: {
|
|
368
412
|
$: "> Scroller > Table",
|
|
369
413
|
display: "flex",
|
|
@@ -520,6 +564,35 @@ const TableElement = tasty({
|
|
|
520
564
|
}
|
|
521
565
|
}
|
|
522
566
|
});
|
|
567
|
+
const TREE_TOGGLE_STYLES = {
|
|
568
|
+
display: "grid",
|
|
569
|
+
placeItems: "center",
|
|
570
|
+
placeContent: "center",
|
|
571
|
+
flexGrow: 0,
|
|
572
|
+
flexShrink: 0,
|
|
573
|
+
flexBasis: "auto",
|
|
574
|
+
width: "3x",
|
|
575
|
+
height: "3x",
|
|
576
|
+
radius: true,
|
|
577
|
+
transition: "theme"
|
|
578
|
+
};
|
|
579
|
+
/** Disclosure control rendered in the configured tree column. */
|
|
580
|
+
const TableTreeToggle = tasty(Action, {
|
|
581
|
+
qa: "TableTreeToggle",
|
|
582
|
+
styles: {
|
|
583
|
+
...TREE_TOGGLE_STYLES,
|
|
584
|
+
color: {
|
|
585
|
+
"": "#dark-02",
|
|
586
|
+
":hover": "#dark"
|
|
587
|
+
},
|
|
588
|
+
fill: {
|
|
589
|
+
"": "#clear",
|
|
590
|
+
":hover": "#dark.04"
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
});
|
|
594
|
+
/** Leaf placeholder matching the disclosure control's footprint. */
|
|
595
|
+
const TableTreeTogglePlaceholder = tasty({ styles: TREE_TOGGLE_STYLES });
|
|
523
596
|
/**
|
|
524
597
|
* The header cell's content. `Item` lives INSIDE the `<th>`, never as the `<th>`
|
|
525
598
|
* itself — it emits `aria-selected` unconditionally (`Item.tsx:964`), which on a
|
|
@@ -557,5 +630,5 @@ const TableHeaderItem = tasty(_Item, {
|
|
|
557
630
|
});
|
|
558
631
|
|
|
559
632
|
//#endregion
|
|
560
|
-
export { TableElement, TableHeaderItem };
|
|
633
|
+
export { TableElement, TableHeaderItem, TableTreeToggle, TableTreeTogglePlaceholder };
|
|
561
634
|
//# sourceMappingURL=styled.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styled.js","names":["Item"],"sources":["../../../../src/components/data/TableBase/styled.ts"],"sourcesContent":["import { keyframes, tasty } from '@tenphi/tasty';\n\nimport { Item } from '../../content/Item';\n\nimport type { Styles } from '@tenphi/tasty';\n\n/**\n * Geometry shared by the three row groups. They cannot share a sub-element key,\n * so they share a const — the same technique `Item.tsx` uses for\n * `DEFAULT_ICON_STYLES` / `ADDITION_STYLES`.\n */\n/**\n * The refresh sweep: a band of reduced opacity travelling left to right, the\n * way ag-grid marks a grid that is reloading.\n *\n * A mask rather than a coloured overlay, so the band genuinely lowers the\n * content's opacity instead of painting a surface-coloured stripe over it. That\n * costs nothing in theming — the gradient is pure black and alpha, with no\n * colour token to resolve — and it stays correct on any backdrop.\n *\n * `mask-position` runs 100% → 0% because a mask wider than its box moves the\n * OPPOSITE way to the position value: raising it slides the image left, which\n * would send the band right to left.\n */\nconst refreshSweep = keyframes({\n '0%': { 'mask-position': '100% 0' },\n '100%': { 'mask-position': '0% 0' },\n});\n\nconst ROW_STYLES: Styles = {\n // The stretched `rowLink` anchor positions against this.\n position: 'relative',\n};\n\nconst CELL_STYLES: Styles = {\n boxSizing: 'border-box',\n // Row height lives on the CELLS, not the `<tr>`: table layout ignores\n // `min-height` on a row, and sizes it from its cells instead. `height` on a\n // cell is treated as a minimum, so a wrapping or auto-height cell still grows\n // the row.\n //\n // Cells are `border-box` and carry the 1px row separator, so the border is\n // added on top: `$row-height` is the content box, and a default row occupies\n // 41px in total.\n height: '($row-height + 1bw)',\n padding: '$cell-padding-y $cell-padding-x',\n textAlign: {\n '': 'start',\n '@own(align=center)': 'center',\n '@own(align=end)': 'end',\n },\n verticalAlign: 'middle',\n overflow: 'hidden',\n // An `autoHeight` column wraps and lets its row grow. `height` on a cell is a\n // minimum in table layout, so the declared row height stays the floor.\n whiteSpace: { '': 'nowrap', '@own(wrap)': 'normal' },\n paddingBlock: { '': '$cell-padding-y', '@own(wrap)': '1x' },\n // The checkbox column is a square affordance, not content: it centres its\n // control and contributes no inline padding of its own.\n paddingInline: {\n '': '$cell-padding-x',\n '@own(kind=selection) | @own(kind=actions)': 0,\n },\n // Pinned cells overlay the scrolling ones, so they must be opaque. Reading\n // the row's inherited paint tokens means every row state is matched for free\n // — no duplicated state matrix, no chance of the two drifting apart.\n // Reading the row's inherited paint tokens means every row state is matched\n // for free. A selected cell steps out of that and takes a flat accent tint:\n // without it a wide range is a mesh of per-cell rings rather than one block,\n // and the row's hover would keep moving underneath a selection the user has\n // already committed to.\n /**\n * One more level of indirection than the row publishes, and the level a\n * per-column tint plugs into.\n *\n * An untinted cell is simply its row. A tinted one swaps its own base and text\n * — see `column-tint.ts`, which generates a `@own(tint=…)` branch per distinct\n * column colour and merges it in through `styles.Cell` / `styles.HeaderCell`.\n *\n * The tint is pre-composed into the BASE rather than stacked as a second\n * overlay, because `fill` has exactly two layers and the interaction paint\n * needs the other one. That is what keeps hover, focus, selection and\n * drop-target working over a tinted column instead of being displaced by it —\n * and it is why the row band has to reach the cell (`data-odd` is mirrored onto\n * body cells) rather than staying on the `<tr>`.\n */\n '#cell-base': '#row-base',\n '#cell-text': '#row-text',\n fill: {\n '': '#cell-base #row-overlay',\n '@own(cell-selected)': '#cell-base #purple.10',\n },\n color: '#cell-text',\n opacity: '$dim',\n position: { '': 'static', '@own(pin=start | pin=end)': 'sticky' },\n insetInlineStart: { '': 'auto', '@own(pin=start)': '$pin-offset' },\n insetInlineEnd: { '': 'auto', '@own(pin=end)': '$pin-offset' },\n zIndex: { '': 'auto', '@own(pin=start | pin=end)': 1 },\n // The innermost pinned column needs an edge, or content scrolling underneath\n // reads as part of the pinned group. An inset box-shadow rather than a border\n // so it costs no column width, and `#border` rather than `#shadow` so it\n // matches the row dividers instead of reading as a hard black line on a dark\n // surface.\n // The pinned column's edge, and the selected cell's ring. Both are inset\n // shadows and both share this map, so the two compose rather than one\n // clobbering the other on a pinned selected cell.\n //\n // The ring is a shadow rather than an `outline`: an outline is drawn OUTSIDE\n // the box, and pulling it back with a negative `outlineOffset` needs a value\n // tasty will not resolve (`-1bw`), so the ring came out a pixel oversized on\n // every side — over the row divider above and the column rule to the left. An\n // inset shadow lands exactly on the cell's own edges and costs no layout.\n shadow: {\n '': false,\n '@own(pin-edge) & @own(pin=start)': 'inset -1bw 0 0 0 #border',\n '@own(pin-edge) & @own(pin=end)': 'inset 1bw 0 0 0 #border',\n '@own(cell-selected)': 'inset 0 0 0 1bw #purple',\n '@own(cell-selected) & @own(pin-edge) & @own(pin=start)':\n 'inset 0 0 0 1bw #purple, inset -1bw 0 0 0 #border',\n '@own(cell-selected) & @own(pin-edge) & @own(pin=end)':\n 'inset 0 0 0 1bw #purple, inset 1bw 0 0 0 #border',\n },\n // The frame's rounded corner, mirrored onto the cell that meets it. Without\n // it a selected cell there has its ring sliced off at 45°, since the root\n // clips with a radius. One border-width smaller than the frame's, because the\n // cell sits inside the frame's own border.\n radius: {\n '': 0,\n // `1cr` is the card radius (`--card-radius`), used directly rather than\n // aliased onto a token of our own — and emphatically not onto `$radius`,\n // which is the kit's GLOBAL radius. Declaring that here handed every\n // Button, Input and Tag rendered inside a cell the card's 10px instead of\n // the 6px they inherit everywhere else, and took every `1r`/`2r` unit in\n // the subtree with it.\n '@own(corner=start)': '(1cr - 1bw) bottom-left',\n '@own(corner=end)': '(1cr - 1bw) bottom-right',\n },\n // The vertical rule, resolved in two steps so the border maps below stay\n // small. `$column-rule` is the TABLE's answer (root-level `column-dividers`);\n // this narrows it per cell.\n //\n // A WIDTH rather than a colour. A transparent 1px border still occupies its\n // px: with `border-box` cells that quietly took a pixel of content width from\n // every column of every table, dividers or not.\n //\n // The trailing column is exempt: its rule lands flush against the frame in\n // `card` shape and reads as a doubled edge, and in `plain` shape it is a line\n // hanging off the end of the table with nothing after it.\n '$column-divider': { '': '$column-rule', '@own(last-column)': '0px' },\n transition: 'fill',\n};\n\nexport const TableElement = tasty({\n qa: 'Table',\n styles: {\n /* ── tokens the root owns ─────────────────────────────────────────── */\n // Rows are 40px at the default size and the header is one step tighter at\n // 32px — the proportion the Cloud tables use. Each is the content height;\n // the 1px separator is added on top (see `CELL_STYLES.height`).\n '$row-height': {\n '': '$size-lg',\n 'size=xsmall': '$size-sm',\n 'size=small': '$size-md',\n 'size=large': '$size-xl',\n 'size=xlarge': '7x',\n },\n '$header-height': {\n '': '$size-md',\n 'size=xsmall': '$size-xs',\n 'size=small': '$size-sm',\n 'size=large': '$size-lg',\n 'size=xlarge': '$size-xl',\n },\n // 16px. Matches the `cellHorizontalPadding` the Cloud tables ship (ag-grid's\n // own default is 15px, which is off the 8px grid).\n '$cell-padding-x': '2x',\n '$cell-padding-y': 0,\n '$pin-offset': '0px',\n $dim: 1,\n '$link-decoration': 'none',\n '$resizer-hit': '1x',\n '$resizer-offset': '-.5x',\n '$resizer-line-width': '1bw',\n '#resizer-line': '#clear',\n // Vertical rules between columns: on for a grid read down a column, off for\n // a list read across a row. See `TableView`'s `hasColumnDividers`.\n '$column-rule': { '': '0px', 'column-dividers': '1bw' },\n // Neutral defaults so a cell rendered outside a row still paints sanely.\n '#row-base': '#surface',\n '#row-overlay': '#clear',\n '#row-text': '#surface-text',\n // The cell-level pair defaults to the row's, and a tinted column overrides\n // its own — see `CELL_STYLES`. Declared here too so the chain has a root even\n // for a cell that is somehow outside a row.\n '#cell-base': '#row-base',\n '#cell-text': '#row-text',\n\n /* ── frame ────────────────────────────────────────────────────────── */\n display: 'grid',\n gridRows: 'max-content minmax(0, 1fr) max-content',\n gridColumns: 'minmax(0, 1fr)',\n position: 'relative',\n boxSizing: 'border-box',\n fill: '#surface',\n color: '#surface-text',\n radius: { '': 0, 'shape=card': '1cr' },\n border: { '': false, 'shape=card': true },\n overflow: 'hidden',\n // Bounded by the consumer (`height` / `maxHeight`). There is no page-scroll\n // mode: an unbounded table simply sizes to its content.\n height: 'max 100%',\n\n /* ── the single scroller ──────────────────────────────────────────── */\n Scroller: {\n $: '>',\n gridRow: 2,\n position: 'relative',\n overflow: 'auto',\n /**\n * No focus ring of its own.\n *\n * The scroller takes `tabIndex={-1}` so a cell press can move focus here\n * and the range's shortcuts (Escape, ⌘/Ctrl+C) have somewhere to land. It\n * is a mechanism, not a control the user aimed at — but the browser does\n * not know that, and drew its default `outline: auto` around the whole\n * scrollport. Three edges are clipped by the frame's `overflow: hidden`,\n * so what actually shipped was a stray line across the bottom of the\n * table, right above the footer.\n *\n * Nothing is lost by removing it: focus only ever arrives here alongside a\n * selected cell, and that cell draws its own ring.\n *\n * `'none'`, not `false` — tasty reads `false` as \"no ring of the kit's\n * own\" and emits no declaration at all, which leaves the browser's default\n * in place. Verified: with `false` the Scroller's rule carried no\n * `outline` property.\n */\n outline: 'none',\n // A reserved gutter stops an appearing scrollbar from reflowing every\n // column. With one scroller for head and body there is nothing else to\n // keep in sync — this is the whole reason for the native-table design.\n scrollbar: 'thin stable',\n // Locked per axis, and only on an axis that can actually scroll.\n //\n // `none` rather than `contain`: both stop a swipe at the scroll edge from\n // chaining to the page — which is what keeps a horizontal flick from\n // triggering browser back-navigation — but `contain` still allows the\n // rubber-band bounce, and bouncing a table drags its rows away from the\n // sticky header and shows blank surface behind them.\n //\n // The non-scrollable axis stays `auto` on purpose. Chrome applies\n // overscroll rules to any `overflow: auto` element, including one whose\n // content fits, so locking both axes unconditionally makes a five-row\n // table swallow the wheel and pin the page behind it.\n // While a range drag is in progress the pointer is painting cells, not\n // text — without this a drag across the grid leaves every cell it passed\n // highlighted blue underneath the range.\n userSelect: { '': 'auto', 'range-dragging': 'none' },\n overscrollBehavior: {\n '': 'auto',\n 'scroll-x & scroll-y': 'none',\n 'scroll-x & !scroll-y': 'none auto',\n '!scroll-x & scroll-y': 'auto none',\n },\n },\n\n Table: {\n $: '> Scroller >',\n // The whole table fades while a refresh is in flight — header included.\n // Dimming only the rows left the header at full strength, which read as\n // though the columns were current and only the data was not.\n opacity: { '': 1, stale: 0.5 },\n // `#black` throughout, but only its ALPHA is doing anything: a gradient\n // mask defaults to `mask-mode: alpha`, so the colour channel is discarded\n // and `#black.4` is simply \"40% through\". Any opaque token would render\n // identically — `#black` is the conventional way to write it.\n maskImage: {\n '': 'none',\n stale:\n 'linear-gradient(90deg, #black 0%, #black 35%, #black.4 50%, #black 65%, #black 100%)',\n // A flat, fully opaque mask is a no-op, so there is nothing to sweep —\n // the table still fades, it just does not move. A loading state can\n // last a long time, and this one would otherwise animate continuously\n // beside the data with no way to stop it. Written as its own gradient\n // rather than `none` so it cannot merge with the default above.\n '@media(prefers-reduced-motion)':\n 'linear-gradient(90deg, #black 0%, #black 100%)',\n },\n // Three times the width, so the band is a third of the table and there is\n // an opaque stretch either side of it. The default `repeat` tiles\n // seamlessly, both ends of the gradient being fully opaque.\n //\n // oxlint's `tasty(known-property)` flags this — its property list has\n // `maskImage` but not `maskSize`, in either spelling. Tasty passes an\n // unknown key through as raw CSS, so it emits fine: verified computing to\n // `300% 100%` with the sweep running. The warning is the linter's gap.\n maskSize: '300% 100%',\n animation: {\n '': 'none',\n stale: `${refreshSweep} 1.4s linear infinite`,\n },\n // Belt and braces with the flat mask above, and the same shape `Spin`\n // already uses.\n animationPlayState: {\n '': 'running',\n '@media(prefers-reduced-motion)': 'paused',\n },\n transition: 'opacity',\n // `fixed` makes `<colgroup>` authoritative, so the header and the body\n // are guaranteed to agree on every column width.\n tableLayout: 'fixed',\n // `separate` is required: with `collapse`, a sticky `<thead>` loses its\n // borders and they scroll away with the content.\n borderCollapse: 'separate',\n borderSpacing: 0,\n // The exact width is set inline from the resolved layout; this is only\n // the pre-measurement fallback.\n width: '100%',\n preset: 't3',\n },\n\n /* ── head ─────────────────────────────────────────────────────────── */\n Head: {\n $: '> Scroller > Table >',\n position: { '': 'static', 'sticky-header': 'sticky' },\n inset: { '': 'auto', 'sticky-header': '0 top' },\n zIndex: 2,\n },\n HeadRow: {\n $: '> Scroller > Table > Head >',\n ...ROW_STYLES,\n // Header rows never carry interaction paint; neutralise the inherited\n // tokens so nothing can leak in from a row above.\n '#row-base': '#surface-2',\n '#row-overlay': '#clear',\n '#row-text': '#dark-03',\n $dim: 1,\n },\n HeaderCell: {\n $: '> Scroller > Table > Head > HeadRow >',\n ...CELL_STYLES,\n // No padding at all: the `Item` inside fills the cell edge to edge and\n // supplies the indent itself, per side. That is what lets a leading icon\n // sit tighter than text and a trailing icon sit flush — see\n // `TableHeaderItem`.\n //\n // `paddingInline` as well as the shorthand: the shared cell styles set\n // the longhand for the checkbox column, and a longhand arriving through\n // the spread outlives a `padding: 0` written after it.\n padding: 0,\n paddingInline: 0,\n height: '($header-height + 1bw)',\n // The header's typography lives here rather than on the `Item`, so a\n // consumer can restyle it through `headerCellStyles` / `styles.HeaderCell`.\n // The adapter supplies the real default via `headerPreset`; this is only\n // the fallback for a `TableView` rendered without one.\n preset: 't3m',\n border: '1bw #border bottom, $column-divider #border right',\n zIndex: { '': 'auto', '@own(pin=start | pin=end)': 3 },\n // One entry, not two sharing a value: tasty coalesces entries in a state\n // map that serialize identically, promotes them to the group's maximum\n // priority and negates them against everything below — see the row state\n // matrix below and `src/data/AGENTS.md`.\n fill: {\n '': '#cell-base #row-overlay',\n '(@own(sortable) & @own(:hover)) | @own(menu-open)':\n '#cell-base #surface-text.04',\n },\n // `pointer` wins on a sortable header: sorting is the primary action, and a\n // native drag needs movement while a click does not, so both still work.\n // `grab` is only honest where there is nothing else to click.\n cursor: {\n '': 'default',\n '@own(sortable)': 'pointer',\n '@own(draggable) & !@own(sortable)': 'grab',\n '@own(dragging)': 'grabbing',\n },\n // Matches the row being dragged.\n opacity: { '': 1, '@own(dragging)': 0.4 },\n userSelect: 'none',\n // The containing block for `Resizer`. Cells are `static` by default, so\n // without this every handle resolves against the scroller instead and\n // they all stack up at its right edge.\n position: { '': 'relative', '@own(pin=start | pin=end)': 'sticky' },\n // A cell clips its overflow so a long label cannot bleed into its\n // neighbour, but the resize handle straddles the boundary on purpose and\n // would lose its outer half. Only cells that actually have one opt out.\n overflow: { '': 'hidden', '@own(resizable)': 'visible' },\n /**\n * How visible the sort arrow is when the column is NOT sorted — read by\n * `SortIndicator`.\n *\n * Published as an inherited custom property because a sub-element's state\n * keys resolve against the ROOT, not its DOM parent: from inside\n * `SortIndicator`, `@own(:hover)` asks whether the 16px arrow itself is\n * hovered, not the header cell it sits in. Same mechanism as `$dim` and\n * `$resizer-offset`.\n *\n * `:focus-visible` as well as `:hover`, so a keyboard user gets the same\n * hint. One grouped key rather than two entries sharing `.4`: a state map\n * whose entries serialize identically gets coalesced and negated.\n */\n '$sort-hint': {\n '': 0,\n '@own(sortable) & (@own(:hover) | @own(:focus-visible))': 0.4,\n },\n // How far the handle hangs past this cell's trailing edge — read by\n // `Resizer`. Published as an inherited custom property rather than asked\n // for from the handle with `@parent(...)`: a sub-element's state keys\n // resolve against the ROOT, so the handle cannot ask about the cell it\n // sits in (the same reason `#row-base` and `$link-decoration` exist).\n //\n // The trailing column has no neighbour to straddle. Left hanging, it puts\n // half its width past the table and the scroller gains a few pixels of\n // horizontal scroll onto blank space.\n '$resizer-offset': { '': '-.5x', '@own(last-column)': '0px' },\n },\n\n /**\n * The column resize handle, on the header cell's trailing edge.\n *\n * Positioned with longhands rather than an `inset` shorthand: the\n * arithmetic form compiled to garbage (`32px -24px 1px 16px`), which put\n * the handle inside the body and collapsed its height. It sits fully inside\n * the cell, so there is no negative offset to get wrong.\n */\n Resizer: {\n $: '> Scroller > Table > Head > HeadRow > HeaderCell >',\n position: 'absolute',\n top: 0,\n bottom: 0,\n // Centred on the boundary rather than tucked inside the cell: a handle\n // you can only grab from one side of the line is half a target, and the\n // focus ring would sit visibly off to the left of the edge it resizes.\n // The offset is half of `$resizer-hit`.\n right: '$resizer-offset',\n // A 1px line is impossible to grab, so the hit area is wider than it.\n width: '$resizer-hit',\n zIndex: 2,\n cursor: 'col-resize',\n touchAction: 'none',\n outline: {\n '': 'none',\n '@own(:focus-visible)': '1bw #focus',\n },\n outlineOffset: '1bw',\n\n /**\n * The line is a real child, not `&::after`: state maps inside a\n * pseudo-element block do not compile — `width` and `fill` both came out\n * empty — so the handle's own state is published as tokens instead, the\n * same mechanism `#row-base` and `$link-decoration` use.\n */\n // Drawn at rest so the handle is discoverable — except when the table\n // already rules its columns, where the cell's own border is that line and\n // a second one 4px away reads as a doubled edge. (`column-dividers` has no\n // `@own`: bare keys resolve against the root, which is where it lives.)\n '#resizer-line': {\n '': '#border',\n 'column-dividers': '#clear',\n '@own(:hover) | @own(:focus-visible)': '#purple',\n },\n '$resizer-line-width': {\n '': '1bw',\n '@own(:hover) | @own(:focus-visible)': '2bw',\n },\n },\n\n /**\n * The visible column edge. Drawn at rest rather than only on hover — an\n * affordance you have to find by hovering an 8px strip is one nobody finds.\n * A table that rules its columns already draws that edge, so there the line\n * only appears under the cursor (see `#resizer-line`).\n */\n ResizerLine: {\n $: '> Scroller > Table > Head > HeadRow > HeaderCell > Resizer >',\n // Absolute rather than flex-aligned: `placeContent` maps to\n // `align-content justify-content`, so the obvious-looking `'end center'`\n // silently centred the line instead of ending it.\n //\n // Centred inside the handle, which is itself centred on the boundary, so\n // the line lands exactly on the edge it represents and a thicker hover\n // state grows evenly to both sides.\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: '50%',\n translate: '-50% 0',\n width: '$resizer-line-width',\n fill: '#resizer-line',\n transition: 'theme',\n },\n\n /**\n * Where a dragged column would land.\n *\n * A distinct sub-element NAME from the row's `DropIndicator` rather than a\n * second selector chain on the same one: two entries whose chains differ is\n * exactly the shape that produced an indicator matching nothing at all.\n *\n * Positioned fully INSIDE the cell box. `HeaderCell` is `overflow: hidden`\n * and only opts out to `visible` when it is resizable, so the centred\n * `translate: -50%` the resizer line uses would lose its outer half on every\n * non-resizable column.\n */\n ColumnDropIndicator: {\n $: '> Scroller > Table > Head > HeadRow > HeaderCell >',\n position: 'absolute',\n top: 0,\n bottom: 0,\n width: '2bw',\n insetInlineStart: { '': 'auto', '@own(position=before)': 0 },\n insetInlineEnd: { '': 'auto', '@own(position=after)': 0 },\n fill: '#purple',\n radius: '1r',\n // Above the pinned header cell (3) and the resize handle (2).\n zIndex: 4,\n },\n\n /**\n * Centres the checkbox in its cell. A `<td>` cannot be a flex container\n * without dropping out of table layout, so the centring lives on a wrapper\n * inside it.\n *\n * Descendant rather than direct-child, so one entry covers both the header\n * cell and the body cells.\n */\n /**\n * The stretched row link. A `<tr>` cannot be wrapped in an `<a>`, so the\n * anchor sits in the row-header cell and covers the row through `inset`.\n * Its text comes from the row-header cell, so the accessible name is the\n * row's name rather than \"link\".\n *\n * Below the cells' own content in the stacking order, so an in-cell button\n * or menu trigger still takes its own clicks.\n */\n RowLink: {\n $: '> Scroller > Table > Body > Row > Cell >',\n position: 'absolute',\n inset: 0,\n zIndex: 0,\n // The row already paints hover and focus; the link must add nothing.\n fill: '#clear',\n radius: 0,\n outline: {\n '': 'none',\n // Keyboard focus still has to be visible, even though the row is what\n // the user perceives as focused.\n focused: '1bw #focus',\n },\n },\n\n /**\n * The line showing where a dragged row would land.\n *\n * Its own row, because a native table cannot hold an arbitrary element\n * between two rows — the shape `ListBox` uses with `<li>`.\n *\n * The row and its cell collapse to nothing and the line is positioned out\n * of flow, so inserting one mid-drag does not push the rows apart. The line\n * then sits *over* the divider it replaces rather than beside it.\n */\n DropIndicatorRow: {\n $: '> Scroller > Table > Body >',\n height: 0,\n },\n\n DropIndicatorCell: {\n $: '> Scroller > Table > Body > DropIndicatorRow >',\n // Every one of these matters: a `<td>` carries UA padding, and any of\n // them left in place gives the row real height and shifts the table.\n padding: 0,\n border: 0,\n height: 0,\n lineHeight: 0,\n fontSize: 0,\n // The containing block for the line below.\n position: 'relative',\n overflow: 'visible',\n },\n\n DropIndicator: {\n $: '> Scroller > Table > Body > DropIndicatorRow > DropIndicatorCell >',\n position: 'absolute',\n insetInlineStart: 0,\n insetInlineEnd: 0,\n top: 0,\n height: '2bw',\n // Centred on the boundary, so it covers the row divider instead of\n // sitting above or below it.\n translate: '0 -50%',\n fill: '#purple',\n radius: '1r',\n zIndex: 3,\n outline: {\n '': 'none',\n // `@own`, not a bare `:focus-visible`: a sub-element's state keys\n // resolve against the ROOT, so the plain form asked whether the whole\n // table was focused. This is the keyboard drop target and needs its own.\n '@own(:focus-visible)': '2bw #purple',\n },\n outlineOffset: '1bw',\n },\n\n /**\n * Row numbers. Muted and tabular so they read as a ruler down the side\n * rather than as a data column competing with the real ones.\n */\n RowNumber: {\n $: '> Scroller > Table > Body > Row > Cell',\n color: '#surface-text-soft',\n fontVariantNumeric: 'tabular-nums',\n },\n\n /** Wraps the `⋮` trigger so it centres without becoming a table cell box. */\n RowActions: {\n $: '> Scroller > Table > Body > Row > Cell >',\n position: 'relative',\n // Above `RowLink`, or the stretched anchor would swallow its clicks.\n zIndex: 1,\n display: 'flex',\n placeContent: 'center',\n placeItems: 'center',\n height: '100%',\n },\n\n SelectionBox: {\n $: '> Scroller > Table',\n display: 'flex',\n placeContent: 'center',\n placeItems: 'center',\n height: '100%',\n },\n\n /**\n * The sort arrow. Lives in the header `Item`'s `suffix`, so it participates\n * in the header's grid rather than overlapping the label. Reserved space\n * even when unsorted — otherwise the label shifts on every sort.\n */\n SortIndicator: {\n // Descendant, not direct child: the indicator is handed to the header\n // `Item` as a slot, so it renders inside Item's own `RightIcon` (or\n // `Suffix`) wrapper rather than directly under the `<th>`.\n $: '> Scroller > Table > Head > HeadRow > HeaderCell',\n display: 'grid',\n placeItems: 'center',\n width: '2x',\n height: '2x',\n color: '#surface-text',\n // Hovering a sortable header previews the arrow it would get; sorting for\n // real makes it solid. `$sort-hint` is the header cell's answer — see\n // there for why this cannot just ask about hover itself.\n //\n // The preview points the right way for free: `data-dir` is absent while\n // unsorted, so the `scale` map below leaves the chevron pointing up, and\n // the first press of an unsorted column sorts ascending. The hint predicts\n // the press rather than just advertising that one is possible.\n opacity: {\n '': '$sort-hint',\n '@own(sorted)': 1,\n },\n // No `scale` flip any more: `TableView` renders the real\n // `ArrowNarrowDownIcon` for `desc` rather than turning the up arrow over,\n // so there is no transform left to animate. `opacity` still is — that is\n // the hover hint fading in.\n transition: 'opacity',\n },\n\n /* ── body ─────────────────────────────────────────────────────────── */\n Body: {\n $: '> Scroller > Table >',\n },\n Row: {\n $: '> Scroller > Table > Body >',\n ...ROW_STYLES,\n // `position: relative` (below) is also the containing block for\n // `RowLink`, which stretches over the whole row from inside the\n // row-header cell, and for the drop indicator.\n /**\n * Totals and subtotals, pinned to the edges of the scroller.\n *\n * They live in `<tbody>` so they keep ordinary row styling, so the\n * stickiness has to be stated here. The top offset is the header's own\n * height — a pinned row sticks *under* the header, not over it.\n */\n position: { '': 'relative', '@own(pinned)': 'sticky' },\n insetBlockStart: {\n '': 'auto',\n '@own(pinned=top)': '($header-height + 1bw)',\n },\n insetBlockEnd: { '': 'auto', '@own(pinned=bottom)': 0 },\n zIndex: { '': 'auto', '@own(pinned)': 1 },\n\n // The row being dragged, and a row that would receive a drop *on* it.\n // Landing *between* rows is drawn by `DropIndicator` instead.\n opacity: { '': 1, '@own(dragging)': 0.4 },\n // An inset shadow rather than an outline: an outline on a `<tr>` is drawn\n // outside the row and overlaps its neighbours, and `inside` is not a\n // modifier `outline` accepts.\n shadow: {\n '': false,\n '@own(drop-target)': 'inset 0 0 0 2bw #purple',\n },\n cursor: {\n '': 'default',\n '@own(clickable)': 'pointer',\n '@own(draggable)': 'grab',\n '@own(dragging)': 'grabbing',\n },\n\n /* ─── the row state matrix ─────────────────────────────────────────\n * Three orthogonal maps rather than one. Deliberate: tasty coalesces\n * entries in a single state map that share a serialized value, promoting\n * them to the group's maximum priority and negating them against\n * everything below — which silently turns a middle-priority compound\n * rule into FALSE (see src/data/AGENTS.md). A combined\n * `selected × hovered × focused × disabled × dimmed × odd` map is 64\n * entries and would be riddled with collisions.\n *\n * 1. `odd` lives alone in `#row-base`, with two distinct values.\n * 2. `dimmed` never appears in a fill map — it drives `$dim`/`#row-text`.\n * 3. Every value string inside `#row-overlay` is unique.\n * 4. The bare '' default is exempt from merging, so it may repeat a\n * value used elsewhere.\n * ────────────────────────────────────────────────────────────────── */\n '#row-base': {\n '': '#surface',\n '@own(odd)': '#surface-2',\n // Opaque and distinct, because scrolling rows pass underneath it.\n '@own(pinned)': '#surface-3',\n },\n '#row-overlay': {\n '': '#surface-text.0',\n '@own(:hover)': '#surface-text.04',\n '@own(focused)': '#surface-text.06',\n '@own(selected)': '#surface-text.09',\n '@own(selected & :hover)': '#surface-text.12',\n '@own(drop-target)': '#purple.10',\n '@own(disabled)': '#surface-text.02',\n },\n '#row-text': {\n '': '#surface-text',\n '@own(dimmed)': '#surface-text-soft',\n '@own(disabled)': '#surface-text-soft-2',\n },\n $dim: {\n '': 1,\n '@own(dimmed)': 0.6,\n },\n // Read by a row-header cell that carries a `rowLink`.\n '$link-decoration': {\n '': 'none',\n '@own(:hover)': 'underline',\n },\n },\n Cell: {\n $: '> Scroller > Table > Body > Row >',\n ...CELL_STYLES,\n // A row-header cell is a `<th>`, which the UA renders bold. Weight is the\n // table's decision, not the tag's — and a UA rule beats inheritance, so it\n // has to be stated. Deliberately NOT in the shared cell styles: the header\n // cell is a `<th>` as well, and there this would overwrite the weight its\n // `preset` sets.\n fontWeight: {\n '': 'inherit',\n // A row-header cell carrying a `rowLink` reads as a link, so it takes\n // the weight `Link` does — colour alone is easy to miss in a dense\n // table, and there is nothing else marking the row as navigable.\n '@own(link)': 600,\n },\n color: {\n '': '#cell-text',\n '@own(link)': '#purple-text',\n },\n // Underline only while the row is hovered, matching how the kit's `Link`\n // stays undecorated at rest.\n //\n // Read from a token the Row publishes rather than asking about the row\n // from here: a sub-element's state keys resolve against the *root*, and\n // `@parent(:hover)` did not constrain the rule at all — every linked cell\n // came out underlined. Custom properties inherit through the DOM and\n // ignore selector context, which is the same mechanism `$dim` and\n // `#row-text` already use.\n textDecoration: {\n '': 'none',\n '@own(link)': '$link-decoration',\n },\n // A bottom border separates two rows, so the last row has nothing to\n // separate from. Whenever something else already draws that closing edge\n // — the frame in `card` shape, or the footer's own top border — the row's\n // border lands on top of it and reads as one thick 2px line.\n //\n // `last-row` is stamped on the cell by the renderer rather than derived\n // in CSS, for two reasons:\n //\n // 1. Virtualization. The window is padded with spacer `<tr>`s, so\n // mid-scroll the last *mounted* row is not `:last-child` — the\n // trailing spacer is. A structural selector would move the missing\n // border around as you scroll; the stamped flag always marks the\n // last row of the DATA.\n // 2. `@parent(:last-child, >)` asks \"is my parent the last child of my\n // grandparent\". Asked from the Row that is a question about the\n // table body, identical for every row, and an ancestor-constant\n // condition inside a mutually-exclusive map silently deletes the\n // default's `:not(...)` branch — which is how an earlier attempt\n // removed every divider at once. (`@own(:last-child)` is the form\n // that varies per row, but see 1.)\n //\n // `column-dividers` has no `@own`: a sub-element's bare state keys resolve\n // against the ROOT, which is exactly right here — the vertical rule is a\n // property of the table, not of one cell.\n //\n // Every value string is distinct, which is what keeps this map safe from\n // tasty's identical-value merge (see src/data/AGENTS.md). That is also why\n // the two \"no closing edge\" cases used to be OR'd into one key; the state\n // row no longer needs it, since it is a `StateCell` rather than a `Cell`.\n // Two groups, so the horizontal and the vertical rule vary independently:\n // the trailing group's width is `$column-divider`, which already knows\n // whether this table rules its columns and whether this is the last one.\n // Directions a group does not name come out zero-width, which is how the\n // middle entry drops the bottom edge without touching the rule.\n //\n // Three entries, three distinct values — a map whose entries share a\n // serialized value gets merged and negated against everything below it\n // (see src/data/AGENTS.md), which is what an exhaustive\n // dividers × last-column × last-row matrix would have walked into.\n border: {\n '': '1bw #border bottom, $column-divider #border right',\n // The frame or the footer already draws the closing edge; a second one\n // on top of it reads as a single 2px line.\n '(shape=card | has-footer) & @own(last-row)':\n '$column-divider #border right',\n // A pinned bottom row opens the pinned group, so the divider goes above\n // it — the last scrolling row has already dropped its own bottom edge,\n // and a total sitting at the frame's edge needs nothing below.\n '@own(pinned=bottom)': '1bw #border top, $column-divider #border right',\n },\n },\n\n /**\n * The single full-span cell that carries the empty / no-results / error\n * content.\n *\n * Deliberately NOT a `Cell`: a `Cell` paints `#row-base`/`#row-overlay`, so\n * the state content picked up the row's banding and hover fill and lit up\n * under the cursor as though it were a row of data to click. It is not a\n * row, so it does not read the row's paint tokens at all.\n */\n StateCell: {\n $: '> Scroller > Table > Body > Row >',\n boxSizing: 'border-box',\n fill: '#surface',\n color: '#surface-text',\n border: false,\n textAlign: 'center',\n verticalAlign: 'middle',\n },\n\n /**\n * Empty / no-results / error content. Rendered as a full-span cell inside\n * the table rather than as an absolutely-positioned overlay, so the column\n * header stays visible and nothing has to be excluded from the scroll area.\n */\n StateContent: {\n $: '> Scroller > Table > Body > Row > StateCell >',\n display: 'grid',\n placeItems: 'center',\n placeContent: 'center',\n gap: '1x',\n padding: '8x 2x',\n preset: 't3',\n color: '#surface-text-soft',\n textAlign: 'center',\n },\n\n /* ── foot (pinned totals) ─────────────────────────────────────────── */\n /* ── consumer overlay ─────────────────────────────────────────────── */\n /**\n * Sits over the Scroller, not inside it, so it stays put while the rows\n * underneath remain scrollable and readable.\n *\n * A refresh does NOT use this — it sweeps the table itself (see `Table`).\n * A spinner parked in the middle of the rows covered the very content the\n * \"keep showing the previous result\" behaviour exists to preserve.\n */\n Overlay: {\n $: '>',\n gridRow: 2,\n position: 'absolute',\n inset: 0,\n display: 'flex',\n placeContent: 'center',\n placeItems: 'center',\n // No scrim: the body already dims itself, and a second layer of dimming\n // over the same rows only makes the previous result harder to read — the\n // one thing this behaviour exists to preserve.\n zIndex: 3,\n pointerEvents: 'none',\n },\n\n Foot: {\n $: '> Scroller > Table >',\n position: 'sticky',\n inset: '0 bottom',\n zIndex: 2,\n },\n FootRow: {\n $: '> Scroller > Table > Foot >',\n ...ROW_STYLES,\n '#row-base': '#surface-2',\n '#row-overlay': '#clear',\n '#row-text': '#surface-text',\n $dim: 1,\n },\n FootCell: {\n $: '> Scroller > Table > Foot > FootRow >',\n ...CELL_STYLES,\n border: '1bw #border top',\n preset: 't3m',\n },\n },\n});\n\n/**\n * The header cell's content. `Item` lives INSIDE the `<th>`, never as the `<th>`\n * itself — it emits `aria-selected` unconditionally (`Item.tsx:964`), which on a\n * `columnheader` would claim the column is selected rather than sorted.\n *\n * Keeping it inside also means the `<th>` owns the interaction fill while\n * `Item` contributes only layout, and — the real prize — `Item`'s `Actions`\n * slot already stops click/pointer/Enter/Space propagation, so pressing a\n * column menu can never trigger the sort.\n */\nexport const TableHeaderItem = tasty(Item, {\n as: 'div',\n // Deliberately NOT `type=\"header\"`. That maps Item's preset onto the heading\n // scale via state rules that outrank a plain override, and it renders the\n // label as an `<h3>`, which would put every column name into the document\n // outline.\n styles: {\n // `Item` is `inline-grid`; the header cell needs it to fill the `<th>`\n // horizontally. Same fix as `TreeRowItem` in Tree/styled.ts. Its height is\n // left alone so it keeps its natural `medium` size rather than stretching\n // to whatever the row height happens to be.\n display: 'grid',\n width: '100%',\n radius: 0,\n // `Item` reserves a 1px transparent border for its focus/hover treatments.\n // The `<th>` owns those here, and the border would inset the label by 1px\n // against the body cells below.\n border: 0,\n // Typography and colour are the header CELL's decision, so they stay\n // overridable through the table's own `styles`. See `HeaderCell`.\n preset: 'inherit',\n color: 'inherit',\n // Zero: `Item` applies this to the label only, which would indent the label\n // but not an icon beside it. The padding below sits on the `Item` box\n // instead, so it moves whatever is actually first in the row.\n '$inline-padding': 0,\n\n /**\n * The indent, per side, chosen for optical rather than geometric alignment.\n *\n * Text lines up with the body text below it at the full cell padding. An\n * icon does not: at this size it is a small, light shape, and the same 16px\n * reads as a gap — 8px sits right. A trailing icon (the sort arrow) wants\n * none at all, so it hangs at the column edge rather than floating short of\n * it.\n *\n * The `padding` shorthand rather than `paddingInline`: `Item` writes its own\n * `padding`, and a shorthand landing after a longhand wipes it — the\n * longhand form compiled away silently and every column kept the default.\n *\n * One map rather than per-side rules so the four combinations stay\n * explicit, and every value string is distinct — a state map whose entries\n * share a serialized value gets merged and negated (see\n * src/data/AGENTS.md).\n */\n padding: {\n '': '0 $cell-padding-x',\n 'has-icon': '1x left, $cell-padding-x right',\n 'has-right-icon': '$cell-padding-x left',\n 'has-icon & has-right-icon': '1x left',\n },\n // The `<th>` owns the interaction paint — neutralise Item's own ramp so the\n // two do not stack.\n fill: {\n '': '#clear',\n hovered: '#clear',\n pressed: '#clear',\n selected: '#clear',\n },\n // The default `c2` header preset uppercases its text. That is right for the\n // column name and wrong for the sentence explaining it.\n Description: { textTransform: 'none' },\n },\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"styled.js","names":["Item"],"sources":["../../../../src/components/data/TableBase/styled.ts"],"sourcesContent":["import { keyframes, tasty } from '@tenphi/tasty';\n\nimport { Action } from '../../actions/Action/Action';\nimport { Item } from '../../content/Item';\n\nimport type { Styles } from '@tenphi/tasty';\n\n/**\n * Geometry shared by the three row groups. They cannot share a sub-element key,\n * so they share a const — the same technique `Item.tsx` uses for\n * `DEFAULT_ICON_STYLES` / `ADDITION_STYLES`.\n */\n/**\n * The refresh sweep: a band of reduced opacity travelling left to right, the\n * way ag-grid marks a grid that is reloading.\n *\n * A mask rather than a coloured overlay, so the band genuinely lowers the\n * content's opacity instead of painting a surface-coloured stripe over it. That\n * costs nothing in theming — the gradient is pure black and alpha, with no\n * colour token to resolve — and it stays correct on any backdrop.\n *\n * `mask-position` runs 100% → 0% because a mask wider than its box moves the\n * OPPOSITE way to the position value: raising it slides the image left, which\n * would send the band right to left.\n */\nconst refreshSweep = keyframes({\n '0%': { 'mask-position': '100% 0' },\n '100%': { 'mask-position': '0% 0' },\n});\n\nconst ROW_STYLES: Styles = {\n // The stretched `rowLink` anchor positions against this.\n position: 'relative',\n};\n\nconst CELL_STYLES: Styles = {\n boxSizing: 'border-box',\n // Row height lives on the CELLS, not the `<tr>`: table layout ignores\n // `min-height` on a row, and sizes it from its cells instead. `height` on a\n // cell is treated as a minimum, so a wrapping or auto-height cell still grows\n // the row.\n //\n // Cells are `border-box` and carry the 1px row separator, so the border is\n // added on top: `$row-height` is the content box, and a default row occupies\n // 41px in total.\n height: '($row-height + 1bw)',\n padding: '$cell-padding-y $cell-padding-x',\n textAlign: {\n '': 'start',\n '@own(align=center)': 'center',\n '@own(align=end)': 'end',\n },\n verticalAlign: 'middle',\n overflow: 'hidden',\n // An `autoHeight` column wraps and lets its row grow. `height` on a cell is a\n // minimum in table layout, so the declared row height stays the floor.\n whiteSpace: { '': 'nowrap', '@own(wrap)': 'normal' },\n paddingBlock: { '': '$cell-padding-y', '@own(wrap)': '1x' },\n // The checkbox column is a square affordance, not content: it centres its\n // control and contributes no inline padding of its own.\n paddingInline: {\n '': '$cell-padding-x',\n '@own(kind=selection) | @own(kind=actions)': 0,\n },\n // Pinned cells overlay the scrolling ones, so they must be opaque. Reading\n // the row's inherited paint tokens means every row state is matched for free\n // — no duplicated state matrix, no chance of the two drifting apart.\n // Reading the row's inherited paint tokens means every row state is matched\n // for free. A selected cell steps out of that and takes a flat accent tint:\n // without it a wide range is a mesh of per-cell rings rather than one block,\n // and the row's hover would keep moving underneath a selection the user has\n // already committed to.\n /**\n * One more level of indirection than the row publishes, and the level a\n * per-column tint plugs into.\n *\n * An untinted cell is simply its row. A tinted one swaps its own base and text\n * — see `column-tint.ts`, which generates a `@own(tint=…)` branch per distinct\n * column colour and merges it in through `styles.Cell` / `styles.HeaderCell`.\n *\n * The tint is pre-composed into the BASE rather than stacked as a second\n * overlay, because `fill` has exactly two layers and the interaction paint\n * needs the other one. That is what keeps hover, focus, selection and\n * drop-target working over a tinted column instead of being displaced by it —\n * and it is why the row band has to reach the cell (`data-odd` is mirrored onto\n * body cells) rather than staying on the `<tr>`.\n */\n '#cell-base': '#row-base',\n '#cell-text': '#row-text',\n fill: {\n '': '#cell-base #row-overlay',\n '@own(cell-selected)': '#cell-base #purple.10',\n },\n color: '#cell-text',\n opacity: '$dim',\n position: { '': 'static', '@own(pin=start | pin=end)': 'sticky' },\n insetInlineStart: { '': 'auto', '@own(pin=start)': '$pin-offset' },\n insetInlineEnd: { '': 'auto', '@own(pin=end)': '$pin-offset' },\n zIndex: { '': 'auto', '@own(pin=start | pin=end)': 1 },\n // The innermost pinned column needs an edge, or content scrolling underneath\n // reads as part of the pinned group. An inset box-shadow rather than a border\n // so it costs no column width, and `#border` rather than `#shadow` so it\n // matches the row dividers instead of reading as a hard black line on a dark\n // surface.\n // The pinned column's edge, and the selected cell's ring. Both are inset\n // shadows and both share this map, so the two compose rather than one\n // clobbering the other on a pinned selected cell.\n //\n // The ring is a shadow rather than an `outline`: an outline is drawn OUTSIDE\n // the box, and pulling it back with a negative `outlineOffset` needs a value\n // tasty will not resolve (`-1bw`), so the ring came out a pixel oversized on\n // every side — over the row divider above and the column rule to the left. An\n // inset shadow lands exactly on the cell's own edges and costs no layout.\n shadow: {\n '': false,\n '@own(pin-edge) & @own(pin=start)': 'inset -1bw 0 0 0 #border',\n '@own(pin-edge) & @own(pin=end)': 'inset 1bw 0 0 0 #border',\n '@own(cell-selected)': 'inset 0 0 0 1bw #purple',\n '@own(cell-selected) & @own(pin-edge) & @own(pin=start)':\n 'inset 0 0 0 1bw #purple, inset -1bw 0 0 0 #border',\n '@own(cell-selected) & @own(pin-edge) & @own(pin=end)':\n 'inset 0 0 0 1bw #purple, inset 1bw 0 0 0 #border',\n },\n // The frame's rounded corner, mirrored onto the cell that meets it. Without\n // it a selected cell there has its ring sliced off at 45°, since the root\n // clips with a radius. One border-width smaller than the frame's, because the\n // cell sits inside the frame's own border.\n radius: {\n '': 0,\n // `1cr` is the card radius (`--card-radius`), used directly rather than\n // aliased onto a token of our own — and emphatically not onto `$radius`,\n // which is the kit's GLOBAL radius. Declaring that here handed every\n // Button, Input and Tag rendered inside a cell the card's 10px instead of\n // the 6px they inherit everywhere else, and took every `1r`/`2r` unit in\n // the subtree with it.\n '@own(corner=start)': '(1cr - 1bw) bottom-left',\n '@own(corner=end)': '(1cr - 1bw) bottom-right',\n },\n // The vertical rule, resolved in two steps so the border maps below stay\n // small. `$column-rule` is the TABLE's answer (root-level `column-dividers`);\n // this narrows it per cell.\n //\n // A WIDTH rather than a colour. A transparent 1px border still occupies its\n // px: with `border-box` cells that quietly took a pixel of content width from\n // every column of every table, dividers or not.\n //\n // The trailing column is exempt: its rule lands flush against the frame in\n // `card` shape and reads as a doubled edge, and in `plain` shape it is a line\n // hanging off the end of the table with nothing after it.\n '$column-divider': { '': '$column-rule', '@own(last-column)': '0px' },\n transition: 'fill',\n};\n\nexport const TableElement = tasty({\n qa: 'Table',\n styles: {\n /* ── tokens the root owns ─────────────────────────────────────────── */\n // Rows are 40px at the default size and the header is one step tighter at\n // 32px — the proportion the Cloud tables use. Each is the content height;\n // the 1px separator is added on top (see `CELL_STYLES.height`).\n '$row-height': {\n '': '$size-lg',\n 'size=xsmall': '$size-sm',\n 'size=small': '$size-md',\n 'size=large': '$size-xl',\n 'size=xlarge': '7x',\n },\n '$header-height': {\n '': '$size-md',\n 'size=xsmall': '$size-xs',\n 'size=small': '$size-sm',\n 'size=large': '$size-lg',\n 'size=xlarge': '$size-xl',\n },\n // 16px. Matches the `cellHorizontalPadding` the Cloud tables ship (ag-grid's\n // own default is 15px, which is off the 8px grid).\n '$cell-padding-x': '2x',\n '$cell-padding-y': 0,\n '$pin-offset': '0px',\n $dim: 1,\n '$link-decoration': 'none',\n '$resizer-hit': '1x',\n '$resizer-offset': '-.5x',\n '$resizer-line-width': '1bw',\n '#resizer-line': '#clear',\n // Vertical rules between columns: on for a grid read down a column, off for\n // a list read across a row. See `TableView`'s `hasColumnDividers`.\n '$column-rule': { '': '0px', 'column-dividers': '1bw' },\n // Neutral defaults so a cell rendered outside a row still paints sanely.\n '#row-base': '#surface',\n '#row-overlay': '#clear',\n '#row-text': '#surface-text',\n // The cell-level pair defaults to the row's, and a tinted column overrides\n // its own — see `CELL_STYLES`. Declared here too so the chain has a root even\n // for a cell that is somehow outside a row.\n '#cell-base': '#row-base',\n '#cell-text': '#row-text',\n\n /* ── frame ────────────────────────────────────────────────────────── */\n display: 'grid',\n gridRows: 'max-content minmax(0, 1fr) max-content',\n gridColumns: 'minmax(0, 1fr)',\n position: 'relative',\n boxSizing: 'border-box',\n fill: '#surface',\n color: '#surface-text',\n radius: { '': 0, 'shape=card': '1cr' },\n border: { '': false, 'shape=card': true },\n overflow: 'hidden',\n // Bounded by the consumer (`height` / `maxHeight`). There is no page-scroll\n // mode: an unbounded table simply sizes to its content.\n height: 'max 100%',\n\n /* ── the single scroller ──────────────────────────────────────────── */\n Scroller: {\n $: '>',\n gridRow: 2,\n position: 'relative',\n overflow: 'auto',\n /**\n * No focus ring of its own.\n *\n * The scroller takes `tabIndex={-1}` so a cell press can move focus here\n * and the range's shortcuts (Escape, ⌘/Ctrl+C) have somewhere to land. It\n * is a mechanism, not a control the user aimed at — but the browser does\n * not know that, and drew its default `outline: auto` around the whole\n * scrollport. Three edges are clipped by the frame's `overflow: hidden`,\n * so what actually shipped was a stray line across the bottom of the\n * table, right above the footer.\n *\n * Nothing is lost by removing it: focus only ever arrives here alongside a\n * selected cell, and that cell draws its own ring.\n *\n * `'none'`, not `false` — tasty reads `false` as \"no ring of the kit's\n * own\" and emits no declaration at all, which leaves the browser's default\n * in place. Verified: with `false` the Scroller's rule carried no\n * `outline` property.\n */\n outline: 'none',\n // A reserved gutter stops an appearing scrollbar from reflowing every\n // column. With one scroller for head and body there is nothing else to\n // keep in sync — this is the whole reason for the native-table design.\n scrollbar: 'thin stable',\n // Locked per axis, and only on an axis that can actually scroll.\n //\n // `none` rather than `contain`: both stop a swipe at the scroll edge from\n // chaining to the page — which is what keeps a horizontal flick from\n // triggering browser back-navigation — but `contain` still allows the\n // rubber-band bounce, and bouncing a table drags its rows away from the\n // sticky header and shows blank surface behind them.\n //\n // The non-scrollable axis stays `auto` on purpose. Chrome applies\n // overscroll rules to any `overflow: auto` element, including one whose\n // content fits, so locking both axes unconditionally makes a five-row\n // table swallow the wheel and pin the page behind it.\n // While a range drag is in progress the pointer is painting cells, not\n // text — without this a drag across the grid leaves every cell it passed\n // highlighted blue underneath the range.\n userSelect: { '': 'auto', 'range-dragging': 'none' },\n overscrollBehavior: {\n '': 'auto',\n 'scroll-x & scroll-y': 'none',\n 'scroll-x & !scroll-y': 'none auto',\n '!scroll-x & scroll-y': 'auto none',\n },\n },\n\n Table: {\n $: '> Scroller >',\n // The whole table fades while a refresh is in flight — header included.\n // Dimming only the rows left the header at full strength, which read as\n // though the columns were current and only the data was not.\n opacity: { '': 1, stale: 0.5 },\n // `#black` throughout, but only its ALPHA is doing anything: a gradient\n // mask defaults to `mask-mode: alpha`, so the colour channel is discarded\n // and `#black.4` is simply \"40% through\". Any opaque token would render\n // identically — `#black` is the conventional way to write it.\n maskImage: {\n '': 'none',\n stale:\n 'linear-gradient(90deg, #black 0%, #black 35%, #black.4 50%, #black 65%, #black 100%)',\n // A flat, fully opaque mask is a no-op, so there is nothing to sweep —\n // the table still fades, it just does not move. A loading state can\n // last a long time, and this one would otherwise animate continuously\n // beside the data with no way to stop it. Written as its own gradient\n // rather than `none` so it cannot merge with the default above.\n '@media(prefers-reduced-motion)':\n 'linear-gradient(90deg, #black 0%, #black 100%)',\n },\n // Three times the width, so the band is a third of the table and there is\n // an opaque stretch either side of it. The default `repeat` tiles\n // seamlessly, both ends of the gradient being fully opaque.\n //\n // oxlint's `tasty(known-property)` flags this — its property list has\n // `maskImage` but not `maskSize`, in either spelling. Tasty passes an\n // unknown key through as raw CSS, so it emits fine: verified computing to\n // `300% 100%` with the sweep running. The warning is the linter's gap.\n maskSize: '300% 100%',\n animation: {\n '': 'none',\n stale: `${refreshSweep} 1.4s linear infinite`,\n },\n // Belt and braces with the flat mask above, and the same shape `Spin`\n // already uses.\n animationPlayState: {\n '': 'running',\n '@media(prefers-reduced-motion)': 'paused',\n },\n transition: 'opacity',\n // `fixed` makes `<colgroup>` authoritative, so the header and the body\n // are guaranteed to agree on every column width.\n tableLayout: 'fixed',\n // `separate` is required: with `collapse`, a sticky `<thead>` loses its\n // borders and they scroll away with the content.\n borderCollapse: 'separate',\n borderSpacing: 0,\n // The exact width is set inline from the resolved layout; this is only\n // the pre-measurement fallback.\n width: '100%',\n preset: 't3',\n },\n\n /* ── head ─────────────────────────────────────────────────────────── */\n Head: {\n $: '> Scroller > Table >',\n position: { '': 'static', 'sticky-header': 'sticky' },\n inset: { '': 'auto', 'sticky-header': '0 top' },\n zIndex: 2,\n },\n HeadRow: {\n $: '> Scroller > Table > Head >',\n ...ROW_STYLES,\n // Header rows never carry interaction paint; neutralise the inherited\n // tokens so nothing can leak in from a row above.\n '#row-base': '#surface-2',\n '#row-overlay': '#clear',\n '#row-text': '#dark-03',\n $dim: 1,\n },\n HeaderGroupCell: {\n $: '> Scroller > Table > Head > HeadRow >',\n ...CELL_STYLES,\n padding: 0,\n paddingInline: 0,\n height: '($header-height + 1bw)',\n preset: 't3m',\n border: '1bw #border bottom, $column-divider #border right',\n fill: '#surface-3',\n userSelect: 'none',\n position: { '': 'relative', '@own(pin=start | pin=end)': 'sticky' },\n overflow: 'hidden',\n zIndex: { '': 'auto', '@own(pin=start | pin=end)': 3 },\n },\n HeaderCell: {\n $: '> Scroller > Table > Head > HeadRow >',\n ...CELL_STYLES,\n // No padding at all: the `Item` inside fills the cell edge to edge and\n // supplies the indent itself, per side. That is what lets a leading icon\n // sit tighter than text and a trailing icon sit flush — see\n // `TableHeaderItem`.\n //\n // `paddingInline` as well as the shorthand: the shared cell styles set\n // the longhand for the checkbox column, and a longhand arriving through\n // the spread outlives a `padding: 0` written after it.\n padding: 0,\n paddingInline: 0,\n height: '($header-height + 1bw)',\n // The header's typography lives here rather than on the `Item`, so a\n // consumer can restyle it through `headerCellStyles` / `styles.HeaderCell`.\n // The adapter supplies the real default via `headerPreset`; this is only\n // the fallback for a `TableView` rendered without one.\n preset: 't3m',\n border: '1bw #border bottom, $column-divider #border right',\n zIndex: { '': 'auto', '@own(pin=start | pin=end)': 3 },\n // One entry, not two sharing a value: tasty coalesces entries in a state\n // map that serialize identically, promotes them to the group's maximum\n // priority and negates them against everything below — see the row state\n // matrix below and `src/data/AGENTS.md`.\n fill: {\n '': '#cell-base #row-overlay',\n '(@own(sortable) & @own(:hover)) | @own(menu-open)':\n '#cell-base #surface-text.04',\n },\n // `pointer` wins on a sortable header: sorting is the primary action, and a\n // native drag needs movement while a click does not, so both still work.\n // `grab` is only honest where there is nothing else to click.\n cursor: {\n '': 'default',\n '@own(sortable)': 'pointer',\n '@own(draggable) & !@own(sortable)': 'grab',\n '@own(dragging)': 'grabbing',\n },\n // Matches the row being dragged.\n opacity: { '': 1, '@own(dragging)': 0.4 },\n userSelect: 'none',\n // The containing block for `Resizer`. Cells are `static` by default, so\n // without this every handle resolves against the scroller instead and\n // they all stack up at its right edge.\n position: { '': 'relative', '@own(pin=start | pin=end)': 'sticky' },\n // A cell clips its overflow so a long label cannot bleed into its\n // neighbour, but the resize handle straddles the boundary on purpose and\n // would lose its outer half. Only cells that actually have one opt out.\n overflow: { '': 'hidden', '@own(resizable)': 'visible' },\n /**\n * How visible the sort arrow is when the column is NOT sorted — read by\n * `SortIndicator`.\n *\n * Published as an inherited custom property because a sub-element's state\n * keys resolve against the ROOT, not its DOM parent: from inside\n * `SortIndicator`, `@own(:hover)` asks whether the 16px arrow itself is\n * hovered, not the header cell it sits in. Same mechanism as `$dim` and\n * `$resizer-offset`.\n *\n * `:focus-visible` as well as `:hover`, so a keyboard user gets the same\n * hint. One grouped key rather than two entries sharing `.4`: a state map\n * whose entries serialize identically gets coalesced and negated.\n */\n '$sort-hint': {\n '': 0,\n '@own(sortable) & (@own(:hover) | @own(:focus-visible))': 0.4,\n },\n // How far the handle hangs past this cell's trailing edge — read by\n // `Resizer`. Published as an inherited custom property rather than asked\n // for from the handle with `@parent(...)`: a sub-element's state keys\n // resolve against the ROOT, so the handle cannot ask about the cell it\n // sits in (the same reason `#row-base` and `$link-decoration` exist).\n //\n // The trailing column has no neighbour to straddle. Left hanging, it puts\n // half its width past the table and the scroller gains a few pixels of\n // horizontal scroll onto blank space.\n '$resizer-offset': { '': '-.5x', '@own(last-column)': '0px' },\n },\n\n /**\n * The column resize handle, on the header cell's trailing edge.\n *\n * Positioned with longhands rather than an `inset` shorthand: the\n * arithmetic form compiled to garbage (`32px -24px 1px 16px`), which put\n * the handle inside the body and collapsed its height. It sits fully inside\n * the cell, so there is no negative offset to get wrong.\n */\n Resizer: {\n $: '> Scroller > Table > Head > HeadRow > HeaderCell >',\n position: 'absolute',\n top: 0,\n bottom: 0,\n // Centred on the boundary rather than tucked inside the cell: a handle\n // you can only grab from one side of the line is half a target, and the\n // focus ring would sit visibly off to the left of the edge it resizes.\n // The offset is half of `$resizer-hit`.\n right: '$resizer-offset',\n // A 1px line is impossible to grab, so the hit area is wider than it.\n width: '$resizer-hit',\n zIndex: 2,\n cursor: 'col-resize',\n touchAction: 'none',\n outline: {\n '': 'none',\n '@own(:focus-visible)': '1bw #focus',\n },\n outlineOffset: '1bw',\n\n /**\n * The line is a real child, not `&::after`: state maps inside a\n * pseudo-element block do not compile — `width` and `fill` both came out\n * empty — so the handle's own state is published as tokens instead, the\n * same mechanism `#row-base` and `$link-decoration` use.\n */\n // Drawn at rest so the handle is discoverable — except when the table\n // already rules its columns, where the cell's own border is that line and\n // a second one 4px away reads as a doubled edge. (`column-dividers` has no\n // `@own`: bare keys resolve against the root, which is where it lives.)\n '#resizer-line': {\n '': '#border',\n 'column-dividers': '#clear',\n '@own(:hover) | @own(:focus-visible)': '#purple',\n },\n '$resizer-line-width': {\n '': '1bw',\n '@own(:hover) | @own(:focus-visible)': '2bw',\n },\n },\n\n /**\n * The visible column edge. Drawn at rest rather than only on hover — an\n * affordance you have to find by hovering an 8px strip is one nobody finds.\n * A table that rules its columns already draws that edge, so there the line\n * only appears under the cursor (see `#resizer-line`).\n */\n ResizerLine: {\n $: '> Scroller > Table > Head > HeadRow > HeaderCell > Resizer >',\n // Absolute rather than flex-aligned: `placeContent` maps to\n // `align-content justify-content`, so the obvious-looking `'end center'`\n // silently centred the line instead of ending it.\n //\n // Centred inside the handle, which is itself centred on the boundary, so\n // the line lands exactly on the edge it represents and a thicker hover\n // state grows evenly to both sides.\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: '50%',\n translate: '-50% 0',\n width: '$resizer-line-width',\n fill: '#resizer-line',\n transition: 'theme',\n },\n\n /**\n * Where a dragged column would land.\n *\n * A distinct sub-element NAME from the row's `DropIndicator` rather than a\n * second selector chain on the same one: two entries whose chains differ is\n * exactly the shape that produced an indicator matching nothing at all.\n *\n * Positioned fully INSIDE the cell box. `HeaderCell` is `overflow: hidden`\n * and only opts out to `visible` when it is resizable, so the centred\n * `translate: -50%` the resizer line uses would lose its outer half on every\n * non-resizable column.\n */\n ColumnDropIndicator: {\n $: '> Scroller > Table > Head > HeadRow > HeaderCell >',\n position: 'absolute',\n top: 0,\n bottom: 0,\n width: '2bw',\n insetInlineStart: { '': 'auto', '@own(position=before)': 0 },\n insetInlineEnd: { '': 'auto', '@own(position=after)': 0 },\n fill: '#purple',\n radius: '1r',\n // Above the pinned header cell (3) and the resize handle (2).\n zIndex: 4,\n },\n\n /**\n * Centres the checkbox in its cell. A `<td>` cannot be a flex container\n * without dropping out of table layout, so the centring lives on a wrapper\n * inside it.\n *\n * Descendant rather than direct-child, so one entry covers both the header\n * cell and the body cells.\n */\n /**\n * The stretched row link. A `<tr>` cannot be wrapped in an `<a>`, so the\n * anchor sits in the row-header cell and covers the row through `inset`.\n * Its text comes from the row-header cell, so the accessible name is the\n * row's name rather than \"link\".\n *\n * Below the cells' own content in the stacking order, so an in-cell button\n * or menu trigger still takes its own clicks.\n */\n RowLink: {\n $: '> Scroller > Table > Body > Row > Cell >',\n position: 'absolute',\n inset: 0,\n zIndex: 0,\n // The row already paints hover and focus; the link must add nothing.\n fill: '#clear',\n radius: 0,\n outline: {\n '': 'none',\n // Keyboard focus still has to be visible, even though the row is what\n // the user perceives as focused.\n focused: '1bw #focus',\n },\n },\n\n /**\n * The line showing where a dragged row would land.\n *\n * Its own row, because a native table cannot hold an arbitrary element\n * between two rows — the shape `ListBox` uses with `<li>`.\n *\n * The row and its cell collapse to nothing and the line is positioned out\n * of flow, so inserting one mid-drag does not push the rows apart. The line\n * then sits *over* the divider it replaces rather than beside it.\n */\n DropIndicatorRow: {\n $: '> Scroller > Table > Body >',\n height: 0,\n },\n\n DropIndicatorCell: {\n $: '> Scroller > Table > Body > DropIndicatorRow >',\n // Every one of these matters: a `<td>` carries UA padding, and any of\n // them left in place gives the row real height and shifts the table.\n padding: 0,\n border: 0,\n height: 0,\n lineHeight: 0,\n fontSize: 0,\n // The containing block for the line below.\n position: 'relative',\n overflow: 'visible',\n },\n\n DropIndicator: {\n $: '> Scroller > Table > Body > DropIndicatorRow > DropIndicatorCell >',\n position: 'absolute',\n insetInlineStart: 0,\n insetInlineEnd: 0,\n top: 0,\n height: '2bw',\n // Centred on the boundary, so it covers the row divider instead of\n // sitting above or below it.\n translate: '0 -50%',\n fill: '#purple',\n radius: '1r',\n zIndex: 3,\n outline: {\n '': 'none',\n // `@own`, not a bare `:focus-visible`: a sub-element's state keys\n // resolve against the ROOT, so the plain form asked whether the whole\n // table was focused. This is the keyboard drop target and needs its own.\n '@own(:focus-visible)': '2bw #purple',\n },\n outlineOffset: '1bw',\n },\n\n /**\n * Row numbers. Muted and tabular so they read as a ruler down the side\n * rather than as a data column competing with the real ones.\n */\n RowNumber: {\n $: '> Scroller > Table > Body > Row > Cell',\n color: '#surface-text-soft',\n fontVariantNumeric: 'tabular-nums',\n },\n\n /** Wraps the `⋮` trigger so it centres without becoming a table cell box. */\n RowActions: {\n $: '> Scroller > Table > Body > Row > Cell >',\n position: 'relative',\n // Above `RowLink`, or the stretched anchor would swallow its clicks.\n zIndex: 1,\n display: 'flex',\n placeContent: 'center',\n placeItems: 'center',\n height: '100%',\n },\n\n /**\n * Hierarchy chrome inside the consumer-selected tree column. The wrapper\n * owns indentation so custom renderers, links and text truncation all move\n * together as one row label.\n */\n TreeContent: {\n $: '> Scroller > Table > Body > Row > Cell >',\n display: 'flex',\n alignItems: 'center',\n gap: '.5x',\n minWidth: 0,\n padding: 'left ($tree-indent * 2x)',\n '$tree-indent': '($tree-level, 0)',\n },\n\n TreeValue: {\n $: '> Scroller > Table > Body > Row > Cell > TreeContent >',\n flexGrow: 1,\n flexShrink: 1,\n flexBasis: 0,\n minWidth: 0,\n overflow: 'hidden',\n },\n\n TreeToggle: {\n $: '> Scroller > Table > Body > Row > Cell > TreeContent >',\n flexGrow: 0,\n flexShrink: 0,\n flexBasis: 'auto',\n },\n\n SelectionBox: {\n $: '> Scroller > Table',\n display: 'flex',\n placeContent: 'center',\n placeItems: 'center',\n height: '100%',\n },\n\n /**\n * The sort arrow. Lives in the header `Item`'s `suffix`, so it participates\n * in the header's grid rather than overlapping the label. Reserved space\n * even when unsorted — otherwise the label shifts on every sort.\n */\n SortIndicator: {\n // Descendant, not direct child: the indicator is handed to the header\n // `Item` as a slot, so it renders inside Item's own `RightIcon` (or\n // `Suffix`) wrapper rather than directly under the `<th>`.\n $: '> Scroller > Table > Head > HeadRow > HeaderCell',\n display: 'grid',\n placeItems: 'center',\n width: '2x',\n height: '2x',\n color: '#surface-text',\n // Hovering a sortable header previews the arrow it would get; sorting for\n // real makes it solid. `$sort-hint` is the header cell's answer — see\n // there for why this cannot just ask about hover itself.\n //\n // The preview points the right way for free: `data-dir` is absent while\n // unsorted, so the `scale` map below leaves the chevron pointing up, and\n // the first press of an unsorted column sorts ascending. The hint predicts\n // the press rather than just advertising that one is possible.\n opacity: {\n '': '$sort-hint',\n '@own(sorted)': 1,\n },\n // No `scale` flip any more: `TableView` renders the real\n // `ArrowNarrowDownIcon` for `desc` rather than turning the up arrow over,\n // so there is no transform left to animate. `opacity` still is — that is\n // the hover hint fading in.\n transition: 'opacity',\n },\n\n /* ── body ─────────────────────────────────────────────────────────── */\n Body: {\n $: '> Scroller > Table >',\n },\n Row: {\n $: '> Scroller > Table > Body >',\n ...ROW_STYLES,\n // `position: relative` (below) is also the containing block for\n // `RowLink`, which stretches over the whole row from inside the\n // row-header cell, and for the drop indicator.\n /**\n * Totals and subtotals, pinned to the edges of the scroller.\n *\n * They live in `<tbody>` so they keep ordinary row styling, so the\n * stickiness has to be stated here. The top offset is the header's own\n * height — a pinned row sticks *under* the header, not over it.\n */\n position: { '': 'relative', '@own(pinned)': 'sticky' },\n insetBlockStart: {\n '': 'auto',\n '@own(pinned=top)': '($header-height + 1bw)',\n },\n insetBlockEnd: { '': 'auto', '@own(pinned=bottom)': 0 },\n zIndex: { '': 'auto', '@own(pinned)': 1 },\n\n // The row being dragged, and a row that would receive a drop *on* it.\n // Landing *between* rows is drawn by `DropIndicator` instead.\n opacity: { '': 1, '@own(dragging)': 0.4 },\n // An inset shadow rather than an outline: an outline on a `<tr>` is drawn\n // outside the row and overlaps its neighbours, and `inside` is not a\n // modifier `outline` accepts.\n shadow: {\n '': false,\n '@own(drop-target)': 'inset 0 0 0 2bw #purple',\n },\n cursor: {\n '': 'default',\n '@own(clickable)': 'pointer',\n '@own(draggable)': 'grab',\n '@own(dragging)': 'grabbing',\n },\n\n /* ─── the row state matrix ─────────────────────────────────────────\n * Three orthogonal maps rather than one. Deliberate: tasty coalesces\n * entries in a single state map that share a serialized value, promoting\n * them to the group's maximum priority and negating them against\n * everything below — which silently turns a middle-priority compound\n * rule into FALSE (see src/data/AGENTS.md). A combined\n * `selected × hovered × focused × disabled × dimmed × odd` map is 64\n * entries and would be riddled with collisions.\n *\n * 1. `odd` lives alone in `#row-base`, with two distinct values.\n * 2. `dimmed` never appears in a fill map — it drives `$dim`/`#row-text`.\n * 3. Every value string inside `#row-overlay` is unique.\n * 4. The bare '' default is exempt from merging, so it may repeat a\n * value used elsewhere.\n * ────────────────────────────────────────────────────────────────── */\n '#row-base': {\n '': '#surface',\n '@own(odd)': '#surface-2',\n // Opaque and distinct, because scrolling rows pass underneath it.\n '@own(pinned)': '#surface-3',\n },\n '#row-overlay': {\n '': '#surface-text.0',\n '@own(:hover)': '#surface-text.04',\n '@own(focused)': '#surface-text.06',\n '@own(selected)': '#surface-text.09',\n '@own(selected & :hover)': '#surface-text.12',\n '@own(drop-target)': '#purple.10',\n '@own(disabled)': '#surface-text.02',\n },\n '#row-text': {\n '': '#surface-text',\n '@own(dimmed)': '#surface-text-soft',\n '@own(disabled)': '#surface-text-soft-2',\n },\n $dim: {\n '': 1,\n '@own(dimmed)': 0.6,\n },\n // Read by a row-header cell that carries a `rowLink`.\n '$link-decoration': {\n '': 'none',\n '@own(:hover)': 'underline',\n },\n },\n Cell: {\n $: '> Scroller > Table > Body > Row >',\n ...CELL_STYLES,\n // A row-header cell is a `<th>`, which the UA renders bold. Weight is the\n // table's decision, not the tag's — and a UA rule beats inheritance, so it\n // has to be stated. Deliberately NOT in the shared cell styles: the header\n // cell is a `<th>` as well, and there this would overwrite the weight its\n // `preset` sets.\n fontWeight: {\n '': 'inherit',\n // A row-header cell carrying a `rowLink` reads as a link, so it takes\n // the weight `Link` does — colour alone is easy to miss in a dense\n // table, and there is nothing else marking the row as navigable.\n '@own(link)': 600,\n },\n color: {\n '': '#cell-text',\n '@own(link)': '#purple-text',\n },\n // Underline only while the row is hovered, matching how the kit's `Link`\n // stays undecorated at rest.\n //\n // Read from a token the Row publishes rather than asking about the row\n // from here: a sub-element's state keys resolve against the *root*, and\n // `@parent(:hover)` did not constrain the rule at all — every linked cell\n // came out underlined. Custom properties inherit through the DOM and\n // ignore selector context, which is the same mechanism `$dim` and\n // `#row-text` already use.\n textDecoration: {\n '': 'none',\n '@own(link)': '$link-decoration',\n },\n // A bottom border separates two rows, so the last row has nothing to\n // separate from. Whenever something else already draws that closing edge\n // — the frame in `card` shape, or the footer's own top border — the row's\n // border lands on top of it and reads as one thick 2px line.\n //\n // `last-row` is stamped on the cell by the renderer rather than derived\n // in CSS, for two reasons:\n //\n // 1. Virtualization. The window is padded with spacer `<tr>`s, so\n // mid-scroll the last *mounted* row is not `:last-child` — the\n // trailing spacer is. A structural selector would move the missing\n // border around as you scroll; the stamped flag always marks the\n // last row of the DATA.\n // 2. `@parent(:last-child, >)` asks \"is my parent the last child of my\n // grandparent\". Asked from the Row that is a question about the\n // table body, identical for every row, and an ancestor-constant\n // condition inside a mutually-exclusive map silently deletes the\n // default's `:not(...)` branch — which is how an earlier attempt\n // removed every divider at once. (`@own(:last-child)` is the form\n // that varies per row, but see 1.)\n //\n // `column-dividers` has no `@own`: a sub-element's bare state keys resolve\n // against the ROOT, which is exactly right here — the vertical rule is a\n // property of the table, not of one cell.\n //\n // Every value string is distinct, which is what keeps this map safe from\n // tasty's identical-value merge (see src/data/AGENTS.md). That is also why\n // the two \"no closing edge\" cases used to be OR'd into one key; the state\n // row no longer needs it, since it is a `StateCell` rather than a `Cell`.\n // Two groups, so the horizontal and the vertical rule vary independently:\n // the trailing group's width is `$column-divider`, which already knows\n // whether this table rules its columns and whether this is the last one.\n // Directions a group does not name come out zero-width, which is how the\n // middle entry drops the bottom edge without touching the rule.\n //\n // Three entries, three distinct values — a map whose entries share a\n // serialized value gets merged and negated against everything below it\n // (see src/data/AGENTS.md), which is what an exhaustive\n // dividers × last-column × last-row matrix would have walked into.\n border: {\n '': '1bw #border bottom, $column-divider #border right',\n // The frame or the footer already draws the closing edge; a second one\n // on top of it reads as a single 2px line.\n '(shape=card | has-footer) & @own(last-row)':\n '$column-divider #border right',\n // A pinned bottom row opens the pinned group, so the divider goes above\n // it — the last scrolling row has already dropped its own bottom edge,\n // and a total sitting at the frame's edge needs nothing below.\n '@own(pinned=bottom)': '1bw #border top, $column-divider #border right',\n },\n },\n\n /**\n * The single full-span cell that carries the empty / no-results / error\n * content.\n *\n * Deliberately NOT a `Cell`: a `Cell` paints `#row-base`/`#row-overlay`, so\n * the state content picked up the row's banding and hover fill and lit up\n * under the cursor as though it were a row of data to click. It is not a\n * row, so it does not read the row's paint tokens at all.\n */\n StateCell: {\n $: '> Scroller > Table > Body > Row >',\n boxSizing: 'border-box',\n fill: '#surface',\n color: '#surface-text',\n border: false,\n textAlign: 'center',\n verticalAlign: 'middle',\n },\n\n /**\n * Empty / no-results / error content. Rendered as a full-span cell inside\n * the table rather than as an absolutely-positioned overlay, so the column\n * header stays visible and nothing has to be excluded from the scroll area.\n */\n StateContent: {\n $: '> Scroller > Table > Body > Row > StateCell >',\n display: 'grid',\n placeItems: 'center',\n placeContent: 'center',\n gap: '1x',\n padding: '8x 2x',\n preset: 't3',\n color: '#surface-text-soft',\n textAlign: 'center',\n },\n\n /* ── foot (pinned totals) ─────────────────────────────────────────── */\n /* ── consumer overlay ─────────────────────────────────────────────── */\n /**\n * Sits over the Scroller, not inside it, so it stays put while the rows\n * underneath remain scrollable and readable.\n *\n * A refresh does NOT use this — it sweeps the table itself (see `Table`).\n * A spinner parked in the middle of the rows covered the very content the\n * \"keep showing the previous result\" behaviour exists to preserve.\n */\n Overlay: {\n $: '>',\n gridRow: 2,\n position: 'absolute',\n inset: 0,\n display: 'flex',\n placeContent: 'center',\n placeItems: 'center',\n // No scrim: the body already dims itself, and a second layer of dimming\n // over the same rows only makes the previous result harder to read — the\n // one thing this behaviour exists to preserve.\n zIndex: 3,\n pointerEvents: 'none',\n },\n\n Foot: {\n $: '> Scroller > Table >',\n position: 'sticky',\n inset: '0 bottom',\n zIndex: 2,\n },\n FootRow: {\n $: '> Scroller > Table > Foot >',\n ...ROW_STYLES,\n '#row-base': '#surface-2',\n '#row-overlay': '#clear',\n '#row-text': '#surface-text',\n $dim: 1,\n },\n FootCell: {\n $: '> Scroller > Table > Foot > FootRow >',\n ...CELL_STYLES,\n border: '1bw #border top',\n preset: 't3m',\n },\n },\n});\n\nconst TREE_TOGGLE_STYLES: Styles = {\n display: 'grid',\n placeItems: 'center',\n placeContent: 'center',\n flexGrow: 0,\n flexShrink: 0,\n flexBasis: 'auto',\n width: '3x',\n height: '3x',\n radius: true,\n transition: 'theme',\n};\n\n/** Disclosure control rendered in the configured tree column. */\nexport const TableTreeToggle = tasty(Action, {\n qa: 'TableTreeToggle',\n styles: {\n ...TREE_TOGGLE_STYLES,\n color: { '': '#dark-02', ':hover': '#dark' },\n fill: { '': '#clear', ':hover': '#dark.04' },\n },\n});\n\n/** Leaf placeholder matching the disclosure control's footprint. */\nexport const TableTreeTogglePlaceholder = tasty({\n styles: TREE_TOGGLE_STYLES,\n});\n\n/**\n * The header cell's content. `Item` lives INSIDE the `<th>`, never as the `<th>`\n * itself — it emits `aria-selected` unconditionally (`Item.tsx:964`), which on a\n * `columnheader` would claim the column is selected rather than sorted.\n *\n * Keeping it inside also means the `<th>` owns the interaction fill while\n * `Item` contributes only layout, and — the real prize — `Item`'s `Actions`\n * slot already stops click/pointer/Enter/Space propagation, so pressing a\n * column menu can never trigger the sort.\n */\nexport const TableHeaderItem = tasty(Item, {\n as: 'div',\n // Deliberately NOT `type=\"header\"`. That maps Item's preset onto the heading\n // scale via state rules that outrank a plain override, and it renders the\n // label as an `<h3>`, which would put every column name into the document\n // outline.\n styles: {\n // `Item` is `inline-grid`; the header cell needs it to fill the `<th>`\n // horizontally. Same fix as `TreeRowItem` in Tree/styled.ts. Its height is\n // left alone so it keeps its natural `medium` size rather than stretching\n // to whatever the row height happens to be.\n display: 'grid',\n width: '100%',\n radius: 0,\n // `Item` reserves a 1px transparent border for its focus/hover treatments.\n // The `<th>` owns those here, and the border would inset the label by 1px\n // against the body cells below.\n border: 0,\n // Typography and colour are the header CELL's decision, so they stay\n // overridable through the table's own `styles`. See `HeaderCell`.\n preset: 'inherit',\n color: 'inherit',\n // Zero: `Item` applies this to the label only, which would indent the label\n // but not an icon beside it. The padding below sits on the `Item` box\n // instead, so it moves whatever is actually first in the row.\n '$inline-padding': 0,\n\n /**\n * The indent, per side, chosen for optical rather than geometric alignment.\n *\n * Text lines up with the body text below it at the full cell padding. An\n * icon does not: at this size it is a small, light shape, and the same 16px\n * reads as a gap — 8px sits right. A trailing icon (the sort arrow) wants\n * none at all, so it hangs at the column edge rather than floating short of\n * it.\n *\n * The `padding` shorthand rather than `paddingInline`: `Item` writes its own\n * `padding`, and a shorthand landing after a longhand wipes it — the\n * longhand form compiled away silently and every column kept the default.\n *\n * One map rather than per-side rules so the four combinations stay\n * explicit, and every value string is distinct — a state map whose entries\n * share a serialized value gets merged and negated (see\n * src/data/AGENTS.md).\n */\n padding: {\n '': '0 $cell-padding-x',\n 'has-icon': '1x left, $cell-padding-x right',\n 'has-right-icon': '$cell-padding-x left',\n 'has-icon & has-right-icon': '1x left',\n },\n // The `<th>` owns the interaction paint — neutralise Item's own ramp so the\n // two do not stack.\n fill: {\n '': '#clear',\n hovered: '#clear',\n pressed: '#clear',\n selected: '#clear',\n },\n // The default `c2` header preset uppercases its text. That is right for the\n // column name and wrong for the sentence explaining it.\n Description: { textTransform: 'none' },\n },\n});\n"],"mappings":"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"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/** @license MIT | @cube-dev/ui-kit v0.165.0 | Cube Dev Team */
|
|
2
|
+
//#region src/components/data/TableBase/table-tree.ts
|
|
3
|
+
/** Build identity and parent/child indexes without modifying consumer rows. */
|
|
4
|
+
function buildTableTree(rows, getChildren, getKey) {
|
|
5
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
6
|
+
const parentOf = /* @__PURE__ */ new Map();
|
|
7
|
+
const childrenOf = /* @__PURE__ */ new Map();
|
|
8
|
+
const duplicateKeys = [];
|
|
9
|
+
const cyclicKeys = [];
|
|
10
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
11
|
+
const visitingRows = /* @__PURE__ */ new Set();
|
|
12
|
+
let sourceIndex = 0;
|
|
13
|
+
const visit = (input, parentKey, level) => {
|
|
14
|
+
const output = [];
|
|
15
|
+
input.forEach((row, siblingIndex) => {
|
|
16
|
+
const currentSourceIndex = sourceIndex++;
|
|
17
|
+
const key = getKey(row, currentSourceIndex);
|
|
18
|
+
if (visiting.has(key) || visitingRows.has(row)) {
|
|
19
|
+
cyclicKeys.push(key);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (byKey.has(key)) {
|
|
23
|
+
duplicateKeys.push(key);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const node = {
|
|
27
|
+
key,
|
|
28
|
+
row,
|
|
29
|
+
parentKey,
|
|
30
|
+
level,
|
|
31
|
+
siblingIndex,
|
|
32
|
+
siblingCount: input.length,
|
|
33
|
+
sourceIndex: currentSourceIndex,
|
|
34
|
+
children: []
|
|
35
|
+
};
|
|
36
|
+
byKey.set(key, node);
|
|
37
|
+
parentOf.set(key, parentKey);
|
|
38
|
+
visiting.add(key);
|
|
39
|
+
visitingRows.add(row);
|
|
40
|
+
node.children = visit(getChildren(row) ?? [], key, level + 1);
|
|
41
|
+
visiting.delete(key);
|
|
42
|
+
visitingRows.delete(row);
|
|
43
|
+
childrenOf.set(key, node.children.map((child) => child.key));
|
|
44
|
+
output.push(node);
|
|
45
|
+
});
|
|
46
|
+
return output;
|
|
47
|
+
};
|
|
48
|
+
return {
|
|
49
|
+
roots: visit(rows, null, 0),
|
|
50
|
+
byKey,
|
|
51
|
+
parentOf,
|
|
52
|
+
childrenOf,
|
|
53
|
+
duplicateKeys,
|
|
54
|
+
cyclicKeys
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function sortTableTree(nodes, compare) {
|
|
58
|
+
const sorted = nodes.map((node) => ({
|
|
59
|
+
...node,
|
|
60
|
+
children: sortTableTree(node.children, compare)
|
|
61
|
+
})).sort(compare);
|
|
62
|
+
return sorted.map((node, siblingIndex) => ({
|
|
63
|
+
...node,
|
|
64
|
+
siblingIndex,
|
|
65
|
+
siblingCount: sorted.length
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Keep matching rows, their ancestor paths, and the complete subtree of a row
|
|
70
|
+
* that matches itself. Every retained branch is opened while filtering so a
|
|
71
|
+
* match can never remain hidden behind a collapsed ancestor.
|
|
72
|
+
*/
|
|
73
|
+
function filterTableTree(nodes, matches) {
|
|
74
|
+
const forcedExpandedKeys = /* @__PURE__ */ new Set();
|
|
75
|
+
const cloneComplete = (node) => {
|
|
76
|
+
const children = node.children.map(cloneComplete);
|
|
77
|
+
if (children.length) forcedExpandedKeys.add(node.key);
|
|
78
|
+
return {
|
|
79
|
+
...node,
|
|
80
|
+
children: reindexTableTree(children)
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
const visit = (node) => {
|
|
84
|
+
if (matches(node)) return cloneComplete(node);
|
|
85
|
+
const children = node.children.map(visit).filter((child) => child != null);
|
|
86
|
+
if (!children.length) return null;
|
|
87
|
+
forcedExpandedKeys.add(node.key);
|
|
88
|
+
return {
|
|
89
|
+
...node,
|
|
90
|
+
children: reindexTableTree(children)
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
return {
|
|
94
|
+
roots: reindexTableTree(nodes.map(visit).filter((node) => node != null)),
|
|
95
|
+
forcedExpandedKeys
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/** Re-number a transformed sibling collection for its rendered treegrid. */
|
|
99
|
+
function reindexTableTree(nodes) {
|
|
100
|
+
return nodes.map((node, siblingIndex) => ({
|
|
101
|
+
...node,
|
|
102
|
+
siblingIndex,
|
|
103
|
+
siblingCount: nodes.length,
|
|
104
|
+
children: reindexTableTree(node.children)
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
function flattenTableTree(nodes, expandedKeys) {
|
|
108
|
+
const output = [];
|
|
109
|
+
const visit = (items) => {
|
|
110
|
+
for (const node of items) {
|
|
111
|
+
output.push(node);
|
|
112
|
+
if (expandedKeys == null || expandedKeys.has(node.key)) visit(node.children);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
visit(nodes);
|
|
116
|
+
return output;
|
|
117
|
+
}
|
|
118
|
+
function isTableTreeDescendant(model, possibleDescendant, ancestor) {
|
|
119
|
+
let parent = model.parentOf.get(possibleDescendant);
|
|
120
|
+
while (parent != null) {
|
|
121
|
+
if (parent === ancestor) return true;
|
|
122
|
+
parent = model.parentOf.get(parent);
|
|
123
|
+
}
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
//#endregion
|
|
128
|
+
export { buildTableTree, filterTableTree, flattenTableTree, isTableTreeDescendant, reindexTableTree, sortTableTree };
|
|
129
|
+
//# sourceMappingURL=table-tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table-tree.js","names":[],"sources":["../../../../src/components/data/TableBase/table-tree.ts"],"sourcesContent":["import type { Key } from '@react-types/shared';\n\nexport interface TableTreeNode<T> {\n key: Key;\n row: T;\n parentKey: Key | null;\n level: number;\n siblingIndex: number;\n siblingCount: number;\n sourceIndex: number;\n children: TableTreeNode<T>[];\n}\n\nexport interface TableTreeModel<T> {\n roots: TableTreeNode<T>[];\n byKey: Map<Key, TableTreeNode<T>>;\n parentOf: Map<Key, Key | null>;\n childrenOf: Map<Key, Key[]>;\n duplicateKeys: Key[];\n cyclicKeys: Key[];\n}\n\n/** Build identity and parent/child indexes without modifying consumer rows. */\nexport function buildTableTree<T>(\n rows: readonly T[],\n getChildren: (row: T) => readonly T[] | undefined,\n getKey: (row: T, sourceIndex: number) => Key,\n): TableTreeModel<T> {\n const byKey = new Map<Key, TableTreeNode<T>>();\n const parentOf = new Map<Key, Key | null>();\n const childrenOf = new Map<Key, Key[]>();\n const duplicateKeys: Key[] = [];\n const cyclicKeys: Key[] = [];\n const visiting = new Set<Key>();\n const visitingRows = new Set<T>();\n let sourceIndex = 0;\n\n const visit = (\n input: readonly T[],\n parentKey: Key | null,\n level: number,\n ): TableTreeNode<T>[] => {\n const output: TableTreeNode<T>[] = [];\n\n input.forEach((row, siblingIndex) => {\n const currentSourceIndex = sourceIndex++;\n const key = getKey(row, currentSourceIndex);\n\n if (visiting.has(key) || visitingRows.has(row)) {\n cyclicKeys.push(key);\n return;\n }\n\n if (byKey.has(key)) {\n duplicateKeys.push(key);\n return;\n }\n\n const node: TableTreeNode<T> = {\n key,\n row,\n parentKey,\n level,\n siblingIndex,\n siblingCount: input.length,\n sourceIndex: currentSourceIndex,\n children: [],\n };\n\n byKey.set(key, node);\n parentOf.set(key, parentKey);\n visiting.add(key);\n visitingRows.add(row);\n node.children = visit(getChildren(row) ?? [], key, level + 1);\n visiting.delete(key);\n visitingRows.delete(row);\n childrenOf.set(\n key,\n node.children.map((child) => child.key),\n );\n output.push(node);\n });\n\n return output;\n };\n\n const roots = visit(rows, null, 0);\n\n return {\n roots,\n byKey,\n parentOf,\n childrenOf,\n duplicateKeys,\n cyclicKeys,\n };\n}\n\nexport function sortTableTree<T>(\n nodes: readonly TableTreeNode<T>[],\n compare: (a: TableTreeNode<T>, b: TableTreeNode<T>) => number,\n): TableTreeNode<T>[] {\n const sorted = nodes\n .map((node) => ({\n ...node,\n children: sortTableTree(node.children, compare),\n }))\n .sort(compare);\n\n return sorted.map((node, siblingIndex) => ({\n ...node,\n siblingIndex,\n siblingCount: sorted.length,\n }));\n}\n\nexport interface FilteredTableTree<T> {\n roots: TableTreeNode<T>[];\n forcedExpandedKeys: Set<Key>;\n}\n\n/**\n * Keep matching rows, their ancestor paths, and the complete subtree of a row\n * that matches itself. Every retained branch is opened while filtering so a\n * match can never remain hidden behind a collapsed ancestor.\n */\nexport function filterTableTree<T>(\n nodes: readonly TableTreeNode<T>[],\n matches: (node: TableTreeNode<T>) => boolean,\n): FilteredTableTree<T> {\n const forcedExpandedKeys = new Set<Key>();\n\n const cloneComplete = (node: TableTreeNode<T>): TableTreeNode<T> => {\n const children = node.children.map(cloneComplete);\n if (children.length) forcedExpandedKeys.add(node.key);\n\n return { ...node, children: reindexTableTree(children) };\n };\n\n const visit = (node: TableTreeNode<T>): TableTreeNode<T> | null => {\n if (matches(node)) return cloneComplete(node);\n\n const children = node.children\n .map(visit)\n .filter((child): child is TableTreeNode<T> => child != null);\n\n if (!children.length) return null;\n\n forcedExpandedKeys.add(node.key);\n return { ...node, children: reindexTableTree(children) };\n };\n\n return {\n roots: reindexTableTree(\n nodes.map(visit).filter((node): node is TableTreeNode<T> => node != null),\n ),\n forcedExpandedKeys,\n };\n}\n\n/** Re-number a transformed sibling collection for its rendered treegrid. */\nexport function reindexTableTree<T>(\n nodes: readonly TableTreeNode<T>[],\n): TableTreeNode<T>[] {\n return nodes.map((node, siblingIndex) => ({\n ...node,\n siblingIndex,\n siblingCount: nodes.length,\n children: reindexTableTree(node.children),\n }));\n}\n\nexport function flattenTableTree<T>(\n nodes: readonly TableTreeNode<T>[],\n expandedKeys?: ReadonlySet<Key>,\n): TableTreeNode<T>[] {\n const output: TableTreeNode<T>[] = [];\n\n const visit = (items: readonly TableTreeNode<T>[]) => {\n for (const node of items) {\n output.push(node);\n if (expandedKeys == null || expandedKeys.has(node.key)) {\n visit(node.children);\n }\n }\n };\n\n visit(nodes);\n return output;\n}\n\nexport function tableTreeDescendantKeys<T>(node: TableTreeNode<T>): Key[] {\n return flattenTableTree(node.children).map((child) => child.key);\n}\n\nexport function isTableTreeDescendant<T>(\n model: Pick<TableTreeModel<T>, 'parentOf'>,\n possibleDescendant: Key,\n ancestor: Key,\n) {\n let parent = model.parentOf.get(possibleDescendant);\n\n while (parent != null) {\n if (parent === ancestor) return true;\n parent = model.parentOf.get(parent);\n }\n\n return false;\n}\n"],"mappings":"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"}
|
|
@@ -23,6 +23,47 @@ interface CubeTableCellRange {
|
|
|
23
23
|
fromColumnKey: string;
|
|
24
24
|
toColumnKey: string;
|
|
25
25
|
}
|
|
26
|
+
interface CubeTableTreeRowState {
|
|
27
|
+
/** Zero-based depth in the hierarchy. */
|
|
28
|
+
level: number;
|
|
29
|
+
parentKey: Key$1 | null;
|
|
30
|
+
hasChildren: boolean;
|
|
31
|
+
isExpanded: boolean;
|
|
32
|
+
}
|
|
33
|
+
interface CubeTableRowExpandInfo<T = any> {
|
|
34
|
+
row: T;
|
|
35
|
+
rowKey: Key$1;
|
|
36
|
+
level: number;
|
|
37
|
+
parentKey: Key$1 | null;
|
|
38
|
+
expanded: boolean;
|
|
39
|
+
}
|
|
40
|
+
/** Shared root sizing contract used by both table adapters. */
|
|
41
|
+
interface CubeTableLayoutProps {
|
|
42
|
+
/**
|
|
43
|
+
* Shrink-wraps the frame to its rendered rows instead of filling the
|
|
44
|
+
* available flex pane. This mode disables virtualization because there is no
|
|
45
|
+
* bounded vertical viewport to virtualize against.
|
|
46
|
+
*
|
|
47
|
+
* @default false
|
|
48
|
+
*/
|
|
49
|
+
isAutoHeight?: boolean;
|
|
50
|
+
}
|
|
51
|
+
/** Shared opt-in hierarchy contract used by both table adapters. */
|
|
52
|
+
interface CubeTableTreeProps<T = any> {
|
|
53
|
+
/**
|
|
54
|
+
* Returns a row's already-loaded children. Supplying this enables tree mode
|
|
55
|
+
* and makes `data` the top-level row collection.
|
|
56
|
+
*/
|
|
57
|
+
getRowChildren?: (row: T) => readonly T[] | undefined;
|
|
58
|
+
/** Column that owns the indentation and disclosure control. */
|
|
59
|
+
treeColumnKey?: string;
|
|
60
|
+
/** Controlled expanded row keys. */
|
|
61
|
+
expandedKeys?: Key$1[];
|
|
62
|
+
/** Initially expanded row keys. */
|
|
63
|
+
defaultExpandedKeys?: Key$1[];
|
|
64
|
+
/** Called after a user expands or collapses a row. */
|
|
65
|
+
onExpand?: (keys: Key$1[], info: CubeTableRowExpandInfo<T>) => void;
|
|
66
|
+
}
|
|
26
67
|
interface CubeTableSort {
|
|
27
68
|
/** `key` of the sorted column. */
|
|
28
69
|
columnKey: string;
|
|
@@ -49,6 +90,8 @@ interface CubeTableCellContext<T = any> {
|
|
|
49
90
|
*/
|
|
50
91
|
isRowFocused?: boolean;
|
|
51
92
|
isDropTarget?: boolean;
|
|
93
|
+
/** Present only when `getRowChildren` enables tree mode. */
|
|
94
|
+
tree?: CubeTableTreeRowState;
|
|
52
95
|
}
|
|
53
96
|
interface CubeTableRowContext<T = any> {
|
|
54
97
|
row: T;
|
|
@@ -59,6 +102,8 @@ interface CubeTableRowContext<T = any> {
|
|
|
59
102
|
/** Not yet wired — always absent. See `CubeTableCellContext` for why. */
|
|
60
103
|
isFocused?: boolean;
|
|
61
104
|
isDropTarget?: boolean;
|
|
105
|
+
/** Present only when `getRowChildren` enables tree mode. */
|
|
106
|
+
tree?: CubeTableTreeRowState;
|
|
62
107
|
}
|
|
63
108
|
interface CubeTableHeaderContext {
|
|
64
109
|
columnKey: string;
|
|
@@ -254,5 +299,5 @@ type CubeTableSelectionMode = 'none' | 'single' | 'multiple';
|
|
|
254
299
|
*/
|
|
255
300
|
type CubeTableSelectAllMode = 'page' | 'filtered' | 'all';
|
|
256
301
|
//#endregion
|
|
257
|
-
export { CubeTableAlign, CubeTableCellContext, CubeTableCellRange, CubeTableColumn, CubeTableColumnHeader, CubeTableHeaderContext, CubeTableLoadingIndicator, CubeTableRowContext, CubeTableRowSection, CubeTableRowSize, CubeTableSelectAllMode, CubeTableSelectionMode, CubeTableSort, CubeTableSortDirection };
|
|
302
|
+
export { CubeTableAlign, CubeTableCellContext, CubeTableCellRange, CubeTableColumn, CubeTableColumnHeader, CubeTableHeaderContext, CubeTableLayoutProps, CubeTableLoadingIndicator, CubeTableRowContext, CubeTableRowExpandInfo, CubeTableRowSection, CubeTableRowSize, CubeTableSelectAllMode, CubeTableSelectionMode, CubeTableSort, CubeTableSortDirection, CubeTableTreeProps, CubeTableTreeRowState };
|
|
258
303
|
//# sourceMappingURL=types.d.ts.map
|