srcdev-nuxt-components 4.0.6 → 5.0.1

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 +50 -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/display-details/DisplayDetailsCore.vue +49 -60
  25. package/components/{functional/display-dialog → display-dialog}/DisplayDialogCore.vue +49 -38
  26. package/components/display-prompt/DisplayPromptCore.vue +187 -0
  27. package/components/expanding-panel/ExpandingPanel.vue +124 -0
  28. package/components/{presentation/layout-row → layout-row}/LayoutRow.vue +12 -4
  29. package/components/responsive-header/NavigationItems.vue +23 -18
  30. package/components/responsive-header/ResponsiveHeader.vue +376 -276
  31. package/components/skip-links/SkipLinks.vue +85 -0
  32. package/components/{presentation/tabs → tabs}/TabsCore.vue +27 -58
  33. package/composables/useDialogControls.ts +22 -1
  34. package/package.json +1 -1
  35. package/assets/styles/a11y/index.css +0 -2
  36. package/assets/styles/forms/index.css +0 -2
  37. package/assets/styles/forms/themes/_error.css +0 -77
  38. package/assets/styles/forms/themes/_ghost.css +0 -77
  39. package/assets/styles/forms/themes/_input-action.css +0 -20
  40. package/assets/styles/forms/themes/_primary.css +0 -82
  41. package/assets/styles/forms/themes/_secondary.css +0 -77
  42. package/assets/styles/forms/themes/_success.css +0 -77
  43. package/assets/styles/forms/themes/_tertiary.css +0 -77
  44. package/assets/styles/forms/themes/_warning.css +0 -77
  45. package/assets/styles/forms/themes/index.css +0 -8
  46. package/assets/styles/forms/variables/_sizes.css +0 -82
  47. package/assets/styles/forms/variables/index.css +0 -2
  48. package/assets/styles/typography/index.css +0 -2
  49. package/assets/styles/typography/utils/_font-classes.css +0 -160
  50. package/assets/styles/typography/utils/_weights.css +0 -69
  51. package/assets/styles/typography/utils/index.css +0 -2
  52. package/assets/styles/typography/variables/_colors.css +0 -14
  53. package/assets/styles/typography/variables/index.css +0 -2
  54. package/assets/styles/utils/_animations.css +0 -42
  55. package/assets/styles/utils/_canvasWidths.css +0 -18
  56. package/assets/styles/utils/_display.css +0 -7
  57. package/assets/styles/utils/_page.css +0 -27
  58. package/assets/styles/utils/_placement.css +0 -73
  59. package/assets/styles/utils/index.css +0 -7
  60. package/assets/styles/variables/components/_accordian.css +0 -7
  61. package/assets/styles/variables/components/_container-glow-core.css +0 -16
  62. package/assets/styles/variables/components/_display-dialog-core.css +0 -35
  63. package/assets/styles/variables/components/_tabs.css +0 -18
  64. package/assets/styles/variables/components/display-prompt-core/_scaffolding.css +0 -57
  65. package/assets/styles/variables/components/display-prompt-core/index.css +0 -2
  66. package/assets/styles/variables/components/display-prompt-core/themes/_error.css +0 -39
  67. package/assets/styles/variables/components/display-prompt-core/themes/_info.css +0 -39
  68. package/assets/styles/variables/components/display-prompt-core/themes/_success.css +0 -39
  69. package/assets/styles/variables/components/display-prompt-core/themes/_warning.css +0 -39
  70. package/assets/styles/variables/components/index.css +0 -5
  71. package/assets/styles/variables/index.css +0 -2
  72. package/components/functional/accordian/AccordianCore.vue +0 -138
  73. package/components/presentation/display-prompt/DisplayPromptCore.vue +0 -150
  74. /package/assets/styles/{variables/components/display-prompt-core → extends-layer/srcdev-components}/themes/index.css +0 -0
  75. /package/assets/styles/{a11y → setup/a11y}/_utils.css +0 -0
  76. /package/assets/styles/{typography/variables/_reponsive-font-size.css → setup/typography/vars/_reponsive-font-sizes.css} +0 -0
  77. /package/assets/styles/{utils → setup/utility-classes}/_margin-helpers.css +0 -0
  78. /package/assets/styles/{utils → setup/utility-classes}/_padding-helpers.css +0 -0
  79. /package/assets/styles/{variables → setup/variables}/colors/_blue.css +0 -0
  80. /package/assets/styles/{variables → setup/variables}/colors/_gray.css +0 -0
  81. /package/assets/styles/{variables → setup/variables}/colors/_green.css +0 -0
  82. /package/assets/styles/{variables → setup/variables}/colors/_orange.css +0 -0
  83. /package/assets/styles/{variables → setup/variables}/colors/_red.css +0 -0
  84. /package/assets/styles/{variables → setup/variables}/colors/_yellow.css +0 -0
  85. /package/assets/styles/{variables/colors/colors.css → setup/variables/colors/index.css} +0 -0
  86. /package/components/{functional/display-dialog → display-dialog}/variants/DisplayDialogConfirm.vue +0 -0
  87. /package/components/{functional/display-dialog → display-dialog}/variants/DisplayDialogScrollableContent.vue +0 -0
  88. /package/components/{presentation/display-grid → display-grid}/DisplayGridCore.vue +0 -0
  89. /package/components/{presentation/display-prompt → display-prompt}/variants/DisplayPromptError.vue +0 -0
  90. /package/components/{presentation/layout-grids → layout-grids}/LayoutGridA.vue +0 -0
  91. /package/components/{presentation/layout-grids → layout-grids}/LayoutGridB.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,30 +1,51 @@
