lau-ecom-design-system 1.0.22 → 1.0.26
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/dist/lau-ecom-design-system.esm.css +6 -2
- package/dist/lau-ecom-design-system.esm.js +1743 -505
- package/dist/lau-ecom-design-system.min.css +6 -2
- package/dist/lau-ecom-design-system.min.js +1 -1
- package/dist/lau-ecom-design-system.ssr.css +6 -2
- package/dist/lau-ecom-design-system.ssr.js +1779 -470
- package/dist/style.css +222 -134
- package/package.json +1 -1
- package/src/components/LauEcomIcon/LauEcomUpcIconClose.vue +29 -0
- package/src/components/LauEcomIcon/LauEcomUpcIconNavArrow.vue +1 -1
- package/src/components/LauEcomIcon/LauEcomUpcIconSearch.vue +6 -16
- package/src/components/LauEcomInputSearch/LauEcomInputSearch.vue +445 -322
- package/src/components/LauEcomInputSearch/LauEcomInputSearchDesktop.vue +229 -0
- package/src/components/LauEcomInputSearch/LauEcomInputSearchMobile.vue +187 -0
- package/src/components/LauEcomInputSearchHeader/LauEcomInputSearchHeader.vue +432 -0
- package/src/components/LauEcomInputSearchHeader/LauEcomInputSearchHeaderDesktop.vue +324 -0
- package/src/components/LauEcomInputSearchHeader/LauEcomInputSearchHeaderMobile.vue +279 -0
- package/src/components/LauEcomInput2/LauEcomInput2.vue +0 -207
@@ -1,323 +1,446 @@
|
|
1
|
-
<script lang="ts" setup>
|
2
|
-
import { ref, computed, onMounted, onBeforeUnmount, watch, nextTick } from "vue";
|
3
|
-
import {
|
4
|
-
LauEcomUpcIconSearch,
|
5
|
-
LauEcomCoreIconNavClose as LauEcomUpcIconClose,
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
const
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
emit("update:modelValue", searchQuery.value);
|
75
|
-
};
|
76
|
-
|
77
|
-
const clearSearch = () => {
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
}
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
const
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
expandedContainer.value.style.
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
}
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
<
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
1
|
+
<script lang="ts" setup>
|
2
|
+
import { ref, computed, onMounted, onBeforeUnmount, watch, nextTick } from "vue";
|
3
|
+
import {
|
4
|
+
LauEcomUpcIconSearch,
|
5
|
+
LauEcomCoreIconNavClose as LauEcomUpcIconClose,
|
6
|
+
LauEcomUpcIconNavArrow,
|
7
|
+
} from "../LauEcomIcon";
|
8
|
+
|
9
|
+
interface Props {
|
10
|
+
placeholder?: string;
|
11
|
+
isDisabled?: boolean;
|
12
|
+
modelValue?: string;
|
13
|
+
forceClose?: boolean;
|
14
|
+
buttonColorClass?: string;
|
15
|
+
buttonTextColorClass?: string;
|
16
|
+
buttonClass?: string;
|
17
|
+
inputClass?: string;
|
18
|
+
containerClass?: string;
|
19
|
+
expandedWidth?: string;
|
20
|
+
isMobileSearch?: boolean;
|
21
|
+
arrowColorClass?: string;
|
22
|
+
arrowButtonClass?: string;
|
23
|
+
mobileInputWidth?: string;
|
24
|
+
mobileInputHeight?: string;
|
25
|
+
mobilePanelClass?: string;
|
26
|
+
expandedBackgroundClass?: string;
|
27
|
+
overlayClass?: string;
|
28
|
+
}
|
29
|
+
|
30
|
+
const props = withDefaults(defineProps<Props>(), {
|
31
|
+
placeholder: "Quiero aprender...",
|
32
|
+
isDisabled: false,
|
33
|
+
modelValue: "",
|
34
|
+
forceClose: false,
|
35
|
+
buttonColorClass: "bg-base-color-primary-20",
|
36
|
+
buttonTextColorClass: "text-base-color-primary-60",
|
37
|
+
buttonClass: "",
|
38
|
+
inputClass: "dsEcom-h-10 dsEcom-rounded-lg",
|
39
|
+
containerClass: "",
|
40
|
+
expandedWidth: "50vw",
|
41
|
+
isMobileSearch: false,
|
42
|
+
arrowColorClass: "text-neutral-100",
|
43
|
+
arrowButtonClass: "",
|
44
|
+
mobileInputWidth: "240px",
|
45
|
+
mobileInputHeight: "40px",
|
46
|
+
mobilePanelClass: "bg-white",
|
47
|
+
expandedBackgroundClass: "dsEcom-bg-white",
|
48
|
+
overlayClass: "dsEcom-bg-black dsEcom-opacity-50"
|
49
|
+
});
|
50
|
+
|
51
|
+
const emit = defineEmits({
|
52
|
+
"update:modelValue": (value: string) => true,
|
53
|
+
"search": (value: string) => true,
|
54
|
+
"click:search-icon": () => true
|
55
|
+
});
|
56
|
+
|
57
|
+
const searchQuery = ref(props.modelValue);
|
58
|
+
const isExpanded = ref(false);
|
59
|
+
const showOverlay = ref(false);
|
60
|
+
|
61
|
+
const isMobileView = ref(false);
|
62
|
+
const isMobileSearchOpen = ref(false);
|
63
|
+
|
64
|
+
const handleSearch = () => {
|
65
|
+
if (searchQuery.value && searchQuery.value.trim()) {
|
66
|
+
emit("search", searchQuery.value);
|
67
|
+
emit("update:modelValue", searchQuery.value);
|
68
|
+
emit("click:search-icon");
|
69
|
+
closeSearch();
|
70
|
+
}
|
71
|
+
};
|
72
|
+
|
73
|
+
const handleInput = () => {
|
74
|
+
emit("update:modelValue", searchQuery.value);
|
75
|
+
};
|
76
|
+
|
77
|
+
const clearSearch = () => {
|
78
|
+
searchQuery.value = "";
|
79
|
+
emit("update:modelValue", "");
|
80
|
+
};
|
81
|
+
|
82
|
+
const closeSearch = () => {
|
83
|
+
showOverlay.value = false;
|
84
|
+
setTimeout(() => {
|
85
|
+
isExpanded.value = false;
|
86
|
+
}, 300);
|
87
|
+
};
|
88
|
+
|
89
|
+
const handleFocus = () => {
|
90
|
+
isExpanded.value = true;
|
91
|
+
showOverlay.value = true;
|
92
|
+
};
|
93
|
+
|
94
|
+
const containerClasses = computed(() => {
|
95
|
+
return [
|
96
|
+
"dsEcom-transition-transform dsEcom-duration-300 dsEcom-ease-in-out dsEcom-relative",
|
97
|
+
{
|
98
|
+
"dsEcom-w-[250px] md:dsEcom-w-[350px]": !isExpanded.value
|
99
|
+
}
|
100
|
+
];
|
101
|
+
});
|
102
|
+
|
103
|
+
const overlayClasses = computed(() => [
|
104
|
+
"dsEcom-fixed dsEcom-inset-0 dsEcom-transition-opacity dsEcom-duration-300 dsEcom-ease-in-out dsEcom-z-40",
|
105
|
+
props.overlayClass,
|
106
|
+
{
|
107
|
+
"dsEcom-opacity-100": showOverlay.value,
|
108
|
+
"dsEcom-opacity-0 dsEcom-pointer-events-none": !showOverlay.value
|
109
|
+
}
|
110
|
+
]);
|
111
|
+
|
112
|
+
const originalContainer = ref<HTMLElement | null>(null);
|
113
|
+
const expandedContainer = ref<HTMLElement | null>(null);
|
114
|
+
|
115
|
+
const updateExpandedPosition = () => {
|
116
|
+
if (originalContainer.value && expandedContainer.value) {
|
117
|
+
const rect = originalContainer.value.getBoundingClientRect();
|
118
|
+
const viewportHeight = window.innerHeight;
|
119
|
+
const viewportWidth = window.innerWidth;
|
120
|
+
|
121
|
+
let topPosition;
|
122
|
+
if (rect.top < 0) {
|
123
|
+
topPosition = '20px';
|
124
|
+
} else if (rect.top > viewportHeight) {
|
125
|
+
topPosition = '20px';
|
126
|
+
} else {
|
127
|
+
topPosition = `${rect.top}px`;
|
128
|
+
}
|
129
|
+
|
130
|
+
// Mantenemos la posición original del input
|
131
|
+
const leftPosition = `${rect.left}px`;
|
132
|
+
|
133
|
+
expandedContainer.value.style.position = 'fixed';
|
134
|
+
expandedContainer.value.style.top = topPosition;
|
135
|
+
expandedContainer.value.style.left = leftPosition;
|
136
|
+
expandedContainer.value.style.transform = 'none';
|
137
|
+
expandedContainer.value.style.width = props.expandedWidth;
|
138
|
+
expandedContainer.value.style.maxWidth = '90vw';
|
139
|
+
|
140
|
+
// Ajustamos si se sale por la derecha
|
141
|
+
const expandedWidth = parseInt(props.expandedWidth);
|
142
|
+
if (rect.left + expandedWidth > viewportWidth) {
|
143
|
+
// Si se sale por la derecha, ajustamos el ancho para que quepa
|
144
|
+
const availableWidth = viewportWidth - rect.left - 32; // 32px de margen
|
145
|
+
expandedContainer.value.style.width = `${availableWidth}px`;
|
146
|
+
}
|
147
|
+
}
|
148
|
+
};
|
149
|
+
|
150
|
+
const checkMobileView = () => {
|
151
|
+
isMobileView.value = window.innerWidth < 768;
|
152
|
+
};
|
153
|
+
|
154
|
+
const handleMobileSearchClick = () => {
|
155
|
+
isMobileSearchOpen.value = true;
|
156
|
+
nextTick(() => {
|
157
|
+
if (expandedContainer.value) {
|
158
|
+
const input = expandedContainer.value.querySelector('input');
|
159
|
+
input?.focus();
|
160
|
+
}
|
161
|
+
});
|
162
|
+
};
|
163
|
+
|
164
|
+
const handleMobileSearchClose = () => {
|
165
|
+
// Primero ocultamos con la transición
|
166
|
+
const panel = document.querySelector('.dsEcom-fixed') as HTMLElement;
|
167
|
+
if (panel) {
|
168
|
+
panel.style.opacity = '0';
|
169
|
+
panel.style.transform = 'translateY(100%)';
|
170
|
+
}
|
171
|
+
|
172
|
+
// Luego actualizamos el estado después de la transición
|
173
|
+
setTimeout(() => {
|
174
|
+
isMobileSearchOpen.value = false;
|
175
|
+
searchQuery.value = '';
|
176
|
+
emit('update:modelValue', '');
|
177
|
+
}, 300);
|
178
|
+
};
|
179
|
+
|
180
|
+
const handleMobileSearch = () => {
|
181
|
+
if (searchQuery.value && searchQuery.value.trim()) {
|
182
|
+
emit("search", searchQuery.value);
|
183
|
+
emit("update:modelValue", searchQuery.value);
|
184
|
+
emit("click:search-icon");
|
185
|
+
handleMobileSearchClose();
|
186
|
+
}
|
187
|
+
};
|
188
|
+
|
189
|
+
const handleMobileClear = () => {
|
190
|
+
clearSearch();
|
191
|
+
};
|
192
|
+
|
193
|
+
onMounted(() => {
|
194
|
+
checkMobileView();
|
195
|
+
window.addEventListener('resize', updateExpandedPosition);
|
196
|
+
window.addEventListener('resize', checkMobileView);
|
197
|
+
});
|
198
|
+
|
199
|
+
onBeforeUnmount(() => {
|
200
|
+
window.removeEventListener('resize', updateExpandedPosition);
|
201
|
+
window.removeEventListener('resize', checkMobileView);
|
202
|
+
});
|
203
|
+
|
204
|
+
watch(isExpanded, (newValue) => {
|
205
|
+
if (newValue) {
|
206
|
+
nextTick(updateExpandedPosition);
|
207
|
+
}
|
208
|
+
});
|
209
|
+
|
210
|
+
watch(() => props.forceClose, (newValue) => {
|
211
|
+
if (newValue) {
|
212
|
+
closeSearch();
|
213
|
+
}
|
214
|
+
});
|
215
|
+
|
216
|
+
watch(() => props.modelValue, (newValue) => {
|
217
|
+
if (newValue !== searchQuery.value) {
|
218
|
+
searchQuery.value = newValue;
|
219
|
+
}
|
220
|
+
});
|
221
|
+
</script>
|
222
|
+
|
223
|
+
<template>
|
224
|
+
<div class="dsEcom-relative">
|
225
|
+
<!-- Versión móvil - Solo botón de búsqueda -->
|
226
|
+
<button
|
227
|
+
v-show="isMobileView && !isMobileSearchOpen"
|
228
|
+
@click="handleMobileSearchClick"
|
229
|
+
class="dsEcom-p-2 dsEcom-rounded-lg dsEcom-transition-all dsEcom-duration-300 dsEcom-transform-gpu"
|
230
|
+
:class="[buttonColorClass]"
|
231
|
+
>
|
232
|
+
<LauEcomUpcIconSearch
|
233
|
+
width="24"
|
234
|
+
height="24"
|
235
|
+
:class="[buttonTextColorClass]"
|
236
|
+
/>
|
237
|
+
</button>
|
238
|
+
|
239
|
+
<!-- Capa blanca móvil -->
|
240
|
+
<div
|
241
|
+
v-show="isMobileView && isMobileSearchOpen"
|
242
|
+
class="dsEcom-fixed dsEcom-inset-0 dsEcom-z-50 dsEcom-transition-all dsEcom-duration-300 dsEcom-transform-gpu"
|
243
|
+
:class="[mobilePanelClass]"
|
244
|
+
:style="{
|
245
|
+
opacity: isMobileSearchOpen ? '1' : '0',
|
246
|
+
transform: isMobileSearchOpen ? 'translateY(0)' : 'translateY(100%)'
|
247
|
+
}"
|
248
|
+
>
|
249
|
+
<div class="dsEcom-flex dsEcom-items-center dsEcom-gap-2 dsEcom-p-4">
|
250
|
+
<!-- Input y botones -->
|
251
|
+
<div class="dsEcom-flex dsEcom-items-center dsEcom-gap-2 dsEcom-flex-1 dsEcom-transform-gpu">
|
252
|
+
<button
|
253
|
+
@click="handleMobileSearchClose"
|
254
|
+
class="dsEcom-p-2 dsEcom-rounded-lg dsEcom-transition-all dsEcom-duration-300 dsEcom-transform-gpu"
|
255
|
+
:class="[arrowButtonClass]"
|
256
|
+
>
|
257
|
+
<LauEcomUpcIconNavArrow
|
258
|
+
width="24"
|
259
|
+
height="24"
|
260
|
+
class="dsEcom-transform dsEcom-rotate-90 dsEcom-transition-all dsEcom-duration-300 dsEcom-transform-gpu"
|
261
|
+
:class="[arrowColorClass]"
|
262
|
+
color="currentColor"
|
263
|
+
/>
|
264
|
+
</button>
|
265
|
+
|
266
|
+
<div class="dsEcom-flex dsEcom-items-center dsEcom-gap-0 dsEcom-flex-1 dsEcom-transform-gpu">
|
267
|
+
<input
|
268
|
+
v-model="searchQuery"
|
269
|
+
type="text"
|
270
|
+
:placeholder="placeholder"
|
271
|
+
:disabled="isDisabled"
|
272
|
+
:style="{
|
273
|
+
width: props.mobileInputWidth,
|
274
|
+
height: props.mobileInputHeight
|
275
|
+
}"
|
276
|
+
class="lau-ecom-input dsEcom-pl-4 dsEcom-pr-4 dsEcom-border dsEcom-border-neutral-80 dsEcom-rounded-l-lg dsEcom-focus:outline-none dsEcom-focus:ring-2 dsEcom-focus:ring-primary-60 dsEcom-flex-1 dsEcom-transition-all dsEcom-duration-300 dsEcom-transform-gpu"
|
277
|
+
@input="handleInput"
|
278
|
+
@keyup.enter="handleMobileSearch"
|
279
|
+
/>
|
280
|
+
<button
|
281
|
+
@click="handleMobileSearch"
|
282
|
+
:style="{ height: props.mobileInputHeight }"
|
283
|
+
:class="[
|
284
|
+
'dsEcom-px-3 dsEcom-rounded-r-lg dsEcom-border-0 dsEcom-transition-all dsEcom-duration-300 dsEcom-transform-gpu',
|
285
|
+
buttonColorClass,
|
286
|
+
buttonTextColorClass
|
287
|
+
]"
|
288
|
+
>
|
289
|
+
<LauEcomUpcIconSearch width="20" height="20" color="currentColor" />
|
290
|
+
</button>
|
291
|
+
</div>
|
292
|
+
|
293
|
+
<button
|
294
|
+
v-show="searchQuery.length >= 3"
|
295
|
+
@click="handleMobileClear"
|
296
|
+
class="dsEcom-p-2 dsEcom-text-neutral-100 hover:dsEcom-text-neutral-80 dsEcom-transition-all dsEcom-duration-300 dsEcom-transform-gpu"
|
297
|
+
>
|
298
|
+
<LauEcomUpcIconClose width="16" height="16" />
|
299
|
+
</button>
|
300
|
+
</div>
|
301
|
+
</div>
|
302
|
+
</div>
|
303
|
+
|
304
|
+
<!-- Versión desktop -->
|
305
|
+
<div v-show="!isMobileView" class="dsEcom-transition-all dsEcom-duration-300 dsEcom-transform-gpu">
|
306
|
+
<div
|
307
|
+
:class="[containerClasses, props.containerClass]"
|
308
|
+
ref="originalContainer"
|
309
|
+
>
|
310
|
+
<div class="dsEcom-relative" :class="{ 'dsEcom-invisible': isExpanded }">
|
311
|
+
<input
|
312
|
+
v-model="searchQuery"
|
313
|
+
type="text"
|
314
|
+
:placeholder="placeholder"
|
315
|
+
:disabled="isDisabled"
|
316
|
+
:class="[
|
317
|
+
'lau-ecom-input dsEcom-border dsEcom-border-neutral-80 dsEcom-pl-4 dsEcom-pr-24 dsEcom-w-full dsEcom-focus:outline-none dsEcom-focus:ring-2 dsEcom-focus:ring-primary-60 dsEcom-transition-all dsEcom-duration-300',
|
318
|
+
props.inputClass,
|
319
|
+
{ 'dsEcom-opacity-0': isExpanded }
|
320
|
+
]"
|
321
|
+
@focus="handleFocus"
|
322
|
+
@input="handleInput"
|
323
|
+
@keyup.enter="handleSearch"
|
324
|
+
/>
|
325
|
+
<div class="dsEcom-absolute dsEcom-right-0 dsEcom-inset-y-0 dsEcom-flex dsEcom-items-stretch">
|
326
|
+
<button
|
327
|
+
v-if="searchQuery.length >= 3"
|
328
|
+
@click="clearSearch"
|
329
|
+
:class="[
|
330
|
+
'dsEcom-flex dsEcom-items-center dsEcom-px-1.5 dsEcom-text-neutral-100 hover:dsEcom-text-neutral-80 dsEcom-transition-all dsEcom-duration-300',
|
331
|
+
props.inputClass
|
332
|
+
]"
|
333
|
+
>
|
334
|
+
<LauEcomUpcIconClose width="16" height="16" />
|
335
|
+
</button>
|
336
|
+
|
337
|
+
<button
|
338
|
+
@click="handleSearch"
|
339
|
+
:class="[
|
340
|
+
'dsEcom-flex dsEcom-items-center dsEcom-px-3 dsEcom-transition-all dsEcom-duration-300',
|
341
|
+
props.inputClass?.includes('rounded') ? props.inputClass : 'dsEcom-rounded-r-lg',
|
342
|
+
props.buttonColorClass,
|
343
|
+
props.buttonTextColorClass,
|
344
|
+
'dsEcom-border-0'
|
345
|
+
]"
|
346
|
+
style="margin: 1px; height: calc(100% - 2px);"
|
347
|
+
>
|
348
|
+
<LauEcomUpcIconSearch width="20" height="20" color="currentColor" />
|
349
|
+
</button>
|
350
|
+
</div>
|
351
|
+
</div>
|
352
|
+
</div>
|
353
|
+
|
354
|
+
<!-- Overlay -->
|
355
|
+
<div
|
356
|
+
v-show="isExpanded"
|
357
|
+
:class="[
|
358
|
+
overlayClasses,
|
359
|
+
'dsEcom-transition-opacity dsEcom-duration-300 dsEcom-ease-in-out'
|
360
|
+
]"
|
361
|
+
@click="closeSearch"
|
362
|
+
></div>
|
363
|
+
|
364
|
+
<!-- Versión expandida -->
|
365
|
+
<div
|
366
|
+
v-show="isExpanded"
|
367
|
+
class="dsEcom-fixed dsEcom-z-50 dsEcom-shadow-lg dsEcom-overflow-hidden dsEcom-transition-all dsEcom-duration-300"
|
368
|
+
:class="[
|
369
|
+
props.inputClass?.includes('rounded') ? props.inputClass : 'dsEcom-rounded-lg',
|
370
|
+
expandedBackgroundClass
|
371
|
+
]"
|
372
|
+
ref="expandedContainer"
|
373
|
+
>
|
374
|
+
<div class="dsEcom-relative">
|
375
|
+
<input
|
376
|
+
v-model="searchQuery"
|
377
|
+
type="text"
|
378
|
+
:placeholder="placeholder"
|
379
|
+
:disabled="isDisabled"
|
380
|
+
:class="[
|
381
|
+
'lau-ecom-input dsEcom-border dsEcom-border-neutral-80 dsEcom-pl-4 dsEcom-pr-24 dsEcom-w-full dsEcom-focus:outline-none dsEcom-focus:ring-2 dsEcom-focus:ring-primary-60 dsEcom-transition-all dsEcom-duration-300',
|
382
|
+
props.inputClass
|
383
|
+
]"
|
384
|
+
@input="handleInput"
|
385
|
+
@keyup.enter="handleSearch"
|
386
|
+
autofocus
|
387
|
+
/>
|
388
|
+
<div class="dsEcom-absolute dsEcom-right-0 dsEcom-inset-y-0 dsEcom-flex dsEcom-items-stretch">
|
389
|
+
<button
|
390
|
+
v-if="searchQuery.length >= 3"
|
391
|
+
@click="clearSearch"
|
392
|
+
:class="[
|
393
|
+
'dsEcom-flex dsEcom-items-center dsEcom-px-1.5 dsEcom-text-neutral-100 hover:dsEcom-text-neutral-80 dsEcom-transition-all dsEcom-duration-300',
|
394
|
+
props.inputClass
|
395
|
+
]"
|
396
|
+
>
|
397
|
+
<LauEcomUpcIconClose width="16" height="16" />
|
398
|
+
</button>
|
399
|
+
|
400
|
+
<button
|
401
|
+
@click="handleSearch"
|
402
|
+
:class="[
|
403
|
+
'dsEcom-flex dsEcom-items-center dsEcom-px-3 dsEcom-transition-all dsEcom-duration-300',
|
404
|
+
{ 'dsEcom-rounded-r-lg': !props.inputClass?.includes('rounded') },
|
405
|
+
props.buttonColorClass,
|
406
|
+
props.buttonTextColorClass,
|
407
|
+
'dsEcom-border-0'
|
408
|
+
]"
|
409
|
+
style="margin: 1px; height: calc(100% - 2px);"
|
410
|
+
>
|
411
|
+
<LauEcomUpcIconSearch width="20" height="20" color="currentColor" />
|
412
|
+
</button>
|
413
|
+
</div>
|
414
|
+
</div>
|
415
|
+
</div>
|
416
|
+
</div>
|
417
|
+
</div>
|
418
|
+
</template>
|
419
|
+
|
420
|
+
<style scoped>
|
421
|
+
.lau-ecom-input {
|
422
|
+
transition: all 0.3s ease-in-out;
|
423
|
+
backface-visibility: hidden;
|
424
|
+
transform: translateZ(0);
|
425
|
+
-webkit-font-smoothing: antialiased;
|
426
|
+
-moz-osx-font-smoothing: grayscale;
|
427
|
+
will-change: transform, opacity;
|
428
|
+
}
|
429
|
+
|
430
|
+
.dsEcom-transform-gpu {
|
431
|
+
transform: translateZ(0);
|
432
|
+
backface-visibility: hidden;
|
433
|
+
perspective: 1000px;
|
434
|
+
will-change: transform, opacity;
|
435
|
+
}
|
436
|
+
|
437
|
+
/* Agregamos transiciones específicas para móvil */
|
438
|
+
@media (max-width: 768px) {
|
439
|
+
.dsEcom-fixed {
|
440
|
+
transition: transform 0.3s ease-in-out, opacity 0.3s ease-in-out;
|
441
|
+
will-change: transform, opacity;
|
442
|
+
}
|
443
|
+
}
|
444
|
+
</style>
|
445
|
+
|
323
446
|
|