srcdev-nuxt-components 4.0.5 → 5.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 (94) hide show
  1. package/README.md +171 -2
  2. package/assets/styles/extends-layer/srcdev-components/display-prompt-core/index.css +70 -0
  3. package/assets/styles/extends-layer/srcdev-components/index.css +2 -0
  4. package/assets/styles/extends-layer/srcdev-components/themes/_error.css +15 -0
  5. package/assets/styles/extends-layer/srcdev-components/themes/_info.css +15 -0
  6. package/assets/styles/extends-layer/srcdev-components/themes/_success.css +15 -0
  7. package/assets/styles/extends-layer/srcdev-components/themes/_warning.css +15 -0
  8. package/assets/styles/main.css +2 -5
  9. package/assets/styles/{forms/variables/_theme.css → setup/_head.css} +0 -6
  10. package/assets/styles/{a11y → setup/a11y}/_variables.css +2 -0
  11. package/assets/styles/setup/a11y/index.css +2 -0
  12. package/assets/styles/setup/index.css +5 -0
  13. package/assets/styles/setup/typography/index.css +2 -0
  14. package/assets/styles/setup/typography/utility-classes/_generic-font-classes.css +192 -0
  15. package/assets/styles/setup/typography/utility-classes/_generic-font-variation-settings.css +29 -0
  16. package/assets/styles/setup/typography/utility-classes/_generic-font-weights.css +41 -0
  17. package/assets/styles/setup/typography/utility-classes/index.css +3 -0
  18. package/assets/styles/setup/typography/vars/index.css +1 -0
  19. package/assets/styles/setup/utility-classes/_page.css +49 -0
  20. package/assets/styles/setup/utility-classes/index.css +3 -0
  21. package/assets/styles/setup/variables/index.css +1 -0
  22. package/components/accordian/AccordianCore.vue +46 -0
  23. package/components/{presentation/container-glow → container-glow}/ContainerGlowCore.vue +80 -80
  24. package/components/content-grid/ContentGrid.vue +85 -0
  25. package/components/display-details/DisplayDetailsCore.vue +49 -60
  26. package/components/{functional/display-dialog → display-dialog}/DisplayDialogCore.vue +49 -38
  27. package/components/display-prompt/DisplayPromptCore.vue +187 -0
  28. package/components/expanding-panel/ExpandingPanel.vue +124 -0
  29. package/components/responsive-header/NavigationItems.vue +23 -18
  30. package/components/responsive-header/ResponsiveHeader.vue +345 -278
  31. package/components/{presentation/tabs → tabs}/TabsCore.vue +27 -58
  32. package/composables/useDialogControls.ts +22 -1
  33. package/package.json +1 -1
  34. package/assets/styles/a11y/index.css +0 -2
  35. package/assets/styles/forms/index.css +0 -2
  36. package/assets/styles/forms/themes/_error.css +0 -77
  37. package/assets/styles/forms/themes/_ghost.css +0 -77
  38. package/assets/styles/forms/themes/_input-action.css +0 -20
  39. package/assets/styles/forms/themes/_primary.css +0 -82
  40. package/assets/styles/forms/themes/_secondary.css +0 -77
  41. package/assets/styles/forms/themes/_success.css +0 -77
  42. package/assets/styles/forms/themes/_tertiary.css +0 -77
  43. package/assets/styles/forms/themes/_warning.css +0 -77
  44. package/assets/styles/forms/themes/index.css +0 -8
  45. package/assets/styles/forms/variables/_sizes.css +0 -82
  46. package/assets/styles/forms/variables/index.css +0 -2
  47. package/assets/styles/typography/index.css +0 -2
  48. package/assets/styles/typography/utils/_font-classes.css +0 -160
  49. package/assets/styles/typography/utils/_weights.css +0 -69
  50. package/assets/styles/typography/utils/index.css +0 -2
  51. package/assets/styles/typography/variables/_colors.css +0 -14
  52. package/assets/styles/typography/variables/index.css +0 -2
  53. package/assets/styles/utils/_animations.css +0 -42
  54. package/assets/styles/utils/_canvasWidths.css +0 -18
  55. package/assets/styles/utils/_display.css +0 -7
  56. package/assets/styles/utils/_page.css +0 -27
  57. package/assets/styles/utils/_placement.css +0 -73
  58. package/assets/styles/utils/index.css +0 -7
  59. package/assets/styles/variables/components/_accordian.css +0 -7
  60. package/assets/styles/variables/components/_container-glow-core.css +0 -16
  61. package/assets/styles/variables/components/_display-dialog-core.css +0 -35
  62. package/assets/styles/variables/components/_tabs.css +0 -18
  63. package/assets/styles/variables/components/display-prompt-core/_scaffolding.css +0 -57
  64. package/assets/styles/variables/components/display-prompt-core/index.css +0 -2
  65. package/assets/styles/variables/components/display-prompt-core/themes/_error.css +0 -39
  66. package/assets/styles/variables/components/display-prompt-core/themes/_info.css +0 -39
  67. package/assets/styles/variables/components/display-prompt-core/themes/_success.css +0 -39
  68. package/assets/styles/variables/components/display-prompt-core/themes/_warning.css +0 -39
  69. package/assets/styles/variables/components/index.css +0 -5
  70. package/assets/styles/variables/index.css +0 -2
  71. package/components/functional/accordian/AccordianCore.vue +0 -138
  72. package/components/presentation/display-prompt/DisplayPromptCore.vue +0 -150
  73. /package/assets/styles/{variables/components/display-prompt-core → extends-layer/srcdev-components}/themes/index.css +0 -0
  74. /package/assets/styles/{a11y → setup/a11y}/_utils.css +0 -0
  75. /package/assets/styles/{typography/variables/_reponsive-font-size.css → setup/typography/vars/_reponsive-font-sizes.css} +0 -0
  76. /package/assets/styles/{utils → setup/utility-classes}/_margin-helpers.css +0 -0
  77. /package/assets/styles/{utils → setup/utility-classes}/_padding-helpers.css +0 -0
  78. /package/assets/styles/{variables → setup/variables}/colors/_blue.css +0 -0
  79. /package/assets/styles/{variables → setup/variables}/colors/_gray.css +0 -0
  80. /package/assets/styles/{variables → setup/variables}/colors/_green.css +0 -0
  81. /package/assets/styles/{variables → setup/variables}/colors/_orange.css +0 -0
  82. /package/assets/styles/{variables → setup/variables}/colors/_red.css +0 -0
  83. /package/assets/styles/{variables → setup/variables}/colors/_yellow.css +0 -0
  84. /package/assets/styles/{variables/colors/colors.css → setup/variables/colors/index.css} +0 -0
  85. /package/components/{functional/display-dialog → display-dialog}/variants/DisplayDialogConfirm.vue +0 -0
  86. /package/components/{functional/display-dialog → display-dialog}/variants/DisplayDialogScrollableContent.vue +0 -0
  87. /package/components/{presentation/display-grid → display-grid}/DisplayGridCore.vue +0 -0
  88. /package/components/{presentation/display-prompt → display-prompt}/variants/DisplayPromptError.vue +0 -0
  89. /package/components/{presentation/layout-grids → layout-grids}/LayoutGridA.vue +0 -0
  90. /package/components/{presentation/layout-grids → layout-grids}/LayoutGridB.vue +0 -0
  91. /package/components/{presentation/layout-row → layout-row}/LayoutRow.vue +0 -0
  92. /package/components/{presentation/masonry-grid → masonry-grid}/MasonryGrid.vue +0 -0
  93. /package/components/{presentation/masonry-grid-sorted → masonry-grid-sorted}/MasonryGridSorted.vue +0 -0
  94. /package/components/{functional/pop-over → pop-over}/PopOver.vue +0 -0
