@rotki/ui-library 2.9.1 → 2.11.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.
Files changed (77) hide show
  1. package/dist/components/accordions/accordion/RuiAccordion.vue.d.ts +3 -3
  2. package/dist/components/accordions/accordion/RuiAccordion.vue.js +87 -8
  3. package/dist/components/accordions/accordion/RuiAccordion.vue.js.map +1 -1
  4. package/dist/components/accordions/accordion/RuiAccordion.vue2.js +1 -62
  5. package/dist/components/accordions/accordion/RuiAccordion.vue2.js.map +1 -1
  6. package/dist/components/alerts/RuiAlert.vue.d.ts +3 -3
  7. package/dist/components/buttons/button/RuiButton.vue.d.ts +9 -5
  8. package/dist/components/buttons/button-group/RuiButtonGroup.vue.d.ts +9 -5
  9. package/dist/components/calendar/RuiCalendar.vue.js +12 -0
  10. package/dist/components/calendar/RuiCalendar.vue.js.map +1 -1
  11. package/dist/components/calendar/RuiCalendarMenu.vue.js +1 -1
  12. package/dist/components/calendar/RuiCalendarMenu.vue2.js +2 -2
  13. package/dist/components/calendar/RuiCalendarMenu.vue2.js.map +1 -1
  14. package/dist/components/calendar/state.js +1 -1
  15. package/dist/components/calendar/state.js.map +1 -1
  16. package/dist/components/cards/RuiCard.vue.d.ts +6 -6
  17. package/dist/components/date-time-picker/RuiDateTimePicker.vue.d.ts +3 -4
  18. package/dist/components/date-time-picker/RuiDateTimePicker.vue2.js +70 -251
  19. package/dist/components/date-time-picker/RuiDateTimePicker.vue2.js.map +1 -1
  20. package/dist/components/date-time-picker/use-date-time-selection.d.ts +38 -0
  21. package/dist/components/date-time-picker/use-date-time-selection.js +286 -0
  22. package/dist/components/date-time-picker/use-date-time-selection.js.map +1 -0
  23. package/dist/components/date-time-picker/use-keyboard-handler.d.ts +2 -0
  24. package/dist/components/date-time-picker/use-keyboard-handler.js +71 -60
  25. package/dist/components/date-time-picker/use-keyboard-handler.js.map +1 -1
  26. package/dist/components/forms/auto-complete/RuiAutoComplete.vue.d.ts +29 -25
  27. package/dist/components/forms/auto-complete/RuiAutoComplete.vue2.js +5 -3
  28. package/dist/components/forms/auto-complete/RuiAutoComplete.vue2.js.map +1 -1
  29. package/dist/components/forms/checkbox/RuiCheckbox.vue.d.ts +2 -2
  30. package/dist/components/forms/checkbox/RuiCheckbox.vue2.js +13 -8
  31. package/dist/components/forms/checkbox/RuiCheckbox.vue2.js.map +1 -1
  32. package/dist/components/forms/radio-button/radio/RuiRadio.vue.d.ts +9 -5
  33. package/dist/components/forms/radio-button/radio/RuiRadio.vue2.js +12 -8
  34. package/dist/components/forms/radio-button/radio/RuiRadio.vue2.js.map +1 -1
  35. package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue.d.ts +9 -5
  36. package/dist/components/forms/revealable-text-field/RuiRevealableTextField.vue.d.ts +4 -4
  37. package/dist/components/forms/select/RuiMenuSelect.vue.d.ts +29 -25
  38. package/dist/components/forms/select/RuiMenuSelect.vue2.js +4 -2
  39. package/dist/components/forms/select/RuiMenuSelect.vue2.js.map +1 -1
  40. package/dist/components/forms/slider/RuiSlider.vue2.js +14 -11
  41. package/dist/components/forms/slider/RuiSlider.vue2.js.map +1 -1
  42. package/dist/components/forms/switch/RuiSwitch.vue2.js +10 -7
  43. package/dist/components/forms/switch/RuiSwitch.vue2.js.map +1 -1
  44. package/dist/components/forms/text-area/RuiTextArea.vue.d.ts +3 -3
  45. package/dist/components/forms/text-area/RuiTextArea.vue2.js +15 -12
  46. package/dist/components/forms/text-area/RuiTextArea.vue2.js.map +1 -1
  47. package/dist/components/forms/text-field/RuiTextField.vue.d.ts +3 -3
  48. package/dist/components/forms/text-field/RuiTextField.vue2.js +13 -10
  49. package/dist/components/forms/text-field/RuiTextField.vue2.js.map +1 -1
  50. package/dist/components/icons/IconBrowser.vue.d.ts +3 -0
  51. package/dist/components/icons/LazyIcon.vue.d.ts +10 -0
  52. package/dist/components/overlays/badge/RuiBadge.vue.d.ts +3 -3
  53. package/dist/components/overlays/bottom-sheet/RuiBottomSheet.vue.d.ts +2 -2
  54. package/dist/components/overlays/dialog/RuiDialog.vue.d.ts +2 -2
  55. package/dist/components/overlays/menu/RuiMenu.vue.d.ts +2 -2
  56. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue.d.ts +2 -2
  57. package/dist/components/overlays/notification/RuiNotification.vue.d.ts +2 -2
  58. package/dist/components/overlays/tooltip/RuiTooltip.vue.d.ts +2 -2
  59. package/dist/components/tables/RuiDataTable.vue.d.ts +9 -5
  60. package/dist/components/tables/RuiExpandButton.vue.d.ts +2 -2
  61. package/dist/components/tables/RuiTableHead.vue.d.ts +9 -5
  62. package/dist/components/tabs/tab/RuiTab.vue.d.ts +1 -1
  63. package/dist/components/tabs/tab-item/RuiTabItem.vue.d.ts +3 -3
  64. package/dist/components/tabs/tab-items/RuiTabItems.vue.d.ts +9 -5
  65. package/dist/components/time-picker/RuiTimePicker.vue2.js +0 -1
  66. package/dist/components/time-picker/RuiTimePicker.vue2.js.map +1 -1
  67. package/dist/composables/defaults/table.js +1 -1
  68. package/dist/composables/defaults/table.js.map +1 -1
  69. package/dist/composables/icons.js +1 -1
  70. package/dist/composables/icons.js.map +1 -1
  71. package/dist/composables/use-rui-i18n.js +1 -1
  72. package/dist/composables/use-rui-i18n.js.map +1 -1
  73. package/dist/style.css +98 -61
  74. package/dist/web-types.json +116 -72
  75. package/package.json +31 -40
  76. package/dist/components/accordions/accordion/RuiAccordion.vue3.js +0 -18
  77. package/dist/components/accordions/accordion/RuiAccordion.vue3.js.map +0 -1
