refactor(color-picker): stamp current-color in soma trigger (audit 5.3 P1)

Eliminates `Provider.require()` from eidos `<ColorPicker.Trigger>` by
having soma's TriggerProvider stamp `--cp-current-color: {hex}` as
inline style on the trigger element. Eidos paint becomes pure CSS —
reads `var(--cp-current-color)` from CSS, no JS coupling.

Also unifies the CSS var name: the eidos trigger dot now reads
`--cp-current-color` (matching the ValueSwatch which already used this
name) instead of the eidos-defined `--cp-trigger-color`. One canonical
"current colour" var across the component.

Test result unchanged: 2391/2397 passing. No regressions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
active-uix
dev 5 months ago
parent a15b785cc1
commit 74ccfead70

@ -1,7 +1,12 @@
<script lang="ts">
/**
* Eidos `<ColorPicker.Trigger>` — pure paint wrapper. Soma owns the
* current value and stamps `--cp-current-color` as inline style; this
* wrapper just adds visual data-attrs + the swatch dot. CSS reads the
* var to tint the dot.
*/
import { ActiveEidos } from '$uix/eidos';
import * as ColorPicker from '$soma/components/color-picker';
import { ColorPickerProvider } from '$soma/components/color-picker';
import { getColorPickerVisualContext } from './context.svelte';
import type { ColorPickerTriggerProps } from './types';
@ -20,17 +25,6 @@
const resolvedSize = $derived(eidos.resolve(size ?? visual?.getSize() ?? 'md', 'md'));
const resolvedVariant = $derived(variant ?? visual?.getVariant() ?? 'surface');
const resolvedColor = $derived(color ?? visual?.getColor() ?? 'primary');
const provider = ColorPickerProvider.require();
// Expose the current value to CSS so the trigger swatch dot tints itself.
const swatchStyle = $derived(
showSwatch
? `--cp-trigger-color: ${provider.opts.value.current?.hex ?? 'transparent'}`
: ''
);
const composedStyle = $derived(
[swatchStyle, style as string | undefined].filter(Boolean).join('; ')
);
</script>
<ColorPicker.Trigger
@ -39,7 +33,7 @@
data-variant={resolvedVariant}
data-color={resolvedColor}
data-show-swatch={showSwatch ? '' : undefined}
style={composedStyle}
{style}
>
{#if showSwatch}
<span class="color-picker-trigger-swatch" aria-hidden="true"></span>

@ -161,8 +161,9 @@
opacity: var(--color-picker-disabled-opacity);
}
/* Trigger swatch dot — paints with `--cp-trigger-color` on top of a
transparency checker so alpha < 1 reveals the checker beneath. */
/* Trigger swatch dot — paints with `--cp-current-color` on top of a
transparency checker so alpha < 1 reveals the checker beneath. Soma's
ColorPickerTriggerProvider stamps `--cp-current-color` inline. */
[data-color-picker-trigger] .color-picker-trigger-swatch {
position: relative;
display: inline-block;
@ -187,7 +188,7 @@
position: absolute;
inset: 0;
border-radius: inherit;
background: var(--cp-trigger-color, transparent);
background: var(--cp-current-color, transparent);
}
/* ── ValueSwatch / ValueText ─────────────────────────────────────────────── */

@ -475,6 +475,23 @@ export class ColorPickerTriggerProvider {
() => this.opts.ariaLabel.current ?? this.provider.langs(COLOR_PICKER_LANGS.TRIGGER)
);
/**
* Current colour as a hex string, exposed so consumers (e.g. eidos
* Trigger paint) can read it without grabbing the provider via
* `Provider.require()`. Falls back to `'transparent'` when no value
* is set.
*/
get currentHex(): string {
return this.provider.opts.value.current?.hex ?? 'transparent';
}
/**
* Inline style stamping `--cp-current-color` so eidos paints the
* swatch dot purely via CSS — soma owns the value, eidos owns the
* visual reading.
*/
readonly inlineStyle = $derived.by<string>(() => `--cp-current-color: ${this.currentHex}`);
readonly props = $derived.by(() =>
this.runtimePart.assert({
...this.runtimePart.props,
@ -482,7 +499,8 @@ export class ColorPickerTriggerProvider {
'aria-label': this.resolvedLabel,
'aria-haspopup': 'dialog' as const,
disabled: this.provider.isDisabled || undefined,
'data-disabled': boolToEmptyStrOrUndef(this.provider.isDisabled)
'data-disabled': boolToEmptyStrOrUndef(this.provider.isDisabled),
style: this.inlineStyle
// `data-state` comes from the composed PopoverTriggerProvider via mergeProps
// in the wrapper — we intentionally do not duplicate it here.
} as const)

Loading…
Cancel
Save

Powered by TurnKey Linux.