@crisp-ui-kit/crisp 0.2.0 → 0.5.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 (244) hide show
  1. package/README.md +6 -0
  2. package/dist/base.css +25 -0
  3. package/dist/button.css +1 -1
  4. package/dist/command.css +1 -1
  5. package/dist/contextmenu.css +1 -1
  6. package/dist/datatable.css +60 -0
  7. package/dist/datatable.d.ts +7 -0
  8. package/dist/datepicker.css +1 -1
  9. package/dist/dialog.css +1 -1
  10. package/dist/esm/components/accordion/accordion.js +32 -0
  11. package/dist/esm/components/accordion/accordion.recipe.js +23 -0
  12. package/dist/esm/components/accordion/index.js +2 -0
  13. package/dist/esm/components/avatar/avatar.js +8 -0
  14. package/dist/esm/components/avatar/avatar.recipe.js +39 -0
  15. package/dist/esm/components/avatar/index.js +2 -0
  16. package/dist/esm/components/avatargroup/avatargroup.js +16 -0
  17. package/dist/esm/components/avatargroup/avatargroup.recipe.js +15 -0
  18. package/dist/esm/components/avatargroup/index.js +2 -0
  19. package/dist/esm/components/badge/badge.js +8 -0
  20. package/dist/esm/components/badge/badge.recipe.js +65 -0
  21. package/dist/esm/components/badge/index.js +2 -0
  22. package/dist/esm/components/barchart/barchart.js +29 -0
  23. package/dist/esm/components/barchart/barchart.recipe.js +26 -0
  24. package/dist/esm/components/barchart/index.js +2 -0
  25. package/dist/esm/components/breadcrumb/breadcrumb.js +17 -0
  26. package/dist/esm/components/breadcrumb/breadcrumb.recipe.js +18 -0
  27. package/dist/esm/components/breadcrumb/index.js +2 -0
  28. package/dist/esm/components/bulkbar/bulkbar.js +16 -0
  29. package/dist/esm/components/bulkbar/bulkbar.recipe.js +28 -0
  30. package/dist/esm/components/bulkbar/index.js +2 -0
  31. package/dist/esm/components/button/button.js +15 -0
  32. package/dist/esm/components/button/button.recipe.js +39 -0
  33. package/dist/esm/components/button/index.js +2 -0
  34. package/dist/esm/components/callout/callout.js +22 -0
  35. package/dist/esm/components/callout/callout.recipe.js +26 -0
  36. package/dist/esm/components/callout/index.js +2 -0
  37. package/dist/esm/components/card/card.js +15 -0
  38. package/dist/esm/components/card/card.recipe.js +28 -0
  39. package/dist/esm/components/card/index.js +2 -0
  40. package/dist/esm/components/checkbox/checkbox.js +20 -0
  41. package/dist/esm/components/checkbox/checkbox.recipe.js +23 -0
  42. package/dist/esm/components/checkbox/index.js +2 -0
  43. package/dist/esm/components/contextmenu/contextmenu.js +42 -0
  44. package/dist/esm/components/contextmenu/contextmenu.recipe.js +21 -0
  45. package/dist/esm/components/contextmenu/index.js +2 -0
  46. package/dist/esm/components/datatable/datatable.js +245 -0
  47. package/dist/esm/components/datatable/datatable.recipe.js +72 -0
  48. package/dist/esm/components/datatable/index.js +2 -0
  49. package/dist/esm/components/datepicker/datepicker.js +57 -0
  50. package/dist/esm/components/datepicker/datepicker.recipe.js +32 -0
  51. package/dist/esm/components/datepicker/index.js +2 -0
  52. package/dist/esm/components/dialog/dialog.js +48 -0
  53. package/dist/esm/components/dialog/dialog.recipe.js +32 -0
  54. package/dist/esm/components/dialog/index.js +2 -0
  55. package/dist/esm/components/divider/divider.js +7 -0
  56. package/dist/esm/components/divider/divider.recipe.js +14 -0
  57. package/dist/esm/components/divider/index.js +2 -0
  58. package/dist/esm/components/donutchart/donutchart.js +38 -0
  59. package/dist/esm/components/donutchart/donutchart.recipe.js +27 -0
  60. package/dist/esm/components/donutchart/index.js +2 -0
  61. package/dist/esm/components/drawer/drawer.js +42 -0
  62. package/dist/esm/components/drawer/drawer.recipe.js +27 -0
  63. package/dist/esm/components/drawer/index.js +2 -0
  64. package/dist/esm/components/emptystate/emptystate.js +7 -0
  65. package/dist/esm/components/emptystate/emptystate.recipe.js +31 -0
  66. package/dist/esm/components/emptystate/index.js +2 -0
  67. package/dist/esm/components/formfield/formfield.js +14 -0
  68. package/dist/esm/components/formfield/formfield.recipe.js +19 -0
  69. package/dist/esm/components/formfield/index.js +2 -0
  70. package/dist/esm/components/input/index.js +2 -0
  71. package/dist/esm/components/input/input.js +8 -0
  72. package/dist/esm/components/input/input.recipe.js +23 -0
  73. package/dist/esm/components/kbd/index.js +2 -0
  74. package/dist/esm/components/kbd/kbd.js +8 -0
  75. package/dist/esm/components/kbd/kbd.recipe.js +20 -0
  76. package/dist/esm/components/linechart/index.js +2 -0
  77. package/dist/esm/components/linechart/linechart.js +41 -0
  78. package/dist/esm/components/linechart/linechart.recipe.js +27 -0
  79. package/dist/esm/components/menu/index.js +2 -0
  80. package/dist/esm/components/menu/menu.js +137 -0
  81. package/dist/esm/components/menu/menu.recipe.js +51 -0
  82. package/dist/esm/components/multiselect/index.js +2 -0
  83. package/dist/esm/components/multiselect/multiselect.js +118 -0
  84. package/dist/esm/components/multiselect/multiselect.recipe.js +68 -0
  85. package/dist/esm/components/popover/index.js +2 -0
  86. package/dist/esm/components/popover/popover.js +70 -0
  87. package/dist/esm/components/popover/popover.recipe.js +18 -0
  88. package/dist/esm/components/progress/index.js +2 -0
  89. package/dist/esm/components/progress/progress.js +23 -0
  90. package/dist/esm/components/progress/progress.recipe.js +17 -0
  91. package/dist/esm/components/radiogroup/index.js +2 -0
  92. package/dist/esm/components/radiogroup/radiogroup.js +46 -0
  93. package/dist/esm/components/radiogroup/radiogroup.recipe.js +37 -0
  94. package/dist/esm/components/segmented/index.js +2 -0
  95. package/dist/esm/components/segmented/segmented.js +59 -0
  96. package/dist/esm/components/segmented/segmented.recipe.js +20 -0
  97. package/dist/esm/components/select/index.js +2 -0
  98. package/dist/esm/components/select/select.js +144 -0
  99. package/dist/esm/components/select/select.recipe.js +76 -0
  100. package/dist/esm/components/skeleton/index.js +2 -0
  101. package/dist/esm/components/skeleton/skeleton.js +7 -0
  102. package/dist/esm/components/skeleton/skeleton.recipe.js +14 -0
  103. package/dist/esm/components/spinner/index.js +2 -0
  104. package/dist/esm/components/spinner/spinner.js +11 -0
  105. package/dist/esm/components/spinner/spinner.recipe.js +13 -0
  106. package/dist/esm/components/stagebar/index.js +2 -0
  107. package/dist/esm/components/stagebar/stagebar.js +23 -0
  108. package/dist/esm/components/stagebar/stagebar.recipe.js +14 -0
  109. package/dist/esm/components/statcard/index.js +2 -0
  110. package/dist/esm/components/statcard/statcard.js +12 -0
  111. package/dist/esm/components/statcard/statcard.recipe.js +34 -0
  112. package/dist/esm/components/switch/index.js +2 -0
  113. package/dist/esm/components/switch/switch.js +22 -0
  114. package/dist/esm/components/switch/switch.recipe.js +26 -0
  115. package/dist/esm/components/table/index.js +2 -0
  116. package/dist/esm/components/table/table.js +30 -0
  117. package/dist/esm/components/table/table.recipe.js +40 -0
  118. package/dist/esm/components/tabletoolbar/index.js +2 -0
  119. package/dist/esm/components/tabletoolbar/tabletoolbar.chrome.js +79 -0
  120. package/dist/esm/components/tabletoolbar/tabletoolbar.js +191 -0
  121. package/dist/esm/components/tabletoolbar/tabletoolbar.recipe.js +23 -0
  122. package/dist/esm/components/tabs/index.js +2 -0
  123. package/dist/esm/components/tabs/tabs.js +70 -0
  124. package/dist/esm/components/tabs/tabs.recipe.js +33 -0
  125. package/dist/esm/components/textarea/index.js +2 -0
  126. package/dist/esm/components/textarea/textarea.js +20 -0
  127. package/dist/esm/components/textarea/textarea.recipe.js +31 -0
  128. package/dist/esm/components/toast/index.js +2 -0
  129. package/dist/esm/components/toast/toast.js +58 -0
  130. package/dist/esm/components/toast/toast.recipe.js +28 -0
  131. package/dist/esm/components/tooltip/index.js +2 -0
  132. package/dist/esm/components/tooltip/tooltip.js +45 -0
  133. package/dist/esm/components/tooltip/tooltip.recipe.js +13 -0
  134. package/dist/esm/core/cx.js +1 -0
  135. package/dist/esm/core/define.js +3 -0
  136. package/dist/esm/core/index.js +4 -0
  137. package/dist/esm/core/primitive.js +13 -0
  138. package/dist/esm/core/resolve.js +41 -0
  139. package/dist/esm/core/types.js +1 -0
  140. package/dist/esm/index.js +71 -0
  141. package/dist/esm/product/appshell/appshell.js +44 -0
  142. package/dist/esm/product/appshell/appshell.recipe.js +27 -0
  143. package/dist/esm/product/appshell/index.js +2 -0
  144. package/dist/esm/product/board/board.js +42 -0
  145. package/dist/esm/product/board/board.recipe.js +28 -0
  146. package/dist/esm/product/board/index.js +2 -0
  147. package/dist/esm/product/command/command.js +188 -0
  148. package/dist/esm/product/command/command.recipe.js +19 -0
  149. package/dist/esm/product/command/index.js +2 -0
  150. package/dist/esm/product/entitycard/entitycard.js +11 -0
  151. package/dist/esm/product/entitycard/entitycard.recipe.js +29 -0
  152. package/dist/esm/product/entitycard/index.js +2 -0
  153. package/dist/esm/product/flowcanvas/flowcanvas.js +85 -0
  154. package/dist/esm/product/flowcanvas/flowcanvas.recipe.js +25 -0
  155. package/dist/esm/product/flowcanvas/index.js +2 -0
  156. package/dist/esm/product/inbox/inbox.js +13 -0
  157. package/dist/esm/product/inbox/inbox.recipe.js +43 -0
  158. package/dist/esm/product/inbox/index.js +2 -0
  159. package/dist/esm/product/listpage/index.js +2 -0
  160. package/dist/esm/product/listpage/listpage.js +21 -0
  161. package/dist/esm/product/listpage/listpage.recipe.js +43 -0
  162. package/dist/esm/product/navitem/index.js +1 -0
  163. package/dist/esm/product/navitem/navitem.js +8 -0
  164. package/dist/esm/product/navitem/navitem.recipe.js +21 -0
  165. package/dist/esm/product/onboarding/index.js +2 -0
  166. package/dist/esm/product/onboarding/onboarding.js +14 -0
  167. package/dist/esm/product/onboarding/onboarding.recipe.js +41 -0
  168. package/dist/esm/product/recordpage/index.js +2 -0
  169. package/dist/esm/product/recordpage/recordpage.js +286 -0
  170. package/dist/esm/product/recordpage/recordpage.recipe.js +157 -0
  171. package/dist/esm/product/recordpanel/index.js +2 -0
  172. package/dist/esm/product/recordpanel/recordpanel.js +47 -0
  173. package/dist/esm/product/recordpanel/recordpanel.recipe.js +52 -0
  174. package/dist/esm/product/recordstable/company-logos.js +26 -0
  175. package/dist/esm/product/recordstable/index.js +2 -0
  176. package/dist/esm/product/recordstable/recordstable.js +963 -0
  177. package/dist/esm/product/recordstable/recordstable.recipe.js +149 -0
  178. package/dist/esm/product/richtext/index.js +2 -0
  179. package/dist/esm/product/richtext/richtext.js +111 -0
  180. package/dist/esm/product/richtext/richtext.recipe.js +40 -0
  181. package/dist/esm/product/settingssection/index.js +2 -0
  182. package/dist/esm/product/settingssection/settingssection.js +11 -0
  183. package/dist/esm/product/settingssection/settingssection.recipe.js +20 -0
  184. package/dist/esm/product/settingsshell/index.js +2 -0
  185. package/dist/esm/product/settingsshell/settingsshell.js +23 -0
  186. package/dist/esm/product/settingsshell/settingsshell.recipe.js +38 -0
  187. package/dist/esm/product/sidebar/index.js +2 -0
  188. package/dist/esm/product/sidebar/sidebar.js +112 -0
  189. package/dist/esm/product/sidebar/sidebar.recipe.js +18 -0
  190. package/dist/esm/product/tasklist/index.js +2 -0
  191. package/dist/esm/product/tasklist/tasklist.js +16 -0
  192. package/dist/esm/product/tasklist/tasklist.recipe.js +35 -0
  193. package/dist/esm/product/trialbanner/index.js +2 -0
  194. package/dist/esm/product/trialbanner/trialbanner.js +10 -0
  195. package/dist/esm/product/trialbanner/trialbanner.recipe.js +29 -0
  196. package/dist/esm/product/viewtoggle/index.js +2 -0
  197. package/dist/esm/product/viewtoggle/viewtoggle.js +11 -0
  198. package/dist/esm/product/viewtoggle/viewtoggle.recipe.js +24 -0
  199. package/dist/esm/tokens/contract.js +18 -0
  200. package/dist/esm/tokens/index.js +4 -0
  201. package/dist/esm/tokens/palette.js +30 -0
  202. package/dist/esm/tokens/scale.js +60 -0
  203. package/dist/esm/tokens/semantic.js +30 -0
  204. package/dist/menu.css +2 -2
  205. package/dist/multiselect.css +3 -3
  206. package/dist/popover.css +1 -1
  207. package/dist/recordpage.css +5 -5
  208. package/dist/recordstable.css +4 -4
  209. package/dist/select.css +10 -4
  210. package/dist/select.d.ts +2 -1
  211. package/dist/sidebar.css +1 -1
  212. package/dist/statcard.css +6 -0
  213. package/dist/statcard.d.ts +2 -2
  214. package/dist/styles.css +222 -27
  215. package/dist/table.css +26 -0
  216. package/dist/table.d.ts +8 -0
  217. package/dist/tabletoolbar.css +70 -0
  218. package/dist/tabletoolbar.d.ts +7 -0
  219. package/dist/tokens.css +24 -0
  220. package/dist/types/components/datatable/datatable.d.ts +98 -0
  221. package/dist/types/components/datatable/datatable.recipe.d.ts +3 -0
  222. package/dist/types/components/datatable/index.d.ts +2 -0
  223. package/dist/types/components/select/select.d.ts +3 -1
  224. package/dist/types/components/select/select.recipe.d.ts +12 -0
  225. package/dist/types/components/statcard/statcard.d.ts +6 -1
  226. package/dist/types/components/statcard/statcard.recipe.d.ts +12 -2
  227. package/dist/types/components/table/index.d.ts +2 -0
  228. package/dist/types/components/table/table.d.ts +53 -0
  229. package/dist/types/components/table/table.recipe.d.ts +21 -0
  230. package/dist/types/components/tabletoolbar/index.d.ts +2 -0
  231. package/dist/types/components/tabletoolbar/tabletoolbar.chrome.d.ts +2 -0
  232. package/dist/types/components/tabletoolbar/tabletoolbar.d.ts +63 -0
  233. package/dist/types/components/tabletoolbar/tabletoolbar.recipe.d.ts +3 -0
  234. package/dist/types/index.d.ts +3 -0
  235. package/dist/types/product/recordstable/company-logos.d.ts +1 -0
  236. package/dist/types/product/recordstable/recordstable.d.ts +42 -1
  237. package/dist/types/product/sidebar/index.d.ts +1 -1
  238. package/dist/types/product/sidebar/sidebar.d.ts +85 -0
  239. package/dist/types/tokens/contract.d.ts +12 -0
  240. package/dist/types/tokens/palette.d.ts +48 -0
  241. package/dist/types/tokens/semantic.d.ts +12 -0
  242. package/dist/viewtoggle.css +2 -2
  243. package/package.json +259 -9
  244. package/dist/index.js +0 -9690
