@vaam-apps/ui 0.1.0 → 0.1.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 (283) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/components/data/code.d.ts +0 -1
  3. package/dist/components/data/code.js +0 -1
  4. package/dist/components/data/copy-button.d.ts +0 -1
  5. package/dist/components/data/copy-button.js +0 -1
  6. package/dist/components/data/detail-row.d.ts +0 -1
  7. package/dist/components/data/detail-row.js +0 -1
  8. package/dist/components/data/id-display.d.ts +0 -1
  9. package/dist/components/data/id-display.js +0 -1
  10. package/dist/components/data/masked-value.d.ts +0 -1
  11. package/dist/components/data/masked-value.js +0 -1
  12. package/dist/components/data/money.d.ts +0 -1
  13. package/dist/components/data/money.js +0 -1
  14. package/dist/components/data/phone-display.d.ts +0 -1
  15. package/dist/components/data/phone-display.js +0 -1
  16. package/dist/components/data/stat-tile.d.ts +0 -1
  17. package/dist/components/data/stat-tile.js +0 -1
  18. package/dist/components/data/timestamp-display.d.ts +0 -1
  19. package/dist/components/data/timestamp-display.js +0 -1
  20. package/dist/components/patterns/inline-banner.d.ts +0 -1
  21. package/dist/components/patterns/inline-banner.js +0 -1
  22. package/dist/components/patterns/inline-empty-state.d.ts +0 -1
  23. package/dist/components/patterns/inline-empty-state.js +0 -1
  24. package/dist/components/patterns/live-row.d.ts +0 -1
  25. package/dist/components/patterns/live-row.js +0 -1
  26. package/dist/components/patterns/payload-inspector.d.ts +0 -1
  27. package/dist/components/patterns/payload-inspector.js +0 -1
  28. package/dist/components/patterns/route-skeleton.d.ts +0 -1
  29. package/dist/components/patterns/route-skeleton.js +0 -1
  30. package/dist/components/patterns/screen-layout.d.ts +0 -1
  31. package/dist/components/patterns/screen-layout.js +0 -1
  32. package/dist/components/patterns/stale-write-banner.d.ts +0 -1
  33. package/dist/components/patterns/stale-write-banner.js +0 -1
  34. package/dist/components/patterns/state-timeline.d.ts +0 -1
  35. package/dist/components/patterns/state-timeline.js +0 -1
  36. package/dist/components/primitives/badge.d.ts +0 -1
  37. package/dist/components/primitives/badge.js +0 -1
  38. package/dist/components/primitives/button.d.ts +0 -1
  39. package/dist/components/primitives/button.js +0 -1
  40. package/dist/components/primitives/calendar.d.ts +0 -1
  41. package/dist/components/primitives/calendar.js +0 -1
  42. package/dist/components/primitives/card.d.ts +0 -1
  43. package/dist/components/primitives/card.js +0 -1
  44. package/dist/components/primitives/checkbox.d.ts +0 -1
  45. package/dist/components/primitives/checkbox.js +0 -1
  46. package/dist/components/primitives/chip-select.d.ts +0 -1
  47. package/dist/components/primitives/chip-select.js +0 -1
  48. package/dist/components/primitives/command-menu.d.ts +0 -1
  49. package/dist/components/primitives/command-menu.js +0 -1
  50. package/dist/components/primitives/confirm-dialog.d.ts +0 -1
  51. package/dist/components/primitives/confirm-dialog.js +0 -1
  52. package/dist/components/primitives/date-picker.d.ts +0 -1
  53. package/dist/components/primitives/date-picker.js +0 -1
  54. package/dist/components/primitives/dialog.d.ts +0 -1
  55. package/dist/components/primitives/dialog.js +0 -1
  56. package/dist/components/primitives/drawer.d.ts +0 -1
  57. package/dist/components/primitives/drawer.js +0 -1
  58. package/dist/components/primitives/dropdown-menu.d.ts +0 -1
  59. package/dist/components/primitives/dropdown-menu.js +0 -1
  60. package/dist/components/primitives/form-field.d.ts +0 -1
  61. package/dist/components/primitives/form-field.js +0 -1
  62. package/dist/components/primitives/inline-confirm.d.ts +0 -1
  63. package/dist/components/primitives/inline-confirm.js +0 -1
  64. package/dist/components/primitives/input.d.ts +0 -1
  65. package/dist/components/primitives/input.js +0 -1
  66. package/dist/components/primitives/label.d.ts +0 -1
  67. package/dist/components/primitives/label.js +0 -1
  68. package/dist/components/primitives/pagination.d.ts +0 -1
  69. package/dist/components/primitives/pagination.js +0 -1
  70. package/dist/components/primitives/popover.d.ts +0 -1
  71. package/dist/components/primitives/popover.js +0 -1
  72. package/dist/components/primitives/progress.d.ts +0 -1
  73. package/dist/components/primitives/progress.js +0 -1
  74. package/dist/components/primitives/radio-group.d.ts +0 -1
  75. package/dist/components/primitives/radio-group.js +0 -1
  76. package/dist/components/primitives/select.d.ts +0 -1
  77. package/dist/components/primitives/select.js +0 -1
  78. package/dist/components/primitives/separator.d.ts +0 -1
  79. package/dist/components/primitives/separator.js +0 -1
  80. package/dist/components/primitives/side-nav.d.ts +0 -1
  81. package/dist/components/primitives/side-nav.js +0 -1
  82. package/dist/components/primitives/skeleton.d.ts +0 -1
  83. package/dist/components/primitives/skeleton.js +0 -1
  84. package/dist/components/primitives/spinner.d.ts +0 -1
  85. package/dist/components/primitives/spinner.js +0 -1
  86. package/dist/components/primitives/switch.d.ts +0 -1
  87. package/dist/components/primitives/switch.js +0 -1
  88. package/dist/components/primitives/table.d.ts +0 -1
  89. package/dist/components/primitives/table.js +0 -1
  90. package/dist/components/primitives/tabs.d.ts +0 -1
  91. package/dist/components/primitives/tabs.js +0 -1
  92. package/dist/components/primitives/textarea.d.ts +0 -1
  93. package/dist/components/primitives/textarea.js +0 -1
  94. package/dist/components/primitives/toast.d.ts +0 -1
  95. package/dist/components/primitives/toast.js +0 -1
  96. package/dist/components/primitives/tooltip.d.ts +0 -1
  97. package/dist/components/primitives/tooltip.js +0 -1
  98. package/dist/components/status/state-chip.d.ts +0 -1
  99. package/dist/components/status/state-chip.js +0 -1
  100. package/dist/components/status/state-mark.d.ts +0 -1
  101. package/dist/components/status/state-mark.js +0 -1
  102. package/dist/components/status/status-pill.d.ts +0 -1
  103. package/dist/components/status/status-pill.js +0 -1
  104. package/dist/components/status/status-tokens.d.ts +0 -1
  105. package/dist/components/status/status-tokens.js +0 -1
  106. package/dist/index.d.ts +0 -1
  107. package/dist/index.js +0 -1
  108. package/dist/lib/cn.d.ts +0 -1
  109. package/dist/lib/cn.js +0 -1
  110. package/dist/lib/money.d.ts +0 -1
  111. package/dist/lib/money.js +0 -1
  112. package/dist/lib/omit-undefined.d.ts +0 -1
  113. package/dist/lib/omit-undefined.js +0 -1
  114. package/package.json +3 -7
  115. package/dist/components/data/code.d.ts.map +0 -1
  116. package/dist/components/data/code.js.map +0 -1
  117. package/dist/components/data/copy-button.d.ts.map +0 -1
  118. package/dist/components/data/copy-button.js.map +0 -1
  119. package/dist/components/data/detail-row.d.ts.map +0 -1
  120. package/dist/components/data/detail-row.js.map +0 -1
  121. package/dist/components/data/id-display.d.ts.map +0 -1
  122. package/dist/components/data/id-display.js.map +0 -1
  123. package/dist/components/data/masked-value.d.ts.map +0 -1
  124. package/dist/components/data/masked-value.js.map +0 -1
  125. package/dist/components/data/money.d.ts.map +0 -1
  126. package/dist/components/data/money.js.map +0 -1
  127. package/dist/components/data/phone-display.d.ts.map +0 -1
  128. package/dist/components/data/phone-display.js.map +0 -1
  129. package/dist/components/data/stat-tile.d.ts.map +0 -1
  130. package/dist/components/data/stat-tile.js.map +0 -1
  131. package/dist/components/data/timestamp-display.d.ts.map +0 -1
  132. package/dist/components/data/timestamp-display.js.map +0 -1
  133. package/dist/components/patterns/inline-banner.d.ts.map +0 -1
  134. package/dist/components/patterns/inline-banner.js.map +0 -1
  135. package/dist/components/patterns/inline-empty-state.d.ts.map +0 -1
  136. package/dist/components/patterns/inline-empty-state.js.map +0 -1
  137. package/dist/components/patterns/live-row.d.ts.map +0 -1
  138. package/dist/components/patterns/live-row.js.map +0 -1
  139. package/dist/components/patterns/payload-inspector.d.ts.map +0 -1
  140. package/dist/components/patterns/payload-inspector.js.map +0 -1
  141. package/dist/components/patterns/route-skeleton.d.ts.map +0 -1
  142. package/dist/components/patterns/route-skeleton.js.map +0 -1
  143. package/dist/components/patterns/screen-layout.d.ts.map +0 -1
  144. package/dist/components/patterns/screen-layout.js.map +0 -1
  145. package/dist/components/patterns/stale-write-banner.d.ts.map +0 -1
  146. package/dist/components/patterns/stale-write-banner.js.map +0 -1
  147. package/dist/components/patterns/state-timeline.d.ts.map +0 -1
  148. package/dist/components/patterns/state-timeline.js.map +0 -1
  149. package/dist/components/primitives/badge.d.ts.map +0 -1
  150. package/dist/components/primitives/badge.js.map +0 -1
  151. package/dist/components/primitives/button.d.ts.map +0 -1
  152. package/dist/components/primitives/button.js.map +0 -1
  153. package/dist/components/primitives/calendar.d.ts.map +0 -1
  154. package/dist/components/primitives/calendar.js.map +0 -1
  155. package/dist/components/primitives/card.d.ts.map +0 -1
  156. package/dist/components/primitives/card.js.map +0 -1
  157. package/dist/components/primitives/checkbox.d.ts.map +0 -1
  158. package/dist/components/primitives/checkbox.js.map +0 -1
  159. package/dist/components/primitives/chip-select.d.ts.map +0 -1
  160. package/dist/components/primitives/chip-select.js.map +0 -1
  161. package/dist/components/primitives/command-menu.d.ts.map +0 -1
  162. package/dist/components/primitives/command-menu.js.map +0 -1
  163. package/dist/components/primitives/confirm-dialog.d.ts.map +0 -1
  164. package/dist/components/primitives/confirm-dialog.js.map +0 -1
  165. package/dist/components/primitives/date-picker.d.ts.map +0 -1
  166. package/dist/components/primitives/date-picker.js.map +0 -1
  167. package/dist/components/primitives/dialog.d.ts.map +0 -1
  168. package/dist/components/primitives/dialog.js.map +0 -1
  169. package/dist/components/primitives/drawer.d.ts.map +0 -1
  170. package/dist/components/primitives/drawer.js.map +0 -1
  171. package/dist/components/primitives/dropdown-menu.d.ts.map +0 -1
  172. package/dist/components/primitives/dropdown-menu.js.map +0 -1
  173. package/dist/components/primitives/form-field.d.ts.map +0 -1
  174. package/dist/components/primitives/form-field.js.map +0 -1
  175. package/dist/components/primitives/inline-confirm.d.ts.map +0 -1
  176. package/dist/components/primitives/inline-confirm.js.map +0 -1
  177. package/dist/components/primitives/input.d.ts.map +0 -1
  178. package/dist/components/primitives/input.js.map +0 -1
  179. package/dist/components/primitives/label.d.ts.map +0 -1
  180. package/dist/components/primitives/label.js.map +0 -1
  181. package/dist/components/primitives/pagination.d.ts.map +0 -1
  182. package/dist/components/primitives/pagination.js.map +0 -1
  183. package/dist/components/primitives/popover.d.ts.map +0 -1
  184. package/dist/components/primitives/popover.js.map +0 -1
  185. package/dist/components/primitives/progress.d.ts.map +0 -1
  186. package/dist/components/primitives/progress.js.map +0 -1
  187. package/dist/components/primitives/radio-group.d.ts.map +0 -1
  188. package/dist/components/primitives/radio-group.js.map +0 -1
  189. package/dist/components/primitives/select.d.ts.map +0 -1
  190. package/dist/components/primitives/select.js.map +0 -1
  191. package/dist/components/primitives/separator.d.ts.map +0 -1
  192. package/dist/components/primitives/separator.js.map +0 -1
  193. package/dist/components/primitives/side-nav.d.ts.map +0 -1
  194. package/dist/components/primitives/side-nav.js.map +0 -1
  195. package/dist/components/primitives/skeleton.d.ts.map +0 -1
  196. package/dist/components/primitives/skeleton.js.map +0 -1
  197. package/dist/components/primitives/spinner.d.ts.map +0 -1
  198. package/dist/components/primitives/spinner.js.map +0 -1
  199. package/dist/components/primitives/switch.d.ts.map +0 -1
  200. package/dist/components/primitives/switch.js.map +0 -1
  201. package/dist/components/primitives/table.d.ts.map +0 -1
  202. package/dist/components/primitives/table.js.map +0 -1
  203. package/dist/components/primitives/tabs.d.ts.map +0 -1
  204. package/dist/components/primitives/tabs.js.map +0 -1
  205. package/dist/components/primitives/textarea.d.ts.map +0 -1
  206. package/dist/components/primitives/textarea.js.map +0 -1
  207. package/dist/components/primitives/toast.d.ts.map +0 -1
  208. package/dist/components/primitives/toast.js.map +0 -1
  209. package/dist/components/primitives/tooltip.d.ts.map +0 -1
  210. package/dist/components/primitives/tooltip.js.map +0 -1
  211. package/dist/components/status/state-chip.d.ts.map +0 -1
  212. package/dist/components/status/state-chip.js.map +0 -1
  213. package/dist/components/status/state-mark.d.ts.map +0 -1
  214. package/dist/components/status/state-mark.js.map +0 -1
  215. package/dist/components/status/status-pill.d.ts.map +0 -1
  216. package/dist/components/status/status-pill.js.map +0 -1
  217. package/dist/components/status/status-tokens.d.ts.map +0 -1
  218. package/dist/components/status/status-tokens.js.map +0 -1
  219. package/dist/index.d.ts.map +0 -1
  220. package/dist/index.js.map +0 -1
  221. package/dist/lib/cn.d.ts.map +0 -1
  222. package/dist/lib/cn.js.map +0 -1
  223. package/dist/lib/money.d.ts.map +0 -1
  224. package/dist/lib/money.js.map +0 -1
  225. package/dist/lib/omit-undefined.d.ts.map +0 -1
  226. package/dist/lib/omit-undefined.js.map +0 -1
  227. package/src/components/data/code.tsx +0 -43
  228. package/src/components/data/copy-button.tsx +0 -97
  229. package/src/components/data/detail-row.tsx +0 -113
  230. package/src/components/data/id-display.tsx +0 -49
  231. package/src/components/data/masked-value.tsx +0 -96
  232. package/src/components/data/money.tsx +0 -46
  233. package/src/components/data/phone-display.tsx +0 -60
  234. package/src/components/data/stat-tile.tsx +0 -68
  235. package/src/components/data/timestamp-display.tsx +0 -106
  236. package/src/components/patterns/inline-banner.tsx +0 -60
  237. package/src/components/patterns/inline-empty-state.tsx +0 -45
  238. package/src/components/patterns/live-row.tsx +0 -75
  239. package/src/components/patterns/payload-inspector.tsx +0 -157
  240. package/src/components/patterns/route-skeleton.tsx +0 -77
  241. package/src/components/patterns/screen-layout.tsx +0 -44
  242. package/src/components/patterns/stale-write-banner.tsx +0 -44
  243. package/src/components/patterns/state-timeline.tsx +0 -229
  244. package/src/components/primitives/badge.tsx +0 -40
  245. package/src/components/primitives/button.tsx +0 -54
  246. package/src/components/primitives/calendar.tsx +0 -136
  247. package/src/components/primitives/card.tsx +0 -70
  248. package/src/components/primitives/checkbox.tsx +0 -101
  249. package/src/components/primitives/chip-select.tsx +0 -105
  250. package/src/components/primitives/command-menu.tsx +0 -92
  251. package/src/components/primitives/confirm-dialog.tsx +0 -109
  252. package/src/components/primitives/date-picker.tsx +0 -271
  253. package/src/components/primitives/dialog.tsx +0 -195
  254. package/src/components/primitives/drawer.tsx +0 -326
  255. package/src/components/primitives/dropdown-menu.tsx +0 -128
  256. package/src/components/primitives/form-field.tsx +0 -136
  257. package/src/components/primitives/inline-confirm.tsx +0 -118
  258. package/src/components/primitives/input.tsx +0 -21
  259. package/src/components/primitives/label.tsx +0 -43
  260. package/src/components/primitives/pagination.tsx +0 -110
  261. package/src/components/primitives/popover.tsx +0 -41
  262. package/src/components/primitives/progress.tsx +0 -66
  263. package/src/components/primitives/radio-group.tsx +0 -90
  264. package/src/components/primitives/select.tsx +0 -254
  265. package/src/components/primitives/separator.tsx +0 -49
  266. package/src/components/primitives/side-nav.tsx +0 -253
  267. package/src/components/primitives/skeleton.tsx +0 -25
  268. package/src/components/primitives/spinner.tsx +0 -39
  269. package/src/components/primitives/switch.tsx +0 -74
  270. package/src/components/primitives/table.tsx +0 -157
  271. package/src/components/primitives/tabs.tsx +0 -163
  272. package/src/components/primitives/textarea.tsx +0 -21
  273. package/src/components/primitives/toast.tsx +0 -117
  274. package/src/components/primitives/tooltip.tsx +0 -38
  275. package/src/components/status/state-chip.tsx +0 -70
  276. package/src/components/status/state-mark.tsx +0 -154
  277. package/src/components/status/status-pill.tsx +0 -153
  278. package/src/components/status/status-tokens.ts +0 -173
  279. package/src/index.ts +0 -96
  280. package/src/lib/cn.ts +0 -168
  281. package/src/lib/money.ts +0 -164
  282. package/src/lib/omit-undefined.ts +0 -25
  283. /package/{src → dist}/styles/theme.css +0 -0
