@dashforge/tw 0.5.0-beta → 0.7.0-beta

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.
Files changed (105) hide show
  1. package/CHANGELOG.md +526 -0
  2. package/THEME-AUDIT.md +175 -0
  3. package/dist/index.esm.js +2504 -51
  4. package/dist/src/components/Accordion/accordion.variants.d.ts.map +1 -1
  5. package/dist/src/components/Box/box.variants.d.ts.map +1 -1
  6. package/dist/src/components/DataGrid/DataGrid.d.ts +29 -0
  7. package/dist/src/components/DataGrid/DataGrid.d.ts.map +1 -0
  8. package/dist/src/components/DataGrid/dataGrid.types.d.ts +171 -0
  9. package/dist/src/components/DataGrid/dataGrid.types.d.ts.map +1 -0
  10. package/dist/src/components/DataGrid/dataGrid.variants.d.ts +216 -0
  11. package/dist/src/components/DataGrid/dataGrid.variants.d.ts.map +1 -0
  12. package/dist/src/components/Dialog/dialog.variants.d.ts.map +1 -1
  13. package/dist/src/components/Divider/divider.variants.d.ts.map +1 -1
  14. package/dist/src/components/Pagination/Pagination.d.ts.map +1 -1
  15. package/dist/src/components/Pagination/pagination.variants.d.ts.map +1 -1
  16. package/dist/src/components/Popover/popover.variants.d.ts.map +1 -1
  17. package/dist/src/components/Skeleton/skeleton.variants.d.ts.map +1 -1
  18. package/dist/src/components/Table/Table.d.ts +24 -0
  19. package/dist/src/components/Table/Table.d.ts.map +1 -0
  20. package/dist/src/components/Table/cells/RenderButton.d.ts +13 -0
  21. package/dist/src/components/Table/cells/RenderButton.d.ts.map +1 -0
  22. package/dist/src/components/Table/cells/RenderChip.d.ts +80 -0
  23. package/dist/src/components/Table/cells/RenderChip.d.ts.map +1 -0
  24. package/dist/src/components/Table/cells/RenderText.d.ts +21 -0
  25. package/dist/src/components/Table/cells/RenderText.d.ts.map +1 -0
  26. package/dist/src/components/Table/cells/RenderTwoLine.d.ts +20 -0
  27. package/dist/src/components/Table/cells/RenderTwoLine.d.ts.map +1 -0
  28. package/dist/src/components/Table/cells/RowActionsMenu.d.ts +36 -0
  29. package/dist/src/components/Table/cells/RowActionsMenu.d.ts.map +1 -0
  30. package/dist/src/components/Table/cells/index.d.ts +11 -0
  31. package/dist/src/components/Table/cells/index.d.ts.map +1 -0
  32. package/dist/src/components/Table/table.types.d.ts +312 -0
  33. package/dist/src/components/Table/table.types.d.ts.map +1 -0
  34. package/dist/src/components/Table/table.variants.d.ts +285 -0
  35. package/dist/src/components/Table/table.variants.d.ts.map +1 -0
  36. package/dist/src/components/Tabs/tabs.variants.d.ts.map +1 -1
  37. package/dist/src/components/Tooltip/tooltip.variants.d.ts.map +1 -1
  38. package/dist/src/components/Typography/typography.variants.d.ts.map +1 -1
  39. package/dist/src/components/_shared/data/getNestedValue.d.ts +20 -0
  40. package/dist/src/components/_shared/data/getNestedValue.d.ts.map +1 -0
  41. package/dist/src/components/_shared/data/useColumnAutoDetect.d.ts +45 -0
  42. package/dist/src/components/_shared/data/useColumnAutoDetect.d.ts.map +1 -0
  43. package/dist/src/components/_shared/data/useControllableState.d.ts +23 -0
  44. package/dist/src/components/_shared/data/useControllableState.d.ts.map +1 -0
  45. package/dist/src/components/_shared/data/useDebouncedValue.d.ts +10 -0
  46. package/dist/src/components/_shared/data/useDebouncedValue.d.ts.map +1 -0
  47. package/dist/src/components/_shared/data/useTableFilter.d.ts +13 -0
  48. package/dist/src/components/_shared/data/useTableFilter.d.ts.map +1 -0
  49. package/dist/src/components/_shared/data/useTableSearch.d.ts +23 -0
  50. package/dist/src/components/_shared/data/useTableSearch.d.ts.map +1 -0
  51. package/dist/src/components/_shared/data/useTableSelection.d.ts +25 -0
  52. package/dist/src/components/_shared/data/useTableSelection.d.ts.map +1 -0
  53. package/dist/src/components/_shared/data/useTableSort.d.ts +20 -0
  54. package/dist/src/components/_shared/data/useTableSort.d.ts.map +1 -0
  55. package/dist/src/components/_shared/data/useVirtualizer.d.ts +107 -0
  56. package/dist/src/components/_shared/data/useVirtualizer.d.ts.map +1 -0
  57. package/dist/src/index.d.ts +10 -1
  58. package/dist/src/index.d.ts.map +1 -1
  59. package/package.json +3 -3
  60. package/src/components/Accordion/accordion.variants.ts +5 -3
  61. package/src/components/Box/Box.test.tsx +32 -11
  62. package/src/components/Box/box.variants.ts +23 -4
  63. package/src/components/DataGrid/DataGrid.test.tsx +496 -0
  64. package/src/components/DataGrid/DataGrid.tsx +831 -0
  65. package/src/components/DataGrid/dataGrid.types.ts +189 -0
  66. package/src/components/DataGrid/dataGrid.variants.ts +144 -0
  67. package/src/components/Dialog/dialog.variants.ts +10 -6
  68. package/src/components/Divider/Divider.test.tsx +3 -1
  69. package/src/components/Divider/Divider.tsx +1 -1
  70. package/src/components/Divider/divider.variants.ts +2 -1
  71. package/src/components/Pagination/Pagination.tsx +3 -1
  72. package/src/components/Pagination/pagination.variants.ts +19 -13
  73. package/src/components/Popover/popover.variants.ts +10 -4
  74. package/src/components/Skeleton/skeleton.variants.ts +2 -1
  75. package/src/components/Table/Table.test.tsx +603 -0
  76. package/src/components/Table/Table.tsx +816 -0
  77. package/src/components/Table/cells/RenderButton.tsx +23 -0
  78. package/src/components/Table/cells/RenderChip.tsx +103 -0
  79. package/src/components/Table/cells/RenderText.tsx +37 -0
  80. package/src/components/Table/cells/RenderTwoLine.tsx +34 -0
  81. package/src/components/Table/cells/RowActionsMenu.tsx +147 -0
  82. package/src/components/Table/cells/index.ts +14 -0
  83. package/src/components/Table/table.types.ts +346 -0
  84. package/src/components/Table/table.variants.ts +207 -0
  85. package/src/components/Tabs/tabs.variants.ts +19 -8
  86. package/src/components/Tooltip/tooltip.variants.ts +12 -2
  87. package/src/components/Typography/Typography.test.tsx +3 -1
  88. package/src/components/Typography/typography.variants.ts +6 -2
  89. package/src/components/_shared/data/getNestedValue.test.ts +50 -0
  90. package/src/components/_shared/data/getNestedValue.ts +32 -0
  91. package/src/components/_shared/data/useColumnAutoDetect.test.ts +123 -0
  92. package/src/components/_shared/data/useColumnAutoDetect.ts +100 -0
  93. package/src/components/_shared/data/useControllableState.ts +48 -0
  94. package/src/components/_shared/data/useDebouncedValue.ts +24 -0
  95. package/src/components/_shared/data/useTableFilter.ts +37 -0
  96. package/src/components/_shared/data/useTableSearch.test.ts +115 -0
  97. package/src/components/_shared/data/useTableSearch.ts +66 -0
  98. package/src/components/_shared/data/useTableSelection.test.ts +100 -0
  99. package/src/components/_shared/data/useTableSelection.ts +100 -0
  100. package/src/components/_shared/data/useTableSort.test.ts +150 -0
  101. package/src/components/_shared/data/useTableSort.ts +141 -0
  102. package/src/components/_shared/data/useVirtualizer.test.ts +158 -0
  103. package/src/components/_shared/data/useVirtualizer.ts +199 -0
  104. package/src/components/_shared/themeIdentity.test.ts +113 -0
  105. package/src/index.ts +59 -1
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Walk a dotted path through an object and return the value, or
3
+ * `undefined` if any segment is missing / nullish.
4
+ *
5
+ * Bug fix from the MUI-side Table (Sprint 4.1 motivation): the
6
+ * existing wrapper typed `field: NestedKeyOf<T>` but performed a
7
+ * flat `row[col.field]` lookup at runtime — nested keys silently
8
+ * returned `undefined`. This helper makes the runtime match the
9
+ * type contract.
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * getNestedValue({ user: { name: 'Jane' } }, 'user.name') // 'Jane'
14
+ * getNestedValue({ user: null }, 'user.name') // undefined
15
+ * getNestedValue({}, 'a.b.c') // undefined
16
+ * getNestedValue({ a: { b: 0 } }, 'a.b') // 0 (NOT undefined)
17
+ * ```
18
+ */
19
+ export declare function getNestedValue<T extends object>(row: T, path: string): unknown;
20
+ //# sourceMappingURL=getNestedValue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getNestedValue.d.ts","sourceRoot":"","sources":["../../../../../src/components/_shared/data/getNestedValue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAC7C,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,MAAM,GACX,OAAO,CAUT"}
@@ -0,0 +1,45 @@
1
+ import type { TableColumn, TableColumnInferredType } from '../../Table/table.types.js';
2
+ /**
3
+ * Auto-detects the primitive type of each column by scanning the
4
+ * first non-null value across the supplied rows. Drives smart
5
+ * defaults for `align` and `monospace` on the cell render path.
6
+ *
7
+ * Scans only the first N rows (default 50) for performance — if the
8
+ * dataset's first 50 rows are unrepresentative, the consumer can
9
+ * override per-column via explicit `align` / `monospace` props.
10
+ *
11
+ * Returns `Map<columnField, inferredType>`.
12
+ */
13
+ export declare function useColumnAutoDetect<T extends object>(rows: T[], cols: TableColumn<T>[], sampleSize?: number): Map<string, TableColumnInferredType>;
14
+ /**
15
+ * Resolves the effective `align` for a column, honoring explicit
16
+ * `col.align` first and falling back to the inferred type.
17
+ */
18
+ export declare function resolveAlign(col: {
19
+ align?: 'left' | 'right' | 'center';
20
+ }, inferred: TableColumnInferredType | undefined): 'left' | 'right' | 'center';
21
+ /**
22
+ * Resolves the effective `tabularNums` flag for a column.
23
+ *
24
+ * `tabular-nums` is a `font-variant-numeric` rule that makes every
25
+ * digit occupy the same width — it does NOT change the font family.
26
+ * Auto-applied for `number` and `date` columns so currency values
27
+ * and ISO dates align cleanly. Explicit `col.tabularNums` wins.
28
+ */
29
+ export declare function resolveTabularNums(col: {
30
+ tabularNums?: boolean;
31
+ }, inferred: TableColumnInferredType | undefined): boolean;
32
+ /**
33
+ * Resolves the effective `monospace` flag for a column.
34
+ *
35
+ * `font-mono` changes the font FAMILY to a monospace stack, which
36
+ * would override the consumer's theme `font-sans`. The library
37
+ * never auto-applies it — only an explicit `col.monospace: true`
38
+ * opts in. Consumers wanting a custom mono stack configure it
39
+ * through Tailwind's `theme.extend.fontFamily.mono` in their own
40
+ * preset (the dashforgePreset does not own the `fontFamily` axis).
41
+ */
42
+ export declare function resolveMonospace(col: {
43
+ monospace?: boolean;
44
+ }): boolean;
45
+ //# sourceMappingURL=useColumnAutoDetect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useColumnAutoDetect.d.ts","sourceRoot":"","sources":["../../../../../src/components/_shared/data/useColumnAutoDetect.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAEvF;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,MAAM,EAClD,IAAI,EAAE,CAAC,EAAE,EACT,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,EACtB,UAAU,SAAK,GACd,GAAG,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAiBtC;AAcD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;CAAE,EAC5C,QAAQ,EAAE,uBAAuB,GAAG,SAAS,GAC5C,MAAM,GAAG,OAAO,GAAG,QAAQ,CAU7B;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,EAC9B,QAAQ,EAAE,uBAAuB,GAAG,SAAS,GAC5C,OAAO,CAGT;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAC3B,OAAO,CAET"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Generic "controllable" state hook — switches between controlled
3
+ * (via parent-supplied value + setter) and uncontrolled (internal
4
+ * `useState`).
5
+ *
6
+ * - If `controlledValue !== undefined`, the hook is in **controlled**
7
+ * mode: the internal state is ignored; the returned setter calls
8
+ * `onControlledChange` only.
9
+ * - Otherwise it's in **uncontrolled** mode: internal `useState`,
10
+ * defaulting to `defaultValue`. The optional `onControlledChange`
11
+ * is still fired on every change so the parent can react.
12
+ *
13
+ * The control mode is determined per-render. Mixing modes (passing
14
+ * `controlledValue` undefined sometimes) is a consumer bug — we don't
15
+ * try to "remember" the last mode (React's rules-of-hooks make that
16
+ * unsafe).
17
+ */
18
+ export declare function useControllableState<T>(args: {
19
+ controlledValue: T | undefined;
20
+ defaultValue: T;
21
+ onChange?: (value: T) => void;
22
+ }): [T, (next: T | ((prev: T) => T)) => void];
23
+ //# sourceMappingURL=useControllableState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useControllableState.d.ts","sourceRoot":"","sources":["../../../../../src/components/_shared/data/useControllableState.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,IAAI,EAAE;IAC5C,eAAe,EAAE,CAAC,GAAG,SAAS,CAAC;IAC/B,YAAY,EAAE,CAAC,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;CAC/B,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAwB5C"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Returns a debounced version of `value` — only updates after `delayMs`
3
+ * of no further changes. Used by the search input so we don't re-filter
4
+ * the entire row set on every keystroke.
5
+ *
6
+ * `delayMs <= 0` short-circuits to the input value (no debounce —
7
+ * useful for tests).
8
+ */
9
+ export declare function useDebouncedValue<T>(value: T, delayMs: number): T;
10
+ //# sourceMappingURL=useDebouncedValue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDebouncedValue.d.ts","sourceRoot":"","sources":["../../../../../src/components/_shared/data/useDebouncedValue.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,CAajE"}
@@ -0,0 +1,13 @@
1
+ import type { TableFilterModel } from '../../Table/table.types.js';
2
+ /**
3
+ * Filters `rows` by the per-column filter model. v1 only supports
4
+ * the `contains` operator (text substring) — additional ops
5
+ * (`equals`, `in`, `gte`, `lte`, `between`, `before`, `after`)
6
+ * land in v1-bis once the filter UI surface for each shape is
7
+ * fleshed out.
8
+ *
9
+ * AND semantics across columns: a row must match EVERY active
10
+ * filter. Within a single filter, the op decides the predicate.
11
+ */
12
+ export declare function useTableFilter<T extends object>(rows: T[], filterModel: TableFilterModel): T[];
13
+ //# sourceMappingURL=useTableFilter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTableFilter.d.ts","sourceRoot":"","sources":["../../../../../src/components/_shared/data/useTableFilter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAC7C,IAAI,EAAE,CAAC,EAAE,EACT,WAAW,EAAE,gBAAgB,GAC5B,CAAC,EAAE,CAkBL"}
@@ -0,0 +1,23 @@
1
+ import type { TableColumn } from '../../Table/table.types.js';
2
+ /**
3
+ * Stringify any value into a search-comparable form. Handles all
4
+ * the edge cases that bit the MUI-side Table:
5
+ *
6
+ * - `null` / `undefined` → `''`
7
+ * - `string` → as-is
8
+ * - `number` / `bigint` → `String(value)`
9
+ * - `boolean` → `'true'` / `'false'`
10
+ * - `Date` → ISO 8601
11
+ * - `Array` / object → `JSON.stringify` (best effort)
12
+ */
13
+ export declare function stringifyForSearch(value: unknown): string;
14
+ /**
15
+ * Filters `rows` by `query` against the columns flagged
16
+ * `searchable: true`. Empty / whitespace-only query is a no-op
17
+ * (returns the original rows).
18
+ *
19
+ * Case-insensitive substring match. The caller is responsible for
20
+ * debouncing the input (use `useDebouncedValue`).
21
+ */
22
+ export declare function useTableSearch<T extends object>(rows: T[], cols: TableColumn<T>[], query: string): T[];
23
+ //# sourceMappingURL=useTableSearch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTableSearch.d.ts","sourceRoot":"","sources":["../../../../../src/components/_shared/data/useTableSearch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAqBzD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAC7C,IAAI,EAAE,CAAC,EAAE,EACT,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,EACtB,KAAK,EAAE,MAAM,GACZ,CAAC,EAAE,CAeL"}
@@ -0,0 +1,25 @@
1
+ import type { TableRowSelectionMode } from '../../Table/table.types.js';
2
+ export interface UseTableSelectionResult {
3
+ selectedRowIds: string[];
4
+ isSelected: (rowId: string) => boolean;
5
+ toggleRow: (rowId: string) => void;
6
+ toggleAll: (allRowIds: string[]) => void;
7
+ clearSelection: () => void;
8
+ /** True when EVERY id in `allRowIds` is selected. */
9
+ isAllSelected: (allRowIds: string[]) => boolean;
10
+ /** True when at least one (but not all) of `allRowIds` is selected. */
11
+ isIndeterminate: (allRowIds: string[]) => boolean;
12
+ }
13
+ /**
14
+ * Selection logic helper. Given the controllable selection state +
15
+ * the setter (from `useControllableState`), exposes ergonomic
16
+ * helpers the Table calls from its render path.
17
+ *
18
+ * - `single` mode: at most one row selected. Toggling another
19
+ * replaces the previous.
20
+ * - `multiple` mode: any subset selectable; toggling adds/removes.
21
+ * - `none` mode: every toggle is a no-op (the Table shouldn't
22
+ * render the checkbox cells anyway, but this is defensive).
23
+ */
24
+ export declare function useTableSelection(mode: TableRowSelectionMode, selectedRowIds: string[], setSelectedRowIds: (next: string[] | ((prev: string[]) => string[])) => void): UseTableSelectionResult;
25
+ //# sourceMappingURL=useTableSelection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTableSelection.d.ts","sourceRoot":"","sources":["../../../../../src/components/_shared/data/useTableSelection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAExE,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACvC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACzC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,qDAAqD;IACrD,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;IAChD,uEAAuE;IACvE,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;CACnD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,qBAAqB,EAC3B,cAAc,EAAE,MAAM,EAAE,EACxB,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC,KAAK,IAAI,GAC3E,uBAAuB,CAqEzB"}
@@ -0,0 +1,20 @@
1
+ import type { TableColumn, TableSortModel } from '../../Table/table.types.js';
2
+ /**
3
+ * Applies the `sortModel` to `rows`. Returns a NEW sorted array
4
+ * (does not mutate input). Stable sort guaranteed by the underlying
5
+ * `Array.prototype.sort` in modern engines.
6
+ *
7
+ * Multi-column sort: items earlier in `sortModel` have higher
8
+ * precedence. Equal values fall through to the next sort item; if
9
+ * all sort items tie, the original order is preserved (stable).
10
+ */
11
+ export declare function useTableSort<T extends object>(rows: T[], cols: TableColumn<T>[], sortModel: TableSortModel): T[];
12
+ /**
13
+ * Three-state sort cycler: `none` → `asc` → `desc` → `none`.
14
+ *
15
+ * Used by the header click handler. Returns the next sort model
16
+ * to apply, given the current model + the clicked field + whether
17
+ * the user is multi-sorting (shift key).
18
+ */
19
+ export declare function cycleSortFor(current: TableSortModel, field: string, multi: boolean): TableSortModel;
20
+ //# sourceMappingURL=useTableSort.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTableSort.d.ts","sourceRoot":"","sources":["../../../../../src/components/_shared/data/useTableSort.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EAEf,MAAM,4BAA4B,CAAC;AA+CpC;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAC3C,IAAI,EAAE,CAAC,EAAE,EACT,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,EACtB,SAAS,EAAE,cAAc,GACxB,CAAC,EAAE,CA2CL;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,OAAO,GACb,cAAc,CAkBhB"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Window descriptor — which slice of the row array is currently
3
+ * mounted in DOM, and how much spacer height to render above and
4
+ * below the visible window so the scrollbar size matches the
5
+ * "virtual" total height.
6
+ */
7
+ export interface VirtualizerWindow {
8
+ /** First row index inside the visible window (inclusive). */
9
+ startIndex: number;
10
+ /** Last row index inside the visible window (inclusive). */
11
+ endIndex: number;
12
+ /** Pixels to render above the visible rows (spacer top). */
13
+ paddingTop: number;
14
+ /** Pixels to render below the visible rows (spacer bottom). */
15
+ paddingBottom: number;
16
+ }
17
+ export interface UseVirtualizerArgs {
18
+ /** Total number of rows in the underlying data set. */
19
+ totalCount: number;
20
+ /** Fixed row height in pixels. */
21
+ rowHeight: number;
22
+ /**
23
+ * Visible viewport height in pixels. Pass the height of the
24
+ * scroll container.
25
+ */
26
+ viewportHeight: number;
27
+ /** Current scrollTop of the scroll container. */
28
+ scrollTop: number;
29
+ /**
30
+ * How many extra rows to render above / below the visible window
31
+ * for smoother scrolling (reduces blank-flash on fast scroll).
32
+ * @default 5
33
+ */
34
+ overscan?: number;
35
+ }
36
+ /**
37
+ * Compute the visible window of rows + the spacer heights given the
38
+ * current scroll position. Pure function — exported for testability.
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * computeWindow({ totalCount: 1000, rowHeight: 48, viewportHeight: 600,
43
+ * scrollTop: 0, overscan: 5 });
44
+ * // → { startIndex: 0, endIndex: 17, paddingTop: 0, paddingBottom: 47136 }
45
+ * ```
46
+ */
47
+ export declare function computeWindow(args: UseVirtualizerArgs): VirtualizerWindow;
48
+ /**
49
+ * `useVirtualizer` — viewport-based row windowing for `<DataGrid>`.
50
+ *
51
+ * Hand-rolled (no `@tanstack/react-virtual` dep — constraint memorized
52
+ * in `feedback_dashforge_preset_is_identity` companion: "no new
53
+ * external runtime deps"). Uses scroll event + `requestAnimationFrame`
54
+ * debounce + `ResizeObserver` on the container. Fixed row height
55
+ * only in v1 — variable-height with measurement cache deferred to
56
+ * v1-bis.
57
+ *
58
+ * Returns:
59
+ * - `scrollRef`: attach to the scroll container `<div>`.
60
+ * - `window`: which row indices to mount + top/bottom spacer heights
61
+ * to preserve scroll-area size.
62
+ * - `viewportHeight`: current container height (re-measured on
63
+ * `ResizeObserver` ticks).
64
+ *
65
+ * The DataGrid renders `rows.slice(window.startIndex, window.endIndex + 1)`
66
+ * between two spacer `<tr style={{ height: paddingTop }} />` elements
67
+ * (above and below). This preserves `<table>` semantics — screen
68
+ * readers see a continuous structure with `aria-hidden` spacers.
69
+ *
70
+ * @example
71
+ * ```tsx
72
+ * const { scrollRef, window } = useVirtualizer({
73
+ * totalCount: rows.length,
74
+ * rowHeight: 48,
75
+ * overscan: 5,
76
+ * });
77
+ *
78
+ * return (
79
+ * <div ref={scrollRef} style={{ height: 600, overflow: 'auto' }}>
80
+ * <table>
81
+ * <tbody>
82
+ * <tr aria-hidden="true" style={{ height: window.paddingTop }} />
83
+ * {rows.slice(window.startIndex, window.endIndex + 1).map(...)}
84
+ * <tr aria-hidden="true" style={{ height: window.paddingBottom }} />
85
+ * </tbody>
86
+ * </table>
87
+ * </div>
88
+ * );
89
+ * ```
90
+ */
91
+ export declare function useVirtualizer(args: {
92
+ totalCount: number;
93
+ rowHeight: number;
94
+ overscan?: number;
95
+ /**
96
+ * Initial viewport height — used before the ResizeObserver
97
+ * settles on first paint. Pass an explicit `height` prop value
98
+ * if you have one; otherwise the hook re-measures on layout.
99
+ * @default 400
100
+ */
101
+ initialViewportHeight?: number;
102
+ }): {
103
+ scrollRef: React.RefObject<HTMLDivElement | null>;
104
+ window: VirtualizerWindow;
105
+ viewportHeight: number;
106
+ };
107
+ //# sourceMappingURL=useVirtualizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVirtualizer.d.ts","sourceRoot":"","sources":["../../../../../src/components/_shared/data/useVirtualizer.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,6DAA6D;IAC7D,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,kBAAkB,GAAG,iBAAiB,CAmBzE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC,GAAG;IACF,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAClD,MAAM,EAAE,iBAAiB,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;CACxB,CAqEA"}
@@ -114,6 +114,15 @@ export { skeletonVariants } from './components/Skeleton/skeleton.variants.js';
114
114
  export { Pagination } from './components/Pagination/Pagination.js';
