@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.
- package/README.md +9 -0
- package/dist/carbon-vue-3.common.js +884 -324
- package/dist/carbon-vue-3.common.js.map +1 -1
- package/dist/carbon-vue-3.umd.js +884 -324
- 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/dist/web-types.json +30 -3
- package/package.json +8 -5
- package/src/components/CvAccordion/CvAccordion.stories.mdx +11 -2
- package/src/components/CvAccordion/CvAccordionItem.vue +1 -1
- package/src/components/CvBreadcrumb/CvBreadcrumb.vue +1 -0
- package/src/components/CvBreadcrumb/CvBreadcrumbItem.vue +1 -0
- package/src/components/CvButton/CvButton.vue +1 -0
- package/src/components/CvButton/CvButtonSet.vue +1 -0
- package/src/components/CvButton/CvIconButton.vue +2 -1
- package/src/components/CvCheckbox/CvCheckbox.vue +2 -1
- package/src/components/CvCodeSnippet/CvCodeSnippet.vue +8 -3
- package/src/components/CvCodeSnippet/_CviCodeSnippetInline.vue +1 -0
- package/src/components/CvCodeSnippet/_CviCodeSnippetMultiline.vue +1 -0
- package/src/components/CvCodeSnippet/_CviCodeSnippetOneline.vue +1 -0
- package/src/components/CvComboBox/CvComboBox.vue +2 -1
- package/src/components/CvDataTable/CvDataTable.stories.mdx +26 -49
- package/src/components/CvDataTable/CvDataTable.vue +71 -52
- package/src/components/CvDataTable/CvDataTableRow.vue +11 -3
- package/src/components/CvDataTable/_CvDataTableRowInner.vue +18 -8
- package/src/components/CvDataTable/cvDataTableStore.js +1 -27
- package/src/components/CvDatePicker/CvDatePicker.stories.js +30 -6
- package/src/components/CvDatePicker/CvDatePicker.vue +24 -19
- package/src/components/CvDropdown/CvDropdown.stories.mdx +12 -2
- package/src/components/CvDropdown/CvDropdown.vue +4 -3
- package/src/components/CvFileUploader/CvFileUploader.vue +2 -2
- package/src/components/CvList/CvList.vue +1 -0
- package/src/components/CvList/CvListItem.vue +1 -1
- package/src/components/CvNotification/CvInlineNotification.vue +1 -0
- package/src/components/CvNotification/CvToastNotification.stories.js +65 -5
- package/src/components/CvNotification/CvToastNotification.vue +1 -0
- package/src/components/CvNotification/CvToastNotificationTemplate.mdx +17 -0
- package/src/components/CvNumberInput/CvNumberInput.vue +3 -3
- package/src/components/CvOverflowMenu/CvOverflowMenuItem.vue +2 -2
- package/src/components/CvPagination/CvPagination.stories.mdx +22 -15
- package/src/components/CvPagination/CvPagination.vue +16 -1
- package/src/components/CvProgress/CvProgress.stories.mdx +29 -7
- package/src/components/CvProgress/CvProgress.vue +1 -0
- package/src/components/CvProgress/CvProgressStep.vue +2 -0
- package/src/components/CvSlider/CvSlider.vue +1 -1
- package/src/components/CvTag/CvTag.stories.js +0 -2
- package/src/components/CvTag/CvTag.vue +6 -4
- package/src/index.js +112 -0
- package/telemetry.yml +8 -0
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
<thead>
|
|
133
133
|
<tr>
|
|
134
134
|
<th
|
|
135
|
-
v-if="
|
|
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="
|
|
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 =
|
|
401
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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 {
|
|
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
|
|
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 =
|
|
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 "{{buttonLabel()}}"</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
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
196
|
-
|
|
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
|
-
|
|
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
|
-
|
|
154
|
-
|
|
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"
|