@kodffe/ui 0.0.0-stage → 0.10.1

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 (304) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +11 -0
  2. package/dist/accordion/accordion.d.ts +44 -0
  3. package/dist/accordion/accordion.js +84 -0
  4. package/dist/accordion/accordion.js.map +1 -0
  5. package/dist/alert/alert.d.ts +17 -0
  6. package/dist/alert/alert.js +59 -0
  7. package/dist/alert/alert.js.map +1 -0
  8. package/dist/app-shell/app-footer.d.ts +29 -0
  9. package/dist/app-shell/app-footer.js +39 -0
  10. package/dist/app-shell/app-footer.js.map +1 -0
  11. package/dist/app-shell/app-shell-context.d.ts +10 -0
  12. package/dist/app-shell/app-shell-context.js +12 -0
  13. package/dist/app-shell/app-shell-context.js.map +1 -0
  14. package/dist/app-shell/app-shell.d.ts +42 -0
  15. package/dist/app-shell/app-shell.js +191 -0
  16. package/dist/app-shell/app-shell.js.map +1 -0
  17. package/dist/app-shell/floating-actions.d.ts +19 -0
  18. package/dist/app-shell/floating-actions.js +59 -0
  19. package/dist/app-shell/floating-actions.js.map +1 -0
  20. package/dist/app-shell/workspace-switcher.d.ts +25 -0
  21. package/dist/app-shell/workspace-switcher.js +82 -0
  22. package/dist/app-shell/workspace-switcher.js.map +1 -0
  23. package/dist/badge/badge.d.ts +19 -0
  24. package/dist/badge/badge.js +59 -0
  25. package/dist/badge/badge.js.map +1 -0
  26. package/dist/banner/banner.d.ts +22 -0
  27. package/dist/banner/banner.js +80 -0
  28. package/dist/banner/banner.js.map +1 -0
  29. package/dist/breadcrumbs/breadcrumbs.d.ts +18 -0
  30. package/dist/breadcrumbs/breadcrumbs.js +45 -0
  31. package/dist/breadcrumbs/breadcrumbs.js.map +1 -0
  32. package/dist/button/button.d.ts +38 -0
  33. package/dist/button/button.js +83 -0
  34. package/dist/button/button.js.map +1 -0
  35. package/dist/card/card.d.ts +159 -0
  36. package/dist/card/card.js +390 -0
  37. package/dist/card/card.js.map +1 -0
  38. package/dist/card/insight-card.d.ts +19 -0
  39. package/dist/card/insight-card.js +51 -0
  40. package/dist/card/insight-card.js.map +1 -0
  41. package/dist/card/integration-card.d.ts +19 -0
  42. package/dist/card/integration-card.js +70 -0
  43. package/dist/card/integration-card.js.map +1 -0
  44. package/dist/charts/charts.d.ts +75 -0
  45. package/dist/charts/charts.js +453 -0
  46. package/dist/charts/charts.js.map +1 -0
  47. package/dist/choice/choice.d.ts +39 -0
  48. package/dist/choice/choice.js +143 -0
  49. package/dist/choice/choice.js.map +1 -0
  50. package/dist/combobox/combobox.d.ts +46 -0
  51. package/dist/combobox/combobox.js +196 -0
  52. package/dist/combobox/combobox.js.map +1 -0
  53. package/dist/command-palette/command-palette.d.ts +35 -0
  54. package/dist/command-palette/command-palette.js +164 -0
  55. package/dist/command-palette/command-palette.js.map +1 -0
  56. package/dist/confirm-dialog/confirm-dialog.d.ts +37 -0
  57. package/dist/confirm-dialog/confirm-dialog.js +106 -0
  58. package/dist/confirm-dialog/confirm-dialog.js.map +1 -0
  59. package/dist/content/assistant.d.ts +86 -0
  60. package/dist/content/assistant.js +213 -0
  61. package/dist/content/assistant.js.map +1 -0
  62. package/dist/content/content.d.ts +45 -0
  63. package/dist/content/content.js +136 -0
  64. package/dist/content/content.js.map +1 -0
  65. package/dist/data-display/avatar-sizes.d.ts +8 -0
  66. package/dist/data-display/avatar-sizes.js +12 -0
  67. package/dist/data-display/avatar-sizes.js.map +1 -0
  68. package/dist/data-display/avatar.d.ts +21 -0
  69. package/dist/data-display/avatar.js +53 -0
  70. package/dist/data-display/avatar.js.map +1 -0
  71. package/dist/data-display/chip.d.ts +20 -0
  72. package/dist/data-display/chip.js +64 -0
  73. package/dist/data-display/chip.js.map +1 -0
  74. package/dist/data-display/code-block.d.ts +14 -0
  75. package/dist/data-display/code-block.js +50 -0
  76. package/dist/data-display/code-block.js.map +1 -0
  77. package/dist/data-display/data-display.d.ts +73 -0
  78. package/dist/data-display/data-display.js +227 -0
  79. package/dist/data-display/data-display.js.map +1 -0
  80. package/dist/data-display/insights.d.ts +120 -0
  81. package/dist/data-display/insights.js +220 -0
  82. package/dist/data-display/insights.js.map +1 -0
  83. package/dist/data-table/cells.d.ts +86 -0
  84. package/dist/data-table/cells.js +163 -0
  85. package/dist/data-table/cells.js.map +1 -0
  86. package/dist/data-table/data-table.d.ts +112 -0
  87. package/dist/data-table/data-table.js +558 -0
  88. package/dist/data-table/data-table.js.map +1 -0
  89. package/dist/date-picker/date-picker.d.ts +61 -0
  90. package/dist/date-picker/date-picker.js +309 -0
  91. package/dist/date-picker/date-picker.js.map +1 -0
  92. package/dist/drawer/drawer.d.ts +32 -0
  93. package/dist/drawer/drawer.js +72 -0
  94. package/dist/drawer/drawer.js.map +1 -0
  95. package/dist/empty-state/empty-state.d.ts +25 -0
  96. package/dist/empty-state/empty-state.js +78 -0
  97. package/dist/empty-state/empty-state.js.map +1 -0
  98. package/dist/error-state/error-state.d.ts +19 -0
  99. package/dist/error-state/error-state.js +56 -0
  100. package/dist/error-state/error-state.js.map +1 -0
  101. package/dist/event-calendar/calendar-logic.test.d.ts +1 -0
  102. package/dist/event-calendar/dates.d.ts +35 -0
  103. package/dist/event-calendar/dates.js +55 -0
  104. package/dist/event-calendar/dates.js.map +1 -0
  105. package/dist/event-calendar/event-calendar.d.ts +125 -0
  106. package/dist/event-calendar/event-calendar.js +795 -0
  107. package/dist/event-calendar/event-calendar.js.map +1 -0
  108. package/dist/event-calendar/event-details.d.ts +50 -0
  109. package/dist/event-calendar/event-details.js +124 -0
  110. package/dist/event-calendar/event-details.js.map +1 -0
  111. package/dist/event-calendar/layout.d.ts +48 -0
  112. package/dist/event-calendar/layout.js +55 -0
  113. package/dist/event-calendar/layout.js.map +1 -0
  114. package/dist/file-upload/file-upload.d.ts +70 -0
  115. package/dist/file-upload/file-upload.js +307 -0
  116. package/dist/file-upload/file-upload.js.map +1 -0
  117. package/dist/filters/filters.d.ts +48 -0
  118. package/dist/filters/filters.js +103 -0
  119. package/dist/filters/filters.js.map +1 -0
  120. package/dist/form-field/form-field.d.ts +39 -0
  121. package/dist/form-field/form-field.js +88 -0
  122. package/dist/form-field/form-field.js.map +1 -0
  123. package/dist/hover-card/hover-card.d.ts +15 -0
  124. package/dist/hover-card/hover-card.js +27 -0
  125. package/dist/hover-card/hover-card.js.map +1 -0
  126. package/dist/hover-card/person-hover-card.d.ts +26 -0
  127. package/dist/hover-card/person-hover-card.js +85 -0
  128. package/dist/hover-card/person-hover-card.js.map +1 -0
  129. package/dist/icon/icon-tile.d.ts +20 -0
  130. package/dist/icon/icon-tile.js +55 -0
  131. package/dist/icon/icon-tile.js.map +1 -0
  132. package/dist/icon/icon.d.ts +14 -0
  133. package/dist/icon/icon.js +28 -0
  134. package/dist/icon/icon.js.map +1 -0
  135. package/dist/icon/icons.generated.d.ts +358 -0
  136. package/dist/icon/icons.generated.js +362 -0
  137. package/dist/icon/icons.generated.js.map +1 -0
  138. package/dist/index.d.ts +90 -0
  139. package/dist/index.js +88 -0
  140. package/dist/input/extra-inputs.d.ts +122 -0
  141. package/dist/input/extra-inputs.js +351 -0
  142. package/dist/input/extra-inputs.js.map +1 -0
  143. package/dist/input/field-styles.d.ts +5 -0
  144. package/dist/input/field-styles.js +14 -0
  145. package/dist/input/field-styles.js.map +1 -0
  146. package/dist/input/input.d.ts +50 -0
  147. package/dist/input/input.js +107 -0
  148. package/dist/input/input.js.map +1 -0
  149. package/dist/layout/layout.d.ts +41 -0
  150. package/dist/layout/layout.js +90 -0
  151. package/dist/layout/layout.js.map +1 -0
  152. package/dist/lib/control-styles.d.ts +9 -0
  153. package/dist/lib/control-styles.js +16 -0
  154. package/dist/lib/control-styles.js.map +1 -0
  155. package/dist/lib/cx.d.ts +2 -0
  156. package/dist/lib/cx.js +8 -0
  157. package/dist/lib/cx.js.map +1 -0
  158. package/dist/lib/glyphs.d.ts +13 -0
  159. package/dist/lib/glyphs.js +67 -0
  160. package/dist/lib/glyphs.js.map +1 -0
  161. package/dist/lib/segmented-styles.d.ts +8 -0
  162. package/dist/lib/segmented-styles.js +12 -0
  163. package/dist/lib/segmented-styles.js.map +1 -0
  164. package/dist/lib/select-on-arrow.d.ts +7 -0
  165. package/dist/lib/select-on-arrow.js +21 -0
  166. package/dist/lib/select-on-arrow.js.map +1 -0
  167. package/dist/lib/skip-link.d.ts +5 -0
  168. package/dist/lib/skip-link.js +13 -0
  169. package/dist/lib/skip-link.js.map +1 -0
  170. package/dist/lib/use-media-query.d.ts +4 -0
  171. package/dist/lib/use-media-query.js +15 -0
  172. package/dist/lib/use-media-query.js.map +1 -0
  173. package/dist/lists/lists.d.ts +76 -0
  174. package/dist/lists/lists.js +133 -0
  175. package/dist/lists/lists.js.map +1 -0
  176. package/dist/locale-switch/locale-switch.d.ts +29 -0
  177. package/dist/locale-switch/locale-switch.js +62 -0
  178. package/dist/locale-switch/locale-switch.js.map +1 -0
  179. package/dist/logo/logo.d.ts +31 -0
  180. package/dist/logo/logo.js +157 -0
  181. package/dist/logo/logo.js.map +1 -0
  182. package/dist/logo/product-logo.d.ts +19 -0
  183. package/dist/logo/product-logo.js +46 -0
  184. package/dist/logo/product-logo.js.map +1 -0
  185. package/dist/marketing/marketing.d.ts +176 -0
  186. package/dist/marketing/marketing.js +451 -0
  187. package/dist/marketing/marketing.js.map +1 -0
  188. package/dist/marketing/newsletter-form.d.ts +21 -0
  189. package/dist/marketing/newsletter-form.js +100 -0
  190. package/dist/marketing/newsletter-form.js.map +1 -0
  191. package/dist/mascot/mascot.d.ts +28 -0
  192. package/dist/mascot/mascot.js +28 -0
  193. package/dist/mascot/mascot.js.map +1 -0
  194. package/dist/mascot/mascots.generated.d.ts +284 -0
  195. package/dist/mascot/mascots.generated.js +287 -0
  196. package/dist/mascot/mascots.generated.js.map +1 -0
  197. package/dist/master-detail/master-detail.d.ts +30 -0
  198. package/dist/master-detail/master-detail.js +71 -0
  199. package/dist/master-detail/master-detail.js.map +1 -0
  200. package/dist/menu/account-menu.d.ts +44 -0
  201. package/dist/menu/account-menu.js +78 -0
  202. package/dist/menu/account-menu.js.map +1 -0
  203. package/dist/menu/context-menu.d.ts +31 -0
  204. package/dist/menu/context-menu.js +111 -0
  205. package/dist/menu/context-menu.js.map +1 -0
  206. package/dist/menu/dropdown-menu.d.ts +49 -0
  207. package/dist/menu/dropdown-menu.js +152 -0
  208. package/dist/menu/dropdown-menu.js.map +1 -0
  209. package/dist/menu/menu-styles.d.ts +8 -0
  210. package/dist/menu/menu-styles.js +6 -0
  211. package/dist/menu/menu-styles.js.map +1 -0
  212. package/dist/menu/menubar.d.ts +31 -0
  213. package/dist/menu/menubar.js +125 -0
  214. package/dist/menu/menubar.js.map +1 -0
  215. package/dist/modal/modal.d.ts +34 -0
  216. package/dist/modal/modal.js +58 -0
  217. package/dist/modal/modal.js.map +1 -0
  218. package/dist/notification-center/notification-center.d.ts +51 -0
  219. package/dist/notification-center/notification-center.js +244 -0
  220. package/dist/notification-center/notification-center.js.map +1 -0
  221. package/dist/otp-input/otp-input.d.ts +23 -0
  222. package/dist/otp-input/otp-input.js +61 -0
  223. package/dist/otp-input/otp-input.js.map +1 -0
  224. package/dist/overlay/overlay.d.ts +53 -0
  225. package/dist/overlay/overlay.js +103 -0
  226. package/dist/overlay/overlay.js.map +1 -0
  227. package/dist/page-header/page-header.d.ts +55 -0
  228. package/dist/page-header/page-header.js +114 -0
  229. package/dist/page-header/page-header.js.map +1 -0
  230. package/dist/page-header/record-headers.d.ts +51 -0
  231. package/dist/page-header/record-headers.js +134 -0
  232. package/dist/page-header/record-headers.js.map +1 -0
  233. package/dist/page-header/section-header.d.ts +21 -0
  234. package/dist/page-header/section-header.js +44 -0
  235. package/dist/page-header/section-header.js.map +1 -0
  236. package/dist/page-navigation/page-navigation.d.ts +59 -0
  237. package/dist/page-navigation/page-navigation.js +136 -0
  238. package/dist/page-navigation/page-navigation.js.map +1 -0
  239. package/dist/pagination/pagination.d.ts +28 -0
  240. package/dist/pagination/pagination.js +102 -0
  241. package/dist/pagination/pagination.js.map +1 -0
  242. package/dist/phone-input/phone-input.d.ts +34 -0
  243. package/dist/phone-input/phone-input.js +171 -0
  244. package/dist/phone-input/phone-input.js.map +1 -0
  245. package/dist/popover/popover.d.ts +23 -0
  246. package/dist/popover/popover.js +40 -0
  247. package/dist/popover/popover.js.map +1 -0
  248. package/dist/progress/progress.d.ts +21 -0
  249. package/dist/progress/progress.js +49 -0
  250. package/dist/progress/progress.js.map +1 -0
  251. package/dist/segmented-control/segmented-control.d.ts +32 -0
  252. package/dist/segmented-control/segmented-control.js +29 -0
  253. package/dist/segmented-control/segmented-control.js.map +1 -0
  254. package/dist/select/select.d.ts +48 -0
  255. package/dist/select/select.js +136 -0
  256. package/dist/select/select.js.map +1 -0
  257. package/dist/settings/permission-matrix.d.ts +29 -0
  258. package/dist/settings/permission-matrix.js +101 -0
  259. package/dist/settings/permission-matrix.js.map +1 -0
  260. package/dist/settings/settings-row.d.ts +32 -0
  261. package/dist/settings/settings-row.js +63 -0
  262. package/dist/settings/settings-row.js.map +1 -0
  263. package/dist/side-nav/side-nav.d.ts +36 -0
  264. package/dist/side-nav/side-nav.js +123 -0
  265. package/dist/side-nav/side-nav.js.map +1 -0
  266. package/dist/site-header/site-header.d.ts +32 -0
  267. package/dist/site-header/site-header.js +99 -0
  268. package/dist/site-header/site-header.js.map +1 -0
  269. package/dist/skeleton/skeleton.d.ts +16 -0
  270. package/dist/skeleton/skeleton.js +19 -0
  271. package/dist/skeleton/skeleton.js.map +1 -0
  272. package/dist/slider/slider.d.ts +15 -0
  273. package/dist/slider/slider.js +48 -0
  274. package/dist/slider/slider.js.map +1 -0
  275. package/dist/spinner/spinner.d.ts +15 -0
  276. package/dist/spinner/spinner.js +42 -0
  277. package/dist/spinner/spinner.js.map +1 -0
  278. package/dist/stepper/step-dots.d.ts +16 -0
  279. package/dist/stepper/step-dots.js +26 -0
  280. package/dist/stepper/step-dots.js.map +1 -0
  281. package/dist/stepper/stepper.d.ts +26 -0
  282. package/dist/stepper/stepper.js +113 -0
  283. package/dist/stepper/stepper.js.map +1 -0
  284. package/dist/tabs/tabs.d.ts +31 -0
  285. package/dist/tabs/tabs.js +66 -0
  286. package/dist/tabs/tabs.js.map +1 -0
  287. package/dist/templates/app-templates.d.ts +126 -0
  288. package/dist/templates/app-templates.js +153 -0
  289. package/dist/templates/app-templates.js.map +1 -0
  290. package/dist/templates/site-templates.d.ts +49 -0
  291. package/dist/templates/site-templates.js +110 -0
  292. package/dist/templates/site-templates.js.map +1 -0
  293. package/dist/toast/toast-store.d.ts +54 -0
  294. package/dist/toast/toast-store.js +49 -0
  295. package/dist/toast/toast-store.js.map +1 -0
  296. package/dist/toast/toaster.d.ts +15 -0
  297. package/dist/toast/toaster.js +124 -0
  298. package/dist/toast/toaster.js.map +1 -0
  299. package/dist/tooltip/tooltip.d.ts +29 -0
  300. package/dist/tooltip/tooltip.js +54 -0
  301. package/dist/tooltip/tooltip.js.map +1 -0
  302. package/package.json +88 -3
  303. package/styles.css +521 -0
  304. package/README.md +0 -3
