@carbon/vue 3.0.12 → 3.0.13

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.
@@ -15,7 +15,9 @@ const initArgs = {
15
15
 
16
16
  const now = new Date();
17
17
  const tomorrow = new Date();
18
+ const nextWeek = new Date();
18
19
  tomorrow.setDate(now.getDate() + 1);
20
+ nextWeek.setDate(now.getDate() + 7);
19
21
 
20
22
  export default {
21
23
  title: `${sbCompPrefix}/CvDatePicker`,
@@ -29,11 +31,12 @@ export default {
29
31
  },
30
32
  },
31
33
  argTypes: {
32
- dateLabel: { type: String, description: 'Date picker label' },
33
- invalidMessage: {
34
+ kind: {
34
35
  type: String,
35
- description: 'Date picker text on invalid value',
36
+ options: ['short', 'simple', 'single', 'range'],
37
+ control: { type: 'select' },
36
38
  },
39
+ calOptions: { type: Object },
37
40
  },
38
41
  };
39
42
 
@@ -41,7 +44,7 @@ export default {
41
44
 
42
45
  const template = `
43
46
  <div>
44
- <cv-date-picker v-bind='args' @change='onChange'>
47
+ <cv-date-picker v-bind="args" @change="onChange" :value="now">
45
48
  </cv-date-picker>
46
49
  </div>
47
50
  `;
@@ -50,6 +53,7 @@ const Template = args => {
50
53
  components: { CvDatePicker },
51
54
  setup: () => ({
52
55
  args,
56
+ now,
53
57
  onChange: action('change'),
54
58
  }),
55
59
  template,
@@ -58,6 +62,11 @@ const Template = args => {
58
62
 
59
63
  export const Default = Template.bind({});
60
64
  Default.args = initArgs;
65
+ Default.parameters = {
66
+ controls: {
67
+ exclude: ['update:modelValue', 'invalid-message', 'modelValue'],
68
+ },
69
+ };
61
70
  Default.parameters = storyParametersObject(
62
71
  Default.parameters,
63
72
  template,
@@ -66,13 +75,13 @@ Default.parameters = storyParametersObject(
66
75
 
67
76
  /* V-MODEL STORY */
68
77
 
69
- const modelValue = ref('');
78
+ const modelValue = ref(now);
70
79
  const templateVModel = `
71
80
  <div>
72
- <cv-date-picker v-bind='args' @change='onChange' v-model="modelValue">
81
+ <cv-date-picker v-bind="args" @change="onChange" v-model="modelValue">
73
82
  </cv-date-picker>
74
83
  </div>
75
- <div style="margin: 32px 0;">
84
+ <div style="margin-top:2rem; background-color: #888888; padding:1rem">
76
85
  <div style="font-size: 150%;">Sample interaction</div>
77
86
  <label for="date-model" style='margin-right: 0.5rem'>V-model:</label>
78
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 } }"/>
@@ -95,6 +104,11 @@ const TemplateVModel = args => {
95
104
 
96
105
  export const vModel = TemplateVModel.bind({});
97
106
  vModel.args = initArgs;
107
+ vModel.parameters = {
108
+ controls: {
109
+ exclude: ['update:modelValue', 'invalid-message', 'modelValue'],
110
+ },
111
+ };
98
112
  vModel.parameters = storyParametersObject(
99
113
  vModel.parameters,
100
114
  templateVModel,
@@ -105,7 +119,7 @@ vModel.parameters = storyParametersObject(
105
119
 
106
120
  const templateInvalidMessage = `
107
121
  <div>
108
- <cv-date-picker v-bind='args' @change='onChange'>
122
+ <cv-date-picker v-bind="args" @change="onChange" :value="now">
109
123
  </cv-date-picker>
110
124
  </div>
111
125
  `;
@@ -115,6 +129,7 @@ const TemplateInvalidMessage = args => {
115
129
  components: { CvDatePicker },
116
130
  setup: () => ({
117
131
  args,
132
+ now,
118
133
  onChange: action('change'),
119
134
  }),
120
135
  template: templateInvalidMessage,
@@ -123,12 +138,22 @@ const TemplateInvalidMessage = args => {
123
138
 
124
139
  export const InvalidMessage = TemplateInvalidMessage.bind({});
125
140
  InvalidMessage.args = { ...initArgs, invalidMessage: 'Invalid date' };
141
+ InvalidMessage.parameters = {
142
+ controls: {
143
+ include: ['invalidMessage'],
144
+ },
145
+ };
146
+ InvalidMessage.parameters = storyParametersObject(
147
+ InvalidMessage.parameters,
148
+ templateInvalidMessage,
149
+ InvalidMessage.args
150
+ );
126
151
 
127
152
  /* INVALID MESSAGE SLOT STORY */
128
153
 
129
154
  const templateInvalidMessageSlot = `
130
155
  <div>
131
- <cv-date-picker v-bind='args' @change='onChange'>
156
+ <cv-date-picker v-bind="args" @change="onChange" :value="now">
132
157
  <template #invalid-message>Invalid date slot</template>
133
158
  </cv-date-picker>
134
159
  </div>
@@ -139,6 +164,7 @@ const TemplateInvalidMessageSlot = args => {
139
164
  components: { CvDatePicker },
140
165
  setup: () => ({
141
166
  args,
167
+ now,
142
168
  onChange: action('change'),
143
169
  }),
144
170
  template: templateInvalidMessageSlot,
@@ -147,13 +173,35 @@ const TemplateInvalidMessageSlot = args => {
147
173
 
148
174
  export const InvalidMessageSlot = TemplateInvalidMessageSlot.bind({});
149
175
  InvalidMessageSlot.args = initArgs;
176
+ InvalidMessageSlot.parameters = {
177
+ controls: {
178
+ include: [],
179
+ },
180
+ docs: {
181
+ description: {
182
+ story: `Use slot to set invalid message \`<template #invalid-message>Invalid date slot</template>\``,
183
+ },
184
+ },
185
+ };
186
+ InvalidMessageSlot.parameters = storyParametersObject(
187
+ InvalidMessageSlot.parameters,
188
+ templateInvalidMessageSlot,
189
+ InvalidMessageSlot.args
190
+ );
150
191
 
151
192
  /* SINGLE USING DATE STORY */
152
193
 
194
+ const singleValue = ref(now);
153
195
  const templateSingleUsingDate = `
154
196
  <div>
155
- <cv-date-picker v-bind='args' @change='onChange' kind="single" :value="now">
197
+ <cv-date-picker v-bind="args" @change="onChange" kind="single" v-model="singleValue">
156
198
  </cv-date-picker>
199
+ </div>`;
200
+ const templateSingleUsingDateVModel = `
201
+ <div style="margin-top:2rem; background-color: #888888; padding:1rem">
202
+ <div style="font-size: 150%;">Sample interaction</div>
203
+ <label for="date-model" style='margin-right: 0.5rem'>V-model:</label>
204
+ <input id="date-model" type="text" :value="singleValue" @change="ev => { singleValue = ev.currentTarget.value }"/>
157
205
  </div>
158
206
  `;
159
207
 
@@ -163,20 +211,90 @@ const TemplateSingleUsingDate = args => {
163
211
  setup: () => ({
164
212
  args,
165
213
  now,
214
+ singleValue,
166
215
  onChange: action('change'),
167
216
  }),
168
- template: templateSingleUsingDate,
217
+ template: templateSingleUsingDate + templateSingleUsingDateVModel,
169
218
  };
170
219
  };
171
220
 
172
221
  export const SingleUsingDate = TemplateSingleUsingDate.bind({});
173
222
  SingleUsingDate.args = initArgs;
223
+ SingleUsingDate.parameters = {
224
+ controls: {
225
+ include: ['dateLabel', 'disabled', 'invalidMessage', 'placeholder'],
226
+ },
227
+ docs: {
228
+ description: {
229
+ story: `Example of single date input with v-model`,
230
+ },
231
+ },
232
+ };
233
+ SingleUsingDate.parameters = storyParametersObject(
234
+ SingleUsingDate.parameters,
235
+ templateSingleUsingDate,
236
+ SingleUsingDate.args
237
+ );
238
+
239
+ /* SINGLE USING MIN MAX PARAMS STORY */
240
+
241
+ const templateSingleUsingMinMax = `
242
+ <div>
243
+ <cv-date-picker v-bind='args' @change="onChange" kind="single" :value="now" :cal-options="calOptions">
244
+ </cv-date-picker>
245
+ </div>
246
+ `;
247
+
248
+ const TemplateSingleUsingMinMax = args => {
249
+ return {
250
+ components: { CvDatePicker },
251
+ setup: () => ({
252
+ args,
253
+ now,
254
+ calOptions: {
255
+ minDate: now,
256
+ maxDate: nextWeek,
257
+ dateFormat: 'm/d/Y',
258
+ },
259
+ onChange: action('change'),
260
+ }),
261
+ template: templateSingleUsingMinMax,
262
+ };
263
+ };
264
+
265
+ const codeMinMax = `
266
+ const now = new Date();
267
+ const nextWeek = new Date();
268
+ nextWeek.setDate(now.getDate() + 7);
269
+ const calOptions = ref({
270
+ minDate: now,
271
+ maxDate: nextWeek,
272
+ dateFormat: 'm/d/Y'
273
+ })
274
+ ${templateSingleUsingMinMax}
275
+ `;
276
+ const docMinMax = `Example showing how "calOptions" prop can be used to control the min/max date.`;
277
+ export const SingleUsingMinMax = TemplateSingleUsingMinMax.bind({});
278
+ SingleUsingMinMax.args = initArgs;
279
+
280
+ SingleUsingMinMax.parameters = {
281
+ controls: {
282
+ exclude: ['update:modelValue', 'invalid-message', 'modelValue', 'kind'],
283
+ },
284
+ docs: {
285
+ source: { code: codeMinMax },
286
+ description: {
287
+ story: docMinMax,
288
+ },
289
+ },
290
+ };
174
291
 
175
292
  /* RANGE USING DATE STORY */
176
293
 
177
294
  const templateRangeUsingDate = `
178
295
  <div>
179
- <cv-date-picker v-bind='args' @change='onChange' kind="range" :value="{startDate: now.toLocaleDateString(), endDate: tomorrow.toLocaleDateString()}">
296
+ <cv-date-picker v-bind="args" @change="onChange" kind="range"
297
+ :value="{startDate: now.toLocaleDateString(), endDate: tomorrow.toLocaleDateString()}">
180
298
  </cv-date-picker>
181
299
  </div>
182
300
  `;
@@ -196,12 +314,22 @@ const TemplateRangeUsingDate = args => {
196
314
 
197
315
  export const RangeUsingDate = TemplateRangeUsingDate.bind({});
198
316
  RangeUsingDate.args = initArgs;
317
+ RangeUsingDate.parameters = {
318
+ controls: {
319
+ exclude: ['update:modelValue', 'invalid-message', 'kind', 'modelValue'],
320
+ },
321
+ };
322
+ RangeUsingDate.parameters = storyParametersObject(
323
+ RangeUsingDate.parameters,
324
+ templateRangeUsingDate,
325
+ RangeUsingDate.args
326
+ );
199
327
 
200
328
  /* MINIMAL STORY */
201
329
 
202
330
  const templateMinimal = `
203
331
  <div>
204
- <cv-date-picker v-bind='args' @change='onChange'>
332
+ <cv-date-picker v-bind="args" @change="onChange" :value="now">
205
333
  </cv-date-picker>
206
334
  </div>
207
335
  `;
@@ -211,6 +339,7 @@ const TemplateMinimal = args => {
211
339
  components: { CvDatePicker },
212
340
  setup: () => ({
213
341
  args,
342
+ now,
214
343
  onChange: action('change'),
215
344
  }),
216
345
  template: templateMinimal,
@@ -218,12 +347,22 @@ const TemplateMinimal = args => {
218
347
  };
219
348
 
220
349
  export const Minimal = TemplateMinimal.bind({});
350
+ Minimal.parameters = {
351
+ controls: {
352
+ exclude: ['update:modelValue', 'invalid-message', 'modelValue'],
353
+ },
354
+ };
355
+ Minimal.parameters = storyParametersObject(
356
+ Minimal.parameters,
357
+ templateMinimal,
358
+ Minimal.args
359
+ );
221
360
 
222
361
  /* SKELETON STORY */
223
362
 
224
363
  const templateSkeleton = `
225
364
  <div>
226
- <cv-date-picker-skeleton v-bind='args'></cv-date-picker-skeleton>
365
+ <cv-date-picker-skeleton v-bind="args"></cv-date-picker-skeleton>
227
366
  </div>
228
367
  `;
229
368
 
@@ -239,3 +378,15 @@ const TemplateSkeleton = args => {
239
378
  };
240
379
 
241
380
  export const Skeleton = TemplateSkeleton.bind({});
381
+ Skeleton.args = initArgs;
382
+ Skeleton.args = initArgs;
383
+ Skeleton.parameters = {
384
+ controls: {
385
+ include: [],
386
+ },
387
+ };
388
+ Skeleton.parameters = storyParametersObject(
389
+ Skeleton.parameters,
390
+ templateSkeleton,
391
+ Skeleton.args
392
+ );
@@ -139,13 +139,22 @@ let calendar;
139
139
 
140
140
  const props = defineProps({
141
141
  modelValue: { type: [String, Object, Array, Date], default: undefined },
142
+ /** Date picker label */
142
143
  dateLabel: { type: String, default: undefined },
144
+ /** Date picker end label (when using kind="range") */
143
145
  dateEndLabel: { type: String, default: 'End date' },
144
- invalid: { type: Boolean, default: false },
146
+ /** If true, the date picker will be disabled */
145
147
  disabled: { type: Boolean, default: false },
148
+ /** Date picker text on invalid value */
146
149
  invalidMessage: { type: String, default: undefined },
150
+ /** Regex pattern used for form validation, default \d{1,2}/\d{1,2}/\d{4} */
147
151
  pattern: { type: String, default: '\\d{1,2}/\\d{1,2}/\\d{4}' },
152
+ /** Date picker input placeholder, shown when date picker is empty. Default 'mm/dd/yyyy' */
148
153
  placeholder: { type: String, default: 'mm/dd/yyyy' },
154
+ /** You can pass flatpickr options through this prop.
155
+ See https://flatpickr.js.org/options/ for more details.
156
+ Some of the options is not supported (for example, onChange, onReady, mode, nextArrow, prevArrow).
157
+ Also, you have to pass dateFormat field in calOptions object if you use it. */
149
158
  calOptions: {
150
159
  type: Object,
151
160
  default() {
@@ -155,6 +164,8 @@ const props = defineProps({
155
164
  },
156
165
  },
157
166
  formItem: { type: Boolean, default: true },
167
+ /** Date picker kind (also known as mode in flatpickr options).
168
+ Possible values: 'short', 'simple', 'single', 'range' */
158
169
  kind: {
159
170
  type: String,
160
171
  default: 'simple',
@@ -300,6 +311,7 @@ const initFlatpickr = () => {
300
311
  };
301
312
 
302
313
  let dateToString = val => {
314
+ if (!val) return '';
303
315
  return calendar.formatDate(val, props.calOptions.dateFormat);
304
316
  };
305
317
 
@@ -336,14 +348,17 @@ const handleUpdateEvent = event => {
336
348
  };
337
349
 
338
350
  const setDate = value => {
339
- if (!value) return;
340
-
341
- if (isSingle.value) {
342
- calendar.setDate(value, true);
343
- } else if (isRange.value) {
344
- calendar.setDate([value.startDate, value.endDate], true);
345
- } else {
346
- date.value.value = value;
351
+ try {
352
+ if (value === undefined) return;
353
+ if (isSingle.value) {
354
+ calendar.setDate(value, true);
355
+ } else if (isRange.value) {
356
+ calendar.setDate([value.startDate, value.endDate], true);
357
+ } else {
358
+ date.value.value = value;
359
+ }
360
+ } catch (e) {
361
+ console.error('setDate', e);
347
362
  }
348
363
  };
349
364
 
@@ -38,11 +38,28 @@ export default {
38
38
  type: 'boolean',
39
39
  table: {
40
40
  type: { summary: 'boolean' },
41
- category: 'props',
41
+ category: 'CvRadioGroup - props',
42
42
  },
43
43
  description:
44
44
  'Property of CvRadioGroup component - stacks inside radio components vertically',
45
45
  },
46
+ legendText: {
47
+ control: 'text',
48
+ table: {
49
+ type: { summary: 'text' },
50
+ category: 'CvRadioGroup - props',
51
+ },
52
+ description: 'Property of CvRadioGroup component',
53
+ },
54
+ hideLegend: {
55
+ type: 'boolean',
56
+ table: {
57
+ type: { summary: 'boolean' },
58
+ category: 'CvRadioGroup - props',
59
+ },
60
+ description:
61
+ 'Property of CvRadioGroup component - makes the legend visually hidden',
62
+ },
46
63
  },
47
64
  };
48
65
 
@@ -105,6 +122,8 @@ const Template = (args, { argTypes }) => {
105
122
  export const Default = Template.bind({});
106
123
  Default.args = {
107
124
  vertical: false,
125
+ legendText: 'CvRadioGroup legend',
126
+ hideLegend: false,
108
127
  };
109
128
  Default.parameters = storyParametersObject(
110
129
  DefaultStoryParameters,
@@ -18,10 +18,7 @@
18
18
  <!-- symbol causes problem in codepen? -->
19
19
  <label :for="cvId" :class="`${carbonPrefix}--radio-button__label`">
20
20
  <span :class="`${carbonPrefix}--radio-button__appearance`"></span>
21
- <span
22
- v-if="label"
23
- :class="{ [`${carbonPrefix}--visually-hidden`]: hideLabel }"
24
- >
21
+ <span :class="{ [`${carbonPrefix}--visually-hidden`]: hideLabel }">
25
22
  {{ label }}
26
23
  </span>
27
24
  </label>
@@ -35,7 +32,12 @@ import { useCvId, propsCvId, useMethods, useRadio } from '../../use';
35
32
  const props = defineProps({
36
33
  modelValue: { type: String, default: undefined },
37
34
  checked: Boolean,
38
- label: { type: String, default: undefined },
35
+ label: {
36
+ type: String,
37
+ default: null,
38
+ required: true,
39
+ validator: label => !!label.length,
40
+ },
39
41
  value: { type: String, required: true },
40
42
  hideLabel: Boolean,
41
43
  labelLeft: Boolean,
@@ -1,13 +1,22 @@
1
1
  <template>
2
2
  <div :class="`cv-radio-group ${carbonPrefix}--form-item`">
3
- <div
3
+ <fieldset
4
4
  :class="[
5
5
  `${carbonPrefix}--radio-button-group`,
6
6
  { [`${carbonPrefix}--radio-button-group--vertical`]: vertical },
7
7
  ]"
8
8
  >
9
+ <legend
10
+ :class="[
11
+ `${carbonPrefix}--label`,
12
+ { [`${carbonPrefix}--visually-hidden`]: hideLegend },
13
+ ]"
14
+ dir="auto"
15
+ >
16
+ {{ legendText }}
17
+ </legend>
9
18
  <slot></slot>
10
- </div>
19
+ </fieldset>
11
20
  </div>
12
21
  </template>
13
22
 
@@ -17,6 +26,13 @@ import { carbonPrefix } from '../../global/settings';
17
26
 
18
27
  defineProps({
19
28
  vertical: Boolean,
29
+ legendText: {
30
+ type: String,
31
+ default: null,
32
+ required: true,
33
+ validator: legend => !!legend.length,
34
+ },
35
+ hideLegend: Boolean,
20
36
  });
21
37
 
22
38
  const emit = defineEmits(['change']);
@@ -12,16 +12,18 @@ exports[`CvRadioButton matches render with right label 1`] = `<div class="cv-rad
12
12
 
13
13
  exports[`CvRadioGroup matches render when horizontal 1`] = `
14
14
  <div class="cv-radio-group bx--form-item">
15
- <div class="bx--radio-button-group">
15
+ <fieldset class="bx--radio-button-group">
16
+ <legend class="bx--label" dir="auto">test legend</legend>
16
17
  <div class="cv-radio-button-stub">RadioButtonStub</div>
17
- </div>
18
+ </fieldset>
18
19
  </div>
19
20
  `;
20
21
 
21
22
  exports[`CvRadioGroup matches render when vertical 1`] = `
22
23
  <div class="cv-radio-group bx--form-item">
23
- <div class="bx--radio-button-group bx--radio-button-group--vertical">
24
+ <fieldset class="bx--radio-button-group bx--radio-button-group--vertical">
25
+ <legend class="bx--label" dir="auto">test legend</legend>
24
26
  <div class="cv-radio-button-stub">RadioButtonStub</div>
25
- </div>
27
+ </fieldset>
26
28
  </div>
27
29
  `;
@@ -1,55 +0,0 @@
1
- import { action } from '@storybook/addon-actions';
2
- import { CvAccordion, CvAccordionItem } from '.';
3
- import { alignConsts, sizeConsts } from './consts';
4
-
5
- import {
6
- sbCompPrefix,
7
- storyParametersObject,
8
- } from '../../global/storybook-utils';
9
-
10
- export default {
11
- title: `${sbCompPrefix}/CvAccordion`,
12
- component: CvAccordion,
13
- argTypes: {
14
- align: {
15
- control: { type: 'select', options: Object.keys(alignConsts.$labels) },
16
- },
17
- size: {
18
- control: { type: 'select', options: Object.keys(sizeConsts.$labels) },
19
- },
20
- },
21
- };
22
-
23
- // <cv-button @click="onClick" v-bind="newArgs">{{defaultSlot}}</cv-button>
24
- const template = `<cv-accordion @change="onChange" v-bind="args">
25
- <cv-accordion-item v-for="n in 4" :key="\`acc-item-\${n}\`" :id="n % 2 ? \`acc-item-\${n}\` : ''">
26
- <template v-slot:title>Section {{n}} title </template>
27
- <template v-slot:content>
28
- <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
29
- </template>
30
- </cv-accordion-item>
31
- </cv-accordion>`;
32
- const Template = (args, { argTypes }) => {
33
- // eslint-disable-next-line no-param-reassign
34
- args = {
35
- ...args,
36
- align: alignConsts[alignConsts.$labels[args.align]],
37
- size: sizeConsts[sizeConsts.$labels[args.size]],
38
- };
39
- return {
40
- props: Object.keys(argTypes),
41
- components: { CvAccordion, CvAccordionItem },
42
- setup() {
43
- return { args, onChange: action('change') };
44
- },
45
- template,
46
- };
47
- };
48
-
49
- export const Default = Template.bind({});
50
- Default.args = {};
51
- Default.parameters = storyParametersObject(
52
- Default.parameters,
53
- template,
54
- Default.args
55
- );