orn-ui
Organism

DateField

Requiere <UIProvider> — Primeros pasos →

Instalación

Instala solo este componente (copia el código fuente a tu proyecto, sin dependencia npm)

npx orn-ui add date-field

O instala el paquete completo e impórtalo

pnpm add orn-ui
import { DateField } from 'orn-ui/date-field';

Uso

  • cuándo usarlo — Una fecha dentro de un formulario: se lee como un Input y abre el calendario en un modal.
  • format — Cómo se lee la fecha elegida en el campo. Conviene alinearlo con el locale.
  • required / error — Mismo patrón que Input y Select.
  • modalTitle / clearLabel — Los textos del modal, para cuando la app no está en inglés.
Clip del demo todavía sin grabar — ver MEDIA.md

Variantes

DateField — input that opens the calendar

<DateField label="Due date" value={fieldDate} onChange={setFieldDate} maxDate={inAMonth} />

DateField — custom format

<DateField
  label="ISO format"
  value={fieldDate}
  onChange={setFieldDate}
  format={(d) => d.toISOString().slice(0, 10)}
/>

DateField — onClear renders the clear button

<DateField
  label="Due date"
  value={fieldDate}
  onChange={setFieldDate}
  onClear={() => setFieldDate(undefined)}
/>

DateField — mode="range", closes when the range closes

<DateField label="Stay" mode="range" range={fieldRange} onRangeChange={setFieldRange} />

DateField — required + error

<DateField label="Due date" required onChange={() => {}} error="Pick a date to continue" />

DateField — disabled

<DateField label="Locked" value={today} onChange={() => {}} disabled />
Código completo del demo
const variants: VariantDef[] = [
  {
    label: 'Inline calendar',
    content: <DatePicker value={date} onChange={setDate} />,
  },
  {
    label: 'mode="range" — tap start, then end',
    content: (
      <View style={{ gap: 8 }}>
        <DatePicker mode="range" range={range} onRangeChange={setRange} />
        <Caption>
          {range?.start
            ? `${range.start.toDateString()} → ${range.end ? range.end.toDateString() : '…'}`
            : 'No range selected'}
        </Caption>
      </View>
    ),
  },
  {
    label: 'mode="range" + minDate/maxDate',
    content: <DatePicker mode="range" range={range} onRangeChange={setRange} minDate={today} maxDate={inAMonth} />,
  },
  {
    label: 'minDate / maxDate (next 7 days only)',
    content: <DatePicker value={ranged} onChange={setRanged} minDate={today} maxDate={inAWeek} />,
  },
  {
    label: 'Week starts on Monday',
    content: <DatePicker value={date} onChange={setDate} firstDayOfWeek={1} />,
  },
  {
    label: 'Localized month/weekday names',
    content: (
      <DatePicker
        value={date}
        onChange={setDate}
        monthNames={SPANISH_MONTHS}
        weekdayNames={SPANISH_WEEKDAYS}
        firstDayOfWeek={1}
      />
    ),
  },
  {
    label: 'DateField — input that opens the calendar',
    content: <DateField label="Due date" value={fieldDate} onChange={setFieldDate} maxDate={inAMonth} />,
  },
  {
    label: 'DateField — custom format',
    content: (
      <DateField
        label="ISO format"
        value={fieldDate}
        onChange={setFieldDate}
        format={(d) => d.toISOString().slice(0, 10)}
      />
    ),
  },
  {
    label: 'DateField — onClear renders the clear button',
    content: (
      <DateField
        label="Due date"
        value={fieldDate}
        onChange={setFieldDate}
        onClear={() => setFieldDate(undefined)}
      />
    ),
  },
  {
    label: 'DateField — mode="range", closes when the range closes',
    content: <DateField label="Stay" mode="range" range={fieldRange} onRangeChange={setFieldRange} />,
  },
  {
    label: 'DateField — required + error',
    content: <DateField label="Due date" required onChange={() => {}} error="Pick a date to continue" />,
  },
  {
    label: 'DateField — disabled',
    content: <DateField label="Locked" value={today} onChange={() => {}} disabled />,
  },
];
return <VariantList variants={variants} />;

Props

Además acepta testID, que se reenvía al nodo raíz. Existe para los tests end-to-end (Maestro maneja la app por el árbol de accesibilidad) y no cambia en nada cómo se ve ni cómo se comporta el componente.

NombreTipoPor defectoDescripción
label?string
required?booleanfalse
mode?'single' | 'range'single'single' elige una fecha; 'range' elige un intervalo con dos toques.
value?DateFecha seleccionada en mode="single".
onChange?(date: Date) => voidSe llama en mode="single".
range?DateRangeRango seleccionado en mode="range".
onRangeChange?(range: DateRange) => voidSe llama en mode="range", tanto al fijar el inicio como al cerrar el rango.
placeholder?stringSelect a date
error?string
disabled?booleanfalse
format?(date: Date) => stringMonth D, YYYYFormatea la fecha del campo.
modalTitle?stringthe `selectDate` from `useLabels()`Título del modal del calendario.
onClear?() => voidSi se pasa, el modal muestra un botón que borra la selección y cierra. Sin esto no hay botón: el "Clear" anterior solo cerraba, sin limpiar nada.
clearLabel?stringthe `clear` from `useLabels()`Texto de ese botón.
containerStyle?StyleProp<ViewStyle>
minDate?Date
maxDate?Date
monthNames?string[]those from `useLabels()`Nombres de los meses.
weekdayNames?string[]those from `useLabels()`Iniciales de los días, índice 0 = domingo.
firstDayOfWeek?0 | 100 = domingo, 1 = lunes.