@siyahi/ui 0.1.9-next.20 → 0.1.9-next.21

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 (88) hide show
  1. package/DESIGN.md +30 -0
  2. package/README.md +3 -3
  3. package/agents/examples/alert.tsx +4 -6
  4. package/agents/examples/bar-list-sides.tsx +11 -3
  5. package/agents/examples/button-states.tsx +23 -0
  6. package/agents/examples/callout.tsx +33 -0
  7. package/agents/examples/change-bar.tsx +104 -0
  8. package/agents/examples/chart-area.tsx +5 -4
  9. package/agents/examples/chart-bar-flows.tsx +3 -2
  10. package/agents/examples/chart-bar-sectors.tsx +2 -0
  11. package/agents/examples/data-table-compact.tsx +95 -0
  12. package/agents/examples/heatmap-calendar.tsx +17 -7
  13. package/agents/examples/heatmap-status.tsx +17 -11
  14. package/agents/examples/heatmap-weekday.tsx +33 -11
  15. package/agents/examples/input-states.tsx +33 -0
  16. package/agents/examples/metric-strip.tsx +9 -3
  17. package/agents/examples/overview-dashboard.tsx +18 -0
  18. package/agents/examples/page-hero.tsx +38 -0
  19. package/agents/examples/range-position-table.tsx +101 -0
  20. package/agents/examples/range-position.tsx +53 -0
  21. package/agents/examples/section-cards-select.tsx +8 -5
  22. package/agents/examples/surfaces.tsx +3 -2
  23. package/agents/examples/target-rows.tsx +70 -0
  24. package/agents/examples/treemap.tsx +2 -1
  25. package/agents/manifest.json +153 -3
  26. package/dist/components/registry/charts/area-chart-card.js +25 -7
  27. package/dist/components/registry/charts/bar-chart-card.d.ts +0 -1
  28. package/dist/components/registry/charts/bar-chart-card.js +11 -4
  29. package/dist/components/registry/charts/line-chart-card.js +2 -2
  30. package/dist/components/registry/dashboardcn/bar-list.js +11 -5
  31. package/dist/components/registry/dashboardcn/kpi-row-card.js +2 -2
  32. package/dist/components/registry/dashboardcn/sparkline.d.ts +5 -1
  33. package/dist/components/registry/dashboardcn/sparkline.js +40 -18
  34. package/dist/components/registry/heatmap/calendar-heatmap.d.ts +4 -2
  35. package/dist/components/registry/heatmap/calendar-heatmap.js +67 -33
  36. package/dist/components/registry/heatmap/status-heatmap.d.ts +5 -3
  37. package/dist/components/registry/heatmap/status-heatmap.js +30 -15
  38. package/dist/components/registry/heatmap/weekday-heatmap.d.ts +4 -2
  39. package/dist/components/registry/heatmap/weekday-heatmap.js +28 -12
  40. package/dist/components/registry/niko-table/core/data-table-context.d.ts +16 -1
  41. package/dist/components/registry/niko-table/core/data-table-context.js +5 -20
  42. package/dist/components/registry/niko-table/core/data-table-root.js +39 -4
  43. package/dist/components/registry/niko-table/core/data-table-structure.js +2 -0
  44. package/dist/components/registry/niko-table/lib/styles.js +1 -1
  45. package/dist/components/registry/niko-table/types/index.d.ts +9 -0
  46. package/dist/components/registry/sidebar-07/nav-main.d.ts +1 -0
  47. package/dist/components/registry/sidebar-07/nav-main.js +9 -2
  48. package/dist/components/siyahi/callout.d.ts +24 -0
  49. package/dist/components/siyahi/callout.js +40 -0
  50. package/dist/components/siyahi/change-bar.d.ts +21 -0
  51. package/dist/components/siyahi/change-bar.js +35 -0
  52. package/dist/components/siyahi/data-table-compact-columns-toggle.d.ts +4 -0
  53. package/dist/components/siyahi/data-table-compact-columns-toggle.js +19 -0
  54. package/dist/components/siyahi/data-table-footnote.d.ts +12 -0
  55. package/dist/components/siyahi/data-table-footnote.js +35 -0
  56. package/dist/components/siyahi/default-sidebar-open.d.ts +8 -0
  57. package/dist/components/siyahi/default-sidebar-open.js +13 -0
  58. package/dist/components/siyahi/page-hero.d.ts +25 -0
  59. package/dist/components/siyahi/page-hero.js +41 -0
  60. package/dist/components/siyahi/page-toc.d.ts +20 -0
  61. package/dist/components/siyahi/page-toc.js +76 -0
  62. package/dist/components/siyahi/quote.d.ts +12 -0
  63. package/dist/components/siyahi/quote.js +23 -0
  64. package/dist/components/siyahi/range-position.d.ts +24 -0
  65. package/dist/components/siyahi/range-position.js +105 -0
  66. package/dist/components/siyahi/siyahi-provider.d.ts +1 -1
  67. package/dist/components/siyahi/siyahi-provider.js +1 -1
  68. package/dist/components/siyahi/target-rows.d.ts +34 -0
  69. package/dist/components/siyahi/target-rows.js +97 -0
  70. package/dist/components/siyahi/treemap.d.ts +4 -1
  71. package/dist/components/siyahi/treemap.js +33 -25
  72. package/dist/components/siyahi/warning-alert.d.ts +10 -0
  73. package/dist/components/siyahi/warning-alert.js +20 -0
  74. package/dist/index.d.ts +15 -4
  75. package/dist/index.js +12 -1
  76. package/dist/lib/chart-frame.d.ts +12 -2
  77. package/dist/lib/chart-frame.js +51 -7
  78. package/dist/lib/chart-series.d.ts +5 -2
  79. package/dist/lib/compact-columns.d.ts +19 -0
  80. package/dist/lib/compact-columns.js +55 -0
  81. package/dist/lib/format.d.ts +7 -2
  82. package/dist/lib/format.js +24 -5
  83. package/dist/lib/treemap.js +6 -1
  84. package/dist/lib/use-element-width.d.ts +5 -0
  85. package/dist/lib/use-element-width.js +15 -0
  86. package/package.json +2 -1
  87. package/report.css +26 -25
  88. package/styles/siyahi.css +159 -43
