Skip to main content
Default Gray Amethyst

Date Picker

<mo-date-picker> | MODatePicker
Since 3.0 stable

Date picker is used to select past, present, or future dates.

<mo-date-picker
  closeOnSelection
  format="dd.MM.yyyy"
  label="Choose date"
  help-text="Click the calendar icon to open the selector popup."
></mo-date-picker>
import { MODatePicker } from '@metsooutotec/modes-web-components/dist/react';

const App = () => (
  <MODatePicker
    closeOnSelection
    format="dd.MM.yyyy"
    label="Choose date"
    helpText="Click the calendar icon to open the selector popup."
  ></MODatePicker>
);

Examples

Range picker

Set the selection attribute to range to render two calendars to allow for date ranges.

<mo-date-picker format="dd.MM.yyyy" selection="range" label="Choose date"></mo-date-picker>
import { MODatePicker } from '@metsooutotec/modes-web-components/dist/react';

const App = () => <MODatePicker format="dd.MM.yyyy" selection="range" label="Choose date"></MODatePicker>;

Setting the value programmatically

The value attribute can be set to either a valid datetime string (that follows the given format), or a Date object to set the current value programmatically. This will also work for ranges, and it will update the input and the calendars.


<mo-date-picker
  id="programmatic"
  closeOnSelection
  format="dd.MM.yyyy"
  label="Date today"
  help-text="The value has been set to today using new Date()"
></mo-date-picker>
<br />
<mo-date-picker format="dd.MM.yyyy" value="18.04.2024 - 03.07.2024" selection="range" help-text="The range has been set using a string '18.04.2024 - 03.07.2024'" label="String range"></mo-date-picker>

<script>
  const picker = document.querySelector('#programmatic');
  picker.value = new Date();
</script>
import { MODatePicker } from '@metsooutotec/modes-web-components/dist/react';

const App = () =>
  <>
    <MODatePicker
        closeOnSelection
        format="dd.MM.yyyy"
        label="Choose date"
        value={new Date()}
        helpText="Click the calendar icon to open the selector popup."
      ></MODatePicker>
    <br />
    <MODatePicker format="dd.MM.yyyy" selection="range" value="18.04.2024 - 03.07.2024" label="Choose date"></MODatePicker>
  <>;

Time picker

Enable the time-input attribute to also add a time to the date.

<mo-date-picker
  format="dd.MM.yyyy, HH:mm"
  time-input
  selection="range"
  label="Choose date and time"
  no-suggestions
></mo-date-picker>
import { MODatePicker } from '@metsooutotec/modes-web-components/dist/react';

const App = () => (
  <MODatePicker
    format="dd.MM.yyyy, HH:mm"
    timeInput
    selection="range"
    label="Choose date and time"
    noSuggestions
  ></MODatePicker>
);

Min and max dates

The date picker forwards identically named attributes to mo-calendar to limit date selection.

<mo-date-picker
  closeOnSelection
  format="dd.MM.yyyy"
  id="min-and-max"
  format="MMMM do, yyyy"
  label="Choose date"
  help-text="Click the calendar icon to open the selector popup."
></mo-date-picker>

<script>
  const picker = document.querySelector('#min-and-max');
  const now = new Date();
  const twoWeeksFromNow = new Date(Date.now() + 6.048e8 * 2);
  picker.min = now;
  picker.max = twoWeeksFromNow;
</script>
import { MODatePicker } from '@metsooutotec/modes-web-components/dist/react';

const App = () => (
  <MODatePicker
    closeOnSelection
    format="dd.MM.yyyy"
    min={new Date()}
    max={new Date(Date.now() + 6.048e8 * 2)}
    format="MMMM do, yyyy"
    label="Choose date"
    helpText="Click the calendar icon to open the selector popup."
  ></MODatePicker>
);

Locale and formatting

Set the locale attribute to customize the locale. The current options are enUS | fi | es | ptBR | pl. Set the format attribute to customize how to show the selected date.

Suomi English Polish Español Português
<div style="display: flex; flex-direction: column; gap: 8px;">
  <mo-select style="align-self: end;" value="fi">
    <mo-option value="fi">Suomi</mo-option>
    <mo-option value="en-US">English</mo-option>
    <mo-option value="pl">Polish</mo-option>
    <mo-option value="es">Español</mo-option>
    <mo-option value="pt-BR">Português</mo-option>
  </mo-select>
  <mo-date-picker
    id="localized"
    label="Valitse päivä"
    locale="fi"
    lang="fi"
    format="do MMMM, yyyy"
    closeOnSelection
    selection="range"
  ></mo-date-picker>
