@tokis/react 1.2.2 → 1.3.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.
Files changed (45) hide show
  1. package/README.md +4 -4
  2. package/dist/cjs/components/avatar/index.js +1 -1
  3. package/dist/cjs/components/card/index.js +4 -1
  4. package/dist/cjs/components/charts/index.js +94 -13
  5. package/dist/cjs/components/datepicker/index.js +17 -2
  6. package/dist/cjs/components/drawer/index.js +4 -1
  7. package/dist/cjs/components/extended/index.js +1 -1
  8. package/dist/cjs/components/hover-card/index.js +3 -1
  9. package/dist/cjs/components/pagination/index.js +1 -1
  10. package/dist/cjs/components/popover/index.js +24 -1
  11. package/dist/cjs/components/radio/index.js +31 -48
  12. package/dist/components/avatar/index.d.ts +3 -0
  13. package/dist/components/avatar/index.d.ts.map +1 -1
  14. package/dist/components/avatar/index.js +1 -1
  15. package/dist/components/avatar/index.js.map +1 -1
  16. package/dist/components/card/index.d.ts +5 -2
  17. package/dist/components/card/index.d.ts.map +1 -1
  18. package/dist/components/card/index.js +4 -1
  19. package/dist/components/card/index.js.map +1 -1
  20. package/dist/components/charts/index.d.ts.map +1 -1
  21. package/dist/components/charts/index.js +94 -13
  22. package/dist/components/charts/index.js.map +1 -1
  23. package/dist/components/datepicker/index.d.ts.map +1 -1
  24. package/dist/components/datepicker/index.js +17 -2
  25. package/dist/components/datepicker/index.js.map +1 -1
  26. package/dist/components/drawer/index.d.ts.map +1 -1
  27. package/dist/components/drawer/index.js +5 -2
  28. package/dist/components/drawer/index.js.map +1 -1
  29. package/dist/components/extended/index.d.ts.map +1 -1
  30. package/dist/components/extended/index.js +1 -1
  31. package/dist/components/extended/index.js.map +1 -1
  32. package/dist/components/hover-card/index.d.ts.map +1 -1
  33. package/dist/components/hover-card/index.js +4 -2
  34. package/dist/components/hover-card/index.js.map +1 -1
  35. package/dist/components/pagination/index.d.ts.map +1 -1
  36. package/dist/components/pagination/index.js +1 -1
  37. package/dist/components/pagination/index.js.map +1 -1
  38. package/dist/components/popover/index.d.ts.map +1 -1
  39. package/dist/components/popover/index.js +24 -1
  40. package/dist/components/popover/index.js.map +1 -1
  41. package/dist/components/radio/index.d.ts +1 -1
  42. package/dist/components/radio/index.d.ts.map +1 -1
  43. package/dist/components/radio/index.js +31 -15
  44. package/dist/components/radio/index.js.map +1 -1
  45. package/package.json +11 -8
package/README.md CHANGED
@@ -39,13 +39,13 @@ function App() {
39
39
 
40
40
  - `react` >= 18.0.0
41
41
  - `react-dom` >= 18.0.0
42
- - `@tokis/core` ^1.1.0
43
- - `@tokis/tokens` ^1.1.0
44
- - `@tokis/theme` ^1.1.0
42
+ - `@tokis/core` ^1.3.0
43
+ - `@tokis/tokens` ^1.3.0
44
+ - `@tokis/theme` ^1.3.0
45
45
 
46
46
  ## Documentation
47
47
 
48
- Visit [tokis.dev](https://tokis.dev/docs/introduction) for interactive demos and full API reference.
48
+ Visit [Tokis Documentation](https://prerakmathur20.github.io/TokisWebsite/) for interactive demos and full API reference.
49
49
 
50
50
  ## License
51
51
 
@@ -49,7 +49,7 @@ function AvatarGroup({ children, max, size = 'md', className }) {
49
49
  const overflow = max && items.length > max ? items.length - max : 0;
50
50
  return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_js_1.cn)('tokis-avatar-group', className), children: [visible, overflow > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_js_1.cn)('tokis-avatar', `tokis-avatar--${size}`), "aria-label": `${overflow} more`, children: ["+", overflow] }))] }));
51
51
  }
52
- exports.Badge = (0, react_1.forwardRef)(({ variant = 'default', dot = false, className, children, ...props }, ref) => ((0, jsx_runtime_1.jsx)("span", { ref: ref, className: (0, cn_js_1.cn)('tokis-badge', `tokis-badge--${variant}`, dot && 'tokis-badge--dot', className), ...props, children: children })));
52
+ exports.Badge = (0, react_1.forwardRef)(({ variant = 'default', dot = false, dotLabel, className, children, ...props }, ref) => ((0, jsx_runtime_1.jsxs)("span", { ref: ref, className: (0, cn_js_1.cn)('tokis-badge', `tokis-badge--${variant}`, dot && 'tokis-badge--dot', className), ...props, children: [dot && dotLabel && (0, jsx_runtime_1.jsx)("span", { className: "tokis-sr-only", children: dotLabel }), children] })));
53
53
  exports.Badge.displayName = 'Badge';
