Skip to main content
Migrate to Polaris

Version 2025-07 is the last API version to support React-based UI components. Later versions use web components, native UI elements with built-in accessibility, better performance, and consistent styling with Shopify's design system. Check out the migration guide to upgrade your extension.

DateField

The DateField component combines a text input with a DatePicker dropdown, giving merchants a compact way to select a single date. It supports common form field props (label, error, and change handlers) along with calendar navigation controls.

For multi-date or range selection, use DatePicker directly.

Support
Targets (46)

Supported targets


Props for the DateField component, which combines a text input with a calendar picker for date selection. Text input props (like label, value, onChange, and error) come from TextFieldProps, while calendar navigation props (like yearMonth, disabled, and onYearMonthChange) come from DatePickerProps.

Anchor to label
label
string
required

The text content to display as the field's label. This label is always required for accessibility as it tells users what information the field expects. The label is rendered visually above the field.

Anchor to defaultYearMonth
defaultYearMonth
{year: ; month: } |

The year and month to display when the calendar first renders. Use this for an uncontrolled calendar that manages its own navigation state. This prop is ignored when yearMonth is set (controlled mode).

Accepts either an object ({ year, month }) or a YYYY-MM string.

Anchor to disabled
disabled
| [] | boolean

The dates that the user can't select.

  • DateString: Disables a specific date, such as '2024-12-25'.
  • Range: Disables a span of dates between start and end. Omit start or end for an open-ended range.
  • Day: Disables every occurrence of a weekday, such as 'Sunday'.
  • Disabled[]: An array combining any of the above.
  • true: Disables the entire date picker.
Anchor to error
error
string

An error message to display below the field. When set, the field receives a specific stylistic treatment (typically a red border) to communicate problems that have to be resolved immediately. The string value is displayed as the error message.

Pass undefined or omit this prop to clear the error state.

string

A unique identifier for the field.

string

An identifier for the field that is unique within the nearest containing Form component.

Anchor to onBlur
onBlur
() => void

A callback fired when the field loses focus. This is useful for triggering validation after the user finishes interacting with the field, or for tracking which fields have been "touched" in a form.

Anchor to onChange
onChange
(value: string) => void

A callback that fires when the user finishes editing the field, typically on blur. Only fires if the value changed. Update your state in this callback and pass the new value back through the value prop.

This doesn't fire on every keystroke. Use onInput for real-time responses like clearing validation errors as the user types. Don't use onInput to control value because that can cause issues on lower-powered devices due to asynchronous rendering.

Anchor to onFocus
onFocus
() => void

A callback fired when the field receives focus. This is useful for clearing errors, showing helper text, or tracking user interaction with form fields.

Anchor to onInput
onInput
(value: string) => void

A callback that fires on every change the user makes in the field, including each keystroke. The callback receives the current value.

Use onInput for immediate responses like clearing validation errors as the user types. Don't use it to control the field's value prop. Use onChange for that instead.

Anchor to onYearMonthChange
onYearMonthChange
(yearMonth: { year: number; month: number; }) => void

A callback that fires when the user navigates to a different month or year (for example, by pressing the forward/back arrows). Receives an object with year and month properties. When using controlled navigation (yearMonth is set), you must update your state and pass the new value back through the yearMonth prop.

Anchor to readOnly
readOnly
boolean
Default: false

Whether the field is read-only. Unlike disabled, a read-only field can still receive focus and its value is included when the form is submitted. Use this when the value should be visible and selectable but not editable, such as a computed total.

Anchor to value
value
T

The current value for the field. If omitted, then the field will be empty. You should update this value in response to the onChange callback.

Anchor to yearMonth
yearMonth
{year: ; month: } |

The year and month currently displayed in the calendar. Use this prop together with onYearMonthChange to control which month the user sees. When set, the calendar won't navigate on its own. You must update this value in response to onYearMonthChange to let the user browse months.

Accepts either an object ({ year, month }) or a YYYY-MM string.


Anchor to Schedule product launch dateSchedule product launch date

Schedule a product launch date and save it from an action modal. This example uses DateField to capture the date, with a Button that schedules the launch.

Schedule product launch date

Schedule a product launch date and save it from an action modal. This example uses `DateField` to capture the date, with a [Button](/docs/api/admin-extensions/2025-07/ui-components/actions/button) that schedules the launch.

Schedule product launch date

import {useState} from 'react';
import {reactExtension, useApi, DateField, Button, BlockStack} from '@shopify/ui-extensions-react/admin';

function App() {
const {data, close} = useApi('admin.product-details.action.render');
const productId = data.selected[0]?.id;
const [date, setDate] = useState('');

return (
<BlockStack>
<DateField
label="Product launch date"
name="launchDate"
value={date}
onChange={setDate}
/>
<Button
variant="primary"
onPress={async () => {
await fetch('/api/products/launch-date', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({productId, launchDate: date}),
});
close();
}}
>
Schedule launch
</Button>
</BlockStack>
);
}

export default reactExtension(
'admin.product-details.action.render',
() => <App />,
);
import {extension, DateField, Button, BlockStack} from '@shopify/ui-extensions/admin';

