@siyahi/ui 0.1.9-next.32 → 0.1.9-next.34

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 (107) hide show
  1. package/DESIGN.md +20 -7
  2. package/agents/examples/chart-panels-three.tsx +51 -0
  3. package/agents/examples/context-menu.tsx +14 -4
  4. package/agents/examples/overview-dashboard.tsx +2 -2
  5. package/agents/examples/{page-hero.tsx → page-header.tsx} +4 -4
  6. package/agents/examples/select.tsx +2 -1
  7. package/agents/manifest.json +16 -3
  8. package/dist/components/registry/charts/area-chart-card.d.ts +2 -2
  9. package/dist/components/registry/charts/area-chart-card.js +1 -0
  10. package/dist/components/registry/charts/bar-chart-card.d.ts +4 -4
  11. package/dist/components/registry/charts/bar-chart-card.js +0 -2
  12. package/dist/components/registry/charts/line-chart-card.d.ts +1 -1
  13. package/dist/components/registry/dashboard-01/section-cards.d.ts +4 -4
  14. package/dist/components/registry/dashboardcn/bar-list.d.ts +8 -8
  15. package/dist/components/registry/dashboardcn/distribution-bar.d.ts +11 -11
  16. package/dist/components/registry/dashboardcn/kpi-row-card.d.ts +4 -4
  17. package/dist/components/registry/dashboardcn/sparkline.d.ts +6 -6
  18. package/dist/components/registry/heatmap/calendar-heatmap.d.ts +50 -50
  19. package/dist/components/registry/heatmap/calendar-heatmap.js +1 -1
  20. package/dist/components/registry/heatmap/status-heatmap.d.ts +44 -44
  21. package/dist/components/registry/heatmap/status-heatmap.js +1 -1
  22. package/dist/components/registry/heatmap/weekday-heatmap.d.ts +53 -53
  23. package/dist/components/registry/heatmap/weekday-heatmap.js +1 -1
  24. package/dist/components/registry/minidev/copy-button.d.ts +2 -2
  25. package/dist/components/registry/niko-table/components/data-table-column-actions.d.ts +1 -1
  26. package/dist/components/registry/niko-table/components/data-table-column-filter.d.ts +1 -1
  27. package/dist/components/registry/niko-table/components/data-table-empty-state.d.ts +7 -7
  28. package/dist/components/registry/niko-table/components/data-table-faceted-filter.d.ts +5 -5
  29. package/dist/components/registry/niko-table/components/data-table-grouped-rows.d.ts +1 -1
  30. package/dist/components/registry/niko-table/components/data-table-row-context-menu-slot.d.ts +1 -1
  31. package/dist/components/registry/niko-table/components/data-table-row-context-menu.d.ts +1 -1
  32. package/dist/components/registry/niko-table/config/feature-detection.d.ts +13 -13
  33. package/dist/components/registry/niko-table/core/data-table-context.d.ts +5 -5
  34. package/dist/components/registry/niko-table/core/data-table-error-boundary.d.ts +3 -3
  35. package/dist/components/registry/niko-table/core/data-table-grouped-row.d.ts +2 -2
  36. package/dist/components/registry/niko-table/core/data-table-root.d.ts +36 -35
  37. package/dist/components/registry/niko-table/core/data-table-structure.d.ts +22 -22
  38. package/dist/components/registry/niko-table/core/data-table-structure.js +6 -0
  39. package/dist/components/registry/niko-table/core/data-table.d.ts +3 -3
  40. package/dist/components/registry/niko-table/core/data-table.js +1 -1
  41. package/dist/components/registry/niko-table/filters/table-column-actions.d.ts +5 -5
  42. package/dist/components/registry/niko-table/filters/table-column-sort.d.ts +6 -6
  43. package/dist/components/registry/niko-table/filters/table-column-sort.js +2 -2
  44. package/dist/components/registry/niko-table/filters/table-column-title.d.ts +2 -2
  45. package/dist/components/registry/niko-table/filters/table-faceted-filter.d.ts +9 -9
  46. package/dist/components/registry/niko-table/filters/table-faceted-filter.js +1 -1
  47. package/dist/components/registry/niko-table/filters/table-search-filter.d.ts +7 -7
  48. package/dist/components/registry/niko-table/hooks/use-generated-options.d.ts +7 -7
  49. package/dist/components/registry/niko-table/lib/build-faceted-options.d.ts +2 -2
  50. package/dist/components/registry/niko-table/lib/column-resize-handle.d.ts +3 -3
  51. package/dist/components/registry/niko-table/lib/column-resize-handle.js +1 -1
  52. package/dist/components/registry/niko-table/lib/create-scroll-handler.d.ts +4 -4
  53. package/dist/components/registry/niko-table/types/index.d.ts +29 -29
  54. package/dist/components/registry/sidebar-07/app-sidebar.d.ts +6 -5
  55. package/dist/components/registry/sidebar-07/nav-main.d.ts +4 -4
  56. package/dist/components/registry/sidebar-07/nav-user.js +16 -19
  57. package/dist/components/siyahi/callout.d.ts +1 -1
  58. package/dist/components/siyahi/change-bar.d.ts +3 -3
  59. package/dist/components/siyahi/change-grid.d.ts +6 -6
  60. package/dist/components/siyahi/data-bar.d.ts +2 -2
  61. package/dist/components/siyahi/data-list.d.ts +1 -1
  62. package/dist/components/siyahi/data-table-row-count.d.ts +1 -1
  63. package/dist/components/siyahi/data-table-sort-header.d.ts +1 -1
  64. package/dist/components/siyahi/delta.d.ts +2 -2
  65. package/dist/components/siyahi/drawdown-chart.d.ts +2 -2
  66. package/dist/components/siyahi/histogram-chart.d.ts +5 -5
  67. package/dist/components/siyahi/local-time.d.ts +1 -1
  68. package/dist/components/siyahi/{page-hero.d.ts → page-header.d.ts} +3 -3
  69. package/dist/components/siyahi/{page-hero.js → page-header.js} +4 -4
  70. package/dist/components/siyahi/page-section.d.ts +1 -1
  71. package/dist/components/siyahi/page-toc.d.ts +2 -2
  72. package/dist/components/siyahi/panel-grid.d.ts +7 -4
  73. package/dist/components/siyahi/panel-grid.js +1 -1
  74. package/dist/components/siyahi/price-chart.d.ts +1 -1
  75. package/dist/components/siyahi/range-position.d.ts +5 -5
  76. package/dist/components/siyahi/range-position.js +1 -1
  77. package/dist/components/siyahi/scale-toggle.d.ts +2 -2
  78. package/dist/components/siyahi/scatter-chart.d.ts +15 -15
  79. package/dist/components/siyahi/scatter-chart.js +14 -1
  80. package/dist/components/siyahi/siyahi-provider.d.ts +3 -2
  81. package/dist/components/siyahi/siyahi-provider.js +1 -4
  82. package/dist/components/siyahi/slope-chart.d.ts +4 -4
  83. package/dist/components/siyahi/status-alert.d.ts +1 -1
  84. package/dist/components/siyahi/status-badge.d.ts +1 -1
  85. package/dist/components/siyahi/target-rows.d.ts +6 -6
  86. package/dist/components/siyahi/target-rows.js +2 -2
  87. package/dist/components/siyahi/treemap.d.ts +8 -8
  88. package/dist/components/siyahi/treemap.js +0 -3
  89. package/dist/components/siyahi/waterfall-chart.d.ts +3 -3
  90. package/dist/index.d.ts +2 -2
  91. package/dist/index.js +2 -2
  92. package/dist/lib/chart-frame.d.ts +48 -20
  93. package/dist/lib/chart-frame.js +60 -30
  94. package/dist/lib/chart-marks.d.ts +2 -2
  95. package/dist/lib/chart-series.d.ts +25 -24
  96. package/dist/lib/format.d.ts +1 -1
  97. package/dist/lib/optional.d.ts +7 -0
  98. package/dist/lib/optional.js +0 -0
  99. package/dist/lib/scatter.d.ts +7 -7
  100. package/dist/lib/ticks.d.ts +9 -0
  101. package/dist/lib/ticks.js +25 -3
  102. package/dist/lib/treemap.d.ts +1 -1
  103. package/dist/lib/use-render-when-fonts-load.d.ts +11 -0
  104. package/dist/lib/use-render-when-fonts-load.js +49 -0
  105. package/package.json +2 -2
  106. package/report.css +1 -0
  107. package/styles/siyahi.css +51 -4
