@coreui/vue-pro 5.14.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-range-picker/CDateRangePicker.js +86 -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-range-picker/CDateRangePicker.js +86 -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 +4 -4
- package/src/components/calendar/CCalendar.ts +55 -70
- package/src/components/calendar/utils.ts +595 -47
- package/src/components/date-range-picker/CDateRangePicker.ts +131 -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
|
@@ -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'
|
|
@@ -649,9 +654,17 @@ const CDateRangePicker = defineComponent({
|
|
|
649
654
|
|
|
650
655
|
const formatDate = (date: Date | string) => {
|
|
651
656
|
if (props.inputDateFormat) {
|
|
652
|
-
|
|
657
|
+
const convertedDate =
|
|
653
658
|
date instanceof Date ? new Date(date) : convertToDateObject(date, props.selectionType)
|
|
654
|
-
|
|
659
|
+
|
|
660
|
+
if (
|
|
661
|
+
!convertedDate ||
|
|
662
|
+
(convertedDate instanceof Date && Number.isNaN(convertedDate.getTime()))
|
|
663
|
+
) {
|
|
664
|
+
return ''
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
return props.inputDateFormat(convertedDate)
|
|
655
668
|
}
|
|
656
669
|
|
|
657
670
|
if (props.selectionType !== 'day') {
|
|
@@ -659,13 +672,20 @@ const CDateRangePicker = defineComponent({
|
|
|
659
672
|
}
|
|
660
673
|
|
|
661
674
|
const _date = new Date(date)
|
|
675
|
+
if (Number.isNaN(_date.getTime())) {
|
|
676
|
+
return ''
|
|
677
|
+
}
|
|
662
678
|
|
|
663
679
|
return props.timepicker
|
|
664
680
|
? _date.toLocaleString(props.locale)
|
|
665
681
|
: _date.toLocaleDateString(props.locale)
|
|
666
682
|
}
|
|
667
683
|
|
|
668
|
-
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
|
+
|
|
669
689
|
if (date) {
|
|
670
690
|
return formatDate(date)
|
|
671
691
|
}
|
|
@@ -750,24 +770,118 @@ const CDateRangePicker = defineComponent({
|
|
|
750
770
|
}
|
|
751
771
|
|
|
752
772
|
const handleOnChange = (value: string, input: string) => {
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
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
|
+
|
|
756
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
|
+
|
|
757
795
|
calendarDate.value = date
|
|
758
796
|
}
|
|
759
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
|
+
|
|
760
804
|
if (input === 'start') {
|
|
761
|
-
startDate.value =
|
|
762
|
-
emit('start-date-change',
|
|
763
|
-
emit('update:start-date',
|
|
805
|
+
startDate.value = formatedDate ?? null
|
|
806
|
+
emit('start-date-change', formatedDate ?? null)
|
|
807
|
+
emit('update:start-date', formatedDate ?? null)
|
|
764
808
|
} else {
|
|
765
|
-
endDate.value =
|
|
766
|
-
emit('end-date-change',
|
|
767
|
-
emit('update:end-date',
|
|
809
|
+
endDate.value = formatedDate ?? null
|
|
810
|
+
emit('end-date-change', formatedDate ?? null)
|
|
811
|
+
emit('update:end-date', formatedDate ?? null)
|
|
768
812
|
}
|
|
769
813
|
}
|
|
770
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
|
+
|
|
771
885
|
const InputGroup = () =>
|
|
772
886
|
h(
|
|
773
887
|
'div',
|
|
@@ -775,74 +889,9 @@ const CDateRangePicker = defineComponent({
|
|
|
775
889
|
class: 'date-picker-input-group',
|
|
776
890
|
},
|
|
777
891
|
[
|
|
778
|
-
|
|
779
|
-
autocomplete: 'off',
|
|
780
|
-
class: [
|
|
781
|
-
'date-picker-input',
|
|
782
|
-
{
|
|
783
|
-
hover: inputStartHoverValue.value,
|
|
784
|
-
},
|
|
785
|
-
],
|
|
786
|
-
disabled: props.disabled,
|
|
787
|
-
...(props.id && { id: getInputIdOrName(props.id, props.range, 'start') }),
|
|
788
|
-
...(props.name && { name: getInputIdOrName(props.name, props.range, 'start') }),
|
|
789
|
-
...(props.id &&
|
|
790
|
-
!Array.isArray(props.id) &&
|
|
791
|
-
!props.name && { name: props.range ? `${props.id}-start-date` : `${props.id}-date` }), // TODO: remove in v6
|
|
792
|
-
onClick: () => {
|
|
793
|
-
selectEndDate.value = false
|
|
794
|
-
},
|
|
795
|
-
onChange: (event: Event) =>
|
|
796
|
-
handleOnChange((event.target as HTMLInputElement).value, 'start'),
|
|
797
|
-
onInput: (event: Event) =>
|
|
798
|
-
useDebouncedCallback(
|
|
799
|
-
() => handleOnChange((event.target as HTMLInputElement).value, 'start'),
|
|
800
|
-
props.inputOnChangeDelay
|
|
801
|
-
),
|
|
802
|
-
placeholder: Array.isArray(props.placeholder)
|
|
803
|
-
? props.placeholder[0]
|
|
804
|
-
: props.placeholder,
|
|
805
|
-
readonly: props.inputReadOnly || typeof props.format === 'string',
|
|
806
|
-
required: props.required,
|
|
807
|
-
ref: inputStartRef,
|
|
808
|
-
value: inputStartHoverValue.value
|
|
809
|
-
? setInputValue(inputStartHoverValue.value)
|
|
810
|
-
: setInputValue(startDate.value),
|
|
811
|
-
}),
|
|
892
|
+
createInputWithWrapper('start'),
|
|
812
893
|
props.range && props.separator !== false && h('div', { class: 'date-picker-separator' }),
|
|
813
|
-
props.range &&
|
|
814
|
-
h('input', {
|
|
815
|
-
autocomplete: 'off',
|
|
816
|
-
class: [
|
|
817
|
-
'date-picker-input',
|
|
818
|
-
{
|
|
819
|
-
hover: inputEndHoverValue.value,
|
|
820
|
-
},
|
|
821
|
-
],
|
|
822
|
-
disabled: props.disabled,
|
|
823
|
-
...(props.id && { id: getInputIdOrName(props.id, props.range, 'end') }),
|
|
824
|
-
...(props.name && { name: getInputIdOrName(props.name, props.range, 'end') }),
|
|
825
|
-
...(props.id &&
|
|
826
|
-
!Array.isArray(props.id) &&
|
|
827
|
-
!props.name && { name: `${props.id}-end-date` }), // TODO: remove in v6
|
|
828
|
-
onClick: () => {
|
|
829
|
-
selectEndDate.value = true
|
|
830
|
-
},
|
|
831
|
-
onChange: (event: Event) =>
|
|
832
|
-
handleOnChange((event.target as HTMLInputElement).value, 'end'),
|
|
833
|
-
onInput: (event: Event) =>
|
|
834
|
-
useDebouncedCallback(
|
|
835
|
-
() => handleOnChange((event.target as HTMLInputElement).value, 'end'),
|
|
836
|
-
props.inputOnChangeDelay
|
|
837
|
-
),
|
|
838
|
-
placeholder: props.placeholder[1],
|
|
839
|
-
readonly: props.inputReadOnly || typeof props.format === 'string',
|
|
840
|
-
required: props.required,
|
|
841
|
-
ref: inputEndRef,
|
|
842
|
-
value: inputEndHoverValue.value
|
|
843
|
-
? setInputValue(inputEndHoverValue.value)
|
|
844
|
-
: setInputValue(endDate.value),
|
|
845
|
-
}),
|
|
894
|
+
props.range && createInputWithWrapper('end'),
|
|
846
895
|
props.indicator &&
|
|
847
896
|
h('div', {
|
|
848
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(() => {
|