@coreui/vue-pro 4.5.0 → 4.6.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.
@@ -1,5 +1,6 @@
1
1
  import { defineComponent, h, PropType, provide, ref, watch } from 'vue'
2
2
 
3
+ import { CFormControlWrapper } from './../form/CFormControlWrapper'
3
4
  import { CPicker } from '../picker'
4
5
 
5
6
  import { CMultiSelectNativeSelect } from './CMultiSelectNativeSelect'
@@ -36,6 +37,50 @@ const CMultiSelect = defineComponent({
36
37
  required: false,
37
38
  default: false,
38
39
  },
40
+ /**
41
+ * Provide valuable, actionable feedback.
42
+ *
43
+ * @since 4.6.0
44
+ */
45
+ feedback: {
46
+ type: String,
47
+ },
48
+ /**
49
+ * Provide valuable, actionable feedback.
50
+ *
51
+ * @since 4.6.0
52
+ */
53
+ feedbackInvalid: {
54
+ type: String,
55
+ },
56
+ /**
57
+ * Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
58
+ *
59
+ * @since 4.6.0
60
+ */
61
+ feedbackValid: {
62
+ type: String,
63
+ },
64
+ /**
65
+ * The id global attribute defines an identifier (ID) that must be unique in the whole document.
66
+ */
67
+ id: {
68
+ type: String,
69
+ },
70
+ /**
71
+ * Set component validation state to invalid.
72
+ *
73
+ * @since 4.6.0
74
+ */
75
+ invalid: Boolean,
76
+ /**
77
+ * Add a caption for a component.
78
+ *
79
+ * @since 4.6.0
80
+ */
81
+ label: {
82
+ type: String,
83
+ },
39
84
  /**
40
85
  * It specifies that multiple options can be selected at once.
41
86
  *
@@ -160,6 +205,26 @@ const CMultiSelect = defineComponent({
160
205
  return ['sm', 'lg'].includes(value)
161
206
  },
162
207
  },
208
+ /**
209
+ * Add helper text to the component.
210
+ *
211
+ * @since 4.6.0
212
+ */
213
+ text: {
214
+ type: String,
215
+ },
216
+ /**
217
+ * Display validation feedback in a styled tooltip.
218
+ *
219
+ * @since 4.6.0
220
+ */
221
+ tooltipFeedback: Boolean,
222
+ /**
223
+ * Set component validation state to valid.
224
+ *
225
+ * @since 4.6.0
226
+ */
227
+ valid: Boolean,
163
228
  /**
164
229
  * Toggle the visibility of multi select dropdown.
165
230
  *
@@ -177,7 +242,7 @@ const CMultiSelect = defineComponent({
177
242
  */
178
243
  'change',
179
244
  ],
