@bethinkpl/design-system 30.4.2 → 31.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 (78) hide show
  1. package/dist/design-system.css +1 -1
  2. package/dist/design-system.js +4195 -4211
  3. package/dist/design-system.js.map +1 -1
  4. package/dist/i18n/en/statsLayout.json +0 -1
  5. package/dist/i18n/pl/statsLayout.json +0 -1
  6. package/dist/lib/js/components/Buttons/IconButton/IconButton.vue.d.ts +1 -0
  7. package/dist/lib/js/components/Cards/CardExpandable/CardExpandable.vue.d.ts +1 -0
  8. package/dist/lib/js/components/Chip/Chip.vue.d.ts +2 -0
  9. package/dist/lib/js/components/DatePickers/DateBox/DateBox.vue.d.ts +1 -0
  10. package/dist/lib/js/components/DatePickers/DatePicker/DatePicker.vue.d.ts +1 -0
  11. package/dist/lib/js/components/DatePickers/DateRangePicker/DateRangePicker.vue.d.ts +1 -0
  12. package/dist/lib/js/components/Drawer/DrawerHeader/DrawerHeader.vue.d.ts +4 -0
  13. package/dist/lib/js/components/Drawer/DrawerListItem/DrawerListItem.vue.d.ts +1 -0
  14. package/dist/lib/js/components/Drawer/DrawerSection/DrawerSection.vue.d.ts +3 -0
  15. package/dist/lib/js/components/Form/RadioButton/RadioButton.vue.d.ts +1 -0
  16. package/dist/lib/js/components/Headers/OverlayHeader/OverlayHeader.vue.d.ts +2 -0
  17. package/dist/lib/js/components/Headers/SectionHeader/SectionHeader.vue.d.ts +2 -0
  18. package/dist/lib/js/components/Icons/Icon/Icon.consts.d.ts +1 -0
  19. package/dist/lib/js/components/Menu/Menu/Menu.consts.d.ts +9 -0
  20. package/dist/lib/js/components/Menu/Menu/Menu.vue.d.ts +28 -0
  21. package/dist/lib/js/components/Menu/Menu/index.d.ts +4 -0
  22. package/dist/lib/js/components/Menu/MenuDivider/MenuDivider.vue.d.ts +71 -0
  23. package/dist/lib/js/components/Menu/MenuDivider/index.d.ts +3 -0
  24. package/dist/lib/js/components/Menu/MenuItem/MenuItem.consts.d.ts +23 -0
  25. package/dist/lib/js/components/Menu/MenuItem/MenuItem.vue.d.ts +68 -0
  26. package/dist/lib/js/components/Menu/MenuItem/index.d.ts +4 -0
  27. package/dist/lib/js/components/Modal/Modal.vue.d.ts +1 -0
  28. package/dist/lib/js/components/Modals/Modal/Modal.vue.d.ts +2 -0
  29. package/dist/lib/js/components/Modals/ModalDialog/ModalDialog.vue.d.ts +2 -0
  30. package/dist/lib/js/components/Pagination/Pagination.vue.d.ts +3 -0
  31. package/dist/lib/js/components/ProgressBar/ProgressBar.vue.d.ts +1 -0
  32. package/dist/lib/js/components/ProgressDonutChart/ProgressDonutChart.vue.d.ts +1 -0
  33. package/dist/lib/js/components/RichList/BasicRichListItem/BasicRichListItem.vue.d.ts +1 -0
  34. package/dist/lib/js/components/RichList/RichListItem/RichListItem.vue.d.ts +1 -0
  35. package/dist/lib/js/components/SelectList/SelectListItem/SelectListItem.vue.d.ts +1 -0
  36. package/dist/lib/js/components/SelectList/SelectListItemToggle/SelectListItemToggle.vue.d.ts +1 -0
  37. package/dist/lib/js/components/StatsLayout/StatsResetBanner/StatsResetBanner.vue.d.ts +2 -2
  38. package/dist/lib/js/components/Statuses/AccessStatus/AccessStatus.vue.d.ts +1 -0
  39. package/dist/lib/js/components/Statuses/BlockadeStatus/BlockadeStatus.vue.d.ts +1 -0
  40. package/dist/lib/js/components/SurveyQuestions/SurveyQuestionOpenEnded/SurveyQuestionOpenEnded.vue.d.ts +3 -0
  41. package/dist/lib/js/components/SurveyQuestions/SurveyQuestionScale/SurveyQuestionScale.vue.d.ts +3 -0
  42. package/dist/lib/js/components/Switch/Switch.vue.d.ts +1 -0
  43. package/dist/lib/js/components/Tile/Tile.sb.shared.d.ts +1 -0
  44. package/dist/lib/js/components/Toggles/ToggleButton/ToggleButton.vue.d.ts +1 -0
  45. package/dist/lib/js/i18n/en.d.ts +0 -1
  46. package/dist/lib/js/i18n/index.d.ts +0 -2
  47. package/dist/lib/js/i18n/pl.d.ts +0 -1
  48. package/dist/lib/js/icons/fontawesome.d.ts +1 -0
  49. package/dist/lib/js/index.d.ts +8 -7
  50. package/lib/js/components/Menu/Menu/Menu.consts.ts +11 -0
  51. package/lib/js/components/Menu/Menu/Menu.spec.ts +134 -0
  52. package/lib/js/components/Menu/Menu/Menu.stories.ts +52 -0
  53. package/lib/js/components/Menu/Menu/Menu.vue +56 -0
  54. package/lib/js/components/Menu/Menu/index.ts +4 -0
  55. package/lib/js/components/{Outline/OutlineDivider/OutlineDivider.stories.ts → Menu/MenuDivider/MenuDivider.stories.ts} +7 -7
  56. package/lib/js/components/{Outline/OutlineDivider/OutlineDivider.vue → Menu/MenuDivider/MenuDivider.vue} +5 -4
  57. package/lib/js/components/Menu/MenuDivider/index.ts +3 -0
  58. package/lib/js/components/Menu/MenuItem/MenuItem.consts.ts +34 -0
  59. package/lib/js/components/Menu/MenuItem/MenuItem.spec.ts +424 -0
  60. package/lib/js/components/Menu/MenuItem/MenuItem.stories.ts +177 -0
  61. package/lib/js/components/Menu/MenuItem/MenuItem.vue +377 -0
  62. package/lib/js/components/Menu/MenuItem/index.ts +4 -0
  63. package/lib/js/components/StatsLayout/StatsLayout.stories.ts +4 -2
  64. package/lib/js/components/StatsLayout/StatsResetBanner/StatsResetBanner.stories.ts +1 -5
  65. package/lib/js/components/StatsLayout/StatsResetBanner/StatsResetBanner.vue +4 -7
  66. package/lib/js/i18n/en/statsLayout.json +0 -1
  67. package/lib/js/i18n/pl/statsLayout.json +0 -1
  68. package/lib/js/icons/fontawesome.ts +2 -0
  69. package/lib/js/index.ts +8 -7
  70. package/package.json +1 -1
  71. package/lib/js/components/Outline/OutlineDivider/index.ts +0 -3
  72. package/lib/js/components/Outline/OutlineItem/OutlineItem.consts.ts +0 -22
  73. package/lib/js/components/Outline/OutlineItem/OutlineItem.stories.ts +0 -120
  74. package/lib/js/components/Outline/OutlineItem/OutlineItem.vue +0 -325
  75. package/lib/js/components/Outline/OutlineItem/index.ts +0 -4
  76. package/lib/js/components/Outline/OutlineSectionHeader/OutlineSectionHeader.stories.ts +0 -35
  77. package/lib/js/components/Outline/OutlineSectionHeader/OutlineSectionHeader.vue +0 -30
  78. package/lib/js/components/Outline/OutlineSectionHeader/index.ts +0 -3