@@ -0,0 +1,227 @@
1
+ import { cx as e } from "../lib/cx.js";
2
+ import { Icon as t } from "../icon/icon.js";
3
+ import { Glyph as n } from "../lib/glyphs.js";
4
+ import { AV_SIZE as r } from "./avatar-sizes.js";
5
+ import { Avatar as i } from "./avatar.js";
6
+ import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
7
+ import { useId as c } from "react";
8
+ //#region src/data-display/data-display.tsx
9
+ var l = {
10
+ primary: "text-primary",
11
+ accent: "text-accent",
12
+ success: "text-success-icon",
13
+ danger: "text-danger-icon"
14
+ };
15
+ function u({ data: t, label: n, height: r = 40, tone: i = "primary", area: u = !0, className: d, ...f }) {
16
+ let p = c();
17
+ if (t.length < 2) return null;
18
+ let m = Math.min(...t), h = Math.max(...t) - m || 1, g = t.map((e, n) => [n / (t.length - 1) * 100, r - 2 - (e - m) / h * (r - 4)]).map(([e, t], n) => `${n ? "L" : "M"}${e.toFixed(2)},${t.toFixed(2)}`).join(" ");
19
+ return /* @__PURE__ */ s("svg", {
20
+ role: "img",
21
+ "aria-label": n,
22
+ viewBox: `0 0 100 ${r}`,
23
+ preserveAspectRatio: "none",
24
+ className: e("block h-10 w-full overflow-visible", l[i], d),
25
+ style: { height: r },
26
+ ...f,
27
+ children: [u && /* @__PURE__ */ s(a, { children: [/* @__PURE__ */ o("defs", { children: /* @__PURE__ */ s("linearGradient", {
28
+ id: p,
29
+ x1: "0",
30
+ x2: "0",
31
+ y1: "0",
32
+ y2: "1",
33
+ children: [/* @__PURE__ */ o("stop", {
34
+ offset: "0",
35
+ stopColor: "currentColor",
36
+ stopOpacity: "0.25"
37
+ }), /* @__PURE__ */ o("stop", {
38
+ offset: "1",
39
+ stopColor: "currentColor",
40
+ stopOpacity: "0"
41
+ })]
42
+ }) }), /* @__PURE__ */ o("path", {
43
+ d: `${g} L100,${r} L0,${r} Z`,
44
+ fill: `url(#${p})`
45
+ })] }), /* @__PURE__ */ o("path", {
46
+ d: g,
47
+ fill: "none",
48
+ stroke: "currentColor",
49
+ strokeWidth: "2",
50
+ strokeLinejoin: "round",
51
+ strokeLinecap: "round",
52
+ vectorEffect: "non-scaling-stroke"
53
+ })]
54
+ });
55
+ }
56
+ function d({ people: t, max: n = 4, size: a = "sm", label: c, className: l, ...u }) {
57
+ let d = t.slice(0, n), f = t.length - d.length;
58
+ return /* @__PURE__ */ s("div", {
59
+ role: "group",
60
+ "aria-label": c ?? t.map((e) => e.name).join(", "),
61
+ className: e("flex items-center -space-x-2", l),
62
+ ...u,
63
+ children: [d.map((e) => /* @__PURE__ */ o(i, {
64
+ ...e,
65
+ size: a,
66
+ className: "ring-2 ring-bg",
67
+ "aria-hidden": "true"
68
+ }, e.name)), f > 0 && /* @__PURE__ */ s("span", {
69
+ "aria-hidden": "true",
70
+ className: e("relative inline-grid place-items-center rounded-full bg-surface-muted font-sans font-bold text-fg-muted ring-2 ring-bg", r[a]),
71
+ children: ["+", f]
72
+ })]
73
+ });
74
+ }
75
+ function f({ icon: n, className: r, children: i, ...a }) {
76
+ return /* @__PURE__ */ s("span", {
77
+ className: e("inline-flex items-center gap-1 rounded-xs bg-surface-muted px-2 py-0.5 font-sans text-xs font-semibold text-fg-muted", r),
78
+ ...a,
79
+ children: [n && /* @__PURE__ */ o(t, {
80
+ name: n,
81
+ size: 14
82
+ }), i]
83
+ });
84
+ }
85
+ var p = {
86
+ default: "bg-surface-muted text-fg-muted",
87
+ success: "bg-success-surface text-success-icon",
88
+ warning: "bg-warning-surface text-warning-icon",
89
+ danger: "bg-danger-surface text-danger-icon",
90
+ info: "bg-info-surface text-info-icon"
91
+ };
92
+ function m({ items: r, className: i }) {
93
+ return /* @__PURE__ */ o("ol", {
94
+ className: e("m-0 grid list-none gap-0 p-0 font-sans", i),
95
+ children: r.map((i, a) => /* @__PURE__ */ s("li", {
96
+ className: "relative grid grid-cols-[auto_1fr] gap-x-4 pb-6 last:pb-0",
97
+ children: [
98
+ a < r.length - 1 && /* @__PURE__ */ o("span", {
99
+ "aria-hidden": "true",
100
+ className: "absolute top-10 bottom-1 left-[17px] w-0.5 rounded-full bg-border"
101
+ }),
102
+ /* @__PURE__ */ o("span", {
103
+ className: e("relative grid size-9 place-items-center rounded-full", p[i.tone ?? "default"]),
104
+ children: i.icon ? /* @__PURE__ */ o(t, {
105
+ name: i.icon,
106
+ size: 20
107
+ }) : /* @__PURE__ */ o(n, {
108
+ name: "dot",
109
+ size: 12
110
+ })
111
+ }),
112
+ /* @__PURE__ */ s("div", {
113
+ className: "min-w-0 pt-1.5",
114
+ children: [
115
+ i.time && /* @__PURE__ */ o("p", {
116
+ className: "m-0 text-xs font-semibold tracking-wide text-fg-muted uppercase",
117
+ children: i.time
118
+ }),
119
+ /* @__PURE__ */ o("p", {
120
+ className: "m-0 text-[15px] font-semibold text-fg",
121
+ children: i.title
122
+ }),
123
+ i.description && /* @__PURE__ */ o("div", {
124
+ className: "mt-0.5 text-sm text-fg-muted",
125
+ children: i.description
126
+ })
127
+ ]
128
+ })
129
+ ]
130
+ }, a))
131
+ });
132
+ }
133
+ function h({ items: t, layout: n = "inline", className: r, ...i }) {
134
+ return /* @__PURE__ */ o("dl", {
135
+ className: e("m-0 font-sans text-sm", n === "inline" && "divide-y divide-border", n === "grid" && "grid gap-x-8 gap-y-5 sm:grid-cols-2 md:grid-cols-3", n === "stacked" && "grid gap-4", r),
136
+ ...i,
137
+ children: t.map((t, r) => /* @__PURE__ */ s("div", {
138
+ className: e(n === "inline" ? "grid gap-1 py-3 sm:grid-cols-[minmax(8rem,1fr)_2fr] sm:gap-4" : "grid gap-1"),
139
+ children: [/* @__PURE__ */ o("dt", {
140
+ className: "font-medium text-fg-muted",
141
+ children: t.term
142
+ }), /* @__PURE__ */ o("dd", {
143
+ className: "m-0 min-w-0 break-words text-fg",
144
+ children: t.description
145
+ })]
146
+ }, r))
147
+ });
148
+ }
149
+ var g = {
150
+ trigger: "border-border bg-surface",
151
+ action: "border-border bg-surface",
152
+ ai: "border-accent bg-accent/10",
153
+ output: "border-primary bg-info-surface"
154
+ };
155
+ function _({ steps: r, label: i, orientation: a = "responsive", className: c }) {
156
+ let l = v[a];
157
+ return /* @__PURE__ */ o("ol", {
158
+ "aria-label": i,
159
+ className: e("m-0 flex list-none gap-0 p-0 font-sans", l.list, c),
160
+ children: r.map((i, a) => /* @__PURE__ */ s("li", {
161
+ className: e("flex", l.item),
162
+ children: [/* @__PURE__ */ s("div", {
163
+ className: e("flex min-w-[10rem] items-center gap-3 rounded-md border-2 px-4 py-3", g[i.kind ?? "action"]),
164
+ children: [i.icon && /* @__PURE__ */ o(t, {
165
+ name: i.icon,
166
+ size: 26,
167
+ className: i.kind === "ai" ? "text-accent" : "text-primary"
168
+ }), /* @__PURE__ */ s("div", {
169
+ className: "min-w-0",
170
+ children: [i.meta && /* @__PURE__ */ o("p", {
171
+ className: "m-0 text-xs font-semibold tracking-wide text-fg-muted uppercase",
172
+ children: i.meta
173
+ }), /* @__PURE__ */ o("p", {
174
+ className: "m-0 text-sm font-semibold text-fg",
175
+ children: i.label
176
+ })]
177
+ })]
178
+ }), a < r.length - 1 && /* @__PURE__ */ s("span", {
179
+ "aria-hidden": "true",
180
+ className: e("flex items-center justify-center text-fg-muted", l.connector),
181
+ children: [
182
+ /* @__PURE__ */ o("span", { className: e("bg-border", l.line) }),
183
+ /* @__PURE__ */ o(n, {
184
+ name: "chevron-down",
185
+ size: 16,
186
+ className: e("-mt-1.5", l.down)
187
+ }),
188
+ /* @__PURE__ */ o(n, {
189
+ name: "chevron-right",
190
+ size: 16,
191
+ className: e("-ml-1.5", l.right)
192
+ })
193
+ ]
194
+ })]
195
+ }, i.id))
196
+ });
197
+ }
198
+ var v = {
199
+ responsive: {
200
+ list: "flex-col items-stretch md:flex-row md:items-center",
201
+ item: "flex-col items-center md:flex-row",
202
+ connector: "flex-col md:flex-row md:px-1",
203
+ line: "h-5 w-0.5 md:h-0.5 md:w-6",
204
+ down: "md:hidden",
205
+ right: "hidden md:block"
206
+ },
207
+ vertical: {
208
+ list: "flex-col items-stretch",
209
+ item: "flex-col items-stretch",
210
+ connector: "flex-col",
211
+ line: "h-5 w-0.5",
212
+ down: "",
213
+ right: "hidden"
214
+ },
215
+ horizontal: {
216
+ list: "flex-row items-center",
217
+ item: "flex-row items-center",
218
+ connector: "px-1",
219
+ line: "h-0.5 w-6",
220
+ down: "hidden",
221
+ right: "block"
222
+ }
223
+ };
224
+ //#endregion
225
+ export { d as AvatarGroup, h as DescriptionList, _ as FlowDiagram, u as Sparkline, f as Tag, m as Timeline };
226
+
227
+ //# sourceMappingURL=data-display.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-display.js","names":["_Fragment","TONE","Sparkline","rest","gradientId","useId","data","min","span","line","i","height","v","x","y","label","cx","tone","className","area","Fragment","AvatarGroup","shown","people","max","extra","p","Avatar","AV_SIZE","size","Tag","icon","Icon","children","DOT","Timeline","items","item","Glyph","DescriptionList","layout","KIND","FlowDiagram","o","FLOW_LAYOUT","orientation","steps","s"],"sources":["../../src/data-display/data-display.tsx"],"sourcesContent":["import { useId, type HTMLAttributes, type ReactNode } from 'react';\nimport { cx } from '../lib/cx';\nimport { Glyph } from '../lib/glyphs';\nimport { Icon, type IconName } from '../icon/icon';\nimport { Avatar, type AvatarProps } from './avatar';\nimport { AV_SIZE } from './avatar-sizes';\n\n/*\n * Server-safe: no state or handlers here, so these render as Server Components in Next.js.\n * Interactive pieces live in their own 'use client' modules (avatar, chip, code-block), exported from\n * the package index — don't re-export them here, or every page using this module would ship them.\n */\n\n/* ---------------- Sparkline ---------------- */\n\nexport interface SparklineProps extends Omit<HTMLAttributes<SVGSVGElement>, 'children'> {\n data: number[];\n /** Accessible summary, e.g. \"Runs per day, last 14 days: rising from 120 to 310\". */\n label: string;\n height?: number;\n tone?: 'primary' | 'accent' | 'success' | 'danger';\n /** Fill the area under the line. */\n area?: boolean;\n}\n\nconst TONE = {\n primary: 'text-primary',\n accent: 'text-accent',\n success: 'text-success-icon',\n danger: 'text-danger-icon',\n};\n\n/** Dependency-free trend line for KPI tiles. For full charts use LineChart, AreaChart, BarChart, DonutChart. */\nexport function Sparkline({\n data,\n label,\n height = 40,\n tone = 'primary',\n area = true,\n className,\n ...rest\n}: SparklineProps) {\n const gradientId = useId();\n if (data.length < 2) return null;\n const w = 100;\n const min = Math.min(...data);\n const max = Math.max(...data);\n const span = max - min || 1;\n const pts = data.map(\n (v, i) => [(i / (data.length - 1)) * w, height - 2 - ((v - min) / span) * (height - 4)] as const,\n );\n const line = pts.map(([x, y], i) => `${i ? 'L' : 'M'}${x.toFixed(2)},${y.toFixed(2)}`).join(' ');\n return (\n <svg\n role=\"img\"\n aria-label={label}\n viewBox={`0 0 ${w} ${height}`}\n preserveAspectRatio=\"none\"\n className={cx('block h-10 w-full overflow-visible', TONE[tone], className)}\n style={{ height }}\n {...rest}\n >\n {area && (\n <>\n <defs>\n <linearGradient id={gradientId} x1=\"0\" x2=\"0\" y1=\"0\" y2=\"1\">\n <stop offset=\"0\" stopColor=\"currentColor\" stopOpacity=\"0.25\" />\n <stop offset=\"1\" stopColor=\"currentColor\" stopOpacity=\"0\" />\n </linearGradient>\n </defs>\n <path d={`${line} L${w},${height} L0,${height} Z`} fill={`url(#${gradientId})`} />\n </>\n )}\n <path\n d={line}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n vectorEffect=\"non-scaling-stroke\"\n />\n </svg>\n );\n}\n\n/* ---------------- AvatarGroup ---------------- */\n\nexport interface AvatarGroupProps extends HTMLAttributes<HTMLDivElement> {\n people: { name: string; src?: string }[];\n max?: number;\n size?: AvatarProps['size'];\n /** Accessible summary, e.g. \"5 members\". Defaults to the names. */\n label?: string;\n}\n\nexport function AvatarGroup({ people, max = 4, size = 'sm', label, className, ...rest }: AvatarGroupProps) {\n const shown = people.slice(0, max);\n const extra = people.length - shown.length;\n return (\n <div\n role=\"group\"\n aria-label={label ?? people.map((p) => p.name).join(', ')}\n className={cx('flex items-center -space-x-2', className)}\n {...rest}\n >\n {shown.map((p) => (\n <Avatar key={p.name} {...p} size={size} className=\"ring-2 ring-bg\" aria-hidden=\"true\" />\n ))}\n {extra > 0 && (\n <span\n aria-hidden=\"true\"\n className={cx(\n 'relative inline-grid place-items-center rounded-full bg-surface-muted font-sans font-bold text-fg-muted ring-2 ring-bg',\n AV_SIZE[size],\n )}\n >\n +{extra}\n </span>\n )}\n </div>\n );\n}\n\n/* ---------------- Tag ---------------- */\n\nexport interface TagProps extends HTMLAttributes<HTMLSpanElement> {\n /** Neutral metadata label (technology, category). For status use `Badge`. */\n children: ReactNode;\n icon?: IconName;\n}\n\nexport function Tag({ icon, className, children, ...rest }: TagProps) {\n return (\n <span\n className={cx(\n 'inline-flex items-center gap-1 rounded-xs bg-surface-muted px-2 py-0.5 font-sans text-xs font-semibold text-fg-muted',\n className,\n )}\n {...rest}\n >\n {icon && <Icon name={icon} size={14} />}\n {children}\n </span>\n );\n}\n\n/* ---------------- Timeline ---------------- */\n\nexport interface TimelineItem {\n title: ReactNode;\n description?: ReactNode;\n /** Label at the start (year, time). */\n time?: ReactNode;\n icon?: IconName;\n tone?: 'default' | 'success' | 'warning' | 'danger' | 'info';\n}\n\nconst DOT = {\n default: 'bg-surface-muted text-fg-muted',\n success: 'bg-success-surface text-success-icon',\n warning: 'bg-warning-surface text-warning-icon',\n danger: 'bg-danger-surface text-danger-icon',\n info: 'bg-info-surface text-info-icon',\n};\n\n/** Vertical sequence of events: company history (years), run logs, activity. */\nexport function Timeline({ items, className }: { items: TimelineItem[]; className?: string }) {\n return (\n <ol className={cx('m-0 grid list-none gap-0 p-0 font-sans', className)}>\n {items.map((item, i) => (\n <li key={i} className=\"relative grid grid-cols-[auto_1fr] gap-x-4 pb-6 last:pb-0\">\n {i < items.length - 1 && (\n <span aria-hidden=\"true\" className=\"absolute top-10 bottom-1 left-[17px] w-0.5 rounded-full bg-border\" />\n )}\n <span className={cx('relative grid size-9 place-items-center rounded-full', DOT[item.tone ?? 'default'])}>\n {item.icon ? <Icon name={item.icon} size={20} /> : <Glyph name=\"dot\" size={12} />}\n </span>\n <div className=\"min-w-0 pt-1.5\">\n {item.time && (\n <p className=\"m-0 text-xs font-semibold tracking-wide text-fg-muted uppercase\">{item.time}</p>\n )}\n <p className=\"m-0 text-[15px] font-semibold text-fg\">{item.title}</p>\n {item.description && <div className=\"mt-0.5 text-sm text-fg-muted\">{item.description}</div>}\n </div>\n </li>\n ))}\n </ol>\n );\n}\n\n/* ---------------- DescriptionList ---------------- */\n\nexport interface DescriptionListProps extends HTMLAttributes<HTMLDListElement> {\n items: { term: ReactNode; description: ReactNode }[];\n /** `stacked` (term above), `inline` (term | value columns from sm), `grid` (2–3 columns of pairs). */\n layout?: 'stacked' | 'inline' | 'grid';\n}\n\n/** Key/value details for record pages (workflow settings, invoice data). */\nexport function DescriptionList({ items, layout = 'inline', className, ...rest }: DescriptionListProps) {\n return (\n <dl\n className={cx(\n 'm-0 font-sans text-sm',\n layout === 'inline' && 'divide-y divide-border',\n layout === 'grid' && 'grid gap-x-8 gap-y-5 sm:grid-cols-2 md:grid-cols-3',\n layout === 'stacked' && 'grid gap-4',\n className,\n )}\n {...rest}\n >\n {items.map((item, i) => (\n <div\n key={i}\n className={cx(\n layout === 'inline' ? 'grid gap-1 py-3 sm:grid-cols-[minmax(8rem,1fr)_2fr] sm:gap-4' : 'grid gap-1',\n )}\n >\n <dt className=\"font-medium text-fg-muted\">{item.term}</dt>\n <dd className=\"m-0 min-w-0 break-words text-fg\">{item.description}</dd>\n </div>\n ))}\n </dl>\n );\n}\n\n/* ---------------- FlowDiagram ---------------- */\n\nexport interface FlowStep {\n id: string;\n label: ReactNode;\n /** App or system (\"Gmail\", \"AI\", \"QuickBooks\"). */\n meta?: ReactNode;\n icon?: IconName;\n kind?: 'trigger' | 'action' | 'ai' | 'output';\n}\n\nconst KIND = {\n trigger: 'border-border bg-surface',\n action: 'border-border bg-surface',\n ai: 'border-accent bg-accent/10',\n output: 'border-primary bg-info-surface',\n};\n\n/**\n * Static automation flow for case studies and the Blueprint tool. `responsive` (default): left to\n * right from 960px, top to bottom below. Use `vertical` in narrow containers. The interactive\n * editor (React Flow) needs its own ADR.\n */\nexport function FlowDiagram({\n steps,\n label,\n orientation = 'responsive',\n className,\n}: {\n steps: FlowStep[];\n label: string;\n orientation?: 'responsive' | 'vertical' | 'horizontal';\n className?: string;\n}) {\n const o = FLOW_LAYOUT[orientation];\n return (\n <ol aria-label={label} className={cx('m-0 flex list-none gap-0 p-0 font-sans', o.list, className)}>\n {steps.map((s, i) => (\n <li key={s.id} className={cx('flex', o.item)}>\n <div\n className={cx(\n 'flex min-w-[10rem] items-center gap-3 rounded-md border-2 px-4 py-3',\n KIND[s.kind ?? 'action'],\n )}\n >\n {s.icon && <Icon name={s.icon} size={26} className={s.kind === 'ai' ? 'text-accent' : 'text-primary'} />}\n <div className=\"min-w-0\">\n {s.meta && <p className=\"m-0 text-xs font-semibold tracking-wide text-fg-muted uppercase\">{s.meta}</p>}\n <p className=\"m-0 text-sm font-semibold text-fg\">{s.label}</p>\n </div>\n </div>\n {i < steps.length - 1 && (\n <span aria-hidden=\"true\" className={cx('flex items-center justify-center text-fg-muted', o.connector)}>\n <span className={cx('bg-border', o.line)} />\n <Glyph name=\"chevron-down\" size={16} className={cx('-mt-1.5', o.down)} />\n <Glyph name=\"chevron-right\" size={16} className={cx('-ml-1.5', o.right)} />\n </span>\n )}\n </li>\n ))}\n </ol>\n );\n}\n\n/* Literal class names per orientation so Tailwind can find them. */\nconst FLOW_LAYOUT = {\n responsive: {\n list: 'flex-col items-stretch md:flex-row md:items-center',\n item: 'flex-col items-center md:flex-row',\n connector: 'flex-col md:flex-row md:px-1',\n line: 'h-5 w-0.5 md:h-0.5 md:w-6',\n down: 'md:hidden',\n right: 'hidden md:block',\n },\n vertical: {\n list: 'flex-col items-stretch',\n item: 'flex-col items-stretch',\n connector: 'flex-col',\n line: 'h-5 w-0.5',\n down: '',\n right: 'hidden',\n },\n horizontal: {\n list: 'flex-row items-center',\n item: 'flex-row items-center',\n connector: 'px-1',\n line: 'h-0.5 w-6',\n down: 'hidden',\n right: 'block',\n },\n};\n"],"mappings":"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"}
@@ -0,0 +1,120 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type IconName } from '../icon/icon';
3
+ export interface LegendItem {
4
+ label: string;
5
+ /** Any CSS color, usually `var(--kf-category-N)`. */
6
+ color: string;
7
+ }
8
+ /** A row of colored dots with labels that explains a status or category palette (tables, calendars, charts). */
9
+ export declare function StatusLegend({ items, label, className, }: {
10
+ items: LegendItem[];
11
+ label?: string;
12
+ className?: string;
13
+ }): import("react").JSX.Element;
14
+ export interface ChipListItem {
15
+ label: string;
16
+ count?: number;
17
+ }
18
+ export interface ChipListProps {
19
+ items: ChipListItem[];
20
+ /** Chips shown before "+N". */
21
+ max?: number;
22
+ labels?: {
23
+ more?: (n: number) => string;
24
+ less?: string;
25
+ };
26
+ className?: string;
27
+ }
28
+ /** Read-only chips with counts that collapse into "+N" after a limit (tags in tables, AI insight topics). */
29
+ export declare function ChipList({ items, max, labels, className }: ChipListProps): import("react").JSX.Element;
30
+ /** Holds the page-level "Show amounts" state for every `SensitiveValue` inside it. Hidden by default. */
31
+ export declare function SensitiveProvider({ children, defaultRevealed, }: {
32
+ children: ReactNode;
33
+ defaultRevealed?: boolean;
34
+ }): import("react").JSX.Element;
35
+ /** The "Show amounts / Hide amounts" toggle for a `SensitiveProvider`. */
36
+ export declare function SensitiveToggle({ labels, className, }: {
37
+ labels?: {
38
+ show?: string;
39
+ hide?: string;
40
+ };
41
+ className?: string;
42
+ }): import("react").JSX.Element | null;
43
+ export interface SensitiveValueProps {
44
+ /**
45
+ * Rendered only when revealed, so it is not in the visible page or the accessibility tree while hidden. It is a
46
+ * visual mask, not access control: the value is still sent to the browser. Data a viewer may not see must not be
47
+ * sent at all (check permissions on the server).
48
+ */
49
+ children: ReactNode;
50
+ /** Width of the mask in characters, so layouts do not jump when revealing (default 6). */
51
+ chars?: number;
52
+ /** Accessible text while hidden. */
53
+ hiddenLabel?: string;
54
+ /** Without a provider: controlled visibility. */
55
+ revealed?: boolean;
56
+ className?: string;
57
+ }
58
+ /** A masked value ("••••") that a page-level toggle reveals (salaries, revenue, balances). */
59
+ export declare function SensitiveValue({ children, chars, hiddenLabel, revealed: revealedProp, className, }: SensitiveValueProps): import("react").JSX.Element;
60
+ export interface ActivityPerson {
61
+ name: string;
62
+ src?: string;
63
+ }
64
+ export interface ActivityItem {
65
+ id: string;
66
+ from: ActivityPerson;
67
+ /** The receiver ("A → B"); omit for one-person events. */
68
+ to?: ActivityPerson;
69
+ /** What happened or why ("for helping with the March close"). */
70
+ text?: ReactNode;
71
+ /** Relative time to show ("2 h ago") and the exact time for `<time>`. */
72
+ time: string;
73
+ dateTime?: string;
74
+ /** Where it came from (Slack, the web app…). */
75
+ source?: {
76
+ icon: IconName;
77
+ label: string;
78
+ };
79
+ }
80
+ /** A list of events: "A → B", a reason and a relative time with its source (kudos, audit log, notifications). */
81
+ export declare function ActivityFeed({ items, columns, className, 'aria-label': label, }: {
82
+ items: ActivityItem[];
83
+ columns?: 1 | 2;
84
+ className?: string;
85
+ 'aria-label'?: string;
86
+ }): import("react").JSX.Element;
87
+ export interface RankedItem {
88
+ id: string;
89
+ name: string;
90
+ src?: string;
91
+ value: number;
92
+ /** Formatted value ("13 kudos"); defaults to the number. */
93
+ display?: string;
94
+ }
95
+ /** A leaderboard: rank, avatar, name, an inline bar and the value (top receivers, top plans). */
96
+ export declare function RankedList({ items, color, className, 'aria-label': label, }: {
97
+ items: RankedItem[];
98
+ color?: string;
99
+ className?: string;
100
+ 'aria-label'?: string;
101
+ }): import("react").JSX.Element;
102
+ export interface BarSeries {
103
+ key: string;
104
+ label: string;
105
+ color: string;
106
+ }
107
+ export interface SegmentedBarRow {
108
+ label: string;
109
+ values: Record<string, number>;
110
+ }
111
+ /**
112
+ * One bar per row split into colored segments, with one legend (usage by type, evidence by month, budget split).
113
+ * Each row also states its values as text for screen readers.
114
+ */
115
+ export declare function SegmentedBar({ series, rows, format, className, }: {
116
+ series: BarSeries[];
117
+ rows: SegmentedBarRow[];
118
+ format?: (n: number) => string;
119
+ className?: string;
120
+ }): import("react").JSX.Element;
@@ -0,0 +1,220 @@
1
+ "use client";
2
+ import { cx as e } from "../lib/cx.js";
3
+ import { Icon as t } from "../icon/icon.js";
4
+ import { Avatar as n } from "./avatar.js";
5
+ import { Fragment as r, jsx as i, jsxs as a } from "react/jsx-runtime";
6
+ import { createContext as o, useContext as s, useState as c } from "react";
7
+ //#region src/data-display/insights.tsx
8
+ function l({ items: t, label: n = "Legend", className: r }) {
9
+ return /* @__PURE__ */ i("ul", {
10
+ "aria-label": n,
11
+ className: e("m-0 flex list-none flex-wrap gap-x-4 gap-y-1.5 p-0 font-sans text-sm text-fg-muted", r),
12
+ children: t.map((e) => /* @__PURE__ */ a("li", {
13
+ className: "inline-flex items-center gap-1.5",
14
+ children: [/* @__PURE__ */ i("span", {
15
+ "aria-hidden": "true",
16
+ className: "size-2.5 rounded-full",
17
+ style: { background: e.color }
18
+ }), e.label]
19
+ }, e.label))
20
+ });
21
+ }
22
+ function u({ items: t, max: n = 3, labels: r = {}, className: o }) {
23
+ let [s, l] = c(!1), u = s ? t : t.slice(0, n), d = t.length - u.length, f = "inline-flex items-center gap-1 rounded-full bg-surface-muted px-2.5 py-0.5 text-xs font-semibold text-fg";
24
+ return /* @__PURE__ */ a("ul", {
25
+ className: e("m-0 flex list-none flex-wrap gap-1.5 p-0 font-sans", o),
26
+ children: [u.map((e) => /* @__PURE__ */ a("li", {
27
+ className: f,
28
+ children: [e.label, e.count !== void 0 && /* @__PURE__ */ i("span", {
29
+ className: "text-fg-muted tabular-nums",
30
+ children: e.count
31
+ })]
32
+ }, e.label)), (d > 0 || s && t.length > n) && /* @__PURE__ */ i("li", { children: /* @__PURE__ */ i("button", {
33
+ type: "button",
34
+ "aria-expanded": s,
35
+ onClick: () => l((e) => !e),
36
+ className: e(f, "cursor-pointer border-0 text-link hover:bg-info-surface focus-visible:outline-3 focus-visible:outline-offset-1 focus-visible:outline-focus"),
37
+ children: s ? r.less ?? "Show less" : r.more?.(d) ?? `+${d}`
38
+ }) })]
39
+ });
40
+ }
41
+ var d = o(null);
42
+ function f({ children: e, defaultRevealed: t = !1 }) {
43
+ let [n, r] = c(t);
44
+ return /* @__PURE__ */ i(d.Provider, {
45
+ value: {
46
+ revealed: n,
47
+ setRevealed: r
48
+ },
49
+ children: e
50
+ });
51
+ }
52
+ function p({ labels: n = {}, className: r }) {
53
+ let o = s(d);
54
+ return o ? /* @__PURE__ */ a("button", {
55
+ type: "button",
56
+ "aria-pressed": o.revealed,
57
+ onClick: () => o.setRevealed(!o.revealed),
58
+ className: e("inline-flex min-h-9 cursor-pointer items-center gap-1.5 rounded-full border border-border bg-surface px-3 font-sans text-sm font-semibold text-fg hover:bg-surface-muted", "focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-focus pointer-coarse:min-h-11", r),
59
+ children: [/* @__PURE__ */ i(t, {
60
+ name: o.revealed ? "eye-off" : "eye",
61
+ size: 16
62
+ }), o.revealed ? n.hide ?? "Hide amounts" : n.show ?? "Show amounts"]
63
+ }) : null;
64
+ }
65
+ function m({ children: t, chars: n = 6, hiddenLabel: r = "Hidden", revealed: a, className: o }) {
66
+ let c = s(d), l = a ?? c?.revealed ?? !1;
67
+ return /* @__PURE__ */ i("span", {
68
+ className: e("inline-block tabular-nums", o),
69
+ style: { minWidth: `${n}ch` },
70
+ children: l ? t : /* @__PURE__ */ i("span", {
71
+ role: "img",
72
+ "aria-label": r,
73
+ className: "tracking-widest text-fg-muted",
74
+ children: "•".repeat(Math.max(3, Math.min(n, 8)))
75
+ })
76
+ });
77
+ }
78
+ function h({ items: o, columns: s = 1, className: c, "aria-label": l }) {
79
+ return /* @__PURE__ */ i("ol", {
80
+ "aria-label": l,
81
+ className: e("m-0 grid list-none gap-3 p-0 font-sans", s === 2 && "md:grid-cols-2", c),
82
+ children: o.map((e) => /* @__PURE__ */ a("li", {
83
+ className: "flex gap-3 rounded-md border border-border bg-surface p-3",
84
+ children: [/* @__PURE__ */ i(n, {
85
+ name: e.from.name,
86
+ src: e.from.src,
87
+ size: "sm",
88
+ decorative: !0
89
+ }), /* @__PURE__ */ a("div", {
90
+ className: "grid min-w-0 flex-1 gap-1 text-sm",
91
+ children: [
92
+ /* @__PURE__ */ a("p", {
93
+ className: "m-0 flex flex-wrap items-center gap-1.5 font-semibold text-fg",
94
+ children: [e.from.name, e.to && /* @__PURE__ */ a(r, { children: [
95
+ /* @__PURE__ */ i(t, {
96
+ name: "arrow-right",
97
+ size: 14,
98
+ className: "text-fg-muted"
99
+ }),
100
+ /* @__PURE__ */ i("span", {
101
+ className: "sr-only",
102
+ children: "to"
103
+ }),
104
+ e.to.name
105
+ ] })]
106
+ }),
107
+ e.text && /* @__PURE__ */ i("p", {
108
+ className: "m-0 text-fg-muted",
109
+ children: e.text
110
+ }),
111
+ /* @__PURE__ */ a("p", {
112
+ className: "m-0 flex items-center gap-1.5 text-xs text-fg-muted",
113
+ children: [/* @__PURE__ */ i("time", {
114
+ dateTime: e.dateTime,
115
+ children: e.time
116
+ }), e.source && /* @__PURE__ */ a(r, { children: [
117
+ /* @__PURE__ */ i("span", {
118
+ "aria-hidden": "true",
119
+ children: "·"
120
+ }),
121
+ /* @__PURE__ */ i(t, {
122
+ name: e.source.icon,
123
+ size: 14
124
+ }),
125
+ e.source.label
126
+ ] })]
127
+ })
128
+ ]
129
+ })]
130
+ }, e.id))
131
+ });
132
+ }
133
+ function g({ items: t, color: r = "var(--kf-primary)", className: o, "aria-label": s }) {
134
+ let c = Math.max(1, ...t.map((e) => e.value));
135
+ return /* @__PURE__ */ i("ol", {
136
+ "aria-label": s,
137
+ className: e("m-0 grid list-none gap-2.5 p-0 font-sans text-sm", o),
138
+ children: t.map((t, o) => /* @__PURE__ */ a("li", {
139
+ className: "grid grid-cols-[1.5rem_auto_minmax(0,1fr)_auto] items-center gap-3",
140
+ children: [
141
+ /* @__PURE__ */ i("span", {
142
+ className: e("text-right font-bold tabular-nums", o < 3 ? "text-fg" : "text-fg-muted"),
143
+ children: o + 1
144
+ }),
145
+ /* @__PURE__ */ i(n, {
146
+ name: t.name,
147
+ src: t.src,
148
+ size: "xs",
149
+ decorative: !0
150
+ }),
151
+ /* @__PURE__ */ a("span", {
152
+ className: "grid min-w-0 gap-1",
153
+ children: [/* @__PURE__ */ i("span", {
154
+ className: "truncate font-medium text-fg",
155
+ children: t.name
156
+ }), /* @__PURE__ */ i("span", {
157
+ "aria-hidden": "true",
158
+ className: "h-1.5 rounded-full bg-surface-muted",
159
+ children: /* @__PURE__ */ i("span", {
160
+ className: "block h-full rounded-full",
161
+ style: {
162
+ width: `${t.value / c * 100}%`,
163
+ background: r
164
+ }
165
+ })
166
+ })]
167
+ }),
168
+ /* @__PURE__ */ i("span", {
169
+ className: "font-semibold text-fg tabular-nums",
170
+ children: t.display ?? t.value
171
+ })
172
+ ]
173
+ }, t.id))
174
+ });
175
+ }
176
+ function _({ series: t, rows: n, format: r = String, className: o }) {
177
+ return /* @__PURE__ */ a("div", {
178
+ className: e("grid gap-4 font-sans text-sm", o),
179
+ children: [/* @__PURE__ */ i(l, { items: t.map((e) => ({
180
+ label: e.label,
181
+ color: e.color
182
+ })) }), /* @__PURE__ */ i("ul", {
183
+ className: "m-0 grid list-none gap-3 p-0",
184
+ children: n.map((e) => {
185
+ let n = t.reduce((t, n) => t + (e.values[n.key] ?? 0), 0);
186
+ return /* @__PURE__ */ a("li", {
187
+ className: "grid gap-1.5",
188
+ children: [
189
+ /* @__PURE__ */ a("div", {
190
+ className: "flex items-baseline justify-between gap-3",
191
+ children: [/* @__PURE__ */ i("span", {
192
+ className: "font-medium text-fg",
193
+ children: e.label
194
+ }), /* @__PURE__ */ i("span", {
195
+ className: "text-fg-muted tabular-nums",
196
+ children: r(n)
197
+ })]
198
+ }),
199
+ /* @__PURE__ */ i("div", {
200
+ "aria-hidden": "true",
201
+ className: "flex h-2.5 gap-0.5 overflow-hidden rounded-full bg-surface-muted",
202
+ children: t.map((t) => e.values[t.key] ? /* @__PURE__ */ i("span", { style: {
203
+ width: `${(e.values[t.key] ?? 0) / Math.max(n, 1) * 100}%`,
204
+ background: t.color
205
+ } }, t.key) : null)
206
+ }),
207
+ /* @__PURE__ */ i("span", {
208
+ className: "sr-only",
209
+ children: t.map((t) => `${t.label}: ${r(e.values[t.key] ?? 0)}`).join(", ")
210
+ })
211
+ ]
212
+ }, e.label);
213
+ })
214
+ })]
215
+ });
216
+ }
217
+ //#endregion
218
+ export { h as ActivityFeed, u as ChipList, g as RankedList, _ as SegmentedBar, f as SensitiveProvider, p as SensitiveToggle, m as SensitiveValue, l as StatusLegend };
219
+
220
+ //# sourceMappingURL=insights.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"insights.js","names":["_Fragment","StatusLegend","label","cx","className","items","i","ChipList","open","setOpen","useState","shown","max","hidden","chip","o","labels","SensitiveContext","createContext","SensitiveProvider","revealed","setRevealed","defaultRevealed","SensitiveToggle","ctx","useContext","Icon","SensitiveValue","revealedProp","chars","children","hiddenLabel","ActivityFeed","columns","Avatar","a","Fragment","RankedList","n","color","SegmentedBar","series","s","rows","total","r","format"],"sources":["../../src/data-display/insights.tsx"],"sourcesContent":["'use client';\n\nimport { createContext, useContext, useState, type ReactNode } from 'react';\nimport { cx } from '../lib/cx';\nimport { Icon, type IconName } from '../icon/icon';\nimport { Avatar } from './avatar';\n\n/* ---------------- StatusLegend ---------------- */\n\nexport interface LegendItem {\n label: string;\n /** Any CSS color, usually `var(--kf-category-N)`. */\n color: string;\n}\n\n/** A row of colored dots with labels that explains a status or category palette (tables, calendars, charts). */\nexport function StatusLegend({\n items,\n label = 'Legend',\n className,\n}: {\n items: LegendItem[];\n label?: string;\n className?: string;\n}) {\n return (\n <ul\n aria-label={label}\n className={cx('m-0 flex list-none flex-wrap gap-x-4 gap-y-1.5 p-0 font-sans text-sm text-fg-muted', className)}\n >\n {items.map((i) => (\n <li key={i.label} className=\"inline-flex items-center gap-1.5\">\n <span aria-hidden=\"true\" className=\"size-2.5 rounded-full\" style={{ background: i.color }} />\n {i.label}\n </li>\n ))}\n </ul>\n );\n}\n\n/* ---------------- ChipList ---------------- */\n\nexport interface ChipListItem {\n label: string;\n count?: number;\n}\n\nexport interface ChipListProps {\n items: ChipListItem[];\n /** Chips shown before \"+N\". */\n max?: number;\n labels?: { more?: (n: number) => string; less?: string };\n className?: string;\n}\n\n/** Read-only chips with counts that collapse into \"+N\" after a limit (tags in tables, AI insight topics). */\nexport function ChipList({ items, max = 3, labels = {}, className }: ChipListProps) {\n const [open, setOpen] = useState(false);\n const shown = open ? items : items.slice(0, max);\n const hidden = items.length - shown.length;\n const chip =\n 'inline-flex items-center gap-1 rounded-full bg-surface-muted px-2.5 py-0.5 text-xs font-semibold text-fg';\n return (\n <ul className={cx('m-0 flex list-none flex-wrap gap-1.5 p-0 font-sans', className)}>\n {shown.map((i) => (\n <li key={i.label} className={chip}>\n {i.label}\n {i.count !== undefined && <span className=\"text-fg-muted tabular-nums\">{i.count}</span>}\n </li>\n ))}\n {(hidden > 0 || (open && items.length > max)) && (\n <li>\n <button\n type=\"button\"\n aria-expanded={open}\n onClick={() => setOpen((o) => !o)}\n className={cx(\n chip,\n 'cursor-pointer border-0 text-link hover:bg-info-surface focus-visible:outline-3 focus-visible:outline-offset-1 focus-visible:outline-focus',\n )}\n >\n {open ? (labels.less ?? 'Show less') : (labels.more?.(hidden) ?? `+${hidden}`)}\n </button>\n </li>\n )}\n </ul>\n );\n}\n\n/* ---------------- SensitiveValue ---------------- */\n\nconst SensitiveContext = createContext<{ revealed: boolean; setRevealed: (v: boolean) => void } | null>(null);\n\n/** Holds the page-level \"Show amounts\" state for every `SensitiveValue` inside it. Hidden by default. */\nexport function SensitiveProvider({\n children,\n defaultRevealed = false,\n}: {\n children: ReactNode;\n defaultRevealed?: boolean;\n}) {\n const [revealed, setRevealed] = useState(defaultRevealed);\n return <SensitiveContext.Provider value={{ revealed, setRevealed }}>{children}</SensitiveContext.Provider>;\n}\n\n/** The \"Show amounts / Hide amounts\" toggle for a `SensitiveProvider`. */\nexport function SensitiveToggle({\n labels = {},\n className,\n}: {\n labels?: { show?: string; hide?: string };\n className?: string;\n}) {\n const ctx = useContext(SensitiveContext);\n if (!ctx) return null;\n return (\n <button\n type=\"button\"\n aria-pressed={ctx.revealed}\n onClick={() => ctx.setRevealed(!ctx.revealed)}\n className={cx(\n 'inline-flex min-h-9 cursor-pointer items-center gap-1.5 rounded-full border border-border bg-surface px-3 font-sans text-sm font-semibold text-fg hover:bg-surface-muted',\n 'focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-focus pointer-coarse:min-h-11',\n className,\n )}\n >\n <Icon name={ctx.revealed ? 'eye-off' : 'eye'} size={16} />\n {ctx.revealed ? (labels.hide ?? 'Hide amounts') : (labels.show ?? 'Show amounts')}\n </button>\n );\n}\n\nexport interface SensitiveValueProps {\n /**\n * Rendered only when revealed, so it is not in the visible page or the accessibility tree while hidden. It is a\n * visual mask, not access control: the value is still sent to the browser. Data a viewer may not see must not be\n * sent at all (check permissions on the server).\n */\n children: ReactNode;\n /** Width of the mask in characters, so layouts do not jump when revealing (default 6). */\n chars?: number;\n /** Accessible text while hidden. */\n hiddenLabel?: string;\n /** Without a provider: controlled visibility. */\n revealed?: boolean;\n className?: string;\n}\n\n/** A masked value (\"••••\") that a page-level toggle reveals (salaries, revenue, balances). */\nexport function SensitiveValue({\n children,\n chars = 6,\n hiddenLabel = 'Hidden',\n revealed: revealedProp,\n className,\n}: SensitiveValueProps) {\n const ctx = useContext(SensitiveContext);\n const revealed = revealedProp ?? ctx?.revealed ?? false;\n return (\n <span className={cx('inline-block tabular-nums', className)} style={{ minWidth: `${chars}ch` }}>\n {revealed ? (\n children\n ) : (\n <span role=\"img\" aria-label={hiddenLabel} className=\"tracking-widest text-fg-muted\">\n {'•'.repeat(Math.max(3, Math.min(chars, 8)))}\n </span>\n )}\n </span>\n );\n}\n\n/* ---------------- ActivityFeed ---------------- */\n\nexport interface ActivityPerson {\n name: string;\n src?: string;\n}\n\nexport interface ActivityItem {\n id: string;\n from: ActivityPerson;\n /** The receiver (\"A → B\"); omit for one-person events. */\n to?: ActivityPerson;\n /** What happened or why (\"for helping with the March close\"). */\n text?: ReactNode;\n /** Relative time to show (\"2 h ago\") and the exact time for `<time>`. */\n time: string;\n dateTime?: string;\n /** Where it came from (Slack, the web app…). */\n source?: { icon: IconName; label: string };\n}\n\n/** A list of events: \"A → B\", a reason and a relative time with its source (kudos, audit log, notifications). */\nexport function ActivityFeed({\n items,\n columns = 1,\n className,\n 'aria-label': label,\n}: {\n items: ActivityItem[];\n columns?: 1 | 2;\n className?: string;\n 'aria-label'?: string;\n}) {\n return (\n <ol\n aria-label={label}\n className={cx('m-0 grid list-none gap-3 p-0 font-sans', columns === 2 && 'md:grid-cols-2', className)}\n >\n {items.map((a) => (\n <li key={a.id} className=\"flex gap-3 rounded-md border border-border bg-surface p-3\">\n <Avatar name={a.from.name} src={a.from.src} size=\"sm\" decorative />\n <div className=\"grid min-w-0 flex-1 gap-1 text-sm\">\n <p className=\"m-0 flex flex-wrap items-center gap-1.5 font-semibold text-fg\">\n {a.from.name}\n {a.to && (\n <>\n <Icon name=\"arrow-right\" size={14} className=\"text-fg-muted\" />\n <span className=\"sr-only\">to</span>\n {a.to.name}\n </>\n )}\n </p>\n {a.text && <p className=\"m-0 text-fg-muted\">{a.text}</p>}\n <p className=\"m-0 flex items-center gap-1.5 text-xs text-fg-muted\">\n <time dateTime={a.dateTime}>{a.time}</time>\n {a.source && (\n <>\n <span aria-hidden=\"true\">·</span>\n <Icon name={a.source.icon} size={14} />\n {a.source.label}\n </>\n )}\n </p>\n </div>\n </li>\n ))}\n </ol>\n );\n}\n\n/* ---------------- RankedList ---------------- */\n\nexport interface RankedItem {\n id: string;\n name: string;\n src?: string;\n value: number;\n /** Formatted value (\"13 kudos\"); defaults to the number. */\n display?: string;\n}\n\n/** A leaderboard: rank, avatar, name, an inline bar and the value (top receivers, top plans). */\nexport function RankedList({\n items,\n color = 'var(--kf-primary)',\n className,\n 'aria-label': label,\n}: {\n items: RankedItem[];\n color?: string;\n className?: string;\n 'aria-label'?: string;\n}) {\n const max = Math.max(1, ...items.map((i) => i.value));\n return (\n <ol aria-label={label} className={cx('m-0 grid list-none gap-2.5 p-0 font-sans text-sm', className)}>\n {items.map((i, n) => (\n <li key={i.id} className=\"grid grid-cols-[1.5rem_auto_minmax(0,1fr)_auto] items-center gap-3\">\n <span className={cx('text-right font-bold tabular-nums', n < 3 ? 'text-fg' : 'text-fg-muted')}>{n + 1}</span>\n <Avatar name={i.name} src={i.src} size=\"xs\" decorative />\n <span className=\"grid min-w-0 gap-1\">\n <span className=\"truncate font-medium text-fg\">{i.name}</span>\n <span aria-hidden=\"true\" className=\"h-1.5 rounded-full bg-surface-muted\">\n <span\n className=\"block h-full rounded-full\"\n style={{ width: `${(i.value / max) * 100}%`, background: color }}\n />\n </span>\n </span>\n <span className=\"font-semibold text-fg tabular-nums\">{i.display ?? i.value}</span>\n </li>\n ))}\n </ol>\n );\n}\n\n/* ---------------- SegmentedBar ---------------- */\n\nexport interface BarSeries {\n key: string;\n label: string;\n color: string;\n}\n\nexport interface SegmentedBarRow {\n label: string;\n values: Record<string, number>;\n}\n\n/**\n * One bar per row split into colored segments, with one legend (usage by type, evidence by month, budget split).\n * Each row also states its values as text for screen readers.\n */\nexport function SegmentedBar({\n series,\n rows,\n format = String,\n className,\n}: {\n series: BarSeries[];\n rows: SegmentedBarRow[];\n format?: (n: number) => string;\n className?: string;\n}) {\n return (\n <div className={cx('grid gap-4 font-sans text-sm', className)}>\n <StatusLegend items={series.map((s) => ({ label: s.label, color: s.color }))} />\n <ul className=\"m-0 grid list-none gap-3 p-0\">\n {rows.map((r) => {\n const total = series.reduce((t, s) => t + (r.values[s.key] ?? 0), 0);\n return (\n <li key={r.label} className=\"grid gap-1.5\">\n <div className=\"flex items-baseline justify-between gap-3\">\n <span className=\"font-medium text-fg\">{r.label}</span>\n <span className=\"text-fg-muted tabular-nums\">{format(total)}</span>\n </div>\n <div aria-hidden=\"true\" className=\"flex h-2.5 gap-0.5 overflow-hidden rounded-full bg-surface-muted\">\n {series.map((s) =>\n r.values[s.key] ? (\n <span\n key={s.key}\n style={{ width: `${((r.values[s.key] ?? 0) / Math.max(total, 1)) * 100}%`, background: s.color }}\n />\n ) : null,\n )}\n </div>\n <span className=\"sr-only\">\n {series.map((s) => `${s.label}: ${format(r.values[s.key] ?? 0)}`).join(', ')}\n </span>\n </li>\n );\n })}\n </ul>\n </div>\n );\n}\n"],"mappings":"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"}