1
1
  <template>
2
- <div class="navigation" :class="[elementClasses, { loaded: navLoaded }]" ref="navigationWrapper">
3
- <nav class="main-navigation" ref="mainNav">
4
-
5
- <ul v-for="(navGroup, groupKey) in responsiveNavLinks" :key="groupKey" class="main-navigation-list"
6
- :ref="el => setNavRef(String(groupKey), el as HTMLUListElement | null)">
2
+ <div class="navigation" :class="[elementClasses, { loaded: navLoaded }]" ref="navigationWrapper" role="banner">
3
+ <nav class="main-navigation" ref="mainNav" aria-label="Main navigation">
4
+ <ul v-for="(navGroup, groupKey) in responsiveNavLinks" :key="groupKey" class="main-navigation-list" :ref="el => setNavRef(String(groupKey), el as HTMLUListElement | null)">
7
5
  <template v-for="(link, localIndex) in navGroup" :key="localIndex">
8
- <li v-if="link.path" class="main-navigation-item"
6
+ <li
7
+ v-if="link.path"
8
+ class="main-navigation-item"
9
9
  :class="{ 'visually-hidden': !mainNavigationState.clonedNavLinks?.[groupKey]?.[localIndex]?.config?.visible }"
10
10
  :style="{ '--_main-navigation-item-width': mainNavigationState.clonedNavLinks?.[groupKey]?.[localIndex]?.config?.width + 'px' }"
11
- ref="mainNavigationItems" :data-group-key="groupKey" :data-local-index="localIndex">
12
- <NuxtLink class="main-navigation-link" :to="link.path">{{ link.name }}</NuxtLink>
11
+ ref="mainNavigationItems"
12
+ :data-group-key="groupKey"
13
+ :data-local-index="localIndex"
14
+ @mouseenter="handleNavigationItemHover"
15
+ @focusin="handleNavigationItemHover"
16
+ >
17
+ <NuxtLink class="main-navigation-link" :class="{ 'has-icon': link.iconName }" :to="link.path">
18
+ <Icon v-if="link.iconName" :name="link.iconName" class="decorator-icon" aria-hidden="true" />
19
+ {{ link.name }}
20
+ </NuxtLink>
13
21
  </li>
14
- <li v-else class="main-navigation-item"
22
+ <li
23
+ v-else
24
+ class="main-navigation-item"
15
25
  :class="{ 'visually-hidden': !mainNavigationState.clonedNavLinks?.[groupKey]?.[localIndex]?.config?.visible }"
16
26
  :style="{ '--_main-navigation-item-width': mainNavigationState.clonedNavLinks?.[groupKey]?.[localIndex]?.config?.width + 'px' }"
17
- ref="mainNavigationItems" :data-group-key="groupKey" :data-local-index="localIndex">
27
+ ref="mainNavigationItems"
28
+ :data-group-key="groupKey"
29
+ :data-local-index="localIndex"
30
+ >
18
31
  <details class="main-navigation-details" name="navigation-group" ref="navigationDetails">
19
- <summary @mouseenter="handleSummaryHover($event)" @focusin="handleSummaryHover($event)"
20
- class="main-navigation-details-summary has-toggle-icon">
21
- <Icon name="mdi:chevron-down" class="icon" />
32
+ <summary
33
+ @mouseenter="handleSummaryHover($event)"
34
+ @focusin="handleSummaryHover($event)"
35
+ @click.prevent="handleSummaryAction($event)"
36
+ @keypup.prevent.stop="handleSummaryAction($event)"
37
+ class="main-navigation-details-summary has-toggle-icon"
38
+ :aria-label="`${link.childLinksTitle} submenu`"
39
+ >
40
+ <Icon name="mdi:chevron-down" class="icon" :aria-hidden="true" />
41
+ <Icon v-if="link.iconName" :name="link.iconName" class="decorator-icon" aria-hidden="true" />
42
+
22
43
  {{ link.childLinksTitle }}
23
44
  </summary>
