@carbon/vue 3.0.20 → 3.0.22

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 (49) hide show
  1. package/dist/carbon-vue-3.common.js +4420 -4885
  2. package/dist/carbon-vue-3.common.js.map +1 -1
  3. package/dist/carbon-vue-3.umd.js +4422 -4887
  4. package/dist/carbon-vue-3.umd.js.map +1 -1
  5. package/dist/carbon-vue-3.umd.min.js +4 -4
  6. package/dist/carbon-vue-3.umd.min.js.map +1 -1
  7. package/dist/web-types.json +14 -1
  8. package/package.json +4 -4
  9. package/src/components/CvAspectRatio/CvAspectRatio.stories.js +2 -5
  10. package/src/components/CvBreadcrumb/CvBreadcrumb.stories.js +2 -5
  11. package/src/components/CvButton/CvButton.stories.js +1 -3
  12. package/src/components/CvButton/CvButtonSet.stories.js +2 -6
  13. package/src/components/CvButton/CvButtonSkeleton.stories.js +1 -3
  14. package/src/components/CvButton/CvIconButton.stories.js +1 -3
  15. package/src/components/CvCheckbox/CvCheckbox.stories.js +5 -4
  16. package/src/components/CvCodeSnippet/CvCodeSnippet.stories.js +1 -2
  17. package/src/components/CvComboBox/CvComboBox.stories.js +2 -5
  18. package/src/components/CvCopyButton/CvCopyButton.stories.js +2 -5
  19. package/src/components/CvDataTable/CvDataTable.stories.mdx +82 -12
  20. package/src/components/CvDataTable/CvDataTable.vue +71 -96
  21. package/src/components/CvDataTable/CvDataTableHeading.vue +25 -45
  22. package/src/components/CvDataTable/CvDataTableRow.vue +50 -49
  23. package/src/components/CvDataTable/_CvDataTableRowInner.vue +9 -18
  24. package/src/components/CvDatePicker/CvDatePicker.stories.js +101 -27
  25. package/src/components/CvDatePicker/CvDatePicker.vue +4 -2
  26. package/src/components/CvLink/CvLink.stories.js +1 -2
  27. package/src/components/CvList/CvList.stories.js +2 -5
  28. package/src/components/CvLoading/CvLoading.stories.js +2 -5
  29. package/src/components/CvMultiSelect/CvMultiSelect.vue +4 -1
  30. package/src/components/CvNotification/CvInlineNotification.stories.js +2 -2
  31. package/src/components/CvNotification/CvToastNotification.stories.js +2 -2
  32. package/src/components/CvNumberInput/CvNumberInput.stories.js +2 -6
  33. package/src/components/CvNumberInput/CvNumberInputSkeleton.stories.js +2 -6
  34. package/src/components/CvRadioButton/CvRadioButton.stories.js +2 -5
  35. package/src/components/CvSkeletonText/CvSkeletonText.stories.js +2 -5
  36. package/src/components/CvSlider/CvSlider.stories.js +2 -6
  37. package/src/components/CvSlider/CvSliderSkeleton.stories.js +2 -6
  38. package/src/components/CvStructuredList/CvStructuredList.stories.js +2 -5
  39. package/src/components/CvTag/CvTag.stories.js +2 -5
  40. package/src/components/CvTag/CvTagSkeleton.stories.js +2 -5
  41. package/src/components/CvTextArea/CvTextArea.stories.js +2 -6
  42. package/src/components/CvTextArea/CvTextAreaSkeleton.stories.js +2 -6
  43. package/src/components/CvTextInput/CvTextInput.stories.js +2 -5
  44. package/src/components/CvToggle/CvToggle.stories.js +2 -5
  45. package/src/components/CvTooltip/CvDefinitionTooltip.stories.js +2 -6
  46. package/src/components/CvTooltip/CvInteractiveTooltip.stories.js +2 -6
  47. package/src/components/CvTooltip/CvTooltip.stories.js +2 -6
  48. package/src/use/overflow.js +2 -2
  49. package/src/components/CvDataTable/cvDataTableStore.js +0 -314
@@ -236,11 +236,9 @@ import CvPagination from '../CvPagination';
236
236
  import Search16 from '@carbon/icons-vue/es/search/16';
