Date Picker
A calendar-based picker supporting single date and date range modes. On mobile it renders in a bottom sheet; on desktop it uses a popover. Accepts Date objects, strings in multiple formats (dd/MM/yyyy, yyyy-MM-dd, etc.), or Unix timestamps.
Installation
1. Install the required shadcn primitives:
npx shadcn@latest add calendar popover sheet2. Copy the source code:
- Source:
packages/ui/src/common/data-input/dates/date-picker.tsx - Also copy:
date-input/anddate-range-input/sub-folders - Place in your project:
components/common/data-input/dates/
3. Install dependencies:
npm install react-day-picker date-fns4. Update the import paths to match your project structure.
Usage
import { DatePicker } from "@hoag/ui/date-picker";
export default function Demo() {
const [value, setValue] = React.useState();
return (
<DatePicker
mode="single"
label="Ngày sinh"
value={value}
onChange={(date, formatted) => {
setValue(date);
console.log(date, formatted);
}}
/>
);
}Default
const [value, setValue] = React.useState<Date | undefined>();
<DatePicker
mode="single"
label="Chọn ngày"
value={value}
onChange={(date) => setValue(date)}
/>;Date Range
Đặt mode="range" để cho phép chọn khoảng ngày. Dùng onRangeChange thay vì onChange.
const [range, setRange] = React.useState<DateRange | undefined>();
<DatePicker
mode="range"
label="Khoảng thời gian"
range={range}
onRangeChange={(nextRange) => setRange(nextRange)}
/>;With Initial Value
value chấp nhận Date, chuỗi (dd/MM/yyyy, yyyy-MM-dd, dd.MM.yyyy, ...) hoặc Unix timestamp (giây hoặc millisecond).
{
/* string format */
}
<DatePicker mode="single" label="Ngày sinh" value="15/06/1995" />;
{
/* Date object */
}
<DatePicker mode="single" label="Hôm nay" value={new Date()} />;
{
/* Unix timestamp (seconds) */
}
<DatePicker mode="single" value={1718438400} />;Range with Initial Value
<DatePicker
mode="range"
label="Khoảng thời gian"
range={{ from: "01/03/2026", to: "15/03/2026" }}
/>Required
<DatePicker mode="single" label="Ngày sinh" isRequired />With Error
Ngày không hợp lệ
<DatePicker
mode="single"
label="Ngày hết hạn"
error
helperText="Ngày không hợp lệ"
/>With Helper Text
Chọn ngày bắt đầu hợp đồng
<DatePicker
mode="single"
label="Ngày bắt đầu"
helperText="Chọn ngày bắt đầu hợp đồng"
/>Large Size
<DatePicker mode="single" label="Default size" />
<DatePicker mode="single" label="Large size" size="lg" />With Remove Icon
Dùng hasRemoveIcon để hiển thị nút xóa khi có giá trị.
<DatePicker
mode="single"
label="Ngày sinh"
value="15/06/1995"
hasRemoveIcon
onClearValue={() => console.log("cleared")}
/>Disabled
<DatePicker mode="single" label="Disabled" value="01/01/2026" disabled />API Reference
<DatePicker>
| Prop | Type | Default | Description |
|---|---|---|---|
mode | "single" | "range" | "single" | Calendar selection mode |
value | Date | string | number | — | Controlled value (single mode). Accepts Date, formatted string, or timestamp |
range | { from?: Date | string | number; to?: Date | string | number } | — | Controlled value (range mode) |
onChange | (date: Date | undefined, formatted?: string) => void | — | Callback on date select (single mode) |
onRangeChange | (range?: DateRange, formatted?: { from?: string; to?: string }) => void | — | Callback on range select (range mode) |
onApply | (range?: DateRange, formatted?: { from?: string; to?: string }) => void | — | Callback on Apply button click (range mode) |
onClearValue | () => void | — | Callback when clear/remove button is clicked |
label | string | — | Input label text |
isRequired | boolean | false | Show required asterisk (*) next to label |
size | "default" | "lg" | "default" | Input size variant |
error | boolean | false | Error state (red border + helperText in red) |
helperText | string | — | Helper / error text below the input |
helperTextClass | string | — | Custom CSS class for helper text |
disabled | boolean | false | Disable the picker |
minDate | Date | — | Minimum selectable date |
maxDate | Date | — | Maximum selectable date |
disabledDates | (date: Date) => boolean | — | Function to disable specific dates on the calendar |
hasRemoveIcon | boolean | false | Show remove/clear icon when a value is selected |
onBlur | React.FocusEventHandler<HTMLInputElement> | — | Blur event handler for the input |
onFocus | React.FocusEventHandler<HTMLInputElement> | — | Focus event handler for the input |
className | string | — | Custom CSS class for the trigger button |
Supported value formats
| Format | Example |
|---|---|
dd/MM/yyyy | 15/06/1995 |
d/M/yyyy | 1/6/1995 |
dd-MM-yyyy | 15-06-1995 |
dd.MM.yyyy | 15.06.1995 |
yyyy/MM/dd | 1995/06/15 |
yyyy-MM-dd | 1995-06-15 |
| Unix timestamp (ms) | 1718438400000 |
| Unix timestamp (s) | 1718438400 |