@datum-cloud/datum-ui 2.3.0 → 2.3.2

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.
@@ -0,0 +1,18 @@
1
+ import type { ReactNode } from 'react';
2
+ /**
3
+ * Height animation for a group body. Do not use Radix CollapsibleContent:
4
+ * it measures `--radix-collapsible-content-height` with getBoundingClientRect,
5
+ * and later groups inside `overflow-x-auto` often measure as 0px.
6
+ *
7
+ * Keep this node mounted. AnimatePresence exit from `height: auto` has to
8
+ * measure on the way out, which is the beat of delay after a click.
9
+ * `initial={false}` skips the enter animation for groups that start open.
10
+ *
11
+ * Overflow stays hidden. The header/body divider is a 1px rule inside this
12
+ * wrapper, not a row `border-t`, so it is not clipped.
13
+ */
14
+ export declare function GroupedCollapsibleBody({ open, reduceMotion, children, }: {
15
+ open: boolean;
16
+ reduceMotion: boolean;
17
+ children: ReactNode;
18
+ }): import("react").JSX.Element;
@@ -1,2 +1,2 @@
1
- import { t as GroupedTable } from "../grouped-table--jejU1Jy.mjs";
1
+ import { t as GroupedTable } from "../grouped-table-C5V8ESJe.mjs";
2
2
  export { GroupedTable };
@@ -1,16 +1,56 @@
1
1
  import { t as cn } from "./utils-Bu32wN-x.mjs";
2
+ import { t as Button } from "./button-A1qTjZ8U.mjs";
2
3
  import { t as Icon } from "./icon-wrapper-DKfJlJd0.mjs";
3
- import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "./collapsible/index.mjs";
4
+ import { Collapsible, CollapsibleTrigger } from "./collapsible/index.mjs";
4
5
  import { t as useControllableState } from "./use-controllable-state-Dna7u3r9.mjs";
5
- import { t as Input } from "./input-j4tbmYYz.mjs";
6
6
  import { Skeleton } from "./skeleton/index.mjs";
7
7
  import { TableBody, TableCell, TableHead, TableHeader, TableRow } from "./table/index.mjs";
8
8
  import { f as rowMatchesSearch, g as createSelectionColumn, h as DataTableColumnHeader, m as DataTableRowActions, p as dataTableFeatures } from "./data-table-Du7_FLBi.mjs";
9
9
  import { n as useDebouncedSearchInput } from "./use-debounced-search-input-yu_F0QBt.mjs";
10
- import { ChevronRight } from "lucide-react";
10
+ import { InputWithAddons } from "./input-with-addons/index.mjs";
11
+ import { ChevronRight, Search, X } from "lucide-react";
11
12
  import { useCallback, useMemo, useState } from "react";
12
13
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
14
+ import { motion, useReducedMotion } from "motion/react";
13
15
  import { flexRender, useTable } from "@tanstack/react-table";
16
+ //#region src/components/features/grouped-table/components/grouped-collapsible-body.tsx
17
+ const OPEN_TRANSITION = {
18
+ duration: .18,
19
+ ease: [
20
+ .23,
21
+ 1,
22
+ .32,
23
+ 1
24
+ ]
25
+ };
26
+ const INSTANT = { duration: 0 };
27
+ /**
28
+ * Height animation for a group body. Do not use Radix CollapsibleContent:
29
+ * it measures `--radix-collapsible-content-height` with getBoundingClientRect,
30
+ * and later groups inside `overflow-x-auto` often measure as 0px.
31
+ *
32
+ * Keep this node mounted. AnimatePresence exit from `height: auto` has to
33
+ * measure on the way out, which is the beat of delay after a click.
34
+ * `initial={false}` skips the enter animation for groups that start open.
35
+ *
36
+ * Overflow stays hidden. The header/body divider is a 1px rule inside this
37
+ * wrapper, not a row `border-t`, so it is not clipped.
38
+ */
39
+ function GroupedCollapsibleBody({ open, reduceMotion, children }) {
40
+ return /* @__PURE__ */ jsxs(motion.div, {
41
+ "data-slot": "grouped-table-group-content",
42
+ initial: false,
43
+ animate: { height: open ? "auto" : 0 },
44
+ transition: reduceMotion ? INSTANT : OPEN_TRANSITION,
45
+ className: "overflow-hidden",
46
+ inert: !open,
47
+ children: [/* @__PURE__ */ jsx("div", {
48
+ "data-slot": "grouped-table-group-rule",
49
+ className: "bg-border h-px"
50
+ }), children]
51
+ });
52
+ }
53
+ //#endregion
14
54
  //#region src/components/features/grouped-table/components/grouped-skeleton.tsx