180
- setup(props, { emit }) {
245
+ setup(props, { attrs, emit }) {
181
246
  const flattenArray = (options: Option[]): Option[] => {
182
247
  return options.reduce((acc: Option[], val: Option) => {
183
248
  return acc.concat(Array.isArray(val.options) ? flattenArray(val.options) : val)
@@ -324,6 +389,14 @@ const CMultiSelect = defineComponent({
324
389
 
325
390
  const handleOptionClick = (option: Option) => {
326
391
  options.value = updateOptions(option.value)
392
+
393
+ if (!props.multiple) {
394
+ visible.value = false
395
+ search.value = ''
396
+ if (searchRef.value) {
397
+ searchRef.value.value = ''
398
+ }
399
+ }
327
400
  }
328
401
 
329
402
  const handleSelectAll = () => {
@@ -344,83 +417,110 @@ const CMultiSelect = defineComponent({
344
417
  onChange: () => emit('change', selected.value),
345
418
  }),
346
419
  h(
347
- CPicker,
420
+ CFormControlWrapper,
348
421
  {
349
- class: [
350
- 'form-multi-select',
351
- {
352
- 'form-multi-select-with-cleaner': props.cleaner,
353
- disabled: props.disabled,
354
- [`form-multi-select-${props.size}`]: props.size,
355
- 'form-multi-select-selection-tags': props.multiple && props.selectionType === 'tags',
356
- show: visible.value,
357
- },
358
- ],
359
- disabled: props.disabled,
360
- onShow: () => {
361
- props.search && searchRef.value && searchRef.value.focus()
362
- },
422
+ describedby: attrs['aria-describedby'],
423
+ feedback: props.feedback,
424
+ feedbackInvalid: props.feedbackInvalid,
425
+ feedbackValid: props.feedbackValid,
426
+ id: props.id,
427
+ invalid: props.invalid,
428
+ label: props.label,
429
+ text: props.text,
430
+ tooltipFeedback: props.tooltipFeedback,
431
+ valid: props.valid,
363
432
  },
364
433
  {
365
- toggler: () =>
366
- h('div', {}, [
367
- h(CMultiSelectSelection, {
368
- multiple: props.multiple,
369
- onRemove: (option: Option) => !props.disabled && handleOptionClick(option),
370
- search: props.search,
371
- selected: selected.value,
372
- selectionType: props.selectionType,
373
- selectionTypeCounterText: props.selectionTypeCounterText,
374
- }),
375
- props.multiple &&
376
- props.cleaner &&
377
- selected.value.length > 0 &&
378
- !props.disabled &&
379
- h('button', {
380
- type: 'button',
381
- class: 'form-multi-select-selection-cleaner',
382
- onClick: () => handleDeselectAll(),
383
- }),
384
- props.search &&
385
- h('input', {
386
- type: 'text',
387
- class: 'form-multi-select-search',
388
- autocomplete: 'off',
389
- ...(selected.value.length === 0 && { placeholder: props.placeholder }),
390
- ...(selected.value.length &&
391
- props.selectionType === 'counter' && {
392
- placeholder: `${selected.value.length} ${props.selectionTypeCounterText}`,
434
+ default: () =>
435
+ h(
436
+ CPicker,
437
+ {
438
+ class: [
439
+ 'form-multi-select',
440
+ {
441
+ 'form-multi-select-with-cleaner': props.cleaner,
442
+ disabled: props.disabled,
443
+ [`form-multi-select-${props.size}`]: props.size,
444
+ 'form-multi-select-selection-tags':
445
+ props.multiple && props.selectionType === 'tags',
446
+ show: visible.value,
447
+ 'is-invalid': props.invalid,
448
+ 'is-valid': props.valid,
449
+ },
450
+ ],
451
+ disabled: props.disabled,
452
+ id: props.id,
453
+ onHide: () => {
454
+ visible.value = false
455
+ },
456
+ onShow: () => {
457
+ props.search && searchRef.value && searchRef.value.focus()
458
+ visible.value = true
459
+ },
460
+ visible: visible.value,
461
+ },
462
+ {
463
+ toggler: () =>
464
+ h('div', {}, [
465
+ h(CMultiSelectSelection, {
466
+ multiple: props.multiple,
467
+ onRemove: (option: Option) => !props.disabled && handleOptionClick(option),
468
+ search: props.search,
469
+ selected: selected.value,
470
+ selectionType: props.selectionType,
471
+ selectionTypeCounterText: props.selectionTypeCounterText,
393
472
  }),
394
- ...(selected.value.length &&
395
- !props.multiple && {
396
- placeholder: selected.value.map((option) => option.text)[0],
473
+ props.multiple &&
474
+ props.cleaner &&
475
+ selected.value.length > 0 &&
476
+ !props.disabled &&
477
+ h('button', {
478
+ type: 'button',
479
+ class: 'form-multi-select-selection-cleaner',
480
+ onClick: () => handleDeselectAll(),
481
+ }),
482
+ props.search &&
483
+ h('input', {
484
+ type: 'text',
485
+ class: 'form-multi-select-search',
486
+ autocomplete: 'off',
487
+ ...(selected.value.length === 0 && { placeholder: props.placeholder }),
488
+ ...(selected.value.length &&
489
+ props.selectionType === 'counter' && {
490
+ placeholder: `${selected.value.length} ${props.selectionTypeCounterText}`,
491
+ }),
492
+ ...(selected.value.length &&
493
+ !props.multiple && {
494
+ placeholder: selected.value.map((option) => option.text)[0],
495
+ }),
496
+ disabled: props.disabled,
497
+ onInput: (event: InputEvent) => handleSearchChange(event),
498
+ onKeydown: (event: KeyboardEvent) => handleSearchKeyDown(event),
499
+ ...(props.multiple &&
500
+ selected.value.length &&
501
+ props.selectionType !== 'counter' && { size: search.value.length + 2 }),
502
+ ref: searchRef,
503
+ }),
504
+ ]),
505
+ default: () =>
506
+ h('div', {}, [
507
+ props.multiple &&
508
+ props.selectAll &&
509
+ h(
510
+ 'button',
511
+ { class: 'form-multi-select-all', onClick: () => handleSelectAll() },
512
+ props.selectAllLabel,
513
+ ),
514
+ h(CMultiSelectOptions, {
515
+ onOptionClick: (option: Option) => handleOptionClick(option),
516
+ options: vOptions.value,
517
+ optionsMaxHeight: props.optionsMaxHeight,
518
+ optionsStyle: props.optionsStyle,
519
+ searchNoResultsLabel: props.searchNoResultsLabel,
397
520
  }),
398
- disabled: props.disabled,
399
- onInput: (event: InputEvent) => handleSearchChange(event),
400
- onKeydown: (event: KeyboardEvent) => handleSearchKeyDown(event),
401
- ...(props.multiple &&
402
- selected.value.length &&
403
- props.selectionType !== 'counter' && { size: search.value.length + 2 }),
404
- ref: searchRef,
405
- }),
406
- ]),
407
- default: () =>
408
- h('div', {}, [
409
- props.multiple &&
410
- props.selectAll &&
411
- h(
412
- 'button',
413
- { class: 'form-multi-select-all', onClick: () => handleSelectAll() },
414
- props.selectAllLabel,
415
- ),
416
- h(CMultiSelectOptions, {
417
- onOptionClick: (option: Option) => handleOptionClick(option),
418
- options: vOptions.value,
419
- optionsMaxHeight: props.optionsMaxHeight,
420
- optionsStyle: props.optionsStyle,
421
- searchNoResultsLabel: props.searchNoResultsLabel,
422
- }),
423
- ]),
521
+ ]),
522
+ },
523
+ ),
424
524
  },
425
525
  ),
426
526
  ]
@@ -1,6 +1,7 @@
1
1
  import { defineComponent, h, ref, watch } from 'vue'
2
2
 
3
3
  import { CFormInput, CFormSelect, CInputGroup, CInputGroupText } from '../form/'
4
+ import { CFormControlWrapper } from './../form/CFormControlWrapper'
4
5
  import { CPicker } from '../picker'
5
6
  import { CTimePickerRollCol } from './CTimePickerRollCol'
6
7
 
@@ -110,6 +111,34 @@ const CTimePicker = defineComponent({
110
111
  return ['ghost', 'outline'].includes(value)
111
112
  },
112
113
  },
114
+ /**
115
+ * Provide valuable, actionable feedback.
116
+ *
117
+ * @since 4.6.0
118
+ */
119
+ feedback: {
120
+ type: String,
121
+ },
122
+ /**
123
+ * Provide valuable, actionable feedback.
124
+ *
125
+ * @since 4.6.0
126
+ */
127
+ feedbackInvalid: {
128
+ type: String,
129
+ },
130
+ /**
131
+ * Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
132
+ *
133
+ * @since 4.6.0
134
+ */
135
+ feedbackValid: {
136
+ type: String,
137
+ },
138
+ /**
139
+ * The id global attribute defines an identifier (ID) that must be unique in the whole document.
140
+ */
141
+ id: String,
113
142
  /**
114
143
  * Toggle visibility or set the content of the input indicator.
115
144
  */
@@ -121,6 +150,20 @@ const CTimePicker = defineComponent({
121
150
  * Toggle the readonly state for the component.
122
151
  */
123
152
  inputReadOnly: Boolean,
153
+ /**
154
+ * Set component validation state to invalid.
155
+ *
156
+ * @since 4.6.0
157
+ */
158
+ invalid: Boolean,
159
+ /**
160
+ * Add a caption for a component.
161
+ *
162
+ * @since 4.6.0
163
+ */
164
+ label: {
165
+ type: String,
166
+ },
124
167
  /**
125
168
  * Sets the default locale for components. If not set, it is inherited from the navigator.language.
126
169
  */
@@ -147,12 +190,32 @@ const CTimePicker = defineComponent({
147
190
  return ['sm', 'lg'].includes(value)
148
191
  },
149
192
  },
193
+ /**
194
+ * Add helper text to the component.
195
+ *
196
+ * @since 4.6.0
197
+ */
198
+ text: {
199
+ type: String,
200
+ },
150
201
  /**
151
202
  * Initial selected time.
152
203
  */
153
204
  time: {
154
205
  type: [Date, String],
155
206
  },
207
+ /**
208
+ * Display validation feedback in a styled tooltip.
209
+ *
210
+ * @since 4.6.0
211
+ */
212
+ tooltipFeedback: Boolean,
213
+ /**
214
+ * Set component validation state to valid.
215
+ *
216
+ * @since 4.6.0
217
+ */
218
+ valid: Boolean,
156
219
  /**
157
220
  * Set the time picker variant to a roll or select.
158
221
  *
@@ -180,7 +243,7 @@ const CTimePicker = defineComponent({
180
243
  */
181
244
  'show',
182
245
  ],
183
- setup(props, { emit, slots }) {
246
+ setup(props, { emit, attrs, slots }) {
184
247
  const date = ref<Date | null>(convertTimeToDate(props.time))
185
248
  const initialDate = ref<Date | null>(null)
186
249
  const ampm = ref<'am' | 'pm'>(date.value ? getAmPm(new Date(date.value), props.locale) : 'am')
@@ -348,56 +411,74 @@ const CTimePicker = defineComponent({
348
411
 
349
412
  return () =>
350
413
  h(
351
- CPicker,
414
+ CFormControlWrapper,
352
415
  {
353
- cancelButton: props.cancelButton,
354
- cancelButtonColor: props.cancelButtonColor,
355
- cancelButtonSize: props.cancelButtonSize,
356
- cancelButtonVariant: props.cancelButtonVariant,
357
- class: 'time-picker',
358
- confirmButton: props.confirmButton,
359
- confirmButtonColor: props.confirmButtonColor,
360
- confirmButtonSize: props.confirmButtonSize,
361
- confirmButtonVariant: props.confirmButtonVariant,
362
- container: props.container,
363
- disabled: props.disabled,
364
- footer: true,
365
- onCancel: () => {
366
- if (initialDate.value) {
367
- date.value = new Date(initialDate.value)
368
- }
369
- },
370
- onHide: () => {
371
- emit('hide')
372
- },
373
- onShow: () => {
374
- if (date.value) {
375
- initialDate.value = new Date(date.value)
376
- }
377
-
378
- emit('show')
379
- },
416
+ describedby: attrs['aria-describedby'],
417
+ feedback: props.feedback,
418
+ feedbackInvalid: props.feedbackInvalid,
419
+ feedbackValid: props.feedbackValid,
420
+ id: props.id,
421
+ invalid: props.invalid,
422
+ label: props.label,
423
+ text: props.text,
424
+ tooltipFeedback: props.tooltipFeedback,
425
+ valid: props.valid,
380
426
  },
381
427
  {
382
- ...(slots.cancelButton && {
383
- cancelButton: () => slots.cancelButton && slots.cancelButton(),
384
- }),
385
- ...(slots.confirmButton && {
386
- confirmButton: () => slots.confirmButton && slots.confirmButton(),
387
- }),
388
- toggler: () => InputGroup(),
389
428
  default: () =>
390
429
  h(
391
- 'div',
430
+ CPicker,
431
+ {
432
+ cancelButton: props.cancelButton,
433
+ cancelButtonColor: props.cancelButtonColor,
434
+ cancelButtonSize: props.cancelButtonSize,
435
+ cancelButtonVariant: props.cancelButtonVariant,
436
+ class: ['time-picker', { 'is-invalid': props.invalid, 'is-valid': props.valid }],
437
+ confirmButton: props.confirmButton,
438
+ confirmButtonColor: props.confirmButtonColor,
439
+ confirmButtonSize: props.confirmButtonSize,
440
+ confirmButtonVariant: props.confirmButtonVariant,
441
+ container: props.container,
442
+ disabled: props.disabled,
443
+ footer: true,
444
+ onCancel: () => {
445
+ if (initialDate.value) {
446
+ date.value = new Date(initialDate.value)
447
+ }
448
+ },
449
+ onHide: () => {
450
+ emit('hide')
451
+ },
452
+ onShow: () => {
453
+ if (date.value) {
454
+ initialDate.value = new Date(date.value)
455
+ }
456
+
457
+ emit('show')
458
+ },
459
+ },
392
460
  {
393
- class: [
394
- 'time-picker-body',
395
- {
396
- ['time-picker-roll']: props.variant === 'roll',
397
- },
398
- ],
461
+ ...(slots.cancelButton && {
462
+ cancelButton: () => slots.cancelButton && slots.cancelButton(),
463
+ }),
464
+ ...(slots.confirmButton && {
465
+ confirmButton: () => slots.confirmButton && slots.confirmButton(),
466
+ }),
467
+ toggler: () => InputGroup(),
468
+ default: () =>
469
+ h(
470
+ 'div',
471
+ {
472
+ class: [
473
+ 'time-picker-body',
474
+ {
475
+ ['time-picker-roll']: props.variant === 'roll',
476
+ },
477
+ ],
478
+ },
479
+ props.variant === 'select' ? TimePickerSelect() : TimePickerRoll(),
480
+ ),
399
481
  },
400
- props.variant === 'select' ? TimePickerSelect() : TimePickerRoll(),
401
482
  ),
402
483
  },
403
484
  )