srcdev-nuxt-components 2.1.4 → 2.1.6

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.
@@ -0,0 +1,144 @@
1
+ @layer deep-expanding-menu-setup {
2
+ @position-try --anchor-left {
3
+ inset: auto;
4
+ top: calc(anchor(bottom) + 10px);
5
+ left: calc(anchor(left) + 10px);
6
+ }
7
+
8
+ @position-try-fallbacks --anchor-right {
9
+ inset: auto;
10
+ top: calc(anchor(bottom) + 10px);
11
+ right: calc(anchor(right) + 10px);
12
+ }
13
+
14
+ .deep-expanding-menu {
15
+ --_gap-between-top-level-items: 24px;
16
+
17
+ container-type: inline-size;
18
+ display: grid;
19
+ grid-template-areas: 'element-stack';
20
+
21
+ .inner {
22
+ grid-area: element-stack;
23
+ display: flex;
24
+ gap: var(--_gap-between-top-level-items);
25
+ align-items: center;
26
+
27
+ .navigation-link,
28
+ .navigation-group-toggle {
29
+ all: unset;
30
+ border-bottom: 2px solid transparent;
31
+ padding-block: 8px;
32
+
33
+ transition: border-color 200ms;
34
+
35
+ &:hover {
36
+ cursor: pointer;
37
+ border-color: light-dark(var(--blue-12), var(--gray-0));
38
+ }
39
+
40
+ &:focus {
41
+ border-color: light-dark(var(--blue-12), var(--gray-0));
42
+ }
43
+
44
+ &:focus-visible {
45
+ border-color: light-dark(var(--blue-12), var(--gray-0));
46
+ }
47
+ }
48
+
49
+ .navigation-group {
50
+ --_icon-transform: scaleY(1);
51
+ position: relative;
52
+
53
+ .navigation-group-toggle {
54
+ anchor-name: var(--_anchor-name);
55
+
56
+ display: flex;
57
+ align-items: center;
58
+ gap: 12px;
59
+
60
+ .icon {
61
+ display: block;
62
+ font-size: 1.2rem;
63
+
64
+ transform: var(--_icon-transform);
65
+ transition: transform 200ms;
66
+ }
67
+ }
68
+
69
+ .navigation-group-panel {
70
+ display: none;
71
+ position: absolute;
72
+ position-anchor: var(--_anchor-name);
73
+ margin: 0;
74
+ /* inset: auto; */
75
+ top: calc(anchor(bottom) + 10px);
76
+ left: calc(anchor(left) + 0px);
77
+
78
+ opacity: 0;
79
+ transition: opacity 200ms, display 200ms, overlay 200ms;
80
+ transition-behavior: allow-discrete;
81
+
82
+ width: min(100%, 50vw);
83
+
84
+ background-color: white;
85
+ border: 1px solid black;
86
+ border-radius: 12px;
87
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
88
+ padding: 12px;
89
+ overflow: clip;
90
+
91
+ &:popover-open {
92
+ display: block;
93
+ opacity: 1;
94
+
95
+ @starting-style {
96
+ display: block;
97
+ opacity: 0;
98
+ }
99
+ }
100
+
101
+ h4 {
102
+ color: var(--gray-12);
103
+ }
104
+
105
+ .navigation-group-list {
106
+ display: grid;
107
+ grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
108
+ gap: 12px;
109
+ padding-inline-start: 0;
110
+ margin-block-end: 8px;
111
+
112
+ .navigation-group-item {
113
+ display: block;
114
+
115
+ a.navigation-group-link {
116
+ display: inline-block;
117
+ color: var(--gray-12);
118
+ text-decoration: none;
119
+ padding-block: 8px;
120
+
121
+ border-bottom: 2px solid transparent;
122
+
123
+ transition: border-color 200ms;
124
+
125
+ &:hover {
126
+ cursor: pointer;
127
+ border-color: var(--gray-12);
128
+ }
129
+
130
+ &:focus-visible {
131
+ border-color: var(--gray-12);
132
+ }
133
+ }
134
+ }
135
+ }
136
+ }
137
+
138
+ &:has(.navigation-group-panel:popover-open) {
139
+ --_icon-transform: scaleY(-1);
140
+ }
141
+ }
142
+ }
143
+ }
144
+ }
@@ -0,0 +1 @@
1
+ @import './_scaffolding.css';
@@ -3,3 +3,4 @@
3
3
  @import './display-prompt-core';
4
4
  @import './_display-dialog-core';
5
5
  @import './_container-glow-core.css';
6
+ @import './deep-expanding-menu';
@@ -10,7 +10,7 @@
10
10
  <Icon name="bi:caret-down-fill" class="icon" />
11
11
  </button>
12
12
 