237
237
  import Close16 from '@carbon/icons-vue/es/close/16';
238
238
  import ChevronRight16 from '@carbon/icons-vue/es/chevron--right/16';
239
- import { getBus, removeBus } from '../../global/component-utils/event-bus';
240
239
  import {
241
240
  computed,
242
241
  nextTick,
243
- onBeforeMount,
244
242
  onMounted,
245
243
  onUnmounted,
246
244
  onUpdated,
@@ -251,8 +249,6 @@ import {
251
249
  provide,
252
250
  } from 'vue';
253
251
  import { props as propsCvId, useCvId } from '../../use/cvId';
254
- //TODO: Remove this store and replace with provide/inject
255
- import store from './cvDataTableStore';
256
252
  import Empty from '../CvEmpty/_CvEmpty.vue';
257
253
 
258
254
  const props = defineProps({
@@ -356,20 +352,6 @@ watch(
356
352
  () => (isSkeleton.value = props.skeleton)
357
353
  );
358
354
 
359
- let bus = undefined;
360
- onBeforeMount(() => {
361
- bus = getBus(uid.value);
362
- bus.on('cv:check-change', onRowCheckChange);
363
- bus.on('cv:click', onMenuItemClick);
364
- bus.on('cv:sort', onSort);
365
- bus.on('cv:expanded-change', onCvExpandedChange);
366
- store.addTable(uid);
367
- });
368
- onUnmounted(() => {
369
- removeBus(uid.value);
370
- store.removeTable(uid.value);
371
- });
372
-
373
355
  watch(() => props.rowsSelected, updateRowsSelected);
374
356
 
375
357
  const searchContainer = ref(null);
@@ -393,6 +375,7 @@ watch(
393
375
  else expandingRowIds.value.delete('table-expand-row');
394
376
  }
395
377
  );
378
+ const clearSearchVisible = ref(false);
396
379
 
397
380
  onMounted(() => {
398
381
  if (searchContainer.value) {
@@ -416,6 +399,8 @@ onUpdated(checkSlots);
416
399
  const hasActions = ref(false);
417
400
  const hasToolbar = ref(false);
418
401
  const hasBatchActions = ref(false);
402
+ const isHelper = ref(false);
403
+
419
404
  provide('has-batch-actions', hasBatchActions);
420
405
 
421
406
  function checkSlots() {
@@ -442,9 +427,11 @@ function columnHeading(c) {
442
427
  }
443
428
  }
444
429
 
430
+ const sortableHeadings = ref(new Set());
431
+ provide('sortableHeadings', sortableHeadings);
445
432
  const isSortable = computed(() => {
446
433
  // is any column sortable
447
- return props.sortable || store.someSortableHeadings(uid.value);
434
+ return props.sortable || sortableHeadings.value.size > 0;
448
435
  });
449
436
 
450
437
  function isColSortable(c) {
@@ -453,7 +440,6 @@ function isColSortable(c) {
453
440
  return (col && col.sortable) || props.sortable;
454
441
  }
455
442
 
456
- const isHelper = ref(false);
457
443
  const hasTableHeader = computed(() => {
458
444
  return props.title || isHelper.value;
459
445
  });
@@ -482,13 +468,15 @@ const internalPagination = computed(() => {
482
468
  return false;
483
469
  });
484
470
 
485
- const registeredRows = ref([]);
471
+ const rowIds = ref(new Set());
472
+ provide('row-ids', rowIds);
473
+
486
474
  const internalNumberOfItems = computed(() => {
487
475
  const internal = internalPagination.value;
488
476
  if (internal.numberOfItems !== undefined) {
489
477
  return internal.numberOfItems;
490
478
  } else {
491
- return registeredRows.value.length;
479
+ return rowIds.value.size;
492
480
  }
493
481
  });
494
482
 
@@ -527,6 +515,19 @@ function checkSearchExpand(force) {
527
515
  }
528
516
 
529
517
  const dataRowsSelected = ref(props.rowsSelected);
518
+ provide('rows-selected', dataRowsSelected);
519
+
520
+ const headingChecked = ref(false);
521
+ watch(
522
+ () => dataRowsSelected,
523
+ () => {
524
+ headingChecked.value =
525
+ rowIds.value.size > 0 &&
526
+ dataRowsSelected.value.length === rowIds.value.size;
527
+ },
528
+ { deep: true }
529
+ );
530
+
530
531
  const batchActive = computed(() => {
531
532
  return (
532
533
  props.stickyBatchActive ||
@@ -535,29 +536,8 @@ const batchActive = computed(() => {
535
536
  );
536
537
  });
537
538
 
538
- const headingChecked = ref(false);
539
-
540
- watch(
541
- () => store.state[uid.value],
542
- () => {
543
- const rows = store.rows(uid);
544
- headingChecked.value = dataRowsSelected.value.length === rows.length;
545
- },
546
- { deep: true }
547
- );
548
539
  function updateRowsSelected() {
549
- dataRowsSelected.value = [];
550
- const rows = store.rows(uid);
551
- for (const i in rows) {
552
- let child = rows[i];
553
- const checked = props.rowsSelected.includes(child.value);
554
- store.updateRow(uid, { id: child.id, isChecked: checked });
555
-
556
- if (checked) {
557
- dataRowsSelected.value.push(child.value);
558
- }
559
- }
560
- headingChecked.value = dataRowsSelected.value.length === rows.length;
540
+ dataRowsSelected.value = [...props.rowsSelected];
561
541
  }
562
542
 
563
543
  const emit = defineEmits([
@@ -571,7 +551,6 @@ const emit = defineEmits([
571
551
  'pagination',
572
552
  ]);
573
553
  const searchValue = ref(props.initialSearchValue);
574
- const clearSearchVisible = ref(false);
575
554
  function onClearClick() {
576
555
  searchValue.value = '';
577
556
  clearSearchVisible.value = false;
@@ -583,87 +562,83 @@ function onClearClick() {
583
562
  }
584
563
  function onHeadingCheckChange() {
585
564
  // check /uncheck all children
586
- dataRowsSelected.value = [];
587
- const rows = store.rows(uid);
588
- for (const child of rows) {
589
- if (headingChecked.value) {
590
- dataRowsSelected.value.push(child.value);
591
- }
592
-
593
- if (child.isChecked !== headingChecked.value) {
594
- store.updateRow(uid, { id: child.id, isChecked: headingChecked.value });
595
-
596
- emit('row-select-change', {
597
- value: child.value,
598
- selected: headingChecked.value,
599
- });
600
- }
601
- }
602
- emit('row-select-changes', dataRowsSelected.value);
603
- emit('update:rowsSelected', dataRowsSelected.value);
565
+ if (headingChecked.value) dataRowsSelected.value = [...rowIds.value];
566
+ else dataRowsSelected.value = [];
604
567
  }
605
568
  function deselect() {
606
569
  headingChecked.value = false;
607
570
  onHeadingCheckChange();
608
571
  }
609
- function onRowCheckChange(payload) {
610
- const { value, checked } = payload;
611
- let modelSet = new Set(dataRowsSelected.value);
612
-
613
- if (!checked) {
614
- modelSet.delete(value);
615
- } else {
616
- modelSet.add(value);
617
- }
618
- dataRowsSelected.value = Array.from(modelSet);
619
- const rows = store.rows(uid);
620
- headingChecked.value = dataRowsSelected.value.length === rows.length;
621
572
 
573
+ const previousEmit = ref([...props.rowsSelected]);
574
+ watch(
575
+ dataRowsSelected,
576
+ () => {
577
+ // was tempted to use Set.symmetricDifference but support for that was only
578
+ // add in Feb/June 2024
579
+ const diff = dataRowsSelected.value
580
+ .filter(x => !previousEmit.value.includes(x))
581
+ .concat(
582
+ previousEmit.value.filter(x => !dataRowsSelected.value.includes(x))
583
+ );
584
+ if (diff.length > 0) {
585
+ emit('row-select-changes', dataRowsSelected.value);
586
+ emit('update:rowsSelected', dataRowsSelected.value);
587
+ previousEmit.value = [...dataRowsSelected.value];
588
+ }
589
+ },
590
+ { deep: true }
591
+ );
592
+ function onRowCheckChange(value, checked) {
622
593
  emit('row-select-change', { value, selected: checked });
623
- emit('row-select-changes', dataRowsSelected.value);
624
- emit('update:rowsSelected', dataRowsSelected.value);
625
594
  }
595
+ provide('cv:check-change', onRowCheckChange);
596
+
626
597
  function onMenuItemClick(val) {
627
598
  emit('overflow-menu-click', val);
628
599
  }
600
+ provide('cv:click', onMenuItemClick);
601
+
629
602
  function onInternalSearch() {
630
603
  clearSearchVisible.value = searchValue.value.length > 0;
631
604
  // eslint-disable-next-line vue/require-explicit-emits
632
605
  emit('search', searchValue.value);
633
606
  }
607
+
608
+ const headingIds = ref(new Set());
609
+ provide('heading-ids', headingIds);
610
+ const currentSortHeadingId = ref(null);
611
+ provide('current-sort-heading-id', currentSortHeadingId);
634
612
  function onSort(payload) {
635
613
  const { heading, value } = payload;
636
- const headings = store.headings(uid);
637
- let index;
638
- for (let colIndex in headings) {
639
- const column = headings[colIndex];
640
- if (column.id === heading.id) {
641
- store.updateHeading(uid, { ...column, order: value });
642
- index = colIndex;
643
- } else {
644
- store.updateHeading(uid, { ...column, order: 'none' });
645
- }
646
- }
614
+ const headings = Array.from(headingIds.value);
615
+ currentSortHeadingId.value = heading.id;
616
+ const index = headings.indexOf(heading.id);
647
617
  emit('sort', { index, order: value, name: heading.name });
648
618
  }
619
+ provide('cv:sort', onSort);
649
620
 
650
621
  // are all rows expanded
651
- const dataExpandAll = computed(() => {
652
- return store.allExpandedRows(uid);
653
- });
622
+ /** @type {Ref<Set<String>>} */
623
+ const expandedRowIds = ref(new Set());
624
+ provide('expanded-row-ids', expandedRowIds);
625
+
626
+ const dataExpandAll = computed(
627
+ () => expandedRowIds.value.size === rowIds.value.size
628
+ );
654
629
  function toggleExpandAll() {
655
630
  const toggle = !dataExpandAll.value;
656
- const rows = store.rows(uid);
657
- for (const row of rows) {
658
- store.updateRow(uid, { id: row.id, isExpanded: toggle });
659
- }
631
+ if (toggle) {
632
+ rowIds.value.forEach(rowId => expandedRowIds.value.add(rowId));
633
+ } else expandedRowIds.value.clear();
660
634
  }
661
635
 
662
636
  /**
663
637
  * A child row is changed
664
- * @param {{kind:string, uid:string, value:string, isExpanded:boolean}} row
638
+ * @param {{id:string, value:string, expandable:string, isExpanded:boolean, isChecked:boolean}} row
665
639
  */
666
640
  function onCvExpandedChange(row) {
667
641
  emit('row-expanded', row);
668
642
  }
643
+ provide('cv:expanded-change', onCvExpandedChange);
669
644
  </script>
@@ -1,10 +1,5 @@
1
1
  <template>
2
- <th
3
- :id="cvId"
4
- ref="el"
5
- :aria-sort="internalOrder"
6
- :style="skeleton && headingStyle"
7
- >
2
+ <th :id="cvId" :aria-sort="internalOrder" :style="skeleton && headingStyle">
8
3
  <button
9
4
  v-if="sortable"
10
5
  type="button"
@@ -46,9 +41,7 @@ import Arrows16 from '@carbon/icons-vue/es/arrows--vertical/16';
46
41
  import CvEmpty from '../CvEmpty/_CvEmpty.vue';
47
42
  import { props as propsCvId, useCvId } from '../../use/cvId';
48
43
  import { carbonPrefix } from '../../global/settings';
49
- import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
50
- import { getBus } from '../../global/component-utils/event-bus';
51
- import store from './cvDataTableStore';
44
+ import { computed, onBeforeUnmount, onMounted, ref, watch, inject } from 'vue';
52
45
 
53
46
  const nextOrder = {
54
47
  ascending: 'descending',
@@ -67,69 +60,56 @@ const props = defineProps({
67
60
  });
68
61
  const cvId = useCvId(props, true);
69
62
  const dataOrder = ref(props.order);
70
- const parent = ref(null);
71
63
  watch(
72
64
  () => props.order,
73
65
  () => {
74
66
  if (dataOrder.value !== props.order) {
75
67
  dataOrder.value = props.order;
76
- store.updateHeading(parent, {
77
- id: cvId.value,
78
- order: dataOrder.value,
79
- });
80
68
  onSortClick();
81
69
  }
82
70
  }
83
71
  );
72
+ const sortableHeaders = inject('sortableHeadings', ref(new Set()));
84
73
  watch(
85
74
  () => props.sortable,
86
75
  () => {
87
- store.updateHeading(parent, {
88
- id: cvId.value,
89
- sortable: props.sortable,
90
- });
76
+ if (props.sortable) sortableHeaders.value.add(cvId.value);
77
+ else sortableHeaders.value.delete(cvId.value);
91
78
  }
92
79
  );
93
80
 
94
- let bus = undefined;
95
- const el = ref(null);
81
+ const headingIds = inject('heading-ids', ref(new Set()));
96
82
  onMounted(() => {
97
- const pe = el.value.closest('.cv-data-table');
98
- parent.value = pe?.getAttribute('id');
99
- if (parent.value) bus = getBus(parent);
100
- else console.warn('data table not found');
101
-
102
- const exists = store.findHeading(parent, cvId);
103
- if (exists)
104
- console.error(
105
- `CvDataTable: Duplicate ID specified for CvDataTableHeading, may cause issues. {id: ${cvId.value}, name: ${props.name}`
106
- );
107
- else
108
- store.updateHeading(parent, {
109
- id: cvId.value,
110
- name: props.name,
111
- order: dataOrder.value,
112
- sortable: props.sortable,
113
- });
83
+ headingIds.value.add(cvId.value);
84
+ if (props.sortable) {
85
+ sortableHeaders.value.add(cvId.value);
86
+ if (props.order !== 'none') onSortClick();
87
+ }
114
88
  });
115
89
 
116
90
  onBeforeUnmount(() => {
117
- store.removeHeading(parent, cvId);
91
+ headingIds.value.delete(cvId.value);
92
+ sortableHeaders.value.delete(cvId.value);
118
93
  });
119
- function onSortClick() {
120
- bus?.emit('cv:sort', {
94
+
95
+ const notifyHeaderSort = inject('cv:sort');
96
+ function onSortClick(ev) {
97
+ // If this is a click event, update to next sort order. Otherwise, this is
98
+ // being called from a watcher.
99
+ if (ev) dataOrder.value = nextOrder[dataOrder.value];
100
+ notifyHeaderSort({
121
101
  heading: { id: cvId.value, name: props.name },
122
- value: nextOrder[internalOrder.value],
102
+ value: dataOrder.value,
123
103
  });
124
104
  }
105
+
106
+ const currentSortHeadingId = inject('current-sort-heading-id', ref(null));
125
107
  const internalOrder = computed(() => {
126
108
  if (!props.sortable) {
127
109
  return undefined;
128
110
  }
129
- const heading = store.findHeading(parent, cvId);
130
- if (['ascending', 'descending', 'none'].includes(heading?.order))
131
- return heading.order;
132
- else return 'none';
111
+ if (currentSortHeadingId.value !== cvId.value) return 'none';
112
+ return dataOrder.value;
133
113
  });
134
114
 
135
115
  const headingLabelTag = computed(() => {
@@ -8,6 +8,7 @@
8
8
  ref="row"
9
9
  :row-id="cvId"
10
10
  v-bind="$attrs"
11
+ :value="value"
11
12
  :expanding-row="dataExpandable"
12
13
  :expanded="dataExpanded"
13
14
  @expanded-change="onExpandedChange"
@@ -32,6 +33,7 @@
32
33
  v-bind="$attrs"
33
34
  :id="cvId"
34
35
  ref="row"
36
+ :value="rowValue"
35
37
  class="cv-data-table-row"
36
38
  :row-id="cvId"
37
39
  @checked-change="onCheckedChange"
@@ -48,100 +50,99 @@ import {
48
50
  computed,
49
51
  onBeforeUnmount,
50
52
  onMounted,
51
- onUpdated,
52
53
  ref,
53
54
  useAttrs,
54
55
  useSlots,
55
56
  watch,
56
57
  inject,
58
+ onUpdated,
57
59
  } from 'vue';
58
- import store from './cvDataTableStore';
59
- import { getBus } from '../../global/component-utils/event-bus';
60
60
 
61
61
  const props = defineProps({
62
+ /** The value associated with the input (required for tables with batch actions) */
63
+ value: { type: String, default: undefined },
64
+ /** This row will be initially expanded */
62
65
  expanded: Boolean,
63
66
  ...propsCvId,
64
67
  });
65
68
  const cvId = useCvId(props, true);
69
+ // For historical reasons we have a prop named "value" but this makes the code
70
+ // hard to read since .value is used for refs. So it would be props.value
71
+ // which is weird. Let's shadow this as "rowValue"
72
+ const rowValue = ref(props.value);
73
+ watch(
74
+ () => props.value,
75
+ () => (rowValue.value = props.value)
76
+ );
66
77
 
67
78
  /** @type {Ref<Set<String>>} */
68
79
  const expandingRowIds = inject('expanding-row-ids', ref(new Set()));
69
80
  const dataExpandable = ref(false);
70
81
  watch(dataExpandable, () => {
71
- if (dataExpandable.value) expandingRowIds.value?.add(cvId.value);
82
+ if (dataExpandable.value) expandingRowIds.value.add(cvId.value);
72
83
  else expandingRowIds.value?.delete(cvId.value);
73
84
  });
74
85
  const dataSomeExpandingRows = computed(() => {
75
86
  return expandingRowIds.value?.size > 0;
76
87
  });
77
-
78
88
  const attrs = useAttrs();
89
+ const rowIds = inject('row-ids', ref(new Set()));
90
+ const expandedRowIds = inject('expanded-row-ids', ref(new Set()));
91
+
79
92
  const slots = useSlots();
80
93
  const row = ref(null);
81
- const parent = ref(null);
82
- let bus;
83
- onMounted(() => {
84
- const el = row.value?.$el;
85
- const pe = el?.closest('.cv-data-table');
86
- parent.value = pe?.getAttribute('id');
87
- if (parent.value) {
88
- bus = getBus(parent);
89
- store.getTable(parent);
90
- } else console.warn('data table not found');
94
+ const rowsSelected = inject('rows-selected');
91
95
 
96
+ onMounted(() => {
92
97
  dataExpandable.value = !!slots.expandedContent;
93
- const exists = store.findRow(parent, cvId);
94
- if (exists)
95
- console.error(
96
- `CvDataTable: Duplicate ID specified for CvDataTableRow, may cause issues. {id: ${cvId.value}, value: ${attrs.value}}`
97
- );
98
- else
99
- store.updateRow(parent, {
100
- id: cvId.value,
101
- value: attrs.value,
102
- expandable: dataExpandable.value,
103
- isExpanded: props.expanded,
104
- isChecked: false,
105
- });
98
+ rowIds.value.add(cvId.value);
99
+ if (props.expanded) expandedRowIds.value.add(cvId.value);
106
100
  });
107
101
  onUpdated(() => {
108
- const curr = dataExpandable.value;
109
102
  dataExpandable.value = !!slots.expandedContent;
110
- if (dataExpandable.value !== curr)
111
- store.updateRow(parent, {
112
- id: cvId.value,
113
- expandable: dataExpandable.value,
114
- });
115
103
  });
116
104
  onBeforeUnmount(() => {
117
- store.removeRow(parent, cvId);
105
+ rowIds.value.delete(cvId.value);
106
+ expandingRowIds.value.delete(cvId.value);
107
+ expandedRowIds.value.delete(cvId.value);
108
+ const index = rowsSelected.value.indexOf(rowValue.value);
109
+ if (index > -1) rowsSelected.value.splice(index, 1);
118
110
  });
119
111
  const dataExpanded = computed(() => {
120
- return Boolean(props.expanded || store.isRowExpanded(parent, cvId));
112
+ return Boolean(props.expanded || expandedRowIds.value.has(cvId.value));
121
113
  });
122
114
  watch(
123
115
  () => props.expanded,
124
116
  () => {
125
- store.updateRow(parent, {
126
- id: cvId.value,
127
- isExpanded: props.expanded,
128
- });
117
+ if (props.expanded) expandedRowIds.value.add(cvId.value);
118
+ else expandingRowIds.value.delete(cvId.value);
129
119
  }
130
120
  );
131
121
 
122
+ const notifyExpandedChange = inject('cv:expanded-change');
123
+
132
124
  function onExpandedChange(val) {
133
- const row = store.findRow(parent, cvId);
134
- store.updateRow(parent, {
125
+ notifyExpandedChange({
135
126
  id: cvId.value,
127
+ value: rowValue.value,
128
+ expandable: expandingRowIds.value.has(cvId.value),
136
129
  isExpanded: val,
130
+ isChecked: rowsSelected.value.includes(rowValue.value),
137
131
  });
138
- bus?.emit('cv:expanded-change', row);
139
132
  }
140
- function onCheckedChange(val) {
141
- store.updateRow(parent, {
142
- id: cvId.value,
143
- isChecked: val,
144
- });
145
- bus?.emit('cv:check-change', { value: attrs.value, checked: val });
133
+
134
+ // Manage the checkmark on the row. Notify the table if it changes.
135
+ const notifyCheckedChange = inject('cv:check-change');
136
+ function onCheckedChange(isChecked) {
137
+ if (!rowsSelected.value) return;
138
+ const index = rowsSelected.value.indexOf(rowValue.value);
139
+ if (isChecked) {
140
+ // if the row value is not already in the rowsSelected array, add it.
141
+ if (index === -1) rowsSelected.value.push(rowValue.value);
142
+ } else {
143
+ // if the row value is in the rowsSelected array, delete it.
144
+ if (index > -1) rowsSelected.value.splice(index, 1);
145
+ }
146
+ notifyCheckedChange(attrs.value, isChecked);
146
147
  }
147
148
  </script>
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <tr
3
- ref="el"
4
3
  class="cv-data-table-row-inner"
4
+ :data-value="value"
5
5
  :class="{
6
6
  [`${carbonPrefix}--parent-row`]: expandingRow,
7
7
  [`${carbonPrefix}--expandable-row`]: dataExpanded,
@@ -76,8 +76,6 @@ import {
76
76
  watch,
77
77
  inject,
78
78
  } from 'vue';
79
- import store from './cvDataTableStore';
80
- import { getBus } from '../../global/component-utils/event-bus';
81
79
 
82
80
  const props = defineProps({
83
81
  ariaLabelForBatchCheckbox: { type: String, default: undefined },
@@ -124,21 +122,11 @@ function checkSlots() {
124
122
  onMounted(checkSlots);
125
123
  onUpdated(checkSlots);
126
124
 
127
- const el = ref(null);
128
- const parent = ref(null);
129
- let bus;
130
- onMounted(() => {
131
- const pe = el.value.closest('.cv-data-table');
132
- parent.value = pe?.getAttribute('id');
133
- if (parent.value) {
134
- store.getTable(parent);
135
- bus = getBus(parent);
136
- } else console.warn('data table not found');
137
- });
138
125
  const hasBatchActions = inject('has-batch-actions', ref(false));
139
126
 
127
+ const emitClick = inject('cv:click');
140
128
  function onMenuItemClick(val) {
141
- bus.emit('cv:click', val);
129
+ emitClick(val);
142
130
  }
143
131
 
144
132
  const emit = defineEmits(['expanded-change', 'checked-change']);
@@ -165,11 +153,14 @@ watch(
165
153
  emit('checked-change', dataExpanded.value);
166
154
  }
167
155
  );
156
+ const rowsSelected = inject('rows-selected');
168
157
  watch(
169
- () => store.state[parent.value]?.rows,
158
+ () => rowsSelected,
170
159
  () => {
171
- const row = store.findRow(parent, props.rowId);
172
- const isChecked = row?.isChecked;
160
+ // For historical reasons we have a prop named "value" but this makes the code
161
+ // below look weird since .value is used for refs. So just a note that this
162
+ // is not a ref is a prop named "value"
163
+ const isChecked = rowsSelected.value.includes(props.value);
173
164
  if (isChecked !== undefined) {
174
165
  dataChecked.value = isChecked;
175
166
  }