srcdev-nuxt-components 2.5.0 → 2.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/deep-expanding-menu/DeepExpandingMenu.vue +3 -3
- package/components/deep-expanding-menu/DeepExpandingMenuOld.vue +3 -3
- package/components/responsive-header/NavigationItems.vue +7 -35
- package/components/responsive-header/ResponsiveHeader.vue +249 -307
- package/package.json +1 -1
- package/types/responsiveHeader.ts +38 -0
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
<script lang="ts">
|
|
28
28
|
const TAGS_ALLOWED = <string[]>['div', 'section', 'nav', 'ul', 'ol'];
|
|
29
29
|
|
|
30
|
-
interface
|
|
30
|
+
interface ResponsiveHeaderNavItem {
|
|
31
31
|
name: string;
|
|
32
32
|
path?: string;
|
|
33
33
|
isExternal?: boolean;
|
|
34
|
-
childLinks?:
|
|
34
|
+
childLinks?: ResponsiveHeaderNavItem[];
|
|
35
35
|
childLinksTitle?: string;
|
|
36
36
|
}
|
|
37
37
|
</script>
|
|
@@ -46,7 +46,7 @@ const props = defineProps({
|
|
|
46
46
|
},
|
|
47
47
|
},
|
|
48
48
|
navLinks: {
|
|
49
|
-
type: Array as PropType<
|
|
49
|
+
type: Array as PropType<ResponsiveHeaderNavItem[]>,
|
|
50
50
|
default: () => [],
|
|
51
51
|
},
|
|
52
52
|
styleClassPassthrough: {
|
|
@@ -34,7 +34,7 @@ const props = defineProps({
|
|
|
34
34
|
},
|
|
35
35
|
},
|
|
36
36
|
navLinks: {
|
|
37
|
-
type: Array as PropType<
|
|
37
|
+
type: Array as PropType<ResponsiveHeaderNavItem[]>,
|
|
38
38
|
default: () => [],
|
|
39
39
|
},
|
|
40
40
|
styleClassPassthrough: {
|
|
@@ -66,12 +66,12 @@ onMounted(() => {
|
|
|
66
66
|
<script lang="ts">
|
|
67
67
|
const TAGS_ALLOWED = <string[]>['div', 'section', 'nav', 'ul', 'ol'];
|
|
68
68
|
|
|
69
|
-
interface
|
|
69
|
+
interface ResponsiveHeaderNavItem {
|
|
70
70
|
name: string;
|
|
71
71
|
path?: string;
|
|
72
72
|
isExternal?: boolean;
|
|
73
73
|
childLinksTitle?: string;
|
|
74
|
-
childLinks?:
|
|
74
|
+
childLinks?: ResponsiveHeaderNavItem[];
|
|
75
75
|
}
|
|
76
76
|
</script>
|
|
77
77
|
|
|
@@ -49,37 +49,12 @@
|
|
|
49
49
|
</div>
|
|
50
50
|
</template>
|
|
51
51
|
|
|
52
|
-
<script lang="ts">
|
|
53
|
-
interface NavLinkConfig {
|
|
54
|
-
left: number;
|
|
55
|
-
right: number;
|
|
56
|
-
width?: number;
|
|
57
|
-
visible: boolean;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
interface INavLink {
|
|
61
|
-
name: string;
|
|
62
|
-
path?: string;
|
|
63
|
-
isExternal?: boolean;
|
|
64
|
-
childLinksTitle?: string;
|
|
65
|
-
childLinks?: INavLink[];
|
|
66
|
-
config?: NavLinkConfig;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
interface IResponsiveNavLinks {
|
|
70
|
-
[key: string]: INavLink[];
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
interface INavigationRefTrackState {
|
|
74
|
-
navListVisibility: Record<string, boolean>;
|
|
75
|
-
clonedNavLinks?: IResponsiveNavLinks;
|
|
76
|
-
}
|
|
77
|
-
</script>
|
|
78
|
-
|
|
79
52
|
<script setup lang="ts">
|
|
53
|
+
import type { ResponsiveHeaderState } from '@/types/responsiveHeader';
|
|
54
|
+
|
|
80
55
|
const props = defineProps({
|
|
81
56
|
mainNavigationState: {
|
|
82
|
-
type: Object as PropType<
|
|
57
|
+
type: Object as PropType<ResponsiveHeaderState>,
|
|
83
58
|
default: () => [],
|
|
84
59
|
},
|
|
85
60
|
styleClassPassthrough: {
|
|
@@ -89,6 +64,7 @@ const props = defineProps({
|
|
|
89
64
|
});
|
|
90
65
|
|
|
91
66
|
const detailsAanimationDuration = 200;
|
|
67
|
+
const detailsAanimationDurationString = `${detailsAanimationDuration}ms`;
|
|
92
68
|
|
|
93
69
|
const widestNavLinkWidthInMainNavigationState = computed(() => {
|
|
94
70
|
return Object.values(props.mainNavigationState.clonedNavLinks || {}).reduce((maxWidth, group) => {
|
|
@@ -156,9 +132,7 @@ watch(
|
|
|
156
132
|
text-wrap: nowrap;
|
|
157
133
|
}
|
|
158
134
|
}
|
|
159
|
-
.icon {
|
|
160
|
-
|
|
161
|
-
}
|
|
135
|
+
/* .icon {} */
|
|
162
136
|
}
|
|
163
137
|
.display-details-content {
|
|
164
138
|
.overflow-navigation-sub-nav-inner {
|
|
@@ -168,7 +142,7 @@ watch(
|
|
|
168
142
|
flex-direction: column;
|
|
169
143
|
gap: 12px;
|
|
170
144
|
margin-block-start: var(--_overflow-navigation-sub-nav-list-margin-block-start);
|
|
171
|
-
transition: margin-block-start v-bind(
|
|
145
|
+
transition: margin-block-start v-bind(detailsAanimationDurationString) ease;
|
|
172
146
|
|
|
173
147
|
.overflow-navigation-sub-nav-item {
|
|
174
148
|
|
|
@@ -176,9 +150,7 @@ watch(
|
|
|
176
150
|
text-decoration: none;
|
|
177
151
|
color: inherit;
|
|
178
152
|
|
|
179
|
-
.overflow-navigation-sub-nav-text {
|
|
180
|
-
|
|
181
|
-
}
|
|
153
|
+
/* .overflow-navigation-sub-nav-text {} */
|
|
182
154
|
}
|
|
183
155
|
}
|
|
184
156
|
}
|
|
@@ -1,78 +1,61 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
<
|
|
8
|
-
v-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
<Icon name="gravity-ui:ellipsis" class="icon" />
|
|
60
|
-
</summary>
|
|
61
|
-
<div class="overflow-details-nav">
|
|
62
|
-
<NavigationItems
|
|
63
|
-
:main-navigation-state="mainNavigationState"
|
|
64
|
-
/>
|
|
65
|
-
</div>
|
|
66
|
-
</details>
|
|
67
|
-
<NuxtLink class="main-navigation-link" to="/"><Icon name="material-symbols:settings-outline-rounded" class="icon" /></NuxtLink>
|
|
68
|
-
</nav>
|
|
69
|
-
</div>
|
|
70
|
-
</header>
|
|
71
|
-
<LayoutRow
|
|
72
|
-
tag="div"
|
|
73
|
-
variant="full"
|
|
74
|
-
:style-class-passthrough="['mb-20', 'debug-grid']"
|
|
75
|
-
>
|
|
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)">
|
|
7
|
+
<template v-for="(link, localIndex) in navGroup" :key="localIndex">
|
|
8
|
+
<li v-if="link.path" class="main-navigation-item"
|
|
9
|
+
:class="{ 'visually-hidden': !mainNavigationState.clonedNavLinks?.[groupKey]?.[localIndex]?.config?.visible }"
|
|
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>
|
|
13
|
+
</li>
|
|
14
|
+
<li v-else class="main-navigation-item"
|
|
15
|
+
:class="{ 'visually-hidden': !mainNavigationState.clonedNavLinks?.[groupKey]?.[localIndex]?.config?.visible }"
|
|
16
|
+
:style="{ '--_main-navigation-item-width': mainNavigationState.clonedNavLinks?.[groupKey]?.[localIndex]?.config?.width + 'px' }"
|
|
17
|
+
ref="mainNavigationItems" :data-group-key="groupKey" :data-local-index="localIndex">
|
|
18
|
+
<details class="main-navigation-details" name="navigation-group" ref="navigationDetails">
|
|
19
|
+
<summary @mouseover="handleSummaryHover($event)" @focusin="handleSummaryHover($event)"
|
|
20
|
+
class="main-navigation-details-summary has-toggle-icon">
|
|
21
|
+
<Icon name="mdi:chevron-down" class="icon" />
|
|
22
|
+
{{ link.childLinksTitle }}
|
|
23
|
+
</summary>
|
|
24
|
+
<div class="main-navigation-sub-nav">
|
|
25
|
+
<ul class="main-navigation-sub-nav-list">
|
|
26
|
+
<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>
|
|
28
|
+
</li>
|
|
29
|
+
</ul>
|
|
30
|
+
</div>
|
|
31
|
+
</details>
|
|
32
|
+
</li>
|
|
33
|
+
</template>
|
|
34
|
+
</ul>
|
|
35
|
+
|
|
36
|
+
</nav>
|
|
37
|
+
<nav class="secondary-navigation" ref="secondaryNav">
|
|
38
|
+
<details class="overflow-details" :class="[{ 'visually-hidden': !navLoaded || !showOverflowDetails }]"
|
|
39
|
+
ref="overflowDetails" name="overflow-group">
|
|
40
|
+
<summary class="overflow-details-summary has-toggle-icon">
|
|
41
|
+
<Icon name="gravity-ui:ellipsis" class="icon" />
|
|
42
|
+
</summary>
|
|
43
|
+
<div class="overflow-details-nav">
|
|
44
|
+
<NavigationItems :main-navigation-state="mainNavigationState" />
|
|
45
|
+
</div>
|
|
46
|
+
</details>
|
|
47
|
+
<ul class="secondary-navigation-list">
|
|
48
|
+
<li class="secondary-navigation-item">
|
|
49
|
+
<NuxtLink class="secondary-navigation-link" to="/">
|
|
50
|
+
<Icon name="material-symbols:settings-outline-rounded" class="icon" />
|
|
51
|
+
</NuxtLink>
|
|
52
|
+
</li>
|
|
53
|
+
</ul>
|
|
54
|
+
</nav>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
<LayoutRow tag="div" variant="full" :style-class-passthrough="['mb-20', 'debug-grid']">
|
|
76
59
|
<ClientOnly>
|
|
77
60
|
<div>
|
|
78
61
|
<h2 class="heading-4">navigationWrapperRects</h2>
|
|
@@ -90,51 +73,13 @@
|
|
|
90
73
|
</LayoutRow>
|
|
91
74
|
</template>
|
|
92
75
|
|
|
93
|
-
<script lang="ts">
|
|
94
|
-
|
|
95
|
-
interface INavLink {
|
|
96
|
-
name: string;
|
|
97
|
-
path?: string;
|
|
98
|
-
isExternal?: boolean;
|
|
99
|
-
childLinksTitle?: string;
|
|
100
|
-
childLinks?: INavLink[];
|
|
101
|
-
config?: NavLinkConfig;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
interface IResponsiveNavLinks {
|
|
105
|
-
[key: string]: INavLink[];
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
interface IFlooredRect {
|
|
109
|
-
left: number;
|
|
110
|
-
right: number;
|
|
111
|
-
top: number;
|
|
112
|
-
bottom: number;
|
|
113
|
-
width: number;
|
|
114
|
-
height: number;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
interface NavLinkConfig {
|
|
118
|
-
left: number;
|
|
119
|
-
right: number;
|
|
120
|
-
width?: number;
|
|
121
|
-
visible: boolean;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
interface INavigationRefTrackState {
|
|
125
|
-
navListVisibility: Record<string, boolean>;
|
|
126
|
-
clonedNavLinks?: IResponsiveNavLinks;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
</script>
|
|
131
|
-
|
|
132
76
|
<script setup lang="ts">
|
|
133
77
|
import { useResizeObserver, onClickOutside } from '@vueuse/core';
|
|
78
|
+
import type { ResponsiveHeaderProp, ResponsiveHeaderState, IFlooredRect } from '@/types/responsiveHeader';
|
|
134
79
|
|
|
135
80
|
const props = defineProps({
|
|
136
81
|
responsiveNavLinks: {
|
|
137
|
-
type: Object as PropType<
|
|
82
|
+
type: Object as PropType<ResponsiveHeaderProp>,
|
|
138
83
|
default: () => [],
|
|
139
84
|
},
|
|
140
85
|
gapBetweenFirstAndSecondNav: {
|
|
@@ -147,7 +92,6 @@ const props = defineProps({
|
|
|
147
92
|
},
|
|
148
93
|
});
|
|
149
94
|
|
|
150
|
-
|
|
151
95
|
const navLoaded = ref(false);
|
|
152
96
|
const navigationWrapperRef = useTemplateRef('navigationWrapper');
|
|
153
97
|
|
|
@@ -162,7 +106,7 @@ const handleSummaryHover = (event: MouseEvent | FocusEvent) => {
|
|
|
162
106
|
}
|
|
163
107
|
};
|
|
164
108
|
|
|
165
|
-
const mainNavigationState = ref<
|
|
109
|
+
const mainNavigationState = ref<ResponsiveHeaderState>({
|
|
166
110
|
navListVisibility: {
|
|
167
111
|
firstNav: false,
|
|
168
112
|
secondNav: false,
|
|
@@ -198,7 +142,11 @@ const showOverflowDetails = computed(() => {
|
|
|
198
142
|
});
|
|
199
143
|
|
|
200
144
|
const mainNavigationMarginBlockEnd = computed(() => {
|
|
201
|
-
|
|
145
|
+
return secondaryNavRects.value ? secondaryNavRects.value.width + props.gapBetweenFirstAndSecondNav : 0;
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const mainNavigationMarginBlockEndStr = computed(() => {
|
|
149
|
+
return mainNavigationMarginBlockEnd.value + 'px';
|
|
202
150
|
});
|
|
203
151
|
|
|
204
152
|
const initTemplateRefs = async () => {
|
|
@@ -303,21 +251,8 @@ watch(
|
|
|
303
251
|
</script>
|
|
304
252
|
|
|
305
253
|
<style lang="css">
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
grid-template-columns: auto 1fr;
|
|
309
|
-
gap: 24px;
|
|
310
|
-
align-items: center;
|
|
311
|
-
padding-block: 12px;
|
|
312
|
-
padding-inline: 24px;
|
|
313
|
-
|
|
314
|
-
/* Make sure always on top of page content */
|
|
315
|
-
position: relative;
|
|
316
|
-
z-index: 999999;
|
|
317
|
-
|
|
318
|
-
h1 {
|
|
319
|
-
text-wrap-mode: nowrap;
|
|
320
|
-
}
|
|
254
|
+
|
|
255
|
+
.navigation {
|
|
321
256
|
|
|
322
257
|
ul,
|
|
323
258
|
ol {
|
|
@@ -333,241 +268,248 @@ watch(
|
|
|
333
268
|
}
|
|
334
269
|
}
|
|
335
270
|
|
|
336
|
-
|
|
337
|
-
--_icon-transform: scaleY(1);
|
|
338
|
-
|
|
339
|
-
&[open] {
|
|
340
|
-
--_icon-transform: scaleY(-1);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
.has-toggle-icon {
|
|
344
|
-
display: flex;
|
|
345
|
-
gap: 6px;
|
|
346
|
-
text-wrap-mode: nowrap;
|
|
271
|
+
--_link-visibility-transition: none;
|
|
347
272
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
transform: var(--_icon-transform);
|
|
351
|
-
transition: transform 0.2s ease-in-out;
|
|
352
|
-
}
|
|
353
|
-
}
|
|
273
|
+
&.loaded {
|
|
274
|
+
--_link-visibility-transition: all 0.2s ease-in-out;
|
|
354
275
|
}
|
|
355
276
|
|
|
356
|
-
|
|
357
|
-
|
|
277
|
+
display: grid;
|
|
278
|
+
grid-template-areas: 'navStack';
|
|
358
279
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
280
|
+
margin: 12px;
|
|
281
|
+
border-radius: 8px;
|
|
282
|
+
background-color: #efefef05;
|
|
283
|
+
border: 1px solid #efefef75;
|
|
284
|
+
padding: 12px;
|
|
362
285
|
|
|
286
|
+
.main-navigation {
|
|
287
|
+
grid-area: navStack;
|
|
288
|
+
display: flex;
|
|
289
|
+
flex-wrap: nowrap;
|
|
290
|
+
flex-grow: 1;
|
|
291
|
+
justify-content: space-between;
|
|
292
|
+
gap: 60px;
|
|
363
293
|
|
|
364
|
-
|
|
365
|
-
|
|
294
|
+
overflow-x: hidden;
|
|
295
|
+
margin-inline-end: v-bind(mainNavigationMarginBlockEndStr);
|
|
366
296
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
border: 1px solid #efefef75;
|
|
371
|
-
padding: 12px;
|
|
297
|
+
&.collapsed {
|
|
298
|
+
justify-content: flex-start;
|
|
299
|
+
}
|
|
372
300
|
|
|
373
|
-
|
|
374
|
-
* .main-navigation-link & .main-navigation-details placed here they can also exist within
|
|
375
|
-
*/
|
|
376
|
-
.main-navigation-link {
|
|
301
|
+
.main-navigation-list {
|
|
377
302
|
display: flex;
|
|
378
|
-
|
|
379
|
-
color: inherit;
|
|
380
|
-
text-decoration: none;
|
|
381
|
-
}
|
|
303
|
+
flex-wrap: nowrap;
|
|
382
304
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
list-style: none;
|
|
305
|
+
&:nth-of-type(1) {
|
|
306
|
+
gap: 30px;
|
|
386
307
|
}
|
|
387
308
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
display: none;
|
|
309
|
+
&:nth-of-type(2) {
|
|
310
|
+
gap: 30px;
|
|
391
311
|
}
|
|
392
312
|
|
|
393
|
-
|
|
394
|
-
cursor: pointer;
|
|
395
|
-
}
|
|
313
|
+
.main-navigation-item {
|
|
396
314
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
background-color: #000;
|
|
403
|
-
translate: 0 12px;
|
|
315
|
+
width: var(--_main-navigation-item-width);
|
|
316
|
+
overflow: hidden;
|
|
317
|
+
transition:
|
|
318
|
+
opacity 0.2s ease-in-out,
|
|
319
|
+
visibility 0.2s ease-in-out;
|
|
404
320
|
|
|
405
|
-
|
|
321
|
+
.main-navigation-link {
|
|
322
|
+
display: flex;
|
|
323
|
+
text-wrap-mode: nowrap;
|
|
324
|
+
color: inherit;
|
|
325
|
+
text-decoration: none;
|
|
326
|
+
margin-inline-start: 0;
|
|
327
|
+
transition: var(--_link-visibility-transition);
|
|
328
|
+
}
|
|
406
329
|
|
|
407
|
-
.main-navigation-
|
|
330
|
+
.main-navigation-details {
|
|
408
331
|
|
|
409
|
-
|
|
410
|
-
grid-template-columns: repeat(2, auto);
|
|
411
|
-
gap: 12px;
|
|
332
|
+
--_icon-transform: scaleY(1);
|
|
412
333
|
|
|
413
|
-
|
|
414
|
-
|
|
334
|
+
margin-inline-start: 0;
|
|
335
|
+
transition: var(--_link-visibility-transition);
|
|
415
336
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
337
|
+
&[open] {
|
|
338
|
+
--_icon-transform: scaleY(-1);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.has-toggle-icon {
|
|
342
|
+
display: flex;
|
|
343
|
+
gap: 6px;
|
|
344
|
+
text-wrap-mode: nowrap;
|
|
419
345
|
|
|
420
|
-
.
|
|
346
|
+
.icon {
|
|
421
347
|
display: block;
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
color: inherit;
|
|
348
|
+
transform: var(--_icon-transform);
|
|
349
|
+
transition: transform 0.2s ease-in-out;
|
|
425
350
|
}
|
|
426
351
|
}
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
352
|
|
|
431
|
-
|
|
432
|
-
grid-area: navStack;
|
|
433
|
-
display: flex;
|
|
434
|
-
flex-wrap: nowrap;
|
|
435
|
-
flex-grow: 1;
|
|
436
|
-
justify-content: space-between;
|
|
437
|
-
gap: 60px;
|
|
353
|
+
.main-navigation-details-summary {
|
|
438
354
|
|
|
439
|
-
|
|
440
|
-
|
|
355
|
+
&::-webkit-details-marker,
|
|
356
|
+
&::marker {
|
|
357
|
+
display: none;
|
|
358
|
+
}
|
|
441
359
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
360
|
+
&:hover {
|
|
361
|
+
cursor: pointer;
|
|
362
|
+
}
|
|
445
363
|
|
|
446
|
-
|
|
447
|
-
display: flex;
|
|
448
|
-
flex-wrap: nowrap;
|
|
364
|
+
}
|
|
449
365
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
366
|
+
.main-navigation-sub-nav {
|
|
367
|
+
position: absolute;
|
|
368
|
+
padding: 12px;
|
|
369
|
+
border: 1px solid #efefef75;
|
|
370
|
+
border-radius: 8px;
|
|
371
|
+
background-color: #000;
|
|
372
|
+
translate: 0 12px;
|
|
453
373
|
|
|
454
|
-
|
|
455
|
-
gap: 30px;
|
|
456
|
-
}
|
|
374
|
+
min-width: var(--_main-navigation-item-width);
|
|
457
375
|
|
|
458
|
-
|
|
459
|
-
width: var(--_main-navigation-item-width);
|
|
460
|
-
overflow: hidden;
|
|
461
|
-
transition:
|
|
462
|
-
opacity 0.2s ease-in-out,
|
|
463
|
-
visibility 0.2s ease-in-out;
|
|
376
|
+
.main-navigation-sub-nav-list {
|
|
464
377
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
transition: var(--_link-visibility-transition);
|
|
469
|
-
}
|
|
378
|
+
display: grid;
|
|
379
|
+
grid-template-columns: repeat(2, auto);
|
|
380
|
+
gap: 12px;
|
|
470
381
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
opacity: 0;
|
|
382
|
+
.main-navigation-sub-nav-item {
|
|
383
|
+
margin-bottom: 8px;
|
|
474
384
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
385
|
+
&:last-child {
|
|
386
|
+
margin-bottom: 0;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.main-navigation-sub-nav-link {
|
|
390
|
+
display: block;
|
|
391
|
+
text-wrap-mode: nowrap;
|
|
392
|
+
text-decoration: none;
|
|
393
|
+
color: inherit;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
478
396
|
}
|
|
479
397
|
}
|
|
480
398
|
}
|
|
399
|
+
|
|
400
|
+
&.visually-hidden {
|
|
401
|
+
visibility: hidden;
|
|
402
|
+
opacity: 0;
|
|
403
|
+
|
|
404
|
+
.main-navigation-details,
|
|
405
|
+
.main-navigation-link {
|
|
406
|
+
margin-inline-start: var(--_main-navigation-item-width);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
481
409
|
}
|
|
482
410
|
}
|
|
411
|
+
}
|
|
483
412
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
413
|
+
.secondary-navigation {
|
|
414
|
+
grid-area: navStack;
|
|
415
|
+
justify-self: end;
|
|
487
416
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
417
|
+
display: flex;
|
|
418
|
+
gap: 12px;
|
|
419
|
+
align-items: center;
|
|
491
420
|
|
|
492
|
-
|
|
493
|
-
/* display: none; */
|
|
421
|
+
.secondary-navigation-list {
|
|
494
422
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
423
|
+
.secondary-navigation-item {
|
|
424
|
+
|
|
425
|
+
.secondary-navigation-link {
|
|
426
|
+
display: flex;
|
|
427
|
+
align-items: center;
|
|
428
|
+
font: inherit;
|
|
429
|
+
color: inherit;
|
|
430
|
+
|
|
431
|
+
.icon {
|
|
432
|
+
height: 1.35em;
|
|
433
|
+
width: 1.35em;
|
|
434
|
+
}
|
|
498
435
|
}
|
|
499
436
|
}
|
|
437
|
+
}
|
|
500
438
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
width: fit-content;
|
|
508
|
-
/* overflow: hidden; */
|
|
509
|
-
|
|
510
|
-
transition: all 0.2s ease-in-out;
|
|
439
|
+
.main-navigation-link {
|
|
440
|
+
.icon {
|
|
441
|
+
height: 1.35em;
|
|
442
|
+
width: 1.35em;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
511
445
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
446
|
+
.overflow-details {
|
|
447
|
+
list-style: none;
|
|
448
|
+
padding: 0;
|
|
449
|
+
margin: 0;
|
|
450
|
+
position: relative;
|
|
451
|
+
cursor: pointer;
|
|
452
|
+
width: fit-content;
|
|
517
453
|
|
|
518
|
-
|
|
519
|
-
--_icon-zoom: 1;
|
|
520
|
-
display: flex;
|
|
521
|
-
align-items: center;
|
|
522
|
-
justify-content: center;
|
|
523
|
-
padding-inline: 5px;
|
|
524
|
-
text-wrap: nowrap;
|
|
454
|
+
transition: all 0.2s ease-in-out;
|
|
525
455
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
456
|
+
&.visually-hidden {
|
|
457
|
+
opacity: 0;
|
|
458
|
+
visibility: hidden;
|
|
459
|
+
width: 0;
|
|
460
|
+
}
|
|
531
461
|
|
|
532
|
-
|
|
533
|
-
|
|
462
|
+
.overflow-details-summary {
|
|
463
|
+
--_icon-zoom: 1;
|
|
464
|
+
display: flex;
|
|
465
|
+
align-items: center;
|
|
466
|
+
justify-content: center;
|
|
467
|
+
padding-inline: 5px;
|
|
468
|
+
text-wrap: nowrap;
|
|
534
469
|
|
|
470
|
+
aspect-ratio: 1;
|
|
471
|
+
border-radius: 4px;
|
|
472
|
+
border: 1px solid #ffffff90;
|
|
473
|
+
outline: 1px solid #ffffff10;
|
|
474
|
+
background-color: Canvas;
|
|
535
475
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
display: none;
|
|
539
|
-
}
|
|
476
|
+
width: 28px;
|
|
477
|
+
overflow: hidden;
|
|
540
478
|
|
|
541
|
-
&:hover {
|
|
542
|
-
--_icon-zoom: 1.2;
|
|
543
|
-
outline: 1px solid #ffffff;
|
|
544
|
-
}
|
|
545
479
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
}
|
|
480
|
+
&::-webkit-details-marker,
|
|
481
|
+
&::marker {
|
|
482
|
+
display: none;
|
|
550
483
|
}
|
|
551
484
|
|
|
485
|
+
&:hover {
|
|
486
|
+
--_icon-zoom: 1.2;
|
|
487
|
+
outline: 1px solid #ffffff;
|
|
488
|
+
}
|
|
552
489
|
|
|
553
|
-
.
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
right: 0;
|
|
557
|
-
background-color: #000;
|
|
558
|
-
border: 1px solid #ffffff90;
|
|
559
|
-
border-radius: 8px;
|
|
560
|
-
padding: 12px;
|
|
561
|
-
margin: 0;
|
|
562
|
-
z-index: 999;
|
|
563
|
-
min-width: var(--_overflow-drop-down-width, fit-content);
|
|
564
|
-
|
|
565
|
-
display: grid;
|
|
566
|
-
grid-auto-flow: row;
|
|
567
|
-
gap: 8px;
|
|
490
|
+
.icon {
|
|
491
|
+
scale: var(--_icon-zoom);
|
|
492
|
+
transition: scale 0.2s ease-in-out;
|
|
568
493
|
}
|
|
569
494
|
}
|
|
570
495
|
|
|
496
|
+
|
|
497
|
+
.overflow-details-nav {
|
|
498
|
+
position: absolute;
|
|
499
|
+
top: 135%;
|
|
500
|
+
right: 0;
|
|
501
|
+
background-color: #000;
|
|
502
|
+
border: 1px solid #ffffff90;
|
|
503
|
+
border-radius: 8px;
|
|
504
|
+
padding: 12px;
|
|
505
|
+
margin: 0;
|
|
506
|
+
z-index: 999;
|
|
507
|
+
min-width: var(--_overflow-drop-down-width, fit-content);
|
|
508
|
+
|
|
509
|
+
display: grid;
|
|
510
|
+
grid-auto-flow: row;
|
|
511
|
+
gap: 8px;
|
|
512
|
+
}
|
|
571
513
|
}
|
|
572
514
|
}
|
|
573
515
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export interface ResponsiveHeaderNavItem {
|
|
2
|
+
name: string;
|
|
3
|
+
path?: string;
|
|
4
|
+
iconName?: string;
|
|
5
|
+
imageSrc?: string;
|
|
6
|
+
imageAlt?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
isActive?: boolean;
|
|
9
|
+
isExternal?: boolean;
|
|
10
|
+
childLinksTitle?: string;
|
|
11
|
+
childLinks?: ResponsiveHeaderNavItem[];
|
|
12
|
+
config?: ResponsiveHeaderItemRects;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ResponsiveHeaderProp {
|
|
16
|
+
[key: string]: ResponsiveHeaderNavItem[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface IFlooredRect {
|
|
20
|
+
left: number;
|
|
21
|
+
right: number;
|
|
22
|
+
top: number;
|
|
23
|
+
bottom: number;
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface ResponsiveHeaderItemRects {
|
|
29
|
+
left: number;
|
|
30
|
+
right: number;
|
|
31
|
+
width?: number;
|
|
32
|
+
visible: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface ResponsiveHeaderState {
|
|
36
|
+
navListVisibility: Record<string, boolean>;
|
|
37
|
+
clonedNavLinks?: ResponsiveHeaderProp;
|
|
38
|
+
}
|