15
55
  function GroupedSkeleton({ columns = 4, groups = 2, rowsPerGroup = 3 }) {
16
56
  return /* @__PURE__ */ jsx("div", {
@@ -33,12 +73,37 @@ function GroupedToolbar({ search, onSearchChange, placeholder = "Search...", deb
33
73
  return /* @__PURE__ */ jsx("div", {
34
74
  className: cn("pb-3", className),
35
75
  "data-slot": "gt-toolbar",
36
- children: /* @__PURE__ */ jsx(Input, {
37
- placeholder,
38
- value,
39
- onChange: (e) => setValue(e.target.value),
40
- "aria-label": placeholder,
41
- "data-slot": "gt-search"
76
+ children: /* @__PURE__ */ jsx("div", {
77
+ className: "w-full min-w-full flex-1 rounded-md sm:max-w-3xs md:min-w-80",
78
+ children: /* @__PURE__ */ jsx(InputWithAddons, {
79
+ type: "text",
80
+ placeholder,
81
+ value,
82
+ onChange: (e) => setValue(e.target.value),
83
+ containerClassName: "h-9",
84
+ className: "h-full text-xs placeholder:text-xs md:text-xs",
85
+ "aria-label": placeholder,
86
+ "data-slot": "gt-search",
87
+ leading: /* @__PURE__ */ jsx(Icon, {
88
+ icon: Search,
89
+ size: 14,
90
+ className: "text-icon-quaternary"
91
+ }),
92
+ trailing: value ? /* @__PURE__ */ jsxs(Button, {
93
+ type: "quaternary",
94
+ theme: "borderless",
95
+ size: "icon",
96
+ onClick: () => setValue(""),
97
+ className: "hover:text-destructive text-icon-quaternary size-4 p-0 hover:bg-transparent",
98
+ children: [/* @__PURE__ */ jsx(Icon, {
99
+ icon: X,
100
+ size: 14
101
+ }), /* @__PURE__ */ jsx("span", {
102
+ className: "sr-only",
103
+ children: "Clear search"
104
+ })]
105
+ }) : void 0
106
+ })
42
107
  })
43
108
  });
44
109
  }
@@ -202,6 +267,7 @@ function GroupedTable(props) {
202
267
  expanded,
203
268
  onExpandedChange
204
269
  });
270
+ const reduceMotion = Boolean(useReducedMotion());
205
271
  const resolvedColumns = useMemo(() => composeColumns(columns, {
206
272
  enableRowSelection,
207
273
  enableSorting,
@@ -223,7 +289,11 @@ function GroupedTable(props) {
223
289
  state: {
224
290
  sorting,
225
291
  rowSelection,
226
- globalFilter: search
292
+ globalFilter: search,
293
+ pagination: {
294
+ pageIndex: 0,
295
+ pageSize: Math.max(flatData.length, 1)
296
+ }
227
297
  },
228
298
  onSortingChange: setSorting,
229
299
  onRowSelectionChange: setRowSelection,
@@ -239,7 +309,7 @@ function GroupedTable(props) {
239
309
  });
240
310
  const headerGroups = table.getHeaderGroups();
241
311
  const coreRows = table.getCoreRowModel().rows;
242
- const filteredRows = table.getRowModel().rows;
312
+ const filteredRows = table.getFilteredRowModel().rows;
243
313
  const buckets = useMemo(() => bucketRows(groups, coreRows, filteredRows), [
244
314
  groups,
245
315
  coreRows,
@@ -285,15 +355,17 @@ function GroupedTable(props) {
285
355
  children: header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())
286
356
  }, header.id))
287
357
  }, hg.id)) })]
288
- }), visibleSlices.map((slice) => {
358
+ }), visibleSlices.map((slice, sliceIndex) => {
289
359
  const open = isSearching ? true : isOpen(slice.id);
290
360
  return /* @__PURE__ */ jsxs(Collapsible, {
291
361
  open,
362
+ "data-slot": "grouped-table-group",
363
+ className: cn(sliceIndex > 0 && "border-border border-t"),
292
364
  onOpenChange: () => {
293
365
  if (!isSearching) toggle(slice.id);
294
366
  },
295
367
  children: [/* @__PURE__ */ jsxs(CollapsibleTrigger, {
296
- className: cn("flex h-10 w-full items-center gap-2 border-b bg-muted/40 px-2 text-left align-middle text-sm font-medium text-muted-foreground transition-colors hover:bg-muted/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", resolveClassName(groupHeaderClassName, slice.group)),
368
+ className: cn("flex h-10 w-full items-center gap-2 bg-muted/40 px-2 text-left align-middle text-sm font-medium text-muted-foreground transition-colors hover:bg-muted/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", resolveClassName(groupHeaderClassName, slice.group)),
297
369
  children: [
298
370
  /* @__PURE__ */ jsx(Icon, {
299
371
  icon: ChevronRight,
@@ -306,8 +378,9 @@ function GroupedTable(props) {
306
378
  children: slice.meta
307
379
  })
308
380
  ]
309
- }), /* @__PURE__ */ jsx(CollapsibleContent, {
310
- className: "overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down",
381
+ }), /* @__PURE__ */ jsx(GroupedCollapsibleBody, {
382
+ open,
383
+ reduceMotion,
311
384
  children: /* @__PURE__ */ jsxs("table", {
312
385
  className: cn("w-full table-fixed text-sm", tableClassName),
313
386
  "aria-label": typeof slice.title === "string" ? slice.title : void 0,
package/dist/index.mjs CHANGED
@@ -69,7 +69,7 @@ import { InputWithAddons } from "./input-with-addons/index.mjs";
69
69
  import { t as TimePicker } from "./time-picker-CFhaHTtI.mjs";
70
70
  import { t as Transfer } from "./transfer-CEq9AhL7.mjs";
71
71
  import { a as getResponsiveValue, c as GRID_COLUMNS, d as RESPONSIVE_MAP, i as getGutter, l as GRID_PREFIX, n as Row, o as registerMediaQuery, r as RowContext, s as GRID_BREAKPOINTS, t as Col, u as RESPONSIVE_ARRAY } from "./col-BYGWTB4j.mjs";
72
- import { t as GroupedTable } from "./grouped-table--jejU1Jy.mjs";
72
+ import { t as GroupedTable } from "./grouped-table-C5V8ESJe.mjs";
73
73
  import { t as InputNumber } from "./input-number-TXmW-X9o.mjs";
74
74
  import { a as logoStyles, i as LogoFlat, n as LogoStacked, r as LogoIcon, t as LogoText } from "./logo-text-Dpm5O6Kg.mjs";
75
75
  import { t as Logo } from "./logo-C3FxD7jb.mjs";
@@ -23,7 +23,7 @@ function TableHeader({ className, ...props }) {
23
23
  function TableBody({ className, ...props }) {
24
24
  return /* @__PURE__ */ jsx("tbody", {
25
25
  "data-slot": "table-body",
26
- className: cn("[&_tr:last-child]:border-0", className),
26
+ className: cn("[&_tr:last-child]:border-b-0", className),
27
27
  ...props
28
28
  });
29
29
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@datum-cloud/datum-ui",
3
3
  "type": "module",
4
- "version": "2.3.0",
4
+ "version": "2.3.2",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "url": "https://github.com/datum-cloud/datum-ui"