</div>

<script>
  const select = document.querySelector('mo-select');
  const datePicker = document.querySelector('#localized');
  const labels = {
    fi: 'Valitse päivä',
    'en-US': 'Choose date',
    'pt-BR': 'Escolha a data',
    es: 'Elegir fecha',
    pl: 'Wybierz datę'
  };
  select.addEventListener('mo-change', e => {
    datePicker.locale = e.target.value;
    datePicker.lang = e.target.value.split('-')[0];
    datePicker.label = labels[e.target.value];
  });
</script>
import { MODatePicker, MOOption, MOSelect } from '@metsooutotec/modes-web-components/dist/react';

const App = () => (
  <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
    <MOSelect style={{ alignSelf: 'end' }} value="fi">
      <MOoption value="fi">Suomi</MOoption>
      <MOoption value="en-US">English</MOoption>
      <MOoption value="pl">Polish</MOoption>
      <MOoption value="es">Español</MOoption>
      <MOoption value="pt-BR">Português</MOoption>
    </MOSelect>
    <MODatePicker
      id="localized"
      label="Valitse päivä"
      locale="fi"
      lang="fi"
      format="do MMMM, yyyy"
      closeOnSelection
      selection="range"
    ></MODatePicker>
  </div>
);

Factory time

If you need to have a preset time on a time range that users cannot customize, use the time-readonly and time-default-value attributes to set that. This example shows off the “factory time” logic.

<mo-date-picker
  format="dd.MM.yyyy, HH:mm"
  time-input
  time-readonly
  time-default-value="06:00"
  selection="range"
  label="Choose date and time"
></mo-date-picker>
import { MODatePicker } from '@metsooutotec/modes-web-components/dist/react';

const App = () => (
  <MODatePicker
    format="dd.MM.yyyy, HH:mm"
    timeInput
    timeReadonly
    timeDefaultValue="06:00"
    selection="range"
    label="Choose date and time"
  ></MODatePicker>
);

Use the footer and sidebar slots to add content below and to the side of the calendars in the popup dialog.

Unfortunately due to the way slots function, it is not possible to slot in content in two different places in the markup. In other words, the mobile date picker being separate from the desktop one as it is in a drawer causes the effect that content must be provided for both desktop and mobile separately.

<mo-date-picker id="footer-date" selection="range" label="Choose date range">
  <div class="footer-div" slot="footer">
    <mo-button id="cancel-btn" variant="secondary">Cancel</mo-button>
    <mo-button id="apply-btn">Apply</mo-button>
  </div>
  <div class="sidebar-div" slot="sidebar">
    <mo-radio-group class="rg" hide-fieldset orientation="vertical">
      <mo-radio-button value="86400">Day</mo-radio-button>
      <mo-radio-button value="604800">Week</mo-radio-button>
      <mo-radio-button value="2592000">Month</mo-radio-button>
      <mo-radio-button value="31536000">Year</mo-radio-button>
    </mo-radio-group>
  </div>
  <div class="footer-div" slot="mobile-footer">
    <mo-button id="cancel-btn-mobile" variant="secondary">Cancel</mo-button>
    <mo-button id="apply-btn-mobile">Apply</mo-button>
  </div>
  <div class="sidebar-div" slot="mobile-sidebar">
    <mo-radio-group class="rg-mobile" hide-fieldset>
      <mo-radio-button value="86400">Day</mo-radio-button>
      <mo-radio-button value="604800">Week</mo-radio-button>
      <mo-radio-button value="2592000">Month</mo-radio-button>
      <mo-radio-button value="31536000">Year</mo-radio-button>
    </mo-radio-group>
  </div>
</mo-date-picker>