@@ -14,7 +14,7 @@ export interface ChartSeriesItem<T> {
14
14
  label: string;
15
15
  color: ChartColor;
16
16
  /** A bar below zero takes this colour instead, such as var(--negative) for a loss beside var(--positive). */
17
- negativeColor?: ChartColor;
17
+ negativeColor?: ChartColor | undefined;
18
18
  }
19
19
  /**
20
20
  * The series in draw, stack and legend order; give the slots in order from
@@ -28,16 +28,16 @@ export type ChartSeries<T> = readonly ChartSeriesItem<T>[];
28
28
  */
29
29
  export type ChartReferenceLine = ({
30
30
  y: number;
31
- x?: never;
31
+ x?: never | undefined;
32
32
  } | {
33
33
  x: number | string;
34
- y?: never;
34
+ y?: never | undefined;
35
35
  }) & {
36
- label?: string;
36
+ label?: string | undefined;
37
37
  /** "strong" draws it in the text colour, for the line that matters most; "muted" by default. */
38
- emphasis?: "muted" | "strong";
38
+ emphasis?: "muted" | "strong" | undefined;
39
39
  /** Where the label sits against the line. Defaults to insideTopLeft. */
40
- labelPosition?: "insideTopLeft" | "insideTopRight" | "insideBottomLeft" | "insideBottomRight";
40
+ labelPosition?: "insideTopLeft" | "insideTopRight" | "insideBottomLeft" | "insideBottomRight" | undefined;
41
41
  };
