@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.
- package/DESIGN.md +20 -7
- package/agents/examples/chart-panels-three.tsx +51 -0
- package/agents/examples/context-menu.tsx +14 -4
- package/agents/examples/overview-dashboard.tsx +2 -2
- package/agents/examples/{page-hero.tsx → page-header.tsx} +4 -4
- package/agents/examples/select.tsx +2 -1
- package/agents/manifest.json +16 -3
- package/dist/components/registry/charts/area-chart-card.d.ts +2 -2
- package/dist/components/registry/charts/area-chart-card.js +1 -0
- package/dist/components/registry/charts/bar-chart-card.d.ts +4 -4
- package/dist/components/registry/charts/bar-chart-card.js +0 -2
- package/dist/components/registry/charts/line-chart-card.d.ts +1 -1
- package/dist/components/registry/dashboard-01/section-cards.d.ts +4 -4
- package/dist/components/registry/dashboardcn/bar-list.d.ts +8 -8
- package/dist/components/registry/dashboardcn/distribution-bar.d.ts +11 -11
- package/dist/components/registry/dashboardcn/kpi-row-card.d.ts +4 -4
- package/dist/components/registry/dashboardcn/sparkline.d.ts +6 -6
- package/dist/components/registry/heatmap/calendar-heatmap.d.ts +50 -50
- package/dist/components/registry/heatmap/calendar-heatmap.js +1 -1
- package/dist/components/registry/heatmap/status-heatmap.d.ts +44 -44
- package/dist/components/registry/heatmap/status-heatmap.js +1 -1
- package/dist/components/registry/heatmap/weekday-heatmap.d.ts +53 -53
- package/dist/components/registry/heatmap/weekday-heatmap.js +1 -1
- package/dist/components/registry/minidev/copy-button.d.ts +2 -2
- package/dist/components/registry/niko-table/components/data-table-column-actions.d.ts +1 -1
- package/dist/components/registry/niko-table/components/data-table-column-filter.d.ts +1 -1
- package/dist/components/registry/niko-table/components/data-table-empty-state.d.ts +7 -7
- package/dist/components/registry/niko-table/components/data-table-faceted-filter.d.ts +5 -5
- package/dist/components/registry/niko-table/components/data-table-grouped-rows.d.ts +1 -1
- package/dist/components/registry/niko-table/components/data-table-row-context-menu-slot.d.ts +1 -1
- package/dist/components/registry/niko-table/components/data-table-row-context-menu.d.ts +1 -1
- package/dist/components/registry/niko-table/config/feature-detection.d.ts +13 -13
- package/dist/components/registry/niko-table/core/data-table-context.d.ts +5 -5
- package/dist/components/registry/niko-table/core/data-table-error-boundary.d.ts +3 -3
- package/dist/components/registry/niko-table/core/data-table-grouped-row.d.ts +2 -2
- package/dist/components/registry/niko-table/core/data-table-root.d.ts +36 -35
- package/dist/components/registry/niko-table/core/data-table-structure.d.ts +22 -22
- package/dist/components/registry/niko-table/core/data-table-structure.js +6 -0
- package/dist/components/registry/niko-table/core/data-table.d.ts +3 -3
- package/dist/components/registry/niko-table/core/data-table.js +1 -1
- package/dist/components/registry/niko-table/filters/table-column-actions.d.ts +5 -5
- package/dist/components/registry/niko-table/filters/table-column-sort.d.ts +6 -6
- package/dist/components/registry/niko-table/filters/table-column-sort.js +2 -2
- package/dist/components/registry/niko-table/filters/table-column-title.d.ts +2 -2
- package/dist/components/registry/niko-table/filters/table-faceted-filter.d.ts +9 -9
- package/dist/components/registry/niko-table/filters/table-faceted-filter.js +1 -1
- package/dist/components/registry/niko-table/filters/table-search-filter.d.ts +7 -7
- package/dist/components/registry/niko-table/hooks/use-generated-options.d.ts +7 -7
- package/dist/components/registry/niko-table/lib/build-faceted-options.d.ts +2 -2
- package/dist/components/registry/niko-table/lib/column-resize-handle.d.ts +3 -3
- package/dist/components/registry/niko-table/lib/column-resize-handle.js +1 -1
- package/dist/components/registry/niko-table/lib/create-scroll-handler.d.ts +4 -4
- package/dist/components/registry/niko-table/types/index.d.ts +29 -29
- package/dist/components/registry/sidebar-07/app-sidebar.d.ts +6 -5
- package/dist/components/registry/sidebar-07/nav-main.d.ts +4 -4
- package/dist/components/registry/sidebar-07/nav-user.js +16 -19
- package/dist/components/siyahi/callout.d.ts +1 -1
- package/dist/components/siyahi/change-bar.d.ts +3 -3
- package/dist/components/siyahi/change-grid.d.ts +6 -6
- package/dist/components/siyahi/data-bar.d.ts +2 -2
- package/dist/components/siyahi/data-list.d.ts +1 -1
- package/dist/components/siyahi/data-table-row-count.d.ts +1 -1
- package/dist/components/siyahi/data-table-sort-header.d.ts +1 -1
- package/dist/components/siyahi/delta.d.ts +2 -2
- package/dist/components/siyahi/drawdown-chart.d.ts +2 -2
- package/dist/components/siyahi/histogram-chart.d.ts +5 -5
- package/dist/components/siyahi/local-time.d.ts +1 -1
- package/dist/components/siyahi/{page-hero.d.ts → page-header.d.ts} +3 -3
- package/dist/components/siyahi/{page-hero.js → page-header.js} +4 -4
- package/dist/components/siyahi/page-section.d.ts +1 -1
- package/dist/components/siyahi/page-toc.d.ts +2 -2
- package/dist/components/siyahi/panel-grid.d.ts +7 -4
- package/dist/components/siyahi/panel-grid.js +1 -1
- package/dist/components/siyahi/price-chart.d.ts +1 -1
- package/dist/components/siyahi/range-position.d.ts +5 -5
- package/dist/components/siyahi/range-position.js +1 -1
- package/dist/components/siyahi/scale-toggle.d.ts +2 -2
- package/dist/components/siyahi/scatter-chart.d.ts +15 -15
- package/dist/components/siyahi/scatter-chart.js +14 -1
- package/dist/components/siyahi/siyahi-provider.d.ts +3 -2
- package/dist/components/siyahi/siyahi-provider.js +1 -4
- package/dist/components/siyahi/slope-chart.d.ts +4 -4
- package/dist/components/siyahi/status-alert.d.ts +1 -1
- package/dist/components/siyahi/status-badge.d.ts +1 -1
- package/dist/components/siyahi/target-rows.d.ts +6 -6
- package/dist/components/siyahi/target-rows.js +2 -2
- package/dist/components/siyahi/treemap.d.ts +8 -8
- package/dist/components/siyahi/treemap.js +0 -3
- package/dist/components/siyahi/waterfall-chart.d.ts +3 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/lib/chart-frame.d.ts +48 -20
- package/dist/lib/chart-frame.js +60 -30
- package/dist/lib/chart-marks.d.ts +2 -2
- package/dist/lib/chart-series.d.ts +25 -24
- package/dist/lib/format.d.ts +1 -1
- package/dist/lib/optional.d.ts +7 -0
- package/dist/lib/optional.js +0 -0
- package/dist/lib/scatter.d.ts +7 -7
- package/dist/lib/ticks.d.ts +9 -0
- package/dist/lib/ticks.js +25 -3
- package/dist/lib/treemap.d.ts +1 -1
- package/dist/lib/use-render-when-fonts-load.d.ts +11 -0
- package/dist/lib/use-render-when-fonts-load.js +49 -0
- package/package.json +2 -2
- package/report.css +1 -0
- 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
|
|
68
|
-
*
|
|
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
|
package/dist/lib/format.d.ts
CHANGED
|
@@ -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
|
package/dist/lib/scatter.d.ts
CHANGED
|
@@ -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
|
};
|
package/dist/lib/ticks.d.ts
CHANGED
|
@@ -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 =
|
|
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 };
|
package/dist/lib/treemap.d.ts
CHANGED
|
@@ -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.
|
|
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
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
|
|
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
|
-
/*
|
|
480
|
-
|
|
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
|
|