@motion-proto/live-tokens 0.97.0 → 0.99.0
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 +339 -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 +144 -19
- 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 +204 -3
- package/dist-plugin/index.js +306 -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 +5 -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 +40 -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 +164 -0
- package/src/editor/core/a11y/a11yReportTypes.ts +77 -0
- package/src/editor/core/a11y/contrastFailures.ts +22 -0
- package/src/editor/core/a11y/contrastFixes.ts +41 -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 +82 -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 +411 -0
- package/src/editor/docs/content/editing-tokens.md +32 -1
- package/src/editor/docs/content.generated.ts +2 -1
- package/src/editor/pages/ComponentEditorPage.svelte +11 -1
- package/src/editor/pages/EditorShell.svelte +98 -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/styles/ui-editor.css +2 -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 +9 -0
- package/src/editor/ui/UITokenSelector.svelte +26 -2
- package/src/editor/ui/a11y/A11yByEye.svelte +264 -0
- package/src/editor/ui/a11y/A11yComponentIssues.svelte +121 -0
- package/src/editor/ui/a11y/A11yFindingRow.svelte +119 -0
- package/src/editor/ui/a11y/A11yIssueRow.svelte +152 -0
- package/src/editor/ui/a11y/A11yOverview.svelte +246 -0
- package/src/editor/ui/a11y/A11yPanel.svelte +153 -0
- package/src/editor/ui/a11y/A11yPropertyMark.svelte +84 -0
- package/src/editor/ui/a11y/A11yRailMark.svelte +41 -0
- package/src/editor/ui/a11y/AccessibilityTab.svelte +321 -0
- package/src/editor/ui/a11y/a11yView.ts +257 -0
- package/src/editor/ui/contrastReadout.ts +45 -0
- package/src/live-tokens/data/colors-and-type/halloween.json +1 -1
- package/src/live-tokens/data/themes/autumn.json +35 -35
- package/src/live-tokens/data/themes/halloween.json +36 -36
- package/src/live-tokens/data/themes/midnight-study.json +35 -35
- package/src/live-tokens/data/themes/ocean.json +35 -35
- package/src/live-tokens/data/themes/royal-velvet.json +35 -35
- package/src/live-tokens/data/themes/sketchy.json +35 -35
- package/src/live-tokens/data/themes/spring-meadow.json +35 -35
- package/src/live-tokens/data/themes/sunset.json +35 -35
- package/src/system/components/Badge.svelte +3 -3
- package/src/system/components/Button.svelte +12 -6
- 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/InlineEditActions.svelte +1 -1
- package/src/system/components/Input.svelte +9 -2
- package/src/system/components/MenuSelect.svelte +31 -3
- package/src/system/components/Notification.svelte +1 -1
- package/src/system/components/ProgressBar.svelte +7 -1
- package/src/system/components/RadioButton.svelte +36 -3
- package/src/system/components/SegmentedControl.svelte +36 -2
- package/src/system/components/SlidePager.svelte +3 -3
- package/src/system/components/Slider.svelte +19 -15
- package/src/system/components/TabBar.svelte +33 -3
- package/src/system/components/Toggle.svelte +3 -3
- 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-NB3NZRBM.js → chunk-7CM5D7PF.js} +5 -1
- package/src/testing-js/chunk-7CM5D7PF.js.map +1 -0
- package/src/testing-js/{chunk-X6KHEVIG.js → chunk-7QXUJRSO.js} +97 -29
- package/src/testing-js/chunk-7QXUJRSO.js.map +1 -0
- package/src/testing-js/chunk-GZKUYLDW.js +193 -0
- package/src/testing-js/chunk-GZKUYLDW.js.map +1 -0
- package/src/testing-js/chunk-RTZQLW3F.js +649 -0
- package/src/testing-js/chunk-RTZQLW3F.js.map +1 -0
- package/src/testing-js/{chunk-SHBYZUPD.js → chunk-RWOT2XDB.js} +212 -15
- package/src/testing-js/chunk-RWOT2XDB.js.map +1 -0
- package/src/testing-js/{chunk-GKO27NGN.js → chunk-THWGMSRH.js} +2 -2
- 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 +313 -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 +11 -11
- package/src/testing-js/index.js.map +1 -1
- 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/_gitignore +3 -0
- 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-THWGMSRH.js.map} +0 -0
|
@@ -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={() => {}}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { buildTypeGroupTokens, buildTypeGroupShareableContexts } 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 = 'input';
|
|
6
7
|
|
|
@@ -146,6 +147,28 @@
|
|
|
146
147
|
// Silence unused-import lint without changing behavior; buildTypeGroupTokens stays available
|
|
147
148
|
// for editors that want auto-derived color rows, but we keep ours hand-built for slot-prefixed groupKeys.
|
|
148
149
|
void buildTypeGroupTokens;
|
|
150
|
+
|
|
151
|
+
function textPair(foreground: string, state: string, backdrop: string[]): ContrastPair {
|
|
152
|
+
const g = typeGroups[state][0];
|
|
153
|
+
return { foreground, backdrop, role: 'text', fontSize: g.sizeVariable, fontWeight: g.weightVariable };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// The placeholder paints on each state's surface at that state's text size.
|
|
157
|
+
// The icon button takes the focused icon color on hover and focus while the
|
|
158
|
+
// field itself stays unfocused. Label, hint and error sit on no surface.
|
|
159
|
+
export const contrastPairs: ContrastPair[] = [
|
|
160
|
+
textPair('--input-default-text', 'default', ['--input-default-surface']),
|
|
161
|
+
textPair('--input-focused-text', 'focused', ['--input-focused-surface']),
|
|
162
|
+
{ ...textPair('--input-disabled-text', 'disabled', ['--input-disabled-surface']), inactive: true },
|
|
163
|
+
{ ...textPair('--input-default-placeholder', 'default', ['--input-default-surface']), context: 'default' },
|
|
164
|
+
{ ...textPair('--input-default-placeholder', 'focused', ['--input-focused-surface']), context: 'focused' },
|
|
165
|
+
{ ...textPair('--input-default-placeholder', 'disabled', ['--input-disabled-surface']), context: 'disabled', inactive: true },
|
|
166
|
+
{ foreground: '--input-default-icon', backdrop: ['--input-default-surface'], role: 'non-text' },
|
|
167
|
+
{ foreground: '--input-focused-icon', backdrop: ['--input-focused-surface'], role: 'non-text', context: 'focused' },
|
|
168
|
+
{ foreground: '--input-focused-icon', backdrop: ['--input-default-surface'], role: 'non-text', context: 'icon button' },
|
|
169
|
+
{ foreground: '--input-disabled-icon', backdrop: ['--input-disabled-surface'], role: 'non-text', inactive: true },
|
|
170
|
+
...(['label', 'hint', 'error'] as const).map((slot) => textPair(`--input-${slot}`, slot, [])),
|
|
171
|
+
];
|
|
149
172
|
</script>
|
|
150
173
|
|
|
151
174
|
<script lang="ts">
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { buildTypeGroupTokens, buildTypeGroupShareableContexts } 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 = 'menuselect';
|
|
6
7
|
|
|
@@ -106,6 +107,29 @@
|
|
|
106
107
|
default: { default: 'var(--color-transparent)' },
|
|
107
108
|
},
|
|
108
109
|
];
|
|
110
|
+
|
|
111
|
+
// Every item sits on the menu surface. The check mark paints on the selected item alone.
|
|
112
|
+
const menu = '--menuselect-menu-surface';
|
|
113
|
+
function itemContrastPairs(s: 'default' | 'hover' | 'selected' | 'disabled'): ContrastPair[] {
|
|
114
|
+
const backdrop = s === 'hover'
|
|
115
|
+
? ['--menuselect-hover-tint-enabled', '--menuselect-hover-surface', menu]
|
|
116
|
+
: [`--menuselect-${s}-surface`, menu];
|
|
117
|
+
const inactive = s === 'disabled' ? { inactive: true } : {};
|
|
118
|
+
const marks = s === 'selected' ? ['--menuselect-selected-icon', '--menuselect-selected-indicator'] : [`--menuselect-${s}-icon`];
|
|
119
|
+
return [
|
|
120
|
+
...typeGroups[`${s} item`].map((g): ContrastPair => ({
|
|
121
|
+
foreground: g.colorVariable,
|
|
122
|
+
backdrop,
|
|
123
|
+
role: 'text',
|
|
124
|
+
fontSize: g.sizeVariable,
|
|
125
|
+
fontWeight: g.weightVariable,
|
|
126
|
+
...inactive,
|
|
127
|
+
})),
|
|
128
|
+
...marks.map((foreground): ContrastPair => ({ foreground, backdrop, role: 'non-text', ...inactive })),
|
|
129
|
+
];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export const contrastPairs: ContrastPair[] = (['default', 'hover', 'selected', 'disabled'] as const).flatMap(itemContrastPairs);
|
|
109
133
|
</script>
|
|
110
134
|
|
|
111
135
|
<script lang="ts">
|
|
@@ -115,6 +139,7 @@
|
|
|
115
139
|
import { editorState, setComponentAlias, clearComponentAlias } from '../core/store/editorStore';
|
|
116
140
|
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
117
141
|
import Toggle from '../ui/Toggle.svelte';
|
|
142
|
+
import A11yPropertyMark from '../ui/a11y/A11yPropertyMark.svelte';
|
|
118
143
|
import UIPaletteSelector from '../ui/UIPaletteSelector.svelte';
|
|
119
144
|
|
|
120
145
|
// One switch. Turning the tint on also stands each hover surface down to its
|
|
@@ -178,7 +203,7 @@
|
|
|
178
203
|
{#snippet extraPropertyRows(stateName)}
|
|
179
204
|
{#if stateName === 'hover item'}
|
|
180
205
|
<div class="property-row" data-token-variables="--menuselect-hover-tint-enabled">
|
|
181
|
-
<span class="property-label">tint layer
|
|
206
|
+
<span class="property-label">tint layer<A11yPropertyMark variables={['--menuselect-hover-tint-enabled']} /></span>
|
|
182
207
|
<Toggle checked={tintOn} onchange={setTintOn} />
|
|
183
208
|
</div>
|
|
184
209
|
{#if tintOn}
|
|
@@ -203,6 +228,7 @@
|
|
|
203
228
|
items={previewItems}
|
|
204
229
|
value={previewValue}
|
|
205
230
|
forceHoverValue={previewForceHover}
|
|
231
|
+
ariaLabel="Options"
|
|
206
232
|
/>
|
|
207
233
|
{/snippet}
|
|
208
234
|
</VariantGroup>
|
|
@@ -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 = 'notification';
|
|
5
6
|
const variants = ['info', 'success', 'warning', 'danger'] as const;
|
|
@@ -67,6 +68,20 @@
|
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
const variantOptions = variants.map((v) => ({ value: v, label: v.charAt(0).toUpperCase() + v.slice(1) }));
|
|
71
|
+
|
|
72
|
+
// The body color also paints the dismiss button on the header. The body has
|
|
73
|
+
// no surface, and size="small" sets its description in --font-size-sm.
|
|
74
|
+
function variantContrastPairs(v: Variant): ContrastPair[] {
|
|
75
|
+
const header = [`--notification-${v}-surface`];
|
|
76
|
+
return [
|
|
77
|
+
{ foreground: `--notification-${v}-title`, backdrop: header, role: 'text', fontSize: `--notification-${v}-title-font-size`, fontWeight: `--notification-${v}-title-font-weight` },
|
|
78
|
+
{ foreground: `--notification-${v}-icon`, backdrop: header, role: 'non-text' },
|
|
79
|
+
{ foreground: `--notification-${v}-text`, backdrop: header, role: 'non-text', context: 'dismiss button' },
|
|
80
|
+
{ foreground: `--notification-${v}-text`, backdrop: [], role: 'text', fontSize: '--font-size-sm', fontWeight: `--notification-${v}-text-font-weight`, context: 'body' },
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export const contrastPairs: ContrastPair[] = variants.flatMap(variantContrastPairs);
|
|
70
85
|
</script>
|
|
71
86
|
|
|
72
87
|
<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 = 'progressbar';
|
|
6
7
|
|
|
@@ -71,6 +72,18 @@
|
|
|
71
72
|
...buildTypeGroupColorTokens(typeGroups, { component }),
|
|
72
73
|
...typeGroupTokens,
|
|
73
74
|
];
|
|
75
|
+
|
|
76
|
+
// The label and value sit on no surface. The fill paints on the track.
|
|
77
|
+
export const contrastPairs: ContrastPair[] = [
|
|
78
|
+
...typeGroups.default.map((g): ContrastPair => ({
|
|
79
|
+
foreground: g.colorVariable,
|
|
80
|
+
backdrop: [],
|
|
81
|
+
role: 'text',
|
|
82
|
+
fontSize: g.sizeVariable,
|
|
83
|
+
fontWeight: g.weightVariable,
|
|
84
|
+
})),
|
|
85
|
+
{ foreground: '--progressbar-fill', backdrop: ['--progressbar-track-surface'], role: 'non-text' },
|
|
86
|
+
];
|
|
74
87
|
</script>
|
|
75
88
|
|
|
76
89
|
<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 = 'radiobutton';
|
|
6
7
|
|
|
@@ -79,6 +80,24 @@
|
|
|
79
80
|
...buildTypeGroupColorTokens(typeGroups, { component, variants: Object.keys(states) }),
|
|
80
81
|
...typeGroupTokens,
|
|
81
82
|
];
|
|
83
|
+
|
|
84
|
+
// The button paints no surface without the `color` prop, and the default dot
|
|
85
|
+
// stays hidden.
|
|
86
|
+
function stateContrastPairs(s: 'default' | 'hover' | 'selected'): ContrastPair[] {
|
|
87
|
+
const marks = s === 'default' ? ['--radiobutton-default-dot-border-color'] : [`--radiobutton-${s}-dot-border-color`, `--radiobutton-${s}-dot-fill`];
|
|
88
|
+
return [
|
|
89
|
+
...typeGroups[s].map((g): ContrastPair => ({
|
|
90
|
+
foreground: g.colorVariable,
|
|
91
|
+
backdrop: [],
|
|
92
|
+
role: 'text',
|
|
93
|
+
fontSize: g.sizeVariable,
|
|
94
|
+
fontWeight: g.weightVariable,
|
|
95
|
+
})),
|
|
96
|
+
...marks.map((foreground): ContrastPair => ({ foreground, backdrop: [], role: 'non-text' })),
|
|
97
|
+
];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export const contrastPairs: ContrastPair[] = (['default', 'hover', 'selected'] as const).flatMap(stateContrastPairs);
|
|
82
101
|
</script>
|
|
83
102
|
|
|
84
103
|
<script lang="ts">
|
|
@@ -109,7 +128,7 @@
|
|
|
109
128
|
{#snippet children({ activeState })}
|
|
110
129
|
{@const forceClass = activeState === 'hover' ? 'force-hover' : ''}
|
|
111
130
|
{@const forceSelected = activeState === 'selected'}
|
|
112
|
-
<div class="radio-demo-row">
|
|
131
|
+
<div class="radio-demo-row" role="radiogroup" aria-label="Priority">
|
|
113
132
|
<RadioButton
|
|
114
133
|
label="Defense"
|
|
115
134
|
selected={forceSelected || selectedRadio === 'option-a'}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { buildSiblings } from './scaffolding/siblings';
|
|
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 = 'sectiondivider';
|
|
6
7
|
|
|
@@ -193,6 +194,21 @@
|
|
|
193
194
|
},
|
|
194
195
|
];
|
|
195
196
|
const INTRINSIC_BY_KEY = new Map(intrinsics.map((i) => [i.key, i]));
|
|
197
|
+
|
|
198
|
+
// The hairline is decorative: the heading carries the section break, so
|
|
199
|
+
// WCAG 2.2 SC 1.4.11 sets no floor on it and it has no pair.
|
|
200
|
+
function variantContrastPairs(v: Variant): ContrastPair[] {
|
|
201
|
+
const backdrop = [`--sectiondivider-${v}-surface`];
|
|
202
|
+
return variantTypeGroups(v).map((g): ContrastPair => ({
|
|
203
|
+
foreground: g.colorVariable,
|
|
204
|
+
backdrop,
|
|
205
|
+
role: 'text',
|
|
206
|
+
fontSize: g.sizeVariable,
|
|
207
|
+
fontWeight: g.weightVariable,
|
|
208
|
+
}));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export const contrastPairs: ContrastPair[] = variants.flatMap((v) => variantContrastPairs(v.key));
|
|
196
212
|
</script>
|
|
197
213
|
|
|
198
214
|
<script lang="ts">
|
|
@@ -200,6 +216,7 @@
|
|
|
200
216
|
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
201
217
|
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
202
218
|
import GradientEditor from '../ui/GradientEditor.svelte';
|
|
219
|
+
import A11yPropertyMark from '../ui/a11y/A11yPropertyMark.svelte';
|
|
203
220
|
import { editorState, mutate, setComponentAlias, setComponentConfig } from '../core/store/editorStore';
|
|
204
221
|
import { componentGradientSource } from '../core/store/gradientSource';
|
|
205
222
|
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
@@ -376,16 +393,19 @@
|
|
|
376
393
|
description: {
|
|
377
394
|
checked: getShowDescription(v),
|
|
378
395
|
label: 'Show description',
|
|
396
|
+
variables: [`--sectiondivider-${v}-description-display`],
|
|
379
397
|
onchange: (c: boolean) => setIntrinsic(v, 'description-display', c ? 'flex' : 'none'),
|
|
380
398
|
},
|
|
381
399
|
eyebrow: {
|
|
382
400
|
checked: getShowEyebrow(v),
|
|
383
401
|
label: 'Show eyebrow',
|
|
402
|
+
variables: [`--sectiondivider-${v}-eyebrow-display`],
|
|
384
403
|
onchange: (c: boolean) => setIntrinsic(v, 'eyebrow-display', c ? 'block' : 'none'),
|
|
385
404
|
},
|
|
386
405
|
hairline: {
|
|
387
406
|
checked: getShowHairline(v),
|
|
388
407
|
label: 'Show',
|
|
408
|
+
variables: [`--sectiondivider-${v}-hairline`],
|
|
389
409
|
onchange: (c: boolean) => setIntrinsic(v, 'hairline', c ? getHairlinePosition(v) : 'none'),
|
|
390
410
|
},
|
|
391
411
|
};
|
|
@@ -431,8 +451,8 @@
|
|
|
431
451
|
</div>
|
|
432
452
|
{/snippet}
|
|
433
453
|
{#snippet extraPropertyRowsTop(_stateName)}
|
|
434
|
-
<div class="property-row sd-intrinsic-row">
|
|
435
|
-
<span class="property-label">alignment
|
|
454
|
+
<div class="property-row sd-intrinsic-row" data-token-variables={`--sectiondivider-${v.key}-align`}>
|
|
455
|
+
<span class="property-label">alignment<A11yPropertyMark variables={[`--sectiondivider-${v.key}-align`]} /></span>
|
|
436
456
|
<select
|
|
437
457
|
class="sd-intrinsic-select"
|
|
438
458
|
value={getAlign(v.key)}
|
|
@@ -462,18 +482,21 @@
|
|
|
462
482
|
{/snippet}
|
|
463
483
|
{#snippet elementExtras(elementName)}
|
|
464
484
|
{#if elementName === 'eyebrow'}
|
|
465
|
-
<
|
|
466
|
-
<
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
485
|
+
<span class="sd-element-check-host" data-token-variables={`--sectiondivider-${v.key}-eyebrow-text-transform`}>
|
|
486
|
+
<label class="sd-element-check">
|
|
487
|
+
<input
|
|
488
|
+
type="checkbox"
|
|
489
|
+
checked={getEyebrowUppercase(v.key)}
|
|
490
|
+
onchange={(e) => setIntrinsic(v.key, 'eyebrow-text-transform', (e.currentTarget as HTMLInputElement).checked ? 'uppercase' : 'none')}
|
|
491
|
+
/>
|
|
492
|
+
<span>All caps</span>
|
|
493
|
+
</label>
|
|
494
|
+
<A11yPropertyMark variables={[`--sectiondivider-${v.key}-eyebrow-text-transform`]} />
|
|
495
|
+
</span>
|
|
473
496
|
{/if}
|
|
474
497
|
{#if elementName === 'hairline'}
|
|
475
|
-
<div class="property-row sd-intrinsic-row sd-hairline-position-row">
|
|
476
|
-
<span class="property-label">position
|
|
498
|
+
<div class="property-row sd-intrinsic-row sd-hairline-position-row" data-token-variables={`--sectiondivider-${v.key}-hairline`}>
|
|
499
|
+
<span class="property-label">position<A11yPropertyMark variables={[`--sectiondivider-${v.key}-hairline`]} /></span>
|
|
477
500
|
<select
|
|
478
501
|
class="sd-intrinsic-select"
|
|
479
502
|
value={getHairlinePosition(v.key)}
|
|
@@ -551,6 +574,11 @@
|
|
|
551
574
|
/* Inline boolean control inside an element-section (e.g. "All caps" under
|
|
552
575
|
the eyebrow heading). Sits flush-left so it reads as a section property
|
|
553
576
|
rather than aligning with the token grid below. */
|
|
577
|
+
:global(.sd-element-check-host) {
|
|
578
|
+
display: inline-flex;
|
|
579
|
+
align-items: center;
|
|
580
|
+
margin-bottom: var(--ui-space-4);
|
|
581
|
+
}
|
|
554
582
|
:global(.sd-element-check) {
|
|
555
583
|
display: inline-flex;
|
|
556
584
|
align-items: center;
|
|
@@ -559,7 +587,6 @@
|
|
|
559
587
|
color: var(--ui-text-secondary);
|
|
560
588
|
cursor: pointer;
|
|
561
589
|
user-select: none;
|
|
562
|
-
margin-bottom: var(--ui-space-4);
|
|
563
590
|
}
|
|
564
591
|
:global(.sd-element-check:hover) { color: var(--ui-text-primary); }
|
|
565
592
|
:global(.sd-element-check input) { margin: 0; cursor: pointer; }
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { buildTypeGroupTokens, buildTypeGroupShareableContexts } 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 = 'segmentedcontrol';
|
|
6
7
|
|
|
@@ -140,6 +141,32 @@
|
|
|
140
141
|
default: { default: 'var(--color-transparent)' },
|
|
141
142
|
},
|
|
142
143
|
];
|
|
144
|
+
|
|
145
|
+
// Every option sits on the bar, and the default option paints no surface of
|
|
146
|
+
// its own. The small size sets every option's text in
|
|
147
|
+
// --segmentedcontrol-option-small-text-font-size, the smaller of its two sizes.
|
|
148
|
+
function optionContrastPairs(state: string, icon: string, backdrop: string[]): ContrastPair[] {
|
|
149
|
+
const inactive = state === 'disabled option' ? { inactive: true } : {};
|
|
150
|
+
return [
|
|
151
|
+
...typeGroups[state].map((g): ContrastPair => ({
|
|
152
|
+
foreground: g.colorVariable,
|
|
153
|
+
backdrop,
|
|
154
|
+
role: 'text',
|
|
155
|
+
fontSize: '--segmentedcontrol-option-small-text-font-size',
|
|
156
|
+
fontWeight: g.weightVariable,
|
|
157
|
+
...inactive,
|
|
158
|
+
})),
|
|
159
|
+
{ foreground: icon, backdrop, role: 'non-text', ...inactive },
|
|
160
|
+
];
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const bar = '--segmentedcontrol-bar-surface';
|
|
164
|
+
export const contrastPairs: ContrastPair[] = [
|
|
165
|
+
...optionContrastPairs('default option', '--segmentedcontrol-option-icon', [bar]),
|
|
166
|
+
...optionContrastPairs('hover option', '--segmentedcontrol-option-hover-icon', ['--segmentedcontrol-hover-tint-enabled', '--segmentedcontrol-option-hover-surface', bar]),
|
|
167
|
+
...optionContrastPairs('selected option', '--segmentedcontrol-selected-icon', ['--segmentedcontrol-selected-surface', bar]),
|
|
168
|
+
...optionContrastPairs('disabled option', '--segmentedcontrol-disabled-icon', ['--segmentedcontrol-disabled-surface', bar]),
|
|
169
|
+
];
|
|
143
170
|
</script>
|
|
144
171
|
|
|
145
172
|
<script lang="ts">
|
|
@@ -149,6 +176,7 @@
|
|
|
149
176
|
import { editorState, setComponentAlias, clearComponentAlias } from '../core/store/editorStore';
|
|
150
177
|
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
151
178
|
import Toggle from '../ui/Toggle.svelte';
|
|
179
|
+
import A11yPropertyMark from '../ui/a11y/A11yPropertyMark.svelte';
|
|
152
180
|
import UIPaletteSelector from '../ui/UIPaletteSelector.svelte';
|
|
153
181
|
|
|
154
182
|
// One switch. Turning the tint on also stands each hover surface down to its
|
|
@@ -214,7 +242,7 @@
|
|
|
214
242
|
{#snippet extraPropertyRows(stateName)}
|
|
215
243
|
{#if stateName === 'hover option'}
|
|
216
244
|
<div class="property-row" data-token-variables="--segmentedcontrol-hover-tint-enabled">
|
|
217
|
-
<span class="property-label">tint layer
|
|
245
|
+
<span class="property-label">tint layer<A11yPropertyMark variables={['--segmentedcontrol-hover-tint-enabled']} /></span>
|
|
218
246
|
<Toggle checked={tintOn} onchange={setTintOn} />
|
|
219
247
|
</div>
|
|
220
248
|
{#if tintOn}
|
|
@@ -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 = 'sidenavigation';
|
|
6
7
|
|
|
@@ -271,6 +272,43 @@
|
|
|
271
272
|
default: { default: 'var(--color-transparent)' },
|
|
272
273
|
},
|
|
273
274
|
];
|
|
275
|
+
|
|
276
|
+
// Every part sits on the panel, and a hover rule lays the tint over its
|
|
277
|
+
// surface. The section header's own CollapsibleSection surface belongs to
|
|
278
|
+
// that component and stays out of the stack.
|
|
279
|
+
const panel = '--sidenavigation-panel-surface';
|
|
280
|
+
const tint = '--sidenavigation-hover-tint-enabled';
|
|
281
|
+
const partStack = (part: string, s: string): string[] =>
|
|
282
|
+
s === 'hover' ? [tint, `--sidenavigation-${part}-hover-surface`] : [`--sidenavigation-${part}-${s}-surface`];
|
|
283
|
+
const textPairs = (groups: TypeGroupConfig[], backdrop: string[]): ContrastPair[] =>
|
|
284
|
+
groups.map((g) => ({ foreground: g.colorVariable, backdrop, role: 'text', fontSize: g.sizeVariable, fontWeight: g.weightVariable }));
|
|
285
|
+
|
|
286
|
+
// The toggle sits on the title, which a pointer on the toggle also hovers.
|
|
287
|
+
const toggleContrastPairs: ContrastPair[] = [
|
|
288
|
+
...STATEFUL_STATES.map((title): ContrastPair => ({
|
|
289
|
+
foreground: '--sidenavigation-toggle-default-icon',
|
|
290
|
+
backdrop: ['--sidenavigation-toggle-default-surface', ...partStack('title', title), panel],
|
|
291
|
+
role: 'non-text',
|
|
292
|
+
context: `title ${title}`,
|
|
293
|
+
})),
|
|
294
|
+
...(['hover', 'selected'] as const).map((title): ContrastPair => ({
|
|
295
|
+
foreground: '--sidenavigation-toggle-hover-icon',
|
|
296
|
+
backdrop: [...partStack('toggle', 'hover'), ...partStack('title', title), panel],
|
|
297
|
+
role: 'non-text',
|
|
298
|
+
context: `title ${title}`,
|
|
299
|
+
})),
|
|
300
|
+
];
|
|
301
|
+
|
|
302
|
+
export const contrastPairs: ContrastPair[] = [
|
|
303
|
+
...STATEFUL_STATES.flatMap((s): ContrastPair[] => [
|
|
304
|
+
...textPairs(titleStateTypeGroups(s), ['--sidenavigation-title-label-surface', ...partStack('title', s), panel]),
|
|
305
|
+
...textPairs(sectionStateTypeGroups(s), [...partStack('section', s), panel]),
|
|
306
|
+
...textPairs(itemStateTypeGroups(s), [...partStack('item', s), panel]),
|
|
307
|
+
...textPairs(footerStateTypeGroups(s), [...partStack('footer', s), panel]),
|
|
308
|
+
{ foreground: `--sidenavigation-footer-${s}-icon`, backdrop: [...partStack('footer', s), panel], role: 'non-text' },
|
|
309
|
+
]),
|
|
310
|
+
...toggleContrastPairs,
|
|
311
|
+
];
|
|
274
312
|
</script>
|
|
275
313
|
|
|
276
314
|
<script lang="ts">
|
|
@@ -280,6 +318,7 @@
|
|
|
280
318
|
import { editorState, setComponentAlias, clearComponentAlias } from '../core/store/editorStore';
|
|
281
319
|
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
282
320
|
import Toggle from '../ui/Toggle.svelte';
|
|
321
|
+
import A11yPropertyMark from '../ui/a11y/A11yPropertyMark.svelte';
|
|
283
322
|
import UIPaletteSelector from '../ui/UIPaletteSelector.svelte';
|
|
284
323
|
|
|
285
324
|
// One switch. Turning the tint on also stands each hover surface down to its
|
|
@@ -384,7 +423,7 @@
|
|
|
384
423
|
{#snippet extraPropertyRows(stateName)}
|
|
385
424
|
{#if stateName.endsWith(' / Hover')}
|
|
386
425
|
<div class="property-row" data-token-variables="--sidenavigation-hover-tint-enabled">
|
|
387
|
-
<span class="property-label">tint layer
|
|
426
|
+
<span class="property-label">tint layer<A11yPropertyMark variables={['--sidenavigation-hover-tint-enabled']} /></span>
|
|
388
427
|
<Toggle checked={tintOn} onchange={setTintOn} />
|
|
389
428
|
</div>
|
|
390
429
|
{#if tintOn}
|
|
@@ -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 = 'slidepager';
|
|
5
6
|
|
|
@@ -46,6 +47,25 @@
|
|
|
46
47
|
};
|
|
47
48
|
|
|
48
49
|
export const allTokens: Token[] = Object.values(states).flat();
|
|
50
|
+
|
|
51
|
+
// The bar sits on the page inline and on the scrim when zoomed.
|
|
52
|
+
const scrim = '--slidepager-scrim-surface';
|
|
53
|
+
function controlContrastPairs(foreground: string, surface: string, inactive: boolean): ContrastPair[] {
|
|
54
|
+
const flag = inactive ? { inactive } : {};
|
|
55
|
+
return [
|
|
56
|
+
{ foreground, backdrop: [surface], role: 'non-text', context: 'inline', ...flag },
|
|
57
|
+
{ foreground, backdrop: [surface, scrim], role: 'non-text', context: 'zoomed', ...flag },
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
const counter = { foreground: '--slidepager-counter-text', role: 'text', fontSize: '--slidepager-counter-font-size', fontWeight: '--slidepager-counter-font-weight' } as const;
|
|
61
|
+
|
|
62
|
+
export const contrastPairs: ContrastPair[] = [
|
|
63
|
+
...controlContrastPairs('--slidepager-control-icon', '--slidepager-control-surface', false),
|
|
64
|
+
...controlContrastPairs('--slidepager-control-hover-icon', '--slidepager-control-hover-surface', false),
|
|
65
|
+
...controlContrastPairs('--slidepager-control-disabled-icon', '--slidepager-control-disabled-surface', true),
|
|
66
|
+
{ ...counter, backdrop: [], context: 'inline' },
|
|
67
|
+
{ ...counter, backdrop: [scrim], context: 'zoomed' },
|
|
68
|
+
];
|
|
49
69
|
</script>
|
|
50
70
|
|
|
51
71
|
<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
|
import { sliderVariants } from '../../system/components/Slider.svelte';
|
|
5
6
|
|
|
6
7
|
export const component = 'slider';
|
|
@@ -109,6 +110,38 @@
|
|
|
109
110
|
]);
|
|
110
111
|
|
|
111
112
|
const variantOptions = variants.map((v) => ({ value: v, label: v.charAt(0).toUpperCase() + v.slice(1) }));
|
|
113
|
+
|
|
114
|
+
// The fill paints on the track, and the thumb straddles the fill and the track.
|
|
115
|
+
function variantContrastPairs(v: Variant): ContrastPair[] {
|
|
116
|
+
const thumbPairs = (thumb: string, fill: string, track: string, inactive: boolean): ContrastPair[] => {
|
|
117
|
+
const flag = inactive ? { inactive } : {};
|
|
118
|
+
return [
|
|
119
|
+
{ foreground: thumb, backdrop: [fill, track], role: 'non-text', context: 'fill', ...flag },
|
|
120
|
+
{ foreground: thumb, backdrop: [track], role: 'non-text', context: 'track', ...flag },
|
|
121
|
+
];
|
|
122
|
+
};
|
|
123
|
+
const track = `--slider-${v}-track-surface`;
|
|
124
|
+
const disabledTrack = `--slider-${v}-disabled-track-surface`;
|
|
125
|
+
return [
|
|
126
|
+
{ foreground: `--slider-${v}-fill`, backdrop: [track], role: 'non-text' },
|
|
127
|
+
...thumbPairs(`--slider-${v}-thumb-surface`, `--slider-${v}-fill`, track, false),
|
|
128
|
+
...thumbPairs(`--slider-${v}-hover-thumb-surface`, `--slider-${v}-fill`, track, false),
|
|
129
|
+
{ foreground: `--slider-${v}-disabled-fill`, backdrop: [disabledTrack], role: 'non-text', inactive: true },
|
|
130
|
+
...thumbPairs(`--slider-${v}-disabled-thumb-surface`, `--slider-${v}-disabled-fill`, disabledTrack, true),
|
|
131
|
+
];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Both variants share the label and value, which sit on no surface.
|
|
135
|
+
export const contrastPairs: ContrastPair[] = [
|
|
136
|
+
...typeGroups.default.map((g): ContrastPair => ({
|
|
137
|
+
foreground: g.colorVariable,
|
|
138
|
+
backdrop: [],
|
|
139
|
+
role: 'text',
|
|
140
|
+
fontSize: g.sizeVariable,
|
|
141
|
+
fontWeight: g.weightVariable,
|
|
142
|
+
})),
|
|
143
|
+
...variants.flatMap(variantContrastPairs),
|
|
144
|
+
];
|
|
112
145
|
</script>
|
|
113
146
|
|
|
114
147
|
<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 = 'tabbar';
|
|
6
7
|
|
|
@@ -93,6 +94,25 @@
|
|
|
93
94
|
default: { default: 'var(--color-transparent)' },
|
|
94
95
|
},
|
|
95
96
|
];
|
|
97
|
+
|
|
98
|
+
// The bottom indicator paints over its own tab's surface.
|
|
99
|
+
function tabContrastPairs(s: TabState): ContrastPair[] {
|
|
100
|
+
const backdrop = s === 'hover' ? ['--tabbar-hover-tint-enabled', '--tabbar-hover-surface'] : [`--tabbar-${s}-surface`];
|
|
101
|
+
const inactive = s === 'disabled' ? { inactive: true } : {};
|
|
102
|
+
return [
|
|
103
|
+
...tabStateTypeGroups(s).map((g): ContrastPair => ({
|
|
104
|
+
foreground: g.colorVariable,
|
|
105
|
+
backdrop,
|
|
106
|
+
role: 'text',
|
|
107
|
+
fontSize: g.sizeVariable,
|
|
108
|
+
fontWeight: g.weightVariable,
|
|
109
|
+
...inactive,
|
|
110
|
+
})),
|
|
111
|
+
{ foreground: `--tabbar-${s}-border`, backdrop, role: 'non-text', ...inactive },
|
|
112
|
+
];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export const contrastPairs: ContrastPair[] = tabStateNames.flatMap(tabContrastPairs);
|
|
96
116
|
</script>
|
|
97
117
|
|
|
98
118
|
<script lang="ts">
|
|
@@ -102,6 +122,7 @@
|
|
|
102
122
|
import { editorState, setComponentAlias, clearComponentAlias } from '../core/store/editorStore';
|
|
103
123
|
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
104
124
|
import Toggle from '../ui/Toggle.svelte';
|
|
125
|
+
import A11yPropertyMark from '../ui/a11y/A11yPropertyMark.svelte';
|
|
105
126
|
import UIPaletteSelector from '../ui/UIPaletteSelector.svelte';
|
|
106
127
|
|
|
107
128
|
// One switch. Turning the tint on also stands each hover surface down to its
|
|
@@ -163,7 +184,7 @@
|
|
|
163
184
|
{#snippet extraPropertyRows(stateName)}
|
|
164
185
|
{#if stateName === 'hover tab'}
|
|
165
186
|
<div class="property-row" data-token-variables="--tabbar-hover-tint-enabled">
|
|
166
|
-
<span class="property-label">tint layer
|
|
187
|
+
<span class="property-label">tint layer<A11yPropertyMark variables={['--tabbar-hover-tint-enabled']} /></span>
|
|
167
188
|
<Toggle checked={tintOn} onchange={setTintOn} />
|
|
168
189
|
</div>
|
|
169
190
|
{#if tintOn}
|
|
@@ -177,7 +198,7 @@
|
|
|
177
198
|
{#snippet children({ activeState })}
|
|
178
199
|
{@const forceClass = activeState === 'hover tab' ? 'force-hover' : ''}
|
|
179
200
|
<TabBar tabs={demoTabs} value={selectedDemoTab} class={forceClass} onchange={(id) => (selectedDemoTab = id)} />
|
|
180
|
-
<div class="tab-content-demo">
|
|
201
|
+
<div class="tab-content-demo" data-preview-demo>
|
|
181
202
|
<p style="margin: 0;">placeholder tab content</p>
|
|
182
203
|
</div>
|
|
183
204
|
{/snippet}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { buildTypeGroupColorTokens, buildTypeGroupFontTokens } 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 = 'table';
|
|
6
7
|
|
|
@@ -72,6 +73,19 @@
|
|
|
72
73
|
...buildTypeGroupColorTokens(typeGroups, derivation),
|
|
73
74
|
...buildTypeGroupFontTokens(typeGroups, derivation),
|
|
74
75
|
];
|
|
76
|
+
|
|
77
|
+
// Every cell sits on the wrapper. Even rows lay the stripe over the row surface.
|
|
78
|
+
const wrapper = '--table-default-surface';
|
|
79
|
+
const textPair = (state: string, backdrop: string[]): ContrastPair => {
|
|
80
|
+
const g = typeGroups[state][0];
|
|
81
|
+
return { foreground: g.colorVariable, backdrop, role: 'text', fontSize: g.sizeVariable, fontWeight: g.weightVariable };
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export const contrastPairs: ContrastPair[] = [
|
|
85
|
+
textPair('header', ['--table-default-header-surface', wrapper]),
|
|
86
|
+
{ ...textPair('cell', ['--table-default-row-surface', wrapper]), context: 'odd rows' },
|
|
87
|
+
{ ...textPair('cell', ['--table-default-row-stripe-surface', '--table-default-row-surface', wrapper]), context: 'even rows' },
|
|
88
|
+
];
|
|
75
89
|
</script>
|
|
76
90
|
|
|
77
91
|
<script lang="ts">
|