package/styles/siyahi.css CHANGED
@@ -1,7 +1,10 @@
1
1
  /*
2
2
  * Siyahi theme: the only file in the package that holds colour values.
3
- * Stock shadcn/ui `neutral` for both schemes, plus four meaning colours and a
4
- * five-hue chart palette. `packages/tools/contrast.mjs` checks every value
3
+ * shadcn/ui `neutral` greys for both schemes, with ink indigo (hue 275)
4
+ * placed, not spread: links, focus rings, the selected sidebar item's text
5
+ * and the first chart series. Buttons, badges and toggles stay monochrome,
6
+ * where black and white read strongest. Plus three meaning
7
+ * colours and a five-hue chart palette. `packages/tools/contrast.mjs` checks every value
5
8
  * here in the build; when a check fails, change the value, never the bar.
6
9
  */
7
10
  @import "tailwindcss";
@@ -81,7 +84,7 @@
81
84
  :root {
82
85
  color-scheme: light dark;
83
86
  --radius: 0.625rem;
84
- --background: oklch(1 0 0);
87
+ --background: oklch(0.985 0 0);
85
88
  --foreground: oklch(0.145 0 0);
86
89
  --card: oklch(1 0 0);
87
90
  --card-foreground: oklch(0.145 0 0);
@@ -98,7 +101,7 @@
98
101
  --destructive: oklch(0.577 0.245 27.325);
99
102
  --border: oklch(0.922 0 0);
100
103
  --input: oklch(0.922 0 0);
101
- --ring: oklch(0.708 0 0);
104
+ --ring: oklch(0.62 0.16 275);
102
105
  /* Tailwind green-700, red-600, amber-700, blue-600. */
103
106
  --positive: oklch(0.527 0.154 150.069);
104
107
  --positive-foreground: oklch(0.985 0 0);
@@ -106,28 +109,30 @@
106
109
  --negative-foreground: oklch(0.985 0 0);
107
110
  --warning: oklch(0.555 0.163 48.998);
108
111
  --warning-foreground: oklch(0.985 0 0);
109
- --link: oklch(0.546 0.245 262.881);
112
+ --link: oklch(0.51 0.2 275);
110
113
  /*
111
- * Blue, emerald, amber, violet, rose. Each slot reaches 3:1 against the card
112
- * and against the slots next to it, which only lightness can give, so
113
- * emerald and violet are the deep members in both schemes. Slots two apart
114
+ * Indigo, amber, plum, sky, teal: no green or red, so no series reads as a
115
+ * gain or a loss. Each slot reaches 3:1 against the card and against the
116
+ * slots next to it, which only lightness can give, so indigo, plum and teal
117
+ * are the deep members and amber and sky the pale ones, in both schemes: a
118
+ * pale indigo in dark read as lavender and lost the accent. Slots two apart
114
119
  * share a lightness and are told apart by hue; series take slots in order.
115
120
  * Every chart value is inside sRGB, so the browser paints what the contrast
116
121
  * check scored.
117
122
  */
118
- --chart-1: oklch(0.65 0.17 259.8);
119
- --chart-2: oklch(0.35 0.07 163.2);
120
- --chart-3: oklch(0.66 0.15 60);
121
- --chart-4: oklch(0.36 0.17 293);
122
- --chart-5: oklch(0.65 0.21 16.4);
123
+ --chart-1: oklch(0.4 0.17 275);
124
+ --chart-2: oklch(0.66 0.13 70);
125
+ --chart-3: oklch(0.38 0.13 335);
126
+ --chart-4: oklch(0.66 0.11 235);
127
+ --chart-5: oklch(0.36 0.06 205);
123
128
  --sidebar: oklch(0.985 0 0);
124
129
  --sidebar-foreground: oklch(0.145 0 0);
125
130
  --sidebar-primary: oklch(0.205 0 0);
126
131
  --sidebar-primary-foreground: oklch(0.985 0 0);
127
132
  --sidebar-accent: oklch(0.97 0 0);
128
- --sidebar-accent-foreground: oklch(0.205 0 0);
133
+ --sidebar-accent-foreground: oklch(0.45 0.2 275);
129
134
  --sidebar-border: oklch(0.922 0 0);
130
- --sidebar-ring: oklch(0.708 0 0);
135
+ --sidebar-ring: oklch(0.62 0.16 275);
131
136
 
132
137
  @variant dark {
133
138
  /*
@@ -136,49 +141,49 @@
136
141
  * cards' grey gone on a ruled page the canvas is what text sits on.
137
142
  * Claude Code (#181818, about #e8e8e8 text) and T3 Code (#0a0a0a, about
138
143
  * #bebebe) both narrow that gap; this sits between them, at 14.9:1.
139
- * The card matches the canvas, so the contrast check scores the colour
140
- * a ruled chart is drawn on, and the sidebar is a shade darker, as in
141
- * the light scheme.
144
+ * Cards sit one step above the canvas, so data reads as raised, as the
145
+ * white card does on the light canvas; the sidebar is a shade darker.
142
146
  */
143
- --background: oklch(0.18 0 0);
147
+ --background: oklch(0.14 0 0);
144
148
  --foreground: oklch(0.922 0 0);
145
- --card: oklch(0.18 0 0);
149
+ --card: oklch(0.215 0 0);
146
150
  --card-foreground: oklch(0.922 0 0);
147
- --popover: oklch(0.18 0 0);
151
+ --popover: oklch(0.215 0 0);
148
152
  --popover-foreground: oklch(0.922 0 0);
149
153
  --primary: oklch(0.922 0 0);
150
154
  --primary-foreground: oklch(0.205 0 0);
151
155
  --secondary: oklch(0.269 0 0);
152
156
  --secondary-foreground: oklch(0.922 0 0);
153
157
  --muted: oklch(0.269 0 0);
154
- --muted-foreground: oklch(0.708 0 0);
158
+ /* A step above shadcn's 0.708: subtitles, footnotes and table labels at data density read too dim. */
159
+ --muted-foreground: oklch(0.74 0 0);
155
160
  --accent: oklch(0.269 0 0);
156
161
  --accent-foreground: oklch(0.922 0 0);
157
162
  --destructive: oklch(0.704 0.191 22.216);
158
163
  --border: oklch(1 0 0 / 10%);
159
164
  --input: oklch(1 0 0 / 15%);
160
- --ring: oklch(0.556 0 0);
161
- /* Tailwind green-400, red-400, amber-400, blue-400. */
162
- --positive: oklch(0.792 0.209 151.711);
165
+ --ring: oklch(0.6 0.14 275);
166
+ /* Green toned down from Tailwind green-400 to the lightness and calm of red-400 beside it, so gains do not shout; amber-400. */
167
+ --positive: oklch(0.74 0.16 151.711);
163
168
  --positive-foreground: oklch(0.145 0 0);
164
169
  --negative: oklch(0.704 0.191 22.216);
165
170
  --negative-foreground: oklch(0.145 0 0);
166
171
  --warning: oklch(0.828 0.189 84.429);
167
172
  --warning-foreground: oklch(0.145 0 0);
168
- --link: oklch(0.707 0.165 254.624);
169
- --chart-1: oklch(0.84 0.08 255);
170
- --chart-2: oklch(0.52 0.11 163.2);
171
- --chart-3: oklch(0.86 0.13 80);
172
- --chart-4: oklch(0.55 0.25 293);
173
- --chart-5: oklch(0.84 0.085 12);
173
+ --link: oklch(0.75 0.13 275);
174
+ --chart-1: oklch(0.58 0.2 275);
175
+ --chart-2: oklch(0.88 0.08 75);
176
+ --chart-3: oklch(0.58 0.16 335);
177
+ --chart-4: oklch(0.88 0.05 235);
178
+ --chart-5: oklch(0.56 0.08 205);
174
179
  --sidebar: oklch(0.145 0 0);
175
180
  --sidebar-foreground: oklch(0.922 0 0);
176
- --sidebar-primary: oklch(0.488 0.243 264.376);
177
- --sidebar-primary-foreground: oklch(0.985 0 0);
181
+ --sidebar-primary: oklch(0.922 0 0);
182
+ --sidebar-primary-foreground: oklch(0.205 0 0);
178
183
  --sidebar-accent: oklch(0.269 0 0);
179
- --sidebar-accent-foreground: oklch(0.922 0 0);
184
+ --sidebar-accent-foreground: oklch(0.8 0.1 275);
180
185
  --sidebar-border: oklch(1 0 0 / 10%);
181
- --sidebar-ring: oklch(0.556 0 0);
186
+ --sidebar-ring: oklch(0.6 0.14 275);
182
187
  }
183
188
  }