<script>
  const picker = document.querySelector('#footer-date');
  const radioGrp = document.querySelector('.rg');
  const radioGrpMobile = document.querySelector('.rg-mobile');
  const cancelBtn = document.querySelector('#cancel-btn');
  const applyBtn = document.querySelector('#apply-btn');
  const cancelBtnMobile = document.querySelector('#cancel-btn');
  const applyBtnMobile = document.querySelector('#apply-btn');
  cancelBtn.addEventListener('click', () => {
    picker.reset();
    picker.hide();
  });
  applyBtn.addEventListener('click', () => {
    picker.hide();
  });
  cancelBtnMobile.addEventListener('click', () => {
    picker.reset();
    picker.hide();
  });
  applyBtnMobile.addEventListener('click', () => {
    picker.hide();
  });
  radioGrp.addEventListener('mo-change', e => {
    const value = e.target.value;
    const today = new Date();
    const rangeEndMs = new Date().getTime() + parseInt(value) * 1000;
    const rangeEndDate = new Date(rangeEndMs);
    picker.value = [today, rangeEndDate];
  });
  radioGrpMobile.addEventListener('mo-change', e => {
    const value = e.target.value;
    const today = new Date();
    const rangeEndMs = new Date().getTime() + parseInt(value) * 1000;
    const rangeEndDate = new Date(rangeEndMs);
    picker.value = [today, rangeEndDate];
  });
</script>

<style>
  .footer-div,
  .sidebar-div {
    display: flex;
    align-items: center;
    gap: var(--mo-spacing-small);
    width: 100%;
    justify-content: flex-end;
    box-sizing: border-box;
  }
  .sidebar-div {
    flex-direction: column;
    gap: 0;
  }
  mo-radio-button {
    margin: 0;
  }
  mo-date-picker::part(sidebar) {
    padding: 0;
  }
  mo-date-picker::part(mobile-sidebar) {
    padding: 0;
  }
  @media screen and (max-width: 576px) {
    .footer-div,
    .sidebar-div {
      flex-direction: row;
      width: 100%;
    }
    .footer-div {
      justify-content: flex-end;
    }
    .sidebar-div {
      justify-content: flex-start;
    }
  }
</style>
import { MODatePicker } from '@metsooutotec/modes-web-components/dist/react';

const App = () => (
  <MODatePicker
    format="dd.MM.yyyy, HH:mm"
    timeInput
    timeReadonly
    timeDefaultValue="06:00"
    selection="range"
    label="Choose date and time"
  >
    <div class="footer-div" slot="footer">
      <MOButton id="cancel-btn" variant="secondary">
        Cancel
      </MOButton>
      <MOButton id="apply-btn">Apply</MOButton>
    </div>
    <div class="sidebar-div" slot="sidebar">
      <MORadioGroup hideFieldset orientation="vertical">
        <MORadioButton value="86400">Day</MORadioButton>
        <MORadioButton value="604800">Week</MORadioButton>
        <MORadioButton value="2592000">Month</MORadioButton>
        <MORadioButton value="31536000">Year</MORadioButton>
      </MORadioGroup>
    </div>
  </MODatePicker>
);

Importing

If you’re using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use any of the following snippets to cherry pick this component.

Bundler React Script

To import this component using a bundler:

import '@metsooutotec/modes-web-components/dist/components/date-picker/date-picker.js';

To import this component as a React component:

import MODatePicker from '@metsooutotec/modes-web-components/dist/react/date-picker/';

To import this component using a script tag:

<script type="module" src="https://modes-web.metso.com/dist/components/cdn/components/date-picker/date-picker.js"></script>

Properties

