UNPKG

compote-ui

Version:

An opinionated UI component library for Svelte, built on top of [Ark UI](https://ark-ui.com) with additional components and features not available in the core Ark UI library.

65 lines (64 loc) 2.43 kB
import { parseDate, parseDateTime, parseAbsolute, parseAbsoluteToLocal, fromDate, getLocalTimeZone } from '@internationalized/date'; const DATE_ONLY = /^\d{4}-\d{2}-\d{2}$/; // Trailing `Z`, or a `+HH`, `+HH:MM`, `+HHMM` offset. const HAS_OFFSET = /(?:[zZ]|[+-]\d{2}(?::?\d{2})?)$/; /** Normalize a DB datetime string to ISO 8601: space → `T`, bare `+HH` offset → `+HH:00`. */ function normalizeIso(value) { return value.replace(' ', 'T').replace(/([+-]\d{2})$/, '$1:00'); } /** Report the runtime shape of a value so a change can be emitted in the same shape. */ export function dateValueShape(value) { if (value == null) return null; if (typeof value === 'string') return 'string'; if (value instanceof Date) return 'date'; return 'date-value'; } /** * Coerce a string / `Date` / `DateValue` into a `DateValue` for Ark UI. * * String auto-detection: * - `"2024-01-15"` → {@link parseDate} (date-only) * - `"2024-01-15T10:30:00"` → {@link parseDateTime} (local datetime) * - `"2024-01-15T10:30:00Z"` / `"…+02:00"` → zoned (in `timeZone`, else local) */ export function toDateValue(value, timeZone) { if (value == null) return null; if (value instanceof Date) return fromDate(value, timeZone ?? getLocalTimeZone()); if (typeof value !== 'string') return value; const raw = value.trim(); if (!raw) return null; if (DATE_ONLY.test(raw)) return parseDate(raw); const iso = normalizeIso(raw); if (HAS_OFFSET.test(iso)) { return timeZone ? parseAbsolute(iso, timeZone) : parseAbsoluteToLocal(iso); } return parseDateTime(iso); } /** Serialize a `DateValue` to an ISO string (absolute `…Z` for zoned values). */ export function dateValueToString(value) { return 'timeZone' in value ? value.toAbsoluteString() : value.toString(); } /** Convert a `DateValue` to a native `Date`. */ export function dateValueToDate(value, timeZone) { return 'timeZone' in value ? value.toDate() : value.toDate(timeZone ?? getLocalTimeZone()); } /** Emit a `DateValue` back in the original `shape` it was bound as. */ export function fromDateValue(value, shape, timeZone) { if (value == null) return null; if (shape === 'string') return dateValueToString(value); if (shape === 'date') return dateValueToDate(value, timeZone); return value; }