mac-human-design 0.1.22 → 0.1.24
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/changelog.md
CHANGED
|
@@ -2,6 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
This file tracks changes between published npm versions of `mac-human-design`.
|
|
4
4
|
|
|
5
|
+
## 0.1.24
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added `role="toolbar"`, optional accessible labels, labelled control groups,
|
|
10
|
+
and title accessibility handling to `MacWindowToolbar`.
|
|
11
|
+
- Added gallery coverage for an explicitly labelled `MacWindowToolbar`.
|
|
12
|
+
- Extended the macOS design verifier to protect toolbar accessibility and
|
|
13
|
+
Tauri drag-region invariants.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- `MacWindowToolbar` now gives leading, content, and trailing control groups
|
|
18
|
+
stable accessible labels while preserving no-drag regions around interactive
|
|
19
|
+
controls.
|
|
20
|
+
- Bumped the package to `0.1.24`.
|
|
21
|
+
|
|
22
|
+
## 0.1.23
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- Added `grid`/`table` semantics, row and column metadata, busy state, selected
|
|
27
|
+
row state, keyboard row activation, and optional accessible labels to
|
|
28
|
+
`MacDataTable`.
|
|
29
|
+
- Added focus-visible styling for interactive `MacDataTable` rows.
|
|
30
|
+
- Extended the macOS design verifier to protect interactive table/grid
|
|
31
|
+
accessibility invariants.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- Interactive table rows can now be selected with Space and opened/activated
|
|
36
|
+
with Enter when row handlers are provided.
|
|
37
|
+
- Bumped the package to `0.1.23`.
|
|
38
|
+
|
|
5
39
|
## 0.1.22
|
|
6
40
|
|
|
7
41
|
### Added
|
package/package.json
CHANGED
|
@@ -8,6 +8,8 @@ const packageJsonPath = path.join(repoRoot, "package.json");
|
|
|
8
8
|
const wrapperPath = path.join(repoRoot, "src", "components", "MacBaseUI.tsx");
|
|
9
9
|
const symbolIconButtonPath = path.join(repoRoot, "src", "components", "SymbolIconButton.tsx");
|
|
10
10
|
const galleryPath = path.join(repoRoot, "src", "components", "MacBaseUIGallery.tsx");
|
|
11
|
+
const dataTablePath = path.join(repoRoot, "src", "components", "MacDataTable.tsx");
|
|
12
|
+
const windowToolbarPath = path.join(repoRoot, "src", "components", "MacWindowToolbar.tsx");
|
|
11
13
|
const symbolServicePath = path.join(repoRoot, "src", "symbols", "systemSymbolService.ts");
|
|
12
14
|
|
|
13
15
|
function readText(filePath) {
|
|
@@ -48,6 +50,8 @@ const packageJson = JSON.parse(readText(packageJsonPath));
|
|
|
48
50
|
const wrapperSource = readText(wrapperPath);
|
|
49
51
|
const symbolIconButtonSource = readText(symbolIconButtonPath);
|
|
50
52
|
const gallerySource = readText(galleryPath);
|
|
53
|
+
const dataTableSource = readText(dataTablePath);
|
|
54
|
+
const windowToolbarSource = readText(windowToolbarPath);
|
|
51
55
|
const symbolServiceSource = readText(symbolServicePath);
|
|
52
56
|
|
|
53
57
|
function getCssRuleBody(selector) {
|
|
@@ -249,6 +253,51 @@ if (
|
|
|
249
253
|
]);
|
|
250
254
|
}
|
|
251
255
|
|
|
256
|
+
const missingDataTableRequirements = [
|
|
257
|
+
["interactive grid role", /const tableRole = hasInteractiveRows \? "grid" : "table"/],
|
|
258
|
+
["aria busy state", /aria-busy=\{loading \|\| undefined\}/],
|
|
259
|
+
["row count metadata", /aria-rowcount=\{loading \? undefined : rows\.length \+ 1\}/],
|
|
260
|
+
["column count metadata", /aria-colcount=\{columns\.length\}/],
|
|
261
|
+
["header row index", /aria-rowindex=\{1\}/],
|
|
262
|
+
["cell column index", /aria-colindex=\{columnIndex \+ 1\}/],
|
|
263
|
+
["interactive row selected state", /aria-selected=\{hasInteractiveRows \? selected : undefined\}/],
|
|
264
|
+
["interactive row tab stop", /tabIndex=\{hasInteractiveRows \? 0 : undefined\}/],
|
|
265
|
+
["keyboard row handler", /handleRowKeyDown/],
|
|
266
|
+
["enter key activation", /event\.key === "Enter"/],
|
|
267
|
+
["space key activation", /event\.key === " "/],
|
|
268
|
+
].filter(([, pattern]) => !pattern.test(dataTableSource));
|
|
269
|
+
|
|
270
|
+
if (missingDataTableRequirements.length > 0) {
|
|
271
|
+
fail(
|
|
272
|
+
"Missing MacDataTable interactive grid accessibility invariants.",
|
|
273
|
+
missingDataTableRequirements.map(([label]) => label),
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
requireCssDeclarations(".hd-mac-data-table-row-interactive:focus-visible", [
|
|
278
|
+
["focus outline reset", /outline\s*:\s*none\s*;/],
|
|
279
|
+
["focus ring", /var\(--hd-mac-focus-ring\)/],
|
|
280
|
+
]);
|
|
281
|
+
|
|
282
|
+
const missingToolbarRequirements = [
|
|
283
|
+
["toolbar role", /role=["']toolbar["']/],
|
|
284
|
+
["optional aria label", /aria-label=\{ariaLabel\}/],
|
|
285
|
+
["optional aria labelledby", /aria-labelledby=\{ariaLabelledBy\}/],
|
|
286
|
+
["leading group role", /role=["']group["'][\s\S]*?aria-label=\{leadingLabel\}/],
|
|
287
|
+
["children group role", /role=["']group["'][\s\S]*?aria-label=\{childrenLabel\}/],
|
|
288
|
+
["trailing group role", /role=["']group["'][\s\S]*?aria-label=\{trailingLabel\}/],
|
|
289
|
+
["drag region root", /data-tauri-drag-region/],
|
|
290
|
+
["interactive groups no-drag", /data-tauri-no-drag-region/],
|
|
291
|
+
["gallery toolbar accessible label", /<MacWindowToolbar[\s\S]*?ariaLabel=["']Library toolbar["']/],
|
|
292
|
+
].filter(([, pattern]) => !pattern.test(windowToolbarSource) && !pattern.test(gallerySource));
|
|
293
|
+
|
|
294
|
+
if (missingToolbarRequirements.length > 0) {
|
|
295
|
+
fail(
|
|
296
|
+
"Missing MacWindowToolbar accessibility and drag-region invariants.",
|
|
297
|
+
missingToolbarRequirements.map(([label]) => label),
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
|
|
252
301
|
const missingSymbolServiceRequirements = [
|
|
253
302
|
["transparent symbol padding trim", /trimTransparentSymbolPadding/],
|
|
254
303
|
["alpha threshold trim", /TRANSPARENT_ALPHA_THRESHOLD/],
|
|
@@ -416,6 +416,7 @@ export function MacBaseUIGallery() {
|
|
|
416
416
|
<MacAvatar.Fallback>HD</MacAvatar.Fallback>
|
|
417
417
|
</MacAvatar.Root>
|
|
418
418
|
<MacWindowToolbar
|
|
419
|
+
ariaLabel="Library toolbar"
|
|
419
420
|
leading={<MacSegmentedControl options={choices} value={segment} onChange={setSegment} />}
|
|
420
421
|
title="Library"
|
|
421
422
|
trailing={<MacIconButton aria-label="Refresh">↻</MacIconButton>}
|
|
@@ -17,6 +17,8 @@ export type MacDataTableProps<Row> = {
|
|
|
17
17
|
columns: readonly MacDataTableColumn<Row>[];
|
|
18
18
|
rows: readonly Row[];
|
|
19
19
|
getRowKey: (row: Row, index: number) => React.Key;
|
|
20
|
+
ariaLabel?: string;
|
|
21
|
+
ariaLabelledBy?: string;
|
|
20
22
|
isRowSelected?: (row: Row, index: number) => boolean;
|
|
21
23
|
onRowClick?: (row: Row, index: number) => void;
|
|
22
24
|
onRowDoubleClick?: (row: Row, index: number) => void;
|
|
@@ -53,6 +55,8 @@ export function MacDataTable<Row>({
|
|
|
53
55
|
columns,
|
|
54
56
|
rows,
|
|
55
57
|
getRowKey,
|
|
58
|
+
ariaLabel,
|
|
59
|
+
ariaLabelledBy,
|
|
56
60
|
isRowSelected,
|
|
57
61
|
onRowClick,
|
|
58
62
|
onRowDoubleClick,
|
|
@@ -67,6 +71,30 @@ export function MacDataTable<Row>({
|
|
|
67
71
|
}: MacDataTableProps<Row>) {
|
|
68
72
|
const gridTemplateColumns = columns.map((column) => column.width).join(" ");
|
|
69
73
|
const hasInteractiveRows = Boolean(onRowClick || onRowDoubleClick);
|
|
74
|
+
const tableRole = hasInteractiveRows ? "grid" : "table";
|
|
75
|
+
|
|
76
|
+
const handleRowKeyDown = React.useCallback(
|
|
77
|
+
(event: React.KeyboardEvent, row: Row, index: number) => {
|
|
78
|
+
if (!hasInteractiveRows) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (event.key === "Enter") {
|
|
83
|
+
event.preventDefault();
|
|
84
|
+
if (onRowDoubleClick) {
|
|
85
|
+
onRowDoubleClick(row, index);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
onRowClick?.(row, index);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (event.key === " ") {
|
|
92
|
+
event.preventDefault();
|
|
93
|
+
onRowClick?.(row, index);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
[hasInteractiveRows, onRowClick, onRowDoubleClick],
|
|
97
|
+
);
|
|
70
98
|
|
|
71
99
|
return (
|
|
72
100
|
<motion.div
|
|
@@ -74,12 +102,19 @@ export function MacDataTable<Row>({
|
|
|
74
102
|
animate={{ opacity: 1 }}
|
|
75
103
|
transition={tableTransition}
|
|
76
104
|
className={joinClasses("hd-mac-data-table", bordered && "hd-mac-data-table-bordered", className)}
|
|
105
|
+
role={tableRole}
|
|
106
|
+
aria-label={ariaLabel}
|
|
107
|
+
aria-labelledby={ariaLabelledBy}
|
|
108
|
+
aria-busy={loading || undefined}
|
|
109
|
+
aria-rowcount={loading ? undefined : rows.length + 1}
|
|
110
|
+
aria-colcount={columns.length}
|
|
77
111
|
style={style}
|
|
78
112
|
>
|
|
79
113
|
<motion.div
|
|
80
114
|
layout
|
|
81
115
|
className="hd-mac-data-table-header"
|
|
82
116
|
role="row"
|
|
117
|
+
aria-rowindex={1}
|
|
83
118
|
style={{ gridTemplateColumns }}
|
|
84
119
|
transition={tableTransition}
|
|
85
120
|
>
|
|
@@ -92,6 +127,7 @@ export function MacDataTable<Row>({
|
|
|
92
127
|
column.headerClassName,
|
|
93
128
|
)}
|
|
94
129
|
role="columnheader"
|
|
130
|
+
aria-colindex={columns.indexOf(column) + 1}
|
|
95
131
|
style={column.headerStyle}
|
|
96
132
|
>
|
|
97
133
|
{column.header}
|
|
@@ -139,10 +175,14 @@ export function MacDataTable<Row>({
|
|
|
139
175
|
data-selected={selected || undefined}
|
|
140
176
|
onClick={onRowClick ? () => onRowClick(row, index) : undefined}
|
|
141
177
|
onDoubleClick={onRowDoubleClick ? () => onRowDoubleClick(row, index) : undefined}
|
|
178
|
+
onKeyDown={hasInteractiveRows ? (event) => handleRowKeyDown(event, row, index) : undefined}
|
|
142
179
|
role="row"
|
|
180
|
+
aria-rowindex={index + 2}
|
|
181
|
+
aria-selected={hasInteractiveRows ? selected : undefined}
|
|
182
|
+
tabIndex={hasInteractiveRows ? 0 : undefined}
|
|
143
183
|
style={{ gridTemplateColumns, ...rowStyle?.(row, index) }}
|
|
144
184
|
>
|
|
145
|
-
{columns.map((column) => (
|
|
185
|
+
{columns.map((column, columnIndex) => (
|
|
146
186
|
<div
|
|
147
187
|
key={column.id}
|
|
148
188
|
className={joinClasses(
|
|
@@ -151,6 +191,7 @@ export function MacDataTable<Row>({
|
|
|
151
191
|
column.className,
|
|
152
192
|
)}
|
|
153
193
|
role="cell"
|
|
194
|
+
aria-colindex={columnIndex + 1}
|
|
154
195
|
style={column.style}
|
|
155
196
|
>
|
|
156
197
|
{column.render(row, index)}
|
|
@@ -3,9 +3,14 @@ import { motion, type Transition } from "motion/react";
|
|
|
3
3
|
|
|
4
4
|
export type MacWindowToolbarProps = {
|
|
5
5
|
leading?: React.ReactNode;
|
|
6
|
+
leadingLabel?: string;
|
|
6
7
|
title?: React.ReactNode;
|
|
7
8
|
trailing?: React.ReactNode;
|
|
9
|
+
trailingLabel?: string;
|
|
8
10
|
children?: React.ReactNode;
|
|
11
|
+
childrenLabel?: string;
|
|
12
|
+
ariaLabel?: string;
|
|
13
|
+
ariaLabelledBy?: string;
|
|
9
14
|
className?: string;
|
|
10
15
|
style?: React.CSSProperties;
|
|
11
16
|
};
|
|
@@ -21,9 +26,14 @@ const toolbarTransition: Transition = {
|
|
|
21
26
|
|
|
22
27
|
export function MacWindowToolbar({
|
|
23
28
|
leading,
|
|
29
|
+
leadingLabel = "Primary toolbar controls",
|
|
24
30
|
title,
|
|
25
31
|
trailing,
|
|
32
|
+
trailingLabel = "Secondary toolbar controls",
|
|
26
33
|
children,
|
|
34
|
+
childrenLabel = "Toolbar controls",
|
|
35
|
+
ariaLabel,
|
|
36
|
+
ariaLabelledBy,
|
|
27
37
|
className,
|
|
28
38
|
style,
|
|
29
39
|
}: MacWindowToolbarProps) {
|
|
@@ -33,6 +43,9 @@ export function MacWindowToolbar({
|
|
|
33
43
|
animate={{ opacity: 1, y: 0 }}
|
|
34
44
|
transition={toolbarTransition}
|
|
35
45
|
className={joinClasses("hd-mac-window-toolbar", className)}
|
|
46
|
+
role="toolbar"
|
|
47
|
+
aria-label={ariaLabel}
|
|
48
|
+
aria-labelledby={ariaLabelledBy}
|
|
36
49
|
data-tauri-drag-region
|
|
37
50
|
style={style}
|
|
38
51
|
>
|
|
@@ -40,6 +53,8 @@ export function MacWindowToolbar({
|
|
|
40
53
|
<motion.div
|
|
41
54
|
layout
|
|
42
55
|
className="hd-mac-window-toolbar-group"
|
|
56
|
+
role="group"
|
|
57
|
+
aria-label={leadingLabel}
|
|
43
58
|
data-tauri-no-drag-region
|
|
44
59
|
transition={toolbarTransition}
|
|
45
60
|
>
|
|
@@ -50,6 +65,7 @@ export function MacWindowToolbar({
|
|
|
50
65
|
<motion.div
|
|
51
66
|
layout
|
|
52
67
|
className="hd-mac-window-toolbar-title"
|
|
68
|
+
aria-hidden={typeof title === "string" ? undefined : true}
|
|
53
69
|
data-tauri-drag-region
|
|
54
70
|
transition={toolbarTransition}
|
|
55
71
|
>
|
|
@@ -60,6 +76,8 @@ export function MacWindowToolbar({
|
|
|
60
76
|
<motion.div
|
|
61
77
|
layout
|
|
62
78
|
className="hd-mac-window-toolbar-content"
|
|
79
|
+
role="group"
|
|
80
|
+
aria-label={childrenLabel}
|
|
63
81
|
data-tauri-no-drag-region
|
|
64
82
|
transition={toolbarTransition}
|
|
65
83
|
>
|
|
@@ -70,6 +88,8 @@ export function MacWindowToolbar({
|
|
|
70
88
|
<motion.div
|
|
71
89
|
layout
|
|
72
90
|
className="hd-mac-window-toolbar-group"
|
|
91
|
+
role="group"
|
|
92
|
+
aria-label={trailingLabel}
|
|
73
93
|
data-tauri-no-drag-region
|
|
74
94
|
transition={toolbarTransition}
|
|
75
95
|
>
|
|
@@ -1481,6 +1481,13 @@
|
|
|
1481
1481
|
cursor: default;
|
|
1482
1482
|
}
|
|
1483
1483
|
|
|
1484
|
+
.hd-mac-data-table-row-interactive:focus-visible {
|
|
1485
|
+
outline: none;
|
|
1486
|
+
box-shadow:
|
|
1487
|
+
var(--hd-mac-focus-ring),
|
|
1488
|
+
inset 0 0 0 1px color-mix(in srgb, var(--hd-mac-blue) 24%, transparent);
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1484
1491
|
.hd-mac-data-table-row-interactive:hover {
|
|
1485
1492
|
background: var(--hd-mac-fill-hover);
|
|
1486
1493
|
}
|
|
@@ -1494,6 +1501,12 @@
|
|
|
1494
1501
|
box-shadow: inset 3px 0 0 var(--hd-mac-blue);
|
|
1495
1502
|
}
|
|
1496
1503
|
|
|
1504
|
+
.hd-mac-data-table-row[data-selected]:focus-visible {
|
|
1505
|
+
box-shadow:
|
|
1506
|
+
var(--hd-mac-focus-ring),
|
|
1507
|
+
inset 3px 0 0 var(--hd-mac-blue);
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1497
1510
|
.hd-mac-data-table-row[data-selected]:hover {
|
|
1498
1511
|
background: color-mix(in srgb, var(--hd-mac-blue) 24%, transparent);
|
|
1499
1512
|
}
|