@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.
Files changed (58) hide show
  1. package/dist/components/Types.d.ts +5 -5
  2. package/dist/components/date-picker/CDatePicker.d.ts +2 -1
  3. package/dist/components/date-range-picker/CDateRangePicker.d.ts +31 -1
  4. package/dist/components/form/CFormInput.d.ts +166 -1
  5. package/dist/components/form/CFormSelect.d.ts +1 -1
  6. package/dist/components/grid/CCol.d.ts +3 -3
  7. package/dist/components/grid/CRow.d.ts +1 -1
  8. package/dist/components/index.d.ts +1 -0
  9. package/dist/components/multi-select/CMultiSelect.d.ts +12 -4
  10. package/dist/components/multi-select/CMultiSelectOptions.d.ts +11 -0
  11. package/dist/components/multi-select/CMultiSelectSelection.d.ts +3 -3
  12. package/dist/components/pagination/index.d.ts +1 -2
  13. package/dist/components/picker/CPicker.d.ts +1 -1
  14. package/dist/components/popover/CPopover.d.ts +1 -1
  15. package/dist/components/smart-pagination/CSmartPagination.d.ts +257 -0
  16. package/dist/components/smart-pagination/index.d.ts +6 -0
  17. package/dist/components/smart-table/CSmartTable.d.ts +6 -4
  18. package/dist/components/smart-table/CSmartTableFilter.d.ts +2 -2
  19. package/dist/components/smart-table/CSmartTableHead.d.ts +2 -2
  20. package/dist/components/smart-table/CSmartTableInterface.d.ts +4 -1
  21. package/dist/components/table/CTable.d.ts +1 -1
  22. package/dist/components/table/CTableCaption.d.ts +2 -8
  23. package/dist/components/time-picker/CTimePicker.d.ts +2 -1
  24. package/dist/components/tooltip/CTooltip.d.ts +1 -1
  25. package/dist/components/widgets/CWidgetStatsD.d.ts +1 -1
  26. package/dist/index.es.js +877 -682
  27. package/dist/index.es.js.map +1 -1
  28. package/dist/index.js +876 -680
  29. package/dist/index.js.map +1 -1
  30. package/dist/utils/getNextSibling.d.ts +2 -0
  31. package/dist/utils/getPreviousSibling.d.ts +2 -0
  32. package/dist/utils/index.d.ts +4 -0
  33. package/dist/utils/isVisible.d.ts +2 -0
  34. package/dist/utils/time.d.ts +2 -2
  35. package/package.json +1 -1
  36. package/src/components/carousel/CCarousel.ts +1 -9
  37. package/src/components/date-picker/CDatePicker.ts +11 -2
  38. package/src/components/date-range-picker/CDateRangePicker.ts +54 -0
  39. package/src/components/form/CFormInput.ts +2 -0
  40. package/src/components/index.ts +1 -0
  41. package/src/components/loading-button/CLoadingButton.ts +1 -2
  42. package/src/components/multi-select/CMultiSelect.ts +125 -103
  43. package/src/components/multi-select/CMultiSelectOptions.ts +48 -10
  44. package/src/components/multi-select/CMultiSelectSelection.ts +1 -1
  45. package/src/components/pagination/index.ts +1 -3
  46. package/src/components/sidebar/CSidebar.ts +2 -10
  47. package/src/components/{pagination → smart-pagination}/CSmartPagination.ts +1 -2
  48. package/src/components/smart-pagination/index.ts +10 -0
  49. package/src/components/smart-table/CSmartTable.ts +10 -5
  50. package/src/components/smart-table/CSmartTableInterface.ts +4 -0
  51. package/src/components/table/CTableCaption.ts +0 -1
  52. package/src/components/time-picker/CTimePicker.ts +73 -20
  53. package/src/components/time-picker/CTimePickerRollCol.ts +9 -0
  54. package/src/utils/getNextSibling.ts +18 -0
  55. package/src/utils/getPreviousSibling.ts +18 -0
  56. package/src/utils/index.ts +5 -0
  57. package/src/utils/isVisible.ts +11 -0
  58. package/src/utils/time.ts +14 -6
