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 <DatePicker.Footer> 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) <noreply@anthropic.com>
active-uix
dev 5 months ago
parent f4707bd0c9
commit fd3a0b00c9

@ -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);

@ -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<Size, 'sm' | 'md' | 'lg'>
export type CalendarSize = Extract<Size, 'xs' | 'sm' | 'md' | 'lg'>
export type CalendarVariant = ControlVariant
export type CalendarColor = ColorRole

@ -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)}

@ -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);

@ -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)}

@ -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);

@ -779,7 +779,7 @@
<label data-uix-control>
<span data-uix-control-label>size</span>
<span data-uix-chips role="radiogroup">
{#each ['sm', 'md', 'lg'] as value}
{#each ['xs', 'sm', 'md', 'lg'] as value}
<button
data-uix-chip
data-active={size === value}

@ -694,7 +694,7 @@
<label data-uix-control>
<span data-uix-control-label>size</span>
<span data-uix-chips role="radiogroup">
{#each ['sm', 'md', 'lg'] as value}
{#each ['xs', 'sm', 'md', 'lg'] as value}
<button data-uix-chip data-active={size === value} onclick={() => (size = value as DatePickerSize)}>{value}</button>
{/each}
</span>
@ -1090,11 +1090,6 @@
</div>
{/each}
</div>
<DatePicker.Footer>
<DatePicker.Clear />
<DatePicker.Cancel />
<DatePicker.Close />
</DatePicker.Footer>
{/snippet}
<style>

@ -775,7 +775,7 @@
<label data-uix-control>
<span data-uix-control-label>size</span>
<span data-uix-chips role="radiogroup">
{#each ['sm', 'md', 'lg'] as value}
{#each ['xs', 'sm', 'md', 'lg'] as value}
<button data-uix-chip data-active={size === value} onclick={() => (size = value as DateRangePickerSize)}>{value}</button>
{/each}
</span>

Loading…
Cancel
Save

Powered by TurnKey Linux.