@@ -1,154 +0,0 @@
1
- import type { SVGProps } from "react";
2
- import { cn } from "../../lib/cn";
3
- import type { StatusMark, StatusMeta } from "./status-tokens";
4
-
5
- export interface StateMarkProps extends Omit<SVGProps<SVGSVGElement>, "className"> {
6
- /** One state's presentation, e.g. `MY_STATUS_SYSTEM[state]`. */
7
- meta: StatusMeta;
8
- /** Rendered size in px. Below 12 the glyph loses its interior mark and
9
- * should not be used — at that size the silhouette alone is doing all
10
- * the work and a plain dot would be more honest. */
11
- size?: 12 | 14 | 16;
12
- className?: string | undefined;
13
- }
14
-
15
- // Geometry per design doc §4.3, at a 16x16 viewBox: circle r=6 centred at
16
- // (8,8), stroke 1.5; the progress wedge/ring inset 1.5 from that stroke
17
- // (r=4.5); diamond = square rotated 45deg, circumradius 7; square = 10x10
18
- // centred, corner radius 1. All at stroke-width 1.5.
19
- const CX = 8;
20
- const CY = 8;
21
- const R = 6;
22
- const R_INNER = 4.5;
23
-
24
- /** Clockwise pie wedge from 12 o'clock, `sweepDeg` degrees, radius `r`. */
25
- function pieWedgePath(sweepDeg: number, r: number): string {
26
- const rad = (sweepDeg * Math.PI) / 180;
27
- const x = CX + r * Math.sin(rad);
28
- const y = CY - r * Math.cos(rad);
29
- const largeArc = sweepDeg > 180 ? 1 : 0;
30
- return `M${CX},${CY} L${CX},${CY - r} A${r},${r} 0 ${largeArc},1 ${round(x)},${round(y)} Z`;
31
- }
32
-
33
- function round(n: number): number {
34
- return Math.round(n * 100) / 100;
35
- }
36
-
37
- const DIAMOND_POINTS = `${CX},${CY - 7} ${CX + 7},${CY} ${CX},${CY + 7} ${CX - 7},${CY}`;
38
-
39
- function Silhouette({ meta }: { meta: StatusMeta }) {
40
- const fill = meta.filled ? "currentColor" : "none";
41
- const stroke = "currentColor";
42
-
43
- switch (meta.silhouette) {
44
- case "circle":
45
- return <circle cx={CX} cy={CY} r={R} fill={fill} stroke={stroke} strokeWidth={1.5} />;
46
- case "diamond":
47
- return <polygon points={DIAMOND_POINTS} fill={fill} stroke={stroke} strokeWidth={1.5} />;
48
- case "square":
49
- return (
50
- <rect
51
- x={3}
52
- y={3}
53
- width={10}
54
- height={10}
55
- rx={1}
56
- fill={fill}
57
- stroke={stroke}
58
- strokeWidth={1.5}
59
- />
60
- );
61
- }
62
- }
63
-
64
- /**
65
- * Terminal states (delivered/cancelled/expired/rejected/failed) render a
66
- * solid, filled silhouette (design doc §4.3: "is it over?" is readable from
67
- * fill alone). The interior mark then has to cut through that fill to stay
68
- * legible — this is the one place `StateMark` is not literally
69
- * single-tone: the mark strokes in `--state-mark-knockout` (default: the
70
- * page canvas colour) rather than `currentColor`, since a currentColor
71
- * stroke on a currentColor fill would be invisible. Non-terminal marks
72
- * (pie wedges, the submitted ring, the uncertain "?", the undelivered
73
- * pause bars) stay `currentColor` throughout, on an unfilled silhouette.
74
- */
75
- function InteriorMark({ mark, knockout }: { mark: StatusMark; knockout: boolean }) {
76
- const stroke = knockout ? "var(--state-mark-knockout, var(--color-base-100))" : "currentColor";
77
- const common = {
78
- stroke,
79
- strokeWidth: 1.5,
80
- strokeLinecap: "round" as const,
81
- fill: "none" as const,
82
- };
83
-
84
- switch (mark) {
85
- case "pie-1":
86
- return <path d={pieWedgePath(90, R_INNER)} fill="currentColor" />;
87
- case "pie-2":
88
- return <path d={pieWedgePath(180, R_INNER)} fill="currentColor" />;
89
- case "pie-3":
90
- return <path d={pieWedgePath(270, R_INNER)} fill="currentColor" />;
91
- case "ring":
92
- return (
93
- <circle cx={CX} cy={CY} r={R_INNER} fill="none" stroke="currentColor" strokeWidth={1.5} />
94
- );
95
- case "check":
96
- return <polyline points="5.4,8.3 7.2,10.2 11,5.8" strokeLinejoin="round" {...common} />;
97
- case "cross":
98
- return (
99
- <g {...common}>
100
- <line x1={5.6} y1={5.6} x2={10.4} y2={10.4} />
101
- <line x1={10.4} y1={5.6} x2={5.6} y2={10.4} />
102
- </g>
103
- );
104
- case "slash":
105
- return <line x1={5.6} y1={10.4} x2={10.4} y2={5.6} {...common} />;
106
- case "bar":
107
- return <line x1={5} y1={8} x2={11} y2={8} {...common} />;
108
- case "clock":
109
- return (
110
- <g {...common}>
111
- <line x1={8} y1={8} x2={8} y2={5.4} />
112
- <line x1={8} y1={8} x2={10.1} y2={8.9} />
113
- </g>
114
- );
115
- case "question":
116
- return (
117
- <g {...common}>
118
- <path d="M6.2 6.6c0-1.1 0.9-1.9 1.9-1.9s1.9 0.7 1.9 1.7c0 1.3-1.9 1.3-1.9 2.9" />
119
- <circle cx={8} cy={10.7} r={0.15} fill="currentColor" stroke="none" />
120
- </g>
121
- );
122
- case "pause":
123
- return (
124
- <g {...common}>
125
- <line x1={6.3} y1={5.5} x2={6.3} y2={10.5} />
126
- <line x1={9.7} y1={5.5} x2={9.7} y2={10.5} />
127
- </g>
128
- );
129
- }
130
- }
131
-
132
- /**
133
- * The status-glyph SVG primitive: silhouette × interior mark × fill.
134
- *
135
- * Parameterised on a raw [`StatusMeta`] rather than on any particular
136
- * state enum, so every state machine's pill renders through this one
137
- * geometry instead of forking it. Pure, and `aria-hidden` — the
138
- * accessible name belongs on the wrapping pill, which has the label.
139
- */
140
- export function StateMark({ meta, size = 14, className, ...props }: StateMarkProps) {
141
- return (
142
- <svg
143
- viewBox="0 0 16 16"
144
- width={size}
145
- height={size}
146
- aria-hidden="true"
147
- className={cn("shrink-0", className)}
148
- {...props}
149
- >
150
- <Silhouette meta={meta} />
151
- <InteriorMark mark={meta.mark} knockout={meta.filled} />
152
- </svg>
153
- );
154
- }
@@ -1,153 +0,0 @@
1
- import type { ComponentType, ReactNode } from "react";
2
- import { cn } from "../../lib/cn";
3
- import { StateMark } from "./state-mark";
4
- import { HUE_CLASSES, type StatusMeta, type StatusSystem } from "./status-tokens";
5
-
6
- export interface StatusPillProps {
7
- /** One state's presentation, e.g. `MY_STATUS_SYSTEM[state]`. */
8
- meta: StatusMeta;
9
- /** The raw enum literal, shown when `showLiteral` is set and used in the
10
- * accessible name. Optional: a pill for a state machine whose literals
11
- * are not user-facing can omit it. */
12
- literal?: string | undefined;
13
- /** Default `'auto'`: resolved from the state's own `attention` field. */
14
- variant?: "auto" | "quiet" | "loud";
15
- size?: "sm" | "md";
16
- /** Render the mono enum literal beside the label. True in detail views,
17
- * false in tables, where the label alone is enough and the literal is
18
- * noise repeated down the column. */
19
- showLiteral?: boolean;
20
- /** Short mono qualifier, e.g. `failed · 4xx`. */
21
- detail?: ReactNode;
22
- /** Optimistic-transition case: dimmed + dashed, held until the server
23
- * confirms. Never use it to mean "we think this is probably the state" —
24
- * only for a transition this client has itself just requested. */
25
- pending?: boolean;
26
- interactive?: boolean;
27
- onClick?: (() => void) | undefined;
28
- className?: string | undefined;
29
- }
30
-
31
- /**
32
- * The canonical status representation: glyph + label + attention
33
- * treatment. Typically the single most-reused component in an operator
34
- * console — every screen showing a state renders through it.
35
- *
36
- * Takes a [`StatusMeta`] rather than a state literal, so one
37
- * implementation serves every state machine in an application.
38
- * [`createStatusPill`] is the ergonomic wrapper; reach for this directly
39
- * only when the meta comes from somewhere other than a fixed table.
40
- */
41
- export function StatusPill({
42
- meta,
43
- literal,
44
- variant = "auto",
45
- size = "sm",
46
- showLiteral = false,
47
- detail,
48
- pending = false,
49
- interactive = false,
50
- onClick,
51
- className,
52
- }: StatusPillProps) {
53
- const resolvedVariant = variant === "auto" ? meta.attention : variant;
54
- const loud = resolvedVariant === "loud";
55
- const hue = HUE_CLASSES[meta.hue];
56
- const markSize = size === "md" ? 16 : 14;
57
-
58
- const Comp = interactive ? "button" : "span";
59
-
60
- return (
61
- <Comp
62
- type={interactive ? "button" : undefined}
63
- onClick={interactive ? onClick : undefined}
64
- title={meta.tooltip}
65
- // A non-interactive pill is an image of a state, not a label for
66
- // one; without `role="img"` the `aria-label` on a `<span>` is
67
- // ignored by several screen readers.
68
- role={interactive ? undefined : "img"}
69
- aria-label={literal === undefined ? meta.label : `${literal} — ${meta.label}`}
70
- className={cn(
71
- "inline-flex items-center gap-[5px] whitespace-nowrap align-middle",
72
- "text-caption",
73
- loud && [hue.bg, hue.border, "rounded-sm border py-0.5 pr-1.5 pl-[5px] font-medium"],
74
- // A dashed outline, and NOT dimming. `pending` used to be
75
- // `opacity-60`, which took its own text to 2.71:1 against the
76
- // page — below AA, and unreadable at exactly the moment a reader
77
- // most wants to know what is happening. Measured before changing
78
- // it: the opacity that keeps this text at AA is 0.90, by which
79
- // point the dimming conveys nothing. So the state says so with a
80
- // border instead, at full text contrast.
81
- //
82
- // A quiet pill has no border to dash, so it grows the same box a
83
- // loud one has — otherwise `pending` would be invisible on the
84
- // majority of pills.
85
- pending && "border-dashed",
86
- pending && !loud && "rounded-sm border border-edge-strong py-0.5 pr-1.5 pl-[5px]",
87
- interactive && "cursor-pointer",
88
- className,
89
- )}
90
- >
91
- <StateMark meta={meta} size={markSize} className={hue.fg} />
92
- <span className={loud ? hue.fg : "text-muted-foreground"}>{meta.label}</span>
93
- {/* `muted`, not `subtle`, once the pill is loud. A loud pill paints a
94
- state tint behind this text, and `--subtle-foreground` does not
95
- reach 4.5:1 on a tint over anything lighter than the page
96
- background — 4.36:1 over a card, 3.85:1 over a hovered row.
97
- Measured, and not fixable by nudging the token: the value that
98
- would clear AA on a tint is ΔE 2 from `--muted-foreground`,
99
- which collapses the three-tier text ladder into two. So the
100
- tier changes with the background instead. */}
101
- {showLiteral && literal !== undefined && (
102
- <span
103
- className={cn(
104
- "font-mono text-micro",
105
- loud ? "text-muted-foreground" : "text-subtle-foreground",
106
- )}
107
- >
108
- {literal}
109
- </span>
110
- )}
111
- {detail != null && (
112
- <span
113
- className={cn("font-mono", loud ? "text-muted-foreground" : "text-subtle-foreground")}
114
- >
115
- {detail}
116
- </span>
117
- )}
118
- </Comp>
119
- );
120
- }
121
-
122
- export type TypedStatusPillProps<S extends string> = Omit<StatusPillProps, "meta" | "literal"> & {
123
- state: S;
124
- };
125
-
126
- /**
127
- * Binds a [`StatusSystem`] to a pill component whose `state` prop accepts
128
- * exactly that system's states and nothing else.
129
- *
130
- * ```tsx
131
- * export const OrderStatusPill = createStatusPill(ORDER_STATUS);
132
- * <OrderStatusPill state="refunded" showLiteral />
133
- * ```
134
- *
135
- * This replaced three hand-written, near-identical pill components — one
136
- * per state machine — that differed only in which table they indexed and
137
- * had already drifted apart in small ways (one set `role="img"`, one did
138
- * not; one supported `interactive`, two did not). Their own doc comments
139
- * each argued for staying separate on the grounds that the state machines
140
- * genuinely differ in meaning — which is true, and is preserved here:
141
- * each machine still has its own table and its own component identity,
142
- * and `state` is still typed to one machine's literals, so a `JobState`
143
- * cannot be passed to an order pill. What they do not need is three
144
- * copies of the rendering.
145
- */
146
- export function createStatusPill<S extends string>(
147
- system: StatusSystem<S>,
148
- ): ComponentType<TypedStatusPillProps<S>> {
149
- function BoundStatusPill({ state, ...props }: TypedStatusPillProps<S>) {
150
- return <StatusPill meta={system[state]} literal={state} {...props} />;
151
- }
152
- return BoundStatusPill;
153
- }
@@ -1,173 +0,0 @@
1
- /**
2
- * The vocabulary of a status-glyph system — types and shared classes only,
3
- * no domain data.
4
- *
5
- * # What this is
6
- *
7
- * A *status system* is one state machine's presentation: a table mapping
8
- * every state that machine can be in to a glyph, a hue, an attention level
9
- * and human copy. This module owns the vocabulary and the rendering; the
10
- * table itself belongs to whoever owns the state machine, which is never
11
- * this package.
12
- *
13
- * ```tsx
14
- * const ORDER_STATUS = defineStatusSystem({
15
- * pending: { family: "in-flight", silhouette: "circle", mark: "pie-1",
16
- * hue: "neutral", filled: false, attention: "quiet",
17
- * label: "Pending", tooltip: "Awaiting payment." },
18
- * paid: { family: "terminal", silhouette: "circle", mark: "check",
19
- * hue: "success", filled: true, attention: "quiet",
20
- * label: "Paid", tooltip: "Settled." },
21
- * refunded: { family: "terminal", silhouette: "circle", mark: "bar",
22
- * hue: "neutral", filled: true, attention: "quiet",
23
- * label: "Refunded", tooltip: "Returned to the payer." },
24
- * });
25
- *
26
- * const OrderStatusPill = createStatusPill(ORDER_STATUS);
27
- * <OrderStatusPill state="paid" />
28
- * ```
29
- *
30
- * # Every field here is PRESENTATIONAL
31
- *
32
- * Never use `family` — or anything else in a `StatusMeta` — to decide
33
- * whether an action is permitted. Terminality is data, and the server
34
- * owns it: a UI that greys out "cancel" because its own table says
35
- * `terminal` will be wrong the first time the state machine changes and
36
- * nobody remembers this table exists. Propose the action and let the
37
- * server refuse it.
38
- *
39
- * # Why a glyph and not just colour
40
- *
41
- * Colour alone fails for the ~8% of men with a colour-vision deficiency,
42
- * and fails completely in a screenshot pasted into a monochrome ticket.
43
- * Each state therefore differs in *silhouette* (circle / diamond /
44
- * square), *interior mark*, and *fill* as well as hue — three redundant
45
- * channels, so no single one is load-bearing.
46
- */
47
-
48
- /**
49
- * The three-way split every state machine this system has met so far
50
- * reduces to: still moving, stopped somewhere that needs a human, or done.
51
- *
52
- * `unresolved` is the one worth naming explicitly — it is not a failure
53
- * and not a success, and systems that only model two outcomes end up
54
- * calling it whichever is more convenient, which is how "we never learned
55
- * the outcome" gets reported to a user as "delivered".
56
- */
57
- export type StatusFamily = "in-flight" | "unresolved" | "terminal";
58
-
59
- export type StatusSilhouette = "circle" | "diamond" | "square";
60
-
61
- /**
62
- * The interior mark drawn inside the silhouette. `pie-1`..`pie-3` are the
63
- * quarter-fill progress wedge; `ring` is a completed stroke with a hollow
64
- * centre (handed off, awaiting an external answer).
65
- */
66
- export type StatusMark =
67
- | "pie-1"
68
- | "pie-2"
69
- | "pie-3"
70
- | "ring"
71
- | "check"
72
- | "bar"
73
- | "clock"
74
- | "slash"
75
- | "cross"
76
- | "question"
77
- | "pause";
78
-
79
- /**
80
- * The saturated hues a status may take.
81
- *
82
- * `warning` and `uncertain` are deliberately distinct despite both reading
83
- * as "attention": `uncertain` means the outcome is unknown, `warning`
84
- * means a recoverable condition needs a human. `expired` and `parked` are
85
- * separated from `neutral` for the same reason — a state nobody needs to
86
- * act on and a state waiting for someone should not look identical.
87
- */
88
- export type StatusHue =
89
- | "neutral"
90
- | "success"
91
- | "warning"
92
- | "danger"
93
- | "uncertain"
94
- | "expired"
95
- | "parked";
96
-
97
- /** Quiet: glyph only, no fill. Loud: tinted background + border. */
98
- export type StatusAttention = "quiet" | "loud";
99
-
100
- export interface StatusMeta {
101
- family: StatusFamily;
102
- silhouette: StatusSilhouette;
103
- mark: StatusMark;
104
- hue: StatusHue;
105
- /** Terminal marks sit on a filled silhouette; in-flight/unresolved marks are stroked-only. */
106
- filled: boolean;
107
- attention: StatusAttention;
108
- /** Human-facing name. Sentence case, not the raw enum literal. */
109
- label: string;
110
- /** One or two sentences saying what this state means and what happens next. */
111
- tooltip: string;
112
- }
113
-
114
- /** One state machine's complete presentation table. */
115
- export type StatusSystem<S extends string> = Readonly<Record<S, StatusMeta>>;
116
-
117
- /**
118
- * Identity at runtime; exists for inference. Without it a caller must
119
- * write `const X: StatusSystem<"a" | "b"> = {…}` and repeat every key in
120
- * the type annotation; with it, `S` is inferred from the object's own keys
121
- * and `createStatusPill(X)` then accepts exactly those keys and no others.
122
- */
123
- export function defineStatusSystem<S extends string>(system: StatusSystem<S>): StatusSystem<S> {
124
- return system;
125
- }
126
-
127
- /**
128
- * Whether a state is terminal *according to its own table* — a
129
- * presentational question ("should this row stop animating"), never an
130
- * authorisation one. See this module's own warning above.
131
- */
132
- export function isTerminalStatus<S extends string>(system: StatusSystem<S>, state: S): boolean {
133
- return system[state].family === "terminal";
134
- }
135
-
136
- /** Hue → the token classes every status surface renders through. */
137
- export const HUE_CLASSES: Record<StatusHue, { fg: string; bg: string; border: string }> = {
138
- neutral: {
139
- fg: "text-state-neutral-fg",
140
- bg: "bg-state-neutral-bg",
141
- border: "border-state-neutral-border",
142
- },
143
- success: {
144
- fg: "text-state-success-fg",
145
- bg: "bg-state-success-bg",
146
- border: "border-state-success-border",
147
- },
148
- warning: {
149
- fg: "text-state-warning-fg",
150
- bg: "bg-state-warning-bg",
151
- border: "border-state-warning-border",
152
- },
153
- danger: {
154
- fg: "text-state-danger-fg",
155
- bg: "bg-state-danger-bg",
156
- border: "border-state-danger-border",
157
- },
158
- uncertain: {
159
- fg: "text-state-uncertain-fg",
160
- bg: "bg-state-uncertain-bg",
161
- border: "border-state-uncertain-border",
162
- },
163
- expired: {
164
- fg: "text-state-expired-fg",
165
- bg: "bg-state-expired-bg",
166
- border: "border-state-expired-border",
167
- },
168
- parked: {
169
- fg: "text-state-parked-fg",
170
- bg: "bg-state-parked-bg",
171
- border: "border-state-parked-border",
172
- },
173
- };
package/src/index.ts DELETED
@@ -1,96 +0,0 @@
1
- /**
2
- * `@vaam-apps/ui` — a dark-first React component library for operator
3
- * consoles: daisyUI for styling, Headless UI for behaviour, and a
4
- * parameterised status-glyph system for state machines.
5
- *
6
- * Import the token layer **once**, from the app's own global stylesheet,
7
- * after loading Tailwind and the daisyUI plugin:
8
- *
9
- * ```css
10
- * @import "tailwindcss";
11
- * @plugin "daisyui";
12
- * @import "@vaam-apps/ui/styles/theme.css";
13
- * @source "../node_modules/@vaam-apps/ui/dist";
14
- * ```
15
- *
16
- * The `@source` line is not optional: Tailwind v4 only generates the
17
- * utilities it can see used, and it does not look inside `node_modules`
18
- * by default. Omit it and every component renders unstyled — a silent
19
- * failure that is miserable to debug.
20
- */
21
-
22
- // ---------------------------------------------------------------------------
23
- // Data display — consistency is the deliverable, so these are components
24
- // rather than ad hoc per-screen formatting.
25
- // ---------------------------------------------------------------------------
26
- export * from "./components/data/code";
27
- export * from "./components/data/copy-button";
28
- export * from "./components/data/detail-row";
29
- export * from "./components/data/id-display";
30
- export * from "./components/data/masked-value";
31
- export * from "./components/data/money";
32
- export * from "./components/data/phone-display";
33
- export * from "./components/data/stat-tile";
34
- export * from "./components/data/timestamp-display";
35
- // ---------------------------------------------------------------------------
36
- // Patterns — composed screen-level building blocks. Still domain-free,
37
- // but opinionated about layout in a way the primitives are not.
38
- // ---------------------------------------------------------------------------
39
- export * from "./components/patterns/inline-banner";
40
- export * from "./components/patterns/inline-empty-state";
41
- export * from "./components/patterns/live-row";
42
- export * from "./components/patterns/payload-inspector";
43
- export * from "./components/patterns/route-skeleton";
44
- export * from "./components/patterns/screen-layout";
45
- export * from "./components/patterns/stale-write-banner";
46
- export * from "./components/patterns/state-timeline";
47
- // ---------------------------------------------------------------------------
48
- // Primitives
49
- // ---------------------------------------------------------------------------
50
- export * from "./components/primitives/badge";
51
- export * from "./components/primitives/button";
52
- export * from "./components/primitives/calendar";
53
- export * from "./components/primitives/card";
54
- export * from "./components/primitives/checkbox";
55
- export * from "./components/primitives/chip-select";
56
- export * from "./components/primitives/command-menu";
57
- export * from "./components/primitives/confirm-dialog";
58
- export * from "./components/primitives/date-picker";
59
- export * from "./components/primitives/dialog";
60
- export * from "./components/primitives/drawer";
61
- export * from "./components/primitives/dropdown-menu";
62
- export * from "./components/primitives/form-field";
63
- export * from "./components/primitives/inline-confirm";
64
- export * from "./components/primitives/input";
65
- export * from "./components/primitives/label";
66
- export * from "./components/primitives/pagination";
67
- export * from "./components/primitives/popover";
68
- export * from "./components/primitives/progress";
69
- export * from "./components/primitives/radio-group";
70
- export * from "./components/primitives/select";
71
- export * from "./components/primitives/separator";
72
- export * from "./components/primitives/side-nav";
73
- export * from "./components/primitives/skeleton";
74
- export * from "./components/primitives/spinner";
75
- export * from "./components/primitives/switch";
76
- export * from "./components/primitives/table";
77
- export * from "./components/primitives/tabs";
78
- export * from "./components/primitives/textarea";
79
- export * from "./components/primitives/toast";
80
- export * from "./components/primitives/tooltip";
81
- // ---------------------------------------------------------------------------
82
- // Status — the most-reused surface in an operator console. Read
83
- // `status-tokens.ts` first: the tables live in the consuming application,
84
- // not here.
85
- // ---------------------------------------------------------------------------
86
- export * from "./components/status/state-chip";
87
- export * from "./components/status/state-mark";
88
- export * from "./components/status/status-pill";
89
- export * from "./components/status/status-tokens";
90
-
91
- // ---------------------------------------------------------------------------
92
- // Utilities
93
- // ---------------------------------------------------------------------------
94
- export { cn } from "./lib/cn";
95
- export * from "./lib/money";
96
- export { omitUndefined } from "./lib/omit-undefined";