@motion-proto/live-tokens 0.58.0 → 0.59.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/CHANGELOG.md +49 -0
- package/dist-plugin/generateColorsAndType/index.cjs +4 -3
- package/dist-plugin/generateColorsAndType/index.js +4 -3
- package/package.json +1 -1
- package/src/editor/component-editor/ImageLightboxEditor.svelte +11 -2
- package/src/editor/core/sketch/sketchPresets.ts +8 -8
- package/src/editor/core/themes/parsers/shadow.ts +12 -4
- package/src/editor/ui/ColorEditPanel.svelte +13 -9
- package/src/editor/ui/PaletteEditor.svelte +11 -3
- package/src/editor/ui/UIInlineEditActions.svelte +97 -0
- package/src/live-tokens/data/colors-and-type/autumn.json +5 -5
- package/src/live-tokens/data/colors-and-type/default.json +5 -5
- package/src/live-tokens/data/colors-and-type/halloween.json +5 -5
- package/src/live-tokens/data/colors-and-type/midnight-study.json +5 -5
- package/src/live-tokens/data/colors-and-type/ocean.json +5 -5
- package/src/live-tokens/data/colors-and-type/royal-velvet.json +5 -5
- package/src/live-tokens/data/colors-and-type/sketchy.json +5 -5
- package/src/live-tokens/data/colors-and-type/spring-meadow.json +5 -5
- package/src/live-tokens/data/colors-and-type/sunset.json +5 -5
- package/src/live-tokens/data/themes/autumn.json +5 -5
- package/src/live-tokens/data/themes/halloween.json +5 -5
- package/src/live-tokens/data/themes/midnight-study.json +5 -5
- package/src/live-tokens/data/themes/ocean.json +5 -5
- package/src/live-tokens/data/themes/royal-velvet.json +5 -5
- package/src/live-tokens/data/themes/sketchy.json +5 -5
- package/src/live-tokens/data/themes/spring-meadow.json +5 -5
- package/src/live-tokens/data/themes/sunset.json +5 -5
- package/src/live-tokens/data/tokens.generated.css +5 -5
- package/src/system/components/ImageLightbox.svelte +26 -2
- package/src/system/styles/tokens.css +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,54 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.59.0 — The shadow traces the art
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`shadow` on `ImageLightbox`.** The tile cast its shadow from its own
|
|
8
|
+
rectangle and offered no way out, so a PNG or WebP with transparency sat on a
|
|
9
|
+
phantom slab: the shadow drew the box, and the box was not the picture. Art
|
|
10
|
+
cut out against the page — a device mockup, a logo, a chart on no background —
|
|
11
|
+
showed a hard rounded rectangle behind it. `shadow` now picks where that
|
|
12
|
+
shadow falls. `box` is the old behaviour and stays the default. `content`
|
|
13
|
+
casts from the image's own alpha, so the shadow follows the silhouette.
|
|
14
|
+
`none` drops it. All three read the one `--imagelightbox-tile-shadow` the
|
|
15
|
+
theme already sets — the mode moves the shadow, it does not restyle it. The
|
|
16
|
+
open modal keeps its shadow only under `box`: it casts against a near-opaque
|
|
17
|
+
scrim where nothing reads, and filtering the pan-and-zoom surface would
|
|
18
|
+
repaint it every frame.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- **A shadow token writes its spread slot only when the spread is set.**
|
|
23
|
+
`--shadow-md` read `3px 3px 6px 0px hsla(…)`, and that fourth length was the
|
|
24
|
+
reason a shadow token could not also be a filter: `drop-shadow()` has no
|
|
25
|
+
spread slot, so the declaration was invalid and dropped. Every shipped theme
|
|
26
|
+
carries a zero spread, so the slot said nothing and cost the scale half its
|
|
27
|
+
reach. The zero-spread form is now three lengths, which `box-shadow` reads
|
|
28
|
+
identically and `drop-shadow()` accepts — one token, both properties, no
|
|
29
|
+
second scale to keep in step. The spread control is untouched: dial one and
|
|
30
|
+
the token grows its fourth length back, still a shadow but no longer a
|
|
31
|
+
filter, so a theme with a real spread has no shadow under `content`.
|
|
32
|
+
Four-length values still parse, and normalise on the next save.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- **The colour edit panel wears editor chrome again.** Its confirm, cancel and
|
|
37
|
+
"Remove override" buttons were the shipped `Button` and `InlineEditActions`
|
|
38
|
+
components, which read the theme's own tokens — so the controls you edit a
|
|
39
|
+
theme *with* restyled themselves as you edited, and a saturated success or
|
|
40
|
+
danger palette turned three small chrome buttons into slabs. They are now
|
|
41
|
+
`UIInlineEditActions` and `UIPillButton`, drawn from the theme-immune `--ui-*`
|
|
42
|
+
scale like the rest of the editor. `UIInlineEditActions` is the editor's
|
|
43
|
+
check/cross pair, sized to the 1.5rem chrome buttons it sits beside.
|
|
44
|
+
- **The base colour panel offers a confirm and a cancel.** Opening a palette's
|
|
45
|
+
editor showed the base panel with no way to accept or discard — every slider
|
|
46
|
+
wrote straight through, and only the docked step panel carried the pair. The
|
|
47
|
+
panel now shows both, greyed until an edit is pending; the first touch of a
|
|
48
|
+
slider, a hex field or the eyedropper opens the same session the step panel
|
|
49
|
+
uses, so cancel restores the colour the panel opened with and confirm keeps
|
|
50
|
+
the drag as one undo step.
|
|
51
|
+
|
|
3
52
|
## 0.58.0 — The sketch layer states its contract
|
|
4
53
|
|
|
5
54
|
### Added
|
|
@@ -719,15 +719,16 @@ function computeAngleDistance(x, y) {
|
|
|
719
719
|
return { angle: Math.round(angle), distance };
|
|
720
720
|
}
|
|
721
721
|
function shadowTokenCss(t) {
|
|
722
|
-
|
|
722
|
+
const spread = t.spread ? `${t.spread}px ` : "";
|
|
723
|
+
return `${t.x}px ${t.y}px ${t.blur}px ${spread}hsla(${t.hue}, ${t.saturation}%, ${t.lightness}%, ${t.opacity})`;
|
|
723
724
|
}
|
|
724
725
|
function parseShadowCss(variable, raw) {
|
|
725
|
-
const m = raw.trim().match(/^(-?\d+)px\s+(-?\d+)px\s+(\d+)px\s+(-?\d+)px\s+hsla\(([\d.]+),\s*([\d.]+)%,\s*([\d.]+)%,\s*([\d.]+)\)$/);
|
|
726
|
+
const m = raw.trim().match(/^(-?\d+)px\s+(-?\d+)px\s+(\d+)px\s+(?:(-?\d+)px\s+)?hsla\(([\d.]+),\s*([\d.]+)%,\s*([\d.]+)%,\s*([\d.]+)\)$/);
|
|
726
727
|
if (!m) return null;
|
|
727
728
|
const x = parseInt(m[1], 10);
|
|
728
729
|
const y = parseInt(m[2], 10);
|
|
729
730
|
const blur = parseInt(m[3], 10);
|
|
730
|
-
const spread = parseInt(m[4], 10);
|
|
731
|
+
const spread = m[4] === void 0 ? 0 : parseInt(m[4], 10);
|
|
731
732
|
const hue = Math.round(parseFloat(m[5]));
|
|
732
733
|
const saturation = Math.round(parseFloat(m[6]));
|
|
733
734
|
const lightness = Math.round(parseFloat(m[7]));
|
|
@@ -105,15 +105,16 @@ function computeAngleDistance(x, y) {
|
|
|
105
105
|
return { angle: Math.round(angle), distance };
|
|
106
106
|
}
|
|
107
107
|
function shadowTokenCss(t) {
|
|
108
|
-
|
|
108
|
+
const spread = t.spread ? `${t.spread}px ` : "";
|
|
109
|
+
return `${t.x}px ${t.y}px ${t.blur}px ${spread}hsla(${t.hue}, ${t.saturation}%, ${t.lightness}%, ${t.opacity})`;
|
|
109
110
|
}
|
|
110
111
|
function parseShadowCss(variable, raw) {
|
|
111
|
-
const m = raw.trim().match(/^(-?\d+)px\s+(-?\d+)px\s+(\d+)px\s+(-?\d+)px\s+hsla\(([\d.]+),\s*([\d.]+)%,\s*([\d.]+)%,\s*([\d.]+)\)$/);
|
|
112
|
+
const m = raw.trim().match(/^(-?\d+)px\s+(-?\d+)px\s+(\d+)px\s+(?:(-?\d+)px\s+)?hsla\(([\d.]+),\s*([\d.]+)%,\s*([\d.]+)%,\s*([\d.]+)\)$/);
|
|
112
113
|
if (!m) return null;
|
|
113
114
|
const x = parseInt(m[1], 10);
|
|
114
115
|
const y = parseInt(m[2], 10);
|
|
115
116
|
const blur = parseInt(m[3], 10);
|
|
116
|
-
const spread = parseInt(m[4], 10);
|
|
117
|
+
const spread = m[4] === void 0 ? 0 : parseInt(m[4], 10);
|
|
117
118
|
const hue = Math.round(parseFloat(m[5]));
|
|
118
119
|
const saturation = Math.round(parseFloat(m[6]));
|
|
119
120
|
const lightness = Math.round(parseFloat(m[7]));
|
package/package.json
CHANGED
|
@@ -44,12 +44,13 @@
|
|
|
44
44
|
];
|
|
45
45
|
|
|
46
46
|
let multiple = $state(true);
|
|
47
|
+
let shadow = $state<'box' | 'content' | 'none'>('box');
|
|
47
48
|
</script>
|
|
48
49
|
|
|
49
50
|
<ComponentEditorBase
|
|
50
51
|
{component}
|
|
51
52
|
title="Image Lightbox"
|
|
52
|
-
description="Click an inline image to expand it into a centered modal with a backdrop. Pass multiple images for a gallery (chevrons + counter). Extended mode adds zoom controls and drag panning."
|
|
53
|
+
description="Click an inline image to expand it into a centered modal with a backdrop. Pass multiple images for a gallery (chevrons + counter). Extended mode adds zoom controls and drag panning. `shadow` picks where the one tile-shadow token falls: `box` casts it from the tile rectangle, `content` from the image's own alpha, or `none`."
|
|
53
54
|
tokens={allTokens}
|
|
54
55
|
>
|
|
55
56
|
<VariantGroup name="imagelightbox" title="Image Lightbox" {states} {component}>
|
|
@@ -58,9 +59,17 @@
|
|
|
58
59
|
<input type="checkbox" checked={multiple} onchange={(e) => (multiple = e.currentTarget.checked)} />
|
|
59
60
|
<span>Multiple images</span>
|
|
60
61
|
</label>
|
|
62
|
+
<label class="preview-toggle">
|
|
63
|
+
<span>Shadow</span>
|
|
64
|
+
<select value={shadow} onchange={(e) => (shadow = e.currentTarget.value as typeof shadow)}>
|
|
65
|
+
<option value="box">Box</option>
|
|
66
|
+
<option value="content">Content</option>
|
|
67
|
+
<option value="none">None</option>
|
|
68
|
+
</select>
|
|
69
|
+
</label>
|
|
61
70
|
{/snippet}
|
|
62
71
|
<div class="preview-frame">
|
|
63
|
-
<ImageLightbox images={multiple ? demoImages : [demoImages[0]]} extended />
|
|
72
|
+
<ImageLightbox images={multiple ? demoImages : [demoImages[0]]} {shadow} extended />
|
|
64
73
|
</div>
|
|
65
74
|
</VariantGroup>
|
|
66
75
|
</ComponentEditorBase>
|
|
@@ -151,10 +151,10 @@ export const SKETCH_PRESETS: Record<string, SketchSettings> = {
|
|
|
151
151
|
blurb: 'Broad translucent nib gone round twice on the same line, so the overlap darkens and the ink pools where it slows.',
|
|
152
152
|
fillTravel: 2, strokeTravel: 1.5, wobble: 56, waveform: 1.4, borderWavelength: 1.3,
|
|
153
153
|
strokeWidth: 4, doubleStroke: true, retracePass: 'copy', strokeInk: 0.52, retraceOffset: 2.2,
|
|
154
|
-
maskBlob:
|
|
154
|
+
maskBlob: 115, maskOutputMin: 0.21, maskOutputMax: 1, maskOctaves: 3, maskPosterize: 4, maskSoftness: 2.5,
|
|
155
155
|
jitterX: 3, jitterY: 3, jitterRot: 0.8, jitterScale: 0.045,
|
|
156
156
|
cornerSpread: 10, cornerTravel: 8,
|
|
157
|
-
pressure: 0.2, pressureMod: 0.25, pooling: 2, iconTravel: 1.25,
|
|
157
|
+
pressure: 0.2, pressureMod: 0.25, pooling: 2, iconTravel: 1.25, iconMaskScale: 4,
|
|
158
158
|
},
|
|
159
159
|
|
|
160
160
|
whiteboard: {
|
|
@@ -196,22 +196,22 @@ export const SKETCH_PRESETS: Record<string, SketchSettings> = {
|
|
|
196
196
|
blurb: 'Ballpoint in a hurry. Everything loose at once: a square wave sends every edge to full travel, and the second pass lands wherever it lands.',
|
|
197
197
|
fillTravel: 3, strokeTravel: 2.25, wobble: 50, roughness: 3, waveform: 2.5,
|
|
198
198
|
strokeWidth: 2.25, doubleStroke: true, retracePass: 'reseeded', retraceOffset: 4, strokeInk: 1,
|
|
199
|
-
maskBlob: 150, maskOutputMin: 0.
|
|
199
|
+
maskBlob: 150, maskOutputMin: 0.43, maskOutputMax: 0.95, maskOctaves: 2, maskPosterize: 2, maskSoftness: 6.7,
|
|
200
200
|
jitterX: 6, jitterY: 6, jitterRot: 1.8, jitterScale: 0.1,
|
|
201
201
|
cornerSpread: 20, cornerTravel: 17,
|
|
202
|
-
pressure: 0.45, pressureMod: 0.6, pooling: 2.5, iconTravel: 2.25,
|
|
202
|
+
pressure: 0.45, pressureMod: 0.6, pooling: 2.5, iconTravel: 2.25, iconMaskScale: 3.6,
|
|
203
203
|
},
|
|
204
204
|
|
|
205
205
|
dry: {
|
|
206
206
|
...base, label: 'Dry marker',
|
|
207
|
-
blurb: 'Ink that ran out. One scratchy pass that breaks up along its length, over a fill the mask has
|
|
207
|
+
blurb: 'Ink that ran out. One scratchy pass that breaks up along its length, over a fill the mask has worn nearly through in patches.',
|
|
208
208
|
fillTravel: 2.25, strokeTravel: 1.75, wobble: 50, waveform: 2, borderWavelength: 0.5,
|
|
209
209
|
strokeWidth: 3.5, doubleStroke: false, strokeInk: 0.4,
|
|
210
|
-
maskBlob: 150, maskOutputMin: 0, maskOutputMax: 0.
|
|
211
|
-
maskOctaves: 2, maskPosterize: 4, maskSoftness:
|
|
210
|
+
maskBlob: 150, maskOutputMin: 0.15, maskOutputMax: 0.91,
|
|
211
|
+
maskOctaves: 2, maskPosterize: 4, maskSoftness: 1.75,
|
|
212
212
|
jitterX: 5, jitterY: 5, jitterRot: 1.4, jitterScale: 0.08,
|
|
213
213
|
cornerSpread: 16, cornerTravel: 13,
|
|
214
|
-
pressure: 0.4, pressureMod: 0.8, pooling: 1.5, iconTravel: 1.75, iconMaskScale:
|
|
214
|
+
pressure: 0.4, pressureMod: 0.8, pooling: 1.5, iconTravel: 1.75, iconMaskScale: 3.8,
|
|
215
215
|
},
|
|
216
216
|
};
|
|
217
217
|
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The single source of truth for the CSS form of a shadow scale token:
|
|
3
3
|
*
|
|
4
|
-
* <x>px <y>px <blur>px <spread>px hsla(<h>, <s>%, <l>%, <a>)
|
|
4
|
+
* <x>px <y>px <blur>px [<spread>px] hsla(<h>, <s>%, <l>%, <a>)
|
|
5
|
+
*
|
|
6
|
+
* The spread slot is written only when it is non-zero. A three-length shadow is
|
|
7
|
+
* legal in `box-shadow` (spread defaults to 0) and in `filter: drop-shadow()`,
|
|
8
|
+
* which has no spread slot at all — so one token dresses both, and a component
|
|
9
|
+
* casting from an image's alpha reads the same variable as one casting from a
|
|
10
|
+
* box. Dial a spread and the token grows its fourth length: still a shadow,
|
|
11
|
+
* no longer a filter.
|
|
5
12
|
*
|
|
6
13
|
* Everything that reads or writes that form goes through `parseShadowCss` /
|
|
7
14
|
* `shadowTokenCss`, so the theme generator (Node, no store) and the editor
|
|
@@ -33,16 +40,17 @@ export function computeAngleDistance(x: number, y: number): { angle: number; dis
|
|
|
33
40
|
}
|
|
34
41
|
|
|
35
42
|
export function shadowTokenCss(t: ShadowValue): string {
|
|
36
|
-
|
|
43
|
+
const spread = t.spread ? `${t.spread}px ` : '';
|
|
44
|
+
return `${t.x}px ${t.y}px ${t.blur}px ${spread}hsla(${t.hue}, ${t.saturation}%, ${t.lightness}%, ${t.opacity})`;
|
|
37
45
|
}
|
|
38
46
|
|
|
39
47
|
export function parseShadowCss(variable: string, raw: string): ShadowToken | null {
|
|
40
|
-
const m = raw.trim().match(/^(-?\d+)px\s+(-?\d+)px\s+(\d+)px\s+(-?\d+)px\s+hsla\(([\d.]+),\s*([\d.]+)%,\s*([\d.]+)%,\s*([\d.]+)\)$/);
|
|
48
|
+
const m = raw.trim().match(/^(-?\d+)px\s+(-?\d+)px\s+(\d+)px\s+(?:(-?\d+)px\s+)?hsla\(([\d.]+),\s*([\d.]+)%,\s*([\d.]+)%,\s*([\d.]+)\)$/);
|
|
41
49
|
if (!m) return null;
|
|
42
50
|
const x = parseInt(m[1], 10);
|
|
43
51
|
const y = parseInt(m[2], 10);
|
|
44
52
|
const blur = parseInt(m[3], 10);
|
|
45
|
-
const spread = parseInt(m[4], 10);
|
|
53
|
+
const spread = m[4] === undefined ? 0 : parseInt(m[4], 10);
|
|
46
54
|
const hue = Math.round(parseFloat(m[5]));
|
|
47
55
|
const saturation = Math.round(parseFloat(m[6]));
|
|
48
56
|
const lightness = Math.round(parseFloat(m[7]));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { hexToOklch, oklchToHex, gamutClamp } from '../core/palettes/oklch';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import UIInlineEditActions from './UIInlineEditActions.svelte';
|
|
4
|
+
import UIPillButton from './UIPillButton.svelte';
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
/** Hide the confirm/cancel actions for live-apply consumers (Colors view
|
|
16
16
|
* readout) where edits commit through the store as they happen. */
|
|
17
17
|
hideActions?: boolean;
|
|
18
|
+
/** Greys the confirm/cancel pair out while no edit is pending. */
|
|
19
|
+
actionsDisabled?: boolean;
|
|
18
20
|
/** Hide the preview square where the surrounding view already shows the
|
|
19
21
|
* color (Colors view: wheel, swatches and derived scale all do). */
|
|
20
22
|
hidePreview?: boolean;
|
|
@@ -43,6 +45,7 @@
|
|
|
43
45
|
highlighted = false,
|
|
44
46
|
showRemoveOverride = false,
|
|
45
47
|
hideActions = false,
|
|
48
|
+
actionsDisabled = false,
|
|
46
49
|
hidePreview = false,
|
|
47
50
|
onConfirm = () => {},
|
|
48
51
|
onCancel = () => {},
|
|
@@ -171,16 +174,17 @@
|
|
|
171
174
|
{#if !hideActions}
|
|
172
175
|
<div class="hsl-panel-actions">
|
|
173
176
|
{#if showRemoveOverride}
|
|
174
|
-
<
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
icon="
|
|
178
|
-
|
|
179
|
-
>Remove override</
|
|
177
|
+
<UIPillButton
|
|
178
|
+
size="compact"
|
|
179
|
+
variant="outline"
|
|
180
|
+
icon="fa-trash"
|
|
181
|
+
onclick={onRemoveOverride}
|
|
182
|
+
>Remove override</UIPillButton>
|
|
180
183
|
{/if}
|
|
181
|
-
<
|
|
184
|
+
<UIInlineEditActions
|
|
182
185
|
onSave={onConfirm}
|
|
183
186
|
onCancel={onCancel}
|
|
187
|
+
disabled={actionsDisabled}
|
|
184
188
|
saveTitle="Apply changes"
|
|
185
189
|
cancelTitle="Discard changes"
|
|
186
190
|
/>
|
|
@@ -203,6 +203,14 @@
|
|
|
203
203
|
|
|
204
204
|
function startBaseEdit() {
|
|
205
205
|
if (editing.kind === 'editingBase') { confirmEdit(); return; }
|
|
206
|
+
ensureBaseSession();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// The base panel applies every change straight to the store, so its
|
|
210
|
+
// confirm/cancel pair needs a session to act on. Opening one lazily on the
|
|
211
|
+
// first touch keeps the panel's mere presence from clipping the undo floor.
|
|
212
|
+
function ensureBaseSession() {
|
|
213
|
+
if (editing.kind === 'editingBase') return;
|
|
206
214
|
editing = { kind: 'editingBase' };
|
|
207
215
|
openSession();
|
|
208
216
|
}
|
|
@@ -626,18 +634,18 @@
|
|
|
626
634
|
<ColorEditPanel
|
|
627
635
|
title={basePanelTitle}
|
|
628
636
|
showRemoveOverride={false}
|
|
629
|
-
|
|
637
|
+
actionsDisabled={!isEditingBase}
|
|
630
638
|
hidePreview
|
|
631
639
|
hue={baseColor.h}
|
|
632
640
|
chroma={baseColor.c}
|
|
633
641
|
lightness={baseColor.l * 100}
|
|
634
642
|
chromaMax={BASE_CHROMA_MAX}
|
|
635
643
|
chromaHint={neutral ? NEUTRAL_CALM_CHROMA : undefined}
|
|
636
|
-
onHueChromaChange={(h, c, l) => setBaseColor(label, { l: l / 100, c, h })}
|
|
644
|
+
onHueChromaChange={(h, c, l) => { ensureBaseSession(); setBaseColor(label, { l: l / 100, c, h }); }}
|
|
637
645
|
onConfirm={confirmEdit}
|
|
638
646
|
onCancel={cancelEdit}
|
|
639
647
|
onRemoveOverride={() => {}}
|
|
640
|
-
onSliderStart={() => beginSliderGesture(`edit ${label} base`)}
|
|
648
|
+
onSliderStart={() => { ensureBaseSession(); beginSliderGesture(`edit ${label} base`); }}
|
|
641
649
|
/>
|
|
642
650
|
</div>
|
|
643
651
|
</div>
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
interface Props {
|
|
3
|
+
onSave: () => void | Promise<void>;
|
|
4
|
+
onCancel: () => void;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
saveTitle?: string;
|
|
7
|
+
cancelTitle?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let {
|
|
11
|
+
onSave,
|
|
12
|
+
onCancel,
|
|
13
|
+
disabled = false,
|
|
14
|
+
saveTitle = 'Save',
|
|
15
|
+
cancelTitle = 'Cancel'
|
|
16
|
+
}: Props = $props();
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<div class="ui-inline-actions">
|
|
20
|
+
<button
|
|
21
|
+
class="ui-ia ui-ia-save"
|
|
22
|
+
type="button"
|
|
23
|
+
{disabled}
|
|
24
|
+
title={saveTitle}
|
|
25
|
+
aria-label={saveTitle}
|
|
26
|
+
onclick={onSave}
|
|
27
|
+
><i class="fas fa-check" aria-hidden="true"></i></button>
|
|
28
|
+
<button
|
|
29
|
+
class="ui-ia ui-ia-cancel"
|
|
30
|
+
type="button"
|
|
31
|
+
{disabled}
|
|
32
|
+
title={cancelTitle}
|
|
33
|
+
aria-label={cancelTitle}
|
|
34
|
+
onclick={onCancel}
|
|
35
|
+
><i class="fas fa-xmark" aria-hidden="true"></i></button>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<style>
|
|
39
|
+
.ui-inline-actions {
|
|
40
|
+
display: inline-flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
gap: var(--ui-space-4);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* Sized to the 1.5rem chrome buttons it sits beside (eyedropper, swatch). */
|
|
46
|
+
.ui-ia {
|
|
47
|
+
display: inline-flex;
|
|
48
|
+
align-items: center;
|
|
49
|
+
justify-content: center;
|
|
50
|
+
width: 1.5rem;
|
|
51
|
+
height: 1.5rem;
|
|
52
|
+
padding: 0;
|
|
53
|
+
border-radius: var(--ui-radius-sm);
|
|
54
|
+
font-size: var(--ui-font-size-xs);
|
|
55
|
+
line-height: 1;
|
|
56
|
+
cursor: pointer;
|
|
57
|
+
transition:
|
|
58
|
+
background var(--ui-transition-fast),
|
|
59
|
+
border-color var(--ui-transition-fast),
|
|
60
|
+
color var(--ui-transition-fast);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.ui-ia-save {
|
|
64
|
+
background: linear-gradient(180deg, rgba(90, 168, 94, 0.35) 0%, rgba(90, 168, 94, 0.18) 100%);
|
|
65
|
+
border: 1px solid rgba(90, 168, 94, 0.6);
|
|
66
|
+
color: var(--ui-text-primary);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.ui-ia-save:hover:not(:disabled) {
|
|
70
|
+
background: linear-gradient(180deg, rgba(90, 168, 94, 0.48) 0%, rgba(90, 168, 94, 0.26) 100%);
|
|
71
|
+
border-color: rgba(90, 168, 94, 0.78);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.ui-ia-cancel {
|
|
75
|
+
background: linear-gradient(180deg, rgba(255, 255, 255, 0.06) 0%, rgba(255, 255, 255, 0.02) 100%);
|
|
76
|
+
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
77
|
+
color: var(--ui-text-secondary);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.ui-ia-cancel:hover:not(:disabled) {
|
|
81
|
+
background: linear-gradient(180deg, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0.05) 100%);
|
|
82
|
+
border-color: rgba(255, 255, 255, 0.5);
|
|
83
|
+
color: var(--ui-text-primary);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.ui-ia:focus-visible {
|
|
87
|
+
outline: none;
|
|
88
|
+
box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.18);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.ui-ia:disabled {
|
|
92
|
+
background: linear-gradient(180deg, rgba(255, 255, 255, 0.04) 0%, rgba(255, 255, 255, 0.02) 100%);
|
|
93
|
+
border-color: rgba(255, 255, 255, 0.14);
|
|
94
|
+
color: var(--ui-text-disabled);
|
|
95
|
+
cursor: not-allowed;
|
|
96
|
+
}
|
|
97
|
+
</style>
|
|
@@ -2265,11 +2265,11 @@
|
|
|
2265
2265
|
"--hover-low": "color-mix(in srgb, var(--text-primary) 5%, transparent)",
|
|
2266
2266
|
"--hover": "color-mix(in srgb, var(--text-primary) 10%, transparent)",
|
|
2267
2267
|
"--hover-high": "color-mix(in srgb, var(--text-primary) 15%, transparent)",
|
|
2268
|
-
"--shadow-sm": "1px 1px 2px
|
|
2269
|
-
"--shadow-md": "3px 3px 6px
|
|
2270
|
-
"--shadow-lg": "5px 5px 9px
|
|
2271
|
-
"--shadow-xl": "6px 7px 13px
|
|
2272
|
-
"--shadow-2xl": "8px 9px 16px
|
|
2268
|
+
"--shadow-sm": "1px 1px 2px hsla(237, 18%, 3%, 0.25)",
|
|
2269
|
+
"--shadow-md": "3px 3px 6px hsla(237, 18%, 3%, 0.25)",
|
|
2270
|
+
"--shadow-lg": "5px 5px 9px hsla(237, 18%, 3%, 0.25)",
|
|
2271
|
+
"--shadow-xl": "6px 7px 13px hsla(237, 18%, 3%, 0.25)",
|
|
2272
|
+
"--shadow-2xl": "8px 9px 16px hsla(237, 18%, 3%, 0.25)"
|
|
2273
2273
|
},
|
|
2274
2274
|
"fontSources": [
|
|
2275
2275
|
{
|
|
@@ -2296,11 +2296,11 @@
|
|
|
2296
2296
|
"--hover-low": "color-mix(in srgb, var(--text-primary) 5%, transparent)",
|
|
2297
2297
|
"--hover": "color-mix(in srgb, var(--text-primary) 10%, transparent)",
|
|
2298
2298
|
"--hover-high": "color-mix(in srgb, var(--text-primary) 15%, transparent)",
|
|
2299
|
-
"--shadow-sm": "1px 1px 2px
|
|
2300
|
-
"--shadow-md": "3px 3px 6px
|
|
2301
|
-
"--shadow-lg": "5px 5px 9px
|
|
2302
|
-
"--shadow-xl": "6px 7px 13px
|
|
2303
|
-
"--shadow-2xl": "8px 9px 16px
|
|
2299
|
+
"--shadow-sm": "1px 1px 2px hsla(237, 18%, 3%, 0.9)",
|
|
2300
|
+
"--shadow-md": "3px 3px 6px hsla(237, 18%, 3%, 0.9)",
|
|
2301
|
+
"--shadow-lg": "5px 5px 9px hsla(237, 18%, 3%, 0.9)",
|
|
2302
|
+
"--shadow-xl": "6px 7px 13px hsla(237, 18%, 3%, 0.9)",
|
|
2303
|
+
"--shadow-2xl": "8px 9px 16px hsla(237, 18%, 3%, 0.9)"
|
|
2304
2304
|
},
|
|
2305
2305
|
"fontSources": [
|
|
2306
2306
|
{
|
|
@@ -2312,11 +2312,11 @@
|
|
|
2312
2312
|
"--hover-low": "color-mix(in srgb, var(--text-primary) 5%, transparent)",
|
|
2313
2313
|
"--hover": "color-mix(in srgb, var(--text-primary) 10%, transparent)",
|
|
2314
2314
|
"--hover-high": "color-mix(in srgb, var(--text-primary) 15%, transparent)",
|
|
2315
|
-
"--shadow-sm": "1px 1px 2px
|
|
2316
|
-
"--shadow-md": "3px 3px 6px
|
|
2317
|
-
"--shadow-lg": "5px 5px 9px
|
|
2318
|
-
"--shadow-xl": "6px 7px 13px
|
|
2319
|
-
"--shadow-2xl": "8px 9px 16px
|
|
2315
|
+
"--shadow-sm": "1px 1px 2px hsla(237, 18%, 3%, 0.9)",
|
|
2316
|
+
"--shadow-md": "3px 3px 6px hsla(237, 18%, 3%, 0.9)",
|
|
2317
|
+
"--shadow-lg": "5px 5px 9px hsla(237, 18%, 3%, 0.9)",
|
|
2318
|
+
"--shadow-xl": "6px 7px 13px hsla(237, 18%, 3%, 0.9)",
|
|
2319
|
+
"--shadow-2xl": "8px 9px 16px hsla(237, 18%, 3%, 0.9)"
|
|
2320
2320
|
},
|
|
2321
2321
|
"fontSources": [
|
|
2322
2322
|
{
|
|
@@ -2312,11 +2312,11 @@
|
|
|
2312
2312
|
"--hover-low": "color-mix(in srgb, var(--text-primary) 5%, transparent)",
|
|
2313
2313
|
"--hover": "color-mix(in srgb, var(--text-primary) 10%, transparent)",
|
|
2314
2314
|
"--hover-high": "color-mix(in srgb, var(--text-primary) 15%, transparent)",
|
|
2315
|
-
"--shadow-sm": "1px 1px 2px
|
|
2316
|
-
"--shadow-md": "3px 3px 6px
|
|
2317
|
-
"--shadow-lg": "5px 5px 9px
|
|
2318
|
-
"--shadow-xl": "6px 7px 13px
|
|
2319
|
-
"--shadow-2xl": "8px 9px 16px
|
|
2315
|
+
"--shadow-sm": "1px 1px 2px hsla(237, 18%, 3%, 0.9)",
|
|
2316
|
+
"--shadow-md": "3px 3px 6px hsla(237, 18%, 3%, 0.9)",
|
|
2317
|
+
"--shadow-lg": "5px 5px 9px hsla(237, 18%, 3%, 0.9)",
|
|
2318
|
+
"--shadow-xl": "6px 7px 13px hsla(237, 18%, 3%, 0.9)",
|
|
2319
|
+
"--shadow-2xl": "8px 9px 16px hsla(237, 18%, 3%, 0.9)"
|
|
2320
2320
|
},
|
|
2321
2321
|
"fontSources": [
|
|
2322
2322
|
{
|
|
@@ -2265,11 +2265,11 @@
|
|
|
2265
2265
|
"--hover-low": "color-mix(in srgb, var(--text-primary) 5%, transparent)",
|
|
2266
2266
|
"--hover": "color-mix(in srgb, var(--text-primary) 10%, transparent)",
|
|
2267
2267
|
"--hover-high": "color-mix(in srgb, var(--text-primary) 15%, transparent)",
|
|
2268
|
-
"--shadow-sm": "1px 1px 2px
|
|
2269
|
-
"--shadow-md": "3px 3px 6px
|
|
2270
|
-
"--shadow-lg": "5px 5px 9px
|
|
2271
|
-
"--shadow-xl": "6px 7px 13px
|
|
2272
|
-
"--shadow-2xl": "8px 9px 16px
|
|
2268
|
+
"--shadow-sm": "1px 1px 2px hsla(237, 18%, 3%, 0.2)",
|
|
2269
|
+
"--shadow-md": "3px 3px 6px hsla(237, 18%, 3%, 0.2)",
|
|
2270
|
+
"--shadow-lg": "5px 5px 9px hsla(237, 18%, 3%, 0.2)",
|
|
2271
|
+
"--shadow-xl": "6px 7px 13px hsla(237, 18%, 3%, 0.2)",
|
|
2272
|
+
"--shadow-2xl": "8px 9px 16px hsla(237, 18%, 3%, 0.2)"
|
|
2273
2273
|
},
|
|
2274
2274
|
"fontSources": [
|
|
2275
2275
|
{
|
|
@@ -2297,11 +2297,11 @@
|
|
|
2297
2297
|
"--hover-low": "color-mix(in srgb, var(--text-primary) 5%, transparent)",
|
|
2298
2298
|
"--hover": "color-mix(in srgb, var(--text-primary) 10%, transparent)",
|
|
2299
2299
|
"--hover-high": "color-mix(in srgb, var(--text-primary) 15%, transparent)",
|
|
2300
|
-
"--shadow-sm": "1px 1px 2px
|
|
2301
|
-
"--shadow-md": "3px 3px 6px
|
|
2302
|
-
"--shadow-lg": "5px 5px 9px
|
|
2303
|
-
"--shadow-xl": "6px 7px 13px
|
|
2304
|
-
"--shadow-2xl": "8px 9px 16px
|
|
2300
|
+
"--shadow-sm": "1px 1px 2px hsla(237, 18%, 3%, 0.9)",
|
|
2301
|
+
"--shadow-md": "3px 3px 6px hsla(237, 18%, 3%, 0.9)",
|
|
2302
|
+
"--shadow-lg": "5px 5px 9px hsla(237, 18%, 3%, 0.9)",
|
|
2303
|
+
"--shadow-xl": "6px 7px 13px hsla(237, 18%, 3%, 0.9)",
|
|
2304
|
+
"--shadow-2xl": "8px 9px 16px hsla(237, 18%, 3%, 0.9)"
|
|
2305
2305
|
},
|
|
2306
2306
|
"fontSources": [
|
|
2307
2307
|
{
|
|
@@ -2251,11 +2251,11 @@
|
|
|
2251
2251
|
"--hover-low": "color-mix(in srgb, var(--text-primary) 5%, transparent)",
|
|
2252
2252
|
"--hover": "color-mix(in srgb, var(--text-primary) 10%, transparent)",
|
|
2253
2253
|
"--hover-high": "color-mix(in srgb, var(--text-primary) 15%, transparent)",
|
|
2254
|
-
"--shadow-sm": "1px 1px 2px
|
|
2255
|
-
"--shadow-md": "3px 3px 6px
|
|
2256
|
-
"--shadow-lg": "5px 5px 9px
|
|
2257
|
-
"--shadow-xl": "6px 7px 13px
|
|
2258
|
-
"--shadow-2xl": "8px 9px 16px
|
|
2254
|
+
"--shadow-sm": "1px 1px 2px hsla(237, 18%, 3%, 0.2)",
|
|
2255
|
+
"--shadow-md": "3px 3px 6px hsla(237, 18%, 3%, 0.2)",
|
|
2256
|
+
"--shadow-lg": "5px 5px 9px hsla(237, 18%, 3%, 0.2)",
|
|
2257
|
+
"--shadow-xl": "6px 7px 13px hsla(237, 18%, 3%, 0.2)",
|
|
2258
|
+
"--shadow-2xl": "8px 9px 16px hsla(237, 18%, 3%, 0.2)"
|
|
2259
2259
|
},
|
|
2260
2260
|
"fontSources": [
|
|
2261
2261
|
{
|
|
@@ -2251,11 +2251,11 @@
|
|
|
2251
2251
|
"--hover-low": "color-mix(in srgb, var(--text-primary) 5%, transparent)",
|
|
2252
2252
|
"--hover": "color-mix(in srgb, var(--text-primary) 10%, transparent)",
|
|
2253
2253
|
"--hover-high": "color-mix(in srgb, var(--text-primary) 15%, transparent)",
|
|
2254
|
-
"--shadow-sm": "1px 1px 2px
|
|
2255
|
-
"--shadow-md": "3px 3px 6px
|
|
2256
|
-
"--shadow-lg": "5px 5px 9px
|
|
2257
|
-
"--shadow-xl": "6px 7px 13px
|
|
2258
|
-
"--shadow-2xl": "8px 9px 16px
|
|
2254
|
+
"--shadow-sm": "1px 1px 2px hsla(237, 18%, 3%, 0.2)",
|
|
2255
|
+
"--shadow-md": "3px 3px 6px hsla(237, 18%, 3%, 0.2)",
|
|
2256
|
+
"--shadow-lg": "5px 5px 9px hsla(237, 18%, 3%, 0.2)",
|
|
2257
|
+
"--shadow-xl": "6px 7px 13px hsla(237, 18%, 3%, 0.2)",
|
|
2258
|
+
"--shadow-2xl": "8px 9px 16px hsla(237, 18%, 3%, 0.2)"
|
|
2259
2259
|
},
|
|
2260
2260
|
"fontSources": [
|
|
2261
2261
|
{
|
|
@@ -2312,11 +2312,11 @@
|
|
|
2312
2312
|
"--hover-low": "color-mix(in srgb, var(--text-primary) 5%, transparent)",
|
|
2313
2313
|
"--hover": "color-mix(in srgb, var(--text-primary) 10%, transparent)",
|
|
2314
2314
|
"--hover-high": "color-mix(in srgb, var(--text-primary) 15%, transparent)",
|
|
2315
|
-
"--shadow-sm": "1px 1px 2px
|
|
2316
|
-
"--shadow-md": "3px 3px 6px
|
|
2317
|
-
"--shadow-lg": "5px 5px 9px
|
|
2318
|
-
"--shadow-xl": "6px 7px 13px
|
|
2319
|
-
"--shadow-2xl": "8px 9px 16px
|
|
2315
|
+
"--shadow-sm": "1px 1px 2px hsla(237, 18%, 3%, 0.9)",
|
|
2316
|
+
"--shadow-md": "3px 3px 6px hsla(237, 18%, 3%, 0.9)",
|
|
2317
|
+
"--shadow-lg": "5px 5px 9px hsla(237, 18%, 3%, 0.9)",
|
|
2318
|
+
"--shadow-xl": "6px 7px 13px hsla(237, 18%, 3%, 0.9)",
|
|
2319
|
+
"--shadow-2xl": "8px 9px 16px hsla(237, 18%, 3%, 0.9)"
|
|
2320
2320
|
},
|
|
2321
2321
|
"fontSources": [
|
|
2322
2322
|
{
|
|
@@ -2270,11 +2270,11 @@
|
|
|
2270
2270
|
"--hover-low": "color-mix(in srgb, var(--text-primary) 5%, transparent)",
|
|
2271
2271
|
"--hover": "color-mix(in srgb, var(--text-primary) 10%, transparent)",
|
|
2272
2272
|
"--hover-high": "color-mix(in srgb, var(--text-primary) 15%, transparent)",
|
|
2273
|
-
"--shadow-sm": "1px 1px 2px
|
|
2274
|
-
"--shadow-md": "3px 3px 6px
|
|
2275
|
-
"--shadow-lg": "5px 5px 9px
|
|
2276
|
-
"--shadow-xl": "6px 7px 13px
|
|
2277
|
-
"--shadow-2xl": "8px 9px 16px
|
|
2273
|
+
"--shadow-sm": "1px 1px 2px hsla(237, 18%, 3%, 0.25)",
|
|
2274
|
+
"--shadow-md": "3px 3px 6px hsla(237, 18%, 3%, 0.25)",
|
|
2275
|
+
"--shadow-lg": "5px 5px 9px hsla(237, 18%, 3%, 0.25)",
|
|
2276
|
+
"--shadow-xl": "6px 7px 13px hsla(237, 18%, 3%, 0.25)",
|
|
2277
|
+
"--shadow-2xl": "8px 9px 16px hsla(237, 18%, 3%, 0.25)"
|
|
2278
2278
|
},
|
|
2279
2279
|
"fontSources": [
|
|
2280
2280
|
{
|
|
@@ -2317,11 +2317,11 @@
|
|
|
2317
2317
|
"--hover-low": "color-mix(in srgb, var(--text-primary) 5%, transparent)",
|
|
2318
2318
|
"--hover": "color-mix(in srgb, var(--text-primary) 10%, transparent)",
|
|
2319
2319
|
"--hover-high": "color-mix(in srgb, var(--text-primary) 15%, transparent)",
|
|
2320
|
-
"--shadow-sm": "1px 1px 2px
|
|
2321
|
-
"--shadow-md": "3px 3px 6px
|
|
2322
|
-
"--shadow-lg": "5px 5px 9px
|
|
2323
|
-
"--shadow-xl": "6px 7px 13px
|
|
2324
|
-
"--shadow-2xl": "8px 9px 16px
|
|
2320
|
+
"--shadow-sm": "1px 1px 2px hsla(237, 18%, 3%, 0.9)",
|
|
2321
|
+
"--shadow-md": "3px 3px 6px hsla(237, 18%, 3%, 0.9)",
|
|
2322
|
+
"--shadow-lg": "5px 5px 9px hsla(237, 18%, 3%, 0.9)",
|
|
2323
|
+
"--shadow-xl": "6px 7px 13px hsla(237, 18%, 3%, 0.9)",
|
|
2324
|
+
"--shadow-2xl": "8px 9px 16px hsla(237, 18%, 3%, 0.9)"
|
|
2325
2325
|
},
|
|
2326
2326
|
"fontSources": [
|
|
2327
2327
|
{
|
|
@@ -2317,11 +2317,11 @@
|
|
|
2317
2317
|
"--hover-low": "color-mix(in srgb, var(--text-primary) 5%, transparent)",
|
|
2318
2318
|
"--hover": "color-mix(in srgb, var(--text-primary) 10%, transparent)",
|
|
2319
2319
|
"--hover-high": "color-mix(in srgb, var(--text-primary) 15%, transparent)",
|
|
2320
|
-
"--shadow-sm": "1px 1px 2px
|
|
2321
|
-
"--shadow-md": "3px 3px 6px
|
|
2322
|
-
"--shadow-lg": "5px 5px 9px
|
|
2323
|
-
"--shadow-xl": "6px 7px 13px
|
|
2324
|
-
"--shadow-2xl": "8px 9px 16px
|
|
2320
|
+
"--shadow-sm": "1px 1px 2px hsla(237, 18%, 3%, 0.9)",
|
|
2321
|
+
"--shadow-md": "3px 3px 6px hsla(237, 18%, 3%, 0.9)",
|
|
2322
|
+
"--shadow-lg": "5px 5px 9px hsla(237, 18%, 3%, 0.9)",
|
|
2323
|
+
"--shadow-xl": "6px 7px 13px hsla(237, 18%, 3%, 0.9)",
|
|
2324
|
+
"--shadow-2xl": "8px 9px 16px hsla(237, 18%, 3%, 0.9)"
|
|
2325
2325
|
},
|
|
2326
2326
|
"fontSources": [
|
|
2327
2327
|
{
|
|
@@ -2270,11 +2270,11 @@
|
|
|
2270
2270
|
"--hover-low": "color-mix(in srgb, var(--text-primary) 5%, transparent)",
|
|
2271
2271
|
"--hover": "color-mix(in srgb, var(--text-primary) 10%, transparent)",
|
|
2272
2272
|
"--hover-high": "color-mix(in srgb, var(--text-primary) 15%, transparent)",
|
|
2273
|
-
"--shadow-sm": "1px 1px 2px
|
|
2274
|
-
"--shadow-md": "3px 3px 6px
|
|
2275
|
-
"--shadow-lg": "5px 5px 9px
|
|
2276
|
-
"--shadow-xl": "6px 7px 13px
|
|
2277
|
-
"--shadow-2xl": "8px 9px 16px
|
|
2273
|
+
"--shadow-sm": "1px 1px 2px hsla(237, 18%, 3%, 0.2)",
|
|
2274
|
+
"--shadow-md": "3px 3px 6px hsla(237, 18%, 3%, 0.2)",
|
|
2275
|
+
"--shadow-lg": "5px 5px 9px hsla(237, 18%, 3%, 0.2)",
|
|
2276
|
+
"--shadow-xl": "6px 7px 13px hsla(237, 18%, 3%, 0.2)",
|
|
2277
|
+
"--shadow-2xl": "8px 9px 16px hsla(237, 18%, 3%, 0.2)"
|
|
2278
2278
|
},
|
|
2279
2279
|
"fontSources": [
|
|
2280
2280
|
{
|
|
@@ -2302,11 +2302,11 @@
|
|
|
2302
2302
|
"--hover-low": "color-mix(in srgb, var(--text-primary) 5%, transparent)",
|
|
2303
2303
|
"--hover": "color-mix(in srgb, var(--text-primary) 10%, transparent)",
|
|
2304
2304
|
"--hover-high": "color-mix(in srgb, var(--text-primary) 15%, transparent)",
|
|
2305
|
-
"--shadow-sm": "1px 1px 2px
|
|
2306
|
-
"--shadow-md": "3px 3px 6px
|
|
2307
|
-
"--shadow-lg": "5px 5px 9px
|
|
2308
|
-
"--shadow-xl": "6px 7px 13px
|
|
2309
|
-
"--shadow-2xl": "8px 9px 16px
|
|
2305
|
+
"--shadow-sm": "1px 1px 2px hsla(237, 18%, 3%, 0.9)",
|
|
2306
|
+
"--shadow-md": "3px 3px 6px hsla(237, 18%, 3%, 0.9)",
|
|
2307
|
+
"--shadow-lg": "5px 5px 9px hsla(237, 18%, 3%, 0.9)",
|
|
2308
|
+
"--shadow-xl": "6px 7px 13px hsla(237, 18%, 3%, 0.9)",
|
|
2309
|
+
"--shadow-2xl": "8px 9px 16px hsla(237, 18%, 3%, 0.9)"
|
|
2310
2310
|
},
|
|
2311
2311
|
"fontSources": [
|
|
2312
2312
|
{
|
|
@@ -2256,11 +2256,11 @@
|
|
|
2256
2256
|
"--hover-low": "color-mix(in srgb, var(--text-primary) 5%, transparent)",
|
|
2257
2257
|
"--hover": "color-mix(in srgb, var(--text-primary) 10%, transparent)",
|
|
2258
2258
|
"--hover-high": "color-mix(in srgb, var(--text-primary) 15%, transparent)",
|
|
2259
|
-
"--shadow-sm": "1px 1px 2px
|
|
2260
|
-
"--shadow-md": "3px 3px 6px
|
|
2261
|
-
"--shadow-lg": "5px 5px 9px
|
|
2262
|
-
"--shadow-xl": "6px 7px 13px
|
|
2263
|
-
"--shadow-2xl": "8px 9px 16px
|
|
2259
|
+
"--shadow-sm": "1px 1px 2px hsla(237, 18%, 3%, 0.2)",
|
|
2260
|
+
"--shadow-md": "3px 3px 6px hsla(237, 18%, 3%, 0.2)",
|
|
2261
|
+
"--shadow-lg": "5px 5px 9px hsla(237, 18%, 3%, 0.2)",
|
|
2262
|
+
"--shadow-xl": "6px 7px 13px hsla(237, 18%, 3%, 0.2)",
|
|
2263
|
+
"--shadow-2xl": "8px 9px 16px hsla(237, 18%, 3%, 0.2)"
|
|
2264
2264
|
},
|
|
2265
2265
|
"fontSources": [
|
|
2266
2266
|
{
|
|
@@ -2256,11 +2256,11 @@
|
|
|
2256
2256
|
"--hover-low": "color-mix(in srgb, var(--text-primary) 5%, transparent)",
|
|
2257
2257
|
"--hover": "color-mix(in srgb, var(--text-primary) 10%, transparent)",
|
|
2258
2258
|
"--hover-high": "color-mix(in srgb, var(--text-primary) 15%, transparent)",
|
|
2259
|
-
"--shadow-sm": "1px 1px 2px
|
|
2260
|
-
"--shadow-md": "3px 3px 6px
|
|
2261
|
-
"--shadow-lg": "5px 5px 9px
|
|
2262
|
-
"--shadow-xl": "6px 7px 13px
|
|
2263
|
-
"--shadow-2xl": "8px 9px 16px
|
|
2259
|
+
"--shadow-sm": "1px 1px 2px hsla(237, 18%, 3%, 0.2)",
|
|
2260
|
+
"--shadow-md": "3px 3px 6px hsla(237, 18%, 3%, 0.2)",
|
|
2261
|
+
"--shadow-lg": "5px 5px 9px hsla(237, 18%, 3%, 0.2)",
|
|
2262
|
+
"--shadow-xl": "6px 7px 13px hsla(237, 18%, 3%, 0.2)",
|
|
2263
|
+
"--shadow-2xl": "8px 9px 16px hsla(237, 18%, 3%, 0.2)"
|
|
2264
2264
|
},
|
|
2265
2265
|
"fontSources": [
|
|
2266
2266
|
{
|
|
@@ -2317,11 +2317,11 @@
|
|
|
2317
2317
|
"--hover-low": "color-mix(in srgb, var(--text-primary) 5%, transparent)",
|
|
2318
2318
|
"--hover": "color-mix(in srgb, var(--text-primary) 10%, transparent)",
|
|
2319
2319
|
"--hover-high": "color-mix(in srgb, var(--text-primary) 15%, transparent)",
|
|
2320
|
-
"--shadow-sm": "1px 1px 2px
|
|
2321
|
-
"--shadow-md": "3px 3px 6px
|
|
2322
|
-
"--shadow-lg": "5px 5px 9px
|
|
2323
|
-
"--shadow-xl": "6px 7px 13px
|
|
2324
|
-
"--shadow-2xl": "8px 9px 16px
|
|
2320
|
+
"--shadow-sm": "1px 1px 2px hsla(237, 18%, 3%, 0.9)",
|
|
2321
|
+
"--shadow-md": "3px 3px 6px hsla(237, 18%, 3%, 0.9)",
|
|
2322
|
+
"--shadow-lg": "5px 5px 9px hsla(237, 18%, 3%, 0.9)",
|
|
2323
|
+
"--shadow-xl": "6px 7px 13px hsla(237, 18%, 3%, 0.9)",
|
|
2324
|
+
"--shadow-2xl": "8px 9px 16px hsla(237, 18%, 3%, 0.9)"
|
|
2325
2325
|
},
|
|
2326
2326
|
"fontSources": [
|
|
2327
2327
|
{
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
--hover-low: color-mix(in srgb, var(--text-primary) 5%, transparent);
|
|
54
54
|
--hover: color-mix(in srgb, var(--text-primary) 10%, transparent);
|
|
55
55
|
--hover-high: color-mix(in srgb, var(--text-primary) 15%, transparent);
|
|
56
|
-
--shadow-sm: 1px 1px 2px
|
|
57
|
-
--shadow-md: 3px 3px 6px
|
|
58
|
-
--shadow-lg: 5px 5px 9px
|
|
59
|
-
--shadow-xl: 6px 7px 13px
|
|
60
|
-
--shadow-2xl: 8px 9px 16px
|
|
56
|
+
--shadow-sm: 1px 1px 2px hsla(237, 18%, 3%, 0.9);
|
|
57
|
+
--shadow-md: 3px 3px 6px hsla(237, 18%, 3%, 0.9);
|
|
58
|
+
--shadow-lg: 5px 5px 9px hsla(237, 18%, 3%, 0.9);
|
|
59
|
+
--shadow-xl: 6px 7px 13px hsla(237, 18%, 3%, 0.9);
|
|
60
|
+
--shadow-2xl: 8px 9px 16px hsla(237, 18%, 3%, 0.9);
|
|
61
61
|
--color-brand-100: oklch(0.95 0.0279 355.35);
|
|
62
62
|
--color-brand-200: oklch(0.8508 0.0915 355.35);
|
|
63
63
|
--color-brand-300: oklch(0.7516 0.1697 355.35);
|
|
@@ -24,6 +24,13 @@
|
|
|
24
24
|
`cover` only crops when the thumbnail has its own box (an aspect from
|
|
25
25
|
`width`/`height`, or a CSS-constrained container). */
|
|
26
26
|
fit?: 'contain' | 'cover';
|
|
27
|
+
/** Where the tile's shadow lands. Both modes read
|
|
28
|
+
`--imagelightbox-tile-shadow`: `box` casts it from the tile's rectangle,
|
|
29
|
+
`content` casts it from the image's own alpha, so art with transparency
|
|
30
|
+
doesn't sit on a phantom rectangle. `none` drops it. A theme that dials
|
|
31
|
+
a non-zero spread has no shadow under `content` — `drop-shadow()` has no
|
|
32
|
+
spread slot. */
|
|
33
|
+
shadow?: 'box' | 'content' | 'none';
|
|
27
34
|
/** When true, shows a bottom toolbar (zoom in/out + percent) and a top-right close button, and enables wheel/drag zoom inside the open modal. When false, click anywhere closes. */
|
|
28
35
|
extended?: boolean;
|
|
29
36
|
/** Maximum zoom, as a multiple of the image's natural resolution: `1` = 100%
|
|
@@ -55,6 +62,7 @@
|
|
|
55
62
|
images = undefined,
|
|
56
63
|
maxWidth = undefined,
|
|
57
64
|
fit = 'contain',
|
|
65
|
+
shadow = 'box',
|
|
58
66
|
extended = false,
|
|
59
67
|
maxZoom = undefined,
|
|
60
68
|
capNatural = false,
|
|
@@ -582,6 +590,8 @@
|
|
|
582
590
|
<button
|
|
583
591
|
bind:this={thumbEl}
|
|
584
592
|
class="image-lightbox-thumb"
|
|
593
|
+
class:shadow-box={shadow === 'box'}
|
|
594
|
+
class:shadow-content={shadow === 'content'}
|
|
585
595
|
style:--imagelightbox-tile-object-fit={fit}
|
|
586
596
|
type="button"
|
|
587
597
|
aria-label={cover?.alt ? `Expand image: ${cover.alt}` : 'Expand image'}
|
|
@@ -618,6 +628,8 @@
|
|
|
618
628
|
<div
|
|
619
629
|
bind:this={stageEl}
|
|
620
630
|
class="image-lightbox-stage"
|
|
631
|
+
class:shadow-box={shadow === 'box'}
|
|
632
|
+
class:shadow-content={shadow === 'content'}
|
|
621
633
|
role="presentation"
|
|
622
634
|
tabindex="-1"
|
|
623
635
|
onclick={onStageClick}
|
|
@@ -747,12 +759,25 @@
|
|
|
747
759
|
cursor: zoom-in;
|
|
748
760
|
border: var(--imagelightbox-tile-border-width) solid var(--imagelightbox-tile-border);
|
|
749
761
|
border-radius: var(--imagelightbox-tile-radius);
|
|
750
|
-
box-shadow: var(--imagelightbox-tile-shadow);
|
|
751
762
|
background: transparent;
|
|
752
763
|
overflow: hidden;
|
|
753
764
|
transition: transform 250ms ease;
|
|
754
765
|
}
|
|
755
766
|
|
|
767
|
+
.image-lightbox-thumb.shadow-box,
|
|
768
|
+
.image-lightbox-stage.shadow-box {
|
|
769
|
+
box-shadow: var(--imagelightbox-tile-shadow);
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/* Content mode traces the image's alpha. The filter goes on the tile, not the
|
|
773
|
+
<img>: applied to the element it runs after that element's own overflow
|
|
774
|
+
clip, so the shadow lands outside the box instead of being cropped by it.
|
|
775
|
+
The open modal stays bare — it casts against a near-opaque scrim where no
|
|
776
|
+
shadow reads, and a filter over the pan/zoom surface repaints every frame. */
|
|
777
|
+
.image-lightbox-thumb.shadow-content {
|
|
778
|
+
filter: drop-shadow(var(--imagelightbox-tile-shadow));
|
|
779
|
+
}
|
|
780
|
+
|
|
756
781
|
.image-lightbox-thumb:hover {
|
|
757
782
|
transform: scale(1.02);
|
|
758
783
|
}
|
|
@@ -793,7 +818,6 @@
|
|
|
793
818
|
cursor: zoom-out;
|
|
794
819
|
border: var(--imagelightbox-tile-border-width) solid var(--imagelightbox-tile-border);
|
|
795
820
|
border-radius: var(--imagelightbox-tile-radius);
|
|
796
|
-
box-shadow: var(--imagelightbox-tile-shadow);
|
|
797
821
|
background: transparent;
|
|
798
822
|
}
|
|
799
823
|
|
|
@@ -530,11 +530,11 @@
|
|
|
530
530
|
|
|
531
531
|
/* Shadows (elevation scale) */
|
|
532
532
|
--shadow-none: none;
|
|
533
|
-
--shadow-sm: 1px 1px 2px
|
|
534
|
-
--shadow-md: 3px 3px 6px
|
|
535
|
-
--shadow-lg: 5px 5px 9px
|
|
536
|
-
--shadow-xl: 6px 7px 13px
|
|
537
|
-
--shadow-2xl: 8px 9px 16px
|
|
533
|
+
--shadow-sm: 1px 1px 2px hsla(237, 18%, 3%, 0.9);
|
|
534
|
+
--shadow-md: 3px 3px 6px hsla(237, 18%, 3%, 0.9);
|
|
535
|
+
--shadow-lg: 5px 5px 9px hsla(237, 18%, 3%, 0.9);
|
|
536
|
+
--shadow-xl: 6px 7px 13px hsla(237, 18%, 3%, 0.9);
|
|
537
|
+
--shadow-2xl: 8px 9px 16px hsla(237, 18%, 3%, 0.9);
|
|
538
538
|
|
|
539
539
|
/* Focus rings (box-shadow outline) */
|
|
540
540
|
--ring-focus-sm: 0 0 0 2px hsla(0, 78%, 60%, 0.1);
|