mac-human-design 0.1.19 → 0.1.21
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,34 @@
|
|
|
2
2
|
|
|
3
3
|
This file tracks changes between published npm versions of `mac-human-design`.
|
|
4
4
|
|
|
5
|
+
## 0.1.21
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added macOS gallery coverage for loading and disabled `SymbolIconButton`
|
|
10
|
+
states plus info, success, and error `StatusMessage` states.
|
|
11
|
+
- Extended the macOS design verifier to require those icon and status states in
|
|
12
|
+
gallery builds.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Added compact gallery status-stack styling for grouped status message
|
|
17
|
+
previews.
|
|
18
|
+
- Bumped the package to `0.1.21`.
|
|
19
|
+
|
|
20
|
+
## 0.1.20
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- Added automated macOS design verifier coverage for icon-button alignment
|
|
25
|
+
invariants, including fixed icon button dimensions, grid centering,
|
|
26
|
+
symbol glyph centering, non-positional icon-button Motion feedback,
|
|
27
|
+
`SymbolIconButton` structure, and SF Symbol PNG normalization.
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- Bumped the package to `0.1.20`.
|
|
32
|
+
|
|
5
33
|
## 0.1.19
|
|
6
34
|
|
|
7
35
|
### Fixed
|
package/package.json
CHANGED
|
@@ -6,6 +6,9 @@ const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."
|
|
|
6
6
|
const stylesPath = path.join(repoRoot, "src", "styles", "macosBaseUi.css");
|
|
7
7
|
const packageJsonPath = path.join(repoRoot, "package.json");
|
|
8
8
|
const wrapperPath = path.join(repoRoot, "src", "components", "MacBaseUI.tsx");
|
|
9
|
+
const symbolIconButtonPath = path.join(repoRoot, "src", "components", "SymbolIconButton.tsx");
|
|
10
|
+
const galleryPath = path.join(repoRoot, "src", "components", "MacBaseUIGallery.tsx");
|
|
11
|
+
const symbolServicePath = path.join(repoRoot, "src", "symbols", "systemSymbolService.ts");
|
|
9
12
|
|
|
10
13
|
function readText(filePath) {
|
|
11
14
|
return fs.readFileSync(filePath, "utf8");
|
|
@@ -43,6 +46,29 @@ const sources = new Map(
|
|
|
43
46
|
const stylesSource = readText(stylesPath);
|
|
44
47
|
const packageJson = JSON.parse(readText(packageJsonPath));
|
|
45
48
|
const wrapperSource = readText(wrapperPath);
|
|
49
|
+
const symbolIconButtonSource = readText(symbolIconButtonPath);
|
|
50
|
+
const gallerySource = readText(galleryPath);
|
|
51
|
+
const symbolServiceSource = readText(symbolServicePath);
|
|
52
|
+
|
|
53
|
+
function getCssRuleBody(selector) {
|
|
54
|
+
const escapedSelector = selector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
55
|
+
const rulePattern = new RegExp(`(?:^|\\n)${escapedSelector}\\s*\\{([\\s\\S]*?)\\}`, "g");
|
|
56
|
+
for (const match of stylesSource.matchAll(rulePattern)) {
|
|
57
|
+
const prefix = stylesSource.slice(0, match.index).trimEnd();
|
|
58
|
+
if (!prefix.endsWith(",")) {
|
|
59
|
+
return match[1];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return "";
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function requireCssDeclarations(selector, declarations) {
|
|
66
|
+
const body = getCssRuleBody(selector);
|
|
67
|
+
const missingDeclarations = declarations.filter(([label, pattern]) => !pattern.test(body));
|
|
68
|
+
if (missingDeclarations.length > 0) {
|
|
69
|
+
fail(`Missing required CSS declarations for ${selector}.`, missingDeclarations.map(([label]) => label));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
46
72
|
|
|
47
73
|
const requiredStyleFeatures = [
|
|
48
74
|
["system font stack", /-apple-system,\s*BlinkMacSystemFont/],
|
|
@@ -98,6 +124,108 @@ if (motionCreateMatches.length !== 1 || !allowedMotionCreatePattern.test(wrapper
|
|
|
98
124
|
]);
|
|
99
125
|
}
|
|
100
126
|
|
|
127
|
+
requireCssDeclarations(".hd-mac-icon-button", [
|
|
128
|
+
["fixed 28px width", /width\s*:\s*28px\s*;/],
|
|
129
|
+
["fixed 28px height", /height\s*:\s*28px\s*;/],
|
|
130
|
+
["fixed 28px min-width", /min-width\s*:\s*28px\s*;/],
|
|
131
|
+
["fixed 28px min-height", /min-height\s*:\s*28px\s*;/],
|
|
132
|
+
]);
|
|
133
|
+
|
|
134
|
+
requireCssDeclarations(".hd-mac-symbol-icon-button", [
|
|
135
|
+
["fixed 30px width", /width\s*:\s*30px\s*;/],
|
|
136
|
+
["fixed 30px height", /height\s*:\s*30px\s*;/],
|
|
137
|
+
["fixed 30px min-width", /min-width\s*:\s*30px\s*;/],
|
|
138
|
+
["fixed 30px min-height", /min-height\s*:\s*30px\s*;/],
|
|
139
|
+
]);
|
|
140
|
+
|
|
141
|
+
requireCssDeclarations(".hd-mac-symbol-icon", [
|
|
142
|
+
["single grid cell placement", /grid-area\s*:\s*1\s*\/\s*1\s*;/],
|
|
143
|
+
["flex centering display", /display\s*:\s*inline-flex\s*;/],
|
|
144
|
+
["vertical glyph centering", /align-items\s*:\s*center\s*;/],
|
|
145
|
+
["horizontal glyph centering", /justify-content\s*:\s*center\s*;/],
|
|
146
|
+
["automatic optical centering margin", /margin\s*:\s*auto\s*;/],
|
|
147
|
+
["center transform origin", /transform-origin\s*:\s*center\s*;/],
|
|
148
|
+
]);
|
|
149
|
+
|
|
150
|
+
const sharedIconButtonRule = stylesSource.match(
|
|
151
|
+
/\.hd-mac-icon-button,\s*\n\.hd-mac-symbol-icon-button\s*\{([\s\S]*?)\}/,
|
|
152
|
+
)?.[1] ?? "";
|
|
153
|
+
const missingSharedIconButtonDeclarations = [
|
|
154
|
+
["grid icon-button layout", /display\s*:\s*inline-grid\s*;/],
|
|
155
|
+
["grid item centering", /place-items\s*:\s*center\s*;/],
|
|
156
|
+
["grid content centering", /place-content\s*:\s*center\s*;/],
|
|
157
|
+
["zero padding", /padding\s*:\s*0\s*;/],
|
|
158
|
+
["zero line-height", /line-height\s*:\s*0\s*;/],
|
|
159
|
+
["center transform origin", /transform-origin\s*:\s*center\s*;/],
|
|
160
|
+
["middle inline alignment", /vertical-align\s*:\s*middle\s*;/],
|
|
161
|
+
].filter(([, pattern]) => !pattern.test(sharedIconButtonRule));
|
|
162
|
+
|
|
163
|
+
if (missingSharedIconButtonDeclarations.length > 0) {
|
|
164
|
+
fail(
|
|
165
|
+
"Missing required shared icon-button centering declarations.",
|
|
166
|
+
missingSharedIconButtonDeclarations.map(([label]) => label),
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const iconMotionBranch = wrapperSource.match(
|
|
171
|
+
/if\s*\(\s*includesAny\(macClassName,\s*\[\s*"hd-mac-icon-button",\s*"hd-mac-help-button"\s*\]\)\s*\)\s*\{([\s\S]*?)\n\s*\}/,
|
|
172
|
+
)?.[1] ?? "";
|
|
173
|
+
if (!/whileHover\s*:\s*\{\s*scale\s*:\s*1\.04\s*\}/.test(iconMotionBranch)) {
|
|
174
|
+
fail("Icon-only controls must use center-origin scale hover feedback.", ["src/components/MacBaseUI.tsx"]);
|
|
175
|
+
}
|
|
176
|
+
if (!/whileTap\s*:\s*\{\s*scale\s*:\s*0\.94\s*\}/.test(iconMotionBranch)) {
|
|
177
|
+
fail("Icon-only controls must use center-origin scale press feedback.", ["src/components/MacBaseUI.tsx"]);
|
|
178
|
+
}
|
|
179
|
+
if (/\by\s*:/.test(iconMotionBranch)) {
|
|
180
|
+
fail("Icon-only controls must not use vertical Motion offsets.", ["src/components/MacBaseUI.tsx"]);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const symbolIconRequirements = [
|
|
184
|
+
["SymbolIconButton imports MacIconButton", /import\s+\{\s*MacIconButton,\s*MacTooltip\s*\}\s+from\s+["']\.\/MacBaseUI["']/],
|
|
185
|
+
["SymbolIconButton render element is MacIconButton", /render=\{\s*<MacIconButton\b/],
|
|
186
|
+
["SymbolIconButton applies hd-mac-symbol-icon-button class", /className=["']hd-mac-symbol-icon-button["']/],
|
|
187
|
+
["masked symbol class path", /className=["']hd-mac-symbol-icon hd-mac-symbol-icon-mask["']/],
|
|
188
|
+
["fallback symbol class path", /className=["']hd-mac-symbol-icon hd-mac-symbol-icon-fallback["']/],
|
|
189
|
+
["mask centering", /maskPosition:\s*["']center["']/],
|
|
190
|
+
["webkit mask centering", /WebkitMaskPosition:\s*["']center["']/],
|
|
191
|
+
];
|
|
192
|
+
|
|
193
|
+
const missingSymbolIconRequirements = symbolIconRequirements
|
|
194
|
+
.filter(([, pattern]) => !pattern.test(symbolIconButtonSource))
|
|
195
|
+
.map(([label]) => label);
|
|
196
|
+
|
|
197
|
+
if (missingSymbolIconRequirements.length > 0) {
|
|
198
|
+
fail("Missing SymbolIconButton alignment invariants.", missingSymbolIconRequirements);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const missingGalleryStateCoverage = [
|
|
202
|
+
["loading symbol icon button", /<SymbolIconButton[\s\S]*?\bisLoading\b/],
|
|
203
|
+
["disabled symbol icon button", /<SymbolIconButton[\s\S]*?\bdisabled\b/],
|
|
204
|
+
["info status message", /<StatusMessage\s+intent=["']info["']/],
|
|
205
|
+
["success status message", /<StatusMessage\s+intent=["']success["']/],
|
|
206
|
+
["error status message", /<StatusMessage\s+intent=["']error["']/],
|
|
207
|
+
].filter(([, pattern]) => !pattern.test(gallerySource));
|
|
208
|
+
|
|
209
|
+
if (missingGalleryStateCoverage.length > 0) {
|
|
210
|
+
fail(
|
|
211
|
+
"Missing macOS gallery coverage for critical icon and status states.",
|
|
212
|
+
missingGalleryStateCoverage.map(([label]) => label),
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const missingSymbolServiceRequirements = [
|
|
217
|
+
["transparent symbol padding trim", /trimTransparentSymbolPadding/],
|
|
218
|
+
["alpha threshold trim", /TRANSPARENT_ALPHA_THRESHOLD/],
|
|
219
|
+
["canvas crop path", /trimmedCanvas\.toDataURL\(["']image\/png["']\)/],
|
|
220
|
+
].filter(([, pattern]) => !pattern.test(symbolServiceSource));
|
|
221
|
+
|
|
222
|
+
if (missingSymbolServiceRequirements.length > 0) {
|
|
223
|
+
fail(
|
|
224
|
+
"Missing system symbol image normalization invariants.",
|
|
225
|
+
missingSymbolServiceRequirements.map(([label]) => label),
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
|
|
101
229
|
const negativeLetterSpacing = [];
|
|
102
230
|
const viewportScaledFonts = [];
|
|
103
231
|
|
|
@@ -142,5 +270,5 @@ if (process.exitCode) {
|
|
|
142
270
|
}
|
|
143
271
|
|
|
144
272
|
console.log(
|
|
145
|
-
`Verified macOS design features, typography constraints, and ${hdMacClasses.size} styled hd-mac classes.`,
|
|
273
|
+
`Verified macOS design features, icon-button alignment invariants, typography constraints, and ${hdMacClasses.size} styled hd-mac classes.`,
|
|
146
274
|
);
|
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
import { MacDataTable } from "./MacDataTable";
|
|
57
57
|
import { MacSegmentedControl } from "./MacSegmentedControl";
|
|
58
58
|
import { MacWindowToolbar } from "./MacWindowToolbar";
|
|
59
|
+
import { StatusMessage } from "./StatusMessage";
|
|
59
60
|
import { SymbolIconButton } from "./SymbolIconButton";
|
|
60
61
|
|
|
61
62
|
const choices = [
|
|
@@ -97,6 +98,8 @@ export function MacBaseUIGallery() {
|
|
|
97
98
|
<SymbolIconButton label="Refresh" symbolName="arrow.clockwise" fallback="↻" onClick={() => {}} />
|
|
98
99
|
<SymbolIconButton label="Upload" symbolName="square.and.arrow.up" fallback="↑" onClick={() => {}} />
|
|
99
100
|
<SymbolIconButton label="Fallback refresh" symbolName="arrow.clockwise" fallback="↻" onClick={() => {}} symbolEnabled={false} />
|
|
101
|
+
<SymbolIconButton label="Loading refresh" symbolName="arrow.clockwise" fallback="↻" onClick={() => {}} isLoading />
|
|
102
|
+
<SymbolIconButton label="Disabled upload" symbolName="square.and.arrow.up" fallback="↑" onClick={() => {}} disabled />
|
|
100
103
|
<MacHelpButton aria-label="Help">?</MacHelpButton>
|
|
101
104
|
</GallerySection>
|
|
102
105
|
|
|
@@ -366,6 +369,7 @@ export function MacBaseUIGallery() {
|
|
|
366
369
|
<MacButton disabled>Disabled</MacButton>
|
|
367
370
|
<MacPrimaryButton disabled>Disabled Primary</MacPrimaryButton>
|
|
368
371
|
<MacInput disabled placeholder="Disabled text field" />
|
|
372
|
+
<SymbolIconButton label="Disabled refresh" symbolName="arrow.clockwise" fallback="↻" onClick={() => {}} disabled />
|
|
369
373
|
<label className="hd-mac-gallery-inline-choice">
|
|
370
374
|
<MacCheckbox.Root indeterminate>
|
|
371
375
|
<MacCheckbox.Indicator />
|
|
@@ -378,6 +382,11 @@ export function MacBaseUIGallery() {
|
|
|
378
382
|
</GallerySection>
|
|
379
383
|
|
|
380
384
|
<GallerySection title="Feedback">
|
|
385
|
+
<div className="hd-mac-gallery-status-stack">
|
|
386
|
+
<StatusMessage intent="info" message="Connected to the selected bucket." />
|
|
387
|
+
<StatusMessage intent="success" message="Upload completed." />
|
|
388
|
+
<StatusMessage intent="error" message="Unable to fetch object metadata." />
|
|
389
|
+
</div>
|
|
381
390
|
<MacProgress.Root value={62}>
|
|
382
391
|
<MacProgress.Label>Progress</MacProgress.Label>
|
|
383
392
|
<MacProgress.Track>
|
|
@@ -1544,6 +1544,16 @@
|
|
|
1544
1544
|
font: 400 13px/18px var(--hd-mac-font);
|
|
1545
1545
|
}
|
|
1546
1546
|
|
|
1547
|
+
.hd-mac-gallery-status-stack {
|
|
1548
|
+
display: grid;
|
|
1549
|
+
min-width: min(340px, 100%);
|
|
1550
|
+
gap: 6px;
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
.hd-mac-gallery-status-stack > .hd-mac-status-message {
|
|
1554
|
+
margin-top: 0;
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1547
1557
|
.hd-mac-gallery-scroll {
|
|
1548
1558
|
width: 190px;
|
|
1549
1559
|
height: 48px;
|