twico-ui 1.43.0 → 1.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/index.cjs +199 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +108 -3
- package/dist/index.d.ts +108 -3
- package/dist/index.mjs +199 -9
- package/dist/index.mjs.map +1 -1
- package/llms.txt +7 -0
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -2624,6 +2624,20 @@ interface DatatableBatchAction<T = any> {
|
|
|
2624
2624
|
/** #322: hide the action entirely when the predicate returns true (e.g. `(_, rows) => rows.every(r => r.isGroup)`
|
|
2625
2625
|
* drops "Mark as new thread" when only group rows are selected). A static `true` always hides it. */
|
|
2626
2626
|
hidden?: boolean | ((keys: Array<string | number>, rows: T[]) => boolean);
|
|
2627
|
+
/** #479: why the action is disabled, shown as the button's tooltip — the batch mirror of the row-action
|
|
2628
|
+
* `disabledReason` (#399/#419). It may be a **predicate over the selection**, because that is where the
|
|
2629
|
+
* answer usually lives: a batch is refused for selection-dependent reasons ("that selection is 5.1 GB; the
|
|
2630
|
+
* limit is 4 GB", "at most 50 items per batch") that the label cannot carry and the user cannot infer from
|
|
2631
|
+
* a greyed-out button.
|
|
2632
|
+
*
|
|
2633
|
+
* When a reason is present the button renders `aria-disabled` rather than native `disabled`, so it stays in
|
|
2634
|
+
* the tab order and the reason is reachable by hover AND keyboard; click and Enter/Space stay blocked. With
|
|
2635
|
+
* no reason the tooltip would only repeat the label, so the button stays natively disabled and out of the
|
|
2636
|
+
* tab order — the same rule as the row-action path. There is deliberately no `hiddenReason`: a hidden
|
|
2637
|
+
* action explains nothing. */
|
|
2638
|
+
disabledReason?:
|
|
2639
|
+
| React.ReactNode
|
|
2640
|
+
| ((keys: Array<string | number>, rows: T[]) => React.ReactNode);
|
|
2627
2641
|
}
|
|
2628
2642
|
|
|
2629
2643
|
declare function Datatable<T = any>(props: DatatableProps<T>): React.JSX.Element;
|
|
@@ -2688,8 +2702,19 @@ interface CardGridSortOption {
|
|
|
2688
2702
|
interface CardGridProps<Row = any> extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> {
|
|
2689
2703
|
/** The rows: the full set in client mode, or the current page in `serverMode`. */
|
|
2690
2704
|
rows?: Row[];
|
|
2691
|
-
/**
|
|
2692
|
-
|
|
2705
|
+
/**
|
|
2706
|
+
* Render one card for a row. Required.
|
|
2707
|
+
*
|
|
2708
|
+
* #478: with `checkboxSelection`, the third argument carries that card's selection state so a
|
|
2709
|
+
* consumer can put the control inside their own layout (set `selectionPlacement="none"` to drop the
|
|
2710
|
+
* grid's overlay) without re-implementing any selection state. It is `undefined` when
|
|
2711
|
+
* `checkboxSelection` is off.
|
|
2712
|
+
*/
|
|
2713
|
+
renderCard: (
|
|
2714
|
+
row: Row,
|
|
2715
|
+
index: number,
|
|
2716
|
+
selection?: { selected: boolean; toggle: () => void },
|
|
2717
|
+
) => React.ReactNode;
|
|
2693
2718
|
/** Stable key per row: a field name or an accessor. @default "id" */
|
|
2694
2719
|
rowKey?: string | ((row: Row) => React.Key);
|
|
2695
2720
|
/** Min card width for the responsive auto-fill grid (Grid `minChildWidth`). @default "18rem" */
|
|
@@ -2752,6 +2777,86 @@ interface CardGridProps<Row = any> extends Omit<React.HTMLAttributes<HTMLDivElem
|
|
|
2752
2777
|
emptyState?: React.ReactNode;
|
|
2753
2778
|
/** Optional heading above the grid. */
|
|
2754
2779
|
label?: React.ReactNode;
|
|
2780
|
+
|
|
2781
|
+
/**
|
|
2782
|
+
* #478: show a selection checkbox on each card and a selection toolbar when anything is picked —
|
|
2783
|
+
* the same prop name, and the same behaviour, as `Datatable`. A card grid is what you reach for
|
|
2784
|
+
* when the rows are visual (assets, previews, renders), where "pick several and do one thing to
|
|
2785
|
+
* them" is most of the point.
|
|
2786
|
+
* @default false
|
|
2787
|
+
*/
|
|
2788
|
+
checkboxSelection?: boolean;
|
|
2789
|
+
/**
|
|
2790
|
+
* Actions shown in the selection toolbar, with the same shape as `DatatableBatchAction` — including
|
|
2791
|
+
* `disabled` / `hidden` / `disabledReason` as predicates over the current selection (#479), and
|
|
2792
|
+
* `ctx.anchorEl` so an action can anchor a popover to its own button.
|
|
2793
|
+
*/
|
|
2794
|
+
batchActions?: CardGridBatchAction<Row>[];
|
|
2795
|
+
/** Fired when the selection changes — `(keys, rows)`, matching `Datatable.onRowSelectionChange`. */
|
|
2796
|
+
onRowSelectionChange?: (keys: Array<string | number>, rows: Row[]) => void;
|
|
2797
|
+
/**
|
|
2798
|
+
* Where the grid draws its checkbox over each card. `"none"` suppresses the overlay entirely for
|
|
2799
|
+
* consumers who render the control themselves from `renderCard`'s third argument.
|
|
2800
|
+
* @default "top-start"
|
|
2801
|
+
*/
|
|
2802
|
+
selectionPlacement?: "top-start" | "top-end" | "bottom-start" | "bottom-end" | "none";
|
|
2803
|
+
/**
|
|
2804
|
+
* Per-card `aria-label` for the checkbox. Worth setting: unlike a table row, a card's own content is
|
|
2805
|
+
* not necessarily announced with the control, so the default `"Select item"` is the same for every
|
|
2806
|
+
* card. @default (row, index) => "Select item"
|
|
2807
|
+
*/
|
|
2808
|
+
selectionLabel?: (row: Row, index: number) => string;
|
|
2809
|
+
/** Show the page-scoped "Select all on this page" control. @default true */
|
|
2810
|
+
showSelectAll?: boolean;
|
|
2811
|
+
/**
|
|
2812
|
+
* Retain the row OBJECTS of off-page selections so `batchActions` and `onRowSelectionChange` receive
|
|
2813
|
+
* them for a selection spanning several pages. `keys` is always the authoritative cross-page
|
|
2814
|
+
* selection (as in `Datatable`); this exists because the grid only renders one page, which is the
|
|
2815
|
+
* `Map<id, row>` consumers were otherwise hand-rolling.
|
|
2816
|
+
*
|
|
2817
|
+
* Opt-in because it holds references the host may expect to be released, and **bounded**: `true`
|
|
2818
|
+
* retains up to 1000 rows, or pass a number for your own cap. Past the cap it stops retaining and
|
|
2819
|
+
* those keys simply resolve to nothing in `rows`, so re-fetch by key.
|
|
2820
|
+
* @default false
|
|
2821
|
+
*/
|
|
2822
|
+
retainSelectedRows?: boolean | number;
|
|
2823
|
+
}
|
|
2824
|
+
|
|
2825
|
+
/** Extra context handed to a CardGrid batch action's `onClick`. */
|
|
2826
|
+
interface CardGridBatchActionContext {
|
|
2827
|
+
/** The toolbar button that was clicked — anchor a popover or panel to it. */
|
|
2828
|
+
anchorEl: HTMLElement;
|
|
2829
|
+
}
|
|
2830
|
+
|
|
2831
|
+
/** A batch action shown in CardGrid's selection toolbar. Mirrors `DatatableBatchAction`. */
|
|
2832
|
+
interface CardGridBatchAction<Row = any> {
|
|
2833
|
+
/** Button label. */
|
|
2834
|
+
label: string;
|
|
2835
|
+
/** Leading icon node. */
|
|
2836
|
+
icon?: React.ReactNode;
|
|
2837
|
+
/** Handler: `(selectedKeys, selectedRows, clearSelection, ctx)`. */
|
|
2838
|
+
onClick?: (
|
|
2839
|
+
keys: Array<string | number>,
|
|
2840
|
+
rows: Row[],
|
|
2841
|
+
clearSelection: () => void,
|
|
2842
|
+
ctx: CardGridBatchActionContext,
|
|
2843
|
+
) => void;
|
|
2844
|
+
/** Render in danger color. */
|
|
2845
|
+
danger?: boolean;
|
|
2846
|
+
/** Disable the action — a static boolean, or a predicate over the current selection. */
|
|
2847
|
+
disabled?: boolean | ((keys: Array<string | number>, rows: Row[]) => boolean);
|
|
2848
|
+
/** Hide the action entirely — a static boolean, or a predicate over the current selection. */
|
|
2849
|
+
hidden?: boolean | ((keys: Array<string | number>, rows: Row[]) => boolean);
|
|
2850
|
+
/**
|
|
2851
|
+
* Why the action is disabled, shown as the button's tooltip (#479). May be a predicate over the
|
|
2852
|
+
* selection, because that is usually where the answer lives ("that selection is 5.1 GB; the limit is
|
|
2853
|
+
* 4 GB"). With a reason present the button renders `aria-disabled` rather than native `disabled`, so
|
|
2854
|
+
* it stays focusable and the reason is keyboard-reachable; without one it stays natively disabled and
|
|
2855
|
+
* out of the tab order.
|
|
2856
|
+
*/
|
|
2857
|
+
disabledReason?:
|
|
2858
|
+
| React.ReactNode
|
|
2859
|
+
| ((keys: Array<string | number>, rows: Row[]) => React.ReactNode);
|
|
2755
2860
|
}
|
|
2756
2861
|
|
|
2757
2862
|
declare function CardGrid<Row = any>(props: CardGridProps<Row>): React.JSX.Element;
|
|
@@ -4961,4 +5066,4 @@ declare function useFilePicker(options?: UseFilePickerOptions): {
|
|
|
4961
5066
|
getInputProps: () => React.InputHTMLAttributes<HTMLInputElement> & { ref: React.RefObject<HTMLInputElement | null> };
|
|
4962
5067
|
};
|
|
4963
5068
|
|
|
4964
|
-
export { Accordion, type AccordionItem, type AccordionProps, type ActionTone, Alert, type AlertProps, Anchor, type AnchorProps, AppShell, type AppShellProps, Avatar, AvatarMenu, type AvatarMenuProps, type AvatarProps, Badge, type BadgeProps, type BarTone, Box, type BoxOwnProps, type BoxProps, Boxplot, type BoxplotDatum, type BoxplotProps, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, BubbleChart, type BubbleChartProps, Button, type ButtonProps, Candlestick, type CandlestickDatum, type CandlestickProps, Card, CardGrid, type CardGridFilter, type CardGridProps, type CardGridQuery, type CardGridSort, type CardGridSortOption, type CardProps, Carousel, type CarouselProps, Chart, type ChartDatum, type ChartProps, Checkbox, type CheckboxProps, Code, type CodeProps, ColorPicker, type ColorPickerProps, ColorSchemeScript, type ColorSchemeScriptOptions, type ColorSchemeScriptProps, Combobox, type ComboboxGroup, type ComboboxOption, type ComboboxProps, type Command, CommandPalette, type CommandPaletteProps, Container, type ContainerOwnProps, type ContainerProps, Currency, CurrencyField, type CurrencyFieldProps, type CurrencyOption, type CurrencyProps, Datatable, type DatatableBatchAction, type DatatableBatchActionContext, type DatatableBatchUpdateDetail, type DatatableColumn, type DatatableFilter, type DatatableFilterOp, type DatatableNumberOp, type DatatableProps, type DatatableQuery, type DatatableRowAction, type DatatableState, type DatatableStringOp, DatePicker, type DatePickerProps, type DateRange, DateRangePicker, type DateRangePickerProps, DateTimePicker, type DateTimePickerProps, Dialog, type DialogProps, type DiffOp, DiffTable, type DiffTableColumn, type DiffTableProps, Divider, type DividerProps, DonutChart, type DonutChartDatum, type DonutChartProps, Drawer, type DrawerProps, EmptyState, type EmptyStateProps, Field, type FieldProps, FileUpload, type FileUploadProps, FilterBar, type FilterBarProps, type FilterClause, type FilterField, type FilterFieldType, type FilterValues, Form, type FormProps, FunnelChart, type FunnelChartProps, type FunnelDatum, Gauge, type GaugeProps, type GaugeSeries, Grid, type GridOwnProps, type GridProps, Heading, type HeadingOwnProps, type HeadingProps, type HeadingSize, Heatmap, type HeatmapDatum, type HeatmapProps, IconButton, type IconButtonProps, Image, type ImageProps, ImageViewer, type ImageViewerControlsApi, type ImageViewerProps, type ImageViewerState, Input, type InputProps, Kanban, type KanbanCard, type KanbanColumn, type KanbanProps, Kbd, type KbdProps, Label, type LabelProps, List, type ListItemData, type ListProps, Menu, type MenuItemDef, type MenuProps, MultiSelect, type MultiSelectGroup, type MultiSelectOption, type MultiSelectProps, Navbar, type NavbarLink, type NavbarProps, type Option, type OptionGroup, Pagination, type PaginationProps, PieChart, type PieChartDatum, type PieChartProps, PolarAreaChart, type PolarAreaChartProps, type PolarAreaDatum, type PolymorphicAs, type PolymorphicComponent, type PolymorphicProps, type PolymorphicPropsWithRef, type PolymorphicRef, Popover, type PopoverProps, Portal, type PortalProps, Pre, type PreProps, Progress, type ProgressProps, RadarChart, type RadarChartProps, type RadarDatum, Radio, RadioGroup, type RadioGroupOption, type RadioGroupProps, type RadioProps, RangeChart, type RangeChartProps, type RangeDatum, Rating, type RatingProps, type ResponsiveColumns, ScatterChart, type ScatterChartProps, type ScatterPoint, type ScatterSeries, Select, type SelectGroup, type SelectOption, type SelectProps, Sidebar, type SidebarItem, type SidebarProps, Skeleton, type SkeletonProps, Slider, type SliderProps, Sparkline, type SparklineDatum, type SparklineProps, Spinner, type SpinnerProps, Stack, type StackOwnProps, type StackProps, Stat, type StatProps, type Step, Stepper, type StepperProps, Switch, type SwitchProps, type Sx, type TabItem, Table, type TableColumn, type TableProps, Tabs, type TabsProps, Tag, type TagProps, Text, type TextOwnProps, type TextProps, type TextTone, Textarea, type TextareaProps, type Theme, ThemeProvider, type ThemeProviderProps, type ThemeTokens, TimePicker, type TimePickerProps, Timeline, type TimelineItem, type TimelineProps, Toast, type ToastApi, type ToastOptions, type ToastProps, ToastProvider, type ToastProviderProps, type ToastTone, ToastViewport, type ToastViewportProps, ToggleGroup, type ToggleGroupItem, type ToggleGroupProps, type Tone, Tooltip, type TooltipProps, type TreeNode, TreeView, type TreeViewProps, Treemap, type TreemapDatum, type TreemapProps, TwicoProvider, type TwicoProviderProps, type UseColorSchemeOptions, type UseFilePickerOptions, type UseFocusTrapOptions, type UseKeyPressOptions, type UseLocalStorageOptions, type UseMediaQueryOptions, type UseWindowSizeOptions, VisuallyHidden, type VisuallyHiddenProps, type WithSx, createTheme, getColorSchemeScript, runDatatableQuery, useClickOutside, useColorScheme, useControllableState, useCopyToClipboard, useDebouncedCallback, useDebouncedValue, useDisclosure, useEventListener, useFilePicker, useFocusTrap, useHover, useId, useIntersectionObserver, useInterval, useIsomorphicLayoutEffect, useKeyPress, useLocalStorage, useMediaQuery, useMounted, usePortal, usePrefersReducedMotion, usePrevious, useScrollLock, useTimeout, useToast, useToggle, useWindowSize };
|
|
5069
|
+
export { Accordion, type AccordionItem, type AccordionProps, type ActionTone, Alert, type AlertProps, Anchor, type AnchorProps, AppShell, type AppShellProps, Avatar, AvatarMenu, type AvatarMenuProps, type AvatarProps, Badge, type BadgeProps, type BarTone, Box, type BoxOwnProps, type BoxProps, Boxplot, type BoxplotDatum, type BoxplotProps, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, BubbleChart, type BubbleChartProps, Button, type ButtonProps, Candlestick, type CandlestickDatum, type CandlestickProps, Card, CardGrid, type CardGridBatchAction, type CardGridBatchActionContext, type CardGridFilter, type CardGridProps, type CardGridQuery, type CardGridSort, type CardGridSortOption, type CardProps, Carousel, type CarouselProps, Chart, type ChartDatum, type ChartProps, Checkbox, type CheckboxProps, Code, type CodeProps, ColorPicker, type ColorPickerProps, ColorSchemeScript, type ColorSchemeScriptOptions, type ColorSchemeScriptProps, Combobox, type ComboboxGroup, type ComboboxOption, type ComboboxProps, type Command, CommandPalette, type CommandPaletteProps, Container, type ContainerOwnProps, type ContainerProps, Currency, CurrencyField, type CurrencyFieldProps, type CurrencyOption, type CurrencyProps, Datatable, type DatatableBatchAction, type DatatableBatchActionContext, type DatatableBatchUpdateDetail, type DatatableColumn, type DatatableFilter, type DatatableFilterOp, type DatatableNumberOp, type DatatableProps, type DatatableQuery, type DatatableRowAction, type DatatableState, type DatatableStringOp, DatePicker, type DatePickerProps, type DateRange, DateRangePicker, type DateRangePickerProps, DateTimePicker, type DateTimePickerProps, Dialog, type DialogProps, type DiffOp, DiffTable, type DiffTableColumn, type DiffTableProps, Divider, type DividerProps, DonutChart, type DonutChartDatum, type DonutChartProps, Drawer, type DrawerProps, EmptyState, type EmptyStateProps, Field, type FieldProps, FileUpload, type FileUploadProps, FilterBar, type FilterBarProps, type FilterClause, type FilterField, type FilterFieldType, type FilterValues, Form, type FormProps, FunnelChart, type FunnelChartProps, type FunnelDatum, Gauge, type GaugeProps, type GaugeSeries, Grid, type GridOwnProps, type GridProps, Heading, type HeadingOwnProps, type HeadingProps, type HeadingSize, Heatmap, type HeatmapDatum, type HeatmapProps, IconButton, type IconButtonProps, Image, type ImageProps, ImageViewer, type ImageViewerControlsApi, type ImageViewerProps, type ImageViewerState, Input, type InputProps, Kanban, type KanbanCard, type KanbanColumn, type KanbanProps, Kbd, type KbdProps, Label, type LabelProps, List, type ListItemData, type ListProps, Menu, type MenuItemDef, type MenuProps, MultiSelect, type MultiSelectGroup, type MultiSelectOption, type MultiSelectProps, Navbar, type NavbarLink, type NavbarProps, type Option, type OptionGroup, Pagination, type PaginationProps, PieChart, type PieChartDatum, type PieChartProps, PolarAreaChart, type PolarAreaChartProps, type PolarAreaDatum, type PolymorphicAs, type PolymorphicComponent, type PolymorphicProps, type PolymorphicPropsWithRef, type PolymorphicRef, Popover, type PopoverProps, Portal, type PortalProps, Pre, type PreProps, Progress, type ProgressProps, RadarChart, type RadarChartProps, type RadarDatum, Radio, RadioGroup, type RadioGroupOption, type RadioGroupProps, type RadioProps, RangeChart, type RangeChartProps, type RangeDatum, Rating, type RatingProps, type ResponsiveColumns, ScatterChart, type ScatterChartProps, type ScatterPoint, type ScatterSeries, Select, type SelectGroup, type SelectOption, type SelectProps, Sidebar, type SidebarItem, type SidebarProps, Skeleton, type SkeletonProps, Slider, type SliderProps, Sparkline, type SparklineDatum, type SparklineProps, Spinner, type SpinnerProps, Stack, type StackOwnProps, type StackProps, Stat, type StatProps, type Step, Stepper, type StepperProps, Switch, type SwitchProps, type Sx, type TabItem, Table, type TableColumn, type TableProps, Tabs, type TabsProps, Tag, type TagProps, Text, type TextOwnProps, type TextProps, type TextTone, Textarea, type TextareaProps, type Theme, ThemeProvider, type ThemeProviderProps, type ThemeTokens, TimePicker, type TimePickerProps, Timeline, type TimelineItem, type TimelineProps, Toast, type ToastApi, type ToastOptions, type ToastProps, ToastProvider, type ToastProviderProps, type ToastTone, ToastViewport, type ToastViewportProps, ToggleGroup, type ToggleGroupItem, type ToggleGroupProps, type Tone, Tooltip, type TooltipProps, type TreeNode, TreeView, type TreeViewProps, Treemap, type TreemapDatum, type TreemapProps, TwicoProvider, type TwicoProviderProps, type UseColorSchemeOptions, type UseFilePickerOptions, type UseFocusTrapOptions, type UseKeyPressOptions, type UseLocalStorageOptions, type UseMediaQueryOptions, type UseWindowSizeOptions, VisuallyHidden, type VisuallyHiddenProps, type WithSx, createTheme, getColorSchemeScript, runDatatableQuery, useClickOutside, useColorScheme, useControllableState, useCopyToClipboard, useDebouncedCallback, useDebouncedValue, useDisclosure, useEventListener, useFilePicker, useFocusTrap, useHover, useId, useIntersectionObserver, useInterval, useIsomorphicLayoutEffect, useKeyPress, useLocalStorage, useMediaQuery, useMounted, usePortal, usePrefersReducedMotion, usePrevious, useScrollLock, useTimeout, useToast, useToggle, useWindowSize };
|
package/dist/index.d.ts
CHANGED
|
@@ -2624,6 +2624,20 @@ interface DatatableBatchAction<T = any> {
|
|
|
2624
2624
|
/** #322: hide the action entirely when the predicate returns true (e.g. `(_, rows) => rows.every(r => r.isGroup)`
|
|
2625
2625
|
* drops "Mark as new thread" when only group rows are selected). A static `true` always hides it. */
|
|
2626
2626
|
hidden?: boolean | ((keys: Array<string | number>, rows: T[]) => boolean);
|
|
2627
|
+
/** #479: why the action is disabled, shown as the button's tooltip — the batch mirror of the row-action
|
|
2628
|
+
* `disabledReason` (#399/#419). It may be a **predicate over the selection**, because that is where the
|
|
2629
|
+
* answer usually lives: a batch is refused for selection-dependent reasons ("that selection is 5.1 GB; the
|
|
2630
|
+
* limit is 4 GB", "at most 50 items per batch") that the label cannot carry and the user cannot infer from
|
|
2631
|
+
* a greyed-out button.
|
|
2632
|
+
*
|
|
2633
|
+
* When a reason is present the button renders `aria-disabled` rather than native `disabled`, so it stays in
|
|
2634
|
+
* the tab order and the reason is reachable by hover AND keyboard; click and Enter/Space stay blocked. With
|
|
2635
|
+
* no reason the tooltip would only repeat the label, so the button stays natively disabled and out of the
|
|
2636
|
+
* tab order — the same rule as the row-action path. There is deliberately no `hiddenReason`: a hidden
|
|
2637
|
+
* action explains nothing. */
|
|
2638
|
+
disabledReason?:
|
|
2639
|
+
| React.ReactNode
|
|
2640
|
+
| ((keys: Array<string | number>, rows: T[]) => React.ReactNode);
|
|
2627
2641
|
}
|
|
2628
2642
|
|
|
2629
2643
|
declare function Datatable<T = any>(props: DatatableProps<T>): React.JSX.Element;
|
|
@@ -2688,8 +2702,19 @@ interface CardGridSortOption {
|
|
|
2688
2702
|
interface CardGridProps<Row = any> extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> {
|
|
2689
2703
|
/** The rows: the full set in client mode, or the current page in `serverMode`. */
|
|
2690
2704
|
rows?: Row[];
|
|
2691
|
-
/**
|
|
2692
|
-
|
|
2705
|
+
/**
|
|
2706
|
+
* Render one card for a row. Required.
|
|
2707
|
+
*
|
|
2708
|
+
* #478: with `checkboxSelection`, the third argument carries that card's selection state so a
|
|
2709
|
+
* consumer can put the control inside their own layout (set `selectionPlacement="none"` to drop the
|
|
2710
|
+
* grid's overlay) without re-implementing any selection state. It is `undefined` when
|
|
2711
|
+
* `checkboxSelection` is off.
|
|
2712
|
+
*/
|
|
2713
|
+
renderCard: (
|
|
2714
|
+
row: Row,
|
|
2715
|
+
index: number,
|
|
2716
|
+
selection?: { selected: boolean; toggle: () => void },
|
|
2717
|
+
) => React.ReactNode;
|
|
2693
2718
|
/** Stable key per row: a field name or an accessor. @default "id" */
|
|
2694
2719
|
rowKey?: string | ((row: Row) => React.Key);
|
|
2695
2720
|
/** Min card width for the responsive auto-fill grid (Grid `minChildWidth`). @default "18rem" */
|
|
@@ -2752,6 +2777,86 @@ interface CardGridProps<Row = any> extends Omit<React.HTMLAttributes<HTMLDivElem
|
|
|
2752
2777
|
emptyState?: React.ReactNode;
|
|
2753
2778
|
/** Optional heading above the grid. */
|
|
2754
2779
|
label?: React.ReactNode;
|
|
2780
|
+
|
|
2781
|
+
/**
|
|
2782
|
+
* #478: show a selection checkbox on each card and a selection toolbar when anything is picked —
|
|
2783
|
+
* the same prop name, and the same behaviour, as `Datatable`. A card grid is what you reach for
|
|
2784
|
+
* when the rows are visual (assets, previews, renders), where "pick several and do one thing to
|
|
2785
|
+
* them" is most of the point.
|
|
2786
|
+
* @default false
|
|
2787
|
+
*/
|
|
2788
|
+
checkboxSelection?: boolean;
|
|
2789
|
+
/**
|
|
2790
|
+
* Actions shown in the selection toolbar, with the same shape as `DatatableBatchAction` — including
|
|
2791
|
+
* `disabled` / `hidden` / `disabledReason` as predicates over the current selection (#479), and
|
|
2792
|
+
* `ctx.anchorEl` so an action can anchor a popover to its own button.
|
|
2793
|
+
*/
|
|
2794
|
+
batchActions?: CardGridBatchAction<Row>[];
|
|
2795
|
+
/** Fired when the selection changes — `(keys, rows)`, matching `Datatable.onRowSelectionChange`. */
|
|
2796
|
+
onRowSelectionChange?: (keys: Array<string | number>, rows: Row[]) => void;
|
|
2797
|
+
/**
|
|
2798
|
+
* Where the grid draws its checkbox over each card. `"none"` suppresses the overlay entirely for
|
|
2799
|
+
* consumers who render the control themselves from `renderCard`'s third argument.
|
|
2800
|
+
* @default "top-start"
|
|
2801
|
+
*/
|
|
2802
|
+
selectionPlacement?: "top-start" | "top-end" | "bottom-start" | "bottom-end" | "none";
|
|
2803
|
+
/**
|
|
2804
|
+
* Per-card `aria-label` for the checkbox. Worth setting: unlike a table row, a card's own content is
|
|
2805
|
+
* not necessarily announced with the control, so the default `"Select item"` is the same for every
|
|
2806
|
+
* card. @default (row, index) => "Select item"
|
|
2807
|
+
*/
|
|
2808
|
+
selectionLabel?: (row: Row, index: number) => string;
|
|
2809
|
+
/** Show the page-scoped "Select all on this page" control. @default true */
|
|
2810
|
+
showSelectAll?: boolean;
|
|
2811
|
+
/**
|
|
2812
|
+
* Retain the row OBJECTS of off-page selections so `batchActions` and `onRowSelectionChange` receive
|
|
2813
|
+
* them for a selection spanning several pages. `keys` is always the authoritative cross-page
|
|
2814
|
+
* selection (as in `Datatable`); this exists because the grid only renders one page, which is the
|
|
2815
|
+
* `Map<id, row>` consumers were otherwise hand-rolling.
|
|
2816
|
+
*
|
|
2817
|
+
* Opt-in because it holds references the host may expect to be released, and **bounded**: `true`
|
|
2818
|
+
* retains up to 1000 rows, or pass a number for your own cap. Past the cap it stops retaining and
|
|
2819
|
+
* those keys simply resolve to nothing in `rows`, so re-fetch by key.
|
|
2820
|
+
* @default false
|
|
2821
|
+
*/
|
|
2822
|
+
retainSelectedRows?: boolean | number;
|
|
2823
|
+
}
|
|
2824
|
+
|
|
2825
|
+
/** Extra context handed to a CardGrid batch action's `onClick`. */
|
|
2826
|
+
interface CardGridBatchActionContext {
|
|
2827
|
+
/** The toolbar button that was clicked — anchor a popover or panel to it. */
|
|
2828
|
+
anchorEl: HTMLElement;
|
|
2829
|
+
}
|
|
2830
|
+
|
|
2831
|
+
/** A batch action shown in CardGrid's selection toolbar. Mirrors `DatatableBatchAction`. */
|
|
2832
|
+
interface CardGridBatchAction<Row = any> {
|
|
2833
|
+
/** Button label. */
|
|
2834
|
+
label: string;
|
|
2835
|
+
/** Leading icon node. */
|
|
2836
|
+
icon?: React.ReactNode;
|
|
2837
|
+
/** Handler: `(selectedKeys, selectedRows, clearSelection, ctx)`. */
|
|
2838
|
+
onClick?: (
|
|
2839
|
+
keys: Array<string | number>,
|
|
2840
|
+
rows: Row[],
|
|
2841
|
+
clearSelection: () => void,
|
|
2842
|
+
ctx: CardGridBatchActionContext,
|
|
2843
|
+
) => void;
|
|
2844
|
+
/** Render in danger color. */
|
|
2845
|
+
danger?: boolean;
|
|
2846
|
+
/** Disable the action — a static boolean, or a predicate over the current selection. */
|
|
2847
|
+
disabled?: boolean | ((keys: Array<string | number>, rows: Row[]) => boolean);
|
|
2848
|
+
/** Hide the action entirely — a static boolean, or a predicate over the current selection. */
|
|
2849
|
+
hidden?: boolean | ((keys: Array<string | number>, rows: Row[]) => boolean);
|
|
2850
|
+
/**
|
|
2851
|
+
* Why the action is disabled, shown as the button's tooltip (#479). May be a predicate over the
|
|
2852
|
+
* selection, because that is usually where the answer lives ("that selection is 5.1 GB; the limit is
|
|
2853
|
+
* 4 GB"). With a reason present the button renders `aria-disabled` rather than native `disabled`, so
|
|
2854
|
+
* it stays focusable and the reason is keyboard-reachable; without one it stays natively disabled and
|
|
2855
|
+
* out of the tab order.
|
|
2856
|
+
*/
|
|
2857
|
+
disabledReason?:
|
|
2858
|
+
| React.ReactNode
|
|
2859
|
+
| ((keys: Array<string | number>, rows: Row[]) => React.ReactNode);
|
|
2755
2860
|
}
|
|
2756
2861
|
|
|
2757
2862
|
declare function CardGrid<Row = any>(props: CardGridProps<Row>): React.JSX.Element;
|
|
@@ -4961,4 +5066,4 @@ declare function useFilePicker(options?: UseFilePickerOptions): {
|
|
|
4961
5066
|
getInputProps: () => React.InputHTMLAttributes<HTMLInputElement> & { ref: React.RefObject<HTMLInputElement | null> };
|
|
4962
5067
|
};
|
|
4963
5068
|
|
|
4964
|
-
export { Accordion, type AccordionItem, type AccordionProps, type ActionTone, Alert, type AlertProps, Anchor, type AnchorProps, AppShell, type AppShellProps, Avatar, AvatarMenu, type AvatarMenuProps, type AvatarProps, Badge, type BadgeProps, type BarTone, Box, type BoxOwnProps, type BoxProps, Boxplot, type BoxplotDatum, type BoxplotProps, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, BubbleChart, type BubbleChartProps, Button, type ButtonProps, Candlestick, type CandlestickDatum, type CandlestickProps, Card, CardGrid, type CardGridFilter, type CardGridProps, type CardGridQuery, type CardGridSort, type CardGridSortOption, type CardProps, Carousel, type CarouselProps, Chart, type ChartDatum, type ChartProps, Checkbox, type CheckboxProps, Code, type CodeProps, ColorPicker, type ColorPickerProps, ColorSchemeScript, type ColorSchemeScriptOptions, type ColorSchemeScriptProps, Combobox, type ComboboxGroup, type ComboboxOption, type ComboboxProps, type Command, CommandPalette, type CommandPaletteProps, Container, type ContainerOwnProps, type ContainerProps, Currency, CurrencyField, type CurrencyFieldProps, type CurrencyOption, type CurrencyProps, Datatable, type DatatableBatchAction, type DatatableBatchActionContext, type DatatableBatchUpdateDetail, type DatatableColumn, type DatatableFilter, type DatatableFilterOp, type DatatableNumberOp, type DatatableProps, type DatatableQuery, type DatatableRowAction, type DatatableState, type DatatableStringOp, DatePicker, type DatePickerProps, type DateRange, DateRangePicker, type DateRangePickerProps, DateTimePicker, type DateTimePickerProps, Dialog, type DialogProps, type DiffOp, DiffTable, type DiffTableColumn, type DiffTableProps, Divider, type DividerProps, DonutChart, type DonutChartDatum, type DonutChartProps, Drawer, type DrawerProps, EmptyState, type EmptyStateProps, Field, type FieldProps, FileUpload, type FileUploadProps, FilterBar, type FilterBarProps, type FilterClause, type FilterField, type FilterFieldType, type FilterValues, Form, type FormProps, FunnelChart, type FunnelChartProps, type FunnelDatum, Gauge, type GaugeProps, type GaugeSeries, Grid, type GridOwnProps, type GridProps, Heading, type HeadingOwnProps, type HeadingProps, type HeadingSize, Heatmap, type HeatmapDatum, type HeatmapProps, IconButton, type IconButtonProps, Image, type ImageProps, ImageViewer, type ImageViewerControlsApi, type ImageViewerProps, type ImageViewerState, Input, type InputProps, Kanban, type KanbanCard, type KanbanColumn, type KanbanProps, Kbd, type KbdProps, Label, type LabelProps, List, type ListItemData, type ListProps, Menu, type MenuItemDef, type MenuProps, MultiSelect, type MultiSelectGroup, type MultiSelectOption, type MultiSelectProps, Navbar, type NavbarLink, type NavbarProps, type Option, type OptionGroup, Pagination, type PaginationProps, PieChart, type PieChartDatum, type PieChartProps, PolarAreaChart, type PolarAreaChartProps, type PolarAreaDatum, type PolymorphicAs, type PolymorphicComponent, type PolymorphicProps, type PolymorphicPropsWithRef, type PolymorphicRef, Popover, type PopoverProps, Portal, type PortalProps, Pre, type PreProps, Progress, type ProgressProps, RadarChart, type RadarChartProps, type RadarDatum, Radio, RadioGroup, type RadioGroupOption, type RadioGroupProps, type RadioProps, RangeChart, type RangeChartProps, type RangeDatum, Rating, type RatingProps, type ResponsiveColumns, ScatterChart, type ScatterChartProps, type ScatterPoint, type ScatterSeries, Select, type SelectGroup, type SelectOption, type SelectProps, Sidebar, type SidebarItem, type SidebarProps, Skeleton, type SkeletonProps, Slider, type SliderProps, Sparkline, type SparklineDatum, type SparklineProps, Spinner, type SpinnerProps, Stack, type StackOwnProps, type StackProps, Stat, type StatProps, type Step, Stepper, type StepperProps, Switch, type SwitchProps, type Sx, type TabItem, Table, type TableColumn, type TableProps, Tabs, type TabsProps, Tag, type TagProps, Text, type TextOwnProps, type TextProps, type TextTone, Textarea, type TextareaProps, type Theme, ThemeProvider, type ThemeProviderProps, type ThemeTokens, TimePicker, type TimePickerProps, Timeline, type TimelineItem, type TimelineProps, Toast, type ToastApi, type ToastOptions, type ToastProps, ToastProvider, type ToastProviderProps, type ToastTone, ToastViewport, type ToastViewportProps, ToggleGroup, type ToggleGroupItem, type ToggleGroupProps, type Tone, Tooltip, type TooltipProps, type TreeNode, TreeView, type TreeViewProps, Treemap, type TreemapDatum, type TreemapProps, TwicoProvider, type TwicoProviderProps, type UseColorSchemeOptions, type UseFilePickerOptions, type UseFocusTrapOptions, type UseKeyPressOptions, type UseLocalStorageOptions, type UseMediaQueryOptions, type UseWindowSizeOptions, VisuallyHidden, type VisuallyHiddenProps, type WithSx, createTheme, getColorSchemeScript, runDatatableQuery, useClickOutside, useColorScheme, useControllableState, useCopyToClipboard, useDebouncedCallback, useDebouncedValue, useDisclosure, useEventListener, useFilePicker, useFocusTrap, useHover, useId, useIntersectionObserver, useInterval, useIsomorphicLayoutEffect, useKeyPress, useLocalStorage, useMediaQuery, useMounted, usePortal, usePrefersReducedMotion, usePrevious, useScrollLock, useTimeout, useToast, useToggle, useWindowSize };
|
|
5069
|
+
export { Accordion, type AccordionItem, type AccordionProps, type ActionTone, Alert, type AlertProps, Anchor, type AnchorProps, AppShell, type AppShellProps, Avatar, AvatarMenu, type AvatarMenuProps, type AvatarProps, Badge, type BadgeProps, type BarTone, Box, type BoxOwnProps, type BoxProps, Boxplot, type BoxplotDatum, type BoxplotProps, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, BubbleChart, type BubbleChartProps, Button, type ButtonProps, Candlestick, type CandlestickDatum, type CandlestickProps, Card, CardGrid, type CardGridBatchAction, type CardGridBatchActionContext, type CardGridFilter, type CardGridProps, type CardGridQuery, type CardGridSort, type CardGridSortOption, type CardProps, Carousel, type CarouselProps, Chart, type ChartDatum, type ChartProps, Checkbox, type CheckboxProps, Code, type CodeProps, ColorPicker, type ColorPickerProps, ColorSchemeScript, type ColorSchemeScriptOptions, type ColorSchemeScriptProps, Combobox, type ComboboxGroup, type ComboboxOption, type ComboboxProps, type Command, CommandPalette, type CommandPaletteProps, Container, type ContainerOwnProps, type ContainerProps, Currency, CurrencyField, type CurrencyFieldProps, type CurrencyOption, type CurrencyProps, Datatable, type DatatableBatchAction, type DatatableBatchActionContext, type DatatableBatchUpdateDetail, type DatatableColumn, type DatatableFilter, type DatatableFilterOp, type DatatableNumberOp, type DatatableProps, type DatatableQuery, type DatatableRowAction, type DatatableState, type DatatableStringOp, DatePicker, type DatePickerProps, type DateRange, DateRangePicker, type DateRangePickerProps, DateTimePicker, type DateTimePickerProps, Dialog, type DialogProps, type DiffOp, DiffTable, type DiffTableColumn, type DiffTableProps, Divider, type DividerProps, DonutChart, type DonutChartDatum, type DonutChartProps, Drawer, type DrawerProps, EmptyState, type EmptyStateProps, Field, type FieldProps, FileUpload, type FileUploadProps, FilterBar, type FilterBarProps, type FilterClause, type FilterField, type FilterFieldType, type FilterValues, Form, type FormProps, FunnelChart, type FunnelChartProps, type FunnelDatum, Gauge, type GaugeProps, type GaugeSeries, Grid, type GridOwnProps, type GridProps, Heading, type HeadingOwnProps, type HeadingProps, type HeadingSize, Heatmap, type HeatmapDatum, type HeatmapProps, IconButton, type IconButtonProps, Image, type ImageProps, ImageViewer, type ImageViewerControlsApi, type ImageViewerProps, type ImageViewerState, Input, type InputProps, Kanban, type KanbanCard, type KanbanColumn, type KanbanProps, Kbd, type KbdProps, Label, type LabelProps, List, type ListItemData, type ListProps, Menu, type MenuItemDef, type MenuProps, MultiSelect, type MultiSelectGroup, type MultiSelectOption, type MultiSelectProps, Navbar, type NavbarLink, type NavbarProps, type Option, type OptionGroup, Pagination, type PaginationProps, PieChart, type PieChartDatum, type PieChartProps, PolarAreaChart, type PolarAreaChartProps, type PolarAreaDatum, type PolymorphicAs, type PolymorphicComponent, type PolymorphicProps, type PolymorphicPropsWithRef, type PolymorphicRef, Popover, type PopoverProps, Portal, type PortalProps, Pre, type PreProps, Progress, type ProgressProps, RadarChart, type RadarChartProps, type RadarDatum, Radio, RadioGroup, type RadioGroupOption, type RadioGroupProps, type RadioProps, RangeChart, type RangeChartProps, type RangeDatum, Rating, type RatingProps, type ResponsiveColumns, ScatterChart, type ScatterChartProps, type ScatterPoint, type ScatterSeries, Select, type SelectGroup, type SelectOption, type SelectProps, Sidebar, type SidebarItem, type SidebarProps, Skeleton, type SkeletonProps, Slider, type SliderProps, Sparkline, type SparklineDatum, type SparklineProps, Spinner, type SpinnerProps, Stack, type StackOwnProps, type StackProps, Stat, type StatProps, type Step, Stepper, type StepperProps, Switch, type SwitchProps, type Sx, type TabItem, Table, type TableColumn, type TableProps, Tabs, type TabsProps, Tag, type TagProps, Text, type TextOwnProps, type TextProps, type TextTone, Textarea, type TextareaProps, type Theme, ThemeProvider, type ThemeProviderProps, type ThemeTokens, TimePicker, type TimePickerProps, Timeline, type TimelineItem, type TimelineProps, Toast, type ToastApi, type ToastOptions, type ToastProps, ToastProvider, type ToastProviderProps, type ToastTone, ToastViewport, type ToastViewportProps, ToggleGroup, type ToggleGroupItem, type ToggleGroupProps, type Tone, Tooltip, type TooltipProps, type TreeNode, TreeView, type TreeViewProps, Treemap, type TreemapDatum, type TreemapProps, TwicoProvider, type TwicoProviderProps, type UseColorSchemeOptions, type UseFilePickerOptions, type UseFocusTrapOptions, type UseKeyPressOptions, type UseLocalStorageOptions, type UseMediaQueryOptions, type UseWindowSizeOptions, VisuallyHidden, type VisuallyHiddenProps, type WithSx, createTheme, getColorSchemeScript, runDatatableQuery, useClickOutside, useColorScheme, useControllableState, useCopyToClipboard, useDebouncedCallback, useDebouncedValue, useDisclosure, useEventListener, useFilePicker, useFocusTrap, useHover, useId, useIntersectionObserver, useInterval, useIsomorphicLayoutEffect, useKeyPress, useLocalStorage, useMediaQuery, useMounted, usePortal, usePrefersReducedMotion, usePrevious, useScrollLock, useTimeout, useToast, useToggle, useWindowSize };
|
package/dist/index.mjs
CHANGED
|
@@ -7227,8 +7227,8 @@ function Currency({
|
|
|
7227
7227
|
}
|
|
7228
7228
|
function useFallbackName(ref, hasOwnName) {
|
|
7229
7229
|
const [needsFallback, setNeedsFallback] = React54__default.useState(false);
|
|
7230
|
-
const
|
|
7231
|
-
|
|
7230
|
+
const useIso2 = typeof document !== "undefined" ? React54__default.useLayoutEffect : React54__default.useEffect;
|
|
7231
|
+
useIso2(() => {
|
|
7232
7232
|
if (hasOwnName) {
|
|
7233
7233
|
setNeedsFallback(false);
|
|
7234
7234
|
return;
|
|
@@ -7244,7 +7244,6 @@ function useFallbackName(ref, hasOwnName) {
|
|
|
7244
7244
|
});
|
|
7245
7245
|
return !hasOwnName && needsFallback;
|
|
7246
7246
|
}
|
|
7247
|
-
typeof document !== "undefined" ? React54__default.useLayoutEffect : React54__default.useEffect;
|
|
7248
7247
|
var SELECT_CSS = `
|
|
7249
7248
|
.twc-field { display: flex; flex-direction: column; gap: var(--space-1-5); font-family: var(--font-sans); }
|
|
7250
7249
|
.twc-field__label { font-size: var(--text-sm); font-weight: var(--font-semibold); color: var(--color-text); display: flex; gap: 4px; align-items: center; }
|
|
@@ -12873,14 +12872,20 @@ function Datatable({
|
|
|
12873
12872
|
const isHidden = typeof a.hidden === "function" ? a.hidden(selKeys, selectedRows) : !!a.hidden;
|
|
12874
12873
|
if (isHidden) return null;
|
|
12875
12874
|
const isDisabled = typeof a.disabled === "function" ? a.disabled(selKeys, selectedRows) : !!a.disabled;
|
|
12876
|
-
|
|
12875
|
+
const reason = isDisabled && a.disabledReason != null ? typeof a.disabledReason === "function" ? a.disabledReason(selKeys, selectedRows) : a.disabledReason : null;
|
|
12876
|
+
const soft = isDisabled && reason != null;
|
|
12877
|
+
const btn = /* @__PURE__ */ jsxs(
|
|
12877
12878
|
"button",
|
|
12878
12879
|
{
|
|
12879
12880
|
type: "button",
|
|
12880
12881
|
className: "twc-dt__batch-btn",
|
|
12881
12882
|
"data-danger": a.danger || void 0,
|
|
12882
|
-
disabled: isDisabled,
|
|
12883
|
-
|
|
12883
|
+
disabled: isDisabled && !soft,
|
|
12884
|
+
"aria-disabled": soft || void 0,
|
|
12885
|
+
onClick: (e) => {
|
|
12886
|
+
if (isDisabled) return;
|
|
12887
|
+
a.onClick?.(selKeys, selectedRows, clearSelection, { anchorEl: e.currentTarget });
|
|
12888
|
+
},
|
|
12884
12889
|
children: [
|
|
12885
12890
|
a.icon,
|
|
12886
12891
|
a.label
|
|
@@ -12888,6 +12893,7 @@ function Datatable({
|
|
|
12888
12893
|
},
|
|
12889
12894
|
i
|
|
12890
12895
|
);
|
|
12896
|
+
return reason != null ? /* @__PURE__ */ jsx(Tooltip, { label: reason, placement: "top", children: btn }, i) : btn;
|
|
12891
12897
|
})
|
|
12892
12898
|
] })
|
|
12893
12899
|
] }) : null,
|
|
@@ -14318,6 +14324,42 @@ var CARDGRID_CSS = `
|
|
|
14318
14324
|
.twc-cardgrid__footer { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2); }
|
|
14319
14325
|
.twc-cardgrid__count { font-size: var(--text-sm); color: var(--color-text-muted); }
|
|
14320
14326
|
.twc-cardgrid__perpage { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); color: var(--color-text-muted); }
|
|
14327
|
+
|
|
14328
|
+
/* #478: selection. The card's selected state is a RING, not a background tint: a card is usually a
|
|
14329
|
+
full-bleed thumbnail, so a tint is invisible behind the image. The ring is drawn with box-shadow on
|
|
14330
|
+
a wrapper so it never participates in layout (no reflow when a card becomes selected) and it reads
|
|
14331
|
+
in both themes, --color-primary clearing 3:1 against both surfaces as a non-text indicator. */
|
|
14332
|
+
.twc-cardgrid__item { position: relative; border-radius: var(--radius-lg); transition: box-shadow var(--duration-fast) var(--ease-standard); }
|
|
14333
|
+
.twc-cardgrid__item[data-selected="true"] { box-shadow: 0 0 0 var(--border-medium) var(--color-primary); }
|
|
14334
|
+
/* The overlay is the GRID's checkbox, not the card's: renderCard owns the whole body, so a
|
|
14335
|
+
consumer-rendered checkbox would compete with the card's own click target and have to be positioned
|
|
14336
|
+
against a thumbnail whose size only the consumer knows. Placement is configurable, and a consumer who
|
|
14337
|
+
wants it inline instead uses the third renderCard argument and sets selectionPlacement="none". */
|
|
14338
|
+
.twc-cardgrid__pick { position: absolute; z-index: 2; display: inline-flex; padding: var(--space-1);
|
|
14339
|
+
background: color-mix(in srgb, var(--color-surface) 82%, transparent); border-radius: var(--radius-md);
|
|
14340
|
+
backdrop-filter: blur(4px); }
|
|
14341
|
+
.twc-cardgrid__item[data-place="top-start"] .twc-cardgrid__pick { top: var(--space-2); inset-inline-start: var(--space-2); }
|
|
14342
|
+
.twc-cardgrid__item[data-place="top-end"] .twc-cardgrid__pick { top: var(--space-2); inset-inline-end: var(--space-2); }
|
|
14343
|
+
.twc-cardgrid__item[data-place="bottom-start"] .twc-cardgrid__pick { bottom: var(--space-2); inset-inline-start: var(--space-2); }
|
|
14344
|
+
.twc-cardgrid__item[data-place="bottom-end"] .twc-cardgrid__pick { bottom: var(--space-2); inset-inline-end: var(--space-2); }
|
|
14345
|
+
.twc-cardgrid__batch { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
|
|
14346
|
+
padding: var(--space-2) var(--space-3); border: var(--border-thin) solid var(--color-primary-border);
|
|
14347
|
+
background: var(--color-primary-subtle); border-radius: var(--radius-md); }
|
|
14348
|
+
.twc-cardgrid__batch-count { font-size: var(--text-sm); font-weight: var(--font-semibold); color: var(--color-primary-subtle-fg); }
|
|
14349
|
+
.twc-cardgrid__batch-actions { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin-inline-start: auto; }
|
|
14350
|
+
.twc-cardgrid__batch-btn { display: inline-flex; align-items: center; gap: var(--space-2); height: var(--control-h-sm);
|
|
14351
|
+
padding-inline: var(--space-3); border: var(--border-thin) solid var(--color-border); background: var(--color-surface);
|
|
14352
|
+
color: var(--color-text); font-family: inherit; font-size: var(--text-xs); font-weight: var(--font-semibold);
|
|
14353
|
+
border-radius: var(--radius-md); cursor: pointer; }
|
|
14354
|
+
.twc-cardgrid__batch-btn:hover:not(:disabled):not([aria-disabled="true"]) { border-color: var(--color-primary-subtle-fg); color: var(--color-primary-subtle-fg); }
|
|
14355
|
+
.twc-cardgrid__batch-btn:disabled, .twc-cardgrid__batch-btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; }
|
|
14356
|
+
.twc-cardgrid__batch-btn[data-danger="true"] { color: var(--color-danger-subtle-fg); }
|
|
14357
|
+
.twc-cardgrid__batch-btn svg { width: 15px; height: 15px; }
|
|
14358
|
+
.twc-cardgrid__batch-x { display: inline-grid; place-items: center; width: 26px; height: 26px; flex: none;
|
|
14359
|
+
border: none; background: transparent; color: var(--color-primary-subtle-fg); cursor: pointer; border-radius: var(--radius-sm); }
|
|
14360
|
+
.twc-cardgrid__batch-x:hover { background: color-mix(in srgb, var(--color-primary) 14%, transparent); }
|
|
14361
|
+
.twc-cardgrid__batch-x svg { width: 15px; height: 15px; }
|
|
14362
|
+
.twc-cardgrid__selall { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); color: var(--color-text-muted); }
|
|
14321
14363
|
`;
|
|
14322
14364
|
function CardGrid({
|
|
14323
14365
|
rows = [],
|
|
@@ -14354,6 +14396,16 @@ function CardGrid({
|
|
|
14354
14396
|
sortMinWidth,
|
|
14355
14397
|
// slots / states
|
|
14356
14398
|
toolbar,
|
|
14399
|
+
// #478: selection + batch actions, deliberately the SAME vocabulary as Datatable rather than a new
|
|
14400
|
+
// one - a card grid is the surface where "pick several of these and do one thing to them" is close to
|
|
14401
|
+
// the whole point, and it was the only Datatable affordance CardGrid lacked.
|
|
14402
|
+
checkboxSelection = false,
|
|
14403
|
+
batchActions = [],
|
|
14404
|
+
onRowSelectionChange,
|
|
14405
|
+
selectionPlacement = "top-start",
|
|
14406
|
+
selectionLabel,
|
|
14407
|
+
showSelectAll = true,
|
|
14408
|
+
retainSelectedRows = false,
|
|
14357
14409
|
emptyState = "No results.",
|
|
14358
14410
|
label,
|
|
14359
14411
|
id,
|
|
@@ -14430,6 +14482,62 @@ function CardGrid({
|
|
|
14430
14482
|
return () => clearTimeout(t);
|
|
14431
14483
|
}, [serverMode, queryKey]);
|
|
14432
14484
|
const keyOf = typeof rowKey === "function" ? rowKey : (r2) => r2 && r2[rowKey];
|
|
14485
|
+
const [selected, setSelected] = React54__default.useState(() => /* @__PURE__ */ new Set());
|
|
14486
|
+
const retainCap = retainSelectedRows === true ? 1e3 : retainSelectedRows || 0;
|
|
14487
|
+
const retainedRef = React54__default.useRef(/* @__PURE__ */ new Map());
|
|
14488
|
+
const selKeys = React54__default.useMemo(() => [...selected], [selected]);
|
|
14489
|
+
const selectedRows = React54__default.useMemo(() => {
|
|
14490
|
+
const onPage = new Map(pageRows.map((r2, i) => [keyOf(r2, i), r2]));
|
|
14491
|
+
return selKeys.map((k) => onPage.get(k) ?? retainedRef.current.get(k)).filter((r2) => r2 !== void 0);
|
|
14492
|
+
}, [selKeys, pageRows]);
|
|
14493
|
+
const clearSelection = React54__default.useCallback(() => {
|
|
14494
|
+
retainedRef.current.clear();
|
|
14495
|
+
setSelected(/* @__PURE__ */ new Set());
|
|
14496
|
+
}, []);
|
|
14497
|
+
const toggleKey = React54__default.useCallback((key, row) => {
|
|
14498
|
+
setSelected((prev) => {
|
|
14499
|
+
const next = new Set(prev);
|
|
14500
|
+
if (next.has(key)) {
|
|
14501
|
+
next.delete(key);
|
|
14502
|
+
retainedRef.current.delete(key);
|
|
14503
|
+
} else {
|
|
14504
|
+
next.add(key);
|
|
14505
|
+
if (retainCap > 0 && row !== void 0 && retainedRef.current.size < retainCap) retainedRef.current.set(key, row);
|
|
14506
|
+
}
|
|
14507
|
+
return next;
|
|
14508
|
+
});
|
|
14509
|
+
}, [retainCap]);
|
|
14510
|
+
const pageKeys = pageRows.map((r2, i) => keyOf(r2, i));
|
|
14511
|
+
const pageSelectedCount = pageKeys.filter((k) => selected.has(k)).length;
|
|
14512
|
+
const allPageSelected = pageKeys.length > 0 && pageSelectedCount === pageKeys.length;
|
|
14513
|
+
const somePageSelected = pageSelectedCount > 0 && !allPageSelected;
|
|
14514
|
+
const togglePage = () => {
|
|
14515
|
+
setSelected((prev) => {
|
|
14516
|
+
const next = new Set(prev);
|
|
14517
|
+
pageRows.forEach((r2, i) => {
|
|
14518
|
+
const k = keyOf(r2, i);
|
|
14519
|
+
if (allPageSelected) {
|
|
14520
|
+
next.delete(k);
|
|
14521
|
+
retainedRef.current.delete(k);
|
|
14522
|
+
} else {
|
|
14523
|
+
next.add(k);
|
|
14524
|
+
if (retainCap > 0 && retainedRef.current.size < retainCap) retainedRef.current.set(k, r2);
|
|
14525
|
+
}
|
|
14526
|
+
});
|
|
14527
|
+
return next;
|
|
14528
|
+
});
|
|
14529
|
+
};
|
|
14530
|
+
const onSelRef = React54__default.useRef(onRowSelectionChange);
|
|
14531
|
+
onSelRef.current = onRowSelectionChange;
|
|
14532
|
+
const prevSelSigRef = React54__default.useRef(null);
|
|
14533
|
+
React54__default.useEffect(() => {
|
|
14534
|
+
const cb = onSelRef.current;
|
|
14535
|
+
if (!cb) return;
|
|
14536
|
+
const sig = selKeys.join(",");
|
|
14537
|
+
if (sig === prevSelSigRef.current) return;
|
|
14538
|
+
prevSelSigRef.current = sig;
|
|
14539
|
+
cb(selKeys, selectedRows);
|
|
14540
|
+
}, [selKeys, selectedRows]);
|
|
14433
14541
|
const from = total === 0 ? 0 : Math.min(shownPage * sizeVal + 1, total);
|
|
14434
14542
|
const to = paginated ? Math.min((shownPage + 1) * sizeVal, total) : total;
|
|
14435
14543
|
const rppOptions = Array.from(new Set([...pageSizeOptions || [], pageSize].filter((n) => n > 0))).sort((a, b) => a - b).map((n) => ({ value: String(n), label: String(n) }));
|
|
@@ -14482,6 +14590,64 @@ function CardGrid({
|
|
|
14482
14590
|
)
|
|
14483
14591
|
] }) : null
|
|
14484
14592
|
] }) : null,
|
|
14593
|
+
checkboxSelection && showSelectAll && pageRows.length > 0 && selected.size === 0 ? /* @__PURE__ */ jsxs("label", { className: "twc-cardgrid__selall", children: [
|
|
14594
|
+
/* @__PURE__ */ jsx(
|
|
14595
|
+
Checkbox,
|
|
14596
|
+
{
|
|
14597
|
+
checked: allPageSelected,
|
|
14598
|
+
indeterminate: somePageSelected,
|
|
14599
|
+
onChange: togglePage,
|
|
14600
|
+
"aria-label": "Select all on this page"
|
|
14601
|
+
}
|
|
14602
|
+
),
|
|
14603
|
+
"Select all on this page"
|
|
14604
|
+
] }) : null,
|
|
14605
|
+
checkboxSelection && selected.size > 0 ? /* @__PURE__ */ jsxs("div", { className: "twc-cardgrid__batch", children: [
|
|
14606
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "twc-cardgrid__batch-x", onClick: clearSelection, "aria-label": "Clear selection", children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) }) }),
|
|
14607
|
+
/* @__PURE__ */ jsxs("span", { className: "twc-cardgrid__batch-count", children: [
|
|
14608
|
+
selected.size,
|
|
14609
|
+
" selected"
|
|
14610
|
+
] }),
|
|
14611
|
+
showSelectAll && pageRows.length > 0 ? /* @__PURE__ */ jsxs("label", { className: "twc-cardgrid__selall", children: [
|
|
14612
|
+
/* @__PURE__ */ jsx(
|
|
14613
|
+
Checkbox,
|
|
14614
|
+
{
|
|
14615
|
+
checked: allPageSelected,
|
|
14616
|
+
indeterminate: somePageSelected,
|
|
14617
|
+
onChange: togglePage,
|
|
14618
|
+
"aria-label": "Select all on this page"
|
|
14619
|
+
}
|
|
14620
|
+
),
|
|
14621
|
+
"This page"
|
|
14622
|
+
] }) : null,
|
|
14623
|
+
/* @__PURE__ */ jsx("div", { className: "twc-cardgrid__batch-actions", children: batchActions.map((a, i) => {
|
|
14624
|
+
const isHidden = typeof a.hidden === "function" ? a.hidden(selKeys, selectedRows) : !!a.hidden;
|
|
14625
|
+
if (isHidden) return null;
|
|
14626
|
+
const isDisabled = typeof a.disabled === "function" ? a.disabled(selKeys, selectedRows) : !!a.disabled;
|
|
14627
|
+
const reason = isDisabled && a.disabledReason != null ? typeof a.disabledReason === "function" ? a.disabledReason(selKeys, selectedRows) : a.disabledReason : null;
|
|
14628
|
+
const soft = isDisabled && reason != null;
|
|
14629
|
+
const btn = /* @__PURE__ */ jsxs(
|
|
14630
|
+
"button",
|
|
14631
|
+
{
|
|
14632
|
+
type: "button",
|
|
14633
|
+
className: "twc-cardgrid__batch-btn",
|
|
14634
|
+
"data-danger": a.danger || void 0,
|
|
14635
|
+
disabled: isDisabled && !soft,
|
|
14636
|
+
"aria-disabled": soft || void 0,
|
|
14637
|
+
onClick: (e) => {
|
|
14638
|
+
if (isDisabled) return;
|
|
14639
|
+
a.onClick?.(selKeys, selectedRows, clearSelection, { anchorEl: e.currentTarget });
|
|
14640
|
+
},
|
|
14641
|
+
children: [
|
|
14642
|
+
a.icon,
|
|
14643
|
+
a.label
|
|
14644
|
+
]
|
|
14645
|
+
},
|
|
14646
|
+
i
|
|
14647
|
+
);
|
|
14648
|
+
return reason != null ? /* @__PURE__ */ jsx(Tooltip, { label: reason, placement: "top", children: btn }, i) : btn;
|
|
14649
|
+
}) })
|
|
14650
|
+
] }) : null,
|
|
14485
14651
|
/* @__PURE__ */ jsxs("div", { className: "twc-cardgrid__body", "data-loading": loading || void 0, "aria-busy": loading || void 0, children: [
|
|
14486
14652
|
loading ? /* @__PURE__ */ jsx("div", { className: "twc-cardgrid__overlay", children: /* @__PURE__ */ jsx("div", { className: "twc-cardgrid__spinner", role: "status", "aria-label": "Loading" }) }) : null,
|
|
14487
14653
|
pageRows.length === 0 && !loading ? /* @__PURE__ */ jsx("div", { className: "twc-cardgrid__empty", children: emptyState }) : /* @__PURE__ */ jsx(
|
|
@@ -14493,7 +14659,31 @@ function CardGrid({
|
|
|
14493
14659
|
gap,
|
|
14494
14660
|
role: "list",
|
|
14495
14661
|
"aria-labelledby": label ? `${fieldId}-label` : void 0,
|
|
14496
|
-
children: pageRows.map((row, i) =>
|
|
14662
|
+
children: pageRows.map((row, i) => {
|
|
14663
|
+
const k = keyOf(row, i);
|
|
14664
|
+
const isSel = checkboxSelection && selected.has(k);
|
|
14665
|
+
return /* @__PURE__ */ jsxs(
|
|
14666
|
+
"div",
|
|
14667
|
+
{
|
|
14668
|
+
role: "listitem",
|
|
14669
|
+
className: "twc-cardgrid__item",
|
|
14670
|
+
"data-selected": isSel || void 0,
|
|
14671
|
+
"data-place": checkboxSelection ? selectionPlacement : void 0,
|
|
14672
|
+
children: [
|
|
14673
|
+
checkboxSelection && selectionPlacement !== "none" ? /* @__PURE__ */ jsx("span", { className: "twc-cardgrid__pick", children: /* @__PURE__ */ jsx(
|
|
14674
|
+
Checkbox,
|
|
14675
|
+
{
|
|
14676
|
+
checked: isSel,
|
|
14677
|
+
onChange: () => toggleKey(k, row),
|
|
14678
|
+
"aria-label": selectionLabel ? selectionLabel(row, i) : "Select item"
|
|
14679
|
+
}
|
|
14680
|
+
) }) : null,
|
|
14681
|
+
renderCard(row, i, checkboxSelection ? { selected: isSel, toggle: () => toggleKey(k, row) } : void 0)
|
|
14682
|
+
]
|
|
14683
|
+
},
|
|
14684
|
+
k ?? i
|
|
14685
|
+
);
|
|
14686
|
+
})
|
|
14497
14687
|
}
|
|
14498
14688
|
)
|
|
14499
14689
|
] }),
|
|
@@ -19510,7 +19700,7 @@ function Tag({
|
|
|
19510
19700
|
}, "aria-label": _removeLabel, type: "button", children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M18 6 6 18M6 6l12 12" }) }) }) : null
|
|
19511
19701
|
] });
|
|
19512
19702
|
}
|
|
19513
|
-
var
|
|
19703
|
+
var useIso = typeof document !== "undefined" ? React54__default.useLayoutEffect : React54__default.useEffect;
|
|
19514
19704
|
var TEXTAREA_CSS = `
|
|
19515
19705
|
.twc-field { display: flex; flex-direction: column; gap: var(--space-1-5); font-family: var(--font-sans); }
|
|
19516
19706
|
.twc-field__label { font-size: var(--text-sm); font-weight: var(--font-semibold); color: var(--color-text); display: flex; gap: 4px; align-items: center; }
|
|
@@ -19609,7 +19799,7 @@ var Textarea = React54__default.forwardRef(function Textarea2({
|
|
|
19609
19799
|
el.style.height = `${next}px`;
|
|
19610
19800
|
el.style.overflowY = el.scrollHeight + vBorder > maxH ? "auto" : "hidden";
|
|
19611
19801
|
};
|
|
19612
|
-
|
|
19802
|
+
useIso(() => {
|
|
19613
19803
|
if (autosize && innerRef.current) resize();
|
|
19614
19804
|
}, [autosize, rest.value, minRows, maxRows, rows]);
|
|
19615
19805
|
const handleInput = (e) => {
|