@alpic-ai/ui 1.147.1 → 1.148.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.
@@ -22,6 +22,7 @@ interface BarChartProps {
22
22
  };
23
23
  markers?: ChartMarker[];
24
24
  texture?: boolean;
25
+ partialLastBar?: boolean;
25
26
  loading?: boolean;
26
27
  valueFormatter?: (value: number) => string;
27
28
  labelFormatter?: (label: string | number) => string;
@@ -41,6 +42,7 @@ declare function BarChart({
41
42
  referenceLine,
42
43
  markers,
43
44
  texture,
45
+ partialLastBar,
44
46
  loading,
45
47
  valueFormatter,
46
48
  labelFormatter,
@@ -7,11 +7,11 @@ import { ChartTooltipContent } from "./chart-tooltip.mjs";
7
7
  import { Skeleton } from "./skeleton.mjs";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
9
  import * as React$1 from "react";
10
- import { Bar, BarChart as BarChart$1, CartesianGrid, LabelList, ReferenceArea, ReferenceDot, ReferenceLine, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
10
+ import { Bar, BarChart as BarChart$1, CartesianGrid, Cell, LabelList, ReferenceArea, ReferenceDot, ReferenceLine, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
11
11
  //#region src/components/bar-chart.tsx
12
12
  const BAR_RADIUS = 4;
13
13
  const MAX_BAR_SIZE = 48;
14
- function BarChart({ data, index, series, variant = "stacked", legend = false, legendAlign = "left", valueLabels = false, height = 200, yAxisWidth = 48, palette, referenceLine, markers, texture = false, loading = false, valueFormatter = (value) => value.toLocaleString("en-US"), labelFormatter, className }) {
14
+ function BarChart({ data, index, series, variant = "stacked", legend = false, legendAlign = "left", valueLabels = false, height = 200, yAxisWidth = 48, palette, referenceLine, markers, texture = false, partialLastBar = false, loading = false, valueFormatter = (value) => value.toLocaleString("en-US"), labelFormatter, className }) {
15
15
  const { palette: paletteColors, theme } = useChartContext(palette);
16
16
  const reactId = React$1.useId().replace(/:/g, "");
17
17
  const resolved = resolveSeries(series, paletteColors, theme);
@@ -38,6 +38,20 @@ function BarChart({ data, index, series, variant = "stacked", legend = false, le
38
38
  series,
39
39
  stacked
40
40
  ]);
41
+ const topSlotByRow = React$1.useMemo(() => {
42
+ if (!stacked) return [];
43
+ return data.map((row) => {
44
+ for (let slot = rendered.length - 1; slot >= 0; slot -= 1) {
45
+ const value = Number(row[rendered[slot]?.key ?? ""]);
46
+ if (Number.isFinite(value) && value > 0) return slot;
47
+ }
48
+ return -1;
49
+ });
50
+ }, [
51
+ data,
52
+ rendered,
53
+ stacked
54
+ ]);
41
55
  const margin = {
42
56
  top: markers?.length || valueLabels ? 18 : 8,
43
57
  right: 8,
@@ -207,7 +221,7 @@ function BarChart({ data, index, series, variant = "stacked", legend = false, le
207
221
  position: "insideBottomRight"
208
222
  } : void 0
209
223
  }),
210
- rendered.map((entry, slot) => /* @__PURE__ */ jsx(Bar, {
224
+ rendered.map((entry, slot) => /* @__PURE__ */ jsxs(Bar, {
211
225
  dataKey: entry.key,
212
226
  name: entry.name,
213
227
  stackId: stacked ? "stack" : void 0,
@@ -220,10 +234,30 @@ function BarChart({ data, index, series, variant = "stacked", legend = false, le
220
234
  isAnimationActive: false,
221
235
  animationDuration: 650,
222
236
  animationEasing: "ease-out",
223
- children: valueLabels && (!stacked || rendered.length === 1) && /* @__PURE__ */ jsx(LabelList, {
237
+ children: [(stacked || partialLastBar) && data.map((row, rowIndex) => {
238
+ const roundedTop = stacked ? topSlotByRow[rowIndex] === slot : true;
239
+ const isPartial = partialLastBar && rowIndex === data.length - 1;
240
+ return /* @__PURE__ */ jsx(Cell, {
241
+ radius: roundedTop ? [
242
+ BAR_RADIUS,
243
+ BAR_RADIUS,
244
+ 0,
245
+ 0
246
+ ] : [
247
+ 0,
248
+ 0,
249
+ 0,
250
+ 0
251
+ ],
252
+ fillOpacity: isPartial ? .15 : 1,
253
+ stroke: isPartial ? entry.color : void 0,
254
+ strokeWidth: isPartial ? 1.25 : 0,
255
+ strokeDasharray: isPartial ? "3 2" : void 0
256
+ }, `${entry.key}-${row[index] ?? rowIndex}`);
257
+ }), valueLabels && (!stacked || rendered.length === 1) && /* @__PURE__ */ jsx(LabelList, {
224
258
  dataKey: entry.key,
225
259
  content: renderValueLabel(entry.color)
226
- })
260
+ })]
227
261
  }, entry.key)),
228
262
  markers?.map((marker) => /* @__PURE__ */ jsx(ReferenceDot, {
229
263
  x: marker.x,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alpic-ai/ui",
3
- "version": "1.147.1",
3
+ "version": "1.148.1",
4
4
  "description": "Alpic design system — shared UI components",
5
5
  "type": "module",
6
6
  "exports": {
@@ -23,48 +23,48 @@
23
23
  "src"
24
24
  ],
25
25
  "peerDependencies": {
26
- "lucide-react": "^1.21.0",
26
+ "lucide-react": "^1.23.0",
27
27
  "react": "^19.2.7",
28
28
  "react-dom": "^19.2.7",
29
- "react-hook-form": "^7.80.0",
29
+ "react-hook-form": "^7.81.0",
30
30
  "sonner": "^2.0.7",
31
- "tailwindcss": "^4.3.1",
31
+ "tailwindcss": "^4.3.2",
32
32
  "tw-animate-css": "^1.4.0"
33
33
  },
34
34
  "dependencies": {
35
- "@radix-ui/react-accordion": "^1.2.14",
36
- "@radix-ui/react-avatar": "^1.2.0",
37
- "@radix-ui/react-checkbox": "^1.3.5",
38
- "@radix-ui/react-collapsible": "^1.1.14",
39
- "@radix-ui/react-dialog": "^1.1.17",
40
- "@radix-ui/react-dropdown-menu": "^2.1.18",
41
- "@radix-ui/react-label": "^2.1.10",
42
- "@radix-ui/react-popover": "^1.1.17",
43
- "@radix-ui/react-radio-group": "^1.4.1",
44
- "@radix-ui/react-scroll-area": "^1.2.12",
45
- "@radix-ui/react-select": "^2.3.1",
46
- "@radix-ui/react-separator": "^1.1.10",
35
+ "@radix-ui/react-accordion": "^1.2.15",
36
+ "@radix-ui/react-avatar": "^1.2.1",
37
+ "@radix-ui/react-checkbox": "^1.3.6",
38
+ "@radix-ui/react-collapsible": "^1.1.15",
39
+ "@radix-ui/react-dialog": "^1.1.18",
40
+ "@radix-ui/react-dropdown-menu": "^2.1.19",
41
+ "@radix-ui/react-label": "^2.1.11",
42
+ "@radix-ui/react-popover": "^1.1.18",
43
+ "@radix-ui/react-radio-group": "^1.4.2",
44
+ "@radix-ui/react-scroll-area": "^1.2.13",
45
+ "@radix-ui/react-select": "^2.3.2",
46
+ "@radix-ui/react-separator": "^1.1.11",
47
47
  "@radix-ui/react-slot": "^1.3.0",
48
- "@radix-ui/react-switch": "^1.3.1",
49
- "@radix-ui/react-tabs": "^1.1.15",
50
- "@radix-ui/react-toggle-group": "^1.1.13",
51
- "@radix-ui/react-tooltip": "^1.2.10",
48
+ "@radix-ui/react-switch": "^1.3.2",
49
+ "@radix-ui/react-tabs": "^1.1.16",
50
+ "@radix-ui/react-toggle-group": "^1.1.14",
51
+ "@radix-ui/react-tooltip": "^1.2.11",
52
52
  "class-variance-authority": "^0.7.1",
53
53
  "clsx": "^2.1.1",
54
54
  "cmdk": "^1.1.1",
55
- "recharts": "^3.9.0",
55
+ "recharts": "^3.9.2",
56
56
  "tailwind-merge": "^3.6.0"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@ladle/react": "^5.1.1",
60
- "@tailwindcss/postcss": "^4.3.1",
60
+ "@tailwindcss/postcss": "^4.3.2",
61
61
  "@types/react": "19.2.17",
62
62
  "@types/react-dom": "19.2.3",
63
- "lucide-react": "^1.21.0",
64
- "react-hook-form": "^7.80.0",
63
+ "lucide-react": "^1.23.0",
64
+ "react-hook-form": "^7.81.0",
65
65
  "shx": "^0.4.0",
66
66
  "sonner": "^2.0.7",
67
- "tailwindcss": "^4.3.1",
67
+ "tailwindcss": "^4.3.2",
68
68
  "tsdown": "^0.22.3",
69
69
  "tw-animate-css": "^1.4.0",
70
70
  "typescript": "^6.0.3"
@@ -4,6 +4,7 @@ import * as React from "react";
4
4
  import {
5
5
  Bar,
6
6
  CartesianGrid,
7
+ Cell,
7
8
  LabelList,
8
9
  BarChart as RechartsBarChart,
9
10
  ReferenceArea,
@@ -41,6 +42,7 @@ export interface BarChartProps {
41
42
  referenceLine?: { y: number; label?: string; band?: boolean };
42
43
  markers?: ChartMarker[];
43
44
  texture?: boolean;
45
+ partialLastBar?: boolean;
44
46
  loading?: boolean;
45
47
  valueFormatter?: (value: number) => string;
46
48
  labelFormatter?: (label: string | number) => string;
@@ -61,6 +63,7 @@ function BarChart({
61
63
  referenceLine,
62
64
  markers,
63
65
  texture = false,
66
+ partialLastBar = false,
64
67
  loading = false,
65
68
  valueFormatter = (value) => value.toLocaleString("en-US"),
66
69
  labelFormatter,
@@ -97,6 +100,21 @@ function BarChart({
97
100
  return max;
98
101
  }, [data, series, stacked]);
99
102
 
103
+ const topSlotByRow = React.useMemo(() => {
104
+ if (!stacked) {
105
+ return [];
106
+ }
107
+ return data.map((row) => {
108
+ for (let slot = rendered.length - 1; slot >= 0; slot -= 1) {
109
+ const value = Number(row[rendered[slot]?.key ?? ""]);
110
+ if (Number.isFinite(value) && value > 0) {
111
+ return slot;
112
+ }
113
+ }
114
+ return -1;
115
+ });
116
+ }, [data, rendered, stacked]);
117
+
100
118
  const margin = { top: markers?.length || valueLabels ? 18 : 8, right: 8, bottom: 2, left: 0 };
101
119
 
102
120
  const axis = {
@@ -278,6 +296,24 @@ function BarChart({
278
296
  animationDuration={650}
279
297
  animationEasing="ease-out"
280
298
  >
299
+ {(stacked || partialLastBar) &&
300
+ data.map((row, rowIndex) => {
301
+ const roundedTop = stacked ? topSlotByRow[rowIndex] === slot : true;
302
+ const isPartial = partialLastBar && rowIndex === data.length - 1;
303
+ const cellRadius = (roundedTop
304
+ ? [BAR_RADIUS, BAR_RADIUS, 0, 0]
305
+ : [0, 0, 0, 0]) as unknown as number;
306
+ return (
307
+ <Cell
308
+ key={`${entry.key}-${row[index] ?? rowIndex}`}
309
+ radius={cellRadius}
310
+ fillOpacity={isPartial ? 0.15 : 1}
311
+ stroke={isPartial ? entry.color : undefined}
312
+ strokeWidth={isPartial ? 1.25 : 0}
313
+ strokeDasharray={isPartial ? "3 2" : undefined}
314
+ />
315
+ );
316
+ })}
281
317
  {valueLabels && (!stacked || rendered.length === 1) && (
282
318
  <LabelList dataKey={entry.key} content={renderValueLabel(entry.color)} />
283
319
  )}