@rotki/ui-library 2.22.1 → 2.23.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/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/buttons/button/RuiButton.vue.d.ts +1 -1
- package/dist/components/buttons/button/button-styles.js +1 -1
- package/dist/components/buttons/button/button-styles.js.map +1 -1
- package/dist/components/buttons/button-group/RuiButtonGroup.js.map +1 -1
- package/dist/components/buttons/button-group/RuiButtonGroup.vue.d.ts +1 -1
- package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/RuiCalendar.js.map +1 -1
- package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js +3 -1
- package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/RuiCalendarGrid.js.map +1 -1
- package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js +121 -25
- package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js +11 -4
- package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePicker.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePicker.vue.d.ts +23 -1
- package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js +136 -24
- package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePickerMenu.js.map +1 -1
- package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue.d.ts +7 -0
- package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js +70 -25
- package/dist/components/date-time-picker/RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-time-picker/RuiTimezoneSelect.js.map +1 -1
- package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js +7 -3
- package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/date-time-picker/segment-utils.d.ts +28 -0
- package/dist/components/date-time-picker/segment-utils.js +42 -1
- package/dist/components/date-time-picker/segment-utils.js.map +1 -1
- package/dist/components/date-time-picker/types.d.ts +2 -0
- package/dist/components/date-time-picker/types.js.map +1 -1
- package/dist/components/date-time-picker/use-date-time-selection.d.ts +6 -0
- package/dist/components/date-time-picker/use-date-time-selection.js +65 -42
- package/dist/components/date-time-picker/use-date-time-selection.js.map +1 -1
- package/dist/components/date-time-picker/use-keyboard-handler.js +4 -3
- package/dist/components/date-time-picker/use-keyboard-handler.js.map +1 -1
- package/dist/components/date-time-picker/utils.d.ts +5 -0
- package/dist/components/date-time-picker/utils.js +12 -1
- package/dist/components/date-time-picker/utils.js.map +1 -1
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue.d.ts +1 -1
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js +2 -5
- package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/category-picker/RuiCategoryPicker.vue.d.ts +1 -1
- package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js +3 -2
- package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/checkbox/RuiCheckbox.vue.d.ts +1 -1
- package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue.d.ts +1 -1
- package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/radio-button/radio/RuiRadio.vue.d.ts +1 -1
- package/dist/components/forms/radio-button/radio-group/RuiRadioGroup.vue.d.ts +1 -1
- package/dist/components/forms/select/RuiMenuSelect.vue.d.ts +1 -1
- package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/RuiDataTable.vue.d.ts +1 -1
- package/dist/components/tables/RuiTableHead.vue.d.ts +1 -1
- package/dist/components/tables/data-table/RuiDataTableBody.vue.d.ts +1 -1
- package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js +2 -8
- package/dist/components/tables/data-table/RuiDataTableBody.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/data-table/RuiDataTableCell.vue.d.ts +1 -1
- package/dist/components/tables/data-table/RuiDataTableExpandedRow.vue.d.ts +1 -1
- package/dist/components/tables/data-table/RuiDataTableGroupRow.vue.d.ts +1 -1
- package/dist/components/tables/data-table/RuiDataTableMobileSort.vue.d.ts +1 -1
- package/dist/components/tables/data-table/RuiDataTableRow.vue.d.ts +1 -1
- package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js +1 -2
- package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/tables/use-pagination-navigation.js.map +1 -1
- package/dist/components/tabs/tab-items/RuiTabItems.vue.d.ts +1 -1
- package/dist/components/tabs/tabs/use-tab-scroll.js +2 -1
- package/dist/components/tabs/tabs/use-tab-scroll.js.map +1 -1
- package/dist/composables/forms/auto-complete/search.d.ts +1 -2
- package/dist/composables/forms/auto-complete/search.js.map +1 -1
- package/dist/composables/forms/auto-complete/value.d.ts +1 -2
- package/dist/composables/forms/auto-complete/value.js.map +1 -1
- package/dist/i18n/keys.d.ts +10 -0
- package/dist/i18n/keys.js +15 -5
- package/dist/i18n/keys.js.map +1 -1
- package/dist/icons/icons_1.d.ts +1 -1
- package/dist/icons/icons_1.js +25 -22
- package/dist/icons/icons_1.js.map +1 -1
- package/dist/icons/icons_2.d.ts +7 -7
- package/dist/icons/icons_2.js +126 -92
- package/dist/icons/icons_2.js.map +1 -1
- package/dist/icons/icons_3.d.ts +12 -12
- package/dist/icons/icons_3.js +119 -177
- package/dist/icons/icons_3.js.map +1 -1
- package/dist/icons/icons_4.d.ts +26 -26
- package/dist/icons/icons_4.js +320 -285
- package/dist/icons/icons_4.js.map +1 -1
- package/dist/icons/icons_5.d.ts +13 -1
- package/dist/icons/icons_5.js +149 -9
- package/dist/icons/icons_5.js.map +1 -1
- package/dist/icons/index.d.ts +1 -1
- package/dist/icons/index.js +34 -22
- package/dist/icons/index.js.map +1 -1
- package/dist/index.js +7 -7
- package/dist/style.css +26 -762
- package/dist/web-types.json +75 -10
- package/package.json +32 -32
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/date-time-picker/RuiDateTimePickerMenu.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { TimeAccuracy } from '@/consts/time-accuracy';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiCalendar from '@/components/calendar/RuiCalendar.vue';\nimport RuiTimezoneSelect from '@/components/date-time-picker/RuiTimezoneSelect.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport RuiTimePicker, { type TimePickerSelection } from '@/components/time-picker/RuiTimePicker.vue';\n\ndefineOptions({\n name: 'RuiDateTimePickerMenu',\n});\n\nconst selectedDate = defineModel<Date | undefined>('selectedDate', { required: true });\nconst selectedTime = defineModel<Date | undefined>('selectedTime', { required: true });\nconst selectedHour = defineModel<number | undefined>('selectedHour', { required: true });\nconst selectedMinute = defineModel<number | undefined>('selectedMinute', { required: true });\nconst selectedSecond = defineModel<number | undefined>('selectedSecond', { required: true });\nconst selectedMillisecond = defineModel<number | undefined>('selectedMillisecond', { required: true });\nconst timeSelection = defineModel<TimePickerSelection>('timeSelection', { required: true });\nconst selectedTimezone = defineModel<string | undefined>('selectedTimezone', { required: true });\nconst calendarMenuOpen = defineModel<boolean>('calendarMenuOpen', { required: true });\n\
|
|
1
|
+
{"version":3,"file":"RuiDateTimePickerMenu.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../src/components/date-time-picker/RuiDateTimePickerMenu.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { DateTimePickerAction } from '@/components/date-time-picker/types';\nimport type { TimeAccuracy } from '@/consts/time-accuracy';\nimport RuiButton from '@/components/buttons/button/RuiButton.vue';\nimport RuiCalendar from '@/components/calendar/RuiCalendar.vue';\nimport RuiTimezoneSelect from '@/components/date-time-picker/RuiTimezoneSelect.vue';\nimport RuiIcon from '@/components/icons/RuiIcon.vue';\nimport RuiTimePicker, { type TimePickerSelection } from '@/components/time-picker/RuiTimePicker.vue';\nimport { useRuiI8n } from '@/composables/use-rui-i18n';\nimport { RUI_I18N_KEYS } from '@/i18n/keys';\n\ndefineOptions({\n name: 'RuiDateTimePickerMenu',\n});\n\nconst selectedDate = defineModel<Date | undefined>('selectedDate', { required: true });\nconst selectedTime = defineModel<Date | undefined>('selectedTime', { required: true });\nconst selectedHour = defineModel<number | undefined>('selectedHour', { required: true });\nconst selectedMinute = defineModel<number | undefined>('selectedMinute', { required: true });\nconst selectedSecond = defineModel<number | undefined>('selectedSecond', { required: true });\nconst selectedMillisecond = defineModel<number | undefined>('selectedMillisecond', { required: true });\nconst timeSelection = defineModel<TimePickerSelection>('timeSelection', { required: true });\nconst selectedTimezone = defineModel<string | undefined>('selectedTimezone', { required: true });\nconst calendarMenuOpen = defineModel<boolean>('calendarMenuOpen', { required: true });\n\nconst { actions = [] } = defineProps<{\n accuracy: TimeAccuracy;\n actions?: DateTimePickerAction[];\n maxDate?: Date | number;\n minDate?: Date | number;\n showTimezone?: boolean;\n}>();\n\nconst emit = defineEmits<{\n 'set-now': [];\n 'set-today': [];\n 'clear': [];\n}>();\n\ndefineSlots<{\n default: () => any;\n}>();\n\nconst { t } = useRuiI8n();\n\nconst keys = RUI_I18N_KEYS.dateTimePicker;\n\ninterface ActionConfig {\n id: DateTimePickerAction;\n icon: 'lu-clock' | 'lu-calendar-days' | 'lu-x';\n label: string;\n handler: () => void;\n}\n\nconst actionConfig = computed<ActionConfig[]>(() => {\n const available: Record<DateTimePickerAction, ActionConfig> = {\n clear: {\n handler: () => emit('clear'),\n icon: 'lu-x',\n id: 'clear',\n label: t(keys.clear, 'Clear'),\n },\n now: {\n handler: () => emit('set-now'),\n icon: 'lu-clock',\n id: 'now',\n label: t(keys.now, 'Now'),\n },\n today: {\n handler: () => emit('set-today'),\n icon: 'lu-calendar-days',\n id: 'today',\n label: t(keys.today, 'Today'),\n },\n };\n\n return actions.map(action => available[action]).filter(Boolean);\n});\n</script>\n\n<template>\n <div class=\"flex flex-col\">\n <div class=\"flex divide-x divide-rui-grey-200 dark:divide-rui-grey-800\">\n <RuiCalendar\n v-model=\"selectedDate\"\n v-model:menu-open=\"calendarMenuOpen\"\n borderless\n :max-date=\"maxDate\"\n :min-date=\"minDate\"\n />\n <RuiTimePicker\n v-model=\"selectedTime\"\n v-model:hour=\"selectedHour\"\n v-model:minute=\"selectedMinute\"\n v-model:second=\"selectedSecond\"\n v-model:millisecond=\"selectedMillisecond\"\n v-model:selection=\"timeSelection\"\n :accuracy=\"accuracy\"\n borderless\n />\n <div v-if=\"showTimezone || $slots.default\">\n <div\n v-if=\"showTimezone\"\n class=\"p-4 pl-3\"\n >\n <RuiTimezoneSelect\n v-model=\"selectedTimezone\"\n data-id=\"timezone-select\"\n hide-details\n class=\"pt-0 pr-0\"\n />\n </div>\n <slot />\n </div>\n </div>\n <div\n v-if=\"actionConfig.length > 0\"\n data-id=\"actions\"\n class=\"flex justify-end gap-1 px-3 py-2 border-t border-rui-grey-200 dark:border-rui-grey-800\"\n >\n <RuiButton\n v-for=\"action in actionConfig\"\n :key=\"action.id\"\n variant=\"text\"\n size=\"sm\"\n color=\"primary\"\n :data-id=\"`action-${action.id}`\"\n @click=\"action.handler()\"\n >\n <template #prepend>\n <RuiIcon\n :name=\"action.icon\"\n size=\"16\"\n />\n </template>\n {{ action.label }}\n </RuiButton>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAeA,MAAM,eAAe,SAA6B,SAAC,cAAkC;EACrF,MAAM,eAAe,SAA6B,SAAC,cAAkC;EACrF,MAAM,eAAe,SAA+B,SAAC,cAAkC;EACvF,MAAM,iBAAiB,SAA+B,SAAC,gBAAoC;EAC3F,MAAM,iBAAiB,SAA+B,SAAC,gBAAoC;EAC3F,MAAM,sBAAsB,SAA+B,SAAC,qBAAyC;EACrG,MAAM,gBAAgB,SAAgC,SAAC,eAAmC;EAC1F,MAAM,mBAAmB,SAA+B,SAAC,kBAAsC;EAC/F,MAAM,mBAAmB,SAAoB,SAAC,kBAAsC;EAUpF,MAAM,OAAO;EAUb,MAAM,EAAE,MAAM,UAAU;EAExB,MAAM,OAAO,cAAc;EAS3B,MAAM,eAAe,eAA+B;GAClD,MAAM,YAAwD;IAC5D,OAAO;KACL,eAAe,KAAK,OAAO;KAC3B,MAAM;KACN,IAAI;KACJ,OAAO,EAAE,KAAK,OAAO,OAAO;IAC9B;IACA,KAAK;KACH,eAAe,KAAK,SAAS;KAC7B,MAAM;KACN,IAAI;KACJ,OAAO,EAAE,KAAK,KAAK,KAAK;IAC1B;IACA,OAAO;KACL,eAAe,KAAK,WAAW;KAC/B,MAAM;KACN,IAAI;KACJ,OAAO,EAAE,KAAK,OAAO,OAAO;IAC9B;GACF;GAEA,OAAO,QAAA,QAAQ,KAAI,WAAU,UAAU,OAAO,CAAC,CAAC,OAAO,OAAO;EAChE,CAAC;;uBAIC,mBAyDM,OAzDN,YAyDM,CAxDJ,mBAgCM,OAhCN,YAgCM;IA/BJ,YAME,qBAAA;iBALS,aAAA;+EAAY,QAAA;KACb,aAAW,iBAAA;iFAAgB,QAAA;KACnC,YAAA;KACC,YAAU,QAAA;KACV,YAAU,QAAA;;;;;;;IAEb,YASE,uBAAA;iBARS,aAAA;+EAAY,QAAA;KACb,MAAM,aAAA;yEAAY,QAAA;KAClB,QAAQ,eAAA;6EAAc,QAAA;KACtB,QAAQ,eAAA;6EAAc,QAAA;KACtB,aAAa,oBAAA;uFAAmB,QAAA;KAChC,WAAW,cAAA;+EAAa,QAAA;KAC/B,UAAU,QAAA;KACX,YAAA;;;;;;;;;;IAES,QAAA,gBAAgBA,KAAAA,OAAO,WAAA,UAAA,GAAlC,mBAaM,OAAA,YAAA,CAXI,QAAA,gBAAA,UAAA,GADR,mBAUM,OAVN,YAUM,CANJ,YAKE,2BAAA;iBAJS,iBAAA;mFAAgB,QAAA;KACzB,WAAQ;KACR,gBAAA;KACA,OAAM;mEAGV,WAAQ,KAAA,QAAA,SAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;OAIJ,MAAA,YAAA,CAAY,CAAC,SAAM,KAAA,UAAA,GAD3B,mBAsBM,OAtBN,YAsBM,EAAA,UAAA,IAAA,GAjBJ,mBAgBY,UAAA,MAAA,WAfO,MAAA,YAAA,IAAV,WAAM;wBADf,YAgBY,mBAAA;KAdT,KAAK,OAAO;KACb,SAAQ;KACR,MAAK;KACL,OAAM;KACL,WAAO,UAAY,OAAO;KAC1B,UAAK,WAAE,OAAO,QAAO;;KAEX,SAAO,cAId,CAHF,YAGE,iBAAA;MAFC,MAAM,OAAO;MACd,MAAK;;4BAGT,CAAA,gBADW,MACX,gBAAG,OAAO,KAAK,GAAA,CAAA,CAAA,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuiTimezoneSelect.js","names":[],"sources":["../../../src/components/date-time-picker/RuiTimezoneSelect.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { AutoCompleteVariant } from '@/components/forms/auto-complete/auto-complete-styles';\nimport type { MenuProps } from '@/components/overlays/menu/RuiMenu.vue';\nimport { timezones } from '@/components/date-time-picker/timezones';\nimport RuiAutoComplete, { type RuiAutoCompleteClassNames } from '@/components/forms/auto-complete/RuiAutoComplete.vue';\n\nexport interface RuiTimezoneSelectProps {\n disabled?: boolean;\n readOnly?: boolean;\n dense?: boolean;\n clearable?: boolean;\n label?: string;\n variant?: AutoCompleteVariant;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n hideDetails?: boolean;\n placeholder?: string;\n required?: boolean;\n classNames?: RuiAutoCompleteClassNames;\n menuOptions?: MenuProps;\n}\n\ndefineOptions({\n name: 'RuiTimezoneSelect',\n});\n\nconst modelValue = defineModel<string | undefined>({ required: true });\n\nconst {\n disabled = false,\n readOnly = false,\n dense = false,\n clearable = false,\n label
|
|
1
|
+
{"version":3,"file":"RuiTimezoneSelect.js","names":[],"sources":["../../../src/components/date-time-picker/RuiTimezoneSelect.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { AutoCompleteVariant } from '@/components/forms/auto-complete/auto-complete-styles';\nimport type { MenuProps } from '@/components/overlays/menu/RuiMenu.vue';\nimport { timezones } from '@/components/date-time-picker/timezones';\nimport RuiAutoComplete, { type RuiAutoCompleteClassNames } from '@/components/forms/auto-complete/RuiAutoComplete.vue';\nimport { useRuiI8n } from '@/composables/use-rui-i18n';\nimport { RUI_I18N_KEYS } from '@/i18n/keys';\n\nexport interface RuiTimezoneSelectProps {\n disabled?: boolean;\n readOnly?: boolean;\n dense?: boolean;\n clearable?: boolean;\n label?: string;\n variant?: AutoCompleteVariant;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n hideDetails?: boolean;\n placeholder?: string;\n required?: boolean;\n classNames?: RuiAutoCompleteClassNames;\n menuOptions?: MenuProps;\n}\n\ndefineOptions({\n name: 'RuiTimezoneSelect',\n});\n\nconst modelValue = defineModel<string | undefined>({ required: true });\n\nconst {\n disabled = false,\n readOnly = false,\n dense = false,\n clearable = false,\n label,\n variant = 'outlined',\n hint,\n errorMessages,\n successMessages,\n hideDetails = false,\n placeholder,\n required = false,\n classNames,\n menuOptions,\n} = defineProps<RuiTimezoneSelectProps>();\n\nconst { t } = useRuiI8n();\n\nconst fieldLabel = computed<string>(() => label ?? t(RUI_I18N_KEYS.timezoneSelect.label, 'Timezone'));\n\ninterface TimezoneOption {\n value: string;\n label: string;\n}\n\nconst options: TimezoneOption[] = timezones.map(value => ({\n value,\n label: value.replace(/_/g, ' '),\n}));\n</script>\n\n<template>\n <RuiAutoComplete\n v-model=\"modelValue\"\n key-attr=\"value\"\n text-attr=\"label\"\n auto-select-first\n :options=\"options\"\n :label=\"fieldLabel\"\n :variant=\"variant\"\n :disabled=\"disabled\"\n :read-only=\"readOnly\"\n :dense=\"dense\"\n :clearable=\"clearable\"\n :hint=\"hint\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hide-details=\"hideDetails\"\n :placeholder=\"placeholder\"\n :required=\"required\"\n :class-names=\"classNames\"\n :menu-options=\"menuOptions\"\n />\n</template>\n"],"mappings":""}
|
package/dist/components/date-time-picker/RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { useRuiI8n } from "../../composables/use-rui-i18n.js";
|
|
1
2
|
import { timezones } from "./timezones.js";
|
|
2
3
|
import RuiAutoComplete_default from "../forms/auto-complete/RuiAutoComplete.js";
|
|
3
|
-
import {
|
|
4
|
+
import { RUI_I18N_KEYS } from "../../i18n/keys.js";
|
|
5
|
+
import { computed, createBlock, defineComponent, mergeModels, openBlock, unref, useModel } from "vue";
|
|
4
6
|
//#region src/components/date-time-picker/RuiTimezoneSelect.vue?vue&type=script&setup=true&lang.ts
|
|
5
7
|
var RuiTimezoneSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
6
8
|
name: "RuiTimezoneSelect",
|
|
@@ -22,7 +24,7 @@ var RuiTimezoneSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*
|
|
|
22
24
|
type: Boolean,
|
|
23
25
|
default: false
|
|
24
26
|
},
|
|
25
|
-
label: {
|
|
27
|
+
label: {},
|
|
26
28
|
variant: { default: "outlined" },
|
|
27
29
|
hint: {},
|
|
28
30
|
errorMessages: {},
|
|
@@ -45,6 +47,8 @@ var RuiTimezoneSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*
|
|
|
45
47
|
emits: ["update:modelValue"],
|
|
46
48
|
setup(__props) {
|
|
47
49
|
const modelValue = useModel(__props, "modelValue");
|
|
50
|
+
const { t } = useRuiI8n();
|
|
51
|
+
const fieldLabel = computed(() => __props.label ?? t(RUI_I18N_KEYS.timezoneSelect.label, "Timezone"));
|
|
48
52
|
const options = timezones.map((value) => ({
|
|
49
53
|
value,
|
|
50
54
|
label: value.replace(/_/g, " ")
|
|
@@ -57,7 +61,7 @@ var RuiTimezoneSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*
|
|
|
57
61
|
"text-attr": "label",
|
|
58
62
|
"auto-select-first": "",
|
|
59
63
|
options: unref(options),
|
|
60
|
-
label:
|
|
64
|
+
label: unref(fieldLabel),
|
|
61
65
|
variant: __props.variant,
|
|
62
66
|
disabled: __props.disabled,
|
|
63
67
|
"read-only": __props.readOnly,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/date-time-picker/RuiTimezoneSelect.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { AutoCompleteVariant } from '@/components/forms/auto-complete/auto-complete-styles';\nimport type { MenuProps } from '@/components/overlays/menu/RuiMenu.vue';\nimport { timezones } from '@/components/date-time-picker/timezones';\nimport RuiAutoComplete, { type RuiAutoCompleteClassNames } from '@/components/forms/auto-complete/RuiAutoComplete.vue';\n\nexport interface RuiTimezoneSelectProps {\n disabled?: boolean;\n readOnly?: boolean;\n dense?: boolean;\n clearable?: boolean;\n label?: string;\n variant?: AutoCompleteVariant;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n hideDetails?: boolean;\n placeholder?: string;\n required?: boolean;\n classNames?: RuiAutoCompleteClassNames;\n menuOptions?: MenuProps;\n}\n\ndefineOptions({\n name: 'RuiTimezoneSelect',\n});\n\nconst modelValue = defineModel<string | undefined>({ required: true });\n\nconst {\n disabled = false,\n readOnly = false,\n dense = false,\n clearable = false,\n label
|
|
1
|
+
{"version":3,"file":"RuiTimezoneSelect.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/components/date-time-picker/RuiTimezoneSelect.vue"],"sourcesContent":["<script lang=\"ts\" setup>\nimport type { AutoCompleteVariant } from '@/components/forms/auto-complete/auto-complete-styles';\nimport type { MenuProps } from '@/components/overlays/menu/RuiMenu.vue';\nimport { timezones } from '@/components/date-time-picker/timezones';\nimport RuiAutoComplete, { type RuiAutoCompleteClassNames } from '@/components/forms/auto-complete/RuiAutoComplete.vue';\nimport { useRuiI8n } from '@/composables/use-rui-i18n';\nimport { RUI_I18N_KEYS } from '@/i18n/keys';\n\nexport interface RuiTimezoneSelectProps {\n disabled?: boolean;\n readOnly?: boolean;\n dense?: boolean;\n clearable?: boolean;\n label?: string;\n variant?: AutoCompleteVariant;\n hint?: string;\n errorMessages?: string | string[];\n successMessages?: string | string[];\n hideDetails?: boolean;\n placeholder?: string;\n required?: boolean;\n classNames?: RuiAutoCompleteClassNames;\n menuOptions?: MenuProps;\n}\n\ndefineOptions({\n name: 'RuiTimezoneSelect',\n});\n\nconst modelValue = defineModel<string | undefined>({ required: true });\n\nconst {\n disabled = false,\n readOnly = false,\n dense = false,\n clearable = false,\n label,\n variant = 'outlined',\n hint,\n errorMessages,\n successMessages,\n hideDetails = false,\n placeholder,\n required = false,\n classNames,\n menuOptions,\n} = defineProps<RuiTimezoneSelectProps>();\n\nconst { t } = useRuiI8n();\n\nconst fieldLabel = computed<string>(() => label ?? t(RUI_I18N_KEYS.timezoneSelect.label, 'Timezone'));\n\ninterface TimezoneOption {\n value: string;\n label: string;\n}\n\nconst options: TimezoneOption[] = timezones.map(value => ({\n value,\n label: value.replace(/_/g, ' '),\n}));\n</script>\n\n<template>\n <RuiAutoComplete\n v-model=\"modelValue\"\n key-attr=\"value\"\n text-attr=\"label\"\n auto-select-first\n :options=\"options\"\n :label=\"fieldLabel\"\n :variant=\"variant\"\n :disabled=\"disabled\"\n :read-only=\"readOnly\"\n :dense=\"dense\"\n :clearable=\"clearable\"\n :hint=\"hint\"\n :error-messages=\"errorMessages\"\n :success-messages=\"successMessages\"\n :hide-details=\"hideDetails\"\n :placeholder=\"placeholder\"\n :required=\"required\"\n :class-names=\"classNames\"\n :menu-options=\"menuOptions\"\n />\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BA,MAAM,aAAa,SAA+B,SAAA,YAAmB;EAmBrE,MAAM,EAAE,MAAM,UAAU;EAExB,MAAM,aAAa,eAAuB,QAAA,SAAS,EAAE,cAAc,eAAe,OAAO,UAAU,CAAC;EAOpG,MAAM,UAA4B,UAAU,KAAI,WAAU;GACxD;GACA,OAAO,MAAM,QAAQ,MAAM,GAAG;EAChC,EAAE;;uBAIA,YAoBE,yBAAA;gBAnBS,WAAA;4EAAU,QAAA;IACnB,YAAS;IACT,aAAU;IACV,qBAAA;IACC,SAAS,MAAA,OAAA;IACT,OAAO,MAAA,UAAA;IACP,SAAS,QAAA;IACT,UAAU,QAAA;IACV,aAAW,QAAA;IACX,OAAO,QAAA;IACP,WAAW,QAAA;IACX,MAAM,QAAA;IACN,kBAAgB,QAAA;IAChB,oBAAkB,QAAA;IAClB,gBAAc,QAAA;IACd,aAAa,QAAA;IACb,UAAU,QAAA;IACV,eAAa,QAAA;IACb,gBAAc,QAAA"}
|
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
import type { DateTimeSegmentType } from '../../components/date-time-picker/types.js';
|
|
2
2
|
import type { TimeAccuracy } from '../../consts/time-accuracy.js';
|
|
3
|
+
import { type Dayjs } from 'dayjs';
|
|
3
4
|
import '../../components/date-time-picker/dayjs-setup.js';
|
|
5
|
+
export interface SegmentValues {
|
|
6
|
+
year?: number;
|
|
7
|
+
month?: number;
|
|
8
|
+
day?: number;
|
|
9
|
+
hour?: number;
|
|
10
|
+
minute?: number;
|
|
11
|
+
second?: number;
|
|
12
|
+
millisecond?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Builds a date from the segments that have been entered so far. Segments the
|
|
16
|
+
* accuracy does not expose are zeroed rather than inherited from the clock the
|
|
17
|
+
* base date started at, so a value cannot pick up a stray second.
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildDateTime(segments: SegmentValues, accuracy: TimeAccuracy, base?: Dayjs): Dayjs;
|
|
20
|
+
/**
|
|
21
|
+
* Turns a `minDate` / `maxDate` prop into a Date. An `epoch` picker states its
|
|
22
|
+
* bounds in whole seconds, so those are widened to milliseconds first.
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveBound(bound: Date | number | undefined, epochSeconds: boolean): Date | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* Pulls a date inside the allowed range. Used by the `now` and `today` actions,
|
|
27
|
+
* which have no partial state: typed input is left to diverge and explain
|
|
28
|
+
* itself through the error message instead, since clamping a keystroke would
|
|
29
|
+
* rewrite a year the moment its first digit landed below the minimum.
|
|
30
|
+
*/
|
|
31
|
+
export declare function clampToBounds(date: Dayjs, min: Date, max?: Date): Dayjs;
|
|
4
32
|
export declare function getClickPosition(event: MouseEvent, input: HTMLInputElement, useCaretPosition: boolean): number;
|
|
5
33
|
export declare function parseAndSetDateValues(pastedText: string, dateFormat: string, accuracy: TimeAccuracy, setValue: (segment: DateTimeSegmentType, value?: number) => void): void;
|
|
@@ -2,6 +2,47 @@ import "./dayjs-setup.js";
|
|
|
2
2
|
import { includeMilliseconds, includeSeconds } from "./utils.js";
|
|
3
3
|
import dayjs from "dayjs";
|
|
4
4
|
//#region src/components/date-time-picker/segment-utils.ts
|
|
5
|
+
/**
|
|
6
|
+
* Builds a date from the segments that have been entered so far. Segments the
|
|
7
|
+
* accuracy does not expose are zeroed rather than inherited from the clock the
|
|
8
|
+
* base date started at, so a value cannot pick up a stray second.
|
|
9
|
+
*/
|
|
10
|
+
function buildDateTime(segments, accuracy, base = dayjs()) {
|
|
11
|
+
const { day, hour, millisecond, minute, month, second, year } = segments;
|
|
12
|
+
let dateTime = base;
|
|
13
|
+
if (year !== void 0) dateTime = dateTime.year(year);
|
|
14
|
+
if (month !== void 0) dateTime = dateTime.month(month - 1);
|
|
15
|
+
if (day !== void 0) dateTime = dateTime.date(Math.min(day, dateTime.daysInMonth()));
|
|
16
|
+
if (hour !== void 0) dateTime = dateTime.hour(hour);
|
|
17
|
+
if (minute !== void 0) dateTime = dateTime.minute(minute);
|
|
18
|
+
if (second !== void 0) dateTime = dateTime.second(second);
|
|
19
|
+
else if (!includeSeconds(accuracy)) dateTime = dateTime.second(0);
|
|
20
|
+
if (millisecond !== void 0) dateTime = dateTime.millisecond(millisecond);
|
|
21
|
+
else if (!includeMilliseconds(accuracy)) dateTime = dateTime.millisecond(0);
|
|
22
|
+
return dateTime;
|
|
23
|
+
}
|
|
24
|
+
var MILLISECONDS = 1e3;
|
|
25
|
+
/**
|
|
26
|
+
* Turns a `minDate` / `maxDate` prop into a Date. An `epoch` picker states its
|
|
27
|
+
* bounds in whole seconds, so those are widened to milliseconds first.
|
|
28
|
+
*/
|
|
29
|
+
function resolveBound(bound, epochSeconds) {
|
|
30
|
+
if (bound === void 0) return;
|
|
31
|
+
if (epochSeconds && typeof bound === "number") return /* @__PURE__ */ new Date(bound * MILLISECONDS);
|
|
32
|
+
return new Date(bound);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Pulls a date inside the allowed range. Used by the `now` and `today` actions,
|
|
36
|
+
* which have no partial state: typed input is left to diverge and explain
|
|
37
|
+
* itself through the error message instead, since clamping a keystroke would
|
|
38
|
+
* rewrite a year the moment its first digit landed below the minimum.
|
|
39
|
+
*/
|
|
40
|
+
function clampToBounds(date, min, max) {
|
|
41
|
+
const lower = dayjs(min);
|
|
42
|
+
if (date.isBefore(lower)) return lower;
|
|
43
|
+
if (max && date.isAfter(max)) return dayjs(max);
|
|
44
|
+
return date;
|
|
45
|
+
}
|
|
5
46
|
function getClickPosition(event, input, useCaretPosition) {
|
|
6
47
|
const fallback = input.selectionStart ?? 0;
|
|
7
48
|
if (!useCaretPosition) return fallback;
|
|
@@ -24,6 +65,6 @@ function parseAndSetDateValues(pastedText, dateFormat, accuracy, setValue) {
|
|
|
24
65
|
} catch {}
|
|
25
66
|
}
|
|
26
67
|
//#endregion
|
|
27
|
-
export { getClickPosition, parseAndSetDateValues };
|
|
68
|
+
export { buildDateTime, clampToBounds, getClickPosition, parseAndSetDateValues, resolveBound };
|
|
28
69
|
|
|
29
70
|
//# sourceMappingURL=segment-utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"segment-utils.js","names":[],"sources":["../../../src/components/date-time-picker/segment-utils.ts"],"sourcesContent":["import type { DateTimeSegmentType } from '@/components/date-time-picker/types';\nimport type { TimeAccuracy } from '@/consts/time-accuracy';\nimport dayjs from 'dayjs';\nimport { includeMilliseconds, includeSeconds } from '@/components/date-time-picker/utils';\n\nimport '@/components/date-time-picker/dayjs-setup';\n\nexport function getClickPosition(\n event: MouseEvent,\n input: HTMLInputElement,\n useCaretPosition: boolean,\n): number {\n const fallback = input.selectionStart ?? 0;\n if (!useCaretPosition)\n return fallback;\n const caretPos = document.caretPositionFromPoint?.(event.clientX, event.clientY);\n if (caretPos)\n return caretPos.offset;\n return document.caretRangeFromPoint?.(event.clientX, event.clientY)?.startOffset ?? fallback;\n}\n\nexport function parseAndSetDateValues(\n pastedText: string,\n dateFormat: string,\n accuracy: TimeAccuracy,\n setValue: (segment: DateTimeSegmentType, value?: number) => void,\n): void {\n try {\n const parsedDate = dayjs(pastedText, dateFormat);\n\n if (!parsedDate.isValid()) {\n return;\n }\n\n const date = parsedDate.toDate();\n setValue('YYYY', date.getFullYear());\n setValue('MM', date.getMonth() + 1);\n setValue('DD', date.getDate());\n setValue('HH', date.getHours());\n setValue('mm', date.getMinutes());\n if (includeSeconds(accuracy)) {\n setValue('ss', date.getSeconds());\n }\n if (includeMilliseconds(accuracy)) {\n setValue('SSS', date.getMilliseconds());\n }\n }\n catch {\n // Invalid format, ignore paste\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"segment-utils.js","names":[],"sources":["../../../src/components/date-time-picker/segment-utils.ts"],"sourcesContent":["import type { DateTimeSegmentType } from '@/components/date-time-picker/types';\nimport type { TimeAccuracy } from '@/consts/time-accuracy';\nimport dayjs, { type Dayjs } from 'dayjs';\nimport { includeMilliseconds, includeSeconds } from '@/components/date-time-picker/utils';\n\nimport '@/components/date-time-picker/dayjs-setup';\n\nexport interface SegmentValues {\n year?: number;\n month?: number;\n day?: number;\n hour?: number;\n minute?: number;\n second?: number;\n millisecond?: number;\n}\n\n/**\n * Builds a date from the segments that have been entered so far. Segments the\n * accuracy does not expose are zeroed rather than inherited from the clock the\n * base date started at, so a value cannot pick up a stray second.\n */\nexport function buildDateTime(segments: SegmentValues, accuracy: TimeAccuracy, base: Dayjs = dayjs()): Dayjs {\n const { day, hour, millisecond, minute, month, second, year } = segments;\n let dateTime = base;\n\n if (year !== undefined)\n dateTime = dateTime.year(year);\n\n if (month !== undefined)\n dateTime = dateTime.month(month - 1);\n\n if (day !== undefined)\n dateTime = dateTime.date(Math.min(day, dateTime.daysInMonth()));\n\n if (hour !== undefined)\n dateTime = dateTime.hour(hour);\n\n if (minute !== undefined)\n dateTime = dateTime.minute(minute);\n\n if (second !== undefined)\n dateTime = dateTime.second(second);\n else if (!includeSeconds(accuracy))\n dateTime = dateTime.second(0);\n\n if (millisecond !== undefined)\n dateTime = dateTime.millisecond(millisecond);\n else if (!includeMilliseconds(accuracy))\n dateTime = dateTime.millisecond(0);\n\n return dateTime;\n}\n\nconst MILLISECONDS = 1000;\n\n/**\n * Turns a `minDate` / `maxDate` prop into a Date. An `epoch` picker states its\n * bounds in whole seconds, so those are widened to milliseconds first.\n */\nexport function resolveBound(bound: Date | number | undefined, epochSeconds: boolean): Date | undefined {\n if (bound === undefined) {\n return undefined;\n }\n\n if (epochSeconds && typeof bound === 'number') {\n return new Date(bound * MILLISECONDS);\n }\n\n return new Date(bound);\n}\n\n/**\n * Pulls a date inside the allowed range. Used by the `now` and `today` actions,\n * which have no partial state: typed input is left to diverge and explain\n * itself through the error message instead, since clamping a keystroke would\n * rewrite a year the moment its first digit landed below the minimum.\n */\nexport function clampToBounds(date: Dayjs, min: Date, max?: Date): Dayjs {\n const lower = dayjs(min);\n if (date.isBefore(lower)) {\n return lower;\n }\n\n if (max && date.isAfter(max)) {\n return dayjs(max);\n }\n\n return date;\n}\n\nexport function getClickPosition(\n event: MouseEvent,\n input: HTMLInputElement,\n useCaretPosition: boolean,\n): number {\n const fallback = input.selectionStart ?? 0;\n if (!useCaretPosition)\n return fallback;\n const caretPos = document.caretPositionFromPoint?.(event.clientX, event.clientY);\n if (caretPos)\n return caretPos.offset;\n return document.caretRangeFromPoint?.(event.clientX, event.clientY)?.startOffset ?? fallback;\n}\n\nexport function parseAndSetDateValues(\n pastedText: string,\n dateFormat: string,\n accuracy: TimeAccuracy,\n setValue: (segment: DateTimeSegmentType, value?: number) => void,\n): void {\n try {\n const parsedDate = dayjs(pastedText, dateFormat);\n\n if (!parsedDate.isValid()) {\n return;\n }\n\n const date = parsedDate.toDate();\n setValue('YYYY', date.getFullYear());\n setValue('MM', date.getMonth() + 1);\n setValue('DD', date.getDate());\n setValue('HH', date.getHours());\n setValue('mm', date.getMinutes());\n if (includeSeconds(accuracy)) {\n setValue('ss', date.getSeconds());\n }\n if (includeMilliseconds(accuracy)) {\n setValue('SSS', date.getMilliseconds());\n }\n }\n catch {\n // Invalid format, ignore paste\n }\n}\n"],"mappings":";;;;;;;;;AAsBA,SAAgB,cAAc,UAAyB,UAAwB,OAAc,MAAM,GAAU;CAC3G,MAAM,EAAE,KAAK,MAAM,aAAa,QAAQ,OAAO,QAAQ,SAAS;CAChE,IAAI,WAAW;CAEf,IAAI,SAAS,KAAA,GACX,WAAW,SAAS,KAAK,IAAI;CAE/B,IAAI,UAAU,KAAA,GACZ,WAAW,SAAS,MAAM,QAAQ,CAAC;CAErC,IAAI,QAAQ,KAAA,GACV,WAAW,SAAS,KAAK,KAAK,IAAI,KAAK,SAAS,YAAY,CAAC,CAAC;CAEhE,IAAI,SAAS,KAAA,GACX,WAAW,SAAS,KAAK,IAAI;CAE/B,IAAI,WAAW,KAAA,GACb,WAAW,SAAS,OAAO,MAAM;CAEnC,IAAI,WAAW,KAAA,GACb,WAAW,SAAS,OAAO,MAAM;MAC9B,IAAI,CAAC,eAAe,QAAQ,GAC/B,WAAW,SAAS,OAAO,CAAC;CAE9B,IAAI,gBAAgB,KAAA,GAClB,WAAW,SAAS,YAAY,WAAW;MACxC,IAAI,CAAC,oBAAoB,QAAQ,GACpC,WAAW,SAAS,YAAY,CAAC;CAEnC,OAAO;AACT;AAEA,IAAM,eAAe;;;;;AAMrB,SAAgB,aAAa,OAAkC,cAAyC;CACtG,IAAI,UAAU,KAAA,GACZ;CAGF,IAAI,gBAAgB,OAAO,UAAU,UACnC,uBAAO,IAAI,KAAK,QAAQ,YAAY;CAGtC,OAAO,IAAI,KAAK,KAAK;AACvB;;;;;;;AAQA,SAAgB,cAAc,MAAa,KAAW,KAAmB;CACvE,MAAM,QAAQ,MAAM,GAAG;CACvB,IAAI,KAAK,SAAS,KAAK,GACrB,OAAO;CAGT,IAAI,OAAO,KAAK,QAAQ,GAAG,GACzB,OAAO,MAAM,GAAG;CAGlB,OAAO;AACT;AAEA,SAAgB,iBACd,OACA,OACA,kBACQ;CACR,MAAM,WAAW,MAAM,kBAAkB;CACzC,IAAI,CAAC,kBACH,OAAO;CACT,MAAM,WAAW,SAAS,yBAAyB,MAAM,SAAS,MAAM,OAAO;CAC/E,IAAI,UACF,OAAO,SAAS;CAClB,OAAO,SAAS,sBAAsB,MAAM,SAAS,MAAM,OAAO,CAAC,EAAE,eAAe;AACtF;AAEA,SAAgB,sBACd,YACA,YACA,UACA,UACM;CACN,IAAI;EACF,MAAM,aAAa,MAAM,YAAY,UAAU;EAE/C,IAAI,CAAC,WAAW,QAAQ,GACtB;EAGF,MAAM,OAAO,WAAW,OAAO;EAC/B,SAAS,QAAQ,KAAK,YAAY,CAAC;EACnC,SAAS,MAAM,KAAK,SAAS,IAAI,CAAC;EAClC,SAAS,MAAM,KAAK,QAAQ,CAAC;EAC7B,SAAS,MAAM,KAAK,SAAS,CAAC;EAC9B,SAAS,MAAM,KAAK,WAAW,CAAC;EAChC,IAAI,eAAe,QAAQ,GACzB,SAAS,MAAM,KAAK,WAAW,CAAC;EAElC,IAAI,oBAAoB,QAAQ,GAC9B,SAAS,OAAO,KAAK,gBAAgB,CAAC;CAE1C,QACM,CAEN;AACF"}
|
|
@@ -3,3 +3,5 @@ export declare const DATE_TIME_SEGMENT_TYPES: readonly ["DD", "MM", "YYYY", "HH"
|
|
|
3
3
|
export type DateTimeSegmentType = typeof DATE_TIME_SEGMENT_TYPES[number];
|
|
4
4
|
export declare function isDateTimeSegmentType(value: string): value is DateTimeSegmentType;
|
|
5
5
|
export type SegmentData = Record<DateTimeSegmentType, Ref<number | undefined>>;
|
|
6
|
+
export declare const DATE_TIME_PICKER_ACTIONS: readonly ["now", "today", "clear"];
|
|
7
|
+
export type DateTimePickerAction = typeof DATE_TIME_PICKER_ACTIONS[number];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","names":[],"sources":["../../../src/components/date-time-picker/types.ts"],"sourcesContent":["import type { Ref } from 'vue';\n\nexport const DATE_TIME_SEGMENT_TYPES = [\n 'DD',\n 'MM',\n 'YYYY',\n 'HH',\n 'mm',\n 'ss',\n 'SSS',\n] as const;\n\nexport type DateTimeSegmentType = typeof DATE_TIME_SEGMENT_TYPES[number];\n\nexport function isDateTimeSegmentType(value: string): value is DateTimeSegmentType {\n return (DATE_TIME_SEGMENT_TYPES as readonly string[]).includes(value);\n}\n\nexport type SegmentData = Record<DateTimeSegmentType, Ref<number | undefined>>;\n"],"mappings":";AAEA,IAAa,0BAA0B;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAIA,SAAgB,sBAAsB,OAA6C;CACjF,OAAQ,wBAA8C,SAAS,KAAK;AACtE"}
|
|
1
|
+
{"version":3,"file":"types.js","names":[],"sources":["../../../src/components/date-time-picker/types.ts"],"sourcesContent":["import type { Ref } from 'vue';\n\nexport const DATE_TIME_SEGMENT_TYPES = [\n 'DD',\n 'MM',\n 'YYYY',\n 'HH',\n 'mm',\n 'ss',\n 'SSS',\n] as const;\n\nexport type DateTimeSegmentType = typeof DATE_TIME_SEGMENT_TYPES[number];\n\nexport function isDateTimeSegmentType(value: string): value is DateTimeSegmentType {\n return (DATE_TIME_SEGMENT_TYPES as readonly string[]).includes(value);\n}\n\nexport type SegmentData = Record<DateTimeSegmentType, Ref<number | undefined>>;\n\nexport const DATE_TIME_PICKER_ACTIONS = ['now', 'today', 'clear'] as const;\n\nexport type DateTimePickerAction = typeof DATE_TIME_PICKER_ACTIONS[number];\n"],"mappings":";AAEA,IAAa,0BAA0B;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAIA,SAAgB,sBAAsB,OAA6C;CACjF,OAAQ,wBAA8C,SAAS,KAAK;AACtE"}
|
|
@@ -12,6 +12,11 @@ interface DateTimeSelectionOptions<T extends DateTimeModelType> {
|
|
|
12
12
|
minDate: Date | number | undefined;
|
|
13
13
|
maxDate: Date | number | 'now' | undefined;
|
|
14
14
|
allowEmpty: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* The field's own format, so a bound named in an error message is written the
|
|
17
|
+
* same way round as the value the user is looking at.
|
|
18
|
+
*/
|
|
19
|
+
dateFormat: Ref<string>;
|
|
15
20
|
}
|
|
16
21
|
interface DateTimeSelectionReturn {
|
|
17
22
|
selectedYear: Ref<number | undefined>;
|
|
@@ -32,6 +37,7 @@ interface DateTimeSelectionReturn {
|
|
|
32
37
|
maxAllowedDate: ComputedRef<Date | undefined>;
|
|
33
38
|
getDateTime: () => Dayjs;
|
|
34
39
|
setNow: () => void;
|
|
40
|
+
setToday: () => void;
|
|
35
41
|
clear: () => void;
|
|
36
42
|
isDateValid: (date: Dayjs) => boolean;
|
|
37
43
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { useRuiI8n } from "../../composables/use-rui-i18n.js";
|
|
2
|
-
import "./dayjs-setup.js";
|
|
3
|
-
import { guessTimezone, includeMilliseconds, includeSeconds } from "./utils.js";
|
|
4
2
|
import { RUI_I18N_KEYS } from "../../i18n/keys.js";
|
|
3
|
+
import "./dayjs-setup.js";
|
|
4
|
+
import { formatWallClock, guessTimezone, includeMilliseconds, includeSeconds } from "./utils.js";
|
|
5
|
+
import { buildDateTime, clampToBounds, resolveBound } from "./segment-utils.js";
|
|
5
6
|
import { computed, nextTick, onMounted, ref, watch } from "vue";
|
|
6
7
|
import { isDefined, watchIgnorable } from "@vueuse/core";
|
|
7
8
|
import { get as get$1, set as set$1 } from "@vueuse/shared";
|
|
@@ -9,7 +10,7 @@ import dayjs from "dayjs";
|
|
|
9
10
|
//#region src/components/date-time-picker/use-date-time-selection.ts
|
|
10
11
|
var MILLISECONDS = 1e3;
|
|
11
12
|
function useDateTimeSelection(options) {
|
|
12
|
-
const { accuracy, allowEmpty, maxDate, minDate, modelValue, type } = options;
|
|
13
|
+
const { accuracy, allowEmpty, dateFormat, maxDate, minDate, modelValue, type } = options;
|
|
13
14
|
const { t } = useRuiI8n();
|
|
14
15
|
const selectedYear = ref();
|
|
15
16
|
const selectedMonth = ref();
|
|
@@ -21,17 +22,9 @@ function useDateTimeSelection(options) {
|
|
|
21
22
|
const selectedTimezone = ref(guessTimezone());
|
|
22
23
|
const internalErrorMessages = ref([]);
|
|
23
24
|
const now = ref(dayjs.tz(void 0, guessTimezone()));
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return new Date(minDate);
|
|
28
|
-
});
|
|
29
|
-
const maxAllowedDate = computed(() => {
|
|
30
|
-
if (maxDate === void 0) return;
|
|
31
|
-
if (maxDate === "now") return get$1(now).toDate();
|
|
32
|
-
if (type === "epoch" && typeof maxDate === "number") return /* @__PURE__ */ new Date(maxDate * MILLISECONDS);
|
|
33
|
-
return new Date(maxDate);
|
|
34
|
-
});
|
|
25
|
+
const epochSeconds = type === "epoch";
|
|
26
|
+
const minAllowedDate = computed(() => resolveBound(minDate, epochSeconds) ?? new Date(1970, 0, 1));
|
|
27
|
+
const maxAllowedDate = computed(() => maxDate === "now" ? get$1(now).toDate() : resolveBound(maxDate, epochSeconds));
|
|
35
28
|
const segmentData = {
|
|
36
29
|
DD: selectedDay,
|
|
37
30
|
HH: selectedHour,
|
|
@@ -73,32 +66,39 @@ function useDateTimeSelection(options) {
|
|
|
73
66
|
});
|
|
74
67
|
const valueSet = computed(() => isDefined(selectedDate) && isDefined(selectedTime));
|
|
75
68
|
function getDateTime() {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
69
|
+
return buildDateTime({
|
|
70
|
+
day: get$1(selectedDay),
|
|
71
|
+
hour: get$1(selectedHour),
|
|
72
|
+
millisecond: get$1(selectedMillisecond),
|
|
73
|
+
minute: get$1(selectedMinute),
|
|
74
|
+
month: get$1(selectedMonth),
|
|
75
|
+
second: get$1(selectedSecond),
|
|
76
|
+
year: get$1(selectedYear)
|
|
77
|
+
}, accuracy);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Writes a bound the way the field writes its value. `toLocaleDateString()`
|
|
81
|
+
* followed the browser locale and ignored the picker's own format, so a
|
|
82
|
+
* day-first field could report its limit month-first, and it dropped the time
|
|
83
|
+
* entirely, which left a mid-day bound unable to explain itself.
|
|
84
|
+
*/
|
|
85
|
+
function formatBound(bound) {
|
|
86
|
+
return dayjs(bound).format(get$1(dateFormat));
|
|
89
87
|
}
|
|
90
88
|
function isDateValid(date) {
|
|
91
89
|
const min = get$1(minAllowedDate);
|
|
92
90
|
const max = get$1(maxAllowedDate);
|
|
93
91
|
set$1(internalErrorMessages, []);
|
|
94
92
|
if (min && date.isBefore(min)) {
|
|
95
|
-
const
|
|
93
|
+
const formatted = formatBound(min);
|
|
94
|
+
const errorMessage = t(RUI_I18N_KEYS.dateTimePicker.dateBeforeMin, { date: formatted }, `Date cannot be before ${formatted}`);
|
|
96
95
|
set$1(internalErrorMessages, [...get$1(internalErrorMessages), errorMessage]);
|
|
97
96
|
return false;
|
|
98
97
|
}
|
|
99
98
|
if (max && date.isAfter(max)) {
|
|
99
|
+
const formatted = formatBound(max);
|
|
100
100
|
const nowError = t(RUI_I18N_KEYS.dateTimePicker.dateInFuture, "The selected date cannot be in the future");
|
|
101
|
-
const maxError = t(RUI_I18N_KEYS.dateTimePicker.dateAfterMax, { date:
|
|
101
|
+
const maxError = t(RUI_I18N_KEYS.dateTimePicker.dateAfterMax, { date: formatted }, `Date cannot be after ${formatted}`);
|
|
102
102
|
const errorMessage = maxDate === "now" ? nowError : maxError;
|
|
103
103
|
set$1(internalErrorMessages, [...get$1(internalErrorMessages), errorMessage]);
|
|
104
104
|
return false;
|
|
@@ -108,20 +108,15 @@ function useDateTimeSelection(options) {
|
|
|
108
108
|
function emitUpdate(updatedModel) {
|
|
109
109
|
set$1(modelValue, {
|
|
110
110
|
"date": () => updatedModel.toDate(),
|
|
111
|
-
"epoch": () => updatedModel.valueOf() / MILLISECONDS,
|
|
111
|
+
"epoch": () => Math.floor(updatedModel.valueOf() / MILLISECONDS),
|
|
112
112
|
"epoch-ms": () => updatedModel.valueOf()
|
|
113
113
|
}[type]());
|
|
114
114
|
}
|
|
115
115
|
function updateModelValue() {
|
|
116
116
|
if (!isDefined(selectedDate) || !isDefined(selectedTime)) return;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const time = get$1(selectedTime);
|
|
121
|
-
const updatedModel = dayjs.tz(isDefined(modelValue) ? get$1(modelValue) : void 0, get$1(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);
|
|
122
|
-
if (!isDateValid(updatedModel)) return;
|
|
123
|
-
emitUpdate(updatedModel);
|
|
124
|
-
}
|
|
117
|
+
const updatedModel = dayjs.tz(formatWallClock(get$1(selectedDate), get$1(selectedTime), accuracy), get$1(selectedTimezone));
|
|
118
|
+
if (!isDateValid(updatedModel)) return;
|
|
119
|
+
emitUpdate(updatedModel);
|
|
125
120
|
}
|
|
126
121
|
function clear() {
|
|
127
122
|
set$1(internalErrorMessages, []);
|
|
@@ -134,10 +129,10 @@ function useDateTimeSelection(options) {
|
|
|
134
129
|
set$1(selectedMillisecond, void 0);
|
|
135
130
|
set$1(modelValue, void 0);
|
|
136
131
|
}
|
|
137
|
-
function
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
132
|
+
function clampToAllowed(date) {
|
|
133
|
+
return clampToBounds(date, get$1(minAllowedDate), get$1(maxAllowedDate));
|
|
134
|
+
}
|
|
135
|
+
function applySegments(date) {
|
|
141
136
|
set$1(selectedYear, date.year());
|
|
142
137
|
set$1(selectedMonth, date.month() + 1);
|
|
143
138
|
set$1(selectedDay, date.date());
|
|
@@ -145,6 +140,33 @@ function useDateTimeSelection(options) {
|
|
|
145
140
|
set$1(selectedMinute, date.minute());
|
|
146
141
|
set$1(selectedSecond, includeSeconds(accuracy) ? date.second() : 0);
|
|
147
142
|
set$1(selectedMillisecond, includeMilliseconds(accuracy) ? date.millisecond() : 0);
|
|
143
|
+
}
|
|
144
|
+
function setNow() {
|
|
145
|
+
set$1(internalErrorMessages, []);
|
|
146
|
+
const date = dayjs();
|
|
147
|
+
set$1(now, date);
|
|
148
|
+
applySegments(clampToAllowed(date));
|
|
149
|
+
nextTick(() => {
|
|
150
|
+
updateModelValue();
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Moves the date part to today and leaves the time part alone, so a picked
|
|
155
|
+
* time survives. Falls back to midnight when no time has been entered yet.
|
|
156
|
+
*/
|
|
157
|
+
function setToday() {
|
|
158
|
+
set$1(internalErrorMessages, []);
|
|
159
|
+
const date = dayjs();
|
|
160
|
+
set$1(now, date);
|
|
161
|
+
applySegments(clampToAllowed(buildDateTime({
|
|
162
|
+
day: date.date(),
|
|
163
|
+
hour: get$1(selectedHour) ?? 0,
|
|
164
|
+
millisecond: get$1(selectedMillisecond) ?? 0,
|
|
165
|
+
minute: get$1(selectedMinute) ?? 0,
|
|
166
|
+
month: date.month() + 1,
|
|
167
|
+
second: get$1(selectedSecond) ?? 0,
|
|
168
|
+
year: date.year()
|
|
169
|
+
}, accuracy, date)));
|
|
148
170
|
nextTick(() => {
|
|
149
171
|
updateModelValue();
|
|
150
172
|
});
|
|
@@ -218,6 +240,7 @@ function useDateTimeSelection(options) {
|
|
|
218
240
|
selectedTimezone,
|
|
219
241
|
selectedYear,
|
|
220
242
|
setNow,
|
|
243
|
+
setToday,
|
|
221
244
|
valueSet
|
|
222
245
|
};
|
|
223
246
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-date-time-selection.js","names":[],"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';\nimport '@/components/date-time-picker/dayjs-setup';\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"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-date-time-selection.js","names":[],"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 { buildDateTime, clampToBounds, resolveBound } from '@/components/date-time-picker/segment-utils';\nimport { formatWallClock, guessTimezone, includeMilliseconds, includeSeconds } from '@/components/date-time-picker/utils';\nimport { useRuiI8n } from '@/composables/use-rui-i18n';\nimport { RUI_I18N_KEYS } from '@/i18n/keys';\nimport '@/components/date-time-picker/dayjs-setup';\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 * The field's own format, so a bound named in an error message is written the\n * same way round as the value the user is looking at.\n */\n dateFormat: Ref<string>;\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 setToday: () => 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 dateFormat,\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 epochSeconds = type === 'epoch';\n\n const minAllowedDate = computed<Date>(\n () => resolveBound(minDate, epochSeconds) ?? new Date(1970, 0, 1),\n );\n\n const maxAllowedDate = computed<Date | undefined>(\n () => (maxDate === 'now' ? get(now).toDate() : resolveBound(maxDate, epochSeconds)),\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 return buildDateTime({\n day: get(selectedDay),\n hour: get(selectedHour),\n millisecond: get(selectedMillisecond),\n minute: get(selectedMinute),\n month: get(selectedMonth),\n second: get(selectedSecond),\n year: get(selectedYear),\n }, accuracy);\n }\n\n /**\n * Writes a bound the way the field writes its value. `toLocaleDateString()`\n * followed the browser locale and ignored the picker's own format, so a\n * day-first field could report its limit month-first, and it dropped the time\n * entirely, which left a mid-day bound unable to explain itself.\n */\n function formatBound(bound: Date): string {\n return dayjs(bound).format(get(dateFormat));\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 formatted = formatBound(min);\n const errorMessage = t(RUI_I18N_KEYS.dateTimePicker.dateBeforeMin, {\n date: formatted,\n }, `Date cannot be before ${formatted}`);\n set(internalErrorMessages, [...get(internalErrorMessages), errorMessage]);\n return false;\n }\n\n if (max && date.isAfter(max)) {\n const formatted = formatBound(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: formatted }, `Date cannot be after ${formatted}`);\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 // an epoch is whole seconds; `millisecond` accuracy would otherwise emit a fraction\n 'epoch': () => Math.floor(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 // The segments are a wall-clock reading, so they are formatted and parsed\n // in the selected timezone. Mutating a `dayjs.tz()` built from the old\n // value instead would keep that value's UTC offset, and moving the date\n // across a DST boundary then shifted the time by an hour.\n const updatedModel = dayjs.tz(\n formatWallClock(get(selectedDate), get(selectedTime), accuracy),\n get(selectedTimezone),\n );\n\n if (!isDateValid(updatedModel)) {\n return;\n }\n\n emitUpdate(updatedModel);\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 clampToAllowed(date: Dayjs): Dayjs {\n return clampToBounds(date, get(minAllowedDate), get(maxAllowedDate));\n }\n\n function applySegments(date: Dayjs): void {\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\n function setNow(): void {\n set(internalErrorMessages, []);\n\n const date = dayjs();\n set(now, date);\n applySegments(clampToAllowed(date));\n\n nextTick(() => {\n updateModelValue();\n });\n }\n\n /**\n * Moves the date part to today and leaves the time part alone, so a picked\n * time survives. Falls back to midnight when no time has been entered yet.\n */\n function setToday(): void {\n set(internalErrorMessages, []);\n\n const date = dayjs();\n set(now, date);\n\n const target = buildDateTime({\n day: date.date(),\n hour: get(selectedHour) ?? 0,\n millisecond: get(selectedMillisecond) ?? 0,\n minute: get(selectedMinute) ?? 0,\n month: date.month() + 1,\n second: get(selectedSecond) ?? 0,\n year: date.year(),\n }, accuracy, date);\n\n applySegments(clampToAllowed(target));\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 setToday,\n valueSet,\n };\n}\n"],"mappings":";;;;;;;;;;AAwDA,IAAM,eAAe;AAErB,SAAgB,qBACd,SACyB;CACzB,MAAM,EACJ,UACA,YACA,YACA,SACA,SACA,YACA,SACE;CAEJ,MAAM,EAAE,MAAM,UAAU;CAExB,MAAM,eAAe,IAAwB;CAC7C,MAAM,gBAAgB,IAAwB;CAC9C,MAAM,cAAc,IAAwB;CAE5C,MAAM,eAAe,IAAwB;CAC7C,MAAM,iBAAiB,IAAwB;CAC/C,MAAM,iBAAiB,IAAwB;CAC/C,MAAM,sBAAsB,IAAwB;CACpD,MAAM,mBAAmB,IAAwB,cAAc,CAAC;CAEhE,MAAM,wBAAwB,IAAc,CAAC,CAAC;CAC9C,MAAM,MAAM,IAAW,MAAM,GAAG,KAAA,GAAW,cAAc,CAAC,CAAC;CAE3D,MAAM,eAAe,SAAS;CAE9B,MAAM,iBAAiB,eACf,aAAa,SAAS,YAAY,KAAK,IAAI,KAAK,MAAM,GAAG,CAAC,CAClE;CAEA,MAAM,iBAAiB,eACd,YAAY,QAAQ,MAAI,GAAG,CAAC,CAAC,OAAO,IAAI,aAAa,SAAS,YAAY,CACnF;CAEA,MAAM,cAA2B;EAC/B,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,KAAK;EACL,MAAM;EACN,IAAI;EACJ,IAAI;CACN;CAEA,MAAM,eAAe,SAA2B;EAC9C,MAAM;GACJ,IAAI,EAAE,UAAU,YAAY,KAAK,UAAU,aAAa,KAAK,UAAU,WAAW,IAChF;GAEF,MAAM,uBAAO,IAAI,KAAK;GACtB,KAAK,YAAY,MAAI,YAAY,CAAC;GAGlC,KAAK,QAAQ,CAAC;GACd,KAAK,SAAS,MAAI,aAAa,IAAI,CAAC;GACpC,KAAK,QAAQ,MAAI,WAAW,CAAC;GAC7B,OAAO;EACT;EACA,IAAI,OAAc;GAChB,MAAI,cAAc,OAAO,YAAY,CAAC;GACtC,MAAI,eAAe,QAAQ,MAAM,SAAS,IAAI,IAAI,KAAA,CAAS;GAC3D,MAAI,aAAa,OAAO,QAAQ,CAAC;EACnC;CACF,CAAC;CAED,MAAM,eAAe,SAA2B;EAC9C,MAAM;GACJ,IAAI,EAAE,UAAU,YAAY,KAAK,UAAU,cAAc,IACvD;GAEF,MAAM,uBAAO,IAAI,KAAK;GACtB,KAAK,SACH,MAAI,YAAY,GAChB,MAAI,cAAc,GAClB,MAAI,cAAc,KAAK,GACvB,MAAI,mBAAmB,KAAK,CAC9B;GACA,OAAO;EACT;EACA,IAAI,OAAc;GAChB,MAAI,cAAc,OAAO,SAAS,CAAC;GACnC,MAAI,gBAAgB,OAAO,WAAW,CAAC;GACvC,MAAI,gBAAgB,OAAO,WAAW,CAAC;GACvC,MAAI,qBAAqB,OAAO,gBAAgB,CAAC;EACnD;CACF,CAAC;CAED,MAAM,WAAW,eAAwB,UAAU,YAAY,KAAK,UAAU,YAAY,CAAC;CAE3F,SAAS,cAAqB;EAC5B,OAAO,cAAc;GACnB,KAAK,MAAI,WAAW;GACpB,MAAM,MAAI,YAAY;GACtB,aAAa,MAAI,mBAAmB;GACpC,QAAQ,MAAI,cAAc;GAC1B,OAAO,MAAI,aAAa;GACxB,QAAQ,MAAI,cAAc;GAC1B,MAAM,MAAI,YAAY;EACxB,GAAG,QAAQ;CACb;;;;;;;CAQA,SAAS,YAAY,OAAqB;EACxC,OAAO,MAAM,KAAK,CAAC,CAAC,OAAO,MAAI,UAAU,CAAC;CAC5C;CAEA,SAAS,YAAY,MAAsB;EACzC,MAAM,MAAM,MAAI,cAAc;EAC9B,MAAM,MAAM,MAAI,cAAc;EAE9B,MAAI,uBAAuB,CAAC,CAAC;EAE7B,IAAI,OAAO,KAAK,SAAS,GAAG,GAAG;GAC7B,MAAM,YAAY,YAAY,GAAG;GACjC,MAAM,eAAe,EAAE,cAAc,eAAe,eAAe,EACjE,MAAM,UACR,GAAG,yBAAyB,WAAW;GACvC,MAAI,uBAAuB,CAAC,GAAG,MAAI,qBAAqB,GAAG,YAAY,CAAC;GACxE,OAAO;EACT;EAEA,IAAI,OAAO,KAAK,QAAQ,GAAG,GAAG;GAC5B,MAAM,YAAY,YAAY,GAAG;GACjC,MAAM,WAAW,EAAE,cAAc,eAAe,cAAc,2CAA2C;GACzG,MAAM,WAAW,EAAE,cAAc,eAAe,cAAc,EAAE,MAAM,UAAU,GAAG,wBAAwB,WAAW;GACtH,MAAM,eAAe,YAAY,QAAQ,WAAW;GACpD,MAAI,uBAAuB,CAAC,GAAG,MAAI,qBAAqB,GAAG,YAAY,CAAC;GACxE,OAAO;EACT;EAEA,OAAO;CACT;CAEA,SAAS,WAAW,cAA2B;EAQ7C,MAAI,YAAY;GANd,cAAc,aAAa,OAAO;GAElC,eAAe,KAAK,MAAM,aAAa,QAAQ,IAAI,YAAY;GAC/D,kBAAkB,aAAa,QAAQ;EAGzB,EAAQ,KAAK,CAAC,CAAsB;CACtD;CAEA,SAAS,mBAAyB;EAChC,IAAI,CAAC,UAAU,YAAY,KAAK,CAAC,UAAU,YAAY,GACrD;EAOF,MAAM,eAAe,MAAM,GACzB,gBAAgB,MAAI,YAAY,GAAG,MAAI,YAAY,GAAG,QAAQ,GAC9D,MAAI,gBAAgB,CACtB;EAEA,IAAI,CAAC,YAAY,YAAY,GAC3B;EAGF,WAAW,YAAY;CACzB;CAEA,SAAS,QAAc;EACrB,MAAI,uBAAuB,CAAC,CAAC;EAC7B,MAAI,cAAc,KAAA,CAAS;EAC3B,MAAI,eAAe,KAAA,CAAS;EAC5B,MAAI,aAAa,KAAA,CAAS;EAC1B,MAAI,cAAc,KAAA,CAAS;EAC3B,MAAI,gBAAgB,KAAA,CAAS;EAC7B,MAAI,gBAAgB,KAAA,CAAS;EAC7B,MAAI,qBAAqB,KAAA,CAAS;EAClC,MAAI,YAAY,KAAA,CAA8B;CAChD;CAEA,SAAS,eAAe,MAAoB;EAC1C,OAAO,cAAc,MAAM,MAAI,cAAc,GAAG,MAAI,cAAc,CAAC;CACrE;CAEA,SAAS,cAAc,MAAmB;EACxC,MAAI,cAAc,KAAK,KAAK,CAAC;EAC7B,MAAI,eAAe,KAAK,MAAM,IAAI,CAAC;EACnC,MAAI,aAAa,KAAK,KAAK,CAAC;EAC5B,MAAI,cAAc,KAAK,KAAK,CAAC;EAC7B,MAAI,gBAAgB,KAAK,OAAO,CAAC;EACjC,MAAI,gBAAgB,eAAe,QAAQ,IAAI,KAAK,OAAO,IAAI,CAAC;EAChE,MAAI,qBAAqB,oBAAoB,QAAQ,IAAI,KAAK,YAAY,IAAI,CAAC;CACjF;CAEA,SAAS,SAAe;EACtB,MAAI,uBAAuB,CAAC,CAAC;EAE7B,MAAM,OAAO,MAAM;EACnB,MAAI,KAAK,IAAI;EACb,cAAc,eAAe,IAAI,CAAC;EAElC,eAAe;GACb,iBAAiB;EACnB,CAAC;CACH;;;;;CAMA,SAAS,WAAiB;EACxB,MAAI,uBAAuB,CAAC,CAAC;EAE7B,MAAM,OAAO,MAAM;EACnB,MAAI,KAAK,IAAI;EAYb,cAAc,eAVC,cAAc;GAC3B,KAAK,KAAK,KAAK;GACf,MAAM,MAAI,YAAY,KAAK;GAC3B,aAAa,MAAI,mBAAmB,KAAK;GACzC,QAAQ,MAAI,cAAc,KAAK;GAC/B,OAAO,KAAK,MAAM,IAAI;GACtB,QAAQ,MAAI,cAAc,KAAK;GAC/B,MAAM,KAAK,KAAK;EAClB,GAAG,UAAU,IAEgB,CAAM,CAAC;EAEpC,eAAe;GACb,iBAAiB;EACnB,CAAC;CACH;CAEA,SAAS,eAAe,MAAmB;EACzC,MAAM,OAAO,KAAK,KAAK;EACvB,MAAM,QAAQ,KAAK,MAAM,IAAI;EAC7B,MAAM,MAAM,KAAK,KAAK;EACtB,MAAM,OAAO,KAAK,KAAK;EACvB,MAAM,SAAS,KAAK,OAAO;EAC3B,MAAM,SAAS,eAAe,QAAQ,IAAI,KAAK,OAAO,IAAI,KAAA;EAC1D,MAAM,cAAc,oBAAoB,QAAQ,IAAI,KAAK,YAAY,IAAI,KAAA;EAEzE,IAAI,MAAI,YAAY,MAAM,MACxB,MAAI,cAAc,IAAI;EACxB,IAAI,MAAI,aAAa,MAAM,OACzB,MAAI,eAAe,KAAK;EAC1B,IAAI,MAAI,WAAW,MAAM,KACvB,MAAI,aAAa,GAAG;EACtB,IAAI,MAAI,YAAY,MAAM,MACxB,MAAI,cAAc,IAAI;EACxB,IAAI,MAAI,cAAc,MAAM,QAC1B,MAAI,gBAAgB,MAAM;EAC5B,IAAI,MAAI,cAAc,MAAM,QAC1B,MAAI,gBAAgB,MAAM;EAC5B,IAAI,MAAI,mBAAmB,MAAM,aAC/B,MAAI,qBAAqB,WAAW;CACxC;CAEA,MAAM,EAAE,kBAAkB,eAAe,CAAC,cAAc,YAAY,IAAI,CAAC,iBAAiB,kBAAkB,CAAC,kBAAkB,sBAAsB;EACnJ,MAAM,kBAAkB,MAAI,gBAAgB;EAC5C,MAAM,UAAU,MAAM,GAAG,iBAAiB,eAAe;EACzD,MAAM,UAAU,MAAM,GAAG,kBAAkB,eAAe;EAC1D,MAAM,UAAU,MAAM,GAAG,iBAAiB,eAAe;EACzD,MAAM,UAAU,MAAM,GAAG,kBAAkB,eAAe;EAE1D,IAAI,QAAQ,OAAO,OAAO,KAAK,QAAQ,OAAO,OAAO,GACnD;EAGF,MAAI,KAAK,MAAM,CAAC;EAChB,iBAAiB;CACnB,CAAC;CAED,SAAS,oBAAoB,OAAgC;EAC3D,oBAAoB;GAClB,MAAM,eAAe,SAAS,WAAW,OAAO,UAAU,WACtD,QAAQ,eACR;GACJ,MAAM,OAAO,MAAM,GAAG,cAAc,MAAI,gBAAgB,CAAC;GACzD,YAAY,IAAI;GAChB,eAAe,IAAI;EACrB,CAAC;CACH;CAEA,MAAM,mBAAmB,gBAAoC;EAC3D,IAAI,eAAe,UAAU,YAAY,KAAK,UAAU,YAAY,GAAG;GACrE,MAAI,KAAK,MAAM,CAAC;GAChB,iBAAiB;EACnB;CACF,CAAC;CAED,MAAM,aAAa,UAAU;EAC3B,MAAI,KAAK,MAAM,CAAC;EAChB,IAAI,UAAU,KAAA,GACZ,MAAM;OAGN,oBAAoB,KAAK;CAE7B,CAAC;CAED,gBAAgB;EACd,IAAI,UAAU,UAAU,GACtB,oBAAoB,MAAI,UAAU,CAAC;OAEhC,IAAI,CAAC,YACR,OAAO;CAEX,CAAC;CAED,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { assert } from "../../utils/assert.js";
|
|
2
|
-
import { SEGMENT_CONFIG, SEGMENT_METHODS } from "./segment-config.js";
|
|
3
2
|
import { getClickPosition, parseAndSetDateValues } from "./segment-utils.js";
|
|
3
|
+
import { SEGMENT_CONFIG, SEGMENT_METHODS } from "./segment-config.js";
|
|
4
4
|
import { isDateTimeSegmentType } from "./types.js";
|
|
5
5
|
import { computed, nextTick } from "vue";
|
|
6
6
|
import { isDefined } from "@vueuse/core";
|
|
@@ -132,13 +132,14 @@ function useKeyboardHandler(options) {
|
|
|
132
132
|
function handleKeyDown(event) {
|
|
133
133
|
if (disabled || readonly) return;
|
|
134
134
|
const { key } = event;
|
|
135
|
-
if (
|
|
136
|
-
event.preventDefault();
|
|
135
|
+
if (event.ctrlKey || event.metaKey || event.altKey) return;
|
|
137
136
|
if (key === "ArrowRight" || key === "ArrowLeft") navigateSegments(key);
|
|
138
137
|
else if (key === "ArrowUp" || key === "ArrowDown") handleKeyboardNavigation(event);
|
|
139
138
|
else if (key === "Backspace") handleBackspace(event);
|
|
140
139
|
else if (key === "Delete") onInputDeletePressed(event);
|
|
141
140
|
else if (/^\d$/.test(key)) handleDigitPressed(event, key);
|
|
141
|
+
else return;
|
|
142
|
+
event.preventDefault();
|
|
142
143
|
}
|
|
143
144
|
let clickedSegment;
|
|
144
145
|
function handleMouseDown(event) {
|