@@ -1,7 +1,7 @@
1
1
  <template>
2
- <dialog class="display-dialog-core" :class="[variant, elementClasses]" role="dialog" :align-dialog :open :data-dialog-id="dataDialogId" ref="dialogRef">
2
+ <dialog class="display-dialog-core" :class="[elementClasses]" role="dialog" :align-dialog :justify-dialog :open :data-dialog-id="dataDialogId" ref="dialogRef">
3
3
  <focus-trap v-model:active="open" :clickOutsideDeactivates="true" @deactivate="closeDialog()">
4
- <div class="inner">
4
+ <div class="inner" :class="[variant]">
5
5
  <div class="header">
6
6
  <div v-if="hasDialogTitle" class="col-left">
7
7
  <slot name="dialogTitle"></slot>
@@ -40,15 +40,15 @@ const props = defineProps({
40
40
  default: 'dialog',
41
41
  validator: (val) => ['dialog', 'modal', 'confirm'].includes(val as string),
42
42
  },
43
- positionX: {
43
+ justifyDialog: {
44
44
  type: String,
45
45
  default: 'center',
46
- validator: (val) => ['left', 'center', 'right'].includes(val as string),
46
+ validator: (val) => ['start', 'center', 'end'].includes(val as string),
47
47
  },
48
- positionY: {
48
+ alignDialog: {
49
49
  type: String,
50
50
  default: 'center',
51
- validator: (val) => ['top', 'center', 'bottom'].includes(val as string),
51
+ validator: (val) => ['start', 'center', 'end'].includes(val as string),
52
52
  },
53
53
  lockViewport: {
54
54
  type: Boolean,
@@ -83,8 +83,6 @@ const hasDialogTitle = computed(() => slots.dialogTitle !== undefined);
83
83
  const hasDialogContent = computed(() => slots.dialogContent !== undefined);
84
84
  const hasActionButtons = computed(() => slots.actionButtons !== undefined);
85
85
 
86
- const alignDialog = computed(() => `${props.positionY}-${props.positionX}`);
87
-
88
86
  onMounted(() => {
89
87
  bodyTag.value = document.querySelector('body');
90
88
  if (lockViewport.value && bodyTag.value !== null) {
@@ -95,9 +93,6 @@ onMounted(() => {
95
93
 
96
94
  <style lang="css">
97
95
  .display-dialog-core {
98
- --_dialog-inner-height: initial;
99
- --_dialog-inner-width: 100vw;
100
-
101
96
  display: flex;
102
97
  position: fixed;
103
98
  left: 0;
@@ -106,7 +101,7 @@ onMounted(() => {
106
101
  height: 100%;
107
102
  backdrop-filter: blur(5px);
108
103
  background-color: rgba(0, 0, 0, 0.5);
109
- z-index: 13;
104
+ z-index: 999999;
110
105
  opacity: 0;
111
106
  border: none;
112
107
  padding: 0;
@@ -125,54 +120,70 @@ onMounted(() => {
125
120
  }
126
121
  }
127
122
 
128
- &[align-dialog$='center'] {
129
- justify-content: center;
130
- }
131
- &[align-dialog^='center'] {
132
- align-items: center;
123
+ /* * Positioning the dialog */
124
+ &[justify-dialog='start'] {
125
+ justify-content: flex-start;
133
126
  }
134
127
 
135
- &.confirm {
136
- --_dialog-inner-width: initial;
128
+ &[justify-dialog='center'] {
129
+ justify-content: center;
137
130
  }
138
131
 
139
- &.dialog {
140
- --_dialog-inner-height: 70dvh;
141
- --_dialog-inner-width: min(75%, 720px);
132
+ &[justify-dialog='end'] {
133
+ justify-content: flex-end;
142
134
  }
143
135
 
144
- &.form {
145
- --_dialog-inner-width: initial;
136
+ &[align-dialog='start'] {
137
+ align-items: flex-start;
146
138
  }
147
139
 
148
- &.fullscreen {
149
- --_dialog-inner-width: initial;
140
+ &[align-dialog='center'] {
141
+ align-items: center;
150
142
  }
151
-
152
- &.modal {
153
- --_dialog-inner-width: initial;
143
+ &[align-dialog='end'] {
144
+ align-items: flex-end;
154
145
  }
155
146
 
156
147
  .inner {
157
148
  display: grid;
158
149
  grid-template-rows: auto 1fr auto;
159
150
 
160
- border-radius: var(--dialog-border-radius);
161
- border: var(--dialog-border);
162
- outline: var(--dialog-outline);
151
+ border-radius: 8px;
152
+ border: 1px solid light-dark(var(--gray-10), var(--gray-2));
153
+ outline: 1px solid light-dark(var(--gray-12), var(--gray-0));
163
154
 
164
155
  background-color: var(--dialog-inner-background);
165
- height: var(--_dialog-inner-height);
166
- width: var(--_dialog-inner-width);
167
-
156
+ height: initial;
157
+ width: 100vw;
168
158
  overflow: hidden;
169
159
 
160
+ &.confirm {
161
+ width: initial;
162
+ }
163
+
164
+ &.dialog {
165
+ height: 70dvh;
166
+ width: min(75%, 720px);
167
+ }
168
+
169
+ &.form {
170
+ width: initial;
171
+ }
172
+
173
+ &.fullscreen {
174
+ width: initial;
175
+ }
176
+
177
+ &.modal {
178
+ width: initial;
179
+ }
180
+
170
181
  .header {
171
182
  display: grid;
172
183
  grid-template-columns: auto 1fr auto;
173
184
  align-items: center;
174
185
 
175
- padding: var(--dialog-header-padding);
186
+ padding: 12px;
176
187
 
177
188
  .col-left {
178
189
  /* grid-column: 1; */
@@ -223,7 +234,7 @@ onMounted(() => {
223
234
 
224
235
  .dialog-content {
225
236
  overflow: hidden;
226
- padding: var(--dialog-content-padding);
237
+ padding: 12px;
227
238
 
228
239
  &.allow-content-scroll {
229
240
  overflow-y: auto;
@@ -237,7 +248,7 @@ onMounted(() => {
237
248
  display: flex;
238
249
  gap: 1.2rem;
239
250
  justify-content: flex-end;
240
- padding: var(--dialog-footer-padding);
251
+ padding: 12px;
241
252
  }
242
253
  }
243
254
  }
@@ -0,0 +1,187 @@
1
+ <template>
2
+ <div class="display-prompt-core" :class="[{ dismissed: hide }, { 'use-local-style-overrides': useLocalStyleOverrides }]" :data-test-id="`display-prompt-core-${theme}`">
3
+ <div class="display-prompt-wrapper" :data-prompt-theme="theme" :class="[elementClasses]" data-test-id="display-prompt">
4
+ <div class="display-prompt-inner">
5
+ <div class="display-prompt-icon" data-test-id="prompt-icon">
6
+ <slot name="customDecoratorIcon">
7
+ <Icon :name="displayPromptIcons[theme]" class="icon" :color="iconColor" />
8
+ </slot>
9
+ </div>
10
+ <div class="display-prompt-content">
11
+ <p class="title" data-test-id="display-prompt-title">
12
+ <slot name="title"></slot>
13
+ </p>
14
+ <p v-if="hasContent" class="text" data-test-id="display-prompt-content">
15
+ <slot name="content"></slot>
16
+ </p>
17
+ </div>
18
+ <button v-if="dismissible" @click.prevent="dismissPrompt()" data-test-id="display-prompt-action" class="display-prompt-action">
19
+ <slot name="customCloseIcon">
20
+ <Icon name="bitcoin-icons:cross-filled" class="icon" />
21
+ </slot>
22
+ <span class="sr-only">
23
+ <slot name="customTitle">Close this prompt</slot>
24
+ </span>
25
+ </button>
26
+ </div>
27
+ </div>
28
+ </div>
29
+ </template>
30
+
31
+ <script setup lang="ts">
32
+ const props = defineProps({
33
+ dismissible: {
34
+ type: Boolean,
35
+ default: false,
36
+ },
37
+ theme: {
38
+ type: String,
39
+ default: 'error',
40
+ validator(value: string) {
41
+ return ['error', 'info', 'success', 'warning', 'secondary'].includes(value);
42
+ },
43
+ },
44
+ styleClassPassthrough: {
45
+ type: Array as PropType<string[]>,
46
+ default: () => [],
47
+ },
48
+ iconColor: {
49
+ type: String as PropType<string>,
50
+ default: 'dark-grey',
51
+ validator(value: string) {
52
+ return ['dark-grey', 'white'].includes(value);
53
+ },
54
+ },
55
+ useLocalStyleOverrides: {
56
+ type: Boolean,
57
+ default: false,
58
+ },
59
+ displayPromptIcons: {
60
+ type: Object as PropType<Record<string, string>>,
61
+ default: () => ({
62
+ error: 'akar-icons:circle-alert',
63
+ info: 'akar-icons:info',
64
+ success: 'akar-icons:check',
65
+ warning: 'akar-icons:circle-alert',
66
+ secondary: 'akar-icons:info',
67
+ }),
68
+ },
69
+ });
70
+
71
+ const slots = useSlots();
72
+ const hasContent = ref(slots.content !== undefined);
73
+ const hide = ref(false);
74
+ const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
75
+
76
+ const dismissPrompt = () => {
77
+ // styleClassPassthrough.value = '';
78
+ hide.value = true;
79
+ };
80
+ </script>
81
+
82
+ <style lang="css">
83
+ .display-prompt-core {
84
+ display: grid;
85
+ grid-template-rows: 1fr;
86
+ opacity: 1;
87
+ transition: all 200ms ease-in-out;
88
+
89
+ &.dismissed {
90
+ grid-template-rows: 0fr;
91
+ opacity: 0;
92
+ pointer-events: none;
93
+ }
94
+
95
+ .display-prompt-wrapper {
96
+ background-color: var(--component-theme-0);
97
+ border: 1px solid var(--component-theme-8);
98
+ border-radius: 4px;
99
+
100
+ border-inline-start: 8px solid var(--component-theme-8);
101
+ border-start-start-radius: 8px;
102
+ border-end-start-radius: 8px;
103
+
104
+ overflow: hidden;
105
+
106
+ .display-prompt-inner {
107
+ align-items: center;
108
+ display: flex;
109
+ gap: 12px;
110
+ justify-content: space-between;
111
+ padding-block: 1rem;
112
+ padding-inline: 1.5rem;
113
+
114
+ .display-prompt-icon {
115
+ display: inline-flex;
116
+ .icon {
117
+ color: var(--component-theme-8);
118
+ display: inline-block;
119
+ font-size: 3rem;
120
+ font-style: normal;
121
+ font-weight: normal;
122
+ overflow: hidden;
123
+ }
124
+ }
125
+
126
+ .display-prompt-content {
127
+ display: block flex;
128
+ flex-direction: column;
129
+ flex-grow: 1;
130
+ gap: 1rem;
131
+ margin: 0;
132
+ padding: 0.2rem;
133
+
134
+ .title {
135
+ font-size: var(--step-2);
136
+ font-weight: bold;
137
+ line-height: 1.3;
138
+ color: var(--component-theme-8);
139
+ margin: 0;
140
+ padding: 0;
141
+ }
142
+
143
+ .text {
144
+ font-size: var(--step-2);
145
+ font-weight: normal;
146
+ line-height: 1.3;
147
+ color: var(--component-theme-8);
148
+ margin: 0;
149
+ padding: 0;
150
+ }
151
+ }
152
+ .display-prompt-action {
153
+ background-color: transparent;
154
+ display: block flex;
155
+ align-items: center;
156
+ justify-content: center;
157
+ margin: 1rem;
158
+ padding: 0.5rem;
159
+ border: 0.1rem solid var(--component-theme-8);
160
+ border-radius: 50%;
161
+ outline: 1px solid var(--component-theme-3);
162
+
163
+ transition: border 200ms ease-in-out, outline 200ms ease-in-out;
164
+
165
+ &:hover {
166
+ cursor: pointer;
167
+ border: 0.1rem solid var(--component-theme-12);
168
+ outline: 2px solid var(--component-theme-6);
169
+ }
170
+
171
+ &:focus-visible {
172
+ box-shadow: var(--focus-box-shadow-colour-on);
173
+ border: 0.1rem solid var(--component-theme-12);
174
+ outline: 2px solid var(--component-theme-6);
175
+ }
176
+
177
+ .icon {
178
+ color: var(--component-theme-8);
179
+ display: block;
180
+ font-size: var(--step-2);
181
+ padding: 1rem;
182
+ }
183
+ }
184
+ }
185
+ }
186
+ }
187
+ </style>
@@ -0,0 +1,124 @@
1
+ <template>
2
+ <div class="expanding-panel" :class="[elementClasses]">
3
+ <details class="expanding-panel-details" :name>
4
+ <summary class="expanding-panel-summary" :id="triggerId" :aria-controls="contentId">
5
+ <span class="label-wrapper">
6
+ <slot name="summary"></slot>
7
+ </span>
8
+ <span class="icon-wrapper">
9
+ <slot name="icon">
10
+ <Icon name="bi:caret-down-fill" class="icon mi-12" />
11
+ </slot>
12
+ </span>
13
+ </summary>
14
+ </details>
15
+ <div class="expanding-panel-content" :aria-labelledby="triggerId" :id="contentId" role="region">
16
+ <div class="inner">
17
+ <slot name="content"></slot>
18
+ </div>
19
+ </div>
20
+ </div>
21
+ </template>
22
+
23
+ <script setup lang="ts">
24
+ const props = defineProps({
25
+ name: {
26
+ type: String,
27
+ default: '',
28
+ },
29
+ iconSize: {
30
+ type: String,
31
+ default: 'medium',
32
+ },
33
+ animationDuration: {
34
+ type: Number,
35
+ default: 400,
36
+ },
37
+ styleClassPassthrough: {
38
+ type: Array as PropType<string[]>,
39
+ default: () => [],
40
+ },
41
+ });
42
+
43
+ const name = computed(() => props.name || useId());
44
+
45
+ const triggerId = computed(() => `id-${name.value}-trigger`);
46
+ const contentId = computed(() => `id-${name.value}-content`);
47
+ const animationDurationStr = computed(() => `${props.animationDuration}ms`);
48
+
49
+ const { elementClasses, resetElementClasses, updateElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
50
+ </script>
51
+
52
+ <style lang="css">
53
+ .expanding-panel {
54
+ .expanding-panel-details {
55
+ .expanding-panel-summary {
56
+ display: flex;
57
+ align-items: center;
58
+ justify-content: space-between;
59
+ flex-direction: row;
60
+ gap: 0;
61
+ list-style: none;
62
+
63
+ padding-inline: 0.5rem;
64
+
65
+ &::-webkit-details-marker,
66
+ &::marker {
67
+ display: none;
68
+ }
69
+
70
+ overflow: clip;
71
+
72
+ .label-wrapper {
73
+ }
74
+ .icon-wrapper {
75
+ display: flex;
76
+ align-items: center;
77
+ justify-content: space-between;
78
+
79
+ aspect-ratio: 1;
80
+ outline: 1px solid var(--gray-3);
81
+ padding: 1rem;
82
+ overflow: hidden;
83
+
84
+ .icon {
85
+ display: block;
86
+ transform: scaleY(1);
87
+ transition: transform v-bind(animationDurationStr) ease-in-out;
88
+ font-size: 1.2rem;
89
+ }
90
+ }
91
+ }
92
+
93
+ &[open] {
94
+ .expanding-panel-summary {
95
+ .icon-wrapper {
96
+ .icon {
97
+ transform: scaleY(-1);
98
+ }
99
+ }
100
+ }
101
+ + .expanding-panel-content {
102
+ grid-template-rows: 1fr;
103
+ .inner {
104
+ /* transform: scaleY(1); */
105
+ }
106
+ }
107
+ }
108
+ }
109
+
110
+ .expanding-panel-content {
111
+ display: grid;
112
+ grid-template-rows: 0fr;
113
+ transition: all v-bind(animationDurationStr) ease-in-out;
114
+
115
+ .inner {
116
+ overflow: hidden;
117
+ padding: 0.5rem;
118
+
119
+ /* transform: scaleY(0); */
120
+ /* transition: transform v-bind(animationDurationStr) ease-in-out; */
121
+ }
122
+ }
123
+ }
124
+ </style>
@@ -1,43 +1,56 @@
1
1
  <template>
2
- <div class="overflow-navigation-wrapper" :class="elementClasses">
2
+ <div class="overflow-navigation-wrapper" :class="elementClasses" role="menu" aria-label="Overflow navigation menu">
3
3
  <ul
4
4
  v-for="(navGroup, groupKey) in mainNavigationState.clonedNavLinks"
5
5
  :key="groupKey"
6
6
  class="overflow-navigation-list"
7
- :class="[{visible: !mainNavigationState.navListVisibility[groupKey]}]"
7
+ :class="[{ visible: !mainNavigationState.navListVisibility[groupKey] }]"
8
8
  :style="{ '--_overflow-navigation-list-min-width': widestNavLinkWidthInMainNavigationState + 'px' }"
9
+ role="none"
9
10
  >
10
11
  <template v-for="(link, localIndex) in navGroup" :key="localIndex">
11
12
  <li
12
13
  v-if="link.path"
13
14
  class="overflow-navigation-item"
14
- :class="{ 'visible': !mainNavigationState.clonedNavLinks?.[groupKey]?.[localIndex]?.config?.visible }"
15
+ :class="{ visible: !mainNavigationState.clonedNavLinks?.[groupKey]?.[localIndex]?.config?.visible }"
15
16
  :style="{ '--_main-navigation-item-width': mainNavigationState.clonedNavLinks?.[groupKey]?.[localIndex]?.config?.width + 'px' }"
16
17
  :data-group-key="groupKey"
17
18
  :data-local-index="localIndex"
19
+ role="none"
18
20
  >
19
- <NuxtLink class="overflow-navigation-link" :to="link.path"><span class="overflow-navigation-text">{{ link.name }}</span></NuxtLink>
21
+ <NuxtLink class="overflow-navigation-link" :to="link.path" role="menuitem">
22
+ <span class="overflow-navigation-text">{{ link.name }}</span>
23
+ </NuxtLink>
20
24
  </li>
21
25
  <li
22
26
  v-else
23
27
  class="overflow-navigation-item"
24
- :class="{ 'visible': !mainNavigationState.clonedNavLinks?.[groupKey]?.[localIndex]?.config?.visible }"
28
+ :class="{ visible: !mainNavigationState.clonedNavLinks?.[groupKey]?.[localIndex]?.config?.visible }"
25
29
  :style="{ '--_main-navigation-item-width': mainNavigationState.clonedNavLinks?.[groupKey]?.[localIndex]?.config?.width + 'px' }"
26
30
  :data-group-key="groupKey"
27
31
  :data-local-index="localIndex"
32
+ role="none"
28
33
  >
29
- <DisplayDetailsCore :id="useId()" name="overflow-navigation-group" :animation-duration="detailsAanimationDuration" icon-size="medium" :style-class-passthrough="['overflow-navigation-details']">
34
+ <DisplayDetailsCore
35
+ :id="useId()"
36
+ name="overflow-navigation-group"
37
+ :animation-duration="detailsAanimationDuration"
38
+ icon-size="medium"
39
+ :style-class-passthrough="['overflow-navigation-details']"
40
+ >
30
41
  <template #summary>
31
- <span class="overflow-navigation-text">{{ link.childLinksTitle }}</span>
42
+ <span class="overflow-navigation-text" :aria-label="`${link.childLinksTitle} submenu`" role="menuitem" :aria-haspopup="true">{{ link.childLinksTitle }}</span>
32
43
  </template>
33
44
  <template #summaryIcon>
34
- <Icon name="mdi:chevron-down" class="icon" />
45
+ <Icon name="mdi:chevron-down" class="icon" :aria-hidden="true" />
35
46
  </template>
36
47
  <template #content>
37
48
  <div class="overflow-navigation-sub-nav-inner">
38
49
  <ul class="overflow-navigation-sub-nav-list">
39
50
  <li v-for="childLink in link.childLinks" :key="childLink.name" class="overflow-navigation-sub-nav-item">
40
- <NuxtLink :to="childLink.path" class="overflow-navigation-sub-nav-link"><span class="overflow-navigation-sub-nav-text">{{ childLink.name }}</span></NuxtLink>
51
+ <NuxtLink :to="childLink.path" class="overflow-navigation-sub-nav-link" role="menuitem">
52
+ <span class="overflow-navigation-sub-nav-text">{{ childLink.name }}</span>
53
+ </NuxtLink>
41
54
  </li>
42
55
  </ul>
43
56
  </div>
@@ -68,10 +81,7 @@ const detailsAanimationDurationString = `${detailsAanimationDuration}ms`;
68
81
 
69
82
  const widestNavLinkWidthInMainNavigationState = computed(() => {
70
83
  return Object.values(props.mainNavigationState.clonedNavLinks || {}).reduce((maxWidth, group) => {
71
- return Math.max(
72
- maxWidth,
73
- ...group.map(link => link.config?.width || 0)
74
- );
84
+ return Math.max(maxWidth, ...group.map((link) => link.config?.width || 0));
75
85
  }, 0);
76
86
  });
77
87
 
@@ -86,14 +96,12 @@ watch(
86
96
  </script>
87
97
 
88
98
  <style lang="css">
89
-
90
99
  .overflow-navigation-wrapper {
91
100
  display: flex;
92
101
  flex-direction: column;
93
102
  gap: 12px;
94
103
 
95
104
  .overflow-navigation-list {
96
-
97
105
  display: none;
98
106
 
99
107
  &.visible {
@@ -104,7 +112,6 @@ watch(
104
112
  }
105
113
 
106
114
  .overflow-navigation-item {
107
-
108
115
  display: none;
109
116
 
110
117
  &.visible {
@@ -137,7 +144,6 @@ watch(
137
144
  .display-details-content {
138
145
  .overflow-navigation-sub-nav-inner {
139
146
  .overflow-navigation-sub-nav-list {
140
-
141
147
  display: flex;
142
148
  flex-direction: column;
143
149
  gap: 12px;
@@ -145,7 +151,6 @@ watch(
145
151
  transition: margin-block-start v-bind(detailsAanimationDurationString) ease;
146
152
 
147
153
  .overflow-navigation-sub-nav-item {
148
-
149
154
  .overflow-navigation-sub-nav-link {
150
155
  text-decoration: none;
151
156
  color: inherit;