Skip to content

datetime2 component migration

Adi Dahiya edited this page Oct 13, 2022 · 15 revisions

To prepare for the Popover changes coming in Blueprint v5.0, we're providing "v2" variants of @blueprintjs/datetime and @blueprintjs/timezone components which use Popover2 instead of Popover. Migrate to these now in order to ensure a smooth migration path.

These components are available in the new @blueprintjs/datetime2 package:

Replacement for DateInput, with notable changes:

  • The component now uses Popover2 instead of Popover, so there are some DOM layout changes and the type of popoverProps has changed to Popover2Props. Two popover wrapper elements have been removed, and the popover interactions are now attached directly to the InputGroup. See Popover2 migration for more info.
  • The controlled value and uncontrolled defaultValue API have changed to use an ISO string instead of a JS Date value. ISO strings are also returned in the onChange callback. This allows the component to be more explicit about timezones.
  • The component optionally embeds a TimezoneSelect inside the input which allows the user to change the timezone of the selected datetime. This can be enabled with the new prop showTimezoneSelect={true}.
  • Key event handlers have been updated to use non-deprecated KeyboardEvent APIs. This may affect testing code which relies on setting event.which key codes to simulate keyboard behavior. Tests should be updated to use the event.key property instead.

API changes

Before:

const [date, setDate] = React.useState(new Date());

return (
  <DateInput value={date} onChange={setDate} />
);

After:

const [date, setDate] = React.useState(new Date().toISOString());
// alternatively, you can specify the string explicitly, like "2022-07-14T15:01:08.859Z" or "2022-07-14T11:01:08.859-4:00"

return (
  <DateInput value={date} onChange={setDate} />
);

Migration utilities

For automated migrations to the new string-based API, we provide some adapter utility functions to convert your data and callbacks to use the updated types. You can test out these adapters in this code sandbox. Here's a code example:

import { DateInput2 } from "@blueprintjs/datetime2";
import React, { useCallback, useState } from "react";

function Example() {
  const [dateValue, setDateValue] = useState<Date | null>(null);
  const handleChange = useCallback(setDateValue, [setDateValue]);
  const formatDate = useCallback((date: Date) => date.toLocaleString(), []);
  const parseDate = useCallback((str: string) => new Date(str), []);

  return (
    <DateInput2
      formatDate={formatDate}
      onChange={DateInput2.MigrationUtils.onChangeAdapter(handleChange)}
      parseDate={parseDate}
      placeholder="M/D/YYYY"
      value={DateInput2.MigrationUtils.valueAdapter(dateValue)}
    />
  );
}

Rendered DOM changes

- <span class="bp4-popover-wrapper">
-   <span aria-haspopup="true" class="bp4-popover-target">
-     <div class="bp4-input-group">
-       <input type="text" autocomplete="off" placeholder="JS Date" class="bp4-input" value="7/14/2022">
-     </div>
-   </span>
- </span>
+ <div class="bp4-input-group bp4-date-input bp4-popover2-target">
+   <input type="text" autocomplete="off" placeholder="MM/dd/yyyy" class="bp4-input" value="07/14/2022">
+   <!-- optional timezone select here -->
+ </div>

Replacement for DateRangeInput, with notable changes:

  • The component now uses Popover2 instead of Popover, so there are some DOM changes and the type of popoverProps has changed to Popover2Props. Two popover wrapper elements have been removed, and the popover interactions are now attached directly to the InputGroup. See Popover2 migration for more info.

Rendered DOM changes

- <span class="bp4-popover-wrapper">
-   <span aria-haspopup="true" class="bp4-popover-target">
-     <div class="bp4-control-group">
-         <div class="bp4-input-group">...</div>
-         <div class="bp4-input-group">...</div>
-     </div>
-   </span>
- </span>
+ <div aria-haspopup="true" class="bp4-control-group bp4-date-range-input bp4-popover2-target">
+     <div class="bp4-input-group">...</div>
+     <div class="bp4-input-group">...</div>
+ </div>

Replacement for TimezonePicker, with notable changes:

  • Component name has changed to better match semantic naming patterns of other Blueprint components:
    • It is a specialized select component, not a picker component.
    • Note that we use the term "picker" to refer to DatePicker / DateRangePicker, which do not rely on popovers.
  • New name means that class names have changed:
    • .bp4-timezone-picker.bp4-timezone-select
    • .bp4-timezone-picker-popover.bp4-timezone-select-popover
    • ℹ️ remember to always use the $bp-ns variable in Sass and the Classes constants in TS/JS when referencing Blueprint class names
  • Component uses Select2 instead of Select, so there are some DOM changes — see Select2 migration for more info.
  • New prop fill matches behavior of <Select fill>.
  • The type of popoverProps has changed to Popover2Props, which means a few properties have changed. See Popover2 migration for more info.
    • popover positioning may be specified with "placement" or "position"
    • boundary has been replaced with rootBoundary, which better matches popper.js' definition of what a "boundary" is
    • modifiers type has changed
    • targetClassName and targetTagName properties have been removed

Rendered DOM changes

- <span class="bp4-popover-wrapper bp4-timezone-picker">
-   <span aria-haspopup="true" class="bp4-popover-target">
-     <div class="">
-       <button type="button" class="bp4-button">
-         ...
-       </button>
-     </div>
-   </span>
- </span>
+ <div
+   aria-controls="listbox-1"
+   aria-expanded="false"
+   aria-haspopup="listbox"
+   class="bp4-timezone-select bp4-popover2-target"
+   role="combobox"
+ >
+   <button type="button" class="bp4-button">
+     ...
+   </button>
+ </div>
Clone this wiki locally