libreria-astro-lefebvre 0.0.172 → 0.0.173

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libreria-astro-lefebvre",
3
- "version": "0.0.172",
3
+ "version": "0.0.173",
4
4
  "description": "Librería de componentes Astro, React y Vue para Lefebvre",
5
5
  "author": "Equipo web desarrollo Lefebvre",
6
6
  "type": "module",
@@ -63,6 +63,8 @@ const categories: MenuItem[] = (categoriesProp && categoriesProp.length > 0)
63
63
 
64
64
  const currentPath = Astro.url.pathname;
65
65
 
66
+ const identifier = 'header-cab-' + Math.random().toString(36).substring(2, 10);
67
+
66
68
  const structuredData = `<script type="application/ld+json">
67
69
  {
68
70
  "@context": "https://schema.org",
@@ -88,7 +90,7 @@ const categories: MenuItem[] = (categoriesProp && categoriesProp.length > 0)
88
90
 
89
91
  ---
90
92
 
91
- <header class="sticky top-0 w-full font-inter bg-white z-50 flex flex-col justify-center align-center items-center p-0 overflow-hidden">
93
+ <header class="sticky top-0 w-full font-inter bg-white z-50 flex flex-col justify-center align-center items-center p-0">
92
94
  <nav class="px-4 py-3 w-full">
93
95
 
94
96
  <div class="max-w-7xl flex items-center justify-between mx-auto">
@@ -115,26 +117,36 @@ const categories: MenuItem[] = (categoriesProp && categoriesProp.length > 0)
115
117
  </nav>
116
118
  <nav class="w-full flex items-center border-y border-gray-300">
117
119
  <ul class="max-w-7xl hidden md:flex items-center justify-start md:gap-2 lg:gap-8 mx-auto">
118
- {categories.map(category => {
120
+ {categories.map((category, index) => {
119
121
  const isActive = currentPath.includes(category.link) ||
120
122
  (subdirectory !== '' && (subdirectory + currentPath).includes(category.link));
123
+ const hasSub = category.subcategories?.length > 0;
124
+ const submenuId = `${identifier}-d-${index}`;
121
125
  return (
122
- <li class={`relative group border-b-4 hover:border-b-4 hover:border-[#001978] hover:bg-gray-100 ${isActive ? 'border-b-4 border-[#001978] active' : 'border-transparent'}`}>
123
- <a href={category.link} target={category.target ?? '_self'} class="flex items-center md:px-4 lg:px-8 py-6">
126
+ <li class={`relative flex items-center border-b-4 hover:border-b-4 hover:border-[#001978] hover:bg-gray-100 ${isActive ? 'border-b-4 border-[#001978] active' : 'border-transparent'}`}>
127
+ <a href={category.link} target={category.target ?? '_self'} class={`flex items-center py-6 md:pl-4 lg:pl-8 ${hasSub ? '' : 'md:pr-4 lg:pr-8'}`}>
124
128
  <span>
125
129
  {category.name}
126
130
  </span>
127
- {category.subcategories?.length > 0 && (
128
- <span class="ml-2 text-xs">
129
- <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 32 32" fill="none">
130
- <path fill-rule="evenodd" clip-rule="evenodd" d="M4.26007 10.3273C4.63157 9.91868 5.26402 9.88856 5.67268 10.2601L16 19.6485L26.3273 10.2601C26.736 9.88856 27.3684 9.91868 27.7399 10.3273C28.1115 10.736 28.0813 11.3684 27.6727 11.7399L16.6727 21.7399C16.2913 22.0867 15.7088 22.0867 15.3273 21.7399L4.32733 11.7399C3.91868 11.3684 3.88856 10.736 4.26007 10.3273Z" fill="currentColor"/>
131
- </svg>
132
- </span>
133
- )}
134
131
  </a>
135
- {category.subcategories?.length > 0 && (
136
- <ul class="absolute left-0 mt-1 bg-white border border-gray-300 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all z-10 min-w-[280px]"
137
-
132
+ {hasSub && (
133
+ <button
134
+ type="button"
135
+ class={`${identifier}-toggle flex items-center py-6 pl-2 md:pr-4 lg:pr-8 cursor-pointer`}
136
+ aria-label={`Mostrar submenú de ${category.name}`}
137
+ aria-expanded="false"
138
+ aria-controls={submenuId}
139
+ data-submenu-id={submenuId}
140
+ >
141
+ <svg class="transition-transform" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 32 32" fill="none">
142
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M4.26007 10.3273C4.63157 9.91868 5.26402 9.88856 5.67268 10.2601L16 19.6485L26.3273 10.2601C26.736 9.88856 27.3684 9.91868 27.7399 10.3273C28.1115 10.736 28.0813 11.3684 27.6727 11.7399L16.6727 21.7399C16.2913 22.0867 15.7088 22.0867 15.3273 21.7399L4.32733 11.7399C3.91868 11.3684 3.88856 10.736 4.26007 10.3273Z" fill="currentColor"/>
143
+ </svg>
144
+ </button>
145
+ )}
146
+ {hasSub && (
147
+ <ul
148
+ id={submenuId}
149
+ class={`${identifier}-submenu absolute left-0 top-full mt-1 bg-white border border-gray-300 hidden z-10 min-w-[230px]`}
138
150
  >
139
151
  {category.subcategories?.map(sub => (
140
152
  <li class="hover:text-indigo-900 hover:font-semibold">
@@ -150,29 +162,39 @@ const categories: MenuItem[] = (categoriesProp && categoriesProp.length > 0)
150
162
 
151
163
  <nav class="hidden w-full bg-white border-gray-200" id="navbar-default">
152
164
  <div class="max-w-screen-xl flex flex-wrap items-center justify-between mx-auto">
153
-
165
+
154
166
  <div class="w-full md:flex md:w-auto">
155
167
  <ul>
156
- {categories.map(category => {
168
+ {categories.map((category, index) => {
157
169
  const isActive = currentPath.includes(category.link) ||
158
170
  (subdirectory !== '' && (subdirectory + currentPath).includes(category.link));
171
+ const hasSub = category.subcategories?.length > 0;
172
+ const submenuId = `${identifier}-m-${index}`;
159
173
  return (
160
- <li class={`relative group px-6 py-4 border-b-2 hover:border-b-2 hover:border-indigo-600 ${isActive ? 'border-b-4 border-[#001978] active' : 'border-transparent'}`}>
174
+ <li class={`relative flex items-center px-6 py-4 border-b-2 hover:border-b-2 hover:border-indigo-600 ${isActive ? 'border-b-4 border-[#001978] active' : 'border-transparent'}`}>
161
175
  <a href={category.link} target={category.target ?? '_self'} class="flex items-center">
162
176
  <span class="hover:underline">
163
177
  {category.name}
164
178
  </span>
165
- {category.subcategories?.length > 0 && (
166
- <span class="ml-2 text-xs">
167
- <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 32 32" fill="none">
168
- <path fill-rule="evenodd" clip-rule="evenodd" d="M4.26007 10.3273C4.63157 9.91868 5.26402 9.88856 5.67268 10.2601L16 19.6485L26.3273 10.2601C26.736 9.88856 27.3684 9.91868 27.7399 10.3273C28.1115 10.736 28.0813 11.3684 27.6727 11.7399L16.6727 21.7399C16.2913 22.0867 15.7088 22.0867 15.3273 21.7399L4.32733 11.7399C3.91868 11.3684 3.88856 10.736 4.26007 10.3273Z" fill="currentColor"/>
169
- </svg>
170
- </span>
171
- )}
172
179
  </a>
173
- {category.subcategories?.length > 0 && (
174
- <ul class="absolute left-0 mt-1 bg-white border border-gray-300 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all z-10 min-w-[280px]"
175
-
180
+ {hasSub && (
181
+ <button
182
+ type="button"
183
+ class={`${identifier}-toggle ml-2 p-2 cursor-pointer`}
184
+ aria-label={`Mostrar submenú de ${category.name}`}
185
+ aria-expanded="false"
186
+ aria-controls={submenuId}
187
+ data-submenu-id={submenuId}
188
+ >
189
+ <svg class="transition-transform" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 32 32" fill="none">
190
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M4.26007 10.3273C4.63157 9.91868 5.26402 9.88856 5.67268 10.2601L16 19.6485L26.3273 10.2601C26.736 9.88856 27.3684 9.91868 27.7399 10.3273C28.1115 10.736 28.0813 11.3684 27.6727 11.7399L16.6727 21.7399C16.2913 22.0867 15.7088 22.0867 15.3273 21.7399L4.32733 11.7399C3.91868 11.3684 3.88856 10.736 4.26007 10.3273Z" fill="currentColor"/>
191
+ </svg>
192
+ </button>
193
+ )}
194
+ {hasSub && (
195
+ <ul
196
+ id={submenuId}
197
+ class={`${identifier}-submenu absolute left-0 top-full bg-white border border-gray-300 hidden z-10 w-full md:w-auto min-w-[230px]`}
176
198
  >
177
199
  {category.subcategories?.map(sub => (
178
200
  <li class="hover:text-indigo-900 hover:font-semibold">
@@ -191,4 +213,57 @@ const categories: MenuItem[] = (categoriesProp && categoriesProp.length > 0)
191
213
 
192
214
  </header>
193
215
 
216
+ <script is:inline define:vars={{ identifier }}>
217
+ document.querySelectorAll(`.${identifier}-toggle`).forEach(btn => {
218
+ btn.addEventListener('click', (e) => {
219
+ e.stopPropagation();
220
+ const id = btn.getAttribute('data-submenu-id');
221
+ const submenu = document.getElementById(id);
222
+ if (!submenu) return;
223
+ const willOpen = submenu.classList.contains('hidden');
224
+
225
+ document.querySelectorAll(`.${identifier}-submenu`).forEach(s => {
226
+ if (s !== submenu) s.classList.add('hidden');
227
+ });
228
+ document.querySelectorAll(`.${identifier}-toggle`).forEach(b => {
229
+ if (b !== btn) {
230
+ b.setAttribute('aria-expanded', 'false');
231
+ const svg = b.querySelector('svg');
232
+ if (svg) svg.classList.remove('rotate-180');
233
+ }
234
+ });
235
+
236
+ submenu.classList.toggle('hidden');
237
+ btn.setAttribute('aria-expanded', String(willOpen));
238
+ const svg = btn.querySelector('svg');
239
+ if (svg) svg.classList.toggle('rotate-180', willOpen);
240
+ });
241
+ });
242
+
243
+ document.addEventListener('click', (e) => {
244
+ if (e.target.closest(`.${identifier}-toggle`)) return;
245
+ if (e.target.closest(`.${identifier}-submenu`)) return;
246
+ document.querySelectorAll(`.${identifier}-submenu`).forEach(s => {
247
+ s.classList.add('hidden');
248
+ });
249
+ document.querySelectorAll(`.${identifier}-toggle`).forEach(b => {
250
+ b.setAttribute('aria-expanded', 'false');
251
+ const svg = b.querySelector('svg');
252
+ if (svg) svg.classList.remove('rotate-180');
253
+ });
254
+ });
255
+
256
+ document.addEventListener('keydown', (e) => {
257
+ if (e.key !== 'Escape') return;
258
+ document.querySelectorAll(`.${identifier}-submenu`).forEach(s => {
259
+ s.classList.add('hidden');
260
+ });
261
+ document.querySelectorAll(`.${identifier}-toggle`).forEach(b => {
262
+ b.setAttribute('aria-expanded', 'false');
263
+ const svg = b.querySelector('svg');
264
+ if (svg) svg.classList.remove('rotate-180');
265
+ });
266
+ });
267
+ </script>
268
+
194
269
  <Fragment set:html={structuredData} />