@@ -0,0 +1,38 @@
1
+ import type { ComputedRef, Ref, WritableComputedRef } from 'vue';
2
+ import type { SegmentData } from '../../components/date-time-picker/types.js';
3
+ import type { TimeAccuracy } from '../../consts/time-accuracy.js';
4
+ import { type Dayjs } from 'dayjs';
5
+ type DateTimeModelType = 'date' | 'epoch-ms' | 'epoch';
6
+ type ModelValueType<T extends DateTimeModelType> = T extends 'date' ? Date | undefined : T extends 'epoch-ms' ? number | undefined : T extends 'epoch' ? number | undefined : Date | number | undefined;
7
+ interface DateTimeSelectionOptions<T extends DateTimeModelType> {
8
+ modelValue: Ref<ModelValueType<T>>;
9
+ type: T;
10
+ accuracy: TimeAccuracy;
11
+ minDate: Date | number | undefined;
12
+ maxDate: Date | number | 'now' | undefined;
13
+ allowEmpty: boolean;
14
+ }
15
+ interface DateTimeSelectionReturn {
16
+ selectedYear: Ref<number | undefined>;
17
+ selectedMonth: Ref<number | undefined>;
18
+ selectedDay: Ref<number | undefined>;
19
+ selectedHour: Ref<number | undefined>;
20
+ selectedMinute: Ref<number | undefined>;
21
+ selectedSecond: Ref<number | undefined>;
22
+ selectedMillisecond: Ref<number | undefined>;
23
+ selectedTimezone: Ref<string | undefined>;
24
+ selectedDate: WritableComputedRef<Date | undefined>;
25
+ selectedTime: WritableComputedRef<Date | undefined>;
26
+ valueSet: ComputedRef<boolean>;
27
+ internalErrorMessages: Ref<string[]>;
28
+ now: Ref<Dayjs>;
29
+ segmentData: SegmentData;
30
+ minAllowedDate: ComputedRef<Date>;
31
+ maxAllowedDate: ComputedRef<Date | undefined>;
32
+ getDateTime: () => Dayjs;
33
+ setNow: () => void;
34
+ clear: () => void;
35
+ isDateValid: (date: Dayjs) => boolean;
36
+ }
37
+ export declare function useDateTimeSelection<T extends DateTimeModelType>(options: DateTimeSelectionOptions<T>): DateTimeSelectionReturn;
38
+ export {};
@@ -0,0 +1,286 @@
1
+ import dayjs from "dayjs";
2
+ import { guessTimezone, includeSeconds, includeMilliseconds } from "./utils.js";
3
+ import { useRuiI8n } from "../../composables/use-rui-i18n.js";
4
+ import { RUI_I18N_KEYS } from "../../i18n/keys.js";
5
+ import { ref, computed, watch, onMounted, nextTick } from "vue";
6
+ import { get, set } from "@vueuse/shared";
7
+ import { isDefined, watchIgnorable } from "@vueuse/core";
8
+ const MILLISECONDS = 1e3;
9
+ function useDateTimeSelection(options) {
10
+ const {
11
+ accuracy,
12
+ allowEmpty,
13
+ maxDate,
14
+ minDate,
15
+ modelValue,
16
+ type
17
+ } = options;
18
+ const { t } = useRuiI8n();
19
+ const selectedYear = ref();
20
+ const selectedMonth = ref();
21
+ const selectedDay = ref();
22
+ const selectedHour = ref();
23
+ const selectedMinute = ref();
24
+ const selectedSecond = ref();
25
+ const selectedMillisecond = ref();
26
+ const selectedTimezone = ref(guessTimezone());
27
+ const internalErrorMessages = ref([]);
28
+ const now = ref(dayjs.tz(void 0, guessTimezone()));
29
+ const minAllowedDate = computed(() => {
30
+ if (minDate === void 0) {
31
+ return new Date(1970, 0, 1);
32
+ }
33
+ if (type === "epoch" && typeof minDate === "number") {
34
+ return new Date(minDate * MILLISECONDS);
35
+ }
36
+ return new Date(minDate);
37
+ });
38
+ const maxAllowedDate = computed(() => {
39
+ if (maxDate === void 0) {
40
+ return void 0;
41
+ }
42
+ if (maxDate === "now") {
43
+ return get(now).toDate();
44
+ }
45
+ if (type === "epoch" && typeof maxDate === "number") {
46
+ return new Date(maxDate * MILLISECONDS);
47
+ }
48
+ return new Date(maxDate);
49
+ });
50
+ const segmentData = {
51
+ DD: selectedDay,
52
+ HH: selectedHour,
53
+ MM: selectedMonth,
54
+ SSS: selectedMillisecond,
55
+ YYYY: selectedYear,
56
+ mm: selectedMinute,
57
+ ss: selectedSecond
58
+ };
59
+ const selectedDate = computed({
60
+ get() {
61
+ if (!(isDefined(selectedYear) && isDefined(selectedMonth) && isDefined(selectedDay))) {
62
+ return void 0;
63
+ }
64
+ const date = /* @__PURE__ */ new Date();
65
+ date.setFullYear(get(selectedYear));
66
+ date.setDate(1);
67
+ date.setMonth(get(selectedMonth) - 1);
68
+ date.setDate(get(selectedDay));
69
+ return date;
70
+ },
71
+ set(value) {
72
+ set(selectedYear, value?.getFullYear());
73
+ set(selectedMonth, value ? value.getMonth() + 1 : void 0);
74
+ set(selectedDay, value?.getDate());
75
+ }
76
+ });
77
+ const selectedTime = computed({
78
+ get() {
79
+ if (!(isDefined(selectedHour) && isDefined(selectedMinute))) {
80
+ return void 0;
81
+ }
82
+ const date = /* @__PURE__ */ new Date();
83
+ date.setHours(
84
+ get(selectedHour),
85
+ get(selectedMinute),
86
+ get(selectedSecond) ?? 0,
87
+ get(selectedMillisecond) ?? 0
88
+ );
89
+ return date;
90
+ },
91
+ set(value) {
92
+ set(selectedHour, value?.getHours());
93
+ set(selectedMinute, value?.getMinutes());
94
+ set(selectedSecond, value?.getSeconds());
95
+ set(selectedMillisecond, value?.getMilliseconds());
96
+ }
97
+ });
98
+ const valueSet = computed(() => isDefined(selectedDate) && isDefined(selectedTime));
99
+ function getDateTime() {
100
+ let dateTime = dayjs();
101
+ if (isDefined(selectedYear)) {
102
+ dateTime = dateTime.year(get(selectedYear));
103
+ }
104
+ if (isDefined(selectedMonth)) {
105
+ dateTime = dateTime.month(get(selectedMonth) - 1);
106
+ }
107
+ if (isDefined(selectedDay)) {
108
+ const daysInMonth = dateTime.daysInMonth();
109
+ const day = Math.min(get(selectedDay), daysInMonth);
110
+ dateTime = dateTime.date(day);
111
+ }
112
+ if (isDefined(selectedHour)) {
113
+ dateTime = dateTime.hour(get(selectedHour));
114
+ }
115
+ if (isDefined(selectedMinute)) {
116
+ dateTime = dateTime.minute(get(selectedMinute));
117
+ }
118
+ if (isDefined(selectedSecond)) {
119
+ dateTime = dateTime.second(get(selectedSecond));
120
+ }
121
+ if (isDefined(selectedMillisecond)) {
122
+ dateTime = dateTime.millisecond(get(selectedMillisecond));
123
+ }
124
+ return dateTime;
125
+ }
126
+ function isDateValid(date) {
127
+ const min = get(minAllowedDate);
128
+ const max = get(maxAllowedDate);
129
+ set(internalErrorMessages, []);
130
+ if (min && date.isBefore(min)) {
131
+ const errorMessage = t(RUI_I18N_KEYS.dateTimePicker.dateBeforeMin, {
132
+ date: min.toLocaleDateString()
133
+ }, `Date cannot be before ${min.toLocaleDateString()}`);
134
+ set(internalErrorMessages, [...get(internalErrorMessages), errorMessage]);
135
+ return false;
136
+ }
137
+ if (max && date.isAfter(max)) {
138
+ const nowError = t(RUI_I18N_KEYS.dateTimePicker.dateInFuture, "The selected date cannot be in the future");
139
+ const maxError = t(RUI_I18N_KEYS.dateTimePicker.dateAfterMax, { date: max.toLocaleDateString() }, `Date cannot be after ${max.toLocaleDateString()}`);
140
+ const errorMessage = maxDate === "now" ? nowError : maxError;
141
+ set(internalErrorMessages, [...get(internalErrorMessages), errorMessage]);
142
+ return false;
143
+ }
144
+ return true;
145
+ }
146
+ function emitUpdate(updatedModel) {
147
+ const typeMap = {
148
+ "date": () => updatedModel.toDate(),
149
+ "epoch": () => updatedModel.valueOf() / MILLISECONDS,
150
+ "epoch-ms": () => updatedModel.valueOf()
151
+ };
152
+ set(modelValue, typeMap[type]());
153
+ }
154
+ function updateModelValue() {
155
+ if (!isDefined(selectedDate) || !isDefined(selectedTime)) {
156
+ return;
157
+ }
158
+ if (!(isDefined(selectedDate) && isDefined(selectedTime))) {
159
+ set(modelValue, void 0);
160
+ } else {
161
+ const date = get(selectedDate);
162
+ const time = get(selectedTime);
163
+ const updatedModel = dayjs.tz(isDefined(modelValue) ? get(modelValue) : void 0, get(selectedTimezone)).year(date.getFullYear()).month(date.getMonth()).date(date.getDate()).hour(time.getHours()).minute(time.getMinutes()).second(includeSeconds(accuracy) ? time.getSeconds() : 0).millisecond(includeMilliseconds(accuracy) ? time.getMilliseconds() : 0);
164
+ if (!isDateValid(updatedModel)) {
165
+ return;
166
+ }
167
+ emitUpdate(updatedModel);
168
+ }
169
+ }
170
+ function clear() {
171
+ set(internalErrorMessages, []);
172
+ set(selectedYear, void 0);
173
+ set(selectedMonth, void 0);
174
+ set(selectedDay, void 0);
175
+ set(selectedHour, void 0);
176
+ set(selectedMinute, void 0);
177
+ set(selectedSecond, void 0);
178
+ set(selectedMillisecond, void 0);
179
+ set(modelValue, void 0);
180
+ }
181
+ function setNow() {
182
+ set(internalErrorMessages, []);
183
+ const date = dayjs();
184
+ set(now, date);
185
+ set(selectedYear, date.year());
186
+ set(selectedMonth, date.month() + 1);
187
+ set(selectedDay, date.date());
188
+ set(selectedHour, date.hour());
189
+ set(selectedMinute, date.minute());
190
+ set(selectedSecond, includeSeconds(accuracy) ? date.second() : 0);
191
+ set(selectedMillisecond, includeMilliseconds(accuracy) ? date.millisecond() : 0);
192
+ nextTick(() => {
193
+ updateModelValue();
194
+ });
195
+ }
196
+ function updateSegments(date) {
197
+ const year = date.year();
198
+ const month = date.month() + 1;
199
+ const day = date.date();
200
+ const hour = date.hour();
201
+ const minute = date.minute();
202
+ const second = includeSeconds(accuracy) ? date.second() : void 0;
203
+ const millisecond = includeMilliseconds(accuracy) ? date.millisecond() : void 0;
204
+ if (get(selectedYear) !== year)
205
+ set(selectedYear, year);
206
+ if (get(selectedMonth) !== month)
207
+ set(selectedMonth, month);
208
+ if (get(selectedDay) !== day)
209
+ set(selectedDay, day);
210
+ if (get(selectedHour) !== hour)
211
+ set(selectedHour, hour);
212
+ if (get(selectedMinute) !== minute)
213
+ set(selectedMinute, minute);
214
+ if (get(selectedSecond) !== second)
215
+ set(selectedSecond, second);
216
+ if (get(selectedMillisecond) !== millisecond)
217
+ set(selectedMillisecond, millisecond);
218
+ }
219
+ const { ignoreUpdates } = watchIgnorable([selectedDate, selectedTime], ([newSelectedDate, newSelectedTime], [prevSelectedDate, prevSelectedTime]) => {
220
+ const currentTimezone = get(selectedTimezone);
221
+ const newDate = dayjs.tz(newSelectedDate, currentTimezone);
222
+ const oldDate = dayjs.tz(prevSelectedDate, currentTimezone);
223
+ const newTime = dayjs.tz(newSelectedTime, currentTimezone);
224
+ const oldTime = dayjs.tz(prevSelectedTime, currentTimezone);
225
+ if (newDate.isSame(oldDate) && newTime.isSame(oldTime)) {
226
+ return;
227
+ }
228
+ set(now, dayjs());
229
+ updateModelValue();
230
+ });
231
+ function updateInternalModel(value) {
232
+ ignoreUpdates(() => {
233
+ const updatedValue = type === "epoch" && typeof value === "number" ? value * MILLISECONDS : value;
234
+ const date = dayjs.tz(updatedValue, get(selectedTimezone));
235
+ isDateValid(date);
236
+ updateSegments(date);
237
+ });
238
+ }
239
+ watch(selectedTimezone, (newTimezone) => {
240
+ if (newTimezone && isDefined(selectedDate) && isDefined(selectedTime)) {
241
+ set(now, dayjs());
242
+ updateModelValue();
243
+ }
244
+ });
245
+ watch(modelValue, (value) => {
246
+ set(now, dayjs());
247
+ if (value === void 0) {
248
+ clear();
249
+ } else {
250
+ updateInternalModel(value);
251
+ }
252
+ });
253
+ onMounted(() => {
254
+ if (isDefined(modelValue)) {
255
+ updateInternalModel(get(modelValue));
256
+ } else if (!allowEmpty) {
257
+ setNow();
258
+ }
259
+ });
260
+ return {
261
+ clear,
262
+ getDateTime,
263
+ internalErrorMessages,
264
+ isDateValid,
265
+ maxAllowedDate,
266
+ minAllowedDate,
267
+ now,
268
+ segmentData,
269
+ selectedDate,
270
+ selectedDay,
271
+ selectedHour,
272
+ selectedMillisecond,
273
+ selectedMinute,
274
+ selectedMonth,
275
+ selectedSecond,
276
+ selectedTime,
277
+ selectedTimezone,
278
+ selectedYear,
279
+ setNow,
280
+ valueSet
281
+ };
282
+ }
283
+ export {
284
+ useDateTimeSelection
285
+ };
286
+ //# sourceMappingURL=use-date-time-selection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-date-time-selection.js","sources":["../../../src/components/date-time-picker/use-date-time-selection.ts"],"sourcesContent":["import type { ComputedRef, Ref, WritableComputedRef } from 'vue';\nimport type { SegmentData } from '@/components/date-time-picker/types';\nimport type { TimeAccuracy } from '@/consts/time-accuracy';\nimport dayjs, { type Dayjs } from 'dayjs';\nimport { guessTimezone, includeMilliseconds, includeSeconds } from '@/components/date-time-picker/utils';\nimport { useRuiI8n } from '@/composables/use-rui-i18n';\nimport { RUI_I18N_KEYS } from '@/i18n/keys';\n\ntype DateTimeModelType = 'date' | 'epoch-ms' | 'epoch';\n\ntype ModelValueType<T extends DateTimeModelType> =\n T extends 'date' ? Date | undefined :\n T extends 'epoch-ms' ? number | undefined :\n T extends 'epoch' ? number | undefined :\n Date | number | undefined;\n\ninterface DateTimeSelectionOptions<T extends DateTimeModelType> {\n modelValue: Ref<ModelValueType<T>>;\n type: T;\n accuracy: TimeAccuracy;\n minDate: Date | number | undefined;\n maxDate: Date | number | 'now' | undefined;\n allowEmpty: boolean;\n}\n\ninterface DateTimeSelectionReturn {\n selectedYear: Ref<number | undefined>;\n selectedMonth: Ref<number | undefined>;\n selectedDay: Ref<number | undefined>;\n selectedHour: Ref<number | undefined>;\n selectedMinute: Ref<number | undefined>;\n selectedSecond: Ref<number | undefined>;\n selectedMillisecond: Ref<number | undefined>;\n selectedTimezone: Ref<string | undefined>;\n selectedDate: WritableComputedRef<Date | undefined>;\n selectedTime: WritableComputedRef<Date | undefined>;\n valueSet: ComputedRef<boolean>;\n internalErrorMessages: Ref<string[]>;\n now: Ref<Dayjs>;\n segmentData: SegmentData;\n minAllowedDate: ComputedRef<Date>;\n maxAllowedDate: ComputedRef<Date | undefined>;\n getDateTime: () => Dayjs;\n setNow: () => void;\n clear: () => void;\n isDateValid: (date: Dayjs) => boolean;\n}\n\nconst MILLISECONDS = 1000;\n\nexport function useDateTimeSelection<T extends DateTimeModelType>(\n options: DateTimeSelectionOptions<T>,\n): DateTimeSelectionReturn {\n const {\n accuracy,\n allowEmpty,\n maxDate,\n minDate,\n modelValue,\n type,\n } = options;\n\n const { t } = useRuiI8n();\n\n const selectedYear = ref<number | undefined>();\n const selectedMonth = ref<number | undefined>();\n const selectedDay = ref<number | undefined>();\n\n const selectedHour = ref<number | undefined>();\n const selectedMinute = ref<number | undefined>();\n const selectedSecond = ref<number | undefined>();\n const selectedMillisecond = ref<number | undefined>();\n const selectedTimezone = ref<string | undefined>(guessTimezone());\n\n const internalErrorMessages = ref<string[]>([]);\n const now = ref<Dayjs>(dayjs.tz(undefined, guessTimezone()));\n\n const minAllowedDate = computed<Date>(() => {\n if (minDate === undefined) {\n return new Date(1970, 0, 1);\n }\n\n if (type === 'epoch' && typeof minDate === 'number') {\n return new Date(minDate * MILLISECONDS);\n }\n\n return new Date(minDate);\n });\n\n const maxAllowedDate = computed<Date | undefined>(() => {\n if (maxDate === undefined) {\n return undefined;\n }\n if (maxDate === 'now') {\n return get(now).toDate();\n }\n if (type === 'epoch' && typeof maxDate === 'number') {\n return new Date(maxDate * MILLISECONDS);\n }\n return new Date(maxDate);\n });\n\n const segmentData: SegmentData = {\n DD: selectedDay,\n HH: selectedHour,\n MM: selectedMonth,\n SSS: selectedMillisecond,\n YYYY: selectedYear,\n mm: selectedMinute,\n ss: selectedSecond,\n };\n\n const selectedDate = computed<Date | undefined>({\n get() {\n if (!(isDefined(selectedYear) && isDefined(selectedMonth) && isDefined(selectedDay))) {\n return undefined;\n }\n const date = new Date();\n date.setFullYear(get(selectedYear));\n // Set day to 1 first to prevent month overflow when today's day > days in target month\n // e.g., if today is Dec 30 and we set month to Feb, day 30 would overflow to March\n date.setDate(1);\n date.setMonth(get(selectedMonth) - 1);\n date.setDate(get(selectedDay));\n return date;\n },\n set(value?: Date) {\n set(selectedYear, value?.getFullYear());\n set(selectedMonth, value ? value.getMonth() + 1 : undefined);\n set(selectedDay, value?.getDate());\n },\n });\n\n const selectedTime = computed<Date | undefined>({\n get() {\n if (!(isDefined(selectedHour) && isDefined(selectedMinute))) {\n return undefined;\n }\n const date = new Date();\n date.setHours(\n get(selectedHour),\n get(selectedMinute),\n get(selectedSecond) ?? 0,\n get(selectedMillisecond) ?? 0,\n );\n return date;\n },\n set(value?: Date) {\n set(selectedHour, value?.getHours());\n set(selectedMinute, value?.getMinutes());\n set(selectedSecond, value?.getSeconds());\n set(selectedMillisecond, value?.getMilliseconds());\n },\n });\n\n const valueSet = computed<boolean>(() => isDefined(selectedDate) && isDefined(selectedTime));\n\n function getDateTime(): Dayjs {\n let dateTime = dayjs();\n\n if (isDefined(selectedYear)) {\n dateTime = dateTime.year(get(selectedYear));\n }\n\n if (isDefined(selectedMonth)) {\n dateTime = dateTime.month(get(selectedMonth) - 1);\n }\n\n if (isDefined(selectedDay)) {\n const daysInMonth = dateTime.daysInMonth();\n const day = Math.min(get(selectedDay), daysInMonth);\n dateTime = dateTime.date(day);\n }\n\n if (isDefined(selectedHour)) {\n dateTime = dateTime.hour(get(selectedHour));\n }\n\n if (isDefined(selectedMinute)) {\n dateTime = dateTime.minute(get(selectedMinute));\n }\n\n if (isDefined(selectedSecond)) {\n dateTime = dateTime.second(get(selectedSecond));\n }\n\n if (isDefined(selectedMillisecond)) {\n dateTime = dateTime.millisecond(get(selectedMillisecond));\n }\n\n return dateTime;\n }\n\n function isDateValid(date: Dayjs): boolean {\n const min = get(minAllowedDate);\n const max = get(maxAllowedDate);\n\n set(internalErrorMessages, []);\n\n if (min && date.isBefore(min)) {\n const errorMessage = t(RUI_I18N_KEYS.dateTimePicker.dateBeforeMin, {\n date: min.toLocaleDateString(),\n }, `Date cannot be before ${min.toLocaleDateString()}`);\n set(internalErrorMessages, [...get(internalErrorMessages), errorMessage]);\n return false;\n }\n\n if (max && date.isAfter(max)) {\n const nowError = t(RUI_I18N_KEYS.dateTimePicker.dateInFuture, 'The selected date cannot be in the future');\n const maxError = t(RUI_I18N_KEYS.dateTimePicker.dateAfterMax, { date: max.toLocaleDateString() }, `Date cannot be after ${max.toLocaleDateString()}`);\n const errorMessage = maxDate === 'now' ? nowError : maxError;\n set(internalErrorMessages, [...get(internalErrorMessages), errorMessage]);\n return false;\n }\n\n return true;\n }\n\n function emitUpdate(updatedModel: Dayjs): void {\n const typeMap = {\n 'date': () => updatedModel.toDate(),\n 'epoch': () => updatedModel.valueOf() / MILLISECONDS,\n 'epoch-ms': () => updatedModel.valueOf(),\n } as const;\n\n set(modelValue, typeMap[type]() as ModelValueType<T>);\n }\n\n function updateModelValue(): void {\n if (!isDefined(selectedDate) || !isDefined(selectedTime)) {\n return;\n }\n\n if (!(isDefined(selectedDate) && isDefined(selectedTime))) {\n set(modelValue, undefined as ModelValueType<T>);\n }\n else {\n const date = get(selectedDate);\n const time = get(selectedTime);\n\n const updatedModel = dayjs.tz(isDefined(modelValue) ? get(modelValue) : undefined, get(selectedTimezone))\n .year(date.getFullYear())\n .month(date.getMonth())\n .date(date.getDate())\n .hour(time.getHours())\n .minute(time.getMinutes())\n .second(includeSeconds(accuracy) ? time.getSeconds() : 0)\n .millisecond(includeMilliseconds(accuracy) ? time.getMilliseconds() : 0);\n\n if (!isDateValid(updatedModel)) {\n return;\n }\n\n emitUpdate(updatedModel);\n }\n }\n\n function clear(): void {\n set(internalErrorMessages, []);\n set(selectedYear, undefined);\n set(selectedMonth, undefined);\n set(selectedDay, undefined);\n set(selectedHour, undefined);\n set(selectedMinute, undefined);\n set(selectedSecond, undefined);\n set(selectedMillisecond, undefined);\n set(modelValue, undefined as ModelValueType<T>);\n }\n\n function setNow(): void {\n set(internalErrorMessages, []);\n\n const date = dayjs();\n set(now, date);\n set(selectedYear, date.year());\n set(selectedMonth, date.month() + 1);\n set(selectedDay, date.date());\n set(selectedHour, date.hour());\n set(selectedMinute, date.minute());\n set(selectedSecond, includeSeconds(accuracy) ? date.second() : 0);\n set(selectedMillisecond, includeMilliseconds(accuracy) ? date.millisecond() : 0);\n\n nextTick(() => {\n updateModelValue();\n });\n }\n\n function updateSegments(date: Dayjs): void {\n const year = date.year();\n const month = date.month() + 1;\n const day = date.date();\n const hour = date.hour();\n const minute = date.minute();\n const second = includeSeconds(accuracy) ? date.second() : undefined;\n const millisecond = includeMilliseconds(accuracy) ? date.millisecond() : undefined;\n\n if (get(selectedYear) !== year)\n set(selectedYear, year);\n if (get(selectedMonth) !== month)\n set(selectedMonth, month);\n if (get(selectedDay) !== day)\n set(selectedDay, day);\n if (get(selectedHour) !== hour)\n set(selectedHour, hour);\n if (get(selectedMinute) !== minute)\n set(selectedMinute, minute);\n if (get(selectedSecond) !== second)\n set(selectedSecond, second);\n if (get(selectedMillisecond) !== millisecond)\n set(selectedMillisecond, millisecond);\n }\n\n const { ignoreUpdates } = watchIgnorable([selectedDate, selectedTime], ([newSelectedDate, newSelectedTime], [prevSelectedDate, prevSelectedTime]) => {\n const currentTimezone = get(selectedTimezone);\n const newDate = dayjs.tz(newSelectedDate, currentTimezone);\n const oldDate = dayjs.tz(prevSelectedDate, currentTimezone);\n const newTime = dayjs.tz(newSelectedTime, currentTimezone);\n const oldTime = dayjs.tz(prevSelectedTime, currentTimezone);\n\n if (newDate.isSame(oldDate) && newTime.isSame(oldTime)) {\n return;\n }\n\n set(now, dayjs());\n updateModelValue();\n });\n\n function updateInternalModel(value: ModelValueType<T>): void {\n ignoreUpdates(() => {\n const updatedValue = type === 'epoch' && typeof value === 'number'\n ? value * MILLISECONDS\n : value;\n const date = dayjs.tz(updatedValue, get(selectedTimezone));\n isDateValid(date);\n updateSegments(date);\n });\n }\n\n watch(selectedTimezone, (newTimezone: string | undefined) => {\n if (newTimezone && isDefined(selectedDate) && isDefined(selectedTime)) {\n set(now, dayjs());\n updateModelValue();\n }\n });\n\n watch(modelValue, (value) => {\n set(now, dayjs());\n if (value === undefined) {\n clear();\n }\n else {\n updateInternalModel(value);\n }\n });\n\n onMounted(() => {\n if (isDefined(modelValue)) {\n updateInternalModel(get(modelValue));\n }\n else if (!allowEmpty) {\n setNow();\n }\n });\n\n return {\n clear,\n getDateTime,\n internalErrorMessages,\n isDateValid,\n maxAllowedDate,\n minAllowedDate,\n now,\n segmentData,\n selectedDate,\n selectedDay,\n selectedHour,\n selectedMillisecond,\n selectedMinute,\n selectedMonth,\n selectedSecond,\n selectedTime,\n selectedTimezone,\n selectedYear,\n setNow,\n valueSet,\n };\n}\n"],"names":[],"mappings":"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"}
@@ -22,11 +22,13 @@ interface KeyboardHandlerOptions {
22
22
  export declare function useKeyboardHandler(options: KeyboardHandlerOptions): {
23
23
  clear: (segmentType?: string) => void;
24
24
  getCurrentSegment: (position?: number) => Segment | undefined;
25
+ handleBlur: () => void;
25
26
  handleClick: (event: MouseEvent) => void;
26
27
  handleFocus: () => void;
27
28
  handleInput: (event: Event) => void;
28
29
  handleInputSelection: (event: Event) => void;
29
30
  handleKeyDown: (event: KeyboardEvent) => void;
31
+ handleMouseDown: (event: MouseEvent) => void;
30
32
  handlePaste: (event: ClipboardEvent) => void;
31
33
  setSegment: (segmentType: DateTimeSegmentType) => void;
32
34
  };
@@ -5,6 +5,24 @@ import { assert } from "../../utils/assert.js";
5
5
  import { computed, nextTick } from "vue";
6
6
  import { get, set } from "@vueuse/shared";
7
7
  import { isDefined } from "@vueuse/core";
8
+ const SEGMENT_METHODS = {
9
+ DD: "date",
10
+ HH: "hour",
11
+ MM: "month",
12
+ SSS: "millisecond",
13
+ YYYY: "year",
14
+ mm: "minute",
15
+ ss: "second"
16
+ };
17
+ const SEGMENT_CONFIG = {
18
+ DD: { maxValue: 31, minValue: 1 },
19
+ HH: { maxValue: 23, minValue: 0 },
20
+ MM: { maxValue: 12, minValue: 1 },
21
+ SSS: { maxValue: 999, minValue: 0 },
22
+ YYYY: { maxValue: 9999, minValue: 1 },
23
+ mm: { maxValue: 59, minValue: 0 },
24
+ ss: { maxValue: 59, minValue: 0 }
25
+ };
8
26
  function useKeyboardHandler(options) {
9
27
  const {
10
28
  accuracy,
@@ -81,17 +99,8 @@ function useKeyboardHandler(options) {
81
99
  const currentSegment = getCurrentSegment();
82
100
  if (!currentSegment)
83
101
  return;
84
- const segmentMethods = {
85
- DD: "date",
86
- HH: "hour",
87
- MM: "month",
88
- mm: "minute",
89
- ss: "second",
90
- SSS: "millisecond",
91
- YYYY: "year"
92
- };
93
102
  const segmentType = currentSegment.type;
94
- const method = segmentMethods[segmentType];
103
+ const method = SEGMENT_METHODS[segmentType];
95
104
  const selectedDate = getDateTime();
96
105
  const updatedDate = selectedDate.set(method, selectedDate.get(method) + (increment ? 1 : -1));
97
106
  if (updatedDate.year() >= 1970) {
@@ -127,57 +136,41 @@ function useKeyboardHandler(options) {
127
136
  }
128
137
  }
129
138
  function handleDigitPressed(event, digit) {
130
- if (!(event.target instanceof HTMLInputElement)) {
139
+ if (!(event.target instanceof HTMLInputElement))
131
140
  return;
132
- }
133
141
  const position = event.target.selectionStart ?? 0;
134
142
  const currentSegment = getCurrentSegment(position);
135
- if (!currentSegment)
136
- return;
137
- const number = parseInt(digit);
138
- if (isNaN(number))
143
+ if (!currentSegment || isNaN(parseInt(digit)))
139
144
  return;
140
- const segmentConfig = {
141
- DD: { maxValue: 31, minValue: 1 },
142
- HH: { maxValue: 23, minValue: 0 },
143
- MM: { maxValue: 12, minValue: 1 },
144
- mm: { maxValue: 59, minValue: 0 },
145
- ss: { maxValue: 59, minValue: 0 },
146
- SSS: { maxValue: 999, minValue: 0 },
147
- YYYY: { maxValue: 9999, minValue: 1 }
148
- };
149
145
  const segmentType = currentSegment.type;
150
- if (isDateTimeSegmentType(segmentType)) {
151
- const config = segmentConfig[segmentType];
152
- const value = get(currentValue) ?? "";
153
- const combinedValue = parseInt(`${value}${digit}`);
154
- const nextCombinedValue = parseInt(`${value}${digit}0`);
155
- const maxLength = segmentType.length;
156
- const minValue = config.minValue ?? 0;
157
- if (combinedValue >= minValue && combinedValue <= config.maxValue) {
158
- setValue(segmentType, combinedValue);
159
- setCursorPosition(currentSegment);
160
- }
161
- const willExceedMax = nextCombinedValue > config.maxValue;
162
- const reachedMaxLength = combinedValue.toString().length >= maxLength;
163
- if (willExceedMax || reachedMaxLength) {
164
- navigateSegments("ArrowRight");
165
- }
146
+ if (!isDateTimeSegmentType(segmentType))
147
+ return;
148
+ const config = SEGMENT_CONFIG[segmentType];
149
+ const value = get(currentValue) ?? "";
150
+ const combinedStr = `${value}${digit}`;
151
+ const combinedValue = parseInt(combinedStr);
152
+ const maxLength = segmentType.length;
153
+ const minValue = config.minValue ?? 0;
154
+ if (combinedValue >= minValue && combinedValue <= config.maxValue) {
155
+ setValue(segmentType, combinedValue);
156
+ setCursorPosition(currentSegment);
157
+ } else if (combinedValue < minValue && combinedStr.length < maxLength) {
158
+ set(currentValue, combinedValue);
166
159
  }
160
+ const willExceedMax = parseInt(`${combinedStr}0`) > config.maxValue;
161
+ if (willExceedMax || combinedStr.length >= maxLength)
162
+ navigateSegments("ArrowRight");
167
163
  }
168
164
  function handleKeyboardNavigation(event) {
169
- if (event.key === "ArrowUp") {
165
+ if (event.key === "ArrowUp")
170
166
  changeSegmentValue(true);
171
- } else if (event.key === "ArrowDown") {
167
+ else if (event.key === "ArrowDown")
172
168
  changeSegmentValue(false);
173
- }
174
169
  }
175
170
  function handleBackspace(event) {
176
- if (!(event.target instanceof HTMLInputElement)) {
171
+ if (!(event.target instanceof HTMLInputElement))
177
172
  return;
178
- }
179
- const position = event.target.selectionStart ?? 0;
180
- const currentSegment = getCurrentSegment(position);
173
+ const currentSegment = getCurrentSegment(event.target.selectionStart ?? 0);
181
174
  if (!currentSegment)
182
175
  return;
183
176
  const value = get(currentValue) ?? getCurrent(currentSegment.type) ?? "";
@@ -186,11 +179,9 @@ function useKeyboardHandler(options) {
186
179
  setCursorPosition(currentSegment);
187
180
  }
188
181
  function onInputDeletePressed(event) {
189
- if (!(event.target instanceof HTMLInputElement)) {
182
+ if (!(event.target instanceof HTMLInputElement))
190
183
  return;
191
- }
192
- const selectionStart = event.target.selectionStart ?? 0;
193
- const segment = getCurrentSegment(selectionStart);
184
+ const segment = getCurrentSegment(event.target.selectionStart ?? 0);
194
185
  if (segment) {
195
186
  clear(segment.type);
196
187
  setCursorPosition(segment);
@@ -200,21 +191,19 @@ function useKeyboardHandler(options) {
200
191
  if (disabled || readonly)
201
192
  return;
202
193
  const { key } = event;
203
- if (["Tab"].includes(key)) {
194
+ if (key === "Tab")
204
195
  return;
205
- }
206
196
  event.preventDefault();
207
- if (key === "ArrowRight" || key === "ArrowLeft") {
197
+ if (key === "ArrowRight" || key === "ArrowLeft")
208
198
  navigateSegments(key);
209
- } else if (key === "ArrowUp" || key === "ArrowDown") {
199
+ else if (key === "ArrowUp" || key === "ArrowDown")
210
200
  handleKeyboardNavigation(event);
211
- } else if (key === "Backspace") {
201
+ else if (key === "Backspace")
212
202
  handleBackspace(event);
213
- } else if (key === "Delete") {
203
+ else if (key === "Delete")
214
204
  onInputDeletePressed(event);
215
- } else if (/^\d$/.test(key)) {
205
+ else if (/^\d$/.test(key))
216
206
  handleDigitPressed(event, key);
217
- }
218
207
  }
219
208
  function getClickPosition(event, input, useCaretPosition) {
220
209
  const fallback = input.selectionStart ?? 0;
@@ -223,11 +212,21 @@ function useKeyboardHandler(options) {
223
212
  return caretPos.offset;
224
213
  return document.caretRangeFromPoint?.(event.clientX, event.clientY)?.startOffset ?? fallback;
225
214
  }
215
+ let clickedSegment;
216
+ function handleMouseDown(event) {
217
+ if (disabled || readonly || !(event.target instanceof HTMLInputElement))
218
+ return;
219
+ const currentSegment = getCurrentSegment(getClickPosition(event, event.target));
220
+ if (currentSegment) {
221
+ clickedSegment = currentSegment;
222
+ }
223
+ }
226
224
  function handleClick(event) {
227
225
  if (disabled || readonly || !(event.target instanceof HTMLInputElement))
228
226
  return;
229
227
  const currentSegment = getCurrentSegment(getClickPosition(event, event.target));
230
228
  if (currentSegment) {
229
+ clickedSegment = currentSegment;
231
230
  set(cursorPosition, currentSegment.end);
232
231
  event.target.setSelectionRange(currentSegment.start, currentSegment.end);
233
232
  }
@@ -237,6 +236,11 @@ function useKeyboardHandler(options) {
237
236
  set(cursorPosition, target.selectionStart ?? 0);
238
237
  }
239
238
  function handleFocus() {
239
+ if (clickedSegment) {
240
+ setCursorPosition(clickedSegment);
241
+ clickedSegment = void 0;
242
+ return;
243
+ }
240
244
  const input = get(textInput);
241
245
  if (input && input.selectionStart !== input.selectionEnd)
242
246
  return;
@@ -244,6 +248,11 @@ function useKeyboardHandler(options) {
244
248
  if (firstSegment)
245
249
  setCursorPosition(firstSegment);
246
250
  }
251
+ function handleBlur() {
252
+ set(cursorPosition, 0);
253
+ set(currentValue, void 0);
254
+ clickedSegment = void 0;
255
+ }
247
256
  function parseAndSetDateValues(pastedText) {
248
257
  try {
249
258
  const parsedDate = dayjs(pastedText, get(dateFormat));
@@ -293,11 +302,13 @@ function useKeyboardHandler(options) {
293
302
  return {
294
303
  clear,
295
304
  getCurrentSegment,
305
+ handleBlur,
296
306
  handleClick,
297
307
  handleFocus,
298
308
  handleInput,
299
309
  handleInputSelection,
300
310
  handleKeyDown,
311
+ handleMouseDown,
301
312
  handlePaste,
302
313
  setSegment
303
314
  };