Add terra date domain adapter

main
dev 6 months ago
parent 5039a3e38a
commit 29e6168261

@ -21,7 +21,7 @@ La idea es que, cuando creemos un componente nuevo, no inventemos otro patron di
- el estado complejo vive fuera del markup, normalmente en clases `State`
- los componentes hijos (`Input`, `Trigger`, `Content`, `Segment`, etc.) leen estado mediante contexto, no por prop drilling
- los defaults globales viven en `TerraConfig`, pero los componentes no deben acoplarse a `actx`
- la logica de dominio compartida debe ir a `glob` o a `utils`, no enterrada en un componente concreto
- la logica de dominio compartida debe vivir fuera del componente; si `terra` necesita un dominio externo, debe entrar por un adapter claro
- los wrappers `.svelte` deben ser pequenos: recibir props, crear estado, mezclar atributos y renderizar
## 2. Estructura base de la libreria
@ -211,7 +211,7 @@ Ejemplos comunes:
- `DateFieldRootState`
- `DateFieldInputState`
- `DateFieldLabelState`
- `DateFieldLabe$state`
- `DateFieldSegmentState`
- `TimeFieldRootState`
@ -500,7 +500,7 @@ export class MyComponentRootState {
Si hay subpiezas con comportamiento, crea clases como:
- `MyComponentInputState`
- `MyComponentLabelState`
- `MyComponentLabe$state`
- `MyComponentItemState`
Cada una hace `MyComponentRootContext.get()` y deriva lo que necesita.
@ -523,7 +523,7 @@ Ejemplo:
```ts
export { default as Root } from './components/mi-componente.svelte';
export { default as Item } from './components/mi-componente-item.svelte';
export { default as Item } from './components/mi-componente-virtual-list-item.svelte';
export type {
MyComponentRootProps as RootProps,
@ -559,6 +559,21 @@ Esto es especialmente importante para:
- componentes con teclado complejo
- componentes configurables por `TerraConfig`
## 13. Frontera de dominio: adapters
Cuando `terra` depende de una libreria de dominio externa (por ejemplo fechas), no debe importar sus archivos directamente desde cada componente. La regla es:
- el dominio vive fuera de `terra`
- `terra` define un adapter local y estable
- los componentes importan del adapter, no de la libreria externa
Ejemplo actual:
- `src/uix/terra/adapters/dates/index.ts`
Ese adapter actua como frontera para toda la familia date/time. Si la libreria compartida cambia de estructura, el impacto se concentra ahi y no se propaga a veinte componentes.
## 13. Convencion especial para date/time
La familia date/time tiene una regla extra:
@ -566,7 +581,7 @@ La familia date/time tiene una regla extra:
- no debe acoplarse a `actx`
- debe aceptar props explicitas
- debe heredar defaults desde `TerraConfig`
- debe apoyarse en `glob/date` para tipos y helpers de dominio
- debe apoyarse en un adapter de dominio de `terra`, no en imports dispersos a la libreria externa
Hoy esto afecta especialmente a:
@ -579,7 +594,7 @@ Hoy esto afecta especialmente a:
Para estos componentes, si necesitas formato/locale:
- usa `glob/lib` para tipos y helpers (`DatiDateOrder`, `DatiTimeFormat`, `getDefaultDate`, `getDefaultTime`, etc.)
- usa `src/uix/terra/adapters/dates` como frontera unica hacia la libreria de fechas
- usa `resolveDateOrderProp`, `resolveHourCycleProp`, `resolveLocaleProp`
- no importes `actx` dentro del modulo
@ -623,7 +638,7 @@ Antes de dar por bueno un componente, revisar:
- hay `mergeProps` en los wrappers
- la accesibilidad base (`role`, `aria-*`, `data-*`) sale del estado, no del usuario final
- si soporta defaults globales, usa `TerraConfig`
- si es date/time, usa `glob/date`
- si es date/time, importa desde `src/uix/terra/adapters/dates`
- tiene demo en `src/routes/test/`
## 17. Ejemplo minimo de lectura del sistema
@ -737,7 +752,7 @@ export class XRootState {
Patron habitual:
- `XInputState`
- `XLabelState`
- `XLabe$state`
- `XSegmentState`
- `XHiddenInputState`
@ -973,3 +988,155 @@ Si quieres una version ultra resumida para trabajar rapido, piensa en `terra` as
- `exports.ts` define la API `Elemento.SubElemento`
- `src/routes/test/` valida que el componente existe de verdad
## 21. Estado actual de la arquitectura
A fecha de hoy, `terra` ya no debe entenderse como una migracion desde `uisv` o `acel`, sino como la base estable del framework.
### 21.1 Capas actuales
- `terra` = primitives headless, comportamiento, accesibilidad, contexto y defaults compartidos
- `air` = capa visual/opinionated, todavia en fase temprana
- `glob` = logica y formatos de dominio (fechas, numeros, currency, units, locale)
- `routes/test` = banco de pruebas real de la libreria
### 21.2 Que ya no forma parte de `terra`
No debemos volver a introducir en `terra` estas ideas:
- managers globales tipo `uiux.toast`
- managers globales tipo `uiux.modal`
- componentes puramente visuales sin valor como primitive
- aliases legacy tipo `Acel*`, `Bits*`, `boxWith`, `simpleBox`, `derived`
### 21.3 Que si pertenece a `terra`
Pertenece a `terra` todo lo que represente comportamiento reusable y headless:
- overlays como `Dialog`, `AlertDialog`, `Popover`, `Drawer`
- inputs complejos como `DateField`, `TimeField`, `Select`, `Combobox`
- composicion de formularios y validacion accesible
- configuracion de defaults via `TerraConfig`
- virtualizacion, focus management, dismiss layers, portal, floating, etc.
## 22. Drawer y futuros overlays
`Drawer` ya existe como primitive real en `terra`.
La decision de arquitectura actual es:
- `Drawer` si vive en `terra`
- `Sheet` no necesita ser otra primitive base distinta por ahora
### 22.1 Como pensar `Sheet`
`Sheet` probablemente sera una abstraccion de producto o de capa visual sobre `Drawer`, no una nueva infraestructura.
Regla recomendada:
- si cambia el comportamiento base, evaluar primitive nueva
- si cambia sobre todo la presentacion o la semantica UX, resolverlo en `air`
## 23. Analisis de `Form`
`Form` es uno de los siguientes primitives importantes para `terra`.
### 23.1 Referencias externas recomendadas
Para inspiracion de diseño:
- `React Aria` como referencia principal de `Form`
- `Ark UI` como referencia principal de `Field`
- `Radix` como referencia general de primitives compuestos
La lectura actual es:
- `React Aria` resuelve muy bien validacion, submit, errores de servidor y accesibilidad
- `Ark UI` resuelve muy bien el contexto de `Field` y la composicion alrededor del control
- `Radix` sigue siendo una buena referencia general, pero su `Form` no es el mejor modelo para composicion interna completa del sistema
### 23.2 Objetivo de `Form` en `terra`
`Form` no debe convertirse en una form library cerrada. Debe ser una primitive headless para:
- contexto de formulario
- submit y reset
- estado `pending`
- invalidacion global o por campo
- errores de servidor
- foco al primer invalido si aplica
- composicion correcta con `Field`, `Select`, `Combobox`, `Checkbox`, `RadioGroup`, `DateField`, etc.
### 23.3 Superficie inicial recomendada
Primera version razonable:
- `Form.Root`
- `Form.Field`
- `Form.Label`
- `Form.Description`
- `Form.Error`
- `Form.Submit`
- `Form.Reset`
Y quizas a nivel de estado:
- `pending`
- `disabled`
- `readonly`
- `required`
- `invalid`
- `touched`
- `dirty`
### 23.4 Relacion entre `Form` y `Field`
`Field` no debe desaparecer. Debe crecer y coordinarse con `Form`.
Modelo recomendado:
- `Field` = primitive de campo y de asociacion accesible entre label/control/help/error
- `Form` = primitive de formulario, submit, reset, contexto y errores globales
Es decir:
- `Field` organiza el campo
- `Form` organiza el formulario
### 23.5 Inputs especializados futuros
No conviene convertir `Field` en un monstruo con modos especiales. Mejor construir una familia de inputs sobre `Field` + `Form` + `glob`.
Buenos candidatos futuros:
- `Input` textual base
- `NumberField`
- `CurrencyField`
- `PhoneField`
- `PatternField`
- `EmailField`
- `UrlField`
- `SearchField`
Ventaja del framework:
- `glob` ya ofrece una base fuerte para formatos y parseo
- eso puede hacer que nuestros campos localizados superen a muchos sistemas existentes
## 24. FloatingButton
Otro primitive pendiente que si encaja en `terra` es `FloatingButton`.
Encaja porque:
- no es solo visual
- tiene semantica de posicionamiento y accion flotante
- puede requerir accesibilidad, layering, portal o posicion fija reusable
Aun asi, la skin final probablemente vivira mejor en `air`.
Regla practica:
- comportamiento y contrato -> `terra`
- variaciones visuales y motion -> `air`

@ -0,0 +1,2 @@
export * from '$lib/util/dates';
export { getPlaceholder } from '$lib/util/dates/format/placeholders';

@ -1,5 +1,5 @@
import { readableActive, type Active, type Getter } from '../../utils';
import { DEFAULT_DATE_ORDER, DEFAULT_TIME_FORMAT, timeFormatToHourCycle, type HourCycle } from '$lib/util/dates';
import { DEFAULT_DATE_ORDER, DEFAULT_TIME_FORMAT, timeFormatToHourCycle, type HourCycle } from '$terra/adapters/dates';
import { type TerraConfigState, getTerraConfig } from './terra-config.ts';
/**

@ -1,5 +1,5 @@
import type { WithChildren } from '../../utils';
import type { DateOrder, HourCycle } from '$lib/util/dates';
import type { DateOrder, HourCycle } from '$terra/adapters/dates';
import type { PortalTarget } from '../portal/types.ts';
export type TerraConfigPropsWithoutChildren = {

@ -5,7 +5,7 @@ import {
isSameDay,
isSameMonth,
isToday,
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import { DEV } from "esm-env";
import { onMount, untrack } from "svelte";
import {
@ -33,7 +33,7 @@ import {
getDateValueType,
isBefore,
dateValueToDate as toDate,
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import { type Announcer, getAnnouncer } from "../utils/datetime/announcer";
import { type Formatter, createFormatter } from "../utils/datetime/formatter";
import {

@ -1,12 +1,12 @@
<script lang="ts">
import { watch } from "runed";
import { readableActive, writableActive, mergeProps } from "../../utils";
import type { DateValue } from "$lib/util/dates";
import type { DateValue } from "$terra/adapters/dates";
import { CalendarRootState } from "../calendar.svelte";
import type { CalendarRootProps } from "../types";
import { useId } from "../../utils/use-id";
import { noop } from "$lib/util/funcs";
import { getDefaultDate } from "$lib/util/dates";
import { getDefaultDate } from "$terra/adapters/dates";
import { resolveDateOrderProp, resolveLocaleProp } from "../../base/config/prop-resolvers";
let {

@ -1,4 +1,4 @@
import type { DateValue, DateOrder } from "$lib/util/dates";
import type { DateValue, DateOrder } from "$terra/adapters/dates";
import type { TerraDatePresentationProps } from "../base/config/types";
import type { OnChangeFn, WithChild, Without } from "../utils/types";
import type {
@ -13,7 +13,7 @@ import type {
TerraPrimitiveTheadAttributes,
TerraPrimitiveTrAttributes,
} from "../utils/attributes";
import type { DateMatcher, Month, WeekStartsOn } from "$lib/util/dates";
import type { DateMatcher, Month, WeekStartsOn } from "$terra/adapters/dates";
export type CalendarRootSnippetProps = {
months: Month<DateValue>[];

@ -7,7 +7,7 @@
import { resolveDateOrderProp, resolveHourCycleProp, resolveLocaleProp } from "../../base/config/prop-resolvers.ts";
import {
getDefaultDate
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import { noop } from '$lib/util/funcs';
let {

@ -34,7 +34,7 @@ import type {
Granularity,
HourCycle,
DateOrder,
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import type {
DateAndTimeSegmentObj,
DateSegmentObj,
@ -65,7 +65,7 @@ import {
DATE_SEGMENT_PARTS,
EDITABLE_TIME_SEGMENT_PARTS,
} from "../utils/datetime/parts.ts";
import { getDaysInMonth, isBefore, dateValueToDate as toDate } from "$lib/util/dates";
import { getDaysInMonth, isBefore, dateValueToDate as toDate } from "$terra/adapters/dates";
import {
getFirstSegment,
handleSegmentNavigation,
@ -73,7 +73,7 @@ import {
moveToNextSegment,
moveToPrevSegment,
} from "../utils/datetime/segments.ts";
import type { DateValue } from '$lib/util/dates';
import type { DateValue } from '$terra/adapters/dates';
export const dateFieldAttrs = createTerraAttrs({
component: "date-field",

@ -3,7 +3,7 @@ import type {
DateOnInvalid,
DateValidator,
Granularity,
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import type { EditableSegmentPart, SegmentPart } from "../utils/datetime/types";
import type { TerraDateTimePresentationProps } from "../base/config/types";
import type { WithChildren, OnChangeFn, WithChild, Without } from "../utils/types";

@ -1,6 +1,6 @@
<script lang="ts">
import { watch } from 'runed';
import type { DateValue } from '$lib/util/dates';
import type { DateValue } from '$terra/adapters/dates';
import { readableActive, writableActive, mergeProps, useId } from '../../utils';
import { DatePickerRootState } from '../date-picker.svelte.ts';
@ -8,7 +8,7 @@
import { PopoverRootState } from '../../popover/popover.svelte.ts';
import { DateFieldRootState } from '../../date-field/date-field.svelte.ts';
import FloatingLayer from '../../base/floating-layer/components/floating-layer.svelte';
import { getDefaultDate } from '$lib/util/dates';
import { getDefaultDate } from '$terra/adapters/dates';
import { resolveDateOrderProp, resolveHourCycleProp, resolveLocaleProp } from '../../base/config/prop-resolvers.ts';
import { noop } from '$lib/util/funcs';

@ -1,4 +1,4 @@
import type { DateValue } from '$lib/util/dates';
import type { DateValue } from '$terra/adapters/dates';
import { Context } from 'runed';
import type { ActiveProps, StateProps } from '../utils';
import type {
@ -7,7 +7,7 @@ import type {
HourCycle,
WeekStartsOn,
DateOrder,
} from '$lib/util/dates';
} from '$terra/adapters/dates';
import type { SegmentPart } from '../utils/datetime/types';
export const DatePickerRootContext = new Context<DatePickerRootState>('DatePicker.Root');

@ -1,4 +1,4 @@
import type { DateValue } from "$lib/util/dates";
import type { DateValue } from "$terra/adapters/dates";
import type { OnChangeFn, WithChild, WithChildren, Without } from "../utils/types.ts";
import type { TerraPrimitiveDivAttributes } from "../utils/attributes";
import type {
@ -7,7 +7,7 @@ import type {
DateValidator,
Granularity,
WeekStartsOn,
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import type { EditableSegmentPart } from "../utils/datetime/types";
import type { TerraDateTimePresentationProps } from "../base/config/types";
import type { CalendarRootSnippetProps } from "../calendar/types.ts";

@ -1,15 +1,15 @@
<script lang="ts">
import { watch } from "runed";
import { readableActive, writableActive, mergeProps } from "../../utils/index";
import type { DateValue } from "$lib/util/dates";
import type { DateValue } from "$terra/adapters/dates";
import { DateRangeFieldRootState } from "../date-range-field.svelte.ts";
import type { DateRangeFieldRootProps } from "../types.js";
import { createId } from "../../utils/index";
import type { DateRange } from "$lib/util/dates";
import type { DateRange } from "$terra/adapters/dates";
import {
getDefaultDate,
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import { resolveDateOrderProp, resolveHourCycleProp, resolveLocaleProp } from "../../base/config/prop-resolvers.ts";
import { noop } from '$lib/util/funcs';

@ -1,5 +1,5 @@
import { Context, watch } from "runed";
import type { DateValue, DateOrder } from "$lib/util/dates";
import type { DateValue, DateOrder } from "$terra/adapters/dates";
import type {
ActiveProps,
@ -25,8 +25,8 @@ import type {
DateRange,
DateRangeValidator,
Granularity,
} from "$lib/util/dates";
import { isBefore } from "$lib/util/dates";
} from "$terra/adapters/dates";
import { isBefore } from "$terra/adapters/dates";
import type { SegmentPart } from "../utils/datetime/types.ts";
import { type Formatter, createFormatter } from "../utils/datetime";
import { removeDescriptionElement } from "../utils/datetime/helpers.ts";

@ -1,4 +1,4 @@
import type { DateValue } from "$lib/util/dates";
import type { DateValue } from "$terra/adapters/dates";
import type { OnChangeFn, WithChild, Without } from "../utils";
import type {
TerraPrimitiveDivAttributes,
@ -9,7 +9,7 @@ import type {
DateRange,
DateRangeValidator,
Granularity,
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import type { EditableSegmentPart, SegmentPart } from "../utils/datetime/types.ts";
import type { TerraDateTimePresentationProps } from "../base/config/types";
import type {

@ -1,6 +1,6 @@
<script lang="ts">
import { watch } from "runed";
import type { DateValue } from "$lib/util/dates";
import type { DateValue } from "$terra/adapters/dates";
import {
readableActive,
writableActive,
@ -19,7 +19,7 @@
import {
type DateRange,
getDefaultDate
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import { resolveDateOrderProp, resolveHourCycleProp, resolveLocaleProp } from "../../base/config/prop-resolvers.ts";
import { noop } from '$lib/util/funcs';

@ -1,4 +1,4 @@
import type { DateValue } from "$lib/util/dates";
import type { DateValue } from "$terra/adapters/dates";
import { Context } from "runed";
import { type ActiveProps, type StateProps } from "../utils";
import type {
@ -8,7 +8,7 @@ import type {
HourCycle,
WeekStartsOn,
DateOrder,
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import type { SegmentPart } from "../utils/datetime/types";
export const DateRangePickerRootContext = new Context<DateRangePickerRootState>(

@ -1,4 +1,4 @@
import type { DateValue } from "$lib/util/dates";
import type { DateValue } from "$terra/adapters/dates";
import type { OnChangeFn, WithChild, Without } from "../utils/types.ts";
import type { TerraPrimitiveDivAttributes } from "../utils/attributes";
import type {
@ -8,7 +8,7 @@ import type {
DateRangeValidator,
Granularity,
WeekStartsOn,
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import type { EditableSegmentPart } from "../utils/datetime/types";
import type { TerraDateTimePresentationProps } from "../base/config/types";
import type { CalendarRootSnippetProps } from "../calendar/types.ts";

@ -1,12 +1,12 @@
<script lang="ts">
import { watch } from "runed";
import { readableActive, writableActive, mergeProps } from "../../utils/index";
import { type DateValue } from "$lib/util/dates";
import { type DateValue } from "$terra/adapters/dates";
import type { RangeCalendarRootProps } from "../types.js";
import { RangeCalendarRootState } from "../range-calendar.svelte.ts";
import { noop } from "$lib/util/funcs";
import { createId } from "../../utils/create-id";
import { getDefaultDate } from "$lib/util/dates";
import { getDefaultDate } from "$terra/adapters/dates";
import { resolveDateOrderProp, resolveLocaleProp } from "../../base/config/prop-resolvers";
const uid = $props.id();

@ -14,7 +14,7 @@ import {
isBefore,
isBetweenInclusive,
dateValueToDate as toDate,
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import {
attachRef,
DOMContext,

@ -1,7 +1,7 @@
import type { DateValue, DateOrder } from "$lib/util/dates";
import type { DateValue, DateOrder } from "$terra/adapters/dates";
import type { TerraDatePresentationProps } from "../base/config/types";
import type { OnChangeFn, WithChild, Without } from "../utils/types";
import type { DateMatcher, DateRange, Month } from "$lib/util/dates";
import type { DateMatcher, DateRange, Month } from "$terra/adapters/dates";
import type { TerraPrimitiveDivAttributes } from "../utils/attributes";
export type RangeCalendarRootSnippetProps = {

@ -3,7 +3,7 @@
import { readableActive, writableActive } from "../../utils";
const noop = () => {};
import { resolveHourCycleProp, resolveLocaleProp } from "../../base/config/prop-resolvers.ts";
import { getDefaultTime, type TimeValue } from "$lib/util/dates";
import { getDefaultTime, type TimeValue } from "$terra/adapters/dates";
import { TimeFieldRootState } from "../time-field.svelte.js";
import type { TimeFieldRootProps } from "../types.js";

@ -11,7 +11,7 @@ import {
dateValueToDate as toDate,
getISOTimeValue,
isTimeBefore,
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import {
type State,
onDestroyEffect,

@ -4,7 +4,7 @@ import type {
TimeOnInvalid,
TimeValidator,
TimeValue,
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import type { EditableTimeSegmentPart, TimeSegmentPart } from "../utils/datetime/types";
import type { TerraDateTimePresentationProps } from "../base/config/types";
import type { WithChildren, OnChangeFn, WithChild, Without } from "../utils/types";

@ -2,7 +2,7 @@
import { watch } from "runed";
import { readableActive, writableActive, createId, mergeProps } from "../../utils/index";
const noop = () => {};
import { getDefaultTime, type TimeRange, type TimeValue } from "$lib/util/dates";
import { getDefaultTime, type TimeRange, type TimeValue } from "$terra/adapters/dates";
import { resolveHourCycleProp, resolveLocaleProp } from "../../base/config/prop-resolvers.ts";
import { TimeRangeFieldRootState } from "../time-range-field.svelte.ts";
import type { TimeRangeFieldRootProps } from "../types.js";

@ -1,5 +1,5 @@
import { Context, watch } from "runed";
import type { Time, TimeValue } from "$lib/util/dates";
import type { Time, TimeValue } from "$terra/adapters/dates";
import type {
ActiveProps,
StateProps,
@ -20,8 +20,8 @@ import type {
TimeOnInvalid,
TimeRange,
TimeRangeValidator,
} from "$lib/util/dates";
import { convertTimeValueToTime, isTimeBefore, getISOTimeValue } from "$lib/util/dates";
} from "$terra/adapters/dates";
import { convertTimeValueToTime, isTimeBefore, getISOTimeValue } from "$terra/adapters/dates";
import { type TimeFormatter, createTimeFormatter } from "../utils/datetime";
import { removeTimeDescriptionElement } from "../utils/datetime/time-helpers.ts";
import { getFirstSegment } from "../utils/datetime/segments.ts";

@ -5,7 +5,7 @@ import type {
TimeRange,
TimeRangeValidator,
TimeValue,
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import type { OnChangeFn, WithChild, Without } from "../utils";
import type {
TerraPrimitiveDivAttributes,

@ -15,7 +15,7 @@ import {
parseAnyDateValue,
parseStringToDateValue,
dateValueToDate as toDate,
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import {
type Active,
type State,

@ -7,7 +7,7 @@ import {
isZonedDateTime,
dateValueToDate as toDate,
convertTimeValueToDateValue,
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import type { Active } from '../active';
export type Formatter = ReturnType<typeof createFormatter>;

@ -6,11 +6,11 @@ import {
isZonedDateTime,
inferGranularity,
getDefaultHourCycle,
} from "$lib/util/dates";
} from "$terra/adapters/dates";
export { inferGranularity, getDefaultHourCycle };
import { styleToString } from "../index";
import type { Formatter } from "./formatter.ts";
import { getPlaceholder } from "$lib/util/dates/format/placeholders";
import { getPlaceholder } from "$terra/adapters/dates";
import type {
DateAndTimeSegmentObj,
DateSegmentPart,

@ -12,14 +12,14 @@ import {
Time,
isZonedDateTime,
getDefaultHourCycle,
} from "$lib/util/dates";
} from "$terra/adapters/dates";
import type { TimeFormatter } from "./formatter.ts";
import { ALL_TIME_SEGMENT_PARTS, EDITABLE_TIME_SEGMENT_PARTS } from "./parts.ts";
import { getTimeSegments } from "./segments.ts";
import type { TimeSegmentPart } from "./types.ts";
import { styleToString } from "../index";
import { useId } from "../use-id";
import { getPlaceholder } from "$lib/util/dates";
import { getPlaceholder } from "$terra/adapters/dates";
@ -358,4 +358,4 @@ export {
isTimeBefore,
isTimeAfter,
getISOTimeValue,
} from "$lib/util/dates";
} from "$terra/adapters/dates";

Loading…
Cancel
Save

Powered by TurnKey Linux.