@@ -0,0 +1,2 @@
1
+ declare const getNextSibling: (elem: HTMLElement, selector?: string) => Element | null | undefined;
2
+ export default getNextSibling;
@@ -0,0 +1,2 @@
1
+ declare const getPreviousSibling: (elem: HTMLElement, selector?: string) => Element | null | undefined;
2
+ export default getPreviousSibling;
@@ -0,0 +1,4 @@
1
+ import getNextSibling from './getNextSibling';
2
+ import getPreviousSibling from './getPreviousSibling';
3
+ import isVisible from './isVisible';
4
+ export { getNextSibling, getPreviousSibling, isVisible };
@@ -0,0 +1,2 @@
1
+ declare const isVisible: (element: HTMLElement) => boolean;
2
+ export default isVisible;
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coreui/vue-pro",
3
- "version": "4.6.0",
3
+ "version": "4.7.0-alpha.0",
4
4
  "description": "UI Components Library for Vue.js",
5
5
  "keywords": [
6
6
  "vue",
@@ -11,15 +11,7 @@ import {
11
11
  watch,
12
12
  } from 'vue'
13
13
 
14
- const isVisible = (element: HTMLDivElement) => {
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: {
@@ -35,6 +35,7 @@ export * from './placeholder'
35
35
  export * from './progress'
36
36
  export * from './popover'
37
37
  export * from './sidebar'
38
+ export * from './smart-pagination'
38
39
  export * from './smart-table'
39
40
  export * from './spinner'
40
41
  export * from './table'
@@ -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 flattenArray = (options: Option[]): Option[] => {
247
- return options.reduce((acc: Option[], val: Option) => {
248
- return acc.concat(Array.isArray(val.options) ? flattenArray(val.options) : val)
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
- const getSelectedOptions = (options: Option[]) => {
253
- return flattenArray(options).filter((option: Option) => {
254
- if (option.selected) {
255
- return option
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
- const updateOptions = (
262
- value: number | string,
263
- _options: Option[] = options.value,
264
- ): Option[] => {
265
- return props.multiple && _options
266
- ? _options &&
267
- _options.map((option: Option) => {
268
- count.value = count.value++
269
- return option.options
270
- ? { ...option, options: updateOptions(value, option.options) }
271
- : option.value == value // TODO: find solution
272
- ? { ...option, selected: !option.selected, order: count.value }
273
- : { ...option }
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
- : _options &&
276
- _options.map((option: Option) => {
277
- return option.options
278
- ? { ...option, options: updateOptions(value, option.options) }
279
- : option.value == value // TODO: find solution
280
- ? { ...option, selected: true }
281
- : { ...option, selected: false }
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
- const toggleAllOptions = (
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
- return option.disabled
300
- ? { ...option }
301
- : selected && !option.selected
302
- ? { ...option, selected: selected, order: counter }
303
- : { ...option, selected: selected }
304
- })
305
- }
333
+ },
334
+ )
306
335
 
307
- const filterOptionsList = (search: string, _options = vOptions.value) => {
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
- const nativeSelectRef = ref<HTMLSelectElement>()
331
- provide('nativeSelectRef', nativeSelectRef)
332
- const searchRef = ref<HTMLInputElement>()
333
-
334
- const options = ref<Option[]>(props.options)
335
- const vOptions = ref<Option[]>(props.options)
336
- const search = ref('')
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) return
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 = toggleAllOptions(options.value, true)
417
+ selectOptions(flattenArray(options.value).filter((option: Option) => !option.disabled))
404
418
  }
405
419
 
406
420
  const handleDeselectAll = () => {
407
- options.value = toggleAllOptions(options.value, false)
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
- { class: 'form-multi-select-all', onClick: () => handleSelectAll() },
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: vOptions.value,
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
- const createOptions = (options: Option[]): VNode | VNode[] => {
54
- return options.length > 0
55
- ? options.map((option: Option) => {
56
- return option.options
57
- ? h('div', { class: 'form-multi-select-options' }, [
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': option.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',
@@ -18,7 +18,7 @@ const CMultiSelectSelection = defineComponent({
18
18
  * Enables search input element.
19
19
  */
20
20
  search: {
21
- type: Boolean,
21
+ type: [Boolean, String],
22
22
  required: false,
23
23
  default: false,
24
24
  },
@@ -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, CSmartPagination }
12
+ export { CPaginationPlugin, CPagination, CPaginationItem }