24
- <div class="main-navigation-sub-nav">
45
+ <div class="main-navigation-sub-nav" role="menu" :aria-labelledby="`summary-${groupKey}-${localIndex}`">
25
46
  <ul class="main-navigation-sub-nav-list">
26
47
  <li class="main-navigation-sub-nav-item" v-for="childLink in link.childLinks" :key="childLink.name">
27
- <NuxtLink :to="childLink.path" class="main-navigation-sub-nav-link">{{ childLink.name }}</NuxtLink>
48
+ <NuxtLink :to="childLink.path" class="main-navigation-sub-nav-link" role="menuitem">{{ childLink.name }}</NuxtLink>
28
49
  </li>
29
50
  </ul>
30
51
  </div>
@@ -32,16 +53,14 @@
32
53
  </li>
33
54
  </template>
34
55
  </ul>
35
-
36
56
  </nav>
37
- <nav class="secondary-navigation" ref="secondaryNav">
38
- <details class="overflow-details" :class="[{ 'visually-hidden': !navLoaded || !showOverflowDetails }]"
39
- ref="overflowDetails" name="overflow-group">
57
+ <nav class="secondary-navigation" ref="secondaryNav" aria-label="Secondary navigation">
58
+ <details class="overflow-details" :class="[{ 'visually-hidden': !navLoaded || !showOverflowDetails }]" ref="overflowDetails" name="overflow-group">
40
59
  <summary class="overflow-details-summary has-toggle-icon">
41
- <Icon :name="overflowDetailsSummaryIcons.more" class="icon" :class="[{ show: !allowNavigationCollapse }]" />
42
- <Icon :name="overflowDetailsSummaryIcons.burger" class="icon" :class="[{ show: allowNavigationCollapse }]" />
60
+ <Icon :name="overflowDetailsSummaryIcons.more" class="icon" :class="[{ show: !allowNavigationCollapse }]" :aria-hidden="true" />
61
+ <Icon :name="overflowDetailsSummaryIcons.burger" class="icon" :class="[{ show: allowNavigationCollapse }]" :aria-hidden="true" />
43
62
  </summary>
44
- <div class="overflow-details-nav">
63
+ <div class="overflow-details-nav" role="menu">
45
64
  <NavigationItems :main-navigation-state="mainNavigationState" />
46
65
  </div>
47
66
  </details>
@@ -52,7 +71,7 @@
52
71
  <div>
53
72
  <h2 class="heading-4">navigationWrapperRects</h2>
54
73
  <pre>{{ navigationWrapperRects }}</pre>
55
- <hr>
74
+ <hr />
56
75
  <h2 class="heading-4">secondaryNavRects</h2>
57
76
  <pre>{{ secondaryNavRects }}</pre>
58
77
  </div>
@@ -83,32 +102,45 @@ const props = defineProps({
83
102
  default: {
84
103
  more: 'gravity-ui:ellipsis',
85
104
  burger: 'gravity-ui:bars',
86
- }
87
- },
88
- collapseNavigationBelowWidth: {
89
- type: Boolean,
90
- default: true,
105
+ },
91
106
  },
92
107
  collapseBreakpoint: {
93
108
  type: Number,
94
- default: 500, // px
109
+ default: null, // px
110
+ },
111
+ collapseAtMainNavIntersection: {
112
+ type: Boolean,
113
+ default: false,
95
114
  },
96
115
  styleClassPassthrough: {
97
116
  type: Array as PropType<string[]>,
98
117
  default: () => [],
99
118
  },
119
+ allowExpandOnGesture: {
120
+ type: Boolean,
121
+ default: true,
122
+ },
100
123
  });
101
124
 
102
125
  const slots = useSlots();
103
126
  const hasSecondaryNavigation = computed(() => slots.secondaryNavigation !== undefined);
104
-
127
+ const collapseNavigationBelowWidth = computed(() => props.collapseBreakpoint !== null || props.collapseAtMainNavIntersection);
128
+ const collapseBreakpoint = ref(props.collapseBreakpoint);
105
129
  const navLoaded = ref(false);
106
130
  const navigationWrapperRef = useTemplateRef('navigationWrapper');
107
131
 