@@ -131,6 +131,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
131
131
  readonly FA_CREDIT_CARD: import('@fortawesome/fontawesome-common-types').IconDefinition;
132
132
  readonly FA_DNA_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
133
133
  readonly FA_DOT_CIRCLE_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
134
+ readonly FA_DOT_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
134
135
  readonly FA_EARTH_AMERICAS: import('@fortawesome/fontawesome-common-types').IconDefinition;
135
136
  readonly FA_ELLIPSIS_VERTICAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
136
137
  readonly FA_ELLIPSIS: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -771,6 +772,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
771
772
  readonly FA_CREDIT_CARD: import('@fortawesome/fontawesome-common-types').IconDefinition;
772
773
  readonly FA_DNA_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
773
774
  readonly FA_DOT_CIRCLE_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
775
+ readonly FA_DOT_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
774
776
  readonly FA_EARTH_AMERICAS: import('@fortawesome/fontawesome-common-types').IconDefinition;
775
777
  readonly FA_ELLIPSIS_VERTICAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
776
778
  readonly FA_ELLIPSIS: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -1308,6 +1310,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
1308
1310
  readonly FA_CREDIT_CARD: import('@fortawesome/fontawesome-common-types').IconDefinition;
1309
1311
  readonly FA_DNA_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
1310
1312
  readonly FA_DOT_CIRCLE_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