184
189
 
@@ -205,6 +210,67 @@
205
210
  }
206
211
  }
207
212
 
213
+ /*
214
+ * Every selected toggle, a view switch or a filter chip alike, fills with the
215
+ * foreground, black on white and white on black, so the reader sees at once
216
+ * what is on; stock shadcn marks it with a faint grey. Unlayered, to outrank
217
+ * the stock aria-pressed:bg-muted.
218
+ */
219
+ :is([data-slot="toggle"], [data-slot="toggle-group-item"]):is([aria-pressed="true"], [data-pressed]) {
220
+ background-color: var(--foreground);
221
+ color: var(--background);
222
+ border-color: var(--foreground);
223
+ }
224
+
225
+ /*
226
+ * A number column (meta.variant "number") right-aligns its head and cells, so
227
+ * figures line up by their units down the column, as a ledger reads.
228
+ */
229
+ :is([data-slot="table-head"], [data-slot="table-cell"])[data-numeric] {
230
+ text-align: right;
231
+ }
232
+ [data-slot="table-head"][data-numeric] > *,
233
+ [data-slot="table-cell"][data-numeric] > :is(div, span)[class*="flex"] {
234
+ justify-content: flex-end;
235
+ margin-inline-start: auto;
236
+ }
237
+
238
+ /*
239
+ * A card on the card surface lifts off the tinted canvas with a faint shadow
240
+ * under its 1px ring (Tailwind composes --tw-shadow with the ring), and a data
241
+ * table inside it drops its own border, so there is one frame, not two.
242
+ */
243
+ @scope (:root, [data-surface="card"]) to ([data-surface="ruled"], [data-surface="open"]) {
244
+ [data-slot="card"] {
245
+ --tw-shadow: 0 1px 2px 0 oklch(0 0 0 / 0.06), 0 1px 3px 0 oklch(0 0 0 / 0.04);
246
+ }
247
+ [data-slot="card"] [data-slot="table-container"] {
248
+ border-color: transparent;
249
+ }
250
+ }
251
+
252
+ /*
253
+ * Chart gridlines take the full border colour: stock shadcn draws them at half
254
+ * of it, which all but vanishes on a dark card (5% white).
255
+ */
256
+ [data-slot="chart"] .recharts-cartesian-grid line {
257
+ stroke: var(--border);
258
+ }
259
+
260
+ /*
261
+ * The selected sub-page marks its stretch of the sidebar's rail in the accent,
262
+ * so the current place reads at a glance in a long list, as a docs index does.
263
+ */
264
+ [data-slot="sidebar-menu-sub-item"]:has(> [data-active])::before {
265
+ content: "";
266
+ position: absolute;
267
+ inset-block: 2px;
268
+ left: -11px;
269
+ width: 2px;
270
+ border-radius: 1px;
271
+ background: var(--sidebar-accent-foreground);
272
+ }
273
+
208
274
  /* Touch targets follow input capability, including touch laptops. */
