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.
@@ -27,11 +27,11 @@
27
27
  <script lang="ts">
28
28
  const TAGS_ALLOWED = <string[]>['div', 'section', 'nav', 'ul', 'ol'];
29
29
 
30
- interface INavLink {
30
+ interface ResponsiveHeaderNavItem {
31
31
  name: string;
32
32
  path?: string;
33
33
  isExternal?: boolean;
34
- childLinks?: INavLink[];
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<INavLink[]>,
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<INavLink[]>,
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 INavLink {
69
+ interface ResponsiveHeaderNavItem {
70
70
  name: string;
71
71
  path?: string;
72
72
  isExternal?: boolean;
73
73
  childLinksTitle?: string;
74
- childLinks?: INavLink[];
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<INavigationRefTrackState>,
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(`${detailsAanimationDuration}ms`) ease;
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
- <header class="responsive-header" :class="[elementClasses]">
3
- <h1><a href="/">Logo</a></h1>
4
- <div class="navigation" :class="[{ loaded: navLoaded }]" ref="navigationWrapper">
5
- <nav class="main-navigation" ref="mainNav">
6
-
7
- <ul
8
- v-for="(navGroup, groupKey) in responsiveNavLinks"
9
- :key="groupKey"
10
- class="main-navigation-list"
11
- :ref="el => setNavRef(String(groupKey), el as HTMLUListElement | null)"
12
- >
13
- <template v-for="(link, localIndex) in navGroup" :key="localIndex">
14
- <li
15
- v-if="link.path"
16
- class="main-navigation-item"
17
- :class="{ 'visually-hidden': !mainNavigationState.clonedNavLinks?.[groupKey]?.[localIndex]?.config?.visible }"
18
- :style="{ '--_main-navigation-item-width': mainNavigationState.clonedNavLinks?.[groupKey]?.[localIndex]?.config?.width + 'px' }"
19
- ref="mainNavigationItems"
20
- :data-group-key="groupKey"
21
- :data-local-index="localIndex"
22
- >
23
- <NuxtLink class="main-navigation-link" :to="link.path">{{ link.name }}</NuxtLink>
24
- </li>
25
- <li
26
- v-else
27
- class="main-navigation-item"
28
- :class="{ 'visually-hidden': !mainNavigationState.clonedNavLinks?.[groupKey]?.[localIndex]?.config?.visible }"
29
- :style="{ '--_main-navigation-item-width': mainNavigationState.clonedNavLinks?.[groupKey]?.[localIndex]?.config?.width + 'px' }"
30
- ref="mainNavigationItems"
31
- :data-group-key="groupKey"
32
- :data-local-index="localIndex"
33
- >
34
- <details
35
- class="main-navigation-details"
36
- name="navigation-group"
37
- ref="navigationDetails"
38
- >
39
- <summary @mouseover="handleSummaryHover($event)" @focusin="handleSummaryHover($event)" class="main-navigation-link has-toggle-icon">
40
- <Icon name="mdi:chevron-down" class="icon" />
41
- {{ link.childLinksTitle }}
42
- </summary>
43
- <div class="main-navigation-sub-nav">
44
- <ul class="main-navigation-sub-nav-list">
45
- <li class="main-navigation-sub-nav-item" v-for="childLink in link.childLinks" :key="childLink.name">
46
- <NuxtLink :to="childLink.path" class="main-navigation-sub-nav-link">{{ childLink.name }}</NuxtLink>
47
- </li>
48
- </ul>
49
- </div>
50
- </details>
51
- </li>
52
- </template>
53
- </ul>
54
-
55
- </nav>
56
- <nav class="secondary-navigation" ref="secondaryNav">
57
- <details class="overflow-details" :class="[{ 'visually-hidden': !navLoaded || !showOverflowDetails }]" ref="overflowDetails" name="overflow-group">
58
- <summary class="overflow-details-summary has-toggle-icon">
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<IResponsiveNavLinks>,
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<INavigationRefTrackState>({
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
- return secondaryNavRects.value ? secondaryNavRects.value.width + props.gapBetweenFirstAndSecondNav : 0;
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
- .responsive-header {
307
- display: grid;
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
- details {
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
- .icon {
349
- display: block;
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
- .navigation {
357
- --_link-visibility-transition: none;
277
+ display: grid;
278
+ grid-template-areas: 'navStack';
358
279
 
359
- &.loaded {
360
- --_link-visibility-transition: all 0.2s ease-in-out;
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
- display: grid;
365
- grid-template-areas: 'navStack';
294
+ overflow-x: hidden;
295
+ margin-inline-end: v-bind(mainNavigationMarginBlockEndStr);
366
296
 
367
- margin: 12px;
368
- border-radius: 8px;
369
- background-color: #efefef05;
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
- text-wrap-mode: nowrap;
379
- color: inherit;
380
- text-decoration: none;
381
- }
303
+ flex-wrap: nowrap;
382
304
 
383
- .main-navigation-details {
384
- .main-navigation-link {
385
- list-style: none;
305
+ &:nth-of-type(1) {
306
+ gap: 30px;
386
307
  }
387
308
 
388
- summary::-webkit-details-marker,
389
- summary::marker {
390
- display: none;
309
+ &:nth-of-type(2) {
310
+ gap: 30px;
391
311
  }
392
312
 
393
- summary:hover {
394
- cursor: pointer;
395
- }
313
+ .main-navigation-item {
396
314
 
397
- .main-navigation-sub-nav {
398
- position: absolute;
399
- padding: 12px;
400
- border: 1px solid #efefef75;
401
- border-radius: 8px;
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
- min-width: var(--_main-navigation-item-width);
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-sub-nav-list {
330
+ .main-navigation-details {
408
331
 
409
- display: grid;
410
- grid-template-columns: repeat(2, auto);
411
- gap: 12px;
332
+ --_icon-transform: scaleY(1);
412
333
 
413
- .main-navigation-sub-nav-item {
414
- margin-bottom: 8px;
334
+ margin-inline-start: 0;
335
+ transition: var(--_link-visibility-transition);
415
336
 
416
- &:last-child {
417
- margin-bottom: 0;
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
- .main-navigation-sub-nav-link {
346
+ .icon {
421
347
  display: block;
422
- text-wrap-mode: nowrap;
423
- text-decoration: none;
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
- .main-navigation {
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
- overflow-x: hidden;
440
- margin-inline-end: v-bind(`${mainNavigationMarginBlockEnd}px`);
355
+ &::-webkit-details-marker,
356
+ &::marker {
357
+ display: none;
358
+ }
441
359
 
442
- &.collapsed {
443
- justify-content: flex-start;
444
- }
360
+ &:hover {
361
+ cursor: pointer;
362
+ }
445
363
 
446
- .main-navigation-list {
447
- display: flex;
448
- flex-wrap: nowrap;
364
+ }
449
365
 
450
- &:nth-of-type(1) {
451
- gap: 30px;
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
- &:nth-of-type(2) {
455
- gap: 30px;
456
- }
374
+ min-width: var(--_main-navigation-item-width);
457
375
 
458
- .main-navigation-item {
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
- .main-navigation-details,
466
- .main-navigation-link {
467
- margin-inline-start: 0;
468
- transition: var(--_link-visibility-transition);
469
- }
378
+ display: grid;
379
+ grid-template-columns: repeat(2, auto);
380
+ gap: 12px;
470
381
 
471
- &.visually-hidden {
472
- visibility: hidden;
473
- opacity: 0;
382
+ .main-navigation-sub-nav-item {
383
+ margin-bottom: 8px;
474
384
 
475
- .main-navigation-details,
476
- .main-navigation-link {
477
- margin-inline-start: var(--_main-navigation-item-width);
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
- .secondary-navigation {
485
- grid-area: navStack;
486
- justify-self: end;
413
+ .secondary-navigation {
414
+ grid-area: navStack;
415
+ justify-self: end;
487
416
 
488
- display: flex;
489
- gap: 12px;
490
- align-items: center;
417
+ display: flex;
418
+ gap: 12px;
419
+ align-items: center;
491
420
 
492
- > a {
493
- /* display: none; */
421
+ .secondary-navigation-list {
494
422
 
495
- .icon {
496
- height: 1.35em;
497
- width: 1.35em;
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
- .overflow-details {
502
- list-style: none;
503
- padding: 0;
504
- margin: 0;
505
- position: relative;
506
- cursor: pointer;
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
- &.visually-hidden {
513
- opacity: 0;
514
- visibility: hidden;
515
- /* width: 0; */
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
- .overflow-details-summary {
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
- aspect-ratio: 1;
527
- border-radius: 4px;
528
- border: 1px solid #ffffff90;
529
- outline: 1px solid #ffffff10;
530
- background-color: Canvas;
456
+ &.visually-hidden {
457
+ opacity: 0;
458
+ visibility: hidden;
459
+ width: 0;
460
+ }
531
461
 
532
- width: 28px;
533
- overflow: hidden;
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
- &::-webkit-details-marker,
537
- &::marker {
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
- .icon {
547
- scale: var(--_icon-zoom);
548
- transition: scale 0.2s ease-in-out;
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
- .overflow-details-nav {
554
- position: absolute;
555
- top: 135%;
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "srcdev-nuxt-components",
3
3
  "type": "module",
4
- "version": "2.5.0",
4
+ "version": "2.5.2",
5
5
  "main": "nuxt.config.ts",
6
6
  "scripts": {
7
7
  "clean": "rm -rf .nuxt && rm -rf .output && rm -rf .playground/.nuxt && rm -rf .playground/.output",
@@ -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
+ }