@carbon/vue 3.0.20 → 3.0.21

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "framework": "vue",
3
3
  "name": "@carbon/vue",
4
- "version": "3.0.19",
4
+ "version": "3.0.20",
5
5
  "contributions": {
6
6
  "html": {
7
7
  "description-markup": "markdown",
@@ -1342,8 +1342,18 @@
1342
1342
  "name": "CvDataTableRow",
1343
1343
  "description": "",
1344
1344
  "attributes": [
1345
+ {
1346
+ "name": "value",
1347
+ "description": "The value associated with the input (required for tables with batch actions)",
1348
+ "value": {
1349
+ "kind": "expression",
1350
+ "type": "string"
1351
+ },
1352
+ "default": "undefined"
1353
+ },
1345
1354
  {
1346
1355
  "name": "expanded",
1356
+ "description": "This row will be initially expanded",
1347
1357
  "value": {
1348
1358
  "kind": "expression",
1349
1359
  "type": "boolean"
@@ -1504,6 +1514,9 @@
1504
1514
  "events": [
1505
1515
  {
1506
1516
  "name": "update:modelValue"
1517
+ },
1518
+ {
1519
+ "name": "dateChange"
1507
1520
  }
1508
1521
  ],
1509
1522
  "slots": [
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@carbon/vue",
3
3
  "license": "Apache-2.0",
4
- "version": "3.0.20",
4
+ "version": "3.0.21",
5
5
  "description": "A collection of components for the Carbon Design System built using Vue.js",
6
6
  "packageManager": "yarn@3.2.0",
7
7
  "main": "dist/carbon-vue-3.umd.min.js",
@@ -15,7 +15,7 @@ export default {
15
15
  argTypes: {
16
16
  ...storybookControlsFromProps(propsCvCheck),
17
17
  value: {
18
- type: 'string',
18
+ type: { raw: 'string', required: true },
19
19
  description:
20
20
  'The value associated with the input (this is also the value that is sent on submit)',
21
21
  table: {
@@ -68,6 +68,7 @@ const Template = args => {
68
68
 
69
69
  export const Default = Template.bind({});
70
70
  Default.args = { label: 'checkbox', value: 'check-1' };
71
+ Default.parameters = { controls: { sort: 'requiredFirst' } };
71
72
  Default.parameters = storyParametersObject(
72
73
  Default.parameters,
73
74
  template,
@@ -81,7 +82,7 @@ const templateVModel = `<div>
81
82
  </cv-checkbox>
82
83
  <div style="margin-top:1rem; background-color: #888888; padding:1rem"><div style="font-size: 150%">Sample interaction</div>
83
84
  <label for="checkbox">V-model: Check 1:</label>
84
- <input id="checkbox" type="checkbox" @change="(ev) => {modelValue = ev.currentTarget.checked}" />
85
+ <input id="checkbox" type="checkbox" v-model="modelValue" />
85
86
  <div>Checked: <span style="font-weight: bold;">{{modelValue}}</span></div>
86
87
  </div>
87
88
  </div>
@@ -103,6 +104,7 @@ vModel.args = {
103
104
  label: 'checkbox',
104
105
  value: 'check-1',
105
106
  };
107
+ vModel.parameters = { controls: { sort: 'requiredFirst' } };
106
108
  vModel.parameters = storyParametersObject(
107
109
  vModel.parameters,
108
110
  templateVModel,
@@ -21,8 +21,10 @@ const testData = ref([
21
21
  { index:"6", name:"Fortran", year:1957, oo:"No", purpose:"Engineering applications", standard:"ANSI", desc: "Fortran was originally developed by IBM in the 1950s for scientific and engineering applications, and subsequently came to dominate scientific computing."},
22
22
  { index:"7", name:"Go", year:2009, oo:"Maybe", purpose:"Networked applications", standard:"Go Spec", desc: "Go's designers were primarily motivated by their shared dislike of C++."},
23
23
  ]);
24
+ const sortOpts = ref({index: "0", order: "none", name: "name"})
24
25
  function sortTestData(opts) {
25
26
  action('sort')(opts)
27
+ sortOpts.value = opts
26
28
  if (opts.order === 'none')
27
29
  return testData.value.sort((a, b) => a.index.localeCompare(b.index, 'en', { sensitivity: 'base' }));
28
30
  let direction = 1
@@ -32,6 +34,16 @@ function sortTestData(opts) {
32
34
  else if (opts.name === 'year')
33
35
  return testData.value.sort((a, b) => direction * (a.year - b.year));
34
36
  }
37
+ // duplicate the test data
38
+ const originalTestData = ref(JSON.parse(JSON.stringify(testData.value)))
39
+ const searchOpts = ref("")
40
+ function searchTestData(opts) {
41
+ action('search')(opts)
42
+ searchOpts.value = opts
43
+ if (!opts) testData.value = JSON.parse(JSON.stringify(originalTestData.value))
44
+ else testData.value = originalTestData.value.filter(data => data.name.indexOf(opts) > -1)
45
+ return sortTestData(sortOpts.value)
46
+ }
35
47
 
36
48
  <Meta title={`${sbCompPrefix}/CvDataTable`} component={CvDataTable} />
37
49
 
@@ -59,7 +71,7 @@ setup() {
59
71
  template: undefined},
60
72
  trashIcon: TrashCanIcon,
61
73
  onSort: sortTestData,
62
- onSearch: action('search'),
74
+ onSearch: searchTestData,
63
75
  onRowSelectChange: action('row-select-change'),
64
76
  onRowSelectChanges: action('row-select-changes'),
65
77
  onOverflowMenuClick: action('overflow-menu-click'),
@@ -77,6 +89,8 @@ setup() {
77
89
  skeletonTitle: args.title,
78
90
  skeletonHelper: args.helperText,
79
91
  testData,
92
+ originalTestData,
93
+ searchOpts
80
94
  };
81
95
  },
82
96
  // And then the `args` are bound to your component with `v-bind="args"`
@@ -91,6 +105,7 @@ const defaultTemplate = `
91
105
  @overflow-menu-click="onOverflowMenuClick"
92
106
  @row-expanded="onRowExpanded"
93
107
  @pagination="onPagination"
108
+ :initialSearchValue="searchOpts"
94
109
  >
95
110
  <template v-if="useBatchActions" #batch-actions>
96
111
  <cv-button :icon="trashIcon" @click="onDelete">Delete</cv-button>
@@ -135,6 +150,7 @@ const expandingRowsTemplate = defaultTemplate.replace(
135
150
  "<!-- Add optional expanding data here -->",
136
151
  `<template #expandedContent>{{row.desc}}</template>`)
137
152
  .replace('@search="onSearch"', '')
153
+ .replace('testData', 'originalTestData')
138
154
  const skeletonTemplate = `
139
155
  <cv-data-table-skeleton
140
156
  :columns="skeletonCols"
@@ -160,7 +176,10 @@ const skeletonTemplate = `
160
176
  - Sorting, filtering and pagination are the responsibility of the component user. This component raises events to facilitate this.
161
177
  For example the test data is sorted like this but this is very specific to this data. Users will need to provide their own sort and filtering.
162
178
  ```javascript
179
+ // sort example
180
+ const sortOpts = ref({index: "0", order: "none", name: "name"})
163
181
  function sortTestData(opts) {
182
+ sortOpts.value = opts // remember this so it can be used in filtering
164
183
  if (opts.order === 'none')
165
184
  return testData.value.sort((a, b) => a.index.localeCompare(b.index, 'en', { sensitivity: 'base' }));
166
185
  let direction = 1
@@ -170,6 +189,12 @@ const skeletonTemplate = `
170
189
  else if (opts.name === 'year')
171
190
  return testData.value.sort((a, b) => direction * (a.year - b.year));
172
191
  }
192
+ // filter example
193
+ function searchTestData(opts) {
194
+ if (!opts) testData.value = allData.value
195
+ else testData.value = allData.value.filter(data => data.name.indexOf(opts) > -1)
196
+ return sortTestData(sortOpts.value)
197
+ }
173
198
  ```
174
199
  - The search bar appears only if the search event is listened for.
175
200
 
@@ -178,6 +203,7 @@ const skeletonTemplate = `
178
203
  - aria-label-expand-row: Aria label for expanding row expansion button. default: 'Expand current row'
179
204
  - aria-label-collapse-row: Aria label for expanding row collapse button. default: 'Collapse current row'
180
205
  - expanded: initial state of the expanded row
206
+ - value: this is the value assign to the checkbox for tables with batch actions.
181
207
 
182
208
  **Migration notes:**
183
209
 
@@ -190,9 +216,6 @@ completion for it. See [discussion](https://github.com/vuejs/core/issues/3432) f
190
216
  `search` emit is still emitted it is just not defined directly on the component.
191
217
  - The React does not seem to have an "autoWidth" property. It is still supported here but likely the better choice is `staticWidth`.
192
218
  - Row sizes in the React component are 'xs', 'sm', 'md', 'lg', & 'xl'. The rowSizes from Vue2 are still supported.
193
- - The Vue 3 implementation uses an internal store to manage the state of the table. You can see updates
194
- to the state by setting the debug variable in the local storage. `localStorage.debug="cv:data-table-store"`
195
- and then reloading the page.
196
219
  - If you were using something like `this.$refs.tableEditPath.batchActive = true` to force batch actions to show even
197
220
  when no items were select, please now use the new property `stickyBatchActive`.
198
221
 
@@ -541,7 +541,8 @@ watch(
541
541
  () => store.state[uid.value],
542
542
  () => {
543
543
  const rows = store.rows(uid);
544
- headingChecked.value = dataRowsSelected.value.length === rows.length;
544
+ headingChecked.value =
545
+ rows.length > 0 && dataRowsSelected.value.length === rows.length;
545
546
  },
546
547
  { deep: true }
547
548
  );
@@ -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="value"
35
37
  class="cv-data-table-row"
36
38
  :row-id="cvId"
37
39
  @checked-change="onCheckedChange"
@@ -59,6 +61,9 @@ import store from './cvDataTableStore';
59
61
  import { getBus } from '../../global/component-utils/event-bus';
60
62
 
61
63
  const props = defineProps({
64
+ /** The value associated with the input (required for tables with batch actions) */
65
+ value: { type: String, default: undefined },
66
+ /** This row will be initially expanded */
62
67
  expanded: Boolean,
63
68
  ...propsCvId,
64
69
  });
@@ -142,6 +147,6 @@ function onCheckedChange(val) {
142
147
  id: cvId.value,
143
148
  isChecked: val,
144
149
  });
145
- bus?.emit('cv:check-change', { value: attrs.value, checked: val });
150
+ bus?.emit('cv:check-change', { value: props.value, checked: val });
146
151
  }
147
152
  </script>
@@ -44,7 +44,7 @@ export default {
44
44
 
45
45
  const template = `
46
46
  <div>
47
- <cv-date-picker v-bind="args" @change="onChange" :value="now">
47
+ <cv-date-picker v-bind="args" :value="now" @change="onChange">
48
48
  </cv-date-picker>
49
49
  </div>
50
50
  `;
@@ -64,7 +64,12 @@ export const Default = Template.bind({});
64
64
  Default.args = initArgs;
65
65
  Default.parameters = {
66
66
  controls: {
67
- exclude: ['update:modelValue', 'invalid-message', 'modelValue'],
67
+ exclude: [
68
+ 'update:modelValue',
69
+ 'invalid-message',
70
+ 'modelValue',
71
+ 'dateChange',
72
+ ],
68
73
  },
69
74
  };
70
75
  Default.parameters = storyParametersObject(
@@ -78,14 +83,13 @@ Default.parameters = storyParametersObject(
78
83
  const modelValue = ref(now);
79
84
  const templateVModel = `
80
85
  <div>
81
- <cv-date-picker v-bind="args" @change="onChange" v-model="modelValue">
86
+ <cv-date-picker v-bind="args" v-model="modelValue">
82
87
  </cv-date-picker>
83
88
  </div>
84
89
  <div style="margin-top:2rem; background-color: #888888; padding:1rem">
85
90
  <div style="font-size: 150%;">Sample interaction</div>
86
91
  <label for="date-model" style='margin-right: 0.5rem'>V-model:</label>
87
- <input id="date-model" type="text" :value="modelValue.startDate || modelValue" @change="ev => { if (args.kind === 'range') { modelValue.startDate = ev.currentTarget.value } else { modelValue = ev.currentTarget.value } }"/>
88
- <input v-if="args.kind === 'range'" id="date-model" type="text" :value="modelValue.endDate" @change="ev => modelValue.endDate = ev.currentTarget.value"/>
92
+ <input id="date-model" type="text" :value="modelValue" @change="ev => { modelValue = ev.currentTarget.value }"/>
89
93
  </div>
90
94
  `;
91
95
 
@@ -96,7 +100,6 @@ const TemplateVModel = args => {
96
100
  args,
97
101
  modelValue,
98
102
  now,
99
- onChange: action('change'),
100
103
  }),
101
104
  template: templateVModel,
102
105
  };
@@ -106,7 +109,14 @@ export const vModel = TemplateVModel.bind({});
106
109
  vModel.args = initArgs;
107
110
  vModel.parameters = {
108
111
  controls: {
109
- exclude: ['update:modelValue', 'invalid-message', 'modelValue'],
112
+ exclude: [
113
+ 'update:modelValue',
114
+ 'invalid-message',
115
+ 'modelValue',
116
+ 'kind',
117
+ 'value',
118
+ 'dateChange',
119
+ ],
110
120
  },
111
121
  };
112
122
  vModel.parameters = storyParametersObject(
@@ -115,11 +125,58 @@ vModel.parameters = storyParametersObject(
115
125
  vModel.args
116
126
  );
117
127
 
128
+ /* range v-model */
129
+ const rangeValue = ref({ startDate: now, endDate: now });
130
+ const templateRangeVModel = `
131
+ <div>
132
+ <cv-date-picker v-bind="args" kind="range" v-model="rangeValue">
133
+ </cv-date-picker>
134
+ </div>
135
+ <div style="margin-top:2rem; background-color: #888888; padding:1rem">
136
+ <div style="font-size: 150%;">Sample range interaction</div>
137
+ <label for="date-model-1" style='margin-right: 0.5rem'>V-model:</label>
138
+ <input id="date-model-1" type="text" :value="rangeValue.startDate" @change="ev => { rangeValue.startDate = ev.currentTarget.value }"/>
139
+ <input id="date-model-2" type="text" :value="rangeValue.endDate" @change="ev => rangeValue.endDate = ev.currentTarget.value"/>
140
+ </div>
141
+ `;
142
+
143
+ const TemplateRangeVModel = args => {
144
+ return {
145
+ components: { CvDatePicker },
146
+ setup: () => ({
147
+ args,
148
+ rangeValue,
149
+ now,
150
+ }),
151
+ template: templateRangeVModel,
152
+ };
153
+ };
154
+
155
+ export const rangeVmodel = TemplateRangeVModel.bind({});
156
+ rangeVmodel.args = initArgs;
157
+ rangeVmodel.parameters = {
158
+ controls: {
159
+ exclude: [
160
+ 'update:modelValue',
161
+ 'invalid-message',
162
+ 'modelValue',
163
+ 'kind',
164
+ 'value',
165
+ 'dateChange',
166
+ ],
167
+ },
168
+ };
169
+ rangeVmodel.parameters = storyParametersObject(
170
+ rangeVmodel.parameters,
171
+ templateRangeVModel,
172
+ rangeVmodel.args
173
+ );
174
+
118
175
  /* INVALID MESSAGE STORY */
119
176
 
120
177
  const templateInvalidMessage = `
121
178
  <div>
122
- <cv-date-picker v-bind="args" @change="onChange" :value="now">
179
+ <cv-date-picker v-bind="args" :value="now" @change="onChange">
123
180
  </cv-date-picker>
124
181
  </div>
125
182
  `;
@@ -153,7 +210,7 @@ InvalidMessage.parameters = storyParametersObject(
153
210
 
154
211
  const templateInvalidMessageSlot = `
155
212
  <div>
156
- <cv-date-picker v-bind="args" @change="onChange" :value="now">
213
+ <cv-date-picker v-bind="args" :value="now" @change="onChange">
157
214
  <template #invalid-message>Invalid date slot</template>
158
215
  </cv-date-picker>
159
216
  </div>
@@ -194,7 +251,7 @@ InvalidMessageSlot.parameters = storyParametersObject(
194
251
  const singleValue = ref(now);
195
252
  const templateSingleUsingDate = `
196
253
  <div>
197
- <cv-date-picker v-bind="args" @change="onChange" kind="single" v-model="singleValue">
254
+ <cv-date-picker v-bind="args" kind="single" v-model="singleValue" @dateChange="onDateChange">
198
255
  </cv-date-picker>
199
256
  </div>`;
200
257
  const templateSingleUsingDateVModel = `
@@ -212,7 +269,7 @@ const TemplateSingleUsingDate = args => {
212
269
  args,
213
270
  now,
214
271
  singleValue,
215
- onChange: action('change'),
272
+ onDateChange: action('dateChange'),
216
273
  }),
217
274
  template: templateSingleUsingDate + templateSingleUsingDateVModel,
218
275
  };
@@ -258,7 +315,7 @@ function changeMaxDate(inc) {
258
315
  }
259
316
  const templateSingleUsingMinMax = `
260
317
  <div>
261
- <cv-date-picker v-bind='args' @change="onChange" kind="single" :value="now" :cal-options="calOptions">
318
+ <cv-date-picker v-bind='args' kind="single" :value="now" :cal-options="calOptions" @dateChange="onDateChange">
262
319
  </cv-date-picker>
263
320
  <div style="margin-top:2rem; background-color: #888888; padding:1rem; width:fit-content">
264
321
  <div>Reactive updates</div>
@@ -280,7 +337,7 @@ const TemplateSingleUsingMinMax = args => {
280
337
  toggleDateFormat,
281
338
  buttonLabel,
282
339
  changeMaxDate,
283
- onChange: action('change'),
340
+ onDateChange: action('dateChange'),
284
341
  }),
285
342
  template: templateSingleUsingMinMax,
286
343
  };
@@ -303,7 +360,14 @@ SingleUsingMinMax.args = initArgs;
303
360
 
304
361
  SingleUsingMinMax.parameters = {
305
362
  controls: {
306
- exclude: ['update:modelValue', 'invalid-message', 'modelValue', 'kind'],
363
+ exclude: [
364
+ 'update:modelValue',
365
+ 'invalid-message',
366
+ 'modelValue',
367
+ 'kind',
368
+ 'dateChange',
369
+ 'value',
370
+ ],
307
371
  },
308
372
  docs: {
309
373
  source: { code: codeMinMax },
@@ -317,8 +381,10 @@ SingleUsingMinMax.parameters = {
317
381
 
318
382
  const templateRangeUsingDate = `
319
383
  <div>
320
- <cv-date-picker v-bind="args" @change="onChange" kind="range"
321
- :value="{startDate: now.toLocaleDateString(), endDate: tomorrow.toLocaleDateString()}">
384
+ <cv-date-picker v-bind="args"
385
+ kind="range"
386
+ :value="{startDate: now.toLocaleDateString(), endDate: tomorrow.toLocaleDateString()}"
387
+ @dateChange="onDateChange">
322
388
  </cv-date-picker>
323
389
  </div>
324
390
  `;
@@ -330,7 +396,7 @@ const TemplateRangeUsingDate = args => {
330
396
  args,
331
397
  now,
332
398
  tomorrow,
333
- onChange: action('change'),
399
+ onDateChange: action('dateChange'),
334
400
  }),
335
401
  template: templateRangeUsingDate,
336
402
  };
@@ -340,7 +406,14 @@ export const RangeUsingDate = TemplateRangeUsingDate.bind({});
340
406
  RangeUsingDate.args = initArgs;
341
407
  RangeUsingDate.parameters = {
342
408
  controls: {
343
- exclude: ['update:modelValue', 'invalid-message', 'kind', 'modelValue'],
409
+ exclude: [
410
+ 'update:modelValue',
411
+ 'invalid-message',
412
+ 'kind',
413
+ 'modelValue',
414
+ 'dateChange',
415
+ 'value',
416
+ ],
344
417
  },
345
418
  };
346
419
  RangeUsingDate.parameters = storyParametersObject(
@@ -353,8 +426,7 @@ RangeUsingDate.parameters = storyParametersObject(
353
426
 
354
427
  const templateMinimal = `
355
428
  <div>
356
- <cv-date-picker v-bind="args" @change="onChange" :value="now">
357
- </cv-date-picker>
429
+ <cv-date-picker v-bind="args" :value="now" @change="onChange"/>
358
430
  </div>
359
431
  `;
360
432
 
@@ -373,7 +445,13 @@ const TemplateMinimal = args => {
373
445
  export const Minimal = TemplateMinimal.bind({});
374
446
  Minimal.parameters = {
375
447
  controls: {
376
- exclude: ['update:modelValue', 'invalid-message', 'modelValue'],
448
+ exclude: [
449
+ 'update:modelValue',
450
+ 'invalid-message',
451
+ 'modelValue',
452
+ 'dateChange',
453
+ 'value',
454
+ ],
377
455
  },
378
456
  };
379
457
  Minimal.parameters = storyParametersObject(
@@ -395,7 +473,6 @@ const TemplateSkeleton = args => {
395
473
  components: { CvDatePicker, CvDatePickerSkeleton },
396
474
  setup: () => ({
397
475
  args,
398
- onChange: action('change'),
399
476
  }),
400
477
  template: templateSkeleton,
401
478
  };
@@ -179,7 +179,7 @@ const props = defineProps({
179
179
  const cvId = useCvId(props, true, 'date-picker-');
180
180
  const isLight = useIsLight(props);
181
181
 
182
- const emit = defineEmits(['update:modelValue']);
182
+ const emit = defineEmits(['update:modelValue', 'dateChange']);
183
183
 
184
184
  const getKind = computed({
185
185
  get() {
@@ -332,6 +332,7 @@ const handleDatePick = (selectedDates, dateStr, instance) => {
332
332
  });
333
333
 
334
334
  emit('update:modelValue', temp);
335
+ emit('dateChange', selectedDates);
335
336
  } else if (isRange.value && selectedDates[0] && selectedDates[1]) {
336
337
  const startDate = dateToString(selectedDates[0]);
337
338
  const endDate = dateToString(selectedDates[1]);
@@ -345,6 +346,7 @@ const handleDatePick = (selectedDates, dateStr, instance) => {
345
346
  startDate: startDate,
346
347
  endDate: endDate,
347
348
  });
349
+ emit('dateChange', selectedDates);
348
350
  }
349
351
  };
350
352