13
- <div class="navigation-group-panel" popover role="tooltip" :id="`popovertarget-nav-1-${key}`">
13
+ <div class="navigation-group-panel" popover role="menu" :id="`popovertarget-nav-1-${key}`">
14
14
  <h4 class="heading-4 mb-6">{{ link.childLinksTitle }}</h4>
15
15
  <ul class="navigation-group-list">
16
16
  <li class="navigation-group-item" v-for="childLink in link.childLinks" :key="childLink.name">
@@ -64,155 +64,4 @@ watch(
64
64
  resetElementClasses(props.styleClassPassthrough);
65
65
  }
66
66
  );
67
-
68
- // onMounted(() => {
69
- // console.log(detailsRef.value);
70
- // });
71
67
  </script>
72
-
73
- <style lang="css">
74
- @layer deep-expanding-menu-setup {
75
- @position-try --anchor-left {
76
- inset: auto;
77
- top: calc(anchor(bottom) + 10px);
78
- left: calc(anchor(left) + 10px);
79
- }
80
-
81
- @position-try-fallbacks --anchor-right {
82
- inset: auto;
83
- top: calc(anchor(bottom) + 10px);
84
- right: calc(anchor(right) + 10px);
85
- }
86
-
87
- .deep-expanding-menu {
88
- --_gap-between-top-level-items: 24px;
89
-
90
- container-type: inline-size;
91
- display: grid;
92
- grid-template-areas: 'element-stack';
93
-
94
- .inner {
95
- grid-area: element-stack;
96
- display: flex;
97
- gap: var(--_gap-between-top-level-items);
98
- align-items: center;
99
-
100
- .navigation-link,
101
- .navigation-group-toggle {
102
- all: unset;
103
- border-bottom: 2px solid transparent;
104
- padding-block: 8px;
105
-
106
- transition: border-color 200ms;
107
-
108
- &:hover {
109
- cursor: pointer;
110
- border-color: light-dark(var(--blue-12), var(--gray-0));
111
- }
112
-
113
- &:focus {
114
- border-color: light-dark(var(--blue-12), var(--gray-0));
115
- }
116
-
117
- &:focus-visible {
118
- border-color: light-dark(var(--blue-12), var(--gray-0));
119
- }
120
- }
121
-
122
- .navigation-group {
123
- --_icon-transform: scaleY(1);
124
- position: relative;
125
-
126
- .navigation-group-toggle {
127
- anchor-name: var(--_anchor-name);
128
-
129
- display: flex;
130
- align-items: center;
131
- gap: 12px;
132
-
133
- .icon {
134
- display: block;
135
- font-size: 1.2rem;
136
-
137
- transform: var(--_icon-transform);
138
- transition: transform 200ms;
139
- }
140
- }
141
-
142
- .navigation-group-panel {
143
- display: none;
144
- position: absolute;
145
- position-anchor: var(--_anchor-name);
146
- margin: 0;
147
- /* inset: auto; */
148
- top: calc(anchor(bottom) + 10px);
149
- left: calc(anchor(left) + 0px);
150
-
151
- opacity: 0;
152
- transition: opacity 200ms, display 200ms, overlay 200ms;
153
- transition-behavior: allow-discrete;
154
-
155
- width: min(100%, 50vw);
156
-
157
- background-color: white;
158
- border: 1px solid black;
159
- border-radius: 12px;
160
- box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
161
- padding: 12px;
162
- overflow: clip;
163
-
164
- &:popover-open {
165
- display: block;
166
- opacity: 1;
167
-
168
- @starting-style {
169
- display: block;
170
- opacity: 0;
171
- }
172
- }
173
-
174
- h4 {
175
- color: var(--gray-12);
176
- }
177
-
178
- .navigation-group-list {
179
- display: grid;
180
- grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
181
- gap: 12px;
182
- padding-inline-start: 0;
183
- margin-block-end: 8px;
184
-
185
- .navigation-group-item {
186
- display: block;
187
-
188
- a.navigation-group-link {
189
- display: inline-block;
190
- color: var(--gray-12);
191
- text-decoration: none;
192
- padding-block: 8px;
193
-
194
- border-bottom: 2px solid transparent;
195
-
196
- transition: border-color 200ms;
197
-
198
- &:hover {
199
- cursor: pointer;
200
- border-color: var(--gray-12);
201
- }
202
-
203
- &:focus-visible {
204
- border-color: var(--gray-12);
205
- }
206
- }
207
- }
208
- }
209
- }
210
-
211
- &:has(.navigation-group-panel:popover-open) {
212
- --_icon-transform: scaleY(-1);
213
- }
214
- }
215
- }
216
- }
217
- }
218
- </style>
@@ -1,23 +1,21 @@
1
1
  <template>
2
2
  <component :is="tag" class="deep-expanding-menu-old" :class="[elementClasses]">
3
3
  <div class="inner">
