Skip to content

Date Input ​

Three separate fields for day, month, and year. Use for dates the user knows from memory (birth date, passport issue date). Includes label, help text, error state, auto-advance, and accessible markup.

Demo ​

Basic

For eksempel: 27 03 1990

Value: //

Pre-filled

For eksempel: 05 12 2018

Sizes

Error state

Disabled

Custom labels

Installation ​

vue
<script setup>
import { GTDateInput } from '@grundtone/vue';
</script>

In Nuxt, GTDateInput is auto-imported.

When to use ​

Use date input when you need a specific, known date — such as a birth date, document issue date, or historical event. Three separate fields are easier and faster than a single date picker for memorised dates.

Do not use date input for scheduling, booking, or selecting dates from a range. Do not use on mobile native (React Native) — use the platform's native date picker instead.

Usage ​

Basic ​

vue
<GTDateInput
  v-model="birthDate"
  label="Fødselsdato"
  help-text="For eksempel: 27 03 1990"
  autocomplete="bday"
  required
/>

With pre-filled value ​

vue
<script setup>
import { ref } from 'vue';
const passportDate = ref({ day: '05', month: '12', year: '2018' });
</script>

<template>
  <GTDateInput
    v-model="passportDate"
    label="Hvornår blev dit pas udstedt?"
    help-text="For eksempel: 05 12 2018"
  />
</template>

Error state ​

Error messages appear between the label and the fields, replacing help text. All field borders turn red. Only show errors after the user has interacted.

vue
<GTDateInput
  v-model="date"
  label="Startdato"
  error-text="Datoen kan ikke være i fremtiden"
/>

Sizes ​

vue
<GTDateInput v-model="date" label="Small" size="sm" />
<GTDateInput v-model="date" label="Medium" size="md" />
<GTDateInput v-model="date" label="Large" size="lg" />

Custom field labels ​

Default labels are "Dag", "Måned", "År". Override for other languages:

vue
<GTDateInput
  v-model="date"
  label="Date of birth"
  day-label="Day"
  month-label="Month"
  year-label="Year"
/>

Disabled ​

vue
<GTDateInput
  :model-value="{ day: '01', month: '01', year: '2020' }"
  label="Oprettelsesdato"
  disabled
/>

Props ​

PropTypeDefaultDescription
modelValueDateInputValue{ day: '', month: '', year: '' }Bound value (v-model)
sizeDateInputSize'md'Size preset: sm, md, lg
labelstring—Visible label above the date group
helpTextstring—Help text between label and fields
errorTextstring—Error message (replaces helpText)
requiredbooleanfalseRequired field
disabledbooleanfalseDisabled state
idstringautoID prefix for sub-fields
dayLabelstring'Dag'Label for day field
monthLabelstring'Måned'Label for month field
yearLabelstring'År'Label for year field
autocompletestring—Autocomplete prefix (e.g. "bday" → bday-day, bday-month, bday-year)

Events ​

EventPayloadDescription
update:modelValueDateInputValueEmitted on input in any field

Behaviors ​

  • Auto-advance: When the user types 2 digits in day, focus moves to month. When 2 digits in month, focus moves to year.
  • Numeric filtering: Non-digit characters are stripped automatically.
  • Maxlength: Day/month limited to 2 digits, year to 4.

Accessibility ​

  • role="group" on the date wrapper with aria-labelledby
  • Each field has its own <label> (Dag, Måned, År)
  • aria-required set on all fields when required is true
  • aria-invalid set on all fields when errorText is present
  • aria-describedby links the group to help or error text
  • inputmode="numeric" for numeric keyboard on mobile
  • pattern="[0-9]*" for iOS numeric keyboard
  • autocomplete attributes for autofill
  • Error text uses role="alert" for screen reader announcement

Validation with useDateField ​

Use the useDateField composable for reactive validation. It holds a DateInputValue internally and derives a "DD-MM-YYYY" string for validators. It returns a UseFieldReturn-compatible interface, so it works with useFormValidation.

vue
<script setup>
import {
  GTDateInput, GTButton,
  useDateField, useFormValidation,
  required, date, datePast,
} from '@grundtone/vue';

const birthDate = useDateField({
  validators: [
    required('Fødselsdato er påkrævet'),
    date('Ugyldig dato'),
    datePast('Datoen skal være i fortiden'),
  ],
  validateOn: 'blur',
});

const form = useFormValidation({ birthDate });

function onSubmit() {
  if (!form.validateAll()) return;
  console.log('Valid:', birthDate.dateValue.value);
}
</script>

<template>
  <form @submit.prevent="onSubmit">
    <GTDateInput
      v-model="birthDate.dateValue.value"
      :error-text="birthDate.errorText.value"
      v-on="birthDate.handlers"
      label="Fødselsdato"
      help-text="For eksempel: 27 03 1990"
      autocomplete="bday"
      required
    />
    <GTButton type="submit" variant="primary">Submit</GTButton>
  </form>
</template>

See useDateField for full composable documentation.

Available date validators ​

ValidatorDescription
date(message?)Validates that the date exists (e.g. not 31 February)
datePast(message?)Validates that the date is in the past
dateFuture(message?)Validates that the date is in the future

Validators expect a "DD-MM-YYYY" format string (hyphen-separated). useDateField handles this conversion automatically.

CSS Classes ​

ClassDescription
date-inputFlex container for the three fields
date-input__fieldWrapper for a single field
date-input__labelSmall label for each field
date-input__input--dayDay input width constraint
date-input__input--monthMonth input width constraint
date-input__input--yearYear input width constraint
gt-inputBase input class (reused)
gt-input--sm/md/lgSize variants (reused)
gt-input--errorError state (reused)
gt-input-fieldOuter wrapper (reused)
gt-input-labelGroup label (reused)
gt-input-hintHelp text (reused)
gt-input-errorError text (reused)

See Date Input (Design System) for full CSS reference.