@carbon/vue 3.0.21 → 3.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -3
- package/dist/carbon-vue-3.common.js +750 -1169
- package/dist/carbon-vue-3.common.js.map +1 -1
- package/dist/carbon-vue-3.umd.js +750 -1169
- package/dist/carbon-vue-3.umd.js.map +1 -1
- package/dist/carbon-vue-3.umd.min.js +4 -4
- package/dist/carbon-vue-3.umd.min.js.map +1 -1
- package/package.json +10 -7
- package/src/components/CvAspectRatio/CvAspectRatio.stories.js +2 -5
- package/src/components/CvBreadcrumb/CvBreadcrumb.stories.js +2 -5
- package/src/components/CvButton/CvButton.stories.js +1 -3
- package/src/components/CvButton/CvButtonSet.stories.js +2 -6
- package/src/components/CvButton/CvButtonSkeleton.stories.js +1 -3
- package/src/components/CvButton/CvIconButton.stories.js +1 -3
- package/src/components/CvCheckbox/CvCheckbox.stories.js +1 -2
- package/src/components/CvCodeSnippet/CvCodeSnippet.stories.js +1 -2
- package/src/components/CvComboBox/CvComboBox.stories.js +2 -5
- package/src/components/CvCopyButton/CvCopyButton.stories.js +2 -5
- package/src/components/CvDataTable/CvDataTable.stories.mdx +61 -30
- package/src/components/CvDataTable/CvDataTable.vue +73 -103
- package/src/components/CvDataTable/CvDataTableHeading.vue +25 -45
- package/src/components/CvDataTable/CvDataTableRow.vue +52 -51
- package/src/components/CvDataTable/_CvDataTableRowInner.vue +9 -18
- package/src/components/CvDatePicker/CvDatePicker.stories.js +2 -5
- package/src/components/CvDatePicker/CvDatePicker.vue +1 -1
- package/src/components/CvLink/CvLink.stories.js +1 -2
- package/src/components/CvList/CvList.stories.js +2 -5
- package/src/components/CvLoading/CvLoading.stories.js +2 -5
- package/src/components/CvMultiSelect/CvMultiSelect.vue +4 -1
- package/src/components/CvNotification/CvInlineNotification.stories.js +2 -2
- package/src/components/CvNotification/CvToastNotification.stories.js +2 -2
- package/src/components/CvNumberInput/CvNumberInput.stories.js +2 -6
- package/src/components/CvNumberInput/CvNumberInputSkeleton.stories.js +2 -6
- package/src/components/CvRadioButton/CvRadioButton.stories.js +2 -5
- package/src/components/CvSkeletonText/CvSkeletonText.stories.js +2 -5
- package/src/components/CvSlider/CvSlider.stories.js +2 -6
- package/src/components/CvSlider/CvSliderSkeleton.stories.js +2 -6
- package/src/components/CvStructuredList/CvStructuredList.stories.js +2 -5
- package/src/components/CvTag/CvTag.stories.js +2 -5
- package/src/components/CvTag/CvTagSkeleton.stories.js +2 -5
- package/src/components/CvTextArea/CvTextArea.stories.js +2 -6
- package/src/components/CvTextArea/CvTextAreaSkeleton.stories.js +2 -6
- package/src/components/CvTextInput/CvTextInput.stories.js +2 -5
- package/src/components/CvToggle/CvToggle.stories.js +2 -5
- package/src/components/CvTooltip/CvDefinitionTooltip.stories.js +2 -6
- package/src/components/CvTooltip/CvInteractiveTooltip.stories.js +2 -6
- package/src/components/CvTooltip/CvTooltip.stories.js +2 -6
- package/src/components/CvUIShell/CvContent.stories.js +22 -0
- package/src/components/CvUIShell/CvContent.vue +14 -0
- package/src/index.js +1 -0
- package/src/use/overflow.js +2 -2
- package/telemetry.yml +1 -1
- package/dist/web-types.json +0 -5555
- package/src/components/CvDataTable/cvDataTableStore.js +0 -314
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
<thead>
|
|
133
133
|
<tr>
|
|
134
134
|
<th
|
|
135
|
-
v-if="
|
|
135
|
+
v-if="expandable"
|
|
136
136
|
:class="`${carbonPrefix}--table-expand`"
|
|
137
137
|
:data-previous-value="
|
|
138
138
|
dataExpandAll ? 'collapsed' : 'expanded'
|
|
@@ -183,7 +183,7 @@
|
|
|
183
183
|
</tr>
|
|
184
184
|
</thead>
|
|
185
185
|
|
|
186
|
-
<component :is="
|
|
186
|
+
<component :is="expandable ? Empty : 'tbody'">
|
|
187
187
|
<slot name="data">
|
|
188
188
|
<cv-data-table-row
|
|
189
189
|
v-for="(row, rowIndex) in data"
|
|
@@ -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);
|
|
@@ -378,11 +360,7 @@ const search = ref(null);
|
|
|
378
360
|
|
|
379
361
|
/** @type {Ref<Set<String>>} */
|
|
380
362
|
const expandingRowIds = ref(new Set());
|
|
381
|
-
const hasExpandingRows = computed(() => {
|
|
382
|
-
return expandingRowIds.value.size > 0;
|
|
383
|
-
});
|
|
384
363
|
provide('expanding-row-ids', expandingRowIds);
|
|
385
|
-
provide('has-expanding-rows', hasExpandingRows);
|
|
386
364
|
onMounted(() => {
|
|
387
365
|
if (props.expandable) expandingRowIds.value.add('table-expand-row');
|
|
388
366
|
});
|
|
@@ -393,6 +371,7 @@ watch(
|
|
|
393
371
|
else expandingRowIds.value.delete('table-expand-row');
|
|
394
372
|
}
|
|
395
373
|
);
|
|
374
|
+
const clearSearchVisible = ref(false);
|
|
396
375
|
|
|
397
376
|
onMounted(() => {
|
|
398
377
|
if (searchContainer.value) {
|
|
@@ -416,6 +395,8 @@ onUpdated(checkSlots);
|
|
|
416
395
|
const hasActions = ref(false);
|
|
417
396
|
const hasToolbar = ref(false);
|
|
418
397
|
const hasBatchActions = ref(false);
|
|
398
|
+
const isHelper = ref(false);
|
|
399
|
+
|
|
419
400
|
provide('has-batch-actions', hasBatchActions);
|
|
420
401
|
|
|
421
402
|
function checkSlots() {
|
|
@@ -442,9 +423,11 @@ function columnHeading(c) {
|
|
|
442
423
|
}
|
|
443
424
|
}
|
|
444
425
|
|
|
426
|
+
const sortableHeadings = ref(new Set());
|
|
427
|
+
provide('sortableHeadings', sortableHeadings);
|
|
445
428
|
const isSortable = computed(() => {
|
|
446
429
|
// is any column sortable
|
|
447
|
-
return props.sortable ||
|
|
430
|
+
return props.sortable || sortableHeadings.value.size > 0;
|
|
448
431
|
});
|
|
449
432
|
|
|
450
433
|
function isColSortable(c) {
|
|
@@ -453,7 +436,6 @@ function isColSortable(c) {
|
|
|
453
436
|
return (col && col.sortable) || props.sortable;
|
|
454
437
|
}
|
|
455
438
|
|
|
456
|
-
const isHelper = ref(false);
|
|
457
439
|
const hasTableHeader = computed(() => {
|
|
458
440
|
return props.title || isHelper.value;
|
|
459
441
|
});
|
|
@@ -482,13 +464,15 @@ const internalPagination = computed(() => {
|
|
|
482
464
|
return false;
|
|
483
465
|
});
|
|
484
466
|
|
|
485
|
-
const
|
|
467
|
+
const rowIds = ref(new Set());
|
|
468
|
+
provide('row-ids', rowIds);
|
|
469
|
+
|
|
486
470
|
const internalNumberOfItems = computed(() => {
|
|
487
471
|
const internal = internalPagination.value;
|
|
488
472
|
if (internal.numberOfItems !== undefined) {
|
|
489
473
|
return internal.numberOfItems;
|
|
490
474
|
} else {
|
|
491
|
-
return
|
|
475
|
+
return rowIds.value.size;
|
|
492
476
|
}
|
|
493
477
|
});
|
|
494
478
|
|
|
@@ -527,38 +511,29 @@ function checkSearchExpand(force) {
|
|
|
527
511
|
}
|
|
528
512
|
|
|
529
513
|
const dataRowsSelected = ref(props.rowsSelected);
|
|
530
|
-
|
|
531
|
-
return (
|
|
532
|
-
props.stickyBatchActive ||
|
|
533
|
-
dataRowsSelected.value.length > 0 ||
|
|
534
|
-
headingChecked.value
|
|
535
|
-
);
|
|
536
|
-
});
|
|
514
|
+
provide('rows-selected', dataRowsSelected);
|
|
537
515
|
|
|
538
516
|
const headingChecked = ref(false);
|
|
539
|
-
|
|
540
517
|
watch(
|
|
541
|
-
() =>
|
|
518
|
+
() => dataRowsSelected,
|
|
542
519
|
() => {
|
|
543
|
-
const rows = store.rows(uid);
|
|
544
520
|
headingChecked.value =
|
|
545
|
-
|
|
521
|
+
rowIds.value.size > 0 &&
|
|
522
|
+
dataRowsSelected.value.length === rowIds.value.size;
|
|
546
523
|
},
|
|
547
524
|
{ deep: true }
|
|
548
525
|
);
|
|
526
|
+
|
|
527
|
+
const batchActive = computed(() => {
|
|
528
|
+
return (
|
|
529
|
+
props.stickyBatchActive ||
|
|
530
|
+
dataRowsSelected.value.length > 0 ||
|
|
531
|
+
headingChecked.value
|
|
532
|
+
);
|
|
533
|
+
});
|
|
534
|
+
|
|
549
535
|
function updateRowsSelected() {
|
|
550
|
-
dataRowsSelected.value = [];
|
|
551
|
-
const rows = store.rows(uid);
|
|
552
|
-
for (const i in rows) {
|
|
553
|
-
let child = rows[i];
|
|
554
|
-
const checked = props.rowsSelected.includes(child.value);
|
|
555
|
-
store.updateRow(uid, { id: child.id, isChecked: checked });
|
|
556
|
-
|
|
557
|
-
if (checked) {
|
|
558
|
-
dataRowsSelected.value.push(child.value);
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
headingChecked.value = dataRowsSelected.value.length === rows.length;
|
|
536
|
+
dataRowsSelected.value = [...props.rowsSelected];
|
|
562
537
|
}
|
|
563
538
|
|
|
564
539
|
const emit = defineEmits([
|
|
@@ -572,7 +547,6 @@ const emit = defineEmits([
|
|
|
572
547
|
'pagination',
|
|
573
548
|
]);
|
|
574
549
|
const searchValue = ref(props.initialSearchValue);
|
|
575
|
-
const clearSearchVisible = ref(false);
|
|
576
550
|
function onClearClick() {
|
|
577
551
|
searchValue.value = '';
|
|
578
552
|
clearSearchVisible.value = false;
|
|
@@ -584,87 +558,83 @@ function onClearClick() {
|
|
|
584
558
|
}
|
|
585
559
|
function onHeadingCheckChange() {
|
|
586
560
|
// check /uncheck all children
|
|
587
|
-
dataRowsSelected.value = [];
|
|
588
|
-
|
|
589
|
-
for (const child of rows) {
|
|
590
|
-
if (headingChecked.value) {
|
|
591
|
-
dataRowsSelected.value.push(child.value);
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
if (child.isChecked !== headingChecked.value) {
|
|
595
|
-
store.updateRow(uid, { id: child.id, isChecked: headingChecked.value });
|
|
596
|
-
|
|
597
|
-
emit('row-select-change', {
|
|
598
|
-
value: child.value,
|
|
599
|
-
selected: headingChecked.value,
|
|
600
|
-
});
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
emit('row-select-changes', dataRowsSelected.value);
|
|
604
|
-
emit('update:rowsSelected', dataRowsSelected.value);
|
|
561
|
+
if (headingChecked.value) dataRowsSelected.value = [...rowIds.value];
|
|
562
|
+
else dataRowsSelected.value = [];
|
|
605
563
|
}
|
|
606
564
|
function deselect() {
|
|
607
565
|
headingChecked.value = false;
|
|
608
566
|
onHeadingCheckChange();
|
|
609
567
|
}
|
|
610
|
-
function onRowCheckChange(payload) {
|
|
611
|
-
const { value, checked } = payload;
|
|
612
|
-
let modelSet = new Set(dataRowsSelected.value);
|
|
613
|
-
|
|
614
|
-
if (!checked) {
|
|
615
|
-
modelSet.delete(value);
|
|
616
|
-
} else {
|
|
617
|
-
modelSet.add(value);
|
|
618
|
-
}
|
|
619
|
-
dataRowsSelected.value = Array.from(modelSet);
|
|
620
|
-
const rows = store.rows(uid);
|
|
621
|
-
headingChecked.value = dataRowsSelected.value.length === rows.length;
|
|
622
568
|
|
|
569
|
+
const previousEmit = ref([...props.rowsSelected]);
|
|
570
|
+
watch(
|
|
571
|
+
dataRowsSelected,
|
|
572
|
+
() => {
|
|
573
|
+
// was tempted to use Set.symmetricDifference but support for that was only
|
|
574
|
+
// add in Feb/June 2024
|
|
575
|
+
const diff = dataRowsSelected.value
|
|
576
|
+
.filter(x => !previousEmit.value.includes(x))
|
|
577
|
+
.concat(
|
|
578
|
+
previousEmit.value.filter(x => !dataRowsSelected.value.includes(x))
|
|
579
|
+
);
|
|
580
|
+
if (diff.length > 0) {
|
|
581
|
+
emit('row-select-changes', dataRowsSelected.value);
|
|
582
|
+
emit('update:rowsSelected', dataRowsSelected.value);
|
|
583
|
+
previousEmit.value = [...dataRowsSelected.value];
|
|
584
|
+
}
|
|
585
|
+
},
|
|
586
|
+
{ deep: true }
|
|
587
|
+
);
|
|
588
|
+
function onRowCheckChange(value, checked) {
|
|
623
589
|
emit('row-select-change', { value, selected: checked });
|
|
624
|
-
emit('row-select-changes', dataRowsSelected.value);
|
|
625
|
-
emit('update:rowsSelected', dataRowsSelected.value);
|
|
626
590
|
}
|
|
591
|
+
provide('cv:check-change', onRowCheckChange);
|
|
592
|
+
|
|
627
593
|
function onMenuItemClick(val) {
|
|
628
594
|
emit('overflow-menu-click', val);
|
|
629
595
|
}
|
|
596
|
+
provide('cv:click', onMenuItemClick);
|
|
597
|
+
|
|
630
598
|
function onInternalSearch() {
|
|
631
599
|
clearSearchVisible.value = searchValue.value.length > 0;
|
|
632
600
|
// eslint-disable-next-line vue/require-explicit-emits
|
|
633
601
|
emit('search', searchValue.value);
|
|
634
602
|
}
|
|
603
|
+
|
|
604
|
+
const headingIds = ref(new Set());
|
|
605
|
+
provide('heading-ids', headingIds);
|
|
606
|
+
const currentSortHeadingId = ref(null);
|
|
607
|
+
provide('current-sort-heading-id', currentSortHeadingId);
|
|
635
608
|
function onSort(payload) {
|
|
636
609
|
const { heading, value } = payload;
|
|
637
|
-
const headings =
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
const column = headings[colIndex];
|
|
641
|
-
if (column.id === heading.id) {
|
|
642
|
-
store.updateHeading(uid, { ...column, order: value });
|
|
643
|
-
index = colIndex;
|
|
644
|
-
} else {
|
|
645
|
-
store.updateHeading(uid, { ...column, order: 'none' });
|
|
646
|
-
}
|
|
647
|
-
}
|
|
610
|
+
const headings = Array.from(headingIds.value);
|
|
611
|
+
currentSortHeadingId.value = heading.id;
|
|
612
|
+
const index = headings.indexOf(heading.id);
|
|
648
613
|
emit('sort', { index, order: value, name: heading.name });
|
|
649
614
|
}
|
|
615
|
+
provide('cv:sort', onSort);
|
|
650
616
|
|
|
651
617
|
// are all rows expanded
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
618
|
+
/** @type {Ref<Set<String>>} */
|
|
619
|
+
const expandedRowIds = ref(new Set());
|
|
620
|
+
provide('expanded-row-ids', expandedRowIds);
|
|
621
|
+
|
|
622
|
+
const dataExpandAll = computed(
|
|
623
|
+
() => expandedRowIds.value.size === rowIds.value.size
|
|
624
|
+
);
|
|
655
625
|
function toggleExpandAll() {
|
|
656
626
|
const toggle = !dataExpandAll.value;
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
}
|
|
627
|
+
if (toggle) {
|
|
628
|
+
rowIds.value.forEach(rowId => expandedRowIds.value.add(rowId));
|
|
629
|
+
} else expandedRowIds.value.clear();
|
|
661
630
|
}
|
|
662
631
|
|
|
663
632
|
/**
|
|
664
633
|
* A child row is changed
|
|
665
|
-
* @param {{
|
|
634
|
+
* @param {{id:string, value:string, expandable:string, isExpanded:boolean, isChecked:boolean}} row
|
|
666
635
|
*/
|
|
667
636
|
function onCvExpandedChange(row) {
|
|
668
637
|
emit('row-expanded', row);
|
|
669
638
|
}
|
|
639
|
+
provide('cv:expanded-change', onCvExpandedChange);
|
|
670
640
|
</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
|
-
|
|
88
|
-
|
|
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
|
-
|
|
95
|
-
const el = ref(null);
|
|
81
|
+
const headingIds = inject('heading-ids', ref(new Set()));
|
|
96
82
|
onMounted(() => {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
-
|
|
91
|
+
headingIds.value.delete(cvId.value);
|
|
92
|
+
sortableHeaders.value.delete(cvId.value);
|
|
118
93
|
});
|
|
119
|
-
|
|
120
|
-
|
|
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:
|
|
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
|
-
|
|
130
|
-
|
|
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(() => {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
v-bind="$attrs"
|
|
34
34
|
:id="cvId"
|
|
35
35
|
ref="row"
|
|
36
|
-
:value="
|
|
36
|
+
:value="rowValue"
|
|
37
37
|
class="cv-data-table-row"
|
|
38
38
|
:row-id="cvId"
|
|
39
39
|
@checked-change="onCheckedChange"
|
|
@@ -50,15 +50,13 @@ import {
|
|
|
50
50
|
computed,
|
|
51
51
|
onBeforeUnmount,
|
|
52
52
|
onMounted,
|
|
53
|
-
onUpdated,
|
|
54
53
|
ref,
|
|
55
54
|
useAttrs,
|
|
56
55
|
useSlots,
|
|
57
56
|
watch,
|
|
58
57
|
inject,
|
|
58
|
+
onUpdated,
|
|
59
59
|
} from 'vue';
|
|
60
|
-
import store from './cvDataTableStore';
|
|
61
|
-
import { getBus } from '../../global/component-utils/event-bus';
|
|
62
60
|
|
|
63
61
|
const props = defineProps({
|
|
64
62
|
/** The value associated with the input (required for tables with batch actions) */
|
|
@@ -68,85 +66,88 @@ const props = defineProps({
|
|
|
68
66
|
...propsCvId,
|
|
69
67
|
});
|
|
70
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
|
+
);
|
|
71
77
|
|
|
72
78
|
/** @type {Ref<Set<String>>} */
|
|
73
79
|
const expandingRowIds = inject('expanding-row-ids', ref(new Set()));
|
|
74
80
|
const dataExpandable = ref(false);
|
|
75
|
-
watch(dataExpandable,
|
|
76
|
-
if (
|
|
81
|
+
watch(dataExpandable, value => {
|
|
82
|
+
if (value && !expandingRowIds.value.has('table-expand-row')) {
|
|
83
|
+
console.warn(
|
|
84
|
+
`row ${cvId.value} is expandable but the expandable property is not set to true on the table`
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
if (dataExpandable.value) expandingRowIds.value.add(cvId.value);
|
|
77
88
|
else expandingRowIds.value?.delete(cvId.value);
|
|
78
89
|
});
|
|
79
90
|
const dataSomeExpandingRows = computed(() => {
|
|
80
91
|
return expandingRowIds.value?.size > 0;
|
|
81
92
|
});
|
|
82
|
-
|
|
83
93
|
const attrs = useAttrs();
|
|
94
|
+
const rowIds = inject('row-ids', ref(new Set()));
|
|
95
|
+
const expandedRowIds = inject('expanded-row-ids', ref(new Set()));
|
|
96
|
+
|
|
84
97
|
const slots = useSlots();
|
|
85
98
|
const row = ref(null);
|
|
86
|
-
const
|
|
87
|
-
let bus;
|
|
88
|
-
onMounted(() => {
|
|
89
|
-
const el = row.value?.$el;
|
|
90
|
-
const pe = el?.closest('.cv-data-table');
|
|
91
|
-
parent.value = pe?.getAttribute('id');
|
|
92
|
-
if (parent.value) {
|
|
93
|
-
bus = getBus(parent);
|
|
94
|
-
store.getTable(parent);
|
|
95
|
-
} else console.warn('data table not found');
|
|
99
|
+
const rowsSelected = inject('rows-selected');
|
|
96
100
|
|
|
101
|
+
onMounted(() => {
|
|
97
102
|
dataExpandable.value = !!slots.expandedContent;
|
|
98
|
-
|
|
99
|
-
if (
|
|
100
|
-
console.error(
|
|
101
|
-
`CvDataTable: Duplicate ID specified for CvDataTableRow, may cause issues. {id: ${cvId.value}, value: ${attrs.value}}`
|
|
102
|
-
);
|
|
103
|
-
else
|
|
104
|
-
store.updateRow(parent, {
|
|
105
|
-
id: cvId.value,
|
|
106
|
-
value: attrs.value,
|
|
107
|
-
expandable: dataExpandable.value,
|
|
108
|
-
isExpanded: props.expanded,
|
|
109
|
-
isChecked: false,
|
|
110
|
-
});
|
|
103
|
+
rowIds.value.add(cvId.value);
|
|
104
|
+
if (props.expanded) expandedRowIds.value.add(cvId.value);
|
|
111
105
|
});
|
|
112
106
|
onUpdated(() => {
|
|
113
|
-
const curr = dataExpandable.value;
|
|
114
107
|
dataExpandable.value = !!slots.expandedContent;
|
|
115
|
-
if (dataExpandable.value !== curr)
|
|
116
|
-
store.updateRow(parent, {
|
|
117
|
-
id: cvId.value,
|
|
118
|
-
expandable: dataExpandable.value,
|
|
119
|
-
});
|
|
120
108
|
});
|
|
121
109
|
onBeforeUnmount(() => {
|
|
122
|
-
|
|
110
|
+
rowIds.value.delete(cvId.value);
|
|
111
|
+
expandingRowIds.value.delete(cvId.value);
|
|
112
|
+
expandedRowIds.value.delete(cvId.value);
|
|
113
|
+
const index = rowsSelected.value.indexOf(rowValue.value);
|
|
114
|
+
if (index > -1) rowsSelected.value.splice(index, 1);
|
|
123
115
|
});
|
|
124
116
|
const dataExpanded = computed(() => {
|
|
125
|
-
return Boolean(props.expanded ||
|
|
117
|
+
return Boolean(props.expanded || expandedRowIds.value.has(cvId.value));
|
|
126
118
|
});
|
|
127
119
|
watch(
|
|
128
120
|
() => props.expanded,
|
|
129
121
|
() => {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
isExpanded: props.expanded,
|
|
133
|
-
});
|
|
122
|
+
if (props.expanded) expandedRowIds.value.add(cvId.value);
|
|
123
|
+
else expandingRowIds.value.delete(cvId.value);
|
|
134
124
|
}
|
|
135
125
|
);
|
|
136
126
|
|
|
127
|
+
const notifyExpandedChange = inject('cv:expanded-change');
|
|
128
|
+
|
|
137
129
|
function onExpandedChange(val) {
|
|
138
|
-
|
|
139
|
-
store.updateRow(parent, {
|
|
130
|
+
notifyExpandedChange({
|
|
140
131
|
id: cvId.value,
|
|
132
|
+
value: rowValue.value,
|
|
133
|
+
expandable: expandingRowIds.value.has(cvId.value),
|
|
141
134
|
isExpanded: val,
|
|
135
|
+
isChecked: rowsSelected.value.includes(rowValue.value),
|
|
142
136
|
});
|
|
143
|
-
bus?.emit('cv:expanded-change', row);
|
|
144
137
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
138
|
+
|
|
139
|
+
// Manage the checkmark on the row. Notify the table if it changes.
|
|
140
|
+
const notifyCheckedChange = inject('cv:check-change');
|
|
141
|
+
function onCheckedChange(isChecked) {
|
|
142
|
+
if (!rowsSelected.value) return;
|
|
143
|
+
const index = rowsSelected.value.indexOf(rowValue.value);
|
|
144
|
+
if (isChecked) {
|
|
145
|
+
// if the row value is not already in the rowsSelected array, add it.
|
|
146
|
+
if (index === -1) rowsSelected.value.push(rowValue.value);
|
|
147
|
+
} else {
|
|
148
|
+
// if the row value is in the rowsSelected array, delete it.
|
|
149
|
+
if (index > -1) rowsSelected.value.splice(index, 1);
|
|
150
|
+
}
|
|
151
|
+
notifyCheckedChange(attrs.value, isChecked);
|
|
151
152
|
}
|
|
152
153
|
</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
|
-
|
|
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
|
-
() =>
|
|
158
|
+
() => rowsSelected,
|
|
170
159
|
() => {
|
|
171
|
-
|
|
172
|
-
|
|
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
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
sbCompPrefix,
|
|
3
|
-
storyParametersObject,
|
|
4
|
-
} from '../../global/storybook-utils';
|
|
1
|
+
import { storyParametersObject } from '../../global/storybook-utils';
|
|
5
2
|
|
|
6
3
|
import { CvDatePicker } from '.';
|
|
7
4
|
import { CvDatePickerSkeleton } from '.';
|
|
@@ -20,7 +17,7 @@ tomorrow.setDate(now.getDate() + 1);
|
|
|
20
17
|
nextWeek.setDate(now.getDate() + 7);
|
|
21
18
|
|
|
22
19
|
export default {
|
|
23
|
-
title:
|
|
20
|
+
title: 'Component/CvDatePicker',
|
|
24
21
|
component: CvDatePicker,
|
|
25
22
|
parameters: {
|
|
26
23
|
a11y: {
|