@bethinkpl/design-system 39.0.1 → 40.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.
Files changed (84) hide show
  1. package/README.md +1 -1
  2. package/dist/design-system.css +1 -1
  3. package/dist/design-system.js +19314 -19127
  4. package/dist/design-system.js.map +1 -1
  5. package/dist/lib/js/components/ActionContent/ActionContent.vue.d.ts +42 -0
  6. package/dist/lib/js/components/ActionContent/index.d.ts +3 -0
  7. package/dist/lib/js/components/Buttons/IconButton/IconButton.vue.d.ts +4 -1
  8. package/dist/lib/js/components/Cards/Card/Card.consts.d.ts +13 -8
  9. package/dist/lib/js/components/Cards/Card/Card.vue.d.ts +22 -9
  10. package/dist/lib/js/components/Cards/CardExpandable/CardExpandable.vue.d.ts +78 -21
  11. package/dist/lib/js/components/Chip/Chip.vue.d.ts +2 -0
  12. package/dist/lib/js/components/DatePickers/DateBox/DateBox.vue.d.ts +4 -1
  13. package/dist/lib/js/components/DatePickers/DatePicker/DatePicker.vue.d.ts +8 -5
  14. package/dist/lib/js/components/DatePickers/DateRangePicker/DateRangePicker.vue.d.ts +5 -2
  15. package/dist/lib/js/components/Divider/Divider.vue.d.ts +1 -1
  16. package/dist/lib/js/components/Drawer/DrawerDivider/DrawerDivider.vue.d.ts +1 -1
  17. package/dist/lib/js/components/Drawer/DrawerHeader/DrawerHeader.vue.d.ts +12 -3
  18. package/dist/lib/js/components/Drawer/DrawerListItem/DrawerListItem.vue.d.ts +3 -0
  19. package/dist/lib/js/components/Drawer/DrawerSection/DrawerSection.vue.d.ts +13 -4
  20. package/dist/lib/js/components/Drawer/DrawerTile/DrawerTile.vue.d.ts +4 -4
  21. package/dist/lib/js/components/Dropdown/Dropdown.vue.d.ts +1 -1
  22. package/dist/lib/js/components/Form/FormField/FormField.utils.d.ts +1 -1
  23. package/dist/lib/js/components/Form/InputField/InputField.vue.d.ts +2 -2
  24. package/dist/lib/js/components/Form/PasswordField/PasswordField.vue.d.ts +2 -2
  25. package/dist/lib/js/components/Form/RadioButton/RadioButton.vue.d.ts +3 -0
  26. package/dist/lib/js/components/Headers/OverlayHeader/OverlayHeader.vue.d.ts +11 -5
  27. package/dist/lib/js/components/Headers/PageHeader/PageHeader.vue.d.ts +1 -1
  28. package/dist/lib/js/components/Headers/SectionHeader/SectionHeader.vue.d.ts +9 -3
  29. package/dist/lib/js/components/IconText/IconText.vue.d.ts +1 -1
  30. package/dist/lib/js/components/Icons/Icon/Icon.consts.d.ts +3 -0
  31. package/dist/lib/js/components/Image/Image.vue.d.ts +1 -1
  32. package/dist/lib/js/components/Menu/MenuDivider/MenuDivider.vue.d.ts +1 -1
  33. package/dist/lib/js/components/Modal/Modal.vue.d.ts +3 -0
  34. package/dist/lib/js/components/Modals/Modal/Modal.vue.d.ts +8 -2
  35. package/dist/lib/js/components/Modals/ModalDialog/ModalDialog.vue.d.ts +8 -2
  36. package/dist/lib/js/components/Pagination/Pagination.vue.d.ts +8 -2
  37. package/dist/lib/js/components/ProgressBar/ProgressBar.vue.d.ts +3 -0
  38. package/dist/lib/js/components/ProgressDonutChart/ProgressDonutChart.vue.d.ts +3 -0
  39. package/dist/lib/js/components/RichList/BasicRichListItem/BasicRichListItem.vue.d.ts +45 -23
  40. package/dist/lib/js/components/RichList/RichListItem/RichListItem.vue.d.ts +7 -4
  41. package/dist/lib/js/components/SelectList/SelectListItemDivider/SelectListItemDivider.vue.d.ts +1 -1
  42. package/dist/lib/js/components/Skeleton/Skeleton.vue.d.ts +1 -1
  43. package/dist/lib/js/components/Statuses/AccessStatus/AccessStatus.vue.d.ts +3 -0
  44. package/dist/lib/js/components/Statuses/BlockadeStatus/BlockadeStatus.vue.d.ts +3 -0
  45. package/dist/lib/js/components/SurveyQuestions/SurveyQuestionOpenEnded/SurveyQuestionOpenEnded.vue.d.ts +85 -22
  46. package/dist/lib/js/components/SurveyQuestions/SurveyQuestionScale/SurveyQuestionScale.vue.d.ts +85 -22
  47. package/dist/lib/js/components/Switch/Switch.vue.d.ts +3 -0
  48. package/dist/lib/js/components/TextGroup/TextGroup.consts.d.ts +14 -3
  49. package/dist/lib/js/components/TextGroup/TextGroup.vue.d.ts +8 -3
  50. package/dist/lib/js/components/Tile/Tile.sb.shared.d.ts +5 -2
  51. package/dist/lib/js/components/Tile/Tile.vue.d.ts +2 -2
  52. package/dist/lib/js/components/Toast/Toast.vue.d.ts +76 -22
  53. package/dist/lib/js/components/Toggles/ToggleButton/ToggleButton.vue.d.ts +5 -2
  54. package/dist/lib/js/components/Well/Well.consts.d.ts +24 -0
  55. package/dist/lib/js/components/Well/Well.vue.d.ts +13 -1
  56. package/dist/lib/js/icons/fontawesome.d.ts +2 -0
  57. package/dist/lib/js/index.d.ts +2 -0
  58. package/dist/lib/js/utils/type.utils.d.ts +3 -0
  59. package/lib/images/icons/comment-lock.svg +1 -0
  60. package/lib/js/components/ActionContent/ActionContent.spec.ts +99 -0
  61. package/lib/js/components/ActionContent/ActionContent.stories.ts +141 -0
  62. package/lib/js/components/ActionContent/ActionContent.vue +104 -0
  63. package/lib/js/components/ActionContent/index.ts +3 -0
  64. package/lib/js/components/Cards/Card/Card.consts.ts +15 -8
  65. package/lib/js/components/Cards/Card/Card.spec.ts +61 -1
  66. package/lib/js/components/Cards/Card/Card.stories.ts +20 -13
  67. package/lib/js/components/Cards/Card/Card.vue +65 -34
  68. package/lib/js/components/Chip/Chip.spec.ts +28 -0
  69. package/lib/js/components/Chip/Chip.stories.ts +7 -2
  70. package/lib/js/components/Chip/Chip.vue +14 -3
  71. package/lib/js/components/Icons/Icon/Icon.consts.ts +2 -0
  72. package/lib/js/components/ProgressDonutChart/ProgressDonutChart.spec.ts +3 -3
  73. package/lib/js/components/RichList/BasicRichListItem/BasicRichListItem.vue +8 -1
  74. package/lib/js/components/TextGroup/TextGroup.consts.ts +15 -1
  75. package/lib/js/components/TextGroup/TextGroup.stories.ts +14 -5
  76. package/lib/js/components/TextGroup/TextGroup.vue +51 -28
  77. package/lib/js/components/Well/Well.consts.ts +16 -0
  78. package/lib/js/components/Well/Well.spec.ts +112 -0
  79. package/lib/js/components/Well/Well.stories.ts +90 -1
  80. package/lib/js/components/Well/Well.vue +135 -4
  81. package/lib/js/icons/fontawesome.ts +4 -0
  82. package/lib/js/index.ts +2 -0
  83. package/lib/js/utils/type.utils.ts +16 -0
  84. package/package.json +14 -6
