bits-ui 2.4.1 → 2.6.0
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/bits/calendar/calendar.svelte.d.ts +77 -1
- package/dist/bits/calendar/calendar.svelte.js +169 -9
- package/dist/bits/calendar/components/calendar-month-select.svelte +54 -0
- package/dist/bits/calendar/components/calendar-month-select.svelte.d.ts +4 -0
- package/dist/bits/calendar/components/calendar-year-select.svelte +51 -0
- package/dist/bits/calendar/components/calendar-year-select.svelte.d.ts +4 -0
- package/dist/bits/calendar/components/calendar.svelte +6 -0
- package/dist/bits/calendar/exports.d.ts +3 -1
- package/dist/bits/calendar/exports.js +2 -0
- package/dist/bits/calendar/types.d.ts +94 -12
- package/dist/bits/combobox/types.d.ts +1 -1
- package/dist/bits/command/command.svelte.d.ts +26 -2
- package/dist/bits/command/command.svelte.js +378 -27
- package/dist/bits/command/components/command.svelte +4 -0
- package/dist/bits/command/components/command.svelte.d.ts +1 -1
- package/dist/bits/command/types.d.ts +16 -2
- package/dist/bits/date-field/date-field.svelte.js +5 -1
- package/dist/bits/date-picker/components/date-picker-calendar.svelte +3 -0
- package/dist/bits/date-picker/components/date-picker.svelte +4 -0
- package/dist/bits/date-picker/date-picker.svelte.d.ts +2 -0
- package/dist/bits/date-picker/exports.d.ts +3 -1
- package/dist/bits/date-picker/exports.js +2 -0
- package/dist/bits/date-picker/types.d.ts +13 -1
- package/dist/bits/date-range-field/date-range-field.svelte.js +5 -1
- package/dist/bits/date-range-picker/components/date-range-picker-calendar.svelte +5 -0
- package/dist/bits/date-range-picker/components/date-range-picker.svelte +10 -0
- package/dist/bits/date-range-picker/date-range-picker.svelte.d.ts +5 -0
- package/dist/bits/date-range-picker/exports.d.ts +3 -1
- package/dist/bits/date-range-picker/exports.js +2 -0
- package/dist/bits/date-range-picker/types.d.ts +33 -1
- package/dist/bits/range-calendar/components/range-calendar.svelte +10 -0
- package/dist/bits/range-calendar/exports.d.ts +3 -1
- package/dist/bits/range-calendar/exports.js +2 -0
- package/dist/bits/range-calendar/range-calendar.svelte.d.ts +20 -0
- package/dist/bits/range-calendar/range-calendar.svelte.js +120 -6
- package/dist/bits/range-calendar/types.d.ts +44 -12
- package/dist/bits/select/components/select-hidden-input.svelte +6 -2
- package/dist/bits/select/components/select-hidden-input.svelte.d.ts +2 -1
- package/dist/bits/select/components/select.svelte +3 -2
- package/dist/bits/select/types.d.ts +5 -0
- package/dist/internal/date-time/calendar-helpers.svelte.d.ts +8 -2
- package/dist/internal/date-time/calendar-helpers.svelte.js +47 -15
- package/dist/internal/date-time/formatter.d.ts +8 -1
- package/dist/internal/date-time/formatter.js +16 -3
- package/dist/internal/kbd-constants.d.ts +2 -0
- package/dist/internal/kbd-constants.js +2 -0
- package/dist/shared/attributes.d.ts +3 -1
- package/package.json +1 -1
|
@@ -226,6 +226,18 @@ export type DatePickerRootPropsWithoutHTML = WithChildren<{
|
|
|
226
226
|
* date is invalid.
|
|
227
227
|
*/
|
|
228
228
|
errorMessageId?: string;
|
|
229
|
+
/**
|
|
230
|
+
* The format of the month names in the calendar.
|
|
231
|
+
*
|
|
232
|
+
* @default "long"
|
|
233
|
+
*/
|
|
234
|
+
monthFormat?: Intl.DateTimeFormatOptions["month"] | ((month: number) => string);
|
|
235
|
+
/**
|
|
236
|
+
* The format of the year names in the calendar.
|
|
237
|
+
*
|
|
238
|
+
* @default "numeric"
|
|
239
|
+
*/
|
|
240
|
+
yearFormat?: Intl.DateTimeFormatOptions["year"] | ((year: number) => string);
|
|
229
241
|
}>;
|
|
230
242
|
export type DatePickerRootProps = DatePickerRootPropsWithoutHTML;
|
|
231
243
|
export type { PopoverTriggerPropsWithoutHTML as DatePickerTriggerPropsWithoutHTML, PopoverTriggerProps as DatePickerTriggerProps, PopoverContentPropsWithoutHTML as DatePickerContentPropsWithoutHTML, PopoverContentProps as DatePickerContentProps, PopoverContentStaticPropsWithoutHTML as DatePickerContentStaticPropsWithoutHTML, PopoverContentStaticProps as DatePickerContentStaticProps, PopoverArrowPropsWithoutHTML as DatePickerArrowPropsWithoutHTML, PopoverArrowProps as DatePickerArrowProps, PopoverClosePropsWithoutHTML as DatePickerClosePropsWithoutHTML, PopoverCloseProps as DatePickerCloseProps, } from "../popover/types.js";
|
|
@@ -234,4 +246,4 @@ export type DatePickerCalendarPropsWithoutHTML = WithChild<{}, CalendarRootSnipp
|
|
|
234
246
|
export type DatePickerCalendarProps = DatePickerCalendarPropsWithoutHTML & Without<BitsPrimitiveDivAttributes, DatePickerCalendarPropsWithoutHTML>;
|
|
235
247
|
export type DatePickerPortalPropsWithoutHTML = PortalProps;
|
|
236
248
|
export type DatePickerPortalProps = DatePickerPortalPropsWithoutHTML;
|
|
237
|
-
export type { CalendarCellPropsWithoutHTML as DatePickerCellPropsWithoutHTML, CalendarCellProps as DatePickerCellProps, CalendarDayPropsWithoutHTML as DatePickerDayPropsWithoutHTML, CalendarDayProps as DatePickerDayProps, CalendarGridPropsWithoutHTML as DatePickerGridPropsWithoutHTML, CalendarGridProps as DatePickerGridProps, CalendarGridBodyPropsWithoutHTML as DatePickerGridBodyPropsWithoutHTML, CalendarGridBodyProps as DatePickerGridBodyProps, CalendarGridHeadPropsWithoutHTML as DatePickerGridHeadPropsWithoutHTML, CalendarGridHeadProps as DatePickerGridHeadProps, CalendarGridRowPropsWithoutHTML as DatePickerGridRowPropsWithoutHTML, CalendarGridRowProps as DatePickerGridRowProps, CalendarHeadCellPropsWithoutHTML as DatePickerHeadCellPropsWithoutHTML, CalendarHeadCellProps as DatePickerHeadCellProps, CalendarHeaderPropsWithoutHTML as DatePickerHeaderPropsWithoutHTML, CalendarHeaderProps as DatePickerHeaderProps, CalendarHeadingPropsWithoutHTML as DatePickerHeadingPropsWithoutHTML, CalendarHeadingProps as DatePickerHeadingProps, CalendarNextButtonPropsWithoutHTML as DatePickerNextButtonPropsWithoutHTML, CalendarNextButtonProps as DatePickerNextButtonProps, CalendarPrevButtonPropsWithoutHTML as DatePickerPrevButtonPropsWithoutHTML, CalendarPrevButtonProps as DatePickerPrevButtonProps, } from "../calendar/types.js";
|
|
249
|
+
export type { CalendarCellPropsWithoutHTML as DatePickerCellPropsWithoutHTML, CalendarCellProps as DatePickerCellProps, CalendarDayPropsWithoutHTML as DatePickerDayPropsWithoutHTML, CalendarDayProps as DatePickerDayProps, CalendarGridPropsWithoutHTML as DatePickerGridPropsWithoutHTML, CalendarGridProps as DatePickerGridProps, CalendarGridBodyPropsWithoutHTML as DatePickerGridBodyPropsWithoutHTML, CalendarGridBodyProps as DatePickerGridBodyProps, CalendarGridHeadPropsWithoutHTML as DatePickerGridHeadPropsWithoutHTML, CalendarGridHeadProps as DatePickerGridHeadProps, CalendarGridRowPropsWithoutHTML as DatePickerGridRowPropsWithoutHTML, CalendarGridRowProps as DatePickerGridRowProps, CalendarHeadCellPropsWithoutHTML as DatePickerHeadCellPropsWithoutHTML, CalendarHeadCellProps as DatePickerHeadCellProps, CalendarHeaderPropsWithoutHTML as DatePickerHeaderPropsWithoutHTML, CalendarHeaderProps as DatePickerHeaderProps, CalendarHeadingPropsWithoutHTML as DatePickerHeadingPropsWithoutHTML, CalendarHeadingProps as DatePickerHeadingProps, CalendarNextButtonPropsWithoutHTML as DatePickerNextButtonPropsWithoutHTML, CalendarNextButtonProps as DatePickerNextButtonProps, CalendarPrevButtonPropsWithoutHTML as DatePickerPrevButtonPropsWithoutHTML, CalendarPrevButtonProps as DatePickerPrevButtonProps, CalendarMonthSelectProps as DatePickerMonthSelectProps, CalendarMonthSelectPropsWithoutHTML as DatePickerMonthSelectPropsWithoutHTML, CalendarYearSelectProps as DatePickerYearSelectProps, CalendarYearSelectPropsWithoutHTML as DatePickerYearSelectPropsWithoutHTML, } from "../calendar/types.js";
|
|
@@ -26,7 +26,11 @@ export class DateRangeFieldRootState {
|
|
|
26
26
|
domContext;
|
|
27
27
|
constructor(opts) {
|
|
28
28
|
this.opts = opts;
|
|
29
|
-
this.formatter = createFormatter(
|
|
29
|
+
this.formatter = createFormatter({
|
|
30
|
+
initialLocale: this.opts.locale.current,
|
|
31
|
+
monthFormat: box.with(() => "long"),
|
|
32
|
+
yearFormat: box.with(() => "numeric"),
|
|
33
|
+
});
|
|
30
34
|
this.domContext = new DOMContext(this.opts.ref);
|
|
31
35
|
onDestroyEffect(() => {
|
|
32
36
|
removeDescriptionElement(this.descriptionId, this.domContext.getDocument());
|
|
@@ -40,10 +40,15 @@
|
|
|
40
40
|
minValue: dateRangePickerRootState.opts.minValue,
|
|
41
41
|
placeholder: dateRangePickerRootState.opts.placeholder,
|
|
42
42
|
value: dateRangePickerRootState.opts.value,
|
|
43
|
+
excludeDisabled: dateRangePickerRootState.opts.excludeDisabled,
|
|
43
44
|
onRangeSelect: dateRangePickerRootState.opts.onRangeSelect,
|
|
44
45
|
startValue: dateRangePickerRootState.opts.startValue,
|
|
45
46
|
endValue: dateRangePickerRootState.opts.endValue,
|
|
46
47
|
defaultPlaceholder: dateRangePickerRootState.opts.defaultPlaceholder,
|
|
48
|
+
minDays: dateRangePickerRootState.opts.minDays,
|
|
49
|
+
maxDays: dateRangePickerRootState.opts.maxDays,
|
|
50
|
+
monthFormat: dateRangePickerRootState.opts.monthFormat,
|
|
51
|
+
yearFormat: dateRangePickerRootState.opts.yearFormat,
|
|
47
52
|
});
|
|
48
53
|
|
|
49
54
|
const mergedProps = $derived(mergeProps(restProps, rangeCalendarState.props));
|
|
@@ -48,8 +48,13 @@
|
|
|
48
48
|
onEndValueChange = noop,
|
|
49
49
|
validate = noop,
|
|
50
50
|
errorMessageId,
|
|
51
|
+
minDays,
|
|
52
|
+
maxDays,
|
|
53
|
+
excludeDisabled = false,
|
|
51
54
|
child,
|
|
52
55
|
children,
|
|
56
|
+
monthFormat = "long",
|
|
57
|
+
yearFormat = "numeric",
|
|
53
58
|
...restProps
|
|
54
59
|
}: DateRangePickerRootProps = $props();
|
|
55
60
|
|
|
@@ -132,6 +137,8 @@
|
|
|
132
137
|
isDateUnavailable: box.with(() => isDateUnavailable),
|
|
133
138
|
minValue: box.with(() => minValue),
|
|
134
139
|
maxValue: box.with(() => maxValue),
|
|
140
|
+
minDays: box.with(() => minDays),
|
|
141
|
+
maxDays: box.with(() => maxDays),
|
|
135
142
|
disabled: box.with(() => disabled),
|
|
136
143
|
readonly: box.with(() => readonly),
|
|
137
144
|
granularity: box.with(() => granularity),
|
|
@@ -149,6 +156,7 @@
|
|
|
149
156
|
isDateDisabled: box.with(() => isDateDisabled),
|
|
150
157
|
fixedWeeks: box.with(() => fixedWeeks),
|
|
151
158
|
numberOfMonths: box.with(() => numberOfMonths),
|
|
159
|
+
excludeDisabled: box.with(() => excludeDisabled),
|
|
152
160
|
onRangeSelect: box.with(() => onRangeSelect),
|
|
153
161
|
startValue: box.with(
|
|
154
162
|
() => startValue,
|
|
@@ -164,6 +172,8 @@
|
|
|
164
172
|
onEndValueChange(v);
|
|
165
173
|
}
|
|
166
174
|
),
|
|
175
|
+
monthFormat: box.with(() => monthFormat),
|
|
176
|
+
yearFormat: box.with(() => yearFormat),
|
|
167
177
|
defaultPlaceholder,
|
|
168
178
|
});
|
|
169
179
|
|
|
@@ -15,6 +15,8 @@ type DateRangePickerRootStateProps = WritableBoxedValues<{
|
|
|
15
15
|
isDateDisabled: DateMatcher;
|
|
16
16
|
minValue: DateValue | undefined;
|
|
17
17
|
maxValue: DateValue | undefined;
|
|
18
|
+
minDays: number | undefined;
|
|
19
|
+
maxDays: number | undefined;
|
|
18
20
|
disabled: boolean;
|
|
19
21
|
readonly: boolean;
|
|
20
22
|
granularity: Granularity | undefined;
|
|
@@ -30,7 +32,10 @@ type DateRangePickerRootStateProps = WritableBoxedValues<{
|
|
|
30
32
|
numberOfMonths: number;
|
|
31
33
|
calendarLabel: string;
|
|
32
34
|
disableDaysOutsideMonth: boolean;
|
|
35
|
+
excludeDisabled: boolean;
|
|
33
36
|
onRangeSelect?: () => void;
|
|
37
|
+
monthFormat: Intl.DateTimeFormatOptions["month"] | ((month: number) => string);
|
|
38
|
+
yearFormat: Intl.DateTimeFormatOptions["year"] | ((year: number) => string);
|
|
34
39
|
}> & {
|
|
35
40
|
defaultPlaceholder: DateValue;
|
|
36
41
|
};
|
|
@@ -16,6 +16,8 @@ export { default as Header } from "../calendar/components/calendar-header.svelte
|
|
|
16
16
|
export { default as Heading } from "../calendar/components/calendar-heading.svelte";
|
|
17
17
|
export { default as NextButton } from "../calendar/components/calendar-next-button.svelte";
|
|
18
18
|
export { default as PrevButton } from "../calendar/components/calendar-prev-button.svelte";
|
|
19
|
+
export { default as MonthSelect } from "../calendar/components/calendar-month-select.svelte";
|
|
20
|
+
export { default as YearSelect } from "../calendar/components/calendar-year-select.svelte";
|
|
19
21
|
export { default as Cell } from "../range-calendar/components/range-calendar-cell.svelte";
|
|
20
22
|
export { default as Day } from "../range-calendar/components/range-calendar-day.svelte";
|
|
21
|
-
export type { DateRangePickerRootProps as RootProps, DateRangePickerLabelProps as LabelProps, DateRangePickerInputProps as InputProps, DateRangePickerSegmentProps as SegmentProps, DateRangePickerArrowProps as ArrowProps, DateRangePickerCloseProps as CloseProps, DateRangePickerContentProps as ContentProps, DateRangePickerTriggerProps as TriggerProps, DateRangePickerCalendarProps as CalendarProps, DateRangePickerCellProps as CellProps, DateRangePickerDayProps as DayProps, DateRangePickerGridBodyProps as GridBodyProps, DateRangePickerGridHeadProps as GridHeadProps, DateRangePickerGridProps as GridProps, DateRangePickerGridRowProps as GridRowProps, DateRangePickerHeadCellProps as HeadCellProps, DateRangePickerHeaderProps as HeaderProps, DateRangePickerHeadingProps as HeadingProps, DateRangePickerNextButtonProps as NextButtonProps, DateRangePickerPrevButtonProps as PrevButtonProps, } from "./types.js";
|
|
23
|
+
export type { DateRangePickerRootProps as RootProps, DateRangePickerLabelProps as LabelProps, DateRangePickerInputProps as InputProps, DateRangePickerSegmentProps as SegmentProps, DateRangePickerArrowProps as ArrowProps, DateRangePickerCloseProps as CloseProps, DateRangePickerContentProps as ContentProps, DateRangePickerTriggerProps as TriggerProps, DateRangePickerCalendarProps as CalendarProps, DateRangePickerCellProps as CellProps, DateRangePickerDayProps as DayProps, DateRangePickerGridBodyProps as GridBodyProps, DateRangePickerGridHeadProps as GridHeadProps, DateRangePickerGridProps as GridProps, DateRangePickerGridRowProps as GridRowProps, DateRangePickerHeadCellProps as HeadCellProps, DateRangePickerHeaderProps as HeaderProps, DateRangePickerHeadingProps as HeadingProps, DateRangePickerNextButtonProps as NextButtonProps, DateRangePickerPrevButtonProps as PrevButtonProps, DateRangePickerMonthSelectProps as MonthSelectProps, DateRangePickerYearSelectProps as YearSelectProps, } from "./types.js";
|
|
@@ -16,5 +16,7 @@ export { default as Header } from "../calendar/components/calendar-header.svelte
|
|
|
16
16
|
export { default as Heading } from "../calendar/components/calendar-heading.svelte";
|
|
17
17
|
export { default as NextButton } from "../calendar/components/calendar-next-button.svelte";
|
|
18
18
|
export { default as PrevButton } from "../calendar/components/calendar-prev-button.svelte";
|
|
19
|
+
export { default as MonthSelect } from "../calendar/components/calendar-month-select.svelte";
|
|
20
|
+
export { default as YearSelect } from "../calendar/components/calendar-year-select.svelte";
|
|
19
21
|
export { default as Cell } from "../range-calendar/components/range-calendar-cell.svelte";
|
|
20
22
|
export { default as Day } from "../range-calendar/components/range-calendar-day.svelte";
|
|
@@ -233,10 +233,42 @@ export type DateRangePickerRootPropsWithoutHTML = WithChild<{
|
|
|
233
233
|
* date is invalid.
|
|
234
234
|
*/
|
|
235
235
|
errorMessageId?: string;
|
|
236
|
+
/**
|
|
237
|
+
* The minimum number of days that can be selected in a range.
|
|
238
|
+
*
|
|
239
|
+
* @default undefined
|
|
240
|
+
*/
|
|
241
|
+
minDays?: number;
|
|
242
|
+
/**
|
|
243
|
+
* The maximum number of days that can be selected in a range.
|
|
244
|
+
*
|
|
245
|
+
* @default undefined
|
|
246
|
+
*/
|
|
247
|
+
maxDays?: number;
|
|
248
|
+
/**
|
|
249
|
+
* Whether to automatically reset the range if any date within the selected range
|
|
250
|
+
* becomes disabled. When true, the entire range will be cleared if a disabled
|
|
251
|
+
* date is found between the start and end dates.
|
|
252
|
+
*
|
|
253
|
+
* @default false
|
|
254
|
+
*/
|
|
255
|
+
excludeDisabled?: boolean;
|
|
256
|
+
/**
|
|
257
|
+
* The format of the month names in the calendar.
|
|
258
|
+
*
|
|
259
|
+
* @default "long"
|
|
260
|
+
*/
|
|
261
|
+
monthFormat?: Intl.DateTimeFormatOptions["month"] | ((month: number) => string);
|
|
262
|
+
/**
|
|
263
|
+
* The format of the year names in the calendar.
|
|
264
|
+
*
|
|
265
|
+
* @default "numeric"
|
|
266
|
+
*/
|
|
267
|
+
yearFormat?: Intl.DateTimeFormatOptions["year"] | ((year: number) => string);
|
|
236
268
|
}>;
|
|
237
269
|
export type DateRangePickerRootProps = DateRangePickerRootPropsWithoutHTML & Without<BitsPrimitiveDivAttributes, DateRangePickerRootPropsWithoutHTML>;
|
|
238
270
|
export type { PopoverTriggerPropsWithoutHTML as DateRangePickerTriggerPropsWithoutHTML, PopoverTriggerProps as DateRangePickerTriggerProps, PopoverContentPropsWithoutHTML as DateRangePickerContentPropsWithoutHTML, PopoverContentProps as DateRangePickerContentProps, PopoverArrowPropsWithoutHTML as DateRangePickerArrowPropsWithoutHTML, PopoverArrowProps as DateRangePickerArrowProps, PopoverClosePropsWithoutHTML as DateRangePickerClosePropsWithoutHTML, PopoverCloseProps as DateRangePickerCloseProps, } from "../popover/types.js";
|
|
239
271
|
export type { DateRangeFieldInputPropsWithoutHTML as DateRangePickerInputPropsWithoutHTML, DateRangeFieldInputProps as DateRangePickerInputProps, DateRangeFieldLabelPropsWithoutHTML as DateRangePickerLabelPropsWithoutHTML, DateRangeFieldLabelProps as DateRangePickerLabelProps, DateRangeFieldSegmentPropsWithoutHTML as DateRangePickerSegmentPropsWithoutHTML, DateRangeFieldSegmentProps as DateRangePickerSegmentProps, } from "../date-range-field/types.js";
|
|
240
272
|
export type DateRangePickerCalendarPropsWithoutHTML = WithChild<{}, CalendarRootSnippetProps>;
|
|
241
273
|
export type DateRangePickerCalendarProps = DateRangePickerCalendarPropsWithoutHTML & Without<BitsPrimitiveDivAttributes, DateRangePickerCalendarPropsWithoutHTML>;
|
|
242
|
-
export type { RangeCalendarCellPropsWithoutHTML as DateRangePickerCellPropsWithoutHTML, RangeCalendarCellProps as DateRangePickerCellProps, RangeCalendarDayPropsWithoutHTML as DateRangePickerDayPropsWithoutHTML, RangeCalendarDayProps as DateRangePickerDayProps, RangeCalendarGridPropsWithoutHTML as DateRangePickerGridPropsWithoutHTML, RangeCalendarGridProps as DateRangePickerGridProps, RangeCalendarGridBodyPropsWithoutHTML as DateRangePickerGridBodyPropsWithoutHTML, RangeCalendarGridBodyProps as DateRangePickerGridBodyProps, RangeCalendarGridHeadPropsWithoutHTML as DateRangePickerGridHeadPropsWithoutHTML, RangeCalendarGridHeadProps as DateRangePickerGridHeadProps, RangeCalendarGridRowPropsWithoutHTML as DateRangePickerGridRowPropsWithoutHTML, RangeCalendarGridRowProps as DateRangePickerGridRowProps, RangeCalendarHeadCellPropsWithoutHTML as DateRangePickerHeadCellPropsWithoutHTML, RangeCalendarHeadCellProps as DateRangePickerHeadCellProps, RangeCalendarHeaderPropsWithoutHTML as DateRangePickerHeaderPropsWithoutHTML, RangeCalendarHeaderProps as DateRangePickerHeaderProps, RangeCalendarHeadingPropsWithoutHTML as DateRangePickerHeadingPropsWithoutHTML, RangeCalendarHeadingProps as DateRangePickerHeadingProps, RangeCalendarNextButtonPropsWithoutHTML as DateRangePickerNextButtonPropsWithoutHTML, RangeCalendarNextButtonProps as DateRangePickerNextButtonProps, RangeCalendarPrevButtonPropsWithoutHTML as DateRangePickerPrevButtonPropsWithoutHTML, RangeCalendarPrevButtonProps as DateRangePickerPrevButtonProps, } from "../range-calendar/types.js";
|
|
274
|
+
export type { RangeCalendarCellPropsWithoutHTML as DateRangePickerCellPropsWithoutHTML, RangeCalendarCellProps as DateRangePickerCellProps, RangeCalendarDayPropsWithoutHTML as DateRangePickerDayPropsWithoutHTML, RangeCalendarDayProps as DateRangePickerDayProps, RangeCalendarGridPropsWithoutHTML as DateRangePickerGridPropsWithoutHTML, RangeCalendarGridProps as DateRangePickerGridProps, RangeCalendarGridBodyPropsWithoutHTML as DateRangePickerGridBodyPropsWithoutHTML, RangeCalendarGridBodyProps as DateRangePickerGridBodyProps, RangeCalendarGridHeadPropsWithoutHTML as DateRangePickerGridHeadPropsWithoutHTML, RangeCalendarGridHeadProps as DateRangePickerGridHeadProps, RangeCalendarGridRowPropsWithoutHTML as DateRangePickerGridRowPropsWithoutHTML, RangeCalendarGridRowProps as DateRangePickerGridRowProps, RangeCalendarHeadCellPropsWithoutHTML as DateRangePickerHeadCellPropsWithoutHTML, RangeCalendarHeadCellProps as DateRangePickerHeadCellProps, RangeCalendarHeaderPropsWithoutHTML as DateRangePickerHeaderPropsWithoutHTML, RangeCalendarHeaderProps as DateRangePickerHeaderProps, RangeCalendarHeadingPropsWithoutHTML as DateRangePickerHeadingPropsWithoutHTML, RangeCalendarHeadingProps as DateRangePickerHeadingProps, RangeCalendarNextButtonPropsWithoutHTML as DateRangePickerNextButtonPropsWithoutHTML, RangeCalendarNextButtonProps as DateRangePickerNextButtonProps, RangeCalendarPrevButtonPropsWithoutHTML as DateRangePickerPrevButtonPropsWithoutHTML, RangeCalendarPrevButtonProps as DateRangePickerPrevButtonProps, RangeCalendarMonthSelectProps as DateRangePickerMonthSelectProps, RangeCalendarMonthSelectPropsWithoutHTML as DateRangePickerMonthSelectPropsWithoutHTML, RangeCalendarYearSelectProps as DateRangePickerYearSelectProps, RangeCalendarYearSelectPropsWithoutHTML as DateRangePickerYearSelectPropsWithoutHTML, } from "../range-calendar/types.js";
|
|
@@ -35,8 +35,13 @@
|
|
|
35
35
|
maxValue = undefined,
|
|
36
36
|
preventDeselect = false,
|
|
37
37
|
disableDaysOutsideMonth = true,
|
|
38
|
+
minDays,
|
|
39
|
+
maxDays,
|
|
38
40
|
onStartValueChange = noop,
|
|
39
41
|
onEndValueChange = noop,
|
|
42
|
+
excludeDisabled = false,
|
|
43
|
+
monthFormat = "long",
|
|
44
|
+
yearFormat = "numeric",
|
|
40
45
|
...restProps
|
|
41
46
|
}: RangeCalendarRootProps = $props();
|
|
42
47
|
|
|
@@ -112,6 +117,9 @@
|
|
|
112
117
|
calendarLabel: box.with(() => calendarLabel),
|
|
113
118
|
fixedWeeks: box.with(() => fixedWeeks),
|
|
114
119
|
disableDaysOutsideMonth: box.with(() => disableDaysOutsideMonth),
|
|
120
|
+
minDays: box.with(() => minDays),
|
|
121
|
+
maxDays: box.with(() => maxDays),
|
|
122
|
+
excludeDisabled: box.with(() => excludeDisabled),
|
|
115
123
|
startValue: box.with(
|
|
116
124
|
() => startValue,
|
|
117
125
|
(v) => {
|
|
@@ -126,6 +134,8 @@
|
|
|
126
134
|
onEndValueChange(v);
|
|
127
135
|
}
|
|
128
136
|
),
|
|
137
|
+
monthFormat: box.with(() => monthFormat),
|
|
138
|
+
yearFormat: box.with(() => yearFormat),
|
|
129
139
|
defaultPlaceholder,
|
|
130
140
|
});
|
|
131
141
|
|
|
@@ -10,4 +10,6 @@ export { default as Header } from "../calendar/components/calendar-header.svelte
|
|
|
10
10
|
export { default as Heading } from "../calendar/components/calendar-heading.svelte";
|
|
11
11
|
export { default as NextButton } from "../calendar/components/calendar-next-button.svelte";
|
|
12
12
|
export { default as PrevButton } from "../calendar/components/calendar-prev-button.svelte";
|
|
13
|
-
export
|
|
13
|
+
export { default as MonthSelect } from "../calendar/components/calendar-month-select.svelte";
|
|
14
|
+
export { default as YearSelect } from "../calendar/components/calendar-year-select.svelte";
|
|
15
|
+
export type { RangeCalendarRootProps as RootProps, RangeCalendarPrevButtonProps as PrevButtonProps, RangeCalendarNextButtonProps as NextButtonProps, RangeCalendarHeadingProps as HeadingProps, RangeCalendarHeaderProps as HeaderProps, RangeCalendarGridProps as GridProps, RangeCalendarGridHeadProps as GridHeadProps, RangeCalendarHeadCellProps as HeadCellProps, RangeCalendarGridBodyProps as GridBodyProps, RangeCalendarCellProps as CellProps, RangeCalendarGridRowProps as GridRowProps, RangeCalendarDayProps as DayProps, RangeCalendarMonthSelectProps as MonthSelectProps, RangeCalendarYearSelectProps as YearSelectProps, } from "./types.js";
|
|
@@ -10,3 +10,5 @@ export { default as Header } from "../calendar/components/calendar-header.svelte
|
|
|
10
10
|
export { default as Heading } from "../calendar/components/calendar-heading.svelte";
|
|
11
11
|
export { default as NextButton } from "../calendar/components/calendar-next-button.svelte";
|
|
12
12
|
export { default as PrevButton } from "../calendar/components/calendar-prev-button.svelte";
|
|
13
|
+
export { default as MonthSelect } from "../calendar/components/calendar-month-select.svelte";
|
|
14
|
+
export { default as YearSelect } from "../calendar/components/calendar-year-select.svelte";
|
|
@@ -28,11 +28,16 @@ type RangeCalendarRootStateProps = WithRefProps<WritableBoxedValues<{
|
|
|
28
28
|
calendarLabel: string;
|
|
29
29
|
readonly: boolean;
|
|
30
30
|
disableDaysOutsideMonth: boolean;
|
|
31
|
+
excludeDisabled: boolean;
|
|
32
|
+
minDays: number | undefined;
|
|
33
|
+
maxDays: number | undefined;
|
|
31
34
|
/**
|
|
32
35
|
* This is strictly used by the `DateRangePicker` component to close the popover when a date range
|
|
33
36
|
* is selected. It is not intended to be used by the user.
|
|
34
37
|
*/
|
|
35
38
|
onRangeSelect?: () => void;
|
|
39
|
+
monthFormat: Intl.DateTimeFormatOptions["month"] | ((month: number) => string);
|
|
40
|
+
yearFormat: Intl.DateTimeFormatOptions["year"] | ((year: number) => string);
|
|
36
41
|
}> & {
|
|
37
42
|
defaultPlaceholder: DateValue;
|
|
38
43
|
}>;
|
|
@@ -66,6 +71,8 @@ export declare class RangeCalendarRootState {
|
|
|
66
71
|
start: DateValue;
|
|
67
72
|
end: DateValue;
|
|
68
73
|
} | null;
|
|
74
|
+
readonly initialPlaceholderYear: number;
|
|
75
|
+
readonly defaultYears: number[];
|
|
69
76
|
constructor(opts: RangeCalendarRootStateProps);
|
|
70
77
|
setMonths: (months: Month<DateValue>[]) => void;
|
|
71
78
|
isOutsideVisibleMonths(date: DateValue): boolean;
|
|
@@ -120,6 +127,10 @@ export declare class RangeCalendarCellState {
|
|
|
120
127
|
readonly isFocusedDate: boolean;
|
|
121
128
|
readonly isSelectedDate: boolean;
|
|
122
129
|
readonly isSelectionStart: boolean;
|
|
130
|
+
readonly isRangeStart: boolean;
|
|
131
|
+
readonly isRangeEnd: boolean;
|
|
132
|
+
readonly isRangeMiddle: boolean;
|
|
133
|
+
readonly isSelectionMiddle: boolean;
|
|
123
134
|
readonly isSelectionEnd: boolean;
|
|
124
135
|
readonly isHighlighted: boolean;
|
|
125
136
|
readonly labelText: string;
|
|
@@ -138,6 +149,9 @@ export declare class RangeCalendarCellState {
|
|
|
138
149
|
readonly "data-focused": "" | undefined;
|
|
139
150
|
readonly "data-selection-start": "" | undefined;
|
|
140
151
|
readonly "data-selection-end": "" | undefined;
|
|
152
|
+
readonly "data-range-start": "" | undefined;
|
|
153
|
+
readonly "data-range-end": "" | undefined;
|
|
154
|
+
readonly "data-range-middle": "" | undefined;
|
|
141
155
|
readonly "data-highlighted": "" | undefined;
|
|
142
156
|
readonly "data-selected": "" | undefined;
|
|
143
157
|
readonly "data-value": string;
|
|
@@ -152,6 +166,9 @@ export declare class RangeCalendarCellState {
|
|
|
152
166
|
readonly "data-focused": "" | undefined;
|
|
153
167
|
readonly "data-selection-start": "" | undefined;
|
|
154
168
|
readonly "data-selection-end": "" | undefined;
|
|
169
|
+
readonly "data-range-start": "" | undefined;
|
|
170
|
+
readonly "data-range-end": "" | undefined;
|
|
171
|
+
readonly "data-range-middle": "" | undefined;
|
|
155
172
|
readonly "data-highlighted": "" | undefined;
|
|
156
173
|
readonly "data-selected": "" | undefined;
|
|
157
174
|
readonly "data-value": string;
|
|
@@ -191,6 +208,9 @@ declare class RangeCalendarDayState {
|
|
|
191
208
|
readonly "data-focused": "" | undefined;
|
|
192
209
|
readonly "data-selection-start": "" | undefined;
|
|
193
210
|
readonly "data-selection-end": "" | undefined;
|
|
211
|
+
readonly "data-range-start": "" | undefined;
|
|
212
|
+
readonly "data-range-end": "" | undefined;
|
|
213
|
+
readonly "data-range-middle": "" | undefined;
|
|
194
214
|
readonly "data-highlighted": "" | undefined;
|
|
195
215
|
readonly "data-selected": "" | undefined;
|
|
196
216
|
readonly "data-value": string;
|
|
@@ -6,9 +6,9 @@ import { useId } from "../../internal/use-id.js";
|
|
|
6
6
|
import { getAriaDisabled, getAriaSelected, getDataDisabled, getDataSelected, getDataUnavailable, } from "../../internal/attrs.js";
|
|
7
7
|
import { getAnnouncer } from "../../internal/date-time/announcer.js";
|
|
8
8
|
import { createFormatter } from "../../internal/date-time/formatter.js";
|
|
9
|
-
import { calendarAttrs, createMonths, getCalendarElementProps, getCalendarHeadingValue, getIsNextButtonDisabled, getIsPrevButtonDisabled, getWeekdays, handleCalendarKeydown, handleCalendarNextPage, handleCalendarPrevPage, shiftCalendarFocus, useEnsureNonDisabledPlaceholder, useMonthViewOptionsSync, useMonthViewPlaceholderSync, } from "../../internal/date-time/calendar-helpers.svelte.js";
|
|
9
|
+
import { calendarAttrs, createMonths, getCalendarElementProps, getCalendarHeadingValue, getDefaultYears, getIsNextButtonDisabled, getIsPrevButtonDisabled, getWeekdays, handleCalendarKeydown, handleCalendarNextPage, handleCalendarPrevPage, shiftCalendarFocus, useEnsureNonDisabledPlaceholder, useMonthViewOptionsSync, useMonthViewPlaceholderSync, } from "../../internal/date-time/calendar-helpers.svelte.js";
|
|
10
10
|
import { areAllDaysBetweenValid, getDateValueType, isAfter, isBefore, isBetweenInclusive, toDate, } from "../../internal/date-time/utils.js";
|
|
11
|
-
import { onMount } from "svelte";
|
|
11
|
+
import { onMount, untrack } from "svelte";
|
|
12
12
|
export class RangeCalendarRootState {
|
|
13
13
|
opts;
|
|
14
14
|
visibleMonths = $derived.by(() => this.months.map((month) => month.value));
|
|
@@ -69,6 +69,8 @@ export class RangeCalendarRootState {
|
|
|
69
69
|
});
|
|
70
70
|
});
|
|
71
71
|
headingValue = $derived.by(() => {
|
|
72
|
+
this.opts.monthFormat.current;
|
|
73
|
+
this.opts.yearFormat.current;
|
|
72
74
|
return getCalendarHeadingValue({
|
|
73
75
|
months: this.months,
|
|
74
76
|
formatter: this.formatter,
|
|
@@ -93,11 +95,23 @@ export class RangeCalendarRootState {
|
|
|
93
95
|
return range;
|
|
94
96
|
return null;
|
|
95
97
|
});
|
|
98
|
+
initialPlaceholderYear = $derived.by(() => untrack(() => this.opts.placeholder.current.year));
|
|
99
|
+
defaultYears = $derived.by(() => {
|
|
100
|
+
return getDefaultYears({
|
|
101
|
+
minValue: this.opts.minValue.current,
|
|
102
|
+
maxValue: this.opts.maxValue.current,
|
|
103
|
+
placeholderYear: this.initialPlaceholderYear,
|
|
104
|
+
});
|
|
105
|
+
});
|
|
96
106
|
constructor(opts) {
|
|
97
107
|
this.opts = opts;
|
|
98
108
|
this.domContext = new DOMContext(opts.ref);
|
|
99
109
|
this.announcer = getAnnouncer(null);
|
|
100
|
-
this.formatter = createFormatter(
|
|
110
|
+
this.formatter = createFormatter({
|
|
111
|
+
initialLocale: this.opts.locale.current,
|
|
112
|
+
monthFormat: this.opts.monthFormat,
|
|
113
|
+
yearFormat: this.opts.yearFormat,
|
|
114
|
+
});
|
|
101
115
|
this.months = createMonths({
|
|
102
116
|
dateObj: this.opts.placeholder.current,
|
|
103
117
|
weekStartsOn: this.opts.weekStartsOn.current,
|
|
@@ -105,7 +119,7 @@ export class RangeCalendarRootState {
|
|
|
105
119
|
fixedWeeks: this.opts.fixedWeeks.current,
|
|
106
120
|
numberOfMonths: this.opts.numberOfMonths.current,
|
|
107
121
|
});
|
|
108
|
-
$effect(() => {
|
|
122
|
+
$effect.pre(() => {
|
|
109
123
|
if (this.formatter.getLocale() === this.opts.locale.current)
|
|
110
124
|
return;
|
|
111
125
|
this.formatter.setLocale(this.opts.locale.current);
|
|
@@ -175,6 +189,22 @@ export class RangeCalendarRootState {
|
|
|
175
189
|
this.opts.placeholder.current = startValue;
|
|
176
190
|
}
|
|
177
191
|
});
|
|
192
|
+
/**
|
|
193
|
+
* Check for disabled dates in the selected range when excludeDisabled is enabled
|
|
194
|
+
*/
|
|
195
|
+
watch([
|
|
196
|
+
() => this.opts.startValue.current,
|
|
197
|
+
() => this.opts.endValue.current,
|
|
198
|
+
() => this.opts.excludeDisabled.current,
|
|
199
|
+
], ([startValue, endValue, excludeDisabled]) => {
|
|
200
|
+
if (!excludeDisabled || !startValue || !endValue)
|
|
201
|
+
return;
|
|
202
|
+
if (this.#hasDisabledDatesInRange(startValue, endValue)) {
|
|
203
|
+
this.#setStartValue(undefined);
|
|
204
|
+
this.#setEndValue(undefined);
|
|
205
|
+
this.#announceEmpty();
|
|
206
|
+
}
|
|
207
|
+
});
|
|
178
208
|
watch([() => this.opts.startValue.current, () => this.opts.endValue.current], ([startValue, endValue]) => {
|
|
179
209
|
if (this.opts.value.current &&
|
|
180
210
|
this.opts.value.current.start === startValue &&
|
|
@@ -191,9 +221,19 @@ export class RangeCalendarRootState {
|
|
|
191
221
|
const end = endValue;
|
|
192
222
|
this.#setStartValue(end);
|
|
193
223
|
this.#setEndValue(start);
|
|
224
|
+
if (!this.#isRangeValid(endValue, startValue)) {
|
|
225
|
+
this.#setStartValue(startValue);
|
|
226
|
+
this.#setEndValue(undefined);
|
|
227
|
+
return { start: startValue, end: undefined };
|
|
228
|
+
}
|
|
194
229
|
return { start: endValue, end: startValue };
|
|
195
230
|
}
|
|
196
231
|
else {
|
|
232
|
+
if (!this.#isRangeValid(startValue, endValue)) {
|
|
233
|
+
this.#setStartValue(endValue);
|
|
234
|
+
this.#setEndValue(undefined);
|
|
235
|
+
return { start: endValue, end: undefined };
|
|
236
|
+
}
|
|
197
237
|
return {
|
|
198
238
|
start: startValue,
|
|
199
239
|
end: endValue,
|
|
@@ -240,9 +280,19 @@ export class RangeCalendarRootState {
|
|
|
240
280
|
}
|
|
241
281
|
#setStartValue(value) {
|
|
242
282
|
this.opts.startValue.current = value;
|
|
283
|
+
// update the main value prop immediately for external consumers
|
|
284
|
+
this.#updateValue((prev) => ({
|
|
285
|
+
...prev,
|
|
286
|
+
start: value,
|
|
287
|
+
}));
|
|
243
288
|
}
|
|
244
289
|
#setEndValue(value) {
|
|
245
290
|
this.opts.endValue.current = value;
|
|
291
|
+
// update the main value prop immediately for external consumers
|
|
292
|
+
this.#updateValue((prev) => ({
|
|
293
|
+
...prev,
|
|
294
|
+
end: value,
|
|
295
|
+
}));
|
|
246
296
|
}
|
|
247
297
|
setMonths = (months) => {
|
|
248
298
|
this.months = months;
|
|
@@ -286,6 +336,26 @@ export class RangeCalendarRootState {
|
|
|
286
336
|
}
|
|
287
337
|
return false;
|
|
288
338
|
}
|
|
339
|
+
#isRangeValid(start, end) {
|
|
340
|
+
// ensure we always use the correct order for calculation
|
|
341
|
+
const orderedStart = isBefore(end, start) ? end : start;
|
|
342
|
+
const orderedEnd = isBefore(end, start) ? start : end;
|
|
343
|
+
const startDate = orderedStart.toDate(getLocalTimeZone());
|
|
344
|
+
const endDate = orderedEnd.toDate(getLocalTimeZone());
|
|
345
|
+
const timeDifference = endDate.getTime() - startDate.getTime();
|
|
346
|
+
const daysDifference = Math.floor(timeDifference / (1000 * 60 * 60 * 24));
|
|
347
|
+
const daysInRange = daysDifference + 1; // +1 to include both start and end days
|
|
348
|
+
if (this.opts.minDays.current && daysInRange < this.opts.minDays.current)
|
|
349
|
+
return false;
|
|
350
|
+
if (this.opts.maxDays.current && daysInRange > this.opts.maxDays.current)
|
|
351
|
+
return false;
|
|
352
|
+
// check for disabled dates in range if excludeDisabled is enabled
|
|
353
|
+
if (this.opts.excludeDisabled.current &&
|
|
354
|
+
this.#hasDisabledDatesInRange(orderedStart, orderedEnd)) {
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
return true;
|
|
358
|
+
}
|
|
289
359
|
shiftFocus(node, add) {
|
|
290
360
|
return shiftCalendarFocus({
|
|
291
361
|
node,
|
|
@@ -344,8 +414,32 @@ export class RangeCalendarRootState {
|
|
|
344
414
|
this.#setStartValue(date);
|
|
345
415
|
}
|
|
346
416
|
else if (!this.opts.endValue.current) {
|
|
347
|
-
|
|
348
|
-
this
|
|
417
|
+
// determine the start and end dates for validation
|
|
418
|
+
const startDate = this.opts.startValue.current;
|
|
419
|
+
const endDate = date;
|
|
420
|
+
const orderedStart = isBefore(endDate, startDate) ? endDate : startDate;
|
|
421
|
+
const orderedEnd = isBefore(endDate, startDate) ? startDate : endDate;
|
|
422
|
+
// check if the range violates constraints
|
|
423
|
+
if (!this.#isRangeValid(orderedStart, orderedEnd)) {
|
|
424
|
+
// reset to just the clicked date
|
|
425
|
+
this.#setStartValue(date);
|
|
426
|
+
this.#setEndValue(undefined);
|
|
427
|
+
this.#announceSelectedDate(date);
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
// ensure start and end are properly ordered
|
|
431
|
+
if (isBefore(endDate, startDate)) {
|
|
432
|
+
// backward selection - reorder the values
|
|
433
|
+
this.#setStartValue(endDate);
|
|
434
|
+
this.#setEndValue(startDate);
|
|
435
|
+
this.#announceSelectedRange(endDate, startDate);
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
// forward selection - keep original order
|
|
439
|
+
this.#setEndValue(date);
|
|
440
|
+
this.#announceSelectedRange(this.opts.startValue.current, date);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
349
443
|
}
|
|
350
444
|
else if (this.opts.endValue.current && this.opts.startValue.current) {
|
|
351
445
|
this.#setEndValue(undefined);
|
|
@@ -423,6 +517,13 @@ export class RangeCalendarRootState {
|
|
|
423
517
|
onkeydown: this.onkeydown,
|
|
424
518
|
...attachRef(this.opts.ref),
|
|
425
519
|
}));
|
|
520
|
+
#hasDisabledDatesInRange(start, end) {
|
|
521
|
+
for (let date = start; isBefore(date, end) || isSameDay(date, end); date = date.add({ days: 1 })) {
|
|
522
|
+
if (this.isDateDisabled(date))
|
|
523
|
+
return true;
|
|
524
|
+
}
|
|
525
|
+
return false;
|
|
526
|
+
}
|
|
426
527
|
}
|
|
427
528
|
export class RangeCalendarCellState {
|
|
428
529
|
opts;
|
|
@@ -436,6 +537,16 @@ export class RangeCalendarCellState {
|
|
|
436
537
|
isFocusedDate = $derived.by(() => isSameDay(this.opts.date.current, this.root.opts.placeholder.current));
|
|
437
538
|
isSelectedDate = $derived.by(() => this.root.isSelected(this.opts.date.current));
|
|
438
539
|
isSelectionStart = $derived.by(() => this.root.isSelectionStart(this.opts.date.current));
|
|
540
|
+
isRangeStart = $derived.by(() => this.root.isSelectionStart(this.opts.date.current));
|
|
541
|
+
isRangeEnd = $derived.by(() => {
|
|
542
|
+
if (!this.root.opts.endValue.current)
|
|
543
|
+
return this.root.isSelectionStart(this.opts.date.current);
|
|
544
|
+
return this.root.isSelectionEnd(this.opts.date.current);
|
|
545
|
+
});
|
|
546
|
+
isRangeMiddle = $derived.by(() => this.isSelectionMiddle);
|
|
547
|
+
isSelectionMiddle = $derived.by(() => {
|
|
548
|
+
return this.isSelectedDate && !this.isSelectionStart && !this.isSelectionEnd;
|
|
549
|
+
});
|
|
439
550
|
isSelectionEnd = $derived.by(() => this.root.isSelectionEnd(this.opts.date.current));
|
|
440
551
|
isHighlighted = $derived.by(() => this.root.highlightedRange
|
|
441
552
|
? isBetweenInclusive(this.opts.date.current, this.root.highlightedRange.start, this.root.highlightedRange.end)
|
|
@@ -468,6 +579,9 @@ export class RangeCalendarCellState {
|
|
|
468
579
|
"data-focused": this.isFocusedDate ? "" : undefined,
|
|
469
580
|
"data-selection-start": this.isSelectionStart ? "" : undefined,
|
|
470
581
|
"data-selection-end": this.isSelectionEnd ? "" : undefined,
|
|
582
|
+
"data-range-start": this.isRangeStart ? "" : undefined,
|
|
583
|
+
"data-range-end": this.isRangeEnd ? "" : undefined,
|
|
584
|
+
"data-range-middle": this.isRangeMiddle ? "" : undefined,
|
|
471
585
|
"data-highlighted": this.isHighlighted ? "" : undefined,
|
|
472
586
|
"data-selected": getDataSelected(this.isSelectedDate),
|
|
473
587
|
"data-value": this.opts.date.current.toString(),
|