export default extension(
'admin.product-details.action.render',
(root, api) => {
const {data, close} = api;
const productId = data.selected[0]?.id;
let launchDate = '';

const stack = root.createComponent(BlockStack);

const field = root.createComponent(DateField, {
label: 'Product launch date',
name: 'launchDate',
onChange: (value) => {
launchDate = value;
},
});

const saveButton = root.createComponent(
Button,
{
variant: 'primary',
onPress: async () => {
await fetch('/api/products/launch-date', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({productId, launchDate}),
});
close();
},
},
'Schedule launch',
);

stack.appendChild(field);
stack.appendChild(saveButton);
root.appendChild(stack);
},
);

Anchor to Validate future date selectionValidate future date selection

Validate that a selected date is in the future using the error prop. This example checks the expiration date against today's date on each change and displays an inline error for past dates, so merchants can only set valid expiry windows.

Validate future date selection

import {useState} from 'react';
import {reactExtension, useApi, DateField, Button, BlockStack, Text} from '@shopify/ui-extensions-react/admin';

function App() {
const {data, close} = useApi('admin.product-details.action.render');
const productId = data.selected[0]?.id;
const [date, setDate] = useState('');
const [error, setError] = useState(undefined);

return (
<BlockStack>
<Text fontWeight="bold">Product expiry</Text>
<DateField
label="Expiration date"
name="expiryDate"
value={date}
error={error}
onChange={(value) => {
setDate(value);
const selected = new Date(value);
const today = new Date();
setError(
selected <= today ? 'Expiry date must be in the future' : undefined,
);
}}
/>
<Button
variant="primary"
onPress={async () => {
if (date) {
await fetch('/api/products/expiry', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({productId, expiryDate: date}),
});
close();
}
}}
>
Set expiry date
</Button>
</BlockStack>
);
}

export default reactExtension(
'admin.product-details.action.render',
() => <App />,
);
import {extension, DateField, Button, BlockStack, Text} from '@shopify/ui-extensions/admin';

export default extension(
'admin.product-details.action.render',
(root, api) => {
const {data, close} = api;
const productId = data.selected[0]?.id;
let expiryDate = '';

const stack = root.createComponent(BlockStack);

const heading = root.createComponent(
Text,
{fontWeight: 'bold'},
'Product expiry',
);

const field = root.createComponent(DateField, {
label: 'Expiration date',
name: 'expiryDate',
onChange: (value) => {
expiryDate = value;
const selected = new Date(value);
const today = new Date();
if (selected <= today) {
field.updateProps({error: 'Expiry date must be in the future'});
} else {
field.updateProps({error: undefined});
}
},
});

const saveButton = root.createComponent(
Button,
{
variant: 'primary',
onPress: async () => {
if (expiryDate) {
await fetch('/api/products/expiry', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({productId, expiryDate}),
});
close();
}
},
},
'Set expiry date',
);

stack.appendChild(heading);
stack.appendChild(field);
stack.appendChild(saveButton);
root.appendChild(stack);
},
);

Anchor to Display read-only date referencesDisplay read-only date references

Display historical dates as read-only reference fields using the readOnly prop. This example shows the product creation date and last warehouse sync date as non-editable fields, providing merchants with timeline context in a block extension.

Display read-only date references

import {reactExtension, DateField, BlockStack, Text} from '@shopify/ui-extensions-react/admin';

function App() {

return (
<BlockStack>
<Text fontWeight="bold">Important dates</Text>
<DateField label="Date created" name="dateCreated" value="2024-01-15" readOnly />
<DateField label="Last warehouse sync" name="lastSync" value="2024-03-20" readOnly />
</BlockStack>
);
}

export default reactExtension(
'admin.product-details.block.render',
() => <App />,
);
import {extension, DateField, BlockStack, Text} from '@shopify/ui-extensions/admin';

export default extension(
'admin.product-details.block.render',
(root) => {

const stack = root.createComponent(BlockStack);

const heading = root.createComponent(
Text,
{fontWeight: 'bold'},
'Important dates',
);

const createdField = root.createComponent(DateField, {
label: 'Date created',
name: 'dateCreated',
value: '2024-01-15',
readOnly: true,
});

const lastSyncField = root.createComponent(DateField, {
label: 'Last warehouse sync',
name: 'lastSync',
value: '2024-03-20',
readOnly: true,
});

stack.appendChild(heading);
stack.appendChild(createdField);
stack.appendChild(lastSyncField);
root.appendChild(stack);
},
);

  • Use DateField for single-date selection in forms: DateField combines the familiar text input pattern with a calendar dropdown, making it ideal for form layouts where space is limited.
  • Write a clear label: The required label prop tells merchants what date to select. Use specific labels like "Start date", "Ship by date", or "Event date".

  • The text input portion of DateField expects dates in YYYY-MM-DD format. Other date formats entered manually might not be parsed correctly.
  • DateField doesn't support time selection. If you need date and time, you must combine DateField with a separate time input.

Was this page helpful?