diff --git a/resources/js/components/ui/DateRangePicker/DateRangePicker.vue b/resources/js/components/ui/DateRangePicker/DateRangePicker.vue index 69e7a6370b..644bb30361 100644 --- a/resources/js/components/ui/DateRangePicker/DateRangePicker.vue +++ b/resources/js/components/ui/DateRangePicker/DateRangePicker.vue @@ -22,7 +22,6 @@ import { import Card from '../Card/Card.vue'; import Button from '../Button/Button.vue'; import Calendar from '../Calendar/Calendar.vue'; -import Icon from '../Icon/Icon.vue'; import { parseAbsoluteToLocal } from '@internationalized/date'; const emit = defineEmits(['update:modelValue']); @@ -32,7 +31,7 @@ const props = defineProps({ badge: { type: String, default: null }, required: { type: Boolean, default: false }, /** The controlled date range value with `start` and `end` properties.

Each should be an ISO 8601 date and time string with a UTC offset (eg. `2021-11-07T07:45:00Z` or `2021-11-07T07:45:00-07:00`) */ - modelValue: { type: [Object, String], default: null }, + modelValue: { type: [Object, String], required: true, default: () => ({start: null, end: null}) }, /** The minimum selectable date.

Should be an ISO 8601 date and time string with a UTC offset (eg. `2021-11-07T07:45:00Z` or `2021-11-07T07:45:00-07:00`) */ min: { type: [String, Object], default: null }, /** The maximum selectable date.

Should be an ISO 8601 date and time string with a UTC offset (eg. `2021-11-07T07:45:00Z` or `2021-11-07T07:45:00-07:00`) */ @@ -76,6 +75,12 @@ const placeholder = parseAbsoluteToLocal(new Date().toISOString()); const calendarEvents = computed(() => ({ 'update:model-value': (event) => { if (props.granularity === 'day') { + + // Avoid fatal error `Cannot set properties of undefined (setting 'hour')` + if (event.end == null) { + return + } + event.start.hour = 0; event.start.minute = 0; event.start.second = 0; @@ -90,6 +95,12 @@ const calendarEvents = computed(() => ({ emit('update:modelValue', event) }, })); + +const hasDates = computed(() => { + return calendarBindings.value.modelValue != null + && calendarBindings.value.modelValue.end != null + && calendarBindings.value.modelValue?.start != null +})
-
diff --git a/resources/js/stories/DateRangePicker.stories.ts b/resources/js/stories/DateRangePicker.stories.ts index cf0179a4b3..ff026f1bb7 100644 --- a/resources/js/stories/DateRangePicker.stories.ts +++ b/resources/js/stories/DateRangePicker.stories.ts @@ -12,10 +12,10 @@ const meta = { options: ['day', 'hour', 'minute', 'second'], }, 'update:modelValue': { - description: 'Event handler called when the date range value changes.

Returns an object with `start` and `end` properties, each as an ISO 8601 date and time string.', + description: 'Event handler called when the date range value changes.

Returns a range object with `start` and `end` values as `@internationalized/date` instances (e.g. `CalendarDate`, `CalendarDateTime`, `ZonedDateTime`) or `null` when the selection is cleared.', table: { category: 'events', - type: { summary: '(value: { start: string, end: string }) => void' } + type: { summary: '(value: { start: DateValue | null; end: DateValue | null } | null) => void' } } } }, @@ -71,6 +71,27 @@ export const _MinMax: Story = { }), }; +const granularityDayCode = ` + +`; + +export const _GranularityDay: Story = { + tags: ['!dev'], + parameters: { + docs: { + source: { code: granularityDayCode } + } + }, + render: () => ({ + components: { DateRangePicker }, + setup() { + const range = ref({start: null, end: null}); + return { range }; + }, + template: granularityDayCode, + }), +}; + const inlineCode = ` `; @@ -85,7 +106,7 @@ export const _Inline: Story = { render: () => ({ components: { DateRangePicker }, setup() { - const range = ref(null); + const range = ref({start: null, end: null}); return { range }; }, template: inlineCode, diff --git a/resources/js/stories/docs/DateRangePicker.mdx b/resources/js/stories/docs/DateRangePicker.mdx index 230fafeb32..105694aa27 100644 --- a/resources/js/stories/docs/DateRangePicker.mdx +++ b/resources/js/stories/docs/DateRangePicker.mdx @@ -11,6 +11,10 @@ A date range picker component for selecting a start and end date. Perfect for ca Restrict selectable dates using the `min` and `max` props. +## Granularity +The granularity of the date range picker. Options: `day`, `hour`, `minute`, `second` + + ## Inline Display the calendar inline instead of in a popover.