From fd3a0b00c953dd0011fee19482c34af240f21a27 Mon Sep 17 00:00:00 2001 From: dev Date: Fri, 22 May 2026 01:09:29 +0200 Subject: [PATCH] feat(calendar, date-picker, date-range-picker): add xs size + fix duplicate footer xs propagation - Add [data-size='xs'] blocks to calendar.css, date-picker.css, date-range-picker.css (root + inline range calendar). - Extend CalendarSize union with 'xs'; DatePicker / DateRangePicker inherit it through their type re-exports. - date-picker-content + date-range-picker-content clamp xs to sm when forwarding to PopoverContent (PopoverSize starts at sm; the calendar inside still receives xs via data-size). - size chip groups in calendar / date-picker / date-range-picker demos now list xs / sm / md / lg. date-picker demo: fix duplicate footer - The `calendarBody` snippet had a hardcoded that rendered alongside the controllable `pickerFooter` snippet, producing two footer rows when showFooter=true. Removed the hardcoded one. Verified in browser: - date-picker size='xs' -> data-date-field-input height 26px (control-height-xs), padding 8px (space-2), font-size 12px. - date-picker popover now shows a single footer. - svelte-check --threshold error -> 0 errors / 0 warnings / 4572 files. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../eidos/components/calendar/calendar.css | 7 +++++++ src/uix/eidos/components/calendar/types.ts | 2 +- .../date-picker/date-picker-content.svelte | 6 +++++- .../components/date-picker/date-picker.css | 8 ++++++++ .../date-range-picker-content.svelte | 6 +++++- .../date-range-picker/date-range-picker.css | 19 +++++++++++++++++++ .../uix/components/calendar/+page.svelte | 2 +- .../uix/components/date-picker/+page.svelte | 7 +------ .../components/date-range-picker/+page.svelte | 2 +- 9 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/uix/eidos/components/calendar/calendar.css b/src/uix/eidos/components/calendar/calendar.css index 86cd17d4d..8ad68e2b5 100644 --- a/src/uix/eidos/components/calendar/calendar.css +++ b/src/uix/eidos/components/calendar/calendar.css @@ -25,6 +25,13 @@ line-height: var(--calendar-line-height); } +[data-calendar][data-size='xs'] { + --_calendar-padding: var(--calendar-padding-xs); + --_calendar-control-size: var(--calendar-control-size-xs); + --_calendar-day-size: var(--calendar-day-size-xs); + --_calendar-font-size: var(--calendar-font-size-xs); +} + [data-calendar][data-size='sm'] { --_calendar-padding: var(--calendar-padding-sm); --_calendar-control-size: var(--calendar-control-size-sm); diff --git a/src/uix/eidos/components/calendar/types.ts b/src/uix/eidos/components/calendar/types.ts index c2feb1a43..17178e5bb 100644 --- a/src/uix/eidos/components/calendar/types.ts +++ b/src/uix/eidos/components/calendar/types.ts @@ -24,7 +24,7 @@ import type { import type { DateValue } from '$libs/days' import type { ColorRole, ControlVariant, ResponsiveProp, Size } from '$uix/eidos/lib/types' -export type CalendarSize = Extract +export type CalendarSize = Extract export type CalendarVariant = ControlVariant export type CalendarColor = ColorRole diff --git a/src/uix/eidos/components/date-picker/date-picker-content.svelte b/src/uix/eidos/components/date-picker/date-picker-content.svelte index b57116dcf..d01ab5fd4 100644 --- a/src/uix/eidos/components/date-picker/date-picker-content.svelte +++ b/src/uix/eidos/components/date-picker/date-picker-content.svelte @@ -21,6 +21,10 @@ const eidos = ActiveEidos.require(); const visual = getDatePickerVisualContext(); const resolvedSize = $derived(eidos.resolve(size ?? visual?.getSize() ?? 'md', 'md')); + // Popover doesn't have an `xs` chrome variant — clamp to `sm` so the + // popover surface stays consistent while the calendar inside still + // renders at xs via [data-date-picker][data-size='xs']. + const popoverSize = $derived(resolvedSize === 'xs' ? 'sm' : resolvedSize); function serializeLength(value: string | number | undefined): string | undefined { if (value === undefined) return undefined; @@ -62,7 +66,7 @@ {align} {sideOffset} {collisionPadding} - size={resolvedSize} + size={popoverSize} style={composedStyle} > {#snippet children(snippetProps)} diff --git a/src/uix/eidos/components/date-picker/date-picker.css b/src/uix/eidos/components/date-picker/date-picker.css index 0773594f6..99035b37c 100644 --- a/src/uix/eidos/components/date-picker/date-picker.css +++ b/src/uix/eidos/components/date-picker/date-picker.css @@ -19,6 +19,14 @@ line-height: var(--date-field-line-height); } +[data-date-picker][data-size='xs'] { + --_date-field-height: var(--date-field-height-xs); + --_date-field-px: var(--date-field-px-xs); + --_date-field-gap: var(--date-field-gap-xs); + --_date-field-segment-px: var(--date-field-segment-px-xs); + --_date-field-font-size: var(--date-field-font-size-xs); +} + [data-date-picker][data-size='sm'] { --_date-field-height: var(--date-field-height-sm); --_date-field-px: var(--date-field-px-sm); diff --git a/src/uix/eidos/components/date-range-picker/date-range-picker-content.svelte b/src/uix/eidos/components/date-range-picker/date-range-picker-content.svelte index fd7fe4133..2f8190469 100644 --- a/src/uix/eidos/components/date-range-picker/date-range-picker-content.svelte +++ b/src/uix/eidos/components/date-range-picker/date-range-picker-content.svelte @@ -21,6 +21,10 @@ const eidos = ActiveEidos.require(); const visual = getDateRangePickerVisualContext(); const resolvedSize = $derived(eidos.resolve(size ?? visual?.getSize() ?? 'md', 'md')); + // Popover doesn't have an `xs` chrome variant — clamp to `sm` so the + // popover surface stays consistent while the calendar inside still + // renders at xs via [data-date-range-picker][data-size='xs']. + const popoverSize = $derived(resolvedSize === 'xs' ? 'sm' : resolvedSize); function serializeLength(value: string | number | undefined): string | undefined { if (value === undefined) return undefined; @@ -62,7 +66,7 @@ {align} {sideOffset} {collisionPadding} - size={resolvedSize} + size={popoverSize} style={composedStyle} > {#snippet children(snippetProps)} diff --git a/src/uix/eidos/components/date-range-picker/date-range-picker.css b/src/uix/eidos/components/date-range-picker/date-range-picker.css index 7e07ce22d..5c03b233c 100644 --- a/src/uix/eidos/components/date-range-picker/date-range-picker.css +++ b/src/uix/eidos/components/date-range-picker/date-range-picker.css @@ -39,6 +39,18 @@ line-height: var(--date-field-line-height); } +[data-date-range-picker][data-size='xs'] { + --_date-field-height: var(--date-field-height-xs); + --_date-field-px: var(--date-field-px-xs); + --_date-field-gap: var(--date-field-gap-xs); + --_date-field-segment-px: var(--date-field-segment-px-xs); + --_date-field-font-size: var(--date-field-font-size-xs); + --_calendar-padding: var(--calendar-padding-xs); + --_calendar-control-size: var(--calendar-control-size-xs); + --_calendar-day-size: var(--calendar-day-size-xs); + --_calendar-font-size: var(--calendar-font-size-xs); +} + [data-date-range-picker][data-size='sm'] { --_date-field-height: var(--date-field-height-sm); --_date-field-px: var(--date-field-px-sm); @@ -433,6 +445,13 @@ line-height: var(--calendar-line-height); } +[data-date-range-picker-calendar][data-range-calendar][data-size='xs'] { + --_calendar-padding: var(--calendar-padding-xs); + --_calendar-control-size: var(--calendar-control-size-xs); + --_calendar-day-size: var(--calendar-day-size-xs); + --_calendar-font-size: var(--calendar-font-size-xs); +} + [data-date-range-picker-calendar][data-range-calendar][data-size='sm'] { --_calendar-padding: var(--calendar-padding-sm); --_calendar-control-size: var(--calendar-control-size-sm); diff --git a/web/routes/uix/components/calendar/+page.svelte b/web/routes/uix/components/calendar/+page.svelte index 74b62d3f7..4b58962f4 100644 --- a/web/routes/uix/components/calendar/+page.svelte +++ b/web/routes/uix/components/calendar/+page.svelte @@ -779,7 +779,7 @@