@carbon/vue 3.0.13 → 3.0.15

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 (50) hide show
  1. package/README.md +9 -0
  2. package/dist/carbon-vue-3.common.js +884 -324
  3. package/dist/carbon-vue-3.common.js.map +1 -1
  4. package/dist/carbon-vue-3.umd.js +884 -324
  5. package/dist/carbon-vue-3.umd.js.map +1 -1
  6. package/dist/carbon-vue-3.umd.min.js +4 -4
  7. package/dist/carbon-vue-3.umd.min.js.map +1 -1
  8. package/dist/web-types.json +30 -3
  9. package/package.json +8 -5
  10. package/src/components/CvAccordion/CvAccordion.stories.mdx +11 -2
  11. package/src/components/CvAccordion/CvAccordionItem.vue +1 -1
  12. package/src/components/CvBreadcrumb/CvBreadcrumb.vue +1 -0
  13. package/src/components/CvBreadcrumb/CvBreadcrumbItem.vue +1 -0
  14. package/src/components/CvButton/CvButton.vue +1 -0
  15. package/src/components/CvButton/CvButtonSet.vue +1 -0
  16. package/src/components/CvButton/CvIconButton.vue +2 -1
  17. package/src/components/CvCheckbox/CvCheckbox.vue +2 -1
  18. package/src/components/CvCodeSnippet/CvCodeSnippet.vue +8 -3
  19. package/src/components/CvCodeSnippet/_CviCodeSnippetInline.vue +1 -0
  20. package/src/components/CvCodeSnippet/_CviCodeSnippetMultiline.vue +1 -0
  21. package/src/components/CvCodeSnippet/_CviCodeSnippetOneline.vue +1 -0
  22. package/src/components/CvComboBox/CvComboBox.vue +2 -1
  23. package/src/components/CvDataTable/CvDataTable.stories.mdx +26 -49
  24. package/src/components/CvDataTable/CvDataTable.vue +71 -52
  25. package/src/components/CvDataTable/CvDataTableRow.vue +11 -3
  26. package/src/components/CvDataTable/_CvDataTableRowInner.vue +18 -8
  27. package/src/components/CvDataTable/cvDataTableStore.js +1 -27
  28. package/src/components/CvDatePicker/CvDatePicker.stories.js +30 -6
  29. package/src/components/CvDatePicker/CvDatePicker.vue +24 -19
  30. package/src/components/CvDropdown/CvDropdown.stories.mdx +12 -2
  31. package/src/components/CvDropdown/CvDropdown.vue +4 -3
  32. package/src/components/CvFileUploader/CvFileUploader.vue +2 -2
  33. package/src/components/CvList/CvList.vue +1 -0
  34. package/src/components/CvList/CvListItem.vue +1 -1
  35. package/src/components/CvNotification/CvInlineNotification.vue +1 -0
  36. package/src/components/CvNotification/CvToastNotification.stories.js +65 -5
  37. package/src/components/CvNotification/CvToastNotification.vue +1 -0
  38. package/src/components/CvNotification/CvToastNotificationTemplate.mdx +17 -0
  39. package/src/components/CvNumberInput/CvNumberInput.vue +3 -3
  40. package/src/components/CvOverflowMenu/CvOverflowMenuItem.vue +2 -2
  41. package/src/components/CvPagination/CvPagination.stories.mdx +22 -15
  42. package/src/components/CvPagination/CvPagination.vue +16 -1
  43. package/src/components/CvProgress/CvProgress.stories.mdx +29 -7
  44. package/src/components/CvProgress/CvProgress.vue +1 -0
  45. package/src/components/CvProgress/CvProgressStep.vue +2 -0
  46. package/src/components/CvSlider/CvSlider.vue +1 -1
  47. package/src/components/CvTag/CvTag.stories.js +0 -2
  48. package/src/components/CvTag/CvTag.vue +6 -4
  49. package/src/index.js +112 -0
  50. package/telemetry.yml +8 -0
@@ -132,7 +132,7 @@
132
132
  <thead>
133
133
  <tr>
134
134
  <th
135
- v-if="hasExpandables"
135
+ v-if="hasExpandingRows"
136
136
  :class="`${carbonPrefix}--table-expand`"