42
42
  /** What BarChartCard, AreaChartCard and LineChartCard all take. */
43
43
  export interface SeriesChartProps<T extends object, K extends keyof T> {
@@ -51,35 +51,36 @@ export interface SeriesChartProps<T extends object, K extends keyof T> {
51
51
  xKey: K;
52
52
  series: ChartSeries<NoInfer<T>>;
53
53
  /** Categories to label, or tick positions with xDomain. Every named tick is drawn; other rows keep their marks and tooltips. */
54
- xTicks?: readonly T[K][];
54
+ xTicks?: readonly T[K][] | undefined;
55
55
  /** The x axis ticks, and the tooltip's heading unless xTooltipFormatter is set. Defaults to the value as text. */
56
- xFormatter?: (value: T[K]) => string;
56
+ xFormatter?: ((value: T[K]) => string) | undefined;
57
57
  /** The tooltip's heading, when it should say more than a tick: "19:34:13 IST, 10 s average" against "19:34". */
58
- xTooltipFormatter?: (value: T[K]) => string;
58
+ xTooltipFormatter?: ((value: T[K]) => string) | undefined;
59
59
  /** A series' value in the tooltip, and the y axis unless yTickFormatter is set. Defaults to the locale's numbers. */
60
- valueFormatter?: (value: number) => string;
60
+ valueFormatter?: ((value: number) => string) | undefined;
61
61
  /**
62
62
  * The y axis, when its ticks should be shorter than the tooltip's figures: moneyCompact against money. It gets the
63
63
  * axis' largest tick as `scale`, so moneyCompact writes every tick in one unit.
64
64
  */
65
- yTickFormatter?: (value: number, scale: number) => string;
65
+ yTickFormatter?: ((value: number, scale: number) => string) | undefined;
66
66
  /**
67
- * A fixed range for the value axis, such as [0, 100] for a percentage. By default it fits the data; a bar
68
- * chart's always reaches zero.
67
+ * A fixed range for the value axis, such as [0, 100] for a percentage. By default the axis ends on the round
68
+ * ticks that just cover the data (a 46,800 peak ends at 50,000), a stack's totals for a stack, and a bar chart's
69
+ * always reaches zero.
69
70
  */
70
- yDomain?: [number, number];
71
+ yDomain?: [number, number] | undefined;
71
72
  /** Where the value axis puts its ticks, such as [0, 25, 50, 75, 100]. */
72
- yTicks?: readonly number[];
73
+ yTicks?: readonly number[] | undefined;
73
74
  /** Height of the plot and legend, in pixels. Sideways bars grow when wrapped tick details need more room. */
74
75
  height: number;
75
76
  /** A second line under each x tick, so a row's figure reads without a hover: "FY24" then "+₹1.2L". */
76
- xTickDetail?: (row: T) => string;
77
+ xTickDetail?: ((row: T) => string) | undefined;
77
78
  /** A title under the x axis, such as "Hour of day (IST)". Not drawn on sideways bars. */
78
- xLabel?: string;
79
+ xLabel?: string | undefined;
79
80
  /** A title beside the value axis, read bottom to top, such as "Orders". Not drawn on sideways bars. */
80
- yLabel?: string;
81
+ yLabel?: string | undefined;
81
82
  /** Limits and events to mark on the plot. A zero line draws by itself when a value goes below zero. */
82
- referenceLines?: readonly ChartReferenceLine[];
83
+ referenceLines?: readonly ChartReferenceLine[] | undefined;
83
84
  /** Shown in the plot's place, at its height, while the data loads or after it failed to. */
84
85
  placeholder?: ReactNode;
85
86
  /** Lines under the chart, such as a caption or a takeaway, in the card's footer. */
@@ -96,14 +97,14 @@ export interface LineMarksProps<T extends object, K extends keyof T> {
96
97
  * The x value from which the data is a forecast, such as the last month-end: each line goes dashed from it, a faint
97
98
  * hatched band labelled FORECAST covers the stretch, and the end dots are hollow.
98
99
  */
99
- forecastFrom?: NoInfer<T[K]>;
100
+ forecastFrom?: NoInfer<T[K]> | undefined;
100
101
  /** The x value of today: a 1px rule in the link colour with a small TODAY label. */
101
- today?: NoInfer<T[K]>;
102
+ today?: NoInfer<T[K]> | undefined;
102
103
  }
103
104
  /** A numeric x axis, for samples in time or any measure where a mark can sit between two rows. */
104
105
  export interface NumericXProps {
105
106
  /** The x axis runs over this range of the xKey field, which must hold numbers; without it the axis is one slot per row. */
106
- xDomain?: [number, number];
107
+ xDomain?: [number, number] | undefined;
107
108
  }
108
109
  /** A value axis that may run on a log scale: lines and areas, which need not start at zero as bars must. */
109
110
  export interface ValueScaleProps {
@@ -112,9 +113,9 @@ export interface ValueScaleProps {
112
113
  * yScaleToggle is set. Log draws only when every value, and yDomain, is above zero; otherwise the axis is linear.
113
114
  * On log the axis ticks at 1, 2 and 5 inside yDomain, if given, and yTicks is not used.
114
115
  */
115
- yScale?: AxisScale;
116
+ yScale?: AxisScale | undefined;
116
117
  /** Linear and Log buttons for the value axis in the header, after the action, so a reader can switch. */
117
- yScaleToggle?: boolean;
118
+ yScaleToggle?: boolean | undefined;
118
119
  }
119
120
  /**
120
121
  * How a line or an area's edge joins its points: "linear" draws straight segments, as measured samples should
@@ -19,7 +19,7 @@ export declare function count(value: number, locale?: SiyahiLocale): string;
19
19
  export declare function pct(value: number, locale?: SiyahiLocale, fractionDigits?: number): string;
20
20
  export interface TimeOptions {
21
21
  /** Write the date, in the same zone, before the time: 20 Oct 2026, 14:30 IST. */
22
- withDate?: boolean;
22
+ withDate?: boolean | undefined;
23
23
  }
24
24
  /** A 24-hour time in the locale's zone, with the zone written: 14:30 IST. */
25
25
  export declare function time(value: Date | number | string, locale?: SiyahiLocale, { withDate }?: TimeOptions): string;
@@ -0,0 +1,7 @@
1
+ //#region src/lib/optional.d.ts
2
+ /**
3
+ * Every prop of T optional and taking undefined too, where `Partial<T>` under exactOptionalPropertyTypes takes only
4
+ * a missing prop: for settings a page passes some of, such as `locale={{ currency: usd ? "USD" : undefined }}`.
5
+ */
6
+ export type Optional<T> = { [K in keyof T]?: T[K] | undefined; };
7
+ //#endregion
File without changes
@@ -42,11 +42,11 @@ export interface ScatterQuadrants {
42
42
  x: number;
43
43
  y: number;
44
44
  labels?: {
45
- topLeft?: string;
46
- topRight?: string;
47
- bottomLeft?: string;
48
- bottomRight?: string;
49
- };
45
+ topLeft?: string | undefined;
46
+ topRight?: string | undefined;
47
+ bottomLeft?: string | undefined;
48
+ bottomRight?: string | undefined;
49
+ } | undefined;
50
50
  }
51
51
  export type QuadrantLabels = ScatterQuadrants["labels"];
52
52
  /** A split a log axis cannot place, at or below zero, or one that is not a number, is no split at all. */
@@ -58,10 +58,10 @@ export declare const MAX_RADIUS = 20;
58
58
  * nothing draws the smallest dot, so it cannot shrink or hide the others. Points without sizes all take `plain`.
59
59
  */
60
60
  export declare function dotSizes(points: readonly {
61
- size?: number;
61
+ size?: number | undefined;
62
62
  }[], plain: number): {
63
63
  radiusOf: (p: {
64
- size?: number;
64
+ size?: number | undefined;
65
65
  }) => number;
66
66
  sized: boolean;
67
67
  };
@@ -10,6 +10,15 @@ export declare function logTicks(min: number, max: number): number[];
10
10
  * noise, such as 0.3 and 0.30000000000000004, count as one value and get that value as their only tick.
11
11
  */
12
12
  export declare function linearTicks(min: number, max: number, count?: number): number[];
13
+ /**
14
+ * A value axis' ends and ticks: the round ticks that just cover the values, and their outer two as the ends. About
15
+ * six, not five, so a 46,800 peak ends at 50,000 by 10,000s rather than at 60,000 by 20,000s. None when the values
16
+ * span no range (no values, or one), which leaves the axis to the chart.
17
+ */
18
+ export declare function linearAxis(values: readonly number[]): {
19
+ domain: [number, number];
20
+ ticks: number[];
21
+ } | undefined;
13
22
  /** How an axis spaces its values: evenly, or by powers of ten for values that run from tiny to large. */
14
23
  export type AxisScale = "linear" | "log";
15
24
  /** An axis' ticks for its scale: round steps either way, so a linear axis starting at 0.4% reads 0%, 5%, 10%. */
package/dist/lib/ticks.js CHANGED
@@ -39,6 +39,29 @@ function linearTicks(min, max, count = 5) {
39
39
  const last = Math.ceil(max / step - 1e-9);
40
40
  return Array.from({ length: last - first + 1 }, (_, i) => clean((first + i) * step));
41
41
  }
42
+ /** The smallest and largest value, by a loop: Math.min(...values) overflows the call stack past about 100,000. */
43
+ function extent(values) {
44
+ let low = Number.POSITIVE_INFINITY;
45
+ let high = Number.NEGATIVE_INFINITY;
46
+ for (const value of values) {
47
+ low = Math.min(low, value);
48
+ high = Math.max(high, value);
49
+ }
50
+ return [low, high];
51
+ }
52
+ /**
53
+ * A value axis' ends and ticks: the round ticks that just cover the values, and their outer two as the ends. About
54
+ * six, not five, so a 46,800 peak ends at 50,000 by 10,000s rather than at 60,000 by 20,000s. None when the values
55
+ * span no range (no values, or one), which leaves the axis to the chart.
56
+ */
57
+ function linearAxis(values) {
58
+ const ticks = linearTicks(...extent(values), 6);
59
+ const [low, high] = [ticks[0], ticks.at(-1)];
60
+ return low !== void 0 && high !== void 0 && low < high ? {
61
+ domain: [low, high],
62
+ ticks
63
+ } : void 0;
64
+ }
42
65
  /** An axis' ticks for its scale: round steps either way, so a linear axis starting at 0.4% reads 0%, 5%, 10%. */
43
66
  const ticksFor = (scale, min, max) => scale === "log" ? logTicks(min, max) : linearTicks(min, max);
44
67
  /** A log axis has no place for zero or below, so it can draw a set of values only when every one is above zero. */
@@ -55,8 +78,7 @@ function logAxis(values, range) {
55
78
  ticks: logTicks(low, high).filter((tick) => tick >= low && tick <= high)
56
79
  };
57
80
  }
