@alfadocs/ui-kit 0.32.1 → 0.32.3

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.
@@ -1,7 +1,7 @@
1
1
  import { jsxs as v, jsx as r } from "react/jsx-runtime";
2
- import { forwardRef as _, useContext as k, Children as w, createContext as y } from "react";
2
+ import { forwardRef as b, useContext as k, Children as w, createContext as y } from "react";
3
3
  import { c as s } from "./index-D2ZczOXr.js";
4
- const b = [
4
+ const _ = [
5
5
  "violet",
6
6
  "purple",
7
7
  "magenta",
@@ -44,17 +44,17 @@ const b = [
44
44
  // matches Card.elevated and PublicFooter compact. The thicker
45
45
  // line reads as a deliberate boundary rather than a hairline.
46
46
  //
47
- // 0.31.9: `border-t-0` on both variants the 4px accent strip
48
- // (absolutely positioned at top:0 inside the border-box) sits
49
- // BELOW the top border, so visually you see a thin grey
50
- // hairline, then the brand strip. That dilutes the brand
51
- // marker. Dropping the top border lets the accent strip BE the
52
- // card's top edge. The 3px-and-up strip carries enough
53
- // contrast (~5:1 on white in light theme, similar in dark) to
54
- // satisfy the accessible theme's ≥3:1 boundary requirement
55
- // without the extra hairline.
56
- elevated: "ds:shadow-[var(--shadow-card)] ds:border ds:border-t-0 ds:border-[color:var(--card-border)] ds:[.theme-accessible_&]:border-2 ds:[.theme-accessible_&]:border-t-0",
57
- outlined: "ds:border ds:border-t-0 ds:border-[color:var(--card-border)] ds:[.theme-accessible_&]:border-2 ds:[.theme-accessible_&]:border-t-0"
47
+ // 0.32.3: restored full 4-sided border. 0.31.9 dropped
48
+ // `border-top` so the accent strip would be the card's literal
49
+ // top edge but with `border-radius: lg` on all 4 corners the
50
+ // side borders curve toward a non-existent top edge, leaving
51
+ // the top corners visually "open" (visible page-bg slivers
52
+ // where the rounded corner outline should close). The 1px
53
+ // hairline above the accent strip is the cheaper visual cost
54
+ // subtle in light theme (14% black) and matches dark-theme
55
+ // chrome where shadow alone loses contrast.
56
+ elevated: "ds:shadow-[var(--shadow-card)] ds:border ds:border-[color:var(--card-border)] ds:[.theme-accessible_&]:border-2",
57
+ outlined: "ds:border ds:border-[color:var(--card-border)] ds:[.theme-accessible_&]:border-2"
58
58
  }
59
59
  },
60
60
  defaultVariants: { variant: "elevated" }
@@ -153,9 +153,9 @@ const b = [
153
153
  }
154
154
  );
155
155
  function S(a, o) {
156
- return a !== "auto" ? a : o ? b[o.index % b.length] : "primary";
156
+ return a !== "auto" ? a : o ? _[o.index % _.length] : "primary";
157
157
  }
