@photon-ai/pho-ui 2.6.0 → 2.7.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.
Files changed (120) hide show
  1. package/dist/chunks/IconChevronDown-CZilB71T.js +11 -0
  2. package/dist/chunks/IconChevronDown-CZilB71T.js.map +1 -0
  3. package/dist/chunks/IconSearch-BKAHkLyX.js +14 -0
  4. package/dist/chunks/IconSearch-BKAHkLyX.js.map +1 -0
  5. package/dist/chunks/animated-height-CCO-Ocoz.js +48 -0
  6. package/dist/chunks/animated-height-CCO-Ocoz.js.map +1 -0
  7. package/dist/chunks/basic-page-DR5szOOs.js +1373 -0
  8. package/dist/chunks/basic-page-DR5szOOs.js.map +1 -0
  9. package/dist/chunks/{button-DNNs5RsT.js → button-CdqS_t5a.js} +62 -65
  10. package/dist/chunks/button-CdqS_t5a.js.map +1 -0
  11. package/dist/chunks/checkbox-Cdm08HWG.js +129 -0
  12. package/dist/chunks/checkbox-Cdm08HWG.js.map +1 -0
  13. package/dist/chunks/{choice-card-CunOnY9l.js → choice-card-BVNP1NB6.js} +2 -2
  14. package/dist/chunks/{choice-card-CunOnY9l.js.map → choice-card-BVNP1NB6.js.map} +1 -1
  15. package/dist/chunks/data-table-DwbPU0zt.js +2970 -0
  16. package/dist/chunks/data-table-DwbPU0zt.js.map +1 -0
  17. package/dist/chunks/{dialog-8SRNi_rv.js → dialog-BxKACOj5.js} +4 -4
  18. package/dist/chunks/{dialog-8SRNi_rv.js.map → dialog-BxKACOj5.js.map} +1 -1
  19. package/dist/chunks/{error-Crs-wqMC.js → error-D0yoFxCv.js} +2 -2
  20. package/dist/chunks/{error-Crs-wqMC.js.map → error-D0yoFxCv.js.map} +1 -1
  21. package/dist/chunks/is-react-component-DSnjtBmo.js +10 -0
  22. package/dist/chunks/is-react-component-DSnjtBmo.js.map +1 -0
  23. package/dist/chunks/link-provider-DXzDQ08N.js +24 -0
  24. package/dist/chunks/link-provider-DXzDQ08N.js.map +1 -0
  25. package/dist/chunks/rolldown-runtime-DG5F_Nuu.js +27 -0
  26. package/dist/chunks/{scroll-area-Bu7egArU.js → scroll-area-BO-9PMM7.js} +27 -26
  27. package/dist/chunks/scroll-area-BO-9PMM7.js.map +1 -0
  28. package/dist/chunks/sidebar-DVzZsCts.js +223 -0
  29. package/dist/chunks/sidebar-DVzZsCts.js.map +1 -0
  30. package/dist/chunks/skeleton-DwjSl4vC.js +18 -0
  31. package/dist/chunks/skeleton-DwjSl4vC.js.map +1 -0
  32. package/dist/chunks/{toast-DoXaRPIZ.js → toast-iSf6NuAS.js} +43 -45
  33. package/dist/chunks/toast-iSf6NuAS.js.map +1 -0
  34. package/dist/chunks/use-press-pulse-IbNstUT0.js +58 -0
  35. package/dist/chunks/use-press-pulse-IbNstUT0.js.map +1 -0
  36. package/dist/components/button.js +1 -1
  37. package/dist/components/checkbox.js +4 -126
  38. package/dist/components/command.js +54 -57
  39. package/dist/components/command.js.map +1 -1
  40. package/dist/components/data-table.js +11 -0
  41. package/dist/components/dialog.js +1 -1
  42. package/dist/components/error.js +1 -1
  43. package/dist/components/phone-input.js +609 -616
  44. package/dist/components/phone-input.js.map +1 -1
  45. package/dist/components/radio-group.js +2 -2
  46. package/dist/components/scroll-area.js +1 -1
  47. package/dist/components/select.js +35 -39
  48. package/dist/components/select.js.map +1 -1
  49. package/dist/components/skeleton.js +2 -15
  50. package/dist/components/toast.js +1 -1
  51. package/dist/index.js +94 -73
  52. package/dist/motion.js +89 -0
  53. package/dist/motion.js.map +1 -0
  54. package/dist/primitives/accordion.js +1 -1
  55. package/dist/primitives/alert-dialog.js +1 -1
  56. package/dist/primitives/autocomplete.js +1 -1
  57. package/dist/primitives/avatar.js +1 -1
  58. package/dist/primitives/button.js +1 -1
  59. package/dist/primitives/checkbox-group.js +1 -1
  60. package/dist/primitives/checkbox.js +1 -1
  61. package/dist/primitives/collapsible.js +1 -1
  62. package/dist/primitives/combobox.js +1 -1
  63. package/dist/primitives/context-menu.js +1 -1
  64. package/dist/primitives/csp-provider.js +1 -1
  65. package/dist/primitives/dialog.js +1 -1
  66. package/dist/primitives/direction-provider.js +1 -1
  67. package/dist/primitives/drawer.js +1 -1
  68. package/dist/primitives/field.js +1 -1
  69. package/dist/primitives/fieldset.js +1 -1
  70. package/dist/primitives/form.js +1 -1
  71. package/dist/primitives/input.js +1 -1
  72. package/dist/primitives/menu.js +1 -1
  73. package/dist/primitives/menubar.js +1 -1
  74. package/dist/primitives/meter.js +1 -1
  75. package/dist/primitives/navigation-menu.js +1 -1
  76. package/dist/primitives/number-field.js +1 -1
  77. package/dist/primitives/otp-field.js +1 -1
  78. package/dist/primitives/popover.js +1 -1
  79. package/dist/primitives/preview-card.js +1 -1
  80. package/dist/primitives/progress.js +1 -1
  81. package/dist/primitives/radio-group.js +1 -1
  82. package/dist/primitives/radio.js +1 -1
  83. package/dist/primitives/scroll-area.js +1 -1
  84. package/dist/primitives/select.js +1 -1
  85. package/dist/primitives/separator.js +1 -1
  86. package/dist/primitives/slider.js +1 -1
  87. package/dist/primitives/switch.js +1 -1
  88. package/dist/primitives/tabs.js +1 -1
  89. package/dist/primitives/toast.js +1 -1
  90. package/dist/primitives/toggle-group.js +1 -1
  91. package/dist/primitives/toggle.js +1 -1
  92. package/dist/primitives/toolbar.js +1 -1
  93. package/dist/primitives/tooltip.js +1 -1
  94. package/dist/primitives.js +3 -3
  95. package/dist/sections/basic-page.js +16 -14
  96. package/dist/sections/sidebar.js +1 -1
  97. package/dist/src/components/data-table/data-table.d.ts +227 -0
  98. package/dist/src/components/data-table/index.d.ts +2 -0
  99. package/dist/src/index.d.ts +1 -0
  100. package/dist/src/motion/index.d.ts +149 -0
  101. package/dist/src/sections/basic-page/basic-page.d.ts +47 -7
  102. package/dist/src/sections/basic-page/index.d.ts +1 -0
  103. package/dist/utils.js +13 -12
  104. package/package.json +10 -1
  105. package/dist/chunks/animated-height-C2eQstGy.js +0 -51
  106. package/dist/chunks/animated-height-C2eQstGy.js.map +0 -1
  107. package/dist/chunks/basic-page-DsI1xo6p.js +0 -1295
  108. package/dist/chunks/basic-page-DsI1xo6p.js.map +0 -1
  109. package/dist/chunks/button-DNNs5RsT.js.map +0 -1
  110. package/dist/chunks/link-provider-9TFNyDqO.js +0 -28
  111. package/dist/chunks/link-provider-9TFNyDqO.js.map +0 -1
  112. package/dist/chunks/rolldown-runtime-wKSmTnsc.js +0 -22
  113. package/dist/chunks/scroll-area-Bu7egArU.js.map +0 -1
  114. package/dist/chunks/sidebar-DvB-G0BP.js +0 -231
  115. package/dist/chunks/sidebar-DvB-G0BP.js.map +0 -1
  116. package/dist/chunks/toast-DoXaRPIZ.js.map +0 -1
  117. package/dist/chunks/use-press-pulse-8iorQPsh.js +0 -62
  118. package/dist/chunks/use-press-pulse-8iorQPsh.js.map +0 -1
  119. package/dist/components/checkbox.js.map +0 -1
  120. package/dist/components/skeleton.js.map +0 -1
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/form";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/input";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/menu";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/menubar";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/meter";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/navigation-menu";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/number-field";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/otp-field";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/popover";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/preview-card";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/progress";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/radio-group";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/radio";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/scroll-area";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/select";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/separator";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/slider";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/switch";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/tabs";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/toast";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/toggle-group";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/toggle";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/toolbar";
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import "../chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "../chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  export * from "@base-ui/react/tooltip";
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import "./chunks/rolldown-runtime-wKSmTnsc.js";
2
+ import "./chunks/rolldown-runtime-DG5F_Nuu.js";
3
3
  import "./primitives/accordion.js";