@@ -0,0 +1,7 @@
1
+ import type { RecipeFn } from "../core/types";
2
+
3
+ export interface TabletoolbarVariants {
4
+
5
+ }
6
+
7
+ export declare const tabletoolbarRecipe: RecipeFn<{ }>;
package/dist/tokens.css CHANGED
@@ -6,6 +6,18 @@
6
6
  --bg-raised: #f4f4f5;
7
7
  --border-default: #e4e4e7;
8
8
  --border-subtle: #eeeff1;
9
+ --ring-neutral: transparent;
10
+ --bg-tile-active: #ffffff;
11
+ --shadow-tile-active: rgba(0,0,0,0.04);
12
+ --bg-overlay-frost: #ffffff;
13
+ --shadow-overlay1: rgba(28,40,64,0.12);
14
+ --shadow-overlay2: rgba(28,40,64,0.16);
15
+ --shadow-overlay3: rgba(28,40,64,0.16);
16
+ --bg-popover: #ffffff;
17
+ --ring-popover: rgba(0,0,0,0);
18
+ --shadow-popover1: rgba(28,40,64,0.04);
19
+ --shadow-popover2: rgba(28,40,64,0.12);
20
+ --shadow-popover3: rgba(24,41,75,0.16);
9
21
  --fg-primary: #101112;
