uix(color): enruta `data-color` crudo por `resolveComponentColor` en la familia date/time (custom hex sin fuga)

Al ensanchar `*PickerColor` a `ComponentColorProp`, los sub-wrappers que
enhebraban `data-color={color|resolvedColor|visual.getColor()}` CRUDO podían
recibir un valor custom (hex) y estamparlo tal cual en `data-color` (inválido;
roles/escalas ya pintaban por la capa compartida, solo el custom hex no).

Se pasan por el helper `resolveComponentColor` (patrón de `select-trigger.svelte`):
canonical -> `data-color`; valor crudo -> `data-color-custom` + el seed
`--color-custom` que la capa compartida rampa. 12 sub-partes:

- date-picker: root, trigger, calendar
- date-range-picker: root, trigger, calendar, input
- time-picker: trigger, clock
- time-range-picker: trigger, clock
- time-range-field: input

Verificado en navegador (demo date-range-field, custom #00b894): ambos endpoints
quedan data-color=null, data-color-custom='' y --_field-palette-text =
color-mix(...#00b894...) exacto. El soma range-field hace `{...restProps}`
wholesale sobre el [data-field] de cada endpoint, así que data-color-custom + el
seed llegan solos. check: 76 errores ajenos, 0 propios.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
alpha-0.1-sec-dom
dev 3 months ago
parent ca883e8198
commit 4adcc4c7fd

@ -1,17 +1,23 @@
<script lang="ts">
import { ActiveEidos } from '$uix/eidos';
import * as DatePicker from '$soma/components/date-picker';
import { composeInlineStyle } from '$uix/eidos/lib/style';
import { resolveComponentColor } from '$uix/eidos/lib/component-color';
import { getDatePickerVisualContext } from './context.svelte';
import { setCalendarVisual } from '../calendar/visual-context';
import type { DatePickerCalendarProps, DatePickerCalendarSnippetProps } from './types';
let { size, variant, color, children: bodyContent, ...rest }: DatePickerCalendarProps = $props();
let { size, variant, color, style, children: bodyContent, ...rest }: DatePickerCalendarProps =
$props();
const eidos = ActiveEidos.require();
const visual = getDatePickerVisualContext();
const resolvedSize = $derived(eidos.resolve(size ?? visual?.getSize() ?? 'md', 'md'));
const resolvedVariant = $derived(variant ?? visual?.getVariant() ?? 'ghost');
const resolvedColor = $derived(color ?? visual?.getColor() ?? 'primary');
// A canonical colour maps to data-color; a raw value seeds --color-custom for the shared ramp.
const colorAttrs = $derived(resolveComponentColor(resolvedColor));
const mergedStyle = $derived(composeInlineStyle(style, colorAttrs.customStyle));
// The month/year select popovers (MonthGrid/YearGrid) inherit the picker size.
setCalendarVisual({ getSize: () => resolvedSize });
</script>
@ -20,7 +26,9 @@
{...rest}
data-size={resolvedSize}
data-variant={resolvedVariant}
data-color={resolvedColor}
data-color={colorAttrs.dataColor}
data-color-custom={colorAttrs.isCustom ? '' : undefined}
style={mergedStyle}
>
{#snippet children(snippetProps: DatePickerCalendarSnippetProps)}
{@render bodyContent?.(snippetProps)}

@ -3,16 +3,21 @@
import * as DatePicker from '$soma/components/date-picker';
import CalendarIcon from '../icon/lib/calendar.svelte';
import '../field/field-control-trigger.css';
import { composeInlineStyle } from '$uix/eidos/lib/style';
import { resolveComponentColor } from '$uix/eidos/lib/component-color';
import { getDatePickerVisualContext } from './context.svelte';
import type { DatePickerTriggerProps } from './types';
let { size, variant, color, children, ...rest }: DatePickerTriggerProps = $props();
let { size, variant, color, style, children, ...rest }: DatePickerTriggerProps = $props();
const eidos = ActiveEidos.require();
const visual = getDatePickerVisualContext();
const resolvedSize = $derived(eidos.resolve(size ?? visual?.getSize() ?? 'md', 'md'));
const resolvedVariant = $derived(variant ?? visual?.getVariant() ?? 'surface');
const resolvedColor = $derived(color ?? visual?.getColor() ?? 'primary');
// Route the colour through the shared resolver: canonical → data-color, raw → data-color-custom + seed.
const colorAttrs = $derived(resolveComponentColor(resolvedColor));
const mergedStyle = $derived(composeInlineStyle(style, colorAttrs.customStyle));
</script>
<DatePicker.Trigger
@ -20,7 +25,9 @@
data-field-control-trigger=""
data-size={resolvedSize}
data-variant={resolvedVariant}
data-color={resolvedColor}
data-color={colorAttrs.dataColor}
data-color-custom={colorAttrs.isCustom ? '' : undefined}
style={mergedStyle}
>
{#if children}
{@render children()}

@ -11,6 +11,8 @@
import '$uix/eidos/components/year-grid/year-grid.css';
import './date-picker.css';
import { ActiveEidos } from '$uix/eidos';
import { composeInlineStyle } from '$uix/eidos/lib/style';
import { resolveComponentColor } from '$uix/eidos/lib/component-color';
import * as DatePicker from '$soma/components/date-picker';
import { setDatePickerVisualContext, setDatePickerTimeBridge } from './context.svelte';
import { setPickerShellVisual } from '$uix/eidos/components/picker-shell/visual-context';
@ -31,12 +33,16 @@
value = $bindable(),
placeholder = $bindable(),
open = $bindable(false),
style,
children,
...rest
}: DatePickerProps = $props();
const eidos = ActiveEidos.require();
const resolvedSize = $derived(eidos.resolve(size, 'md'));
// Route the colour prop: canonical → data-color, raw CSS colour → data-color-custom + seed.
const colorAttrs = $derived(resolveComponentColor(color));
const mergedStyle = $derived(composeInlineStyle(style, colorAttrs.customStyle));
// Locale drives the hour cycle when `hourCycle` is unset (en-US → 12h, es-ES
// → 24h) — resolved once here and fed to BOTH the segmented input and the
// composed TimePicker so they always agree.
@ -79,7 +85,9 @@
data-date-field=""
data-size={resolvedSize}
data-variant={variant}
data-color={color}
data-color={colorAttrs.dataColor}
data-color-custom={colorAttrs.isCustom ? '' : undefined}
style={mergedStyle}
>
{@render children?.()}
</DatePicker.Provider>

@ -1,13 +1,15 @@
<script lang="ts">
import { ActiveEidos } from '$uix/eidos';
import * as DateRangePicker from '$soma/components/date-range-picker';
import { composeInlineStyle } from '$uix/eidos/lib/style';
import { resolveComponentColor } from '$uix/eidos/lib/component-color';
import { getDateRangePickerVisualContext } from './context.svelte';
import type {
DateRangePickerCalendarProps,
DateRangePickerCalendarSnippetProps
} from './types';
let { size, variant, color, children: bodyContent, ...rest }: DateRangePickerCalendarProps =
let { size, variant, color, style, children: bodyContent, ...rest }: DateRangePickerCalendarProps =
$props();
const eidos = ActiveEidos.require();
@ -15,13 +17,18 @@
const resolvedSize = $derived(eidos.resolve(size ?? visual?.getSize() ?? 'md', 'md'));
const resolvedVariant = $derived(variant ?? visual?.getVariant() ?? 'ghost');
const resolvedColor = $derived(color ?? visual?.getColor() ?? 'primary');
// Route the colour through the resolver: canonical → data-color, raw → data-color-custom + seed.
const colorAttrs = $derived(resolveComponentColor(resolvedColor));
const mergedStyle = $derived(composeInlineStyle(style, colorAttrs.customStyle));
</script>
<DateRangePicker.Calendar
{...rest}
data-size={resolvedSize}
data-variant={resolvedVariant}
data-color={resolvedColor}
data-color={colorAttrs.dataColor}
data-color-custom={colorAttrs.isCustom ? '' : undefined}
style={mergedStyle}
>
{#snippet children(snippetProps: DateRangePickerCalendarSnippetProps)}
{@render bodyContent?.(snippetProps)}

@ -7,19 +7,27 @@
* DateRangeField. Snippet args come from soma unchanged.
*/
import * as DateRangePicker from '$soma/components/date-range-picker';
import { composeInlineStyle } from '$uix/eidos/lib/style';
import { resolveComponentColor } from '$uix/eidos/lib/component-color';
import { getDateRangePickerVisualContext } from './context.svelte';
import type { DateRangePickerInputProps, DateRangePickerInputSnippetProps } from './types';
let { children: bodyContent, ...rest }: DateRangePickerInputProps = $props();
let { children: bodyContent, style, ...rest }: DateRangePickerInputProps = $props();
const visual = getDateRangePickerVisualContext();
// Route the colour prop through the shared resolver: canonical → data-color,
// raw custom → data-color-custom + a --color-custom style seed.
const colorAttrs = $derived(resolveComponentColor(visual?.getColor()));
const mergedStyle = $derived(composeInlineStyle(style, colorAttrs.customStyle));
</script>
<DateRangePicker.Input
{...rest}
data-size={visual?.getSize()}
data-variant={visual?.getVariant()}
data-color={visual?.getColor()}
data-color={colorAttrs.dataColor}
data-color-custom={colorAttrs.isCustom ? '' : undefined}
style={mergedStyle}
>
{#snippet children(args: DateRangePickerInputSnippetProps)}
{@render bodyContent?.(args)}

@ -1,24 +1,31 @@
<script lang="ts">
import { ActiveEidos } from '$uix/eidos';
import * as DateRangePicker from '$soma/components/date-range-picker';
import { composeInlineStyle } from '$uix/eidos/lib/style';
import { resolveComponentColor } from '$uix/eidos/lib/component-color';
import CalendarIcon from '../icon/lib/calendar.svelte';
import { getDateRangePickerVisualContext } from './context.svelte';
import type { DateRangePickerTriggerProps } from './types';
let { size, variant, color, children, ...rest }: DateRangePickerTriggerProps = $props();
let { size, variant, color, style, children, ...rest }: DateRangePickerTriggerProps = $props();
const eidos = ActiveEidos.require();
const visual = getDateRangePickerVisualContext();
const resolvedSize = $derived(eidos.resolve(size ?? visual?.getSize() ?? 'md', 'md'));
const resolvedVariant = $derived(variant ?? visual?.getVariant() ?? 'surface');
const resolvedColor = $derived(color ?? visual?.getColor() ?? 'primary');
// Route the colour through the shared resolver: canonical → data-color, raw → data-color-custom + seed.
const colorAttrs = $derived(resolveComponentColor(resolvedColor));
const mergedStyle = $derived(composeInlineStyle(style, colorAttrs.customStyle));
</script>
<DateRangePicker.Trigger
{...rest}
data-size={resolvedSize}
data-variant={resolvedVariant}
data-color={resolvedColor}
data-color={colorAttrs.dataColor}
data-color-custom={colorAttrs.isCustom ? '' : undefined}
style={mergedStyle}
>
{#if children}
{@render children()}

@ -11,6 +11,8 @@
import '$uix/eidos/components/range-calendar/range-calendar.css';
import './date-range-picker.css';
import { ActiveEidos } from '$uix/eidos';
import { composeInlineStyle } from '$uix/eidos/lib/style';
import { resolveComponentColor } from '$uix/eidos/lib/component-color';
import * as DateRangePicker from '$soma/components/date-range-picker';
import { setDateRangePickerVisualContext, setDateRangePickerTimeBridge } from './context.svelte';
import { setPickerShellVisual } from '$uix/eidos/components/picker-shell/visual-context';
@ -31,12 +33,17 @@
value = $bindable(),
placeholder = $bindable(),
open = $bindable(false),
style,
children,
...rest
}: DateRangePickerProps = $props();
const eidos = ActiveEidos.require();
const resolvedSize = $derived(eidos.resolve(size, 'md'));
// Route the colour through the shared resolver: canonical → data-color,
// raw → data-color-custom + a --color-custom seed the shared layer ramps.
const colorAttrs = $derived(resolveComponentColor(color));
const mergedStyle = $derived(composeInlineStyle(style, colorAttrs.customStyle));
// Locale drives the hour cycle when `hourCycle` is unset — resolved once and
// fed to the start/end inputs + both composed TimePickers.
const effectiveLocale = $derived(locale ?? eidos.langs.getLocale());
@ -74,7 +81,9 @@
bind:open
data-size={resolvedSize}
data-variant={variant}
data-color={color}
data-color={colorAttrs.dataColor}
data-color-custom={colorAttrs.isCustom ? '' : undefined}
style={mergedStyle}
>
{@render children?.()}
</DateRangePicker.Provider>

@ -1,23 +1,30 @@
<script lang="ts">
import { ActiveEidos } from '$uix/eidos';
import * as TimePicker from '$soma/components/time-picker';
import { composeInlineStyle } from '$uix/eidos/lib/style';
import { resolveComponentColor } from '$uix/eidos/lib/component-color';
import { getTimePickerVisualContext } from './context.svelte';
import type { TimePickerClockProps } from './types';
let { size, variant, color, children, ...rest }: TimePickerClockProps = $props();
let { size, variant, color, style, children, ...rest }: TimePickerClockProps = $props();
const eidos = ActiveEidos.require();
const visual = getTimePickerVisualContext();
const resolvedSize = $derived(eidos.resolve(size ?? visual?.getSize() ?? 'md', 'md'));
const resolvedVariant = $derived(variant ?? visual?.getVariant() ?? 'ghost');
const resolvedColor = $derived(color ?? visual?.getColor() ?? 'primary');
// Route the colour through the shared resolver: canonical → data-color, raw → data-color-custom + seed.
const colorAttrs = $derived(resolveComponentColor(resolvedColor));
const mergedStyle = $derived(composeInlineStyle(style, colorAttrs.customStyle));
</script>
<TimePicker.Clock
{...rest}
data-size={resolvedSize}
data-variant={resolvedVariant}
data-color={resolvedColor}
data-color={colorAttrs.dataColor}
data-color-custom={colorAttrs.isCustom ? '' : undefined}
style={mergedStyle}
>
{@render children?.()}
</TimePicker.Clock>

@ -2,23 +2,31 @@
import { ActiveEidos } from '$uix/eidos';
import * as TimePicker from '$soma/components/time-picker';
import ClockIcon from '../icon/lib/clock.svelte';
import { composeInlineStyle } from '$uix/eidos/lib/style';
import { resolveComponentColor } from '$uix/eidos/lib/component-color';
import { getTimePickerVisualContext } from './context.svelte';
import type { TimePickerTriggerProps } from './types';
let { size, variant, color, children, ...rest }: TimePickerTriggerProps = $props();
let { size, variant, color, style, children, ...rest }: TimePickerTriggerProps = $props();
const eidos = ActiveEidos.require();
const visual = getTimePickerVisualContext();
const resolvedSize = $derived(eidos.resolve(size ?? visual?.getSize() ?? 'md', 'md'));
const resolvedVariant = $derived(variant ?? visual?.getVariant() ?? 'surface');
const resolvedColor = $derived(color ?? visual?.getColor() ?? 'primary');
// Route the colour through the shared resolver: canonical → data-color,
// raw → data-color-custom + a --color-custom seed the shared layer ramps.
const colorAttrs = $derived(resolveComponentColor(resolvedColor));
const mergedStyle = $derived(composeInlineStyle(style, colorAttrs.customStyle));
</script>
<TimePicker.Trigger
{...rest}
data-size={resolvedSize}
data-variant={resolvedVariant}
data-color={resolvedColor}
data-color={colorAttrs.dataColor}
data-color-custom={colorAttrs.isCustom ? '' : undefined}
style={mergedStyle}
>
{#if children}
{@render children()}

@ -7,19 +7,27 @@
* (`segments`) come from soma unchanged.
*/
import * as TimeRangeField from '$soma/components/time-range-field';
import { composeInlineStyle } from '$uix/eidos/lib/style';
import { resolveComponentColor } from '$uix/eidos/lib/component-color';
import { getTimeRangeFieldVisualContext } from './context.svelte';
import type { TimeRangeFieldInputProps } from './types';
let { children: bodyContent, ...rest }: TimeRangeFieldInputProps = $props();
let { children: bodyContent, style, ...rest }: TimeRangeFieldInputProps = $props();
const visual = getTimeRangeFieldVisualContext();
// Route the colour: canonical → data-color, raw CSS value → data-color-custom + seed.
const colorAttrs = $derived(resolveComponentColor(visual?.getColor()));
const mergedStyle = $derived(composeInlineStyle(style, colorAttrs.customStyle));
</script>
<TimeRangeField.Input
{...rest}
data-size={visual?.getSize()}
data-variant={visual?.getVariant()}
data-color={visual?.getColor()}
data-color={colorAttrs.dataColor}
data-color-custom={colorAttrs.isCustom ? '' : undefined}
style={mergedStyle}
>
{#snippet children(snippetProps)}
{@render bodyContent?.(snippetProps)}

@ -1,23 +1,30 @@
<script lang="ts">
import { ActiveEidos } from '$uix/eidos';
import * as TimeRangePicker from '$soma/components/time-range-picker';
import { composeInlineStyle } from '$uix/eidos/lib/style';
import { resolveComponentColor } from '$uix/eidos/lib/component-color';
import { getTimeRangePickerVisualContext } from './context.svelte';
import type { TimeRangePickerClockProps } from './types';
let { size, variant, color, children, ...rest }: TimeRangePickerClockProps = $props();
let { size, variant, color, style, children, ...rest }: TimeRangePickerClockProps = $props();
const eidos = ActiveEidos.require();
const visual = getTimeRangePickerVisualContext();
const resolvedSize = $derived(eidos.resolve(size ?? visual?.getSize() ?? 'md', 'md'));
const resolvedVariant = $derived(variant ?? visual?.getVariant() ?? 'ghost');
const resolvedColor = $derived(color ?? visual?.getColor() ?? 'primary');
// Route colour through the shared resolver: canonical → data-color, raw → data-color-custom + seed.
const colorAttrs = $derived(resolveComponentColor(resolvedColor));
const mergedStyle = $derived(composeInlineStyle(style, colorAttrs.customStyle));
</script>
<TimeRangePicker.Clock
{...rest}
data-size={resolvedSize}
data-variant={resolvedVariant}
data-color={resolvedColor}
data-color={colorAttrs.dataColor}
data-color-custom={colorAttrs.isCustom ? '' : undefined}
style={mergedStyle}
>
{@render children?.()}
</TimeRangePicker.Clock>

@ -1,24 +1,31 @@
<script lang="ts">
import { ActiveEidos } from '$uix/eidos';
import * as TimeRangePicker from '$soma/components/time-range-picker';
import { composeInlineStyle } from '$uix/eidos/lib/style';
import { resolveComponentColor } from '$uix/eidos/lib/component-color';
import ClockIcon from '../icon/lib/clock.svelte';
import { getTimeRangePickerVisualContext } from './context.svelte';
import type { TimeRangePickerTriggerProps } from './types';
let { size, variant, color, children, ...rest }: TimeRangePickerTriggerProps = $props();
let { size, variant, color, style, children, ...rest }: TimeRangePickerTriggerProps = $props();
const eidos = ActiveEidos.require();
const visual = getTimeRangePickerVisualContext();
const resolvedSize = $derived(eidos.resolve(size ?? visual?.getSize() ?? 'md', 'md'));
const resolvedVariant = $derived(variant ?? visual?.getVariant() ?? 'surface');
const resolvedColor = $derived(color ?? visual?.getColor() ?? 'primary');
// Route the colour through the shared resolver: canonical → data-color, raw → data-color-custom + seed.
const colorAttrs = $derived(resolveComponentColor(resolvedColor));
const mergedStyle = $derived(composeInlineStyle(style, colorAttrs.customStyle));
</script>
<TimeRangePicker.Trigger
{...rest}
style={mergedStyle}
data-size={resolvedSize}
data-variant={resolvedVariant}
data-color={resolvedColor}
data-color={colorAttrs.dataColor}
data-color-custom={colorAttrs.isCustom ? '' : undefined}
>
{#if children}
{@render children()}

Loading…
Cancel
Save

Powered by TurnKey Linux.