1313
+ readonly FA_DOT_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
1311
1314
  readonly FA_EARTH_AMERICAS: import('@fortawesome/fontawesome-common-types').IconDefinition;
1312
1315
  readonly FA_ELLIPSIS_VERTICAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
1313
1316
  readonly FA_ELLIPSIS: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -150,6 +150,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
150
150
  readonly FA_CREDIT_CARD: import('@fortawesome/fontawesome-common-types').IconDefinition;
151
151
  readonly FA_DNA_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
152
152
  readonly FA_DOT_CIRCLE_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
153
+ readonly FA_DOT_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
153
154
  readonly FA_EARTH_AMERICAS: import('@fortawesome/fontawesome-common-types').IconDefinition;
154
155
  readonly FA_ELLIPSIS_VERTICAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
155
156
  readonly FA_ELLIPSIS: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -744,6 +745,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
744
745
  readonly FA_CREDIT_CARD: import('@fortawesome/fontawesome-common-types').IconDefinition;
745
746
  readonly FA_DNA_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
746
747
  readonly FA_DOT_CIRCLE_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
748
+ readonly FA_DOT_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
747
749
  readonly FA_EARTH_AMERICAS: import('@fortawesome/fontawesome-common-types').IconDefinition;
748
750
  readonly FA_ELLIPSIS_VERTICAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
749
751
  readonly FA_ELLIPSIS: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -1454,6 +1456,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
1454
1456
  readonly FA_CREDIT_CARD: import('@fortawesome/fontawesome-common-types').IconDefinition;
1455
1457
  readonly FA_DNA_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
1456
1458
  readonly FA_DOT_CIRCLE_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
1459
+ readonly FA_DOT_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
1457
1460
  readonly FA_EARTH_AMERICAS: import('@fortawesome/fontawesome-common-types').IconDefinition;
1458
1461
  readonly FA_ELLIPSIS_VERTICAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
1459
1462
  readonly FA_ELLIPSIS: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -150,6 +150,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
150
150
  readonly FA_CREDIT_CARD: import('@fortawesome/fontawesome-common-types').IconDefinition;
151
151
  readonly FA_DNA_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
152
152
  readonly FA_DOT_CIRCLE_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
153
+ readonly FA_DOT_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
153
154
  readonly FA_EARTH_AMERICAS: import('@fortawesome/fontawesome-common-types').IconDefinition;