10
22
  --fg-muted: #71717a;
11
23
  --bg-danger: #e5484d;
@@ -25,6 +37,18 @@
25
37
  --bg-raised: #101112;
26
38
  --border-default: #212224;
27
39
  --border-subtle: #1c1d1f;
40
+ --ring-neutral: #212224;
41
+ --bg-tile-active: #101112;
42
+ --shadow-tile-active: rgba(0,0,0,0);
43
+ --bg-overlay-frost: #1c1d1f;
44
+ --shadow-overlay1: rgba(0,0,0,0.48);
45
+ --shadow-overlay2: rgba(0,0,0,0.64);
46
+ --shadow-overlay3: rgba(0,0,0,0);
47
+ --bg-popover: #17181a;
48
+ --ring-popover: #212224;
49
+ --shadow-popover1: rgba(0,0,0,0.16);
50
+ --shadow-popover2: rgba(0,0,0,0.24);
51
+ --shadow-popover3: rgba(0,0,0,0.32);
28
52
  --fg-primary: #f5f5f5;
29
53
  --fg-muted: #9a9aa2;
30
54
  --bg-danger: #ff5a5f;
@@ -0,0 +1,98 @@
1
+ import * as React from "react";
2
+ type IconType = React.ComponentType<{
3
+ size?: number;
4
+ strokeWidth?: number;
5
+ }>;
6
+ export type EntityValue = {
7
+ name: string;
8
+ avatar?: string;
9
+ };
10
+ export type DataCellType = "text" | "entity" | "tags" | "status" | "date" | "number" | "currency";
11
+ export type DataTableColumn<T> = {
12
+ key: string;
13
+ header: React.ReactNode;
14
+ /** Built-in rich renderer: entity (avatar+name), tags (colour pills), status
15
+ * (dot), date, number, currency. Overridden by `render`. */
16
+ type?: DataCellType;
17
+ /** A leading field-type icon in the header (matches RecordsTable). */
18
+ icon?: IconType;
19
+ /** Currency symbol for `currency` columns (default "$"). */
20
+ symbol?: string;
21
+ /** Allow drag-to-resize on this column (default true). */
22
+ resizable?: boolean;
23
+ /** Tone overrides for `status`/`tags` values (else a stable colour per value). */
24
+ tones?: Record<string, string>;
25
+ /** Enable click-to-sort on this column's header. */
26
+ sortable?: boolean;
27
+ /** Exclude this column from the search filter (default: included). */
28
+ filterable?: boolean;
29
+ /** Allow inline editing (click the cell → text input → Enter/blur commits). */
30
+ editable?: boolean;
31
+ align?: "left" | "right" | "center";
32
+ width?: number;
33
+ /** Custom cell renderer. */
34
+ render?: (value: unknown, row: T) => React.ReactNode;
35
+ /** Derive the sort/filter/display value (defaults to `row[key]`). */
36
+ accessor?: (row: T) => string | number;
37
+ /** Transform the value into a display string (locale formatting, masking, a
38
+ * unit suffix, …); the result still flows through the built-in type
39
+ * renderer, so a `number`/`currency` column keeps its alignment + chrome.
40
+ * Precedence: `render` (full custom node) beats `format` (value string)
41
+ * beats the built-in type renderer. Display-only — sorting and filtering
42
+ * use the raw/`accessor` value, never the formatted string. */
43
+ format?: (value: unknown, row: T) => string;
44
+ /** Footer summary for this column (shown when any column supplies one). */
45
+ summary?: (rows: T[]) => React.ReactNode;
46
+ };
47
+ export type SortState = {
48
+ key: string;
49
+ dir: "asc" | "desc";
50
+ };
51
+ export type DataTableProps<T extends {
52
+ id: string;
53
+ }> = {
54
+ columns: DataTableColumn<T>[];
55
+ data: T[];
56
+ /** Show a leading selection column with a select-all header checkbox. */
57
+ selectable?: boolean;
58
+ selectedIds?: string[];
59
+ onSelectionChange?: (ids: string[]) => void;
60
+ /** Controlled sort (omit for self-managed; seed with `defaultSort`). */
61
+ sort?: SortState | null;
62
+ defaultSort?: SortState;
63
+ onSortChange?: (s: SortState | null) => void;
64
+ /** Show a search box that filters rows across filterable columns. */
65
+ filterable?: boolean;
66
+ searchPlaceholder?: string;
67
+ /** Commit handler for inline edits. */
68
+ onEdit?: (id: string, key: string, value: string) => void;
69
+ /** Sticky the first column(s) with a horizontal scroll shadow (default true). */
70
+ stickyFirst?: boolean;
71
+ /** Tone for `entity`-type avatars: `"brand"` (uniform, matches Attio's real
72
+ * records grid) or `"hashed"` (a stable colour per name — the tone `tags`/
73
+ * `status` pills already use, and entity's previous default). */
74
+ avatarTone?: "brand" | "hashed";
75
+ /** Card-style bordered surface (default) or full-bleed edge-to-edge, like
76
+ * RecordsTable. Passed through to the underlying `Table`. */
77
+ surface?: "card" | "bleed";
78
+ /** Row hover affordance + `onRowClick`. */
79
+ interactive?: boolean;
80
+ onRowClick?: (row: T) => void;
81
+ /** Renders a trailing add-row button ("New record") when provided. */
82
+ onAddRow?: () => void;
83
+ addRowLabel?: React.ReactNode;
84
+ /** Rendered in the body when there are no rows. */
85
+ empty?: React.ReactNode;
86
+ /** Show the "N of M" count on the right of the toolbar (default true). */
87
+ showCount?: boolean;
88
+ /** Extra toolbar content (e.g. buttons) on the right of the toolbar. */
89
+ toolbar?: React.ReactNode;
90
+ className?: string;
91
+ };
92
+ export declare function DataTable<T extends {
93
+ id: string;
94
+ }>({ columns, data, selectable, selectedIds, onSelectionChange, sort: sortProp, defaultSort, onSortChange, filterable, searchPlaceholder, onEdit, stickyFirst, avatarTone, surface, interactive, onRowClick, onAddRow, addRowLabel, empty, showCount, toolbar, className, }: DataTableProps<T>): React.JSX.Element;
95
+ export declare namespace DataTable {
96
+ var displayName: string;
97
+ }
98
+ export {};
@@ -0,0 +1,3 @@
1
+ declare const config: import("../..").RecipeConfig<{}>;
2
+ export declare const datatableRecipe: import("../..").RecipeFn<{}>;
3
+ export default config;
@@ -0,0 +1,2 @@
1
+ export { DataTable, type DataTableColumn, type DataTableProps, type SortState, } from "./datatable";
2
+ export { datatableRecipe } from "./datatable.recipe";
@@ -17,6 +17,8 @@ export type SelectProps = {
17
17
  placeholder?: string;
18
18
  /** `ghost` is borderless until hover — for inline selects (e.g. sort rows). */
19
19
  variant?: "default" | "ghost";
20
+ /** `full` (default) fills its container; `auto` sizes to content. */
21
+ width?: "full" | "auto";
20
22
  /** Show a search field at the top of the list that filters options (Linear/cmdk style). */
21
23
  searchable?: boolean;
22
24
  searchPlaceholder?: string;
@@ -32,7 +34,7 @@ export type SelectProps = {
32
34
  * "No results" empty state). Full keyboard model — ↑/↓ move, Enter/Space pick,
33
35
  * Esc close, Home/End jump, opens upward when tight. Controlled or uncontrolled.
34
36
  */
35
- export declare function Select({ options, value, defaultValue, onValueChange, placeholder, variant, searchable, searchPlaceholder, disabled, className, "aria-label": ariaLabel, id, }: SelectProps): React.JSX.Element;
37
+ export declare function Select({ options, value, defaultValue, onValueChange, placeholder, variant, width, searchable, searchPlaceholder, disabled, className, "aria-label": ariaLabel, id, }: SelectProps): React.JSX.Element;
36
38
  export declare namespace Select {
37
39
  var displayName: string;
38
40
  }
@@ -3,18 +3,30 @@ declare const config: import("../..").RecipeConfig<{
3
3
  default: string;
4
4
  ghost: string;
5
5
  };
6
+ width: {
7
+ full: string;
8
+ auto: string;
9
+ };
6
10
  }>;
