@coreui/vue-pro 4.9.0-rc.0 → 5.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coreui/vue-pro",
3
- "version": "4.9.0-rc.0",
3
+ "version": "5.0.0-alpha.0",
4
4
  "description": "UI Components Library for Vue.js",
5
5
  "keywords": [
6
6
  "vue",
@@ -38,24 +38,24 @@
38
38
  },
39
39
  "devDependencies": {
40
40
  "@popperjs/core": "^2.11.8",
41
- "@rollup/plugin-commonjs": "^25.0.1",
41
+ "@rollup/plugin-commonjs": "^25.0.2",
42
42
  "@rollup/plugin-node-resolve": "^15.1.0",
43
- "@rollup/plugin-typescript": "^11.1.1",
43
+ "@rollup/plugin-typescript": "^11.1.2",
44
44
  "@types/jest": "^29.5.2",
45
- "@vue/test-utils": "^2.3.2",
45
+ "@vue/test-utils": "^2.4.0",
46
46
  "@vue/vue3-jest": "29.2.4",
47
47
  "date-fns": "^2.29.3",
48
- "jest": "^29.5.0",
49
- "jest-environment-jsdom": "^29.5.0",
50
- "rollup": "^3.25.0",
48
+ "jest": "^29.6.0",
49
+ "jest-environment-jsdom": "^29.6.0",
50
+ "rollup": "^3.26.2",
51
51
  "rollup-plugin-vue": "^6.0.0",
52
- "ts-jest": "^29.1.0",
53
- "typescript": "^4.9.5",
52
+ "ts-jest": "^29.1.1",
53
+ "typescript": "^5.1.6",
54
54
  "vue": "^3.3.4",
55
- "vue-types": "^5.0.3"
55
+ "vue-types": "^5.1.0"
56
56
  },
57
57
  "peerDependencies": {
58
- "@coreui/coreui-pro": "^4.5.0",
58
+ "@coreui/coreui-pro": "^5.0.0-alpha.0",
59
59
  "vue": "^3.2.21"
60
60
  },