115
115
  export type { PaginationProps, PaginationSlotProps, PaginationLabels, } from './components/Pagination/pagination.types.js';
116
116
  export { paginationVariants } from './components/Pagination/pagination.variants.js';
117
+ export { Table } from './components/Table/Table.js';
118
+ export type { TableProps, TableColumn, TableColumnInferredType, TableCellContext, TableSortDirection, TableSortItem, TableSortModel, TableFilterItem, TableFilterModel, TableRowSelectionMode, TableExpandableConfig, TableLabels, TableSlotProps, NestedKeyOf, } from './components/Table/table.types.js';
119
+ export { tableVariants } from './components/Table/table.variants.js';
120
+ export { RenderText, RenderTwoLine, RenderChip, RenderButton, RowActionsMenu, } from './components/Table/cells/index.js';
121
+ export type { RenderTextProps, RenderTwoLineProps, RenderChipProps, RenderButtonProps, RowActionsMenuProps, TableRowAction, } from './components/Table/cells/index.js';
122
+ export { getNestedValue } from './components/_shared/data/getNestedValue.js';
123
+ export { DataGrid } from './components/DataGrid/DataGrid.js';
124
+ export type { DataGridProps, DataGridSlotProps, DataGridSelectAllScope, DataGridServerSideFlags, DataGridPaginationConfig, } from './components/DataGrid/dataGrid.types.js';
125
+ export { dataGridVariants } from './components/DataGrid/dataGrid.variants.js';
117
126
  export { useAccessState } from './hooks/useAccessState.js';
