@brycks/core-front 0.6.0 → 0.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.
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),N=require("react"),M=require("../../../utils/styles.cjs"),C=["var(--brycks-primary-default)","var(--brycks-info-default)","var(--brycks-success-default)","var(--brycks-warning-default)","var(--brycks-error-default)","var(--brycks-foreground-subtle)"],b=100,l=b/2,r=l-1;function p(t,c){const a=(t-90)*Math.PI/180;return{x:l+c*Math.cos(a),y:l+c*Math.sin(a)}}function T(t,c){const a=c-t;if(a>=359.999){const i=p(0,r),o=p(180,r);return[`M ${i.x} ${i.y}`,`A ${r} ${r} 0 1 1 ${o.x} ${o.y}`,`A ${r} ${r} 0 1 1 ${i.x} ${i.y}`].join(" ")}const h=p(t,r),d=p(c,r),u=a>180?1:0;return[`M ${l} ${l}`,`L ${h.x} ${h.y}`,`A ${r} ${r} 0 ${u} 1 ${d.x} ${d.y}`,"Z"].join(" ")}const q=t=>String(t),R=N.forwardRef(function({data:c,size:a=168,thickness:h=22,legend:d="right",centerLabel:u,centerValue:i,valueFormatter:o=q,showShare:P=!0,emptyText:S="Sem dados",className:k,testId:v,...g},j){const{slices:y,total:w}=N.useMemo(()=>{const e=c.filter(n=>n.value>0),_=e.reduce((n,$)=>n+$.value,0);let x=0;return{slices:e.map((n,$)=>{const f=_>0?n.value/_:0,O=x;return x+=f*360,{...n,color:n.color??C[$%C.length],share:f,path:T(O,x)}}),total:_}},[c]),m=h>0,A=m?Math.max(0,r-h/a*b):0,E=y.map(e=>`${e.label}: ${o(e.value)} (${Math.round(e.share*100)}%)`).join(", ");return y.length===0?s.jsx("div",{ref:j,className:M.cx("brycks-pie-chart","brycks-pie-chart--empty",k),"data-testid":v,...g,children:s.jsx("span",{className:"brycks-pie-chart__empty",children:S})}):s.jsxs("div",{ref:j,className:M.cx("brycks-pie-chart",`brycks-pie-chart--legend-${d}`,k),"data-testid":v,...g,children:[s.jsxs("div",{className:"brycks-pie-chart__graphic",style:{width:a,height:a},children:[s.jsxs("svg",{viewBox:`0 0 ${b} ${b}`,className:"brycks-pie-chart__svg",role:"img","aria-label":E,children:[y.map(e=>s.jsx("path",{d:e.path,fill:e.color,className:"brycks-pie-chart__slice"},e.id)),m?s.jsx("circle",{cx:l,cy:l,r:A,className:"brycks-pie-chart__hole"}):null]}),m?s.jsxs("div",{className:"brycks-pie-chart__center","aria-hidden":"true",children:[s.jsx("span",{className:"brycks-pie-chart__center-value",children:i??o(w)}),u?s.jsx("span",{className:"brycks-pie-chart__center-label",children:u}):null]}):null]}),d==="none"?null:s.jsx("ul",{className:"brycks-pie-chart__legend",children:y.map(e=>s.jsxs("li",{className:"brycks-pie-chart__legend-item",children:[s.jsx("span",{className:"brycks-pie-chart__legend-dot",style:{backgroundColor:e.color},"aria-hidden":"true"}),s.jsx("span",{className:"brycks-pie-chart__legend-label",children:e.label}),s.jsx("span",{className:"brycks-pie-chart__legend-value",children:o(e.value)}),P?s.jsxs("span",{className:"brycks-pie-chart__legend-share",children:[Math.round(e.share*100),"%"]}):null]},e.id))})]})});R.displayName="PieChart";exports.PieChart=R;
2
+ //# sourceMappingURL=PieChart.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PieChart.cjs","sources":["../../../../src/components/data/PieChart/PieChart.tsx"],"sourcesContent":["/**\n * PieChart Component\n *\n * Distribuição de um total em fatias — pizza ou rosca (donut). Desenhado em SVG\n * puro: sem dependência de runtime, sem canvas, imprimível e nítido em qualquer\n * densidade de tela.\n *\n * Quando usar: partes-de-um-todo mutuamente exclusivas (leads por status,\n * estoque por condição, receita por categoria). Para série temporal ou\n * comparação precisa entre muitas categorias, uma lista/barra lê melhor —\n * a pizza é forte até ~6 fatias.\n *\n * Acessibilidade: o gráfico é `role=\"img\"` com um resumo em `aria-label`, e a\n * legenda repete rótulo + valor + participação como texto real — leitor de tela\n * e daltônico não dependem da cor (cada item tem rótulo e valor).\n *\n * @example\n * <PieChart\n * data={[\n * { id: 'new', label: 'Novo', value: 3, color: 'var(--brycks-info-default)' },\n * { id: 'won', label: 'Convertido', value: 5, color: 'var(--brycks-success-default)' },\n * ]}\n * centerLabel=\"Leads\"\n * />\n *\n * @module components/data/PieChart\n */\n\nimport { forwardRef, useMemo, type HTMLAttributes, type ReactNode } from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type PieChartLegend = 'right' | 'bottom' | 'none'\n\nexport interface PieSlice {\n /** Chave estável da fatia */\n id: string\n /** Rótulo legível (aparece na legenda e no leitor de tela) */\n label: string\n /** Valor absoluto — negativos são ignorados */\n value: number\n /** Cor da fatia; use um token (`var(--brycks-*)`). Sem cor, entra na paleta padrão. */\n color?: string\n}\n\nexport interface PieChartProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onSelect'> {\n /** Fatias do gráfico */\n data: PieSlice[]\n /** Diâmetro do gráfico em px */\n size?: number\n /** Espessura do anel em px. `0` = pizza cheia; padrão = rosca */\n thickness?: number\n /** Posição da legenda */\n legend?: PieChartLegend\n /** Rótulo no centro da rosca (ignorado quando `thickness = 0`) */\n centerLabel?: ReactNode\n /** Conteúdo central; por padrão, a soma dos valores */\n centerValue?: ReactNode\n /** Formata valores na legenda, no centro e no resumo acessível */\n valueFormatter?: (value: number) => string\n /** Exibe a participação percentual de cada fatia na legenda */\n showShare?: boolean\n /** Texto quando não há dado positivo */\n emptyText?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\n/** Paleta de fallback: percorre a rampa semântica antes de repetir. */\nconst DEFAULT_COLORS = [\n 'var(--brycks-primary-default)',\n 'var(--brycks-info-default)',\n 'var(--brycks-success-default)',\n 'var(--brycks-warning-default)',\n 'var(--brycks-error-default)',\n 'var(--brycks-foreground-subtle)',\n]\n\nconst VIEWBOX = 100\nconst CENTER = VIEWBOX / 2\nconst RADIUS = CENTER - 1\n\ninterface ResolvedSlice extends PieSlice {\n color: string\n share: number\n path: string\n}\n\nfunction polarToCartesian(angleInDegrees: number, radius: number) {\n const angleInRadians = ((angleInDegrees - 90) * Math.PI) / 180\n return {\n x: CENTER + radius * Math.cos(angleInRadians),\n y: CENTER + radius * Math.sin(angleInRadians),\n }\n}\n\n/**\n * Arco de uma fatia. Um arco de 360° tem início e fim no mesmo ponto — o `A` do\n * SVG não desenha nada nesse caso; por isso a fatia única vira dois semiarcos.\n */\nfunction slicePath(startAngle: number, endAngle: number): string {\n const sweep = endAngle - startAngle\n if (sweep >= 359.999) {\n const top = polarToCartesian(0, RADIUS)\n const bottom = polarToCartesian(180, RADIUS)\n return [\n `M ${top.x} ${top.y}`,\n `A ${RADIUS} ${RADIUS} 0 1 1 ${bottom.x} ${bottom.y}`,\n `A ${RADIUS} ${RADIUS} 0 1 1 ${top.x} ${top.y}`,\n ].join(' ')\n }\n const start = polarToCartesian(startAngle, RADIUS)\n const end = polarToCartesian(endAngle, RADIUS)\n const largeArc = sweep > 180 ? 1 : 0\n return [\n `M ${CENTER} ${CENTER}`,\n `L ${start.x} ${start.y}`,\n `A ${RADIUS} ${RADIUS} 0 ${largeArc} 1 ${end.x} ${end.y}`,\n 'Z',\n ].join(' ')\n}\n\nconst defaultFormatter = (value: number) => String(value)\n\nexport const PieChart = forwardRef<HTMLDivElement, PieChartProps>(function PieChart(\n {\n data,\n size = 168,\n thickness = 22,\n legend = 'right',\n centerLabel,\n centerValue,\n valueFormatter = defaultFormatter,\n showShare = true,\n emptyText = 'Sem dados',\n className,\n testId,\n ...props\n },\n ref\n) {\n const { slices, total } = useMemo(() => {\n const positive = data.filter((slice) => slice.value > 0)\n const sum = positive.reduce((acc, slice) => acc + slice.value, 0)\n\n let cursor = 0\n const resolved: ResolvedSlice[] = positive.map((slice, index) => {\n const share = sum > 0 ? slice.value / sum : 0\n const startAngle = cursor\n cursor += share * 360\n return {\n ...slice,\n color: slice.color ?? DEFAULT_COLORS[index % DEFAULT_COLORS.length],\n share,\n path: slicePath(startAngle, cursor),\n }\n })\n\n return { slices: resolved, total: sum }\n }, [data])\n\n const isDonut = thickness > 0\n /* O furo é um disco da cor da superfície — mantém o SVG num só elemento e\n evita `mask`, que quebra em impressão e em forced-colors. */\n const holeRadius = isDonut ? Math.max(0, RADIUS - (thickness / size) * VIEWBOX) : 0\n\n const summary = slices\n .map((slice) => `${slice.label}: ${valueFormatter(slice.value)} (${Math.round(slice.share * 100)}%)`)\n .join(', ')\n\n if (slices.length === 0) {\n return (\n <div\n ref={ref}\n className={cx('brycks-pie-chart', 'brycks-pie-chart--empty', className)}\n data-testid={testId}\n {...props}\n >\n <span className=\"brycks-pie-chart__empty\">{emptyText}</span>\n </div>\n )\n }\n\n return (\n <div\n ref={ref}\n className={cx('brycks-pie-chart', `brycks-pie-chart--legend-${legend}`, className)}\n data-testid={testId}\n {...props}\n >\n <div className=\"brycks-pie-chart__graphic\" style={{ width: size, height: size }}>\n <svg\n viewBox={`0 0 ${VIEWBOX} ${VIEWBOX}`}\n className=\"brycks-pie-chart__svg\"\n role=\"img\"\n aria-label={summary}\n >\n {slices.map((slice) => (\n <path\n key={slice.id}\n d={slice.path}\n fill={slice.color}\n className=\"brycks-pie-chart__slice\"\n />\n ))}\n {isDonut ? (\n <circle cx={CENTER} cy={CENTER} r={holeRadius} className=\"brycks-pie-chart__hole\" />\n ) : null}\n </svg>\n\n {isDonut ? (\n <div className=\"brycks-pie-chart__center\" aria-hidden=\"true\">\n <span className=\"brycks-pie-chart__center-value\">\n {centerValue ?? valueFormatter(total)}\n </span>\n {centerLabel ? (\n <span className=\"brycks-pie-chart__center-label\">{centerLabel}</span>\n ) : null}\n </div>\n ) : null}\n </div>\n\n {legend === 'none' ? null : (\n <ul className=\"brycks-pie-chart__legend\">\n {slices.map((slice) => (\n <li key={slice.id} className=\"brycks-pie-chart__legend-item\">\n <span\n className=\"brycks-pie-chart__legend-dot\"\n style={{ backgroundColor: slice.color }}\n aria-hidden=\"true\"\n />\n <span className=\"brycks-pie-chart__legend-label\">{slice.label}</span>\n <span className=\"brycks-pie-chart__legend-value\">{valueFormatter(slice.value)}</span>\n {showShare ? (\n <span className=\"brycks-pie-chart__legend-share\">\n {Math.round(slice.share * 100)}%\n </span>\n ) : null}\n </li>\n ))}\n </ul>\n )}\n </div>\n )\n})\n\nPieChart.displayName = 'PieChart'\n"],"names":["DEFAULT_COLORS","VIEWBOX","CENTER","RADIUS","polarToCartesian","angleInDegrees","radius","angleInRadians","slicePath","startAngle","endAngle","sweep","top","bottom","start","end","largeArc","defaultFormatter","value","PieChart","forwardRef","data","size","thickness","legend","centerLabel","centerValue","valueFormatter","showShare","emptyText","className","testId","props","ref","slices","total","useMemo","positive","slice","sum","acc","cursor","index","share","isDonut","holeRadius","summary","jsx","cx","jsxs"],"mappings":"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"}
@@ -0,0 +1,132 @@
1
+ import { jsx as e, jsxs as h } from "react/jsx-runtime";
2
+ import { forwardRef as D, useMemo as I } from "react";
3
+ import { cx as C } from "../../../utils/styles.js";
4
+ const R = [
5
+ "var(--brycks-primary-default)",
6
+ "var(--brycks-info-default)",
7
+ "var(--brycks-success-default)",
8
+ "var(--brycks-warning-default)",
9
+ "var(--brycks-error-default)",
10
+ "var(--brycks-foreground-subtle)"
11
+ ], b = 100, l = b / 2, a = l - 1;
12
+ function m(t, s) {
13
+ const c = (t - 90) * Math.PI / 180;
14
+ return {
15
+ x: l + s * Math.cos(c),
16
+ y: l + s * Math.sin(c)
17
+ };
18
+ }
19
+ function O(t, s) {
20
+ const c = s - t;
21
+ if (c >= 359.999) {
22
+ const o = m(0, a), i = m(180, a);
23
+ return [
24
+ `M ${o.x} ${o.y}`,
25
+ `A ${a} ${a} 0 1 1 ${i.x} ${i.y}`,
26
+ `A ${a} ${a} 0 1 1 ${o.x} ${o.y}`
27
+ ].join(" ");
28
+ }
29
+ const d = m(t, a), p = m(s, a), u = c > 180 ? 1 : 0;
30
+ return [
31
+ `M ${l} ${l}`,
32
+ `L ${d.x} ${d.y}`,
33
+ `A ${a} ${a} 0 ${u} 1 ${p.x} ${p.y}`,
34
+ "Z"
35
+ ].join(" ");
36
+ }
37
+ const T = (t) => String(t), B = D(function({
38
+ data: s,
39
+ size: c = 168,
40
+ thickness: d = 22,
41
+ legend: p = "right",
42
+ centerLabel: u,
43
+ centerValue: o,
44
+ valueFormatter: i = T,
45
+ showShare: j = !0,
46
+ emptyText: w = "Sem dados",
47
+ className: f,
48
+ testId: g,
49
+ ...N
50
+ }, x) {
51
+ const { slices: y, total: A } = I(() => {
52
+ const r = s.filter((n) => n.value > 0), $ = r.reduce((n, v) => n + v.value, 0);
53
+ let k = 0;
54
+ return { slices: r.map((n, v) => {
55
+ const M = $ > 0 ? n.value / $ : 0, S = k;
56
+ return k += M * 360, {
57
+ ...n,
58
+ color: n.color ?? R[v % R.length],
59
+ share: M,
60
+ path: O(S, k)
61
+ };
62
+ }), total: $ };
63
+ }, [s]), _ = d > 0, P = _ ? Math.max(0, a - d / c * b) : 0, E = y.map((r) => `${r.label}: ${i(r.value)} (${Math.round(r.share * 100)}%)`).join(", ");
64
+ return y.length === 0 ? /* @__PURE__ */ e(
65
+ "div",
66
+ {
67
+ ref: x,
68
+ className: C("brycks-pie-chart", "brycks-pie-chart--empty", f),
69
+ "data-testid": g,
70
+ ...N,
71
+ children: /* @__PURE__ */ e("span", { className: "brycks-pie-chart__empty", children: w })
72
+ }
73
+ ) : /* @__PURE__ */ h(
74
+ "div",
75
+ {
76
+ ref: x,
77
+ className: C("brycks-pie-chart", `brycks-pie-chart--legend-${p}`, f),
78
+ "data-testid": g,
79
+ ...N,
80
+ children: [
81
+ /* @__PURE__ */ h("div", { className: "brycks-pie-chart__graphic", style: { width: c, height: c }, children: [
82
+ /* @__PURE__ */ h(
83
+ "svg",
84
+ {
85
+ viewBox: `0 0 ${b} ${b}`,
86
+ className: "brycks-pie-chart__svg",
87
+ role: "img",
88
+ "aria-label": E,
89
+ children: [
90
+ y.map((r) => /* @__PURE__ */ e(
91
+ "path",
92
+ {
93
+ d: r.path,
94
+ fill: r.color,
95
+ className: "brycks-pie-chart__slice"
96
+ },
97
+ r.id
98
+ )),
99
+ _ ? /* @__PURE__ */ e("circle", { cx: l, cy: l, r: P, className: "brycks-pie-chart__hole" }) : null
100
+ ]
101
+ }
102
+ ),
103
+ _ ? /* @__PURE__ */ h("div", { className: "brycks-pie-chart__center", "aria-hidden": "true", children: [
104
+ /* @__PURE__ */ e("span", { className: "brycks-pie-chart__center-value", children: o ?? i(A) }),
105
+ u ? /* @__PURE__ */ e("span", { className: "brycks-pie-chart__center-label", children: u }) : null
106
+ ] }) : null
107
+ ] }),
108
+ p === "none" ? null : /* @__PURE__ */ e("ul", { className: "brycks-pie-chart__legend", children: y.map((r) => /* @__PURE__ */ h("li", { className: "brycks-pie-chart__legend-item", children: [
109
+ /* @__PURE__ */ e(
110
+ "span",
111
+ {
112
+ className: "brycks-pie-chart__legend-dot",
113
+ style: { backgroundColor: r.color },
114
+ "aria-hidden": "true"
115
+ }
116
+ ),
117
+ /* @__PURE__ */ e("span", { className: "brycks-pie-chart__legend-label", children: r.label }),
118
+ /* @__PURE__ */ e("span", { className: "brycks-pie-chart__legend-value", children: i(r.value) }),
119
+ j ? /* @__PURE__ */ h("span", { className: "brycks-pie-chart__legend-share", children: [
120
+ Math.round(r.share * 100),
121
+ "%"
122
+ ] }) : null
123
+ ] }, r.id)) })
124
+ ]
125
+ }
126
+ );
127
+ });
128
+ B.displayName = "PieChart";
129
+ export {
130
+ B as PieChart
131
+ };
132
+ //# sourceMappingURL=PieChart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PieChart.js","sources":["../../../../src/components/data/PieChart/PieChart.tsx"],"sourcesContent":["/**\n * PieChart Component\n *\n * Distribuição de um total em fatias — pizza ou rosca (donut). Desenhado em SVG\n * puro: sem dependência de runtime, sem canvas, imprimível e nítido em qualquer\n * densidade de tela.\n *\n * Quando usar: partes-de-um-todo mutuamente exclusivas (leads por status,\n * estoque por condição, receita por categoria). Para série temporal ou\n * comparação precisa entre muitas categorias, uma lista/barra lê melhor —\n * a pizza é forte até ~6 fatias.\n *\n * Acessibilidade: o gráfico é `role=\"img\"` com um resumo em `aria-label`, e a\n * legenda repete rótulo + valor + participação como texto real — leitor de tela\n * e daltônico não dependem da cor (cada item tem rótulo e valor).\n *\n * @example\n * <PieChart\n * data={[\n * { id: 'new', label: 'Novo', value: 3, color: 'var(--brycks-info-default)' },\n * { id: 'won', label: 'Convertido', value: 5, color: 'var(--brycks-success-default)' },\n * ]}\n * centerLabel=\"Leads\"\n * />\n *\n * @module components/data/PieChart\n */\n\nimport { forwardRef, useMemo, type HTMLAttributes, type ReactNode } from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type PieChartLegend = 'right' | 'bottom' | 'none'\n\nexport interface PieSlice {\n /** Chave estável da fatia */\n id: string\n /** Rótulo legível (aparece na legenda e no leitor de tela) */\n label: string\n /** Valor absoluto — negativos são ignorados */\n value: number\n /** Cor da fatia; use um token (`var(--brycks-*)`). Sem cor, entra na paleta padrão. */\n color?: string\n}\n\nexport interface PieChartProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onSelect'> {\n /** Fatias do gráfico */\n data: PieSlice[]\n /** Diâmetro do gráfico em px */\n size?: number\n /** Espessura do anel em px. `0` = pizza cheia; padrão = rosca */\n thickness?: number\n /** Posição da legenda */\n legend?: PieChartLegend\n /** Rótulo no centro da rosca (ignorado quando `thickness = 0`) */\n centerLabel?: ReactNode\n /** Conteúdo central; por padrão, a soma dos valores */\n centerValue?: ReactNode\n /** Formata valores na legenda, no centro e no resumo acessível */\n valueFormatter?: (value: number) => string\n /** Exibe a participação percentual de cada fatia na legenda */\n showShare?: boolean\n /** Texto quando não há dado positivo */\n emptyText?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\n/** Paleta de fallback: percorre a rampa semântica antes de repetir. */\nconst DEFAULT_COLORS = [\n 'var(--brycks-primary-default)',\n 'var(--brycks-info-default)',\n 'var(--brycks-success-default)',\n 'var(--brycks-warning-default)',\n 'var(--brycks-error-default)',\n 'var(--brycks-foreground-subtle)',\n]\n\nconst VIEWBOX = 100\nconst CENTER = VIEWBOX / 2\nconst RADIUS = CENTER - 1\n\ninterface ResolvedSlice extends PieSlice {\n color: string\n share: number\n path: string\n}\n\nfunction polarToCartesian(angleInDegrees: number, radius: number) {\n const angleInRadians = ((angleInDegrees - 90) * Math.PI) / 180\n return {\n x: CENTER + radius * Math.cos(angleInRadians),\n y: CENTER + radius * Math.sin(angleInRadians),\n }\n}\n\n/**\n * Arco de uma fatia. Um arco de 360° tem início e fim no mesmo ponto — o `A` do\n * SVG não desenha nada nesse caso; por isso a fatia única vira dois semiarcos.\n */\nfunction slicePath(startAngle: number, endAngle: number): string {\n const sweep = endAngle - startAngle\n if (sweep >= 359.999) {\n const top = polarToCartesian(0, RADIUS)\n const bottom = polarToCartesian(180, RADIUS)\n return [\n `M ${top.x} ${top.y}`,\n `A ${RADIUS} ${RADIUS} 0 1 1 ${bottom.x} ${bottom.y}`,\n `A ${RADIUS} ${RADIUS} 0 1 1 ${top.x} ${top.y}`,\n ].join(' ')\n }\n const start = polarToCartesian(startAngle, RADIUS)\n const end = polarToCartesian(endAngle, RADIUS)\n const largeArc = sweep > 180 ? 1 : 0\n return [\n `M ${CENTER} ${CENTER}`,\n `L ${start.x} ${start.y}`,\n `A ${RADIUS} ${RADIUS} 0 ${largeArc} 1 ${end.x} ${end.y}`,\n 'Z',\n ].join(' ')\n}\n\nconst defaultFormatter = (value: number) => String(value)\n\nexport const PieChart = forwardRef<HTMLDivElement, PieChartProps>(function PieChart(\n {\n data,\n size = 168,\n thickness = 22,\n legend = 'right',\n centerLabel,\n centerValue,\n valueFormatter = defaultFormatter,\n showShare = true,\n emptyText = 'Sem dados',\n className,\n testId,\n ...props\n },\n ref\n) {\n const { slices, total } = useMemo(() => {\n const positive = data.filter((slice) => slice.value > 0)\n const sum = positive.reduce((acc, slice) => acc + slice.value, 0)\n\n let cursor = 0\n const resolved: ResolvedSlice[] = positive.map((slice, index) => {\n const share = sum > 0 ? slice.value / sum : 0\n const startAngle = cursor\n cursor += share * 360\n return {\n ...slice,\n color: slice.color ?? DEFAULT_COLORS[index % DEFAULT_COLORS.length],\n share,\n path: slicePath(startAngle, cursor),\n }\n })\n\n return { slices: resolved, total: sum }\n }, [data])\n\n const isDonut = thickness > 0\n /* O furo é um disco da cor da superfície — mantém o SVG num só elemento e\n evita `mask`, que quebra em impressão e em forced-colors. */\n const holeRadius = isDonut ? Math.max(0, RADIUS - (thickness / size) * VIEWBOX) : 0\n\n const summary = slices\n .map((slice) => `${slice.label}: ${valueFormatter(slice.value)} (${Math.round(slice.share * 100)}%)`)\n .join(', ')\n\n if (slices.length === 0) {\n return (\n <div\n ref={ref}\n className={cx('brycks-pie-chart', 'brycks-pie-chart--empty', className)}\n data-testid={testId}\n {...props}\n >\n <span className=\"brycks-pie-chart__empty\">{emptyText}</span>\n </div>\n )\n }\n\n return (\n <div\n ref={ref}\n className={cx('brycks-pie-chart', `brycks-pie-chart--legend-${legend}`, className)}\n data-testid={testId}\n {...props}\n >\n <div className=\"brycks-pie-chart__graphic\" style={{ width: size, height: size }}>\n <svg\n viewBox={`0 0 ${VIEWBOX} ${VIEWBOX}`}\n className=\"brycks-pie-chart__svg\"\n role=\"img\"\n aria-label={summary}\n >\n {slices.map((slice) => (\n <path\n key={slice.id}\n d={slice.path}\n fill={slice.color}\n className=\"brycks-pie-chart__slice\"\n />\n ))}\n {isDonut ? (\n <circle cx={CENTER} cy={CENTER} r={holeRadius} className=\"brycks-pie-chart__hole\" />\n ) : null}\n </svg>\n\n {isDonut ? (\n <div className=\"brycks-pie-chart__center\" aria-hidden=\"true\">\n <span className=\"brycks-pie-chart__center-value\">\n {centerValue ?? valueFormatter(total)}\n </span>\n {centerLabel ? (\n <span className=\"brycks-pie-chart__center-label\">{centerLabel}</span>\n ) : null}\n </div>\n ) : null}\n </div>\n\n {legend === 'none' ? null : (\n <ul className=\"brycks-pie-chart__legend\">\n {slices.map((slice) => (\n <li key={slice.id} className=\"brycks-pie-chart__legend-item\">\n <span\n className=\"brycks-pie-chart__legend-dot\"\n style={{ backgroundColor: slice.color }}\n aria-hidden=\"true\"\n />\n <span className=\"brycks-pie-chart__legend-label\">{slice.label}</span>\n <span className=\"brycks-pie-chart__legend-value\">{valueFormatter(slice.value)}</span>\n {showShare ? (\n <span className=\"brycks-pie-chart__legend-share\">\n {Math.round(slice.share * 100)}%\n </span>\n ) : null}\n </li>\n ))}\n </ul>\n )}\n </div>\n )\n})\n\nPieChart.displayName = 'PieChart'\n"],"names":["DEFAULT_COLORS","VIEWBOX","CENTER","RADIUS","polarToCartesian","angleInDegrees","radius","angleInRadians","slicePath","startAngle","endAngle","sweep","top","bottom","start","end","largeArc","defaultFormatter","value","PieChart","forwardRef","data","size","thickness","legend","centerLabel","centerValue","valueFormatter","showShare","emptyText","className","testId","props","ref","slices","total","useMemo","positive","slice","sum","acc","cursor","index","share","isDonut","holeRadius","summary","jsx","cx","jsxs"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Table.cjs","sources":["../../../../src/components/data/Table/Table.tsx"],"sourcesContent":["/**\n * Table Component\n *\n * A flexible table component with sorting, selection, and responsive support.\n * Follows design system patterns for consistent styling.\n */\n\nimport {\n forwardRef,\n createContext,\n useContext,\n type CSSProperties,\n type HTMLAttributes,\n type ThHTMLAttributes,\n type TdHTMLAttributes,\n type ReactNode,\n} from 'react'\nimport { cx } from '../../../utils/styles'\nimport { EmptyState } from '../../utility/EmptyState'\nimport { Skeleton } from '../../utility/Skeleton'\n\nexport type TableSize = 'sm' | 'md' | 'lg'\n// `striped` was dead API (no CSS, incompatible with inline row styling) — removed in 0.5.0.\nexport type TableVariant = 'default' | 'bordered'\n\ninterface TableContextValue {\n size: TableSize\n variant: TableVariant\n stickyHeader: boolean\n}\n\nconst TableContext = createContext<TableContextValue>({ size: 'md', variant: 'default', stickyHeader: false })\n\nfunction useTableContext() {\n return useContext(TableContext)\n}\n\nexport interface TableProps extends HTMLAttributes<HTMLTableElement> {\n /** Table size */\n size?: TableSize\n /** Table variant */\n variant?: TableVariant\n /** Whether the table has a sticky header */\n stickyHeader?: boolean\n /** Whether the table is in a loading state */\n loading?: boolean\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const Table = forwardRef<HTMLTableElement, TableProps>(function Table(\n {\n size = 'md',\n variant = 'default',\n stickyHeader = false,\n loading = false,\n className,\n style,\n children,\n testId,\n ...props\n },\n ref\n) {\n return (\n <TableContext.Provider value={{ size, variant, stickyHeader }}>\n <div className=\"brycks-table-container\" style={style}>\n <table\n ref={ref}\n className={cx('brycks-table', `brycks-table--${size}`, `brycks-table--${variant}`, className)}\n style={loading ? { opacity: 0.6 } : undefined}\n aria-busy={loading || undefined}\n data-testid={testId}\n {...props}\n >\n {children}\n </table>\n </div>\n </TableContext.Provider>\n )\n})\n\nTable.displayName = 'Table'\n\n// TableHead\nexport interface TableHeadProps extends HTMLAttributes<HTMLTableSectionElement> {\n /** Whether the header is sticky */\n sticky?: boolean\n /** Custom class name */\n className?: string\n}\n\nexport const TableHead = forwardRef<HTMLTableSectionElement, TableHeadProps>(function TableHead(\n { sticky = false, className, style, children, ...props },\n ref\n) {\n const { stickyHeader } = useTableContext()\n const isSticky = sticky || stickyHeader\n\n return (\n <thead\n ref={ref}\n className={cx('brycks-table-head', isSticky && 'brycks-table-head--sticky', className)}\n style={style}\n {...props}\n >\n {children}\n </thead>\n )\n})\n\nTableHead.displayName = 'TableHead'\n\n// TableBody\nexport interface TableBodyProps extends HTMLAttributes<HTMLTableSectionElement> {\n /** Custom class name */\n className?: string\n}\n\nexport const TableBody = forwardRef<HTMLTableSectionElement, TableBodyProps>(function TableBody(\n { className, style, children, ...props },\n ref\n) {\n return (\n <tbody\n ref={ref}\n className={cx('brycks-table-body', className)}\n style={style}\n {...props}\n >\n {children}\n </tbody>\n )\n})\n\nTableBody.displayName = 'TableBody'\n\n// TableRow\nexport interface TableRowProps extends HTMLAttributes<HTMLTableRowElement> {\n /** Whether the row is selected */\n selected?: boolean\n /** Whether the row is clickable */\n clickable?: boolean\n /** Custom class name */\n className?: string\n}\n\nexport const TableRow = forwardRef<HTMLTableRowElement, TableRowProps>(function TableRow(\n { selected = false, clickable = false, className, style, children, ...props },\n ref\n) {\n return (\n <tr\n ref={ref}\n className={cx(\n 'brycks-table-row',\n selected && 'brycks-table-row--selected',\n clickable && 'brycks-table-row--clickable',\n className\n )}\n style={style}\n {...props}\n >\n {children}\n </tr>\n )\n})\n\nTableRow.displayName = 'TableRow'\n\n// TableHeader (th)\nexport interface TableHeaderProps extends ThHTMLAttributes<HTMLTableCellElement> {\n /** Whether the column is sortable */\n sortable?: boolean\n /** Sort direction */\n sortDirection?: 'asc' | 'desc' | null\n /** Callback when sort is requested */\n onSort?: () => void\n /** Text alignment */\n align?: 'left' | 'center' | 'right'\n /** Custom class name */\n className?: string\n}\n\nfunction SortIcon({ direction }: { direction: 'asc' | 'desc' | null }) {\n if (!direction) {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" style={{ opacity: 0.4 }} aria-hidden=\"true\">\n <path d=\"M7 3L10 6H4L7 3Z\" fill=\"currentColor\" />\n <path d=\"M7 11L4 8H10L7 11Z\" fill=\"currentColor\" />\n </svg>\n )\n }\n\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n {direction === 'asc' ? (\n <path d=\"M7 3L10 6H4L7 3Z\" fill=\"currentColor\" />\n ) : (\n <path d=\"M7 11L4 8H10L7 11Z\" fill=\"currentColor\" />\n )}\n </svg>\n )\n}\n\nexport const TableHeader = forwardRef<HTMLTableCellElement, TableHeaderProps>(function TableHeader(\n {\n sortable = false,\n sortDirection = null,\n onSort,\n align = 'left',\n className,\n style,\n children,\n ...props\n },\n ref\n) {\n // Alignment is dynamic per prop; everything else lives in CSS.\n const alignStyle: CSSProperties = {\n textAlign: align,\n ...style,\n }\n\n const contentJustify: CSSProperties = {\n justifyContent: align === 'right' ? 'flex-end' : align === 'center' ? 'center' : 'flex-start',\n }\n\n return (\n <th\n ref={ref}\n aria-sort={\n sortable\n ? sortDirection === 'asc'\n ? 'ascending'\n : sortDirection === 'desc'\n ? 'descending'\n : 'none'\n : undefined\n }\n className={cx('brycks-table-header', sortable && 'brycks-table-header--sortable', className)}\n style={alignStyle}\n {...props}\n >\n {sortable ? (\n // Sorting happens through a real button so it is reachable by keyboard\n <button\n type=\"button\"\n className=\"brycks-table-header__content brycks-table-header__sort\"\n style={contentJustify}\n onClick={() => onSort?.()}\n >\n {children}\n <SortIcon direction={sortDirection} />\n </button>\n ) : (\n <span className=\"brycks-table-header__content\" style={contentJustify}>\n {children}\n </span>\n )}\n </th>\n )\n})\n\nTableHeader.displayName = 'TableHeader'\n\n// TableCell (td)\nexport interface TableCellProps extends TdHTMLAttributes<HTMLTableCellElement> {\n /** Text alignment */\n align?: 'left' | 'center' | 'right'\n /** Whether to truncate text */\n truncate?: boolean\n /** Custom class name */\n className?: string\n}\n\nexport const TableCell = forwardRef<HTMLTableCellElement, TableCellProps>(function TableCell(\n { align = 'left', truncate = false, className, style, children, ...props },\n ref\n) {\n // Alignment is dynamic per prop; everything else lives in CSS.\n const alignStyle: CSSProperties = {\n textAlign: align,\n ...style,\n }\n\n return (\n <td\n ref={ref}\n className={cx('brycks-table-cell', truncate && 'brycks-table-cell--truncate', className)}\n style={alignStyle}\n title={truncate && typeof children === 'string' ? children : undefined}\n {...props}\n >\n {children}\n </td>\n )\n})\n\nTableCell.displayName = 'TableCell'\n\n// TableFoot\nexport interface TableFootProps extends HTMLAttributes<HTMLTableSectionElement> {\n /** Custom class name */\n className?: string\n}\n\nexport const TableFoot = forwardRef<HTMLTableSectionElement, TableFootProps>(function TableFoot(\n { className, style, children, ...props },\n ref\n) {\n return (\n <tfoot\n ref={ref}\n className={cx('brycks-table-foot', className)}\n style={style}\n {...props}\n >\n {children}\n </tfoot>\n )\n})\n\nTableFoot.displayName = 'TableFoot'\n\n// TableCaption\nexport interface TableCaptionProps extends HTMLAttributes<HTMLTableCaptionElement> {\n /** Caption placement */\n placement?: 'top' | 'bottom'\n /** Custom class name */\n className?: string\n}\n\nexport const TableCaption = forwardRef<HTMLTableCaptionElement, TableCaptionProps>(function TableCaption(\n { placement = 'bottom', className, style, children, ...props },\n ref\n) {\n // Caption side is dynamic per prop; everything else lives in CSS.\n const captionStyle: CSSProperties = {\n captionSide: placement,\n ...style,\n }\n\n return (\n <caption\n ref={ref}\n className={cx('brycks-table-caption', className)}\n style={captionStyle}\n {...props}\n >\n {children}\n </caption>\n )\n})\n\nTableCaption.displayName = 'TableCaption'\n\n// TableEmpty — a full-width empty state row, drop inside <TableBody>\nexport interface TableEmptyProps {\n /** Number of columns to span (match the table's column count) */\n colSpan: number\n /** Icon or illustration */\n icon?: ReactNode\n /** Title text */\n title?: ReactNode\n /** Description text */\n description?: ReactNode\n /** Action element (button, link) */\n action?: ReactNode\n /** Custom class name */\n className?: string\n}\n\nexport const TableEmpty = forwardRef<HTMLTableRowElement, TableEmptyProps>(function TableEmpty(\n { colSpan, icon, title, description, action, className },\n ref\n) {\n return (\n <tr ref={ref} className={cx('brycks-table-empty', className)}>\n <td colSpan={colSpan} style={{ padding: 0 }}>\n <EmptyState icon={icon} title={title} description={description} action={action} />\n </td>\n </tr>\n )\n})\n\nTableEmpty.displayName = 'TableEmpty'\n\n// TableSkeleton — placeholder rows shown while data loads, drop inside <TableBody>\nexport interface TableSkeletonProps {\n /** Number of skeleton rows */\n rows?: number\n /** Number of columns per row (match the table's column count) */\n columns: number\n /** Custom class name applied to each row */\n className?: string\n}\n\n// Deterministic per-column widths so the placeholder reads like real data\nconst skeletonWidths = ['70%', '45%', '85%', '55%', '60%', '40%']\n\nexport function TableSkeleton({ rows = 5, columns, className }: TableSkeletonProps) {\n return (\n <>\n {Array.from({ length: rows }).map((_, rowIndex) => (\n <TableRow key={rowIndex} className={cx('brycks-table-skeleton-row', className)} aria-hidden=\"true\">\n {Array.from({ length: columns }).map((_, colIndex) => (\n <TableCell key={colIndex}>\n <Skeleton variant=\"text\" width={skeletonWidths[colIndex % skeletonWidths.length]} />\n </TableCell>\n ))}\n </TableRow>\n ))}\n </>\n )\n}\n\nTableSkeleton.displayName = 'TableSkeleton'\n"],"names":["TableContext","createContext","useTableContext","useContext","Table","forwardRef","size","variant","stickyHeader","loading","className","style","children","testId","props","ref","jsx","cx","TableHead","sticky","isSticky","TableBody","TableRow","selected","clickable","SortIcon","direction","TableHeader","sortable","sortDirection","onSort","align","alignStyle","contentJustify","jsxs","TableCell","truncate","TableFoot","TableCaption","placement","captionStyle","TableEmpty","colSpan","icon","title","description","action","EmptyState","skeletonWidths","TableSkeleton","rows","columns","Fragment","_","rowIndex","colIndex","Skeleton"],"mappings":"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"}
1
+ {"version":3,"file":"Table.cjs","sources":["../../../../src/components/data/Table/Table.tsx"],"sourcesContent":["/**\r\n * Table Component\r\n *\r\n * A flexible table component with sorting, selection, and responsive support.\r\n * Follows design system patterns for consistent styling.\r\n */\r\n\r\nimport {\r\n forwardRef,\r\n createContext,\r\n useContext,\r\n type CSSProperties,\r\n type HTMLAttributes,\r\n type ThHTMLAttributes,\r\n type TdHTMLAttributes,\r\n type ReactNode,\r\n} from 'react'\r\nimport { cx } from '../../../utils/styles'\r\nimport { EmptyState } from '../../utility/EmptyState'\r\nimport { Skeleton } from '../../utility/Skeleton'\r\n\r\nexport type TableSize = 'sm' | 'md' | 'lg'\r\n// `striped` was dead API (no CSS, incompatible with inline row styling) — removed in 0.5.0.\r\nexport type TableVariant = 'default' | 'bordered'\r\n\r\ninterface TableContextValue {\r\n size: TableSize\r\n variant: TableVariant\r\n stickyHeader: boolean\r\n}\r\n\r\nconst TableContext = createContext<TableContextValue>({ size: 'md', variant: 'default', stickyHeader: false })\r\n\r\nfunction useTableContext() {\r\n return useContext(TableContext)\r\n}\r\n\r\nexport interface TableProps extends HTMLAttributes<HTMLTableElement> {\r\n /** Table size */\r\n size?: TableSize\r\n /** Table variant */\r\n variant?: TableVariant\r\n /** Whether the table has a sticky header */\r\n stickyHeader?: boolean\r\n /** Whether the table is in a loading state */\r\n loading?: boolean\r\n /** Custom class name */\r\n className?: string\r\n /** Test ID */\r\n testId?: string\r\n}\r\n\r\nexport const Table = forwardRef<HTMLTableElement, TableProps>(function Table(\r\n {\r\n size = 'md',\r\n variant = 'default',\r\n stickyHeader = false,\r\n loading = false,\r\n className,\r\n style,\r\n children,\r\n testId,\r\n ...props\r\n },\r\n ref\r\n) {\r\n return (\r\n <TableContext.Provider value={{ size, variant, stickyHeader }}>\r\n <div className=\"brycks-table-container\" style={style}>\r\n <table\r\n ref={ref}\r\n className={cx('brycks-table', `brycks-table--${size}`, `brycks-table--${variant}`, className)}\r\n style={loading ? { opacity: 0.6 } : undefined}\r\n aria-busy={loading || undefined}\r\n data-testid={testId}\r\n {...props}\r\n >\r\n {children}\r\n </table>\r\n </div>\r\n </TableContext.Provider>\r\n )\r\n})\r\n\r\nTable.displayName = 'Table'\r\n\r\n// TableHead\r\nexport interface TableHeadProps extends HTMLAttributes<HTMLTableSectionElement> {\r\n /** Whether the header is sticky */\r\n sticky?: boolean\r\n /** Custom class name */\r\n className?: string\r\n}\r\n\r\nexport const TableHead = forwardRef<HTMLTableSectionElement, TableHeadProps>(function TableHead(\r\n { sticky = false, className, style, children, ...props },\r\n ref\r\n) {\r\n const { stickyHeader } = useTableContext()\r\n const isSticky = sticky || stickyHeader\r\n\r\n return (\r\n <thead\r\n ref={ref}\r\n className={cx('brycks-table-head', isSticky && 'brycks-table-head--sticky', className)}\r\n style={style}\r\n {...props}\r\n >\r\n {children}\r\n </thead>\r\n )\r\n})\r\n\r\nTableHead.displayName = 'TableHead'\r\n\r\n// TableBody\r\nexport interface TableBodyProps extends HTMLAttributes<HTMLTableSectionElement> {\r\n /** Custom class name */\r\n className?: string\r\n}\r\n\r\nexport const TableBody = forwardRef<HTMLTableSectionElement, TableBodyProps>(function TableBody(\r\n { className, style, children, ...props },\r\n ref\r\n) {\r\n return (\r\n <tbody\r\n ref={ref}\r\n className={cx('brycks-table-body', className)}\r\n style={style}\r\n {...props}\r\n >\r\n {children}\r\n </tbody>\r\n )\r\n})\r\n\r\nTableBody.displayName = 'TableBody'\r\n\r\n// TableRow\r\nexport interface TableRowProps extends HTMLAttributes<HTMLTableRowElement> {\r\n /** Whether the row is selected */\r\n selected?: boolean\r\n /** Whether the row is clickable */\r\n clickable?: boolean\r\n /** Custom class name */\r\n className?: string\r\n}\r\n\r\nexport const TableRow = forwardRef<HTMLTableRowElement, TableRowProps>(function TableRow(\r\n { selected = false, clickable = false, className, style, children, ...props },\r\n ref\r\n) {\r\n return (\r\n <tr\r\n ref={ref}\r\n className={cx(\r\n 'brycks-table-row',\r\n selected && 'brycks-table-row--selected',\r\n clickable && 'brycks-table-row--clickable',\r\n className\r\n )}\r\n style={style}\r\n {...props}\r\n >\r\n {children}\r\n </tr>\r\n )\r\n})\r\n\r\nTableRow.displayName = 'TableRow'\r\n\r\n// TableHeader (th)\r\nexport interface TableHeaderProps extends ThHTMLAttributes<HTMLTableCellElement> {\r\n /** Whether the column is sortable */\r\n sortable?: boolean\r\n /** Sort direction */\r\n sortDirection?: 'asc' | 'desc' | null\r\n /** Callback when sort is requested */\r\n onSort?: () => void\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right'\r\n /** Custom class name */\r\n className?: string\r\n}\r\n\r\nfunction SortIcon({ direction }: { direction: 'asc' | 'desc' | null }) {\r\n if (!direction) {\r\n return (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" style={{ opacity: 0.4 }} aria-hidden=\"true\">\r\n <path d=\"M7 3L10 6H4L7 3Z\" fill=\"currentColor\" />\r\n <path d=\"M7 11L4 8H10L7 11Z\" fill=\"currentColor\" />\r\n </svg>\r\n )\r\n }\r\n\r\n return (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\r\n {direction === 'asc' ? (\r\n <path d=\"M7 3L10 6H4L7 3Z\" fill=\"currentColor\" />\r\n ) : (\r\n <path d=\"M7 11L4 8H10L7 11Z\" fill=\"currentColor\" />\r\n )}\r\n </svg>\r\n )\r\n}\r\n\r\nexport const TableHeader = forwardRef<HTMLTableCellElement, TableHeaderProps>(function TableHeader(\r\n {\r\n sortable = false,\r\n sortDirection = null,\r\n onSort,\r\n align = 'left',\r\n className,\r\n style,\r\n children,\r\n ...props\r\n },\r\n ref\r\n) {\r\n // Alignment is dynamic per prop; everything else lives in CSS.\r\n const alignStyle: CSSProperties = {\r\n textAlign: align,\r\n ...style,\r\n }\r\n\r\n const contentJustify: CSSProperties = {\r\n justifyContent: align === 'right' ? 'flex-end' : align === 'center' ? 'center' : 'flex-start',\r\n }\r\n\r\n return (\r\n <th\r\n ref={ref}\r\n aria-sort={\r\n sortable\r\n ? sortDirection === 'asc'\r\n ? 'ascending'\r\n : sortDirection === 'desc'\r\n ? 'descending'\r\n : 'none'\r\n : undefined\r\n }\r\n className={cx('brycks-table-header', sortable && 'brycks-table-header--sortable', className)}\r\n style={alignStyle}\r\n {...props}\r\n >\r\n {sortable ? (\r\n // Sorting happens through a real button so it is reachable by keyboard\r\n <button\r\n type=\"button\"\r\n className=\"brycks-table-header__content brycks-table-header__sort\"\r\n style={contentJustify}\r\n onClick={() => onSort?.()}\r\n >\r\n {children}\r\n <SortIcon direction={sortDirection} />\r\n </button>\r\n ) : (\r\n <span className=\"brycks-table-header__content\" style={contentJustify}>\r\n {children}\r\n </span>\r\n )}\r\n </th>\r\n )\r\n})\r\n\r\nTableHeader.displayName = 'TableHeader'\r\n\r\n// TableCell (td)\r\nexport interface TableCellProps extends TdHTMLAttributes<HTMLTableCellElement> {\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right'\r\n /** Whether to truncate text */\r\n truncate?: boolean\r\n /** Custom class name */\r\n className?: string\r\n}\r\n\r\nexport const TableCell = forwardRef<HTMLTableCellElement, TableCellProps>(function TableCell(\r\n { align = 'left', truncate = false, className, style, children, ...props },\r\n ref\r\n) {\r\n // Alignment is dynamic per prop; everything else lives in CSS.\r\n const alignStyle: CSSProperties = {\r\n textAlign: align,\r\n ...style,\r\n }\r\n\r\n return (\r\n <td\r\n ref={ref}\r\n className={cx('brycks-table-cell', truncate && 'brycks-table-cell--truncate', className)}\r\n style={alignStyle}\r\n title={truncate && typeof children === 'string' ? children : undefined}\r\n {...props}\r\n >\r\n {children}\r\n </td>\r\n )\r\n})\r\n\r\nTableCell.displayName = 'TableCell'\r\n\r\n// TableFoot\r\nexport interface TableFootProps extends HTMLAttributes<HTMLTableSectionElement> {\r\n /** Custom class name */\r\n className?: string\r\n}\r\n\r\nexport const TableFoot = forwardRef<HTMLTableSectionElement, TableFootProps>(function TableFoot(\r\n { className, style, children, ...props },\r\n ref\r\n) {\r\n return (\r\n <tfoot\r\n ref={ref}\r\n className={cx('brycks-table-foot', className)}\r\n style={style}\r\n {...props}\r\n >\r\n {children}\r\n </tfoot>\r\n )\r\n})\r\n\r\nTableFoot.displayName = 'TableFoot'\r\n\r\n// TableCaption\r\nexport interface TableCaptionProps extends HTMLAttributes<HTMLTableCaptionElement> {\r\n /** Caption placement */\r\n placement?: 'top' | 'bottom'\r\n /** Custom class name */\r\n className?: string\r\n}\r\n\r\nexport const TableCaption = forwardRef<HTMLTableCaptionElement, TableCaptionProps>(function TableCaption(\r\n { placement = 'bottom', className, style, children, ...props },\r\n ref\r\n) {\r\n // Caption side is dynamic per prop; everything else lives in CSS.\r\n const captionStyle: CSSProperties = {\r\n captionSide: placement,\r\n ...style,\r\n }\r\n\r\n return (\r\n <caption\r\n ref={ref}\r\n className={cx('brycks-table-caption', className)}\r\n style={captionStyle}\r\n {...props}\r\n >\r\n {children}\r\n </caption>\r\n )\r\n})\r\n\r\nTableCaption.displayName = 'TableCaption'\r\n\r\n// TableEmpty — a full-width empty state row, drop inside <TableBody>\r\nexport interface TableEmptyProps {\r\n /** Number of columns to span (match the table's column count) */\r\n colSpan: number\r\n /** Icon or illustration */\r\n icon?: ReactNode\r\n /** Title text */\r\n title?: ReactNode\r\n /** Description text */\r\n description?: ReactNode\r\n /** Action element (button, link) */\r\n action?: ReactNode\r\n /** Custom class name */\r\n className?: string\r\n}\r\n\r\nexport const TableEmpty = forwardRef<HTMLTableRowElement, TableEmptyProps>(function TableEmpty(\r\n { colSpan, icon, title, description, action, className },\r\n ref\r\n) {\r\n return (\r\n <tr ref={ref} className={cx('brycks-table-empty', className)}>\r\n <td colSpan={colSpan} style={{ padding: 0 }}>\r\n <EmptyState icon={icon} title={title} description={description} action={action} />\r\n </td>\r\n </tr>\r\n )\r\n})\r\n\r\nTableEmpty.displayName = 'TableEmpty'\r\n\r\n// TableSkeleton — placeholder rows shown while data loads, drop inside <TableBody>\r\nexport interface TableSkeletonProps {\r\n /** Number of skeleton rows */\r\n rows?: number\r\n /** Number of columns per row (match the table's column count) */\r\n columns: number\r\n /** Custom class name applied to each row */\r\n className?: string\r\n}\r\n\r\n// Deterministic per-column widths so the placeholder reads like real data\r\nconst skeletonWidths = ['70%', '45%', '85%', '55%', '60%', '40%']\r\n\r\nexport function TableSkeleton({ rows = 5, columns, className }: TableSkeletonProps) {\r\n return (\r\n <>\r\n {Array.from({ length: rows }).map((_, rowIndex) => (\r\n <TableRow key={rowIndex} className={cx('brycks-table-skeleton-row', className)} aria-hidden=\"true\">\r\n {Array.from({ length: columns }).map((_, colIndex) => (\r\n <TableCell key={colIndex}>\r\n <Skeleton variant=\"text\" width={skeletonWidths[colIndex % skeletonWidths.length]} />\r\n </TableCell>\r\n ))}\r\n </TableRow>\r\n ))}\r\n </>\r\n )\r\n}\r\n\r\nTableSkeleton.displayName = 'TableSkeleton'\r\n"],"names":["TableContext","createContext","useTableContext","useContext","Table","forwardRef","size","variant","stickyHeader","loading","className","style","children","testId","props","ref","jsx","cx","TableHead","sticky","isSticky","TableBody","TableRow","selected","clickable","SortIcon","direction","TableHeader","sortable","sortDirection","onSort","align","alignStyle","contentJustify","jsxs","TableCell","truncate","TableFoot","TableCaption","placement","captionStyle","TableEmpty","colSpan","icon","title","description","action","EmptyState","skeletonWidths","TableSkeleton","rows","columns","Fragment","_","rowIndex","colIndex","Skeleton"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Table.js","sources":["../../../../src/components/data/Table/Table.tsx"],"sourcesContent":["/**\n * Table Component\n *\n * A flexible table component with sorting, selection, and responsive support.\n * Follows design system patterns for consistent styling.\n */\n\nimport {\n forwardRef,\n createContext,\n useContext,\n type CSSProperties,\n type HTMLAttributes,\n type ThHTMLAttributes,\n type TdHTMLAttributes,\n type ReactNode,\n} from 'react'\nimport { cx } from '../../../utils/styles'\nimport { EmptyState } from '../../utility/EmptyState'\nimport { Skeleton } from '../../utility/Skeleton'\n\nexport type TableSize = 'sm' | 'md' | 'lg'\n// `striped` was dead API (no CSS, incompatible with inline row styling) — removed in 0.5.0.\nexport type TableVariant = 'default' | 'bordered'\n\ninterface TableContextValue {\n size: TableSize\n variant: TableVariant\n stickyHeader: boolean\n}\n\nconst TableContext = createContext<TableContextValue>({ size: 'md', variant: 'default', stickyHeader: false })\n\nfunction useTableContext() {\n return useContext(TableContext)\n}\n\nexport interface TableProps extends HTMLAttributes<HTMLTableElement> {\n /** Table size */\n size?: TableSize\n /** Table variant */\n variant?: TableVariant\n /** Whether the table has a sticky header */\n stickyHeader?: boolean\n /** Whether the table is in a loading state */\n loading?: boolean\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nexport const Table = forwardRef<HTMLTableElement, TableProps>(function Table(\n {\n size = 'md',\n variant = 'default',\n stickyHeader = false,\n loading = false,\n className,\n style,\n children,\n testId,\n ...props\n },\n ref\n) {\n return (\n <TableContext.Provider value={{ size, variant, stickyHeader }}>\n <div className=\"brycks-table-container\" style={style}>\n <table\n ref={ref}\n className={cx('brycks-table', `brycks-table--${size}`, `brycks-table--${variant}`, className)}\n style={loading ? { opacity: 0.6 } : undefined}\n aria-busy={loading || undefined}\n data-testid={testId}\n {...props}\n >\n {children}\n </table>\n </div>\n </TableContext.Provider>\n )\n})\n\nTable.displayName = 'Table'\n\n// TableHead\nexport interface TableHeadProps extends HTMLAttributes<HTMLTableSectionElement> {\n /** Whether the header is sticky */\n sticky?: boolean\n /** Custom class name */\n className?: string\n}\n\nexport const TableHead = forwardRef<HTMLTableSectionElement, TableHeadProps>(function TableHead(\n { sticky = false, className, style, children, ...props },\n ref\n) {\n const { stickyHeader } = useTableContext()\n const isSticky = sticky || stickyHeader\n\n return (\n <thead\n ref={ref}\n className={cx('brycks-table-head', isSticky && 'brycks-table-head--sticky', className)}\n style={style}\n {...props}\n >\n {children}\n </thead>\n )\n})\n\nTableHead.displayName = 'TableHead'\n\n// TableBody\nexport interface TableBodyProps extends HTMLAttributes<HTMLTableSectionElement> {\n /** Custom class name */\n className?: string\n}\n\nexport const TableBody = forwardRef<HTMLTableSectionElement, TableBodyProps>(function TableBody(\n { className, style, children, ...props },\n ref\n) {\n return (\n <tbody\n ref={ref}\n className={cx('brycks-table-body', className)}\n style={style}\n {...props}\n >\n {children}\n </tbody>\n )\n})\n\nTableBody.displayName = 'TableBody'\n\n// TableRow\nexport interface TableRowProps extends HTMLAttributes<HTMLTableRowElement> {\n /** Whether the row is selected */\n selected?: boolean\n /** Whether the row is clickable */\n clickable?: boolean\n /** Custom class name */\n className?: string\n}\n\nexport const TableRow = forwardRef<HTMLTableRowElement, TableRowProps>(function TableRow(\n { selected = false, clickable = false, className, style, children, ...props },\n ref\n) {\n return (\n <tr\n ref={ref}\n className={cx(\n 'brycks-table-row',\n selected && 'brycks-table-row--selected',\n clickable && 'brycks-table-row--clickable',\n className\n )}\n style={style}\n {...props}\n >\n {children}\n </tr>\n )\n})\n\nTableRow.displayName = 'TableRow'\n\n// TableHeader (th)\nexport interface TableHeaderProps extends ThHTMLAttributes<HTMLTableCellElement> {\n /** Whether the column is sortable */\n sortable?: boolean\n /** Sort direction */\n sortDirection?: 'asc' | 'desc' | null\n /** Callback when sort is requested */\n onSort?: () => void\n /** Text alignment */\n align?: 'left' | 'center' | 'right'\n /** Custom class name */\n className?: string\n}\n\nfunction SortIcon({ direction }: { direction: 'asc' | 'desc' | null }) {\n if (!direction) {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" style={{ opacity: 0.4 }} aria-hidden=\"true\">\n <path d=\"M7 3L10 6H4L7 3Z\" fill=\"currentColor\" />\n <path d=\"M7 11L4 8H10L7 11Z\" fill=\"currentColor\" />\n </svg>\n )\n }\n\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n {direction === 'asc' ? (\n <path d=\"M7 3L10 6H4L7 3Z\" fill=\"currentColor\" />\n ) : (\n <path d=\"M7 11L4 8H10L7 11Z\" fill=\"currentColor\" />\n )}\n </svg>\n )\n}\n\nexport const TableHeader = forwardRef<HTMLTableCellElement, TableHeaderProps>(function TableHeader(\n {\n sortable = false,\n sortDirection = null,\n onSort,\n align = 'left',\n className,\n style,\n children,\n ...props\n },\n ref\n) {\n // Alignment is dynamic per prop; everything else lives in CSS.\n const alignStyle: CSSProperties = {\n textAlign: align,\n ...style,\n }\n\n const contentJustify: CSSProperties = {\n justifyContent: align === 'right' ? 'flex-end' : align === 'center' ? 'center' : 'flex-start',\n }\n\n return (\n <th\n ref={ref}\n aria-sort={\n sortable\n ? sortDirection === 'asc'\n ? 'ascending'\n : sortDirection === 'desc'\n ? 'descending'\n : 'none'\n : undefined\n }\n className={cx('brycks-table-header', sortable && 'brycks-table-header--sortable', className)}\n style={alignStyle}\n {...props}\n >\n {sortable ? (\n // Sorting happens through a real button so it is reachable by keyboard\n <button\n type=\"button\"\n className=\"brycks-table-header__content brycks-table-header__sort\"\n style={contentJustify}\n onClick={() => onSort?.()}\n >\n {children}\n <SortIcon direction={sortDirection} />\n </button>\n ) : (\n <span className=\"brycks-table-header__content\" style={contentJustify}>\n {children}\n </span>\n )}\n </th>\n )\n})\n\nTableHeader.displayName = 'TableHeader'\n\n// TableCell (td)\nexport interface TableCellProps extends TdHTMLAttributes<HTMLTableCellElement> {\n /** Text alignment */\n align?: 'left' | 'center' | 'right'\n /** Whether to truncate text */\n truncate?: boolean\n /** Custom class name */\n className?: string\n}\n\nexport const TableCell = forwardRef<HTMLTableCellElement, TableCellProps>(function TableCell(\n { align = 'left', truncate = false, className, style, children, ...props },\n ref\n) {\n // Alignment is dynamic per prop; everything else lives in CSS.\n const alignStyle: CSSProperties = {\n textAlign: align,\n ...style,\n }\n\n return (\n <td\n ref={ref}\n className={cx('brycks-table-cell', truncate && 'brycks-table-cell--truncate', className)}\n style={alignStyle}\n title={truncate && typeof children === 'string' ? children : undefined}\n {...props}\n >\n {children}\n </td>\n )\n})\n\nTableCell.displayName = 'TableCell'\n\n// TableFoot\nexport interface TableFootProps extends HTMLAttributes<HTMLTableSectionElement> {\n /** Custom class name */\n className?: string\n}\n\nexport const TableFoot = forwardRef<HTMLTableSectionElement, TableFootProps>(function TableFoot(\n { className, style, children, ...props },\n ref\n) {\n return (\n <tfoot\n ref={ref}\n className={cx('brycks-table-foot', className)}\n style={style}\n {...props}\n >\n {children}\n </tfoot>\n )\n})\n\nTableFoot.displayName = 'TableFoot'\n\n// TableCaption\nexport interface TableCaptionProps extends HTMLAttributes<HTMLTableCaptionElement> {\n /** Caption placement */\n placement?: 'top' | 'bottom'\n /** Custom class name */\n className?: string\n}\n\nexport const TableCaption = forwardRef<HTMLTableCaptionElement, TableCaptionProps>(function TableCaption(\n { placement = 'bottom', className, style, children, ...props },\n ref\n) {\n // Caption side is dynamic per prop; everything else lives in CSS.\n const captionStyle: CSSProperties = {\n captionSide: placement,\n ...style,\n }\n\n return (\n <caption\n ref={ref}\n className={cx('brycks-table-caption', className)}\n style={captionStyle}\n {...props}\n >\n {children}\n </caption>\n )\n})\n\nTableCaption.displayName = 'TableCaption'\n\n// TableEmpty — a full-width empty state row, drop inside <TableBody>\nexport interface TableEmptyProps {\n /** Number of columns to span (match the table's column count) */\n colSpan: number\n /** Icon or illustration */\n icon?: ReactNode\n /** Title text */\n title?: ReactNode\n /** Description text */\n description?: ReactNode\n /** Action element (button, link) */\n action?: ReactNode\n /** Custom class name */\n className?: string\n}\n\nexport const TableEmpty = forwardRef<HTMLTableRowElement, TableEmptyProps>(function TableEmpty(\n { colSpan, icon, title, description, action, className },\n ref\n) {\n return (\n <tr ref={ref} className={cx('brycks-table-empty', className)}>\n <td colSpan={colSpan} style={{ padding: 0 }}>\n <EmptyState icon={icon} title={title} description={description} action={action} />\n </td>\n </tr>\n )\n})\n\nTableEmpty.displayName = 'TableEmpty'\n\n// TableSkeleton — placeholder rows shown while data loads, drop inside <TableBody>\nexport interface TableSkeletonProps {\n /** Number of skeleton rows */\n rows?: number\n /** Number of columns per row (match the table's column count) */\n columns: number\n /** Custom class name applied to each row */\n className?: string\n}\n\n// Deterministic per-column widths so the placeholder reads like real data\nconst skeletonWidths = ['70%', '45%', '85%', '55%', '60%', '40%']\n\nexport function TableSkeleton({ rows = 5, columns, className }: TableSkeletonProps) {\n return (\n <>\n {Array.from({ length: rows }).map((_, rowIndex) => (\n <TableRow key={rowIndex} className={cx('brycks-table-skeleton-row', className)} aria-hidden=\"true\">\n {Array.from({ length: columns }).map((_, colIndex) => (\n <TableCell key={colIndex}>\n <Skeleton variant=\"text\" width={skeletonWidths[colIndex % skeletonWidths.length]} />\n </TableCell>\n ))}\n </TableRow>\n ))}\n </>\n )\n}\n\nTableSkeleton.displayName = 'TableSkeleton'\n"],"names":["TableContext","createContext","useTableContext","useContext","Table","forwardRef","size","variant","stickyHeader","loading","className","style","children","testId","props","ref","jsx","cx","TableHead","sticky","TableBody","TableRow","selected","clickable","SortIcon","direction","TableHeader","sortable","sortDirection","onSort","align","alignStyle","contentJustify","jsxs","TableCell","truncate","TableFoot","TableCaption","placement","captionStyle","TableEmpty","colSpan","icon","title","description","action","EmptyState","skeletonWidths","TableSkeleton","rows","columns","Fragment","_","rowIndex","colIndex","Skeleton"],"mappings":"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"}
1
+ {"version":3,"file":"Table.js","sources":["../../../../src/components/data/Table/Table.tsx"],"sourcesContent":["/**\r\n * Table Component\r\n *\r\n * A flexible table component with sorting, selection, and responsive support.\r\n * Follows design system patterns for consistent styling.\r\n */\r\n\r\nimport {\r\n forwardRef,\r\n createContext,\r\n useContext,\r\n type CSSProperties,\r\n type HTMLAttributes,\r\n type ThHTMLAttributes,\r\n type TdHTMLAttributes,\r\n type ReactNode,\r\n} from 'react'\r\nimport { cx } from '../../../utils/styles'\r\nimport { EmptyState } from '../../utility/EmptyState'\r\nimport { Skeleton } from '../../utility/Skeleton'\r\n\r\nexport type TableSize = 'sm' | 'md' | 'lg'\r\n// `striped` was dead API (no CSS, incompatible with inline row styling) — removed in 0.5.0.\r\nexport type TableVariant = 'default' | 'bordered'\r\n\r\ninterface TableContextValue {\r\n size: TableSize\r\n variant: TableVariant\r\n stickyHeader: boolean\r\n}\r\n\r\nconst TableContext = createContext<TableContextValue>({ size: 'md', variant: 'default', stickyHeader: false })\r\n\r\nfunction useTableContext() {\r\n return useContext(TableContext)\r\n}\r\n\r\nexport interface TableProps extends HTMLAttributes<HTMLTableElement> {\r\n /** Table size */\r\n size?: TableSize\r\n /** Table variant */\r\n variant?: TableVariant\r\n /** Whether the table has a sticky header */\r\n stickyHeader?: boolean\r\n /** Whether the table is in a loading state */\r\n loading?: boolean\r\n /** Custom class name */\r\n className?: string\r\n /** Test ID */\r\n testId?: string\r\n}\r\n\r\nexport const Table = forwardRef<HTMLTableElement, TableProps>(function Table(\r\n {\r\n size = 'md',\r\n variant = 'default',\r\n stickyHeader = false,\r\n loading = false,\r\n className,\r\n style,\r\n children,\r\n testId,\r\n ...props\r\n },\r\n ref\r\n) {\r\n return (\r\n <TableContext.Provider value={{ size, variant, stickyHeader }}>\r\n <div className=\"brycks-table-container\" style={style}>\r\n <table\r\n ref={ref}\r\n className={cx('brycks-table', `brycks-table--${size}`, `brycks-table--${variant}`, className)}\r\n style={loading ? { opacity: 0.6 } : undefined}\r\n aria-busy={loading || undefined}\r\n data-testid={testId}\r\n {...props}\r\n >\r\n {children}\r\n </table>\r\n </div>\r\n </TableContext.Provider>\r\n )\r\n})\r\n\r\nTable.displayName = 'Table'\r\n\r\n// TableHead\r\nexport interface TableHeadProps extends HTMLAttributes<HTMLTableSectionElement> {\r\n /** Whether the header is sticky */\r\n sticky?: boolean\r\n /** Custom class name */\r\n className?: string\r\n}\r\n\r\nexport const TableHead = forwardRef<HTMLTableSectionElement, TableHeadProps>(function TableHead(\r\n { sticky = false, className, style, children, ...props },\r\n ref\r\n) {\r\n const { stickyHeader } = useTableContext()\r\n const isSticky = sticky || stickyHeader\r\n\r\n return (\r\n <thead\r\n ref={ref}\r\n className={cx('brycks-table-head', isSticky && 'brycks-table-head--sticky', className)}\r\n style={style}\r\n {...props}\r\n >\r\n {children}\r\n </thead>\r\n )\r\n})\r\n\r\nTableHead.displayName = 'TableHead'\r\n\r\n// TableBody\r\nexport interface TableBodyProps extends HTMLAttributes<HTMLTableSectionElement> {\r\n /** Custom class name */\r\n className?: string\r\n}\r\n\r\nexport const TableBody = forwardRef<HTMLTableSectionElement, TableBodyProps>(function TableBody(\r\n { className, style, children, ...props },\r\n ref\r\n) {\r\n return (\r\n <tbody\r\n ref={ref}\r\n className={cx('brycks-table-body', className)}\r\n style={style}\r\n {...props}\r\n >\r\n {children}\r\n </tbody>\r\n )\r\n})\r\n\r\nTableBody.displayName = 'TableBody'\r\n\r\n// TableRow\r\nexport interface TableRowProps extends HTMLAttributes<HTMLTableRowElement> {\r\n /** Whether the row is selected */\r\n selected?: boolean\r\n /** Whether the row is clickable */\r\n clickable?: boolean\r\n /** Custom class name */\r\n className?: string\r\n}\r\n\r\nexport const TableRow = forwardRef<HTMLTableRowElement, TableRowProps>(function TableRow(\r\n { selected = false, clickable = false, className, style, children, ...props },\r\n ref\r\n) {\r\n return (\r\n <tr\r\n ref={ref}\r\n className={cx(\r\n 'brycks-table-row',\r\n selected && 'brycks-table-row--selected',\r\n clickable && 'brycks-table-row--clickable',\r\n className\r\n )}\r\n style={style}\r\n {...props}\r\n >\r\n {children}\r\n </tr>\r\n )\r\n})\r\n\r\nTableRow.displayName = 'TableRow'\r\n\r\n// TableHeader (th)\r\nexport interface TableHeaderProps extends ThHTMLAttributes<HTMLTableCellElement> {\r\n /** Whether the column is sortable */\r\n sortable?: boolean\r\n /** Sort direction */\r\n sortDirection?: 'asc' | 'desc' | null\r\n /** Callback when sort is requested */\r\n onSort?: () => void\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right'\r\n /** Custom class name */\r\n className?: string\r\n}\r\n\r\nfunction SortIcon({ direction }: { direction: 'asc' | 'desc' | null }) {\r\n if (!direction) {\r\n return (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" style={{ opacity: 0.4 }} aria-hidden=\"true\">\r\n <path d=\"M7 3L10 6H4L7 3Z\" fill=\"currentColor\" />\r\n <path d=\"M7 11L4 8H10L7 11Z\" fill=\"currentColor\" />\r\n </svg>\r\n )\r\n }\r\n\r\n return (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\r\n {direction === 'asc' ? (\r\n <path d=\"M7 3L10 6H4L7 3Z\" fill=\"currentColor\" />\r\n ) : (\r\n <path d=\"M7 11L4 8H10L7 11Z\" fill=\"currentColor\" />\r\n )}\r\n </svg>\r\n )\r\n}\r\n\r\nexport const TableHeader = forwardRef<HTMLTableCellElement, TableHeaderProps>(function TableHeader(\r\n {\r\n sortable = false,\r\n sortDirection = null,\r\n onSort,\r\n align = 'left',\r\n className,\r\n style,\r\n children,\r\n ...props\r\n },\r\n ref\r\n) {\r\n // Alignment is dynamic per prop; everything else lives in CSS.\r\n const alignStyle: CSSProperties = {\r\n textAlign: align,\r\n ...style,\r\n }\r\n\r\n const contentJustify: CSSProperties = {\r\n justifyContent: align === 'right' ? 'flex-end' : align === 'center' ? 'center' : 'flex-start',\r\n }\r\n\r\n return (\r\n <th\r\n ref={ref}\r\n aria-sort={\r\n sortable\r\n ? sortDirection === 'asc'\r\n ? 'ascending'\r\n : sortDirection === 'desc'\r\n ? 'descending'\r\n : 'none'\r\n : undefined\r\n }\r\n className={cx('brycks-table-header', sortable && 'brycks-table-header--sortable', className)}\r\n style={alignStyle}\r\n {...props}\r\n >\r\n {sortable ? (\r\n // Sorting happens through a real button so it is reachable by keyboard\r\n <button\r\n type=\"button\"\r\n className=\"brycks-table-header__content brycks-table-header__sort\"\r\n style={contentJustify}\r\n onClick={() => onSort?.()}\r\n >\r\n {children}\r\n <SortIcon direction={sortDirection} />\r\n </button>\r\n ) : (\r\n <span className=\"brycks-table-header__content\" style={contentJustify}>\r\n {children}\r\n </span>\r\n )}\r\n </th>\r\n )\r\n})\r\n\r\nTableHeader.displayName = 'TableHeader'\r\n\r\n// TableCell (td)\r\nexport interface TableCellProps extends TdHTMLAttributes<HTMLTableCellElement> {\r\n /** Text alignment */\r\n align?: 'left' | 'center' | 'right'\r\n /** Whether to truncate text */\r\n truncate?: boolean\r\n /** Custom class name */\r\n className?: string\r\n}\r\n\r\nexport const TableCell = forwardRef<HTMLTableCellElement, TableCellProps>(function TableCell(\r\n { align = 'left', truncate = false, className, style, children, ...props },\r\n ref\r\n) {\r\n // Alignment is dynamic per prop; everything else lives in CSS.\r\n const alignStyle: CSSProperties = {\r\n textAlign: align,\r\n ...style,\r\n }\r\n\r\n return (\r\n <td\r\n ref={ref}\r\n className={cx('brycks-table-cell', truncate && 'brycks-table-cell--truncate', className)}\r\n style={alignStyle}\r\n title={truncate && typeof children === 'string' ? children : undefined}\r\n {...props}\r\n >\r\n {children}\r\n </td>\r\n )\r\n})\r\n\r\nTableCell.displayName = 'TableCell'\r\n\r\n// TableFoot\r\nexport interface TableFootProps extends HTMLAttributes<HTMLTableSectionElement> {\r\n /** Custom class name */\r\n className?: string\r\n}\r\n\r\nexport const TableFoot = forwardRef<HTMLTableSectionElement, TableFootProps>(function TableFoot(\r\n { className, style, children, ...props },\r\n ref\r\n) {\r\n return (\r\n <tfoot\r\n ref={ref}\r\n className={cx('brycks-table-foot', className)}\r\n style={style}\r\n {...props}\r\n >\r\n {children}\r\n </tfoot>\r\n )\r\n})\r\n\r\nTableFoot.displayName = 'TableFoot'\r\n\r\n// TableCaption\r\nexport interface TableCaptionProps extends HTMLAttributes<HTMLTableCaptionElement> {\r\n /** Caption placement */\r\n placement?: 'top' | 'bottom'\r\n /** Custom class name */\r\n className?: string\r\n}\r\n\r\nexport const TableCaption = forwardRef<HTMLTableCaptionElement, TableCaptionProps>(function TableCaption(\r\n { placement = 'bottom', className, style, children, ...props },\r\n ref\r\n) {\r\n // Caption side is dynamic per prop; everything else lives in CSS.\r\n const captionStyle: CSSProperties = {\r\n captionSide: placement,\r\n ...style,\r\n }\r\n\r\n return (\r\n <caption\r\n ref={ref}\r\n className={cx('brycks-table-caption', className)}\r\n style={captionStyle}\r\n {...props}\r\n >\r\n {children}\r\n </caption>\r\n )\r\n})\r\n\r\nTableCaption.displayName = 'TableCaption'\r\n\r\n// TableEmpty — a full-width empty state row, drop inside <TableBody>\r\nexport interface TableEmptyProps {\r\n /** Number of columns to span (match the table's column count) */\r\n colSpan: number\r\n /** Icon or illustration */\r\n icon?: ReactNode\r\n /** Title text */\r\n title?: ReactNode\r\n /** Description text */\r\n description?: ReactNode\r\n /** Action element (button, link) */\r\n action?: ReactNode\r\n /** Custom class name */\r\n className?: string\r\n}\r\n\r\nexport const TableEmpty = forwardRef<HTMLTableRowElement, TableEmptyProps>(function TableEmpty(\r\n { colSpan, icon, title, description, action, className },\r\n ref\r\n) {\r\n return (\r\n <tr ref={ref} className={cx('brycks-table-empty', className)}>\r\n <td colSpan={colSpan} style={{ padding: 0 }}>\r\n <EmptyState icon={icon} title={title} description={description} action={action} />\r\n </td>\r\n </tr>\r\n )\r\n})\r\n\r\nTableEmpty.displayName = 'TableEmpty'\r\n\r\n// TableSkeleton — placeholder rows shown while data loads, drop inside <TableBody>\r\nexport interface TableSkeletonProps {\r\n /** Number of skeleton rows */\r\n rows?: number\r\n /** Number of columns per row (match the table's column count) */\r\n columns: number\r\n /** Custom class name applied to each row */\r\n className?: string\r\n}\r\n\r\n// Deterministic per-column widths so the placeholder reads like real data\r\nconst skeletonWidths = ['70%', '45%', '85%', '55%', '60%', '40%']\r\n\r\nexport function TableSkeleton({ rows = 5, columns, className }: TableSkeletonProps) {\r\n return (\r\n <>\r\n {Array.from({ length: rows }).map((_, rowIndex) => (\r\n <TableRow key={rowIndex} className={cx('brycks-table-skeleton-row', className)} aria-hidden=\"true\">\r\n {Array.from({ length: columns }).map((_, colIndex) => (\r\n <TableCell key={colIndex}>\r\n <Skeleton variant=\"text\" width={skeletonWidths[colIndex % skeletonWidths.length]} />\r\n </TableCell>\r\n ))}\r\n </TableRow>\r\n ))}\r\n </>\r\n )\r\n}\r\n\r\nTableSkeleton.displayName = 'TableSkeleton'\r\n"],"names":["TableContext","createContext","useTableContext","useContext","Table","forwardRef","size","variant","stickyHeader","loading","className","style","children","testId","props","ref","jsx","cx","TableHead","sticky","TableBody","TableRow","selected","clickable","SortIcon","direction","TableHeader","sortable","sortDirection","onSort","align","alignStyle","contentJustify","jsxs","TableCell","truncate","TableFoot","TableCaption","placement","captionStyle","TableEmpty","colSpan","icon","title","description","action","EmptyState","skeletonWidths","TableSkeleton","rows","columns","Fragment","_","rowIndex","colIndex","Skeleton"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./data/Table/Table.cjs"),t=require("./data/List/List.cjs"),i=require("./data/InfoItem/InfoItem.cjs"),l=require("./data/TreeView/TreeView.cjs"),a=require("./data/VirtualList/VirtualList.cjs");exports.Table=e.Table;exports.TableBody=e.TableBody;exports.TableCaption=e.TableCaption;exports.TableCell=e.TableCell;exports.TableEmpty=e.TableEmpty;exports.TableFoot=e.TableFoot;exports.TableHead=e.TableHead;exports.TableHeader=e.TableHeader;exports.TableRow=e.TableRow;exports.TableSkeleton=e.TableSkeleton;exports.List=t.List;exports.ListDivider=t.ListDivider;exports.ListHeader=t.ListHeader;exports.ListItem=t.ListItem;exports.InfoItem=i.InfoItem;exports.InfoList=i.InfoList;exports.TreeView=l.TreeView;exports.VariableHeightVirtualList=a.VariableHeightVirtualList;exports.VirtualList=a.VirtualList;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./data/Table/Table.cjs"),t=require("./data/List/List.cjs"),i=require("./data/InfoItem/InfoItem.cjs"),l=require("./data/TreeView/TreeView.cjs"),a=require("./data/VirtualList/VirtualList.cjs"),r=require("./data/PieChart/PieChart.cjs");exports.Table=e.Table;exports.TableBody=e.TableBody;exports.TableCaption=e.TableCaption;exports.TableCell=e.TableCell;exports.TableEmpty=e.TableEmpty;exports.TableFoot=e.TableFoot;exports.TableHead=e.TableHead;exports.TableHeader=e.TableHeader;exports.TableRow=e.TableRow;exports.TableSkeleton=e.TableSkeleton;exports.List=t.List;exports.ListDivider=t.ListDivider;exports.ListHeader=t.ListHeader;exports.ListItem=t.ListItem;exports.InfoItem=i.InfoItem;exports.InfoList=i.InfoList;exports.TreeView=l.TreeView;exports.VariableHeightVirtualList=a.VariableHeightVirtualList;exports.VirtualList=a.VirtualList;exports.PieChart=r.PieChart;
2
2
  //# sourceMappingURL=data.cjs.map
@@ -1,27 +1,29 @@
1
- import { Table as a, TableBody as o, TableCaption as r, TableCell as l, TableEmpty as i, TableFoot as b, TableHead as T, TableHeader as m, TableRow as f, TableSkeleton as p } from "./data/Table/Table.js";
2
- import { List as L, ListDivider as d, ListHeader as x, ListItem as n } from "./data/List/List.js";
1
+ import { Table as o, TableBody as r, TableCaption as a, TableCell as i, TableEmpty as l, TableFoot as b, TableHead as T, TableHeader as m, TableRow as f, TableSkeleton as p } from "./data/Table/Table.js";
2
+ import { List as L, ListDivider as x, ListHeader as d, ListItem as n } from "./data/List/List.js";
3
3
  import { InfoItem as I, InfoList as V } from "./data/InfoItem/InfoItem.js";
4
- import { TreeView as w } from "./data/TreeView/TreeView.js";
5
- import { VariableHeightVirtualList as C, VirtualList as g } from "./data/VirtualList/VirtualList.js";
4
+ import { TreeView as h } from "./data/TreeView/TreeView.js";
5
+ import { VariableHeightVirtualList as w, VirtualList as y } from "./data/VirtualList/VirtualList.js";
6
+ import { PieChart as k } from "./data/PieChart/PieChart.js";
6
7
  export {
7
8
  I as InfoItem,
8
9
  V as InfoList,
9
10
  L as List,
10
- d as ListDivider,
11
- x as ListHeader,
11
+ x as ListDivider,
12
+ d as ListHeader,
12
13
  n as ListItem,
13
- a as Table,
14
- o as TableBody,
15
- r as TableCaption,
16
- l as TableCell,
17
- i as TableEmpty,
14
+ k as PieChart,
15
+ o as Table,
16
+ r as TableBody,
17
+ a as TableCaption,
18
+ i as TableCell,
19
+ l as TableEmpty,
18
20
  b as TableFoot,
19
21
  T as TableHead,
20
22
  m as TableHeader,
21
23
  f as TableRow,
22
24
  p as TableSkeleton,
23
- w as TreeView,
24
- C as VariableHeightVirtualList,
25
- g as VirtualList
25
+ h as TreeView,
26
+ w as VariableHeightVirtualList,
27
+ y as VirtualList
26
28
  };
27
29
  //# sourceMappingURL=data.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"data.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
1
+ {"version":3,"file":"data.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("react/jsx-runtime"),e=require("react"),m=require("../../../utils/styles.cjs"),O={sm:{fontSize:13,padding:10,lineHeight:1.5},md:{fontSize:14,padding:12,lineHeight:1.5},lg:{fontSize:15,padding:14,lineHeight:1.5}},H=e.forwardRef(function({size:x="md",variant:b="outline",isInvalid:d,autoResize:a,minRows:S=3,maxRows:k=10,showCount:w,maxLength:n,className:j,style:C,testId:T,disabled:s,value:r,defaultValue:c,onChange:N,...$},q){const[p,y]=e.useState(0),v=e.useRef(null),o=q||v,i=O[x],u=i.fontSize*i.lineHeight,l=u*S+i.padding*2,g=u*k+i.padding*2,f=e.useCallback(()=>{const t=o.current;if(!t||!a)return;t.style.height="auto";const E=t.scrollHeight,P=Math.min(Math.max(E,l),g);t.style.height=`${P}px`},[a,l,g,o]);e.useEffect(()=>{f()},[r,f]),e.useEffect(()=>{const t=String(r??c??"");y(t.length)},[r,c]);const z={minHeight:l,maxHeight:a?g:void 0,resize:s||a?"none":"vertical"},M=t=>{y(t.target.value.length),N?.(t)},R=p>=(n??1/0);return h.jsxs("div",{className:m.cx("brycks-textarea-wrapper",`brycks-textarea-wrapper--${b}`,`brycks-textarea-wrapper--${x}`,d&&"brycks-textarea-wrapper--invalid",s&&"brycks-textarea-wrapper--disabled",j),style:C,children:[h.jsx("textarea",{ref:o,className:"brycks-textarea",style:z,disabled:s,"aria-invalid":d,"data-testid":T,value:r,defaultValue:c,maxLength:n,onChange:M,...$}),w&&h.jsxs("span",{className:m.cx("brycks-textarea-count",R&&"brycks-textarea-count--limit"),children:[p,n?`/${n}`:""]})]})});H.displayName="Textarea";exports.Textarea=H;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("react/jsx-runtime"),e=require("react"),H=require("../../../utils/styles.cjs"),O={sm:{fontSize:13,padding:10,lineHeight:1.5},md:{fontSize:14,padding:12,lineHeight:1.5},lg:{fontSize:15,padding:14,lineHeight:1.5}},b=e.forwardRef(function({size:x="md",variant:k="outline",isInvalid:u,autoResize:n,minRows:S=3,maxRows:w=10,showCount:C,maxLength:r,className:j,style:T,testId:N,disabled:c,value:i,defaultValue:o,onChange:$,...q},a){const[p,d]=e.useState(0),y=e.useRef(null),v=e.useCallback(t=>{y.current=t,typeof a=="function"?a(t):a&&(a.current=t)},[a]),s=O[x],f=s.fontSize*s.lineHeight,l=f*S+s.padding*2,g=f*w+s.padding*2,m=e.useCallback(()=>{const t=y.current;if(!t||!n)return;t.style.height="auto";const E=t.scrollHeight,P=Math.min(Math.max(E,l),g);t.style.height=`${P}px`},[n,l,g]);e.useEffect(()=>{m()},[i,m]),e.useEffect(()=>{const t=String(i??o??"");d(t.length)},[i,o]);const z={minHeight:l,maxHeight:n?g:void 0,resize:c||n?"none":"vertical"},M=t=>{d(t.target.value.length),$?.(t)},R=p>=(r??1/0);return h.jsxs("div",{className:H.cx("brycks-textarea-wrapper",`brycks-textarea-wrapper--${k}`,`brycks-textarea-wrapper--${x}`,u&&"brycks-textarea-wrapper--invalid",c&&"brycks-textarea-wrapper--disabled",j),style:T,children:[h.jsx("textarea",{ref:v,className:"brycks-textarea",style:z,disabled:c,"aria-invalid":u,"data-testid":N,value:i,defaultValue:o,maxLength:r,onChange:M,...q}),C&&h.jsxs("span",{className:H.cx("brycks-textarea-count",R&&"brycks-textarea-count--limit"),children:[p,r?`/${r}`:""]})]})});b.displayName="Textarea";exports.Textarea=b;
2
2
  //# sourceMappingURL=Textarea.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Textarea.cjs","sources":["../../../../src/components/form/Textarea/Textarea.tsx"],"sourcesContent":["/**\n * Textarea Component\n *\n * Multi-line text input with Apple-inspired styling.\n * Supports auto-resize and character counting.\n */\n\nimport {\n forwardRef,\n useState,\n useEffect,\n useRef,\n useCallback,\n type CSSProperties,\n type TextareaHTMLAttributes,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type TextareaSize = 'sm' | 'md' | 'lg'\nexport type TextareaVariant = 'outline' | 'filled'\n\nexport interface TextareaProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'size'> {\n /** Textarea size */\n size?: TextareaSize\n /** Visual variant */\n variant?: TextareaVariant\n /** Error state */\n isInvalid?: boolean\n /** Auto resize based on content */\n autoResize?: boolean\n /** Minimum rows */\n minRows?: number\n /** Maximum rows */\n maxRows?: number\n /** Show character count */\n showCount?: boolean\n /** Max character length */\n maxLength?: number\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeStyles: Record<TextareaSize, { fontSize: number; padding: number; lineHeight: number }> = {\n sm: { fontSize: 13, padding: 10, lineHeight: 1.5 },\n md: { fontSize: 14, padding: 12, lineHeight: 1.5 },\n lg: { fontSize: 15, padding: 14, lineHeight: 1.5 },\n}\n\nexport const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea(\n {\n size = 'md',\n variant = 'outline',\n isInvalid,\n autoResize,\n minRows = 3,\n maxRows = 10,\n showCount,\n maxLength,\n className,\n style,\n testId,\n disabled,\n value,\n defaultValue,\n onChange,\n ...props\n },\n ref\n) {\n const [charCount, setCharCount] = useState(0)\n const internalRef = useRef<HTMLTextAreaElement>(null)\n const textareaRef = (ref as React.RefObject<HTMLTextAreaElement>) || internalRef\n\n const sizeValue = sizeStyles[size]\n const lineHeightPx = sizeValue.fontSize * sizeValue.lineHeight\n const minHeight = lineHeightPx * minRows + sizeValue.padding * 2\n const maxHeight = lineHeightPx * maxRows + sizeValue.padding * 2\n\n const adjustHeight = useCallback(() => {\n const textarea = textareaRef.current\n if (!textarea || !autoResize) return\n\n textarea.style.height = 'auto'\n const scrollHeight = textarea.scrollHeight\n const newHeight = Math.min(Math.max(scrollHeight, minHeight), maxHeight)\n textarea.style.height = `${newHeight}px`\n }, [autoResize, minHeight, maxHeight, textareaRef])\n\n useEffect(() => {\n adjustHeight()\n }, [value, adjustHeight])\n\n useEffect(() => {\n const initialValue = String(value ?? defaultValue ?? '')\n setCharCount(initialValue.length)\n }, [value, defaultValue])\n\n // Only the computed min/max height (derived from rows + font metrics) and the\n // resize mode are dynamic; the rest of the visual styling lives in CSS.\n const textareaStyle: CSSProperties = {\n minHeight,\n maxHeight: autoResize ? maxHeight : undefined,\n resize: disabled || autoResize ? 'none' : 'vertical',\n }\n\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setCharCount(e.target.value.length)\n onChange?.(e)\n }\n\n const atLimit = charCount >= (maxLength ?? Infinity)\n\n return (\n <div\n className={cx(\n 'brycks-textarea-wrapper',\n `brycks-textarea-wrapper--${variant}`,\n `brycks-textarea-wrapper--${size}`,\n isInvalid && 'brycks-textarea-wrapper--invalid',\n disabled && 'brycks-textarea-wrapper--disabled',\n className\n )}\n style={style}\n >\n <textarea\n ref={textareaRef}\n className=\"brycks-textarea\"\n style={textareaStyle}\n disabled={disabled}\n aria-invalid={isInvalid}\n data-testid={testId}\n value={value}\n defaultValue={defaultValue}\n maxLength={maxLength}\n onChange={handleChange}\n {...props}\n />\n\n {showCount && (\n <span className={cx('brycks-textarea-count', atLimit && 'brycks-textarea-count--limit')}>\n {charCount}{maxLength ? `/${maxLength}` : ''}\n </span>\n )}\n </div>\n )\n})\n\nTextarea.displayName = 'Textarea'\n"],"names":["sizeStyles","Textarea","forwardRef","size","variant","isInvalid","autoResize","minRows","maxRows","showCount","maxLength","className","style","testId","disabled","value","defaultValue","onChange","props","ref","charCount","setCharCount","useState","internalRef","useRef","textareaRef","sizeValue","lineHeightPx","minHeight","maxHeight","adjustHeight","useCallback","textarea","scrollHeight","newHeight","useEffect","initialValue","textareaStyle","handleChange","e","atLimit","jsxs","cx","jsx"],"mappings":"+KA4CMA,EAA8F,CAClG,GAAI,CAAE,SAAU,GAAI,QAAS,GAAI,WAAY,GAAA,EAC7C,GAAI,CAAE,SAAU,GAAI,QAAS,GAAI,WAAY,GAAA,EAC7C,GAAI,CAAE,SAAU,GAAI,QAAS,GAAI,WAAY,GAAA,CAC/C,EAEaC,EAAWC,EAAAA,WAA+C,SACrE,CACE,KAAAC,EAAO,KACP,QAAAC,EAAU,UACV,UAAAC,EACA,WAAAC,EACA,QAAAC,EAAU,EACV,QAAAC,EAAU,GACV,UAAAC,EACA,UAAAC,EACA,UAAAC,EACA,MAAAC,EACA,OAAAC,EACA,SAAAC,EACA,MAAAC,EACA,aAAAC,EACA,SAAAC,EACA,GAAGC,CACL,EACAC,EACA,CACA,KAAM,CAACC,EAAWC,CAAY,EAAIC,EAAAA,SAAS,CAAC,EACtCC,EAAcC,EAAAA,OAA4B,IAAI,EAC9CC,EAAeN,GAAgDI,EAE/DG,EAAY1B,EAAWG,CAAI,EAC3BwB,EAAeD,EAAU,SAAWA,EAAU,WAC9CE,EAAYD,EAAepB,EAAUmB,EAAU,QAAU,EACzDG,EAAYF,EAAenB,EAAUkB,EAAU,QAAU,EAEzDI,EAAeC,EAAAA,YAAY,IAAM,CACrC,MAAMC,EAAWP,EAAY,QAC7B,GAAI,CAACO,GAAY,CAAC1B,EAAY,OAE9B0B,EAAS,MAAM,OAAS,OACxB,MAAMC,EAAeD,EAAS,aACxBE,EAAY,KAAK,IAAI,KAAK,IAAID,EAAcL,CAAS,EAAGC,CAAS,EACvEG,EAAS,MAAM,OAAS,GAAGE,CAAS,IACtC,EAAG,CAAC5B,EAAYsB,EAAWC,EAAWJ,CAAW,CAAC,EAElDU,EAAAA,UAAU,IAAM,CACdL,EAAA,CACF,EAAG,CAACf,EAAOe,CAAY,CAAC,EAExBK,EAAAA,UAAU,IAAM,CACd,MAAMC,EAAe,OAAOrB,GAASC,GAAgB,EAAE,EACvDK,EAAae,EAAa,MAAM,CAClC,EAAG,CAACrB,EAAOC,CAAY,CAAC,EAIxB,MAAMqB,EAA+B,CACnC,UAAAT,EACA,UAAWtB,EAAauB,EAAY,OACpC,OAAQf,GAAYR,EAAa,OAAS,UAAA,EAGtCgC,EAAgBC,GAA8C,CAClElB,EAAakB,EAAE,OAAO,MAAM,MAAM,EAClCtB,IAAWsB,CAAC,CACd,EAEMC,EAAUpB,IAAcV,GAAa,KAE3C,OACE+B,EAAAA,KAAC,MAAA,CACC,UAAWC,EAAAA,GACT,0BACA,4BAA4BtC,CAAO,GACnC,4BAA4BD,CAAI,GAChCE,GAAa,mCACbS,GAAY,oCACZH,CAAA,EAEF,MAAAC,EAEA,SAAA,CAAA+B,EAAAA,IAAC,WAAA,CACC,IAAKlB,EACL,UAAU,kBACV,MAAOY,EACP,SAAAvB,EACA,eAAcT,EACd,cAAaQ,EACb,MAAAE,EACA,aAAAC,EACA,UAAAN,EACA,SAAU4B,EACT,GAAGpB,CAAA,CAAA,EAGLT,UACE,OAAA,CAAK,UAAWiC,KAAG,wBAAyBF,GAAW,8BAA8B,EACnF,SAAA,CAAApB,EAAWV,EAAY,IAAIA,CAAS,GAAK,EAAA,CAAA,CAC5C,CAAA,CAAA,CAAA,CAIR,CAAC,EAEDT,EAAS,YAAc"}
1
+ {"version":3,"file":"Textarea.cjs","sources":["../../../../src/components/form/Textarea/Textarea.tsx"],"sourcesContent":["/**\n * Textarea Component\n *\n * Multi-line text input with Apple-inspired styling.\n * Supports auto-resize and character counting.\n */\n\nimport {\n forwardRef,\n useState,\n useEffect,\n useRef,\n useCallback,\n type CSSProperties,\n type TextareaHTMLAttributes,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type TextareaSize = 'sm' | 'md' | 'lg'\nexport type TextareaVariant = 'outline' | 'filled'\n\nexport interface TextareaProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'size'> {\n /** Textarea size */\n size?: TextareaSize\n /** Visual variant */\n variant?: TextareaVariant\n /** Error state */\n isInvalid?: boolean\n /** Auto resize based on content */\n autoResize?: boolean\n /** Minimum rows */\n minRows?: number\n /** Maximum rows */\n maxRows?: number\n /** Show character count */\n showCount?: boolean\n /** Max character length */\n maxLength?: number\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeStyles: Record<TextareaSize, { fontSize: number; padding: number; lineHeight: number }> = {\n sm: { fontSize: 13, padding: 10, lineHeight: 1.5 },\n md: { fontSize: 14, padding: 12, lineHeight: 1.5 },\n lg: { fontSize: 15, padding: 14, lineHeight: 1.5 },\n}\n\nexport const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea(\n {\n size = 'md',\n variant = 'outline',\n isInvalid,\n autoResize,\n minRows = 3,\n maxRows = 10,\n showCount,\n maxLength,\n className,\n style,\n testId,\n disabled,\n value,\n defaultValue,\n onChange,\n ...props\n },\n ref\n) {\n const [charCount, setCharCount] = useState(0)\n const internalRef = useRef<HTMLTextAreaElement>(null)\n // Merge the forwarded ref (object OR callback) with our internal ref. The old\n // `(ref as RefObject) || internalRef` broke with callback refs: a function ref\n // is truthy, so `.current` was undefined and autoResize silently stopped.\n const setTextareaRef = useCallback(\n (node: HTMLTextAreaElement | null) => {\n internalRef.current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) (ref as React.MutableRefObject<HTMLTextAreaElement | null>).current = node\n },\n [ref]\n )\n\n const sizeValue = sizeStyles[size]\n const lineHeightPx = sizeValue.fontSize * sizeValue.lineHeight\n const minHeight = lineHeightPx * minRows + sizeValue.padding * 2\n const maxHeight = lineHeightPx * maxRows + sizeValue.padding * 2\n\n const adjustHeight = useCallback(() => {\n const textarea = internalRef.current\n if (!textarea || !autoResize) return\n\n textarea.style.height = 'auto'\n const scrollHeight = textarea.scrollHeight\n const newHeight = Math.min(Math.max(scrollHeight, minHeight), maxHeight)\n textarea.style.height = `${newHeight}px`\n }, [autoResize, minHeight, maxHeight])\n\n useEffect(() => {\n adjustHeight()\n }, [value, adjustHeight])\n\n useEffect(() => {\n const initialValue = String(value ?? defaultValue ?? '')\n setCharCount(initialValue.length)\n }, [value, defaultValue])\n\n // Only the computed min/max height (derived from rows + font metrics) and the\n // resize mode are dynamic; the rest of the visual styling lives in CSS.\n const textareaStyle: CSSProperties = {\n minHeight,\n maxHeight: autoResize ? maxHeight : undefined,\n resize: disabled || autoResize ? 'none' : 'vertical',\n }\n\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setCharCount(e.target.value.length)\n onChange?.(e)\n }\n\n const atLimit = charCount >= (maxLength ?? Infinity)\n\n return (\n <div\n className={cx(\n 'brycks-textarea-wrapper',\n `brycks-textarea-wrapper--${variant}`,\n `brycks-textarea-wrapper--${size}`,\n isInvalid && 'brycks-textarea-wrapper--invalid',\n disabled && 'brycks-textarea-wrapper--disabled',\n className\n )}\n style={style}\n >\n <textarea\n ref={setTextareaRef}\n className=\"brycks-textarea\"\n style={textareaStyle}\n disabled={disabled}\n aria-invalid={isInvalid}\n data-testid={testId}\n value={value}\n defaultValue={defaultValue}\n maxLength={maxLength}\n onChange={handleChange}\n {...props}\n />\n\n {showCount && (\n <span className={cx('brycks-textarea-count', atLimit && 'brycks-textarea-count--limit')}>\n {charCount}{maxLength ? `/${maxLength}` : ''}\n </span>\n )}\n </div>\n )\n})\n\nTextarea.displayName = 'Textarea'\n"],"names":["sizeStyles","Textarea","forwardRef","size","variant","isInvalid","autoResize","minRows","maxRows","showCount","maxLength","className","style","testId","disabled","value","defaultValue","onChange","props","ref","charCount","setCharCount","useState","internalRef","useRef","setTextareaRef","useCallback","node","sizeValue","lineHeightPx","minHeight","maxHeight","adjustHeight","textarea","scrollHeight","newHeight","useEffect","initialValue","textareaStyle","handleChange","e","atLimit","jsxs","cx","jsx"],"mappings":"+KA4CMA,EAA8F,CAClG,GAAI,CAAE,SAAU,GAAI,QAAS,GAAI,WAAY,GAAA,EAC7C,GAAI,CAAE,SAAU,GAAI,QAAS,GAAI,WAAY,GAAA,EAC7C,GAAI,CAAE,SAAU,GAAI,QAAS,GAAI,WAAY,GAAA,CAC/C,EAEaC,EAAWC,EAAAA,WAA+C,SACrE,CACE,KAAAC,EAAO,KACP,QAAAC,EAAU,UACV,UAAAC,EACA,WAAAC,EACA,QAAAC,EAAU,EACV,QAAAC,EAAU,GACV,UAAAC,EACA,UAAAC,EACA,UAAAC,EACA,MAAAC,EACA,OAAAC,EACA,SAAAC,EACA,MAAAC,EACA,aAAAC,EACA,SAAAC,EACA,GAAGC,CACL,EACAC,EACA,CACA,KAAM,CAACC,EAAWC,CAAY,EAAIC,EAAAA,SAAS,CAAC,EACtCC,EAAcC,EAAAA,OAA4B,IAAI,EAI9CC,EAAiBC,EAAAA,YACpBC,GAAqC,CACpCJ,EAAY,QAAUI,EAClB,OAAOR,GAAQ,WAAYA,EAAIQ,CAAI,EAC9BR,IAAMA,EAA2D,QAAUQ,EACtF,EACA,CAACR,CAAG,CAAA,EAGAS,EAAY5B,EAAWG,CAAI,EAC3B0B,EAAeD,EAAU,SAAWA,EAAU,WAC9CE,EAAYD,EAAetB,EAAUqB,EAAU,QAAU,EACzDG,EAAYF,EAAerB,EAAUoB,EAAU,QAAU,EAEzDI,EAAeN,EAAAA,YAAY,IAAM,CACrC,MAAMO,EAAWV,EAAY,QAC7B,GAAI,CAACU,GAAY,CAAC3B,EAAY,OAE9B2B,EAAS,MAAM,OAAS,OACxB,MAAMC,EAAeD,EAAS,aACxBE,EAAY,KAAK,IAAI,KAAK,IAAID,EAAcJ,CAAS,EAAGC,CAAS,EACvEE,EAAS,MAAM,OAAS,GAAGE,CAAS,IACtC,EAAG,CAAC7B,EAAYwB,EAAWC,CAAS,CAAC,EAErCK,EAAAA,UAAU,IAAM,CACdJ,EAAA,CACF,EAAG,CAACjB,EAAOiB,CAAY,CAAC,EAExBI,EAAAA,UAAU,IAAM,CACd,MAAMC,EAAe,OAAOtB,GAASC,GAAgB,EAAE,EACvDK,EAAagB,EAAa,MAAM,CAClC,EAAG,CAACtB,EAAOC,CAAY,CAAC,EAIxB,MAAMsB,EAA+B,CACnC,UAAAR,EACA,UAAWxB,EAAayB,EAAY,OACpC,OAAQjB,GAAYR,EAAa,OAAS,UAAA,EAGtCiC,EAAgBC,GAA8C,CAClEnB,EAAamB,EAAE,OAAO,MAAM,MAAM,EAClCvB,IAAWuB,CAAC,CACd,EAEMC,EAAUrB,IAAcV,GAAa,KAE3C,OACEgC,EAAAA,KAAC,MAAA,CACC,UAAWC,EAAAA,GACT,0BACA,4BAA4BvC,CAAO,GACnC,4BAA4BD,CAAI,GAChCE,GAAa,mCACbS,GAAY,oCACZH,CAAA,EAEF,MAAAC,EAEA,SAAA,CAAAgC,EAAAA,IAAC,WAAA,CACC,IAAKnB,EACL,UAAU,kBACV,MAAOa,EACP,SAAAxB,EACA,eAAcT,EACd,cAAaQ,EACb,MAAAE,EACA,aAAAC,EACA,UAAAN,EACA,SAAU6B,EACT,GAAGrB,CAAA,CAAA,EAGLT,UACE,OAAA,CAAK,UAAWkC,KAAG,wBAAyBF,GAAW,8BAA8B,EACnF,SAAA,CAAArB,EAAWV,EAAY,IAAIA,CAAS,GAAK,EAAA,CAAA,CAC5C,CAAA,CAAA,CAAA,CAIR,CAAC,EAEDT,EAAS,YAAc"}