@motion-proto/live-tokens 0.97.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 +272 -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/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.js +1 -1
- package/package.json +47 -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 -3
- 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/editorStore.ts +4 -0
- package/src/editor/core/store/editorViewStore.ts +2 -2
- package/src/editor/core/store/unsavedEdits.ts +10 -0
- package/src/editor/core/themes/liveStateStream.ts +7 -1
- package/src/editor/core/themes/parsers/gradient.ts +5 -2
- 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 +28 -1
- package/src/editor/docs/content.generated.ts +2 -1
- package/src/editor/pages/ComponentEditorPage.svelte +10 -1
- package/src/editor/pages/EditorShell.svelte +96 -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/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 +9 -0
- package/src/editor/ui/UITokenSelector.svelte +26 -2
- 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/contrastReadout.ts +45 -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 +18 -25
- 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 +132 -13
- 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/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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@motion-proto/live-tokens",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.98.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
6
6
|
"**/*.css"
|
|
@@ -205,15 +205,24 @@
|
|
|
205
205
|
"check:smoke-install": "bash scripts/smoke-install.sh",
|
|
206
206
|
"check:smoke-create": "bash scripts/smoke-create.sh",
|
|
207
207
|
"eval": "bash scripts/eval.sh",
|
|
208
|
-
"eval:billing": "bash scripts/eval-
|
|
208
|
+
"eval:billing": "bash scripts/eval-harbor.sh",
|
|
209
209
|
"build:eval-project": "bash scripts/build-eval-project.sh",
|
|
210
210
|
"check:smoke-component-tests": "bash scripts/smoke-component-tests.sh",
|
|
211
211
|
"check:smoke-page-tests": "bash scripts/smoke-page-tests.sh",
|
|
212
212
|
"prepublishOnly": "npm run check:no-style-imports && npm run check:no-tooling-imports && npm run check:slot-prose && npm run check:overlay-portal && npm run check:editor-font-isolation && npm run check:component-defaults && npm run check:pages && npm run check:production-is-default && npm run check:docs-content && npm run build:lib && npm run check:token-contract && npm run check:preset-themes && npm run check:skills && npm run check:cli-strings && npm run check:skill-sources && npm run check:skill-atlas && npm run check:smoke-install && npm run check:smoke-create && npm run check:smoke-component-tests && npm run check:smoke-page-tests"
|
|
213
213
|
},
|
|
214
214
|
"peerDependencies": {
|
|
215
|
+
"@axe-core/playwright": "^4.11.1",
|
|
215
216
|
"@playwright/test": "^1.55",
|
|
217
|
+
"@siteimprove/alfa-act": "^0.119.0",
|
|
218
|
+
"@siteimprove/alfa-device": "^0.119.0",
|
|
219
|
+
"@siteimprove/alfa-dom": "^0.119.0",
|
|
220
|
+
"@siteimprove/alfa-http": "^0.119.0",
|
|
221
|
+
"@siteimprove/alfa-rules": "^0.119.0",
|
|
222
|
+
"@siteimprove/alfa-url": "^0.119.0",
|
|
223
|
+
"@siteimprove/alfa-web": "^0.119.0",
|
|
216
224
|
"@sveltejs/vite-plugin-svelte": "^7.0",
|
|
225
|
+
"axe-core": "^4.11.1",
|
|
217
226
|
"happy-dom": "^20.0",
|
|
218
227
|
"sass": "^1.0",
|
|
219
228
|
"svelte": "^5",
|
|
@@ -221,9 +230,36 @@
|
|
|
221
230
|
"vitest": "^4.0 || ^5.0"
|
|
222
231
|
},
|
|
223
232
|
"peerDependenciesMeta": {
|
|
233
|
+
"@axe-core/playwright": {
|
|
234
|
+
"optional": true
|
|
235
|
+
},
|
|
224
236
|
"@playwright/test": {
|
|
225
237
|
"optional": true
|
|
226
238
|
},
|
|
239
|
+
"@siteimprove/alfa-act": {
|
|
240
|
+
"optional": true
|
|
241
|
+
},
|
|
242
|
+
"@siteimprove/alfa-device": {
|
|
243
|
+
"optional": true
|
|
244
|
+
},
|
|
245
|
+
"@siteimprove/alfa-dom": {
|
|
246
|
+
"optional": true
|
|
247
|
+
},
|
|
248
|
+
"@siteimprove/alfa-http": {
|
|
249
|
+
"optional": true
|
|
250
|
+
},
|
|
251
|
+
"@siteimprove/alfa-rules": {
|
|
252
|
+
"optional": true
|
|
253
|
+
},
|
|
254
|
+
"@siteimprove/alfa-url": {
|
|
255
|
+
"optional": true
|
|
256
|
+
},
|
|
257
|
+
"@siteimprove/alfa-web": {
|
|
258
|
+
"optional": true
|
|
259
|
+
},
|
|
260
|
+
"axe-core": {
|
|
261
|
+
"optional": true
|
|
262
|
+
},
|
|
227
263
|
"happy-dom": {
|
|
228
264
|
"optional": true
|
|
229
265
|
},
|
|
@@ -232,9 +268,18 @@
|
|
|
232
268
|
}
|
|
233
269
|
},
|
|
234
270
|
"devDependencies": {
|
|
271
|
+
"@axe-core/playwright": "^4.14.0",
|
|
235
272
|
"@playwright/test": "^1.62.1",
|
|
273
|
+
"@siteimprove/alfa-act": "^0.119.0",
|
|
274
|
+
"@siteimprove/alfa-device": "^0.119.0",
|
|
275
|
+
"@siteimprove/alfa-dom": "^0.119.0",
|
|
276
|
+
"@siteimprove/alfa-http": "^0.119.0",
|
|
277
|
+
"@siteimprove/alfa-rules": "^0.119.0",
|
|
278
|
+
"@siteimprove/alfa-url": "^0.119.0",
|
|
279
|
+
"@siteimprove/alfa-web": "^0.119.0",
|
|
236
280
|
"@sveltejs/vite-plugin-svelte": "^7.1.2",
|
|
237
281
|
"@types/node": "^25.9.1",
|
|
282
|
+
"axe-core": "^4.14.0",
|
|
238
283
|
"happy-dom": "^20.9.0",
|
|
239
284
|
"sass": "^1.98.0",
|
|
240
285
|
"svelte": "^5.55.5",
|
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
|
|
165
165
|
{#if open}
|
|
166
166
|
<div class="labeled-select-panel" bind:this={panelEl} use:portal>
|
|
167
|
-
<MenuSelect {items} {value} minWidth="12rem" onchange={select} />
|
|
167
|
+
<MenuSelect {items} {value} ariaLabel={label} minWidth="12rem" onchange={select} />
|
|
168
168
|
</div>
|
|
169
169
|
{/if}
|
|
170
170
|
|
package/src/editor/bootstrap.ts
CHANGED
|
@@ -50,16 +50,18 @@ export async function bootLiveTokens(
|
|
|
50
50
|
if (import.meta.env.DEV) {
|
|
51
51
|
// Imported here, never statically, so a build drops the editor. The
|
|
52
52
|
// registry alone imports every shipped component and editor.
|
|
53
|
-
const [editorStore, themeDocumentSync, liveStateStream, { initializeTheme }] = await Promise.all([
|
|
53
|
+
const [editorStore, themeDocumentSync, liveStateStream, a11yReport, { initializeTheme }] = await Promise.all([
|
|
54
54
|
import('./core/store/editorStore'),
|
|
55
55
|
import('./core/themes/themeDocumentSync'),
|
|
56
56
|
import('./core/themes/liveStateStream'),
|
|
57
|
+
import('./core/a11y/a11yReport'),
|
|
57
58
|
import('./core/themes/themeInit'),
|
|
58
59
|
import('./component-editor/registry'),
|
|
59
60
|
]);
|
|
60
61
|
editorStore.init();
|
|
61
62
|
themeDocumentSync.init();
|
|
62
63
|
liveStateStream.init();
|
|
64
|
+
void a11yReport.init();
|
|
63
65
|
if (opts.components) {
|
|
64
66
|
for (const entry of opts.components) {
|
|
65
67
|
registerComponent(entry);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import type { Token } from './scaffolding/types';
|
|
3
|
+
import type { ContrastPair } from '../core/palettes/contrastPairs';
|
|
3
4
|
import { badgeVariants } from '../../system/components/Badge.svelte';
|
|
4
5
|
|
|
5
6
|
export const component = 'badge';
|
|
@@ -57,6 +58,18 @@
|
|
|
57
58
|
);
|
|
58
59
|
|
|
59
60
|
const variantOptions = variants.map((v) => ({ value: v, label: v.charAt(0).toUpperCase() + v.slice(1) }));
|
|
61
|
+
|
|
62
|
+
function variantContrastPairs(v: Variant): ContrastPair[] {
|
|
63
|
+
return [{
|
|
64
|
+
foreground: `--badge-${v}-text`,
|
|
65
|
+
backdrop: [`--badge-${v}-surface`],
|
|
66
|
+
role: 'text',
|
|
67
|
+
fontSize: `--badge-${v}-text-font-size`,
|
|
68
|
+
fontWeight: `--badge-${v}-text-font-weight`,
|
|
69
|
+
}];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export const contrastPairs: ContrastPair[] = variants.flatMap(variantContrastPairs);
|
|
60
73
|
</script>
|
|
61
74
|
|
|
62
75
|
<script lang="ts">
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { buildSiblings } from './scaffolding/siblings';
|
|
3
3
|
import type { Token, IntrinsicSpec } from './scaffolding/types';
|
|
4
|
+
import type { ContrastPair } from '../core/palettes/contrastPairs';
|
|
4
5
|
|
|
5
6
|
export const component = 'button';
|
|
6
7
|
|
|
@@ -120,11 +121,41 @@
|
|
|
120
121
|
default: { default: 'var(--color-transparent)' },
|
|
121
122
|
},
|
|
122
123
|
];
|
|
124
|
+
|
|
125
|
+
// The small size keeps each variant's colors, and it is the smaller of the two text sizes.
|
|
126
|
+
const pairFont = { fontSize: '--button-small-text-font-size', fontWeight: '--button-small-text-font-weight' } as const;
|
|
127
|
+
|
|
128
|
+
function variantContrastPairs(v: Variant): ContrastPair[] {
|
|
129
|
+
const text = (s: StateName) => `${statePrefix(v, s)}-text`;
|
|
130
|
+
const surface = (s: StateName) => `${statePrefix(v, s)}-surface`;
|
|
131
|
+
const hoverStack = ['--button-hover-tint-enabled', surface('hover')];
|
|
132
|
+
const disabled: ContrastPair = { foreground: text('disabled'), backdrop: [surface('disabled')], role: 'text', ...pairFont, inactive: true };
|
|
133
|
+
if (v !== 'outline') {
|
|
134
|
+
return [
|
|
135
|
+
{ foreground: text('default'), backdrop: [surface('default')], role: 'text', ...pairFont },
|
|
136
|
+
{ foreground: text('hover'), backdrop: hoverStack, role: 'text', ...pairFont },
|
|
137
|
+
disabled,
|
|
138
|
+
];
|
|
139
|
+
}
|
|
140
|
+
// `:active` repaints the surface without the tint. A pointer press keeps the
|
|
141
|
+
// hover text color, and a key press keeps the default one.
|
|
142
|
+
const active = ['--button-outline-active-surface'];
|
|
143
|
+
return [
|
|
144
|
+
{ foreground: text('default'), backdrop: [surface('default')], role: 'text', ...pairFont, context: 'default' },
|
|
145
|
+
{ foreground: text('default'), backdrop: active, role: 'text', ...pairFont, context: 'active' },
|
|
146
|
+
{ foreground: text('hover'), backdrop: hoverStack, role: 'text', ...pairFont, context: 'hover' },
|
|
147
|
+
{ foreground: text('hover'), backdrop: active, role: 'text', ...pairFont, context: 'active' },
|
|
148
|
+
disabled,
|
|
149
|
+
];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export const contrastPairs: ContrastPair[] = variants.flatMap(variantContrastPairs);
|
|
123
153
|
</script>
|
|
124
154
|
|
|
125
155
|
<script lang="ts">
|
|
126
156
|
import Button from '../../system/components/Button.svelte';
|
|
127
157
|
import Toggle from '../ui/Toggle.svelte';
|
|
158
|
+
import A11yPropertyMark from '../ui/a11y/A11yPropertyMark.svelte';
|
|
128
159
|
import UIPaletteSelector from '../ui/UIPaletteSelector.svelte';
|
|
129
160
|
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
130
161
|
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
@@ -216,7 +247,7 @@
|
|
|
216
247
|
{#snippet extraPropertyRows(stateName)}
|
|
217
248
|
{#if stateName === 'hover'}
|
|
218
249
|
<div class="property-row" data-token-variables="--button-hover-tint-enabled">
|
|
219
|
-
<span class="property-label">tint layer
|
|
250
|
+
<span class="property-label">tint layer<A11yPropertyMark variables={['--button-hover-tint-enabled']} /></span>
|
|
220
251
|
<Toggle checked={tintOn} onchange={setTintOn} />
|
|
221
252
|
</div>
|
|
222
253
|
{#if tintOn}
|
|
@@ -226,7 +257,7 @@
|
|
|
226
257
|
</div>
|
|
227
258
|
{/if}
|
|
228
259
|
<div class="property-row" data-token-variables="--button-shimmer">
|
|
229
|
-
<span class="property-label">hover shimmer
|
|
260
|
+
<span class="property-label">hover shimmer<A11yPropertyMark variables={['--button-shimmer']} /></span>
|
|
230
261
|
<Toggle checked={shimmerEnabled} onchange={handleShimmerChange} />
|
|
231
262
|
</div>
|
|
232
263
|
{/if}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { buildTypeGroupColorTokens } from './scaffolding/buildTypeGroupTokens';
|
|
3
3
|
import type { Token, TypeGroupConfig } from './scaffolding/types';
|
|
4
|
+
import type { ContrastPair } from '../core/palettes/contrastPairs';
|
|
4
5
|
import { calloutVariants } from '../../system/components/Callout.svelte';
|
|
5
6
|
|
|
6
7
|
export const component = 'callout';
|
|
@@ -68,6 +69,18 @@
|
|
|
68
69
|
);
|
|
69
70
|
|
|
70
71
|
const variantOptions = variants.map((v) => ({ value: v, label: v.charAt(0).toUpperCase() + v.slice(1) }));
|
|
72
|
+
|
|
73
|
+
function variantContrastPairs(v: Variant): ContrastPair[] {
|
|
74
|
+
return variantTypeGroups(v).map((g) => ({
|
|
75
|
+
foreground: g.colorVariable,
|
|
76
|
+
backdrop: [`--callout-${v}-surface`],
|
|
77
|
+
role: 'text',
|
|
78
|
+
fontSize: g.sizeVariable,
|
|
79
|
+
fontWeight: g.weightVariable,
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const contrastPairs: ContrastPair[] = variants.flatMap(variantContrastPairs);
|
|
71
84
|
</script>
|
|
72
85
|
|
|
73
86
|
<script lang="ts">
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { buildTypeGroupColorTokens } from './scaffolding/buildTypeGroupTokens';
|
|
3
3
|
import type { Token, TypeGroupConfig, IntrinsicSpec } from './scaffolding/types';
|
|
4
|
+
import type { ContrastPair } from '../core/palettes/contrastPairs';
|
|
4
5
|
|
|
5
6
|
export const component = 'card';
|
|
6
7
|
|
|
@@ -104,12 +105,20 @@
|
|
|
104
105
|
default: { default: HOVER_OFF.shadow },
|
|
105
106
|
},
|
|
106
107
|
];
|
|
108
|
+
|
|
109
|
+
// size="small" sets the title in --font-size-md and the body in
|
|
110
|
+
// --font-size-sm, the smaller of each one's two sizes.
|
|
111
|
+
export const contrastPairs: ContrastPair[] = [
|
|
112
|
+
{ foreground: '--card-default-title', backdrop: ['--card-default-header-surface', '--card-default-surface'], role: 'text', fontSize: '--font-size-md', fontWeight: '--card-default-title-font-weight' },
|
|
113
|
+
{ foreground: '--card-default-body', backdrop: ['--card-default-surface'], role: 'text', fontSize: '--font-size-sm', fontWeight: '--card-default-body-font-weight' },
|
|
114
|
+
];
|
|
107
115
|
</script>
|
|
108
116
|
|
|
109
117
|
<script lang="ts">
|
|
110
118
|
import Card from '../../system/components/Card.svelte';
|
|
111
119
|
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
112
120
|
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
121
|
+
import A11yPropertyMark from '../ui/a11y/A11yPropertyMark.svelte';
|
|
113
122
|
import { editorState, setComponentAlias } from '../core/store/editorStore';
|
|
114
123
|
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
115
124
|
let linked = $derived(computeLinkedBlock(component, linkableContexts, allTokens, $editorState));
|
|
@@ -152,6 +161,7 @@
|
|
|
152
161
|
<input type="checkbox" checked={hoverEnabled} onchange={(e) => setHoverEnabled(e.currentTarget.checked)} />
|
|
153
162
|
<span>Use hover</span>
|
|
154
163
|
</label>
|
|
164
|
+
<A11yPropertyMark variables={['--card-hover-border-enabled', '--card-hover-shadow-enabled']} />
|
|
155
165
|
<p class="hover-help">
|
|
156
166
|
Checked: every card lifts on hover. Unchecked: hover is off by default and a page turns it on
|
|
157
167
|
per card with the <code>hover</code> prop.
|
|
@@ -163,10 +173,10 @@
|
|
|
163
173
|
{@const previewClass = activeState === 'hover' ? 'force-hover' : ''}
|
|
164
174
|
<div class="card-demo">
|
|
165
175
|
<Card title="Card title" icon="fas fa-star" class={previewClass}>
|
|
166
|
-
<div class="content-placeholder">Content Placeholder</div>
|
|
176
|
+
<div class="content-placeholder" data-preview-demo>Content Placeholder</div>
|
|
167
177
|
</Card>
|
|
168
178
|
<Card variant="bare" class={previewClass}>
|
|
169
|
-
<div class="content-placeholder">Bare variant</div>
|
|
179
|
+
<div class="content-placeholder" data-preview-demo>Bare variant</div>
|
|
170
180
|
</Card>
|
|
171
181
|
</div>
|
|
172
182
|
{/snippet}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import type { Token } from './scaffolding/types';
|
|
3
|
+
import type { ContrastPair } from '../core/palettes/contrastPairs';
|
|
3
4
|
|
|
4
5
|
export const component = 'codesnippet';
|
|
5
6
|
|
|
@@ -33,6 +34,15 @@
|
|
|
33
34
|
};
|
|
34
35
|
|
|
35
36
|
export const allTokens: Token[] = Object.values(states).flat();
|
|
37
|
+
|
|
38
|
+
// The copy button and the scrollbar track paint no surface of their own.
|
|
39
|
+
const surface = ['--codesnippet-surface'];
|
|
40
|
+
export const contrastPairs: ContrastPair[] = [
|
|
41
|
+
{ foreground: '--codesnippet-code-text', backdrop: surface, role: 'text', fontSize: '--codesnippet-code-font-size', fontWeight: '--codesnippet-code-font-weight' },
|
|
42
|
+
{ foreground: '--codesnippet-icon', backdrop: surface, role: 'non-text' },
|
|
43
|
+
{ foreground: '--codesnippet-hover-icon', backdrop: surface, role: 'non-text' },
|
|
44
|
+
{ foreground: '--codesnippet-scrollbar-thumb', backdrop: surface, role: 'non-text' },
|
|
45
|
+
];
|
|
36
46
|
</script>
|
|
37
47
|
|
|
38
48
|
<script lang="ts">
|
|
@@ -52,7 +62,7 @@
|
|
|
52
62
|
<VariantGroup name="codesnippet" title="Code Snippet" {states} {component}>
|
|
53
63
|
{#snippet children({ activeState })}
|
|
54
64
|
<div class="codesnippet-preview">
|
|
55
|
-
<label class="preview-text">
|
|
65
|
+
<label class="preview-text" data-preview-demo>
|
|
56
66
|
<span>Preview text</span>
|
|
57
67
|
<textarea
|
|
58
68
|
bind:value={previewCode}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { buildTypeGroupColorTokens } from './scaffolding/buildTypeGroupTokens';
|
|
3
3
|
import type { Token, TypeGroupConfig } from './scaffolding/types';
|
|
4
|
+
import type { ContrastPair } from '../core/palettes/contrastPairs';
|
|
4
5
|
|
|
5
6
|
export const component = 'collapsiblesection';
|
|
6
7
|
|
|
@@ -117,6 +118,22 @@
|
|
|
117
118
|
]);
|
|
118
119
|
|
|
119
120
|
const variantOptions = VARIANTS.map((v) => ({ value: v, label: VARIANT_LABELS[v] }));
|
|
121
|
+
|
|
122
|
+
function headerContrastPairs(v: Variant, s: HeaderState): ContrastPair[] {
|
|
123
|
+
const backdrop = [`--collapsiblesection-${v}-${s}-surface`];
|
|
124
|
+
return [
|
|
125
|
+
...variantTypeGroups(v)[`Header / ${HEADER_STATE_LABELS[s]}`].map((g): ContrastPair => ({
|
|
126
|
+
foreground: g.colorVariable,
|
|
127
|
+
backdrop,
|
|
128
|
+
role: 'text',
|
|
129
|
+
fontSize: g.sizeVariable,
|
|
130
|
+
fontWeight: g.weightVariable,
|
|
131
|
+
})),
|
|
132
|
+
{ foreground: `--collapsiblesection-${v}-${s}-icon`, backdrop, role: 'non-text' },
|
|
133
|
+
];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export const contrastPairs: ContrastPair[] = VARIANTS.flatMap((v) => HEADER_STATES.flatMap((s) => headerContrastPairs(v, s)));
|
|
120
137
|
</script>
|
|
121
138
|
|
|
122
139
|
<script lang="ts">
|
|
@@ -155,7 +172,7 @@
|
|
|
155
172
|
open={isBody}
|
|
156
173
|
class={forceClass}
|
|
157
174
|
>
|
|
158
|
-
<p style="margin: 0; color: var(--text-secondary);">
|
|
175
|
+
<p style="margin: 0; color: var(--text-secondary);" data-preview-demo>
|
|
159
176
|
{#if isContainerPart}
|
|
160
177
|
(Container) — outer chrome only; switch to Body to see the content area.
|
|
161
178
|
{:else}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import type { Token } from './scaffolding/types';
|
|
3
|
+
import type { ContrastPair } from '../core/palettes/contrastPairs';
|
|
3
4
|
import { badgeVariants } from '../../system/components/Badge.svelte';
|
|
4
5
|
|
|
5
6
|
export const component = 'cornerbadge';
|
|
@@ -40,6 +41,18 @@
|
|
|
40
41
|
];
|
|
41
42
|
|
|
42
43
|
const variantOptions = badgeVariants.map((v) => ({ value: v, label: v.charAt(0).toUpperCase() + v.slice(1) }));
|
|
44
|
+
|
|
45
|
+
function variantContrastPairs(v: Variant): ContrastPair[] {
|
|
46
|
+
return [{
|
|
47
|
+
foreground: `--cornerbadge-${v}-text`,
|
|
48
|
+
backdrop: [`--cornerbadge-${v}-surface`],
|
|
49
|
+
role: 'text',
|
|
50
|
+
fontSize: '--cornerbadge-text-font-size',
|
|
51
|
+
fontWeight: '--cornerbadge-text-font-weight',
|
|
52
|
+
}];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const contrastPairs: ContrastPair[] = badgeVariants.flatMap(variantContrastPairs);
|
|
43
56
|
</script>
|
|
44
57
|
|
|
45
58
|
<script lang="ts">
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { buildTypeGroupColorTokens } from './scaffolding/buildTypeGroupTokens';
|
|
3
3
|
import type { Token, TypeGroupConfig } from './scaffolding/types';
|
|
4
|
+
import type { ContrastPair } from '../core/palettes/contrastPairs';
|
|
4
5
|
|
|
5
6
|
export const component = 'dialog';
|
|
6
7
|
|
|
@@ -85,6 +86,20 @@
|
|
|
85
86
|
function variantLabel(v: ButtonVariant): string {
|
|
86
87
|
return v.charAt(0).toUpperCase() + v.slice(1);
|
|
87
88
|
}
|
|
89
|
+
|
|
90
|
+
// The header and body sit on the dialog box, and the box sits on the scrim.
|
|
91
|
+
const boxStack = ['--dialog-surface', '--dialog-scrim-surface'];
|
|
92
|
+
const headerStack = ['--dialog-header-surface', ...boxStack];
|
|
93
|
+
const textPair = (part: string, backdrop: string[]): ContrastPair => {
|
|
94
|
+
const g = frameTypeGroups[part][0];
|
|
95
|
+
return { foreground: g.colorVariable, backdrop, role: 'text', fontSize: g.sizeVariable, fontWeight: g.weightVariable };
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export const contrastPairs: ContrastPair[] = [
|
|
99
|
+
textPair('header', headerStack),
|
|
100
|
+
{ foreground: '--dialog-close-icon', backdrop: headerStack, role: 'non-text' },
|
|
101
|
+
textPair('body', boxStack),
|
|
102
|
+
];
|
|
88
103
|
</script>
|
|
89
104
|
|
|
90
105
|
<script lang="ts">
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { buildSiblings } from './scaffolding/siblings';
|
|
3
3
|
import type { Token, IntrinsicSpec } from './scaffolding/types';
|
|
4
|
+
import type { ContrastPair } from '../core/palettes/contrastPairs';
|
|
4
5
|
|
|
5
6
|
export const component = 'iconbutton';
|
|
6
7
|
|
|
@@ -104,6 +105,32 @@
|
|
|
104
105
|
default: { default: 'var(--color-transparent)' },
|
|
105
106
|
},
|
|
106
107
|
];
|
|
108
|
+
|
|
109
|
+
function variantContrastPairs(v: Variant): ContrastPair[] {
|
|
110
|
+
const icon = (s: StateName) => `${statePrefix(v, s)}-icon`;
|
|
111
|
+
const surface = (s: StateName) => `${statePrefix(v, s)}-surface`;
|
|
112
|
+
const hoverStack = ['--iconbutton-hover-tint-enabled', surface('hover')];
|
|
113
|
+
const disabled: ContrastPair = { foreground: icon('disabled'), backdrop: [surface('disabled')], role: 'non-text', inactive: true };
|
|
114
|
+
if (v !== 'outline') {
|
|
115
|
+
return [
|
|
116
|
+
{ foreground: icon('default'), backdrop: [surface('default')], role: 'non-text' },
|
|
117
|
+
{ foreground: icon('hover'), backdrop: hoverStack, role: 'non-text' },
|
|
118
|
+
disabled,
|
|
119
|
+
];
|
|
120
|
+
}
|
|
121
|
+
// `:active` repaints the surface without the tint. A pointer press keeps the
|
|
122
|
+
// hover icon color, and a key press keeps the default one.
|
|
123
|
+
const active = ['--iconbutton-outline-active-surface'];
|
|
124
|
+
return [
|
|
125
|
+
{ foreground: icon('default'), backdrop: [surface('default')], role: 'non-text', context: 'default' },
|
|
126
|
+
{ foreground: icon('default'), backdrop: active, role: 'non-text', context: 'active' },
|
|
127
|
+
{ foreground: icon('hover'), backdrop: hoverStack, role: 'non-text', context: 'hover' },
|
|
128
|
+
{ foreground: icon('hover'), backdrop: active, role: 'non-text', context: 'active' },
|
|
129
|
+
disabled,
|
|
130
|
+
];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export const contrastPairs: ContrastPair[] = variants.flatMap(variantContrastPairs);
|
|
107
134
|
</script>
|
|
108
135
|
|
|
109
136
|
<script lang="ts">
|
|
@@ -113,6 +140,7 @@
|
|
|
113
140
|
import { editorState, setComponentAlias, clearComponentAlias } from '../core/store/editorStore';
|
|
114
141
|
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
115
142
|
import Toggle from '../ui/Toggle.svelte';
|
|
143
|
+
import A11yPropertyMark from '../ui/a11y/A11yPropertyMark.svelte';
|
|
116
144
|
import UIPaletteSelector from '../ui/UIPaletteSelector.svelte';
|
|
117
145
|
|
|
118
146
|
// One switch. Turning the tint on also stands each hover surface down to its
|
|
@@ -193,7 +221,7 @@
|
|
|
193
221
|
{#snippet extraPropertyRows(stateName)}
|
|
194
222
|
{#if stateName === 'hover'}
|
|
195
223
|
<div class="property-row" data-token-variables="--iconbutton-hover-tint-enabled">
|
|
196
|
-
<span class="property-label">tint layer
|
|
224
|
+
<span class="property-label">tint layer<A11yPropertyMark variables={['--iconbutton-hover-tint-enabled']} /></span>
|
|
197
225
|
<Toggle checked={tintOn} onchange={setTintOn} />
|
|
198
226
|
</div>
|
|
199
227
|
{#if tintOn}
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
51
51
|
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
52
52
|
import { buildSiblings } from './scaffolding/siblings';
|
|
53
|
+
import A11yPropertyMark from '../ui/a11y/A11yPropertyMark.svelte';
|
|
53
54
|
import demoImageUrl from '../../system/assets/newspaper.webp';
|
|
54
55
|
import { editorState, setComponentAlias } from '../core/store/editorStore';
|
|
55
56
|
|
|
@@ -77,17 +78,23 @@
|
|
|
77
78
|
<ComponentEditorBase {component} title="Image" description="Picture in the page flow. Default frames it with rounded corners, a border, and a shadow. Bare shows the picture alone." tokens={allTokens} variants={variantOptions}>
|
|
78
79
|
<VariantGroup name="default" title="Default" states={variantStates('default')} {component} siblings={buildSiblings(variants, 'default', variantStates)}>
|
|
79
80
|
{#snippet stateActions()}
|
|
80
|
-
<
|
|
81
|
-
<
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<
|
|
86
|
-
|
|
87
|
-
|
|
81
|
+
<span class="zoom-control" data-token-variables="--image-zoom-enabled">
|
|
82
|
+
<label class="zoom-enable">
|
|
83
|
+
<input type="checkbox" checked={useZoom} onchange={(e) => setUseZoom(e.currentTarget.checked)} />
|
|
84
|
+
<span>Use zoom on hover</span>
|
|
85
|
+
</label>
|
|
86
|
+
<A11yPropertyMark variables={['--image-zoom-enabled']} />
|
|
87
|
+
</span>
|
|
88
|
+
<span class="zoom-control" data-token-variables="--image-grow-enabled">
|
|
89
|
+
<label class="zoom-enable" class:disabled={!useZoom}>
|
|
90
|
+
<input type="checkbox" checked={overflowScaling} disabled={!useZoom} onchange={(e) => setOverflowScaling(e.currentTarget.checked)} />
|
|
91
|
+
<span>Overflow scaling (mask zoom to frame)</span>
|
|
92
|
+
</label>
|
|
93
|
+
<A11yPropertyMark variables={['--image-grow-enabled']} />
|
|
94
|
+
</span>
|
|
88
95
|
{/snippet}
|
|
89
96
|
<Image src={demoImageUrl} alt="Demo" size="banner" zoom={useZoom ? undefined : false} {overflowScaling} forceHover={useZoom} />
|
|
90
|
-
<p class="zoom-help">
|
|
97
|
+
<p class="zoom-help" data-preview-demo>
|
|
91
98
|
Use zoom on hover: every image scales on hover (a page can still force it per image with the
|
|
92
99
|
<code>zoom</code> prop). Overflow scaling on (default): the content zooms inside the fixed frame,
|
|
93
100
|
masked by overflow. Off: the whole framed image grows past its box. Override per image with
|
|
@@ -100,6 +107,10 @@
|
|
|
100
107
|
</ComponentEditorBase>
|
|
101
108
|
|
|
102
109
|
<style>
|
|
110
|
+
.zoom-control {
|
|
111
|
+
display: inline-flex;
|
|
112
|
+
align-items: center;
|
|
113
|
+
}
|
|
103
114
|
.zoom-enable {
|
|
104
115
|
display: inline-flex;
|
|
105
116
|
align-items: center;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import type { Token, IntrinsicSpec } from './scaffolding/types';
|
|
3
|
+
import type { ContrastPair } from '../core/palettes/contrastPairs';
|
|
3
4
|
|
|
4
5
|
export const component = 'imagelightbox';
|
|
5
6
|
|
|
@@ -39,13 +40,26 @@
|
|
|
39
40
|
default: { default: 'contain' },
|
|
40
41
|
},
|
|
41
42
|
];
|
|
43
|
+
|
|
44
|
+
// One color paints the chrome's icons and its extra-small counter text. The
|
|
45
|
+
// chrome floats on the scrim.
|
|
46
|
+
const scrim = '--imagelightbox-scrim-surface';
|
|
47
|
+
export const contrastPairs: ContrastPair[] = [
|
|
48
|
+
{ foreground: '--imagelightbox-chrome-icon', backdrop: ['--imagelightbox-chrome-surface', scrim], role: 'non-text', context: 'icons' },
|
|
49
|
+
{ foreground: '--imagelightbox-chrome-icon', backdrop: ['--imagelightbox-chrome-hover-surface', scrim], role: 'non-text', context: 'hovered icons' },
|
|
50
|
+
{ foreground: '--imagelightbox-chrome-icon', backdrop: ['--imagelightbox-chrome-surface', scrim], role: 'text', fontSize: '--font-size-xs', context: 'counter' },
|
|
51
|
+
];
|
|
42
52
|
</script>
|
|
43
53
|
|
|
44
54
|
<script lang="ts">
|
|
45
55
|
import ImageLightbox from '../../system/components/ImageLightbox.svelte';
|
|
46
56
|
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
47
57
|
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
58
|
+
import UISegmentedControl from '../ui/UISegmentedControl.svelte';
|
|
59
|
+
import A11yPropertyMark from '../ui/a11y/A11yPropertyMark.svelte';
|
|
48
60
|
import newspaperUrl from '../../system/assets/newspaper.webp';
|
|
61
|
+
import { editorState, setComponentAlias } from '../core/store/editorStore';
|
|
62
|
+
import type { CssVarRef } from '../core/store/editorTypes';
|
|
49
63
|
|
|
50
64
|
const demoImages = [
|
|
51
65
|
// The first entry carries explicit dimensions (the no-reflow path); the second
|
|
@@ -56,6 +70,18 @@
|
|
|
56
70
|
|
|
57
71
|
let multiple = $state(true);
|
|
58
72
|
let shadow = $state<'box' | 'content' | 'none'>('box');
|
|
73
|
+
|
|
74
|
+
type TileFit = 'contain' | 'cover';
|
|
75
|
+
const TILE_FIT = intrinsics[0].variable('default');
|
|
76
|
+
const fitOptions: { value: TileFit; label: string; title: string }[] = [
|
|
77
|
+
{ value: 'contain', label: 'Contain', title: 'Show the whole image inside the tile' },
|
|
78
|
+
{ value: 'cover', label: 'Cover', title: 'Crop the image to fill the tile' },
|
|
79
|
+
];
|
|
80
|
+
let tileFit = $derived.by((): TileFit => {
|
|
81
|
+
const ref = ($editorState.components[component]?.aliases as Record<string, CssVarRef> | undefined)?.[TILE_FIT];
|
|
82
|
+
const value = ref?.kind === 'literal' ? ref.value : intrinsics[0].default.default;
|
|
83
|
+
return value === 'cover' ? 'cover' : 'contain';
|
|
84
|
+
});
|
|
59
85
|
</script>
|
|
60
86
|
|
|
61
87
|
<ComponentEditorBase
|
|
@@ -79,6 +105,21 @@
|
|
|
79
105
|
</select>
|
|
80
106
|
</label>
|
|
81
107
|
{/snippet}
|
|
108
|
+
{#snippet extraPropertyRowsTop(stateName)}
|
|
109
|
+
{#if stateName === 'tile'}
|
|
110
|
+
<div class="property-row" data-token-variables={TILE_FIT}>
|
|
111
|
+
<span class="property-label">tile fit<A11yPropertyMark variables={[TILE_FIT]} /></span>
|
|
112
|
+
<div class="tile-fit-control">
|
|
113
|
+
<UISegmentedControl
|
|
114
|
+
value={tileFit}
|
|
115
|
+
options={fitOptions}
|
|
116
|
+
ariaLabel="Tile fit"
|
|
117
|
+
onchange={(value) => setComponentAlias(component, TILE_FIT, { kind: 'literal', value })}
|
|
118
|
+
/>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
{/if}
|
|
122
|
+
{/snippet}
|
|
82
123
|
<div class="preview-frame">
|
|
83
124
|
<ImageLightbox images={multiple ? demoImages : [demoImages[0]]} {shadow} extended />
|
|
84
125
|
</div>
|
|
@@ -91,6 +132,9 @@
|
|
|
91
132
|
max-width: 28rem;
|
|
92
133
|
margin: 0 auto;
|
|
93
134
|
}
|
|
135
|
+
.tile-fit-control {
|
|
136
|
+
display: flex;
|
|
137
|
+
}
|
|
94
138
|
.preview-toggle {
|
|
95
139
|
display: inline-flex;
|
|
96
140
|
align-items: center;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { buildSiblings } from './scaffolding/siblings';
|
|
3
3
|
import type { Token } from './scaffolding/types';
|
|
4
|
+
import type { ContrastPair } from '../core/palettes/contrastPairs';
|
|
4
5
|
|
|
5
6
|
export const component = 'inlineeditactions';
|
|
6
7
|
|
|
@@ -38,6 +39,17 @@
|
|
|
38
39
|
[`--inlineeditactions-${btn}-default-padding`, btn] as const,
|
|
39
40
|
[`--inlineeditactions-${btn}-default-icon-size`, btn] as const,
|
|
40
41
|
]));
|
|
42
|
+
|
|
43
|
+
// Each button holds a glyph and no text, so its color is a non-text pair.
|
|
44
|
+
function buttonContrastPairs(btn: Button): ContrastPair[] {
|
|
45
|
+
return (['default', 'hover'] as const).map((state) => ({
|
|
46
|
+
foreground: `--inlineeditactions-${btn}-${state}-text`,
|
|
47
|
+
backdrop: [`--inlineeditactions-${btn}-${state}-surface`],
|
|
48
|
+
role: 'non-text',
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const contrastPairs: ContrastPair[] = buttons.flatMap(buttonContrastPairs);
|
|
41
53
|
</script>
|
|
42
54
|
|
|
43
55
|
<script lang="ts">
|
|
@@ -66,7 +78,7 @@
|
|
|
66
78
|
{#snippet children({ activeState })}
|
|
67
79
|
{@const forceClass = activeState === 'hover' ? 'force-hover' : ''}
|
|
68
80
|
<div class="inline-edit-demo-row">
|
|
69
|
-
<span style="color: var(--text-secondary);">Editing value...</span>
|
|
81
|
+
<span style="color: var(--text-secondary);" data-preview-demo>Editing value...</span>
|
|
70
82
|
<InlineEditActions
|
|
71
83
|
onsave={() => {}}
|
|
72
84
|
oncancel={() => {}}
|