7
11
  export declare const selectRecipe: import("../..").RecipeFn<{
8
12
  variant: {
9
13
  default: string;
10
14
  ghost: string;
11
15
  };
16
+ width: {
17
+ full: string;
18
+ auto: string;
19
+ };
12
20
  }> & {
13
21
  config: import("../..").RecipeConfig<{
14
22
  variant: {
15
23
  default: string;
16
24
  ghost: string;
17
25
  };
26
+ width: {
27
+ full: string;
28
+ auto: string;
29
+ };
18
30
  }>;
19
31
  };
20
32
  export default config;
@@ -12,13 +12,18 @@ export type StatCardProps = {
12
12
  deltaSuffix?: string;
13
13
  /** Caption after the delta (e.g. "vs last month"). */
14
14
  caption?: React.ReactNode;
15
+ /** Opt-in bordered card chrome (padding + border + radius), for use
16
+ * standalone instead of hand-wrapping in `<Card><CardBody>`. Default
17
+ * `false` — StatCard renders bare, as measured (pair with `Card` yourself
18
+ * for the Reports grid look). */
19
+ card?: boolean;
15
20
  className?: string;
16
21
  };
17
22
  /**
18
23
  * A single-metric KPI tile — measured from Attio's Reports number/insight cards.
19
24
  * Label, a large value, and an optional up/down delta pill with a caption.
20
25
  */
