@siyahi/ui 0.1.9-next.3 → 0.1.9-next.31
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 +251 -0
- package/README.md +94 -177
- package/THIRD_PARTY_NOTICES.md +11 -11
- package/agents/examples/accordion.tsx +39 -0
- package/agents/examples/alert.tsx +24 -0
- package/agents/examples/app-sidebar.tsx +40 -0
- package/agents/examples/avatar.tsx +24 -0
- package/agents/examples/badge.tsx +26 -0
- package/agents/examples/bar-list-labels.tsx +22 -0
- package/agents/examples/bar-list-sides.tsx +40 -0
- package/agents/examples/bar-list.tsx +24 -0
- package/agents/examples/breadcrumb.tsx +28 -0
- package/agents/examples/button-states.tsx +23 -0
- package/agents/examples/button.tsx +21 -0
- package/agents/examples/calendar.tsx +11 -0
- package/agents/examples/callout.tsx +33 -0
- package/agents/examples/card.tsx +36 -0
- package/agents/examples/change-bar.tsx +104 -0
- package/agents/examples/change-grid-money.tsx +36 -0
- package/agents/examples/change-grid.tsx +43 -0
- package/agents/examples/chart-area-log.tsx +45 -0
- package/agents/examples/chart-area.tsx +39 -0
- package/agents/examples/chart-bar-flows.tsx +32 -0
- package/agents/examples/chart-bar-hourly.tsx +28 -0
- package/agents/examples/chart-bar-losses.tsx +29 -0
- package/agents/examples/chart-bar-teams.tsx +72 -0
- package/agents/examples/chart-bar-years.tsx +42 -0
- package/agents/examples/chart-bar.tsx +56 -0
- package/agents/examples/chart-category-ticks.tsx +50 -0
- package/agents/examples/chart-line-events.tsx +47 -0
- package/agents/examples/chart-line-forecast.tsx +36 -0
- package/agents/examples/chart-line-log.tsx +39 -0
- package/agents/examples/chart-line-quiet.tsx +114 -0
- package/agents/examples/chart-line-timeline.tsx +41 -0
- package/agents/examples/chart-line.tsx +57 -0
- package/agents/examples/chart-panels.tsx +94 -0
- package/agents/examples/code-block.tsx +40 -0
- package/agents/examples/collapsible.tsx +18 -0
- package/agents/examples/command.tsx +29 -0
- package/agents/examples/context-menu.tsx +17 -0
- package/agents/examples/copy-button.tsx +8 -0
- package/agents/examples/data-bar.tsx +114 -0
- package/agents/examples/data-table-compact.tsx +93 -0
- package/agents/examples/data-table-filters.tsx +103 -0
- package/agents/examples/data-table.tsx +96 -0
- package/agents/examples/delta.tsx +18 -0
- package/agents/examples/dialog.tsx +28 -0
- package/agents/examples/distribution-bar-budget.tsx +30 -0
- package/agents/examples/distribution-bar-tug.tsx +74 -0
- package/agents/examples/drawdown-chart.tsx +35 -0
- package/agents/examples/dropdown-menu.tsx +31 -0
- package/agents/examples/field.tsx +108 -0
- package/agents/examples/formatters.tsx +42 -0
- package/agents/examples/heatmap-calendar-signed.tsx +67 -0
- package/agents/examples/heatmap-calendar.tsx +62 -0
- package/agents/examples/heatmap-status.tsx +61 -0
- package/agents/examples/heatmap-weekday.tsx +72 -0
- package/agents/examples/histogram-chart.tsx +28 -0
- package/agents/examples/input-states.tsx +23 -0
- package/agents/examples/input.tsx +17 -0
- package/agents/examples/local-time.tsx +14 -0
- package/agents/examples/metric-strip.tsx +46 -0
- package/agents/examples/overview-dashboard.tsx +180 -0
- package/agents/examples/page-hero.tsx +38 -0
- package/agents/examples/page-section.tsx +52 -0
- package/agents/examples/popover.tsx +23 -0
- package/agents/examples/price-chart.tsx +32 -0
- package/agents/examples/progress-tone.tsx +29 -0
- package/agents/examples/progress.tsx +10 -0
- package/agents/examples/range-position-table.tsx +113 -0
- package/agents/examples/range-position.tsx +55 -0
- package/agents/examples/scatter-chart-quadrants.tsx +63 -0
- package/agents/examples/scatter-chart-scales.tsx +46 -0
- package/agents/examples/scatter-chart.tsx +78 -0
- package/agents/examples/scroll-area.tsx +22 -0
- package/agents/examples/section-cards-select.tsx +28 -0
- package/agents/examples/section-cards-trend.tsx +32 -0
- package/agents/examples/section-cards.tsx +48 -0
- package/agents/examples/select.tsx +27 -0
- package/agents/examples/separator.tsx +13 -0
- package/agents/examples/sheet.tsx +15 -0
- package/agents/examples/skeleton.tsx +11 -0
- package/agents/examples/slider.tsx +5 -0
- package/agents/examples/slope-chart-market.tsx +33 -0
- package/agents/examples/slope-chart.tsx +26 -0
- package/agents/examples/stale-blocks.tsx +56 -0
- package/agents/examples/surfaces.tsx +116 -0
- package/agents/examples/table.tsx +60 -0
- package/agents/examples/tabs.tsx +16 -0
- package/agents/examples/target-rows.tsx +74 -0
- package/agents/examples/toggle-group.tsx +12 -0
- package/agents/examples/toggle.tsx +11 -0
- package/agents/examples/tooltip.tsx +13 -0
- package/agents/examples/treemap.tsx +93 -0
- package/agents/examples/waterfall-chart-stores.tsx +27 -0
- package/agents/examples/waterfall-chart.tsx +37 -0
- package/agents/manifest.json +1391 -0
- package/agents/report-rules.json +7 -0
- package/dist/components/registry/charts/area-chart-card.d.ts +7 -3
- package/dist/components/registry/charts/area-chart-card.js +56 -10
- package/dist/components/registry/charts/bar-chart-card.d.ts +1 -1
- package/dist/components/registry/charts/bar-chart-card.js +20 -22
- package/dist/components/registry/charts/line-chart-card.d.ts +3 -3
- package/dist/components/registry/charts/line-chart-card.js +44 -9
- package/dist/components/registry/dashboard-01/section-cards.d.ts +6 -0
- package/dist/components/registry/dashboard-01/section-cards.js +51 -35
- package/dist/components/registry/dashboardcn/bar-list.js +17 -10
- package/dist/components/registry/dashboardcn/distribution-bar.js +6 -4
- package/dist/components/registry/dashboardcn/kpi-row-card.d.ts +29 -0
- package/dist/components/registry/dashboardcn/kpi-row-card.js +81 -0
- package/dist/components/registry/dashboardcn/sparkline.d.ts +22 -0
- package/dist/components/registry/dashboardcn/sparkline.js +117 -0
- package/dist/components/registry/heatmap/calendar-heatmap.d.ts +11 -3
- package/dist/components/registry/heatmap/calendar-heatmap.js +164 -45
- package/dist/components/registry/heatmap/status-heatmap.d.ts +5 -3
- package/dist/components/registry/heatmap/status-heatmap.js +115 -54
- package/dist/components/registry/heatmap/weekday-heatmap.d.ts +9 -3
- package/dist/components/registry/heatmap/weekday-heatmap.js +83 -53
- package/dist/components/registry/niko-table/core/data-table-context.d.ts +18 -1
- package/dist/components/registry/niko-table/core/data-table-context.js +7 -1
- package/dist/components/registry/niko-table/core/data-table-grouped-row.js +3 -1
- package/dist/components/registry/niko-table/core/data-table-root.js +39 -4
- package/dist/components/registry/niko-table/core/data-table-structure.js +17 -12
- package/dist/components/registry/niko-table/core/data-table.d.ts +2 -2
- package/dist/components/registry/niko-table/core/data-table.js +5 -1
- package/dist/components/registry/niko-table/filters/table-faceted-filter.js +5 -5
- package/dist/components/registry/niko-table/filters/table-search-filter.js +1 -1
- package/dist/components/registry/niko-table/lib/flex-columns.d.ts +1 -1
- package/dist/components/registry/niko-table/lib/flex-columns.js +3 -3
- package/dist/components/registry/niko-table/lib/styles.d.ts +1 -1
- package/dist/components/registry/niko-table/lib/styles.js +3 -3
- package/dist/components/registry/niko-table/types/index.d.ts +9 -0
- package/dist/components/registry/niko-table/ui/table.js +2 -2
- package/dist/components/registry/sidebar-07/app-sidebar.d.ts +1 -1
- package/dist/components/registry/sidebar-07/app-sidebar.js +3 -1
- package/dist/components/registry/sidebar-07/nav-main.d.ts +2 -1
- package/dist/components/registry/sidebar-07/nav-main.js +16 -3
- package/dist/components/siyahi/callout.d.ts +17 -0
- package/dist/components/siyahi/callout.js +34 -0
- package/dist/components/siyahi/change-bar.d.ts +21 -0
- package/dist/components/siyahi/change-bar.js +35 -0
- package/dist/components/siyahi/change-grid.d.ts +31 -0
- package/dist/components/siyahi/change-grid.js +74 -0
- package/dist/components/siyahi/data-bar.d.ts +19 -0
- package/dist/components/siyahi/data-bar.js +29 -0
- package/dist/components/siyahi/data-table-compact-columns-toggle.d.ts +4 -0
- package/dist/components/siyahi/data-table-compact-columns-toggle.js +19 -0
- package/dist/components/siyahi/data-table-footnote.d.ts +12 -0
- package/dist/components/siyahi/data-table-footnote.js +35 -0
- package/dist/components/siyahi/default-sidebar-open.d.ts +8 -0
- package/dist/components/siyahi/default-sidebar-open.js +13 -0
- package/dist/components/siyahi/delta.d.ts +5 -1
- package/dist/components/siyahi/delta.js +14 -9
- package/dist/components/siyahi/drawdown-chart.d.ts +34 -0
- package/dist/components/siyahi/drawdown-chart.js +102 -0
- package/dist/components/siyahi/histogram-chart.d.ts +57 -0
- package/dist/components/siyahi/histogram-chart.js +134 -0
- package/dist/components/siyahi/page-hero.d.ts +23 -0
- package/dist/components/siyahi/page-hero.js +43 -0
- package/dist/components/siyahi/page-section.d.ts +4 -1
- package/dist/components/siyahi/page-section.js +6 -3
- package/dist/components/siyahi/page-toc.d.ts +20 -0
- package/dist/components/siyahi/page-toc.js +76 -0
- package/dist/components/siyahi/panel-grid.d.ts +24 -0
- package/dist/components/siyahi/panel-grid.js +37 -0
- package/dist/components/siyahi/quote.d.ts +12 -0
- package/dist/components/siyahi/quote.js +23 -0
- package/dist/components/siyahi/range-position.d.ts +24 -0
- package/dist/components/siyahi/range-position.js +105 -0
- package/dist/components/siyahi/scale-toggle.d.ts +32 -0
- package/dist/components/siyahi/scale-toggle.js +61 -0
- package/dist/components/siyahi/scatter-chart.d.ts +69 -0
- package/dist/components/siyahi/scatter-chart.js +395 -0
- package/dist/components/siyahi/siyahi-provider.d.ts +15 -2
- package/dist/components/siyahi/siyahi-provider.js +17 -4
- package/dist/components/siyahi/slope-chart.d.ts +35 -0
- package/dist/components/siyahi/slope-chart.js +159 -0
- package/dist/components/siyahi/stale-note.d.ts +9 -0
- package/dist/components/siyahi/stale-note.js +12 -0
- package/dist/components/siyahi/status-alert.d.ts +15 -0
- package/dist/components/siyahi/status-alert.js +29 -0
- package/dist/components/siyahi/status-badge.d.ts +15 -0
- package/dist/components/siyahi/status-badge.js +24 -0
- package/dist/components/siyahi/target-rows.d.ts +34 -0
- package/dist/components/siyahi/target-rows.js +97 -0
- package/dist/components/siyahi/tone-progress.d.ts +1 -1
- package/dist/components/siyahi/tone-progress.js +1 -1
- package/dist/components/siyahi/treemap.d.ts +8 -5
- package/dist/components/siyahi/treemap.js +80 -34
- package/dist/components/siyahi/waterfall-chart.d.ts +51 -0
- package/dist/components/siyahi/waterfall-chart.js +147 -0
- package/dist/components/ui/accordion.js +5 -5
- package/dist/components/ui/alert.js +2 -2
- package/dist/components/ui/badge.js +1 -1
- package/dist/components/ui/breadcrumb.js +2 -2
- package/dist/components/ui/button.js +10 -10
- package/dist/components/ui/calendar.js +1 -1
- package/dist/components/ui/card.js +4 -4
- package/dist/components/ui/chart.js +1 -1
- package/dist/components/ui/code-block.js +13 -12
- package/dist/components/ui/command.js +7 -6
- package/dist/components/ui/context-menu.js +7 -7
- package/dist/components/ui/dialog.js +5 -5
- package/dist/components/ui/dropdown-menu.js +8 -8
- package/dist/components/ui/field.d.ts +26 -0
- package/dist/components/ui/field.js +109 -0
- package/dist/components/ui/input-group.js +11 -11
- package/dist/components/ui/input.js +1 -1
- package/dist/components/ui/label.d.ts +5 -0
- package/dist/components/ui/label.js +13 -0
- package/dist/components/ui/popover.js +3 -3
- package/dist/components/ui/progress.js +1 -1
- package/dist/components/ui/select.js +6 -6
- package/dist/components/ui/sheet.js +5 -5
- package/dist/components/ui/sidebar.js +17 -18
- package/dist/components/ui/skeleton.js +1 -1
- package/dist/components/ui/slider.js +2 -2
- package/dist/components/ui/table.js +2 -2
- package/dist/components/ui/tabs.js +2 -2
- package/dist/components/ui/textarea.js +1 -1
- package/dist/components/ui/toggle-group.js +2 -2
- package/dist/components/ui/toggle.js +4 -4
- package/dist/components/ui/tooltip.js +2 -2
- package/dist/index.d.ts +35 -8
- package/dist/index.js +30 -4
- package/dist/lib/chart-frame.d.ts +51 -7
- package/dist/lib/chart-frame.js +390 -133
- package/dist/lib/chart-marks.d.ts +83 -0
- package/dist/lib/chart-marks.js +216 -0
- package/dist/lib/chart-series.d.ts +42 -10
- package/dist/lib/compact-columns.d.ts +19 -0
- package/dist/lib/compact-columns.js +55 -0
- package/dist/lib/fit-text.d.ts +6 -0
- package/dist/lib/fit-text.js +11 -0
- package/dist/lib/format.d.ts +8 -3
- package/dist/lib/format.js +55 -17
- package/dist/lib/heat.d.ts +7 -0
- package/dist/lib/heat.js +14 -0
- package/dist/lib/heatmap-navigation.d.ts +8 -0
- package/dist/lib/heatmap-navigation.js +49 -0
- package/dist/lib/scatter.d.ts +88 -0
- package/dist/lib/scatter.js +179 -0
- package/dist/lib/ticks.d.ts +27 -0
- package/dist/lib/ticks.js +67 -0
- package/dist/lib/tone.d.ts +36 -0
- package/dist/lib/tone.js +35 -0
- package/dist/lib/treemap.d.ts +0 -5
- package/dist/lib/treemap.js +1 -11
- package/dist/lib/use-element-width.d.ts +5 -0
- package/dist/lib/use-element-width.js +15 -0
- package/package.json +5 -1
- package/registry.lock.json +16 -0
- package/report.css +63 -47
- package/styles/siyahi.css +708 -55
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { cn } from "../../../lib/utils.js";
|
|
2
|
+
import { useElementWidth } from "../../../lib/use-element-width.js";
|
|
3
|
+
import { useHeatmapNavigation } from "../../../lib/heatmap-navigation.js";
|
|
2
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { Fragment as Fragment$1, createContext, use, useMemo } from "react";
|
|
5
|
+
import { Fragment as Fragment$1, createContext, use, useId, useMemo } from "react";
|
|
4
6
|
import { format } from "date-fns";
|
|
5
7
|
//#region src/components/registry/heatmap/status-heatmap.tsx
|
|
6
8
|
const DEFAULT_COLORS = {
|
|
7
9
|
0: "var(--color-secondary)",
|
|
8
|
-
1: "var(--
|
|
10
|
+
1: "var(--destructive)",
|
|
9
11
|
2: "var(--warning)",
|
|
10
|
-
3: "var(--
|
|
12
|
+
3: "color-mix(in oklab, var(--muted-foreground) 30%, transparent)"
|
|
11
13
|
};
|
|
12
14
|
const SEMANTIC_KEYS = {
|
|
13
15
|
0: "noData",
|
|
@@ -45,12 +47,32 @@ const resolveStatusLabel = (value, labels) => {
|
|
|
45
47
|
default: return `Status ${value}`;
|
|
46
48
|
}
|
|
47
49
|
};
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
const DEGRADED = 2;
|
|
51
|
+
/** A degraded day's paint: amber in the lower half of the bar, the healthy grey above it. */
|
|
52
|
+
const DegradedGradient = ({ id, colors, healthyValue }) => /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", {
|
|
53
|
+
id,
|
|
54
|
+
x1: "0",
|
|
55
|
+
y1: "0",
|
|
56
|
+
x2: "0",
|
|
57
|
+
y2: "1",
|
|
58
|
+
children: [/* @__PURE__ */ jsx("stop", {
|
|
59
|
+
offset: "0.5",
|
|
60
|
+
style: { stopColor: resolveColor(healthyValue, colors) }
|
|
61
|
+
}), /* @__PURE__ */ jsx("stop", {
|
|
62
|
+
offset: "0.5",
|
|
63
|
+
style: { stopColor: resolveColor(DEGRADED, colors) }
|
|
64
|
+
})]
|
|
65
|
+
}) });
|
|
66
|
+
const NO_DATA = 0;
|
|
67
|
+
/** A no-data day is drawn hollow unless the page gave that state a colour of its own. */
|
|
68
|
+
const isHollow = (value, colors) => value === NO_DATA && colors?.[NO_DATA] === void 0 && colors?.noData === void 0;
|
|
69
|
+
/** The outline a day carries in the field-edge colour: solid round a healthy day, dashed round a day with no data. */
|
|
70
|
+
const edgeOf = (value, healthyValue, colors) => isHollow(value, colors) ? "dashed" : value === healthyValue ? "solid" : null;
|
|
71
|
+
const blockPaint = (value, degradedId, colors) => value === DEGRADED ? { fill: `url(#${degradedId})` } : { fill: isHollow(value, colors) ? "transparent" : resolveColor(value, colors) };
|
|
53
72
|
const EMPTY_STYLE = {};
|
|
73
|
+
const LEGEND_SWATCH = 10;
|
|
74
|
+
const MIN_FITTED_BAR = 2;
|
|
75
|
+
const DEFAULT_ASPECT_RATIO = .2;
|
|
54
76
|
const StatusHeatmapContext = createContext(null);
|
|
55
77
|
const useStatusHeatmap = () => {
|
|
56
78
|
const context = use(StatusHeatmapContext);
|
|
@@ -84,15 +106,17 @@ const useStatusHeatmap = () => {
|
|
|
84
106
|
*
|
|
85
107
|
* @param data - Array of activities with date (YYYY-MM-DD) and status value (0-3)
|
|
86
108
|
* @param dateFormat - Date format string for tooltips. Default: "MMM d"
|
|
87
|
-
* @param blockAspectRatio - Width/height ratio of blocks. Default:
|
|
109
|
+
* @param blockAspectRatio - Width/height ratio of blocks. Default: bars share the full width
|
|
88
110
|
* @param colors - Custom colors for critical, degraded, and healthy states
|
|
89
111
|
*/
|
|
90
|
-
const StatusHeatmap = ({ data, dateFormat = "MMM d", blockSize = 40, blockMargin = 2, blockRadius = 2, blockAspectRatio
|
|
112
|
+
const StatusHeatmap = ({ data, dateFormat = "MMM d", blockSize = 40, blockMargin = 2, blockRadius = 2, blockAspectRatio: blockAspectRatioProp, colors, locale, labels: labelsProp, fontSize = 14, emptyState, statusValues = [
|
|
91
113
|
0,
|
|
92
114
|
1,
|
|
93
115
|
2,
|
|
94
116
|
3
|
|
95
117
|
], healthyValue = 3, style = EMPTY_STYLE, className, children, ...props }) => {
|
|
118
|
+
const [rootRef, rootWidth] = useElementWidth();
|
|
119
|
+
const degradedId = `status-degraded-${useId().replace(/[^\w-]/g, "")}`;
|
|
96
120
|
const labels = useMemo(() => ({
|
|
97
121
|
statuses: {
|
|
98
122
|
noData: "No Data",
|
|
@@ -112,10 +136,14 @@ const StatusHeatmap = ({ data, dateFormat = "MMM d", blockSize = 40, blockMargin
|
|
|
112
136
|
});
|
|
113
137
|
return Array.from(uniqueDates).sort();
|
|
114
138
|
}, [data]);
|
|
115
|
-
const
|
|
139
|
+
const fits = blockAspectRatioProp === void 0;
|
|
140
|
+
const fitted = (rootWidth - 6 + blockMargin) / Math.max(dates.length, 1) - blockMargin;
|
|
141
|
+
const blockWidth = fits && rootWidth > 0 ? Math.max(MIN_FITTED_BAR, fitted) : blockSize * (blockAspectRatioProp ?? DEFAULT_ASPECT_RATIO);
|
|
142
|
+
const blockAspectRatio = blockWidth / blockSize;
|
|
116
143
|
const width = dates.length * (blockWidth + blockMargin) - blockMargin;
|
|
117
144
|
const height = blockSize;
|
|
118
145
|
const contextValue = useMemo(() => ({
|
|
146
|
+
degradedId,
|
|
119
147
|
data,
|
|
120
148
|
dates,
|
|
121
149
|
blockMargin,
|
|
@@ -133,6 +161,7 @@ const StatusHeatmap = ({ data, dateFormat = "MMM d", blockSize = 40, blockMargin
|
|
|
133
161
|
locale,
|
|
134
162
|
colors
|
|
135
163
|
}), [
|
|
164
|
+
degradedId,
|
|
136
165
|
data,
|
|
137
166
|
dates,
|
|
138
167
|
blockMargin,
|
|
@@ -154,8 +183,9 @@ const StatusHeatmap = ({ data, dateFormat = "MMM d", blockSize = 40, blockMargin
|
|
|
154
183
|
return /* @__PURE__ */ jsx(StatusHeatmapContext, {
|
|
155
184
|
value: contextValue,
|
|
156
185
|
children: /* @__PURE__ */ jsx("div", {
|
|
186
|
+
ref: rootRef,
|
|
157
187
|
"data-slot": "status-heatmap",
|
|
158
|
-
className: cn("flex
|
|
188
|
+
className: cn("flex flex-col gap-2", fits ? "w-full" : "w-max max-w-full", className),
|
|
159
189
|
style: {
|
|
160
190
|
fontSize,
|
|
161
191
|
...style
|
|
@@ -165,8 +195,9 @@ const StatusHeatmap = ({ data, dateFormat = "MMM d", blockSize = 40, blockMargin
|
|
|
165
195
|
})
|
|
166
196
|
});
|
|
167
197
|
};
|
|
168
|
-
const StatusHeatmapBlock = ({ ref, activity, dayIndex, highlighted = false, onCellClick, onCellHover, onClick, onKeyDown, onMouseEnter, onMouseLeave, className, style: styleProp, ...props }) => {
|
|
169
|
-
const { blockSize, blockWidth, blockMargin, blockRadius, labels, colors } = useStatusHeatmap();
|
|
198
|
+
const StatusHeatmapBlock = ({ ref, activity, dayIndex, highlighted = false, selected = false, onCellClick, onCellHover, onClick, onKeyDown, onMouseEnter, onMouseLeave, className, style: styleProp, ...props }) => {
|
|
199
|
+
const { blockSize, blockWidth, blockMargin, blockRadius, labels, colors, degradedId, healthyValue } = useStatusHeatmap();
|
|
200
|
+
const edge = edgeOf(activity.value, healthyValue, colors);
|
|
170
201
|
const statusText = resolveStatusLabel(activity.value, labels.statuses);
|
|
171
202
|
const ariaLabel = (labels.cellLabel ?? "{{date}}: {{status}}").replace("{{date}}", activity.date).replace("{{status}}", statusText);
|
|
172
203
|
const xPosition = (blockWidth + blockMargin) * dayIndex;
|
|
@@ -174,20 +205,23 @@ const StatusHeatmapBlock = ({ ref, activity, dayIndex, highlighted = false, onCe
|
|
|
174
205
|
ref,
|
|
175
206
|
"data-slot": "status-heatmap-block",
|
|
176
207
|
role: onCellClick ? "button" : "img",
|
|
208
|
+
"aria-pressed": onCellClick ? selected : void 0,
|
|
177
209
|
tabIndex: onCellClick ? 0 : -1,
|
|
178
210
|
"aria-label": ariaLabel,
|
|
179
|
-
className: cn("
|
|
211
|
+
className: cn(edge && "stroke-input stroke-1", "hover:stroke-foreground hover:stroke-1", highlighted && "stroke-foreground stroke-1", selected && "stroke-foreground stroke-2 hover:stroke-2", onCellClick && "cursor-pointer", className),
|
|
180
212
|
"data-value": activity.value,
|
|
181
213
|
"data-date": activity.date,
|
|
182
214
|
"data-highlighted": highlighted || void 0,
|
|
215
|
+
"data-selected": selected || void 0,
|
|
183
216
|
height: blockSize,
|
|
184
217
|
rx: blockRadius,
|
|
185
218
|
ry: blockRadius,
|
|
186
219
|
width: blockWidth,
|
|
220
|
+
strokeDasharray: edge === "dashed" ? "2 2" : void 0,
|
|
187
221
|
x: xPosition,
|
|
188
222
|
y: 0,
|
|
189
223
|
style: {
|
|
190
|
-
|
|
224
|
+
...blockPaint(activity.value, degradedId, colors),
|
|
191
225
|
...styleProp
|
|
192
226
|
},
|
|
193
227
|
onClick: (event) => {
|
|
@@ -214,7 +248,8 @@ const StatusHeatmapBlock = ({ ref, activity, dayIndex, highlighted = false, onCe
|
|
|
214
248
|
};
|
|
215
249
|
StatusHeatmapBlock.displayName = "StatusHeatmapBlock";
|
|
216
250
|
const StatusHeatmapBody = ({ hideDateLabels = false, labelInterval = 30, className, labelClassName, children, ...props }) => {
|
|
217
|
-
const
|
|
251
|
+
const navigation = useHeatmapNavigation();
|
|
252
|
+
const { data, dates, width, height, blockWidth, blockMargin, fontSize, dateFormat, locale, labels, colors, degradedId, healthyValue } = useStatusHeatmap();
|
|
218
253
|
const activityMap = useMemo(() => {
|
|
219
254
|
const map = /* @__PURE__ */ new Map();
|
|
220
255
|
data.forEach((activity) => {
|
|
@@ -234,40 +269,53 @@ const StatusHeatmapBody = ({ hideDateLabels = false, labelInterval = 30, classNa
|
|
|
234
269
|
const labelHeight = hideDateLabels ? 0 : labelFontSize * 2;
|
|
235
270
|
return /* @__PURE__ */ jsx("div", {
|
|
236
271
|
"data-slot": "status-heatmap-body",
|
|
272
|
+
ref: navigation.ref,
|
|
237
273
|
className: cn("max-w-full overflow-x-auto overflow-y-hidden", className),
|
|
238
274
|
...props,
|
|
275
|
+
onKeyDown: (event) => {
|
|
276
|
+
props.onKeyDown?.(event);
|
|
277
|
+
if (!event.defaultPrevented) navigation.onKeyDown(event);
|
|
278
|
+
},
|
|
239
279
|
children: /* @__PURE__ */ jsxs("svg", {
|
|
240
280
|
role: "img",
|
|
241
281
|
"aria-label": labels.heatmapLabel ?? "Status heatmap",
|
|
242
282
|
className: "block overflow-visible rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
243
|
-
height: height + labelHeight +
|
|
244
|
-
viewBox: `-
|
|
245
|
-
width: width +
|
|
246
|
-
children: [
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
283
|
+
height: height + labelHeight + 6,
|
|
284
|
+
viewBox: `-3 -3 ${width + 6} ${height + labelHeight + 6}`,
|
|
285
|
+
width: width + 6,
|
|
286
|
+
children: [
|
|
287
|
+
/* @__PURE__ */ jsx(DegradedGradient, {
|
|
288
|
+
id: degradedId,
|
|
289
|
+
colors,
|
|
290
|
+
healthyValue
|
|
291
|
+
}),
|
|
292
|
+
!hideDateLabels && /* @__PURE__ */ jsx("g", {
|
|
293
|
+
className: cn("fill-current font-mono", labelClassName),
|
|
294
|
+
children: dates.map((date, dayIndex) => {
|
|
295
|
+
const isFirst = dayIndex === 0;
|
|
296
|
+
const isLast = dayIndex === dates.length - 1;
|
|
297
|
+
if (dayIndex % labelInterval !== 0 && !isLast) return null;
|
|
298
|
+
const blockLeft = (blockWidth + blockMargin) * dayIndex;
|
|
299
|
+
const xPosition = isFirst ? blockLeft : isLast ? blockLeft + blockWidth : blockLeft + blockWidth / 2;
|
|
300
|
+
const anchor = isFirst ? "start" : isLast ? "end" : "middle";
|
|
301
|
+
return /* @__PURE__ */ jsx("text", {
|
|
302
|
+
x: xPosition,
|
|
303
|
+
y: height + labelFontSize,
|
|
304
|
+
dominantBaseline: "hanging",
|
|
305
|
+
textAnchor: anchor,
|
|
306
|
+
style: { fontSize: `${labelFontSize}px` },
|
|
307
|
+
children: format(new Date(date), dateFormat, { locale })
|
|
308
|
+
}, `date-${date}`);
|
|
309
|
+
})
|
|
310
|
+
}),
|
|
311
|
+
allActivities.map((activity, dayIndex) => {
|
|
312
|
+
const key = activity.date;
|
|
313
|
+
return /* @__PURE__ */ jsx(Fragment$1, { children: children({
|
|
314
|
+
activity,
|
|
315
|
+
dayIndex
|
|
316
|
+
}) }, key);
|
|
263
317
|
})
|
|
264
|
-
|
|
265
|
-
const key = activity.date;
|
|
266
|
-
return /* @__PURE__ */ jsx(Fragment$1, { children: children({
|
|
267
|
-
activity,
|
|
268
|
-
dayIndex
|
|
269
|
-
}) }, key);
|
|
270
|
-
})]
|
|
318
|
+
]
|
|
271
319
|
})
|
|
272
320
|
});
|
|
273
321
|
};
|
|
@@ -292,7 +340,7 @@ const StatusHeatmapStat = ({ compute, label, className, children, ...props }) =>
|
|
|
292
340
|
});
|
|
293
341
|
};
|
|
294
342
|
const StatusHeatmapLegend = ({ labels: labelsProp, className, children, ...props }) => {
|
|
295
|
-
const { labels, statusValues,
|
|
343
|
+
const { labels, statusValues, blockRadius, colors, degradedId, healthyValue } = useStatusHeatmap();
|
|
296
344
|
const statuses = statusValues.map((value) => ({
|
|
297
345
|
value,
|
|
298
346
|
label: resolveStatusLabel(value, labelsProp ?? labels.statuses)
|
|
@@ -300,25 +348,38 @@ const StatusHeatmapLegend = ({ labels: labelsProp, className, children, ...props
|
|
|
300
348
|
return /* @__PURE__ */ jsx("fieldset", {
|
|
301
349
|
"data-slot": "status-heatmap-legend",
|
|
302
350
|
"aria-label": labels.legendLabel ?? "Status legend",
|
|
303
|
-
className: cn("ml-auto flex items-center gap-1", className),
|
|
351
|
+
className: cn("ml-auto flex flex-wrap items-center gap-x-3 gap-y-1", className),
|
|
304
352
|
...props,
|
|
305
353
|
children: statuses.map((status) => children ? /* @__PURE__ */ jsx(Fragment$1, { children: children({
|
|
306
354
|
value: status.value,
|
|
307
355
|
label: status.label
|
|
308
356
|
}) }, `status-${status.value}`) : /* @__PURE__ */ jsxs("div", {
|
|
309
357
|
className: "flex items-center gap-1",
|
|
310
|
-
children: [/* @__PURE__ */
|
|
358
|
+
children: [/* @__PURE__ */ jsxs("svg", {
|
|
311
359
|
"aria-hidden": "true",
|
|
312
|
-
height:
|
|
313
|
-
width:
|
|
314
|
-
children: /* @__PURE__ */ jsx(
|
|
360
|
+
height: LEGEND_SWATCH,
|
|
361
|
+
width: LEGEND_SWATCH,
|
|
362
|
+
children: [status.value === DEGRADED && /* @__PURE__ */ jsx(DegradedGradient, {
|
|
363
|
+
id: `${degradedId}-legend`,
|
|
364
|
+
colors,
|
|
365
|
+
healthyValue
|
|
366
|
+
}), /* @__PURE__ */ jsx("rect", {
|
|
315
367
|
"data-value": status.value,
|
|
316
|
-
|
|
368
|
+
...edgeOf(status.value, healthyValue, colors) ? {
|
|
369
|
+
x: .5,
|
|
370
|
+
y: .5,
|
|
371
|
+
height: 9,
|
|
372
|
+
width: 9,
|
|
373
|
+
className: "stroke-input",
|
|
374
|
+
strokeDasharray: edgeOf(status.value, healthyValue, colors) === "dashed" ? "2 1" : void 0
|
|
375
|
+
} : {
|
|
376
|
+
height: LEGEND_SWATCH,
|
|
377
|
+
width: LEGEND_SWATCH
|
|
378
|
+
},
|
|
317
379
|
rx: blockRadius,
|
|
318
380
|
ry: blockRadius,
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
})
|
|
381
|
+
style: blockPaint(status.value, `${degradedId}-legend`, colors)
|
|
382
|
+
})]
|
|
322
383
|
}), /* @__PURE__ */ jsx("span", {
|
|
323
384
|
className: "font-medium text-muted-foreground text-xs",
|
|
324
385
|
children: status.label
|
|
@@ -36,6 +36,10 @@ export type ColorConfig = {
|
|
|
36
36
|
export type WeekdayHeatmapProps = HTMLAttributes<HTMLDivElement> & {
|
|
37
37
|
data: WeekdayHourlyActivity[];
|
|
38
38
|
weekStart?: Day;
|
|
39
|
+
/** Displayed hours, in order; defaults to the full day. */
|
|
40
|
+
hours?: readonly WeekdayHour[];
|
|
41
|
+
/** Displayed days, in order; defaults to the full week from weekStart. */
|
|
42
|
+
weekdays?: readonly WeekdayIndex[];
|
|
39
43
|
use12Hour?: boolean;
|
|
40
44
|
blockSize?: number;
|
|
41
45
|
blockMargin?: number;
|
|
@@ -86,8 +90,10 @@ export type WeekdayHeatmapProps = HTMLAttributes<HTMLDivElement> & {
|
|
|
86
90
|
* @param extraRow - Appends an aggregated row below the grid. `compute` receives all activities and must return 24 values (one per hour). Rendered through `renderExtraRow` on the body, or falls back to `children`.
|
|
87
91
|
* @param extraColumn - Appends an aggregated column to the right of the grid. `compute` receives all activities and must return 7 values indexed by weekday 0–6. Rendered through `renderExtraColumn` on the body, or falls back to `children`.
|
|
88
92
|
*/
|
|
89
|
-
export declare const WeekdayHeatmap: ({ data, weekStart, use12Hour, blockSize, blockMargin, blockRadius, blockAspectRatio, levels: levelsProp, isNormalized, colors, locale, labels: labelsProp, fontSize, emptyState, totalCount: totalCountProp, extraRow, extraColumn, style, className, children, ...props }: WeekdayHeatmapProps) => string | number | bigint | true | import("react").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | Iterable<ReactNode> | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | null | undefined> | null;
|
|
93
|
+
export declare const WeekdayHeatmap: ({ data, weekStart, hours, weekdays: displayedWeekdays, use12Hour, blockSize: blockSizeProp, blockMargin, blockRadius, blockAspectRatio, levels: levelsProp, isNormalized, colors, locale, labels: labelsProp, fontSize, emptyState, totalCount: totalCountProp, extraRow, extraColumn, style, className, children, ...props }: WeekdayHeatmapProps) => string | number | bigint | true | import("react").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | Iterable<ReactNode> | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | null | undefined> | null;
|
|
90
94
|
export type WeekdayHeatmapBlockProps = HTMLAttributes<SVGRectElement> & {
|
|
95
|
+
/** The cell the page has picked: drawn with a ring and announced as pressed. */
|
|
96
|
+
selected?: boolean;
|
|
91
97
|
activity: WeekdayHourlyActivityWithLevel;
|
|
92
98
|
extra?: "row" | "column";
|
|
93
99
|
highlighted?: boolean;
|
|
@@ -95,9 +101,9 @@ export type WeekdayHeatmapBlockProps = HTMLAttributes<SVGRectElement> & {
|
|
|
95
101
|
onCellHover?: (activity: WeekdayHourlyActivityWithLevel | null) => void;
|
|
96
102
|
className?: string;
|
|
97
103
|
};
|
|
98
|
-
export declare function WeekdayHeatmapBlock({ ref, activity, extra, highlighted, onCellClick, onCellHover, onClick, onKeyDown, onMouseEnter, onMouseLeave, className, style: styleProp, ...props }: WeekdayHeatmapBlockProps & {
|
|
104
|
+
export declare function WeekdayHeatmapBlock({ ref, activity, extra, highlighted, selected, onCellClick, onCellHover, onClick, onKeyDown, onMouseEnter, onMouseLeave, className, style: styleProp, ...props }: WeekdayHeatmapBlockProps & {
|
|
99
105
|
ref?: React.RefObject<SVGRectElement | null>;
|
|
100
|
-
}): import("react").JSX.Element;
|
|
106
|
+
}): import("react").JSX.Element | null;
|
|
101
107
|
export declare namespace WeekdayHeatmapBlock {
|
|
102
108
|
var displayName: string;
|
|
103
109
|
}
|