118
127
  export { cn } from './utils/cn.js';
119
128
  export { tv } from 'tailwind-variants';
@@ -121,5 +130,5 @@ export type { VariantProps } from 'tailwind-variants';
121
130
  /**
122
131
  * Package version (synced with `package.json` at publish time).
123
132
  */
124
- export declare const VERSION = "0.5.0-beta";
133
+ export declare const VERSION = "0.7.0-beta";
125
134
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,YAAY,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAExE,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAChE,YAAY,EACV,cAAc,EACd,kBAAkB,GACnB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AAEjF,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAC7D,YAAY,EACV,aAAa,EACb,iBAAiB,GAClB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAE9E,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,YAAY,EACV,WAAW,EACX,eAAe,GAChB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAIxE,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AAEpF,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAC7D,YAAY,EACV,aAAa,EACb,iBAAiB,GAClB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAI9E,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AACtE,YAAY,EACV,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kDAAkD,CAAC;AAEvF,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAC7D,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,YAAY,GACb,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAI9E,OAAO,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AACzE,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oDAAoD,CAAC;AAI1F,OAAO,EACL,cAAc,EACd,eAAe,GAChB,MAAM,+CAA+C,CAAC;AACvD,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,qDAAqD,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,wDAAwD,CAAC;AAIhG,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AACtE,YAAY,EACV,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kDAAkD,CAAC;AAEvF,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAC1D,YAAY,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAE3E,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,YAAY,EACV,WAAW,EACX,eAAe,GAChB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAExE,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAC7D,YAAY,EACV,aAAa,EACb,iBAAiB,GAClB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAI9E,OAAO,EACL,qBAAqB,EACrB,UAAU,GACX,MAAM,6CAA6C,CAAC;AACrD,YAAY,EACV,0BAA0B,EAC1B,sBAAsB,EACtB,SAAS,EACT,cAAc,EACd,eAAe,GAChB,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sDAAsD,CAAC;AAE7F,OAAO,EACL,gBAAgB,EAChB,WAAW,GACZ,MAAM,mCAAmC,CAAC;AAC3C,YAAY,EACV,qBAAqB,EACrB,WAAW,EACX,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAO9E,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,YAAY,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AAEpF,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAC9C,YAAY,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAE/D,OAAO,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AACpD,YAAY,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAErE,OAAO,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AACjD,YAAY,EACV,SAAS,EACT,kBAAkB,EAClB,aAAa,EACb,OAAO,EACP,eAAe,GAChB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAOlE,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAChE,YAAY,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AAEjF,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAC1D,YAAY,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EACL,eAAe,EACf,mBAAmB,GACpB,MAAM,0CAA0C,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AACtE,YAAY,EAAE,gBAAgB,EAAE,MAAM,+CAA+C,CAAC;AAEtF,OAAO,EAAE,cAAc,EAAE,MAAM,+CAA+C,CAAC;AAC/E,YAAY,EAAE,mBAAmB,EAAE,MAAM,qDAAqD,CAAC;AAI/F,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AACvD,YAAY,EACV,WAAW,EACX,eAAe,GAChB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAExE,OAAO,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AACjD,YAAY,EACV,SAAS,EACT,aAAa,EACb,OAAO,GACR,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAElE,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAC1D,YAAY,EACV,YAAY,EACZ,gBAAgB,GACjB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAE3E,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAC1D,YAAY,EACV,YAAY,EACZ,gBAAgB,GACjB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAE3E,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAChE,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,aAAa,GACd,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AAIjF,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAC7D,YAAY,EACV,aAAa,EACb,iBAAiB,GAClB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAE9E,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AAMpF,OAAO,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AACpD,YAAY,EACV,UAAU,EACV,WAAW,EACX,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,WAAW,EACX,cAAc,EACd,WAAW,GACZ,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAErE,OAAO,EACL,UAAU,EACV,aAAa,EACb,UAAU,EACV,YAAY,EACZ,cAAc,GACf,MAAM,mCAAmC,CAAC;AAC3C,YAAY,EACV,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,GACf,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAQ7E,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAC7D,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4CAA4C,CAAC;AAG9E,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAG3D,OAAO,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AAInC,OAAO,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AACvC,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;GAEG;AACH,eAAO,MAAM,OAAO,eAAe,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dashforge/tw",
3
- "version": "0.5.0-beta",
3
+ "version": "0.7.0-beta",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.esm.js",
@@ -31,8 +31,8 @@
31
31
  "tailwind-variants": "^3.1.1",
