@coreui/vue-pro 5.13.0 → 5.15.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/README.md +1 -1
- package/dist/cjs/components/calendar/CCalendar.js +61 -65
- package/dist/cjs/components/calendar/CCalendar.js.map +1 -1
- package/dist/cjs/components/calendar/utils.d.ts +53 -2
- package/dist/cjs/components/calendar/utils.js +466 -43
- package/dist/cjs/components/calendar/utils.js.map +1 -1
- package/dist/cjs/components/date-picker/CDatePicker.d.ts +19 -0
- package/dist/cjs/components/date-picker/CDatePicker.js +9 -0
- package/dist/cjs/components/date-picker/CDatePicker.js.map +1 -1
- package/dist/cjs/components/date-range-picker/CDateRangePicker.d.ts +19 -0
- package/dist/cjs/components/date-range-picker/CDateRangePicker.js +98 -57
- package/dist/cjs/components/date-range-picker/CDateRangePicker.js.map +1 -1
- package/dist/cjs/components/date-range-picker/utils.d.ts +0 -9
- package/dist/cjs/components/date-range-picker/utils.js +0 -38
- package/dist/cjs/components/date-range-picker/utils.js.map +1 -1
- package/dist/cjs/components/dropdown/CDropdown.js +22 -13
- package/dist/cjs/components/dropdown/CDropdown.js.map +1 -1
- package/dist/cjs/components/dropdown/CDropdownToggle.js +7 -1
- package/dist/cjs/components/dropdown/CDropdownToggle.js.map +1 -1
- package/dist/cjs/components/focus-trap/CFocusTrap.d.ts +108 -0
- package/dist/cjs/components/focus-trap/CFocusTrap.js +254 -0
- package/dist/cjs/components/focus-trap/CFocusTrap.js.map +1 -0
- package/dist/cjs/components/focus-trap/index.d.ts +6 -0
- package/dist/cjs/components/focus-trap/index.js +13 -0
- package/dist/cjs/components/focus-trap/index.js.map +1 -0
- package/dist/cjs/components/focus-trap/utils.d.ts +28 -0
- package/dist/cjs/components/focus-trap/utils.js +83 -0
- package/dist/cjs/components/focus-trap/utils.js.map +1 -0
- package/dist/cjs/components/index.d.ts +1 -0
- package/dist/cjs/components/index.js +70 -66
- package/dist/cjs/components/index.js.map +1 -1
- package/dist/cjs/components/modal/CModal.d.ts +2 -2
- package/dist/cjs/components/modal/CModal.js +19 -27
- package/dist/cjs/components/modal/CModal.js.map +1 -1
- package/dist/cjs/components/modal/CModalHeader.js +4 -2
- package/dist/cjs/components/modal/CModalHeader.js.map +1 -1
- package/dist/cjs/components/offcanvas/COffcanvas.js +3 -2
- package/dist/cjs/components/offcanvas/COffcanvas.js.map +1 -1
- package/dist/cjs/components/picker/CPicker.js +3 -2
- package/dist/cjs/components/picker/CPicker.js.map +1 -1
- package/dist/cjs/components/time-picker/CTimePicker.d.ts +1 -1
- package/dist/cjs/components/time-picker/CTimePicker.js +1 -1
- package/dist/cjs/components/time-picker/CTimePicker.js.map +1 -1
- package/dist/cjs/components/time-picker/utils.d.ts +1 -1
- package/dist/cjs/composables/useDebouncedCallback.d.ts +1 -1
- package/dist/cjs/composables/useDebouncedCallback.js +1 -1
- package/dist/cjs/composables/useDebouncedCallback.js.map +1 -1
- package/dist/cjs/index.js +76 -72
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/components/calendar/CCalendar.js +61 -65
- package/dist/esm/components/calendar/CCalendar.js.map +1 -1
- package/dist/esm/components/calendar/utils.d.ts +53 -2
- package/dist/esm/components/calendar/utils.js +464 -44
- package/dist/esm/components/calendar/utils.js.map +1 -1
- package/dist/esm/components/date-picker/CDatePicker.d.ts +19 -0
- package/dist/esm/components/date-picker/CDatePicker.js +9 -0
- package/dist/esm/components/date-picker/CDatePicker.js.map +1 -1
- package/dist/esm/components/date-range-picker/CDateRangePicker.d.ts +19 -0
- package/dist/esm/components/date-range-picker/CDateRangePicker.js +98 -57
- package/dist/esm/components/date-range-picker/CDateRangePicker.js.map +1 -1
- package/dist/esm/components/date-range-picker/utils.d.ts +0 -9
- package/dist/esm/components/date-range-picker/utils.js +1 -38
- package/dist/esm/components/date-range-picker/utils.js.map +1 -1
- package/dist/esm/components/dropdown/CDropdown.js +23 -14
- package/dist/esm/components/dropdown/CDropdown.js.map +1 -1
- package/dist/esm/components/dropdown/CDropdownToggle.js +7 -1
- package/dist/esm/components/dropdown/CDropdownToggle.js.map +1 -1
- package/dist/esm/components/focus-trap/CFocusTrap.d.ts +108 -0
- package/dist/esm/components/focus-trap/CFocusTrap.js +252 -0
- package/dist/esm/components/focus-trap/CFocusTrap.js.map +1 -0
- package/dist/esm/components/focus-trap/index.d.ts +6 -0
- package/dist/esm/components/focus-trap/index.js +10 -0
- package/dist/esm/components/focus-trap/index.js.map +1 -0
- package/dist/esm/components/focus-trap/utils.d.ts +28 -0
- package/dist/esm/components/focus-trap/utils.js +78 -0
- package/dist/esm/components/focus-trap/utils.js.map +1 -0
- package/dist/esm/components/index.d.ts +1 -0
- package/dist/esm/components/index.js +2 -0
- package/dist/esm/components/index.js.map +1 -1
- package/dist/esm/components/modal/CModal.d.ts +2 -2
- package/dist/esm/components/modal/CModal.js +19 -27
- package/dist/esm/components/modal/CModal.js.map +1 -1
- package/dist/esm/components/modal/CModalHeader.js +4 -2
- package/dist/esm/components/modal/CModalHeader.js.map +1 -1
- package/dist/esm/components/offcanvas/COffcanvas.js +3 -2
- package/dist/esm/components/offcanvas/COffcanvas.js.map +1 -1
- package/dist/esm/components/picker/CPicker.js +3 -2
- package/dist/esm/components/picker/CPicker.js.map +1 -1
- package/dist/esm/components/time-picker/CTimePicker.d.ts +1 -1
- package/dist/esm/components/time-picker/CTimePicker.js +1 -1
- package/dist/esm/components/time-picker/CTimePicker.js.map +1 -1
- package/dist/esm/components/time-picker/utils.d.ts +1 -1
- package/dist/esm/composables/useDebouncedCallback.d.ts +1 -1
- package/dist/esm/composables/useDebouncedCallback.js +1 -1
- package/dist/esm/composables/useDebouncedCallback.js.map +1 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/package.json +5 -5
- package/src/components/calendar/CCalendar.ts +55 -70
- package/src/components/calendar/utils.ts +595 -47
- package/src/components/date-picker/CDatePicker.ts +9 -0
- package/src/components/date-range-picker/CDateRangePicker.ts +144 -82
- package/src/components/date-range-picker/utils.ts +0 -58
- package/src/components/dropdown/CDropdown.ts +34 -23
- package/src/components/dropdown/CDropdownToggle.ts +8 -2
- package/src/components/focus-trap/CFocusTrap.ts +303 -0
- package/src/components/focus-trap/index.ts +10 -0
- package/src/components/focus-trap/utils.ts +90 -0
- package/src/components/index.ts +1 -0
- package/src/components/modal/CModal.ts +32 -37
- package/src/components/modal/CModalHeader.ts +5 -3
- package/src/components/offcanvas/COffcanvas.ts +40 -36
- package/src/components/picker/CPicker.ts +58 -52
- package/src/components/time-picker/CTimePicker.ts +12 -13
- package/src/composables/useDebouncedCallback.ts +1 -1
|
@@ -281,6 +281,15 @@ const CDatePicker = defineComponent({
|
|
|
281
281
|
type: String,
|
|
282
282
|
default: 'Select date',
|
|
283
283
|
},
|
|
284
|
+
/**
|
|
285
|
+
* Enable live preview of dates in input fields when hovering over calendar cells.
|
|
286
|
+
*
|
|
287
|
+
* @since 5.14.0
|
|
288
|
+
*/
|
|
289
|
+
previewDateOnHover: {
|
|
290
|
+
type: Boolean,
|
|
291
|
+
default: true,
|
|
292
|
+
},
|
|
284
293
|
/**
|
|
285
294
|
* Set whether days in adjacent months shown before or after the current month are selectable. This only applies if the `showAdjacementDays` option is set to true.
|
|
286
295
|
*
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import { defineComponent, h, onMounted, PropType, ref, watch } from 'vue'
|
|
1
|
+
import { defineComponent, h, onMounted, PropType, Ref, ref, watch } from 'vue'
|
|
2
2
|
|
|
3
3
|
import { CButton } from '../button'
|
|
4
4
|
import { CCalendar } from '../calendar'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
convertToDateObject,
|
|
7
|
+
getDateBySelectionType,
|
|
8
|
+
getLocalDateFromString,
|
|
9
|
+
isDateDisabled,
|
|
10
|
+
} from '../calendar/utils'
|
|
6
11
|
import { CFormControlWrapper } from './../form/CFormControlWrapper'
|
|
7
12
|
import { CPicker } from '../picker'
|
|
8
13
|
import { CTimePicker } from '../time-picker'
|
|
9
14
|
|
|
10
|
-
import { getInputIdOrName
|
|
15
|
+
import { getInputIdOrName } from './utils'
|
|
11
16
|
|
|
12
17
|
import { useDebouncedCallback } from '../../composables'
|
|
13
18
|
import { Color } from '../props'
|
|
@@ -341,6 +346,15 @@ const CDateRangePicker = defineComponent({
|
|
|
341
346
|
type: [String, Array] as PropType<string | [string, string]>,
|
|
342
347
|
default: () => ['Start date', 'End date'],
|
|
343
348
|
},
|
|
349
|
+
/**
|
|
350
|
+
* Enable live preview of dates in input fields when hovering over calendar cells.
|
|
351
|
+
*
|
|
352
|
+
* @since 5.14.0
|
|
353
|
+
*/
|
|
354
|
+
previewDateOnHover: {
|
|
355
|
+
type: Boolean,
|
|
356
|
+
default: true,
|
|
357
|
+
},
|
|
344
358
|
/**
|
|
345
359
|
* @ignore
|
|
346
360
|
*/
|
|
@@ -640,9 +654,17 @@ const CDateRangePicker = defineComponent({
|
|
|
640
654
|
|
|
641
655
|
const formatDate = (date: Date | string) => {
|
|
642
656
|
if (props.inputDateFormat) {
|
|
643
|
-
|
|
657
|
+
const convertedDate =
|
|
644
658
|
date instanceof Date ? new Date(date) : convertToDateObject(date, props.selectionType)
|
|
645
|
-
|
|
659
|
+
|
|
660
|
+
if (
|
|
661
|
+
!convertedDate ||
|
|
662
|
+
(convertedDate instanceof Date && Number.isNaN(convertedDate.getTime()))
|
|
663
|
+
) {
|
|
664
|
+
return ''
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
return props.inputDateFormat(convertedDate)
|
|
646
668
|
}
|
|
647
669
|
|
|
648
670
|
if (props.selectionType !== 'day') {
|
|
@@ -650,13 +672,20 @@ const CDateRangePicker = defineComponent({
|
|
|
650
672
|
}
|
|
651
673
|
|
|
652
674
|
const _date = new Date(date)
|
|
675
|
+
if (Number.isNaN(_date.getTime())) {
|
|
676
|
+
return ''
|
|
677
|
+
}
|
|
653
678
|
|
|
654
679
|
return props.timepicker
|
|
655
680
|
? _date.toLocaleString(props.locale)
|
|
656
681
|
: _date.toLocaleDateString(props.locale)
|
|
657
682
|
}
|
|
658
683
|
|
|
659
|
-
const setInputValue = (date: Date | string | null) => {
|
|
684
|
+
const setInputValue = (date: Date | string | null, value?: Ref<HTMLInputElement>) => {
|
|
685
|
+
if (date instanceof Date && isNaN(date.getTime())) {
|
|
686
|
+
return value?.value
|
|
687
|
+
}
|
|
688
|
+
|
|
660
689
|
if (date) {
|
|
661
690
|
return formatDate(date)
|
|
662
691
|
}
|
|
@@ -665,6 +694,10 @@ const CDateRangePicker = defineComponent({
|
|
|
665
694
|
}
|
|
666
695
|
|
|
667
696
|
const handleDateHover = (date: Date | string | null) => {
|
|
697
|
+
if (!props.previewDateOnHover) {
|
|
698
|
+
return
|
|
699
|
+
}
|
|
700
|
+
|
|
668
701
|
if (selectEndDate.value) {
|
|
669
702
|
inputEndHoverValue.value = date
|
|
670
703
|
return
|
|
@@ -737,24 +770,118 @@ const CDateRangePicker = defineComponent({
|
|
|
737
770
|
}
|
|
738
771
|
|
|
739
772
|
const handleOnChange = (value: string, input: string) => {
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
773
|
+
let date: Date | string | null = null
|
|
774
|
+
|
|
775
|
+
if (props.inputDateParse) {
|
|
776
|
+
date = props.inputDateParse(value)
|
|
777
|
+
} else if (props.selectionType === 'day') {
|
|
778
|
+
date = getLocalDateFromString(value, props.locale, props.timepicker)
|
|
779
|
+
} else {
|
|
780
|
+
date = convertToDateObject(value, props.selectionType)
|
|
781
|
+
}
|
|
782
|
+
|
|
743
783
|
if (date instanceof Date && date.getTime()) {
|
|
784
|
+
if (
|
|
785
|
+
isDateDisabled(
|
|
786
|
+
date,
|
|
787
|
+
props.minDate ? convertToDateObject(props.minDate, props.selectionType) : null,
|
|
788
|
+
props.maxDate ? convertToDateObject(props.maxDate, props.selectionType) : null,
|
|
789
|
+
props.disabledDates
|
|
790
|
+
)
|
|
791
|
+
) {
|
|
792
|
+
return // Don't update if date is disabled
|
|
793
|
+
}
|
|
794
|
+
|
|
744
795
|
calendarDate.value = date
|
|
745
796
|
}
|
|
746
797
|
|
|
798
|
+
let formatedDate: Date | string | null = date ?? null
|
|
799
|
+
|
|
800
|
+
if (date instanceof Date && date.getTime() && props.selectionType !== 'day') {
|
|
801
|
+
formatedDate = getDateBySelectionType(date, props.selectionType)
|
|
802
|
+
}
|
|
803
|
+
|
|
747
804
|
if (input === 'start') {
|
|
748
|
-
startDate.value =
|
|
749
|
-
emit('start-date-change',
|
|
750
|
-
emit('update:start-date',
|
|
805
|
+
startDate.value = formatedDate ?? null
|
|
806
|
+
emit('start-date-change', formatedDate ?? null)
|
|
807
|
+
emit('update:start-date', formatedDate ?? null)
|
|
751
808
|
} else {
|
|
752
|
-
endDate.value =
|
|
753
|
-
emit('end-date-change',
|
|
754
|
-
emit('update:end-date',
|
|
809
|
+
endDate.value = formatedDate ?? null
|
|
810
|
+
emit('end-date-change', formatedDate ?? null)
|
|
811
|
+
emit('update:end-date', formatedDate ?? null)
|
|
755
812
|
}
|
|
756
813
|
}
|
|
757
814
|
|
|
815
|
+
const createInputElement = (position: 'start' | 'end') => {
|
|
816
|
+
const isStart = position === 'start'
|
|
817
|
+
const hoverValue = isStart ? inputStartHoverValue.value : inputEndHoverValue.value
|
|
818
|
+
const dateValue = isStart ? startDate.value : endDate.value
|
|
819
|
+
const inputRef = isStart ? inputStartRef : inputEndRef
|
|
820
|
+
|
|
821
|
+
return h('input', {
|
|
822
|
+
autocomplete: 'off',
|
|
823
|
+
class: [
|
|
824
|
+
'date-picker-input',
|
|
825
|
+
{
|
|
826
|
+
hover: hoverValue,
|
|
827
|
+
},
|
|
828
|
+
],
|
|
829
|
+
disabled: props.disabled,
|
|
830
|
+
...(props.id && { id: getInputIdOrName(props.id, props.range, position) }),
|
|
831
|
+
...(props.name && { name: getInputIdOrName(props.name, props.range, position) }),
|
|
832
|
+
...(props.id &&
|
|
833
|
+
!Array.isArray(props.id) &&
|
|
834
|
+
!props.name && {
|
|
835
|
+
name: isStart
|
|
836
|
+
? props.range
|
|
837
|
+
? `${props.id}-start-date`
|
|
838
|
+
: `${props.id}-date`
|
|
839
|
+
: `${props.id}-end-date`,
|
|
840
|
+
}), // TODO: remove in v6
|
|
841
|
+
onClick: () => {
|
|
842
|
+
selectEndDate.value = !isStart
|
|
843
|
+
},
|
|
844
|
+
onChange: (event: Event) =>
|
|
845
|
+
handleOnChange((event.target as HTMLInputElement).value, position),
|
|
846
|
+
onInput: useDebouncedCallback(
|
|
847
|
+
(event: Event) => handleOnChange((event.target as HTMLInputElement).value, position),
|
|
848
|
+
props.inputOnChangeDelay
|
|
849
|
+
),
|
|
850
|
+
placeholder: Array.isArray(props.placeholder)
|
|
851
|
+
? props.placeholder[isStart ? 0 : 1]
|
|
852
|
+
: props.placeholder,
|
|
853
|
+
readonly: props.inputReadOnly || typeof props.format === 'string',
|
|
854
|
+
required: props.required,
|
|
855
|
+
ref: inputRef,
|
|
856
|
+
value: setInputValue(dateValue, inputRef.value),
|
|
857
|
+
})
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
const createPreviewInput = (position: 'start' | 'end') => {
|
|
861
|
+
const isStart = position === 'start'
|
|
862
|
+
const hoverValue = isStart ? inputStartHoverValue.value : inputEndHoverValue.value
|
|
863
|
+
|
|
864
|
+
return (
|
|
865
|
+
hoverValue &&
|
|
866
|
+
h('input', {
|
|
867
|
+
class: 'date-picker-input date-picker-input-preview',
|
|
868
|
+
disabled: props.disabled,
|
|
869
|
+
readonly: true,
|
|
870
|
+
tabIndex: -1,
|
|
871
|
+
value: hoverValue ? setInputValue(hoverValue) : '',
|
|
872
|
+
})
|
|
873
|
+
)
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
const createInputWithWrapper = (position: 'start' | 'end') => {
|
|
877
|
+
return props.previewDateOnHover
|
|
878
|
+
? h('div', { class: 'date-picker-input-wrapper' }, [
|
|
879
|
+
createInputElement(position),
|
|
880
|
+
createPreviewInput(position),
|
|
881
|
+
])
|
|
882
|
+
: createInputElement(position)
|
|
883
|
+
}
|
|
884
|
+
|
|
758
885
|
const InputGroup = () =>
|
|
759
886
|
h(
|
|
760
887
|
'div',
|
|
@@ -762,74 +889,9 @@ const CDateRangePicker = defineComponent({
|
|
|
762
889
|
class: 'date-picker-input-group',
|
|
763
890
|
},
|
|
764
891
|
[
|
|
765
|
-
|
|
766
|
-
autocomplete: 'off',
|
|
767
|
-
class: [
|
|
768
|
-
'date-picker-input',
|
|
769
|
-
{
|
|
770
|
-
hover: inputStartHoverValue.value,
|
|
771
|
-
},
|
|
772
|
-
],
|
|
773
|
-
disabled: props.disabled,
|
|
774
|
-
...(props.id && { id: getInputIdOrName(props.id, props.range, 'start') }),
|
|
775
|
-
...(props.name && { name: getInputIdOrName(props.name, props.range, 'start') }),
|
|
776
|
-
...(props.id &&
|
|
777
|
-
!Array.isArray(props.id) &&
|
|
778
|
-
!props.name && { name: props.range ? `${props.id}-start-date` : `${props.id}-date` }), // TODO: remove in v6
|
|
779
|
-
onClick: () => {
|
|
780
|
-
selectEndDate.value = false
|
|
781
|
-
},
|
|
782
|
-
onChange: (event: Event) =>
|
|
783
|
-
handleOnChange((event.target as HTMLInputElement).value, 'start'),
|
|
784
|
-
onInput: (event: Event) =>
|
|
785
|
-
useDebouncedCallback(
|
|
786
|
-
() => handleOnChange((event.target as HTMLInputElement).value, 'start'),
|
|
787
|
-
props.inputOnChangeDelay
|
|
788
|
-
),
|
|
789
|
-
placeholder: Array.isArray(props.placeholder)
|
|
790
|
-
? props.placeholder[0]
|
|
791
|
-
: props.placeholder,
|
|
792
|
-
readonly: props.inputReadOnly || typeof props.format === 'string',
|
|
793
|
-
required: props.required,
|
|
794
|
-
ref: inputStartRef,
|
|
795
|
-
value: inputStartHoverValue.value
|
|
796
|
-
? setInputValue(inputStartHoverValue.value)
|
|
797
|
-
: setInputValue(startDate.value),
|
|
798
|
-
}),
|
|
892
|
+
createInputWithWrapper('start'),
|
|
799
893
|
props.range && props.separator !== false && h('div', { class: 'date-picker-separator' }),
|
|
800
|
-
props.range &&
|
|
801
|
-
h('input', {
|
|
802
|
-
autocomplete: 'off',
|
|
803
|
-
class: [
|
|
804
|
-
'date-picker-input',
|
|
805
|
-
{
|
|
806
|
-
hover: inputEndHoverValue.value,
|
|
807
|
-
},
|
|
808
|
-
],
|
|
809
|
-
disabled: props.disabled,
|
|
810
|
-
...(props.id && { id: getInputIdOrName(props.id, props.range, 'end') }),
|
|
811
|
-
...(props.name && { name: getInputIdOrName(props.name, props.range, 'end') }),
|
|
812
|
-
...(props.id &&
|
|
813
|
-
!Array.isArray(props.id) &&
|
|
814
|
-
!props.name && { name: `${props.id}-end-date` }), // TODO: remove in v6
|
|
815
|
-
onClick: () => {
|
|
816
|
-
selectEndDate.value = true
|
|
817
|
-
},
|
|
818
|
-
onChange: (event: Event) =>
|
|
819
|
-
handleOnChange((event.target as HTMLInputElement).value, 'end'),
|
|
820
|
-
onInput: (event: Event) =>
|
|
821
|
-
useDebouncedCallback(
|
|
822
|
-
() => handleOnChange((event.target as HTMLInputElement).value, 'end'),
|
|
823
|
-
props.inputOnChangeDelay
|
|
824
|
-
),
|
|
825
|
-
placeholder: props.placeholder[1],
|
|
826
|
-
readonly: props.inputReadOnly || typeof props.format === 'string',
|
|
827
|
-
required: props.required,
|
|
828
|
-
ref: inputEndRef,
|
|
829
|
-
value: inputEndHoverValue.value
|
|
830
|
-
? setInputValue(inputEndHoverValue.value)
|
|
831
|
-
: setInputValue(endDate.value),
|
|
832
|
-
}),
|
|
894
|
+
props.range && createInputWithWrapper('end'),
|
|
833
895
|
props.indicator &&
|
|
834
896
|
h('div', {
|
|
835
897
|
class: 'date-picker-indicator',
|
|
@@ -21,61 +21,3 @@ export const getInputIdOrName = (
|
|
|
21
21
|
|
|
22
22
|
return attribute
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Parses a date string into a Date object based on the provided locale and time inclusion.
|
|
27
|
-
*
|
|
28
|
-
* @param dateString - The date string to parse.
|
|
29
|
-
* @param locale - The locale to use for parsing the date string.
|
|
30
|
-
* @param includeTime - Optional. Determines whether to include time in the parsed Date object.
|
|
31
|
-
* @returns A Date object representing the parsed date and time, or `undefined` if parsing fails.
|
|
32
|
-
*/
|
|
33
|
-
export const getLocalDateFromString = (
|
|
34
|
-
string: string,
|
|
35
|
-
locale: string,
|
|
36
|
-
time?: boolean
|
|
37
|
-
): Date | undefined => {
|
|
38
|
-
const date = new Date(2013, 11, 31, 17, 19, 22)
|
|
39
|
-
let regex = time ? date.toLocaleString(locale) : date.toLocaleDateString(locale)
|
|
40
|
-
regex = regex
|
|
41
|
-
.replace('2013', '(?<year>[0-9]{2,4})')
|
|
42
|
-
.replace('12', '(?<month>[0-9]{1,2})')
|
|
43
|
-
.replace('31', '(?<day>[0-9]{1,2})')
|
|
44
|
-
|
|
45
|
-
if (time) {
|
|
46
|
-
regex = regex
|
|
47
|
-
.replace('5', '(?<hour>[0-9]{1,2})')
|
|
48
|
-
.replace('17', '(?<hour>[0-9]{1,2})')
|
|
49
|
-
.replace('19', '(?<minute>[0-9]{1,2})')
|
|
50
|
-
.replace('22', '(?<second>[0-9]{1,2})')
|
|
51
|
-
.replace('PM', '(?<ampm>[A-Z]{2})')
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const rgx = new RegExp(`${regex}`)
|
|
55
|
-
const partials = string.match(rgx)
|
|
56
|
-
|
|
57
|
-
if (partials === null) return
|
|
58
|
-
|
|
59
|
-
const newDate =
|
|
60
|
-
partials.groups &&
|
|
61
|
-
(time
|
|
62
|
-
? new Date(
|
|
63
|
-
Number(partials.groups['year']),
|
|
64
|
-
Number(partials.groups['month']) - 1,
|
|
65
|
-
Number(partials.groups['day']),
|
|
66
|
-
partials.groups['ampm']
|
|
67
|
-
? partials.groups['ampm'] === 'PM'
|
|
68
|
-
? Number(partials.groups['hour']) + 12
|
|
69
|
-
: Number(partials.groups['hour'])
|
|
70
|
-
: Number(partials.groups['hour']),
|
|
71
|
-
Number(partials.groups['minute']),
|
|
72
|
-
Number(partials.groups['second'])
|
|
73
|
-
)
|
|
74
|
-
: new Date(
|
|
75
|
-
Number(partials.groups['year']),
|
|
76
|
-
Number(partials.groups['month']) - 1,
|
|
77
|
-
Number(partials.groups['day'])
|
|
78
|
-
))
|
|
79
|
-
|
|
80
|
-
return newDate
|
|
81
|
-
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent, h, ref, provide, watch, PropType } from 'vue'
|
|
1
|
+
import { defineComponent, h, ref, provide, watch, PropType, onUnmounted, nextTick } from 'vue'
|
|
2
2
|
import type { Placement } from '@popperjs/core'
|
|
3
3
|
|
|
4
4
|
import { usePopper } from '../../composables'
|
|
@@ -158,6 +158,7 @@ const CDropdown = defineComponent({
|
|
|
158
158
|
setup(props, { slots, emit }) {
|
|
159
159
|
const dropdownToggleRef = ref()
|
|
160
160
|
const dropdownMenuRef = ref()
|
|
161
|
+
const pendingKeyDownEventRef = ref<KeyboardEvent | null>(null)
|
|
161
162
|
const popper = ref(typeof props.alignment === 'object' ? false : props.popper)
|
|
162
163
|
const visible = ref(props.visible)
|
|
163
164
|
|
|
@@ -176,7 +177,7 @@ const CDropdown = defineComponent({
|
|
|
176
177
|
props.placement,
|
|
177
178
|
props.direction,
|
|
178
179
|
props.alignment,
|
|
179
|
-
isRTL(dropdownMenuRef.value)
|
|
180
|
+
isRTL(dropdownMenuRef.value)
|
|
180
181
|
) as Placement,
|
|
181
182
|
}
|
|
182
183
|
|
|
@@ -184,16 +185,27 @@ const CDropdown = defineComponent({
|
|
|
184
185
|
() => props.visible,
|
|
185
186
|
() => {
|
|
186
187
|
visible.value = props.visible
|
|
187
|
-
}
|
|
188
|
+
}
|
|
188
189
|
)
|
|
189
190
|
|
|
190
191
|
watch(visible, () => {
|
|
191
192
|
if (visible.value && dropdownToggleRef.value && dropdownMenuRef.value) {
|
|
192
|
-
|
|
193
|
+
if (popper.value) {
|
|
194
|
+
initPopper(dropdownToggleRef.value, dropdownMenuRef.value, popperConfig)
|
|
195
|
+
}
|
|
196
|
+
|
|
193
197
|
window.addEventListener('mouseup', handleMouseUp)
|
|
194
198
|
window.addEventListener('keyup', handleKeyup)
|
|
195
199
|
dropdownToggleRef.value.addEventListener('keydown', handleKeydown)
|
|
196
200
|
dropdownMenuRef.value.addEventListener('keydown', handleKeydown)
|
|
201
|
+
|
|
202
|
+
if (pendingKeyDownEventRef.value) {
|
|
203
|
+
nextTick(() => {
|
|
204
|
+
handleKeydown(pendingKeyDownEventRef.value as KeyboardEvent)
|
|
205
|
+
pendingKeyDownEventRef.value = null
|
|
206
|
+
})
|
|
207
|
+
}
|
|
208
|
+
|
|
197
209
|
emit('show')
|
|
198
210
|
return
|
|
199
211
|
}
|
|
@@ -201,10 +213,14 @@ const CDropdown = defineComponent({
|
|
|
201
213
|
popper.value && destroyPopper()
|
|
202
214
|
window.removeEventListener('mouseup', handleMouseUp)
|
|
203
215
|
window.removeEventListener('keyup', handleKeyup)
|
|
216
|
+
dropdownMenuRef.value && dropdownMenuRef.value.removeEventListener('keydown', handleKeydown)
|
|
217
|
+
emit('hide')
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
onUnmounted(() => {
|
|
204
221
|
dropdownToggleRef.value &&
|
|
205
222
|
dropdownToggleRef.value.removeEventListener('keydown', handleKeydown)
|
|
206
223
|
dropdownMenuRef.value && dropdownMenuRef.value.removeEventListener('keydown', handleKeydown)
|
|
207
|
-
emit('hide')
|
|
208
224
|
})
|
|
209
225
|
|
|
210
226
|
provide('config', {
|
|
@@ -219,18 +235,14 @@ const CDropdown = defineComponent({
|
|
|
219
235
|
provide('visible', visible)
|
|
220
236
|
provide('dropdownToggleRef', dropdownToggleRef)
|
|
221
237
|
provide('dropdownMenuRef', dropdownMenuRef)
|
|
238
|
+
provide('pendingKeyDownEventRef', pendingKeyDownEventRef)
|
|
222
239
|
|
|
223
240
|
const handleKeydown = (event: KeyboardEvent) => {
|
|
224
|
-
if (
|
|
225
|
-
visible.value &&
|
|
226
|
-
dropdownMenuRef.value &&
|
|
227
|
-
(event.key === 'ArrowDown' || event.key === 'ArrowUp')
|
|
228
|
-
) {
|
|
241
|
+
if (dropdownMenuRef.value && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {
|
|
229
242
|
event.preventDefault()
|
|
230
243
|
const target = event.target as HTMLElement
|
|
231
|
-
// eslint-disable-next-line unicorn/prefer-spread
|
|
232
244
|
const items: HTMLElement[] = Array.from(
|
|
233
|
-
dropdownMenuRef.value.querySelectorAll('.dropdown-item:not(.disabled):not(:disabled)')
|
|
245
|
+
dropdownMenuRef.value.querySelectorAll('.dropdown-item:not(.disabled):not(:disabled)')
|
|
234
246
|
)
|
|
235
247
|
getNextActiveElement(items, target, event.key === 'ArrowDown', true).focus()
|
|
236
248
|
}
|
|
@@ -243,6 +255,7 @@ const CDropdown = defineComponent({
|
|
|
243
255
|
|
|
244
256
|
if (event.key === 'Escape') {
|
|
245
257
|
setVisible(false)
|
|
258
|
+
dropdownToggleRef.value?.focus()
|
|
246
259
|
}
|
|
247
260
|
}
|
|
248
261
|
|
|
@@ -267,22 +280,20 @@ const CDropdown = defineComponent({
|
|
|
267
280
|
}
|
|
268
281
|
}
|
|
269
282
|
|
|
270
|
-
const setVisible = (_visible?: boolean) => {
|
|
283
|
+
const setVisible = (_visible?: boolean, event?: KeyboardEvent) => {
|
|
271
284
|
if (props.disabled) {
|
|
272
285
|
return
|
|
273
286
|
}
|
|
274
287
|
|
|
275
|
-
if (typeof _visible
|
|
288
|
+
if (typeof _visible === 'boolean') {
|
|
289
|
+
if (event) {
|
|
290
|
+
pendingKeyDownEventRef.value = event || null
|
|
291
|
+
}
|
|
292
|
+
|
|
276
293
|
visible.value = _visible
|
|
277
|
-
return
|
|
278
|
-
}
|
|
279
294
|
|
|
280
|
-
if (visible.value === true) {
|
|
281
|
-
visible.value = false
|
|
282
295
|
return
|
|
283
296
|
}
|
|
284
|
-
|
|
285
|
-
visible.value = true
|
|
286
297
|
}
|
|
287
298
|
|
|
288
299
|
provide('setVisible', setVisible)
|
|
@@ -298,11 +309,11 @@ const CDropdown = defineComponent({
|
|
|
298
309
|
props.direction === 'center'
|
|
299
310
|
? 'dropdown-center'
|
|
300
311
|
: props.direction === 'dropup-center'
|
|
301
|
-
|
|
302
|
-
|
|
312
|
+
? 'dropup dropup-center'
|
|
313
|
+
: props.direction,
|
|
303
314
|
],
|
|
304
315
|
},
|
|
305
|
-
slots.default && slots.default()
|
|
316
|
+
slots.default && slots.default()
|
|
306
317
|
)
|
|
307
318
|
},
|
|
308
319
|
})
|
|
@@ -100,7 +100,7 @@ const CDropdownToggle = defineComponent({
|
|
|
100
100
|
const dropdownToggleRef = inject('dropdownToggleRef') as Ref<HTMLElement>
|
|
101
101
|
const dropdownVariant = inject('variant') as string
|
|
102
102
|
const visible = inject('visible') as Ref<boolean>
|
|
103
|
-
const setVisible = inject('setVisible') as (_visible?: boolean) => void
|
|
103
|
+
const setVisible = inject('setVisible') as (_visible?: boolean, event?: KeyboardEvent) => void
|
|
104
104
|
|
|
105
105
|
const triggers = {
|
|
106
106
|
...((props.trigger === 'click' || props.trigger.includes('click')) && {
|
|
@@ -110,7 +110,7 @@ const CDropdownToggle = defineComponent({
|
|
|
110
110
|
return
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
setVisible()
|
|
113
|
+
setVisible(!visible.value)
|
|
114
114
|
},
|
|
115
115
|
}),
|
|
116
116
|
...((props.trigger === 'focus' || props.trigger.includes('focus')) && {
|
|
@@ -128,6 +128,12 @@ const CDropdownToggle = defineComponent({
|
|
|
128
128
|
setVisible(false)
|
|
129
129
|
},
|
|
130
130
|
}),
|
|
131
|
+
onkeydown: (event: KeyboardEvent) => {
|
|
132
|
+
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
133
|
+
event.preventDefault()
|
|
134
|
+
setVisible(true, event)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
131
137
|
}
|
|
132
138
|
|
|
133
139
|
const togglerProps = computed(() => {
|