108
- const handleSummaryHover = (event: MouseEvent | FocusEvent) => {
132
+ const closeAllNavigationDetails = () => {
133
+ navigationDetailsRefs.value?.forEach((element) => {
134
+ element?.removeAttribute('open');
135
+ });
136
+ overflowDetailsRef.value?.removeAttribute('open');
137
+ };
138
+
139
+ const toggleDetailsElement = (event: Event) => {
109
140
  const summaryElement = event.currentTarget as HTMLElement;
110
141
  const parentDetailsElement = summaryElement.closest('details');
111
142
  if (!parentDetailsElement) return;
143
+
112
144
  if (parentDetailsElement.hasAttribute('open')) {
113
145
  parentDetailsElement.removeAttribute('open');
114
146
  } else {
@@ -117,6 +149,39 @@ const handleSummaryHover = (event: MouseEvent | FocusEvent) => {
117
149
  overflowDetailsRef.value?.removeAttribute('open');
118
150
  };
119
151
 
152
+ const handleSummaryHover = (event: MouseEvent | FocusEvent) => {
153
+ if (!props.allowExpandOnGesture) {
154
+ return;
155
+ }
156
+
157
+ // Close all other open navigation details first
158
+ const summaryElement = event.currentTarget as HTMLElement;
159
+ const parentDetailsElement = summaryElement.closest('details');
160
+
161
+ navigationDetailsRefs.value?.forEach((element) => {
162
+ if (element !== parentDetailsElement) {
163
+ element?.removeAttribute('open');
164
+ }
165
+ });
166
+ overflowDetailsRef.value?.removeAttribute('open');
167
+
168
+ // Then toggle the current one
169
+ toggleDetailsElement(event);
170
+ };
171
+
172
+ const handleNavigationItemHover = () => {
173
+ if (!props.allowExpandOnGesture) {
174
+ return;
175
+ }
176
+
177
+ // Close all open navigation details when hovering over regular nav items
178
+ closeAllNavigationDetails();
179
+ };
180
+
181
+ const handleSummaryAction = (event: MouseEvent | KeyboardEvent) => {
182
+ toggleDetailsElement(event);
183
+ };
184
+
120
185
  const mainNavigationState = ref<ResponsiveHeaderState>({
121
186
  navListVisibility: {
122
187
  firstNav: false,
@@ -129,8 +194,8 @@ const mainNavigationState = ref<ResponsiveHeaderState>({
129
194
  const navRefs = ref<Record<string, HTMLUListElement | null>>({});
130
195
 
131
196
  const setNavRef = (key: string, el: HTMLUListElement | null) => {
132
- navRefs.value[key] = el
133
- }
197
+ navRefs.value[key] = el;
198
+ };
134
199
 
135
200
  const navigationWrapperRects = ref<IFlooredRect | null>(null);
136
201
  const firstNavRef = ref<HTMLUListElement | null>(null);
@@ -165,7 +230,7 @@ const initTemplateRefs = async () => {
165
230
  firstNavRef.value = navRefs.value['firstNav'] as HTMLUListElement | null;
166
231
  secondNavRef.value = navRefs.value['secondNav'] as HTMLUListElement | null;
167
232
  return;
168
- }
233
+ };
169
234
 
170
235
  const getFlooredRect = (rect: DOMRect | null) => {
171
236
  if (!rect) return null;
@@ -177,21 +242,30 @@ const getFlooredRect = (rect: DOMRect | null) => {
177
242
  width: Math.floor(rect.width),
178
243
  height: Math.floor(rect.height),
179
244
  };
180
- }
245
+ };
181
246
 
182
247
  const updateNavigationConfig = async (source: string) => {
183
248
  navigationWrapperRects.value = getFlooredRect((navigationWrapperRef.value && navigationWrapperRef.value.getBoundingClientRect()) ?? null) || null;
184
249
  secondaryNavRects.value = getFlooredRect((secondaryNavRef.value && secondaryNavRef.value.getBoundingClientRect()) ?? null) || null;
185
250
  firstNavRects.value = getFlooredRect((firstNavRef.value && firstNavRef.value.getBoundingClientRect()) ?? null) || null;
186
251
  secondNavRects.value = getFlooredRect((secondNavRef.value && secondNavRef.value.getBoundingClientRect()) ?? null) || null;
187
- }
252
+
253
+ if (collapseNavigationBelowWidth.value && firstNavRects.value) {
254
+ collapseBreakpoint.value = firstNavRects.value?.right;
255
+ }
256
+ };
188
257
 
189
258
  const allowNavigationCollapse = computed(() => {
190
- return props.collapseNavigationBelowWidth && navigationWrapperRects.value && navigationWrapperRects.value.width < props.collapseBreakpoint;
259
+ return (
260
+ collapseNavigationBelowWidth.value &&
261
+ navigationWrapperRects.value &&
262
+ secondaryNavRects.value !== null &&
263
+ Math.floor(secondaryNavRects.value.left - props.gapBetweenFirstAndSecondNav) <= collapseBreakpoint.value
264
+ );
191
265
  });
192
266
 
193
267
  const determineNavigationItemVisibility = (rect: DOMRect) => {
194
- // Check if navigation should be collapsed based on width
268
+ // Check if navigation should be collapsed based on width breakpoint
195
269
  if (allowNavigationCollapse.value) {
196
270
  return false;
197
271
  }
@@ -209,7 +283,6 @@ const initMainNavigationState = () => {
209
283
  if (!mainNavigationItemsRefs.value) return;
210
284
 
211
285
  mainNavigationItemsRefs.value.forEach((item, index) => {
212
-
213
286
  const rect = item.getBoundingClientRect();
214
287
 
215
288
  const groupKey = item.dataset.groupKey;
@@ -243,11 +316,10 @@ const initMainNavigationState = () => {
243
316
  } else if (typeof groupKey === 'string') {
244
317
  mainNavigationState.value.navListVisibility[groupKey] = true;
245
318
  }
246
- })
247
-
248
- }
319
+ });
320
+ };
249
321
 
250
- onMounted(async() => {
322
+ onMounted(async () => {
251
323
  await initTemplateRefs().then(() => {
252
324
  setTimeout(() => {
253
325
  navLoaded.value = true;
@@ -260,14 +332,15 @@ onMounted(async() => {
260
332
  });
261
333
  });
262
334
  // Add onClickOutside to overflowDetailsRef
263
- overflowDetailsRef.value && onClickOutside(overflowDetailsRef.value, () => {
264
- overflowDetailsRef.value?.removeAttribute('open');
265
- });
335
+ overflowDetailsRef.value &&
336
+ onClickOutside(overflowDetailsRef.value, () => {
337
+ overflowDetailsRef.value?.removeAttribute('open');
338
+ });
266
339
  });
267
340
 
268
341
  useResizeObserver(navigationWrapperRef, async () => {
269
- await updateNavigationConfig("useResizeObserver").then(() => {
270
- initMainNavigationState()
342
+ await updateNavigationConfig('useResizeObserver').then(() => {
343
+ initMainNavigationState();
271
344
  });
272
345
  });
273
346
 
@@ -282,305 +355,332 @@ watch(
282
355
  </script>
283
356
 
284
357
  <style lang="css">
285
-
286
- .navigation {
287
-
288
- ul,
289
- ol {
290
- list-style-type: none;
291
- margin: 0;
292
- padding: 0;
293
-
294
- li {
295
- /* text-box-trim: trim-both; */
296
- /* text-box-edge: cap alphabetic; */
297
- display: flex;
298
- align-items: center;
299
- }
358
+ .navigation {
359
+ ul,
360
+ ol {
361
+ list-style-type: none;
362
+ margin: 0;
363
+ padding: 0;
364
+
365
+ li {
366
+ /* text-box-trim: trim-both; */
367
+ /* text-box-edge: cap alphabetic; */
368
+ display: flex;
369
+ align-items: center;
300
370
  }
371
+ }
301
372
 
302
- --_link-visibility-transition: none;
303
-
304
- &.loaded {
305
- --_link-visibility-transition: all 0.2s ease-in-out;
306
- }
373
+ --_link-visibility-transition: none;
307
374
 
308
- /* flex-grow: 1; */
309
- display: grid;
310
- grid-template-areas: 'navStack';
375
+ &.loaded {
376
+ --_link-visibility-transition: all 0.2s ease-in-out;
377
+ }
311
378
 
312
- margin: 12px;
313
- border-radius: 8px;
314
- background-color: #efefef05;
315
- border: 1px solid #efefef75;
316
- padding: 12px;
379
+ /* flex-grow: 1; */
380
+ display: grid;
381
+ grid-template-areas: 'navStack';
382
+
383
+ margin: 12px;
384
+ border-radius: 8px;
385
+ background-color: #efefef05;
386
+ border: 1px solid #efefef75;
387
+ padding: 12px;
388
+
389
+ .main-navigation {
390
+ /* Set up some global vars */
391
+ --_link-padding-block: 0.8rem;
392
+ --_link-padding-inline: 0.2rem;
393
+ --_link-margin-block: 0.1rem;
394
+ --_link-margin-inline: 0.1rem;
395
+ --_link-focus-visible-outline-width: 0.2rem;
396
+ --_link-border-default: 2px solid transparent;
397
+ --_link-border-bottom-hover: var(--green-8);
398
+
399
+ grid-area: navStack;
400
+ display: flex;
401
+ flex-wrap: nowrap;
402
+ flex-grow: 1;
403
+ justify-content: space-between;
404
+ gap: 60px;
405
+
406
+ overflow-x: hidden;
407
+ margin-inline-end: v-bind(mainNavigationMarginBlockEndStr);
408
+
409
+ &.collapsed {
410
+ justify-content: flex-start;
411
+ }
317
412
 
318
- .main-navigation {
319
- grid-area: navStack;
413
+ .main-navigation-list {
320
414
  display: flex;
321
415
  flex-wrap: nowrap;
322
- flex-grow: 1;
323
- justify-content: space-between;
324
- gap: 60px;
325
416
 
326
- overflow-x: hidden;
327
- margin-inline-end: v-bind(mainNavigationMarginBlockEndStr);
417
+ &:nth-of-type(1) {
418
+ gap: 30px;
419
+ }
328
420
 
329
- &.collapsed {
330
- justify-content: flex-start;
421
+ &:nth-of-type(2) {
422
+ gap: 30px;
331
423
  }
332
424
 
333
- .main-navigation-list {
334
- display: flex;
335
- flex-wrap: nowrap;
425
+ .main-navigation-item {
426
+ width: var(--_main-navigation-item-width);
427
+ overflow: hidden;
428
+ transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
429
+ padding-block: var(--_link-focus-visible-outline-width);
430
+ padding-inline: var(--_link-focus-visible-outline-width);
431
+
432
+ .main-navigation-link {
433
+ display: flex;
434
+ gap: 6px;
435
+ text-wrap-mode: nowrap;
436
+ color: inherit;
437
+ text-decoration: none;
438
+ margin-inline-start: 0;
439
+ transition: var(--_link-visibility-transition);
440
+
441
+ padding-block: var(--_link-padding-block);
442
+ padding-inline: var(--_link-padding-inline);
443
+ margin-block: var(--_link-margin-block);
444
+ margin-inline: var(--_link-margin-inline);
445
+ border-bottom: var(--_link-border-default);
336
446
 
337
- &:nth-of-type(1) {
338
- gap: 30px;
447
+ &:hover {
448
+ cursor: pointer;
449
+ border-bottom-color: var(--_link-border-bottom-hover);
450
+ }
339
451
  }
340
452
 
341
- &:nth-of-type(2) {
342
- gap: 30px;
343
- }
453
+ .main-navigation-details {
454
+ --_icon-transform: scaleY(1);
344
455
 
345
- .main-navigation-item {
456
+ margin-inline-start: 0;
457
+ transition: var(--_link-visibility-transition);
346
458
 
347
- width: var(--_main-navigation-item-width);
348
- overflow: hidden;
349
- transition:
350
- opacity 0.2s ease-in-out,
351
- visibility 0.2s ease-in-out;
459
+ &[open] {
460
+ --_icon-transform: scaleY(-1);
352
461
 
353
- .main-navigation-link {
354
- display: flex;
355
- text-wrap-mode: nowrap;
356
- color: inherit;
357
- text-decoration: none;
358
- margin-inline-start: 0;
359
- transition: var(--_link-visibility-transition);
462
+ .main-navigation-details-summary {
463
+ border-bottom-color: var(--_link-border-bottom-hover);
464
+ }
360
465
  }
361
466
 
362
- .main-navigation-details {
363
-
364
- --_icon-transform: scaleY(1);
365
-
366
- margin-inline-start: 0;
367
- transition: var(--_link-visibility-transition);
467
+ .has-toggle-icon {
468
+ display: flex;
469
+ gap: 6px;
470
+ text-wrap-mode: nowrap;
368
471
 
369
- &[open] {
370
- --_icon-transform: scaleY(-1);
472
+ .icon {
473
+ display: block;
474
+ transform: var(--_icon-transform);
475
+ transition: transform 0.2s ease-in-out;
371
476
  }
477
+ }
372
478
 
373
- .has-toggle-icon {
374
- display: flex;
375
- gap: 6px;
376
- text-wrap-mode: nowrap;
479
+ .main-navigation-details-summary {
480
+ padding-block: var(--_link-padding-block);
481
+ padding-inline: var(--_link-padding-inline);
482
+ margin-block: var(--_link-margin-block);
483
+ margin-inline: var(--_link-margin-inline);
484
+ border-bottom: var(--_link-border-default);
377
485
 
378
- .icon {
379
- display: block;
380
- transform: var(--_icon-transform);
381
- transition: transform 0.2s ease-in-out;
382
- }
486
+ &::-webkit-details-marker,
487
+ &::marker {
488
+ display: none;
383
489
  }
384
490
 
385
- .main-navigation-details-summary {
386
-
387
- &::-webkit-details-marker,
388
- &::marker {
389
- display: none;
390
- }
391
-
392
- &:hover {
393
- cursor: pointer;
394
- }
395
-
491
+ &:hover {
492
+ cursor: pointer;
493
+ border-bottom-color: var(--_link-border-bottom-hover);
396
494
  }
397
495
 
398
- .main-navigation-sub-nav {
399
- position: absolute;
400
- padding: 12px;
401
- border: 1px solid #efefef75;
402
- border-radius: 8px;
403
- background-color: #000;
404
- translate: 0 12px;
496
+ .decorator-icon {
497
+ margin-inline-start: 8px;
498
+ }
499
+ }
405
500
 
406
- min-width: var(--_main-navigation-item-width);
501
+ .main-navigation-sub-nav {
502
+ position: absolute;
503
+ padding: 12px;
504
+ border: 1px solid #efefef75;
505
+ border-radius: 8px;
506
+ background-color: #000;
507
+ translate: 0 12px;
407
508
 
408
- .main-navigation-sub-nav-list {
509
+ min-width: var(--_main-navigation-item-width);
409
510
 
410
- display: grid;
411
- grid-template-columns: repeat(2, auto);
412
- gap: 12px;
511
+ .main-navigation-sub-nav-list {
512
+ display: grid;
513
+ grid-template-columns: repeat(2, auto);
514
+ gap: 12px;
413
515
 
414
- .main-navigation-sub-nav-item {
415
- margin-bottom: 8px;
516
+ .main-navigation-sub-nav-item {
517
+ margin-bottom: 8px;
416
518
 
417
- &:last-child {
418
- margin-bottom: 0;
419
- }
519
+ &:last-child {
520
+ margin-bottom: 0;
521
+ }
420
522
 
421
- .main-navigation-sub-nav-link {
422
- display: block;
423
- text-wrap-mode: nowrap;
424
- text-decoration: none;
425
- color: inherit;
426
- }
523
+ .main-navigation-sub-nav-link {
524
+ display: block;
525
+ text-wrap-mode: nowrap;
526
+ text-decoration: none;
527
+ color: inherit;
427
528
  }
428
529
  }
429
530
  }
430
531
  }
532
+ }
431
533
 
432
- &.visually-hidden {
433
- visibility: hidden;
434
- opacity: 0;
534
+ &.visually-hidden {
535
+ visibility: hidden;
536
+ opacity: 0;
435
537
 
436
- .main-navigation-details,
437
- .main-navigation-link {
438
- margin-inline-start: var(--_main-navigation-item-width);
439
- }
538
+ .main-navigation-details,
539
+ .main-navigation-link {
540
+ margin-inline-start: var(--_main-navigation-item-width);
440
541
  }
441
542
  }
442
543
  }
443
544
  }
545
+ }
444
546
 
445
- .secondary-navigation {
446
- grid-area: navStack;
447
- justify-self: end;
448
-
449
- display: flex;
450
- gap: 12px;
451
- align-items: center;
452
-
453
- .secondary-navigation-list {
547
+ .secondary-navigation {
548
+ grid-area: navStack;
549
+ justify-self: end;
454
550
 
455
- .secondary-navigation-item {
551
+ display: flex;
552
+ gap: 12px;
553
+ align-items: center;
456
554
 
457
- .secondary-navigation-link {
458
- display: flex;
459
- align-items: center;
460
- font: inherit;
461
- color: inherit;
555
+ .secondary-navigation-list {
556
+ .secondary-navigation-item {
557
+ .secondary-navigation-link {
558
+ display: flex;
559
+ align-items: center;
560
+ font: inherit;
561
+ color: inherit;
462
562
 
463
- .icon {
464
- height: 1.35em;
465
- width: 1.35em;
466
- }
563
+ .icon {
564
+ height: 1.35em;
565
+ width: 1.35em;
467
566
  }
468
567
  }
469
568
  }
569
+ }
470
570
 
471
- .main-navigation-link {
472
- .icon {
473
- height: 1.35em;
474
- width: 1.35em;
475
- }
571
+ .main-navigation-link {
572
+ .icon {
573
+ height: 1.35em;
574
+ width: 1.35em;
476
575
  }
576
+ }
477
577
 
478
- .overflow-details {
479
- list-style: none;
480
- padding: 0;
481
- margin: 0;
482
- position: relative;
483
- cursor: pointer;
484
- width: fit-content;
578
+ .overflow-details {
579
+ list-style: none;
580
+ padding: 0;
581
+ margin: 0;
582
+ position: relative;
583
+ cursor: pointer;
584
+ width: fit-content;
485
585
 
486
- transition: all 0.2s ease-in-out;
586
+ transition: all 0.2s ease-in-out;
487
587
 
488
- &.visually-hidden {
489
- opacity: 0;
490
- visibility: hidden;
491
- width: 0;
588
+ &.visually-hidden {
589
+ opacity: 0;
590
+ visibility: hidden;
591
+ width: 0;
592
+ }
593
+
594
+ .overflow-details-summary {
595
+ --_icon-zoom: 1;
596
+ --_icon-size: 20px;
597
+ --_border-width: 1px;
598
+ --_outline-width: 1px;
599
+ --_transition-duration: 0.2s;
600
+
601
+ display: grid;
602
+ grid-template-areas: 'icon';
603
+ align-items: center;
604
+ justify-content: center;
605
+ padding-inline: 5px;
606
+ text-wrap: nowrap;
607
+
608
+ aspect-ratio: 1;
609
+ border-radius: 4px;
610
+ border: var(--_border-width) solid #ffffff90;
611
+ outline: var(--_outline-width) solid #ffffff10;
612
+ background-color: Canvas;
613
+
614
+ width: var(--_icon-size);
615
+ height: var(--_icon-size);
616
+ overflow: hidden;
617
+ transition-property: all;
618
+ transition-timing-function: linear;
619
+ transition-duration: var(--_transition-duration);
620
+
621
+ &::-webkit-details-marker,
622
+ &::marker {
623
+ display: none;
492
624
  }
493
625
 
494
- .overflow-details-summary {
495
- --_icon-zoom: 1;
496
- --_icon-size: 20px;
497
- --_border-width: 1px;
498
- --_outline-width: 1px;
499
- --_transition-duration: 0.2s;
626
+ &:hover,
627
+ &:focus-visible {
628
+ --_icon-zoom: 1.2;
629
+ outline: var(--_outline-width) solid #ffffff;
630
+ }
500
631
 
501
- display: grid;
502
- grid-template-areas: 'icon';
503
- align-items: center;
504
- justify-content: center;
505
- padding-inline: 5px;
506
- text-wrap: nowrap;
507
-
508
- aspect-ratio: 1;
509
- border-radius: 4px;
510
- border: var(--_border-width) solid #ffffff90;
511
- outline: var(--_outline-width) solid #ffffff10;
512
- background-color: Canvas;
513
-
514
- width: var(--_icon-size);
515
- height: var(--_icon-size);
516
- overflow: hidden;
517
- transition-property: all;
518
- transition-timing-function: linear;
519
- transition-duration: var(--_transition-duration);
520
-
521
- &::-webkit-details-marker,
522
- &::marker {
523
- display: none;
524
- }
632
+ .icon {
633
+ grid-area: icon;
634
+ scale: var(--_icon-zoom);
635
+ transition: scale 0.2s ease-in-out;
636
+ width: calc(var(--_icon-size) - var(--_border-width) * 2 - var(--_outline-width) * 2);
637
+ height: calc(var(--_icon-size) - var(--_border-width) * 2 - var(--_outline-width) * 2);
525
638
 
526
- &:hover {
527
- --_icon-zoom: 1.2;
528
- outline: var(--_outline-width) solid #ffffff;
529
- }
639
+ opacity: 0;
640
+ transition-property: opacity, transform; /* For reference */
641
+ transition-timing-function: linear; /* For reference */
642
+ transition-duration: var(--_transition-duration); /* For reference */
530
643
 
531
- .icon {
532
- grid-area: icon;
533
- scale: var(--_icon-zoom);
534
- transition: scale 0.2s ease-in-out;
535
- width: calc(var(--_icon-size) - var(--_border-width) * 2 - var(--_outline-width) * 2);
536
- height: calc(var(--_icon-size) - var(--_border-width) * 2 - var(--_outline-width) * 2);
537
-
538
- opacity: 0;
539
- transition-property: opacity, transform; /* For reference */
540
- transition-timing-function: linear; /* For reference */
541
- transition-duration: var(--_transition-duration); /* For reference */
542
-
543
- &.show {
544
- opacity: 1;
545
- }
644
+ &.show {
645
+ opacity: 1;
546
646
  }
547
647
  }
648
+ }
548
649
 
650
+ .overflow-details-nav {
651
+ position: absolute;
652
+ top: 135%;
653
+ right: 0;
654
+ background-color: #000;
655
+ border: 1px solid #ffffff90;
656
+ border-radius: 8px;
657
+ padding: 12px;
658
+ margin: 0;
659
+ z-index: 999;
660
+ min-width: var(--_overflow-drop-down-width, fit-content);
549
661
 
550
- .overflow-details-nav {
551
- position: absolute;
552
- top: 135%;
553
- right: 0;
554
- background-color: #000;
555
- border: 1px solid #ffffff90;
556
- border-radius: 8px;
557
- padding: 12px;
558
- margin: 0;
559
- z-index: 999;
560
- min-width: var(--_overflow-drop-down-width, fit-content);
561
-
562
- display: grid;
563
- grid-auto-flow: row;
564
- gap: 8px;
565
- }
662
+ display: grid;
663
+ grid-auto-flow: row;
664
+ gap: 8px;
566
665
  }
567
666
  }
568
667
  }
668
+ }
569
669
 
570
- .debug-grid {
571
- display: none;
670
+ .debug-grid {
671
+ display: none;
572
672
 
573
- .layout-row-inner > div {
574
- display: flex;
575
- flex-wrap: wrap;
576
- gap: 12px;
673
+ .layout-row-inner > div {
674
+ display: flex;
675
+ flex-wrap: wrap;
676
+ gap: 12px;
577
677
 
578
- margin-inline: 12px;
678
+ margin-inline: 12px;
579
679
 
580
- > div {
581
- outline: 1px solid gray;
582
- padding: 12px;
583
- }
680
+ > div {
681
+ outline: 1px solid gray;
682
+ padding: 12px;
584
683
  }
585
684
  }
685
+ }
586
686
  </style>