137
137
  :data-previous-value="
138
138
  dataExpandAll ? 'collapsed' : 'expanded'
@@ -157,7 +157,9 @@
157
157
  v-if="hasBatchActions"
158
158
  :class="`${carbonPrefix}--table-column-checkbox`"
159
159
  >
160
+ <cv-checkbox-skeleton v-if="isSkeleton" />
160
161
  <cv-checkbox
162
+ v-else
161
163
  v-model="headingChecked"
162
164
  :form-item="false"
163
165
  value="headingCheck"
@@ -181,7 +183,7 @@
181
183
  </tr>
182
184
  </thead>
183
185
 
184
- <component :is="hasExpandables ? Empty : 'tbody'">
186
+ <component :is="hasExpandingRows ? Empty : 'tbody'">
185
187
  <slot name="data">
186
188
  <cv-data-table-row
187
189
  v-for="(row, rowIndex) in data"
@@ -229,7 +231,7 @@ import CvDataTableHeading from './CvDataTableHeading.vue';
229
231
  import CvDataTableRow from './CvDataTableRow.vue';
230
232
  import CvDataTableCell from './CvDataTableCell.vue';
231
233
  import CvButton from '../CvButton';
232
- import CvCheckbox from '../CvCheckbox';
234
+ import { CvCheckbox, CvCheckboxSkeleton } from '../CvCheckbox';
233
235
  import CvPagination from '../CvPagination';
234
236
  import Search16 from '@carbon/icons-vue/es/search/16';
235
237
  import Close16 from '@carbon/icons-vue/es/close/16';
@@ -246,43 +248,39 @@ import {
246
248
  unref,
247
249
  useSlots,
248
250
  watch,
251
+ provide,
249
252
  } from 'vue';
250
253
  import { props as propsCvId, useCvId } from '../../use/cvId';
254
+ //TODO: Remove this store and replace with provide/inject
251
255
  import store from './cvDataTableStore';
252
256
  import Empty from '../CvEmpty/_CvEmpty.vue';
253
257
 