4
4
  import "./primitives/alert-dialog.js";
5
5
  import "./primitives/autocomplete.js";
@@ -48,13 +48,13 @@ export * from "@base-ui/react/popover";
48
48
  export * from "@base-ui/react/avatar";
49
49
  export * from "@base-ui/react/form";
50
50
  export * from "@base-ui/react/menu";
51
+ export * from "@base-ui/react/checkbox";
52
+ export * from "@base-ui/react/checkbox-group";
51
53
  export * from "@base-ui/react/toast";
52
54
  export * from "@base-ui/react/accordion";
53
55
  export * from "@base-ui/react/alert-dialog";
54
56
  export * from "@base-ui/react/autocomplete";
55
57
  export * from "@base-ui/react/button";
56
- export * from "@base-ui/react/checkbox";
57
- export * from "@base-ui/react/checkbox-group";
58
58
  export * from "@base-ui/react/collapsible";
59
59
  export * from "@base-ui/react/combobox";
60
60
  export * from "@base-ui/react/context-menu";
@@ -1,18 +1,20 @@
1
1
  "use client";
2
- import { a as A, c as E, d as s, f as a, i as S, l as C, m as I, n as B, o as P, p as e, r as N, s as o, t as D, u as R } from "../chunks/basic-page-DsI1xo6p.js";
2
+ import { a as s, c as A, d as E, f as a, i as C, l as S, m as o, n as I, o as e, p as B, r as P, s as N, t as r, u as t } from "../chunks/basic-page-DR5szOOs.js";
3
+ import { o as R } from "../chunks/data-table-DwbPU0zt.js";
3
4
  export {
4
- D as AUTO_SAVE_DELAY_MS,
5
- B as BASIC_PAGE_CALLOUT,
6
- N as BASIC_PAGE_CARD,
7
- S as BASIC_PAGE_ITEM,
8
- A as BASIC_PAGE_ITEM_PANEL,
9
- P as BASIC_PAGE_ITEM_PANEL_DIVIDED,
10
- o as BASIC_PAGE_ROW,
11
- E as BasicPage,
12
- C as CONDENSE_BAR_ENTER,
13
- R as CONDENSE_BAR_RISE_PX,
14
- s as CONDENSE_BAR_TRAVEL,
5
+ r as AUTO_SAVE_DELAY_MS,
6
+ I as BASIC_PAGE_CALLOUT,
7
+ P as BASIC_PAGE_CARD,
8
+ C as BASIC_PAGE_ITEM,
9
+ s as BASIC_PAGE_ITEM_PANEL,
10
+ e as BASIC_PAGE_ITEM_PANEL_DIVIDED,
11
+ N as BASIC_PAGE_ROW,
12
+ A as BasicPage,
13
+ S as CONDENSE_BAR_ENTER,
14
+ t as CONDENSE_BAR_RISE_PX,
15
+ E as CONDENSE_BAR_TRAVEL,
16
+ R as createColumns,
15
17
  a as formToasts,
16
- e as useAutoSave,
17
- I as useCondense
18
+ B as useAutoSave,
19
+ o as useCondense
18
20
  };
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { a as I, c as _, i as A, n as R, o as S, r as a, s, t as T } from "../chunks/sidebar-DvB-G0BP.js";
2
+ import { a as I, c as _, i as A, n as R, o as S, r as a, s, t as T } from "../chunks/sidebar-DVzZsCts.js";
3
3
  export {
4
4
  T as SIDEBAR_HEADER_INSET,
5
5
  R as SIDEBAR_ITEM,
@@ -0,0 +1,227 @@
1
+ import { ComponentProps, ReactNode, Ref } from 'react';
2
+ import { ColumnDef, RowData, SortingState } from '@tanstack/react-table';
3
+ /**
4
+ * DataTable — a table of records with column semantics: sortable headers,
5
+ * aligned cells, rows that are links into a subpage. TanStack Table (v9)
6
+ * does the thinking — column defs, sorting, row identity — and renders
7
+ * nothing; every pixel here is Pho's.
8
+ *
9
+ * Design notes:
10
+ * - The surface is `BasicPage.Card`'s: hairline border, `base` radius, the
11
+ * page's primary fill, hairline rules between rows. A table is a card of
12
+ * rows that happen to line up in columns, so it sits in a page's `Stack`
13
+ * as any card does.
14
+ * - Header cells are description ink at body size — never small caps, never
15
+ * bold. Hierarchy comes from ink alone; the header is a label row, not a
16
+ * banner.
17
+ * - A sortable header is a button inside the cell: the label and its
18
+ * indicator (`IconSelector` at rest, a chevron once sorted). `aria-sort`
19
+ * sits on the `th`.
20
+ * - Rows that navigate stretch one link across the row (the first cell's
21
+ * link, extended with a pseudo-element), so the whole row is one target
22
+ * for pointer and one stop for keyboard. Hover washes the row; the row
23
+ * whose page is open beside the table (`current`) keeps the wash — the
24
+ * same cue `BasicPage.RowLink` gives under `aria-current`.
25
+ * - Numbers align to the end with tabular figures (`meta.align: "end"`).
26
+ * - `search` is one box over every column — plain contains matching, and
27
+ * the body says when nothing matches. In a page, `BasicPage.Search` in
28
+ * the section header adopts the box; alone, the table keeps one in a
29
+ * toolbar row inside its frame. Server-side search keeps its own box
30
+ * outside.
31
+ * - A wide table scrolls sideways inside its own frame; the page never does.
32
+ * `contain: inline-size` keeps the table's intrinsic width out of the
33
+ * page's — a host that sizes to content (a scroll area's fit-content
34
+ * pane, a grid's auto column) would otherwise grow to the widest row.
35
+ *
36
+ * Reach for it when a list needs column semantics — sorting, aligned
37
+ * figures, several fields side by side. A list where each row is one
38
+ * label and a chevron stays `BasicPage.RowLink`.
39
+ */
40
+ /** Column metadata a `DataTable` understands. */
41
+ export interface DataTableColumnMeta {
42
+ /** Cell alignment — `end` for figures (right-aligned, tabular). */
43
+ align?: "start" | "end";
44
+ }
45
+ /**
46
+ * The feature set every `DataTable` runs on — sorting with the stock sort
47
+ * functions, the column meta above. Fixed, so column definitions written
48
+ * once fit every table.
49
+ */
50
+ declare const features: {
51
+ rowSortingFeature: import('@tanstack/react-table').TableFeature;
52
+ rowSelectionFeature: import('@tanstack/react-table').TableFeature;
53
+ columnFilteringFeature: import('@tanstack/react-table').TableFeature;
54
+ globalFilteringFeature: import('@tanstack/react-table').TableFeature;
55
+ sortedRowModel: (table: import('@tanstack/react-table').Table<any, any>) => () => import('@tanstack/react-table').RowModel<any, any>;
56
+ filteredRowModel: (table: import('@tanstack/react-table').Table<any, any>) => () => import('@tanstack/react-table').RowModel<any, any>;
57
+ filterFns: {
58
+ includesString: import('@tanstack/react-table').CreatedFilterFn<any, any>;
59
+ };
60
+ sortFns: {
61
+ alphanumeric: import('@tanstack/react-table').CreatedSortFn<any, any>;
62
+ basic: import('@tanstack/react-table').CreatedSortFn<any, any>;
63
+ datetime: import('@tanstack/react-table').CreatedSortFn<any, any>;
64
+ text: import('@tanstack/react-table').CreatedSortFn<any, any>;
65
+ };
66
+ columnMeta: DataTableColumnMeta;
67
+ };
68
+ export type DataTableFeatures = typeof features;
69
+ /** A column definition for a `DataTable` of `TData` rows. */
70
+ export type DataTableColumn<TData extends RowData, TValue = unknown> = ColumnDef<DataTableFeatures, TData, TValue>;
71
+ /**
72
+ * The column helper, bound to the table's feature set — `accessor`,
73
+ * `display`, `group`, and `columns` to collect them with their types
74
+ * intact.
75
+ *
76
+ * @example
77
+ * const col = createColumns<Request>();
78
+ * const columns = col.columns([
79
+ * col.accessor("actor", { header: "Actor" }),
80
+ * col.accessor("amount", { header: "Amount", meta: { align: "end" } }),
81
+ * ]);
82
+ */
83
+ export declare function createColumns<TData extends RowData>(): import('@tanstack/react-table').ColumnHelper<{
84
+ rowSortingFeature: import('@tanstack/react-table').TableFeature;
85
+ rowSelectionFeature: import('@tanstack/react-table').TableFeature;
86
+ columnFilteringFeature: import('@tanstack/react-table').TableFeature;
87
+ globalFilteringFeature: import('@tanstack/react-table').TableFeature;
88
+ sortedRowModel: (table: import('@tanstack/react-table').Table<any, any>) => () => import('@tanstack/react-table').RowModel<any, any>;
89
+ filteredRowModel: (table: import('@tanstack/react-table').Table<any, any>) => () => import('@tanstack/react-table').RowModel<any, any>;
90
+ filterFns: {
91
+ includesString: import('@tanstack/react-table').CreatedFilterFn<any, any>;
92
+ };
93
+ sortFns: {
94
+ alphanumeric: import('@tanstack/react-table').CreatedSortFn<any, any>;
95
+ basic: import('@tanstack/react-table').CreatedSortFn<any, any>;
96
+ datetime: import('@tanstack/react-table').CreatedSortFn<any, any>;
97
+ text: import('@tanstack/react-table').CreatedSortFn<any, any>;
98
+ };
99
+ columnMeta: DataTableColumnMeta;
100
+ }, TData>;
101
+ export interface DataTableProps<TData extends RowData> extends Omit<ComponentProps<"div">, "children"> {
102
+ columns: ReadonlyArray<DataTableColumn<TData, any>>;
103
+ data: ReadonlyArray<TData>;
104
+ /**
105
+ * A row's identity — what `current` is matched against, and what keeps a
106
+ * row itself across sorts. Defaults to the row's `id` field, else its
107
+ * index.
108
+ */
109
+ getRowId?: (row: TData) => string;
110
+ /**
111
+ * Rows that navigate: each row is one link into a subpage, through the
112
+ * host's `LinkProvider`. Beside a `BasicPage.Aside`, the subpage opens
113
+ * next to the table.
114
+ */
115
+ rowHref?: (row: TData) => string;
116
+ /** The row whose page is open (its id) — it keeps the wash. */
117
+ current?: string | null;
118
+ /**
119
+ * Sorting is on for every accessor column (`enableSorting: false` on a
120
+ * column turns it off there). Uncontrolled by default; `defaultSort`
121
+ * seeds it. Pass `sort` with `onSortChange` to own it — the way to sort
122
+ * on the server.
123
+ */
124
+ defaultSort?: SortingState;
125
+ sort?: SortingState;
126
+ onSortChange?: (sort: SortingState) => void;
127
+ /**
128
+ * A search box on the table — `true`, or the placeholder it should
129
+ * show. One box searches every column (a column opts out with
130
+ * `enableGlobalFilter: false`); matching is a plain case-insensitive
131
+ * contains, on the client. With no matches the body says so. When the
132
+ * list doesn't all come down, keep the box outside and ask the server.
133
+ */
134
+ search?: boolean | string;
135
+ /**
136
+ * Controls in the frame's top band — a `BasicPage.Search` first, then a
137
+ * filter or two. The band is part of the table (one surface, a hairline
138
+ * above the header row), so nothing floats over the page and the
139
+ * spacing above and below is the frame's own. A `Search` here adopts
140
+ * the table's box the way a header one does.
141
+ */
142
+ toolbar?: ReactNode;
143
+ /**
144
+ * Row selection: hand either of these and rows grow a leading checkbox
145
+ * column. The header checkbox works the visible set — everything the
146
+ * search still shows — so select-all after a search means what it says;
147
+ * rows selected earlier and then hidden stay selected. `selected` is
148
+ * the selected ids (ids come from `getRowId`; pair with
149
+ * `onSelectedChange` to own the state); `onSelectedChange` alone
150
+ * listens while the table keeps it. The page renders its own bulk
151
+ * actions from the ids — the table only keeps the score.
152
+ */
153
+ selected?: readonly string[];
154
+ onSelectedChange?: (ids: string[]) => void;
155
+ /**
156
+ * File rows into labeled groups: return a label and the row renders
157
+ * under it, `null` and it stays in the main body. Groups follow the
158
+ * main body, in the order their labels first appear in `data`, each
159
+ * under a quiet label row — and only while they have rows, so a group
160
+ * a search empties simply leaves. Sorting orders rows within their
161
+ * group.
162
+ */
163
+ group?: (row: TData) => string | null;
164
+ /**
165
+ * Glide the frame's height when the rows change — a search narrowing,
166
+ * a filter, bones becoming rows. The height follows the content on the
167
+ * page spring instead of jumping; reserve it for tables whose rows
168
+ * change while mounted (same contract as `BasicPage.Card`'s).
169
+ */
170
+ animateHeight?: boolean;
171
+ /** Bones while the rows are on their way — `true` for five, or a count. */
172
+ loading?: boolean | number;
173
+ /** What the body says when there are no rows. */
174
+ empty?: ReactNode;
175
+ ref?: Ref<HTMLDivElement>;
176
+ }
177
+ /**
178
+ * A host that sizes itself around tables provides this; each table
179
+ * announces itself while mounted. `BasicPage.Root` runs wide when the
180
+ * page carries one and `width` was left unsaid.
181
+ */
182
+ export declare const TableHostContext: import('react').Context<((present: boolean) => void) | null>;
183
+ /** A searchable table's search, published for a header to adopt. */
184
+ export interface TableSearchApi {
185
+ placeholder: string;
186
+ query: string;
187
+ setQuery: (query: string) => void;
188
+ /** Rows still showing after the current query. */
189
+ matched: number;
190
+ /** Rows in the list, before search. */
191
+ total: number;
192
+ }
193
+ interface TableSearchState {
194
+ api: TableSearchApi | null;
195
+ adopted: boolean;
196
+ }
197
+ /**
198
+ * The channel between a searchable table and a `BasicPage.Search` placed
199
+ * in a section header: the table publishes its search (placeholder,
200
+ * query, the setter); a mounted `Search` adopts it, and the table's own
201
+ * box yields. Provided by `BasicPage.Root`; a table outside any page
202
+ * keeps its built-in box. One searchable table per page — a later
203
+ * publisher takes the slot.
204
+ */
205
+ export interface TableSearchStore {
206
+ get: () => TableSearchState;
207
+ subscribe: (listener: () => void) => () => void;
208
+ publish: (api: TableSearchApi | null) => void;
209
+ adopt: (adopted: boolean) => void;
210
+ }
211
+ export declare function createTableSearchStore(): TableSearchStore;
212
+ export declare const TableSearchContext: import('react').Context<TableSearchStore | null>;
213
+ export interface GhostSearchProps extends Omit<ComponentProps<"input">, "value" | "onChange" | "type" | "children"> {
214
+ value: string;
215
+ onChange: (value: string) => void;
216
+ }
217
+ /**
218
+ * The search's ghost face — a magnifier and a bare field, quiet ink on a
219
+ * text line, no box around it. What a table wears in its own toolbar
220
+ * band; `BasicPage.Search variant="ghost"` is the same face wherever a
221
+ * page wants it. Presentational: hand it the value and the setter.
222
+ */
223
+ export declare function GhostSearch({ value, onChange, className, ...props }: GhostSearchProps): import("react").JSX.Element;
224
+ /** Same chrome as `BasicPage.Card`, minus its dividers — rows draw their own. */
225
+ declare const DATA_TABLE_SURFACE = "rounded-base border border-pho-secondary bg-pho-primary";
226
+ declare function DataTable<TData extends RowData>({ columns, data, getRowId, rowHref, current, selected, onSelectedChange, defaultSort, sort, onSortChange, search, toolbar, group, animateHeight, loading, empty, className, ...props }: DataTableProps<TData>): import("react").JSX.Element;
227
+ export { DataTable, DATA_TABLE_SURFACE };
@@ -0,0 +1,2 @@
1
+ export { DataTable, DATA_TABLE_SURFACE, GhostSearch, type GhostSearchProps, TableHostContext, TableSearchContext, createTableSearchStore, type TableSearchApi, type TableSearchStore, createColumns, type DataTableProps, type DataTableColumn, type DataTableColumnMeta, type DataTableFeatures, } from './data-table';
2
+ export type { SortingState } from '@tanstack/react-table';
@@ -6,6 +6,7 @@
6
6
  * This root barrel re-exports everything for convenience.
7
7
  */
8
8
  export * from './utils';
9
+ export * from './motion';
9
10
  export * from './components/button';
10
11
  export * from './components/input';
11
12
  export * from './components/input-group';
@@ -0,0 +1,149 @@
1
+ /**
2
+ * The motion vocabulary — every animation in Pho speaks it. Five springs,
3
+ * three timings, two CSS eases, and a handful of distances cover the
4
+ * system; components import from here and add nothing of their own.
5
+ *
6
+ * The grammar:
7
+ * - **Arrive** on `SPRING_ENTRANCE` with `FADE_ENTRANCE` — content
8
+ * surfaces, it doesn't slide in.
9
+ * - **Swap** on `FADE_SWAP`, displacement on `TRAVEL_LINEAR` — crossfades
10
+ * ease out, travel is linear.
11
+ * - **Press** on the press springs — deeper mass for bigger surfaces.
12
+ * - **Follow** on `SPRING_SETTLE` — heights and reflows chase content.
13
+ */
14
+ /**
15
+ * Pages arrive on this — the `Stack` entrance, `Reveal`, `Title` / `Header`
16
+ * enter, the Title ↔ Back morph, `Alert` / `Footer` height reveals.
17
+ * Measured off a 60fps iOS push: ~330ms, a long gentle glide, everything
18
+ * co-landing; essentially critically damped (overshoot would flash
19
+ * clipped content).
20
+ */
21
+ export declare const SPRING_ENTRANCE: {
22
+ readonly type: "spring";
23
+ readonly stiffness: 400;
24
+ readonly damping: 40;
25
+ };
26
+ /**
27
+ * Layout follows content on this — `AnimatedHeight`, a command palette's
28
+ * rows gliding into new places. Stiffer than the entrance: reflow should
29
+ * settle before it reads as motion.
30
+ */
31
+ export declare const SPRING_SETTLE: {
32
+ readonly type: "spring";
33
+ readonly stiffness: 640;
34
+ readonly damping: 50;
35
+ };
36
+ /**
37
+ * The press pulse for full-size surfaces — `Button`, a sidebar row.
38
+ * Framer source: `spring-physics 200 30 0.1`.
39
+ */
40
+ export declare const SPRING_PRESS: {
41
+ readonly type: "spring";
42
+ readonly stiffness: 200;
43
+ readonly damping: 30;
44
+ readonly mass: 0.1;
45
+ };
46
+ /** The press pulse for small controls — toggles, checks; quick and light. */
47
+ export declare const SPRING_PRESS_QUICK: {
48
+ readonly type: "spring";
49
+ readonly stiffness: 700;
50
+ readonly damping: 32;
51
+ readonly mass: 0.06;
52
+ };
53
+ /** The press pulse for inline triggers — a `Select` sitting in text. */
54
+ export declare const SPRING_PRESS_INLINE: {
55
+ readonly type: "spring";
56
+ readonly stiffness: 1100;
57
+ readonly damping: 40;
58
+ readonly mass: 0.04;
59
+ };
60
+ /** The fade that rides `SPRING_ENTRANCE` — spans most of the glide. */
61
+ export declare const FADE_ENTRANCE: {
62
+ readonly duration: 0.25;
63
+ readonly ease: "easeOut";
64
+ };
65
+ /**
66
+ * The swap — crossfading faces, a condensed bar arriving, a saved word,
67
+ * an aside changing pages. Fades ease out.
68
+ */
69
+ export declare const FADE_SWAP: {
70
+ readonly duration: 0.2;
71
+ readonly ease: "easeOut";
72
+ };
73
+ /**
74
+ * Displacement — a bar's rise, a drawer's scope swap, a search box's
75
+ * width. Travel is linear: the eye reads speed changes as personality,
76
+ * and furniture has none.
77
+ */
78
+ export declare const TRAVEL_LINEAR: {
79
+ readonly duration: 0.2;
80
+ readonly ease: "linear";
81
+ };
82
+ /** CSS pop-in for floating layers (menus, select popups) — slight overshoot. */
83
+ export declare const EASE_POP = "cubic-bezier(0.34, 1.3, 0.64, 1)";
84
+ /** CSS stack glide — toasts trading places (Kumo's curve). */
85
+ export declare const EASE_STACK = "cubic-bezier(0.22, 1, 0.36, 1)";
86
+ /** Rise distance for entrances — content surfaces from just below. */
87
+ export declare const RISE_PX = 12;
88
+ /** Rise distance for the condensed bar — it comes from nearer still. */
89
+ export declare const BAR_RISE_PX = -8;
90
+ /** Press depth for small controls. */
91
+ export declare const PRESS_SCALE = 0.96;
92
+ /** Press depth for rows and full-size surfaces — shallower. */
93
+ export declare const PRESS_SCALE_ROW = 0.97;
94
+ /** The blur budget — one breath of blur, everywhere it is used. */
95
+ export declare const BLUR_PX = 1;
96
+ /**
97
+ * The crossfade recipe — fade with a breath of blur, both ways. Spread
98
+ * onto a motion element inside `AnimatePresence`:
99
+ *
100
+ * <motion.div {...fadeThroughBlur(reduceMotion)} />
101
+ *
102
+ * Under reduced motion the swap is instant and never blurs.
103
+ */
104
+ export declare function fadeThroughBlur(reduceMotion?: boolean | null): {
105
+ readonly initial: {
106
+ readonly opacity: 0;
107
+ readonly filter: "blur(0px)" | "blur(1px)";
108
+ };
109
+ readonly animate: {
110
+ readonly opacity: 1;
111
+ readonly filter: "blur(0px)";
112
+ };
113
+ readonly exit: {
114
+ readonly opacity: 0;
115
+ readonly filter: "blur(0px)" | "blur(1px)";
116
+ };
117
+ readonly transition: {
118
+ readonly duration: 0.2;
119
+ readonly ease: "easeOut";
120
+ } | {
121
+ readonly duration: 0;
122
+ };
123
+ };
124
+ /**
125
+ * The entrance recipe — rise `RISE_PX` on `SPRING_ENTRANCE` while
126
+ * `FADE_ENTRANCE` brings the ink. What `Stack` and `Reveal` do; spread it
127
+ * onto a motion element for content that should arrive the same way.
128
+ */
129
+ export declare function riseIn(reduceMotion?: boolean | null): {
130
+ readonly initial: false | {
131
+ readonly opacity: 0;
132
+ readonly y: 12;
133
+ };
134
+ readonly animate: {
135
+ readonly opacity: 1;
136
+ readonly y: 0;
137
+ };
138
+ readonly transition: {
139
+ readonly y: {
140
+ readonly type: "spring";
141
+ readonly stiffness: 400;
142
+ readonly damping: 40;
143
+ };
144
+ readonly opacity: {
145
+ readonly duration: 0.25;
146
+ readonly ease: "easeOut";
147
+ };
148
+ };
149
+ };