You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/eidos/components/calendar
dev fd3a0b00c9
feat(calendar, date-picker, date-range-picker): add xs size + fix duplicate footer
5 months ago
..
README.md calendar: README sections + data-readonly recipe + audit A-3.7 refinement 5 months ago
calendar-cell.svelte Add Eidos calendar component 5 months ago
calendar-day.svelte Add Eidos calendar component 5 months ago
calendar-grid-body.svelte Add Eidos calendar component 5 months ago
calendar-grid-head.svelte Add Eidos calendar component 5 months ago
calendar-grid-row.svelte Add Eidos calendar component 5 months ago
calendar-grid.svelte Add Eidos calendar component 5 months ago
calendar-head-cell.svelte Add Eidos calendar component 5 months ago
calendar-header.svelte Add Eidos calendar component 5 months ago
calendar-heading.svelte Add Eidos calendar component 5 months ago
calendar-month-select.svelte Add Eidos calendar component 5 months ago
calendar-next-button.svelte Add Eidos calendar component 5 months ago
calendar-prev-button.svelte Add Eidos calendar component 5 months ago
calendar-year-select.svelte Add Eidos calendar component 5 months ago
calendar.css feat(calendar, date-picker, date-range-picker): add xs size + fix duplicate footer 5 months ago
calendar.svelte Add Eidos calendar component 5 months ago
index.ts Add Eidos calendar component 5 months ago
types.ts feat(calendar, date-picker, date-range-picker): add xs size + fix duplicate footer 5 months ago

README.md

Eidos Calendar

Visual wrapper for Soma Calendar. Calendar follows the compound Eidos surface: Calendar is the public root and parts hang from it (Calendar.Day, Calendar.Grid, etc.). There is no public Provider export.

Baseline

Source Relevant coverage Decision
Air morfo-runtime:src/uix/air/components/calendar Full visual shell over Terra: root size, header, heading, prev/next, month/year selects, grid, cell/day states; direct Air sound on selection/navigation. Keep the full part coverage and size. Do not copy direct sound; selection/navigation move to Morfo/Sema.
Soma current Single/multiple value, placeholder navigation, min/max, disabled/unavailable/holiday matchers, fixed weeks, multi-month, week numbers, locale, RTL and live announcements. Eidos wraps every public Soma part and adds only size, variant, color.
Morfo current 15 declared parts including WeekNumber contract, grid APG, day/cell state data. Add semantic events because Calendar is interactive. WeekNumber remains contract-only until Soma exposes a component.
Sema current No calendar pack before this migration. Add calendarSema for select/unselect and navigation.

Comparativa

Capability Air React Aria Ark UI Bits UI shadcn-svelte UIX decision
Single date yes yes yes yes yes Soma owns.
Multiple dates inherited Terra RangeCalendar separate in React Aria; non-contiguous supported by API docs selectionMode="multiple" type="multiple" via Bits Calendar Soma supports type="multiple".
Multiple months yes visibleDuration numOfMonths numberOfMonths via Bits Calendar Soma supports numberOfMonths; Eidos styles without assuming layout.
Fixed weeks yes display option fixedWeeks fixedWeeks via Bits Calendar Soma supports.
Month/year select yes documented as custom dropdowns documented example public MonthSelect/YearSelect generated wrappers around Bits Eidos exposes MonthSelect and YearSelect.
Min/max/unavailable yes minValue, maxValue, isDateUnavailable min, max, isDateUnavailable min/max/unavailable/disabled via Bits Calendar Soma supports selection and view bounds; invalid pairs surface as invalid + logger error.
Week numbers no Air-specific part not a first-class Calendar part showWeekNumbers documented separately through composition not primary API Soma exposes showWeekNumbers snippet data; visual support is included.
Holiday/weekend flags Air styled some date states only custom render state custom machine state possible custom render state possible via custom code Soma emits data-holiday and data-weekend; Eidos styles both.
Semantic feedback Air called interaction sounds in wrapper library-specific announcements callbacks callbacks none in wrapper Morfo/Sema owns commit-select, commit-unselect, shift-navigate.