54
54
  exports.Chip = (0, react_1.forwardRef)(({ selected = false, onDelete, disabled = false, icon, className, children, onClick, ...props }, ref) => ((0, jsx_runtime_1.jsxs)("div", { ref: ref, role: onClick ? 'button' : undefined, tabIndex: onClick && !disabled ? 0 : undefined, "aria-pressed": onClick ? selected : undefined, "aria-disabled": disabled || undefined, className: (0, cn_js_1.cn)('tokis-chip', onClick && 'tokis-chip--clickable', selected && 'tokis-chip--selected', className), onClick: !disabled ? onClick : undefined, onKeyDown: onClick && !disabled ? (e) => { if (e.key === 'Enter' || e.key === ' ') {
55
55
  e.preventDefault();
@@ -4,7 +4,10 @@ exports.Divider = exports.CardDescription = exports.CardTitle = exports.CardFoot
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const cn_js_1 = require("../../utils/cn");
7
- exports.Card = (0, react_1.forwardRef)(({ variant = 'default', clickable = false, className, children, ...props }, ref) => ((0, jsx_runtime_1.jsx)("div", { ref: ref, className: (0, cn_js_1.cn)('tokis-card', variant !== 'default' && `tokis-card--${variant}`, clickable && 'tokis-card--clickable', className), role: clickable ? 'button' : undefined, tabIndex: clickable ? 0 : undefined, ...props, children: children })));
7
+ exports.Card = (0, react_1.forwardRef)(({ variant = 'default', clickable = false, as: Tag, className, children, ...props }, ref) => {
8
+ const Component = Tag ?? (clickable ? 'div' : 'article');
9
+ return ((0, jsx_runtime_1.jsx)(Component, { ref: ref, className: (0, cn_js_1.cn)('tokis-card', variant !== 'default' && `tokis-card--${variant}`, clickable && 'tokis-card--clickable', className), role: clickable ? 'button' : undefined, tabIndex: clickable ? 0 : undefined, ...props, children: children }));
10
+ });
8
11
  exports.Card.displayName = 'Card';
9
12
  exports.CardHeader = (0, react_1.forwardRef)(({ className, ...props }, ref) => ((0, jsx_runtime_1.jsx)("div", { ref: ref, className: (0, cn_js_1.cn)('tokis-card-header', className), ...props })));
10
13
  exports.CardHeader.displayName = 'CardHeader';
@@ -35,6 +35,9 @@ function BarChart({ data, height = 200, barColor, animated = true, horizontal =
35
35
  (0, react_1.useEffect)(() => { if (animated)
36
36
  setTimeout(() => setMounted(true), 50); }, [animated]);
37
37
  const [hoveredBar, setHoveredBar] = (0, react_1.useState)(null);
38
+ // Two ref arrays — one for vertical bars, one for horizontal bars (both must be called unconditionally)
39
+ const barRefs = (0, react_1.useRef)([]);
40
+ const hBarRefs = (0, react_1.useRef)([]);
38
41
  const maxVal = Math.max(...data.map((d) => d.value), 1);
39
42
  const padding = { top: 8, right: 8, bottom: 32, left: 40 };
40
43
  const w = containerWidth;
@@ -43,8 +46,27 @@ function BarChart({ data, height = 200, barColor, animated = true, horizontal =
43
46
  const chartH = h - padding.top - padding.bottom;
44
47
  const barWidth = (chartW / data.length) * 0.6;
45
48
  const barGap = (chartW / data.length) * 0.4;
49
+ const handleBarKeyDown = (e, i) => {
50
+ if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
51
+ e.preventDefault();
52
+ barRefs.current[(i + 1) % data.length]?.focus();
53
+ }
54
+ else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
55
+ e.preventDefault();
56
+ barRefs.current[(i - 1 + data.length) % data.length]?.focus();
57
+ }
58
+ else if (e.key === 'Home') {
59
+ e.preventDefault();
60
+ barRefs.current[0]?.focus();
61
+ }
62
+ else if (e.key === 'End') {
63
+ e.preventDefault();
64
+ barRefs.current[data.length - 1]?.focus();
65
+ }
66
+ };
67
+ const ariaLabel = `Bar chart showing: ${data.map((d) => `${d.label} ${d.value}`).join(', ')}`;
46
68
  if (!horizontal) {
47
- return ((0, jsx_runtime_1.jsx)("div", { ref: containerRef, className: (0, cn_js_1.cn)('tokis-chart tokis-chart--bar', className), children: (0, jsx_runtime_1.jsx)("svg", { width: w, height: h, "aria-label": "Bar chart", onMouseMove: (e) => {
69
+ return ((0, jsx_runtime_1.jsx)("div", { ref: containerRef, className: (0, cn_js_1.cn)('tokis-chart tokis-chart--bar', className), children: (0, jsx_runtime_1.jsx)("svg", { width: w, height: h, "aria-label": ariaLabel, onMouseMove: (e) => {
48
70
  const svgRect = e.currentTarget.getBoundingClientRect();
49
71
  const mouseX = e.clientX - svgRect.left - padding.left;
50
72
  const colW = chartW / data.length;
@@ -55,7 +77,7 @@ function BarChart({ data, height = 200, barColor, animated = true, horizontal =
55
77
  const barH = (d.value / maxVal) * chartH;
56
78
  const y = chartH - (mounted || !animated ? barH : 0);
57
79
  const color = d.color ?? barColor ?? DEFAULT_COLORS[i % DEFAULT_COLORS.length];
58
- return ((0, jsx_runtime_1.jsxs)("g", { children: [(0, jsx_runtime_1.jsx)("rect", { x: x, y: y, width: barWidth, height: mounted || !animated ? barH : 0, fill: color, rx: 3, opacity: hoveredBar !== null && hoveredBar !== i ? 0.5 : 1, style: { transition: animated ? 'y 0.6s ease, height 0.6s ease' : undefined } }), (0, jsx_runtime_1.jsx)("text", { x: x + barWidth / 2, y: chartH + 18, fontSize: "10", fill: "var(--tokis-text-secondary)", textAnchor: "middle", children: d.label })] }, i));
80
+ return ((0, jsx_runtime_1.jsxs)("g", { children: [(0, jsx_runtime_1.jsx)("rect", { ref: (el) => { barRefs.current[i] = el; }, x: x, y: y, width: barWidth, height: mounted || !animated ? barH : 0, fill: color, rx: 3, opacity: hoveredBar !== null && hoveredBar !== i ? 0.5 : 1, style: { transition: animated ? 'y 0.6s ease, height 0.6s ease' : undefined, outline: 'none' }, tabIndex: i === 0 ? 0 : -1, role: "img", "aria-label": `${d.label}: ${d.value}`, onFocus: () => setHoveredBar(i), onBlur: () => setHoveredBar(null), onKeyDown: (e) => handleBarKeyDown(e, i) }), (0, jsx_runtime_1.jsx)("text", { x: x + barWidth / 2, y: chartH + 18, fontSize: "10", fill: "var(--tokis-text-secondary)", textAnchor: "middle", "aria-hidden": "true", children: d.label })] }, i));
59
81
  }), hoveredBar !== null && (() => {
60
82
  const d = data[hoveredBar];
61
83
  const x = hoveredBar * (chartW / data.length) + barGap / 2 + barWidth / 2;
@@ -63,17 +85,27 @@ function BarChart({ data, height = 200, barColor, animated = true, horizontal =
63
85
  const tipY = Math.max(4, chartH - (mounted || !animated ? barH : 0) - 28);
64
86
  const txt = String(d.value);
65
87
  const tw = Math.max(36, txt.length * 7 + 16);
66
- return ((0, jsx_runtime_1.jsxs)("g", { style: { pointerEvents: 'none' }, children: [(0, jsx_runtime_1.jsx)("rect", { x: x - tw / 2, y: tipY, width: tw, height: 20, rx: 4, fill: "rgba(17,24,39,0.92)" }), (0, jsx_runtime_1.jsx)("text", { x: x, y: tipY + 13, fontSize: "10", textAnchor: "middle", fill: "#fff", fontWeight: "600", children: txt })] }));
88
+ return ((0, jsx_runtime_1.jsxs)("g", { style: { pointerEvents: 'none' }, "aria-hidden": "true", children: [(0, jsx_runtime_1.jsx)("rect", { x: x - tw / 2, y: tipY, width: tw, height: 20, rx: 4, fill: "rgba(17,24,39,0.92)" }), (0, jsx_runtime_1.jsx)("text", { x: x, y: tipY + 13, fontSize: "10", textAnchor: "middle", fill: "#fff", fontWeight: "600", children: txt })] }));
67
89
  })()] }) }) }));
68
90
  }
69
91
  // Horizontal
70
- const barH = (chartH / data.length) * 0.6;
71
- const barGapH = (chartH / data.length) * 0.4;
72
- return ((0, jsx_runtime_1.jsx)("div", { ref: containerRef, className: (0, cn_js_1.cn)('tokis-chart tokis-chart--bar', className), children: (0, jsx_runtime_1.jsx)("svg", { width: w, height: h, "aria-label": "Bar chart horizontal", children: (0, jsx_runtime_1.jsx)("g", { transform: `translate(${padding.left},${padding.top})`, children: data.map((d, i) => {
73
- const y = i * (chartH / data.length) + barGapH / 2;
92
+ const hBarH = (chartH / data.length) * 0.6;
93
+ const hBarGap = (chartH / data.length) * 0.4;
94
+ const handleHBarKeyDown = (e, i) => {
95
+ if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
96
+ e.preventDefault();
97
+ hBarRefs.current[(i + 1) % data.length]?.focus();
98
+ }
99
+ else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
100
+ e.preventDefault();
101
+ hBarRefs.current[(i - 1 + data.length) % data.length]?.focus();
102
+ }
103
+ };
104
+ return ((0, jsx_runtime_1.jsx)("div", { ref: containerRef, className: (0, cn_js_1.cn)('tokis-chart tokis-chart--bar', className), children: (0, jsx_runtime_1.jsx)("svg", { width: w, height: h, "aria-label": ariaLabel, children: (0, jsx_runtime_1.jsx)("g", { transform: `translate(${padding.left},${padding.top})`, children: data.map((d, i) => {
105
+ const y = i * (chartH / data.length) + hBarGap / 2;
74
106
  const barW = (d.value / maxVal) * chartW;
75
107
  const color = d.color ?? barColor ?? DEFAULT_COLORS[i % DEFAULT_COLORS.length];
76
- return ((0, jsx_runtime_1.jsxs)("g", { children: [(0, jsx_runtime_1.jsx)("text", { x: -8, y: y + barH / 2 + 4, fontSize: "10", fill: "var(--tokis-text-secondary)", textAnchor: "end", children: d.label }), (0, jsx_runtime_1.jsx)("rect", { x: 0, y: y, width: mounted || !animated ? barW : 0, height: barH, fill: color, rx: 3, style: { transition: animated ? 'width 0.6s ease' : undefined } })] }, i));
108
+ return ((0, jsx_runtime_1.jsxs)("g", { children: [(0, jsx_runtime_1.jsx)("text", { x: -8, y: y + hBarH / 2 + 4, fontSize: "10", fill: "var(--tokis-text-secondary)", textAnchor: "end", "aria-hidden": "true", children: d.label }), (0, jsx_runtime_1.jsx)("rect", { ref: (el) => { hBarRefs.current[i] = el; }, x: 0, y: y, width: mounted || !animated ? barW : 0, height: hBarH, fill: color, rx: 3, style: { transition: animated ? 'width 0.6s ease' : undefined, outline: 'none' }, tabIndex: i === 0 ? 0 : -1, role: "img", "aria-label": `${d.label}: ${d.value}`, onFocus: () => setHoveredBar(i), onBlur: () => setHoveredBar(null), onKeyDown: (e) => handleHBarKeyDown(e, i) })] }, i));
77
109
  }) }) }) }));
78
110
  }
79
111
  BarChart.displayName = 'BarChart';
@@ -97,6 +129,7 @@ function LineChart({ labels, datasets, height = 200, smooth = true, animated = t
97
129
  const containerWidth = useContainerWidth(containerRef);
98
130
  const [mounted, setMounted] = (0, react_1.useState)(false);
99
131
  const [hoveredCol, setHoveredCol] = (0, react_1.useState)(null);
132
+ const pointRefs = (0, react_1.useRef)([]);
100
133
  (0, react_1.useEffect)(() => { if (animated)
101
134
  setTimeout(() => setMounted(true), 50); }, [animated]);
102
135
  const padding = { top: 12, right: 12, bottom: 32, left: 44 };
@@ -112,17 +145,45 @@ function LineChart({ labels, datasets, height = 200, smooth = true, animated = t
112
145
  x: (idx / (labels.length - 1 || 1)) * chartW,
113
146
  y: chartH - ((val - minVal) / range) * chartH,
114
147
  });
115
- return ((0, jsx_runtime_1.jsxs)("div", { ref: containerRef, className: (0, cn_js_1.cn)('tokis-chart tokis-chart--line', className), children: [(0, jsx_runtime_1.jsx)("svg", { width: w, height: h, "aria-label": "Line chart", onMouseMove: (e) => {
148
+ const lineAriaLabel = `Line chart showing ${datasets.map((d) => d.label).join(' and ')} over ${labels.join(', ')}`;
149
+ const handlePointKeyDown = (e, colIdx) => {
150
+ if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
151
+ e.preventDefault();
152
+ const next = Math.min(colIdx + 1, labels.length - 1);
153
+ pointRefs.current[0]?.[next]?.focus();
154
+ }
155
+ else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
156
+ e.preventDefault();
157
+ const prev = Math.max(colIdx - 1, 0);
158
+ pointRefs.current[0]?.[prev]?.focus();
159
+ }
160
+ else if (e.key === 'Home') {
161
+ e.preventDefault();
162
+ pointRefs.current[0]?.[0]?.focus();
163
+ }
164
+ else if (e.key === 'End') {
165
+ e.preventDefault();
166
+ pointRefs.current[0]?.[labels.length - 1]?.focus();
167
+ }
168
+ };
169
+ return ((0, jsx_runtime_1.jsxs)("div", { ref: containerRef, className: (0, cn_js_1.cn)('tokis-chart tokis-chart--line', className), children: [(0, jsx_runtime_1.jsx)("svg", { width: w, height: h, "aria-label": lineAriaLabel, onMouseMove: (e) => {
116
170
  const svgRect = e.currentTarget.getBoundingClientRect();
117
171
  const mouseX = e.clientX - svgRect.left - padding.left;
118
172
  const colW = chartW / (labels.length - 1 || 1);
119
173
  const idx = Math.round(mouseX / colW);
120
174
  setHoveredCol(idx >= 0 && idx < labels.length ? idx : null);
121
- }, onMouseLeave: () => setHoveredCol(null), children: (0, jsx_runtime_1.jsxs)("g", { transform: `translate(${padding.left},${padding.top})`, children: [[0, 0.25, 0.5, 0.75, 1].map((t) => ((0, jsx_runtime_1.jsxs)("g", { transform: `translate(0,${chartH * (1 - t)})`, children: [(0, jsx_runtime_1.jsx)("line", { x1: 0, x2: chartW, stroke: "var(--tokis-color-border)", strokeWidth: "1" }), (0, jsx_runtime_1.jsx)("text", { x: -8, y: 4, fontSize: "10", fill: "var(--tokis-text-tertiary)", textAnchor: "end", children: Math.round(minVal + range * t) })] }, t))), labels.map((lbl, i) => ((0, jsx_runtime_1.jsx)("text", { x: toPoint(0, i).x, y: chartH + 18, fontSize: "10", fill: "var(--tokis-text-secondary)", textAnchor: "middle", children: lbl }, i))), datasets.map((dataset, di) => {
175
+ }, onMouseLeave: () => setHoveredCol(null), children: (0, jsx_runtime_1.jsxs)("g", { transform: `translate(${padding.left},${padding.top})`, children: [[0, 0.25, 0.5, 0.75, 1].map((t) => ((0, jsx_runtime_1.jsxs)("g", { transform: `translate(0,${chartH * (1 - t)})`, children: [(0, jsx_runtime_1.jsx)("line", { x1: 0, x2: chartW, stroke: "var(--tokis-color-border)", strokeWidth: "1" }), (0, jsx_runtime_1.jsx)("text", { x: -8, y: 4, fontSize: "10", fill: "var(--tokis-text-tertiary)", textAnchor: "end", children: Math.round(minVal + range * t) })] }, t))), labels.map((lbl, i) => ((0, jsx_runtime_1.jsx)("text", { x: toPoint(0, i).x, y: chartH + 18, fontSize: "10", fill: "var(--tokis-text-secondary)", textAnchor: "middle", "aria-hidden": "true", children: lbl }, i))), datasets.map((dataset, di) => {
122
176
  const points = dataset.data.map((v, i) => toPoint(v, i));
123
177
  const pathD = toPath(points, smooth);
124
178
  const color = dataset.color ?? DEFAULT_COLORS[di % DEFAULT_COLORS.length];
125
- return ((0, jsx_runtime_1.jsxs)("g", { children: [(0, jsx_runtime_1.jsx)("path", { d: pathD, fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: animated ? { strokeDasharray: 2000, strokeDashoffset: mounted ? 0 : 2000, transition: 'stroke-dashoffset 1s ease' } : undefined }), points.map((p, pi) => ((0, jsx_runtime_1.jsx)("circle", { cx: p.x, cy: p.y, r: 3, fill: color, style: animated ? { opacity: mounted ? 1 : 0, transition: `opacity 0.5s ease ${pi * 0.05}s` } : undefined }, pi)))] }, di));
179
+ if (!pointRefs.current[di])
180
+ pointRefs.current[di] = [];
181
+ return ((0, jsx_runtime_1.jsxs)("g", { children: [(0, jsx_runtime_1.jsx)("path", { d: pathD, fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", style: animated ? { strokeDasharray: 2000, strokeDashoffset: mounted ? 0 : 2000, transition: 'stroke-dashoffset 1s ease' } : undefined }), points.map((p, pi) => {
182
+ const isFirstDataset = di === 0;
183
+ return ((0, jsx_runtime_1.jsx)("circle", { ref: (el) => { pointRefs.current[di][pi] = el; }, cx: p.x, cy: p.y, r: isFirstDataset ? 4 : 3, fill: color, style: { outline: 'none', ...(animated ? { opacity: mounted ? 1 : 0, transition: `opacity 0.5s ease ${pi * 0.05}s` } : undefined) }, tabIndex: isFirstDataset ? (pi === 0 ? 0 : -1) : -1, role: isFirstDataset ? 'img' : undefined, "aria-label": isFirstDataset
184
+ ? `${labels[pi]}: ${datasets.map((ds) => `${ds.label} ${ds.data[pi]}`).join(', ')}`
185
+ : undefined, onFocus: isFirstDataset ? () => setHoveredCol(pi) : undefined, onBlur: isFirstDataset ? () => setHoveredCol(null) : undefined, onKeyDown: isFirstDataset ? (e) => handlePointKeyDown(e, pi) : undefined }, pi));
186
+ })] }, di));
126
187
  }), hoveredCol !== null && (() => {
127
188
  const x = toPoint(0, hoveredCol).x;
128
189
  const vals = datasets.map((ds) => ({ val: ds.data[hoveredCol], color: ds.color ?? DEFAULT_COLORS[datasets.indexOf(ds) % DEFAULT_COLORS.length], label: ds.label }));
@@ -131,7 +192,7 @@ function LineChart({ labels, datasets, height = 200, smooth = true, animated = t
131
192
  return null;
132
193
  const y = toPoint(firstVal.val, hoveredCol).y;
133
194
  const isMulti = vals.length > 1;
134
- return ((0, jsx_runtime_1.jsxs)("g", { style: { pointerEvents: 'none' }, children: [(0, jsx_runtime_1.jsx)("line", { x1: x, x2: x, y1: 0, y2: chartH, stroke: "var(--tokis-color-border)", strokeWidth: "1", strokeDasharray: "3,3" }), vals.map(({ val, color }, vi) => {
195
+ return ((0, jsx_runtime_1.jsxs)("g", { style: { pointerEvents: 'none' }, "aria-hidden": "true", children: [(0, jsx_runtime_1.jsx)("line", { x1: x, x2: x, y1: 0, y2: chartH, stroke: "var(--tokis-color-border)", strokeWidth: "1", strokeDasharray: "3,3" }), vals.map(({ val, color }, vi) => {
135
196
  if (val === undefined)
136
197
  return null;
137
198
  const py = toPoint(val, hoveredCol).y;
@@ -158,6 +219,7 @@ function PieChart({ data, donut = false, size = 200, animated = true, showLegend
158
219
  (0, react_1.useEffect)(() => { if (animated)
159
220
  setTimeout(() => setMounted(true), 50); }, [animated]);
160
221
  const [hovered, setHovered] = (0, react_1.useState)(null);
222
+ const sliceRefs = (0, react_1.useRef)([]);
161
223
  const total = data.reduce((s, d) => s + d.value, 0) || 1;
162
224
  const cx = size / 2;
163
225
  const cy = size / 2;
@@ -187,7 +249,26 @@ function PieChart({ data, donut = false, size = 200, animated = true, showLegend
187
249
  : `M${cx + offsetX},${cy + offsetY} L${x1},${y1} A${r},${r} 0 ${largeArc},1 ${x2},${y2} Z`;
188
250
  return { ...d, pathD, color: d.color ?? DEFAULT_COLORS[i % DEFAULT_COLORS.length] };
189
251
  });
190
- return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_js_1.cn)('tokis-chart tokis-chart--pie', className), children: [(0, jsx_runtime_1.jsx)("svg", { width: size, height: size, "aria-label": "Pie chart", children: slices.map((s, i) => ((0, jsx_runtime_1.jsx)("path", { d: s.pathD, fill: s.color, style: { opacity: mounted || !animated ? 1 : 0, transition: animated ? `opacity 0.4s ease ${i * 0.07}s` : undefined, cursor: 'pointer' }, onMouseEnter: () => setHovered(i), onMouseLeave: () => setHovered(null), children: (0, jsx_runtime_1.jsxs)("title", { children: [s.label, ": ", s.value, " (", ((s.value / total) * 100).toFixed(1), "%)"] }) }, i))) }), showLegend && ((0, jsx_runtime_1.jsx)("div", { className: "tokis-chart__legend", children: slices.map((s, i) => ((0, jsx_runtime_1.jsxs)("span", { className: "tokis-chart__legend-item", children: [(0, jsx_runtime_1.jsx)("span", { className: "tokis-chart__legend-dot", style: { background: s.color } }), s.label] }, i))) }))] }));
252
+ const pieAriaLabel = `${donut ? 'Donut' : 'Pie'} chart showing: ${data.map((d) => `${d.label} ${d.value} (${((d.value / total) * 100).toFixed(1)}%)`).join(', ')}`;
253
+ const handleSliceKeyDown = (e, i) => {
254
+ if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
255
+ e.preventDefault();
256
+ sliceRefs.current[(i + 1) % slices.length]?.focus();
257
+ }
258
+ else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
259
+ e.preventDefault();
260
+ sliceRefs.current[(i - 1 + slices.length) % slices.length]?.focus();
261
+ }
262
+ else if (e.key === 'Home') {
263
+ e.preventDefault();
264
+ sliceRefs.current[0]?.focus();
265
+ }
266
+ else if (e.key === 'End') {
267
+ e.preventDefault();
268
+ sliceRefs.current[slices.length - 1]?.focus();
269
+ }
270
+ };
271
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_js_1.cn)('tokis-chart tokis-chart--pie', className), children: [(0, jsx_runtime_1.jsx)("svg", { width: size, height: size, "aria-label": pieAriaLabel, children: slices.map((s, i) => ((0, jsx_runtime_1.jsx)("path", { ref: (el) => { sliceRefs.current[i] = el; }, d: s.pathD, fill: s.color, style: { opacity: mounted || !animated ? 1 : 0, transition: animated ? `opacity 0.4s ease ${i * 0.07}s` : undefined, cursor: 'pointer', outline: 'none' }, tabIndex: i === 0 ? 0 : -1, role: "img", "aria-label": `${s.label}: ${s.value} (${((s.value / total) * 100).toFixed(1)}%)`, onMouseEnter: () => setHovered(i), onMouseLeave: () => setHovered(null), onFocus: () => setHovered(i), onBlur: () => setHovered(null), onKeyDown: (e) => handleSliceKeyDown(e, i), children: (0, jsx_runtime_1.jsxs)("title", { children: [s.label, ": ", s.value, " (", ((s.value / total) * 100).toFixed(1), "%)"] }) }, i))) }), showLegend && ((0, jsx_runtime_1.jsx)("div", { className: "tokis-chart__legend", children: slices.map((s, i) => ((0, jsx_runtime_1.jsxs)("span", { className: "tokis-chart__legend-item", children: [(0, jsx_runtime_1.jsx)("span", { className: "tokis-chart__legend-dot", style: { background: s.color } }), s.label] }, i))) }))] }));
191
272
  }
192
273
  PieChart.displayName = 'PieChart';
193
274
  function Sparkline({ data, type = 'line', width = 80, height = 24, color = 'var(--tokis-color-primary)', className, }) {
@@ -20,10 +20,12 @@ const cn_js_1 = require("../../utils/cn");
20
20
  const Calendar_js_1 = require("./Calendar");
21
21
  const date_utils_js_1 = require("./date-utils");
22
22
  // ─── Shared floating panel hook ───────────────────────────────────────────────
23
+ const FOCUSABLE = 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
23
24
  function useFloatingPanel(onClose) {
24
25
  const [open, setOpen] = (0, react_1.useState)(false);
25
26
  const triggerRef = (0, react_1.useRef)(null);
26
27
  const panelRef = (0, react_1.useRef)(null);
28
+ const previousFocusRef = (0, react_1.useRef)(null);
27
29
  const [pos, setPos] = (0, react_1.useState)({ top: 0, left: 0 });
28
30
  const updatePos = (0, react_1.useCallback)(() => {
29
31
  const el = triggerRef.current;
@@ -36,14 +38,27 @@ function useFloatingPanel(onClose) {
36
38
  });
37
39
  }, []);
38
40
  const openPanel = () => {
41
+ previousFocusRef.current = document.activeElement;
39
42
  updatePos();
40
43
  setOpen(true);
41
44
  };
42
45
  const closePanel = (0, react_1.useCallback)(() => {
43
46
  setOpen(false);
44
47
  onClose?.();
45
- triggerRef.current?.focus();
48
+ (previousFocusRef.current ?? triggerRef.current)?.focus();
49
+ previousFocusRef.current = null;
46
50
  }, [onClose]);
51
+ // Move focus into the panel when it opens so keyboard users can interact with it
52
+ (0, react_1.useEffect)(() => {
53
+ if (!open)
54
+ return;
55
+ requestAnimationFrame(() => {
56
+ if (!panelRef.current)
57
+ return;
58
+ const first = panelRef.current.querySelector(FOCUSABLE);
59
+ (first ?? panelRef.current).focus();
60
+ });
61
+ }, [open]);
47
62
  // Close on outside click
48
63
  (0, react_1.useEffect)(() => {
49
64
  if (!open)
@@ -86,7 +101,7 @@ function DatePicker({ value: valueProp, defaultValue, onChange, label, placehold
86
101
  setInternalValue(undefined);
87
102
  onChange?.(undefined);
88
103
  };
89
- return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_js_1.cn)('tokis-datepicker', error && 'tokis-datepicker--error', disabled && 'tokis-datepicker--disabled', className), children: [label && ((0, jsx_runtime_1.jsxs)("label", { className: "tokis-label", htmlFor: id, children: [label, required && (0, jsx_runtime_1.jsx)("span", { className: "tokis-label-required", "aria-hidden": "true", children: " *" })] })), (0, jsx_runtime_1.jsxs)("div", { className: "tokis-datepicker-input-wrap", children: [(0, jsx_runtime_1.jsxs)("button", { ref: triggerRef, id: id, type: "button", className: (0, cn_js_1.cn)('tokis-datepicker-trigger', open && 'tokis-datepicker-trigger--open'), disabled: disabled, "aria-haspopup": "dialog", "aria-expanded": open, "aria-label": label ? `${label}: ${parsedDate ? (0, date_utils_js_1.formatDisplayDate)(parsedDate) : 'not set'}` : undefined, onClick: () => (open ? closePanel() : openPanel()), children: [(0, jsx_runtime_1.jsx)("span", { className: (0, cn_js_1.cn)('tokis-datepicker-value', !parsedDate && 'tokis-datepicker-placeholder'), children: parsedDate ? (0, date_utils_js_1.formatDisplayDate)(parsedDate) : placeholder }), (0, jsx_runtime_1.jsx)("span", { className: "tokis-datepicker-icon", "aria-hidden": "true", children: "\uD83D\uDCC5" })] }), parsedDate && !disabled && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "tokis-datepicker-clear", "aria-label": "Clear date", onClick: handleClear, children: "\u2715" }))] }), open && ((0, jsx_runtime_1.jsx)(index_js_1.Portal, { children: (0, jsx_runtime_1.jsx)("div", { ref: panelRef, className: "tokis-datepicker-panel", role: "dialog", "aria-modal": "false", "aria-label": label ?? 'Date picker', style: { top: pos.top, left: pos.left }, children: (0, jsx_runtime_1.jsx)(Calendar_js_1.Calendar, { value: value, onChange: handleSelect, min: min, max: max }) }) }))] }));
104
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_js_1.cn)('tokis-datepicker', error && 'tokis-datepicker--error', disabled && 'tokis-datepicker--disabled', className), children: [label && ((0, jsx_runtime_1.jsxs)("label", { className: "tokis-label", htmlFor: id, children: [label, required && (0, jsx_runtime_1.jsx)("span", { className: "tokis-label-required", "aria-hidden": "true", children: " *" })] })), (0, jsx_runtime_1.jsxs)("div", { className: "tokis-datepicker-input-wrap", children: [(0, jsx_runtime_1.jsxs)("button", { ref: triggerRef, id: id, type: "button", className: (0, cn_js_1.cn)('tokis-datepicker-trigger', open && 'tokis-datepicker-trigger--open'), disabled: disabled, "aria-haspopup": "dialog", "aria-expanded": open, "aria-label": label ? `${label}: ${parsedDate ? (0, date_utils_js_1.formatDisplayDate)(parsedDate) : 'not set'}` : undefined, onClick: () => (open ? closePanel() : openPanel()), children: [(0, jsx_runtime_1.jsx)("span", { className: (0, cn_js_1.cn)('tokis-datepicker-value', !parsedDate && 'tokis-datepicker-placeholder'), children: parsedDate ? (0, date_utils_js_1.formatDisplayDate)(parsedDate) : placeholder }), (0, jsx_runtime_1.jsx)("span", { className: "tokis-datepicker-icon", "aria-hidden": "true", children: "\uD83D\uDCC5" })] }), parsedDate && !disabled && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "tokis-datepicker-clear", "aria-label": "Clear date", onClick: handleClear, children: "\u2715" }))] }), open && ((0, jsx_runtime_1.jsx)(index_js_1.Portal, { children: (0, jsx_runtime_1.jsx)("div", { ref: panelRef, className: "tokis-datepicker-panel", role: "dialog", "aria-modal": "false", "aria-label": label ?? 'Date picker', tabIndex: -1, style: { top: pos.top, left: pos.left }, children: (0, jsx_runtime_1.jsx)(Calendar_js_1.Calendar, { value: value, onChange: handleSelect, min: min, max: max }) }) }))] }));
90
105
  }
91
106
  function TimePicker({ value: valueProp, defaultValue, onChange, label, disabled = false, required = false, error = false, hourFormat = 24, minuteStep = 1, className, }) {
92
107
  const [internalValue, setInternalValue] = (0, react_1.useState)(defaultValue ?? '00:00');
@@ -8,6 +8,9 @@ const index_js_1 = require("../portal/index");
8
8
  const core_1 = require("@tokis/core");
9
9
  function Drawer({ open, onClose, side = 'right', title, description, children, footer, closeOnBackdrop = true, closeOnEsc = true, className }) {
10
10
  const contentRef = (0, react_1.useRef)(null);
11
+ const drawerId = (0, react_1.useId)();
12
+ const titleId = title ? `${drawerId}-title` : undefined;
13
+ const descId = description ? `${drawerId}-desc` : undefined;
11
14
  (0, react_1.useEffect)(() => {
12
15
  if (!open)
13
16
  return;
@@ -33,5 +36,5 @@ function Drawer({ open, onClose, side = 'right', title, description, children, f
33
36
  }, [open]);
34
37
  if (!open)
35
38
  return null;
36
- return ((0, jsx_runtime_1.jsxs)(index_js_1.Portal, { children: [(0, jsx_runtime_1.jsx)("div", { className: "tokis-drawer-backdrop", "aria-hidden": "true", onClick: closeOnBackdrop ? onClose : undefined }), (0, jsx_runtime_1.jsxs)("div", { ref: contentRef, role: "dialog", "aria-modal": "true", tabIndex: -1, className: (0, cn_js_1.cn)(`tokis-drawer-content tokis-drawer-content--${side}`, className), onClick: (e) => e.stopPropagation(), children: [(title || description) && ((0, jsx_runtime_1.jsxs)("div", { className: "tokis-drawer-header", children: [title && (0, jsx_runtime_1.jsx)("h2", { className: "tokis-drawer-title", children: title }), description && (0, jsx_runtime_1.jsx)("p", { className: "tokis-drawer-description", children: description }), (0, jsx_runtime_1.jsx)("button", { className: "tokis-drawer-close", onClick: onClose, "aria-label": "Close drawer", children: (0, jsx_runtime_1.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: (0, jsx_runtime_1.jsx)("path", { d: "M3 3l10 10M13 3L3 13", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) }) })] })), (0, jsx_runtime_1.jsx)("div", { className: "tokis-drawer-body", children: children }), footer && (0, jsx_runtime_1.jsx)("div", { className: "tokis-drawer-footer", children: footer })] })] }));
39
+ return ((0, jsx_runtime_1.jsxs)(index_js_1.Portal, { children: [(0, jsx_runtime_1.jsx)("div", { className: "tokis-drawer-backdrop", "aria-hidden": "true", onClick: closeOnBackdrop ? onClose : undefined }), (0, jsx_runtime_1.jsxs)("div", { ref: contentRef, role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, "aria-describedby": descId, tabIndex: -1, className: (0, cn_js_1.cn)(`tokis-drawer-content tokis-drawer-content--${side}`, className), onClick: (e) => e.stopPropagation(), children: [(title || description) && ((0, jsx_runtime_1.jsxs)("div", { className: "tokis-drawer-header", children: [title && (0, jsx_runtime_1.jsx)("h2", { id: titleId, className: "tokis-drawer-title", children: title }), description && (0, jsx_runtime_1.jsx)("p", { id: descId, className: "tokis-drawer-description", children: description }), (0, jsx_runtime_1.jsx)("button", { className: "tokis-drawer-close", onClick: onClose, "aria-label": "Close drawer", children: (0, jsx_runtime_1.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: (0, jsx_runtime_1.jsx)("path", { d: "M3 3l10 10M13 3L3 13", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) }) })] })), (0, jsx_runtime_1.jsx)("div", { className: "tokis-drawer-body", children: children }), footer && (0, jsx_runtime_1.jsx)("div", { className: "tokis-drawer-footer", children: footer })] })] }));
37
40
  }
@@ -104,7 +104,7 @@ function Rating({ value = 0, max = 5, readOnly = false, onChange, size = 'md', l
104
104
  return ((0, jsx_runtime_1.jsx)("div", { className: (0, cn_js_1.cn)('tokis-rating', readOnly && 'tokis-rating--readonly'), role: "radiogroup", "aria-label": label, "data-readonly": readOnly || undefined, children: Array.from({ length: max }).map((_, index) => {
105
105
  const current = index + 1;
106
106
  const filled = current <= display;
107
- return ((0, jsx_runtime_1.jsx)("button", { type: "button", role: "radio", "aria-checked": current <= value, "aria-label": `${current} star${current !== 1 ? 's' : ''}`, disabled: readOnly, className: (0, cn_js_1.cn)('tokis-rating-star', filled && 'tokis-rating-star--active', hovered !== null && filled && 'tokis-rating-star--hover'), style: { fontSize: sizeMap[size] }, onClick: () => onChange?.(current), onMouseEnter: () => !readOnly && setHovered(current), onMouseLeave: () => !readOnly && setHovered(null), children: (0, jsx_runtime_1.jsx)("svg", { viewBox: "0 0 24 24", width: sizeMap[size], height: sizeMap[size], "aria-hidden": "true", fill: filled ? 'currentColor' : 'none', stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: (0, jsx_runtime_1.jsx)("path", { d: "M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" }) }) }, current));
107
+ return ((0, jsx_runtime_1.jsx)("button", { type: "button", role: "radio", "aria-checked": current <= value, "aria-label": `${current} star${current !== 1 ? 's' : ''}`, disabled: readOnly, className: (0, cn_js_1.cn)('tokis-rating-star', filled && 'tokis-rating-star--active', hovered !== null && filled && 'tokis-rating-star--hover'), style: { fontSize: sizeMap[size] }, onClick: () => onChange?.(current), onMouseEnter: () => !readOnly && setHovered(current), onMouseLeave: () => !readOnly && setHovered(null), onFocus: () => !readOnly && setHovered(current), onBlur: () => !readOnly && setHovered(null), children: (0, jsx_runtime_1.jsx)("svg", { viewBox: "0 0 24 24", width: sizeMap[size], height: sizeMap[size], "aria-hidden": "true", fill: filled ? 'currentColor' : 'none', stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: (0, jsx_runtime_1.jsx)("path", { d: "M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" }) }) }, current));
108
108
  }) }));
109
109
  }
110
110
  function TransferList({ left, right, onChange, leftTitle = 'Available', rightTitle = 'Selected' }) {
@@ -52,6 +52,7 @@ function HoverCard({ trigger, content, placement = 'bottom', openDelay = 300, cl
52
52
  const [positioned, setPositioned] = (0, react_1.useState)(false);
53
53
  const [pos, setPos] = (0, react_1.useState)({ top: 0, left: 0 });
54
54
  const anchorRef = (0, react_1.useRef)(null);
55
+ const cardId = (0, react_1.useId)();
55
56
  const openTimer = (0, react_1.useRef)();
56
57
  const closeTimer = (0, react_1.useRef)();
57
58
  const show = (0, react_1.useCallback)(() => {
@@ -79,6 +80,7 @@ function HoverCard({ trigger, content, placement = 'bottom', openDelay = 300, cl
79
80
  };
80
81
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [react_1.default.cloneElement(trigger, {
81
82
  ref: anchorRef,
83
+ 'aria-describedby': visible ? cardId : undefined,
82
84
  onMouseEnter: (...args) => {
83
85
  show();
84
86
  trigger.props.onMouseEnter?.(...args);
@@ -95,7 +97,7 @@ function HoverCard({ trigger, content, placement = 'bottom', openDelay = 300, cl
95
97
  hide();
96
98
  trigger.props.onBlur?.(...args);
97
99
  },
98
- }), visible && ((0, jsx_runtime_1.jsx)(index_js_1.Portal, { children: (0, jsx_runtime_1.jsx)("div", { className: (0, cn_js_1.cn)('tokis-hover-card', `tokis-hover-card--${placement}`, className), style: {
100
+ }), visible && ((0, jsx_runtime_1.jsx)(index_js_1.Portal, { children: (0, jsx_runtime_1.jsx)("div", { id: cardId, role: "tooltip", className: (0, cn_js_1.cn)('tokis-hover-card', `tokis-hover-card--${placement}`, className), style: {
99
101
  position: 'fixed',
100
102
  top: pos.top,
101
103
  left: pos.left,
@@ -41,6 +41,6 @@ function Pagination({ page, totalPages, onChange, siblingCount = 1, className, }
41
41
  return ((0, jsx_runtime_1.jsx)("span", { className: "tokis-pagination__ellipsis", "aria-hidden": "true", children: "\u2026" }, item));
42
42
  }
43
43
  const isActive = item === page;
44
- return ((0, jsx_runtime_1.jsx)("button", { className: (0, cn_js_1.cn)('tokis-pagination__item', isActive && 'tokis-pagination__item--active'), onClick: () => onChange(item), "aria-label": `Go to page ${item}`, "aria-current": isActive ? 'page' : undefined, disabled: isActive, children: item }, `${item}-${index}`));
44
+ return ((0, jsx_runtime_1.jsx)("button", { className: (0, cn_js_1.cn)('tokis-pagination__item', isActive && 'tokis-pagination__item--active'), onClick: isActive ? undefined : () => onChange(item), "aria-label": isActive ? `Page ${item}, current page` : `Go to page ${item}`, "aria-current": isActive ? 'page' : undefined, children: item }, `${item}-${index}`));
45
45
  }), (0, jsx_runtime_1.jsx)("button", { className: (0, cn_js_1.cn)('tokis-pagination__item', 'tokis-pagination__next', page === totalPages && 'tokis-pagination__item--disabled'), onClick: handleNext, disabled: page === totalPages, "aria-label": "Go to next page", "aria-disabled": page === totalPages, children: (0, jsx_runtime_1.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: (0, jsx_runtime_1.jsx)("path", { d: "M6 4l4 4-4 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] }));
46
46
  }
@@ -44,6 +44,7 @@ function Popover({ trigger, content, title, placement = 'bottom-start', open, de
44
44
  const [pos, setPos] = (0, react_1.useState)({ top: 0, left: 0 });
45
45
  const triggerRef = (0, react_1.useRef)(null);
46
46
  const contentRef = (0, react_1.useRef)(null);
47
+ const previousFocusRef = (0, react_1.useRef)(null);
47
48
  const popoverId = (0, react_1.useId)();
48
49
  const setOpen = (0, react_1.useCallback)((val) => {
49
50
  if (open === undefined)
@@ -103,7 +104,29 @@ function Popover({ trigger, content, title, placement = 'bottom-start', open, de
103
104
  document.addEventListener('keydown', h);
104
105
  return () => document.removeEventListener('keydown', h);
105
106
  }, [isOpen, closeOnEsc, setOpen]);
106
- const handleToggle = () => { updatePosition(); setOpen(!isOpen); };
107
+ // Move focus into popover on open; restore it to the trigger on close
108
+ (0, react_1.useEffect)(() => {
109
+ if (isOpen) {
110
+ requestAnimationFrame(() => {
111
+ if (!contentRef.current)
112
+ return;
113
+ const focusableSelectors = 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
114
+ const firstFocusable = contentRef.current.querySelector(focusableSelectors);
115
+ (firstFocusable ?? contentRef.current).focus();
116
+ });
117
+ }
118
+ else if (previousFocusRef.current) {
119
+ previousFocusRef.current.focus();
120
+ previousFocusRef.current = null;
121
+ }
122
+ }, [isOpen]);
123
+ const handleToggle = () => {
124
+ if (!isOpen) {
125
+ previousFocusRef.current = document.activeElement;
126
+ }
127
+ updatePosition();
128
+ setOpen(!isOpen);
129
+ };
107
130
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [react_1.default.cloneElement(trigger, {
108
131
  ref: triggerRef,
109
132
  'aria-expanded': isOpen,
@@ -1,60 +1,43 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
3
  exports.Radio = Radio;
37
4
  exports.RadioGroup = RadioGroup;
38
5
  const jsx_runtime_1 = require("react/jsx-runtime");
39
- const react_1 = __importStar(require("react"));
6
+ const react_1 = require("react");
40
7
  const cn_js_1 = require("../../utils/cn");
41
- function Radio({ value, label, description, disabled = false, checked = false, name, onChange, className }) {
8
+ const RadioGroupContext = (0, react_1.createContext)(null);
9
+ function Radio({ value, label, description, disabled = false, checked, name, onChange, className }) {
10
+ const ctx = (0, react_1.useContext)(RadioGroupContext);
42
11
  const autoId = (0, react_1.useId)();
43
12
  const radioId = `radio-${autoId}`;
44
13
  const descId = description ? `${radioId}-desc` : undefined;
45
- return ((0, jsx_runtime_1.jsxs)("label", { className: (0, cn_js_1.cn)('tokis-radio-root', className), "data-disabled": disabled || undefined, htmlFor: radioId, children: [(0, jsx_runtime_1.jsx)("input", { type: "radio", id: radioId, name: name, value: value, checked: checked, disabled: disabled, onChange: (e) => e.target.checked && onChange?.(value), className: "tokis-radio-native", "aria-describedby": descId }), (0, jsx_runtime_1.jsx)("span", { "aria-hidden": "true", className: "tokis-radio-control", "data-checked": checked ? 'true' : undefined }), (label || description) && ((0, jsx_runtime_1.jsxs)("div", { children: [label && (0, jsx_runtime_1.jsx)("span", { className: "tokis-radio-label", children: label }), description && (0, jsx_runtime_1.jsx)("p", { id: descId, className: "tokis-radio-description", children: description })] }))] }));
14
+ // When inside a RadioGroup, use context values; otherwise fall back to own props.
15
+ const resolvedName = ctx?.name ?? name ?? '';
16
+ const resolvedChecked = ctx ? ctx.value === value : (checked ?? false);
17
+ const resolvedDisabled = ctx ? (ctx.groupDisabled || disabled) : disabled;
18
+ const handleChange = (e) => {
19
+ if (!e.target.checked)
20
+ return;
21
+ if (ctx) {
22
+ ctx.onChange?.(value);
23
+ }
24
+ else {
25
+ onChange?.(value);
26
+ }
27
+ };
28
+ return ((0, jsx_runtime_1.jsxs)("label", { className: (0, cn_js_1.cn)('tokis-radio-root', className), "data-disabled": resolvedDisabled || undefined, htmlFor: radioId, children: [(0, jsx_runtime_1.jsx)("input", { type: "radio", id: radioId, name: resolvedName, value: value, checked: resolvedChecked, disabled: resolvedDisabled, onChange: handleChange, className: "tokis-radio-native", "aria-describedby": descId }), (0, jsx_runtime_1.jsx)("span", { "aria-hidden": "true", className: "tokis-radio-control", "data-checked": resolvedChecked ? 'true' : undefined }), (label || description) && ((0, jsx_runtime_1.jsxs)("div", { children: [label && (0, jsx_runtime_1.jsx)("span", { className: "tokis-radio-label", children: label }), description && (0, jsx_runtime_1.jsx)("p", { id: descId, className: "tokis-radio-description", children: description })] }))] }));
46
29
  }
47
- function RadioGroup({ value, onChange, name, orientation = 'vertical', disabled = false, children, className, label }) {
30
+ function RadioGroup({ value: controlledValue, defaultValue, onChange, name, orientation = 'vertical', disabled = false, children, className, label, }) {
48
31
  const groupId = (0, react_1.useId)();
49
- return ((0, jsx_runtime_1.jsxs)("div", { role: "radiogroup", "aria-labelledby": label ? groupId : undefined, "aria-disabled": disabled, className: (0, cn_js_1.cn)('tokis-radio-group', orientation === 'horizontal' && 'tokis-radio-group--horizontal', className), children: [label && (0, jsx_runtime_1.jsx)("span", { id: groupId, className: "tokis-label", style: { marginBottom: 'var(--tokis-spacing-1)' }, children: label }), react_1.default.Children.map(children, (child) => {
50
- if (!react_1.default.isValidElement(child))
51
- return child;
52
- const item = child;
53
- return react_1.default.cloneElement(item, {
54
- name: name ?? groupId,
55
- checked: value !== undefined ? item.props.value === value : item.props.checked,
56
- disabled: disabled || item.props.disabled,
57
- onChange: (v) => onChange?.(v),
58
- });
59
- })] }));
32
+ const resolvedName = name ?? groupId;
33
+ // Support uncontrolled usage via defaultValue
34
+ const [uncontrolledValue, setUncontrolledValue] = (0, react_1.useState)(defaultValue);
35
+ const isControlled = controlledValue !== undefined;
36
+ const value = isControlled ? controlledValue : uncontrolledValue;
37
+ const handleChange = (v) => {
38
+ if (!isControlled)
39
+ setUncontrolledValue(v);
40
+ onChange?.(v);
41
+ };
42
+ return ((0, jsx_runtime_1.jsx)(RadioGroupContext.Provider, { value: { name: resolvedName, value, groupDisabled: disabled, onChange: handleChange }, children: (0, jsx_runtime_1.jsxs)("div", { role: "radiogroup", "aria-labelledby": label ? groupId : undefined, "aria-disabled": disabled || undefined, className: (0, cn_js_1.cn)('tokis-radio-group', orientation === 'horizontal' && 'tokis-radio-group--horizontal', className), children: [label && (0, jsx_runtime_1.jsx)("span", { id: groupId, className: "tokis-label", style: { marginBottom: 'var(--tokis-spacing-1)' }, children: label }), children] }) }));
60
43
  }
@@ -21,6 +21,9 @@ export type BadgeVariant = 'default' | 'primary' | 'success' | 'warning' | 'erro
21
21
  export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
22
22
  variant?: BadgeVariant;
23
23
  dot?: boolean;
24
+ /** Text alternative for screen readers when using the dot indicator.
25
+ * Required for WCAG 1.1.1 compliance when `dot={true}` conveys status information. */
26
+ dotLabel?: string;
24
27
  }
25
28
  export declare const Badge: React.ForwardRefExoticComponent<BadgeProps & React.RefAttributes<HTMLSpanElement>>;
26
29
  export interface ChipProps extends React.HTMLAttributes<HTMLDivElement> {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/avatar/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAI1C,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC1D,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE9C,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD,eAAO,MAAM,MAAM,oFASjB,CAAC;AAGH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAW,EAAE,SAAS,EAAE,EAAE,gBAAgB,2CAetF;AAGD,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAExG,MAAM,WAAW,UAAW,SAAQ,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC;IACvE,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,eAAO,MAAM,KAAK,oFAQhB,CAAC;AAIH,MAAM,WAAW,SAAU,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB;AAED,eAAO,MAAM,IAAI,kFA6Bf,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/avatar/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAI1C,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC1D,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE9C,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD,eAAO,MAAM,MAAM,oFASjB,CAAC;AAGH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAW,EAAE,SAAS,EAAE,EAAE,gBAAgB,2CAetF;AAGD,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAExG,MAAM,WAAW,UAAW,SAAQ,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC;IACvE,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;2FACuF;IACvF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,KAAK,oFAShB,CAAC;AAIH,MAAM,WAAW,SAAU,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB;AAED,eAAO,MAAM,IAAI,kFA6Bf,CAAC"}
@@ -12,7 +12,7 @@ export function AvatarGroup({ children, max, size = 'md', className }) {
12
12
  const overflow = max && items.length > max ? items.length - max : 0;
13
13
  return (_jsxs("div", { className: cn('tokis-avatar-group', className), children: [visible, overflow > 0 && (_jsxs("div", { className: cn('tokis-avatar', `tokis-avatar--${size}`), "aria-label": `${overflow} more`, children: ["+", overflow] }))] }));
14
14
  }
15
- export const Badge = forwardRef(({ variant = 'default', dot = false, className, children, ...props }, ref) => (_jsx("span", { ref: ref, className: cn('tokis-badge', `tokis-badge--${variant}`, dot && 'tokis-badge--dot', className), ...props, children: children })));
15
+ export const Badge = forwardRef(({ variant = 'default', dot = false, dotLabel, className, children, ...props }, ref) => (_jsxs("span", { ref: ref, className: cn('tokis-badge', `tokis-badge--${variant}`, dot && 'tokis-badge--dot', className), ...props, children: [dot && dotLabel && _jsx("span", { className: "tokis-sr-only", children: dotLabel }), children] })));
16
16
  Badge.displayName = 'Badge';
17
17
  export const Chip = forwardRef(({ selected = false, onDelete, disabled = false, icon, className, children, onClick, ...props }, ref) => (_jsxs("div", { ref: ref, role: onClick ? 'button' : undefined, tabIndex: onClick && !disabled ? 0 : undefined, "aria-pressed": onClick ? selected : undefined, "aria-disabled": disabled || undefined, className: cn('tokis-chip', onClick && 'tokis-chip--clickable', selected && 'tokis-chip--selected', className), onClick: !disabled ? onClick : undefined, onKeyDown: onClick && !disabled ? (e) => { if (e.key === 'Enter' || e.key === ' ') {
18
18
  e.preventDefault();
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/avatar/index.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/avatar/index.tsx"],"names":[],"mappings":"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"}
@@ -1,9 +1,12 @@
1
1
  import React from 'react';
2
- export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
2
+ export interface CardProps extends React.HTMLAttributes<HTMLElement> {
3
3
  variant?: 'default' | 'elevated' | 'ghost';
4
4
  clickable?: boolean;
5
+ /** Override the rendered element. Defaults to `article` for non-clickable cards
6
+ * (semantic grouping for screen readers) and `div` for clickable cards. */
7
+ as?: React.ElementType;
5
8
  }
6
- export declare const Card: React.ForwardRefExoticComponent<CardProps & React.RefAttributes<HTMLDivElement>>;
9
+ export declare const Card: React.ForwardRefExoticComponent<CardProps & React.RefAttributes<HTMLElement>>;
7
10
  export declare const CardHeader: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
8
11
  export declare const CardBody: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
9
12
  export declare const CardFooter: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/card/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAI1C,MAAM,WAAW,SAAU,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACrE,OAAO,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;IAC3C,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AACD,eAAO,MAAM,IAAI,kFAQf,CAAC;AAGH,eAAO,MAAM,UAAU,6GAErB,CAAC;AAGH,eAAO,MAAM,QAAQ,6GAEnB,CAAC;AAGH,eAAO,MAAM,UAAU,6GAErB,CAAC;AAGH,eAAO,MAAM,SAAS,qHAEpB,CAAC;AAGH,eAAO,MAAM,eAAe,yHAE1B,CAAC;AAIH,MAAM,WAAW,YAAa,SAAQ,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC;IACrE,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB;AACD,eAAO,MAAM,OAAO,oFAiBlB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/card/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAI1C,MAAM,WAAW,SAAU,SAAQ,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC;IAClE,OAAO,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;IAC3C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;gFAC4E;IAC5E,EAAE,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC;CACxB;AACD,eAAO,MAAM,IAAI,+EAWf,CAAC;AAGH,eAAO,MAAM,UAAU,6GAErB,CAAC;AAGH,eAAO,MAAM,QAAQ,6GAEnB,CAAC;AAGH,eAAO,MAAM,UAAU,6GAErB,CAAC;AAGH,eAAO,MAAM,SAAS,qHAEpB,CAAC;AAGH,eAAO,MAAM,eAAe,yHAE1B,CAAC;AAIH,MAAM,WAAW,YAAa,SAAQ,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC;IACrE,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB;AACD,eAAO,MAAM,OAAO,oFAiBlB,CAAC"}