@motion-proto/live-tokens 0.6.2 → 0.8.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/README.md +14 -13
- package/dist-plugin/index.cjs +854 -226
- package/dist-plugin/index.d.cts +2 -1
- package/dist-plugin/index.d.ts +2 -1
- package/dist-plugin/index.js +852 -225
- package/package.json +26 -40
- package/src/{styles → app}/site.css +1 -1
- package/src/{component-editor → editor/component-editor}/BadgeEditor.svelte +8 -82
- package/src/{component-editor → editor/component-editor}/CalloutEditor.svelte +4 -4
- package/src/{component-editor → editor/component-editor}/CardEditor.svelte +28 -76
- package/src/{component-editor → editor/component-editor}/CollapsibleSectionEditor.svelte +37 -30
- package/src/{component-editor → editor/component-editor}/CornerBadgeEditor.svelte +31 -93
- package/src/{component-editor → editor/component-editor}/DialogEditor.svelte +60 -57
- package/src/editor/component-editor/ImageEditor.svelte +30 -0
- package/src/{component-editor → editor/component-editor}/InlineEditActionsEditor.svelte +6 -4
- package/src/editor/component-editor/MenuSelectEditor.svelte +160 -0
- package/src/{component-editor → editor/component-editor}/NotificationEditor.svelte +67 -38
- package/src/{component-editor → editor/component-editor}/ProgressBarEditor.svelte +5 -4
- package/src/{component-editor → editor/component-editor}/RadioButtonEditor.svelte +3 -3
- package/src/editor/component-editor/SectionDividerEditor.svelte +565 -0
- package/src/{component-editor → editor/component-editor}/SegmentedControlEditor.svelte +2 -2
- package/src/{component-editor → editor/component-editor}/StandardButtonsEditor.svelte +29 -21
- package/src/{component-editor → editor/component-editor}/TabBarEditor.svelte +9 -14
- package/src/{component-editor → editor/component-editor}/TableEditor.svelte +9 -18
- package/src/{component-editor → editor/component-editor}/TooltipEditor.svelte +11 -47
- package/src/editor/component-editor/editors.d.ts +10 -0
- package/src/{component-editor → editor/component-editor}/registry.ts +28 -18
- package/src/{component-editor → editor/component-editor}/scaffolding/AngleDial.svelte +54 -15
- package/src/{component-editor → editor/component-editor}/scaffolding/ComponentEditorBase.svelte +3 -51
- package/src/{component-editor → editor/component-editor}/scaffolding/ComponentFileManager.svelte +151 -424
- package/src/{component-editor → editor/component-editor}/scaffolding/ComponentFileMenu.svelte +18 -170
- package/src/{component-editor → editor/component-editor}/scaffolding/ComponentsTab.svelte +2 -2
- package/src/{component-editor → editor/component-editor}/scaffolding/CopyFromMenu.svelte +44 -4
- package/src/{component-editor → editor/component-editor}/scaffolding/FieldsetWrapper.svelte +1 -1
- package/src/{component-editor → editor/component-editor}/scaffolding/LinkageChart.svelte +6 -6
- package/src/{component-editor → editor/component-editor}/scaffolding/LinkedBlock.svelte +6 -12
- package/src/editor/component-editor/scaffolding/NonStylableConfig.svelte +38 -0
- package/src/editor/component-editor/scaffolding/RadialShapePad.svelte +483 -0
- package/src/{component-editor → editor/component-editor}/scaffolding/SaveAsDialog.svelte +66 -12
- package/src/editor/component-editor/scaffolding/ShadowBackdrop.svelte +85 -0
- package/src/editor/component-editor/scaffolding/ShadowBackdropControls.svelte +132 -0
- package/src/editor/component-editor/scaffolding/StateBlock.svelte +345 -0
- package/src/{component-editor → editor/component-editor}/scaffolding/TokenLayout.svelte +17 -12
- package/src/{component-editor → editor/component-editor}/scaffolding/TypeEditor.svelte +13 -1
- package/src/editor/component-editor/scaffolding/VariantGroup.svelte +858 -0
- package/src/{component-editor → editor/component-editor}/scaffolding/buildTypeGroupTokens.ts +1 -0
- package/src/{component-editor → editor/component-editor}/scaffolding/editorContext.ts +19 -9
- package/src/{component-editor → editor/component-editor}/scaffolding/linkedBlock.ts +2 -2
- package/src/{component-editor → editor/component-editor}/scaffolding/types.ts +25 -0
- package/src/{lib → editor/core/components}/componentConfigKeys.ts +8 -0
- package/src/{lib → editor/core/components}/componentConfigService.ts +3 -3
- package/src/{lib → editor/core/components}/componentPersist.ts +11 -9
- package/src/editor/core/flashStatus.ts +30 -0
- package/src/{lib → editor/core/fonts}/fontLoader.ts +2 -2
- package/src/{lib → editor/core/fonts}/fontMigration.ts +4 -4
- package/src/{lib → editor/core/fonts}/fontParse.ts +1 -1
- package/src/editor/core/manifests/manifestService.ts +171 -0
- package/src/editor/core/palettes/familySwap.ts +99 -0
- package/src/{lib → editor/core/palettes}/paletteDerivation.ts +71 -2
- package/src/{lib → editor/core/palettes}/tokenRegistry.ts +9 -6
- package/src/editor/core/productionPulse.ts +37 -0
- package/src/{lib → editor/core/routing}/router.ts +1 -1
- package/src/{lib/files/versionedFileResource.ts → editor/core/storage/files/versionedFileResourceClient.ts} +8 -1
- package/src/{lib → editor/core/store}/editorCore.ts +24 -8
- package/src/{lib → editor/core/store}/editorPersistence.ts +3 -3
- package/src/{lib → editor/core/store}/editorRenderer.ts +2 -2
- package/src/{lib → editor/core/store}/editorStore.ts +222 -28
- package/src/{lib → editor/core/store}/editorTypes.ts +56 -13
- package/src/editor/core/store/gradientSource.ts +192 -0
- package/src/editor/core/themes/migrations/2026-05-19-collapsiblesection-drop-frame-surface.ts +28 -0
- package/src/editor/core/themes/migrations/2026-05-19-sectiondivider-rich-gradient.ts +35 -0
- package/src/editor/core/themes/migrations/2026-05-20-sectiondivider-slim-variants.ts +82 -0
- package/src/editor/core/themes/migrations/2026-05-21-sectiondivider-spacing-to-padding.ts +24 -0
- package/src/editor/core/themes/migrations/2026-05-22-sectiondivider-intrinsics-to-css.ts +81 -0
- package/src/{lib → editor/core/themes}/migrations/index.ts +10 -0
- package/src/{lib → editor/core/themes}/slices/columns.ts +2 -2
- package/src/{lib → editor/core/themes}/slices/components.ts +20 -6
- package/src/{lib → editor/core/themes}/slices/fonts.ts +1 -1
- package/src/{lib → editor/core/themes}/slices/gradients.ts +89 -14
- package/src/{lib → editor/core/themes}/slices/overlays.ts +1 -1
- package/src/{lib → editor/core/themes}/slices/palettes.ts +1 -1
- package/src/{lib → editor/core/themes}/slices/shadows.ts +3 -3
- package/src/{lib → editor/core/themes}/themeInit.ts +8 -8
- package/src/{lib → editor/core/themes}/themeService.ts +6 -6
- package/src/{lib → editor/core/themes}/themeTypes.ts +67 -8
- package/src/editor/index.ts +69 -0
- package/src/{lib → editor/overlay}/ColumnsOverlay.svelte +0 -1
- package/src/{lib → editor/overlay}/LiveEditorOverlay.svelte +80 -129
- package/src/{lib → editor/overlay}/columnsOverlay.ts +2 -2
- package/src/{pages → editor/pages}/ComponentEditorPage.svelte +12 -12
- package/src/{pages → editor/pages}/Editor.svelte +4 -4
- package/src/{pages → editor/pages}/EditorShell.svelte +18 -36
- package/src/{styles → editor/styles}/ui-editor.css +43 -22
- package/src/{styles → editor/styles}/ui-form-controls.css +23 -24
- package/src/{ui → editor/ui}/BezierCurveEditor.svelte +119 -68
- package/src/{ui → editor/ui}/ColorEditPanel.svelte +13 -13
- package/src/{ui → editor/ui}/EditorViewSwitcher.svelte +7 -6
- package/src/editor/ui/FileLoadList.svelte +367 -0
- package/src/editor/ui/FilePill.svelte +80 -0
- package/src/editor/ui/FontStackEditor.svelte +499 -0
- package/src/editor/ui/GradientEditor.svelte +690 -0
- package/src/{ui → editor/ui}/GradientStopPicker.svelte +12 -4
- package/src/editor/ui/ManifestFileManager.svelte +438 -0
- package/src/{ui → editor/ui}/PaletteEditor.svelte +180 -673
- package/src/editor/ui/ProjectFontsSection.svelte +638 -0
- package/src/{ui → editor/ui}/SurfacesTab.svelte +3 -3
- package/src/{ui → editor/ui}/TextTab.svelte +3 -3
- package/src/editor/ui/ThemeFileManager.svelte +783 -0
- package/src/{ui → editor/ui}/UICopyPopover.svelte +4 -4
- package/src/{ui → editor/ui}/UIFontFamilySelector.svelte +6 -7
- package/src/{ui → editor/ui}/UIFontSizeSelector.svelte +4 -1
- package/src/editor/ui/UIInfoPopover.svelte +243 -0
- package/src/editor/ui/UILetterSpacingSelector.svelte +65 -0
- package/src/{ui → editor/ui}/UILineHeightSelector.svelte +5 -5
- package/src/{ui → editor/ui}/UILinkToggle.svelte +2 -2
- package/src/{ui → editor/ui}/UIPaddingSelector.svelte +6 -6
- package/src/{ui → editor/ui}/UIPaletteSelector.svelte +57 -30
- package/src/editor/ui/UIPillButton.svelte +168 -0
- package/src/{ui → editor/ui}/UIRadio.svelte +2 -2
- package/src/{ui → editor/ui}/UIRelinkConfirmPopover.svelte +4 -4
- package/src/editor/ui/UISegmentedControl.svelte +114 -0
- package/src/editor/ui/UISquareButton.svelte +172 -0
- package/src/{ui → editor/ui}/UITokenSelector.svelte +14 -11
- package/src/{ui → editor/ui}/UIVariantSelector.svelte +1 -1
- package/src/{ui → editor/ui}/VariablesTab.svelte +46 -17
- package/src/{ui → editor/ui}/palette/GradientStopEditor.svelte +13 -13
- package/src/{ui → editor/ui}/palette/OverridesPanel.svelte +24 -47
- package/src/{ui → editor/ui}/palette/PaletteBase.svelte +11 -8
- package/src/{ui → editor/ui}/palette/paletteEditorState.ts +1 -1
- package/src/editor/ui/palette/paletteMath.ts +275 -0
- package/src/{ui → editor/ui}/sections/ColumnsSection.svelte +137 -18
- package/src/{ui → editor/ui}/sections/GradientsSection.svelte +8 -8
- package/src/{ui → editor/ui}/sections/OverlaysSection.svelte +18 -18
- package/src/{ui → editor/ui}/sections/ShadowsSection.svelte +23 -23
- package/src/{ui → editor/ui}/sections/TokenScaleTable.svelte +3 -3
- package/src/{components → system/components}/Badge.svelte +0 -36
- package/src/{components → system/components}/Button.svelte +2 -2
- package/src/{components → system/components}/Card.svelte +34 -60
- package/src/{components → system/components}/CollapsibleSection.svelte +25 -2
- package/src/{components → system/components}/CornerBadge.svelte +8 -24
- package/src/{components → system/components}/Dialog.svelte +1 -1
- package/src/system/components/FloatingTokenTags.css +275 -0
- package/src/system/components/FloatingTokenTags.svelte +543 -0
- package/src/{components → system/components}/InlineEditActions.svelte +6 -4
- package/src/system/components/MenuSelect.svelte +229 -0
- package/src/{components → system/components}/Notification.svelte +8 -1
- package/src/{components → system/components}/ProgressBar.svelte +29 -11
- package/src/system/components/SectionDivider.svelte +560 -0
- package/src/{components → system/components}/SegmentedControl.svelte +49 -43
- package/src/{components → system/components}/TabBar.svelte +81 -65
- package/src/{components → system/components}/Table.svelte +17 -3
- package/src/{components → system/components}/Tooltip.svelte +6 -4
- package/src/system/styles/CONVENTIONS.md +178 -0
- package/src/system/styles/fonts.css +20 -0
- package/src/system/styles/tokens.css +601 -0
- package/src/system/styles/tokens.generated.css +544 -0
- package/src/component-editor/ImageEditor.svelte +0 -74
- package/src/component-editor/SectionDividerEditor.svelte +0 -265
- package/src/component-editor/scaffolding/DividerEditor.svelte +0 -94
- package/src/component-editor/scaffolding/GradientCard.svelte +0 -296
- package/src/component-editor/scaffolding/NonStylableConfig.svelte +0 -62
- package/src/component-editor/scaffolding/ShadowBackdrop.svelte +0 -37
- package/src/component-editor/scaffolding/ShadowBackdropControls.svelte +0 -61
- package/src/component-editor/scaffolding/StateBlock.svelte +0 -132
- package/src/component-editor/scaffolding/VariantGroup.svelte +0 -310
- package/src/components/SectionDivider.svelte +0 -483
- package/src/data/google-fonts.json +0 -75
- package/src/lib/index.ts +0 -68
- package/src/lib/presetService.ts +0 -214
- package/src/lib/productionPulse.ts +0 -32
- package/src/styles/fonts.css +0 -30
- package/src/styles/tokens.css +0 -1324
- package/src/ui/FontStackEditor.svelte +0 -361
- package/src/ui/GradientEditor.svelte +0 -470
- package/src/ui/PresetFileManager.svelte +0 -1116
- package/src/ui/ProjectFontsSection.svelte +0 -645
- package/src/ui/ThemeFileManager.svelte +0 -1020
- package/src/ui/UnsavedComponentsDialog.svelte +0 -315
- /package/src/{component-editor → editor/component-editor}/index.ts +0 -0
- /package/src/{component-editor → editor/component-editor}/scaffolding/DemoHeader.svelte +0 -0
- /package/src/{component-editor → editor/component-editor}/scaffolding/componentSectionType.ts +0 -0
- /package/src/{component-editor → editor/component-editor}/scaffolding/componentSources.ts +0 -0
- /package/src/{component-editor → editor/component-editor}/scaffolding/defaultSections.ts +0 -0
- /package/src/{component-editor → editor/component-editor}/scaffolding/siblings.ts +0 -0
- /package/src/{lib → editor/core}/cssVarSync.ts +0 -0
- /package/src/{lib → editor/core/palettes}/oklch.ts +0 -0
- /package/src/{lib → editor/core/routing}/navLinkTypes.ts +0 -0
- /package/src/{lib → editor/core/routing}/parentRouteStore.ts +0 -0
- /package/src/{lib → editor/core/storage}/storage.ts +0 -0
- /package/src/{lib → editor/core/store}/editorConfig.ts +0 -0
- /package/src/{lib → editor/core/store}/editorConfigStore.ts +0 -0
- /package/src/{lib → editor/core/store}/editorKeybindings.ts +0 -0
- /package/src/{lib → editor/core/store}/editorViewStore.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-04-24-component-prefix-and-suffix-renames.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-04-24-legacy-keys-and-bg-to-canvas.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-04-27-segmentedcontrol-disabled-flatten.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-05-08-collapsiblesection-frame-and-cleanup.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-05-08-collapsiblesection-variant-namespace.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-05-10-sectiondivider-gradient-stops.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-05-13-primary-to-brand.ts +0 -0
- /package/src/{lib → editor/core/themes}/parsers/globalRootBlock.ts +0 -0
- /package/src/{lib → editor/core/themes}/slices/domainVars.ts +0 -0
- /package/src/{lib → editor/overlay}/overlayState.ts +0 -0
- /package/src/{pages → editor/pages}/ComponentEditorPage.svelte.d.ts +0 -0
- /package/src/{pages → editor/pages}/Editor.svelte.d.ts +0 -0
- /package/src/{ui → editor/ui}/Toggle.svelte +0 -0
- /package/src/{ui → editor/ui}/UIDialog.svelte +0 -0
- /package/src/{ui → editor/ui}/UIFontWeightSelector.svelte +0 -0
- /package/src/{ui → editor/ui}/UIOptionItem.svelte +0 -0
- /package/src/{ui → editor/ui}/UIOptionList.svelte +0 -0
- /package/src/{ui → editor/ui}/UIRadioGroup.svelte +0 -0
- /package/src/{lib → editor/ui}/copyPopover.ts +0 -0
- /package/src/{ui → editor/ui}/curveEngine.ts +0 -0
- /package/src/{ui → editor/ui}/index.ts +0 -0
- /package/src/{ui → editor/ui}/keepInViewport.ts +0 -0
- /package/src/{ui → editor/ui}/palette/ScaleCurveEditor.svelte +0 -0
- /package/src/{lib → editor/ui}/scrollSection.ts +0 -0
- /package/src/{ui → editor/ui}/sections/tokenScales.ts +0 -0
- /package/src/{ui → editor/ui}/variantScales.ts +0 -0
- /package/src/{assets → system/assets}/newspaper.webp +0 -0
- /package/src/{assets → system/assets}/offering.webp +0 -0
- /package/src/{components → system/components}/Callout.svelte +0 -0
- /package/src/{components → system/components}/Image.svelte +0 -0
- /package/src/{components → system/components}/RadioButton.svelte +0 -0
- /package/src/{components → system/components}/types.ts +0 -0
- /package/src/{styles → system/styles}/_padding.scss +0 -0
- /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-italic-latin-ext.woff2 +0 -0
- /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-italic-latin.woff2 +0 -0
- /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-roman-latin-ext.woff2 +0 -0
- /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-roman-latin.woff2 +0 -0
- /package/src/{styles → system/styles}/fonts/Manrope/Manrope-latin-ext.woff2 +0 -0
- /package/src/{styles → system/styles}/fonts/Manrope/Manrope-latin.woff2 +0 -0
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import type { Token } from './scaffolding/types';
|
|
3
|
-
import { badgeVariants } from '
|
|
3
|
+
import { badgeVariants } from '../../system/components/Badge.svelte';
|
|
4
4
|
|
|
5
5
|
export const component = 'cornerbadge';
|
|
6
6
|
|
|
7
|
-
// One state per
|
|
8
|
-
// every token has a role-specific groupKey so the LinkedBlock groups
|
|
9
|
-
// "outer-radius" across variants (not against inner/h-axis/v-axis). Changing
|
|
10
|
-
// a variant's outer corner radius propagates to the same role on every other
|
|
11
|
-
// variant when linked; roles within a variant stay independent.
|
|
7
|
+
// One state per variant; role-specific groupKeys link the same role across variants while keeping roles independent within a variant.
|
|
12
8
|
function variantTokens(v: typeof badgeVariants[number]): Token[] {
|
|
13
9
|
return [
|
|
14
10
|
{ label: 'offset from corner', canBeLinked: true, groupKey: 'margin', variable: `--corner-badge-${v}-margin` },
|
|
@@ -17,12 +13,7 @@
|
|
|
17
13
|
{ label: 'horizontal-axis radius', canBeLinked: true, groupKey: 'h-axis-radius', variable: `--corner-badge-${v}-h-axis-radius` },
|
|
18
14
|
{ label: 'vertical-axis radius', canBeLinked: true, groupKey: 'v-axis-radius', variable: `--corner-badge-${v}-v-axis-radius` },
|
|
19
15
|
{ label: 'padding', canBeLinked: true, groupKey: 'padding', variable: `--corner-badge-${v}-padding` },
|
|
20
|
-
//
|
|
21
|
-
// padding. Declared (hidden) so the schema sees them as siblings across
|
|
22
|
-
// variants — `padding-top` on primary links to `padding-top` on accent, etc.
|
|
23
|
-
// The themed-padding mixin in CornerBadge.svelte reads them via
|
|
24
|
-
// `var(--corner-badge-${v}-padding-top, fallback)`; no `:root` default is
|
|
25
|
-
// needed (test skips `hidden: true` tokens by design — see editorTokens.test.ts).
|
|
16
|
+
// Hidden per-side overrides for UIPaddingSelector split mode; declared so siblings link across variants.
|
|
26
17
|
{ label: 'padding-top', canBeLinked: true, groupKey: 'padding-top', variable: `--corner-badge-${v}-padding-top`, hidden: true },
|
|
27
18
|
{ label: 'padding-right', canBeLinked: true, groupKey: 'padding-right', variable: `--corner-badge-${v}-padding-right`, hidden: true },
|
|
28
19
|
{ label: 'padding-bottom', canBeLinked: true, groupKey: 'padding-bottom', variable: `--corner-badge-${v}-padding-bottom`, hidden: true },
|
|
@@ -33,15 +24,9 @@
|
|
|
33
24
|
{ label: 'line height', canBeLinked: true, groupKey: 'text-line-height', variable: `--corner-badge-${v}-text-line-height` },
|
|
34
25
|
];
|
|
35
26
|
}
|
|
36
|
-
const
|
|
37
|
-
badgeVariants.map((v) => [v, variantTokens(v)]),
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
export const allTokens: Token[] = Object.values(states).flat();
|
|
27
|
+
export const allTokens: Token[] = badgeVariants.flatMap((v) => variantTokens(v));
|
|
41
28
|
|
|
42
|
-
//
|
|
43
|
-
// when ≥2 variants currently agree on an alias for the same groupKey. Variant
|
|
44
|
-
// name is the context label so the chart rows mirror the variant tab strip.
|
|
29
|
+
// Linkable vars across variants; variant name as context label so chart rows mirror the tab strip.
|
|
45
30
|
const linkableContexts = new Map<string, string>(
|
|
46
31
|
badgeVariants.flatMap((v) =>
|
|
47
32
|
variantTokens(v)
|
|
@@ -49,34 +34,21 @@
|
|
|
49
34
|
.map((t) => [t.variable, v] as [string, string]),
|
|
50
35
|
),
|
|
51
36
|
);
|
|
37
|
+
|
|
38
|
+
const variantOptions = badgeVariants.map((v) => ({ value: v, label: v.charAt(0).toUpperCase() + v.slice(1) }));
|
|
52
39
|
</script>
|
|
53
40
|
|
|
54
41
|
<script lang="ts">
|
|
55
|
-
import {
|
|
56
|
-
import CornerBadge, { type CornerAnchor } from '../components/CornerBadge.svelte';
|
|
57
|
-
import type { BadgeVariant } from '../components/Badge.svelte';
|
|
42
|
+
import CornerBadge, { type CornerAnchor } from '../../system/components/CornerBadge.svelte';
|
|
58
43
|
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
59
44
|
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
60
|
-
import
|
|
61
|
-
import UIRadioGroup from '../ui/UIRadioGroup.svelte';
|
|
62
|
-
import UIPaletteSelector from '../ui/UIPaletteSelector.svelte';
|
|
63
|
-
import { setCssVar } from '../lib/cssVarSync';
|
|
64
|
-
import { editorState } from '../lib/editorStore';
|
|
45
|
+
import { editorState } from '../core/store/editorStore';
|
|
65
46
|
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
66
|
-
import
|
|
47
|
+
import { buildSiblings } from './scaffolding/siblings';
|
|
48
|
+
import demoImageUrl from '../../system/assets/newspaper.webp';
|
|
67
49
|
|
|
68
50
|
let linked = $derived(computeLinkedBlock(component, linkableContexts, allTokens, $editorState));
|
|
69
|
-
let
|
|
70
|
-
badgeVariants.map((v) => [v, withLinkedDisabled(variantTokens(v), linked.varSet)]),
|
|
71
|
-
) as Record<string, Token[]>);
|
|
72
|
-
|
|
73
|
-
const bgVar = '--backdrop-cornerbadge-surface';
|
|
74
|
-
|
|
75
|
-
onMount(() => {
|
|
76
|
-
if (!document.documentElement.style.getPropertyValue(bgVar)) {
|
|
77
|
-
setCssVar(bgVar, 'var(--surface-canvas)');
|
|
78
|
-
}
|
|
79
|
-
});
|
|
51
|
+
let visibleVariantTokens = $derived((v: typeof badgeVariants[number]) => withLinkedDisabled(variantTokens(v), linked.varSet));
|
|
80
52
|
|
|
81
53
|
let anchor: CornerAnchor = $state('bottom-right');
|
|
82
54
|
const anchorGrid: ReadonlyArray<{ value: CornerAnchor; icon: string; label: string }> = [
|
|
@@ -85,22 +57,19 @@
|
|
|
85
57
|
{ value: 'bottom-left', icon: 'fas fa-arrow-down-left', label: 'Bottom left' },
|
|
86
58
|
{ value: 'bottom-right', icon: 'fas fa-arrow-down-right', label: 'Bottom right' },
|
|
87
59
|
];
|
|
88
|
-
|
|
89
|
-
let variant: BadgeVariant = $state('accent');
|
|
90
|
-
const variantOptions = badgeVariants.map((v) => ({ value: v, label: v.charAt(0).toUpperCase() + v.slice(1) }));
|
|
91
60
|
</script>
|
|
92
61
|
|
|
93
|
-
<ComponentEditorBase {component} title="Corner Badge" description="Badge pinned flush to a corner of a positioned ancestor. Composes <code>Badge</code>; adds offset + inner-radius tokens.
|
|
94
|
-
{#
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
<span>Anchor</span>
|
|
62
|
+
<ComponentEditorBase {component} title="Corner Badge" description="Badge pinned flush to a corner of a positioned ancestor. Composes <code>Badge</code>; adds offset + inner-radius tokens." tokens={allTokens} {linked} variants={variantOptions}>
|
|
63
|
+
{#each badgeVariants as v}
|
|
64
|
+
<VariantGroup
|
|
65
|
+
name={v}
|
|
66
|
+
title={v.charAt(0).toUpperCase() + v.slice(1)}
|
|
67
|
+
states={{ [v]: visibleVariantTokens(v) }}
|
|
68
|
+
{component}
|
|
69
|
+
siblings={buildSiblings(badgeVariants, v, (sv) => ({ [sv]: variantTokens(sv) }))}
|
|
70
|
+
>
|
|
71
|
+
{#snippet canvasToolbarExtras()}
|
|
72
|
+
<span class="canvas-toolbar-eyebrow">Anchor</span>
|
|
104
73
|
<div class="anchor-grid" role="radiogroup" aria-label="Corner badge anchor">
|
|
105
74
|
{#each anchorGrid as opt (opt.value)}
|
|
106
75
|
<button
|
|
@@ -117,36 +86,25 @@
|
|
|
117
86
|
</button>
|
|
118
87
|
{/each}
|
|
119
88
|
</div>
|
|
120
|
-
|
|
121
|
-
<div class="control-row">
|
|
122
|
-
<span>Variant</span>
|
|
123
|
-
<UIRadioGroup bind:value={variant} name="corner-badge-variant" options={variantOptions} />
|
|
124
|
-
</div>
|
|
125
|
-
|
|
126
|
-
{/snippet}
|
|
127
|
-
<VariantGroup name="cornerbadge" title="Corner Badge" states={visibleStates} {component}>
|
|
128
|
-
<ShadowBackdrop mode="color" colorVariable={bgVar}>
|
|
89
|
+
{/snippet}
|
|
129
90
|
<div class="corner-stage-wrap">
|
|
130
91
|
<div class="corner-stage">
|
|
131
92
|
<img src={demoImageUrl} alt="" class="corner-stage-image" />
|
|
132
|
-
<CornerBadge {
|
|
93
|
+
<CornerBadge variant={v} {anchor}>{v.charAt(0).toUpperCase() + v.slice(1)}</CornerBadge>
|
|
133
94
|
</div>
|
|
134
95
|
</div>
|
|
135
|
-
</
|
|
136
|
-
|
|
96
|
+
</VariantGroup>
|
|
97
|
+
{/each}
|
|
137
98
|
</ComponentEditorBase>
|
|
138
99
|
|
|
139
100
|
<style>
|
|
140
|
-
/* Center
|
|
101
|
+
/* Center stage so it doesn't stretch full-width. */
|
|
141
102
|
.corner-stage-wrap {
|
|
142
103
|
display: grid;
|
|
143
104
|
place-items: center;
|
|
144
105
|
}
|
|
145
106
|
|
|
146
|
-
/*
|
|
147
|
-
actually pins to a corner, and a visible surface so offset/radius are observable. */
|
|
148
|
-
/* No overflow:hidden here — the badge needs to be able to extend past the stage
|
|
149
|
-
(e.g. when the offset is 0 or negative). Rounded corners live on the image. */
|
|
107
|
+
/* Positioned ancestor for CornerBadge; no overflow:hidden so badge can extend past edges. */
|
|
150
108
|
.corner-stage {
|
|
151
109
|
position: relative;
|
|
152
110
|
width: 380px;
|
|
@@ -159,26 +117,6 @@
|
|
|
159
117
|
border-radius: var(--ui-radius-md);
|
|
160
118
|
}
|
|
161
119
|
|
|
162
|
-
.control-row {
|
|
163
|
-
display: inline-flex;
|
|
164
|
-
align-items: center;
|
|
165
|
-
gap: var(--ui-space-8);
|
|
166
|
-
font-size: var(--ui-font-size-sm);
|
|
167
|
-
color: var(--ui-text-secondary);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
.backdrop-config {
|
|
171
|
-
display: inline-flex;
|
|
172
|
-
align-items: center;
|
|
173
|
-
gap: var(--ui-space-8);
|
|
174
|
-
}
|
|
175
|
-
.picker-slot {
|
|
176
|
-
min-width: 8rem;
|
|
177
|
-
}
|
|
178
|
-
.picker-slot :global(.ui-token-selector) {
|
|
179
|
-
width: 100%;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
120
|
.anchor-grid {
|
|
183
121
|
display: grid;
|
|
184
122
|
grid-template-columns: repeat(2, 1.5rem);
|
|
@@ -189,7 +127,7 @@
|
|
|
189
127
|
display: grid;
|
|
190
128
|
place-items: center;
|
|
191
129
|
padding: 0;
|
|
192
|
-
border: 1px solid var(--ui-border-
|
|
130
|
+
border: 1px solid var(--ui-border-low, rgba(255, 255, 255, 0.1));
|
|
193
131
|
border-radius: var(--ui-radius-sm);
|
|
194
132
|
background: transparent;
|
|
195
133
|
color: var(--ui-text-tertiary);
|
|
@@ -204,6 +142,6 @@
|
|
|
204
142
|
.anchor-btn.checked {
|
|
205
143
|
background: var(--ui-surface-active, rgba(255, 255, 255, 0.12));
|
|
206
144
|
color: var(--ui-text-primary);
|
|
207
|
-
border-color: var(--ui-border-
|
|
145
|
+
border-color: var(--ui-border-higher, rgba(255, 255, 255, 0.25));
|
|
208
146
|
}
|
|
209
147
|
</style>
|
|
@@ -88,12 +88,10 @@
|
|
|
88
88
|
</script>
|
|
89
89
|
|
|
90
90
|
<script lang="ts">
|
|
91
|
-
import Dialog from '
|
|
91
|
+
import Dialog from '../../system/components/Dialog.svelte';
|
|
92
92
|
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
93
93
|
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
94
|
-
import { editorState, setComponentConfig } from '../
|
|
95
|
-
import ShadowBackdrop from './scaffolding/ShadowBackdrop.svelte';
|
|
96
|
-
import ShadowBackdropControls from './scaffolding/ShadowBackdropControls.svelte';
|
|
94
|
+
import { editorState, setComponentConfig } from '../core/store/editorStore';
|
|
97
95
|
|
|
98
96
|
let config = $derived($editorState.components.dialog?.config ?? {});
|
|
99
97
|
let confirmVariant = $derived((BUTTON_VARIANTS.includes(config[CONFIRM_VAR] as ButtonVariant) ? config[CONFIRM_VAR] : DEFAULT_CONFIRM) as ButtonVariant);
|
|
@@ -108,67 +106,72 @@
|
|
|
108
106
|
setComponentConfig(component, CANCEL_VAR, v);
|
|
109
107
|
}
|
|
110
108
|
|
|
111
|
-
let bgMode: 'image' | 'color' = $state('image');
|
|
112
|
-
const bgVar = '--backdrop-dialog-surface';
|
|
113
109
|
</script>
|
|
114
110
|
|
|
115
|
-
<ComponentEditorBase {component} title="Dialog" description="Modal dialog with focus management and slide-in animation.
|
|
116
|
-
{
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
<
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
<
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
</Dialog>
|
|
148
|
-
</ShadowBackdrop>
|
|
149
|
-
</div>
|
|
150
|
-
<VariantGroup name="dialog" title="Dialog" states={frameStates} typeGroups={frameTypeGroups} {component} />
|
|
111
|
+
<ComponentEditorBase {component} title="Dialog" description="Modal dialog with focus management and slide-in animation." tokens={allTokens}>
|
|
112
|
+
<VariantGroup name="dialog" title="Dialog" states={frameStates} typeGroups={frameTypeGroups} {component} backdropPadding="0">
|
|
113
|
+
{#snippet extraPropertyRows(stateName)}
|
|
114
|
+
{#if stateName === 'footer'}
|
|
115
|
+
<div class="property-row button-variant-row">
|
|
116
|
+
<span class="property-label">right button</span>
|
|
117
|
+
<select class="ui-form-select compact" value={confirmVariant} onchange={setConfirmVariant}>
|
|
118
|
+
{#each BUTTON_VARIANTS as v}
|
|
119
|
+
<option value={v}>{variantLabel(v)}</option>
|
|
120
|
+
{/each}
|
|
121
|
+
</select>
|
|
122
|
+
</div>
|
|
123
|
+
<div class="property-row button-variant-row">
|
|
124
|
+
<span class="property-label">left button</span>
|
|
125
|
+
<select class="ui-form-select compact" value={cancelVariant} onchange={setCancelVariant}>
|
|
126
|
+
{#each BUTTON_VARIANTS as v}
|
|
127
|
+
<option value={v}>{variantLabel(v)}</option>
|
|
128
|
+
{/each}
|
|
129
|
+
</select>
|
|
130
|
+
</div>
|
|
131
|
+
{/if}
|
|
132
|
+
{/snippet}
|
|
133
|
+
<Dialog
|
|
134
|
+
show
|
|
135
|
+
inline
|
|
136
|
+
title="Sample Dialog"
|
|
137
|
+
confirm={{ label: 'Save', onClick: () => {} }}
|
|
138
|
+
cancel={{ label: 'Cancel', onClick: () => {} }}
|
|
139
|
+
>
|
|
140
|
+
<p style="margin: 0;">This is the dialog body content. It supports any slotted content including forms, lists, or other components.</p>
|
|
141
|
+
</Dialog>
|
|
142
|
+
</VariantGroup>
|
|
151
143
|
</ComponentEditorBase>
|
|
152
144
|
|
|
153
145
|
<style>
|
|
154
|
-
.dialog-
|
|
155
|
-
display: flex;
|
|
156
|
-
justify-content: center;
|
|
157
|
-
align-items: center;
|
|
158
|
-
width: 100%;
|
|
159
|
-
min-width: 0;
|
|
160
|
-
}
|
|
161
|
-
.dialog-preview :global(.shadow-backdrop) {
|
|
162
|
-
display: flex;
|
|
163
|
-
justify-content: center;
|
|
164
|
-
align-items: center;
|
|
165
|
-
width: 100%;
|
|
166
|
-
min-width: 0;
|
|
167
|
-
}
|
|
168
|
-
.dialog-preview :global(.dialog-backdrop.inline) {
|
|
146
|
+
:global(.dialog-backdrop.inline) {
|
|
169
147
|
width: auto;
|
|
170
148
|
box-sizing: border-box;
|
|
171
149
|
padding: clamp(24px, 6vw, 128px);
|
|
172
150
|
}
|
|
151
|
+
|
|
152
|
+
/* Pull the button-variant rows into the same 3-column geometry the token
|
|
153
|
+
grid uses (label / 8rem selector / context) so they line up under
|
|
154
|
+
`padding`, `border width`, etc. Also shrink the native select to match
|
|
155
|
+
the visual weight of the `.ui-ts-trigger` chips used by the other
|
|
156
|
+
selectors on the row. */
|
|
157
|
+
:global(.extra-property-rows .property-row.button-variant-row) {
|
|
158
|
+
/* Col 1 min matches the typical max-content width of the token labels
|
|
159
|
+
above (`border color`, `border width`) so the select edge sits flush
|
|
160
|
+
with the selector column in the token grid even though the two grids
|
|
161
|
+
are independent. */
|
|
162
|
+
grid-template-columns: minmax(6.5rem, max-content) 8rem 1fr;
|
|
163
|
+
padding-left: var(--ui-space-12);
|
|
164
|
+
column-gap: var(--ui-space-10);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
:global(.ui-form-select.compact) {
|
|
168
|
+
min-height: 1.75rem;
|
|
169
|
+
padding: 0 var(--ui-space-8);
|
|
170
|
+
padding-right: var(--ui-space-24);
|
|
171
|
+
background-color: var(--ui-surface-low);
|
|
172
|
+
background-position: right var(--ui-space-8) center;
|
|
173
|
+
font-size: var(--ui-font-size-sm);
|
|
174
|
+
width: 100%;
|
|
175
|
+
}
|
|
173
176
|
</style>
|
|
174
177
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import type { Token } from './scaffolding/types';
|
|
3
|
+
|
|
4
|
+
export const component = 'image';
|
|
5
|
+
|
|
6
|
+
// Single object: image frame.
|
|
7
|
+
const states: Record<string, Token[]> = {
|
|
8
|
+
image: [
|
|
9
|
+
{ label: 'border color', groupKey: 'border', variable: '--image-default-border' },
|
|
10
|
+
{ label: 'border width', groupKey: 'width', variable: '--image-default-border-width' },
|
|
11
|
+
{ label: 'corner radius', groupKey: 'radius', variable: '--image-default-radius' },
|
|
12
|
+
{ label: 'image shadow', groupKey: 'shadow', variable: '--image-default-shadow' },
|
|
13
|
+
],
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const allTokens: Token[] = Object.values(states).flat();
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<script lang="ts">
|
|
20
|
+
import Image from '../../system/components/Image.svelte';
|
|
21
|
+
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
22
|
+
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
23
|
+
import demoImageUrl from '../../system/assets/offering.webp';
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<ComponentEditorBase {component} title="Image" description="Framed image with rounded corners, border, and shadow." tokens={allTokens}>
|
|
27
|
+
<VariantGroup name="image" title="Image" {states} {component}>
|
|
28
|
+
<Image src={demoImageUrl} alt="Demo" variant="banner" />
|
|
29
|
+
</VariantGroup>
|
|
30
|
+
</ComponentEditorBase>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
|
+
import { buildSiblings } from './scaffolding/siblings';
|
|
2
3
|
import type { Token } from './scaffolding/types';
|
|
3
4
|
|
|
4
5
|
export const component = 'inlineeditactions';
|
|
@@ -8,6 +9,7 @@
|
|
|
8
9
|
// Save and cancel are different objects, so they don't link to each other by default.
|
|
9
10
|
const buttons = ['save', 'cancel'] as const;
|
|
10
11
|
type Button = typeof buttons[number];
|
|
12
|
+
const variantOptions = buttons.map((b) => ({ value: b, label: b === 'save' ? 'Save button' : 'Cancel button' }));
|
|
11
13
|
function buttonStateTokens(btn: Button, state: 'default' | 'hover'): Token[] {
|
|
12
14
|
return [
|
|
13
15
|
{ label: 'surface color', groupKey: 'surface', variable: `--inlineeditactions-${btn}-${state}-surface` },
|
|
@@ -39,10 +41,10 @@
|
|
|
39
41
|
</script>
|
|
40
42
|
|
|
41
43
|
<script lang="ts">
|
|
42
|
-
import InlineEditActions from '
|
|
44
|
+
import InlineEditActions from '../../system/components/InlineEditActions.svelte';
|
|
43
45
|
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
44
46
|
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
45
|
-
import { editorState } from '../
|
|
47
|
+
import { editorState } from '../core/store/editorStore';
|
|
46
48
|
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
47
49
|
|
|
48
50
|
let linked = $derived(computeLinkedBlock(component, linkableContexts, allTokens, $editorState));
|
|
@@ -52,14 +54,14 @@
|
|
|
52
54
|
) as Record<string, Token[]>);
|
|
53
55
|
</script>
|
|
54
56
|
|
|
55
|
-
<ComponentEditorBase {component} title="Inline Edit Actions" description="Confirm/cancel button pair for inline editing.
|
|
57
|
+
<ComponentEditorBase {component} title="Inline Edit Actions" description="Confirm/cancel button pair for inline editing." tokens={allTokens} {linked} variants={variantOptions}>
|
|
56
58
|
{#each buttons as btn}
|
|
57
59
|
<VariantGroup
|
|
58
60
|
name={btn}
|
|
59
61
|
title={btn === 'save' ? 'Save button' : 'Cancel button'}
|
|
60
62
|
states={visibleStatesByButton(btn)}
|
|
61
63
|
{component}
|
|
62
|
-
|
|
64
|
+
siblings={buildSiblings(buttons, btn, buttonStates)}
|
|
63
65
|
>
|
|
64
66
|
{#snippet children({ activeState })}
|
|
65
67
|
{@const forceClass = activeState === 'hover' ? 'force-hover' : ''}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { buildTypeGroupTokens, buildTypeGroupShareableContexts } from './scaffolding/buildTypeGroupTokens';
|
|
3
|
+
import type { Token, TypeGroupConfig } from './scaffolding/types';
|
|
4
|
+
|
|
5
|
+
export const component = 'menuselect';
|
|
6
|
+
|
|
7
|
+
// Non-text tokens per state; text/font lives in typeGroups. Item-shape tokens sit under `menu` so they read as one decision across states.
|
|
8
|
+
const states: Record<string, Token[]> = {
|
|
9
|
+
menu: [
|
|
10
|
+
{ label: 'surface color', groupKey: 'surface', variable: '--menuselect-menu-surface' },
|
|
11
|
+
{ label: 'border color', groupKey: 'border', variable: '--menuselect-menu-border' },
|
|
12
|
+
{ label: 'border width', groupKey: 'width', variable: '--menuselect-menu-border-width' },
|
|
13
|
+
{ label: 'corner radius', groupKey: 'menu-radius', variable: '--menuselect-menu-radius' },
|
|
14
|
+
{ label: 'padding', variable: '--menuselect-menu-padding', groupKey: 'menu-padding' },
|
|
15
|
+
{ label: 'padding-top', variable: '--menuselect-menu-padding-top', groupKey: 'menu-padding-top', hidden: true },
|
|
16
|
+
{ label: 'padding-right', variable: '--menuselect-menu-padding-right', groupKey: 'menu-padding-right', hidden: true },
|
|
17
|
+
{ label: 'padding-bottom', variable: '--menuselect-menu-padding-bottom', groupKey: 'menu-padding-bottom', hidden: true },
|
|
18
|
+
{ label: 'padding-left', variable: '--menuselect-menu-padding-left', groupKey: 'menu-padding-left', hidden: true },
|
|
19
|
+
{ label: 'item gap', groupKey: 'gap', variable: '--menuselect-menu-gap' },
|
|
20
|
+
{ label: 'shadow', groupKey: 'shadow', variable: '--menuselect-menu-shadow' },
|
|
21
|
+
{ label: 'item radius', groupKey: 'item-radius', variable: '--menuselect-item-radius' },
|
|
22
|
+
{ label: 'item padding', variable: '--menuselect-item-padding', groupKey: 'item-padding' },
|
|
23
|
+
{ label: 'item padding-top', variable: '--menuselect-item-padding-top', groupKey: 'item-padding-top', hidden: true },
|
|
24
|
+
{ label: 'item padding-right', variable: '--menuselect-item-padding-right', groupKey: 'item-padding-right', hidden: true },
|
|
25
|
+
{ label: 'item padding-bottom', variable: '--menuselect-item-padding-bottom', groupKey: 'item-padding-bottom', hidden: true },
|
|
26
|
+
{ label: 'item padding-left', variable: '--menuselect-item-padding-left', groupKey: 'item-padding-left', hidden: true },
|
|
27
|
+
],
|
|
28
|
+
'default item': [
|
|
29
|
+
{ label: 'surface color', groupKey: 'surface', variable: '--menuselect-default-surface' },
|
|
30
|
+
{ label: 'icon color', groupKey: 'icon', variable: '--menuselect-default-icon' },
|
|
31
|
+
{ label: 'icon size', canBeLinked: true, groupKey: 'icon-size', variable: '--menuselect-default-icon-size' },
|
|
32
|
+
],
|
|
33
|
+
'hover item': [
|
|
34
|
+
{ label: 'surface color', groupKey: 'surface', variable: '--menuselect-hover-surface' },
|
|
35
|
+
{ label: 'icon color', groupKey: 'icon', variable: '--menuselect-hover-icon' },
|
|
36
|
+
{ label: 'icon size', canBeLinked: true, groupKey: 'icon-size', variable: '--menuselect-hover-icon-size' },
|
|
37
|
+
],
|
|
38
|
+
'selected item': [
|
|
39
|
+
{ label: 'surface color', groupKey: 'surface', variable: '--menuselect-selected-surface' },
|
|
40
|
+
{ label: 'icon color', groupKey: 'icon', variable: '--menuselect-selected-icon' },
|
|
41
|
+
{ label: 'icon size', canBeLinked: true, groupKey: 'icon-size', variable: '--menuselect-selected-icon-size' },
|
|
42
|
+
{ label: 'indicator color', groupKey: 'indicator', variable: '--menuselect-selected-indicator' },
|
|
43
|
+
],
|
|
44
|
+
'disabled item': [
|
|
45
|
+
{ label: 'surface color', groupKey: 'surface', variable: '--menuselect-disabled-surface' },
|
|
46
|
+
{ label: 'icon color', groupKey: 'icon', variable: '--menuselect-disabled-icon' },
|
|
47
|
+
{ label: 'icon size', canBeLinked: true, groupKey: 'icon-size', variable: '--menuselect-disabled-icon-size' },
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// Per-state item-label typography; linkable groupKeys let users collapse or diverge across states.
|
|
52
|
+
const typeGroups: Record<string, TypeGroupConfig[]> = {
|
|
53
|
+
'default item': [{
|
|
54
|
+
legend: 'item label',
|
|
55
|
+
colorVariable: '--menuselect-default-text',
|
|
56
|
+
familyVariable: '--menuselect-default-text-font-family',
|
|
57
|
+
sizeVariable: '--menuselect-default-text-font-size',
|
|
58
|
+
weightVariable: '--menuselect-default-text-font-weight',
|
|
59
|
+
lineHeightVariable: '--menuselect-default-text-line-height',
|
|
60
|
+
}],
|
|
61
|
+
'hover item': [{
|
|
62
|
+
legend: 'item label',
|
|
63
|
+
colorVariable: '--menuselect-hover-text',
|
|
64
|
+
familyVariable: '--menuselect-hover-text-font-family',
|
|
65
|
+
sizeVariable: '--menuselect-hover-text-font-size',
|
|
66
|
+
weightVariable: '--menuselect-hover-text-font-weight',
|
|
67
|
+
lineHeightVariable: '--menuselect-hover-text-line-height',
|
|
68
|
+
}],
|
|
69
|
+
'selected item': [{
|
|
70
|
+
legend: 'item label',
|
|
71
|
+
colorVariable: '--menuselect-selected-text',
|
|
72
|
+
familyVariable: '--menuselect-selected-text-font-family',
|
|
73
|
+
sizeVariable: '--menuselect-selected-text-font-size',
|
|
74
|
+
weightVariable: '--menuselect-selected-text-font-weight',
|
|
75
|
+
lineHeightVariable: '--menuselect-selected-text-line-height',
|
|
76
|
+
}],
|
|
77
|
+
'disabled item': [{
|
|
78
|
+
legend: 'item label',
|
|
79
|
+
colorVariable: '--menuselect-disabled-text',
|
|
80
|
+
familyVariable: '--menuselect-disabled-text-font-family',
|
|
81
|
+
sizeVariable: '--menuselect-disabled-text-font-size',
|
|
82
|
+
weightVariable: '--menuselect-disabled-text-font-weight',
|
|
83
|
+
lineHeightVariable: '--menuselect-disabled-text-line-height',
|
|
84
|
+
}],
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const typeGroupTokens: Token[] = buildTypeGroupTokens(typeGroups);
|
|
88
|
+
export const allTokens: Token[] = [...Object.values(states).flat(), ...typeGroupTokens];
|
|
89
|
+
|
|
90
|
+
const linkableContexts = new Map<string, string>([
|
|
91
|
+
...buildTypeGroupShareableContexts(typeGroups),
|
|
92
|
+
['--menuselect-default-icon-size', 'default item'],
|
|
93
|
+
['--menuselect-hover-icon-size', 'hover item'],
|
|
94
|
+
['--menuselect-selected-icon-size', 'selected item'],
|
|
95
|
+
['--menuselect-disabled-icon-size', 'disabled item'],
|
|
96
|
+
]);
|
|
97
|
+
</script>
|
|
98
|
+
|
|
99
|
+
<script lang="ts">
|
|
100
|
+
import MenuSelect from '../../system/components/MenuSelect.svelte';
|
|
101
|
+
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
102
|
+
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
103
|
+
import { editorState } from '../core/store/editorStore';
|
|
104
|
+
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
105
|
+
|
|
106
|
+
type Item = { value: string; label: string; icon?: string; disabled?: boolean };
|
|
107
|
+
const items: Item[] = [
|
|
108
|
+
{ value: 'option-1', label: 'Option one', icon: 'fas fa-circle' },
|
|
109
|
+
{ value: 'option-2', label: 'Option two', icon: 'fas fa-square' },
|
|
110
|
+
{ value: 'option-3', label: 'Option three', icon: 'fas fa-triangle-exclamation' },
|
|
111
|
+
{ value: 'option-4', label: 'Option four', icon: 'fas fa-ban', disabled: true },
|
|
112
|
+
];
|
|
113
|
+
|
|
114
|
+
let showIcons = $state(true);
|
|
115
|
+
let previewItems = $derived(showIcons ? items : items.map((it) => ({ ...it, icon: undefined })));
|
|
116
|
+
|
|
117
|
+
let linked = $derived(computeLinkedBlock(component, linkableContexts, allTokens, $editorState));
|
|
118
|
+
|
|
119
|
+
let visibleStates = $derived(Object.fromEntries(
|
|
120
|
+
Object.entries(states).map(([name, list]) => [name, withLinkedDisabled(list, linked.varSet)]),
|
|
121
|
+
) as Record<string, Token[]>);
|
|
122
|
+
</script>
|
|
123
|
+
|
|
124
|
+
<ComponentEditorBase {component} title="Menu Select" description="A select-style dropdown panel. Items support default, hover, selected, and disabled states." tokens={allTokens} {linked}>
|
|
125
|
+
<VariantGroup
|
|
126
|
+
name="menuselect"
|
|
127
|
+
title="Menu Select"
|
|
128
|
+
states={visibleStates}
|
|
129
|
+
{typeGroups}
|
|
130
|
+
{component}
|
|
131
|
+
>
|
|
132
|
+
{#snippet canvasToolbarExtras()}
|
|
133
|
+
<hr class="canvas-toolbar-divider" />
|
|
134
|
+
<label class="show-icons-row">
|
|
135
|
+
<input type="checkbox" bind:checked={showIcons} />
|
|
136
|
+
<span>Show icons</span>
|
|
137
|
+
</label>
|
|
138
|
+
{/snippet}
|
|
139
|
+
{#snippet children({ activeState })}
|
|
140
|
+
{@const previewValue = activeState === 'selected item' ? 'option-2' : ''}
|
|
141
|
+
{@const previewForceHover = activeState === 'hover item' ? 'option-1' : null}
|
|
142
|
+
<MenuSelect
|
|
143
|
+
items={previewItems}
|
|
144
|
+
value={previewValue}
|
|
145
|
+
forceHoverValue={previewForceHover}
|
|
146
|
+
/>
|
|
147
|
+
{/snippet}
|
|
148
|
+
</VariantGroup>
|
|
149
|
+
</ComponentEditorBase>
|
|
150
|
+
|
|
151
|
+
<style>
|
|
152
|
+
.show-icons-row {
|
|
153
|
+
display: inline-flex;
|
|
154
|
+
align-items: center;
|
|
155
|
+
gap: var(--ui-space-6);
|
|
156
|
+
font-size: var(--ui-font-size-sm);
|
|
157
|
+
color: rgba(255, 255, 255, 0.78);
|
|
158
|
+
cursor: pointer;
|
|
159
|
+
}
|
|
160
|
+
</style>
|