254
258
  const props = defineProps({
259
+ /** Arial label for the action bar. */
255
260
  actionBarAriaLabel: { type: String, default: 'Table Action Bar' },
261
+ /** Arial label for the "collapse all" button in tables with expandable rows". */
256
262
  collapseAllAriaLabel: { type: String, default: 'Collapse all rows' },
263
+ /** Arial label for the "expand all" button in tables with expandable rows". */
257
264
  expandAllAriaLabel: { type: String, default: 'Expand all rows' },
265
+ /** Arial label for the "select all" button in tables with selectable rows". */
258
266
  selectAllAriaLabel: { type: String, default: 'Select all rows' },
259
- /**
260
- * Table will size use auto sizing
261
- */
267
+ /** Table will size use auto sizing */
262
268
  autoWidth: { type: Boolean, default: false },
263
- /**
264
- * Label for the button to cancel batch actions
265
- */
269
+ /** Label for the button to cancel batch actions */
266
270
  batchCancelLabel: { type: String, default: 'Cancel' },
267
- /**
268
- * Table will have no border
269
- */
271
+ /** Table will have no border */
270
272
  borderless: { type: Boolean, default: false },
271
273
  /**
272
274
  * An array of overflow menu labels. On click CvDataTable will raise an 'overflow-menu-click' event passing an object containing menuIndex, menuLabel and rowValue
273
275
  * - As part of the array pass an object containing props for the overflowMenu. E.g. { label: 'Overflow menu', tipAlignment: 'end', tipPosition: 'top' },
274
276
  */
275
277
  overflowMenu: { type: [Boolean, Array], default: () => [] },
276
- /**
277
- * can be set to true or an object containing camel case props for a CvPagination component
278
- */
278
+ /** can be set to true or an object containing camel case props for a CvPagination component */
279
279
  pagination: {
280
280
  type: [Boolean, Object],
281
281
  default: false,
282
282
  },
283
- /**
284
- * 'compact', 'small', or 'tall'
285
- */
283
+ /** 'compact', 'small', or 'tall' */
286
284
  rowSize: {
287
285
  type: String,
288
286
  default: 'lg',
@@ -308,14 +306,12 @@ const props = defineProps({
308
306
  searchLabel: { type: String, default: 'Search' },
309
307
  searchPlaceholder: { type: String, default: 'Search' },
310
308
  searchClearLabel: { type: String, default: 'Clear search' },
311
- /**
312
- * Set text in search bar on table generation
313
- */
309
+ /** Set text in search bar on table generation */
314
310
  initialSearchValue: { type: String, default: '' },
315
- /**
316
- * can be sorted
317
- */
311
+ /** can be sorted */
318
312
  sortable: { type: Boolean, default: false },
313
+ /** Table will have expandable rows */
314
+ expandable: { type: Boolean, default: false },
319
315
  title: { type: String, default: undefined },
320
316
  /**
321
317
  * An array containing a list of columns
@@ -327,35 +323,39 @@ const props = defineProps({
327
323
  * - Optionally a sortable property - if any column sets this to true then only columns with sortable set to true are sortable. NOTE: table sortable property not required.
328
324
  */
329
325
  columns: { type: Array, default: () => [] },
330
- /**
331
- * Two-dimensional array of strings.
332
- */
326
+ /** Two-dimensional array of strings. */
333
327
  data: { type: Array, default: () => [] },
334
- /**
335
- * the table striped
336
- */
328
+ /** `true` to use Zebra style striping. */
337
329
  zebra: { type: Boolean, default: false },
338
- /**
339
- * Specify whether the header should be sticky. Still experimental: may not work with every combination of table props.
340
- */
330
+ /** Specify whether the header should be sticky. Still experimental: may not work with every combination of table props. */
341
331
  stickyHeader: { type: Boolean, default: false },
342
- /**
343
- * An array containing the selected row values. Supports v-model via the row-select-changes event.
344
- */
332
+ /** An array containing the selected row values. Supports v-model via the row-select-changes event. */
345
333
  rowsSelected: { type: Array, default: () => [] },
334
+ /** Normally batch actions are hidden if no items are selected. Set this to true to always show batch actions */
335
+ stickyBatchActive: { type: Boolean, default: false },
336
+ /** subtext on the table */
346
337
  helperText: { type: String, default: undefined },
338
+ /** Animate the search bar opening */
347
339
  expandingSearch: { type: Boolean, default: true },
340
+ /** Show table loading / skeleton state */
348
341
  skeleton: { type: Boolean, default: false },
342
+ /** Should the expand all button be available */
349
343
  hasExpandAll: { type: Boolean, default: false },
350
- /**
351
- * Use a width of 'auto' instead of 100%
352
- */
344
+ /** Use a width of 'auto' instead of 100% */
353
345
  staticWidth: { type: Boolean, default: false },
346
+ /** User defined search action */
354
347
  onSearch: { type: Function, default: undefined },
355
348
  ...propsCvId,
356
349
  });
357
350
  const uid = useCvId(props, true);
358
351
 
352
+ const isSkeleton = ref(props.skeleton);
353
+ provide('is-skeleton', isSkeleton);
354
+ watch(
355
+ () => props.skeleton,
356
+ () => (isSkeleton.value = props.skeleton)
357
+ );
358
+
359
359
  let bus = undefined;
360
360
  onBeforeMount(() => {
361
361
  bus = getBus(uid.value);
@@ -375,6 +375,25 @@ watch(() => props.rowsSelected, updateRowsSelected);
375
375
  const searchContainer = ref(null);
376
376
  const magnifier = ref(null);
377
377
  const search = ref(null);
378
+
379
+ /** @type {Ref<Set<String>>} */
380
+ const expandingRowIds = ref(new Set());
381
+ const hasExpandingRows = computed(() => {
382
+ return expandingRowIds.value.size > 0;
383
+ });
384
+ provide('expanding-row-ids', expandingRowIds);
385
+ provide('has-expanding-rows', hasExpandingRows);
386
+ onMounted(() => {
387
+ if (props.expandable) expandingRowIds.value.add('table-expand-row');
388
+ });
389
+ watch(
390
+ () => props.expandable,
391
+ () => {
392
+ if (props.expandable) expandingRowIds.value.add('table-expand-row');
393
+ else expandingRowIds.value.delete('table-expand-row');
394
+ }
395
+ );
396
+
378
397
  onMounted(() => {
379
398
  if (searchContainer.value) {
380
399
  magnifier.value?.addEventListener('blur', checkSearchFocus);
@@ -382,7 +401,6 @@ onMounted(() => {
382
401
  }
383
402
  if (props.initialSearchValue) clearSearchVisible.value = true;
384
403
  updateRowsSelected();
385
- store.setSomeExpandingRows(uid);
386
404
  });
387
405
 
388
406
  onUnmounted(() => {
@@ -397,12 +415,12 @@ onUpdated(checkSlots);
397
415
 
398
416
  const hasActions = ref(false);
399
417
  const hasToolbar = ref(false);
400
- const hasBatchActions = computed(() => {
401
- return store.hasBatchActions(uid);
402
- });
418
+ const hasBatchActions = ref(false);
419
+ provide('has-batch-actions', hasBatchActions);
420
+
403
421
  function checkSlots() {
404
422
  // NOTE: slots is not reactive so needs to be managed on updated
405
- store.setBatchActions(uid, !!slots['batch-actions']);
423
+ hasBatchActions.value = !!slots['batch-actions'];
406
424
  hasActions.value = !!slots.actions;
407
425
  hasToolbar.value = !!(
408
426
  slots.actions ||
@@ -428,6 +446,7 @@ const isSortable = computed(() => {
428
446
  // is any column sortable
429
447
  return props.sortable || store.someSortableHeadings(uid.value);
430
448
  });
449
+
431
450
  function isColSortable(c) {
432
451
  const col = unref(c);
433
452
  // is specific column or all sortable
@@ -439,10 +458,6 @@ const hasTableHeader = computed(() => {
439
458
  return props.title || isHelper.value;
440
459
  });
441
460
 
442
- const hasExpandables = computed(() => {
443
- return store.someExpandingRows(uid);
444
- });
445
-
446
461
  const hasOverflowMenu = computed(() => {
447
462
  return (
448
463
  props.overflowMenu === true ||
@@ -512,7 +527,14 @@ function checkSearchExpand(force) {
512
527
  }
513
528
 
514
529
  const dataRowsSelected = ref(props.rowsSelected);
515
- const batchActive = ref(false);
530
+ const batchActive = computed(() => {
531
+ return (
532
+ props.stickyBatchActive ||
533
+ dataRowsSelected.value.length > 0 ||
534
+ headingChecked.value
535
+ );
536
+ });
537
+
516
538
  const headingChecked = ref(false);
517
539
 
518
540
  watch(
@@ -536,7 +558,6 @@ function updateRowsSelected() {
536
558
  }
537
559
  }
538
560
  headingChecked.value = dataRowsSelected.value.length === rows.length;
539
- batchActive.value = dataRowsSelected.value.length > 0;
540
561
  }
541
562
 
542
563
  const emit = defineEmits([
@@ -562,7 +583,6 @@ function onClearClick() {
562
583
  }
563
584
  function onHeadingCheckChange() {
564
585
  // check /uncheck all children
565
- batchActive.value = headingChecked.value;
566
586
  dataRowsSelected.value = [];
567
587
  const rows = store.rows(uid);
568
588
  for (const child of rows) {
@@ -598,7 +618,6 @@ function onRowCheckChange(payload) {
598
618
  dataRowsSelected.value = Array.from(modelSet);
599
619
  const rows = store.rows(uid);
600
620
  headingChecked.value = dataRowsSelected.value.length === rows.length;
601
- batchActive.value = dataRowsSelected.value.length > 0;
602
621
 
603
622
  emit('row-select-change', { value, selected: checked });
604
623
  emit('row-select-changes', dataRowsSelected.value);
@@ -53,6 +53,7 @@ import {
53
53
  useAttrs,
54
54
  useSlots,
55
55
  watch,
56
+ inject,
56
57
  } from 'vue';
57
58
  import store from './cvDataTableStore';
58
59
  import { getBus } from '../../global/component-utils/event-bus';
@@ -63,7 +64,16 @@ const props = defineProps({
63
64
  });
64
65
  const cvId = useCvId(props, true);
65
66
 
67
+ /** @type {Ref<Set<String>>} */
68
+ const expandingRowIds = inject('expanding-row-ids', ref(new Set()));
66
69
  const dataExpandable = ref(false);
70
+ watch(dataExpandable, () => {
71
+ if (dataExpandable.value) expandingRowIds.value?.add(cvId.value);
72
+ else expandingRowIds.value?.delete(cvId.value);
73
+ });
74
+ const dataSomeExpandingRows = computed(() => {
75
+ return expandingRowIds.value?.size > 0;
76
+ });
67
77
 
68
78
  const attrs = useAttrs();
69
79
  const slots = useSlots();
@@ -118,9 +128,7 @@ watch(
118
128
  });
119
129
  }
120
130
  );
121
- const dataSomeExpandingRows = computed(() => {
122
- return store.someExpandingRows(parent);
123
- });
131
+
124
132
  function onExpandedChange(val) {
125
133
  const row = store.findRow(parent, cvId);
126
134
  store.updateRow(parent, {
@@ -21,13 +21,14 @@
21
21
  >
22
22
  <ChevronRight16 :class="`${carbonPrefix}--table-expand__svg`" />
23
23
  </button>
24
- <div v-else>{{ expandingRow }}</div>
25
24
  </td>
26
25
  <td
27
26
  v-if="hasBatchActions"
28
27
  :class="`${carbonPrefix}--table-column-checkbox`"
29
28
  >
29
+ <cv-checkbox-skeleton v-if="isSkeleton" />
30
30
  <cv-checkbox
31
+ v-else
31
32
  ref="rowChecked"
32
33
  v-model="dataChecked"
33
34
  :form-item="false"
@@ -36,7 +37,7 @@
36
37
  :label="
37
38
  ariaLabelForBatchCheckbox || `Select row ${value} for batch action`
38
39
  "
39
- hide-label
40
+ :hide-label="true"
40
41
  @change="onChange"
41
42
  />
42
43
  </td>
@@ -62,11 +63,19 @@
62
63
 
63
64
  <script setup>
64
65
  import { carbonPrefix } from '../../global/settings';
65
- import CvCheckbox from '../CvCheckbox';
66
+ import { CvCheckbox, CvCheckboxSkeleton } from '../CvCheckbox';
66
67
  import CvOverflowMenu from '../CvOverflowMenu';
67
68
  import CvOverflowMenuItem from '../CvOverflowMenu/CvOverflowMenuItem.vue';
68
69
  import ChevronRight16 from '@carbon/icons-vue/es/chevron--right/16';
69
- import { computed, onMounted, onUpdated, ref, useSlots, watch } from 'vue';
70
+ import {
71
+ computed,
72
+ onMounted,
73
+ onUpdated,
74
+ ref,
75
+ useSlots,
76
+ watch,
77
+ inject,
78
+ } from 'vue';
70
79
  import store from './cvDataTableStore';
71
80
  import { getBus } from '../../global/component-utils/event-bus';
72
81
 
@@ -82,8 +91,11 @@ const props = defineProps({
82
91
  rowId: { type: String, default: undefined },
83
92
  });
84
93
 
94
+ const isSkeleton = inject('is-skeleton', ref(false));
95
+ /** @type {Ref<UnwrapRef<Set<>>>} */
96
+ const expandingRowIds = inject('expanding-row-ids', ref(new Set()));
85
97
  const dataSomeExpandingRows = computed(() => {
86
- return store.someExpandingRows(parent);
98
+ return expandingRowIds.value.size > 0;
87
99
  });
88
100
 
89
101
  const overflowMenuButtons = computed(() => {
@@ -123,9 +135,7 @@ onMounted(() => {
123
135
  bus = getBus(parent);
124
136
  } else console.warn('data table not found');
125
137
  });
126
- const hasBatchActions = computed(() => {
127
- return store.hasBatchActions(parent);
128
- });
138
+ const hasBatchActions = inject('has-batch-actions', ref(false));
129
139
 
130
140
  function onMenuItemClick(val) {
131
141
  bus.emit('cv:click', val);
@@ -1,3 +1,4 @@
1
+ //TODO: Remove this store and replace with provide/inject
1
2
  import { reactive, unref } from 'vue';
2
3
  let loggerEnabled = false;
3
4
  try {
@@ -82,7 +83,6 @@ const logger = loggerEnabled ? console.debug : () => {};
82
83
  * @typedef {Object} CvTableData
83
84
  * @property {Array<CvRowData>} rows - table row data
84
85
  * @property {Array<CvHeadingData>} headings - table heading data
85
- * @property {boolean} hasBatchActions - Batch actions are available
86
86
  * @property {boolean} hasExpandable - At least some rows are expandable
87
87
  */
88
88
 
@@ -97,7 +97,6 @@ export default reactive({
97
97
  this.state[table] = {
98
98
  rows: [],
99
99
  headings: [],
100
- hasBatchActions: false,
101
100
  hasExpandable: false,
102
101
  };
103
102
  logger(`added table:${table}`);
@@ -121,31 +120,6 @@ export default reactive({
121
120
  if (!this.state[table]) this.addTable(table);
122
121
  return this.state[table];
123
122
  },
124
- /**
125
- * Does the table have batch actions
126
- * @param {CvTableDataString} tableId
127
- * @returns {boolean|undefined}
128
- */
129
- hasBatchActions(tableId) {
130
- const table = unref(tableId);
131
- if (!this.state[table]) return;
132
- const hasBatchActions = this.state[table]?.hasBatchActions;
133
- logger(`get hasBatchActions:${table} result:${hasBatchActions}`);
134
- return hasBatchActions;
135
- },
136
- /**
137
- * Set if the table has batch actions or not
138
- * @param {CvTableDataString} tableId
139
- * @param {boolean} val
140
- */
141
- setBatchActions(tableId, val) {
142
- const table = unref(tableId);
143
- if (!this.state[table]) return;
144
- if (this.state[table].hasBatchActions !== val) {
145
- this.state[table].hasBatchActions = val;
146
- logger(`setBatchActions:${table} payload:${val}`);
147
- }
148
- },
149
123
  /**
150
124
  * Find a heading by table + heading id
151
125
  * @param {CvTableDataString} tableId
@@ -237,11 +237,36 @@ SingleUsingDate.parameters = storyParametersObject(
237
237
  );
238
238
 
239
239
  /* SINGLE USING MIN MAX PARAMS STORY */
240
-
240
+ const DATE_SHORT = 'm/d/Y';
241
+ const DATE_MED = 'M j, Y';
242
+ const calOptions = ref({
243
+ minDate: now,
244
+ maxDate: nextWeek,
245
+ dateFormat: DATE_SHORT,
246
+ });
247
+ function toggleDateFormat() {
248
+ calOptions.value.dateFormat =
249
+ calOptions.value.dateFormat === DATE_SHORT ? DATE_MED : DATE_SHORT;
250
+ }
251
+ function buttonLabel() {
252
+ return calOptions.value.dateFormat === DATE_SHORT ? DATE_MED : DATE_SHORT;
253
+ }
254
+ function changeMaxDate(inc) {
255
+ calOptions.value.maxDate = new Date(
256
+ nextWeek.setDate(nextWeek.getDate() + inc)
257
+ );
258
+ }
241
259
  const templateSingleUsingMinMax = `
242
260
  <div>
243
261
  <cv-date-picker v-bind='args' @change="onChange" kind="single" :value="now" :cal-options="calOptions">
244
262
  </cv-date-picker>
263
+ <div style="margin-top:2rem; background-color: #888888; padding:1rem; width:fit-content">
264
+ <div>Reactive updates</div>
265
+ <button @click='toggleDateFormat'>change date format &quot;{{buttonLabel()}}&quot;</button><br/>
266
+ <button @click='changeMaxDate(1)'>+1 day to max date</button>
267
+ <button @click='changeMaxDate(-1)'>-1 day from max date</button>
268
+ <div>Max date: {{calOptions.maxDate}}</div>
269
+ </div>
245
270
  </div>
246
271
  `;
247
272
 
@@ -251,11 +276,10 @@ const TemplateSingleUsingMinMax = args => {
251
276
  setup: () => ({
252
277
  args,
253
278
  now,
254
- calOptions: {
255
- minDate: now,
256
- maxDate: nextWeek,
257
- dateFormat: 'm/d/Y',
258
- },
279
+ calOptions,
280
+ toggleDateFormat,
281
+ buttonLabel,
282
+ changeMaxDate,
259
283
  onChange: action('change'),
260
284
  }),
261
285
  template: templateSingleUsingMinMax,
@@ -24,7 +24,7 @@
24
24
  'single',
25
25
  'range',
26
26
  ].includes(getKind),
27
- [`${carbonPrefix}--date-picker--nolabel`]: getDateLabel !== undefined,
27
+ [`${carbonPrefix}--date-picker--nolabel`]: !getDateLabel,
28
28
  }"
29
29
  >
30
30
  <label
@@ -135,7 +135,7 @@ const dateWrapper = ref(null);
135
135
  const date = ref(null);
136
136
  const todate = ref(null);
137
137
 
138
- let calendar;
138
+ const calendar = ref(null);
139
139
 
140
140
  const props = defineProps({
141
141
  modelValue: { type: [String, Object, Array, Date], default: undefined },
@@ -191,18 +191,16 @@ const getKind = computed({
191
191
  },
192
192
  });
193
193
 
194
- const getDateLabel = computed({
195
- get() {
196
- if (props.kind === 'range' && !props.dateLabel) {
194
+ const getDateLabel = computed(() => {
195
+ if (props.dateLabel !== undefined) {
196
+ return props.dateLabel;
197
+ } else {
198
+ if (props.kind === 'range') {
197
199
  return 'Start date';
200
+ } else {
201
+ return 'Date';
198
202
  }
199
-
200
- if (!props.dateLabel) {
201
- return 'Date label';
202
- }
203
-
204
- return props.dateLabel;
205
- },
203
+ }
206
204
  });
207
205
 
208
206
  const isRange = computed(() => {
@@ -309,10 +307,19 @@ const onCalReady = (selectedDates, dateStr, instance) => {
309
307
  const initFlatpickr = () => {
310
308
  return flatpickr(date.value, getFlatpickrOptions());
311
309
  };
310
+ watch(
311
+ () => props.calOptions,
312
+ () => {
313
+ for (const [key, value] of Object.entries(props.calOptions)) {
314
+ calendar.value.set(key, value);
315
+ }
316
+ },
317
+ { deep: true }
318
+ );
312
319
 
313
320
  let dateToString = val => {
314
321
  if (!val) return '';
315
- return calendar.formatDate(val, props.calOptions.dateFormat);
322
+ return calendar.value?.formatDate(val, props.calOptions.dateFormat);
316
323
  };
317
324
 
318
325
  // eslint-disable-next-line no-unused-vars
@@ -351,9 +358,9 @@ const setDate = value => {
351
358
  try {
352
359
  if (value === undefined) return;
353
360
  if (isSingle.value) {
354
- calendar.setDate(value, true);
361
+ calendar.value?.setDate(value, true);
355
362
  } else if (isRange.value) {
356
- calendar.setDate([value.startDate, value.endDate], true);
363
+ calendar.value?.setDate([value.startDate, value.endDate], true);
357
364
  } else {
358
365
  date.value.value = value;
359
366
  }
@@ -395,16 +402,14 @@ onBeforeMount(() => {
395
402
 
396
403
  onMounted(() => {
397
404
  if (['range', 'single'].includes(props.kind)) {
398
- calendar = initFlatpickr();
405
+ calendar.value = initFlatpickr();
399
406
  }
400
407
 
401
408
  setDate(props.modelValue || props.value);
402
409
  });
403
410
 
404
411
  onUnmounted(() => {
405
- if (calendar) {
406
- calendar.destroy();
407
- }
412
+ calendar.value?.destroy();
408
413
  });
409
414
  </script>
410
415
 
@@ -129,6 +129,7 @@ const vmodelTemplate = `
129
129
  <cv-dropdown-item value="mysterious">The Armorer</cv-dropdown-item>
130
130
  <cv-dropdown-item value="bounty-hunter">Greef Karga</cv-dropdown-item>
131
131
  </cv-dropdown>
132
+ <div style="margin-top:2rem; background-color: #888888; padding:1rem">
132
133
  <div>V-Model value: {{ myValue }}</div>
133
134
  <select v-model="myValue">
134
135
  <option value="mando">Mandalorian</option>
@@ -136,7 +137,12 @@ const vmodelTemplate = `
136
137
  <option value="baby-yoda">Grogu</option>
137
138
  <option value="mysterious">Armorer</option>
138
139
  <option value="bounty-hunter">Karga</option>
140
+ <option value="none">None</option>
139
141
  </select>
142
+ <div>
143
+ <button @click="myValue = undefined">Clear value</button>
144
+ </div>
145
+ </div>
140
146
  </div>
141
147
  `;
142
148
  const skeletonTemplate = `
@@ -150,10 +156,14 @@ const skeletonTemplate = `
150
156
  Notes:
151
157
 
152
158
  - You can place a Dropdown inline with other content by using the inline variant
153
- Migration notes:
154
- - Added the `size` option to match Carbon React
159
+
160
+ Migration notes:
161
+ - **Breaking**. The selected item contents are no longer copied directly to the "internal caption". If you are trying to style both
162
+ the drop-down item and its appearance after it is selected, please see the `internal-caption` slot. See the "Slots"
163
+ story for an example.- Added the `size` option to match Carbon React
155
164
  - Added the `warningMessage` option to match Carbon React
156
165
 
166
+
157
167
  <Canvas>
158
168
  <Story
159
169
  name="Default"
@@ -77,7 +77,7 @@
77
77
  :aria-expanded="open ? 'true' : 'false'"
78
78
  :aria-labelledby="ariaLabeledBy"
79
79
  :class="`${carbonPrefix}--list-box__field`"
80
- :disabled="disabled"
80
+ :disabled="disabled || null"
81
81
  aria-haspopup="true"
82
82
  type="button"
83
83
  >
@@ -282,6 +282,7 @@ watch(
282
282
  () => props.modelValue,
283
283
  () => {
284
284
  dataValue.value = props.modelValue;
285
+ dataCaption.value = undefined;
285
286
  }
286
287
  );
287
288
  watch(dataValue, () => {
@@ -293,9 +294,9 @@ watch(open, () => {
293
294
  });
294
295
  const ariaLabeledBy = computed(() => {
295
296
  if (props.label) {
296
- return `${uid}-label ${uid}-value`;
297
+ return `${uid.value}-label ${uid.value}-value`;
297
298
  } else {
298
- return `${uid}-value`;
299
+ return `${uid.value}-value`;
299
300
  }
300
301
  });
301
302
  const internalCaption = computed(() => {
@@ -34,7 +34,7 @@
34
34
  ref="fileInput"
35
35
  :class="`${carbonPrefix}--file-input`"
36
36
  :accept="accept"
37
- :disabled="disabled"
37
+ :disabled="disabled || null"
38
38
  type="file"
39
39
  v-bind="$attrs"
40
40
  data-file-uploader
@@ -70,7 +70,7 @@
70
70
  ref="fileInput"
71
71
  :class="`${carbonPrefix}--file-input`"
72
72
  :accept="accept"
73
- :disabled="disabled"
73
+ :disabled="disabled || null"
74
74
  type="file"
75
75
  v-bind="$attrs"
76
76
  tabindex="-1"
@@ -1,6 +1,7 @@
1
1
  <template>
2
2
  <component
3
3
  :is="listType"
4
+ class="cv-list"
4
5
  :class="{
5
6
  [`${carbonPrefix}--list--nested`]: nested,
6
7
  [`${carbonPrefix}--list--ordered`]: isActuallyOrdered,
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <li :class="`${carbonPrefix}--list__item`"><slot /></li>
2
+ <li class="cv-list-item" :class="`${carbonPrefix}--list__item`"><slot /></li>
3
3
  </template>
4
4
 
5
5
  <script>