Name Description Reflects Type Default
mainCalendar Calendars MOCalendar -
format Format for the date. See date-fns documentation for all options: https://date-fns.org/v3.3.1/docs/format string 'dd.MM.yyyy'
label The label of the date picker. string ''
placeholder The date picker’s placeholder text. If omitted, the date picker will use the format as the placeholder. string | undefined -
helpText
help-text
The date picker’s help text. If you need to display HTML, use the help-text slot instead. string ''
disabled Makes the date picker input component disabled. This prevents users from being able to interact with the input, and conveys its inactive state to assistive technologies. boolean false
size The date picker’s size. 'small' | 'medium' | 'large' 'medium'
selection The date picker’s selection type. 'single' | 'range' 'single'
name The date picker’s name attribute. string -
error Renders the field in an error state boolean false
success Renders the field in a success state boolean false
errorText
error-text
Error text to show in place of help text when input is invalid. string ''
successText
success-text
Success text to show in place of help text when input is valid. string ''
value The current selected date(s). Either a string, Date object, or a tuple of either. Date | string | [Date | undefined, Date | undefined] | [string | undefined, string | undefined] | undefined -
visibleValue The visible value displayed in the input. string ''
rangeDateSeparator The date picker’s range date separator. string ' - '
timeInput
time-input
Add a time input to the bottom of the calendar. boolean false
timeStep
time-step
The time step in seconds. number 3600
timeMin
time-min
Minimum time allowed. Supported time formats are in ISO 8601: - hh:mm - hh:mm:ss - hh:mm:ss.fff string '00:00'
timeMax
time-max
Maximum time allowed. Supported time formats are in ISO 8601: - hh:mm - hh:mm:ss - hh:mm:ss.fff string '23:59'
timeReadonly
time-readonly
Makes the time input readonly. boolean false
timeDefaultValue
time-default-value
Default time value. Use this in combination with readonly when users should always have the same time selected. E.g. when using factory time, the time can be set to 06:00. string | undefined -
min The minimum allowed date. Dates before this will be disabled from selection. Date | string | undefined -
max The maximum allowed date. Dates after this will be disabled from selection. Date | string | undefined -
invalid This will be true when the control is in an invalid state. Validity is determined by props such as type, required, minlength, maxlength, and pattern using the browser’s constraint validation API. boolean true
open Indicates whether or not the date picker is open. You can toggle this attribute to show and hide the dialog, or you can use the show() and hide() methods and this attribute will reflect the date picker’s open state. boolean false
closeOnSelection Indicates whether the date picker should close automatically when a date is selected. boolean false
locale List of pre-defined locales for easy selection. 'en-US' | 'fi' | 'es' | 'pt-BR' | 'pl' | undefined 'en-US'
customLocale Allows total customization of locale, should be a date-fns object: https://date-fns.org/v3.3.1/docs/I18n Locale | undefined -
weekStartsOn The first day of the week. 0 is Sunday, 1 is Monday, etc. 0 | 1 | 2 | 3 | 4 | 5 | 6 | undefined 1
isDateDisabled A function that determines which dates should be disabled in the calendar. The function receives a Date object and should return true if the date should be disabled. Can be used for things like disabling weekends, holidays, or specific days of the week. (date: Date) => boolean | undefined -
placement The preferred placement of the datepicker’s dialog. Note that the actual placement may vary as needed to keep the dialog inside of the viewport. 'bottom-start' | 'top-start' | 'top-end' | 'bottom-end' 'bottom-end'
locales Default locales imported from date-fns. array [ { locale: enUS, name: 'en-US', label: 'English (US)' }, { locale: fi, name: 'fi', label: 'Finnish' }, { locale: es, name: 'es', label: 'Spanish' }, { locale: ptBR, name: 'pt-BR', label: 'Portuguese (Brazil)' }, { locale: pl, name: 'pl', label: 'Polish' } ]
validity Gets the validity state object - -
validationMessage Gets the validation message - -
updateComplete A read-only promise that resolves when the component has finished updating.

Learn more about attributes and properties.

Events

Name React Event Description Event Detail
mo-change onMoChange Emitted when the datetime picker’s value changes. -
mo-hide onMoHide Emitted when the datetime picker is hidden. -
mo-show onMoShow Emitted when the datetime picker is shown. -

Learn more about events.

Methods

Name Description Arguments
checkValidity() Checks for validity but does not show a validation message. Returns true when valid and false when invalid. -
getForm() Gets the associated form, if one exists. -
reportValidity() Checks for validity and shows the browser’s validation message if the control is invalid. -
show() Shows the date picker dialog. { focus = true }:
hide() Hides the date picker dialog. -
reset() Resets the date picker to an empty state. -

Learn more about methods.

Parts

Name Description
base The component’s internal wrapper.
input The input component’s base.
label__base The input label.
calendars The container for the calendars.
sidebar The sidebar container.
footer The footer container.
main-calendar The main calendar container.
range-calendar The range calendar container.
mobile-footer The mobile footer container.
mobile-sidebar The mobile sidebar container.
form-control The form control container.
form-control-input The form control input container.
form-control-help-text The form control help text container.
form-control-error-text The form control error text container.
form-control-success-text The form control success text container.

Learn more about customizing CSS parts.