@coreui/vue-pro 4.4.2 → 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.
Files changed (27) hide show
  1. package/dist/components/calendar/CCalendar.d.ts +41 -3
  2. package/dist/components/date-picker/CDatePicker.d.ts +41 -3
  3. package/dist/components/date-range-picker/CDateRangePicker.d.ts +160 -3
  4. package/dist/components/multi-select/CMultiSelect copy.d.ts +305 -0
  5. package/dist/components/multi-select/CMultiSelect.d.ts +168 -0
  6. package/dist/components/smart-table/CSmartTable.d.ts +2 -2
  7. package/dist/components/smart-table/CSmartTableHead.d.ts +15 -3
  8. package/dist/components/smart-table/CSmartTableInterface.d.ts +1 -1
  9. package/dist/components/table/CTable.d.ts +170 -8
  10. package/dist/components/table/CTableDataCell.d.ts +14 -0
  11. package/dist/index.es.js +1006 -474
  12. package/dist/index.es.js.map +1 -1
  13. package/dist/index.js +1006 -474
  14. package/dist/index.js.map +1 -1
  15. package/package.json +2 -2
  16. package/src/components/calendar/CCalendar.ts +46 -4
  17. package/src/components/date-picker/CDatePicker.ts +33 -1
  18. package/src/components/date-range-picker/CDateRangePicker.ts +286 -170
  19. package/src/components/form/CFormInput.ts +1 -1
  20. package/src/components/multi-select/CMultiSelect.ts +204 -93
  21. package/src/components/smart-table/CSmartTable.ts +22 -21
  22. package/src/components/smart-table/CSmartTableHead.ts +45 -24
  23. package/src/components/smart-table/CSmartTableInterface.ts +1 -1
  24. package/src/components/smart-table/CSmartTableItemsPerPageSelector.ts +1 -1
  25. package/src/components/table/CTable.ts +243 -9
  26. package/src/components/table/CTableDataCell.ts +9 -1
  27. package/src/components/time-picker/CTimePicker.ts +125 -44
package/dist/index.js CHANGED
@@ -1163,6 +1163,29 @@ const CCalendar = vue.defineComponent({
1163
1163
  type: Number,
1164
1164
  default: 1,
1165
1165
  },
1166
+ /**
1167
+ * Set the format of day name.
1168
+ *
1169
+ * @default 'numeric'
1170
+ * @since 4.6.0
1171
+ */
1172
+ dayFormat: {
1173
+ type: [Function, String],
1174
+ default: 'numeric',
1175
+ required: false,
1176
+ validator: (value) => {
1177
+ if (typeof value === 'string') {
1178
+ return ['numeric', '2-digit'].includes(value);
1179
+ }
1180
+ if (typeof value === 'function') {
1181
+ return true;
1182
+ }
1183
+ if (typeof value === 'function') {
1184
+ return true;
1185
+ }
1186
+ return false;
1187
+ },
1188
+ },
1166
1189
  /**
1167
1190
  * Specify the list of dates that cannot be selected.
1168
1191
  */
@@ -1215,6 +1238,12 @@ const CCalendar = vue.defineComponent({
1215
1238
  type: Boolean,
1216
1239
  default: true,
1217
1240
  },
1241
+ /**
1242
+ * Reorder year-month navigation, and render year first.
1243
+ *
1244
+ * @since 4.6.0
1245
+ */
1246
+ navYearFirst: Boolean,
1218
1247
  /**
1219
1248
  * Allow range selection.
1220
1249
  */
@@ -1235,7 +1264,7 @@ const CCalendar = vue.defineComponent({
1235
1264
  * @type number | 'long' | 'narrow' | 'short'
1236
1265
  */
1237
1266
  weekdayFormat: {
1238
- type: [Number, String],
1267
+ type: [Function, Number, String],
1239
1268
  default: 2,
1240
1269
  validator: (value) => {
1241
1270
  if (typeof value === 'string') {
@@ -1244,6 +1273,9 @@ const CCalendar = vue.defineComponent({
1244
1273
  if (typeof value === 'number') {
1245
1274
  return true;
1246
1275
  }
1276
+ if (typeof value === 'function') {
1277
+ return true;
1278
+ }
1247
1279
  return false;
1248
1280
  },
1249
1281
  },
@@ -1419,11 +1451,15 @@ const CCalendar = vue.defineComponent({
1419
1451
  vue.h('thead', {}, vue.h('tr', {}, weekDays.map(({ date }) => {
1420
1452
  return vue.h('th', { class: 'calendar-cell' }, vue.h('div', {
1421
1453
  class: 'calendar-header-cell-inner',
1422
- }, props.weekdayFormat === 'string'
1423
- ? date.toLocaleDateString(props.locale, { weekday: props.weekdayFormat })
1424
- : date
1425
- .toLocaleDateString(props.locale, { weekday: 'long' })
1426
- .slice(0, props.weekdayFormat)));
1454
+ }, typeof props.weekdayFormat === 'function'
1455
+ ? props.weekdayFormat(date)
1456
+ : typeof props.weekdayFormat === 'string'
1457
+ ? date.toLocaleDateString(props.locale, {
1458
+ weekday: props.weekdayFormat,
1459
+ })
1460
+ : date
1461
+ .toLocaleDateString(props.locale, { weekday: 'long' })
1462
+ .slice(0, props.weekdayFormat)));
1427
1463
  }))),
1428
1464
  vue.h('tbody', {}, [
1429
1465
  view.value === 'days' &&
@@ -1456,7 +1492,11 @@ const CCalendar = vue.defineComponent({
1456
1492
  }),
1457
1493
  }, vue.h('div', {
1458
1494
  class: 'calendar-cell-inner',
1459
- }, date.toLocaleDateString(props.locale, { day: 'numeric' })));
1495
+ }, typeof props.dayFormat === 'function'
1496
+ ? props.dayFormat(date)
1497
+ : date.toLocaleDateString(props.locale, {
1498
+ day: props.dayFormat,
1499
+ })));
1460
1500
  }));
1461
1501
  }),
1462
1502
  view.value === 'months' &&
@@ -1524,6 +1564,7 @@ const CCalendar = vue.defineComponent({
1524
1564
  ]),