21
- export declare function StatCard({ label, icon, value, delta, deltaSuffix, caption, className, }: StatCardProps): React.JSX.Element;
26
+ export declare function StatCard({ label, icon, value, delta, deltaSuffix, caption, card, className, }: StatCardProps): React.JSX.Element;
22
27
  export declare namespace StatCard {
23
28
  var displayName: string;
24
29
  }
@@ -1,3 +1,13 @@
1
- declare const config: import("../..").RecipeConfig<{}>;
2
- export declare const statcardRecipe: import("../..").RecipeFn<{}>;
1
+ declare const config: import("../..").RecipeConfig<{
2
+ card: {
3
+ true: string;
4
+ false: string;
5
+ };
6
+ }>;
7
+ export declare const statcardRecipe: import("../..").RecipeFn<{
8
+ card: {
9
+ true: string;
10
+ false: string;
11
+ };
12
+ }>;
3
13
  export default config;
@@ -0,0 +1,2 @@
1
+ export { Table, TableBody, TableCaption, TableCell, type TableCellAlign, type TableCellProps, TableFooter, TableHead, TableHeader, type TableHeadProps, type TableProps, TableRow, } from "./table";
2
+ export { tableRecipe } from "./table.recipe";
@@ -0,0 +1,53 @@
1
+ import * as React from "react";
2
+ import type { VariantProps } from "../../core";
3
+ import { tableRecipe } from "./table.recipe";
4
+ export type TableProps = React.ComponentPropsWithoutRef<"table"> & VariantProps<typeof tableRecipe> & {
5
+ /** Class for the outer bordered wrapper (the recipe root). */
6
+ wrapperClassName?: string;
7
+ /** Props spread onto the horizontally-scrollable container (for sticky-column shadows). */
8
+ scrollProps?: React.ComponentPropsWithoutRef<"div"> & {
9
+ ref?: React.Ref<HTMLDivElement>;
10
+ };
11
+ };
12
+ /**
13
+ * A composable data table. Wraps `<table>` in a horizontally scrollable
14
+ * surface — `surface="card"` (default) bordered + rounded, `surface="bleed"`
15
+ * edge-to-edge like RecordsTable's full-page grid. Compose with
16
+ * `TableHeader`, `TableBody`, `TableFooter`, `TableRow`, `TableHead`,
17
+ * `TableCell`, and `TableCaption`.
18
+ */
19
+ export declare const Table: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.TableHTMLAttributes<HTMLTableElement>, HTMLTableElement>, "ref"> & VariantProps<import("../..").RecipeFn<{
20
+ interactive: {
21
+ true: string;
22
+ false: string;
23
+ };
24
+ surface: {
25
+ card: string;
26
+ bleed: string;
27
+ };
28
+ }>> & {
29
+ /** Class for the outer bordered wrapper (the recipe root). */
30
+ wrapperClassName?: string;
31
+ /** Props spread onto the horizontally-scrollable container (for sticky-column shadows). */
32
+ scrollProps?: React.ComponentPropsWithoutRef<"div"> & {
33
+ ref?: React.Ref<HTMLDivElement>;
34
+ };
35
+ } & React.RefAttributes<HTMLTableElement>>;
36
+ export declare const TableHeader: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLTableSectionElement>, HTMLTableSectionElement>, "ref"> & React.RefAttributes<HTMLTableSectionElement>>;
37
+ export declare const TableBody: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLTableSectionElement>, HTMLTableSectionElement>, "ref"> & React.RefAttributes<HTMLTableSectionElement>>;
38
+ export declare const TableFooter: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLTableSectionElement>, HTMLTableSectionElement>, "ref"> & React.RefAttributes<HTMLTableSectionElement>>;
39
+ export declare const TableRow: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLTableRowElement>, HTMLTableRowElement>, "ref"> & React.RefAttributes<HTMLTableRowElement>>;
40
+ export type TableCellAlign = "left" | "right" | "center";
41
+ export type TableHeadProps = React.ComponentPropsWithoutRef<"th"> & {
42
+ align?: TableCellAlign;
43
+ };
44
+ export declare const TableHead: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.ThHTMLAttributes<HTMLTableHeaderCellElement>, HTMLTableHeaderCellElement>, "ref"> & {
45
+ align?: TableCellAlign;
46
+ } & React.RefAttributes<HTMLTableCellElement>>;
47
+ export type TableCellProps = React.ComponentPropsWithoutRef<"td"> & {
48
+ align?: TableCellAlign;
49
+ };
50
+ export declare const TableCell: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.TdHTMLAttributes<HTMLTableDataCellElement>, HTMLTableDataCellElement>, "ref"> & {
51
+ align?: TableCellAlign;
52
+ } & React.RefAttributes<HTMLTableCellElement>>;
53
+ export declare const TableCaption: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, "ref"> & React.RefAttributes<HTMLTableCaptionElement>>;
@@ -0,0 +1,21 @@
1
+ declare const config: import("../..").RecipeConfig<{
2
+ interactive: {
3
+ true: string;
4
+ false: string;
5
+ };
6
+ surface: {
7
+ card: string;
8
+ bleed: string;
9
+ };
10
+ }>;
11
+ export declare const tableRecipe: import("../..").RecipeFn<{
12
+ interactive: {
13
+ true: string;
14
+ false: string;
15
+ };
16
+ surface: {
17
+ card: string;
18
+ bleed: string;
19
+ };
20
+ }>;
21
+ export default config;
@@ -0,0 +1,2 @@
1
+ export * from "./tabletoolbar";
2
+ export { tabletoolbarRecipe } from "./tabletoolbar.recipe";
@@ -0,0 +1,2 @@
1
+ export declare const toolbarChromeHead: (p: string) => string;
2
+ export declare const toolbarChromeBody: (p: string) => string;
@@ -0,0 +1,63 @@
1
+ import * as React from "react";
2
+ type IconType = React.ComponentType<{
3
+ size?: number;
4
+ strokeWidth?: number;
5
+ }>;
6
+ export type SortDir = "asc" | "desc";
7
+ export type ToolbarSort = {
8
+ key: string;
9
+ dir: SortDir;
10
+ };
11
+ export type ToolbarFilterOp = "contains" | "is" | "isnot" | "empty" | "notempty";
12
+ export type ToolbarFilter = {
13
+ id: string;
14
+ key: string;
15
+ op: ToolbarFilterOp;
16
+ value: string;
17
+ };
18
+ export type TableToolbarColumn = {
19
+ key: string;
20
+ label: string;
21
+ /** Leading field-type icon, shown in the field pickers. */
22
+ icon?: IconType;
23
+ };
24
+ export type TableToolbarProps = {
25
+ /** The fields that can be sorted and filtered on. */
26
+ columns: TableToolbarColumn[];
27
+ /** Controlled sorts. Omit to let the toolbar manage them internally. */
28
+ sorts?: ToolbarSort[];
29
+ defaultSorts?: ToolbarSort[];
30
+ onSortsChange?: (sorts: ToolbarSort[]) => void;
31
+ /** Controlled filter conditions. Omit for internal state. */
32
+ filters?: ToolbarFilter[];
33
+ defaultFilters?: ToolbarFilter[];
34
+ onFiltersChange?: (filters: ToolbarFilter[]) => void;
35
+ /** Right-aligned count, e.g. `${rows.length} records`. */
36
+ count?: React.ReactNode;
37
+ /** Right-aligned actions after the count (a "New" button, say). */
38
+ children?: React.ReactNode;
39
+ /** Shows a "Learn about sorting" link in the sort popover when set. */
40
+ helpHref?: string;
41
+ className?: string;
42
+ };
43
+ /**
44
+ * Applies a toolbar's filter conditions to any row array. Reads the raw value
45
+ * at `row[key]` (override with `get` for derived fields) — never a formatted
46
+ * display string, so a grouped-thousands "$1,200" still matches "1200".
47
+ */
48
+ export declare function applyFilters<T>(rows: T[], filters: ToolbarFilter[], get?: (row: T, key: string) => unknown): T[];
49
+ /**
50
+ * Applies a toolbar's sorts to any row array, in order — sort 0 wins, later
51
+ * sorts break ties. Numbers compare numerically, everything else by locale.
52
+ */
53
+ export declare function applySorts<T>(rows: T[], sorts: ToolbarSort[], get?: (row: T, key: string) => unknown): T[];
54
+ /**
55
+ * Attio's table toolbar as a standalone primitive: the Sort and Filter
56
+ * controls, their menus, the sort-condition rows and the filter chips.
57
+ *
58
+ * `RecordsTable` renders this same measured chrome internally; this is the
59
+ * composable version, to put above `DataTable` or any table of your own. Pair
60
+ * it with `applyFilters` / `applySorts` to turn its state into rows.
61
+ */
62
+ export declare function TableToolbar({ columns, sorts: sortsProp, defaultSorts, onSortsChange, filters: filtersProp, defaultFilters, onFiltersChange, count, children, helpHref, className, }: TableToolbarProps): React.JSX.Element;
63
+ export {};
@@ -0,0 +1,3 @@
1
+ declare const config: import("../..").RecipeConfig<import("../..").RecipeVariantRecord>;
2
+ export declare const tabletoolbarRecipe: import("../..").RecipeFn<import("../..").RecipeVariantRecord>;
3
+ export default config;
@@ -10,6 +10,7 @@ export * from "./components/callout";
10
10
  export * from "./components/card";