Reference docs checked: React Aria Calendar, Ark UI Date Picker, Bits UI Calendar, shadcn-svelte Calendar, Radix Primitives components list and WAI-ARIA APG Date Picker Dialog/Grid.

Morfo / Sema

Event Family Target Runtime source Sema default
commit-select commit.select day CalendarProvider.select(date, target) after value changes soft form commit + tap
commit-unselect commit.remove day same, when a date is removed/cleared subtle form commit + tap
shift-navigate shift.navigate provider fallback, actual button/select/day target when known prevPage, nextPage, setMonth, setYear, keyboard month boundary subtle ascending navigation sound

Calendar is not passive: a 0-event contract would hide committed selection and visible-range navigation from the semantic layer. This migration closes that gap before adding the Eidos recipe.

Eidos API

<script lang="ts">
	import { Calendar } from '$uix/eidos/components/calendar';
	import { CalendarDate, type DateValue } from '$libs/days';

	const placeholder = new CalendarDate(2026, 5, 1);
	let value = $state<DateValue | undefined>(placeholder);
</script>

<Calendar type="single" bind:value {placeholder} size="md" variant="surface" color="primary">
	{#snippet children({ months, weekdays })}
		<Calendar.Header>
			<Calendar.PrevButton>Previous</Calendar.PrevButton>
			<Calendar.Heading />
			<Calendar.NextButton>Next</Calendar.NextButton>
		</Calendar.Header>
		{#each months as month (month.value.toString())}
			<Calendar.Grid>
				<Calendar.GridHead>
					<Calendar.GridRow>
						{#each weekdays as day}
							<Calendar.HeadCell>{day}</Calendar.HeadCell>
						{/each}
					</Calendar.GridRow>
				</Calendar.GridHead>
				<Calendar.GridBody>
					{#each month.weeks as week}
						<Calendar.GridRow>
							{#each week as date}
								<Calendar.Cell {date} month={month.value}>
									<Calendar.Day />
								</Calendar.Cell>
							{/each}
						</Calendar.GridRow>
					{/each}
				</Calendar.GridBody>
			</Calendar.Grid>
		{/each}
	{/snippet}
</Calendar>

Decisiones

  • No se expone Calendar.Provider en Eidos. El componente raíz monta el provider internamente y estampa data-size / data-variant / data-color. Los consumidores manipulan estado vía props (bind:value, bind:placeholder).
  • commit-select lleva intent: 'affirm' porque seleccionar una fecha es un compromiso evaluativamente positivo (suave). Un commit destructivo correspondería a commit-unselect con intent: 'neutral'.
  • shift-navigate cubre todo el movimiento de mes/año (prev/next, selects, atajos de teclado). No se subdivide por dirección — la perceptiva de Sema se modula con target y sequence, no con variantes de verbo.
  • Las flechas de teclado son focus moves puros: mueven el día enfocado pero no mutan value. Por eso el morfo declara 10 keyboards y sólo 3 eventos: Enter/Space (mutación) → commit-select, los 8 restantes no necesitan evento propio.
  • data-readonly es estado, no atributo de morfo input: el grid marca el aria-readonly y la receta lo tinta con tono atenuado pero permite seguir leyendo y navegando con teclado.

Gaps

Gap Disposición Detalle
Public Calendar.WeekNumber part diferir Morfo declara el part, pero Soma expone los números de semana a través del snippet data de GridRow en vez de un componente DOM. Requiere refactor en Soma antes de exponer en Eidos.
Range selection descartar Vive en range-calendar / componentes de range, no en Calendar.
Popover date picker shell descartar Vive en date-picker; Calendar es inline por diseño.
Modal + footer (clear / cancel / close) compartido con pickers diferir Calendar inline no lo necesita; los pickers lo aportan en su capa. Si llega un caso de Calendar como contenido de Drawer, se reevalúa.
Año/mes con scroll vertical estilo iOS diferir Patrón nuevo, no cubierto por ninguna referencia que mantengamos. Sin caso de uso real.

Powered by TurnKey Linux.