1525
1565
  vue.h('div', {
1526
1566
  class: 'calendar-nav-date',
1567
+ ...(props.navYearFirst && { style: { display: 'flex', justifyContent: 'center' } }),
1527
1568
  }, [
1528
1569
  view.value === 'days' &&
1529
1570
  vue.h(CButton, {
@@ -1541,6 +1582,7 @@ const CCalendar = vue.defineComponent({
1541
1582
  if (props.navigation)
1542
1583
  view.value = 'years';
1543
1584
  },
1585
+ ...(props.navYearFirst && { style: { order: '-1' } }),
1544
1586
  }, () => date.toLocaleDateString(props.locale, { year: 'numeric' })),
1545
1587
  ]),
1546
1588
  props.navigation &&
@@ -8471,7 +8513,7 @@ const CFormInput = vue.defineComponent({
8471
8513
  onInput: (event) => handleInput(event),
8472
8514
  readonly: props.readonly,
8473
8515
  type: props.type,
8474
- ...(props.modelValue && { value: props.modelValue }),
8516
+ ...((props.modelValue || props.modelValue === 0) && { value: props.modelValue })
8475
8517
  }, slots.default && slots.default()),
8476
8518
  ...(slots.feedback && { feedback: () => slots.feedback && slots.feedback() }),
8477
8519
  ...(slots.feedbackInvalid && {
@@ -12069,6 +12111,34 @@ const CTimePicker = vue.defineComponent({
12069
12111
  return ['ghost', 'outline'].includes(value);
12070
12112
  },
12071
12113
  },
12114
+ /**
12115
+ * Provide valuable, actionable feedback.
12116
+ *
12117
+ * @since 4.6.0
12118
+ */
12119
+ feedback: {
12120
+ type: String,
12121
+ },
12122
+ /**
12123
+ * Provide valuable, actionable feedback.
12124
+ *
12125
+ * @since 4.6.0
12126
+ */
12127
+ feedbackInvalid: {
12128
+ type: String,
12129
+ },
12130
+ /**
12131
+ * Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
12132
+ *
12133
+ * @since 4.6.0
12134
+ */
12135
+ feedbackValid: {
12136
+ type: String,
12137
+ },
12138
+ /**
12139
+ * The id global attribute defines an identifier (ID) that must be unique in the whole document.
12140
+ */
12141
+ id: String,
12072
12142
  /**
12073
12143
  * Toggle visibility or set the content of the input indicator.
12074
12144
  */
@@ -12080,6 +12150,20 @@ const CTimePicker = vue.defineComponent({
12080
12150
  * Toggle the readonly state for the component.
12081
12151
  */
12082
12152
  inputReadOnly: Boolean,
12153
+ /**
12154
+ * Set component validation state to invalid.
12155
+ *
12156
+ * @since 4.6.0
12157
+ */
12158
+ invalid: Boolean,
12159
+ /**
12160
+ * Add a caption for a component.
12161
+ *
12162
+ * @since 4.6.0
12163
+ */
12164
+ label: {
12165
+ type: String,
12166
+ },
12083
12167
  /**
12084
12168
  * Sets the default locale for components. If not set, it is inherited from the navigator.language.
12085
12169
  */
@@ -12106,12 +12190,32 @@ const CTimePicker = vue.defineComponent({
12106
12190
  return ['sm', 'lg'].includes(value);
12107
12191
  },
12108
12192
  },
12193
+ /**
12194
+ * Add helper text to the component.
12195
+ *
12196
+ * @since 4.6.0
12197
+ */
12198
+ text: {
12199
+ type: String,
12200
+ },
12109
12201
  /**
12110
12202
  * Initial selected time.
12111
12203
  */
12112
12204
  time: {
12113
12205
  type: [Date, String],
12114
12206
  },
12207
+ /**
12208
+ * Display validation feedback in a styled tooltip.
12209
+ *
12210
+ * @since 4.6.0
12211
+ */
12212
+ tooltipFeedback: Boolean,
12213
+ /**
12214
+ * Set component validation state to valid.
12215
+ *
12216
+ * @since 4.6.0
12217
+ */
12218
+ valid: Boolean,
12115
12219
  /**
12116
12220
  * Set the time picker variant to a roll or select.
12117
12221
  *
@@ -12139,7 +12243,7 @@ const CTimePicker = vue.defineComponent({
12139
12243
  */
12140
12244
  'show',
12141
12245
  ],
12142
- setup(props, { emit, slots }) {
12246
+ setup(props, { emit, attrs, slots }) {
12143
12247
  const date = vue.ref(convertTimeToDate(props.time));
12144
12248
  const initialDate = vue.ref(null);
12145
12249
  const ampm = vue.ref(date.value ? getAmPm(new Date(date.value), props.locale) : 'am');
@@ -12279,49 +12383,62 @@ const CTimePicker = vue.defineComponent({
12279
12383
  selected: ampm.value,
12280
12384
  }),
12281
12385
  ];
12282
- return () => vue.h(CPicker, {
12283
- cancelButton: props.cancelButton,
12284
- cancelButtonColor: props.cancelButtonColor,
12285
- cancelButtonSize: props.cancelButtonSize,
12286
- cancelButtonVariant: props.cancelButtonVariant,
12287
- class: 'time-picker',
12288
- confirmButton: props.confirmButton,
12289
- confirmButtonColor: props.confirmButtonColor,
12290
- confirmButtonSize: props.confirmButtonSize,
12291
- confirmButtonVariant: props.confirmButtonVariant,
12292
- container: props.container,
12293
- disabled: props.disabled,
12294
- footer: true,
12295
- onCancel: () => {
12296
- if (initialDate.value) {
12297
- date.value = new Date(initialDate.value);
12298
- }
12299
- },
12300
- onHide: () => {
12301
- emit('hide');
12302
- },
12303
- onShow: () => {
12304
- if (date.value) {
12305
- initialDate.value = new Date(date.value);
12306
- }
12307
- emit('show');
12308
- },
12386
+ return () => vue.h(CFormControlWrapper, {
12387
+ describedby: attrs['aria-describedby'],
12388
+ feedback: props.feedback,
12389
+ feedbackInvalid: props.feedbackInvalid,
12390
+ feedbackValid: props.feedbackValid,
12391
+ id: props.id,
12392
+ invalid: props.invalid,
12393
+ label: props.label,
12394
+ text: props.text,
12395
+ tooltipFeedback: props.tooltipFeedback,
12396
+ valid: props.valid,
12309
12397
  }, {
12310
- ...(slots.cancelButton && {
12311
- cancelButton: () => slots.cancelButton && slots.cancelButton(),
12312
- }),
12313
- ...(slots.confirmButton && {
12314
- confirmButton: () => slots.confirmButton && slots.confirmButton(),
12398
+ default: () => vue.h(CPicker, {
12399
+ cancelButton: props.cancelButton,
12400
+ cancelButtonColor: props.cancelButtonColor,
12401
+ cancelButtonSize: props.cancelButtonSize,
12402
+ cancelButtonVariant: props.cancelButtonVariant,
12403
+ class: ['time-picker', { 'is-invalid': props.invalid, 'is-valid': props.valid }],
12404
+ confirmButton: props.confirmButton,
12405
+ confirmButtonColor: props.confirmButtonColor,
12406
+ confirmButtonSize: props.confirmButtonSize,
12407
+ confirmButtonVariant: props.confirmButtonVariant,
12408
+ container: props.container,
12409
+ disabled: props.disabled,
12410
+ footer: true,
12411
+ onCancel: () => {
12412
+ if (initialDate.value) {
12413
+ date.value = new Date(initialDate.value);
12414
+ }
12415
+ },
12416
+ onHide: () => {
12417
+ emit('hide');
12418
+ },
12419
+ onShow: () => {
12420
+ if (date.value) {
12421
+ initialDate.value = new Date(date.value);
12422
+ }
12423
+ emit('show');
12424
+ },
12425
+ }, {
12426
+ ...(slots.cancelButton && {
12427
+ cancelButton: () => slots.cancelButton && slots.cancelButton(),
12428
+ }),
12429
+ ...(slots.confirmButton && {
12430
+ confirmButton: () => slots.confirmButton && slots.confirmButton(),
12431
+ }),
12432
+ toggler: () => InputGroup(),
12433
+ default: () => vue.h('div', {
12434
+ class: [
12435
+ 'time-picker-body',
12436
+ {
12437
+ ['time-picker-roll']: props.variant === 'roll',
12438
+ },
12439
+ ],
12440
+ }, props.variant === 'select' ? TimePickerSelect() : TimePickerRoll()),
12315
12441
  }),
12316
- toggler: () => InputGroup(),
12317
- default: () => vue.h('div', {
12318
- class: [
12319
- 'time-picker-body',
12320
- {
12321
- ['time-picker-roll']: props.variant === 'roll',
12322
- },
12323
- ],
12324
- }, props.variant === 'select' ? TimePickerSelect() : TimePickerRoll()),
12325
12442
  });
12326
12443
  },
12327
12444
  });
@@ -12434,6 +12551,29 @@ const CDateRangePicker = vue.defineComponent({
12434
12551
  return ['ghost', 'outline'].includes(value);
12435
12552
  },
12436
12553
  },
12554
+ /**
12555
+ * Set the format of day name.
12556
+ *
12557
+ * @default 'numeric'
12558
+ * @since 4.6.0
12559
+ */
12560
+ dayFormat: {
12561
+ type: [Function, String],
12562
+ default: 'numeric',
12563
+ required: false,
12564
+ validator: (value) => {
12565
+ if (typeof value === 'string') {
12566
+ return ['numeric', '2-digit'].includes(value);
12567
+ }
12568
+ if (typeof value === 'function') {
12569
+ return true;
12570
+ }
12571
+ if (typeof value === 'function') {
12572
+ return true;
12573
+ }
12574
+ return false;
12575
+ },
12576
+ },
12437
12577
  /**
12438
12578
  * Toggle the disabled state for the component.
12439
12579
  */
@@ -12451,6 +12591,30 @@ const CDateRangePicker = vue.defineComponent({
12451
12591
  type: [Date, String],
12452
12592
  required: false,
12453
12593
  },
12594
+ /**
12595
+ * Provide valuable, actionable feedback.
12596
+ *
12597
+ * @since 4.6.0
12598
+ */
12599
+ feedback: {
12600
+ type: String,
12601
+ },
12602
+ /**
12603
+ * Provide valuable, actionable feedback.
12604
+ *
12605
+ * @since 4.6.0
12606
+ */
12607
+ feedbackInvalid: {
12608
+ type: String,
12609
+ },
12610
+ /**
12611
+ * Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
12612
+ *
12613
+ * @since 4.6.0
12614
+ */
12615
+ feedbackValid: {
12616
+ type: String,
12617
+ },
12454
12618
  /**
12455
12619
  * Sets the day of start week.
12456
12620
  * - 0 - Sunday,
@@ -12493,6 +12657,20 @@ const CDateRangePicker = vue.defineComponent({
12493
12657
  * Toggle the readonly state for the component.
12494
12658
  */
12495
12659
  inputReadOnly: Boolean,
12660
+ /**
12661
+ * Set component validation state to invalid.
12662
+ *
12663
+ * @since 4.6.0
12664
+ */
12665
+ invalid: Boolean,
12666
+ /**
12667
+ * Add a caption for a component.
12668
+ *
12669
+ * @since 4.6.0
12670
+ */
12671
+ label: {
12672
+ type: String,
12673
+ },
12496
12674
  /**
12497
12675
  * Sets the default locale for components. If not set, it is inherited from the navigator.language.
12498
12676
  */
@@ -12519,6 +12697,12 @@ const CDateRangePicker = vue.defineComponent({
12519
12697
  type: Boolean,
12520
12698
  default: true,
12521
12699
  },
12700
+ /**
12701
+ * Reorder year-month navigation, and render year first.
12702
+ *
12703
+ * @since 4.6.0
12704
+ */
12705
+ navYearFirst: Boolean,
12522
12706
  /**
12523
12707
  * Specifies a short hint that is visible in the input.
12524
12708
  */
@@ -12566,6 +12750,14 @@ const CDateRangePicker = vue.defineComponent({
12566
12750
  startDate: {
12567
12751
  type: [Date, String],
12568
12752
  },
12753
+ /**
12754
+ * Add helper text to the component.
12755
+ *
12756
+ * @since 4.6.0
12757
+ */
12758
+ text: {
12759
+ type: String,
12760
+ },
12569
12761
  /**
12570
12762
  * Provide an additional time selection by adding select boxes to choose times.
12571
12763
  */
@@ -12609,13 +12801,25 @@ const CDateRangePicker = vue.defineComponent({
12609
12801
  return ['ghost', 'outline'].includes(value);
12610
12802
  },
12611
12803
  },
12804
+ /**
12805
+ * Display validation feedback in a styled tooltip.
12806
+ *
12807
+ * @since 4.6.0
12808
+ */
12809
+ tooltipFeedback: Boolean,
12810
+ /**
12811
+ * Set component validation state to valid.
12812
+ *
12813
+ * @since 4.6.0
12814
+ */
12815
+ valid: Boolean,
12612
12816
  /**
12613
12817
  * Set length or format of day name.
12614
12818
  *
12615
12819
  * @type number | 'long' | 'narrow' | 'short'
12616
12820
  */
12617
12821
  weekdayFormat: {
12618
- type: [Number, String],
12822
+ type: [Function, Number, String],
12619
12823
  default: 2,
12620
12824
  validator: (value) => {
12621
12825
  if (typeof value === 'string') {
@@ -12624,6 +12828,9 @@ const CDateRangePicker = vue.defineComponent({
12624
12828
  if (typeof value === 'number') {
12625
12829
  return true;
12626
12830
  }
12831
+ if (typeof value === 'function') {
12832
+ return true;
12833
+ }
12627
12834
  return false;
12628
12835
  },
12629
12836
  },
@@ -12652,7 +12859,7 @@ const CDateRangePicker = vue.defineComponent({
12652
12859
  */
12653
12860
  'start-date-change',
12654
12861
  ],
12655
- setup(props, { slots, emit }) {
12862
+ setup(props, { slots, attrs, emit }) {
12656
12863
  const calendarDate = vue.ref(props.calendarDate
12657
12864
  ? new Date(props.calendarDate)
12658
12865
  : props.startDate
@@ -12819,148 +13026,165 @@ const CDateRangePicker = vue.defineComponent({
12819
13026
  : vue.h('span', { class: 'picker-input-group-icon date-picker-cleaner-icon' })),
12820
13027
  ]),
12821
13028
  ]);
12822
- return () => vue.h(CPicker, {
12823
- cancelButton: props.cancelButton,
12824
- cancelButtonColor: props.cancelButtonColor,
12825
- cancelButtonSize: props.cancelButtonSize,
12826
- cancelButtonVariant: props.cancelButtonVariant,
12827
- class: 'date-picker',
12828
- confirmButton: props.confirmButton,
12829
- confirmButtonColor: props.confirmButtonColor,
12830
- confirmButtonSize: props.confirmButtonSize,
12831
- confirmButtonVariant: props.confirmButtonVariant,
12832
- disabled: props.disabled,
12833
- footer: props.footer || props.timepicker,
13029
+ return () => vue.h(CFormControlWrapper, {
13030
+ describedby: attrs['aria-describedby'],
13031
+ feedback: props.feedback,
13032
+ feedbackInvalid: props.feedbackInvalid,
13033
+ feedbackValid: props.feedbackValid,
12834
13034
  id: props.id,
12835
- onCancel: () => {
12836
- startDate.value = initialStartDate.value;
12837
- endDate.value = initialEndDate.value;
12838
- },
12839
- onHide: () => {
12840
- emit('hide');
12841
- },
12842
- onShow: () => {
12843
- if (startDate.value) {
12844
- initialStartDate.value = new Date(startDate.value);
12845
- }
12846
- if (endDate.value) {
12847
- initialEndDate.value = new Date(endDate.value);
12848
- }
12849
- emit('show');
12850
- },
13035
+ invalid: props.invalid,
13036
+ label: props.label,
13037
+ text: props.text,
13038
+ tooltipFeedback: props.tooltipFeedback,
13039
+ valid: props.valid,
12851
13040
  }, {
12852
- ...(slots.cancelButton && {
12853
- cancelButton: () => slots.cancelButton && slots.cancelButton(),
12854
- }),
12855
- ...(slots.confirmButton && {
12856
- confirmButton: () => slots.confirmButton && slots.confirmButton(),
12857
- }),
12858
- toggler: () => InputGroup(),
12859
- footer: () => vue.h(CButton, {
12860
- class: 'me-auto',
12861
- color: props.todayButtonColor,
12862
- size: props.todayButtonSize,
12863
- variant: props.todayButtonVariant,
12864
- onClick: () => {
12865
- const date = new Date();
12866
- startDate.value = date;
12867
- endDate.value = date;
12868
- calendarDate.value = date;
13041
+ default: () => vue.h(CPicker, {
13042
+ cancelButton: props.cancelButton,
13043
+ cancelButtonColor: props.cancelButtonColor,
13044
+ cancelButtonSize: props.cancelButtonSize,
13045
+ cancelButtonVariant: props.cancelButtonVariant,
13046
+ class: ['date-picker', { 'is-invalid': props.invalid, 'is-valid': props.valid }],
13047
+ confirmButton: props.confirmButton,
13048
+ confirmButtonColor: props.confirmButtonColor,
13049
+ confirmButtonSize: props.confirmButtonSize,
13050
+ confirmButtonVariant: props.confirmButtonVariant,
13051
+ disabled: props.disabled,
13052
+ footer: props.footer || props.timepicker,
13053
+ id: props.id,
13054
+ onCancel: () => {
13055
+ startDate.value = initialStartDate.value;
13056
+ endDate.value = initialEndDate.value;
12869
13057
  },
12870
- }, () => props.todayButton),
12871
- default: () => vue.h('div', {
12872
- class: 'date-picker-body',
12873
- }, [
12874
- props.ranges &&
12875
- vue.h('div', { class: 'date-picker-ranges' }, Object.keys(props.ranges).map((key) => vue.h(CButton, {
12876
- color: 'secondary',
12877
- onClick: () => {
12878
- if (props.ranges) {
12879
- startDate.value = props.ranges[key][0];
12880
- endDate.value = props.ranges[key][1];
12881
- }
12882
- },
12883
- variant: 'ghost',
12884
- }, () => key))),
12885
- vue.h('div', { class: 'date-picker-calendars' }, vue.h(CCalendar, {
12886
- calendarDate: new Date(calendarDate.value.getFullYear(), calendarDate.value.getMonth(), 1),
12887
- calendars: props.calendars,
12888
- disabledDates: props.disabledDates,
12889
- ...(endDate.value && { endDate: endDate.value }),
12890
- firstDayOfWeek: props.firstDayOfWeek,
12891
- locale: props.locale,
12892
- maxDate: maxDate.value,
12893
- minDate: minDate.value,
12894
- navigation: props.navigation,
12895
- range: props.range,
12896
- selectEndDate: selectEndDate.value,
12897
- ...(startDate.value && { startDate: startDate.value }),
12898
- onCalendarCellHover: (date) => handleCalendarCellHover(date),
12899
- onCalendarDateChange: (date) => handleCalendarDateChange(date),
12900
- onStartDateChange: (date) => handleStartDateChange(date),
12901
- onEndDateChange: (date) => handleEndDateChange(date),
12902
- }, {
12903
- /**
12904
- * @slot Location for next icon.
12905
- */
12906
- ...(slots.navNextIcon && {
12907
- navNextIcon: () => slots.navNextIcon && slots.navNextIcon(),
12908
- }),
12909
- /**
12910
- * @slot Location for next double icon.
12911
- */
12912
- ...(slots.navNextDoubleIcon && {
12913
- navNextDoubleIcon: () => slots.navNextDoubleIcon && slots.navNextDoubleIcon(),
12914
- }),
12915
- /**
12916
- * @slot Location for previous icon.
12917
- */
12918
- ...(slots.navPrevIcon && {
12919
- navPrevIcon: () => slots.navPrevIcon && slots.navPrevIcon(),
12920
- }),
12921
- /**
12922
- * @slot Location for double previous icon.
12923
- */
12924
- ...(slots.navPrevDoubleIcon && {
12925
- navPrevDoubleIcon: () => slots.navPrevDoubleIcon && slots.navPrevDoubleIcon(),
12926
- }),
12927
- })),
12928
- props.timepicker &&
12929
- vue.h('div', { class: 'date-picker-timepickers' }, isMobile.value || (props.range && props.calendars === 1)
12930
- ? [
12931
- vue.h(CTimePicker, {
12932
- container: 'inline',
12933
- disabled: startDate.value === null ? true : false,
12934
- locale: props.locale,
12935
- onChange: (_, __, date) => handleStartDateChange(date),
12936
- time: startDate.value,
12937
- variant: 'select',
12938
- }),
12939
- vue.h(CTimePicker, {
13058
+ onHide: () => {
13059
+ emit('hide');
13060
+ },
13061
+ onShow: () => {
13062
+ if (startDate.value) {
13063
+ initialStartDate.value = new Date(startDate.value);
13064
+ }
13065
+ if (endDate.value) {
13066
+ initialEndDate.value = new Date(endDate.value);
13067
+ }
13068
+ emit('show');
13069
+ },
13070
+ }, {
13071
+ ...(slots.cancelButton && {
13072
+ cancelButton: () => slots.cancelButton && slots.cancelButton(),
13073
+ }),
13074
+ ...(slots.confirmButton && {
13075
+ confirmButton: () => slots.confirmButton && slots.confirmButton(),
13076
+ }),
13077
+ toggler: () => InputGroup(),
13078
+ footer: () => vue.h(CButton, {
13079
+ class: 'me-auto',
13080
+ color: props.todayButtonColor,
13081
+ size: props.todayButtonSize,
13082
+ variant: props.todayButtonVariant,
13083
+ onClick: () => {
13084
+ const date = new Date();
13085
+ startDate.value = date;
13086
+ endDate.value = date;
13087
+ calendarDate.value = date;
13088
+ },
13089
+ }, () => props.todayButton),
13090
+ default: () => vue.h('div', {
13091
+ class: 'date-picker-body',
13092
+ }, [
13093
+ props.ranges &&
13094
+ vue.h('div', { class: 'date-picker-ranges' }, Object.keys(props.ranges).map((key) => vue.h(CButton, {
13095
+ color: 'secondary',
13096
+ onClick: () => {
13097
+ if (props.ranges) {
13098
+ startDate.value = props.ranges[key][0];
13099
+ endDate.value = props.ranges[key][1];
13100
+ }
13101
+ },
13102
+ variant: 'ghost',
13103
+ }, () => key))),
13104
+ vue.h('div', { class: 'date-picker-calendars' }, vue.h(CCalendar, {
13105
+ calendarDate: new Date(calendarDate.value.getFullYear(), calendarDate.value.getMonth(), 1),
13106
+ calendars: props.calendars,
13107
+ dayFormat: props.dayFormat,
13108
+ disabledDates: props.disabledDates,
13109
+ ...(endDate.value && { endDate: endDate.value }),
13110
+ firstDayOfWeek: props.firstDayOfWeek,
13111
+ locale: props.locale,
13112
+ maxDate: maxDate.value,
13113
+ minDate: minDate.value,
13114
+ navYearFirst: props.navYearFirst,
13115
+ navigation: props.navigation,
13116
+ range: props.range,
13117
+ selectEndDate: selectEndDate.value,
13118
+ ...(startDate.value && { startDate: startDate.value }),
13119
+ onCalendarCellHover: (date) => handleCalendarCellHover(date),
13120
+ onCalendarDateChange: (date) => handleCalendarDateChange(date),
13121
+ onStartDateChange: (date) => handleStartDateChange(date),
13122
+ onEndDateChange: (date) => handleEndDateChange(date),
13123
+ }, {
13124
+ /**
13125
+ * @slot Location for next icon.
13126
+ */
13127
+ ...(slots.navNextIcon && {
13128
+ navNextIcon: () => slots.navNextIcon && slots.navNextIcon(),
13129
+ }),
13130
+ /**
13131
+ * @slot Location for next double icon.
13132
+ */
13133
+ ...(slots.navNextDoubleIcon && {
13134
+ navNextDoubleIcon: () => slots.navNextDoubleIcon && slots.navNextDoubleIcon(),
13135
+ }),
13136
+ /**
13137
+ * @slot Location for previous icon.
13138
+ */
13139
+ ...(slots.navPrevIcon && {
13140
+ navPrevIcon: () => slots.navPrevIcon && slots.navPrevIcon(),
13141
+ }),
13142
+ /**
13143
+ * @slot Location for double previous icon.
13144
+ */
13145
+ ...(slots.navPrevDoubleIcon && {
13146
+ navPrevDoubleIcon: () => slots.navPrevDoubleIcon && slots.navPrevDoubleIcon(),
13147
+ }),
13148
+ })),
13149
+ props.timepicker &&
13150
+ vue.h('div', { class: 'date-picker-timepickers' }, isMobile.value || (props.range && props.calendars === 1)
13151
+ ? [
13152
+ vue.h(CTimePicker, {
13153
+ container: 'inline',
13154
+ disabled: startDate.value === null ? true : false,
13155
+ locale: props.locale,
13156
+ onChange: (_, __, date) => handleStartDateChange(date),
13157
+ time: startDate.value,
13158
+ variant: 'select',
13159
+ }),
13160
+ vue.h(CTimePicker, {
13161
+ container: 'inline',
13162
+ disabled: endDate.value === null ? true : false,
13163
+ locale: props.locale,
13164
+ onChange: (_, __, date) => handleEndDateChange(date),
13165
+ time: endDate.value,
13166
+ variant: 'select',
13167
+ }),
13168
+ ]
13169
+ : [...Array(props.calendars)].map((_, index) => vue.h(CTimePicker, {
12940
13170
  container: 'inline',
12941
- disabled: endDate.value === null ? true : false,
13171
+ disabled: index === 0
13172
+ ? startDate.value === null
13173
+ ? true
13174
+ : false
13175
+ : endDate.value === null
13176
+ ? true
13177
+ : false,
12942
13178
  locale: props.locale,
12943
- onChange: (_, __, date) => handleEndDateChange(date),
12944
- time: endDate.value,
13179
+ onChange: (_, __, date) => index === 0
13180
+ ? handleStartDateChange(date)
13181
+ : handleEndDateChange(date),
13182
+ time: index === 0 ? startDate.value : endDate.value,
12945
13183
  variant: 'select',
12946
- }),
12947
- ]
12948
- : [...Array(props.calendars)].map((_, index) => vue.h(CTimePicker, {
12949
- container: 'inline',
12950
- disabled: index === 0
12951
- ? startDate.value === null
12952
- ? true
12953
- : false
12954
- : endDate.value === null
12955
- ? true
12956
- : false,
12957
- locale: props.locale,
12958
- onChange: (_, __, date) => index === 0 ? handleStartDateChange(date) : handleEndDateChange(date),
12959
- time: index === 0 ? startDate.value : endDate.value,
12960
- variant: 'select',
12961
- }))),
12962
- ]),
12963
- });
13184
+ }))),
13185
+ ]),
13186
+ }),
13187
+ });
12964
13188
  },
12965
13189
  });
12966
13190
 
@@ -13065,6 +13289,29 @@ const CDatePicker = vue.defineComponent({
13065
13289
  return ['ghost', 'outline'].includes(value);
13066
13290
  },
13067
13291
  },
13292
+ /**
13293
+ * Set the format of day name.
13294
+ *
13295
+ * @default 'numeric'
13296
+ * @since 4.6.0
13297
+ */
13298
+ dayFormat: {
13299
+ type: [Function, String],
13300
+ default: 'numeric',
13301
+ required: false,
13302
+ validator: (value) => {
13303
+ if (typeof value === 'string') {
13304
+ return ['numeric', '2-digit'].includes(value);
13305
+ }
13306
+ if (typeof value === 'function') {
13307
+ return true;
13308
+ }
13309
+ if (typeof value === 'function') {
13310
+ return true;
13311
+ }
13312
+ return false;
13313
+ },
13314
+ },
13068
13315
  /**
13069
13316
  * Toggle the disabled state for the component.
13070
13317
  */
@@ -13149,6 +13396,12 @@ const CDatePicker = vue.defineComponent({
13149
13396
  type: Boolean,
13150
13397
  default: true,
13151
13398
  },
13399
+ /**
13400
+ * Reorder year-month navigation, and render year first.
13401
+ *
13402
+ * @since 4.6.0
13403
+ */
13404
+ navYearFirst: Boolean,
13152
13405
  /**
13153
13406
  * Specifies a short hint that is visible in the input.
13154
13407
  */
@@ -13178,7 +13431,7 @@ const CDatePicker = vue.defineComponent({
13178
13431
  * @type number | 'long' | 'narrow' | 'short'
13179
13432
  */
13180
13433
  weekdayFormat: {
13181
- type: [Number, String],
13434
+ type: [Function, Number, String],
13182
13435
  default: 2,
13183
13436
  validator: (value) => {
13184
13437
  if (typeof value === 'string') {
@@ -13187,6 +13440,9 @@ const CDatePicker = vue.defineComponent({
13187
13440
  if (typeof value === 'number') {
13188
13441
  return true;
13189
13442
  }
13443
+ if (typeof value === 'function') {
13444
+ return true;
13445
+ }
13190
13446
  return false;
13191
13447
  },
13192
13448
  },
@@ -14577,6 +14833,58 @@ const CMultiSelect = vue.defineComponent({
14577
14833
  required: false,
14578
14834
  default: true,
14579
14835
  },
14836
+ /**
14837
+ * Toggle the disabled state for the component.
14838
+ */
14839
+ disabled: {
14840
+ type: Boolean,
14841
+ required: false,
14842
+ default: false,
14843
+ },
14844
+ /**
14845
+ * Provide valuable, actionable feedback.
14846
+ *
14847
+ * @since 4.6.0
14848
+ */
14849
+ feedback: {
14850
+ type: String,
14851
+ },
14852
+ /**
14853
+ * Provide valuable, actionable feedback.
14854
+ *
14855
+ * @since 4.6.0
14856
+ */
14857
+ feedbackInvalid: {
14858
+ type: String,
14859
+ },
14860
+ /**
14861
+ * Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
14862
+ *
14863
+ * @since 4.6.0
14864
+ */
14865
+ feedbackValid: {
14866
+ type: String,
14867
+ },
14868
+ /**
14869
+ * The id global attribute defines an identifier (ID) that must be unique in the whole document.
14870
+ */
14871
+ id: {
14872
+ type: String,
14873
+ },
14874
+ /**
14875
+ * Set component validation state to invalid.
14876
+ *
14877
+ * @since 4.6.0
14878
+ */
14879
+ invalid: Boolean,
14880
+ /**
14881
+ * Add a caption for a component.
14882
+ *
14883
+ * @since 4.6.0
14884
+ */
14885
+ label: {
14886
+ type: String,
14887
+ },
14580
14888
  /**
14581
14889
  * It specifies that multiple options can be selected at once.
14582
14890
  *
@@ -14689,6 +14997,38 @@ const CMultiSelect = vue.defineComponent({
14689
14997
  default: 'item(s) selected',
14690
14998
  required: false,
14691
14999
  },
15000
+ /**
15001
+ * Size the component small or large.
15002
+ *
15003
+ * @values 'sm', 'lg'
15004
+ */
15005
+ size: {
15006
+ type: String,
15007
+ required: false,
15008
+ validator: (value) => {
15009
+ return ['sm', 'lg'].includes(value);
15010
+ },
15011
+ },
15012
+ /**
15013
+ * Add helper text to the component.
15014
+ *
15015
+ * @since 4.6.0
15016
+ */
15017
+ text: {
15018
+ type: String,
15019
+ },
15020
+ /**
15021
+ * Display validation feedback in a styled tooltip.
15022
+ *
15023
+ * @since 4.6.0
15024
+ */
15025
+ tooltipFeedback: Boolean,
15026
+ /**
15027
+ * Set component validation state to valid.
15028
+ *
15029
+ * @since 4.6.0
15030
+ */
15031
+ valid: Boolean,
14692
15032
  /**
14693
15033
  * Toggle the visibility of multi select dropdown.
14694
15034
  *
@@ -14706,7 +15046,7 @@ const CMultiSelect = vue.defineComponent({
14706
15046
  */
14707
15047
  'change',
14708
15048
  ],
14709
- setup(props, { emit }) {
15049
+ setup(props, { attrs, emit }) {
14710
15050
  const flattenArray = (options) => {
14711
15051
  return options.reduce((acc, val) => {
14712
15052
  return acc.concat(Array.isArray(val.options) ? flattenArray(val.options) : val);
@@ -14771,7 +15111,6 @@ const CMultiSelect = vue.defineComponent({
14771
15111
  }, [])
14772
15112
  : options.value;
14773
15113
  };
14774
- const multiSelectRef = vue.ref();
14775
15114
  const nativeSelectRef = vue.ref();
14776
15115
  vue.provide('nativeSelectRef', nativeSelectRef);
14777
15116
  const searchRef = vue.ref();
@@ -14781,8 +15120,9 @@ const CMultiSelect = vue.defineComponent({
14781
15120
  const visible = vue.ref(props.visible);
14782
15121
  const selected = vue.ref(getSelectedOptions(props.options));
14783
15122
  const count = vue.ref(0);
14784
- vue.watch(() => props.options, () => {
14785
- options.value = props.options;
15123
+ vue.watch(() => props.options, (newValue, oldValue) => {
15124
+ if (JSON.stringify(newValue) !== JSON.stringify(oldValue))
15125
+ options.value = newValue;
14786
15126
  });
14787
15127
  vue.watch(options, () => {
14788
15128
  const _selected = options.value && getSelectedOptions(options.value);
@@ -14805,24 +15145,6 @@ const CMultiSelect = vue.defineComponent({
14805
15145
  nativeSelectRef.value &&
14806
15146
  nativeSelectRef.value.dispatchEvent(new Event('change', { bubbles: true }));
14807
15147
  });
14808
- vue.onMounted(() => {
14809
- window.addEventListener('click', handleClickOutside);
14810
- window.addEventListener('keyup', handleKeyup);
14811
- });
14812
- vue.onUnmounted(() => {
14813
- window.removeEventListener('click', handleClickOutside);
14814
- window.removeEventListener('keyup', handleKeyup);
14815
- });
14816
- const handleKeyup = (event) => {
14817
- if (multiSelectRef.value && !multiSelectRef.value.contains(event.target)) {
14818
- visible.value = false;
14819
- }
14820
- };
14821
- const handleClickOutside = (event) => {
14822
- if (multiSelectRef.value && !multiSelectRef.value.contains(event.target)) {
14823
- visible.value = false;
14824
- }
14825
- };
14826
15148
  const handleSearchChange = (event) => {
14827
15149
  const target = event.target;
14828
15150
  search.value = target.value.toLowerCase();
@@ -14840,6 +15162,13 @@ const CMultiSelect = vue.defineComponent({
14840
15162
  };
14841
15163
  const handleOptionClick = (option) => {
14842
15164
  options.value = updateOptions(option.value);
15165
+ if (!props.multiple) {
15166
+ visible.value = false;
15167
+ search.value = '';
15168
+ if (searchRef.value) {
15169
+ searchRef.value.value = '';
15170
+ }
15171
+ }
14843
15172
  };
14844
15173
  const handleSelectAll = () => {
14845
15174
  options.value = toggleAllOptions(options.value, true);
@@ -14856,68 +15185,97 @@ const CMultiSelect = vue.defineComponent({
14856
15185
  : selected.value.map((option) => option.value)[0],
14857
15186
  onChange: () => emit('change', selected.value),
14858
15187
  }),
14859
- vue.h('div', {
14860
- class: [
14861
- 'form-multi-select',
14862
- {
14863
- show: visible.value,
14864
- 'form-multi-select-selection-tags': props.multiple && props.selectionType === 'tags',
15188
+ vue.h(CFormControlWrapper, {
15189
+ describedby: attrs['aria-describedby'],
15190
+ feedback: props.feedback,
15191
+ feedbackInvalid: props.feedbackInvalid,
15192
+ feedbackValid: props.feedbackValid,
15193
+ id: props.id,
15194
+ invalid: props.invalid,
15195
+ label: props.label,
15196
+ text: props.text,
15197
+ tooltipFeedback: props.tooltipFeedback,
15198
+ valid: props.valid,
15199
+ }, {
15200
+ default: () => vue.h(CPicker, {
15201
+ class: [
15202
+ 'form-multi-select',
15203
+ {
15204
+ 'form-multi-select-with-cleaner': props.cleaner,
15205
+ disabled: props.disabled,
15206
+ [`form-multi-select-${props.size}`]: props.size,
15207
+ 'form-multi-select-selection-tags': props.multiple && props.selectionType === 'tags',
15208
+ show: visible.value,
15209
+ 'is-invalid': props.invalid,
15210
+ 'is-valid': props.valid,
15211
+ },
15212
+ ],
15213
+ disabled: props.disabled,
15214
+ id: props.id,
15215
+ onHide: () => {
15216
+ visible.value = false;
14865
15217
  },
14866
- ],
14867
- onClick: () => {
14868
- visible.value = true;
14869
- props.search && searchRef.value && searchRef.value.focus();
14870
- },
14871
- ref: multiSelectRef,
14872
- }, [
14873
- vue.h(CMultiSelectSelection, {
14874
- multiple: props.multiple,
14875
- onRemove: (option) => handleOptionClick(option),
14876
- search: props.search,
14877
- selected: selected.value,
14878
- selectionType: props.selectionType,
14879
- selectionTypeCounterText: props.selectionTypeCounterText,
14880
- }),
14881
- props.multiple &&
14882
- props.cleaner &&
14883
- selected.value.length > 0 &&
14884
- vue.h('button', {
14885
- type: 'button',
14886
- class: 'form-multi-select-selection-cleaner',
14887
- onClick: () => handleDeselectAll(),
14888
- }),
14889
- props.search &&
14890
- vue.h('input', {
14891
- type: 'text',
14892
- class: 'form-multi-select-search',
14893
- autocomplete: 'off',
14894
- ...(selected.value.length === 0 && { placeholder: props.placeholder }),
14895
- ...(selected.value.length &&
14896
- props.selectionType === 'counter' && {
14897
- placeholder: `${selected.value.length} ${props.selectionTypeCounterText}`,
15218
+ onShow: () => {
15219
+ props.search && searchRef.value && searchRef.value.focus();
15220
+ visible.value = true;
15221
+ },
15222
+ visible: visible.value,
15223
+ }, {
15224
+ toggler: () => vue.h('div', {}, [
15225
+ vue.h(CMultiSelectSelection, {
15226
+ multiple: props.multiple,
15227
+ onRemove: (option) => !props.disabled && handleOptionClick(option),
15228
+ search: props.search,
15229
+ selected: selected.value,
15230
+ selectionType: props.selectionType,
15231
+ selectionTypeCounterText: props.selectionTypeCounterText,
14898
15232
  }),
14899
- ...(selected.value.length &&
14900
- !props.multiple && { placeholder: selected.value.map((option) => option.text)[0] }),
14901
- onInput: (event) => handleSearchChange(event),
14902
- onKeydown: (event) => handleSearchKeyDown(event),
14903
- ...(props.multiple &&
14904
- selected.value.length &&
14905
- props.selectionType !== 'counter' && { size: search.value.length + 2 }),
14906
- ref: searchRef,
14907
- }),
14908
- vue.h('div', { class: 'form-multi-select-dropdown' }, [
14909
- props.multiple &&
14910
- props.selectAll &&
14911
- vue.h('button', { class: 'form-multi-select-all', onClick: () => handleSelectAll() }, props.selectAllLabel),
14912
- vue.h(CMultiSelectOptions, {
14913
- onOptionClick: (option) => handleOptionClick(option),
14914
- options: vOptions.value,
14915
- optionsMaxHeight: props.optionsMaxHeight,
14916
- optionsStyle: props.optionsStyle,
14917
- searchNoResultsLabel: props.searchNoResultsLabel,
14918
- }),
14919
- ]),
14920
- ]),
15233
+ props.multiple &&
15234
+ props.cleaner &&
15235
+ selected.value.length > 0 &&
15236
+ !props.disabled &&
15237
+ vue.h('button', {
15238
+ type: 'button',
15239
+ class: 'form-multi-select-selection-cleaner',
15240
+ onClick: () => handleDeselectAll(),
15241
+ }),
15242
+ props.search &&
15243
+ vue.h('input', {
15244
+ type: 'text',
15245
+ class: 'form-multi-select-search',
15246
+ autocomplete: 'off',
15247
+ ...(selected.value.length === 0 && { placeholder: props.placeholder }),
15248
+ ...(selected.value.length &&
15249
+ props.selectionType === 'counter' && {
15250
+ placeholder: `${selected.value.length} ${props.selectionTypeCounterText}`,
15251
+ }),
15252
+ ...(selected.value.length &&
15253
+ !props.multiple && {
15254
+ placeholder: selected.value.map((option) => option.text)[0],
15255
+ }),
15256
+ disabled: props.disabled,
15257
+ onInput: (event) => handleSearchChange(event),
15258
+ onKeydown: (event) => handleSearchKeyDown(event),
15259
+ ...(props.multiple &&
15260
+ selected.value.length &&
15261
+ props.selectionType !== 'counter' && { size: search.value.length + 2 }),
15262
+ ref: searchRef,
15263
+ }),
15264
+ ]),
15265
+ default: () => vue.h('div', {}, [
15266
+ props.multiple &&
15267
+ props.selectAll &&
15268
+ vue.h('button', { class: 'form-multi-select-all', onClick: () => handleSelectAll() }, props.selectAllLabel),
15269
+ vue.h(CMultiSelectOptions, {
15270
+ onOptionClick: (option) => handleOptionClick(option),
15271
+ options: vOptions.value,
15272
+ optionsMaxHeight: props.optionsMaxHeight,
15273
+ optionsStyle: props.optionsStyle,
15274
+ searchNoResultsLabel: props.searchNoResultsLabel,
15275
+ }),
15276
+ ]),
15277
+ }),
15278
+ }),
14921
15279
  ];
14922
15280
  },
14923
15281
  });
@@ -16576,53 +16934,56 @@ const CSidebarPlugin = {
16576
16934
  },
16577
16935
  };
16578
16936
 
16579
- const CTable = vue.defineComponent({
16580
- name: 'CTable',
16937
+ const CTableBody = vue.defineComponent({
16938
+ name: 'CTableBody',
16581
16939
  props: {
16582
16940
  /**
16583
- * Set the vertical aligment.
16584
- *
16585
- * @values 'bottom', 'middle', 'top'
16586
- */
16587
- align: {
16588
- type: String,
16589
- default: undefined,
16590
- required: false,
16591
- validator: (value) => {
16592
- return ['bottom', 'middle', 'top'].includes(value);
16593
- },
16594
- },
16595
- /**
16596
- * Sets the border color of the component to one of CoreUI’s themed colors.
16941
+ * Sets the color context of the component to one of CoreUI’s themed colors.
16597
16942
  *
16598
- * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
16599
- */
16600
- borderColor: Color,
16601
- /**
16602
- * Add borders on all sides of the table and cells.
16943
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light', string
16603
16944
  */
16604
- bordered: {
16605
- type: Boolean,
16606
- required: false,
16607
- },
16945
+ color: Color,
16946
+ },
16947
+ setup(props, { slots }) {
16948
+ return () => vue.h('tbody', {
16949
+ class: [
16950
+ {
16951
+ [`table-${props.color}`]: props.color,
16952
+ },
16953
+ ],
16954
+ }, slots.default && slots.default());
16955
+ },
16956
+ });
16957
+
16958
+ const CTableCaption = vue.defineComponent({
16959
+ name: 'CTableCaption',
16960
+ props: {},
16961
+ setup(_, { slots }) {
16962
+ return () => vue.h('caption', {}, slots.default && slots.default());
16963
+ },
16964
+ });
16965
+
16966
+ const CTableDataCell = vue.defineComponent({
16967
+ name: 'CTableDataCell',
16968
+ props: {
16608
16969
  /**
16609
- * Remove borders on all sides of the table and cells.
16970
+ * Highlight a table row or cell.
16610
16971
  */
16611
- borderless: {
16972
+ active: {
16612
16973
  type: Boolean,
16613
16974
  required: false,
16614
16975
  },
16615
16976
  /**
16616
- * Put the `<caption>` on the top of the table.
16977
+ * Set the vertical aligment.
16617
16978
  *
16618
- * @values 'top'
16979
+ * @values 'bottom', 'middle', 'top'
16619
16980
  */
16620
- caption: {
16981
+ align: {
16621
16982
  type: String,
16622
16983
  default: undefined,
16623
16984
  required: false,
16624
16985
  validator: (value) => {
16625
- return value === 'top';
16986
+ return ['bottom', 'middle', 'top'].includes(value);
16626
16987
  },
16627
16988
  },
16628
16989
  /**
@@ -16632,88 +16993,50 @@ const CTable = vue.defineComponent({
16632
16993
  */
16633
16994
  color: Color,
16634
16995
  /**
16635
- * Enable a hover state on table rows within a `<CTableBody>`.
16996
+ * @ignore
16636
16997
  */
16637
- hover: {
16638
- type: Boolean,
16998
+ scope: {
16999
+ type: String,
16639
17000
  required: false,
16640
17001
  },
17002
+ },
17003
+ setup(props, { slots }) {
17004
+ return () => vue.h(props.scope ? 'th' : 'td', {
17005
+ class: [
17006
+ {
17007
+ [`align-${props.align}`]: props.align,
17008
+ 'table-active': props.active,
17009
+ [`table-${props.color}`]: props.color,
17010
+ },
17011
+ ],
17012
+ ...(props.scope && { scope: props.scope }),
17013
+ }, slots.default && slots.default());
17014
+ },
17015
+ });
17016
+
17017
+ const CTableFoot = vue.defineComponent({
17018
+ name: 'CTableFoot',
17019
+ props: {
16641
17020
  /**
16642
- * Make any table responsive across all viewports or pick a maximum breakpoint with which to have a responsive table up to.
17021
+ * Sets the color context of the component to one of CoreUI’s themed colors.
16643
17022
  *
16644
- * @values boolean, 'sm', 'md', 'lg', 'xl', 'xxl'
17023
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light', string
16645
17024
  */
16646
- responsive: {
16647
- type: [Boolean, String],
16648
- default: undefined,
16649
- required: false,
16650
- validator: (value) => {
16651
- if (typeof value == 'string') {
16652
- return ['sm', 'md', 'lg', 'xl', 'xxl'].includes(value);
16653
- }
16654
- if (typeof value == 'boolean') {
16655
- return true;
16656
- }
16657
- return false;
16658
- },
16659
- },
16660
- /**
16661
- * Make table more compact by cutting all cell `padding` in half.
16662
- */
16663
- small: {
16664
- type: Boolean,
16665
- required: false,
16666
- },
16667
- /**
16668
- * Add zebra-striping to any table row within the `<CTableBody>`.
16669
- */
16670
- striped: {
16671
- type: Boolean,
16672
- required: false,
16673
- },
16674
- /**
16675
- * Add zebra-striping to any table column.
16676
- *
16677
- * @since 4.4.0
16678
- */
16679
- stripedColumns: {
16680
- type: Boolean,
16681
- required: false,
16682
- },
17025
+ color: Color,
16683
17026
  },
16684
- setup(props, { slots, attrs }) {
16685
- const table = () => vue.h('table', {
17027
+ setup(props, { slots }) {
17028
+ return () => vue.h('tfoot', {
16686
17029
  class: [
16687
- 'table',
16688
17030
  {
16689
- [`align-${props.align}`]: props.align,
16690
- [`caption-${props.caption}`]: props.caption,
16691
- [`border-${props.borderColor}`]: props.borderColor,
16692
- 'table-bordered': props.bordered,
16693
- 'table-borderless': props.borderless,
16694
17031
  [`table-${props.color}`]: props.color,
16695
- 'table-hover': props.hover,
16696
- 'table-sm': props.small,
16697
- 'table-striped': props.striped,
16698
- 'table-striped-columns': props.stripedColumns,
16699
17032
  },
16700
- attrs.class,
16701
17033
  ],
16702
17034
  }, slots.default && slots.default());
16703
- return () => [
16704
- props.responsive
16705
- ? vue.h('div', {
16706
- class: typeof props.responsive === 'boolean'
16707
- ? 'table-responsive'
16708
- : `table-responsive-${props.responsive}`,
16709
- }, table())
16710
- : table(),
16711
- ];
16712
17035
  },
16713
17036
  });
16714
17037
 
16715
- const CTableBody = vue.defineComponent({
16716
- name: 'CTableBody',
17038
+ const CTableHead = vue.defineComponent({
17039
+ name: 'CTableHead',
16717
17040
  props: {
16718
17041
  /**
16719
17042
  * Sets the color context of the component to one of CoreUI’s themed colors.
@@ -16723,7 +17046,7 @@ const CTableBody = vue.defineComponent({
16723
17046
  color: Color,
16724
17047
  },
16725
17048
  setup(props, { slots }) {
16726
- return () => vue.h('tbody', {
17049
+ return () => vue.h('thead', {
16727
17050
  class: [
16728
17051
  {
16729
17052
  [`table-${props.color}`]: props.color,
@@ -16733,19 +17056,32 @@ const CTableBody = vue.defineComponent({
16733
17056
  },
16734
17057
  });
16735
17058
 
16736
- const CTableCaption = vue.defineComponent({
16737
- name: 'CTableCaption',
16738
- props: {},
16739
- setup(_, { slots }) {
16740
- return () => vue.h('caption', {}, slots.default && slots.default());
17059
+ const CTableHeaderCell = vue.defineComponent({
17060
+ name: 'CTableHeaderCell',
17061
+ props: {
17062
+ /**
17063
+ * Sets the color context of the component to one of CoreUI’s themed colors.
17064
+ *
17065
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light', string
17066
+ */
17067
+ color: Color,
17068
+ },
17069
+ setup(props, { slots }) {
17070
+ return () => vue.h('th', {
17071
+ class: [
17072
+ {
17073
+ [`table-${props.color}`]: props.color,
17074
+ },
17075
+ ],
17076
+ }, slots.default && slots.default());
16741
17077
  },
16742
17078
  });
16743
17079
 
16744
- const CTableDataCell = vue.defineComponent({
16745
- name: 'CTableDataCell',
17080
+ const CTableRow = vue.defineComponent({
17081
+ name: 'CTableRow',
16746
17082
  props: {
16747
17083
  /**
16748
- * Highlight a table row or cell.
17084
+ * Highlight a table row or cell..
16749
17085
  */
16750
17086
  active: {
16751
17087
  type: Boolean,
@@ -16772,7 +17108,7 @@ const CTableDataCell = vue.defineComponent({
16772
17108
  color: Color,
16773
17109
  },
16774
17110
  setup(props, { slots }) {
16775
- return () => vue.h('td', {
17111
+ return () => vue.h('tr', {
16776
17112
  class: [
16777
17113
  {
16778
17114
  [`align-${props.align}`]: props.align,
@@ -16784,109 +17120,290 @@ const CTableDataCell = vue.defineComponent({
16784
17120
  },
16785
17121
  });
16786
17122
 
16787
- const CTableFoot = vue.defineComponent({
16788
- name: 'CTableFoot',
17123
+ const pretifyName = (name) => {
17124
+ return name
17125
+ .replace(/[-_.]/g, ' ')
17126
+ .replace(/ +/g, ' ')
17127
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
17128
+ .split(' ')
17129
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
17130
+ .join(' ');
17131
+ };
17132
+ const label = (column) => typeof column === 'object'
17133
+ ? column.label !== undefined
17134
+ ? column.label
17135
+ : pretifyName(column.key)
17136
+ : pretifyName(column);
17137
+ const CTable = vue.defineComponent({
17138
+ name: 'CTable',
16789
17139
  props: {
16790
17140
  /**
16791
- * Sets the color context of the component to one of CoreUI’s themed colors.
17141
+ * Set the vertical aligment.
16792
17142
  *
16793
- * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light', string
17143
+ * @values 'bottom', 'middle', 'top'
16794
17144
  */
16795
- color: Color,
16796
- },
16797
- setup(props, { slots }) {
16798
- return () => vue.h('tfoot', {
16799
- class: [
16800
- {
16801
- [`table-${props.color}`]: props.color,
16802
- },
16803
- ],
16804
- }, slots.default && slots.default());
16805
- },
16806
- });
16807
-
16808
- const CTableHead = vue.defineComponent({
16809
- name: 'CTableHead',
16810
- props: {
17145
+ align: {
17146
+ type: String,
17147
+ default: undefined,
17148
+ required: false,
17149
+ validator: (value) => {
17150
+ return ['bottom', 'middle', 'top'].includes(value);
17151
+ },
17152
+ },
16811
17153
  /**
16812
- * Sets the color context of the component to one of CoreUI’s themed colors.
17154
+ * Sets the border color of the component to one of CoreUI’s themed colors.
16813
17155
  *
16814
- * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light', string
17156
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
16815
17157
  */
16816
- color: Color,
16817
- },
16818
- setup(props, { slots }) {
16819
- return () => vue.h('thead', {
16820
- class: [
16821
- {
16822
- [`table-${props.color}`]: props.color,
16823
- },
16824
- ],
16825
- }, slots.default && slots.default());
16826
- },
16827
- });
16828
-
16829
- const CTableHeaderCell = vue.defineComponent({
16830
- name: 'CTableHeaderCell',
16831
- props: {
17158
+ borderColor: Color,
17159
+ /**
17160
+ * Add borders on all sides of the table and cells.
17161
+ */
17162
+ bordered: {
17163
+ type: Boolean,
17164
+ required: false,
17165
+ },
17166
+ /**
17167
+ * Remove borders on all sides of the table and cells.
17168
+ */
17169
+ borderless: {
17170
+ type: Boolean,
17171
+ required: false,
17172
+ },
17173
+ /**
17174
+ * Put the `<caption>` on the top of the table.
17175
+ *
17176
+ * @values 'top' | string
17177
+ */
17178
+ caption: {
17179
+ type: String,
17180
+ default: undefined,
17181
+ required: false,
17182
+ },
17183
+ /**
17184
+ * Set the text of the table caption and the caption on the top of the table.
17185
+ *
17186
+ * @since 4.5.0
17187
+ */
17188
+ captionTop: {
17189
+ type: String,
17190
+ default: undefined,
17191
+ required: false,
17192
+ },
17193
+ /**
17194
+ * Prop for table columns configuration. If prop is not defined, table will display columns based on the first item keys, omitting keys that begins with underscore (e.g. '_props')
17195
+ *
17196
+ * In columns prop each array item represents one column. Item might be specified in two ways:
17197
+ * String: each item define column name equal to item value.
17198
+ * Object: item is object with following keys available as column configuration:
17199
+ * - key (required)(String) - define column name equal to item key.
17200
+ * - label (String) - define visible label of column. If not defined, label will be generated automatically based on column name, by converting kebab-case and snake_case to individual words and capitalization of each word.
17201
+ * - _props (Object) - adds classes to all cels in column, ex. _props: { scope: 'col', className: 'custom-class' },
17202
+ * - _style (Object) - adds styles to the column header (useful for defining widths)
17203
+ *
17204
+ * @since 4.5.0
17205
+ */
17206
+ columns: {
17207
+ type: Array,
17208
+ required: false,
17209
+ },
16832
17210
  /**
16833
17211
  * Sets the color context of the component to one of CoreUI’s themed colors.
16834
17212
  *
16835
17213
  * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light', string
16836
17214
  */
16837
17215
  color: Color,
16838
- },
16839
- setup(props, { slots }) {
16840
- return () => vue.h('th', {
16841
- class: [
16842
- {
16843
- [`table-${props.color}`]: props.color,
16844
- },
16845
- ],
16846
- }, slots.default && slots.default());
16847
- },
16848
- });
16849
-
16850
- const CTableRow = vue.defineComponent({
16851
- name: 'CTableRow',
16852
- props: {
16853
17216
  /**
16854
- * Highlight a table row or cell..
17217
+ * Array of objects or strings, where each element represents one cell in the table footer.
17218
+ *
17219
+ * Example items:
17220
+ * ['FooterCell', 'FooterCell', 'FooterCell']
17221
+ * or
17222
+ * [{ label: 'FooterCell', _props: { color: 'success' }, ...]
17223
+ *
17224
+ * @since 4.5.0
16855
17225
  */
16856
- active: {
17226
+ footer: {
17227
+ type: Array,
17228
+ default: () => [],
17229
+ required: false,
17230
+ },
17231
+ /**
17232
+ * Enable a hover state on table rows within a `<CTableBody>`.
17233
+ */
17234
+ hover: {
16857
17235
  type: Boolean,
16858
17236
  required: false,
16859
17237
  },
16860
17238
  /**
16861
- * Set the vertical aligment.
17239
+ * Array of objects, where each object represents one item - row in table. Additionally, you can add style classes to each row by passing them by '_props' key and to single cell by '_cellProps'.
16862
17240
  *
16863
- * @values 'bottom', 'middle', 'top'
17241
+ * Example item:
17242
+ * { name: 'John' , age: 12, _props: { color: 'success' }, _cellProps: { age: { className: 'fw-bold'}}}
17243
+ *
17244
+ * @since 4.5.0
16864
17245
  */
16865
- align: {
16866
- type: String,
17246
+ items: {
17247
+ type: Array,
17248
+ default: () => [],
17249
+ required: false,
17250
+ },
17251
+ responsive: {
17252
+ type: [Boolean, String],
16867
17253
  default: undefined,
16868
17254
  required: false,
16869
17255
  validator: (value) => {
16870
- return ['bottom', 'middle', 'top'].includes(value);
17256
+ if (typeof value == 'string') {
17257
+ return ['sm', 'md', 'lg', 'xl', 'xxl'].includes(value);
17258
+ }
17259
+ if (typeof value == 'boolean') {
17260
+ return true;
17261
+ }
17262
+ return false;
16871
17263
  },
16872
17264
  },
16873
17265
  /**
16874
- * Sets the color context of the component to one of CoreUI’s themed colors.
17266
+ * Make table more compact by cutting all cell `padding` in half.
17267
+ */
17268
+ small: {
17269
+ type: Boolean,
17270
+ required: false,
17271
+ },
17272
+ /**
17273
+ * Add zebra-striping to any table row within the `<CTableBody>`.
17274
+ */
17275
+ striped: {
17276
+ type: Boolean,
17277
+ required: false,
17278
+ },
17279
+ /**
17280
+ * Add zebra-striping to any table column.
16875
17281
  *
16876
- * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light', string
17282
+ * @since 4.4.0
16877
17283
  */
16878
- color: Color,
17284
+ stripedColumns: {
17285
+ type: Boolean,
17286
+ required: false,
17287
+ },
17288
+ /**
17289
+ * Properties that will be passed to the table footer component.
17290
+ *
17291
+ * Properties to [CTableFoot](#ctablefoot) component.
17292
+ * @since 4.5.0
17293
+ */
17294
+ tableFootProps: {
17295
+ type: Object,
17296
+ default: undefined,
17297
+ required: false,
17298
+ },
17299
+ /**
17300
+ * Properties that will be passed to the table head component.
17301
+ *
17302
+ * Properties to [CTableHead](#ctablehead) component.
17303
+ * @since 4.5.0
17304
+ */
17305
+ tableHeadProps: {
17306
+ type: Object,
17307
+ default: undefined,
17308
+ required: false,
17309
+ },
16879
17310
  },
16880
- setup(props, { slots }) {
16881
- return () => vue.h('tr', {
17311
+ setup(props, { slots, attrs }) {
17312
+ const rawColumnNames = vue.computed(() => props.columns
17313
+ ? props.columns.map((column) => {
17314
+ if (typeof column === 'object')
17315
+ return column.key;
17316
+ else
17317
+ return column;
17318
+ })
17319
+ : Object.keys(props.items[0] || {}).filter((el) => el.charAt(0) !== '_'));
17320
+ const table = () => vue.h('table', {
16882
17321
  class: [
17322
+ 'table',
16883
17323
  {
16884
17324
  [`align-${props.align}`]: props.align,
16885
- 'table-active': props.active,
17325
+ [`caption-top`]: props.captionTop || props.caption === 'top',
17326
+ [`border-${props.borderColor}`]: props.borderColor,
17327
+ 'table-bordered': props.bordered,
17328
+ 'table-borderless': props.borderless,
16886
17329
  [`table-${props.color}`]: props.color,
17330
+ 'table-hover': props.hover,
17331
+ 'table-sm': props.small,
17332
+ 'table-striped': props.striped,
17333
+ 'table-striped-columns': props.stripedColumns,
16887
17334
  },
17335
+ attrs.class,
16888
17336
  ],
16889
- }, slots.default && slots.default());
17337
+ }, {
17338
+ default: () => [
17339
+ ((props.caption && props.caption !== 'top') || props.captionTop) &&
17340
+ vue.h(CTableCaption, {}, {
17341
+ default: () => props.caption || props.captionTop,
17342
+ }),
17343
+ props.columns &&
17344
+ vue.h(CTableHead, {
17345
+ ...props.tableHeadProps,
17346
+ }, {
17347
+ default: () => vue.h(CTableRow, {}, {
17348
+ default: () => [
17349
+ props.columns &&
17350
+ props.columns.map((column) => vue.h(CTableHeaderCell, {
17351
+ ...(typeof column === 'object' &&
17352
+ column._props && { ...column._props }),
17353
+ ...(typeof column === 'object' &&
17354
+ column._style && { style: { ...column._style } }),
17355
+ }, {
17356
+ default: () => label(column),
17357
+ })),
17358
+ ],
17359
+ }),
17360
+ }),
17361
+ props.items &&
17362
+ vue.h(CTableBody, {}, {
17363
+ default: () => [
17364
+ props.items.map((item) => vue.h(CTableRow, {
17365
+ ...(item._props && { ...item._props }),
17366
+ }, {
17367
+ default: () => [
17368
+ rawColumnNames.value.map((colName) => item[colName] &&
17369
+ vue.h(CTableDataCell, {
17370
+ ...(item._cellProps &&
17371
+ item._cellProps['all'] && { ...item._cellProps['all'] }),
17372
+ ...(item._cellProps &&
17373
+ item._cellProps[colName] && { ...item._cellProps[colName] }),
17374
+ }, {
17375
+ default: () => item[colName],
17376
+ })),
17377
+ ],
17378
+ })),
17379
+ ],
17380
+ }),
17381
+ slots.default && slots.default(),
17382
+ props.footer &&
17383
+ vue.h(CTableFoot, {
17384
+ ...props.tableFootProps,
17385
+ }, {
17386
+ default: () => vue.h(CTableRow, {}, {
17387
+ default: () => [
17388
+ props.footer.map((item) => vue.h(CTableDataCell, {
17389
+ ...(typeof item === 'object' && item._props && { ...item._props }),
17390
+ }, {
17391
+ default: () => (typeof item === 'object' ? item.label : item),
17392
+ })),
17393
+ ],
17394
+ }),
17395
+ }),
17396
+ ],
17397
+ });
17398
+ return () => [
17399
+ props.responsive
17400
+ ? vue.h('div', {
17401
+ class: typeof props.responsive === 'boolean'
17402
+ ? 'table-responsive'
17403
+ : `table-responsive-${props.responsive}`,
17404
+ }, table())
17405
+ : table(),
17406
+ ];
16890
17407
  },
16891
17408
  });
16892
17409
 
@@ -17052,6 +17569,11 @@ const CSmartTableHead = vue.defineComponent({
17052
17569
  default: () => [],
17053
17570
  required: false,
17054
17571
  },
17572
+ items: {
17573
+ type: Array,
17574
+ default: () => [],
17575
+ required: false,
17576
+ },
17055
17577
  selectable: Boolean,
17056
17578
  selectAll: [Boolean, String],
17057
17579
  sorterState: {
@@ -17060,7 +17582,7 @@ const CSmartTableHead = vue.defineComponent({
17060
17582
  require: false,
17061
17583
  },
17062
17584
  },
17063
- emits: ['filterInput', 'filterChange', 'selectAllChecked', 'sortClick'],
17585
+ emits: ['customFilterChange', 'filterInput', 'filterChange', 'selectAllChecked', 'sortClick'],
17064
17586
  setup(props, { slots, emit }) {
17065
17587
  const handleSortClick = (key, index) => {
17066
17588
  emit('sortClick', key, index);
@@ -17107,6 +17629,9 @@ const CSmartTableHead = vue.defineComponent({
17107
17629
  }
17108
17630
  return 0;
17109
17631
  };
17632
+ const getValues = (items, key) => {
17633
+ return items.map((a) => a[key]);
17634
+ };
17110
17635
  const columnSorterIcon = (column) => {
17111
17636
  if (getColumnSorterState(key(column)) === 0) {
17112
17637
  return vue.h('span', { class: 'opacity-25 float-end me-1' }, slots.sortingIcon && slots.sortingIcon());
@@ -17119,6 +17644,9 @@ const CSmartTableHead = vue.defineComponent({
17119
17644
  }
17120
17645
  return;
17121
17646
  };
17647
+ const handleOnCustomFilterChange = (key, value) => {
17648
+ emit('customFilterChange', key, value);
17649
+ };
17122
17650
  const handleFilterInput = (key, value) => {
17123
17651
  emit('filterInput', key, value);
17124
17652
  };
@@ -17169,17 +17697,20 @@ const CSmartTableHead = vue.defineComponent({
17169
17697
  ? true
17170
17698
  : typeof column.filter === 'undefined'
17171
17699
  ? true
17172
- : column.filter) &&
17173
- vue.h(CFormInput, {
17174
- size: 'sm',
17175
- onInput: (event) => handleFilterInput(key(column), event.target.value),
17176
- onChange: (event) => handleFilterChange(key(column), event.target.value),
17177
- 'aria-label': `column name: '${label(column)}' filter input`,
17178
- ...(props.columnFilterValue &&
17179
- props.columnFilterValue[key(column)] && {
17180
- value: props.columnFilterValue[key(column)],
17181
- }),
17182
- }),
17700
+ : column.filter)
17701
+ ? typeof column !== 'string' && typeof column.filter === 'function'
17702
+ ? column.filter(getValues(props.items, key(column)), (value) => handleOnCustomFilterChange(key(column), value))
17703
+ : vue.h(CFormInput, {
17704
+ size: 'sm',
17705
+ onInput: (event) => handleFilterInput(key(column), event.target.value),
17706
+ onChange: (event) => handleFilterChange(key(column), event.target.value),
17707
+ 'aria-label': `column name: '${label(column)}' filter input`,
17708
+ ...(props.columnFilterValue &&
17709
+ props.columnFilterValue[key(column)] && {
17710
+ value: props.columnFilterValue[key(column)],
17711
+ }),
17712
+ })
17713
+ : '',
17183
17714
  })),
17184
17715
  ],
17185
17716
  }),
@@ -17300,7 +17831,7 @@ const CSmartTableItemsPerPageSelector = vue.defineComponent({
17300
17831
  vue.h('div', {
17301
17832
  class: 'col-auto',
17302
17833
  }, vue.h(CFormSelect, {
17303
- defaultValue: props.itemsPerPage,
17834
+ value: props.itemsPerPage,
17304
17835
  onChange: handleChange,
17305
17836
  }, {
17306
17837
  default: () => props.itemsPerPageOptions &&
@@ -17792,6 +18323,7 @@ const CSmartTable = vue.defineComponent({
17792
18323
  }
17793
18324
  });
17794
18325
  // functions
18326
+ const isLazy = (columnFilter) => columnFilter && typeof columnFilter === 'object' && columnFilter.lazy === true;
17795
18327
  const isSortable = (i) => {
17796
18328
  const isDataColumn = itemsDataColumns.value.includes(rawColumnNames.value[i]);
17797
18329
  let column;
@@ -17863,10 +18395,8 @@ const CSmartTable = vue.defineComponent({
17863
18395
  });
17864
18396
  };
17865
18397
  const columnFilterChange = (colName, value, type) => {
17866
- const isLazy = props.columnFilter &&
17867
- typeof props.columnFilter === 'object' &&
17868
- props.columnFilter.lazy === true;
17869
- if ((isLazy && type === 'input') || (!isLazy && type === 'change')) {
18398
+ const _isLazy = isLazy(props.columnFilter);
18399
+ if ((_isLazy && type === 'input') || (!_isLazy && type === 'change')) {
17870
18400
  return;
17871
18401
  }
17872
18402
  activePage.value = 1;
@@ -17874,10 +18404,8 @@ const CSmartTable = vue.defineComponent({
17874
18404
  emit('columnFilterChange', columnFilterState.value);
17875
18405
  };
17876
18406
  const tableFilterChange = (value, type) => {
17877
- const isLazy = props.columnFilter &&
17878
- typeof props.columnFilter === 'object' &&
17879
- props.columnFilter.lazy === true;
17880
- if ((isLazy && type === 'input') || (!isLazy && type === 'change')) {
18407
+ const _isLazy = isLazy(props.columnFilter);
18408
+ if ((_isLazy && type === 'input') || (!_isLazy && type === 'change')) {
17881
18409
  return;
17882
18410
  }
17883
18411
  activePage.value = 1;
@@ -17902,7 +18430,7 @@ const CSmartTable = vue.defineComponent({
17902
18430
  : genCols.value); //! || el
17903
18431
  const itemsDataColumns = vue.computed(() => rawColumnNames.value.filter((name) => genCols.value.includes(name)));
17904
18432
  // variables
17905
- const columnFiltered = () => {
18433
+ const filteredColumns = vue.computed(() => {
17906
18434
  let _items = items.value;
17907
18435
  if (props.columnFilter &&
17908
18436
  typeof props.columnFilter === 'object' &&
@@ -17910,6 +18438,10 @@ const CSmartTable = vue.defineComponent({
17910
18438
  return _items;
17911
18439
  }
17912
18440
  Object.entries(columnFilterState.value).forEach(([key, value]) => {
18441
+ if (value instanceof Function) {
18442
+ _items = _items.filter((item) => value(item[key]));
18443
+ return;
18444
+ }
17913
18445
  const columnFilter = String(value).toLowerCase();
17914
18446
  if (columnFilter && itemsDataColumns.value.includes(key)) {
17915
18447
  _items = _items.filter((item) => {
@@ -17918,9 +18450,9 @@ const CSmartTable = vue.defineComponent({
17918
18450
  }
17919
18451
  });
17920
18452
  return _items;
17921
- };
17922
- const tableFiltered = vue.computed(() => {
17923
- let items = columnFiltered();
18453
+ });
18454
+ const filteredTable = vue.computed(() => {
18455
+ let items = filteredColumns.value;
17924
18456
  if (!tableFilterState.value ||
17925
18457
  (props.tableFilter && typeof props.tableFilter === 'object' && props.tableFilter.external)) {
17926
18458
  return items;
@@ -17940,12 +18472,12 @@ const CSmartTable = vue.defineComponent({
17940
18472
  (props.columnSorter &&
17941
18473
  typeof props.columnSorter === 'object' &&
17942
18474
  props.columnSorter.external)) {
17943
- return tableFiltered.value;
18475
+ return filteredTable.value;
17944
18476
  }
17945
18477
  //if values in column are to be sorted by numeric value they all have to be type number
17946
18478
  // const flip = sorterState.asc ? 1 : -1
17947
18479
  const flip = sorterState.state === 'asc' ? 1 : sorterState.state === 'desc' ? -1 : 0;
17948
- const sorted = tableFiltered.value.slice().sort((item, item2) => {
18480
+ const sorted = filteredTable.value.slice().sort((item, item2) => {
17949
18481
  const value = item[col];
17950
18482
  const value2 = item2[col];
17951
18483
  const a = typeof value === 'number' ? value : String(value).toLowerCase();
@@ -18008,9 +18540,11 @@ const CSmartTable = vue.defineComponent({
18008
18540
  columnFilterValue: columnFilterState.value,
18009
18541
  columns: props.columns ? props.columns : rawColumnNames.value,
18010
18542
  columnSorter: props.columnSorter,
18543
+ items: items.value,
18011
18544
  selectable: props.selectable,
18012
18545
  selectAll: selectedAll.value,
18013
18546
  sorterState: sorterState,
18547
+ onCustomFilterChange: (key, value) => columnFilterChange(key, value),
18014
18548
  onFilterInput: (key, value) => columnFilterChange(key, value, 'input'),
18015
18549
  onFilterChange: (key, value) => columnFilterChange(key, value, 'change'),
18016
18550
  onSelectAllChecked: () => handleSelectAllChecked(),
@@ -18070,8 +18604,6 @@ const CSmartTable = vue.defineComponent({
18070
18604
  columns: props.columns ? props.columns : rawColumnNames.value,
18071
18605
  selectable: props.selectable,
18072
18606
  selectAll: selectedAll.value,
18073
- onFilterInput: (key, value) => columnFilterChange(key, value, 'input'),
18074
- onFilterChange: (key, value) => columnFilterChange(key, value, 'change'),
18075
18607
  onSelectAllChecked: () => handleSelectAllChecked(),
18076
18608
  }),
18077
18609
  ],