11
11
  export * from "./components/checkbox";
12
12
  export * from "./components/contextmenu";
13
+ export * from "./components/datatable";
13
14
  export * from "./components/datepicker";
14
15
  export * from "./components/dialog";
15
16
  export * from "./components/divider";
@@ -32,6 +33,8 @@ export * from "./components/spinner";
32
33
  export * from "./components/stagebar";
33
34
  export * from "./components/statcard";
34
35
  export * from "./components/switch";
36
+ export * from "./components/table";
37
+ export * from "./components/tabletoolbar";
35
38
  export * from "./components/tabs";
36
39
  export * from "./components/textarea";
37
40
  export * from "./components/toast";
@@ -0,0 +1 @@
1
+ export declare const companyLogos: Record<string, string>;
@@ -26,6 +26,42 @@ export type Column = {
26
26
  options?: StatusOption[];
27
27
  /** Choices for a `reference` column (a searchable record picker). */
28
28
  refOptions?: ReferenceOption[];
29
+ /**
30
+ * Full custom cell content — an escape hatch for a display crisp can't
31
+ * express via `type` (sign-coloured currency, a maskable amount, a custom
32
+ * badge, …). Precedence is **`render` > `format` > the built-in `type`
33
+ * renderer**: when `render` is set it is the *only* thing drawn in the
34
+ * cell, replacing whatever `type` would normally render.
35
+ *
36
+ * Interaction contract for a `render` column: it keeps every grid chrome —
37
+ * row height, hairlines, padding, hover/selected tint, the cell focus ring,
38
+ * shift-click range select, the right-click row menu — but is **never**
39
+ * inline-editable and never shows a `type` picker (status/reference/date/
40
+ * tags), because crisp has no way to write a value back into custom
41
+ * content. Use `format` instead if the column should stay editable.
42
+ *
43
+ * ⌘C copies `format(value, row)` when the column also has one, otherwise
44
+ * the raw value stringified the same way a plain column would — never a
45
+ * serialization of the rendered node. Sort, filter, and the footer
46
+ * aggregation all read `row[column.key]` directly and never call `render`.
47
+ */
48
+ render?: (value: unknown, row: Row) => React.ReactNode;
49
+ /**
50
+ * Display-only string transform. Unlike `render`, a `format` column keeps
51
+ * the built-in `type` renderer's chrome (a `currency`/`number` column stays
52
+ * right-aligned in its numeric span; `text`/`url`/`date`/the default case
53
+ * keep their own wrapper) — `format`'s return value simply replaces the
54
+ * text that renderer would otherwise show. `format` fully owns that text,
55
+ * so a `currency` column's `format` should include its own symbol/masking
56
+ * if it wants one (the built-in `$` prefix is skipped once `format` is
57
+ * set). A `format` column stays editable/pickable exactly like a plain
58
+ * `type` column — only `render` disables that.
59
+ *
60
+ * Sort, filter, and the footer aggregation all read the **raw**
61
+ * `row[column.key]` value, never `format`'s output — so a grouped/prefixed
62
+ * currency string still sums and sorts numerically.
63
+ */
64
+ format?: (value: unknown, row: Row) => string;
29
65
  };
