@fabio.caffarello/react-design-system 4.6.0 → 4.8.0

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 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,102 +1,104 @@
1
1
  "use client";
2
- var v = Object.defineProperty, T = Object.defineProperties;
3
- var C = Object.getOwnPropertyDescriptors;
4
- var m = Object.getOwnPropertySymbols;
5
- var h = Object.prototype.hasOwnProperty, d = Object.prototype.propertyIsEnumerable;
6
- var n = (e, t, r) => t in e ? v(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r, f = (e, t) => {
2
+ var A = Object.defineProperty, C = Object.defineProperties;
3
+ var F = Object.getOwnPropertyDescriptors;
4
+ var l = Object.getOwnPropertySymbols;
5
+ var f = Object.prototype.hasOwnProperty, x = Object.prototype.propertyIsEnumerable;
6
+ var h = (e, t, r) => t in e ? A(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r, y = (e, t) => {
7
7
  for (var r in t || (t = {}))
8
- h.call(t, r) && n(e, r, t[r]);
9
- if (m)
10
- for (var r of m(t))
11
- d.call(t, r) && n(e, r, t[r]);
8
+ f.call(t, r) && h(e, r, t[r]);
9
+ if (l)
10
+ for (var r of l(t))
11
+ x.call(t, r) && h(e, r, t[r]);
12
12
  return e;
13
- }, x = (e, t) => T(e, C(t));
14
- var y = (e, t) => {
13
+ }, u = (e, t) => C(e, F(t));
14
+ var b = (e, t) => {
15
15
  var r = {};
16
16
  for (var s in e)
17
- h.call(e, s) && t.indexOf(s) < 0 && (r[s] = e[s]);
18
- if (e != null && m)
19
- for (var s of m(e))
20
- t.indexOf(s) < 0 && d.call(e, s) && (r[s] = e[s]);
17
+ f.call(e, s) && t.indexOf(s) < 0 && (r[s] = e[s]);
18
+ if (e != null && l)
19
+ for (var s of l(e))
20
+ t.indexOf(s) < 0 && x.call(e, s) && (r[s] = e[s]);
21
21
  return r;
22
22
  };
23
- import { jsxs as F, jsx as i } from "react/jsx-runtime";
24
- import { cn as o } from "../../utils/cn.js";
25
- import { getSpacingClass as a } from "../../tokens/spacing.js";
23
+ import { jsxs as I, jsx as m } from "react/jsx-runtime";
24
+ import { cn as i } from "../../utils/cn.js";
25
+ import { getSpacingClass as o } from "../../tokens/spacing.js";
26
26
  import g from "../../primitives/Text/Text.js";
27
- import { getTypographyWeightFromFontWeight as I, getTypographySize as u } from "../../tokens/typography.js";
28
- import { Button as W } from "../../primitives/Button/Button.js";
29
- function G($) {
30
- var p = $, {
27
+ import { getTypographyWeightFromFontWeight as W, getTypographySize as w } from "../../tokens/typography.js";
28
+ import { Button as $ } from "../../primitives/Button/Button.js";
29
+ function J(k) {
30
+ var p = k, {
31
31
  title: e,
32
32
  message: t,
33
- actionLabel: r,
34
- onAction: s,
35
- illustration: l,
36
- variant: c = "default",
37
- className: b = ""
38
- } = p, w = y(p, [
33
+ action: r,
34
+ actionLabel: s,
35
+ onAction: c,
36
+ illustration: a,
37
+ variant: n = "default",
38
+ className: v = ""
39
+ } = p, N = b(p, [
39
40
  "title",
40
41
  "message",
42
+ "action",
41
43
  "actionLabel",
42
44
  "onAction",
43
45
  "illustration",
44
46
  "variant",
45
47
  "className"
46
48
  ]);
47
- const N = o(
49
+ const S = i(
48
50
  "flex",
49
51
  "flex-col",
50
52
  "items-center",
51
53
  "justify-center",
52
54
  "text-center",
53
- a("xl", "py"),
54
- a("base", "px"),
55
- b
56
- ), S = c === "withAction" || r && s, j = c === "withIllustration" || l;
57
- return /* @__PURE__ */ F(
55
+ o("xl", "py"),
56
+ o("base", "px"),
57
+ v
58
+ ), d = r != null ? r : s && c ? /* @__PURE__ */ m($, { variant: "primary", onClick: c, children: s }) : null, j = !!d || n === "withAction", T = n === "withIllustration" || a;
59
+ return /* @__PURE__ */ I(
58
60
  "div",
59
- x(f({
60
- className: N,
61
+ u(y({
62
+ className: S,
61
63
  role: "status",
62
64
  "aria-live": "polite",
63
- "aria-label": `${e}. ${t}`
64
- }, w), {
65
+ "aria-label": t ? `${e}. ${t}` : e
66
+ }, N), {
65
67
  children: [
66
- j && l && /* @__PURE__ */ i("div", { className: o(a("base", "mb")), "aria-hidden": "true", children: l }),
67
- /* @__PURE__ */ i(
68
+ T && a && /* @__PURE__ */ m("div", { className: i(o("base", "mb")), "aria-hidden": "true", children: a }),
69
+ /* @__PURE__ */ m(
68
70
  g,
69
71
  {
70
72
  as: "h3",
71
- className: o(
72
- u("h4"),
73
- I("semibold"),
73
+ className: i(
74
+ w("h4"),
75
+ W("semibold"),
74
76
  "text-fg-primary",
75
- a("sm", "mb")
77
+ o("sm", "mb")
76
78
  ),
77
79
  children: e
78
80
  }
79
81
  ),
80
- /* @__PURE__ */ i(
82
+ t && /* @__PURE__ */ m(
81
83
  g,
82
84
  {
83
85
  as: "p",
84
- className: o(
85
- u("bodySmall"),
86
+ className: i(
87
+ w("bodySmall"),
86
88
  "text-fg-secondary",
87
- a("md", "mb"),
89
+ o("md", "mb"),
88
90
  "max-w-sm"
89
91
  // Max width utility - justified as layout constraint
90
92
  ),
91
93
  children: t
92
94
  }
93
95
  ),
94
- S && r && s && /* @__PURE__ */ i(W, { variant: "primary", onClick: s, children: r })
96
+ j && d
95
97
  ]
96
98
  })
97
99
  );
98
100
  }
99
101
  export {
100
- G as default
102
+ J as default
101
103
  };
102
104
  //# sourceMappingURL=EmptyState.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EmptyState.js","sources":["../../../../../src/ui/components/EmptyState/EmptyState.tsx"],"sourcesContent":["\"use client\";\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { Button } from \"../../primitives\";\nimport { Text } from \"../../primitives\";\nimport { cn } from \"../../utils\";\nimport {\n getSpacingClass,\n getTypographySize,\n getTypographyWeightFromFontWeight,\n} from \"../../tokens\";\n\nexport interface EmptyStateProps extends HTMLAttributes<HTMLDivElement> {\n title: string;\n message: string;\n actionLabel?: string;\n onAction?: () => void;\n illustration?: ReactNode;\n variant?: \"default\" | \"withAction\" | \"withIllustration\";\n}\n\n/**\n * EmptyState Component\n *\n * A component for displaying empty states when there's no content to show.\n *\n * @example\n * ```tsx\n * <EmptyState\n * title=\"No epics yet\"\n * message=\"Get started by creating your first epic\"\n * actionLabel=\"Create Epic\"\n * onAction={() => router.push('/epics/new')}\n * />\n * ```\n */\nexport default function EmptyState({\n title,\n message,\n actionLabel,\n onAction,\n illustration,\n variant = \"default\",\n className = \"\",\n ...props\n}: EmptyStateProps) {\n const classes = cn(\n \"flex\",\n \"flex-col\",\n \"items-center\",\n \"justify-center\",\n \"text-center\",\n getSpacingClass(\"xl\", \"py\"),\n getSpacingClass(\"base\", \"px\"),\n className,\n );\n\n const showAction = variant === \"withAction\" || (actionLabel && onAction);\n const showIllustration = variant === \"withIllustration\" || illustration;\n\n return (\n <div\n className={classes}\n role=\"status\"\n aria-live=\"polite\"\n aria-label={`${title}. ${message}`}\n {...props}\n >\n {showIllustration && illustration && (\n <div className={cn(getSpacingClass(\"base\", \"mb\"))} aria-hidden=\"true\">\n {illustration}\n </div>\n )}\n\n <Text\n as=\"h3\"\n className={cn(\n getTypographySize(\"h4\"),\n getTypographyWeightFromFontWeight(\"semibold\"),\n \"text-fg-primary\",\n getSpacingClass(\"sm\", \"mb\"),\n )}\n >\n {title}\n </Text>\n\n <Text\n as=\"p\"\n className={cn(\n getTypographySize(\"bodySmall\"),\n \"text-fg-secondary\",\n getSpacingClass(\"md\", \"mb\"),\n \"max-w-sm\", // Max width utility - justified as layout constraint\n )}\n >\n {message}\n </Text>\n\n {showAction && actionLabel && onAction && (\n <Button variant=\"primary\" onClick={onAction}>\n {actionLabel}\n </Button>\n )}\n </div>\n );\n}\n"],"names":["EmptyState","_a","_b","title","message","actionLabel","onAction","illustration","variant","className","props","__objRest","classes","cn","getSpacingClass","showAction","showIllustration","jsxs","__spreadProps","__spreadValues","jsx","Text","getTypographySize","getTypographyWeightFromFontWeight","Button"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,SAAwBA,EAAWC,GASf;AATe,MAAAC,IAAAD,GACjC;AAAA,WAAAE;AAAA,IACA,SAAAC;AAAA,IACA,aAAAC;AAAA,IACA,UAAAC;AAAA,IACA,cAAAC;AAAA,IACA,SAAAC,IAAU;AAAA,IACV,WAAAC,IAAY;AAAA,MAPqBP,GAQ9BQ,IAAAC,EAR8BT,GAQ9B;AAAA,IAPH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAGA,QAAMU,IAAUC;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACAC,EAAgB,MAAM,IAAI;AAAA,IAC1BA,EAAgB,QAAQ,IAAI;AAAA,IAC5BL;AAAA,EAAA,GAGIM,IAAaP,MAAY,gBAAiBH,KAAeC,GACzDU,IAAmBR,MAAY,sBAAsBD;AAE3D,SACE,gBAAAU;AAAA,IAAC;AAAA,IAAAC,EAAAC,EAAA;AAAA,MACC,WAAWP;AAAA,MACX,MAAK;AAAA,MACL,aAAU;AAAA,MACV,cAAY,GAAGT,CAAK,KAAKC,CAAO;AAAA,OAC5BM,IALL;AAAA,MAOE,UAAA;AAAA,QAAAM,KAAoBT,KACnB,gBAAAa,EAAC,OAAA,EAAI,WAAWP,EAAGC,EAAgB,QAAQ,IAAI,CAAC,GAAG,eAAY,QAC5D,UAAAP,GACH;AAAA,QAGF,gBAAAa;AAAA,UAACC;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,WAAWR;AAAA,cACTS,EAAkB,IAAI;AAAA,cACtBC,EAAkC,UAAU;AAAA,cAC5C;AAAA,cACAT,EAAgB,MAAM,IAAI;AAAA,YAAA;AAAA,YAG3B,UAAAX;AAAA,UAAA;AAAA,QAAA;AAAA,QAGH,gBAAAiB;AAAA,UAACC;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,WAAWR;AAAA,cACTS,EAAkB,WAAW;AAAA,cAC7B;AAAA,cACAR,EAAgB,MAAM,IAAI;AAAA,cAC1B;AAAA;AAAA,YAAA;AAAA,YAGD,UAAAV;AAAA,UAAA;AAAA,QAAA;AAAA,QAGFW,KAAcV,KAAeC,KAC5B,gBAAAc,EAACI,KAAO,SAAQ,WAAU,SAASlB,GAChC,UAAAD,EAAA,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIR;"}
1
+ {"version":3,"file":"EmptyState.js","sources":["../../../../../src/ui/components/EmptyState/EmptyState.tsx"],"sourcesContent":["\"use client\";\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { Button } from \"../../primitives\";\nimport { Text } from \"../../primitives\";\nimport { cn } from \"../../utils\";\nimport {\n getSpacingClass,\n getTypographySize,\n getTypographyWeightFromFontWeight,\n} from \"../../tokens\";\n\nexport interface EmptyStateProps extends HTMLAttributes<HTMLDivElement> {\n title: string;\n /**\n * Descriptive message below the title.\n * Optional — several empty states have only a title (e.g. a section\n * that speaks for itself). When absent, the `aria-label` is just the\n * title; the `<p>` element is not rendered.\n */\n message?: string;\n /**\n * Action slot — accepts any ReactNode (link, button, custom CTA).\n * Takes priority over `actionLabel` + `onAction`.\n *\n * Use this prop when the action is a server-rendered `<a>` or\n * `next/link` (zero-JS route); the component renders it without\n * wrapping it in a client Button. When you need a callback-driven\n * button, use `actionLabel` + `onAction` instead (or pass\n * `<Button onClick={…}>…</Button>` here).\n *\n * @example\n * // Server-rendered link (zero-JS)\n * <EmptyState title=\"Sem resultados\" action={<a href=\"/lista\">Limpar filtros</a>} />\n */\n action?: ReactNode;\n /** @deprecated Prefer the `action` slot for new code. Still supported for backwards compat. */\n actionLabel?: string;\n onAction?: () => void;\n illustration?: ReactNode;\n variant?: \"default\" | \"withAction\" | \"withIllustration\";\n}\n\n/**\n * EmptyState Component\n *\n * A component for displaying empty states when there's no content to show.\n *\n * @example\n * ```tsx\n * <EmptyState\n * title=\"No epics yet\"\n * message=\"Get started by creating your first epic\"\n * actionLabel=\"Create Epic\"\n * onAction={() => router.push('/epics/new')}\n * />\n * ```\n */\nexport default function EmptyState({\n title,\n message,\n action,\n actionLabel,\n onAction,\n illustration,\n variant = \"default\",\n className = \"\",\n ...props\n}: EmptyStateProps) {\n const classes = cn(\n \"flex\",\n \"flex-col\",\n \"items-center\",\n \"justify-center\",\n \"text-center\",\n getSpacingClass(\"xl\", \"py\"),\n getSpacingClass(\"base\", \"px\"),\n className,\n );\n\n // `action` slot takes priority; fall back to the legacy actionLabel+onAction pair.\n const resolvedAction =\n action ??\n (actionLabel && onAction ? (\n <Button variant=\"primary\" onClick={onAction}>\n {actionLabel}\n </Button>\n ) : null);\n\n const showAction = !!resolvedAction || variant === \"withAction\";\n const showIllustration = variant === \"withIllustration\" || illustration;\n\n return (\n <div\n className={classes}\n role=\"status\"\n aria-live=\"polite\"\n aria-label={message ? `${title}. ${message}` : title}\n {...props}\n >\n {showIllustration && illustration && (\n <div className={cn(getSpacingClass(\"base\", \"mb\"))} aria-hidden=\"true\">\n {illustration}\n </div>\n )}\n\n <Text\n as=\"h3\"\n className={cn(\n getTypographySize(\"h4\"),\n getTypographyWeightFromFontWeight(\"semibold\"),\n \"text-fg-primary\",\n getSpacingClass(\"sm\", \"mb\"),\n )}\n >\n {title}\n </Text>\n\n {message && (\n <Text\n as=\"p\"\n className={cn(\n getTypographySize(\"bodySmall\"),\n \"text-fg-secondary\",\n getSpacingClass(\"md\", \"mb\"),\n \"max-w-sm\", // Max width utility - justified as layout constraint\n )}\n >\n {message}\n </Text>\n )}\n\n {showAction && resolvedAction}\n </div>\n );\n}\n"],"names":["EmptyState","_a","_b","title","message","action","actionLabel","onAction","illustration","variant","className","props","__objRest","classes","cn","getSpacingClass","resolvedAction","jsx","Button","showAction","showIllustration","jsxs","__spreadProps","__spreadValues","Text","getTypographySize","getTypographyWeightFromFontWeight"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0DA,SAAwBA,EAAWC,GAUf;AAVe,MAAAC,IAAAD,GACjC;AAAA,WAAAE;AAAA,IACA,SAAAC;AAAA,IACA,QAAAC;AAAA,IACA,aAAAC;AAAA,IACA,UAAAC;AAAA,IACA,cAAAC;AAAA,IACA,SAAAC,IAAU;AAAA,IACV,WAAAC,IAAY;AAAA,MARqBR,GAS9BS,IAAAC,EAT8BV,GAS9B;AAAA,IARH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAGA,QAAMW,IAAUC;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACAC,EAAgB,MAAM,IAAI;AAAA,IAC1BA,EAAgB,QAAQ,IAAI;AAAA,IAC5BL;AAAA,EAAA,GAIIM,IACJX,KAAA,OAAAA,IACCC,KAAeC,IACd,gBAAAU,EAACC,GAAA,EAAO,SAAQ,WAAU,SAASX,GAChC,UAAAD,EAAA,CACH,IACE,MAEAa,IAAa,CAAC,CAACH,KAAkBP,MAAY,cAC7CW,IAAmBX,MAAY,sBAAsBD;AAE3D,SACE,gBAAAa;AAAA,IAAC;AAAA,IAAAC,EAAAC,EAAA;AAAA,MACC,WAAWV;AAAA,MACX,MAAK;AAAA,MACL,aAAU;AAAA,MACV,cAAYT,IAAU,GAAGD,CAAK,KAAKC,CAAO,KAAKD;AAAA,OAC3CQ,IALL;AAAA,MAOE,UAAA;AAAA,QAAAS,KAAoBZ,KACnB,gBAAAS,EAAC,OAAA,EAAI,WAAWH,EAAGC,EAAgB,QAAQ,IAAI,CAAC,GAAG,eAAY,QAC5D,UAAAP,GACH;AAAA,QAGF,gBAAAS;AAAA,UAACO;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,WAAWV;AAAA,cACTW,EAAkB,IAAI;AAAA,cACtBC,EAAkC,UAAU;AAAA,cAC5C;AAAA,cACAX,EAAgB,MAAM,IAAI;AAAA,YAAA;AAAA,YAG3B,UAAAZ;AAAA,UAAA;AAAA,QAAA;AAAA,QAGFC,KACC,gBAAAa;AAAA,UAACO;AAAA,UAAA;AAAA,YACC,IAAG;AAAA,YACH,WAAWV;AAAA,cACTW,EAAkB,WAAW;AAAA,cAC7B;AAAA,cACAV,EAAgB,MAAM,IAAI;AAAA,cAC1B;AAAA;AAAA,YAAA;AAAA,YAGD,UAAAX;AAAA,UAAA;AAAA,QAAA;AAAA,QAIJe,KAAcH;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGrB;"}
@@ -1,62 +1,66 @@
1
1
  "use client";
2
- var U = Object.defineProperty, k = Object.defineProperties;
3
- var q = Object.getOwnPropertyDescriptors;
2
+ var k = Object.defineProperty, q = Object.defineProperties;
3
+ var z = Object.getOwnPropertyDescriptors;
4
4
  var s = Object.getOwnPropertySymbols;
5
- var u = Object.prototype.hasOwnProperty, p = Object.prototype.propertyIsEnumerable;
6
- var f = (t, e, a) => e in t ? U(t, e, { enumerable: !0, configurable: !0, writable: !0, value: a }) : t[e] = a, x = (t, e) => {
5
+ var u = Object.prototype.hasOwnProperty, x = Object.prototype.propertyIsEnumerable;
6
+ var f = (t, e, a) => e in t ? k(t, e, { enumerable: !0, configurable: !0, writable: !0, value: a }) : t[e] = a, h = (t, e) => {
7
7
  for (var a in e || (e = {}))
8
8
  u.call(e, a) && f(t, a, e[a]);
9
9
  if (s)
10
10
  for (var a of s(e))
11
- p.call(e, a) && f(t, a, e[a]);
11
+ x.call(e, a) && f(t, a, e[a]);
12
12
  return t;
13
- }, h = (t, e) => k(t, q(e));
13
+ }, p = (t, e) => q(t, z(e));
14
14
  var g = (t, e) => {
15
15
  var a = {};
16
16
  for (var r in t)
17
17
  u.call(t, r) && e.indexOf(r) < 0 && (a[r] = t[r]);
18
18
  if (t != null && s)
19
19
  for (var r of s(t))
20
- e.indexOf(r) < 0 && p.call(t, r) && (a[r] = t[r]);
20
+ e.indexOf(r) < 0 && x.call(t, r) && (a[r] = t[r]);
21
21
  return a;
22
22
  };
23
- import { jsxs as z, jsx as w } from "react/jsx-runtime";
24
- import { forwardRef as S, useState as y } from "react";
23
+ import { jsxs as S, jsx as w } from "react/jsx-runtime";
24
+ import { forwardRef as B, useState as y } from "react";
25
25
  import { getRadiusClass as o } from "../../tokens/radius.js";
26
26
  import { cn as n } from "../../utils/cn.js";
27
- const B = S(function(D, C) {
28
- var c = D, {
27
+ const D = B(function(G, L) {
28
+ var c = G, {
29
29
  src: e,
30
30
  alt: a,
31
31
  fallback: r,
32
32
  size: v = "md",
33
- variant: i = "circle",
34
- "aria-label": b,
35
- className: j = ""
36
- } = c, A = g(c, [
33
+ variant: l = "circle",
34
+ loading: b = "eager",
35
+ "aria-label": j,
36
+ className: A = ""
37
+ } = c, C = g(c, [
37
38
  "src",
38
39
  "alt",
39
40
  "fallback",
40
41
  "size",
41
42
  "variant",
43
+ "loading",
42
44
  "aria-label",
43
45
  "className"
44
46
  ]);
45
- const [L, N] = y(!1), [E, m] = y(!1), F = {
47
+ const [N, E] = y(!1), [F, m] = y(!1), I = {
46
48
  xs: "h-6 w-6 text-xs",
47
49
  sm: "h-8 w-8 text-sm",
48
50
  md: "h-10 w-10 text-base",
49
51
  lg: "h-12 w-12 text-lg",
50
- xl: "h-16 w-16 text-xl"
51
- }, l = {
52
+ xl: "h-16 w-16 text-xl",
53
+ "2xl": "h-24 w-24 text-3xl",
54
+ "3xl": "h-28 w-28 text-4xl"
55
+ }, i = {
52
56
  circle: o("full"),
53
57
  square: o("none"),
54
58
  rounded: o("md")
55
- }, d = !e || L, I = typeof r == "string" ? r.toUpperCase().slice(0, 2) : r, R = b || a || "User avatar";
56
- return /* @__PURE__ */ z(
59
+ }, d = !e || N, R = typeof r == "string" ? r.toUpperCase().slice(0, 2) : r, U = j || a || "User avatar";
60
+ return /* @__PURE__ */ S(
57
61
  "div",
58
- h(x({
59
- ref: C,
62
+ p(h({
63
+ ref: L,
60
64
  className: n(
61
65
  "relative",
62
66
  "inline-flex",
@@ -65,33 +69,34 @@ const B = S(function(D, C) {
65
69
  "shrink-0",
66
70
  "font-medium",
67
71
  "overflow-hidden",
68
- F[v],
69
- l[i],
72
+ I[v],
73
+ i[l],
70
74
  "bg-surface-muted",
71
75
  "text-fg-primary",
72
- j
76
+ A
73
77
  ),
74
78
  role: "img",
75
- "aria-label": R
76
- }, A), {
79
+ "aria-label": U
80
+ }, C), {
77
81
  children: [
78
82
  !d && e && /* @__PURE__ */ w(
79
83
  "img",
80
84
  {
81
85
  src: e,
82
86
  alt: a || "",
87
+ loading: b,
83
88
  className: n(
84
89
  "w-full",
85
90
  "h-full",
86
91
  "object-cover",
87
- l[i],
88
- E ? "opacity-100" : "opacity-0",
92
+ i[l],
93
+ F ? "opacity-100" : "opacity-0",
89
94
  "transition-opacity",
90
95
  "duration-200"
91
96
  ),
92
97
  onLoad: () => m(!0),
93
98
  onError: () => {
94
- N(!0), m(!1);
99
+ E(!0), m(!1);
95
100
  },
96
101
  "aria-hidden": "true"
97
102
  }
@@ -105,18 +110,18 @@ const B = S(function(D, C) {
105
110
  "justify-center",
106
111
  "w-full",
107
112
  "h-full",
108
- l[i]
113
+ i[l]
109
114
  ),
110
115
  "aria-hidden": "true",
111
- children: I || "?"
116
+ children: R || "?"
112
117
  }
113
118
  )
114
119
  ]
115
120
  })
116
121
  );
117
122
  });
118
- B.displayName = "Avatar";
123
+ D.displayName = "Avatar";
119
124
  export {
120
- B as default
125
+ D as default
121
126
  };
122
127
  //# sourceMappingURL=Avatar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Avatar.js","sources":["../../../../../src/ui/primitives/Avatar/Avatar.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useState,\n forwardRef,\n type HTMLAttributes,\n type ReactNode,\n} from \"react\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport { cn } from \"../../utils\";\n\nexport type AvatarSize = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n\nexport interface AvatarProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n \"children\"\n> {\n src?: string;\n alt?: string;\n fallback?: string | ReactNode;\n size?: AvatarSize;\n variant?: \"circle\" | \"square\" | \"rounded\";\n \"aria-label\"?: string;\n}\n\n/**\n * Avatar Component\n *\n * A versatile avatar component for displaying user profile images or initials.\n * Supports fallback display when image fails to load or is not provided.\n * Fully accessible with ARIA attributes.\n *\n * @example\n * ```tsx\n * // With image\n * <Avatar src=\"/user.jpg\" alt=\"John Doe\" />\n *\n * // With fallback initials\n * <Avatar fallback=\"JD\" alt=\"John Doe\" />\n *\n * // Custom size\n * <Avatar src=\"/user.jpg\" size=\"lg\" />\n * ```\n */\nconst Avatar = forwardRef<HTMLDivElement, AvatarProps>(function Avatar(\n {\n src,\n alt,\n fallback,\n size = \"md\",\n variant = \"circle\",\n \"aria-label\": ariaLabel,\n className = \"\",\n ...props\n },\n ref,\n) {\n const [imageError, setImageError] = useState(false);\n const [imageLoaded, setImageLoaded] = useState(false);\n\n // Size and variant classes (not using cva to avoid type issues with dynamic classes)\n const sizeClasses: Record<AvatarSize, string> = {\n xs: \"h-6 w-6 text-xs\",\n sm: \"h-8 w-8 text-sm\",\n md: \"h-10 w-10 text-base\",\n lg: \"h-12 w-12 text-lg\",\n xl: \"h-16 w-16 text-xl\",\n };\n\n const variantClasses = {\n circle: getRadiusClass(\"full\"),\n square: getRadiusClass(\"none\"),\n rounded: getRadiusClass(\"md\"),\n };\n\n const showFallback = !src || imageError;\n const displayFallback =\n typeof fallback === \"string\"\n ? fallback.toUpperCase().slice(0, 2)\n : fallback;\n\n const defaultAriaLabel = ariaLabel || alt || \"User avatar\";\n\n return (\n <div\n ref={ref}\n className={cn(\n \"relative\",\n \"inline-flex\",\n \"items-center\",\n \"justify-center\",\n \"shrink-0\",\n \"font-medium\",\n \"overflow-hidden\",\n sizeClasses[size],\n variantClasses[variant],\n \"bg-surface-muted\",\n \"text-fg-primary\",\n className,\n )}\n role=\"img\"\n aria-label={defaultAriaLabel}\n {...props}\n >\n {!showFallback && src && (\n <img\n src={src}\n alt={alt || \"\"}\n className={cn(\n \"w-full\",\n \"h-full\",\n \"object-cover\",\n variantClasses[variant],\n !imageLoaded ? \"opacity-0\" : \"opacity-100\",\n \"transition-opacity\",\n \"duration-200\",\n )}\n onLoad={() => setImageLoaded(true)}\n onError={() => {\n setImageError(true);\n setImageLoaded(false);\n }}\n aria-hidden=\"true\"\n />\n )}\n {showFallback && (\n <span\n className={cn(\n \"flex\",\n \"items-center\",\n \"justify-center\",\n \"w-full\",\n \"h-full\",\n variantClasses[variant],\n )}\n aria-hidden=\"true\"\n >\n {displayFallback || \"?\"}\n </span>\n )}\n </div>\n );\n});\n\nAvatar.displayName = \"Avatar\";\n\nexport default Avatar;\n"],"names":["Avatar","forwardRef","_a","ref","_b","src","alt","fallback","size","variant","ariaLabel","className","props","__objRest","imageError","setImageError","useState","imageLoaded","setImageLoaded","sizeClasses","variantClasses","getRadiusClass","showFallback","displayFallback","defaultAriaLabel","jsxs","__spreadProps","__spreadValues","cn","jsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,MAAMA,IAASC,EAAwC,SACrDC,GAUAC,GACA;AAXA,MAAAC,IAAAF,GACE;AAAA,SAAAG;AAAA,IACA,KAAAC;AAAA,IACA,UAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,SAAAC,IAAU;AAAA,IACV,cAAcC;AAAA,IACd,WAAAC,IAAY;AAAA,MAPdP,GAQKQ,IAAAC,EARLT,GAQK;AAAA,IAPH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAKF,QAAM,CAACU,GAAYC,CAAa,IAAIC,EAAS,EAAK,GAC5C,CAACC,GAAaC,CAAc,IAAIF,EAAS,EAAK,GAG9CG,IAA0C;AAAA,IAC9C,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EAAA,GAGAC,IAAiB;AAAA,IACrB,QAAQC,EAAe,MAAM;AAAA,IAC7B,QAAQA,EAAe,MAAM;AAAA,IAC7B,SAASA,EAAe,IAAI;AAAA,EAAA,GAGxBC,IAAe,CAACjB,KAAOS,GACvBS,IACJ,OAAOhB,KAAa,WAChBA,EAAS,cAAc,MAAM,GAAG,CAAC,IACjCA,GAEAiB,IAAmBd,KAAaJ,KAAO;AAE7C,SACE,gBAAAmB;AAAA,IAAC;AAAA,IAAAC,EAAAC,EAAA;AAAA,MACC,KAAAxB;AAAA,MACA,WAAWyB;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAT,EAAYX,CAAI;AAAA,QAChBY,EAAeX,CAAO;AAAA,QACtB;AAAA,QACA;AAAA,QACAE;AAAA,MAAA;AAAA,MAEF,MAAK;AAAA,MACL,cAAYa;AAAA,OACRZ,IAlBL;AAAA,MAoBE,UAAA;AAAA,QAAA,CAACU,KAAgBjB,KAChB,gBAAAwB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAAxB;AAAA,YACA,KAAKC,KAAO;AAAA,YACZ,WAAWsB;AAAA,cACT;AAAA,cACA;AAAA,cACA;AAAA,cACAR,EAAeX,CAAO;AAAA,cACrBQ,IAA4B,gBAAd;AAAA,cACf;AAAA,cACA;AAAA,YAAA;AAAA,YAEF,QAAQ,MAAMC,EAAe,EAAI;AAAA,YACjC,SAAS,MAAM;AACb,cAAAH,EAAc,EAAI,GAClBG,EAAe,EAAK;AAAA,YACtB;AAAA,YACA,eAAY;AAAA,UAAA;AAAA,QAAA;AAAA,QAGfI,KACC,gBAAAO;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWD;AAAA,cACT;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACAR,EAAeX,CAAO;AAAA,YAAA;AAAA,YAExB,eAAY;AAAA,YAEX,UAAAc,KAAmB;AAAA,UAAA;AAAA,QAAA;AAAA,MACtB;AAAA,IAAA;AAAA,EAAA;AAIR,CAAC;AAEDvB,EAAO,cAAc;"}
1
+ {"version":3,"file":"Avatar.js","sources":["../../../../../src/ui/primitives/Avatar/Avatar.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useState,\n forwardRef,\n type HTMLAttributes,\n type ReactNode,\n} from \"react\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport { cn } from \"../../utils\";\nimport type { AvatarSize } from \"./AvatarBase\";\n\n// AvatarSize is defined in AvatarBase (the server-safe base) and\n// re-exported here so consumers importing from Avatar get the same type.\nexport type { AvatarSize } from \"./AvatarBase\";\n\nexport interface AvatarProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n \"children\"\n> {\n src?: string;\n alt?: string;\n fallback?: string | ReactNode;\n size?: AvatarSize;\n variant?: \"circle\" | \"square\" | \"rounded\";\n \"aria-label\"?: string;\n /**\n * Controls the browser's native lazy-loading behaviour for the avatar\n * `<img>`. Set to `\"lazy\"` to defer loading until the avatar is near the\n * viewport — strongly recommended for listings with many off-screen\n * profile images (e.g. a 24-card parliament listing).\n *\n * Maps directly to the native `<img loading>` attribute and has no effect\n * when `src` is absent (no `<img>` is rendered).\n *\n * @default 'eager'\n */\n loading?: \"lazy\" | \"eager\";\n}\n\n/**\n * Avatar Component\n *\n * A versatile avatar component for displaying user profile images or\n * initials. Supports fallback display when image fails to load or is not\n * provided. Fully accessible with ARIA attributes.\n *\n * ### Size scale\n *\n * | size | px | Use case |\n * |------|-----|---------------------------------|\n * | xs | 24 | Tight inline / notification dot |\n * | sm | 32 | Comment thread, compact row |\n * | md | 40 | Default — card header, form row |\n * | lg | 48 | Expanded card, sidebar profile |\n * | xl | 64 | Detail-page section header |\n * | 2xl | 96 | Hero profile (PerfilHeader) |\n * | 3xl | 112 | Full-bleed hero cover |\n *\n * ### Lazy loading\n *\n * Pass `loading=\"lazy\"` on listings to defer off-screen image loads. The\n * default is `\"eager\"` (matches browser default) for backward compatibility.\n *\n * @example\n * ```tsx\n * // With image\n * <Avatar src=\"/user.jpg\" alt=\"John Doe\" />\n *\n * // With fallback initials\n * <Avatar fallback=\"JD\" alt=\"John Doe\" />\n *\n * // Hero profile — larger size + lazy load\n * <Avatar src=\"/perfil.jpg\" alt=\"Dep. Silva\" size=\"2xl\" />\n *\n * // Listing — lazy-load all avatars below the fold\n * <Avatar src=\"/user.jpg\" alt=\"User Name\" loading=\"lazy\" />\n * ```\n */\nconst Avatar = forwardRef<HTMLDivElement, AvatarProps>(function Avatar(\n {\n src,\n alt,\n fallback,\n size = \"md\",\n variant = \"circle\",\n loading = \"eager\",\n \"aria-label\": ariaLabel,\n className = \"\",\n ...props\n },\n ref,\n) {\n const [imageError, setImageError] = useState(false);\n const [imageLoaded, setImageLoaded] = useState(false);\n\n const sizeClasses: Record<AvatarSize, string> = {\n xs: \"h-6 w-6 text-xs\",\n sm: \"h-8 w-8 text-sm\",\n md: \"h-10 w-10 text-base\",\n lg: \"h-12 w-12 text-lg\",\n xl: \"h-16 w-16 text-xl\",\n \"2xl\": \"h-24 w-24 text-3xl\",\n \"3xl\": \"h-28 w-28 text-4xl\",\n };\n\n const variantClasses = {\n circle: getRadiusClass(\"full\"),\n square: getRadiusClass(\"none\"),\n rounded: getRadiusClass(\"md\"),\n };\n\n const showFallback = !src || imageError;\n const displayFallback =\n typeof fallback === \"string\"\n ? fallback.toUpperCase().slice(0, 2)\n : fallback;\n\n const defaultAriaLabel = ariaLabel || alt || \"User avatar\";\n\n return (\n <div\n ref={ref}\n className={cn(\n \"relative\",\n \"inline-flex\",\n \"items-center\",\n \"justify-center\",\n \"shrink-0\",\n \"font-medium\",\n \"overflow-hidden\",\n sizeClasses[size],\n variantClasses[variant],\n \"bg-surface-muted\",\n \"text-fg-primary\",\n className,\n )}\n role=\"img\"\n aria-label={defaultAriaLabel}\n {...props}\n >\n {!showFallback && src && (\n <img\n src={src}\n alt={alt || \"\"}\n loading={loading}\n className={cn(\n \"w-full\",\n \"h-full\",\n \"object-cover\",\n variantClasses[variant],\n !imageLoaded ? \"opacity-0\" : \"opacity-100\",\n \"transition-opacity\",\n \"duration-200\",\n )}\n onLoad={() => setImageLoaded(true)}\n onError={() => {\n setImageError(true);\n setImageLoaded(false);\n }}\n aria-hidden=\"true\"\n />\n )}\n {showFallback && (\n <span\n className={cn(\n \"flex\",\n \"items-center\",\n \"justify-center\",\n \"w-full\",\n \"h-full\",\n variantClasses[variant],\n )}\n aria-hidden=\"true\"\n >\n {displayFallback || \"?\"}\n </span>\n )}\n </div>\n );\n});\n\nAvatar.displayName = \"Avatar\";\n\nexport default Avatar;\n"],"names":["Avatar","forwardRef","_a","ref","_b","src","alt","fallback","size","variant","loading","ariaLabel","className","props","__objRest","imageError","setImageError","useState","imageLoaded","setImageLoaded","sizeClasses","variantClasses","getRadiusClass","showFallback","displayFallback","defaultAriaLabel","jsxs","__spreadProps","__spreadValues","cn","jsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA+EA,MAAMA,IAASC,EAAwC,SACrDC,GAWAC,GACA;AAZA,MAAAC,IAAAF,GACE;AAAA,SAAAG;AAAA,IACA,KAAAC;AAAA,IACA,UAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,SAAAC,IAAU;AAAA,IACV,SAAAC,IAAU;AAAA,IACV,cAAcC;AAAA,IACd,WAAAC,IAAY;AAAA,MARdR,GASKS,IAAAC,EATLV,GASK;AAAA,IARH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAKF,QAAM,CAACW,GAAYC,CAAa,IAAIC,EAAS,EAAK,GAC5C,CAACC,GAAaC,CAAc,IAAIF,EAAS,EAAK,GAE9CG,IAA0C;AAAA,IAC9C,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO;AAAA,EAAA,GAGHC,IAAiB;AAAA,IACrB,QAAQC,EAAe,MAAM;AAAA,IAC7B,QAAQA,EAAe,MAAM;AAAA,IAC7B,SAASA,EAAe,IAAI;AAAA,EAAA,GAGxBC,IAAe,CAAClB,KAAOU,GACvBS,IACJ,OAAOjB,KAAa,WAChBA,EAAS,cAAc,MAAM,GAAG,CAAC,IACjCA,GAEAkB,IAAmBd,KAAaL,KAAO;AAE7C,SACE,gBAAAoB;AAAA,IAAC;AAAA,IAAAC,EAAAC,EAAA;AAAA,MACC,KAAAzB;AAAA,MACA,WAAW0B;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAT,EAAYZ,CAAI;AAAA,QAChBa,EAAeZ,CAAO;AAAA,QACtB;AAAA,QACA;AAAA,QACAG;AAAA,MAAA;AAAA,MAEF,MAAK;AAAA,MACL,cAAYa;AAAA,OACRZ,IAlBL;AAAA,MAoBE,UAAA;AAAA,QAAA,CAACU,KAAgBlB,KAChB,gBAAAyB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAAzB;AAAA,YACA,KAAKC,KAAO;AAAA,YACZ,SAAAI;AAAA,YACA,WAAWmB;AAAA,cACT;AAAA,cACA;AAAA,cACA;AAAA,cACAR,EAAeZ,CAAO;AAAA,cACrBS,IAA4B,gBAAd;AAAA,cACf;AAAA,cACA;AAAA,YAAA;AAAA,YAEF,QAAQ,MAAMC,EAAe,EAAI;AAAA,YACjC,SAAS,MAAM;AACb,cAAAH,EAAc,EAAI,GAClBG,EAAe,EAAK;AAAA,YACtB;AAAA,YACA,eAAY;AAAA,UAAA;AAAA,QAAA;AAAA,QAGfI,KACC,gBAAAO;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWD;AAAA,cACT;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACAR,EAAeZ,CAAO;AAAA,YAAA;AAAA,YAExB,eAAY;AAAA,YAEX,UAAAe,KAAmB;AAAA,UAAA;AAAA,QAAA;AAAA,MACtB;AAAA,IAAA;AAAA,EAAA;AAIR,CAAC;AAEDxB,EAAO,cAAc;"}
@@ -0,0 +1,122 @@
1
+ "use client";
2
+ var B = Object.defineProperty, F = Object.defineProperties;
3
+ var R = Object.getOwnPropertyDescriptors;
4
+ var l = Object.getOwnPropertySymbols;
5
+ var f = Object.prototype.hasOwnProperty, x = Object.prototype.propertyIsEnumerable;
6
+ var d = (e, t, s) => t in e ? B(e, t, { enumerable: !0, configurable: !0, writable: !0, value: s }) : e[t] = s, u = (e, t) => {
7
+ for (var s in t || (t = {}))
8
+ f.call(t, s) && d(e, s, t[s]);
9
+ if (l)
10
+ for (var s of l(t))
11
+ x.call(t, s) && d(e, s, t[s]);
12
+ return e;
13
+ }, h = (e, t) => F(e, R(t));
14
+ var p = (e, t) => {
15
+ var s = {};
16
+ for (var a in e)
17
+ f.call(e, a) && t.indexOf(a) < 0 && (s[a] = e[a]);
18
+ if (e != null && l)
19
+ for (var a of l(e))
20
+ t.indexOf(a) < 0 && x.call(e, a) && (s[a] = e[a]);
21
+ return s;
22
+ };
23
+ import { jsxs as U, jsx as w } from "react/jsx-runtime";
24
+ import { forwardRef as k } from "react";
25
+ import { getRadiusClass as i } from "../../tokens/radius.js";
26
+ import { cn as n } from "../../utils/cn.js";
27
+ const q = {
28
+ xs: "h-6 w-6 text-xs",
29
+ sm: "h-8 w-8 text-sm",
30
+ md: "h-10 w-10 text-base",
31
+ lg: "h-12 w-12 text-lg",
32
+ xl: "h-16 w-16 text-xl",
33
+ "2xl": "h-24 w-24 text-3xl",
34
+ "3xl": "h-28 w-28 text-4xl"
35
+ }, o = {
36
+ circle: i("full"),
37
+ square: i("none"),
38
+ rounded: i("md")
39
+ }, z = k(
40
+ function(L, A) {
41
+ var c = L, {
42
+ src: t,
43
+ alt: s,
44
+ fallback: a,
45
+ size: g = "md",
46
+ variant: r = "circle",
47
+ loading: v = "eager",
48
+ "aria-label": b,
49
+ className: y = ""
50
+ } = c, j = p(c, [
51
+ "src",
52
+ "alt",
53
+ "fallback",
54
+ "size",
55
+ "variant",
56
+ "loading",
57
+ "aria-label",
58
+ "className"
59
+ ]);
60
+ const m = !t, C = typeof a == "string" ? a.toUpperCase().slice(0, 2) : a, N = b || s || "User avatar";
61
+ return /* @__PURE__ */ U(
62
+ "div",
63
+ h(u({
64
+ ref: A,
65
+ className: n(
66
+ "relative",
67
+ "inline-flex",
68
+ "items-center",
69
+ "justify-center",
70
+ "shrink-0",
71
+ "font-medium",
72
+ "overflow-hidden",
73
+ q[g],
74
+ o[r],
75
+ "bg-surface-muted",
76
+ "text-fg-primary",
77
+ y
78
+ ),
79
+ role: "img",
80
+ "aria-label": N
81
+ }, j), {
82
+ children: [
83
+ !m && /* @__PURE__ */ w(
84
+ "img",
85
+ {
86
+ src: t,
87
+ alt: s || "",
88
+ loading: v,
89
+ className: n(
90
+ "w-full",
91
+ "h-full",
92
+ "object-cover",
93
+ o[r]
94
+ ),
95
+ "aria-hidden": "true"
96
+ }
97
+ ),
98
+ m && /* @__PURE__ */ w(
99
+ "span",
100
+ {
101
+ className: n(
102
+ "flex",
103
+ "items-center",
104
+ "justify-center",
105
+ "w-full",
106
+ "h-full",
107
+ o[r]
108
+ ),
109
+ "aria-hidden": "true",
110
+ children: C || "?"
111
+ }
112
+ )
113
+ ]
114
+ })
115
+ );
116
+ }
117
+ );
118
+ z.displayName = "AvatarBase";
119
+ export {
120
+ z as default
121
+ };
122
+ //# sourceMappingURL=AvatarBase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AvatarBase.js","sources":["../../../../../src/ui/primitives/Avatar/AvatarBase.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes, type ReactNode } from \"react\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport { cn } from \"../../utils\";\n\nexport type AvatarSize = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"3xl\";\n\nexport interface AvatarBaseProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n \"children\"\n> {\n src?: string;\n alt?: string;\n fallback?: string | ReactNode;\n size?: AvatarSize;\n variant?: \"circle\" | \"square\" | \"rounded\";\n /**\n * Controls the browser's native lazy-loading behaviour for the avatar\n * `<img>`. Set to `\"lazy\"` to defer loading until the avatar is near the\n * viewport — strongly recommended for listings with many off-screen\n * profile images.\n *\n * Has no effect when `src` is absent (no `<img>` is rendered).\n *\n * @default 'eager'\n */\n loading?: \"lazy\" | \"eager\";\n \"aria-label\"?: string;\n}\n\n// Module-level constants so RSC can evaluate these without per-render alloc.\nconst sizeClasses: Record<AvatarSize, string> = {\n xs: \"h-6 w-6 text-xs\",\n sm: \"h-8 w-8 text-sm\",\n md: \"h-10 w-10 text-base\",\n lg: \"h-12 w-12 text-lg\",\n xl: \"h-16 w-16 text-xl\",\n \"2xl\": \"h-24 w-24 text-3xl\",\n \"3xl\": \"h-28 w-28 text-4xl\",\n};\n\nconst variantClasses = {\n circle: getRadiusClass(\"full\"),\n square: getRadiusClass(\"none\"),\n rounded: getRadiusClass(\"md\"),\n};\n\n/**\n * AvatarBase — the **server-safe presentational core** of `Avatar` (issue #250).\n *\n * It holds no React client state (`useState` / `useEffect` / hooks of any\n * kind), so it is importable from\n * `@fabio.caffarello/react-design-system/server` and renders inside React\n * Server Components and zero-JS routes.\n *\n * ### Trade-off vs `Avatar`\n *\n * | Scenario | AvatarBase behaviour |\n * |---------------------------|---------------------------------------------------|\n * | `src` absent / null | Renders initials fallback — fully server-rendered |\n * | `src` present, loads OK | Renders `<img>` — same as `Avatar` |\n * | `src` present, 404s | Browser broken-image; no graceful JS fallback |\n *\n * Use `Avatar` (main entry) when you need the graceful `onError` swap to\n * initials (requires `useState` — client island). Use `AvatarBase` in\n * Server Components and listings that are deliberately zero-JS, where `src`\n * is null for entries without a photo and a graceful 404 fallback is\n * acceptable to forgo.\n *\n * @example\n * ```tsx\n * // Server Component list — zero-JS, initials rendered on server when src is null\n * import { AvatarBase } from \"@fabio.caffarello/react-design-system/server\";\n *\n * export default function ParlamentarCard({ parlamentar }) {\n * return (\n * <AvatarBase\n * src={parlamentar.fotoUrl ?? undefined}\n * fallback={parlamentar.nome}\n * alt={parlamentar.nome}\n * size=\"md\"\n * loading=\"lazy\"\n * />\n * );\n * }\n * ```\n */\nconst AvatarBase = forwardRef<HTMLDivElement, AvatarBaseProps>(\n function AvatarBase(\n {\n src,\n alt,\n fallback,\n size = \"md\",\n variant = \"circle\",\n loading = \"eager\",\n \"aria-label\": ariaLabel,\n className = \"\",\n ...props\n },\n ref,\n ) {\n const showFallback = !src;\n const displayFallback =\n typeof fallback === \"string\"\n ? fallback.toUpperCase().slice(0, 2)\n : fallback;\n\n const defaultAriaLabel = ariaLabel || alt || \"User avatar\";\n\n return (\n <div\n ref={ref}\n className={cn(\n \"relative\",\n \"inline-flex\",\n \"items-center\",\n \"justify-center\",\n \"shrink-0\",\n \"font-medium\",\n \"overflow-hidden\",\n sizeClasses[size],\n variantClasses[variant],\n \"bg-surface-muted\",\n \"text-fg-primary\",\n className,\n )}\n role=\"img\"\n aria-label={defaultAriaLabel}\n {...props}\n >\n {!showFallback && (\n <img\n src={src}\n alt={alt || \"\"}\n loading={loading}\n className={cn(\n \"w-full\",\n \"h-full\",\n \"object-cover\",\n variantClasses[variant],\n )}\n aria-hidden=\"true\"\n />\n )}\n {showFallback && (\n <span\n className={cn(\n \"flex\",\n \"items-center\",\n \"justify-center\",\n \"w-full\",\n \"h-full\",\n variantClasses[variant],\n )}\n aria-hidden=\"true\"\n >\n {displayFallback || \"?\"}\n </span>\n )}\n </div>\n );\n },\n);\n\nAvatarBase.displayName = \"AvatarBase\";\n\nexport default AvatarBase;\n"],"names":["sizeClasses","variantClasses","getRadiusClass","AvatarBase","forwardRef","_a","ref","_b","src","alt","fallback","size","variant","loading","ariaLabel","className","props","__objRest","showFallback","displayFallback","defaultAriaLabel","jsxs","__spreadProps","__spreadValues","cn","jsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAMA,IAA0C;AAAA,EAC9C,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,OAAO;AACT,GAEMC,IAAiB;AAAA,EACrB,QAAQC,EAAe,MAAM;AAAA,EAC7B,QAAQA,EAAe,MAAM;AAAA,EAC7B,SAASA,EAAe,IAAI;AAC9B,GA0CMC,IAAaC;AAAA,EACjB,SACEC,GAWAC,GACA;AAZA,QAAAC,IAAAF,GACE;AAAA,WAAAG;AAAA,MACA,KAAAC;AAAA,MACA,UAAAC;AAAA,MACA,MAAAC,IAAO;AAAA,MACP,SAAAC,IAAU;AAAA,MACV,SAAAC,IAAU;AAAA,MACV,cAAcC;AAAA,MACd,WAAAC,IAAY;AAAA,QARdR,GASKS,IAAAC,EATLV,GASK;AAAA,MARH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAKF,UAAMW,IAAe,CAACV,GAChBW,IACJ,OAAOT,KAAa,WAChBA,EAAS,cAAc,MAAM,GAAG,CAAC,IACjCA,GAEAU,IAAmBN,KAAaL,KAAO;AAE7C,WACE,gBAAAY;AAAA,MAAC;AAAA,MAAAC,EAAAC,EAAA;AAAA,QACC,KAAAjB;AAAA,QACA,WAAWkB;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACAxB,EAAYW,CAAI;AAAA,UAChBV,EAAeW,CAAO;AAAA,UACtB;AAAA,UACA;AAAA,UACAG;AAAA,QAAA;AAAA,QAEF,MAAK;AAAA,QACL,cAAYK;AAAA,SACRJ,IAlBL;AAAA,QAoBE,UAAA;AAAA,UAAA,CAACE,KACA,gBAAAO;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAAjB;AAAA,cACA,KAAKC,KAAO;AAAA,cACZ,SAAAI;AAAA,cACA,WAAWW;AAAA,gBACT;AAAA,gBACA;AAAA,gBACA;AAAA,gBACAvB,EAAeW,CAAO;AAAA,cAAA;AAAA,cAExB,eAAY;AAAA,YAAA;AAAA,UAAA;AAAA,UAGfM,KACC,gBAAAO;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAWD;AAAA,gBACT;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACAvB,EAAeW,CAAO;AAAA,cAAA;AAAA,cAExB,eAAY;AAAA,cAEX,UAAAO,KAAmB;AAAA,YAAA;AAAA,UAAA;AAAA,QACtB;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEAhB,EAAW,cAAc;"}