4
- <template v-for="(link, key, index) in navLinks" :key="key">
4
+ <template v-for="(link, key) in navLinks" :key="key">
5
5
  <NuxtLink v-if="link.path" :to="link.path" class="navigation-link">{{ link.name }}</NuxtLink>
6
- <details v-else class="navigation-group" name="navigation-group" :style="`--_position-anchor: --anchor-nav-1-${key};, --_anchor-name: --anchor-nav-1-${key};`" ref="navigationGroupRef">
6
+ <details v-else class="navigation-group" name="navigation-group" ref="navigationGroupRef">
7
7
  <summary class="navigation-group-toggle">
8
8
  <span>{{ link.name }}</span>
9
9
  <Icon name="bi:caret-down-fill" class="icon" />
10
10
  </summary>
11
- <ClientOnly>
12
- <div class="navigation-group-panel" :id="`popovertarget-nav-1-${key}`">
13
- <h4 class="heading-4 mb-6">{{ link.childLinksTitle }}</h4>
14
- <ul class="navigation-group-list">
15
- <li class="navigation-group-item" v-for="childLink in link.childLinks" :key="childLink.name">
16
- <NuxtLink :to="childLink.path" class="navigation-group-link">{{ childLink.name }}</NuxtLink>
17
- </li>
18
- </ul>
19
- </div>
20
- </ClientOnly>
11
+ <div class="navigation-group-panel" :id="`popovertarget-nav-1-${key}`">
12
+ <h4 class="heading-4 mb-6">{{ link.childLinksTitle }}</h4>
13
+ <ul class="navigation-group-list">
14
+ <li class="navigation-group-item" v-for="childLink in link.childLinks" :key="childLink.name">
15
+ <NuxtLink :to="childLink.path" class="navigation-group-link">{{ childLink.name }}</NuxtLink>
16
+ </li>
17
+ </ul>
18
+ </div>
21
19
  </details>
22
20
  </template>
23
21
  </div>
@@ -72,6 +70,7 @@ interface INavLink {
72
70
  name: string;
73
71
  path?: string;
74
72
  isExternal?: boolean;
73
+ childLinksTitle?: string;
75
74
  childLinks?: INavLink[];
76
75
  }
77
76
  </script>