209
275
  @media (pointer: coarse) {
210
276
  :is(
@@ -251,17 +317,16 @@
251
317
  }
252
318
 
253
319
  /*
254
- * Surfaces, from SiyahiProvider's surface prop. Ruled, the default, and open
255
- * take the box off every core Card: no fill, no corner, no ring, and no
256
- * tinted footer band; PanelGrid draws the hairlines between ruled blocks.
257
- * Open also drops the card's padding, so a block's content sits level with
258
- * the page's text. A card provider gives shadcn's own card back. Each scope
259
- * starts at the root, so a Card outside any provider is ruled too, and stops
260
- * at a provider that says otherwise. Unlayered, like the rule above, to
320
+ * Surfaces, from SiyahiProvider's surface prop. Card, the default, is
321
+ * shadcn's own card on the tinted canvas. Ruled and open take the box off
322
+ * every core Card: no fill, no corner, no ring, and no tinted footer band;
323
+ * PanelGrid draws the hairlines between ruled blocks. Open also drops the
324
+ * card's padding, so a block's content sits level with the page's text. Each
325
+ * scope stops at a provider that says otherwise. Unlayered, like the rule above, to
261
326
  * outrank the core components' utility classes; a picked SectionCards tile
262
327
  * keeps its ring, which is important.
263
328
  */
264
- @scope (:root, [data-surface="ruled"], [data-surface="open"]) to ([data-surface="card"]) {
329
+ @scope ([data-surface="ruled"], [data-surface="open"]) to ([data-surface="card"]) {
265
330
  [data-slot="card"] {
266
331
  background: none;
267
332
  border-radius: 0;
@@ -281,3 +346,54 @@
281
346
  gap: calc(var(--spacing) * 4);
282
347
  }
283
348
  }
349
+
350
+ /*
351
+ * A table, or a page's section strip, that scrolls sideways fades at the edge
352
+ * with more behind it,
353
+ * so a phone reader sees there is more without a visible scrollbar. The fade
354
+ * follows the scroll position; a table that fits has no timeline and no fade.
355
+ */
356
+ @property --table-fade-start {
357
+ syntax: "<length>";
358
+ inherits: false;
359
+ initial-value: 0px;
360
+ }
361
+ @property --table-fade-end {
362
+ syntax: "<length>";
363
+ inherits: false;
364
+ initial-value: 0px;
365
+ }
366
+ @keyframes table-edge-fade {
367
+ 0% {
368
+ --table-fade-start: 0px;
369
+ --table-fade-end: 2rem;
370
+ }
371
+ 8%,
372
+ 92% {
373
+ --table-fade-start: 2rem;
374
+ --table-fade-end: 2rem;
375
+ }
376
+ 100% {
377
+ --table-fade-start: 2rem;
378
+ --table-fade-end: 0px;
379
+ }
380
+ }
381
+ @layer base {
382
+ :is([data-slot="table-container"], [data-slot="page-toc"] > div) {
383
+ mask-image: linear-gradient(
384
+ to right,
385
+ rgb(0 0 0 / 0.2),
386
+ #000 var(--table-fade-start),
387
+ #000 calc(100% - var(--table-fade-end)),
388
+ rgb(0 0 0 / 0.2)
389
+ );
390
+ animation: table-edge-fade linear both;
391
+ animation-timeline: scroll(self inline);
392
+ }
393
+ /* Scroll position, not motion: the reduced-motion reset above must not collapse it. */
394
+ @media (prefers-reduced-motion: reduce) {
395
+ :is([data-slot="table-container"], [data-slot="page-toc"] > div) {
396
+ animation-duration: auto !important;
397
+ }
398
+ }
399
+ }