58
- const low = Math.min(...values);
59
- const high = Math.max(...values);
81
+ const [low, high] = extent(values);
60
82
  const ticks = logTicks(low, high);
61
83
  return {
62
84
  domain: [ticks[0] ?? low, ticks.at(-1) ?? high],
@@ -64,4 +86,4 @@ function logAxis(values, range) {
64
86
  };
65
87
  }
66
88
  //#endregion
67
- export { fitsLog, linearTicks, logAxis, logTicks, ticksFor };
89
+ export { fitsLog, linearAxis, linearTicks, logAxis, logTicks, ticksFor };
@@ -16,7 +16,7 @@ export interface Layout<T> {
16
16
  /** Squarified layout: items without a group are tiles of their own, the rest sit together under their group's label. */
17
17
  export declare function layout<T extends {
18
18
  weight: number;
19
- group?: string;
19
+ group?: string | undefined;
20
20
  }>(items: T[], width: number, height: number): Layout<T>;
21
21
  //#endregion
22
22
  export {};
@@ -0,0 +1,11 @@
1
+ //#region src/lib/use-render-when-fonts-load.d.ts
2
+ /** How many font loads the page has finished: a width a canvas measured before the last one may be the fallback's. */
3
+ export declare function fontLoads(): number;
4
+ /**
5
+ * Renders the component again when a font load changes what `measure` returns: the width of the component's own
6
+ * text, measured on a canvas. Any face may change it, whenever it loads: Geist after the fallback, a subset for other
7
+ * characters, another family. A load that changes nothing the component measures leaves it alone, as Recharts redraws
8
+ * a chart's marks on every render and their fade-in would play again.
9
+ */
10
+ export declare function useRenderWhenFontsLoad(measure: () => number | string): void;
11
+ //#endregion
@@ -0,0 +1,49 @@
1
+ import { useLayoutEffect, useReducer, useRef } from "react";
2
+ //#region src/lib/use-render-when-fonts-load.ts
3
+ let loads = 0;
4
+ const counted = /* @__PURE__ */ new WeakSet();
5
+ /** How many font loads the page has finished: a width a canvas measured before the last one may be the fallback's. */
6
+ function fontLoads() {
7
+ if (typeof document !== "undefined" && document.fonts && !counted.has(document.fonts)) {
8
+ counted.add(document.fonts);
9
+ document.fonts.addEventListener("loadingdone", () => loads++);
10
+ }
11
+ return loads;
12
+ }
13
+ /**
14
+ * Renders the component again when a font load changes what `measure` returns: the width of the component's own
15
+ * text, measured on a canvas. Any face may change it, whenever it loads: Geist after the fallback, a subset for other
16
+ * characters, another family. A load that changes nothing the component measures leaves it alone, as Recharts redraws
17
+ * a chart's marks on every render and their fade-in would play again.
18
+ */
19
+ function useRenderWhenFontsLoad(measure) {
20
+ const drawn = measure();
21
+ const seen = fontLoads();
22
+ const committed = useRef({
23
+ measure,
24
+ drawn
25
+ });
26
+ const [, render] = useReducer((count) => count + 1, 0);
27
+ useLayoutEffect(() => {
28
+ committed.current = {
29
+ measure,
30
+ drawn
31
+ };
32
+ if (fontLoads() !== seen && measure() !== drawn) render();
33
+ }, [
34
+ measure,
35
+ drawn,
36
+ seen
37
+ ]);
38
+ useLayoutEffect(() => {
39
+ const fonts = document.fonts;
40
+ if (!fonts) return;
41
+ const recheck = () => {
42
+ if (committed.current.measure() !== committed.current.drawn) render();
43
+ };
44
+ fonts.addEventListener("loadingdone", recheck);
45
+ return () => fonts.removeEventListener("loadingdone", recheck);
46
+ }, []);
47
+ }
48
+ //#endregion
49
+ export { fontLoads, useRenderWhenFontsLoad };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@siyahi/ui",
3
- "version": "0.1.9-next.32",
3
+ "version": "0.1.9-next.34",
4
4
  "description": "Stock shadcn/ui on Base UI and Tailwind v4, a finance theme, a few compositions and formatters.",
5
5
  "keywords": [
6
6
  "base-ui",
@@ -81,6 +81,6 @@
81
81
  },
82
82
  "scripts": {
83
83
  "build": "node ../tools/contrast.mjs styles/siyahi.css && vp pack",
84
- "typecheck": "tsc --noEmit"
84
+ "typecheck": "tsc --noEmit && tsc -p test/types"
85
85
  }
86
86
  }
