@tokis/react 1.2.1 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/avatar/index.js +1 -1
- package/dist/cjs/components/card/index.js +4 -1
- package/dist/cjs/components/charts/index.js +94 -13
- package/dist/cjs/components/datepicker/index.js +17 -2
- package/dist/cjs/components/drawer/index.js +4 -1
- package/dist/cjs/components/extended/index.js +1 -1
- package/dist/cjs/components/hover-card/index.js +3 -1
- package/dist/cjs/components/pagination/index.js +1 -1
- package/dist/cjs/components/popover/index.js +24 -1
- package/dist/cjs/components/radio/index.js +31 -48
- package/dist/components/avatar/index.d.ts +3 -0
- package/dist/components/avatar/index.d.ts.map +1 -1
- package/dist/components/avatar/index.js +1 -1
- package/dist/components/avatar/index.js.map +1 -1
- package/dist/components/card/index.d.ts +5 -2
- package/dist/components/card/index.d.ts.map +1 -1
- package/dist/components/card/index.js +4 -1
- package/dist/components/card/index.js.map +1 -1
- package/dist/components/charts/index.d.ts.map +1 -1
- package/dist/components/charts/index.js +94 -13
- package/dist/components/charts/index.js.map +1 -1
- package/dist/components/datepicker/index.d.ts.map +1 -1
- package/dist/components/datepicker/index.js +17 -2
- package/dist/components/datepicker/index.js.map +1 -1
- package/dist/components/drawer/index.d.ts.map +1 -1
- package/dist/components/drawer/index.js +5 -2
- package/dist/components/drawer/index.js.map +1 -1
- package/dist/components/extended/index.d.ts.map +1 -1
- package/dist/components/extended/index.js +1 -1
- package/dist/components/extended/index.js.map +1 -1
- package/dist/components/hover-card/index.d.ts.map +1 -1
- package/dist/components/hover-card/index.js +4 -2
- package/dist/components/hover-card/index.js.map +1 -1
- package/dist/components/pagination/index.d.ts.map +1 -1
- package/dist/components/pagination/index.js +1 -1
- package/dist/components/pagination/index.js.map +1 -1
- package/dist/components/popover/index.d.ts.map +1 -1
- package/dist/components/popover/index.js +24 -1
- package/dist/components/popover/index.js.map +1 -1
- package/dist/components/radio/index.d.ts +1 -1
- package/dist/components/radio/index.d.ts.map +1 -1
- package/dist/components/radio/index.js +31 -15
- package/dist/components/radio/index.js.map +1 -1
- package/package.json +11 -8
|
@@ -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.
|
|
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) =>
|
|
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":
|
|
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
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
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 +
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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 =
|
|
6
|
+
const react_1 = require("react");
|
|
40
7
|
const cn_js_1 = require("../../utils/cn");
|
|
41
|
-
|
|
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
|
-
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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;
|
|
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) => (
|
|
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":";AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAevC,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AAC7E,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAA8B,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,KAAK,GAAG,QAAQ,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CACnI,cACE,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,EAAE,CAAC,cAAc,EAAE,iBAAiB,IAAI,EAAE,EAAE,KAAK,KAAK,QAAQ,IAAI,sBAAsB,EAAE,SAAS,CAAC,gBACnG,IAAI,IAAI,GAAG,EACvB,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,YAE7B,GAAG,CAAC,CAAC,CAAC,cAAK,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,IAAI,IAAI,EAAE,GAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,GAC9E,CACP,CAAC,CAAC;AACH,MAAM,CAAC,WAAW,GAAG,QAAQ,CAAC;AAS9B,MAAM,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI,EAAE,SAAS,EAAoB;IACrF,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAClD,MAAM,QAAQ,GAAG,GAAG,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAEpE,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,oBAAoB,EAAE,SAAS,CAAC,aAChD,OAAO,EACP,QAAQ,GAAG,CAAC,IAAI,CACf,eAAK,SAAS,EAAE,EAAE,CAAC,cAAc,EAAE,iBAAiB,IAAI,EAAE,CAAC,gBAAc,GAAG,QAAQ,OAAO,kBACvF,QAAQ,IACN,CACP,IACG,CACP,CAAC;AACJ,CAAC;
|
|
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<
|
|
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<
|
|
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,
|
|
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"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef } from 'react';
|
|
3
3
|
import { cn } from '../../utils/cn.js';
|
|
4
|
-
export const Card = forwardRef(({ variant = 'default', clickable = false, className, children, ...props }, ref) =>
|
|
4
|
+
export const Card = forwardRef(({ variant = 'default', clickable = false, as: Tag, className, children, ...props }, ref) => {
|
|
5
|
+
const Component = Tag ?? (clickable ? 'div' : 'article');
|
|
6
|
+
return (_jsx(Component, { ref: ref, className: 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
|
+
});
|
|
5
8
|
Card.displayName = 'Card';
|
|
6
9
|
export const CardHeader = forwardRef(({ className, ...props }, ref) => (_jsx("div", { ref: ref, className: cn('tokis-card-header', className), ...props })));
|
|
7
10
|
CardHeader.displayName = 'CardHeader';
|