@motion-proto/live-tokens 0.96.0 → 0.98.2
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/.claude/skills/live-tokens-check-compliance/SKILL.md +5 -0
- package/.claude/skills/live-tokens-create-component/SKILL.md +4 -3
- package/.claude/skills/live-tokens-create-component/references/contract-tests.md +71 -11
- package/CHANGELOG.md +309 -0
- package/README.md +2 -2
- package/bin/check-component.mjs +8 -0
- package/bin/check-page.mjs +6 -0
- package/bin/cli.mjs +36 -6
- package/bin/contractRunner.mjs +142 -17
- package/bin/lib/findings.mjs +20 -4
- package/bin/rules/a11y.mjs +53 -0
- package/bin/set-colors.mjs +1 -0
- package/bin/setup-claude.mjs +2 -2
- package/dist-plugin/{chunk-A4TBP4MM.js → chunk-SLICH4IH.js} +2 -2
- package/dist-plugin/index.cjs +148 -3
- package/dist-plugin/index.js +250 -105
- package/dist-plugin/setColors/index.cjs +7 -1
- package/dist-plugin/setColors/index.d.cts +9 -4
- package/dist-plugin/setColors/index.d.ts +9 -4
- package/dist-plugin/setColors/index.js +8 -2
- package/dist-plugin/setGeometry/index.d.cts +1 -1
- package/dist-plugin/setGeometry/index.d.ts +1 -1
- package/dist-plugin/setType/index.d.cts +1 -1
- package/dist-plugin/setType/index.d.ts +1 -1
- package/dist-plugin/{themeTypes-B8_Idrp4.d.cts → themeTypes-BaTQUyac.d.cts} +10 -1
- package/dist-plugin/{themeTypes-B8_Idrp4.d.ts → themeTypes-BaTQUyac.d.ts} +10 -1
- package/package.json +49 -2
- package/src/demo/LabeledSelect.svelte +1 -1
- package/src/editor/bootstrap.ts +3 -1
- package/src/editor/component-editor/BadgeEditor.svelte +13 -0
- package/src/editor/component-editor/ButtonEditor.svelte +33 -2
- package/src/editor/component-editor/CalloutEditor.svelte +13 -0
- package/src/editor/component-editor/CardEditor.svelte +12 -2
- package/src/editor/component-editor/CodeSnippetEditor.svelte +11 -1
- package/src/editor/component-editor/CollapsibleSectionEditor.svelte +18 -1
- package/src/editor/component-editor/CornerBadgeEditor.svelte +13 -0
- package/src/editor/component-editor/DialogEditor.svelte +15 -0
- package/src/editor/component-editor/IconButtonEditor.svelte +29 -1
- package/src/editor/component-editor/ImageEditor.svelte +20 -9
- package/src/editor/component-editor/ImageLightboxEditor.svelte +44 -0
- package/src/editor/component-editor/InlineEditActionsEditor.svelte +13 -1
- package/src/editor/component-editor/InputEditor.svelte +23 -0
- package/src/editor/component-editor/MenuSelectEditor.svelte +27 -1
- package/src/editor/component-editor/NotificationEditor.svelte +15 -0
- package/src/editor/component-editor/PanelEditor.svelte +1 -1
- package/src/editor/component-editor/ProgressBarEditor.svelte +13 -0
- package/src/editor/component-editor/RadioButtonEditor.svelte +20 -1
- package/src/editor/component-editor/SectionDividerEditor.svelte +41 -13
- package/src/editor/component-editor/SegmentedControlEditor.svelte +29 -1
- package/src/editor/component-editor/SideNavigationEditor.svelte +40 -1
- package/src/editor/component-editor/SlidePagerEditor.svelte +20 -0
- package/src/editor/component-editor/SliderEditor.svelte +33 -0
- package/src/editor/component-editor/TabBarEditor.svelte +23 -2
- package/src/editor/component-editor/TableEditor.svelte +14 -0
- package/src/editor/component-editor/ToggleEditor.svelte +17 -0
- package/src/editor/component-editor/TooltipEditor.svelte +11 -2
- package/src/editor/component-editor/VideoFrameEditor.svelte +8 -0
- package/src/editor/component-editor/VideoLightboxEditor.svelte +10 -0
- package/src/editor/component-editor/registration.ts +2 -1
- package/src/editor/component-editor/registry.ts +69 -27
- package/src/editor/component-editor/scaffolding/DemoHeader.svelte +2 -0
- package/src/editor/component-editor/scaffolding/StateBlock.svelte +19 -8
- package/src/editor/component-editor/scaffolding/TokenLayout.svelte +3 -0
- package/src/editor/component-editor/scaffolding/VariantGroup.svelte +70 -10
- package/src/editor/component-editor/scaffolding/editorContext.ts +7 -0
- package/src/editor/core/a11y/a11yReport.ts +101 -0
- package/src/editor/core/a11y/a11yReportTypes.ts +69 -0
- package/src/editor/core/a11y/contrastFailures.ts +22 -0
- package/src/editor/core/components/contrastPairRegistry.ts +18 -0
- package/src/editor/core/palettes/contrast.ts +44 -0
- package/src/editor/core/palettes/contrastPairs.ts +79 -0
- package/src/editor/core/palettes/resolveColor.ts +77 -0
- package/src/editor/core/store/editorPersistence.ts +9 -1
- package/src/editor/core/store/editorRenderer.ts +2 -0
- package/src/editor/core/store/editorStore.ts +29 -0
- package/src/editor/core/store/editorTypes.ts +9 -0
- package/src/editor/core/store/editorViewStore.ts +2 -2
- package/src/editor/core/store/unsavedEdits.ts +10 -0
- package/src/editor/core/themes/buildColors.ts +16 -5
- package/src/editor/core/themes/liveStateStream.ts +7 -1
- package/src/editor/core/themes/parsers/gradient.ts +5 -2
- package/src/editor/core/themes/slices/customColors.ts +226 -0
- package/src/editor/core/themes/themeTypes.ts +10 -0
- package/src/editor/docs/chapters.ts +1 -0
- package/src/editor/docs/content/accessibility.md +362 -0
- package/src/editor/docs/content/editing-tokens.md +56 -1
- package/src/editor/docs/content.generated.ts +2 -1
- package/src/editor/pages/ComponentEditorPage.svelte +10 -1
- package/src/editor/pages/EditorShell.svelte +97 -10
- package/src/editor/skill-atlas/skillSources.generated.ts +3 -3
- package/src/editor/skill-atlas/trees/check-compliance.ts +3 -3
- package/src/editor/skill-atlas/trees/create-component.ts +12 -12
- package/src/editor/ui/CustomColorReplaceStep.svelte +118 -0
- package/src/editor/ui/EditorViewSwitcher.svelte +15 -2
- package/src/editor/ui/GradientEditor.svelte +9 -1
- package/src/editor/ui/ThemePanel.svelte +4 -4
- package/src/editor/ui/UIContrastReadout.svelte +186 -0
- package/src/editor/ui/UIInfoPopover.svelte +16 -2
- package/src/editor/ui/UIPaletteSelector.svelte +347 -15
- package/src/editor/ui/UITokenSelector.svelte +33 -14
- package/src/editor/ui/VariablesTab.svelte +3 -0
- package/src/editor/ui/a11y/A11yComponentIssues.svelte +103 -0
- package/src/editor/ui/a11y/A11yFindingRow.svelte +57 -0
- package/src/editor/ui/a11y/A11yIssueRow.svelte +121 -0
- package/src/editor/ui/a11y/A11yOverview.svelte +242 -0
- package/src/editor/ui/a11y/A11yPanel.svelte +128 -0
- package/src/editor/ui/a11y/A11yPropertyMark.svelte +84 -0
- package/src/editor/ui/a11y/A11yRailMark.svelte +34 -0
- package/src/editor/ui/a11y/AccessibilityTab.svelte +334 -0
- package/src/editor/ui/a11y/a11yView.ts +218 -0
- package/src/editor/ui/anchorToTrigger.ts +63 -0
- package/src/editor/ui/contrastReadout.ts +45 -0
- package/src/editor/ui/sections/CustomColorsSection.svelte +254 -0
- package/src/live-tokens/data/themes/autumn.json +20 -20
- package/src/live-tokens/data/themes/halloween.json +20 -20
- package/src/live-tokens/data/themes/midnight-study.json +20 -20
- package/src/live-tokens/data/themes/ocean.json +20 -20
- package/src/live-tokens/data/themes/royal-velvet.json +20 -20
- package/src/live-tokens/data/themes/sketchy.json +20 -20
- package/src/live-tokens/data/themes/spring-meadow.json +20 -20
- package/src/live-tokens/data/themes/sunset.json +20 -20
- package/src/system/components/Badge.svelte +3 -3
- package/src/system/components/Button.svelte +9 -3
- package/src/system/components/CodeSnippet.svelte +8 -1
- package/src/system/components/CornerBadge.svelte +3 -3
- package/src/system/components/Dialog.svelte +43 -14
- package/src/system/components/IconButton.svelte +1 -1
- package/src/system/components/Image.svelte +7 -0
- package/src/system/components/ImageLightbox.svelte +26 -26
- package/src/system/components/Input.svelte +8 -1
- package/src/system/components/MenuSelect.svelte +30 -2
- package/src/system/components/Notification.svelte +1 -1
- package/src/system/components/ProgressBar.svelte +6 -0
- package/src/system/components/RadioButton.svelte +36 -3
- package/src/system/components/SegmentedControl.svelte +36 -2
- package/src/system/components/SlidePager.svelte +2 -2
- package/src/system/components/Slider.svelte +13 -9
- package/src/system/components/TabBar.svelte +33 -3
- package/src/system/components/Toggle.svelte +2 -2
- package/src/system/components/VideoFrame.svelte +1 -1
- package/src/system/components/VideoLightbox.svelte +2 -2
- package/src/system/internal/focusTrap.ts +35 -0
- package/src/testing-js/__aria__/badge.yml +40 -0
- package/src/testing-js/__aria__/button.yml +88 -0
- package/src/testing-js/__aria__/callout.yml +12 -0
- package/src/testing-js/__aria__/card.yml +8 -0
- package/src/testing-js/__aria__/codesnippet.yml +21 -0
- package/src/testing-js/__aria__/collapsiblesection.yml +23 -0
- package/src/testing-js/__aria__/cornerbadge.yml +24 -0
- package/src/testing-js/__aria__/dialog.yml +42 -0
- package/src/testing-js/__aria__/iconbutton.yml +57 -0
- package/src/testing-js/__aria__/image.yml +10 -0
- package/src/testing-js/__aria__/imagelightbox.yml +50 -0
- package/src/testing-js/__aria__/inlineeditactions.yml +16 -0
- package/src/testing-js/__aria__/input.yml +61 -0
- package/src/testing-js/__aria__/menuselect.yml +30 -0
- package/src/testing-js/__aria__/notification.yml +30 -0
- package/src/testing-js/__aria__/panel.yml +2 -0
- package/src/testing-js/__aria__/progressbar.yml +2 -0
- package/src/testing-js/__aria__/radiobutton.yml +20 -0
- package/src/testing-js/__aria__/sectiondivider.yml +9 -0
- package/src/testing-js/__aria__/segmentedcontrol.yml +35 -0
- package/src/testing-js/__aria__/sidenavigation.yml +304 -0
- package/src/testing-js/__aria__/slidepager.yml +72 -0
- package/src/testing-js/__aria__/slider.yml +28 -0
- package/src/testing-js/__aria__/tabbar.yml +35 -0
- package/src/testing-js/__aria__/table.yml +144 -0
- package/src/testing-js/__aria__/toggle.yml +12 -0
- package/src/testing-js/__aria__/tooltip.yml +2 -0
- package/src/testing-js/__aria__/videoframe.yml +6 -0
- package/src/testing-js/__aria__/videolightbox.yml +12 -0
- package/src/testing-js/{chunk-WIZ6W7UT.js → chunk-3WCLMOM7.js} +2 -2
- package/src/testing-js/{chunk-SHBYZUPD.js → chunk-5HNZHIHG.js} +211 -14
- package/src/testing-js/chunk-5HNZHIHG.js.map +1 -0
- package/src/testing-js/{chunk-NB3NZRBM.js → chunk-7CM5D7PF.js} +5 -1
- package/src/testing-js/chunk-7CM5D7PF.js.map +1 -0
- package/src/testing-js/chunk-EWSGE27V.js +168 -0
- package/src/testing-js/chunk-EWSGE27V.js.map +1 -0
- package/src/testing-js/{chunk-GKO27NGN.js → chunk-R54I7YL6.js} +2 -2
- package/src/testing-js/{chunk-X6KHEVIG.js → chunk-RWH46IU5.js} +97 -29
- package/src/testing-js/chunk-RWH46IU5.js.map +1 -0
- package/src/testing-js/chunk-SHLPDNAQ.js +658 -0
- package/src/testing-js/chunk-SHLPDNAQ.js.map +1 -0
- package/src/testing-js/{chunk-3UKGXCDL.js → chunk-YVVR3GJZ.js} +1 -1
- package/src/testing-js/chunk-YVVR3GJZ.js.map +1 -0
- package/src/testing-js/component-a11y.contract.js +283 -0
- package/src/testing-js/component-a11y.contract.js.map +1 -0
- package/src/testing-js/component-alias.contract.js +2 -2
- package/src/testing-js/component-behavior.contract.js +2 -2
- package/src/testing-js/component-editor.contract.js +6 -5
- package/src/testing-js/component-editor.contract.js.map +1 -1
- package/src/testing-js/component-render.contract.js +10 -6
- package/src/testing-js/component-render.contract.js.map +1 -1
- package/src/testing-js/index.d.ts +44 -16
- package/src/testing-js/index.js +9 -9
- package/src/testing-js/page-compliance.contract.js +163 -18
- package/src/testing-js/page-compliance.contract.js.map +1 -1
- package/src/testing-js/vitest.js +3 -3
- package/template/package.json +9 -0
- package/src/editor/ui/keepInViewport.ts +0 -84
- package/src/testing-js/chunk-3UKGXCDL.js.map +0 -1
- package/src/testing-js/chunk-NB3NZRBM.js.map +0 -1
- package/src/testing-js/chunk-SHBYZUPD.js.map +0 -1
- package/src/testing-js/chunk-X6KHEVIG.js.map +0 -1
- /package/src/testing-js/{chunk-WIZ6W7UT.js.map → chunk-3WCLMOM7.js.map} +0 -0
- /package/src/testing-js/{chunk-GKO27NGN.js.map → chunk-R54I7YL6.js.map} +0 -0
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
MOTION_MS,
|
|
3
|
+
MOTION_URL,
|
|
4
|
+
TEXT_SPACING_RULE,
|
|
5
|
+
TEXT_SPACING_URL,
|
|
6
|
+
newUnderTextSpacing
|
|
7
|
+
} from "./chunk-SHLPDNAQ.js";
|
|
8
|
+
import {
|
|
9
|
+
missingEngine,
|
|
10
|
+
recordA11y,
|
|
11
|
+
scanAxe
|
|
12
|
+
} from "./chunk-EWSGE27V.js";
|
|
4
13
|
import {
|
|
5
14
|
DEFAULT_PAGE_VIEWPORTS,
|
|
6
15
|
PAGES_ENV,
|
|
7
16
|
PAGE_VIEWPORTS_ENV
|
|
8
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-7CM5D7PF.js";
|
|
18
|
+
import {
|
|
19
|
+
isInapplicable
|
|
20
|
+
} from "./chunk-YVVR3GJZ.js";
|
|
9
21
|
import {
|
|
10
22
|
allContracts
|
|
11
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-5HNZHIHG.js";
|
|
12
24
|
|
|
13
25
|
// src/testing/page-compliance.contract.ts
|
|
14
26
|
import { test } from "@playwright/test";
|
|
@@ -258,6 +270,12 @@ var TEXT_STYLES = [
|
|
|
258
270
|
// src/editor/core/palettes/contrast.ts
|
|
259
271
|
var AA_BODY = 4.5;
|
|
260
272
|
var AA_LARGE = 3;
|
|
273
|
+
var LARGE_TEXT_PX = 24;
|
|
274
|
+
var LARGE_BOLD_PX = 18.66;
|
|
275
|
+
var BOLD = 700;
|
|
276
|
+
function isLargeText(px, weight) {
|
|
277
|
+
return px >= LARGE_TEXT_PX || px >= LARGE_BOLD_PX && weight >= BOLD;
|
|
278
|
+
}
|
|
261
279
|
function linearizeChannel(v8) {
|
|
262
280
|
const s = v8 / 255;
|
|
263
281
|
return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
|
|
@@ -311,6 +329,23 @@ function variantPattern(label) {
|
|
|
311
329
|
const keys = [.../* @__PURE__ */ new Set([words.join("-"), ...words])].map((key) => key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
312
330
|
return `(?:^|-)(?:${keys.join("|")})$`;
|
|
313
331
|
}
|
|
332
|
+
function stateMarkers(contract) {
|
|
333
|
+
if (isInapplicable(contract.states)) return [];
|
|
334
|
+
const markers = [];
|
|
335
|
+
for (const state of contract.states) {
|
|
336
|
+
if (restingState(state.state)) continue;
|
|
337
|
+
const attributes = [];
|
|
338
|
+
for (const [part, attrs] of Object.entries(state.attributes ?? {})) {
|
|
339
|
+
const declared = contract.parts[part];
|
|
340
|
+
if (declared === void 0 || typeof declared !== "string" && declared.portal) continue;
|
|
341
|
+
const selector = part === contract.root ? null : typeof declared === "string" ? declared : declared.selector;
|
|
342
|
+
for (const [name, value] of Object.entries(attrs)) attributes.push({ selector, name, value });
|
|
343
|
+
}
|
|
344
|
+
if (!state.forceClass && !attributes.some((a) => a.value !== null)) continue;
|
|
345
|
+
markers.push({ forceClass: state.forceClass ?? null, attributes });
|
|
346
|
+
}
|
|
347
|
+
return markers;
|
|
348
|
+
}
|
|
314
349
|
function paintChecks(contract, map) {
|
|
315
350
|
const checks = [];
|
|
316
351
|
for (const [part, properties] of Object.entries(map)) {
|
|
@@ -354,7 +389,7 @@ function restingPaintSpec(contract) {
|
|
|
354
389
|
}
|
|
355
390
|
}
|
|
356
391
|
if (entries.length === 0) return null;
|
|
357
|
-
return { id: contract.id, root: rootSelector, entries };
|
|
392
|
+
return { id: contract.id, root: rootSelector, entries, away: stateMarkers(contract) };
|
|
358
393
|
}
|
|
359
394
|
var TEXT_AXES = ["fontFamily", "fontSize", "fontWeight", "lineHeight", "letterSpacing"];
|
|
360
395
|
var BLOCK_DISPLAYS = ["block", "flow-root", "list-item", "flex", "grid", "table-cell", "table-caption"];
|
|
@@ -362,9 +397,6 @@ var GRID_TOLERANCE = 1;
|
|
|
362
397
|
var GRID_VIEWPORT = 768;
|
|
363
398
|
var SETTLE_QUIET_MS = 300;
|
|
364
399
|
var SETTLE_BUDGET_MS = 5e3;
|
|
365
|
-
var LARGE_TEXT_PX = 24;
|
|
366
|
-
var LARGE_BOLD_PX = 18.66;
|
|
367
|
-
var BOLD = 700;
|
|
368
400
|
var cssName = (camel) => camel.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
|
|
369
401
|
function report(failures, scope, describe) {
|
|
370
402
|
const lines = failures.map(describe);
|
|
@@ -376,8 +408,7 @@ function hex(rgb) {
|
|
|
376
408
|
return `#${[r, g, b].map((c) => c.toString(16).padStart(2, "0")).join("")}`;
|
|
377
409
|
}
|
|
378
410
|
function aaFloor(pair) {
|
|
379
|
-
|
|
380
|
-
return large ? AA_LARGE : AA_BODY;
|
|
411
|
+
return isLargeText(pair.fontSize, pair.fontWeight) ? AA_LARGE : AA_BODY;
|
|
381
412
|
}
|
|
382
413
|
function reasons(skipped) {
|
|
383
414
|
return Object.entries(skipped).map(([reason, count]) => `${reason} (${count})`).join(", ");
|
|
@@ -394,7 +425,11 @@ var PageHarness = class _PageHarness {
|
|
|
394
425
|
static async open(page, target, viewport) {
|
|
395
426
|
await installPageProbe(page);
|
|
396
427
|
await page.setViewportSize(viewport);
|
|
397
|
-
await
|
|
428
|
+
await _PageHarness.load(page, target.route);
|
|
429
|
+
return new _PageHarness(page, target, viewport);
|
|
430
|
+
}
|
|
431
|
+
static async load(page, route) {
|
|
432
|
+
await page.goto(route);
|
|
398
433
|
await page.locator(PAGE_CONTAINER).waitFor();
|
|
399
434
|
await page.waitForFunction((selectors) => {
|
|
400
435
|
const container = document.querySelector(selectors.container);
|
|
@@ -403,7 +438,6 @@ var PageHarness = class _PageHarness {
|
|
|
403
438
|
}, { container: PAGE_CONTAINER, chrome: CHROME });
|
|
404
439
|
await page.waitForLoadState("networkidle");
|
|
405
440
|
await _PageHarness.settle(page);
|
|
406
|
-
return new _PageHarness(page, target, viewport);
|
|
407
441
|
}
|
|
408
442
|
/**
|
|
409
443
|
* Every rule here measures geometry, and the geometry moves for as long as
|
|
@@ -523,24 +557,33 @@ var PageHarness = class _PageHarness {
|
|
|
523
557
|
let asserted = 0;
|
|
524
558
|
const root = document.querySelector(container);
|
|
525
559
|
if (!root) return { instances, asserted, failures, uncovered };
|
|
526
|
-
const normalize = (node, css, raw) => {
|
|
560
|
+
const normalize = (node, css, raw, rendered = false) => {
|
|
527
561
|
const probe = document.createElement("div");
|
|
528
|
-
|
|
562
|
+
if (rendered) {
|
|
563
|
+
probe.style.visibility = "hidden";
|
|
564
|
+
probe.style.position = getComputedStyle(node).position;
|
|
565
|
+
} else probe.style.display = "none";
|
|
529
566
|
probe.style.borderStyle = "solid";
|
|
530
567
|
probe.style.outlineStyle = "solid";
|
|
531
568
|
probe.style.fontSize = getComputedStyle(node).fontSize;
|
|
532
569
|
(node.parentElement ?? document.body).appendChild(probe);
|
|
533
570
|
probe.style.setProperty(css.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`), raw);
|
|
534
|
-
const computed = getComputedStyle(probe)[css];
|
|
571
|
+
const computed = (getComputedStyle(probe)[css] ?? "").trim();
|
|
535
572
|
probe.remove();
|
|
536
|
-
return
|
|
573
|
+
return !rendered && computed.endsWith("%") ? normalize(node, css, raw, true) : computed;
|
|
537
574
|
};
|
|
575
|
+
const atRest = (element, markers) => !markers.some((marker) => (marker.forceClass === null || element.classList.contains(marker.forceClass)) && marker.attributes.every(({ selector, name, value }) => {
|
|
576
|
+
const part = selector === null ? element : element.querySelector(selector);
|
|
577
|
+
if (!part) return false;
|
|
578
|
+
return value === null ? !part.hasAttribute(name) : part.getAttribute(name) === value;
|
|
579
|
+
}));
|
|
538
580
|
for (const spec of list) {
|
|
539
581
|
const patterns = spec.entries.map((entry) => entry.pattern === null ? null : new RegExp(entry.pattern));
|
|
540
582
|
const variants = [...new Set(spec.entries.map((entry) => entry.variant).filter((v) => v !== null))];
|
|
541
583
|
for (const element of root.querySelectorAll(spec.root)) {
|
|
542
584
|
if (element.closest(chrome)) continue;
|
|
543
585
|
instances++;
|
|
586
|
+
if (!atRest(element, spec.away)) continue;
|
|
544
587
|
const classes = [...element.classList];
|
|
545
588
|
const line = window.__liveTokensPageLine(element, source);
|
|
546
589
|
let covered = false;
|
|
@@ -842,13 +885,14 @@ var PageHarness = class _PageHarness {
|
|
|
842
885
|
});
|
|
843
886
|
}
|
|
844
887
|
}
|
|
845
|
-
const clips = (style) => style.overflowX !== "visible" || style.overflowY !== "visible";
|
|
846
888
|
for (const spec of list) {
|
|
847
889
|
for (const instance of root.querySelectorAll(spec.root)) {
|
|
848
890
|
if (instance.closest(chrome)) continue;
|
|
849
891
|
let clipper = null;
|
|
850
892
|
for (let node = instance.parentElement; node; node = node.parentElement) {
|
|
851
|
-
|
|
893
|
+
const overflowX = getComputedStyle(node).overflowX;
|
|
894
|
+
if (overflowX === "auto" || overflowX === "scroll") break;
|
|
895
|
+
if (overflowX !== "visible") {
|
|
852
896
|
clipper = node;
|
|
853
897
|
break;
|
|
854
898
|
}
|
|
@@ -957,6 +1001,91 @@ var PageHarness = class _PageHarness {
|
|
|
957
1001
|
}
|
|
958
1002
|
return null;
|
|
959
1003
|
}
|
|
1004
|
+
/**
|
|
1005
|
+
* The accessibility rules return their results. The suite passes them to
|
|
1006
|
+
* `recordA11y`, and the run reports each one at `warn` (decision 3 of
|
|
1007
|
+
* docs/plans/a11y-testing.md).
|
|
1008
|
+
*
|
|
1009
|
+
* axe over the page's own markup. The router's chrome and every shipped
|
|
1010
|
+
* component root stay out, since the component suite answers for what a
|
|
1011
|
+
* component renders, and `color-contrast` stays off, since `page-contrast`
|
|
1012
|
+
* owns page contrast (decision 8).
|
|
1013
|
+
*/
|
|
1014
|
+
async scanA11y(componentRoots2) {
|
|
1015
|
+
const results = await scanAxe(this.page, PAGE_CONTAINER, [CHROME, ...componentRoots2], "a11y-page");
|
|
1016
|
+
const lines = await this.page.evaluate(({ targets: targets2, source }) => targets2.map((target) => {
|
|
1017
|
+
try {
|
|
1018
|
+
const element = document.querySelector(target);
|
|
1019
|
+
return element ? window.__liveTokensPageLine(element, source) : 1;
|
|
1020
|
+
} catch {
|
|
1021
|
+
return 1;
|
|
1022
|
+
}
|
|
1023
|
+
}), { targets: results.map((result) => result.target), source: this.target.source });
|
|
1024
|
+
return results.map((result, index) => ({ ...result, line: lines[index] }));
|
|
1025
|
+
}
|
|
1026
|
+
/** The overflow observation again under the SC 1.4.12 override, minus every
|
|
1027
|
+
* failure the page already has without it, which `page-overflow` reports. */
|
|
1028
|
+
async scanTextSpacing(specs) {
|
|
1029
|
+
const found = await newUnderTextSpacing(
|
|
1030
|
+
this.page,
|
|
1031
|
+
async () => (await this.observeOverflow(specs)).failures,
|
|
1032
|
+
(failure) => `${failure.kind}|${failure.line}|${failure.tag}`
|
|
1033
|
+
);
|
|
1034
|
+
return found.map((failure) => ({
|
|
1035
|
+
rule: "a11y-text-spacing",
|
|
1036
|
+
engineRule: TEXT_SPACING_RULE,
|
|
1037
|
+
impact: null,
|
|
1038
|
+
target: failure.kind === "instance" ? failure.tag : `<${failure.tag}>`,
|
|
1039
|
+
html: "",
|
|
1040
|
+
help: `Under the text spacing override, ${failure.detail}`,
|
|
1041
|
+
helpUrl: TEXT_SPACING_URL,
|
|
1042
|
+
line: failure.line
|
|
1043
|
+
}));
|
|
1044
|
+
}
|
|
1045
|
+
/**
|
|
1046
|
+
* Loads the page again under `prefers-reduced-motion: reduce`, so a script
|
|
1047
|
+
* that reads the preference at mount sees it too, and reports every
|
|
1048
|
+
* animation still running whose run lasts past `MOTION_MS`. The page stays
|
|
1049
|
+
* under the emulation afterwards.
|
|
1050
|
+
*/
|
|
1051
|
+
async scanReducedMotion() {
|
|
1052
|
+
await this.page.emulateMedia({ reducedMotion: "reduce" });
|
|
1053
|
+
await _PageHarness.load(this.page, this.target.route);
|
|
1054
|
+
return this.page.evaluate(({ container, chrome, source, limit, url }) => {
|
|
1055
|
+
const root = document.querySelector(container);
|
|
1056
|
+
if (!root) return [];
|
|
1057
|
+
const results = [];
|
|
1058
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1059
|
+
for (const animation of document.getAnimations()) {
|
|
1060
|
+
if (animation.playState !== "running") continue;
|
|
1061
|
+
const effect = animation.effect;
|
|
1062
|
+
if (!(effect instanceof KeyframeEffect) || !effect.target) continue;
|
|
1063
|
+
const element = effect.target;
|
|
1064
|
+
if (!root.contains(element) || element.closest(chrome)) continue;
|
|
1065
|
+
const end = Number(effect.getComputedTiming().endTime ?? 0);
|
|
1066
|
+
if (end <= limit) continue;
|
|
1067
|
+
const name = animation instanceof CSSAnimation ? `The animation ${animation.animationName.replace(/^svelte-[a-z0-9]+-/, "")}` : animation instanceof CSSTransition ? `A transition of ${animation.transitionProperty}` : `A script animation${animation.id ? ` ${animation.id}` : ""}`;
|
|
1068
|
+
const classes = [...element.classList].filter((c) => !/^svelte-[a-z0-9]+$/.test(c));
|
|
1069
|
+
const target = `${element.tagName.toLowerCase()}${classes.map((c) => `.${c}`).join("")}` + (effect.pseudoElement ?? "");
|
|
1070
|
+
if (seen.has(`${target}
|
|
1071
|
+
${name}`)) continue;
|
|
1072
|
+
seen.add(`${target}
|
|
1073
|
+
${name}`);
|
|
1074
|
+
const html = element.outerHTML;
|
|
1075
|
+
results.push({
|
|
1076
|
+
rule: "a11y-reduced-motion",
|
|
1077
|
+
engineRule: "prefers-reduced-motion",
|
|
1078
|
+
impact: null,
|
|
1079
|
+
target,
|
|
1080
|
+
html: html.slice(0, html.indexOf(">") + 1),
|
|
1081
|
+
help: `${name} keeps running under prefers-reduced-motion: reduce, ` + (Number.isFinite(end) ? `for ${Math.round(end)} ms` : "without end"),
|
|
1082
|
+
helpUrl: url,
|
|
1083
|
+
line: window.__liveTokensPageLine(element, source)
|
|
1084
|
+
});
|
|
1085
|
+
}
|
|
1086
|
+
return results;
|
|
1087
|
+
}, { container: PAGE_CONTAINER, chrome: CHROME, source: this.target.source, limit: MOTION_MS, url: MOTION_URL });
|
|
1088
|
+
}
|
|
960
1089
|
};
|
|
961
1090
|
async function installPageProbe(page) {
|
|
962
1091
|
await page.addInitScript(() => {
|
|
@@ -1015,6 +1144,22 @@ for (const target of targets) {
|
|
|
1015
1144
|
const inapplicable = await harness.assertOverflow(specs);
|
|
1016
1145
|
test.skip(inapplicable !== null, inapplicable ?? "");
|
|
1017
1146
|
});
|
|
1147
|
+
test(`page-a11y | ${target.source} | ${at}`, async ({ page }) => {
|
|
1148
|
+
const missing = await missingEngine(["axe"]);
|
|
1149
|
+
test.skip(missing !== null, missing ?? "");
|
|
1150
|
+
const roots = await componentRoots();
|
|
1151
|
+
const harness = await PageHarness.open(page, target, viewport);
|
|
1152
|
+
recordA11y(await harness.scanA11y(roots));
|
|
1153
|
+
});
|
|
1154
|
+
test(`page-text-spacing | ${target.source} | ${at}`, async ({ page }) => {
|
|
1155
|
+
const specs = await paintSpecs();
|
|
1156
|
+
const harness = await PageHarness.open(page, target, viewport);
|
|
1157
|
+
recordA11y(await harness.scanTextSpacing(specs));
|
|
1158
|
+
});
|
|
1159
|
+
test(`page-reduced-motion | ${target.source} | ${at}`, async ({ page }) => {
|
|
1160
|
+
const harness = await PageHarness.open(page, target, viewport);
|
|
1161
|
+
recordA11y(await harness.scanReducedMotion());
|
|
1162
|
+
});
|
|
1018
1163
|
}
|
|
1019
1164
|
}
|
|
1020
1165
|
//# sourceMappingURL=page-compliance.contract.js.map
|