@@ -12,21 +12,28 @@ export const CARD_PADDING_SIZES = {
12
12
 
13
13
  export type CardPaddingSize = Value<typeof CARD_PADDING_SIZES>;
14
14
 
15
- export const CARD_BORDER_COLORS = CONTAINER_RIBBON_COLORS;
15
+ export const CARD_BACKGROUND_COLORS = {
16
+ DEFAULT: 'default',
17
+ NEUTRAL: 'neutral',
18
+ } as const;
19
+
20
+ export type CardBackgroundColor = Value<typeof CARD_BACKGROUND_COLORS>;
21
+
22
+ export const CARD_RIBBON_COLORS = CONTAINER_RIBBON_COLORS;
16
23
 
17
- export type CardBorderColors = Value<typeof CARD_BORDER_COLORS>;
24
+ export type CardRibbonColors = Value<typeof CARD_RIBBON_COLORS>;
18
25
 
19
- export const CARD_BORDER_SIZES = CONTAINER_RIBBON_SIZES;
26
+ export const CARD_RIBBON_SIZES = CONTAINER_RIBBON_SIZES;
20
27
 
21
- export type CardBorderSizes = Value<typeof CARD_BORDER_SIZES>;
28
+ export type CardRibbonSizes = Value<typeof CARD_RIBBON_SIZES>;
22
29
 
23
- export const CARD_BORDER_POSITIONS = {
30
+ export const CARD_RIBBON_POSITIONS = {
24
31
  TOP: 'top',
25
32
  LEFT: 'left',
26
33
  } as const;
27
34
 
28
- export type CardBorderPositions = Value<typeof CARD_BORDER_POSITIONS>;
35
+ export type CardRibbonPositions = Value<typeof CARD_RIBBON_POSITIONS>;
29
36
 
30
- export const CARD_BORDER_RADIUS = CONTAINER_RIBBON_RADIUSES;
37
+ export const CARD_RIBBON_RADIUS = CONTAINER_RIBBON_RADIUSES;
31
38
 
32
- export type CardBorderRadius = Value<typeof CARD_BORDER_RADIUS>;
39
+ export type CardRibbonRadius = Value<typeof CARD_RIBBON_RADIUS>;
@@ -3,7 +3,7 @@ import { ComponentMountingOptions, mount } from '@vue/test-utils';
3
3
  import { h } from 'vue';
4
4
 
5
5
  import Card from './Card.vue';
6
- import { CARD_PADDING_SIZES } from './Card.consts';
6
+ import { CARD_BACKGROUND_COLORS, CARD_PADDING_SIZES } from './Card.consts';
7
7
 
8
8
  describe('Card', () => {
9
9
  const createComponent = (options: ComponentMountingOptions<typeof Card> = {}) => {
@@ -177,4 +177,64 @@ describe('Card', () => {
177
177
 
178
178
  expect(component.find('.ds-card').classes()).toContain('-ds-flat');
179
179
  });
180
+
181
+ it('should not set no-radius class by default', () => {
182
+ const component = createComponent();
183
+
184
+ expect(component.find('.ds-card').classes()).not.toContain('-ds-noRadius');
185
+ });
186
+
187
+ it('should set no-radius class when hasRadius is false', () => {
188
+ const component = createComponent({
189
+ props: { hasRadius: false },
190
+ });
191
+
192
+ expect(component.find('.ds-card').classes()).toContain('-ds-noRadius');
193
+ });
194
+
195
+ it('should not set neutral background class by default', () => {
196
+ const component = createComponent();
197
+
198
+ expect(component.find('.ds-card').classes()).not.toContain('-ds-backgroundNeutral');
199
+ });
200
+
201
+ it('should set neutral background class when backgroundColor is neutral', () => {
202
+ const component = createComponent({
203
+ props: { backgroundColor: CARD_BACKGROUND_COLORS.NEUTRAL },
204
+ });
205
+
206
+ expect(component.find('.ds-card').classes()).toContain('-ds-backgroundNeutral');
207
+ });
208
+
209
+ it('should not give the ribbon a radius when only hasRibbonRadius is set', () => {
210
+ const component = createComponent({
211
+ props: { hasRibbon: true, hasRibbonRadius: true },
212
+ });
213
+
214
+ expect(component.find('.-ds-radius-bottom').exists()).toBe(false);
215
+ });
216
+
217
+ it('should give the ribbon a radius when hasRibbonRadius and card has no radius', () => {
218
+ const component = createComponent({
219
+ props: { hasRibbon: true, hasRibbonRadius: true, hasRadius: false },
220
+ });
221
+
222
+ expect(component.find('.-ds-radius-bottom').exists()).toBe(true);
223
+ });
224
+
225
+ it('should not give the ribbon a radius when hasRadius is false but hasRibbonRadius is false', () => {
226
+ const component = createComponent({
227
+ props: { hasRibbon: true, hasRibbonRadius: false, hasRadius: false },
228
+ });
229
+
230
+ expect(component.find('.-ds-radius-bottom').exists()).toBe(false);
231
+ });
232
+
233
+ it('should give the ribbon a radius when hasRibbonRadius and card is flat', () => {
234
+ const component = createComponent({
235
+ props: { hasRibbon: true, hasRibbonRadius: true, isFlat: true },
236
+ });
237
+
238
+ expect(component.find('.-ds-radius-bottom').exists()).toBe(true);
239
+ });
180
240
  });
@@ -2,9 +2,10 @@ import Card from './Card.vue';
2
2
 
3
3
  import { Args, ArgTypes, Meta, StoryFn } from '@storybook/vue3';
4
4
  import {
5
- CARD_BORDER_COLORS,
6
- CARD_BORDER_POSITIONS,
7
- CARD_BORDER_SIZES,
5
+ CARD_BACKGROUND_COLORS,
6
+ CARD_RIBBON_COLORS,
7
+ CARD_RIBBON_POSITIONS,
8
+ CARD_RIBBON_SIZES,
8
9
  CARD_PADDING_SIZES,
9
10
  } from './Card.consts';
10
11
  import { LOADING_BAR_COLORS } from '../../LoadingBar';
@@ -44,10 +45,12 @@ const args = {
44
45
  footerHasPadding: false,
45
46
  paddingSize: CARD_PADDING_SIZES.SMALL,
46
47
  dividerUnderHeader: false,
47
- hasBorder: false,
48
- borderPosition: CARD_BORDER_POSITIONS.TOP,
49
- borderSize: CARD_BORDER_SIZES.LARGE,
50
- borderColor: CARD_BORDER_COLORS.NEUTRAL_HEAVY,
48
+ hasRibbon: false,
49
+ hasRadius: true,
50
+ backgroundColor: CARD_BACKGROUND_COLORS.DEFAULT,
51
+ ribbonPosition: CARD_RIBBON_POSITIONS.TOP,
52
+ ribbonSize: CARD_RIBBON_SIZES.MEDIUM,
53
+ ribbonColor: CARD_RIBBON_COLORS.NEUTRAL_HEAVY,
51
54
  hasRibbonRadius: false,
52
55
  hasLoadingBar: false,
53
56
  loadingBarColor: LOADING_BAR_COLORS.NEUTRAL_HEAVY,
@@ -62,17 +65,21 @@ const argTypes = {
62
65
  control: 'text',
63
66
  },
64
67
  footer: { control: 'text' },
65
- borderPosition: {
68
+ backgroundColor: {
66
69
  control: 'select',
67
- options: Object.values(CARD_BORDER_POSITIONS),
70
+ options: Object.values(CARD_BACKGROUND_COLORS),
68
71
  },
69
- borderSize: {
72
+ ribbonPosition: {
70
73
  control: 'select',
71
- options: Object.values(CARD_BORDER_SIZES),
74
+ options: Object.values(CARD_RIBBON_POSITIONS),
72
75
  },
73
- borderColor: {
76
+ ribbonSize: {
74
77
  control: 'select',
75
- options: Object.values(CARD_BORDER_COLORS),
78
+ options: Object.values(CARD_RIBBON_SIZES),
79
+ },
80
+ ribbonColor: {
81
+ control: 'select',
82
+ options: Object.values(CARD_RIBBON_COLORS),
76
83
  },
77
84
  hasRibbonRadius: {
78
85
  control: 'boolean',
@@ -4,17 +4,19 @@
4
4
  'ds-card',
5
5
  {
6
6
  '-ds-paddingLarge': paddingSize === CARD_PADDING_SIZES.LARGE,
7
- '-ds-leftBorder':
8
- hasBorder && !hasLoadingBar && borderPosition === CARD_BORDER_POSITIONS.LEFT,
7
+ '-ds-leftRibbon':
8
+ hasRibbon && !hasLoadingBar && ribbonPosition === CARD_RIBBON_POSITIONS.LEFT,
9
9
  '-ds-flat': isFlat,
10
+ '-ds-noRadius': !hasRadius,
11
+ '-ds-backgroundNeutral': backgroundColor === CARD_BACKGROUND_COLORS.NEUTRAL,
10
12
  },
11
13
  ]"
12
14
  >
13
- <div v-if="hasBorder || hasLoadingBar" class="ds-card__border">
15
+ <div v-if="hasRibbon || hasLoadingBar" class="ds-card__ribbon">
14
16
  <ds-container-ribbon
15
- v-if="hasBorder && !hasLoadingBar"
16
- :size="borderSize"
17
- :color="borderColor"
17
+ v-if="hasRibbon && !hasLoadingBar"
18
+ :size="ribbonSize"
19
+ :color="ribbonColor"
18
20
  :layout="ribbonLayout"
19
21
  :radius="ribbonRadius"
20
22
  />
@@ -22,7 +24,7 @@
22
24
  v-if="hasLoadingBar"
23
25
  :time="loadingBarTime"
24
26
  :color="loadingBarColor"
25
- :size="borderSize"
27
+ :size="ribbonSize"
26
28
  />
27
29
  </div>
28
30
 
@@ -82,9 +84,17 @@
82
84
  background-color: $color-default-background;
83
85
  border-radius: $card-border-radius;
84
86
  box-shadow: $shadow-s;
87
+
88
+ &.-ds-backgroundNeutral {
89
+ background-color: $color-neutral-background;
90
+ }
91
+
92
+ &.-ds-noRadius {
93
+ border-radius: 0;
94
+ }
85
95
  }
86
96
 
87
- &.-ds-leftBorder {
97
+ &.-ds-leftRibbon {
88
98
  flex-direction: row;
89
99
  }
90
100
 
@@ -147,9 +157,9 @@
147
157
  }
148
158
  }
149
159
 
150
- // the border container is added to avoid adding overflow hidden to the card itself
160
+ // the ribbon container is added to avoid adding overflow hidden to the card itself
151
161
  // which would clip floating elements rendered within the card (e.g. dropdowns)
152
- &__border {
162
+ &__ribbon {
153
163
  display: flex;
154
164
  flex-shrink: 0;
155
165
 
@@ -159,13 +169,17 @@
159
169
  overflow: hidden;
160
170
  }
161
171
 
162
- #{$root}:not(.-ds-flat).-ds-leftBorder & {
172
+ #{$root}:not(.-ds-flat).-ds-leftRibbon & {
163
173
  border-bottom-left-radius: $card-border-radius;
164
174
  border-top-left-radius: $card-border-radius;
165
175
  border-top-right-radius: 0;
166
176
  }
167
177
 
168
- .-ds-leftBorder & {
178
+ #{$root}:not(.-ds-flat).-ds-noRadius & {
179
+ border-radius: 0;
180
+ }
181
+
182
+ .-ds-leftRibbon & {
169
183
  height: 100%;
170
184
  left: 0;
171
185
  position: absolute;
@@ -178,18 +192,21 @@
178
192
  <script lang="ts" setup>
179
193
  import { computed } from 'vue';
180
194
 
195
+ import { RemovedProp } from '../../../utils/type.utils';
181
196
  import DsDivider from '../../Divider/Divider.vue';
182
197
  import DsLoadingBar, { LOADING_BAR_COLORS, LoadingBarColors } from '../../LoadingBar';
183
198
  import DsContainerRibbon from '../../ContainerRibbon/ContainerRibbon.vue';
184
199
  import { CONTAINER_RIBBON_LAYOUTS, CONTAINER_RIBBON_RADIUSES } from '../../ContainerRibbon';
185
200
  import {
186
- CARD_BORDER_COLORS,
187
- CARD_BORDER_POSITIONS,
188
- CARD_BORDER_SIZES,
201
+ CARD_BACKGROUND_COLORS,
202
+ CARD_RIBBON_COLORS,
203
+ CARD_RIBBON_POSITIONS,
204
+ CARD_RIBBON_SIZES,
189
205
  CARD_PADDING_SIZES,
190
- CardBorderColors,
191
- CardBorderPositions,
192
- CardBorderSizes,
206
+ CardBackgroundColor,
207
+ CardRibbonColors,
208
+ CardRibbonPositions,
209
+ CardRibbonSizes,
193
210
  CardPaddingSize,
194
211
  } from './Card.consts';
195
212
 
@@ -200,10 +217,12 @@ const {
200
217
  footerHasPadding = false,
201
218
  paddingSize = CARD_PADDING_SIZES.SMALL,
202
219
  dividerUnderHeader = false,
203
- hasBorder = false,
204
- borderPosition = CARD_BORDER_POSITIONS.TOP,
205
- borderSize = CARD_BORDER_SIZES.LARGE,
206
- borderColor = CARD_BORDER_COLORS.NEUTRAL_HEAVY,
220
+ hasRibbon = false,
221
+ hasRadius = true,
222
+ backgroundColor = CARD_BACKGROUND_COLORS.DEFAULT,
223
+ ribbonPosition = CARD_RIBBON_POSITIONS.TOP,
224
+ ribbonSize = CARD_RIBBON_SIZES.MEDIUM,
225
+ ribbonColor = CARD_RIBBON_COLORS.NEUTRAL_HEAVY,
207
226
  hasRibbonRadius = false,
208
227
  hasLoadingBar = false,
209
228
  loadingBarColor = LOADING_BAR_COLORS.NEUTRAL_HEAVY,
@@ -216,16 +235,28 @@ const {
216
235
  footerHasPadding?: boolean;
217
236
  paddingSize?: CardPaddingSize;
218
237
  dividerUnderHeader?: boolean;
219
- hasBorder?: boolean;
220
- borderPosition?: CardBorderPositions;
221
- borderSize?: CardBorderSizes;
222
- borderColor?: CardBorderColors;
238
+ hasRibbon?: boolean;
239
+ hasRadius?: boolean;
240
+ backgroundColor?: CardBackgroundColor;
241
+ ribbonPosition?: CardRibbonPositions;
242
+ ribbonSize?: CardRibbonSizes;
243
+ ribbonColor?: CardRibbonColors;
223
244
  hasRibbonRadius?: boolean;
224
245
  hasLoadingBar?: boolean;
225
246
  loadingBarColor?: LoadingBarColors;
226
247
  loadingBarTime?: string;
227
248
  isFlat?: boolean;
228
249
  isContentScrollable?: boolean;
250
+
251
+ // Renamed props kept as removal markers so existing usages fail type-checking.
252
+ /** @deprecated renamed to `hasRibbon` */
253
+ hasBorder?: RemovedProp<'renamed to hasRibbon'>;
254
+ /** @deprecated renamed to `ribbonPosition` */
255
+ borderPosition?: RemovedProp<'renamed to ribbonPosition'>;
256
+ /** @deprecated renamed to `ribbonSize` */
257
+ borderSize?: RemovedProp<'renamed to ribbonSize'>;
258
+ /** @deprecated renamed to `ribbonColor` */
259
+ borderColor?: RemovedProp<'renamed to ribbonColor'>;
229
260
  }>();
230
261
 
231
262
  defineSlots<{
@@ -236,19 +267,19 @@ defineSlots<{
236
267
 
237
268
  const ribbonLayout = computed(() => {
238
269
  const layoutMap = {
239
- [CARD_BORDER_POSITIONS.TOP]: CONTAINER_RIBBON_LAYOUTS.HORIZONTAL,
240
- [CARD_BORDER_POSITIONS.LEFT]: CONTAINER_RIBBON_LAYOUTS.VERTICAL,
270
+ [CARD_RIBBON_POSITIONS.TOP]: CONTAINER_RIBBON_LAYOUTS.HORIZONTAL,
271
+ [CARD_RIBBON_POSITIONS.LEFT]: CONTAINER_RIBBON_LAYOUTS.VERTICAL,
241
272
  };
242
- return layoutMap[borderPosition] || CONTAINER_RIBBON_LAYOUTS.HORIZONTAL;
273
+ return layoutMap[ribbonPosition] || CONTAINER_RIBBON_LAYOUTS.HORIZONTAL;
243
274
  });
244
275
 
245
276
  const ribbonRadius = computed(() => {
246
- const borderPositionToRibbonRadiusMap = {
247
- [CARD_BORDER_POSITIONS.TOP]: CONTAINER_RIBBON_RADIUSES.BOTTOM,
248
- [CARD_BORDER_POSITIONS.LEFT]: CONTAINER_RIBBON_RADIUSES.RIGHT,
277
+ const ribbonPositionToRibbonRadiusMap = {
278
+ [CARD_RIBBON_POSITIONS.TOP]: CONTAINER_RIBBON_RADIUSES.BOTTOM,
279
+ [CARD_RIBBON_POSITIONS.LEFT]: CONTAINER_RIBBON_RADIUSES.RIGHT,
249
280
  };
250
- return hasRibbonRadius && isFlat
251
- ? borderPositionToRibbonRadiusMap[borderPosition]
281
+ return hasRibbonRadius && (isFlat || !hasRadius)
282
+ ? ribbonPositionToRibbonRadiusMap[ribbonPosition]
252
283
  : CONTAINER_RIBBON_RADIUSES.NONE;
253
284
  });
254
285
  </script>
@@ -10,6 +10,7 @@ import IconButton from '../Buttons/IconButton';
10
10
  interface createComponentOptions {
11
11
  label?: string;
12
12
  leftIcon?: IconDefinition | null;
13
+ rightIcon?: IconDefinition | null;
13
14
  isRemovable?: boolean;
14
15
  size?: string;
15
16
  color?: string;
@@ -20,6 +21,7 @@ describe('Chip', () => {
20
21
  const createComponent = ({
21
22
  label = 'random label',
22
23
  leftIcon = null,
24
+ rightIcon = null,
23
25
  isRemovable = false,
24
26
  size = CHIP_SIZES.SMALL,
25
27
  color = CHIP_COLORS.NEUTRAL,
@@ -29,6 +31,7 @@ describe('Chip', () => {
29
31
  props: {
30
32
  label,
31
33
  leftIcon,
34
+ rightIcon,
32
35
  isRemovable,
33
36
  size,
34
37
  color,
@@ -65,6 +68,31 @@ describe('Chip', () => {
65
68
  );
66
69
  });
67
70
 
71
+ it("doesn't render rightIcon by default", () => {
72
+ const component = createComponent({ rightIcon: null });
73
+
74
+ expect(component.find('.ds-chip__rightIcon').exists()).toBe(false);
75
+ });
76
+
77
+ it('renders rightIcon', () => {
78
+ const component = createComponent({ rightIcon: Object.freeze(ICONS.FA_TAG) });
79
+
80
+ expect(component.find('.ds-chip__rightIcon').exists()).toBe(true);
81
+ expect(component.find('.ds-chip__rightIcon').findComponent(Icon).props().icon).toEqual(
82
+ ICONS.FA_TAG,
83
+ );
84
+ });
85
+
86
+ it('renders rightIcon before the remove button', () => {
87
+ const component = createComponent({
88
+ rightIcon: Object.freeze(ICONS.FA_TAG),
89
+ isRemovable: true,
90
+ });
91
+
92
+ const html = component.html();
93
+ expect(html.indexOf('ds-chip__rightIcon')).toBeLessThan(html.indexOf('ds-chip__remove'));
94
+ });
95
+
68
96
  it("doesn't render leftIcon by default", () => {
69
97
  const component = createComponent({ isRemovable: false });
70
98
 
@@ -21,7 +21,7 @@ const StoryTemplate: StoryFn<typeof Chip> = (args) => ({
21
21
  return args;
22
22
  },
23
23
  template:
24
- '<chip :label="label" :is-label-uppercase="isLabelUppercase" :left-icon="ICONS[leftIcon]" :is-removable="isRemovable" :size="size" :color="color" :color-hex="colorHex" :state="state" :radius="radius" :is-interactive="isInteractive" />',
24
+ '<chip :label="label" :is-label-uppercase="isLabelUppercase" :left-icon="ICONS[leftIcon]" :right-icon="ICONS[rightIcon]" :is-removable="isRemovable" :size="size" :color="color" :color-hex="colorHex" :state="state" :radius="radius" :is-interactive="isInteractive" />',
25
25
  data() {
26
26
  return {
27
27
  ICONS: Object.freeze(ICONS),
@@ -34,7 +34,7 @@ const StoryTemplateWithAccessory: StoryFn<typeof Chip> = (args) => ({
34
34
  return args;
35
35
  },
36
36
  template:
37
- '<chip :label="label" :is-label-uppercase="isLabelUppercase" :left-icon="ICONS[leftIcon]" :is-removable="isRemovable" :size="size" :color="color" :color-hex="colorHex" :state="state" :radius="radius" :is-interactive="isInteractive">' +
37
+ '<chip :label="label" :is-label-uppercase="isLabelUppercase" :left-icon="ICONS[leftIcon]" :right-icon="ICONS[rightIcon]" :is-removable="isRemovable" :size="size" :color="color" :color-hex="colorHex" :state="state" :radius="radius" :is-interactive="isInteractive">' +
38
38
  '<template #accessory><logo-badge :style="svgStyle" /></template>' +
39
39
  '</chip>',
40
40
  data() {
@@ -59,6 +59,7 @@ const args = {
59
59
  label: 'Chip z labelem',
60
60
  isLabelUppercase: false,
61
61
  leftIcon: null,
62
+ rightIcon: null,
62
63
  radius: CHIP_RADIUSES.CAPSULE,
63
64
  size: CHIP_SIZES.SMALL,
64
65
  color: CHIP_DEFAULT_COLOR,
@@ -72,6 +73,10 @@ const argTypes = {
72
73
  control: 'select',
73
74
  options: [null, ...Object.keys(ICONS)],
74
75
  },
76
+ rightIcon: {
77
+ control: 'select',
78
+ options: [null, ...Object.keys(ICONS)],
79
+ },
75
80
  size: {
76
81
  control: 'select',
77
82
  options: Object.values(CHIP_SIZES),
@@ -23,6 +23,12 @@
23
23
  </slot>
24
24
  </span>
25
25
  <span v-if="label" class="ds-chip__label">{{ label }}</span>
26
+ <span v-if="rightIcon" class="ds-chip__rightIcon">
27
+ <icon
28
+ :icon="rightIcon"
29
+ :size="size === CHIP_SIZES.X_SMALL ? ICON_SIZES.XXX_SMALL : ICON_SIZES.XX_SMALL"
30
+ />
31
+ </span>
26
32
  <icon-button
27
33
  v-if="size !== CHIP_SIZES.X_SMALL && isRemovable"
28
34
  class="ds-chip__remove"
@@ -178,7 +184,8 @@ $chip-colors: (
178
184
  &.-ds-color-#{$color-name} {
179
185
  background-color: map-get($color-map, 'background');
180
186
 
181
- #{$self}__leftIcon {
187
+ #{$self}__leftIcon,
188
+ #{$self}__rightIcon {
182
189
  color: map-get($color-map, 'icon');
183
190
  fill: map-get($color-map, 'icon');
184
191
  }
@@ -198,7 +205,8 @@ $chip-colors: (
198
205
  &.-ds-disabled {
199
206
  background-color: map-get(map-get($color-map, 'disabled'), 'background');
200
207
 
201
- #{$self}__leftIcon {
208
+ #{$self}__leftIcon,
209
+ #{$self}__rightIcon {
202
210
  color: map-get(map-get($color-map, 'disabled'), 'icon');
203
211
  fill: map-get($color-map, 'icon');
204
212
  }
@@ -250,7 +258,8 @@ $chip-colors: (
250
258
  white-space: nowrap;
251
259
  }
252
260
 
253
- &__leftIcon {
261
+ &__leftIcon,
262
+ &__rightIcon {
254
263
  display: flex;
255
264
  }
256
265
 
@@ -315,6 +324,7 @@ const {
315
324
  label = null,
316
325
  isLabelUppercase = false,
317
326
  leftIcon = null,
327
+ rightIcon = null,
318
328
  radius = CHIP_RADIUSES.CAPSULE,
319
329
  size = CHIP_SIZES.SMALL,
320
330
  color = CHIP_DEFAULT_COLOR,
@@ -326,6 +336,7 @@ const {
326
336
  label?: string | null;
327
337
  isLabelUppercase?: boolean;
328
338
  leftIcon?: IconItem | null;
339
+ rightIcon?: IconItem | null;
329
340
  radius?: ChipRadius;
330
341
  size?: ChipSize;
331
342
  color?: ChipColor;
@@ -2,6 +2,7 @@ import HeadWithQuestionMark from '../../../../images/icons/head-with-question-ma
2
2
  import Ribbon from '../../../../images/icons/ribbon.svg';
3
3
  import SlidersSearch from '../../../../images/icons/sliders-search.svg';
4
4
  import CommentsCheck from '../../../../images/icons/comments-check.svg';
5
+ import CommentLock from '../../../../images/icons/comment-lock.svg';
5
6
  import Answers from '../../../../images/icons/icon-answers.svg';
6
7
  import HideAnswers from '../../../../images/icons/icon-hide-answers.svg';
7
8
  import SidebarFlipSolid from '../../../../images/icons/sidebar-flip-solid.svg';
@@ -47,6 +48,7 @@ export type IconSize = Value<typeof ICON_SIZES>;
47
48
  const BETHINK_ICONS = {
48
49
  ANSWERS: Answers,
49
50
  CHANGE: Change,
51
+ COMMENT_LOCK: CommentLock,
50
52
  COMMENTS_CHECK: CommentsCheck,
51
53
  HEAD_WITH_QUESTION_MARK: HeadWithQuestionMark,
52
54
  HIDE_ANSWERS: HideAnswers,
@@ -89,8 +89,8 @@ describe('ProgressDonutChart', () => {
89
89
  });
90
90
  const tracks = component.findAll('.ds-progressDonutChart__track');
91
91
  expect(tracks.length).toBe(3);
92
- expect(tracks.at(0)?.attributes('style')).toBe('--length: 30; transform: rotate(90deg);');
93
- expect(tracks.at(1)?.attributes('style')).toBe('--length: 25; transform: rotate(198deg);');
94
- expect(tracks.at(2)?.attributes('style')).toBe('--length: 25; transform: rotate(288deg);');
92
+ expect(tracks[0]?.attributes('style')).toBe('--length: 30; transform: rotate(90deg);');
93
+ expect(tracks[1]?.attributes('style')).toBe('--length: 25; transform: rotate(198deg);');
94
+ expect(tracks[2]?.attributes('style')).toBe('--length: 25; transform: rotate(288deg);');
95
95
  });
96
96
  });
@@ -36,7 +36,7 @@
36
36
  :eyebrow-text="eyebrow"
37
37
  :eyebrow-text-ellipsis="eyebrowEllipsis"
38
38
  :is-eyebrow-text-uppercase="isEyebrowUppercase"
39
- :is-selected="isTextGroupSelected"
39
+ :main-text-color="textGroupMainTextColor"
40
40
  :is-interactive="false"
41
41
  :main-text="text"
42
42
  :main-text-ellipsis="textEllipsis"
@@ -96,8 +96,10 @@
96
96
  import { defineComponent, PropType, toRaw } from 'vue';
97
97
  import { ICON_COLORS, IconColor, IconItem, ICONS } from '../../Icons/Icon';
98
98
  import {
99
+ TEXT_GROUP_MAIN_TEXT_COLORS,
99
100
  TEXT_GROUP_SIZES,
100
101
  TEXT_GROUP_STATES,
102
+ TextGroupMainTextColor,
101
103
  TextGroupSize,
102
104
  TextGroupState,
103
105
  } from '../../TextGroup';
@@ -290,6 +292,11 @@ export default defineComponent({
290
292
  }
291
293
  return TEXT_GROUP_STATES.DEFAULT;
292
294
  },
295
+ textGroupMainTextColor(): TextGroupMainTextColor {
296
+ return this.isTextGroupSelected
297
+ ? TEXT_GROUP_MAIN_TEXT_COLORS.PRIMARY
298
+ : TEXT_GROUP_MAIN_TEXT_COLORS.NEUTRAL;
299
+ },
293
300
  },
294
301
  });
295
302
  </script>
@@ -13,7 +13,18 @@ export const TEXT_GROUP_SIZES = {
13
13
  X_SMALL: 'x-small',
14
14
  SMALL: 'small',
15
15
  MEDIUM: 'medium',
16
- };
16
+ LARGE: 'large',
17
+ } as const;
18
+
19
+ export const TEXT_GROUP_ALIGNS = {
20
+ LEFT: 'left',
21
+ CENTER: 'center',
22
+ } as const;
23
+
24
+ export const TEXT_GROUP_MAIN_TEXT_COLORS = {
25
+ NEUTRAL: 'neutral',
26
+ PRIMARY: 'primary',
27
+ } as const;
17
28
 
18
29
  export const TEXT_GROUP_STATES = {
19
30
  DEFAULT: 'default',
@@ -28,3 +39,6 @@ export type TextGroupLoadingSize =
28
39
  (typeof TEXT_GROUP_LOADING_SIZES)[keyof typeof TEXT_GROUP_LOADING_SIZES];
29
40
  export type TextGroupSize = (typeof TEXT_GROUP_SIZES)[keyof typeof TEXT_GROUP_SIZES];
30
41
  export type TextGroupState = (typeof TEXT_GROUP_STATES)[keyof typeof TEXT_GROUP_STATES];
42
+ export type TextGroupAlign = (typeof TEXT_GROUP_ALIGNS)[keyof typeof TEXT_GROUP_ALIGNS];
43
+ export type TextGroupMainTextColor =
44
+ (typeof TEXT_GROUP_MAIN_TEXT_COLORS)[keyof typeof TEXT_GROUP_MAIN_TEXT_COLORS];
@@ -2,7 +2,9 @@ import { Args, ArgTypes, Meta, StoryFn } from '@storybook/vue3';
2
2
  import DsDivider from '../Divider/Divider.vue';
3
3
  import DsTextGroup from './TextGroup.vue';
4
4
  import {
5
+ TEXT_GROUP_ALIGNS,
5
6
  TEXT_GROUP_LOADING_SIZES,
7
+ TEXT_GROUP_MAIN_TEXT_COLORS,
6
8
  TEXT_GROUP_PROMINENCE,
7
9
  TEXT_GROUP_SIZES,
8
10
  TEXT_GROUP_STATES,
@@ -21,6 +23,8 @@ const StoryTemplate: StoryFn<typeof DsTextGroup> = (args) => ({
21
23
  template: `
22
24
  <ds-text-group
23
25
  :size="size"
26
+ :align="align"
27
+ :main-text-color="mainTextColor"
24
28
  :prominence="prominence"
25
29
  :eyebrow-text="eyebrowText === 'null' ? null : eyebrowText"
26
30
  :eyebrow-text-ellipsis="eyebrowTextEllipsis"
@@ -31,7 +35,6 @@ const StoryTemplate: StoryFn<typeof DsTextGroup> = (args) => ({
31
35
  :supporting-text-ellipsis="supportingTextEllipsis"
32
36
  :is-interactive="isInteractive"
33
37
  :skeleton-loading-size="skeletonLoadingSize"
34
- :is-selected="isSelected"
35
38
  :state="state"
36
39
  :is-supporting-text-tooltip-enabled="isSupportingTextTooltipEnabled"
37
40
  :is-supporting-text-tooltip-enabled-on-mobile="isSupportingTextTooltipEnabledOnMobile"
@@ -54,6 +57,8 @@ export const Interactive = StoryTemplate.bind({});
54
57
  Interactive.args = {
55
58
  mainTextSlot: '',
56
59
  size: TEXT_GROUP_SIZES.MEDIUM,
60
+ align: TEXT_GROUP_ALIGNS.LEFT,
61
+ mainTextColor: TEXT_GROUP_MAIN_TEXT_COLORS.NEUTRAL,
57
62
  prominence: TEXT_GROUP_PROMINENCE.DEFAULT,
58
63
  eyebrowText: 'Eyebrow Uppercase Veritatis aspernatur cupiditate magnam quidem',
59
64
  eyebrowTextEllipsis: false,
@@ -66,7 +71,6 @@ Interactive.args = {
66
71
  supportingTextEllipsis: false,
67
72
  isInteractive: true,
68
73
  skeletonLoadingSize: TEXT_GROUP_LOADING_SIZES.LARGE,
69
- isSelected: false,
70
74
  state: TEXT_GROUP_STATES.DEFAULT,
71
75
  isSupportingTextTooltipEnabled: false,
72
76
  isSupportingTextTooltipEnabledOnMobile: true,
@@ -79,6 +83,14 @@ Interactive.argTypes = {
79
83
  control: 'select',
80
84
  options: Object.values(TEXT_GROUP_SIZES),
81
85
  },
86
+ align: {
87
+ control: 'select',
88
+ options: Object.values(TEXT_GROUP_ALIGNS),
89
+ },
90
+ mainTextColor: {
91
+ control: 'select',
92
+ options: Object.values(TEXT_GROUP_MAIN_TEXT_COLORS),
93
+ },
82
94
  prominence: {
83
95
  control: 'select',
84
96
  options: Object.values(TEXT_GROUP_PROMINENCE),
@@ -114,9 +126,6 @@ Interactive.argTypes = {
114
126
  control: 'select',
115
127
  options: Object.values(TEXT_GROUP_LOADING_SIZES),
116
128
  },
117
- isSelected: {
118
- control: 'boolean',
119
- },
120
129
  state: {
121
130
  control: 'select',
122
131
  options: Object.values(TEXT_GROUP_STATES),