154
155
  readonly FA_ELLIPSIS_VERTICAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
155
156
  readonly FA_ELLIPSIS: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -110,6 +110,7 @@ export declare const data: () => {
110
110
  readonly FA_CREDIT_CARD: import('@fortawesome/fontawesome-common-types').IconDefinition;
111
111
  readonly FA_DNA_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
112
112
  readonly FA_DOT_CIRCLE_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
113
+ readonly FA_DOT_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
113
114
  readonly FA_EARTH_AMERICAS: import('@fortawesome/fontawesome-common-types').IconDefinition;
114
115
  readonly FA_ELLIPSIS_VERTICAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
115
116
  readonly FA_ELLIPSIS: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -166,6 +166,7 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
166
166
  readonly FA_CREDIT_CARD: import('@fortawesome/fontawesome-common-types').IconDefinition;
167
167
  readonly FA_DNA_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
168
168
  readonly FA_DOT_CIRCLE_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
169
+ readonly FA_DOT_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
169
170
  readonly FA_EARTH_AMERICAS: import('@fortawesome/fontawesome-common-types').IconDefinition;
170
171
  readonly FA_ELLIPSIS_VERTICAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
171
172
  readonly FA_ELLIPSIS: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -7,7 +7,6 @@ declare const _default: {
7
7
  "ds.statsLayout.statsErrorBanner.message": string;
8
8
  "ds.statsLayout.statsErrorBanner.title": string;
9
9
  "ds.statsLayout.statsResetBanner.buttonText": string;
10
- "ds.statsLayout.statsResetBanner.message": string;
11
10
  "ds.statsLayout.statsResetBanner.title": string;
12
11
  "ds.pagination.from": string;
13
12
  "ds.accessStatus.status.active": string;
@@ -12,7 +12,6 @@ export declare const messages: {
12
12
  "ds.statsLayout.statsErrorBanner.message": string;
13
13
  "ds.statsLayout.statsErrorBanner.title": string;
14
14
  "ds.statsLayout.statsResetBanner.buttonText": string;
15
- "ds.statsLayout.statsResetBanner.message": string;
16
15
  "ds.statsLayout.statsResetBanner.title": string;
17
16
  "ds.pagination.from": string;
18
17
  "ds.accessStatus.status.active": string;
@@ -33,7 +32,6 @@ export declare const messages: {
33
32
  "ds.statsLayout.statsErrorBanner.message": string;
34
33
  "ds.statsLayout.statsErrorBanner.title": string;
35
34
  "ds.statsLayout.statsResetBanner.buttonText": string;
36
- "ds.statsLayout.statsResetBanner.message": string;
37
35
  "ds.statsLayout.statsResetBanner.title": string;
38
36
  "ds.pagination.from": string;
39
37
  "ds.accessStatus.status.active": string;
@@ -7,7 +7,6 @@ declare const _default: {
7
7
  "ds.statsLayout.statsErrorBanner.message": string;
8
8
  "ds.statsLayout.statsErrorBanner.title": string;
9
9
  "ds.statsLayout.statsResetBanner.buttonText": string;
10
- "ds.statsLayout.statsResetBanner.message": string;
11
10
  "ds.statsLayout.statsResetBanner.title": string;
12
11
  "ds.pagination.from": string;
13
12
  "ds.accessStatus.status.active": string;
@@ -97,6 +97,7 @@ export declare const FONTAWESOME_ICONS: {
97
97
  readonly FA_CREDIT_CARD: import('@fortawesome/fontawesome-common-types').IconDefinition;
98
98
  readonly FA_DNA_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
99
99
  readonly FA_DOT_CIRCLE_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
100
+ readonly FA_DOT_SOLID: import('@fortawesome/fontawesome-common-types').IconDefinition;
100
101
  readonly FA_EARTH_AMERICAS: import('@fortawesome/fontawesome-common-types').IconDefinition;
101
102
  readonly FA_ELLIPSIS_VERTICAL: import('@fortawesome/fontawesome-common-types').IconDefinition;
102
103
  readonly FA_ELLIPSIS: import('@fortawesome/fontawesome-common-types').IconDefinition;
@@ -100,13 +100,14 @@ export { default as DrawerTile } from './components/Drawer/DrawerTile/DrawerTile
100
100
  export { default as DsDrawerTile } from './components/Drawer/DrawerTile/DrawerTile.vue';
101
101
  export { default as DrawerSection } from './components/Drawer/DrawerSection/DrawerSection.vue';
102
102
  export { default as DsDrawerSection } from './components/Drawer/DrawerSection/DrawerSection.vue';
103
- export { default as OutlineItem } from './components/Outline/OutlineItem';
104
- export { default as DsOutlineItem } from './components/Outline/OutlineItem';
105
- export * from './components/Outline/OutlineItem/OutlineItem.consts';
106
- export { default as OutlineDivider } from './components/Outline/OutlineDivider';
107
- export { default as DsOutlineDivider } from './components/Outline/OutlineDivider';
108
- export { default as OutlineSectionHeader } from './components/Outline/OutlineSectionHeader';
109
- export { default as DsOutlineSectionHeader } from './components/Outline/OutlineSectionHeader';
103
+ export { default as Menu } from './components/Menu/Menu';
104
+ export { default as DsMenu } from './components/Menu/Menu';
105
+ export * from './components/Menu/Menu/Menu.consts';
106
+ export { default as MenuItem } from './components/Menu/MenuItem';
107
+ export { default as DsMenuItem } from './components/Menu/MenuItem';
108
+ export * from './components/Menu/MenuItem/MenuItem.consts';
109
+ export { default as MenuDivider } from './components/Menu/MenuDivider';
110
+ export { default as DsMenuDivider } from './components/Menu/MenuDivider';
110
111
  export { default as Chip } from './components/Chip';
111
112
  export { default as DsChip } from './components/Chip';
112
113
  export * from './components/Chip/Chip.consts';
@@ -0,0 +1,11 @@
1
+ import { Value } from '../../../utils/type.utils';
2
+ import type { InjectionKey } from 'vue';
3
+
4
+ export const MENU_LAYOUTS = {
5
+ DEFAULT: 'default',
6
+ EXTENSIVE: 'extensive',
7
+ };
8
+
9
+ export type MenuLayout = Value<typeof MENU_LAYOUTS>;
10
+
11
+ export const MENU_LAYOUT_INJECTION_KEY: InjectionKey<MenuLayout> = Symbol('menuLayout');
@@ -0,0 +1,134 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { mount } from '@vue/test-utils';
3
+ import { h } from 'vue';
4
+ import Menu from './Menu.vue';
5
+ import { MENU_LAYOUT_INJECTION_KEY, MENU_LAYOUTS } from './Menu.consts';
6
+
7
+ describe('Menu', () => {
8
+ it('renders correctly with default props', () => {
9
+ const wrapper = mount(Menu);
10
+
11
+ expect(wrapper.exists()).toBe(true);
12
+ expect(wrapper.element.tagName).toBe('UL');
13
+ expect(wrapper.classes()).toContain('ds-menu');
14
+ });
15
+
16
+ it('renders slot content', () => {
17
+ const slotContent = 'Menu items go here';
18
+ const wrapper = mount(Menu, {
19
+ slots: {
20
+ default: () => h('li', slotContent),
21
+ },
22
+ });
23
+
24
+ expect(wrapper.text()).toContain(slotContent);
25
+ expect(wrapper.find('li').exists()).toBe(true);
26
+ });
27
+
28
+ describe('layout prop', () => {
29
+ it('applies default layout when no layout prop is provided', () => {
30
+ const wrapper = mount(Menu);
31
+
32
+ expect(wrapper.classes()).toContain('ds-menu');
33
+ expect(wrapper.classes()).not.toContain('-ds-extensive');
34
+ });
35
+
36
+ it('applies default layout when layout prop is explicitly set to default', () => {
37
+ const wrapper = mount(Menu, {
38
+ props: {
39
+ layout: MENU_LAYOUTS.DEFAULT,
40
+ },
41
+ });
42
+
43
+ expect(wrapper.classes()).toContain('ds-menu');
44
+ expect(wrapper.classes()).not.toContain('-ds-extensive');
45
+ });
46
+
47
+ it('applies extensive layout when layout prop is set to extensive', () => {
48
+ const wrapper = mount(Menu, {
49
+ props: {
50
+ layout: MENU_LAYOUTS.EXTENSIVE,
51
+ },
52
+ });
53
+
54
+ expect(wrapper.classes()).toContain('ds-menu');
55
+ expect(wrapper.classes()).toContain('-ds-extensive');
56
+ });
57
+ });
58
+
59
+ describe('layout injection', () => {
60
+ it('uses injected layout when no layout prop is provided', () => {
61
+ const wrapper = mount(Menu, {
62
+ global: {
63
+ provide: {
64
+ [MENU_LAYOUT_INJECTION_KEY]: MENU_LAYOUTS.EXTENSIVE,
65
+ },
66
+ },
67
+ });
68
+
69
+ expect(wrapper.classes()).toContain('ds-menu');
70
+ expect(wrapper.classes()).toContain('-ds-extensive');
71
+ });
72
+
73
+ it('prioritizes layout prop over injected layout', () => {
74
+ const wrapper = mount(Menu, {
75
+ props: {
76
+ layout: MENU_LAYOUTS.DEFAULT,
77
+ },
78
+ global: {
79
+ provide: {
80
+ [MENU_LAYOUT_INJECTION_KEY]: MENU_LAYOUTS.EXTENSIVE,
81
+ },
82
+ },
83
+ });
84
+
85
+ expect(wrapper.classes()).toContain('ds-menu');
86
+ expect(wrapper.classes()).not.toContain('-ds-extensive');
87
+ });
88
+ });
89
+
90
+ describe('layout provision', () => {
91
+ it('provides layout value to child components', () => {
92
+ let providedLayout: string | null = null;
93
+
94
+ const ChildComponent = {
95
+ setup() {
96
+ const { inject } = require('vue');
97
+ providedLayout = inject(MENU_LAYOUT_INJECTION_KEY, null);
98
+ return () => h('div', 'child');
99
+ },
100
+ };
101
+
102
+ mount(Menu, {
103
+ props: {
104
+ layout: MENU_LAYOUTS.EXTENSIVE,
105
+ },
106
+ slots: {
107
+ default: () => h(ChildComponent),
108
+ },
109
+ });
110
+
111
+ expect(providedLayout).toBe(MENU_LAYOUTS.EXTENSIVE);
112
+ });
113
+
114
+ it('provides default layout when no layout prop is set', () => {
115
+ let providedLayout: string | null = null;
116
+
117
+ const ChildComponent = {
118
+ setup() {
119
+ const { inject } = require('vue');
120
+ providedLayout = inject(MENU_LAYOUT_INJECTION_KEY, null);
121
+ return () => h('div', 'child');
122
+ },
123
+ };
124
+
125
+ mount(Menu, {
126
+ slots: {
127
+ default: () => h(ChildComponent),
128
+ },
129
+ });
130
+
131
+ expect(providedLayout).toBe(MENU_LAYOUTS.DEFAULT);
132
+ });
133
+ });
134
+ });
@@ -0,0 +1,52 @@
1
+ import { Args, ArgTypes, Meta, StoryFn } from '@storybook/vue3';
2
+ import DsMenu, { MENU_LAYOUTS } from './index';
3
+ import MenuItem from '../MenuItem';
4
+ import MenuDivider from '../MenuDivider';
5
+
6
+ export default {
7
+ title: 'Components/Menu/Menu',
8
+ component: DsMenu,
9
+ } as Meta<typeof DsMenu>;
10
+
11
+ const StoryTemplate: StoryFn<typeof DsMenu> = (args) => ({
12
+ components: { DsMenu, MenuItem, MenuDivider },
13
+ setup() {
14
+ return args;
15
+ },
16
+ template: `
17
+ <ds-menu :layout="layout" >
18
+ <menu-item label="level 1" />
19
+ <menu-item label="level 1" />
20
+ <menu-divider />
21
+ <menu-item label="level 1" />
22
+ <menu-item label="level 1" >
23
+ <template #children>
24
+ <ds-menu>
25
+ <menu-item label="level 2" />
26
+ </ds-menu>
27
+ </template>
28
+ </menu-item>
29
+ <menu-item label="level 1" />
30
+ </ds-menu>`,
31
+ });
32
+
33
+ export const Interactive = StoryTemplate.bind({});
34
+
35
+ const argTypes = {
36
+ layout: {
37
+ control: 'select',
38
+ options: Object.values(MENU_LAYOUTS),
39
+ },
40
+ } as ArgTypes;
41
+
42
+ Interactive.args = {
43
+ layout: MENU_LAYOUTS.DEFAULT,
44
+ } as Args;
45
+ Interactive.argTypes = argTypes;
46
+
47
+ Interactive.parameters = {
48
+ design: {
49
+ type: 'figma',
50
+ url: 'https://www.figma.com/design/izQdYyiBR1GQgFkaOIfIJI/LMS---DS-Components?node-id=15355-7663&m=dev',
51
+ },
52
+ };
@@ -0,0 +1,56 @@
1
+ <template>
2
+ <ul
3
+ :class="[
4
+ 'ds-menu',
5
+ {
6
+ '-ds-extensive': calculatedLayout === MENU_LAYOUTS.EXTENSIVE,
7
+ },
8
+ ]"
9
+ >
10
+ <slot />
11
+ </ul>
12
+ </template>
13
+
14
+ <style scoped lang="scss">
15
+ @import '../../../../styles/settings/spacings';
16
+
17
+ .ds-menu {
18
+ display: flex;
19
+ flex-direction: column;
20
+ gap: $space-5xs;
21
+ margin: 0;
22
+ padding: 0;
23
+
24
+ &.-ds-extensive {
25
+ gap: $space-2xs;
26
+ }
27
+ }
28
+ </style>
29
+
30
+ <script setup lang="ts">
31
+ import { MENU_LAYOUT_INJECTION_KEY, MENU_LAYOUTS, MenuLayout } from './Menu.consts';
32
+ import { computed, inject, provide } from 'vue';
33
+
34
+ const { layout = null } = defineProps<{
35
+ layout?: MenuLayout | null;
36
+ }>();
37
+
38
+ const slots = defineSlots<{
39
+ default?: () => any;
40
+ }>();
41
+
42
+ const calculatedLayout = computed(() => {
43
+ if (layout !== null) {
44
+ return layout;
45
+ }
46
+
47
+ const injectedLayout = inject(MENU_LAYOUT_INJECTION_KEY, null);
48
+ if (injectedLayout !== null) {
49
+ return injectedLayout;
50
+ }
51
+
52
+ return MENU_LAYOUTS.DEFAULT;
53
+ });
54
+
55
+ provide(MENU_LAYOUT_INJECTION_KEY, calculatedLayout.value);
56
+ </script>
@@ -0,0 +1,4 @@
1
+ import DsMenu from './Menu.vue';
2
+
3
+ export default DsMenu;
4
+ export * from './Menu.consts';
@@ -1,19 +1,19 @@
1
- import OutlineDivider from './OutlineDivider.vue';
1
+ import MenuDivider from './MenuDivider.vue';
2
2
  import { Args, ArgTypes, Meta, StoryFn } from '@storybook/vue3';
3
3
  import { DIVIDER_PROMINENCES, DIVIDER_SIZES } from '../../Divider';
4
4
 
5
5
  export default {
6
- title: 'Components/Outline/OutlineDivider',
7
- component: OutlineDivider,
8
- } as Meta<typeof OutlineDivider>;
6
+ title: 'Components/Menu/MenuDivider',
7
+ component: MenuDivider,
8
+ } as Meta<typeof MenuDivider>;
9
9
 
10
- const StoryTemplate: StoryFn<typeof OutlineDivider> = (args) => ({
11
- components: { OutlineDivider },
10
+ const StoryTemplate: StoryFn<typeof MenuDivider> = (args) => ({
11
+ components: { MenuDivider },
12
12
  setup() {
13
13
  return args;
14
14
  },
15
15
  template: `
16
- <outline-divider :prominence="prominence" :size="size" />`,
16
+ <menu-divider :prominence="prominence" :size="size" />`,
17
17
  });
18
18
 
19
19
  export const Interactive = StoryTemplate.bind({});
@@ -1,13 +1,14 @@
1
1
  <template>
2
- <div class="ds-outlineDivider">
2
+ <li class="ds-menuDivider">
3
3
  <ds-divider :prominence="prominence" :size="size" />
4
- </div>
4
+ </li>
5
5
  </template>
6
6
 
7
7
  <style scoped lang="scss">
8
8
  @import '../../../../styles/settings/spacings';
9
9
 
10
- .ds-outlineDivider {
10
+ .ds-menuDivider {
11
+ list-style-type: none;
11
12
  padding: $space-3xs 0;
12
13
  }
13
14
  </style>
@@ -18,7 +19,7 @@ import DsDivider, { DIVIDER_PROMINENCES, DIVIDER_SIZES } from '../../Divider';
18
19
  import { defineComponent } from 'vue';
19
20
 
20
21
  export default defineComponent({
21
- name: 'OutlineDivider',
22
+ name: 'MenuDivider',
22
23
  components: {
23
24
  DsDivider,
24
25
  },
@@ -0,0 +1,3 @@
1
+ import MenuDivider from './MenuDivider.vue';
2
+
3
+ export default MenuDivider;
@@ -0,0 +1,34 @@
1
+ import { Value } from '../../../utils/type.utils';
2
+ import type { InjectionKey } from 'vue';
3
+
4
+ export const MENU_ITEM_SIZES = {
5
+ SMALL: 'small',
6
+ MEDIUM: 'medium',
7
+ };
8
+
9
+ export type MenuItemSize = Value<typeof MENU_ITEM_SIZES>;
10
+
11
+ export const MENU_ITEM_STATES = {
12
+ DEFAULT: 'default',
13
+ DISABLED: 'disabled',
14
+ };
15
+
16
+ export type MenuItemState = Value<typeof MENU_ITEM_STATES>;
17
+
18
+ export const MENU_ITEM_BACKGROUND_COLORS = {
19
+ NEUTRAL_WEAK: 'neutralWeak',
20
+ NEUTRAL: 'neutral',
21
+ };
22
+
23
+ export type MenuItemBackgroundColor = Value<typeof MENU_ITEM_BACKGROUND_COLORS>;
24
+
25
+ export const MENU_ITEM_ACCESSORY_STATES = {
26
+ DOT: 'dot',
27
+ // not implemented for now
28
+ // EXPANDED: 'expanded',
29
+ // COLLAPSED: 'collapsed',
30
+ };
31
+
32
+ export type MenuItemAccessoryState = Value<typeof MENU_ITEM_ACCESSORY_STATES>;
33
+
34
+ export const MENU_ITEM_LEVEL_INJECTION_KEY: InjectionKey<number> = Symbol('menuItemLevel');