Migrate Date Picker from Polaris React
Use s-date-picker when merchants benefit from a visible calendar. Use s-date-field when one date belongs in a standard form.
The value model changes from JavaScript Date objects to date-only strings such as 2025-05-28 and range strings such as 2025-05-28--2025-05-31.
If the app renders this controlled field through React, upgrade to React 19 first. React 18 doesn't provide the custom-element property and event behavior this example relies on. If you can't upgrade yet, leave the controlled Polaris React field in place during this migration slice.
Anchor to Migrate a date rangeMigrate a date range
Migrating a reporting date range
Polaris web components
<s-date-picker
view="2025-05"
type="range"
value="2025-05-28--2025-05-31"
></s-date-picker>Polaris React
import {DatePicker} from '@shopify/polaris';
export function ReportingRange({range, month, year, setRange, changeMonth}) {
return (
<DatePicker
month={month}
year={year}
selected={range}
allowRange
disableDatesBefore={new Date(2025, 0, 1)}
disableDatesAfter={new Date(2025, 11, 31)}
onChange={setRange}
onMonthChange={changeMonth}
/>
);
}Preview
Anchor to Replace DatePicker propertiesReplace Date Picker properties
| Polaris React | Polaris web components | Migration notes |
|---|---|---|
selected Date | value="YYYY-MM-DD" with type="single" | Store a date-only value when time isn't part of the task. |
selected range | value="start--end" with type="range" | Define whether an incomplete range can submit. |
allowRange | type="range" | The destination supports one date or one continuous range. It doesn't support an independent multi-date selection mode. |
month and year | view="YYYY-MM" | Pad the month to two digits. |
onMonthChange(month, year) | onViewchange(event) | Read event.currentTarget.view. |
onChange(range) | onChange(event) | Read event.currentTarget.value. |
disableDatesBefore and disableDatesAfter | allow or disallow ranges | Serialize inclusive date-only boundaries explicitly. |
disableSpecificDates | Comma-separated disallow values | Serialize each date as YYYY-MM-DD. |
weekStartsOn | Remove | Let the localized component own calendar conventions. |
multiMonth | One responsive calendar or start/end s-date-field controls | Don't force two calendars into narrow embedded layouts. |
dayAccessibilityLabelPrefix | Remove | The destination owns day accessibility labels. |
Anchor to Avoid timezone shiftsAvoid timezone shifts
Don't call toISOString().slice(0, 10) on a local-midnight Date without checking the timezone conversion. It can produce the previous or next calendar date. Format the intended local year, month, and day directly, or migrate the domain model to a date-only type at the server boundary.
When reading the destination value, don't create a local Date only to store it again. Keep YYYY-MM-DD through validation and transport when the domain value has no time or timezone.
allow and disallow accept dates, months, years, and inclusive ranges. Convert all old before, after, and specific-date rules, then test their boundaries. If the rules are calculated on the server, render the same normalized constraints that the server validates.
Use view only when the app must control the displayed month. Otherwise use defaultView and let the component own navigation. Don't update the selected date when only the calendar view changes.
Anchor to Choose a date field for formsChoose a date field for forms
Use s-date-field for scheduling or settings forms where a compact labelled input is appropriate. Set label, name, value, required, details, and error on the field. For a range represented by two fields, validate that the end date isn't before the start date and put the error on the relevant field or group.
Anchor to Test the migrationTest the migration
- Select single dates and ranges, including incomplete ranges where the workflow allows them.
- For an old independent multi-date workflow, test the replacement control or redesigned task separately; don't serialize multiple dates into
s-date-picker. - Test before, after, specific-date, and weekday constraints at every boundary.
- Navigate months without changing the selected value.
- Load and submit dates in timezones ahead of and behind UTC, including daylight-saving transitions.
- Test incomplete ranges, form reset, validation errors, keyboard operation, and narrow layouts.
Anchor to Remove Polaris ReactRemove Polaris React
After every date workflow uses a date-only string model, remove DatePicker, Date-object adapters used only by the UI, and duplicated month/year state. Remove @shopify/polaris only after no other route in scope imports it.