@@ -88,7 +87,7 @@ interface INavLink {
88
87
  .inner {
89
88
  grid-area: element-stack;
90
89
  display: flex;
91
- gap: 12px;
90
+ gap: 24px;
92
91
  align-items: center;
93
92
  z-index: 1;
94
93
 
@@ -1,18 +1,18 @@
1
1
  <template>
2
2
  <div class="display-accordian" :class="[elementClasses]" ref="accordianRef">
3
- <template v-for="(item, key) in data" :key="key">
4
- <div class="accordion-panel">
5
- <button class="accordion-trigger" :id="`accordian-${key}-trigger`" aria-expanded="false" :aria-controls="`accordian-${key}-content`" ref="triggerRefs" @click.stop.prevent="handleSummary(key)">
3
+ <details v-for="(item, key) in data" :key="key" class="accordion-panel" name="navigation-group">
4
+ <summary class="accordion-trigger" :id="`accordian-${key}-trigger`" :aria-controls="`accordian-${key}-content`" ref="triggerRefs">
5
+ <span class="label">
6
6
  <slot :name="`accordian-${key}-trigger`"></slot>
7
- </button>
8
-
9
- <div class="accordion-content" :aria-labelledby="`accordian-${key}-trigger`" :id="`accordian-${key}-content`" role="region" aria-hidden="true" ref="contentRefs">
10
- <div>
11
- <slot :name="`accordian-${key}-content`"></slot>
12
- </div>
7
+ </span>
8
+ <Icon name="bi:caret-down-fill" class="icon mi-12" />
9
+ </summary>
10
+ <div class="accordion-content" :aria-labelledby="`accordian-${key}-trigger`" :id="`accordian-${key}-content`" role="region" ref="contentRefs">
11
+ <div class="accordion-content-inner">
12
+ <slot :name="`accordian-${key}-content`"></slot>
13
13
  </div>
14
14
  </div>
15
- </template>
15
+ </details>
16
16
  </div>
17
17
  </template>
18
18
 
@@ -34,31 +34,6 @@ const props = defineProps({
34
34
  });
35
35
 
36
36
  const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
37
-
38
- const accordianRef = ref<HTMLElement>();
39
- const triggerRefs = ref<HTMLElement[]>([]);
40
- const contentRefs = ref<HTMLElement[]>([]);
41
-
42
- onMounted(() => {
43
- if (accordianRef.value) {
44
- triggerRefs.value = Array.from(accordianRef.value.querySelectorAll('.accordion-trigger'));
45
- contentRefs.value = Array.from(accordianRef.value.querySelectorAll('.accordion-content'));
46
- }
47
- });
48
-
49
- const handleSummary = (clickedIndex: number) => {
50
- triggerRefs.value.forEach((element, index) => {
51
- if (clickedIndex === index) {
52
- const currentState = element.getAttribute('aria-expanded');
53
- const newState = currentState !== 'true';
54
- triggerRefs.value[index].setAttribute('aria-expanded', String(newState));
55
- contentRefs.value[index].setAttribute('aria-hidden', String(currentState));
56
- } else {
57
- triggerRefs.value[index].setAttribute('aria-expanded', 'false');
58
- contentRefs.value[index].setAttribute('aria-hidden', 'true');
59
- }
60
- });
61
- };
62
37
  </script>
63
38
 
64
39
  <style lang="css">
@@ -68,46 +43,58 @@ const handleSummary = (clickedIndex: number) => {
68
43
  }
69
44
 
70
45
  .accordion-panel {
46
+ @property --_grid-template-rows {
47
+ syntax: '<length-percentage> | auto | min-content | max-content | minmax( <length-percentage> , <length-percentage> ) | fit-content( <length-percentage> ) | <flex>';
48
+ inherits: true;
49
+ initial-value: 0fr;
50
+ }
51
+
52
+ --_grid-template-rows: 0fr;
53
+ --_icon-transform: scaleY(1);
54
+
71
55
  border: var(--accordian-panel-border);
72
56
  border-radius: var(--accordian-panel-border-radius);
73
57
  margin-block-end: var(--accordian-panel-mbe);
74
- }
75
58
 
76
- .accordion-trigger {
77
- display: block;
78
- width: 100%;
79
- padding: 1rem;
80
- background: var(--accordion-trigger-bg);
81
- border: none;
82
- text-align: left;
83
- cursor: pointer;
84
- }
59
+ &[open] {
60
+ --_grid-template-rows: 1fr;
61
+ --_icon-transform: scaleY(-1);
62
+ }
63
+
64
+ summary::-webkit-details-marker,
65
+ summary::marker {
66
+ display: none;
67
+ }
68
+
69
+ .accordion-trigger {
70
+ display: flex !important;
71
+ align-items: center;
72
+ gap: 12px;
73
+ list-style: none;
74
+ padding: 1rem;
85
75
 
86
- .accordion-content {
87
- display: grid;
88
- grid-template-rows: 0fr;
89
- transition: grid-template-rows ease-in-out 500ms;
76
+ .label {
77
+ display: block;
78
+ flex-grow: 1;
79
+ }
90
80
 
91
- > div {
92
- overflow: hidden;
93
- /* transform: translateY(-1rem);
94
- transition: all ease-in-out 500ms;
81
+ .icon {
82
+ display: block;
83
+ font-size: 1.2rem;
95
84
 
96
- > p {
97
- padding-block: 0;
98
- transition: all ease-in-out 500ms;
99
- } */
85
+ transform: var(--_icon-transform);
86
+ transition: transform 200ms;
87
+ }
100
88
  }
101
- }
102
89
 
103
- .accordion-content[aria-hidden='false'] {
104
- grid-template-rows: 1fr;
90
+ .accordion-content {
91
+ display: grid;
92
+ grid-template-rows: var(--_grid-template-rows);
93
+ transition: all 2000ms;
105
94
 
106
- /* > div {
107
- transform: translateY(0);
108
- > p {
109
- padding-block: 3.2rem;
110
- }
111
- } */
95
+ .accordion-content-inner {
96
+ overflow: hidden;
97
+ }
98
+ }
112
99
  }
113
100
  </style>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "srcdev-nuxt-components",
3
3
  "type": "module",
4
- "version": "2.1.4",
4
+ "version": "2.1.6",
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",
@@ -27,9 +27,9 @@
27
27
  "devDependencies": {
28
28
  "@iconify-json/akar-icons": "1.2.2",
29
29
  "@iconify-json/bitcoin-icons": "1.2.2",
30
- "@nuxt/eslint-config": "1.0.0",
31
- "@nuxt/icon": "1.10.3",
32
- "@nuxt/image": "^1.9.0",
30
+ "@nuxt/eslint-config": "1.2.0",
31
+ "@nuxt/icon": "1.11.0",
32
+ "@nuxt/image": "1.10.0",
33
33
  "eslint": "9.22.0",
34
34
  "happy-dom": "16.8.1",
35
35
  "nuxt": "3.16.0",
@@ -37,6 +37,7 @@
37
37
  "typescript": "5.8.2"
38
38
  },
39
39
  "dependencies": {
40
+ "@oddbird/css-anchor-positioning": "0.4.0",
40
41
  "@vueuse/core": "13.0.0",
41
42
  "focus-trap-vue": "4.0.3",
42
43
  "modern-normalize": "3.0.1"