32
32
  "vitest": "*",
33
33
  "@dashforge/forms": "0.2.3-beta",
34
- "@dashforge/rbac": "0.2.3-beta",
35
- "@dashforge/ui-core": "0.2.3-beta"
34
+ "@dashforge/ui-core": "0.2.3-beta",
35
+ "@dashforge/rbac": "0.2.3-beta"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "react": "^18.0.0 || ^19.0.0",
@@ -3,11 +3,13 @@ import { tv, type VariantProps } from 'tailwind-variants';
3
3
  export const accordionVariants = tv({
4
4
  slots: {
5
5
  root: 'w-full',
6
- item: 'border-b border-neutral-200 dark:border-neutral-800',
6
+ // Neutral palette auto-inverts via the dashforgePreset() CSS-var
7
+ // swap — no `dark:` variant needed (would double-invert).
8
+ item: 'border-b border-neutral-200',
7
9
  header: 'flex',
8
10
  trigger: [
9
11
  'flex flex-1 items-center justify-between py-3 text-left',
10
- 'text-sm font-medium text-neutral-900 dark:text-neutral-50',
12
+ 'text-sm font-medium text-neutral-900',
11
13
  'transition-all hover:underline',
12
14
  'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary-500 focus-visible:rounded',
13
15
  '[&[data-state=open]>svg]:rotate-180',
@@ -15,7 +17,7 @@ export const accordionVariants = tv({
15
17
  'motion-reduce:transition-none',
16
18
  ],
17
19
  content: [
18
- 'overflow-hidden text-sm text-neutral-700 dark:text-neutral-300',
20
+ 'overflow-hidden text-sm text-neutral-700',
19
21
  'data-[state=open]:animate-accordion-down',
20
22
  'data-[state=closed]:animate-accordion-up',
21
23
  'motion-reduce:animate-none',
@@ -46,7 +46,11 @@ describe('<Box>', () => {
46
46
  const { container } = render(<Box variant="elevated" elevation={3}>x</Box>);
47
47
  const cls = container.firstElementChild?.className ?? '';
48
48
  expect(cls).toContain('bg-white');
49
- expect(cls).toContain('dark:bg-neutral-900');
49
+ // Sprint 4.3 theme identity sweep: corrected `dark:bg-neutral-900`
50
+ // (which resolved to near-white in dark mode via inversion — broken
51
+ // elevation) to `dark:bg-neutral-100` which resolves to `#171717`,
52
+ // one elevation tier above the page surface in dark mode.
53
+ expect(cls).toContain('dark:bg-neutral-100');
50
54
  expect(cls).toContain('shadow-md');
51
55
  expect(cls).not.toContain('border ');
52
56
  });
@@ -203,11 +207,17 @@ describe('<Box>', () => {
203
207
  const { container } = render(<Box variant="outlined" color={color}>x</Box>);
204
208
  const cls = container.firstElementChild?.className ?? '';
205
209
  if (color === 'neutral') {
206
- // neutral uses the special border-neutral-200 + bg-white shape
210
+ // Sprint 4.3 identity sweep: neutral outlined uses
211
+ // `border-neutral-200` (auto-inverts via CSS-var swap; no
212
+ // `dark:` needed) + `bg-white dark:bg-neutral-100`
213
+ // (bg-white is hardcoded so `dark:` is required; target
214
+ // `dark:bg-neutral-100` = `#171717` is one tier elevated
215
+ // above the page surface in dark mode).
207
216
  expect(cls).toContain('border-neutral-200');
208
217
  expect(cls).toContain('bg-white');
209
- expect(cls).toContain('dark:border-neutral-700');
210
- expect(cls).toContain('dark:bg-neutral-900');
218
+ expect(cls).toContain('dark:bg-neutral-100');
219
+ // No more dark:border-neutral-700 (auto-inverts).
220
+ expect(cls).not.toContain('dark:border-neutral-');
211
221
  } else {
212
222
  // primary/secondary/success/warning/danger/info share the
213
223
  // border-{color}-300 + bg-{color}-50/40 + dark:* pattern
@@ -229,10 +239,12 @@ describe('<Box>', () => {
229
239
  const { container } = render(<Box variant="soft" color={color}>x</Box>);
230
240
  const cls = container.firstElementChild?.className ?? '';
231
241
  if (color === 'neutral') {
242
+ // Sprint 4.3 identity sweep: both neutral classes auto-invert
243
+ // via the dashforgePreset() CSS-var swap — no `dark:` needed.
232
244
  expect(cls).toContain('bg-neutral-100');
233
245
  expect(cls).toContain('text-neutral-900');
234
- expect(cls).toContain('dark:bg-neutral-800');
235
- expect(cls).toContain('dark:text-neutral-100');
246
+ expect(cls).not.toContain('dark:bg-neutral-');
247
+ expect(cls).not.toContain('dark:text-neutral-');
236
248
  } else {
237
249
  expect(cls).toContain(`bg-${color}-100`);
238
250
  expect(cls).toContain(`text-${color}-900`);
@@ -254,10 +266,17 @@ describe('<Box>', () => {
254
266
  const { container } = render(<Box variant="solid" color={color}>x</Box>);
255
267
  const cls = container.firstElementChild?.className ?? '';
256
268
  if (color === 'neutral') {
269
+ // Sprint 4.3 identity sweep: solid neutral now uses
270
+ // `bg-neutral-900 text-neutral-50` (both auto-invert) — the
271
+ // accent surface inverts WITH the page (dark surface in
272
+ // light mode, light surface in dark mode), consistent with
273
+ // identity rule. Previously was `text-white` (no inversion)
274
+ // forcing double-invert pattern to stay readable.
257
275
  expect(cls).toContain('bg-neutral-900');
258
- expect(cls).toContain('text-white');
259
- expect(cls).toContain('dark:bg-neutral-100');
260
- expect(cls).toContain('dark:text-neutral-900');
276
+ expect(cls).toContain('text-neutral-50');
277
+ expect(cls).not.toContain('text-white');
278
+ expect(cls).not.toContain('dark:bg-neutral-');
279
+ expect(cls).not.toContain('dark:text-neutral-');
261
280
  } else if (color === 'warning') {
262
281
  // warning uses 500/600 instead of 600/500 to keep contrast
263
282
  // legible against an already-yellow surface in light mode.
@@ -289,9 +308,11 @@ describe('<Box>', () => {
289
308
  it('elevated + color="danger" stays on the neutral surface', () => {
290
309
  const { container } = render(<Box variant="elevated" color="danger">x</Box>);
291
310
  const cls = container.firstElementChild?.className ?? '';
292
- // elevated paints bg-white / dark:bg-neutral-900 regardless of intent
311
+ // elevated paints bg-white / dark:bg-neutral-100 regardless of
312
+ // intent (Sprint 4.3 sweep: dark target corrected to
313
+ // `dark:bg-neutral-100` for proper dark elevation).
293
314
  expect(cls).toContain('bg-white');
294
- expect(cls).toContain('dark:bg-neutral-900');
315
+ expect(cls).toContain('dark:bg-neutral-100');
295
316
  expect(cls).not.toContain('bg-danger-');
296
317
  expect(cls).not.toContain('border-danger-');
297
318
  });
@@ -55,7 +55,13 @@ export const boxVariants = tv({
55
55
  variant: {
56
56
  plain: '',
57
57
  outlined: 'border',
58
- elevated: 'bg-white dark:bg-neutral-900',
58
+ // `bg-white` is hardcoded (does NOT auto-invert via CSS vars),
59
+ // so the `dark:` variant is required. Target `dark:bg-neutral-100`
60
+ // resolves to `#171717` via the inversion → one elevation tier
61
+ // above the page surface (`bg-neutral-50` = `#0a0a0a`) in dark
62
+ // mode. `dark:bg-neutral-900` was wrong (resolved to near-white
63
+ // in dark mode — overpowering elevation).
64
+ elevated: 'bg-white dark:bg-neutral-100',
59
65
  soft: '',
60
66
  solid: '',
61
67
  },
@@ -165,7 +171,11 @@ export const boxVariants = tv({
165
171
  { variant: 'outlined', color: 'info',
166
172
  class: 'border-info-300 bg-info-50/40 dark:border-info-800 dark:bg-info-950/30' },
167
173
  { variant: 'outlined', color: 'neutral',
168
- class: 'border-neutral-200 bg-white dark:border-neutral-700 dark:bg-neutral-900' },
174
+ // border-neutral-200 auto-inverts via CSS var swap (no `dark:`
175
+ // needed). bg-white is hardcoded — `dark:bg-neutral-100` keeps
176
+ // elevation tier above page surface in dark mode (NOT
177
+ // `dark:bg-neutral-900` which renders near-white).
178
+ class: 'border-neutral-200 bg-white dark:bg-neutral-100' },
169
179
 
170
180
  // ─── soft × color ─────────────────────────────────────────────────
171
181
  { variant: 'soft', color: 'primary',
@@ -181,7 +191,9 @@ export const boxVariants = tv({
181
191
  { variant: 'soft', color: 'info',
182
192
  class: 'bg-info-100 text-info-900 dark:bg-info-950/50 dark:text-info-100' },
183
193
  { variant: 'soft', color: 'neutral',
184
- class: 'bg-neutral-100 text-neutral-900 dark:bg-neutral-800 dark:text-neutral-100' },
194
+ // Both neutral classes auto-invert via the dashforgePreset() CSS
195
+ // var swap — no `dark:` variants needed.
196
+ class: 'bg-neutral-100 text-neutral-900' },
185
197
 
186
198
  // ─── solid × color ────────────────────────────────────────────────
187
199
  { variant: 'solid', color: 'primary',
@@ -197,7 +209,14 @@ export const boxVariants = tv({
197
209
  { variant: 'solid', color: 'info',
198
210
  class: 'bg-info-600 text-white dark:bg-info-500' },
199
211
  { variant: 'solid', color: 'neutral',
200
- class: 'bg-neutral-900 text-white dark:bg-neutral-100 dark:text-neutral-900' },
212
+ // Solid neutral is the high-emphasis "always-foreground accent"
213
+ // variant. Both classes auto-invert: dark surface + light text
214
+ // in light mode (`#171717` / `#fafafa`) flips to light surface +
215
+ // dark text in dark mode (`#f5f5f5` / `#0a0a0a`). The
216
+ // accent inverts WITH the page surface — consistent with the
217
+ // identity rule. Previously used `text-white` (no auto-invert)
218
+ // which forced double-inversion to keep readable.
219
+ class: 'bg-neutral-900 text-neutral-50' },
201
220
  ],
202
221
 
203
222
  defaultVariants: {