@alpic-ai/ui 1.144.0 → 1.145.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/accordion-card.d.mts +1 -1
- package/dist/components/accordion.d.mts +1 -1
- package/dist/components/alert.d.mts +1 -1
- package/dist/components/area-chart.mjs +5 -7
- package/dist/components/attachment-tile.mjs +1 -1
- package/dist/components/avatar.d.mts +1 -1
- package/dist/components/bar-chart.mjs +6 -12
- package/dist/components/bar-list.mjs +1 -1
- package/dist/components/button.d.mts +1 -1
- package/dist/components/chart-container.mjs +2 -2
- package/dist/components/chart-tooltip.mjs +52 -27
- package/dist/components/combobox.d.mts +1 -1
- package/dist/components/combobox.mjs +1 -1
- package/dist/components/copyable.mjs +1 -1
- package/dist/components/dialog.d.mts +1 -1
- package/dist/components/donut-chart.mjs +1 -1
- package/dist/components/dropdown-menu.d.mts +1 -1
- package/dist/components/form.mjs +1 -1
- package/dist/components/heatmap-chart.d.mts +6 -0
- package/dist/components/heatmap-chart.mjs +147 -117
- package/dist/components/input-group.d.mts +1 -1
- package/dist/components/input.mjs +1 -1
- package/dist/components/line-chart.mjs +5 -7
- package/dist/components/select.d.mts +1 -1
- package/dist/components/sidebar.d.mts +1 -1
- package/dist/components/sidebar.mjs +3 -3
- package/dist/components/skeleton.mjs +1 -1
- package/dist/components/stat.mjs +5 -5
- package/dist/components/tabs.d.mts +1 -1
- package/dist/components/tabs.mjs +1 -1
- package/dist/components/textarea.mjs +1 -1
- package/dist/components/toggle-group.d.mts +1 -1
- package/dist/components/toggle-group.mjs +1 -1
- package/dist/components/tooltip-icon-button.mjs +1 -1
- package/dist/lib/chart-palette.mjs +4 -1
- package/package.json +2 -2
- package/src/components/area-chart.tsx +11 -6
- package/src/components/bar-chart.tsx +12 -7
- package/src/components/chart-tooltip.tsx +17 -1
- package/src/components/heatmap-chart.tsx +49 -5
- package/src/components/line-chart.tsx +11 -6
- package/src/components/skeleton.tsx +1 -1
- package/src/components/stat.tsx +4 -4
- package/src/lib/chart-palette.ts +4 -1
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { cn } from "../lib/cn.mjs";
|
|
3
3
|
import { HEAT_EMPTY, heatColor, heatRamp } from "../lib/chart-palette.mjs";
|
|
4
4
|
import { useChartContext } from "./chart-container.mjs";
|
|
5
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
5
|
import * as React$1 from "react";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { createPortal } from "react-dom";
|
|
8
8
|
//#region src/components/heatmap-chart.tsx
|
|
9
9
|
const PLACEHOLDER_HEIGHT = 168;
|
|
@@ -31,7 +31,7 @@ const uniqueInOrder = (values) => {
|
|
|
31
31
|
}
|
|
32
32
|
return ordered;
|
|
33
33
|
};
|
|
34
|
-
function HeatmapChart({ data, xKey, yKey, dataKey = "value", variant = "square", palette, xLabels, yLabels, showAllXLabels = false, highlightPeak = true, loading = false, valueFormatter = (value) => value.toLocaleString("en-US"), xTickFormatter, yTickFormatter, tooltipMetrics, ariaLabel = "Activity heatmap", className }) {
|
|
34
|
+
function HeatmapChart({ data, xKey, yKey, dataKey = "value", variant = "square", palette, xLabels, yLabels, showAllXLabels = false, highlightPeak = true, loading = false, valueFormatter = (value) => value.toLocaleString("en-US"), xTickFormatter, yTickFormatter, tooltipMetrics, tooltipTitleKey, colorScale = "linear", showLegend = false, ariaLabel = "Activity heatmap", className }) {
|
|
35
35
|
const { paletteName, theme } = useChartContext(palette);
|
|
36
36
|
const [hovered, setHovered] = React$1.useState(null);
|
|
37
37
|
const [mounted, setMounted] = React$1.useState(false);
|
|
@@ -81,6 +81,19 @@ function HeatmapChart({ data, xKey, yKey, dataKey = "value", variant = "square",
|
|
|
81
81
|
yLabels
|
|
82
82
|
]);
|
|
83
83
|
const isEmpty = columns.length === 0 || rows.length === 0 || maxValue <= 0;
|
|
84
|
+
const colorFractionOf = React$1.useMemo(() => {
|
|
85
|
+
if (colorScale === "rank") {
|
|
86
|
+
const sorted = [...new Set(cells.map((cell) => cell.value).filter((value) => value > 0))].sort((lower, upper) => lower - upper);
|
|
87
|
+
const RANK_FLOOR = .18;
|
|
88
|
+
const fractionByValue = new Map(sorted.map((value, index) => [value, sorted.length > 1 ? RANK_FLOOR + (1 - RANK_FLOOR) * (index / (sorted.length - 1)) : 1]));
|
|
89
|
+
return (value) => value > 0 ? fractionByValue.get(value) ?? 0 : 0;
|
|
90
|
+
}
|
|
91
|
+
return (value) => maxValue > 0 ? value / maxValue : 0;
|
|
92
|
+
}, [
|
|
93
|
+
cells,
|
|
94
|
+
colorScale,
|
|
95
|
+
maxValue
|
|
96
|
+
]);
|
|
84
97
|
if (loading) return /* @__PURE__ */ jsxs("div", {
|
|
85
98
|
className: cn("flex items-center justify-center gap-2.5 font-mono text-quaternary-foreground text-text-xs", className),
|
|
86
99
|
style: { minHeight: PLACEHOLDER_HEIGHT },
|
|
@@ -91,7 +104,7 @@ function HeatmapChart({ data, xKey, yKey, dataKey = "value", variant = "square",
|
|
|
91
104
|
style: { minHeight: PLACEHOLDER_HEIGHT },
|
|
92
105
|
children: "no data in range"
|
|
93
106
|
});
|
|
94
|
-
const ramp = heatRamp(paletteName, theme.isDark ? HEAT_EMPTY.dark : HEAT_EMPTY.light);
|
|
107
|
+
const ramp = heatRamp(paletteName, theme.isDark ? HEAT_EMPTY.dark : HEAT_EMPTY.light, theme.isDark);
|
|
95
108
|
const totalWidth = PAD.left + columns.length * CELL + (columns.length - 1) * GAP + PAD.right;
|
|
96
109
|
const totalHeight = PAD.top + rows.length * CELL + (rows.length - 1) * GAP + PAD.bottom;
|
|
97
110
|
const xStride = showAllXLabels ? 1 : Math.ceil(columns.length / MAX_X_TICKS);
|
|
@@ -104,125 +117,142 @@ function HeatmapChart({ data, xKey, yKey, dataKey = "value", variant = "square",
|
|
|
104
117
|
return /* @__PURE__ */ jsxs("div", {
|
|
105
118
|
"data-slot": "heatmap-chart",
|
|
106
119
|
className: cn("w-full", className),
|
|
107
|
-
children: [
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
120
|
+
children: [
|
|
121
|
+
/* @__PURE__ */ jsx("div", {
|
|
122
|
+
className: "overflow-x-auto",
|
|
123
|
+
children: /* @__PURE__ */ jsxs("svg", {
|
|
124
|
+
viewBox: `0 0 ${totalWidth} ${totalHeight}`,
|
|
125
|
+
className: "block min-w-[480px]",
|
|
126
|
+
style: {
|
|
127
|
+
width: "100%",
|
|
128
|
+
height: "auto"
|
|
129
|
+
},
|
|
130
|
+
role: "img",
|
|
131
|
+
"aria-label": ariaLabel,
|
|
132
|
+
onMouseLeave: () => setHovered(null),
|
|
133
|
+
children: [
|
|
134
|
+
columns.map((label, col) => col % xStride === 0 ? /* @__PURE__ */ jsx("text", {
|
|
135
|
+
x: cellX(col) + CELL / 2,
|
|
136
|
+
y: PAD.top - 7,
|
|
137
|
+
textAnchor: "middle",
|
|
138
|
+
className: "fill-quaternary-foreground font-mono text-[8.5px]",
|
|
139
|
+
children: formatX(label)
|
|
140
|
+
}, `x-${label}`) : null),
|
|
141
|
+
rows.map((label, row) => /* @__PURE__ */ jsx("text", {
|
|
142
|
+
x: PAD.left - 8,
|
|
143
|
+
y: cellY(row) + CELL / 2 + 3,
|
|
144
|
+
textAnchor: "end",
|
|
145
|
+
className: "fill-quaternary-foreground font-mono text-[8.5px]",
|
|
146
|
+
children: formatY(label)
|
|
147
|
+
}, `y-${label}`)),
|
|
148
|
+
cells.map((cell) => {
|
|
149
|
+
const fraction = colorFractionOf(cell.value);
|
|
150
|
+
const fill = heatColor(ramp, fraction);
|
|
151
|
+
const key = pairKey(cell.rowLabel, cell.colLabel);
|
|
152
|
+
const isPeak = highlightPeak && key === peakKey;
|
|
153
|
+
if (variant === "dot") return /* @__PURE__ */ jsx("circle", {
|
|
154
|
+
cx: cellX(cell.colIndex) + CELL / 2,
|
|
155
|
+
cy: cellY(cell.rowIndex) + CELL / 2,
|
|
156
|
+
r: CELL / 2 * (DOT_MIN + DOT_RANGE * fraction),
|
|
157
|
+
fill,
|
|
158
|
+
stroke: isPeak ? theme.foreground : void 0,
|
|
159
|
+
strokeWidth: isPeak ? 1.4 : void 0
|
|
160
|
+
}, key);
|
|
161
|
+
return /* @__PURE__ */ jsx("rect", {
|
|
162
|
+
x: cellX(cell.colIndex),
|
|
163
|
+
y: cellY(cell.rowIndex),
|
|
164
|
+
width: CELL,
|
|
165
|
+
height: CELL,
|
|
166
|
+
rx: 2.5,
|
|
167
|
+
fill,
|
|
168
|
+
stroke: isPeak ? theme.foreground : void 0,
|
|
169
|
+
strokeWidth: isPeak ? 1.4 : void 0
|
|
170
|
+
}, key);
|
|
171
|
+
}),
|
|
172
|
+
cells.map((cell) => /* @__PURE__ */ jsx("rect", {
|
|
148
173
|
x: cellX(cell.colIndex),
|
|
149
174
|
y: cellY(cell.rowIndex),
|
|
150
|
-
width:
|
|
151
|
-
height:
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
fill: "transparent",
|
|
164
|
-
onMouseMove: (event) => setHovered({
|
|
165
|
-
x: event.clientX,
|
|
166
|
-
y: event.clientY,
|
|
167
|
-
rowLabel: cell.rowLabel,
|
|
168
|
-
colLabel: cell.colLabel,
|
|
169
|
-
value: cell.value,
|
|
170
|
-
record: cell.record
|
|
171
|
-
})
|
|
172
|
-
}, `hit-${pairKey(cell.rowLabel, cell.colLabel)}`))
|
|
173
|
-
]
|
|
174
|
-
})
|
|
175
|
-
}), mounted && hovered && createPortal(/* @__PURE__ */ jsxs("div", {
|
|
176
|
-
className: "pointer-events-none fixed z-50 min-w-[130px] rounded-lg border border-border bg-popover px-3 py-2.5 text-popover-foreground shadow-lg",
|
|
177
|
-
style: {
|
|
178
|
-
left: tooltipLeft,
|
|
179
|
-
top: tooltipTop
|
|
180
|
-
},
|
|
181
|
-
children: [/* @__PURE__ */ jsxs("p", {
|
|
182
|
-
className: "mb-1.5 font-mono text-[10px] text-quaternary-foreground uppercase tracking-wider",
|
|
183
|
-
children: [
|
|
184
|
-
formatY(hovered.rowLabel),
|
|
185
|
-
" · ",
|
|
186
|
-
formatX(hovered.colLabel)
|
|
187
|
-
]
|
|
188
|
-
}), tooltipMetrics && tooltipMetrics.length > 0 ? /* @__PURE__ */ jsx("div", {
|
|
189
|
-
className: "flex flex-col gap-1",
|
|
190
|
-
children: tooltipMetrics.map((metric) => {
|
|
191
|
-
const raw = hovered.record ? Number(hovered.record[metric.key]) || 0 : 0;
|
|
192
|
-
const isActive = metric.key === dataKey;
|
|
193
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
194
|
-
className: "flex items-center justify-between gap-4 text-text-xs",
|
|
195
|
-
children: [/* @__PURE__ */ jsxs("span", {
|
|
196
|
-
className: "inline-flex items-center gap-2 text-muted-foreground",
|
|
197
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
198
|
-
"aria-hidden": true,
|
|
199
|
-
className: "size-2 shrink-0 rounded-[2px]",
|
|
200
|
-
style: {
|
|
201
|
-
background: isActive ? heatColor(ramp, hovered.value / maxValue) : theme.mutedForeground,
|
|
202
|
-
opacity: isActive ? 1 : .35
|
|
203
|
-
}
|
|
204
|
-
}), metric.label]
|
|
205
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
206
|
-
className: cn("font-mono tabular-nums", isActive ? "font-semibold text-foreground" : "text-muted-foreground"),
|
|
207
|
-
children: (metric.format ?? valueFormatter)(raw)
|
|
208
|
-
})]
|
|
209
|
-
}, metric.key);
|
|
175
|
+
width: 25,
|
|
176
|
+
height: 25,
|
|
177
|
+
fill: "transparent",
|
|
178
|
+
onMouseMove: (event) => setHovered({
|
|
179
|
+
x: event.clientX,
|
|
180
|
+
y: event.clientY,
|
|
181
|
+
rowLabel: cell.rowLabel,
|
|
182
|
+
colLabel: cell.colLabel,
|
|
183
|
+
value: cell.value,
|
|
184
|
+
record: cell.record
|
|
185
|
+
})
|
|
186
|
+
}, `hit-${pairKey(cell.rowLabel, cell.colLabel)}`))
|
|
187
|
+
]
|
|
210
188
|
})
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
189
|
+
}),
|
|
190
|
+
showLegend && /* @__PURE__ */ jsxs("div", {
|
|
191
|
+
className: "mt-3 flex items-center justify-end gap-2",
|
|
192
|
+
children: [
|
|
193
|
+
/* @__PURE__ */ jsx("span", {
|
|
194
|
+
className: "font-mono text-[9px] text-quaternary-foreground uppercase tracking-[0.14em]",
|
|
195
|
+
children: "Less"
|
|
196
|
+
}),
|
|
197
|
+
/* @__PURE__ */ jsx("span", {
|
|
216
198
|
"aria-hidden": true,
|
|
217
|
-
className: "
|
|
218
|
-
style: { background:
|
|
219
|
-
}),
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
199
|
+
className: "h-2 w-24 rounded-full border border-border",
|
|
200
|
+
style: { background: `linear-gradient(90deg, ${ramp.join(", ")})` }
|
|
201
|
+
}),
|
|
202
|
+
/* @__PURE__ */ jsx("span", {
|
|
203
|
+
className: "font-mono text-[9px] text-quaternary-foreground uppercase tracking-[0.14em]",
|
|
204
|
+
children: "More"
|
|
205
|
+
})
|
|
206
|
+
]
|
|
207
|
+
}),
|
|
208
|
+
mounted && hovered && createPortal(/* @__PURE__ */ jsxs("div", {
|
|
209
|
+
className: "pointer-events-none fixed z-50 min-w-[130px] rounded-lg border border-border bg-popover px-3 py-2.5 text-popover-foreground shadow-lg",
|
|
210
|
+
style: {
|
|
211
|
+
left: tooltipLeft,
|
|
212
|
+
top: tooltipTop
|
|
213
|
+
},
|
|
214
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
215
|
+
className: "mb-1.5 font-mono text-[10px] text-quaternary-foreground uppercase tracking-wider",
|
|
216
|
+
children: tooltipTitleKey && typeof hovered.record?.[tooltipTitleKey] === "string" ? hovered.record[tooltipTitleKey] : `${formatY(hovered.rowLabel)} · ${formatX(hovered.colLabel)}`
|
|
217
|
+
}), tooltipMetrics && tooltipMetrics.length > 0 ? /* @__PURE__ */ jsx("div", {
|
|
218
|
+
className: "flex flex-col gap-1",
|
|
219
|
+
children: tooltipMetrics.map((metric) => {
|
|
220
|
+
const raw = hovered.record ? Number(hovered.record[metric.key]) || 0 : 0;
|
|
221
|
+
const isActive = metric.key === dataKey;
|
|
222
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
223
|
+
className: "flex items-center justify-between gap-4 text-text-xs",
|
|
224
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
225
|
+
className: "inline-flex items-center gap-2 text-muted-foreground",
|
|
226
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
227
|
+
"aria-hidden": true,
|
|
228
|
+
className: "size-2 shrink-0 rounded-[2px]",
|
|
229
|
+
style: {
|
|
230
|
+
background: isActive ? heatColor(ramp, colorFractionOf(hovered.value)) : theme.mutedForeground,
|
|
231
|
+
opacity: isActive ? 1 : .35
|
|
232
|
+
}
|
|
233
|
+
}), metric.label]
|
|
234
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
235
|
+
className: cn("font-mono tabular-nums", isActive ? "font-semibold text-foreground" : "text-muted-foreground"),
|
|
236
|
+
children: (metric.format ?? valueFormatter)(raw)
|
|
237
|
+
})]
|
|
238
|
+
}, metric.key);
|
|
239
|
+
})
|
|
240
|
+
}) : /* @__PURE__ */ jsxs("div", {
|
|
241
|
+
className: "flex items-center justify-between gap-4 text-text-xs",
|
|
242
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
243
|
+
className: "inline-flex items-center gap-2 text-muted-foreground",
|
|
244
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
245
|
+
"aria-hidden": true,
|
|
246
|
+
className: "size-2 shrink-0 rounded-[2px]",
|
|
247
|
+
style: { background: heatColor(ramp, colorFractionOf(hovered.value)) }
|
|
248
|
+
}), "activity"]
|
|
249
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
250
|
+
className: "font-mono font-semibold tabular-nums text-foreground",
|
|
251
|
+
children: valueFormatter(hovered.value)
|
|
252
|
+
})]
|
|
223
253
|
})]
|
|
224
|
-
})
|
|
225
|
-
|
|
254
|
+
}), document.body)
|
|
255
|
+
]
|
|
226
256
|
});
|
|
227
257
|
}
|
|
228
258
|
//#endregion
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import { cn } from "../lib/cn.mjs";
|
|
3
3
|
import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip.mjs";
|
|
4
4
|
import { Label } from "./label.mjs";
|
|
5
|
+
import * as React$1 from "react";
|
|
5
6
|
import { Info } from "lucide-react";
|
|
6
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
-
import * as React$1 from "react";
|
|
8
8
|
//#region src/components/input.tsx
|
|
9
9
|
const inputSizeStyles = {
|
|
10
10
|
sm: {
|
|
@@ -4,8 +4,9 @@ import { makeXAxisTick, resolveSeries } from "../lib/chart.mjs";
|
|
|
4
4
|
import { useChartContext } from "./chart-container.mjs";
|
|
5
5
|
import { ChartLegend } from "./chart-legend.mjs";
|
|
6
6
|
import { ChartTooltipContent } from "./chart-tooltip.mjs";
|
|
7
|
-
import {
|
|
7
|
+
import { Skeleton } from "./skeleton.mjs";
|
|
8
8
|
import * as React$1 from "react";
|
|
9
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
10
|
import { CartesianGrid, LabelList, Line, LineChart as LineChart$1, ReferenceArea, ReferenceDot, ReferenceLine, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
|
|
10
11
|
//#region src/components/line-chart.tsx
|
|
11
12
|
const CURVE_TYPE = {
|
|
@@ -91,14 +92,11 @@ function LineChart({ data, index, series, curve = "monotone", legend = false, le
|
|
|
91
92
|
const isEmpty = data.length === 0 || resolved.length === 0;
|
|
92
93
|
return /* @__PURE__ */ jsxs("div", {
|
|
93
94
|
"data-slot": "line-chart",
|
|
94
|
-
className: cn("flex w-full flex-col gap-3", className),
|
|
95
|
+
className: cn("flex w-full flex-col gap-3", "[&_.recharts-surface]:outline-none [&_.recharts-wrapper]:outline-none", className),
|
|
95
96
|
children: [/* @__PURE__ */ jsx("div", {
|
|
96
97
|
className: "w-full",
|
|
97
98
|
style: { height },
|
|
98
|
-
children: loading ? /* @__PURE__ */
|
|
99
|
-
className: "flex h-full items-center justify-center gap-2.5 font-mono text-quaternary-foreground text-text-xs",
|
|
100
|
-
children: [/* @__PURE__ */ jsx("span", { className: "size-4 animate-spin rounded-full border-2 border-border border-t-foreground" }), "loading…"]
|
|
101
|
-
}) : isEmpty ? /* @__PURE__ */ jsx("div", {
|
|
99
|
+
children: loading ? /* @__PURE__ */ jsx(Skeleton, { className: "h-full w-full rounded-lg" }) : isEmpty ? /* @__PURE__ */ jsx("div", {
|
|
102
100
|
className: "flex h-full items-center justify-center rounded-lg border border-border border-dashed font-mono text-quaternary-foreground text-text-xs",
|
|
103
101
|
children: "no data in range"
|
|
104
102
|
}) : /* @__PURE__ */ jsx(ResponsiveContainer, {
|
|
@@ -122,7 +120,7 @@ function LineChart({ data, index, series, curve = "monotone", legend = false, le
|
|
|
122
120
|
...axis,
|
|
123
121
|
tick: makeXAxisTick(theme),
|
|
124
122
|
interval: "preserveStartEnd",
|
|
125
|
-
minTickGap:
|
|
123
|
+
minTickGap: 56
|
|
126
124
|
}),
|
|
127
125
|
/* @__PURE__ */ jsx(YAxis, {
|
|
128
126
|
...axis,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { selectTriggerVariants } from "./select-trigger-variants.mjs";
|
|
2
|
-
import { VariantProps } from "class-variance-authority";
|
|
3
2
|
import * as React$1 from "react";
|
|
3
|
+
import { VariantProps } from "class-variance-authority";
|
|
4
4
|
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
5
5
|
|
|
6
6
|
//#region src/components/select.d.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Button } from "./button.mjs";
|
|
2
2
|
import { TooltipContent } from "./tooltip.mjs";
|
|
3
|
-
import { VariantProps } from "class-variance-authority";
|
|
4
3
|
import * as React$1 from "react";
|
|
4
|
+
import { VariantProps } from "class-variance-authority";
|
|
5
5
|
|
|
6
6
|
//#region src/components/sidebar.d.ts
|
|
7
7
|
type SidebarContextProps = {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { useIsMobile } from "../hooks/use-mobile.mjs";
|
|
2
3
|
import { cn } from "../lib/cn.mjs";
|
|
4
|
+
import { Skeleton } from "./skeleton.mjs";
|
|
3
5
|
import { Button } from "./button.mjs";
|
|
4
6
|
import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip.mjs";
|
|
5
7
|
import { Separator } from "./separator.mjs";
|
|
6
8
|
import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from "./sheet.mjs";
|
|
7
|
-
import
|
|
8
|
-
import { Skeleton } from "./skeleton.mjs";
|
|
9
|
+
import * as React$1 from "react";
|
|
9
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
11
|
import { cva } from "class-variance-authority";
|
|
11
|
-
import * as React$1 from "react";
|
|
12
12
|
import { Slot } from "@radix-ui/react-slot";
|
|
13
13
|
//#region src/components/sidebar.tsx
|
|
14
14
|
const SIDEBAR_COOKIE_NAME = "sidebar_state";
|
|
@@ -3,7 +3,7 @@ import { cn } from "../lib/cn.mjs";
|
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import { cva } from "class-variance-authority";
|
|
5
5
|
//#region src/components/skeleton.tsx
|
|
6
|
-
const skeletonVariants = cva("bg-
|
|
6
|
+
const skeletonVariants = cva("bg-foreground/10 motion-safe:animate-pulse", {
|
|
7
7
|
variants: { shape: {
|
|
8
8
|
rectangle: "rounded-md",
|
|
9
9
|
circle: "rounded-full"
|
package/dist/components/stat.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/cn.mjs";
|
|
3
3
|
import { useChartContext } from "./chart-container.mjs";
|
|
4
|
+
import * as React$1 from "react";
|
|
4
5
|
import { ArrowDown, ArrowUp } from "lucide-react";
|
|
5
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
7
|
import { cva } from "class-variance-authority";
|
|
7
|
-
import * as React$1 from "react";
|
|
8
8
|
import { Area, AreaChart, ResponsiveContainer } from "recharts";
|
|
9
9
|
//#region src/components/stat.tsx
|
|
10
10
|
const statDeltaVariants = cva("inline-flex items-center gap-0.5 rounded-md px-1.5 py-0.5 font-mono text-[11px] font-medium leading-none", {
|
|
@@ -35,13 +35,13 @@ function Stat({ value, unit, delta, sparkline, semantic, className, ...props })
|
|
|
35
35
|
const sentiment = delta && (delta.invert ? delta.direction === "down" : delta.direction === "up") ? "positive" : "negative";
|
|
36
36
|
return /* @__PURE__ */ jsxs("div", {
|
|
37
37
|
"data-slot": "stat",
|
|
38
|
-
className: cn("flex flex-col gap-2.5", className),
|
|
38
|
+
className: cn("flex min-w-0 flex-col gap-2.5", className),
|
|
39
39
|
...props,
|
|
40
40
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
41
|
-
className: "flex items-baseline gap-
|
|
41
|
+
className: "flex min-w-0 items-baseline gap-x-2.5",
|
|
42
42
|
children: [
|
|
43
43
|
/* @__PURE__ */ jsx("span", {
|
|
44
|
-
className: "type-display-sm font-bold leading-none tracking-tight tabular-nums text-foreground",
|
|
44
|
+
className: "type-display-sm min-w-0 truncate font-bold leading-none tracking-tight tabular-nums text-foreground",
|
|
45
45
|
children: value
|
|
46
46
|
}),
|
|
47
47
|
unit && /* @__PURE__ */ jsx("span", {
|
|
@@ -55,7 +55,7 @@ function Stat({ value, unit, delta, sparkline, semantic, className, ...props })
|
|
|
55
55
|
})
|
|
56
56
|
]
|
|
57
57
|
}), hasSpark && /* @__PURE__ */ jsx("div", {
|
|
58
|
-
className: "h-9 w-full",
|
|
58
|
+
className: "pointer-events-none h-9 w-full",
|
|
59
59
|
children: /* @__PURE__ */ jsx(ResponsiveContainer, {
|
|
60
60
|
width: "100%",
|
|
61
61
|
height: "100%",
|
package/dist/components/tabs.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/cn.mjs";
|
|
3
|
+
import { createContext, use } from "react";
|
|
3
4
|
import { jsx } from "react/jsx-runtime";
|
|
4
5
|
import { cva } from "class-variance-authority";
|
|
5
|
-
import { createContext, use } from "react";
|
|
6
6
|
import { Slot } from "@radix-ui/react-slot";
|
|
7
7
|
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
8
8
|
//#region src/components/tabs.tsx
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import { cn } from "../lib/cn.mjs";
|
|
3
3
|
import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip.mjs";
|
|
4
4
|
import { Label } from "./label.mjs";
|
|
5
|
+
import * as React$1 from "react";
|
|
5
6
|
import { Info } from "lucide-react";
|
|
6
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
-
import * as React$1 from "react";
|
|
8
8
|
//#region src/components/textarea.tsx
|
|
9
9
|
function Textarea({ className, id, label, required, hint, error, tooltip, ...props }) {
|
|
10
10
|
const generatedId = React$1.useId();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { VariantProps } from "class-variance-authority";
|
|
2
1
|
import * as React$1 from "react";
|
|
2
|
+
import { VariantProps } from "class-variance-authority";
|
|
3
3
|
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
|
|
4
4
|
|
|
5
5
|
//#region src/components/toggle-group.d.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/cn.mjs";
|
|
3
|
+
import * as React$1 from "react";
|
|
3
4
|
import { jsx } from "react/jsx-runtime";
|
|
4
5
|
import { cva } from "class-variance-authority";
|
|
5
|
-
import * as React$1 from "react";
|
|
6
6
|
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
|
|
7
7
|
//#region src/components/toggle-group.tsx
|
|
8
8
|
const toggleGroupItemVariants = cva([
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Button } from "./button.mjs";
|
|
3
3
|
import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip.mjs";
|
|
4
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
4
|
import { forwardRef } from "react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { Slottable } from "@radix-ui/react-slot";
|
|
7
7
|
//#region src/components/tooltip-icon-button.tsx
|
|
8
8
|
const TooltipIconButton = forwardRef(({ children, tooltip, side = "bottom", ...rest }, ref) => {
|
|
@@ -42,7 +42,10 @@ const HEAT_RAMPS = {
|
|
|
42
42
|
magenta: heatRampMagenta,
|
|
43
43
|
cyan: heatRampMint
|
|
44
44
|
};
|
|
45
|
-
const heatRamp = (palette, empty) =>
|
|
45
|
+
const heatRamp = (palette, empty, isDark = true) => {
|
|
46
|
+
const [, ...colored] = HEAT_RAMPS[palette](empty);
|
|
47
|
+
return [empty, ...isDark ? colored : colored.reverse()];
|
|
48
|
+
};
|
|
46
49
|
const hexToRgb = (hex) => {
|
|
47
50
|
const value = Number.parseInt(hex.slice(1), 16);
|
|
48
51
|
return [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alpic-ai/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.145.1",
|
|
4
4
|
"description": "Alpic design system — shared UI components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"class-variance-authority": "^0.7.1",
|
|
53
53
|
"clsx": "^2.1.1",
|
|
54
54
|
"cmdk": "^1.1.1",
|
|
55
|
-
"recharts": "^3.
|
|
55
|
+
"recharts": "^3.9.0",
|
|
56
56
|
"tailwind-merge": "^3.6.0"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
@@ -21,6 +21,7 @@ import { cn } from "../lib/cn";
|
|
|
21
21
|
import { useChartContext } from "./chart-container";
|
|
22
22
|
import { ChartLegend } from "./chart-legend";
|
|
23
23
|
import { ChartTooltipContent } from "./chart-tooltip";
|
|
24
|
+
import { Skeleton } from "./skeleton";
|
|
24
25
|
|
|
25
26
|
const CURVE_TYPE = { monotone: "monotone", linear: "linear", step: "stepAfter" } as const;
|
|
26
27
|
|
|
@@ -192,13 +193,17 @@ function AreaChart({
|
|
|
192
193
|
const isEmpty = data.length === 0 || rendered.length === 0;
|
|
193
194
|
|
|
194
195
|
return (
|
|
195
|
-
<div
|
|
196
|
+
<div
|
|
197
|
+
data-slot="area-chart"
|
|
198
|
+
className={cn(
|
|
199
|
+
"flex w-full flex-col gap-3",
|
|
200
|
+
"[&_.recharts-surface]:outline-none [&_.recharts-wrapper]:outline-none",
|
|
201
|
+
className,
|
|
202
|
+
)}
|
|
203
|
+
>
|
|
196
204
|
<div className="w-full" style={{ height }}>
|
|
197
205
|
{loading ? (
|
|
198
|
-
<
|
|
199
|
-
<span className="size-4 animate-spin rounded-full border-2 border-border border-t-foreground" />
|
|
200
|
-
loading…
|
|
201
|
-
</div>
|
|
206
|
+
<Skeleton className="h-full w-full rounded-lg" />
|
|
202
207
|
) : isEmpty ? (
|
|
203
208
|
<div className="flex h-full items-center justify-center rounded-lg border border-border border-dashed font-mono text-quaternary-foreground text-text-xs">
|
|
204
209
|
no data in range
|
|
@@ -238,7 +243,7 @@ function AreaChart({
|
|
|
238
243
|
{...axis}
|
|
239
244
|
tick={makeXAxisTick(theme)}
|
|
240
245
|
interval="preserveStartEnd"
|
|
241
|
-
minTickGap={
|
|
246
|
+
minTickGap={56}
|
|
242
247
|
/>
|
|
243
248
|
<YAxis
|
|
244
249
|
{...axis}
|
|
@@ -22,6 +22,7 @@ import type { ChartMarker } from "./area-chart";
|
|
|
22
22
|
import { useChartContext } from "./chart-container";
|
|
23
23
|
import { ChartLegend } from "./chart-legend";
|
|
24
24
|
import { ChartTooltipContent } from "./chart-tooltip";
|
|
25
|
+
import { Skeleton } from "./skeleton";
|
|
25
26
|
|
|
26
27
|
const BAR_RADIUS = 4;
|
|
27
28
|
const MAX_BAR_SIZE = 48;
|
|
@@ -155,13 +156,17 @@ function BarChart({
|
|
|
155
156
|
const isEmpty = data.length === 0 || rendered.length === 0;
|
|
156
157
|
|
|
157
158
|
return (
|
|
158
|
-
<div
|
|
159
|
+
<div
|
|
160
|
+
data-slot="bar-chart"
|
|
161
|
+
className={cn(
|
|
162
|
+
"flex w-full flex-col gap-3",
|
|
163
|
+
"[&_.recharts-surface]:outline-none [&_.recharts-wrapper]:outline-none",
|
|
164
|
+
className,
|
|
165
|
+
)}
|
|
166
|
+
>
|
|
159
167
|
<div className="w-full" style={{ height }}>
|
|
160
168
|
{loading ? (
|
|
161
|
-
<
|
|
162
|
-
<span className="size-4 animate-spin rounded-full border-2 border-border border-t-foreground" />
|
|
163
|
-
loading…
|
|
164
|
-
</div>
|
|
169
|
+
<Skeleton className="h-full w-full rounded-lg" />
|
|
165
170
|
) : isEmpty ? (
|
|
166
171
|
<div className="flex h-full items-center justify-center rounded-lg border border-border border-dashed font-mono text-quaternary-foreground text-text-xs">
|
|
167
172
|
no data in range
|
|
@@ -202,7 +207,7 @@ function BarChart({
|
|
|
202
207
|
{...axis}
|
|
203
208
|
tick={makeXAxisTick(theme)}
|
|
204
209
|
interval="preserveStartEnd"
|
|
205
|
-
minTickGap={
|
|
210
|
+
minTickGap={56}
|
|
206
211
|
/>
|
|
207
212
|
<YAxis
|
|
208
213
|
{...axis}
|
|
@@ -268,7 +273,7 @@ function BarChart({
|
|
|
268
273
|
strokeWidth={0}
|
|
269
274
|
radius={radiusFor(slot)}
|
|
270
275
|
maxBarSize={MAX_BAR_SIZE}
|
|
271
|
-
activeBar={
|
|
276
|
+
activeBar={false}
|
|
272
277
|
isAnimationActive={false}
|
|
273
278
|
animationDuration={650}
|
|
274
279
|
animationEasing="ease-out"
|