30
66
  export type EntityValue = {
31
67
  name: string;
@@ -48,6 +84,11 @@ export type RecordsTableProps = {
48
84
  onOpenRecord?: (row: Row) => void;
49
85
  /** Called when a row's entity name is clicked — navigate to its full record page. */
50
86
  onOpenRecordPage?: (row: Row) => void;
87
+ /** Tone for `entity`/`reference` avatars: `"brand"` (uniform, today's
88
+ * measured Attio records-grid behaviour — the default) or `"hashed"` (a
89
+ * stable colour per name, matching what `DataTable`'s `avatarTone` offers).
90
+ * Entity avatars only — `TAG_TONES`/tag/status tone logic is untouched. */
91
+ avatarTone?: "brand" | "hashed";
51
92
  className?: string;
52
93
  };
53
94
  export declare function tagTone(t: string): string;
@@ -59,7 +100,7 @@ export declare function tagTone(t: string): string;
59
100
  * and a floating bulk-action bar (delete / deselect) when rows are selected.
60
101
  * Selection can be controlled via `selectedIds`/`onSelectionChange`.
61
102
  */
62
- export declare function RecordsTable({ columns: columnsProp, rows: rowsProp, selectedIds, onSelectionChange, showNew, allowAddColumn, onOpenRecord, onOpenRecordPage, className, }: RecordsTableProps): React.JSX.Element;
103
+ export declare function RecordsTable({ columns: columnsProp, rows: rowsProp, selectedIds, onSelectionChange, showNew, allowAddColumn, onOpenRecord, onOpenRecordPage, avatarTone, className, }: RecordsTableProps): React.JSX.Element;
63
104
  export declare const defaultColumns: Column[];
64
105
  export declare const defaultRows: Row[];
65
106
  export {};
@@ -1,2 +1,2 @@
1
- export { Sidebar, type SidebarProps } from "./sidebar";
1
+ export { ATTIO_SIDEBAR_CHATS_SECTION, ATTIO_SIDEBAR_FOOTER, ATTIO_SIDEBAR_ITEMS, ATTIO_SIDEBAR_LISTS_SECTION, ATTIO_SIDEBAR_RECORDS_SECTION, ATTIO_SIDEBAR_WORKSPACE, Sidebar, type SidebarFooter, type SidebarListsSection, type SidebarNavItem, type SidebarProps, type SidebarRecordItem, type SidebarRecordsSection, type SidebarSection, type SidebarWorkspace, } from "./sidebar";
2
2
  export { sidebarRecipe } from "./sidebar.recipe";
@@ -1,11 +1,96 @@
1
1
  import * as React from "react";
2
+ import type { AvatarProps } from "../../components/avatar";
3
+ type IconProps = {
4
+ className?: string;
5
+ };
6
+ /** A row in the main nav, or in a section's item list (Chats, etc). */
7
+ export type SidebarNavItem = {
8
+ label: string;
9
+ /** 16px icon component, rendered `<Icon />`. */
10
+ icon: React.ComponentType<IconProps>;
11
+ active?: boolean;
12
+ trailing?: React.ReactNode;
13
+ };
14
+ /** A row in the Records section — rendered as a tinted 20px glyph avatar. */
15
+ export type SidebarRecordItem = {
16
+ label: string;
17
+ tone: NonNullable<AvatarProps["tone"]>;
18
+ /** 12px glyph, rendered `<Glyph />` inside the tone avatar. */
19
+ glyph: React.ComponentType;
20
+ };
21
+ /** The workspace switcher at the top of the sidebar. */
22
+ export type SidebarWorkspace = {
23
+ name: string;
24
+ /** Avatar initial/letter. */
25
+ avatarLabel: string;
26
+ avatarTone?: NonNullable<AvatarProps["tone"]>;
27
+ };
28
+ /** A collapsible section built from nav-item rows (main nav shape is used, less the divider). */
29
+ export type SidebarSection = {
30
+ label: string;
31
+ items: SidebarNavItem[];
32
+ };
33
+ /** The Records section — same shape as SidebarSection but with glyph-avatar rows. */
34
+ export type SidebarRecordsSection = {
35
+ label: string;
36
+ items: SidebarRecordItem[];
37
+ };
38
+ /** The Lists section — has no item list of its own, just the "+ New list" affordance. */
39
+ export type SidebarListsSection = {
40
+ label: string;
41
+ newListLabel: string;
42
+ };
43
+ /** Footer copy: the onboarding pill, the invite row, and the trial banner. */
44
+ export type SidebarFooter = {
45
+ gettingStartedLabel: string;
46
+ inviteLabel: string;
47
+ trialText: string;
48
+ trialActionLabel: string;
49
+ };
2
50
  export type SidebarProps = React.ComponentPropsWithoutRef<"nav"> & {
3
51
  asChild?: boolean;
4
52
  /** Called when the collapse-panel button in the header is pressed. */
5
53
  onToggleCollapse?: () => void;
54
+ /** Workspace switcher content. Defaults to the measured Attio workspace. */
55
+ workspace?: SidebarWorkspace;
56
+ /** Main nav rows (Home, Tasks, …). Defaults to the measured Attio nav. */
57
+ items?: SidebarNavItem[];
58
+ /** The Records section (label + glyph-avatar rows). */
59
+ recordsSection?: SidebarRecordsSection;
60
+ /** The Lists section (label + "new list" affordance label). */
61
+ listsSection?: SidebarListsSection;
62
+ /** The Chats section (label + nav-item rows). */
63
+ chatsSection?: SidebarSection;
64
+ /** Footer copy (onboarding pill, invite row, trial banner). */
65
+ footer?: SidebarFooter;
6
66
  };
67
+ /** The measured Attio workspace switcher — the default `workspace` prop. */
68
+ export declare const ATTIO_SIDEBAR_WORKSPACE: SidebarWorkspace;
69
+ /** The measured Attio main nav — the default `items` prop. */
70
+ export declare const ATTIO_SIDEBAR_ITEMS: SidebarNavItem[];
71
+ /** The measured Attio Records section — the default `recordsSection` prop. */
72
+ export declare const ATTIO_SIDEBAR_RECORDS_SECTION: SidebarRecordsSection;
73
+ /** The measured Attio Lists section — the default `listsSection` prop. */
74
+ export declare const ATTIO_SIDEBAR_LISTS_SECTION: SidebarListsSection;
75
+ /** The measured Attio Chats section — the default `chatsSection` prop. */
76
+ export declare const ATTIO_SIDEBAR_CHATS_SECTION: SidebarSection;
77
+ /** The measured Attio footer copy — the default `footer` prop. */
78
+ export declare const ATTIO_SIDEBAR_FOOTER: SidebarFooter;
7
79
  export declare const Sidebar: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, "ref"> & {
8
80
  asChild?: boolean;
9
81
  /** Called when the collapse-panel button in the header is pressed. */
10
82
  onToggleCollapse?: () => void;
83
+ /** Workspace switcher content. Defaults to the measured Attio workspace. */
84
+ workspace?: SidebarWorkspace;
85
+ /** Main nav rows (Home, Tasks, …). Defaults to the measured Attio nav. */
86
+ items?: SidebarNavItem[];
87
+ /** The Records section (label + glyph-avatar rows). */
88
+ recordsSection?: SidebarRecordsSection;
89
+ /** The Lists section (label + "new list" affordance label). */
90
+ listsSection?: SidebarListsSection;
91
+ /** The Chats section (label + nav-item rows). */
92
+ chatsSection?: SidebarSection;
93
+ /** Footer copy (onboarding pill, invite row, trial banner). */
94
+ footer?: SidebarFooter;
11
95
  } & React.RefAttributes<HTMLDivElement>>;
96
+ export {};
@@ -8,6 +8,18 @@ export declare const contract: MapLeafNodes<{
8
8
  bgRaised: "gray50";
9
9
  borderDefault: "line200";
10
10
  borderSubtle: "line100";
11
+ ringNeutral: "ringNeutral";
12
+ bgTileActive: "tileActive";
13
+ shadowTileActive: "tileActiveShadow";
14
+ bgOverlayFrost: "overlayFrost";
15
+ shadowOverlay1: "shadowOverlay1";
16
+ shadowOverlay2: "shadowOverlay2";
17
+ shadowOverlay3: "shadowOverlay3";
18
+ bgPopover: "popoverBg";
19
+ ringPopover: "ringPopover";
20
+ shadowPopover1: "shadowPopover1";
21
+ shadowPopover2: "shadowPopover2";
22
+ shadowPopover3: "shadowPopover3";
11
23
  fgPrimary: "gray900";
12
24
  fgMuted: "gray400";
13
25
  bgDanger: "red600";