61
61
  "standard": {
@@ -4,7 +4,6 @@ import { format as dateFormat } from 'date-fns'
4
4
 
5
5
  import { CButton } from '../button'
6
6
  import { CCalendar } from '../calendar'
7
- import { CInputGroup } from '../form'
8
7
  import { CFormControlWrapper } from './../form/CFormControlWrapper'
9
8
  import { CPicker } from '../picker'
10
9
  import { CTimePicker } from '../time-picker'
@@ -645,61 +644,24 @@ const CDateRangePicker = defineComponent({
645
644
  }
646
645
 
647
646
  const InputGroup = () =>
648
- h(CInputGroup, { class: 'picker-input-group', size: props.size }, () => [
649
- h('input', {
650
- autocomplete: 'off',
651
- class: [
652
- 'form-control date-picker-input',
653
- {
654
- hover: inputStartHoverValue.value,
655
- },
656
- ],
657
- disabled: props.disabled,
658
- ...(props.id && { name: props.range ? `${props.id}-start-date` : `${props.id}-date` }),
659
- onClick: () => {
660
- selectEndDate.value = false
661
- },
662
- onInput: (event: Event) => {
663
- const date = getLocalDateFromString(
664
- (event.target as HTMLInputElement).value,
665
- props.locale,
666
- props.timepicker,
667
- )
668
- if (date instanceof Date && date.getTime()) {
669
- calendarDate.value = date
670
- startDate.value = date
671
- }
672
- },
673
- placeholder: Array.isArray(props.placeholder) ? props.placeholder[0] : props.placeholder,
674
- readonly: props.inputReadOnly || typeof props.format === 'string',
675
- required: props.required,
676
- ref: inputStartRef,
677
- value: inputStartHoverValue.value
678
- ? setInputValue(inputStartHoverValue.value)
679
- : setInputValue(startDate.value),
680
- }),
681
- props.range &&
682
- props.separator !== false &&
683
- h(
684
- 'span',
685
- { class: 'input-group-text' },
686
- slots.separator
687
- ? slots.separator()
688
- : h('span', { class: 'picker-input-group-icon date-picker-arrow-icon' }),
689
- ),
690
- props.range &&
647
+ h(
648
+ 'div',
649
+ {
650
+ class: 'date-picker-input-group',
651
+ },
652
+ [
691
653
  h('input', {
692
654
  autocomplete: 'off',
693
655
  class: [
694
- 'form-control date-picker-input',
656
+ 'date-picker-input',
695
657
  {
696
- hover: inputEndHoverValue.value,
658
+ hover: inputStartHoverValue.value,
697
659
  },
698
660
  ],
699
661
  disabled: props.disabled,
700
- ...(props.id && { name: `${props.id}-end-date` }),
662
+ ...(props.id && { name: props.range ? `${props.id}-start-date` : `${props.id}-date` }),
701
663
  onClick: () => {
702
- selectEndDate.value = true
664
+ selectEndDate.value = false
703
665
  },
704
666
  onInput: (event: Event) => {
705
667
  const date = getLocalDateFromString(
@@ -709,43 +671,62 @@ const CDateRangePicker = defineComponent({
709
671
  )
710
672
  if (date instanceof Date && date.getTime()) {
711
673
  calendarDate.value = date
712
- endDate.value = date
674
+ startDate.value = date
713
675
  }
714
676
  },
715
- placeholder: props.placeholder[1],
677
+ placeholder: Array.isArray(props.placeholder)
678
+ ? props.placeholder[0]
679
+ : props.placeholder,
716
680
  readonly: props.inputReadOnly || typeof props.format === 'string',
717
681
  required: props.required,
718
- ref: inputEndRef,
719
- value: inputEndHoverValue.value
720
- ? setInputValue(inputEndHoverValue.value)
721
- : setInputValue(endDate.value),
682
+ ref: inputStartRef,
683
+ value: inputStartHoverValue.value
684
+ ? setInputValue(inputStartHoverValue.value)
685
+ : setInputValue(startDate.value),
722
686
  }),
723
- (props.indicator || props.cleaner) &&
724
- h('span', { class: 'input-group-text' }, [
725
- props.indicator &&
726
- h(
727
- 'span',
687
+ props.range && props.separator !== false && h('div', { class: 'date-picker-separator' }),
688
+ props.range &&
689
+ h('input', {
690
+ autocomplete: 'off',
691
+ class: [
692
+ 'date-picker-input',
728
693
  {
729
- class: 'picker-input-group-indicator',
694
+ hover: inputEndHoverValue.value,
730
695
  },
731
- slots.indicator
732
- ? slots.indicator()
733
- : h('span', { class: 'picker-input-group-icon date-picker-input-icon' }),
734
- ),
735
- props.cleaner &&
736
- h(
737
- 'span',
738
- {
739
- class: 'picker-input-group-cleaner',
740
- onClick: (event: Event) => handleClear(event),
741
- role: 'button',
742
- },
743
- slots.cleaner
744
- ? slots.cleaner()
745
- : h('span', { class: 'picker-input-group-icon date-picker-cleaner-icon' }),
746
- ),
747
- ]),
748
- ])
696
+ ],
697
+ disabled: props.disabled,
698
+ ...(props.id && { name: `${props.id}-end-date` }),
699
+ onClick: () => {
700
+ selectEndDate.value = true
701
+ },
702
+ onInput: (event: Event) => {
703
+ const date = getLocalDateFromString(
704
+ (event.target as HTMLInputElement).value,
705
+ props.locale,
706
+ props.timepicker,
707
+ )
708
+ if (date instanceof Date && date.getTime()) {
709
+ calendarDate.value = date
710
+ endDate.value = date
711
+ }
712
+ },
713
+ placeholder: props.placeholder[1],
714
+ readonly: props.inputReadOnly || typeof props.format === 'string',
715
+ required: props.required,
716
+ ref: inputEndRef,
717
+ value: inputEndHoverValue.value
718
+ ? setInputValue(inputEndHoverValue.value)
719
+ : setInputValue(endDate.value),
720
+ }),
721
+ props.indicator && h('div', { class: 'date-picker-indicator' }),
722
+ props.cleaner &&
723
+ (startDate.value || endDate.value) &&
724
+ h('div', {
725
+ class: 'date-picker-cleaner',
726
+ onClick: (event: Event) => handleClear(event),
727
+ }),
728
+ ],
729
+ )
749
730
 
750
731
  return () =>
751
732
  h(
@@ -770,6 +751,7 @@ const CDateRangePicker = defineComponent({
770
751
  class: [
771
752
  'date-picker',
772
753
  {
754
+ [`date-picker-${props.size}`]: props.size,
773
755
  disabled: props.disabled,
774
756
  'is-invalid': isValid.value === false ? true : false,
775
757
  'is-valid': isValid.value,
@@ -800,7 +782,7 @@ const CDateRangePicker = defineComponent({
800
782
  {
801
783
  toggler: () => InputGroup(),
802
784
  footer: () =>
803
- h('div', { class: 'picker-footer' }, [
785
+ h('div', { class: 'date-picker-footer' }, [
804
786
  props.todayButton &&
805
787
  h(
806
788
  CButton,
@@ -121,7 +121,7 @@ const CDropdown = defineComponent({
121
121
  /**
122
122
  * Offset of the dropdown menu relative to its target.
123
123
  *
124
- * @since 4.9.0-rc.0
124
+ * @since 4.9.0
125
125
  */
126
126
  offset: {
127
127
  type: Array,
@@ -14,6 +14,12 @@ const CFormCheck = defineComponent({
14
14
  * @see http://coreui.io/vue/docs/components/button.html
15
15
  */
16
16
  button: Object,
17
+ /**
18
+ * Use in conjunction with the v-model directive to specify the value that should be assigned to the bound variable when the checkbox is in the `false` state.
19
+ *
20
+ * @since 4.9.0
21
+ */
22
+ falseValue: String,
17
23
  /**
18
24
  * Provide valuable, actionable feedback.
19
25
  *
@@ -66,7 +72,7 @@ const CFormCheck = defineComponent({
66
72
  * The default name for a value passed using v-model.
67
73
  */
68
74
  modelValue: {
69
- type: [Boolean, String],
75
+ type: [Array, Boolean, String],
70
76
  value: undefined,
71
77
  },
72
78
  /**
@@ -81,6 +87,12 @@ const CFormCheck = defineComponent({
81
87
  * @since 4.3.0
82
88
  */
83
89
  tooltipFeedback: Boolean,
90
+ /**
91
+ * Use in conjunction with the v-model directive to specify the value that should be assigned to the bound variable when the checkbox is in the `true` state.
92
+ *
93
+ * @since 4.9.0
94
+ */
95
+ trueValue: String,
84
96
  /**
85
97
  * Specifies the type of component.
86
98
  *
@@ -111,8 +123,35 @@ const CFormCheck = defineComponent({
111
123
  ],
112
124
  setup(props, { attrs, emit, slots }) {
113
125
  const handleChange = (event: InputEvent) => {
126
+ const target = event.target as HTMLInputElement
114
127
  emit('change', event)
115
- emit('update:modelValue', (event.target as HTMLInputElement).value)
128
+
129
+ if (props.falseValue && props.trueValue) {
130
+ emit('update:modelValue', target.checked ? props.trueValue : props.falseValue)
131
+ return
132
+ }
133
+
134
+ if (props.value && Array.isArray(props.modelValue)) {
135
+ if (props.modelValue.includes(props.value)) {
136
+ emit(
137
+ 'update:modelValue',
138
+ props.modelValue.filter((value) => value !== props.value),
139
+ )
140
+ } else {
141
+ emit('update:modelValue', [...props.modelValue, props.value])
142
+ }
143
+
144
+ return
145
+ }
146
+
147
+ if (props.value === undefined) {
148
+ emit('update:modelValue', target.checked)
149
+ return
150
+ }
151
+
152
+ if (props.value && (props.modelValue === undefined || typeof props.modelValue === 'string')) {
153
+ emit('update:modelValue', target.checked ? props.value : undefined)
154
+ }
116
155
  }
117
156
 
118
157
  const className = [
@@ -135,12 +174,22 @@ const CFormCheck = defineComponent({
135
174
  },
136
175
  ]
137
176
 
138
- const isChecked = computed(() => props.modelValue == props.value)
177
+ const isChecked = computed(() => {
178
+ if (Array.isArray(props.modelValue)) {
179
+ return props.modelValue.includes(props.value)
180
+ }
181
+
182
+ if (typeof props.modelValue === 'string') {
183
+ return props.modelValue === props.value
184
+ }
185
+
186
+ return props.modelValue
187
+ })
139
188
 
140
189
  const formControl = () => {
141
190
  return h('input', {
142
191
  ...attrs,
143
- ...(props.modelValue && { checked: isChecked.value }),
192
+ ...(props.modelValue && props.value && { checked: isChecked.value }),
144
193
  class: inputClassName,
145
194
  id: props.id,
146
195
  indeterminate: props.indeterminate,
@@ -19,7 +19,7 @@ const CMultiSelect = defineComponent({
19
19
  /**
20
20
  * Allow users to create options if they are not in the list of options.
21
21
  *
22
- * @since 4.9.0-next.0
22
+ * @since 4.9.0
23
23
  */
24
24
  allowCreateOptions: Boolean,
25
25
  /**
@@ -34,7 +34,7 @@ const CMultiSelect = defineComponent({
34
34
  /**
35
35
  * Clear current search on selecting an item.
36
36
  *
37
- * @since 4.9.0-next.0
37
+ * @since 4.9.0
38
38
  */
39
39
  clearSearchOnSelect: Boolean,
40
40
  /**
@@ -78,7 +78,7 @@ const CMultiSelect = defineComponent({
78
78
  /**
79
79
  * When set, the options list will have a loading style: loading spinner and reduced opacity.
80
80
  *
81
- * @since 4.9.0-next.0
81
+ * @since 4.9.0
82
82
  */
83
83
  loading: Boolean,
84
84
  /**
@@ -535,18 +535,13 @@ const CMultiSelect = defineComponent({
535
535
  'div',
536
536
  {
537
537
  class: [
538
- 'dropdown',
539
- 'picker',
540
538
  'form-multi-select',
541
539
  {
542
- 'form-multi-select-with-cleaner': props.cleaner,
543
540
  disabled: props.disabled,
544
541
  [`form-multi-select-${props.size}`]: props.size,
545
- 'form-multi-select-selection-tags':
546
- props.multiple && props.selectionType === 'tags',
547
- show: visible.value,
548
542
  'is-invalid': props.invalid,
549
543
  'is-valid': props.valid,
544
+ show: visible.value,
550
545
  },
551
546
  ],
552
547
  'aria-expanded': visible.value,
@@ -566,64 +561,78 @@ const CMultiSelect = defineComponent({
566
561
  },
567
562
  {
568
563
  default: () => [
569
- h(CMultiSelectSelection, {
570
- multiple: props.multiple,
571
- placeholder: props.placeholder,
572
- onRemove: (option: Option) =>
573
- !props.disabled && handleOptionClick(option),
574
- search: props.search,
575
- selected: selected.value,
576
- selectionType: props.selectionType,
577
- selectionTypeCounterText: props.selectionTypeCounterText,
578
- }),
579
- props.multiple &&
580
- props.cleaner &&
581
- selected.value.length > 0 &&
582
- !props.disabled &&
583
- h('button', {
584
- type: 'button',
585
- class: 'form-multi-select-selection-cleaner',
586
- onClick: () => handleDeselectAll(),
587
- }),
588
- props.search &&
589
- h('input', {
590
- type: 'text',
591
- class: 'form-multi-select-search',
592
- disabled: props.disabled,
593
- autocomplete: 'off',
594
- onInput: (event: InputEvent) => handleSearchChange(event),
595
- onKeydown: (event: KeyboardEvent) => handleSearchKeyDown(event),
596
- ...(selected.value.length === 0 && {
597
- placeholder: props.placeholder,
598
- }),
599
- ...(selected.value.length > 0 &&
600
- props.selectionType === 'counter' && {
601
- placeholder: `${selected.value.length} ${props.selectionTypeCounterText}`,
564
+ h(
565
+ CMultiSelectSelection,
566
+ {
567
+ multiple: props.multiple,
568
+ placeholder: props.placeholder,
569
+ onRemove: (option: Option) =>
570
+ !props.disabled && handleOptionClick(option),
571
+ search: props.search,
572
+ selected: selected.value,
573
+ selectionType: props.selectionType,
574
+ selectionTypeCounterText: props.selectionTypeCounterText,
575
+ },
576
+ {
577
+ default: () =>
578
+ props.search &&
579
+ h('input', {
580
+ type: 'text',
581
+ class: 'form-multi-select-search',
582
+ disabled: props.disabled,
583
+ autocomplete: 'off',
584
+ onInput: (event: InputEvent) => handleSearchChange(event),
585
+ onKeydown: (event: KeyboardEvent) => handleSearchKeyDown(event),
586
+ ...(selected.value.length === 0 && {
587
+ placeholder: props.placeholder,
588
+ }),
589
+ ...(selected.value.length > 0 &&
590
+ props.selectionType === 'counter' && {
591
+ placeholder: `${selected.value.length} ${props.selectionTypeCounterText}`,
592
+ }),
593
+ ...(selected.value.length > 0 &&
594
+ !props.multiple && {
595
+ placeholder: selected.value.map((option) => option.text)[0],
596
+ }),
597
+
598
+ ...(props.multiple &&
599
+ selected.value.length > 0 &&
600
+ props.selectionType !== 'counter' && {
601
+ size: searchValue.value.length + 2,
602
+ }),
603
+ ref: searchRef,
602
604
  }),
603
- ...(selected.value.length > 0 &&
604
- !props.multiple && {
605
- placeholder: selected.value.map((option) => option.text)[0],
605
+ },
606
+ ),
607
+ h(
608
+ 'div',
609
+ { class: 'form-multi-select-buttons' },
610
+ {
611
+ default: () => [
612
+ h('button', {
613
+ class: 'form-multi-select-cleaner',
614
+ onClick: () => handleDeselectAll(),
615
+ type: 'button',
606
616
  }),
607
-
608
- ...(props.multiple &&
609
- selected.value.length > 0 &&
610
- props.selectionType !== 'counter' && {
611
- size: searchValue.value.length + 2,
617
+ h('button', {
618
+ class: 'form-multi-select-indicator',
619
+ onClick: (event: Event) => {
620
+ event.preventDefault()
621
+ event.stopPropagation()
622
+ visible.value = !visible.value
623
+ },
624
+ type: 'button',
612
625
  }),
613
- ref: searchRef,
614
- }),
626
+ ],
627
+ },
628
+ ),
615
629
  ],
616
630
  },
617
631
  ),
618
632
  h(
619
633
  'div',
620
634
  {
621
- class: [
622
- 'dropdown-menu',
623
- {
624
- show: visible.value,
625
- },
626
- ],
635
+ class: 'form-multi-select-dropdown',
627
636
  role: 'menu',
628
637
  ref: dropdownRef,
629
638
  },
@@ -36,7 +36,12 @@ const CMultiSelectSelection = defineComponent({
36
36
  h(
37
37
  'div',
38
38
  {
39
- class: 'form-multi-select-selection',
39
+ class: [
40
+ 'form-multi-select-selection',
41
+ {
42
+ 'form-multi-select-selection-tags': props.multiple && props.selectionType === 'tags',
43
+ },
44
+ ],
40
45
  },
41
46
  [
42
47
  props.multiple &&
@@ -56,15 +61,11 @@ const CMultiSelectSelection = defineComponent({
56
61
  return h('span', { class: 'form-multi-select-tag' }, [
57
62
  option.text,
58
63
  !option.disabled &&
59
- h(
60
- 'button',
61
- {
62
- class: 'form-multi-select-tag-delete close',
63
- ariaLabel: 'Close',
64
- onClick: () => handleRemove(option),
65
- },
66
- h('span', { ariaHidden: 'true' }, 'x'),
67
- ),
64
+ h('button', {
65
+ class: 'form-multi-select-tag-delete',
66
+ ariaLabel: 'Close',
67
+ onClick: () => handleRemove(option),
68
+ }),
68
69
  ])
69
70
  }
70
71
  return
@@ -130,8 +130,6 @@ const CPicker = defineComponent({
130
130
  'div',
131
131
  {
132
132
  class: [
133
- 'dropdown',
134
- 'picker',
135
133
  attrs.class,
136
134
  {
137
135
  show: visible.value,
@@ -156,26 +154,13 @@ const CPicker = defineComponent({
156
154
  },
157
155
  }),
158
156
  ),
159
- h(
160
- 'div',
161
- {
162
- class: [
163
- 'dropdown-menu',
164
- {
165
- show: visible.value,
166
- },
167
- props.dropdownClassNames,
168
- ],
169
- ref: dropdownRef,
170
- },
171
- [
172
- slots.default && slots.default(),
173
- /**
174
- * @slot Location for the footer element.
175
- */
176
- slots.footer && slots.footer(),
177
- ],
178
- ),
157
+ h('div', { class: props.dropdownClassNames, ref: dropdownRef }, [
158
+ slots.default && slots.default(),
159
+ /**
160
+ * @slot Location for the footer element.
161
+ */
162
+ slots.footer && slots.footer(),
163
+ ]),
179
164
  ],
180
165
  )
181
166
  }
@@ -12,7 +12,7 @@ const CPopover = defineComponent({
12
12
  /**
13
13
  * Apply a CSS fade transition to the popover.
14
14
  *
15
- * @since 4.9.0-rc.0
15
+ * @since 4.9.0
16
16
  */
17
17
  animation: {
18
18
  type: Boolean,
@@ -25,7 +25,7 @@ const CPopover = defineComponent({
25
25
  /**
26
26
  * The delay for displaying and hiding the popover (in milliseconds). When a numerical value is provided, the delay applies to both the hide and show actions. The object structure for specifying the delay is as follows: delay: `{ 'show': 500, 'hide': 100 }`.
27
27
  *
28
- * @since 4.9.0-rc.0
28
+ * @since 4.9.0
29
29
  */
30
30
  delay: {
31
31
  type: [Number, Object] as PropType<number | { show: number; hide: number }>,
@@ -34,7 +34,7 @@ const CPopover = defineComponent({
34
34
  /**
35
35
  * Specify the desired order of fallback placements by providing a list of placements as an array. The placements should be prioritized based on preference.
36
36
  *
37
- * @since 4.9.0-rc.0
37
+ * @since 4.9.0
38
38
  */
39
39
  fallbackPlacements: {
40
40
  type: [String, Array] as PropType<Placements | Placements[]>,