package/report.css CHANGED
@@ -38,6 +38,7 @@
38
38
  --wash: 7%;
39
39
  --wash-edge: 45%;
40
40
  --field-wash: 8%;
41
+ --bar-tint: 50%;
41
42
  --link: oklch(0.51 0.2 275);
42
43
  --chart-1: oklch(0.4 0.17 275);
43
44
  --chart-2: oklch(0.66 0.13 70);
package/styles/siyahi.css CHANGED
@@ -140,6 +140,12 @@
140
140
  --wash-edge: 45%;
141
141
  /* An invalid field's wash: this share of --destructive over the card. */
142
142
  --field-wash: 8%;
143
+ /*
144
+ * Every bar takes this share of its colour over the card, inside a 1px edge of the full colour (lib/chart-frame
145
+ * barFill). At 25% a pale slot's bar barely left the card and a thin stacked segment was two edge lines; the
146
+ * contrast check holds each bar colour's tint against the card and each slot's against the next slot's.
147
+ */
148
+ --bar-tint: 50%;
143
149
  --link: oklch(0.51 0.2 275);
144
150
  /*
145
151
  * Indigo, amber, plum, sky, teal: no green or red, so no series reads as a
@@ -220,6 +226,7 @@
220
226
  --wash: 12%;
221
227
  --wash-edge: 55%;
222
228
  --field-wash: 12%;
229
+ --bar-tint: 50%;
223
230
  --link: oklch(0.75 0.128 275);
224
231
  --chart-1: oklch(0.58 0.2 275);
225
232
  --chart-2: oklch(0.88 0.08 75);
@@ -265,13 +272,15 @@
265
272
  * foreground, black on white and white on black, so the reader sees at once
266
273
  * what is on; stock shadcn marks it with a faint grey. A default (pill) tab
267
274
  * selects the same way: stock fills it with the canvas colour, 1.05:1 against
268
- * its grey list. Unlayered, to outrank the stock aria-pressed:bg-muted.
275
+ * its grey list, lifted on a drop shadow, which the fill makes needless. Unlayered, to outrank the stock
276
+ * aria-pressed:bg-muted.
269
277
  */