158
- const p = _(
158
+ const p = b(
159
159
  ({ columns: a = 3, children: o, className: c, ...d }, l) => {
160
160
  const i = w.toArray(o);
161
161
  return /* @__PURE__ */ r(
@@ -171,7 +171,7 @@ const p = _(
171
171
  }
172
172
  );
173
173
  p.displayName = "BenefitCard.Row";
174
- const x = _(
174
+ const x = b(
175
175
  ({
176
176
  step: a,
177
177
  icon: o,
@@ -241,4 +241,4 @@ const H = Object.assign(x, {
241
241
  export {
242
242
  H as B
243
243
  };
244
- //# sourceMappingURL=benefit-card-_Sc-MGha.js.map
244
+ //# sourceMappingURL=benefit-card-Xnxj4Gmo.js.map
@@ -1,9 +1,9 @@
1
1
  import { jsxs as z, jsx as i } from "react/jsx-runtime";
2
- import { forwardRef as Q, useId as X, useCallback as L, useRef as Z, useMemo as tt } from "react";
2
+ import { forwardRef as X, useId as Z, useCallback as O, useRef as tt, useMemo as et } from "react";
3
3
  import { c as V } from "./index-D2ZczOXr.js";
4
- import { useTranslation as U } from "react-i18next";
5
- import { u as et } from "./use-count-up-BLLetaZ8.js";
6
- const O = V("ds:flex ds:flex-col ds:h-full", {
4
+ import { useTranslation as B } from "react-i18next";
5
+ import { u as st } from "./use-count-up-BLLetaZ8.js";
6
+ const P = V("ds:flex ds:flex-col ds:h-full", {
7
7
  variants: {
8
8
  variant: {
9
9
  default: "ds:gap-[var(--spacing-xs)]",
@@ -14,14 +14,21 @@ const O = V("ds:flex ds:flex-col ds:h-full", {
14
14
  "ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]",
15
15
  "ds:pt-[var(--spacing-md)] ds:pb-[var(--spacing-md)]"
16
16
  ].join(" "),
17
- // White card surface with the shared card shadow — matches
18
- // `Card variant="elevated"` tokens (`--card` + `--shadow-card`) so
19
- // a grid of elevated Stats reads as a set of shaded panels without
20
- // nesting a Card around each one.
17
+ // White card surface with the shared card shadow + border
18
+ // matches `Card variant="elevated"` and `BenefitCard.elevated`
19
+ // tokens (`--card`, `--card-border`, `--shadow-card`,
20
+ // `--radius-lg`) so a grid of elevated Stats reads as a set of
21
+ // shaded panels without nesting a Card around each one. The
22
+ // border is essential in dark mode: shadow alone on a dark
23
+ // surface loses contrast and the card boundary disappears.
24
+ // Accessible theme bumps to `border-2` to match Card / Benefit-
25
+ // Card's 0.31.5 accessibility uplift.
21
26
  elevated: [
22
27
  "ds:gap-[var(--spacing-xs)]",
23
28
  "ds:bg-[var(--card)]",
24
29
  "ds:text-[var(--card-foreground)]",
30
+ "ds:border ds:border-[color:var(--card-border)]",
31
+ "ds:[.theme-accessible_&]:border-2",
25
32
  "ds:shadow-[var(--shadow-card)]",
26
33
  "ds:rounded-[var(--radius-lg)]",
27
34
  "ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]",
@@ -48,7 +55,7 @@ const O = V("ds:flex ds:flex-col ds:h-full", {
48
55
  size: "md",
49
56
  align: "start"
50
57
  }
51
- }), P = V("type-metric ds:text-[var(--foreground)]", {
58
+ }), U = V("type-metric", {
52
59
  variants: {
53
60
  size: {
54
61
  sm: "ds:[--type-metric-size:var(--font-size-xl)]",
@@ -60,6 +67,22 @@ const O = V("ds:flex ds:flex-col ds:h-full", {
60
67
  outlined: "",
61
68
  elevated: "",
62
69
  compact: ""
70
+ },
71
+ // Colour of the headline metric value. Defaults to `--foreground`
72
+ // (the existing render). `primary` / `accent` are the brand intents
73
+ // — use for hero / marketing stats where the number IS the visual
74
+ // marker. `success` / `destructive` / `info` / `warning` map to the
75
+ // semantic tokens for KPI tiles that want to signal status via the
76
+ // value colour itself (e.g. revenue green, debt red). The trend
77
+ // chevron and the label colour are independent of this prop.
78
+ intent: {
79
+ foreground: "ds:text-[var(--foreground)]",
80
+ primary: "ds:text-[var(--primary)]",
81
+ accent: "ds:text-[var(--accent)]",
82
+ success: "ds:text-[var(--success)]",
83
+ destructive: "ds:text-[var(--destructive)]",
84
+ info: "ds:text-[var(--info)]",
85
+ warning: "ds:text-[var(--warning)]"
63
86
  }
64
87
  },
65
88
  compoundVariants: [
@@ -81,9 +104,10 @@ const O = V("ds:flex ds:flex-col ds:h-full", {
81
104
  ],
82
105
  defaultVariants: {
83
106
  size: "md",
84
- variant: "default"
107
+ variant: "default",
108
+ intent: "foreground"
85
109
  }
86
- }), st = V(
110
+ }), rt = V(
87
111
  "ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-label",
88
112
  {
89
113
  variants: {
@@ -97,76 +121,77 @@ const O = V("ds:flex ds:flex-col ds:h-full", {
97
121
  trend: "flat"
98
122
  }
99
123
  }
100
- ), rt = { up: "↑", down: "↓", flat: "→" }, at = {
124
+ ), at = { up: "↑", down: "↓", flat: "→" }, nt = {
101
125
  up: "stat.trend.up",
102
126
  down: "stat.trend.down",
103
127
  flat: "stat.trend.flat"
104
128
  };
105
- function nt({
129
+ function it({
106
130
  trend: d,
107
131
  delta: t,
108
132
  deltaFormat: c = "decimal",
109
133
  locale: a
110
134
  }) {
111
- const { t: e, i18n: l } = U(), o = typeof t == "string" ? t : new Intl.NumberFormat(a ?? l.language, {
135
+ const { t: e, i18n: o } = B(), l = typeof t == "string" ? t : new Intl.NumberFormat(a ?? o.language, {
112
136
  style: c === "percent" ? "percent" : "decimal"
113
137
  }).format(c === "percent" ? t / 100 : t);
114
- return /* @__PURE__ */ z("span", { className: st({ trend: d }), children: [
115
- /* @__PURE__ */ i("span", { "aria-hidden": "true", children: rt[d] }),
116
- /* @__PURE__ */ i("span", { className: "ds:sr-only", children: e(at[d]) }),
117
- o
138
+ return /* @__PURE__ */ z("span", { className: rt({ trend: d }), children: [
139
+ /* @__PURE__ */ i("span", { "aria-hidden": "true", children: at[d] }),
140
+ /* @__PURE__ */ i("span", { className: "ds:sr-only", children: e(nt[d]) }),
141
+ l
118
142
  ] });
119
143
  }
120
- function it(d, t) {
144
+ function dt(d, t) {
121
145
  const c = d.trim();
122
146
  if (c === "") return null;
123
147
  let a = "", e = c;
124
148
  e.startsWith("+") ? (a = "+", e = e.slice(1).trimStart()) : (e.startsWith("-") || e.startsWith("−")) && (a = "-", e = e.slice(1).trimStart());
125
- let l = "";
126
- const o = e.match(/[KMB]$/i);
127
- o && (l = o[0], e = e.slice(0, -1).trimEnd());
128
- let m = "", u = ".";
149
+ let o = "";
150
+ const l = e.match(/[KMB]$/i);
151
+ l && (o = l[0], e = e.slice(0, -1).trimEnd());
152
+ let u = "", m = ".";
129
153
  try {
130
154
  const b = new Intl.NumberFormat(t).formatToParts(12345.6);
131
155
  for (const n of b)
132
- n.type === "group" ? m = n.value : n.type === "decimal" && (u = n.value);
156
+ n.type === "group" ? u = n.value : n.type === "decimal" && (m = n.value);
133
157
  } catch {
134
158
  }
135
159
  const g = e.match(/^(\d+)\.(\d+)$/);
136
- if (g && !(g[2].length === 3 && m === ".")) {
160
+ if (g && !(g[2].length === 3 && u === ".")) {
137
161
  const n = Number.parseFloat(e);
138
162
  if (Number.isFinite(n))
139
- return { target: n, sign: a, suffix: l };
163
+ return { target: n, sign: a, suffix: o };
140
164
  }
141
165
  let s = e;
142
- m !== "" && (s = s.split(m).join("")), u !== "." && (s = s.split(u).join(".")), s = s.replace(/[\s\u00A0\u202F]/g, "");
166
+ u !== "" && (s = s.split(u).join("")), m !== "." && (s = s.split(m).join(".")), s = s.replace(/[\s\u00A0\u202F]/g, "");
143
167
  const v = Number.parseFloat(s);
144
- return Number.isFinite(v) ? { target: v, sign: a, suffix: l } : null;
168
+ return Number.isFinite(v) ? { target: v, sign: a, suffix: o } : null;
145
169
  }
146
- const dt = Q(
170
+ const ct = X(
147
171
  ({
148
172
  label: d,
149
173
  value: t,
150
174
  format: c,
151
175
  currency: a,
152
176
  locale: e,
153
- trend: l,
154
- delta: o,
155
- deltaFormat: m = "decimal",
156
- icon: u,
177
+ trend: o,
178
+ delta: l,
179
+ deltaFormat: u = "decimal",
180
+ icon: m,
157
181
  loading: g = !1,
158
182
  animate: s = !1,
159
183
  animateOnEveryView: v = !1,
160
184
  animateDurationMs: b = 1600,
161
185
  animateLocale: n,
162
- animateSeparators: h,
163
- variant: x = "default",
186
+ animateSeparators: x,
187
+ variant: h = "default",
164
188
  size: y = "md",
165
189
  align: I = "start",
166
- className: M,
167
- ...j
168
- }, k) => {
169
- const { i18n: B } = U(), R = X(), f = e ?? B.language, K = L(() => {
190
+ intent: M = "foreground",
191
+ className: j,
192
+ ...k
193
+ }, R) => {
194
+ const { i18n: K } = B(), T = Z(), f = e ?? K.language, _ = O(() => {
170
195
  if (typeof t == "string") return t;
171
196
  switch (c) {
172
197
  case "currency":
@@ -186,10 +211,10 @@ const dt = Q(
186
211
  return new Intl.NumberFormat(f).format(t);
187
212
  }
188
213
  }, [t, c, f, a])(), N = n ?? f;
189
- Z(!1);
190
- const r = tt(() => s ? typeof t == "number" ? Number.isFinite(t) ? { target: t, sign: "", suffix: "" } : null : it(t, N) : null, [s, t, N]), Y = s && r !== null, _ = (r == null ? void 0 : r.target) ?? 0, F = (r == null ? void 0 : r.sign) ?? "", T = (r == null ? void 0 : r.suffix) ?? "", q = L(
214
+ tt(!1);
215
+ const r = et(() => s ? typeof t == "number" ? Number.isFinite(t) ? { target: t, sign: "", suffix: "" } : null : dt(t, N) : null, [s, t, N]), Y = s && r !== null, q = (r == null ? void 0 : r.target) ?? 0, F = (r == null ? void 0 : r.sign) ?? "", $ = (r == null ? void 0 : r.suffix) ?? "", H = O(
191
216
  (w) => {
192
- const C = (() => {
217
+ const E = (() => {
193
218
  try {
194
219
  return new Intl.NumberFormat(N, {
195
220
  useGrouping: !0
@@ -199,46 +224,46 @@ const dt = Q(
199
224
  }
200
225
  })();
201
226
  let p;
202
- if (C)
203
- if (h) {
204
- const W = Math.abs(w), A = Math.trunc(W), D = W - A, H = h.thousand ?? "", S = String(A).replace(
227
+ if (E)
228
+ if (x) {
229
+ const A = Math.abs(w), D = Math.trunc(A), G = A - D, J = x.thousand ?? "", S = String(D).replace(
205
230
  /\B(?=(\d{3})+(?!\d))/g,
206
- H
231
+ J
207
232
  );
208
- if (D === 0)
233
+ if (G === 0)
209
234
  p = S;
210
235
  else {
211
- const G = D.toFixed(6).replace(/0+$/, "").slice(2), J = h.decimal ?? ".";
212
- p = G ? S + J + G : S;
236
+ const L = G.toFixed(6).replace(/0+$/, "").slice(2), Q = x.decimal ?? ".";
237
+ p = L ? S + Q + L : S;
213
238
  }
214
239
  } else
215
- p = C.format(Math.abs(w));
240
+ p = E.format(Math.abs(w));
216
241
  else
217
242
  p = String(Math.abs(w));
218
- let E = F;
219
- return F === "" && w < 0 && (E = "-"), `${E}${p}${T}`;
243
+ let W = F;
244
+ return F === "" && w < 0 && (W = "-"), `${W}${p}${$}`;
220
245
  },
221
- [N, h, F, T]
222
- ), $ = et({
223
- to: _,
246
+ [N, x, F, $]
247
+ ), C = st({
248
+ to: q,
224
249
  from: 0,
225
250
  durationMs: b,
226
251
  startOnVisible: !0,
227
252
  retriggerOnReEntry: v,
228
253
  // `formatter` is the only path we use — it owns both the locale
229
254
  // formatting and the sign/suffix re-application.
230
- formatter: q
255
+ formatter: H
231
256
  });
232
257
  return g ? /* @__PURE__ */ z(
233
258
  "div",
234
259
  {
235
- ref: k,
260
+ ref: R,
236
261
  role: "group",
237
262
  "aria-busy": "true",
238
263
  "aria-label": d,
239
264
  "data-component": "stat",
240
- className: O({ variant: x, size: y, align: I, className: M }),
241
- ...j,
265
+ className: P({ variant: h, size: y, align: I, className: j }),
266
+ ...k,
242
267
  children: [
243
268
  /* @__PURE__ */ i("div", { className: "ds:h-[var(--skeleton-label-h)] ds:w-[var(--skeleton-label-w)] ds:animate-pulse ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)]" }),
244
269
  /* @__PURE__ */ i("div", { className: "ds:h-[var(--skeleton-value-h)] ds:w-[var(--skeleton-value-w)] ds:animate-pulse ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)]" })
@@ -247,15 +272,15 @@ const dt = Q(
247
272
  ) : /* @__PURE__ */ z(
248
273
  "div",
249
274
  {
250
- ref: k,
275
+ ref: R,
251
276
  role: "group",
252
- "aria-labelledby": R,
277
+ "aria-labelledby": T,
253
278
  "data-component": "stat",
254
- className: O({ variant: x, size: y, align: I, className: M }),
255
- ...j,
279
+ className: P({ variant: h, size: y, align: I, className: j }),
280
+ ...k,
256
281
  children: [
257
282
  /* @__PURE__ */ z("span", { className: "ds:inline-flex ds:items-center", children: [
258
- u && /* @__PURE__ */ i(
283
+ m && /* @__PURE__ */ i(
259
284
  "span",
260
285
  {
261
286
  "aria-hidden": "true",
@@ -268,13 +293,13 @@ const dt = Q(
268
293
  "ds:text-[color:var(--accent)]",
269
294
  "ds:forced-colors:text-[CanvasText]"
270
295
  ].join(" "),
271
- children: u
296
+ children: m
272
297
  }
273
298
  ),
274
299
  /* @__PURE__ */ i(
275
300
  "span",
276
301
  {
277
- id: R,
302
+ id: T,
278
303
  className: "type-label ds:text-[var(--muted-foreground)]",
279
304
  children: d
280
305
  }
@@ -289,19 +314,19 @@ const dt = Q(
289
314
  /* @__PURE__ */ i(
290
315
  "span",
291
316
  {
292
- ref: $.ref,
317
+ ref: C.ref,
293
318
  "aria-live": "off",
294
- className: P({ size: y, variant: x }),
295
- children: $.value
319
+ className: U({ size: y, variant: h, intent: M }),
320
+ children: C.value
296
321
  }
297
322
  )
298
- ) : /* @__PURE__ */ i("span", { className: P({ size: y, variant: x }), children: K }),
299
- l != null && o != null && /* @__PURE__ */ i(
300
- nt,
323
+ ) : /* @__PURE__ */ i("span", { className: U({ size: y, variant: h, intent: M }), children: _ }),
324
+ o != null && l != null && /* @__PURE__ */ i(
325
+ it,
301
326
  {
302
- trend: l,
303
- delta: o,
304
- deltaFormat: m,
327
+ trend: o,
328
+ delta: l,
329
+ deltaFormat: u,
305
330
  locale: e
306
331
  }
307
332
  )
@@ -310,8 +335,8 @@ const dt = Q(
310
335
  );
311
336
  }
312
337
  );
313
- dt.displayName = "Stat";
338
+ ct.displayName = "Stat";
314
339
  export {
315
- dt as S
340
+ ct as S
316
341
  };
317
- //# sourceMappingURL=stat-EC2Papj7.js.map
342
+ //# sourceMappingURL=stat-Bs80Z6Yv.js.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "packageVersion": "0.32.1",
3
+ "packageVersion": "0.32.3",
4
4
  "components": [
5
5
  {
6
6
  "kind": "component",
@@ -1,4 +1,4 @@
1
- import { B as a } from "../../_chunks/benefit-card-_Sc-MGha.js";
1
+ import { B as a } from "../../_chunks/benefit-card-Xnxj4Gmo.js";
2
2
  export {
3
3
  a as BenefitCard
4
4
  };
@@ -1,4 +1,4 @@
1
- import { S as o } from "../../_chunks/stat-EC2Papj7.js";
1
+ import { S as o } from "../../_chunks/stat-Bs80Z6Yv.js";
2
2
  export {
3
3
  o as Stat
4
4
  };
@@ -24,6 +24,15 @@ export interface StatProps extends HTMLAttributes<HTMLDivElement>, VariantProps<
24
24
  deltaFormat?: 'decimal' | 'percent';
25
25
  /** Optional leading icon rendered at the start of the label row. */
26
26
  icon?: ReactNode;
27
+ /**
28
+ * Colour of the headline value. Defaults to `foreground`. Brand
29
+ * intents (`primary`, `accent`) are for hero / marketing stats where
30
+ * the number is the visual marker. Semantic intents
31
+ * (`success`, `destructive`, `info`, `warning`) signal status via
32
+ * the value colour itself — e.g. revenue green, debt red on KPI
33
+ * tiles. Trend chevron and label colour are independent.
34
+ */
35
+ intent?: 'foreground' | 'primary' | 'accent' | 'success' | 'destructive' | 'info' | 'warning';
27
36
  /** Renders animated skeleton placeholders instead of content. */
28
37
  loading?: boolean;
29
38
  /**
package/dist/index.js CHANGED
@@ -44,7 +44,7 @@ import { T as Te, t as be } from "./_chunks/time-picker-B5umYwfv.js";
44
44
  import { A as Re, a as Ie, b as he, c as Fe, d as Ee } from "./_chunks/accordion-bSU21uTV.js";
45
45
  import { A as Ne, g as ke, n as Oe } from "./_chunks/avatar-BNQNhoyL.js";
46
46
  import { B as ye } from "./_chunks/badge-zsf5i5bH.js";
47
- import { B as Me } from "./_chunks/benefit-card-_Sc-MGha.js";
47
+ import { B as Me } from "./_chunks/benefit-card-Xnxj4Gmo.js";
48
48
  import { C as we } from "./_chunks/card-DPmk26CL.js";
49
49
  import { C as ve, c as He } from "./_chunks/carousel.agent-DrX96W-1.js";
50
50
  import { C as Ge } from "./_chunks/contact-card-Cf8Ktyt3.js";
@@ -60,7 +60,7 @@ import { M as vr } from "./_chunks/map-view-knHSNLoe.js";
60
60
  import { R as Wr } from "./_chunks/rating-BRD7O74e.js";
61
61
  import { S as Ur } from "./_chunks/skeleton-CZbwyJAA.js";
62
62
  import { S as Yr, s as jr, u as zr } from "./_chunks/sparkline-DEROcSl0.js";
63
- import { S as Qr } from "./_chunks/stat-EC2Papj7.js";
63
+ import { S as Qr } from "./_chunks/stat-Bs80Z6Yv.js";
64
64
  import { T as Xr } from "./_chunks/tag-CyoaEmf_.js";
65
65
  import { T as $r, t as ao } from "./_chunks/timeline-DQa5Tyz4.js";
66
66
  import { T as ro } from "./_chunks/timestamp-BV2lC-wV.js";