reka-ui 2.8.0 → 2.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Calendar/CalendarCellTrigger.cjs +4 -1
- package/dist/Calendar/CalendarCellTrigger.cjs.map +1 -1
- package/dist/Calendar/CalendarCellTrigger.js +4 -1
- package/dist/Calendar/CalendarCellTrigger.js.map +1 -1
- package/dist/Calendar/CalendarRoot.cjs +12 -7
- package/dist/Calendar/CalendarRoot.cjs.map +1 -1
- package/dist/Calendar/CalendarRoot.js +13 -8
- package/dist/Calendar/CalendarRoot.js.map +1 -1
- package/dist/Calendar/useCalendar.cjs +32 -2
- package/dist/Calendar/useCalendar.cjs.map +1 -1
- package/dist/Calendar/useCalendar.js +33 -3
- package/dist/Calendar/useCalendar.js.map +1 -1
- package/dist/Combobox/ComboboxContentImpl.cjs +2 -1
- package/dist/Combobox/ComboboxContentImpl.cjs.map +1 -1
- package/dist/Combobox/ComboboxContentImpl.js +2 -1
- package/dist/Combobox/ComboboxContentImpl.js.map +1 -1
- package/dist/DatePicker/DatePickerRoot.cjs +4 -3
- package/dist/DatePicker/DatePickerRoot.cjs.map +1 -1
- package/dist/DatePicker/DatePickerRoot.js +4 -3
- package/dist/DatePicker/DatePickerRoot.js.map +1 -1
- package/dist/DateRangePicker/DateRangePickerRoot.cjs +4 -3
- package/dist/DateRangePicker/DateRangePickerRoot.cjs.map +1 -1
- package/dist/DateRangePicker/DateRangePickerRoot.js +5 -4
- package/dist/DateRangePicker/DateRangePickerRoot.js.map +1 -1
- package/dist/RangeCalendar/RangeCalendarCellTrigger.cjs +8 -2
- package/dist/RangeCalendar/RangeCalendarCellTrigger.cjs.map +1 -1
- package/dist/RangeCalendar/RangeCalendarCellTrigger.js +8 -2
- package/dist/RangeCalendar/RangeCalendarCellTrigger.js.map +1 -1
- package/dist/RangeCalendar/RangeCalendarGrid.cjs +2 -1
- package/dist/RangeCalendar/RangeCalendarGrid.cjs.map +1 -1
- package/dist/RangeCalendar/RangeCalendarGrid.js +2 -1
- package/dist/RangeCalendar/RangeCalendarGrid.js.map +1 -1
- package/dist/RangeCalendar/RangeCalendarRoot.cjs +30 -16
- package/dist/RangeCalendar/RangeCalendarRoot.cjs.map +1 -1
- package/dist/RangeCalendar/RangeCalendarRoot.js +31 -17
- package/dist/RangeCalendar/RangeCalendarRoot.js.map +1 -1
- package/dist/RangeCalendar/useRangeCalendar.cjs +41 -8
- package/dist/RangeCalendar/useRangeCalendar.cjs.map +1 -1
- package/dist/RangeCalendar/useRangeCalendar.js +41 -8
- package/dist/RangeCalendar/useRangeCalendar.js.map +1 -1
- package/dist/constant.d.cts.map +1 -1
- package/dist/date/calendar.cjs +29 -9
- package/dist/date/calendar.cjs.map +1 -1
- package/dist/date/calendar.js +25 -11
- package/dist/date/calendar.js.map +1 -1
- package/dist/date/useDateField.cjs +1 -1
- package/dist/date/useDateField.cjs.map +1 -1
- package/dist/date/useDateField.js +1 -1
- package/dist/date/useDateField.js.map +1 -1
- package/dist/date.cjs +1 -0
- package/dist/date.d.cts +2 -2
- package/dist/date.d.ts +2 -2
- package/dist/date.js +2 -2
- package/dist/index.d.cts +841 -836
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +804 -799
- package/dist/index.d.ts.map +1 -1
- package/dist/index2.d.cts +9 -2
- package/dist/index2.d.cts.map +1 -1
- package/dist/index2.d.ts +9 -2
- package/dist/index2.d.ts.map +1 -1
- package/dist/shared/useForwardExpose.cjs +1 -1
- package/dist/shared/useForwardExpose.cjs.map +1 -1
- package/dist/shared/useForwardExpose.js +1 -1
- package/dist/shared/useForwardExpose.js.map +1 -1
- package/package.json +16 -12
- package/src/Calendar/CalendarCellTrigger.vue +8 -1
- package/src/Calendar/CalendarRoot.vue +19 -7
- package/src/Calendar/useCalendar.ts +43 -3
- package/src/Combobox/ComboboxContentImpl.vue +1 -0
- package/src/DatePicker/DatePickerRoot.vue +4 -4
- package/src/DateRangePicker/DateRangePickerRoot.vue +5 -5
- package/src/RadioGroup/RadioGroupRoot.vue +1 -1
- package/src/RangeCalendar/RangeCalendarCellTrigger.vue +13 -3
- package/src/RangeCalendar/RangeCalendarGrid.vue +1 -0
- package/src/RangeCalendar/RangeCalendarRoot.vue +46 -30
- package/src/RangeCalendar/useRangeCalendar.ts +43 -15
- package/src/date/calendar.ts +42 -18
- package/src/shared/date/useDateField.ts +3 -1
- package/src/shared/useForwardExpose.ts +1 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { DateValue } from '@internationalized/date'
|
|
3
3
|
import type { Ref } from 'vue'
|
|
4
|
-
import type { Grid, Matcher, WeekDayFormat } from '@/date'
|
|
4
|
+
import type { Grid, Matcher, WeekDayFormat, WeekStartsOn } from '@/date'
|
|
5
5
|
import type { PrimitiveProps } from '@/Primitive'
|
|
6
6
|
import type { Formatter } from '@/shared'
|
|
7
7
|
import type { DateRange } from '@/shared/date'
|
|
8
8
|
import type { Direction } from '@/shared/types'
|
|
9
9
|
import { isEqualDay } from '@internationalized/date'
|
|
10
10
|
import { useCalendar } from '@/Calendar/useCalendar'
|
|
11
|
-
import { isBefore } from '@/date'
|
|
11
|
+
import { getWeekStartsOn, isBefore } from '@/date'
|
|
12
12
|
import {
|
|
13
13
|
createContext,
|
|
14
14
|
useDirection,
|
|
@@ -28,7 +28,7 @@ type RangeCalendarRootContext = {
|
|
|
28
28
|
preventDeselect: Ref<boolean>
|
|
29
29
|
grid: Ref<Grid<DateValue>[]>
|
|
30
30
|
weekDays: Ref<string[]>
|
|
31
|
-
weekStartsOn: Ref<
|
|
31
|
+
weekStartsOn: Ref<WeekStartsOn>
|
|
32
32
|
weekdayFormat: Ref<WeekDayFormat>
|
|
33
33
|
fixedWeeks: Ref<boolean>
|
|
34
34
|
numberOfMonths: Ref<number>
|
|
@@ -68,6 +68,11 @@ type RangeCalendarRootContext = {
|
|
|
68
68
|
maximumDays: Ref<number | undefined>
|
|
69
69
|
minValue: Ref<DateValue | undefined>
|
|
70
70
|
maxValue: Ref<DateValue | undefined>
|
|
71
|
+
isPlaceholderFocusable: Ref<boolean>
|
|
72
|
+
firstFocusableDate: Ref<DateValue | undefined>
|
|
73
|
+
hasSelectedDate: Ref<boolean>
|
|
74
|
+
isSelectedDisabled: Ref<boolean>
|
|
75
|
+
selectedFocusableDate: Ref<DateValue | undefined>
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
export interface RangeCalendarRootProps extends PrimitiveProps {
|
|
@@ -88,7 +93,7 @@ export interface RangeCalendarRootProps extends PrimitiveProps {
|
|
|
88
93
|
/** The maximum number of days that can be selected in a range */
|
|
89
94
|
maximumDays?: number
|
|
90
95
|
/** The day of the week to start the calendar on */
|
|
91
|
-
weekStartsOn?:
|
|
96
|
+
weekStartsOn?: WeekStartsOn
|
|
92
97
|
/** The format to use for the weekday strings provided via the weekdays slot prop */
|
|
93
98
|
weekdayFormat?: WeekDayFormat
|
|
94
99
|
/** The accessible label for the calendar */
|
|
@@ -145,7 +150,7 @@ export const [injectRangeCalendarRootContext, provideRangeCalendarRootContext]
|
|
|
145
150
|
|
|
146
151
|
<script setup lang="ts">
|
|
147
152
|
import { useEventListener, useVModel } from '@vueuse/core'
|
|
148
|
-
import { onMounted, ref, toRefs, watch } from 'vue'
|
|
153
|
+
import { computed, onMounted, ref, toRefs, watch } from 'vue'
|
|
149
154
|
import { Primitive, usePrimitiveElement } from '@/Primitive'
|
|
150
155
|
|
|
151
156
|
const props = withDefaults(defineProps<RangeCalendarRootProps>(), {
|
|
@@ -153,7 +158,6 @@ const props = withDefaults(defineProps<RangeCalendarRootProps>(), {
|
|
|
153
158
|
as: 'div',
|
|
154
159
|
pagedNavigation: false,
|
|
155
160
|
preventDeselect: false,
|
|
156
|
-
weekStartsOn: 0,
|
|
157
161
|
weekdayFormat: 'narrow',
|
|
158
162
|
fixedWeeks: false,
|
|
159
163
|
numberOfMonths: 1,
|
|
@@ -167,6 +171,7 @@ const props = withDefaults(defineProps<RangeCalendarRootProps>(), {
|
|
|
167
171
|
allowNonContiguousRanges: false,
|
|
168
172
|
maximumDays: undefined,
|
|
169
173
|
disableDaysOutsideCurrentView: false,
|
|
174
|
+
|
|
170
175
|
})
|
|
171
176
|
const emits = defineEmits<RangeCalendarRootEmits>()
|
|
172
177
|
|
|
@@ -179,7 +184,7 @@ defineSlots<{
|
|
|
179
184
|
/** The days of the week */
|
|
180
185
|
weekDays: string[]
|
|
181
186
|
/** The start of the week */
|
|
182
|
-
weekStartsOn:
|
|
187
|
+
weekStartsOn: WeekStartsOn
|
|
183
188
|
/** The calendar locale */
|
|
184
189
|
locale: string
|
|
185
190
|
/** Whether or not to always display 6 weeks in the calendar */
|
|
@@ -194,7 +199,6 @@ const {
|
|
|
194
199
|
readonly,
|
|
195
200
|
initialFocus,
|
|
196
201
|
pagedNavigation,
|
|
197
|
-
weekStartsOn,
|
|
198
202
|
weekdayFormat,
|
|
199
203
|
fixedWeeks,
|
|
200
204
|
numberOfMonths,
|
|
@@ -219,6 +223,7 @@ const { primitiveElement, currentElement: parentElement }
|
|
|
219
223
|
= usePrimitiveElement()
|
|
220
224
|
const dir = useDirection(propDir)
|
|
221
225
|
const locale = useLocale(propLocale)
|
|
226
|
+
const weekStartsOn = computed(() => props.weekStartsOn ?? getWeekStartsOn(locale.value))
|
|
222
227
|
|
|
223
228
|
const lastPressedDateValue = ref() as Ref<DateValue | undefined>
|
|
224
229
|
const focusedValue = ref() as Ref<DateValue | undefined>
|
|
@@ -227,9 +232,12 @@ const isEditing = ref(false)
|
|
|
227
232
|
const modelValue = useVModel(props, 'modelValue', emits, {
|
|
228
233
|
defaultValue: props.defaultValue ?? { start: undefined, end: undefined },
|
|
229
234
|
passive: (props.modelValue === undefined) as false,
|
|
230
|
-
}) as Ref<DateRange>
|
|
235
|
+
}) as Ref<DateRange | null>
|
|
236
|
+
|
|
237
|
+
const normalizeRange = (value?: DateRange | null): DateRange => value ?? { start: undefined, end: undefined }
|
|
238
|
+
const normalizedModelValue = computed(() => normalizeRange(modelValue.value))
|
|
231
239
|
|
|
232
|
-
const validModelValue = ref(modelValue.value) as Ref<DateRange>
|
|
240
|
+
const validModelValue = ref(normalizeRange(modelValue.value)) as Ref<DateRange>
|
|
233
241
|
|
|
234
242
|
watch(validModelValue, (value) => {
|
|
235
243
|
emits('update:validModelValue', value)
|
|
@@ -237,14 +245,14 @@ watch(validModelValue, (value) => {
|
|
|
237
245
|
|
|
238
246
|
const defaultDate = getDefaultDate({
|
|
239
247
|
defaultPlaceholder: props.placeholder,
|
|
240
|
-
defaultValue: modelValue.value.start,
|
|
248
|
+
defaultValue: normalizeRange(modelValue.value).start,
|
|
241
249
|
locale: props.locale,
|
|
242
250
|
})
|
|
243
251
|
|
|
244
|
-
const startValue = ref(modelValue.value.start) as Ref<
|
|
252
|
+
const startValue = ref(normalizeRange(modelValue.value).start) as Ref<
|
|
245
253
|
DateValue | undefined
|
|
246
254
|
>
|
|
247
|
-
const endValue = ref(modelValue.value.end) as Ref<DateValue | undefined>
|
|
255
|
+
const endValue = ref(normalizeRange(modelValue.value).end) as Ref<DateValue | undefined>
|
|
248
256
|
|
|
249
257
|
const placeholder = useVModel(props, 'placeholder', emits, {
|
|
250
258
|
defaultValue: props.defaultPlaceholder ?? defaultDate.copy(),
|
|
@@ -268,6 +276,8 @@ const {
|
|
|
268
276
|
nextPage,
|
|
269
277
|
prevPage,
|
|
270
278
|
formatter,
|
|
279
|
+
isPlaceholderFocusable,
|
|
280
|
+
firstFocusableDate,
|
|
271
281
|
} = useCalendar({
|
|
272
282
|
locale,
|
|
273
283
|
placeholder,
|
|
@@ -296,6 +306,9 @@ const {
|
|
|
296
306
|
isHighlightedStart,
|
|
297
307
|
isHighlightedEnd,
|
|
298
308
|
isDateDisabled: rangeIsDateDisabled,
|
|
309
|
+
hasSelectedDate,
|
|
310
|
+
isSelectedDisabled,
|
|
311
|
+
selectedFocusableDate,
|
|
299
312
|
} = useRangeCalendarState({
|
|
300
313
|
start: startValue,
|
|
301
314
|
end: endValue,
|
|
@@ -308,23 +321,21 @@ const {
|
|
|
308
321
|
maximumDays,
|
|
309
322
|
})
|
|
310
323
|
|
|
311
|
-
watch(modelValue, (_modelValue
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
||
|
|
316
|
-
|
|
317
|
-
) {
|
|
318
|
-
startValue.value =
|
|
324
|
+
watch(modelValue, (_modelValue) => {
|
|
325
|
+
const next = normalizeRange(_modelValue)
|
|
326
|
+
|
|
327
|
+
const isStartSynced = (!next.start && !startValue.value)
|
|
328
|
+
|| (!!next.start && !!startValue.value && isEqualDay(next.start, startValue.value))
|
|
329
|
+
|
|
330
|
+
if (!isStartSynced) {
|
|
331
|
+
startValue.value = next.start?.copy?.()
|
|
319
332
|
}
|
|
320
333
|
|
|
321
|
-
|
|
322
|
-
(
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
) {
|
|
327
|
-
endValue.value = _modelValue?.end?.copy?.()
|
|
334
|
+
const isEndSynced = (!next.end && !endValue.value)
|
|
335
|
+
|| (!!next.end && !!endValue.value && isEqualDay(next.end, endValue.value))
|
|
336
|
+
|
|
337
|
+
if (!isEndSynced) {
|
|
338
|
+
endValue.value = next.end?.copy?.()
|
|
328
339
|
}
|
|
329
340
|
})
|
|
330
341
|
|
|
@@ -382,7 +393,7 @@ provideRangeCalendarRootContext({
|
|
|
382
393
|
startValue,
|
|
383
394
|
endValue,
|
|
384
395
|
formatter,
|
|
385
|
-
modelValue,
|
|
396
|
+
modelValue: normalizedModelValue,
|
|
386
397
|
placeholder,
|
|
387
398
|
disabled,
|
|
388
399
|
initialFocus,
|
|
@@ -422,6 +433,11 @@ provideRangeCalendarRootContext({
|
|
|
422
433
|
maximumDays,
|
|
423
434
|
minValue,
|
|
424
435
|
maxValue,
|
|
436
|
+
isPlaceholderFocusable,
|
|
437
|
+
firstFocusableDate,
|
|
438
|
+
hasSelectedDate,
|
|
439
|
+
isSelectedDisabled,
|
|
440
|
+
selectedFocusableDate,
|
|
425
441
|
})
|
|
426
442
|
|
|
427
443
|
onMounted(() => {
|
|
@@ -470,7 +486,7 @@ onMounted(() => {
|
|
|
470
486
|
:week-starts-on="weekStartsOn"
|
|
471
487
|
:locale="locale"
|
|
472
488
|
:fixed-weeks="fixedWeeks"
|
|
473
|
-
:model-value="
|
|
489
|
+
:model-value="normalizedModelValue"
|
|
474
490
|
/>
|
|
475
491
|
</Primitive>
|
|
476
492
|
</template>
|
|
@@ -41,7 +41,7 @@ export function useRangeCalendarState(props: UseRangeCalendarProps) {
|
|
|
41
41
|
const isInvalid = computed(
|
|
42
42
|
() => {
|
|
43
43
|
if (isStartInvalid.value || isEndInvalid.value)
|
|
44
|
-
return
|
|
44
|
+
return true
|
|
45
45
|
if (props.start.value && props.end.value && isBefore(props.end.value, props.start.value))
|
|
46
46
|
return true
|
|
47
47
|
return false
|
|
@@ -71,12 +71,10 @@ export function useRangeCalendarState(props: UseRangeCalendarProps) {
|
|
|
71
71
|
return false
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
// Check if a date exceeds maximum days limit from the start date
|
|
75
74
|
const rangeIsDateDisabled = (date: DateValue) => {
|
|
76
75
|
if (props.isDateDisabled(date))
|
|
77
76
|
return true
|
|
78
77
|
|
|
79
|
-
// Check if exceeds maximum days limit
|
|
80
78
|
if (props.maximumDays?.value) {
|
|
81
79
|
if (props.start.value && props.end.value) {
|
|
82
80
|
if (props.fixedDate.value) {
|
|
@@ -97,9 +95,6 @@ export function useRangeCalendarState(props: UseRangeCalendarProps) {
|
|
|
97
95
|
}
|
|
98
96
|
}
|
|
99
97
|
|
|
100
|
-
if (!props.start.value || props.end.value || isSameDay(props.start.value, date))
|
|
101
|
-
return false
|
|
102
|
-
|
|
103
98
|
return false
|
|
104
99
|
}
|
|
105
100
|
|
|
@@ -126,17 +121,17 @@ export function useRangeCalendarState(props: UseRangeCalendarProps) {
|
|
|
126
121
|
}
|
|
127
122
|
}
|
|
128
123
|
|
|
129
|
-
// If maximum days is set and the range exceeds it, limit the highlight
|
|
130
|
-
// We only apply this when we're in the middle of a selection (no end date yet)
|
|
131
124
|
if (props.maximumDays?.value && !props.end.value) {
|
|
132
|
-
|
|
133
|
-
const
|
|
134
|
-
? start.add({ days: props.maximumDays.value - 1 })
|
|
135
|
-
: start.subtract({ days: props.maximumDays.value })
|
|
125
|
+
const maximumDays = props.maximumDays.value
|
|
126
|
+
const anchor = props.start.value
|
|
136
127
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
end:
|
|
128
|
+
if (isStartBeforeFocused) {
|
|
129
|
+
const maxEnd = anchor.add({ days: maximumDays - 1 })
|
|
130
|
+
return { start: anchor, end: maxEnd }
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
const minStart = anchor.subtract({ days: maximumDays - 1 })
|
|
134
|
+
return { start: minStart, end: anchor }
|
|
140
135
|
}
|
|
141
136
|
}
|
|
142
137
|
|
|
@@ -162,6 +157,36 @@ export function useRangeCalendarState(props: UseRangeCalendarProps) {
|
|
|
162
157
|
return isSameDay(highlightedRange.value.end, date)
|
|
163
158
|
}
|
|
164
159
|
|
|
160
|
+
const hasSelectedDate = computed(() => {
|
|
161
|
+
return !!(props.start.value || props.end.value)
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
const isStartDateDisabled = computed(() => {
|
|
165
|
+
return !!(props.start.value && props.isDateDisabled(props.start.value))
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
const isEndDateDisabled = computed(() => {
|
|
169
|
+
return !!(props.end.value && props.isDateDisabled(props.end.value))
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
const isSelectedDisabled = computed(() => {
|
|
173
|
+
const hasStart = !!props.start.value
|
|
174
|
+
const hasEnd = !!props.end.value
|
|
175
|
+
if (!hasStart && !hasEnd)
|
|
176
|
+
return false
|
|
177
|
+
if (hasStart && hasEnd)
|
|
178
|
+
return isStartDateDisabled.value && isEndDateDisabled.value
|
|
179
|
+
return (hasStart && isStartDateDisabled.value) || (hasEnd && isEndDateDisabled.value)
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
const selectedFocusableDate = computed(() => {
|
|
183
|
+
if (props.start.value && !isStartDateDisabled.value)
|
|
184
|
+
return props.start.value
|
|
185
|
+
if (props.end.value && !isEndDateDisabled.value)
|
|
186
|
+
return props.end.value
|
|
187
|
+
return undefined
|
|
188
|
+
})
|
|
189
|
+
|
|
165
190
|
return {
|
|
166
191
|
isInvalid,
|
|
167
192
|
isSelected,
|
|
@@ -172,5 +197,8 @@ export function useRangeCalendarState(props: UseRangeCalendarProps) {
|
|
|
172
197
|
isHighlightedStart,
|
|
173
198
|
isHighlightedEnd,
|
|
174
199
|
isDateDisabled: rangeIsDateDisabled,
|
|
200
|
+
hasSelectedDate,
|
|
201
|
+
isSelectedDisabled,
|
|
202
|
+
selectedFocusableDate,
|
|
175
203
|
}
|
|
176
204
|
}
|
package/src/date/calendar.ts
CHANGED
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
import type { DateValue, DayOfWeek } from '@internationalized/date'
|
|
6
6
|
import type { Grid } from './types'
|
|
7
7
|
import type { DateRange } from '@/shared'
|
|
8
|
-
import { CalendarDate, endOfMonth, endOfYear, getDayOfWeek, startOfMonth, startOfYear } from '@internationalized/date'
|
|
8
|
+
import { CalendarDate, endOfMonth, endOfYear, getDayOfWeek, startOfMonth, startOfWeek, startOfYear } from '@internationalized/date'
|
|
9
9
|
import { getDaysInMonth, getLastFirstDayOfWeek, getNextLastDayOfWeek } from './comparators'
|
|
10
10
|
import { chunk } from './utils'
|
|
11
11
|
|
|
12
12
|
export type WeekDayFormat = 'narrow' | 'short' | 'long'
|
|
13
13
|
|
|
14
|
+
export type WeekStartsOn = 0 | 1 | 2 | 3 | 4 | 5 | 6
|
|
15
|
+
|
|
14
16
|
export type CreateSelectProps = {
|
|
15
17
|
/**
|
|
16
18
|
* The date object representing the date (usually the first day of the month/year).
|
|
@@ -27,7 +29,7 @@ export type CreateMonthProps = {
|
|
|
27
29
|
/**
|
|
28
30
|
* The day of the week to start the calendar on (0 for Sunday, 1 for Monday, etc.).
|
|
29
31
|
*/
|
|
30
|
-
weekStartsOn:
|
|
32
|
+
weekStartsOn: WeekStartsOn
|
|
31
33
|
|
|
32
34
|
/**
|
|
33
35
|
* Whether to always render 6 weeks in the calendar, even if the month doesn't
|
|
@@ -219,24 +221,46 @@ export function createDateRange({ start, end }: DateRange): DateValue[] {
|
|
|
219
221
|
return dates
|
|
220
222
|
}
|
|
221
223
|
|
|
224
|
+
/**
|
|
225
|
+
* It's better to use `getWeekStart` from `@internationalized/date`,
|
|
226
|
+
* but sadly it is not yet exported from the package.
|
|
227
|
+
* And the `Intl.Locale` API is not supported well enough yet.
|
|
228
|
+
*/
|
|
229
|
+
export function getWeekStartsOn(locale: string): WeekStartsOn {
|
|
230
|
+
// Jan 6, 2025 is a Monday (ISO day = 1)
|
|
231
|
+
const monday = new CalendarDate(2025, 1, 6)
|
|
232
|
+
const dayOfWeek = getDayOfWeek(monday, locale)
|
|
233
|
+
// dayOfWeek tells us Monday's position in the locale's week (0-indexed)
|
|
234
|
+
// If Monday is position 0 → week starts Monday (1)
|
|
235
|
+
// If Monday is position 1 → week starts Sunday (0)
|
|
236
|
+
return (1 - dayOfWeek + 7) % 7 as WeekStartsOn
|
|
237
|
+
}
|
|
238
|
+
|
|
222
239
|
/**
|
|
223
240
|
* Returns the locale-specific week number
|
|
224
241
|
*/
|
|
225
242
|
export function getWeekNumber(date: DateValue, locale: string = 'en-US', firstDayOfWeek?: DayOfWeek): number {
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
243
|
+
const jan1 = new CalendarDate(date.year, 1, 1)
|
|
244
|
+
|
|
245
|
+
// Detect ISO locale by comparing JS day of week with locale day of week
|
|
246
|
+
const usesISOWeek = jan1.toDate('UTC').getUTCDay() !== getDayOfWeek(jan1, locale)
|
|
247
|
+
const weekStartsOn = firstDayOfWeek ?? (usesISOWeek ? 'mon' : 'sun')
|
|
248
|
+
const firstWeekContainsDate = usesISOWeek ? 4 : 1
|
|
249
|
+
|
|
250
|
+
// Find the "deciding day" - its year determines which year's week numbering to use
|
|
251
|
+
const dayOfWeek = getDayOfWeek(date, locale, weekStartsOn)
|
|
252
|
+
const decidingDay = date.add({ days: 7 - firstWeekContainsDate - dayOfWeek })
|
|
253
|
+
const weekYear = decidingDay.year
|
|
254
|
+
|
|
255
|
+
// Calculate week number from week 1 start
|
|
256
|
+
const week1Ref = new CalendarDate(weekYear, 1, firstWeekContainsDate)
|
|
257
|
+
const week1Start = startOfWeek(week1Ref, locale, weekStartsOn)
|
|
258
|
+
const currentWeekStart = startOfWeek(date, locale, weekStartsOn)
|
|
259
|
+
|
|
260
|
+
const MS_PER_WEEK = 7 * 24 * 60 * 60 * 1000
|
|
261
|
+
const daysDiff = Math.round(
|
|
262
|
+
(currentWeekStart.toDate('UTC').getTime() - week1Start.toDate('UTC').getTime())
|
|
263
|
+
/ MS_PER_WEEK,
|
|
264
|
+
)
|
|
265
|
+
return daysDiff + 1
|
|
242
266
|
}
|
|
@@ -745,7 +745,9 @@ export function useDateField(props: UseDateFieldProps) {
|
|
|
745
745
|
|
|
746
746
|
if (isNumberString(e.key)) {
|
|
747
747
|
const num = Number.parseInt(e.key)
|
|
748
|
-
const is12Hour =
|
|
748
|
+
const is12Hour = props.hourCycle !== undefined
|
|
749
|
+
? props.hourCycle === 12
|
|
750
|
+
: uses12HourFormat(props.formatter.getLocale())
|
|
749
751
|
const max = is12Hour ? 12 : 24
|
|
750
752
|
|
|
751
753
|
let displayPrev = prevValue
|
|
@@ -61,7 +61,7 @@ export function useForwardExpose<T extends ComponentPublicInstance>() {
|
|
|
61
61
|
|
|
62
62
|
// ref not is Element
|
|
63
63
|
// and `useForwardExpose.test.ts > useForwardRef > should forward plain DOM element ref - 2` Passing in `$el`
|
|
64
|
-
if (!(ref instanceof Element) && !Object.
|
|
64
|
+
if (!(ref instanceof Element) && !Object.prototype.hasOwnProperty.call(ref, '$el')) {
|
|
65
65
|
// Retrieves the `exposed` data that has not been unwrapped by `vue` from `$.exposed`.
|
|
66
66
|
const childExposed = ref.$.exposed
|
|
67
67
|
const merged = Object.assign({}, ret)
|