270
278
  :is([data-slot="toggle"], [data-slot="toggle-group-item"]):is([aria-pressed="true"], [data-pressed]),
271
279
  [data-slot="tabs-list"][data-variant="default"] [data-slot="tabs-trigger"][data-active] {
272
280
  background-color: var(--foreground);
273
281
  color: var(--background);
274
282
  border-color: var(--foreground);
283
+ --tw-shadow: 0 0 #0000;
275
284
  }
276
285
 
277
286
  /*
@@ -476,8 +485,47 @@ svg :is(rect, circle, path)[tabindex]:focus-visible,
476
485
  @apply font-mono text-2xs tracking-wider text-muted-foreground uppercase;
477
486
  }
478
487
 
479
- /* Progress is a bar, square as every bar is; stock draws it as a pill. */
480
- [data-slot="progress-track"] {
488
+ /* A group's label in a menu, a select's list or the command palette is a label over its items, set as one. */
489
+ :is(
490
+ [data-slot="dropdown-menu-label"],
491
+ [data-slot="context-menu-label"],
492
+ [data-slot="select-label"],
493
+ [data-slot="command-group"] [cmdk-group-heading]
494
+ ) {
495
+ @apply font-mono text-2xs tracking-wider text-muted-foreground uppercase;
496
+ }
497
+
498
+ /*
499
+ * A menu, a select's list, a popover, a dialog, a sheet and a chart's tooltip read as a sheet of the page, not a
500
+ * bubble floating over it: no drop shadow, and the card's hairline for an edge (stock rings them fainter).
501
+ */
502
+ :is(
503
+ [data-slot="dropdown-menu-content"],
504
+ [data-slot="dropdown-menu-sub-content"],
505
+ [data-slot="context-menu-content"],
506
+ [data-slot="context-menu-sub-content"],
507
+ [data-slot="select-content"],
508
+ [data-slot="popover-content"],
509
+ [data-slot="dialog-content"],
510
+ [data-slot="sheet-content"],
511
+ [data-slot="chart"] .recharts-tooltip-wrapper > div
512
+ ) {
513
+ --tw-shadow: 0 0 #0000;
514
+ --tw-ring-color: var(--border);
515
+ border-color: var(--border);
516
+ }
517
+
518
+ /*
519
+ * Square as every box is: progress, a slider's track and thumb, a scrollbar's thumb, and the colour chips core's
520
+ * chart tooltip and legend draw at a fixed 2px, which no radius token reaches.
521
+ */
522
+ :is(
523
+ [data-slot="progress-track"],
524
+ [data-slot="slider-track"],
525
+ [data-slot="slider-thumb"],
526
+ [data-slot="scroll-area-thumb"],
527
+ [data-slot="chart"] :is(.recharts-tooltip-wrapper, .recharts-legend-wrapper) [class~="rounded-[2px]"]
528
+ ) {
481
529
  border-radius: 0;
482
530
  }
483
531
 
@@ -750,7 +798,6 @@ div[data-slot="sidebar"]:not([data-side], [data-mobile]) {
750
798
  inset-block: 2px;
751
799
  left: -11px;
752
800
  width: 2px;
753
- border-radius: 1px;
754
801
  background: var(--sidebar-accent-foreground);
755
802
  }
756
803