@coreui/vue-pro 4.6.0 → 4.7.0-alpha.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/Types.d.ts +5 -5
- package/dist/components/date-picker/CDatePicker.d.ts +2 -1
- package/dist/components/date-range-picker/CDateRangePicker.d.ts +31 -1
- package/dist/components/form/CFormInput.d.ts +166 -1
- package/dist/components/form/CFormSelect.d.ts +1 -1
- package/dist/components/grid/CCol.d.ts +3 -3
- package/dist/components/grid/CRow.d.ts +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/multi-select/CMultiSelect.d.ts +12 -4
- package/dist/components/multi-select/CMultiSelectOptions.d.ts +11 -0
- package/dist/components/multi-select/CMultiSelectSelection.d.ts +3 -3
- package/dist/components/pagination/index.d.ts +1 -2
- package/dist/components/picker/CPicker.d.ts +1 -1
- package/dist/components/popover/CPopover.d.ts +1 -1
- package/dist/components/smart-pagination/CSmartPagination.d.ts +257 -0
- package/dist/components/smart-pagination/index.d.ts +6 -0
- package/dist/components/smart-table/CSmartTable.d.ts +6 -4
- package/dist/components/smart-table/CSmartTableFilter.d.ts +2 -2
- package/dist/components/smart-table/CSmartTableHead.d.ts +2 -2
- package/dist/components/smart-table/CSmartTableInterface.d.ts +4 -1
- package/dist/components/table/CTable.d.ts +1 -1
- package/dist/components/table/CTableCaption.d.ts +2 -8
- package/dist/components/time-picker/CTimePicker.d.ts +2 -1
- package/dist/components/tooltip/CTooltip.d.ts +1 -1
- package/dist/components/widgets/CWidgetStatsD.d.ts +1 -1
- package/dist/index.es.js +877 -682
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +876 -680
- package/dist/index.js.map +1 -1
- package/dist/utils/getNextSibling.d.ts +2 -0
- package/dist/utils/getPreviousSibling.d.ts +2 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/isVisible.d.ts +2 -0
- package/dist/utils/time.d.ts +2 -2
- package/package.json +1 -1
- package/src/components/carousel/CCarousel.ts +1 -9
- package/src/components/date-picker/CDatePicker.ts +11 -2
- package/src/components/date-range-picker/CDateRangePicker.ts +54 -0
- package/src/components/form/CFormInput.ts +2 -0
- package/src/components/index.ts +1 -0
- package/src/components/loading-button/CLoadingButton.ts +1 -2
- package/src/components/multi-select/CMultiSelect.ts +125 -103
- package/src/components/multi-select/CMultiSelectOptions.ts +48 -10
- package/src/components/multi-select/CMultiSelectSelection.ts +1 -1
- package/src/components/pagination/index.ts +1 -3
- package/src/components/sidebar/CSidebar.ts +2 -10
- package/src/components/{pagination → smart-pagination}/CSmartPagination.ts +1 -2
- package/src/components/smart-pagination/index.ts +10 -0
- package/src/components/smart-table/CSmartTable.ts +10 -5
- package/src/components/smart-table/CSmartTableInterface.ts +4 -0
- package/src/components/table/CTableCaption.ts +0 -1
- package/src/components/time-picker/CTimePicker.ts +73 -20
- package/src/components/time-picker/CTimePickerRollCol.ts +9 -0
- package/src/utils/getNextSibling.ts +18 -0
- package/src/utils/getPreviousSibling.ts +18 -0
- package/src/utils/index.ts +5 -0
- package/src/utils/isVisible.ts +11 -0
- package/src/utils/time.ts +14 -6
package/dist/utils/time.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export declare const convert12hTo24h: (abbr: 'am' | 'pm', hour: number) => numbe
|
|
|
2
2
|
export declare const convert24hTo12h: (hour: number) => number;
|
|
3
3
|
export declare const convertTimeToDate: (time: Date | string | null | undefined) => Date | null;
|
|
4
4
|
export declare const getAmPm: (date: Date, locale: string) => "am" | "pm";
|
|
5
|
-
export declare const getListOfHours: (locale: string) => {
|
|
5
|
+
export declare const getListOfHours: (locale: string, ampm?: 'auto' | boolean) => {
|
|
6
6
|
value: number;
|
|
7
7
|
label: string;
|
|
8
8
|
}[];
|
|
@@ -14,7 +14,7 @@ export declare const getListOfSeconds: (locale: string, valueAsString?: boolean)
|
|
|
14
14
|
value: string | number;
|
|
15
15
|
label: string;
|
|
16
16
|
}[];
|
|
17
|
-
export declare const getSelectedHour: (date: Date | null, locale: string) => number | "";
|
|
17
|
+
export declare const getSelectedHour: (date: Date | null, locale: string, ampm?: 'auto' | boolean) => number | "";
|
|
18
18
|
export declare const getSelectedMinutes: (date: Date | null) => number | "";
|
|
19
19
|
export declare const getSelectedSeconds: (date: Date | null) => number | "";
|
|
20
20
|
export declare const isAmPm: (locale: string) => boolean;
|
package/package.json
CHANGED
|
@@ -11,15 +11,7 @@ import {
|
|
|
11
11
|
watch,
|
|
12
12
|
} from 'vue'
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
const rect = element.getBoundingClientRect()
|
|
16
|
-
return (
|
|
17
|
-
rect.top >= 0 &&
|
|
18
|
-
rect.left >= 0 &&
|
|
19
|
-
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
|
|
20
|
-
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
|
|
21
|
-
)
|
|
22
|
-
}
|
|
14
|
+
import { isVisible } from './../../utils'
|
|
23
15
|
|
|
24
16
|
const CCarousel = defineComponent({
|
|
25
17
|
name: 'CCarousel',
|
|
@@ -265,13 +265,22 @@ const CDatePicker = defineComponent({
|
|
|
265
265
|
* @property {string} formatedDate - formated date
|
|
266
266
|
*/
|
|
267
267
|
'date-change',
|
|
268
|
+
/**
|
|
269
|
+
* Callback fired when the date changed.
|
|
270
|
+
*
|
|
271
|
+
* @property {Date | null} date - date object
|
|
272
|
+
* @since 4.7.0
|
|
273
|
+
*/
|
|
274
|
+
'update:date',
|
|
268
275
|
],
|
|
269
276
|
setup(props, { emit }) {
|
|
270
277
|
return () =>
|
|
271
278
|
h(CDateRangePicker, {
|
|
272
279
|
calendars: 1,
|
|
273
|
-
onStartDateChange: (date: Date, formatedDate: String) =>
|
|
274
|
-
emit('date-change', date, formatedDate)
|
|
280
|
+
onStartDateChange: (date: Date, formatedDate: String) => {
|
|
281
|
+
emit('date-change', date, formatedDate)
|
|
282
|
+
emit('update:date', date)
|
|
283
|
+
},
|
|
275
284
|
range: false,
|
|
276
285
|
startDate: props.date,
|
|
277
286
|
...props,
|
|
@@ -76,6 +76,15 @@ const CDateRangePicker = defineComponent({
|
|
|
76
76
|
type: Boolean,
|
|
77
77
|
default: true,
|
|
78
78
|
},
|
|
79
|
+
/**
|
|
80
|
+
* If true the dropdown will be immediately closed after submitting the full date.
|
|
81
|
+
*
|
|
82
|
+
* @since 4.7.0
|
|
83
|
+
*/
|
|
84
|
+
closeOnSelect: {
|
|
85
|
+
type: Boolean,
|
|
86
|
+
default: true,
|
|
87
|
+
},
|
|
79
88
|
/**
|
|
80
89
|
* Toggle visibility or set the content of confirm button.
|
|
81
90
|
*/
|
|
@@ -377,6 +386,10 @@ const CDateRangePicker = defineComponent({
|
|
|
377
386
|
* @since 4.6.0
|
|
378
387
|
*/
|
|
379
388
|
valid: Boolean,
|
|
389
|
+
/**
|
|
390
|
+
* Toggle the visibility of the component.
|
|
391
|
+
*/
|
|
392
|
+
visible: Boolean,
|
|
380
393
|
/**
|
|
381
394
|
* Set length or format of day name.
|
|
382
395
|
*
|
|
@@ -422,8 +435,23 @@ const CDateRangePicker = defineComponent({
|
|
|
422
435
|
* @property {string} formatedDate - formated date
|
|
423
436
|
*/
|
|
424
437
|
'start-date-change',
|
|
438
|
+
/**
|
|
439
|
+
* Callback fired when the start date changed.
|
|
440
|
+
*
|
|
441
|
+
* @property {Date | null} date - date object
|
|
442
|
+
* @since 4.7.0
|
|
443
|
+
*/
|
|
444
|
+
'update:start-date',
|
|
445
|
+
/**
|
|
446
|
+
* Callback fired when the end date changed.
|
|
447
|
+
*
|
|
448
|
+
* @property {Date | null} date - date object
|
|
449
|
+
* @since 4.7.0
|
|
450
|
+
*/
|
|
451
|
+
'update:end-date',
|
|
425
452
|
],
|
|
426
453
|
setup(props, { slots, attrs, emit }) {
|
|
454
|
+
const visible = ref(props.visible)
|
|
427
455
|
const calendarDate = ref<Date>(
|
|
428
456
|
props.calendarDate
|
|
429
457
|
? new Date(props.calendarDate)
|
|
@@ -526,6 +554,15 @@ const CDateRangePicker = defineComponent({
|
|
|
526
554
|
}
|
|
527
555
|
|
|
528
556
|
emit('start-date-change', date, date ? formatDate(date) : undefined)
|
|
557
|
+
emit('update:start-date', date)
|
|
558
|
+
|
|
559
|
+
if (props.timepicker || props.footer) {
|
|
560
|
+
return
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
if (props.closeOnSelect && !props.range) {
|
|
564
|
+
visible.value = false
|
|
565
|
+
}
|
|
529
566
|
}
|
|
530
567
|
|
|
531
568
|
const handleEndDateChange = (date: Date) => {
|
|
@@ -536,6 +573,15 @@ const CDateRangePicker = defineComponent({
|
|
|
536
573
|
}
|
|
537
574
|
|
|
538
575
|
emit('end-date-change', date, date ? formatDate(date) : undefined)
|
|
576
|
+
emit('update:end-date', date)
|
|
577
|
+
|
|
578
|
+
if (props.timepicker || props.footer) {
|
|
579
|
+
return
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
if (props.closeOnSelect && startDate.value !== null) {
|
|
583
|
+
visible.value = false
|
|
584
|
+
}
|
|
539
585
|
}
|
|
540
586
|
|
|
541
587
|
const handleClear = (event: Event) => {
|
|
@@ -544,6 +590,10 @@ const CDateRangePicker = defineComponent({
|
|
|
544
590
|
endDate.value = null
|
|
545
591
|
inputStartHoverValue.value = null
|
|
546
592
|
inputEndHoverValue.value = null
|
|
593
|
+
emit('start-date-change', null)
|
|
594
|
+
emit('end-date-change', null)
|
|
595
|
+
emit('update:start-date', null)
|
|
596
|
+
emit('update:end-date', null)
|
|
547
597
|
}
|
|
548
598
|
|
|
549
599
|
const InputGroup = () =>
|
|
@@ -681,8 +731,10 @@ const CDateRangePicker = defineComponent({
|
|
|
681
731
|
onCancel: () => {
|
|
682
732
|
startDate.value = initialStartDate.value
|
|
683
733
|
endDate.value = initialEndDate.value
|
|
734
|
+
visible.value = false
|
|
684
735
|
},
|
|
685
736
|
onHide: () => {
|
|
737
|
+
visible.value = false
|
|
686
738
|
emit('hide')
|
|
687
739
|
},
|
|
688
740
|
onShow: () => {
|
|
@@ -694,8 +746,10 @@ const CDateRangePicker = defineComponent({
|
|
|
694
746
|
initialEndDate.value = new Date(endDate.value)
|
|
695
747
|
}
|
|
696
748
|
|
|
749
|
+
visible.value = true
|
|
697
750
|
emit('show')
|
|
698
751
|
},
|
|
752
|
+
visible: visible.value,
|
|
699
753
|
},
|
|
700
754
|
{
|
|
701
755
|
...(slots.cancelButton && {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { defineComponent, h } from 'vue'
|
|
2
2
|
import { CFormControlWrapper } from './CFormControlWrapper'
|
|
3
3
|
|
|
4
|
+
export const File = typeof window !== 'undefined' ? window.File : class File extends Object {}
|
|
5
|
+
|
|
4
6
|
const CFormInput = defineComponent({
|
|
5
7
|
name: 'CFormInput',
|
|
6
8
|
props: {
|
package/src/components/index.ts
CHANGED
|
@@ -71,11 +71,10 @@ const CLoadingButton = defineComponent({
|
|
|
71
71
|
h(
|
|
72
72
|
CButton,
|
|
73
73
|
{
|
|
74
|
+
...props,
|
|
74
75
|
class: ['btn-loading', { ['is-loading']: loading.value }],
|
|
75
76
|
...(props.disabledOnLoading && loading.value && { disabled: true }),
|
|
76
77
|
onClick: () => handleOnClick(),
|
|
77
|
-
// TODO: remove non button props
|
|
78
|
-
...props,
|
|
79
78
|
},
|
|
80
79
|
{
|
|
81
80
|
default: () => [
|
|
@@ -16,6 +16,18 @@ export interface Option {
|
|
|
16
16
|
value: number | string
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
export interface SelectedOption {
|
|
20
|
+
disabled?: boolean
|
|
21
|
+
text: string
|
|
22
|
+
value: number | string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const flattenArray = (options: Option[]): Option[] => {
|
|
26
|
+
return options.reduce((acc: Option[], val: Option) => {
|
|
27
|
+
return acc.concat(Array.isArray(val.options) ? flattenArray(val.options) : val)
|
|
28
|
+
}, [])
|
|
29
|
+
}
|
|
30
|
+
|
|
19
31
|
const CMultiSelect = defineComponent({
|
|
20
32
|
name: 'CMultiSelect',
|
|
21
33
|
props: {
|
|
@@ -137,9 +149,18 @@ const CMultiSelect = defineComponent({
|
|
|
137
149
|
* Enables search input element.
|
|
138
150
|
*/
|
|
139
151
|
search: {
|
|
140
|
-
type: Boolean,
|
|
152
|
+
type: [Boolean, String],
|
|
141
153
|
default: true,
|
|
142
154
|
required: false,
|
|
155
|
+
validator: (value: boolean | string) => {
|
|
156
|
+
if (typeof value == 'string') {
|
|
157
|
+
return ['external'].includes(value)
|
|
158
|
+
}
|
|
159
|
+
if (typeof value == 'boolean') {
|
|
160
|
+
return true
|
|
161
|
+
}
|
|
162
|
+
return false
|
|
163
|
+
},
|
|
143
164
|
},
|
|
144
165
|
/**
|
|
145
166
|
* Sets the label for no results when filtering.
|
|
@@ -241,70 +262,83 @@ const CMultiSelect = defineComponent({
|
|
|
241
262
|
* Execute a function when a user changes the selected option. [docs]
|
|
242
263
|
*/
|
|
243
264
|
'change',
|
|
265
|
+
/**
|
|
266
|
+
* Execute a function when the filter value changed.
|
|
267
|
+
*
|
|
268
|
+
* @since 4.7.0
|
|
269
|
+
*/
|
|
270
|
+
'filterChange',
|
|
244
271
|
],
|
|
245
272
|
setup(props, { attrs, emit }) {
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
273
|
+
const nativeSelectRef = ref<HTMLSelectElement>()
|
|
274
|
+
provide('nativeSelectRef', nativeSelectRef)
|
|
275
|
+
const searchRef = ref<HTMLInputElement>()
|
|
276
|
+
|
|
277
|
+
const options = ref<Option[]>(props.options)
|
|
278
|
+
const search = ref('')
|
|
279
|
+
const selected = ref<SelectedOption[]>([])
|
|
280
|
+
const visible = ref<Boolean>(props.visible)
|
|
281
|
+
|
|
282
|
+
const selectOptions = (options: Option[], deselected?: Option[]) => {
|
|
283
|
+
let _selected = [...selected.value, ...options]
|
|
284
|
+
|
|
285
|
+
if (deselected) {
|
|
286
|
+
_selected = _selected.filter(
|
|
287
|
+
(selectedOption) =>
|
|
288
|
+
!deselected.some((deselectedOption) => deselectedOption.value === selectedOption.value),
|
|
289
|
+
)
|
|
290
|
+
}
|
|
251
291
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
292
|
+
const deduplicated = _selected.reduce((unique: Option[], option) => {
|
|
293
|
+
if (!unique.some((obj) => obj.value === option.value)) {
|
|
294
|
+
unique.push({
|
|
295
|
+
value: option.value,
|
|
296
|
+
text: option.text,
|
|
297
|
+
...(option.disabled && { disabled: option.disabled }),
|
|
298
|
+
})
|
|
256
299
|
}
|
|
257
|
-
return
|
|
258
|
-
})
|
|
300
|
+
return unique
|
|
301
|
+
}, []) as SelectedOption[]
|
|
302
|
+
|
|
303
|
+
selected.value = deduplicated
|
|
259
304
|
}
|
|
260
305
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
306
|
+
watch(
|
|
307
|
+
() => props.options,
|
|
308
|
+
(newValue, oldValue) => {
|
|
309
|
+
if (JSON.stringify(newValue) !== JSON.stringify(oldValue)) {
|
|
310
|
+
options.value = newValue
|
|
311
|
+
const _selected =
|
|
312
|
+
newValue &&
|
|
313
|
+
flattenArray(newValue).filter((option: Option) => {
|
|
314
|
+
if (option.selected) {
|
|
315
|
+
return option
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return
|
|
274
319
|
})
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
320
|
+
|
|
321
|
+
const deselected =
|
|
322
|
+
newValue &&
|
|
323
|
+
flattenArray(newValue).filter((option: Option) => {
|
|
324
|
+
if (option.selected === false) {
|
|
325
|
+
return option
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
return
|
|
282
329
|
})
|
|
283
|
-
}
|
|
284
330
|
|
|
285
|
-
|
|
286
|
-
options: Option[],
|
|
287
|
-
selected: boolean,
|
|
288
|
-
counter: number = count.value,
|
|
289
|
-
): Option[] => {
|
|
290
|
-
return options.map((option: Option) => {
|
|
291
|
-
!option.selected && counter++
|
|
292
|
-
count.value = counter
|
|
293
|
-
if (option.options) {
|
|
294
|
-
return {
|
|
295
|
-
...option,
|
|
296
|
-
options: toggleAllOptions(option.options, selected, counter),
|
|
297
|
-
}
|
|
331
|
+
_selected && selectOptions(_selected, deselected)
|
|
298
332
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
: selected && !option.selected
|
|
302
|
-
? { ...option, selected: selected, order: counter }
|
|
303
|
-
: { ...option, selected: selected }
|
|
304
|
-
})
|
|
305
|
-
}
|
|
333
|
+
},
|
|
334
|
+
)
|
|
306
335
|
|
|
307
|
-
|
|
336
|
+
watch(selected, () => {
|
|
337
|
+
nativeSelectRef.value &&
|
|
338
|
+
nativeSelectRef.value.dispatchEvent(new Event('change', { bubbles: true }))
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
const filterOptionsList = (search: string, _options: Option[]) => {
|
|
308
342
|
return search.length
|
|
309
343
|
? _options &&
|
|
310
344
|
_options.reduce((acc: Option[], val: Option) => {
|
|
@@ -327,84 +361,64 @@ const CMultiSelect = defineComponent({
|
|
|
327
361
|
: options.value
|
|
328
362
|
}
|
|
329
363
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
const visible = ref<Boolean>(props.visible)
|
|
338
|
-
|
|
339
|
-
const selected = ref<Option[]>(getSelectedOptions(props.options))
|
|
340
|
-
const count = ref<number>(0)
|
|
341
|
-
|
|
342
|
-
watch(
|
|
343
|
-
() => props.options,
|
|
344
|
-
(newValue, oldValue) => {
|
|
345
|
-
if (JSON.stringify(newValue) !== JSON.stringify(oldValue)) options.value = newValue
|
|
346
|
-
},
|
|
347
|
-
)
|
|
364
|
+
// watch(
|
|
365
|
+
// () => props.options,
|
|
366
|
+
// (newValue, oldValue) => {
|
|
367
|
+
// console.log(props.options)
|
|
368
|
+
// if (JSON.stringify(newValue) !== JSON.stringify(oldValue)) options.value = newValue
|
|
369
|
+
// },
|
|
370
|
+
// )
|
|
348
371
|
|
|
349
|
-
watch(options, () => {
|
|
350
|
-
const _selected = options.value && getSelectedOptions(options.value)
|
|
351
372
|
|
|
352
|
-
_selected.sort((a: Option, b: Option) => {
|
|
353
|
-
if (typeof a.order === 'undefined') {
|
|
354
|
-
return -1
|
|
355
|
-
}
|
|
356
|
-
if (b.order && a.order > b.order) return 1
|
|
357
|
-
if (b.order && a.order < b.order) return -1
|
|
358
|
-
return 0
|
|
359
|
-
})
|
|
360
|
-
|
|
361
|
-
selected.value = _selected
|
|
362
|
-
})
|
|
363
|
-
|
|
364
|
-
watch([options, search], () => {
|
|
365
|
-
vOptions.value = filterOptionsList(search.value, options.value)
|
|
366
|
-
})
|
|
367
|
-
|
|
368
|
-
watch(selected, () => {
|
|
369
|
-
nativeSelectRef.value &&
|
|
370
|
-
nativeSelectRef.value.dispatchEvent(new Event('change', { bubbles: true }))
|
|
371
|
-
})
|
|
372
373
|
|
|
373
374
|
const handleSearchChange = (event: InputEvent) => {
|
|
374
375
|
const target = event.target as HTMLInputElement
|
|
375
376
|
search.value = target.value.toLowerCase()
|
|
377
|
+
|
|
378
|
+
emit('filterChange', target.value)
|
|
376
379
|
}
|
|
377
380
|
|
|
378
381
|
const handleSearchKeyDown = (event: KeyboardEvent) => {
|
|
379
|
-
if (search.value.length)
|
|
382
|
+
if (search.value.length) {
|
|
383
|
+
return
|
|
384
|
+
}
|
|
385
|
+
|
|
380
386
|
if (event.key === 'Backspace' || event.key === 'Delete') {
|
|
381
387
|
const last = selected.value.filter((option: Option) => !option.disabled).pop()
|
|
382
|
-
|
|
383
388
|
if (last) {
|
|
384
389
|
selected.value = selected.value.filter((option: Option) => option.value !== last.value)
|
|
385
|
-
options.value = updateOptions(last.value)
|
|
386
390
|
}
|
|
387
391
|
}
|
|
388
392
|
}
|
|
389
393
|
|
|
390
394
|
const handleOptionClick = (option: Option) => {
|
|
391
|
-
options.value = updateOptions(option.value)
|
|
392
|
-
|
|
393
395
|
if (!props.multiple) {
|
|
396
|
+
selected.value = [{ value: option.value, text: option.text }] as SelectedOption[]
|
|
394
397
|
visible.value = false
|
|
395
398
|
search.value = ''
|
|
396
399
|
if (searchRef.value) {
|
|
397
400
|
searchRef.value.value = ''
|
|
398
401
|
}
|
|
402
|
+
|
|
403
|
+
return
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if (selected.value.some((_option) => _option.value === option.value)) {
|
|
407
|
+
selected.value = selected.value.filter((_option) => _option.value !== option.value)
|
|
408
|
+
} else {
|
|
409
|
+
selected.value = [
|
|
410
|
+
...selected.value,
|
|
411
|
+
{ value: option.value, text: option.text },
|
|
412
|
+
] as SelectedOption[]
|
|
399
413
|
}
|
|
400
414
|
}
|
|
401
415
|
|
|
402
416
|
const handleSelectAll = () => {
|
|
403
|
-
options.value
|
|
417
|
+
selectOptions(flattenArray(options.value).filter((option: Option) => !option.disabled))
|
|
404
418
|
}
|
|
405
419
|
|
|
406
420
|
const handleDeselectAll = () => {
|
|
407
|
-
|
|
421
|
+
selected.value = selected.value.filter((option) => option.disabled)
|
|
408
422
|
}
|
|
409
423
|
|
|
410
424
|
return () => [
|
|
@@ -508,15 +522,23 @@ const CMultiSelect = defineComponent({
|
|
|
508
522
|
props.selectAll &&
|
|
509
523
|
h(
|
|
510
524
|
'button',
|
|
511
|
-
{
|
|
525
|
+
{
|
|
526
|
+
class: 'form-multi-select-all',
|
|
527
|
+
onClick: () => handleSelectAll(),
|
|
528
|
+
type: 'button',
|
|
529
|
+
},
|
|
512
530
|
props.selectAllLabel,
|
|
513
531
|
),
|
|
514
532
|
h(CMultiSelectOptions, {
|
|
515
533
|
onOptionClick: (option: Option) => handleOptionClick(option),
|
|
516
|
-
options:
|
|
534
|
+
options:
|
|
535
|
+
props.search === 'external'
|
|
536
|
+
? options.value
|
|
537
|
+
: filterOptionsList(search.value, options.value),
|
|
517
538
|
optionsMaxHeight: props.optionsMaxHeight,
|
|
518
539
|
optionsStyle: props.optionsStyle,
|
|
519
540
|
searchNoResultsLabel: props.searchNoResultsLabel,
|
|
541
|
+
selected: selected.value
|
|
520
542
|
}),
|
|
521
543
|
]),
|
|
522
544
|
},
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { defineComponent, h, PropType, VNode } from 'vue'
|
|
2
2
|
import { Option } from './CMultiSelect'
|
|
3
3
|
|
|
4
|
+
import { getNextSibling, getPreviousSibling } from './../../utils'
|
|
5
|
+
|
|
4
6
|
const CMultiSelectOptions = defineComponent({
|
|
5
7
|
name: 'CMultiSelectOptions',
|
|
6
8
|
props: {
|
|
@@ -44,20 +46,53 @@ const CMultiSelectOptions = defineComponent({
|
|
|
44
46
|
default: 'no items',
|
|
45
47
|
required: false,
|
|
46
48
|
},
|
|
49
|
+
selected: {
|
|
50
|
+
type: Array as PropType<Option[]>,
|
|
51
|
+
default: () => [],
|
|
52
|
+
required: false,
|
|
53
|
+
},
|
|
47
54
|
},
|
|
48
55
|
emits: ['optionClick'],
|
|
49
56
|
setup(props, { emit }) {
|
|
57
|
+
const handleKeyDown = (event: KeyboardEvent, option: Option) => {
|
|
58
|
+
if (event.code === 'Space' || event.key === 'Enter') {
|
|
59
|
+
event.preventDefault()
|
|
60
|
+
handleOptionClick && handleOptionClick(option)
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (event.key === 'Down' || event.key === 'ArrowDown') {
|
|
65
|
+
event.preventDefault()
|
|
66
|
+
const target = event.target as HTMLElement
|
|
67
|
+
const next = getNextSibling(target, '.form-multi-select-option')
|
|
68
|
+
if (next) {
|
|
69
|
+
;(next as HTMLElement).focus() // eslint-disable-line prettier/prettier
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (event.key === 'Up' || event.key === 'ArrowUp') {
|
|
74
|
+
event.preventDefault()
|
|
75
|
+
const target = event.target as HTMLElement
|
|
76
|
+
const prev = getPreviousSibling(target, '.form-multi-select-option')
|
|
77
|
+
if (prev) {
|
|
78
|
+
;(prev as HTMLElement).focus() // eslint-disable-line prettier/prettier
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
50
83
|
const handleOptionClick = (option: Option) => {
|
|
51
84
|
emit('optionClick', option as Option)
|
|
52
85
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
86
|
+
|
|
87
|
+
// TODO: find solution how to remove any
|
|
88
|
+
const createOptions = (options: Option[]): VNode | VNode[] | any =>
|
|
89
|
+
options.length > 0
|
|
90
|
+
? options.map((option: Option) =>
|
|
91
|
+
option.options
|
|
92
|
+
? [
|
|
58
93
|
h('div', { class: 'form-multi-select-optgroup-label' }, option.label),
|
|
59
94
|
createOptions(option.options),
|
|
60
|
-
]
|
|
95
|
+
]
|
|
61
96
|
: h(
|
|
62
97
|
'div',
|
|
63
98
|
{
|
|
@@ -65,17 +100,20 @@ const CMultiSelectOptions = defineComponent({
|
|
|
65
100
|
'form-multi-select-option',
|
|
66
101
|
{
|
|
67
102
|
'form-multi-select-option-with-checkbox': props.optionsStyle === 'checkbox',
|
|
68
|
-
'form-multi-selected':
|
|
103
|
+
'form-multi-selected': props.selected.some(
|
|
104
|
+
(_option) => _option.value === option.value,
|
|
105
|
+
),
|
|
69
106
|
disabled: option.disabled,
|
|
70
107
|
},
|
|
71
108
|
],
|
|
72
109
|
onClick: () => handleOptionClick(option),
|
|
110
|
+
onKeydown: (event: any) => handleKeyDown(event, option),
|
|
111
|
+
tabindex: 0,
|
|
73
112
|
},
|
|
74
113
|
option.text,
|
|
75
|
-
)
|
|
76
|
-
|
|
114
|
+
),
|
|
115
|
+
)
|
|
77
116
|
: h('div', { class: 'form-multi-select-options-empty' }, props.searchNoResultsLabel)
|
|
78
|
-
}
|
|
79
117
|
return () =>
|
|
80
118
|
h(
|
|
81
119
|
'div',
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { App } from 'vue'
|
|
2
2
|
import { CPagination } from './CPagination'
|
|
3
3
|
import { CPaginationItem } from './CPaginationItem'
|
|
4
|
-
import { CSmartPagination } from './CSmartPagination'
|
|
5
4
|
|
|
6
5
|
const CPaginationPlugin = {
|
|
7
6
|
install: (app: App): void => {
|
|
8
7
|
app.component(CPagination.name, CPagination)
|
|
9
8
|
app.component(CPaginationItem.name, CPaginationItem)
|
|
10
|
-
app.component(CSmartPagination.name, CSmartPagination)
|
|
11
9
|
},
|
|
12
10
|
}
|
|
13
11
|
|
|
14
|
-
export { CPaginationPlugin, CPagination, CPaginationItem
|
|
12
|
+
export { CPaginationPlugin, CPagination, CPaginationItem }
|