@bethinkpl/design-system 42.0.0 → 44.0.0
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/dist/design-system.css +1 -1
- package/dist/design-system.js +17470 -13135
- package/dist/design-system.js.map +1 -1
- package/dist/lib/js/components/Cards/Card/Card.consts.d.ts +14 -0
- package/dist/lib/js/components/Cards/Card/Card.vue.d.ts +10 -5
- package/dist/lib/js/components/Cards/CardExpandable/CardExpandable.vue.d.ts +33 -15
- package/dist/lib/js/components/Form/PinInputField/PinInputField.consts.d.ts +14 -0
- package/dist/lib/js/components/Form/PinInputField/PinInputField.types.d.ts +12 -0
- package/dist/lib/js/components/Form/PinInputField/PinInputField.utils.d.ts +2 -0
- package/dist/lib/js/components/Form/PinInputField/PinInputField.vue.d.ts +91 -0
- package/dist/lib/js/components/Form/PinInputField/index.d.ts +5 -0
- package/dist/lib/js/components/Form/PinInputField/usePinInputFieldWithinForm.d.ts +8 -0
- package/dist/lib/js/components/Form/SelectField/SelectField.types.d.ts +26 -0
- package/dist/lib/js/components/Form/SelectField/SelectField.utils.d.ts +7 -0
- package/dist/lib/js/components/Form/SelectField/SelectField.vue.d.ts +107 -0
- package/dist/lib/js/components/Form/SelectField/SelectFieldOption.vue.d.ts +19 -0
- package/dist/lib/js/components/Form/SelectField/index.d.ts +4 -0
- package/dist/lib/js/components/Form/SelectField/useSelectFieldWithinForm.d.ts +8 -0
- package/dist/lib/js/components/Form/TextAreaField/TextAreaField.types.d.ts +9 -0
- package/dist/lib/js/components/Form/TextAreaField/TextAreaField.vue.d.ts +76 -0
- package/dist/lib/js/components/Form/TextAreaField/TextAreaFieldAutosized.vue.d.ts +6 -0
- package/dist/lib/js/components/Form/TextAreaField/index.d.ts +4 -0
- package/dist/lib/js/components/LabelValue/LabelValueItem/LabelValueItem.vue.d.ts +12 -1
- package/dist/lib/js/components/Pagination/Pagination.vue.d.ts +2 -0
- package/dist/lib/js/components/SelectList/SelectListItem/SelectListItem.vue.d.ts +2 -0
- package/dist/lib/js/components/SelectList/SelectListItemToggle/SelectListItemToggle.vue.d.ts +2 -0
- package/dist/lib/js/components/SurveyQuestions/SurveyQuestionOpenEnded/SurveyQuestionOpenEnded.vue.d.ts +33 -15
- package/dist/lib/js/components/SurveyQuestions/SurveyQuestionScale/SurveyQuestionScale.vue.d.ts +33 -15
- package/dist/lib/js/components/Toast/Toast.consts.d.ts +11 -9
- package/dist/lib/js/components/Toast/Toast.vue.d.ts +51 -415
- package/dist/lib/js/composables/useFormFieldWithinForm.d.ts +3 -3
- package/dist/lib/js/composables/useTextFieldWithinForm.d.ts +8 -0
- package/dist/lib/js/index.d.ts +6 -0
- package/lib/js/components/Cards/Card/Card.consts.ts +18 -0
- package/lib/js/components/Cards/Card/Card.spec.ts +159 -33
- package/lib/js/components/Cards/Card/Card.stories.ts +21 -2
- package/lib/js/components/Cards/Card/Card.vue +90 -23
- package/lib/js/components/Dropdown/Dropdown.vue +6 -10
- package/lib/js/components/Form/CheckboxGroupField/CheckboxGroupField.spec.ts +15 -0
- package/lib/js/components/Form/CheckboxGroupField/CheckboxGroupField.vue +5 -2
- package/lib/js/components/Form/Form.stories.ts +37 -2
- package/lib/js/components/Form/InputField/InputField.spec.ts +11 -1
- package/lib/js/components/Form/InputField/InputField.vue +7 -4
- package/lib/js/components/Form/PinInputField/PinInputField.consts.ts +18 -0
- package/lib/js/components/Form/PinInputField/PinInputField.spec.ts +394 -0
- package/lib/js/components/Form/PinInputField/PinInputField.stories.ts +124 -0
- package/lib/js/components/Form/PinInputField/PinInputField.types.ts +42 -0
- package/lib/js/components/Form/PinInputField/PinInputField.utils.ts +5 -0
- package/lib/js/components/Form/PinInputField/PinInputField.vue +211 -0
- package/lib/js/components/Form/PinInputField/index.ts +6 -0
- package/lib/js/components/Form/PinInputField/usePinInputFieldWithinForm.ts +29 -0
- package/lib/js/components/Form/SelectField/SelectField.spec.ts +495 -0
- package/lib/js/components/Form/SelectField/SelectField.stories.ts +282 -0
- package/lib/js/components/Form/SelectField/SelectField.types.ts +65 -0
- package/lib/js/components/Form/SelectField/SelectField.utils.ts +83 -0
- package/lib/js/components/Form/SelectField/SelectField.vue +342 -0
- package/lib/js/components/Form/SelectField/SelectFieldOption.vue +51 -0
- package/lib/js/components/Form/SelectField/index.ts +5 -0
- package/lib/js/components/Form/SelectField/useSelectFieldWithinForm.ts +27 -0
- package/lib/js/components/Form/TextAreaField/TextAreaField.spec.ts +341 -0
- package/lib/js/components/Form/TextAreaField/TextAreaField.stories.ts +99 -0
- package/lib/js/components/Form/TextAreaField/TextAreaField.types.ts +23 -0
- package/lib/js/components/Form/TextAreaField/TextAreaField.vue +190 -0
- package/lib/js/components/Form/TextAreaField/TextAreaFieldAutosized.vue +19 -0
- package/lib/js/components/Form/TextAreaField/index.ts +5 -0
- package/lib/js/components/LabelValue/LabelValueItem/LabelValueItem.spec.ts +26 -0
- package/lib/js/components/LabelValue/LabelValueItem/LabelValueItem.stories.ts +16 -3
- package/lib/js/components/LabelValue/LabelValueItem/LabelValueItem.vue +5 -0
- package/lib/js/components/LoadingBar/LoadingBar.spec.ts +84 -0
- package/lib/js/components/LoadingBar/LoadingBar.vue +30 -19
- package/lib/js/components/SelectList/SelectListItem/SelectListItem.spec.ts +77 -0
- package/lib/js/components/SelectList/SelectListItem/SelectListItem.vue +4 -1
- package/lib/js/components/Toast/Toast.consts.ts +4 -2
- package/lib/js/components/Toast/Toast.spec.ts +177 -0
- package/lib/js/components/Toast/Toast.stories.ts +65 -31
- package/lib/js/components/Toast/Toast.vue +176 -195
- package/lib/js/composables/useFormFieldWithinForm.ts +4 -4
- package/lib/js/{components/Form/InputField/useInputFieldWithinForm.ts → composables/useTextFieldWithinForm.ts} +7 -2
- package/lib/js/index.ts +6 -0
- package/lib/js/styles/Shadows/Shadows.stories.scss +16 -0
- package/lib/js/styles/Shadows/Shadows.stories.ts +4 -0
- package/lib/styles/mixins/_dropdown-surface.scss +24 -0
- package/lib/styles/settings/_shadows.scss +18 -0
- package/package.json +1 -1
- package/dist/lib/js/components/Form/InputField/useInputFieldWithinForm.d.ts +0 -8
|
@@ -3,13 +3,37 @@ import { ComponentMountingOptions, mount } from '@vue/test-utils';
|
|
|
3
3
|
import { h } from 'vue';
|
|
4
4
|
|
|
5
5
|
import Card from './Card.vue';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
CARD_BACKGROUND_COLORS,
|
|
8
|
+
CARD_ELEVATIONS,
|
|
9
|
+
CARD_PADDING_SIZES,
|
|
10
|
+
CARD_RADIUSES,
|
|
11
|
+
CardBackgroundColor,
|
|
12
|
+
CardElevation,
|
|
13
|
+
CardPaddingSize,
|
|
14
|
+
CardRadius,
|
|
15
|
+
} from './Card.consts';
|
|
7
16
|
|
|
8
17
|
describe('Card', () => {
|
|
9
18
|
const createComponent = (options: ComponentMountingOptions<typeof Card> = {}) => {
|
|
10
19
|
return mount(Card, options);
|
|
11
20
|
};
|
|
12
21
|
|
|
22
|
+
// asserts that exactly one modifier out of a variant group is applied
|
|
23
|
+
const expectOnlyModifier = (
|
|
24
|
+
classes: Array<string>,
|
|
25
|
+
modifiers: Array<string>,
|
|
26
|
+
expectedModifier: string | null,
|
|
27
|
+
) => {
|
|
28
|
+
modifiers.forEach((modifier) => {
|
|
29
|
+
if (modifier === expectedModifier) {
|
|
30
|
+
expect(classes).toContain(modifier);
|
|
31
|
+
} else {
|
|
32
|
+
expect(classes).not.toContain(modifier);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
|
|
13
37
|
it('should create', () => {
|
|
14
38
|
const component = createComponent();
|
|
15
39
|
|
|
@@ -198,62 +222,143 @@ describe('Card', () => {
|
|
|
198
222
|
);
|
|
199
223
|
});
|
|
200
224
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
225
|
+
const PADDING_MODIFIERS = ['-ds-paddingMedium', '-ds-paddingLarge'];
|
|
226
|
+
|
|
227
|
+
it.each<[CardPaddingSize, string | null]>([
|
|
228
|
+
[CARD_PADDING_SIZES.SMALL, null],
|
|
229
|
+
[CARD_PADDING_SIZES.MEDIUM, '-ds-paddingMedium'],
|
|
230
|
+
[CARD_PADDING_SIZES.LARGE, '-ds-paddingLarge'],
|
|
231
|
+
])('should set the padding class for paddingSize %s', (paddingSize, expectedModifier) => {
|
|
232
|
+
const component = createComponent({ props: { paddingSize } });
|
|
205
233
|
|
|
206
|
-
|
|
234
|
+
expectOnlyModifier(
|
|
235
|
+
component.find('.ds-card').classes(),
|
|
236
|
+
PADDING_MODIFIERS,
|
|
237
|
+
expectedModifier,
|
|
238
|
+
);
|
|
207
239
|
});
|
|
208
240
|
|
|
209
|
-
it('should not set
|
|
210
|
-
const component = createComponent(
|
|
211
|
-
|
|
212
|
-
|
|
241
|
+
it('should not set any padding class by default', () => {
|
|
242
|
+
const component = createComponent();
|
|
243
|
+
|
|
244
|
+
expectOnlyModifier(component.find('.ds-card').classes(), PADDING_MODIFIERS, null);
|
|
245
|
+
});
|
|
213
246
|
|
|
214
|
-
|
|
247
|
+
const ELEVATION_MODIFIERS = ['-ds-elevationTop', '-ds-elevationNone'];
|
|
248
|
+
|
|
249
|
+
it.each<[CardElevation, string | null]>([
|
|
250
|
+
[CARD_ELEVATIONS.DEFAULT, null],
|
|
251
|
+
[CARD_ELEVATIONS.TOP, '-ds-elevationTop'],
|
|
252
|
+
[CARD_ELEVATIONS.NONE, '-ds-elevationNone'],
|
|
253
|
+
])('should set the elevation class for elevation %s', (elevation, expectedModifier) => {
|
|
254
|
+
const component = createComponent({ props: { elevation } });
|
|
255
|
+
|
|
256
|
+
expectOnlyModifier(
|
|
257
|
+
component.find('.ds-card').classes(),
|
|
258
|
+
ELEVATION_MODIFIERS,
|
|
259
|
+
expectedModifier,
|
|
260
|
+
);
|
|
215
261
|
});
|
|
216
262
|
|
|
217
|
-
it('should not set
|
|
263
|
+
it('should not set any elevation class by default', () => {
|
|
218
264
|
const component = createComponent();
|
|
219
265
|
|
|
220
|
-
|
|
266
|
+
expectOnlyModifier(component.find('.ds-card').classes(), ELEVATION_MODIFIERS, null);
|
|
221
267
|
});
|
|
222
268
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
269
|
+
const RADIUS_MODIFIERS = ['-ds-radiusTop', '-ds-radiusNone'];
|
|
270
|
+
|
|
271
|
+
it.each<[CardRadius, string | null]>([
|
|
272
|
+
[CARD_RADIUSES.ALL, null],
|
|
273
|
+
[CARD_RADIUSES.TOP, '-ds-radiusTop'],
|
|
274
|
+
[CARD_RADIUSES.NONE, '-ds-radiusNone'],
|
|
275
|
+
])('should set the radius class for radius %s', (radius, expectedModifier) => {
|
|
276
|
+
const component = createComponent({ props: { radius } });
|
|
227
277
|
|
|
228
|
-
|
|
278
|
+
expectOnlyModifier(
|
|
279
|
+
component.find('.ds-card').classes(),
|
|
280
|
+
RADIUS_MODIFIERS,
|
|
281
|
+
expectedModifier,
|
|
282
|
+
);
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
it('should not set any radius class by default', () => {
|
|
286
|
+
const component = createComponent();
|
|
287
|
+
|
|
288
|
+
expectOnlyModifier(component.find('.ds-card').classes(), RADIUS_MODIFIERS, null);
|
|
229
289
|
});
|
|
230
290
|
|
|
231
|
-
|
|
291
|
+
const BACKGROUND_MODIFIERS = ['-ds-backgroundNeutral', '-ds-backgroundNone'];
|
|
292
|
+
|
|
293
|
+
it.each<[CardBackgroundColor, string | null]>([
|
|
294
|
+
[CARD_BACKGROUND_COLORS.DEFAULT, null],
|
|
295
|
+
[CARD_BACKGROUND_COLORS.NEUTRAL, '-ds-backgroundNeutral'],
|
|
296
|
+
[CARD_BACKGROUND_COLORS.NONE, '-ds-backgroundNone'],
|
|
297
|
+
])(
|
|
298
|
+
'should set the background class for backgroundColor %s',
|
|
299
|
+
(backgroundColor, expectedModifier) => {
|
|
300
|
+
const component = createComponent({ props: { backgroundColor } });
|
|
301
|
+
|
|
302
|
+
expectOnlyModifier(
|
|
303
|
+
component.find('.ds-card').classes(),
|
|
304
|
+
BACKGROUND_MODIFIERS,
|
|
305
|
+
expectedModifier,
|
|
306
|
+
);
|
|
307
|
+
},
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
it('should not set any background class by default', () => {
|
|
232
311
|
const component = createComponent();
|
|
233
312
|
|
|
234
|
-
|
|
313
|
+
expectOnlyModifier(component.find('.ds-card').classes(), BACKGROUND_MODIFIERS, null);
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
it('should set the none modifiers of all three visual axes when isFlat is true', () => {
|
|
317
|
+
const classes = createComponent({ props: { isFlat: true } })
|
|
318
|
+
.find('.ds-card')
|
|
319
|
+
.classes();
|
|
320
|
+
|
|
321
|
+
expectOnlyModifier(classes, ELEVATION_MODIFIERS, '-ds-elevationNone');
|
|
322
|
+
expectOnlyModifier(classes, RADIUS_MODIFIERS, '-ds-radiusNone');
|
|
323
|
+
expectOnlyModifier(classes, BACKGROUND_MODIFIERS, '-ds-backgroundNone');
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
it('should not change the padding when isFlat is true', () => {
|
|
327
|
+
const component = createComponent({ props: { isFlat: true } });
|
|
328
|
+
|
|
329
|
+
expectOnlyModifier(component.find('.ds-card').classes(), PADDING_MODIFIERS, null);
|
|
235
330
|
});
|
|
236
331
|
|
|
237
|
-
it('should
|
|
332
|
+
it('should let an explicit elevation override isFlat', () => {
|
|
238
333
|
const component = createComponent({
|
|
239
|
-
props: {
|
|
334
|
+
props: { isFlat: true, elevation: CARD_ELEVATIONS.TOP },
|
|
240
335
|
});
|
|
241
336
|
|
|
242
|
-
|
|
337
|
+
expectOnlyModifier(
|
|
338
|
+
component.find('.ds-card').classes(),
|
|
339
|
+
ELEVATION_MODIFIERS,
|
|
340
|
+
'-ds-elevationTop',
|
|
341
|
+
);
|
|
243
342
|
});
|
|
244
343
|
|
|
245
|
-
it('should
|
|
246
|
-
const component = createComponent(
|
|
344
|
+
it('should let an explicit radius override isFlat', () => {
|
|
345
|
+
const component = createComponent({
|
|
346
|
+
props: { isFlat: true, radius: CARD_RADIUSES.TOP },
|
|
347
|
+
});
|
|
247
348
|
|
|
248
|
-
|
|
349
|
+
expectOnlyModifier(component.find('.ds-card').classes(), RADIUS_MODIFIERS, '-ds-radiusTop');
|
|
249
350
|
});
|
|
250
351
|
|
|
251
|
-
it('should
|
|
352
|
+
it('should let an explicit backgroundColor override isFlat', () => {
|
|
252
353
|
const component = createComponent({
|
|
253
|
-
props: { backgroundColor: CARD_BACKGROUND_COLORS.NEUTRAL },
|
|
354
|
+
props: { isFlat: true, backgroundColor: CARD_BACKGROUND_COLORS.NEUTRAL },
|
|
254
355
|
});
|
|
255
356
|
|
|
256
|
-
|
|
357
|
+
expectOnlyModifier(
|
|
358
|
+
component.find('.ds-card').classes(),
|
|
359
|
+
BACKGROUND_MODIFIERS,
|
|
360
|
+
'-ds-backgroundNeutral',
|
|
361
|
+
);
|
|
257
362
|
});
|
|
258
363
|
|
|
259
364
|
it('should not give the ribbon a radius when only hasRibbonRadius is set', () => {
|
|
@@ -266,25 +371,46 @@ describe('Card', () => {
|
|
|
266
371
|
|
|
267
372
|
it('should give the ribbon a radius when hasRibbonRadius and card has no radius', () => {
|
|
268
373
|
const component = createComponent({
|
|
269
|
-
props: { hasRibbon: true, hasRibbonRadius: true,
|
|
374
|
+
props: { hasRibbon: true, hasRibbonRadius: true, radius: CARD_RADIUSES.NONE },
|
|
270
375
|
});
|
|
271
376
|
|
|
272
377
|
expect(component.find('.-ds-radius-bottom').exists()).toBe(true);
|
|
273
378
|
});
|
|
274
379
|
|
|
275
|
-
it('should not give the ribbon a radius when
|
|
380
|
+
it('should not give the ribbon a radius when radius is none but hasRibbonRadius is false', () => {
|
|
381
|
+
const component = createComponent({
|
|
382
|
+
props: { hasRibbon: true, hasRibbonRadius: false, radius: CARD_RADIUSES.NONE },
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
expect(component.find('.-ds-radius-bottom').exists()).toBe(false);
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
it('should not give the ribbon a radius when the card is rounded at the top', () => {
|
|
276
389
|
const component = createComponent({
|
|
277
|
-
props: { hasRibbon: true, hasRibbonRadius:
|
|
390
|
+
props: { hasRibbon: true, hasRibbonRadius: true, radius: CARD_RADIUSES.TOP },
|
|
278
391
|
});
|
|
279
392
|
|
|
280
393
|
expect(component.find('.-ds-radius-bottom').exists()).toBe(false);
|
|
281
394
|
});
|
|
282
395
|
|
|
283
|
-
it('should give the ribbon a radius when hasRibbonRadius and card is flat', () => {
|
|
396
|
+
it('should give the ribbon a radius when hasRibbonRadius and the card is flat', () => {
|
|
284
397
|
const component = createComponent({
|
|
285
398
|
props: { hasRibbon: true, hasRibbonRadius: true, isFlat: true },
|
|
286
399
|
});
|
|
287
400
|
|
|
288
401
|
expect(component.find('.-ds-radius-bottom').exists()).toBe(true);
|
|
289
402
|
});
|
|
403
|
+
|
|
404
|
+
it('should not give the ribbon a radius when a flat card is overridden with radius top', () => {
|
|
405
|
+
const component = createComponent({
|
|
406
|
+
props: {
|
|
407
|
+
hasRibbon: true,
|
|
408
|
+
hasRibbonRadius: true,
|
|
409
|
+
isFlat: true,
|
|
410
|
+
radius: CARD_RADIUSES.TOP,
|
|
411
|
+
},
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
expect(component.find('.-ds-radius-bottom').exists()).toBe(false);
|
|
415
|
+
});
|
|
290
416
|
});
|
|
@@ -3,6 +3,8 @@ import Card from './Card.vue';
|
|
|
3
3
|
import { Args, ArgTypes, Meta, StoryFn } from '@storybook/vue3';
|
|
4
4
|
import {
|
|
5
5
|
CARD_BACKGROUND_COLORS,
|
|
6
|
+
CARD_ELEVATIONS,
|
|
7
|
+
CARD_RADIUSES,
|
|
6
8
|
CARD_RIBBON_COLORS,
|
|
7
9
|
CARD_RIBBON_POSITIONS,
|
|
8
10
|
CARD_RIBBON_SIZES,
|
|
@@ -50,7 +52,9 @@ const args = {
|
|
|
50
52
|
paddingSize: CARD_PADDING_SIZES.SMALL,
|
|
51
53
|
dividerUnderHeader: false,
|
|
52
54
|
hasRibbon: false,
|
|
53
|
-
|
|
55
|
+
isFlat: false,
|
|
56
|
+
elevation: CARD_ELEVATIONS.DEFAULT,
|
|
57
|
+
radius: CARD_RADIUSES.ALL,
|
|
54
58
|
backgroundColor: CARD_BACKGROUND_COLORS.DEFAULT,
|
|
55
59
|
ribbonPosition: CARD_RIBBON_POSITIONS.TOP,
|
|
56
60
|
ribbonSize: CARD_RIBBON_SIZES.MEDIUM,
|
|
@@ -59,7 +63,6 @@ const args = {
|
|
|
59
63
|
hasLoadingBar: false,
|
|
60
64
|
loadingBarColor: LOADING_BAR_COLORS.NEUTRAL_HEAVY,
|
|
61
65
|
loadingBarTime: '0',
|
|
62
|
-
isFlat: false,
|
|
63
66
|
isContentScrollable: false,
|
|
64
67
|
} as Args;
|
|
65
68
|
|
|
@@ -70,6 +73,17 @@ const argTypes = {
|
|
|
70
73
|
},
|
|
71
74
|
footer: { control: 'text' },
|
|
72
75
|
experimentalContent: { control: 'text' },
|
|
76
|
+
isFlat: {
|
|
77
|
+
control: 'boolean',
|
|
78
|
+
},
|
|
79
|
+
elevation: {
|
|
80
|
+
control: 'select',
|
|
81
|
+
options: Object.values(CARD_ELEVATIONS),
|
|
82
|
+
},
|
|
83
|
+
radius: {
|
|
84
|
+
control: 'select',
|
|
85
|
+
options: Object.values(CARD_RADIUSES),
|
|
86
|
+
},
|
|
73
87
|
backgroundColor: {
|
|
74
88
|
control: 'select',
|
|
75
89
|
options: Object.values(CARD_BACKGROUND_COLORS),
|
|
@@ -108,3 +122,8 @@ Interactive.parameters = {
|
|
|
108
122
|
url: 'https://www.figma.com/file/izQdYyiBR1GQgFkaOIfIJI/LMS---DS---Components?node-id=1552%3A34959',
|
|
109
123
|
},
|
|
110
124
|
};
|
|
125
|
+
|
|
126
|
+
export const Flat = StoryTemplate.bind({});
|
|
127
|
+
|
|
128
|
+
Flat.argTypes = argTypes;
|
|
129
|
+
Flat.args = { ...args, isFlat: true };
|
|
@@ -3,12 +3,17 @@
|
|
|
3
3
|
:class="[
|
|
4
4
|
'ds-card',
|
|
5
5
|
{
|
|
6
|
+
'-ds-paddingMedium': paddingSize === CARD_PADDING_SIZES.MEDIUM,
|
|
6
7
|
'-ds-paddingLarge': paddingSize === CARD_PADDING_SIZES.LARGE,
|
|
7
8
|
'-ds-leftRibbon':
|
|
8
9
|
hasRibbon && !hasLoadingBar && ribbonPosition === CARD_RIBBON_POSITIONS.LEFT,
|
|
9
|
-
'-ds-
|
|
10
|
-
'-ds-
|
|
11
|
-
'-ds-
|
|
10
|
+
'-ds-elevationTop': effectiveElevation === CARD_ELEVATIONS.TOP,
|
|
11
|
+
'-ds-elevationNone': effectiveElevation === CARD_ELEVATIONS.NONE,
|
|
12
|
+
'-ds-radiusTop': effectiveRadius === CARD_RADIUSES.TOP,
|
|
13
|
+
'-ds-radiusNone': effectiveRadius === CARD_RADIUSES.NONE,
|
|
14
|
+
'-ds-backgroundNeutral':
|
|
15
|
+
effectiveBackgroundColor === CARD_BACKGROUND_COLORS.NEUTRAL,
|
|
16
|
+
'-ds-backgroundNone': effectiveBackgroundColor === CARD_BACKGROUND_COLORS.NONE,
|
|
12
17
|
},
|
|
13
18
|
]"
|
|
14
19
|
>
|
|
@@ -80,23 +85,36 @@
|
|
|
80
85
|
$root: &;
|
|
81
86
|
$card-border-radius: $radius-m;
|
|
82
87
|
|
|
88
|
+
background-color: $color-default-background;
|
|
89
|
+
border-radius: $card-border-radius;
|
|
90
|
+
box-shadow: $shadow-s;
|
|
83
91
|
display: flex;
|
|
84
92
|
flex-direction: column;
|
|
85
93
|
position: relative;
|
|
86
94
|
width: inherit;
|
|
87
95
|
|
|
88
|
-
|
|
89
|
-
background-color: $color-
|
|
90
|
-
|
|
91
|
-
box-shadow: $shadow-s;
|
|
96
|
+
&.-ds-backgroundNeutral {
|
|
97
|
+
background-color: $color-neutral-background;
|
|
98
|
+
}
|
|
92
99
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
100
|
+
&.-ds-backgroundNone {
|
|
101
|
+
background-color: transparent;
|
|
102
|
+
}
|
|
96
103
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
104
|
+
&.-ds-elevationTop {
|
|
105
|
+
box-shadow: $shadow-top-s;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
&.-ds-elevationNone {
|
|
109
|
+
box-shadow: none;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
&.-ds-radiusTop {
|
|
113
|
+
border-radius: $card-border-radius $card-border-radius 0 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
&.-ds-radiusNone {
|
|
117
|
+
border-radius: 0;
|
|
100
118
|
}
|
|
101
119
|
|
|
102
120
|
&.-ds-leftRibbon {
|
|
@@ -127,6 +145,10 @@
|
|
|
127
145
|
&.-ds-withPadding {
|
|
128
146
|
padding: $space-8;
|
|
129
147
|
|
|
148
|
+
#{$root}.-ds-paddingMedium & {
|
|
149
|
+
padding: $space-12 $space-12 $space-8;
|
|
150
|
+
}
|
|
151
|
+
|
|
130
152
|
#{$root}.-ds-paddingLarge & {
|
|
131
153
|
padding: $space-16 $space-16 $space-8;
|
|
132
154
|
}
|
|
@@ -137,6 +159,10 @@
|
|
|
137
159
|
&.-ds-withHorizontalMargin {
|
|
138
160
|
margin: 0 $space-8;
|
|
139
161
|
|
|
162
|
+
#{$root}.-ds-paddingMedium & {
|
|
163
|
+
margin: 0 $space-12;
|
|
164
|
+
}
|
|
165
|
+
|
|
140
166
|
#{$root}.-ds-paddingLarge & {
|
|
141
167
|
margin: 0 $space-16;
|
|
142
168
|
}
|
|
@@ -149,6 +175,10 @@
|
|
|
149
175
|
&.-ds-withPadding {
|
|
150
176
|
padding: $space-8;
|
|
151
177
|
|
|
178
|
+
#{$root}.-ds-paddingMedium & {
|
|
179
|
+
padding: $space-8 $space-12;
|
|
180
|
+
}
|
|
181
|
+
|
|
152
182
|
#{$root}.-ds-paddingLarge & {
|
|
153
183
|
padding: $space-8 $space-16;
|
|
154
184
|
}
|
|
@@ -164,6 +194,10 @@
|
|
|
164
194
|
&.-ds-withPadding {
|
|
165
195
|
padding: 0 $space-8 $space-8;
|
|
166
196
|
|
|
197
|
+
#{$root}.-ds-paddingMedium & {
|
|
198
|
+
padding: 0 $space-12 $space-12;
|
|
199
|
+
}
|
|
200
|
+
|
|
167
201
|
#{$root}.-ds-paddingLarge & {
|
|
168
202
|
padding: 0 $space-16 $space-16;
|
|
169
203
|
}
|
|
@@ -176,20 +210,21 @@
|
|
|
176
210
|
display: flex;
|
|
177
211
|
flex-shrink: 0;
|
|
178
212
|
|
|
179
|
-
#{$root}:not(.-ds-
|
|
213
|
+
#{$root}:not(.-ds-radiusNone) & {
|
|
180
214
|
border-top-left-radius: $card-border-radius;
|
|
181
215
|
border-top-right-radius: $card-border-radius;
|
|
182
216
|
overflow: hidden;
|
|
183
217
|
}
|
|
184
218
|
|
|
185
|
-
#{$root}:not(.-ds-
|
|
186
|
-
border-bottom-left-radius: $card-border-radius;
|
|
219
|
+
#{$root}:not(.-ds-radiusNone).-ds-leftRibbon & {
|
|
187
220
|
border-top-left-radius: $card-border-radius;
|
|
188
221
|
border-top-right-radius: 0;
|
|
189
222
|
}
|
|
190
223
|
|
|
191
|
-
|
|
192
|
-
|
|
224
|
+
// a left ribbon spans the full height of the card, so its bottom corner is
|
|
225
|
+
// only rounded when the card itself is rounded at the bottom
|
|
226
|
+
#{$root}:not(.-ds-radiusNone):not(.-ds-radiusTop).-ds-leftRibbon & {
|
|
227
|
+
border-bottom-left-radius: $card-border-radius;
|
|
193
228
|
}
|
|
194
229
|
|
|
195
230
|
.-ds-leftRibbon & {
|
|
@@ -213,13 +248,18 @@ import DsDivider from '../../Divider/Divider.vue';
|
|
|
213
248
|
import DsLoadingBar, { LOADING_BAR_COLORS, LoadingBarColors } from '../../LoadingBar';
|
|
214
249
|
import DsContainerRibbon from '../../ContainerRibbon/ContainerRibbon.vue';
|
|
215
250
|
import { CONTAINER_RIBBON_LAYOUTS, CONTAINER_RIBBON_RADIUSES } from '../../ContainerRibbon';
|
|
251
|
+
import { RemovedProp } from '../../../utils/type.utils';
|
|
216
252
|
import {
|
|
217
253
|
CARD_BACKGROUND_COLORS,
|
|
254
|
+
CARD_ELEVATIONS,
|
|
255
|
+
CARD_RADIUSES,
|
|
218
256
|
CARD_RIBBON_COLORS,
|
|
219
257
|
CARD_RIBBON_POSITIONS,
|
|
220
258
|
CARD_RIBBON_SIZES,
|
|
221
259
|
CARD_PADDING_SIZES,
|
|
222
260
|
CardBackgroundColor,
|
|
261
|
+
CardElevation,
|
|
262
|
+
CardRadius,
|
|
223
263
|
CardRibbonColors,
|
|
224
264
|
CardRibbonPositions,
|
|
225
265
|
CardRibbonSizes,
|
|
@@ -234,8 +274,10 @@ const {
|
|
|
234
274
|
paddingSize = CARD_PADDING_SIZES.SMALL,
|
|
235
275
|
dividerUnderHeader = false,
|
|
236
276
|
hasRibbon = false,
|
|
237
|
-
|
|
277
|
+
elevation = CARD_ELEVATIONS.DEFAULT,
|
|
278
|
+
radius = CARD_RADIUSES.ALL,
|
|
238
279
|
backgroundColor = CARD_BACKGROUND_COLORS.DEFAULT,
|
|
280
|
+
isFlat = false,
|
|
239
281
|
ribbonPosition = CARD_RIBBON_POSITIONS.TOP,
|
|
240
282
|
ribbonSize = CARD_RIBBON_SIZES.MEDIUM,
|
|
241
283
|
ribbonColor = CARD_RIBBON_COLORS.NEUTRAL_HEAVY,
|
|
@@ -243,7 +285,6 @@ const {
|
|
|
243
285
|
hasLoadingBar = false,
|
|
244
286
|
loadingBarColor = LOADING_BAR_COLORS.NEUTRAL_HEAVY,
|
|
245
287
|
loadingBarTime = '0',
|
|
246
|
-
isFlat = false,
|
|
247
288
|
isContentScrollable = false,
|
|
248
289
|
} = defineProps<{
|
|
249
290
|
contentHasPadding?: boolean;
|
|
@@ -252,8 +293,15 @@ const {
|
|
|
252
293
|
paddingSize?: CardPaddingSize;
|
|
253
294
|
dividerUnderHeader?: boolean;
|
|
254
295
|
hasRibbon?: boolean;
|
|
255
|
-
|
|
296
|
+
elevation?: CardElevation;
|
|
297
|
+
radius?: CardRadius;
|
|
256
298
|
backgroundColor?: CardBackgroundColor;
|
|
299
|
+
/**
|
|
300
|
+
* Shorthand for `elevation="none"`, `radius="none"` and `background-color="none"`.
|
|
301
|
+
* An axis explicitly set to a non-default value still wins over `isFlat`,
|
|
302
|
+
* so `is-flat radius="top"` keeps the top corners rounded.
|
|
303
|
+
*/
|
|
304
|
+
isFlat?: boolean;
|
|
257
305
|
ribbonPosition?: CardRibbonPositions;
|
|
258
306
|
ribbonSize?: CardRibbonSizes;
|
|
259
307
|
ribbonColor?: CardRibbonColors;
|
|
@@ -261,8 +309,10 @@ const {
|
|
|
261
309
|
hasLoadingBar?: boolean;
|
|
262
310
|
loadingBarColor?: LoadingBarColors;
|
|
263
311
|
loadingBarTime?: string;
|
|
264
|
-
isFlat?: boolean;
|
|
265
312
|
isContentScrollable?: boolean;
|
|
313
|
+
// Removed props kept as removal markers so existing usages fail type-checking.
|
|
314
|
+
/** @deprecated renamed to `radius` (all | top | none) */
|
|
315
|
+
hasRadius?: RemovedProp<'renamed to radius'>;
|
|
266
316
|
}>();
|
|
267
317
|
|
|
268
318
|
defineSlots<{
|
|
@@ -280,12 +330,29 @@ const ribbonLayout = computed(() => {
|
|
|
280
330
|
return layoutMap[ribbonPosition] || CONTAINER_RIBBON_LAYOUTS.HORIZONTAL;
|
|
281
331
|
});
|
|
282
332
|
|
|
333
|
+
// `isFlat` is a shorthand that lowers the defaults of the three visual axes to `none`.
|
|
334
|
+
// An axis explicitly set to a non-default value still wins, so `isFlat` combines with
|
|
335
|
+
// e.g. `radius="top"`.
|
|
336
|
+
const effectiveElevation = computed(() =>
|
|
337
|
+
isFlat && elevation === CARD_ELEVATIONS.DEFAULT ? CARD_ELEVATIONS.NONE : elevation,
|
|
338
|
+
);
|
|
339
|
+
|
|
340
|
+
const effectiveRadius = computed(() =>
|
|
341
|
+
isFlat && radius === CARD_RADIUSES.ALL ? CARD_RADIUSES.NONE : radius,
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
const effectiveBackgroundColor = computed(() =>
|
|
345
|
+
isFlat && backgroundColor === CARD_BACKGROUND_COLORS.DEFAULT
|
|
346
|
+
? CARD_BACKGROUND_COLORS.NONE
|
|
347
|
+
: backgroundColor,
|
|
348
|
+
);
|
|
349
|
+
|
|
283
350
|
const ribbonRadius = computed(() => {
|
|
284
351
|
const ribbonPositionToRibbonRadiusMap = {
|
|
285
352
|
[CARD_RIBBON_POSITIONS.TOP]: CONTAINER_RIBBON_RADIUSES.BOTTOM,
|
|
286
353
|
[CARD_RIBBON_POSITIONS.LEFT]: CONTAINER_RIBBON_RADIUSES.RIGHT,
|
|
287
354
|
};
|
|
288
|
-
return hasRibbonRadius &&
|
|
355
|
+
return hasRibbonRadius && effectiveRadius.value === CARD_RADIUSES.NONE
|
|
289
356
|
? ribbonPositionToRibbonRadiusMap[ribbonPosition]
|
|
290
357
|
: CONTAINER_RIBBON_RADIUSES.NONE;
|
|
291
358
|
});
|
|
@@ -36,30 +36,26 @@
|
|
|
36
36
|
</template>
|
|
37
37
|
|
|
38
38
|
<style lang="scss" scoped>
|
|
39
|
-
@import '../../../../lib/styles/settings/colors/tokens';
|
|
40
|
-
@import '../../../../lib/styles/settings/radiuses';
|
|
41
39
|
@import '../../../../lib/styles/settings/spacings';
|
|
42
|
-
@import '../../../../lib/styles/
|
|
40
|
+
@import '../../../../lib/styles/mixins/dropdown-surface';
|
|
43
41
|
|
|
44
42
|
.ds-dropdown {
|
|
45
|
-
|
|
43
|
+
@include dropdownSurface;
|
|
44
|
+
|
|
45
|
+
// Resets for the styles vue-popperjs ships in vue-popper.css.
|
|
46
46
|
border: 0;
|
|
47
47
|
border-radius: 0;
|
|
48
|
-
box-shadow: $shadow-m;
|
|
49
48
|
max-width: 100%;
|
|
50
49
|
min-width: 128px;
|
|
51
|
-
overflow: hidden;
|
|
52
50
|
padding: 0;
|
|
53
51
|
text-align: left;
|
|
54
52
|
|
|
55
53
|
&.-ds-radiusBottom {
|
|
56
|
-
|
|
57
|
-
border-bottom-right-radius: $radius-s;
|
|
54
|
+
@include dropdownSurfaceRadiusBottom;
|
|
58
55
|
}
|
|
59
56
|
|
|
60
57
|
&.-ds-radiusTop {
|
|
61
|
-
|
|
62
|
-
border-top-right-radius: $radius-s;
|
|
58
|
+
@include dropdownSurfaceRadiusTop;
|
|
63
59
|
}
|
|
64
60
|
|
|
65
61
|
&[x-placement^='bottom'] {
|
|
@@ -104,6 +104,21 @@ describe('CheckboxGroupField', () => {
|
|
|
104
104
|
);
|
|
105
105
|
});
|
|
106
106
|
|
|
107
|
+
it('sets aria-describedby only when a message is rendered', () => {
|
|
108
|
+
const wrapper = mount(CheckboxGroupField, {
|
|
109
|
+
props: {
|
|
110
|
+
label: 'Test Label',
|
|
111
|
+
},
|
|
112
|
+
slots: {
|
|
113
|
+
field: '<div>Content</div>',
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
expect(
|
|
118
|
+
wrapper.find('.ds-checkboxGroupField').attributes('aria-describedby'),
|
|
119
|
+
).toBeUndefined();
|
|
120
|
+
});
|
|
121
|
+
|
|
107
122
|
describe('vee-validate integration', () => {
|
|
108
123
|
it('integrates with vee-validate form context and reflects initial values', async () => {
|
|
109
124
|
// eslint-disable-next-line vue/one-component-per-file
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
v-model="value"
|
|
6
6
|
class="ds-checkboxGroupField"
|
|
7
7
|
role="group"
|
|
8
|
-
:aria-describedby="messageId"
|
|
8
|
+
:aria-describedby="hasMessage ? messageId : undefined"
|
|
9
9
|
:aria-labelledby="labelId"
|
|
10
10
|
:disabled="formFieldProps.state === FORM_FIELD_STATES.DISABLED"
|
|
11
11
|
loop
|
|
@@ -64,7 +64,7 @@ const {
|
|
|
64
64
|
...rest
|
|
65
65
|
} = defineProps<CheckboxGroupFieldProps>();
|
|
66
66
|
|
|
67
|
-
defineSlots<CheckboxGroupFieldSlots>();
|
|
67
|
+
const slots = defineSlots<CheckboxGroupFieldSlots>();
|
|
68
68
|
|
|
69
69
|
const modelValue = defineModel<Array<string>>({
|
|
70
70
|
default: [],
|
|
@@ -77,6 +77,9 @@ const formFieldProps = computed<FormFieldProps>(() => {
|
|
|
77
77
|
return extractFormFieldProps(rest, errors.value);
|
|
78
78
|
});
|
|
79
79
|
|
|
80
|
+
// Avoids pointing `aria-describedby` at a message element that is never rendered.
|
|
81
|
+
const hasMessage = computed(() => !!(formFieldProps.value.messageText || slots.message));
|
|
82
|
+
|
|
80
83
|
const mappedState = computed(() => {
|
|
81
84
|
const stateMap: Record<FormFieldState, CheckboxState> = {
|
|
82
85
|
[FORM_FIELD_STATES.DEFAULT]: CHECKBOX_STATES.DEFAULT,
|