lau-ecom-design-system 1.0.20 → 1.0.22

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,7 +1,7 @@
1
1
  {
2
2
  "name": "lau-ecom-design-system",
3
3
  "private": false,
4
- "version": "1.0.20",
4
+ "version": "1.0.22",
5
5
  "sourceType": "module",
6
6
  "sideEffects": false,
7
7
  "main": "dist/lau-ecom-design-system.ssr.js",
@@ -26,7 +26,8 @@
26
26
  "preview": "vite preview",
27
27
  "storybook": "storybook dev -p 6006",
28
28
  "build-storybook": "storybook build",
29
- "prepare": "husky"
29
+ "prepare": "husky",
30
+ "watch": "rollup -c -w"
30
31
  },
31
32
  "dependencies": {
32
33
  "vue": "^3.5.12"
@@ -5,7 +5,6 @@ import {
5
5
  LauEcomUpcIconExclamationTriangle,
6
6
  } from "../LauEcomIcon";
7
7
  import { DropdownItem } from "./types";
8
- import { Colors } from "../../utils";
9
8
 
10
9
  interface Props {
11
10
  id?: string;
@@ -14,6 +13,9 @@ interface Props {
14
13
  placeholder?: string;
15
14
  dropdownItems: DropdownItem[];
16
15
  errorMessage?: string;
16
+ disabledColor?: string;
17
+ errorColor?: string;
18
+ defaultColor?: string;
17
19
  }
18
20
 
19
21
  const props = withDefaults(defineProps<Props>(), {
@@ -22,6 +24,9 @@ const props = withDefaults(defineProps<Props>(), {
22
24
  isDisabled: false,
23
25
  placeholder: "Placeholder",
24
26
  errorMessage: "",
27
+ disabledColor: "var(--neutral-70)",
28
+ errorColor: "var(--feedback-error-60)",
29
+ defaultColor: "var(--neutral-100)",
25
30
  });
26
31
 
27
32
  const isOpen = ref(false);
@@ -62,9 +67,9 @@ const lauEcomIconClasses = computed(() => {
62
67
  });
63
68
 
64
69
  const iconArrowDownColor = computed(() => {
65
- if (props.isDisabled) return Colors["upc-color-neutral-70"];
66
- if (props.errorMessage) return Colors["upc-color-red-60-base"];
67
- return Colors["upc-color-neutral-100"];
70
+ if (props.isDisabled) return props.disabledColor;
71
+ if (props.errorMessage) return props.errorColor;
72
+ return props.defaultColor;
68
73
  });
69
74
  </script>
70
75
 
@@ -110,7 +115,7 @@ const iconArrowDownColor = computed(() => {
110
115
  <LauEcomUpcIconExclamationTriangle
111
116
  width="16"
112
117
  height="16"
113
- :color="Colors['upc-color-red-60-base']"
118
+ :color="errorColor"
114
119
  />
115
120
  </span>
116
121
  <p class="dsEcom-ml-1">
@@ -0,0 +1,39 @@
1
+ <script lang="ts" setup>
2
+ withDefaults(
3
+ defineProps<{
4
+ color?: string;
5
+ width?: string;
6
+ height?: string;
7
+ }>(),
8
+ {
9
+ color: "currentColor",
10
+ width: "24",
11
+ height: "24",
12
+ },
13
+ );
14
+ </script>
15
+
16
+ <template>
17
+ <svg
18
+ :width="width"
19
+ :height="height"
20
+ viewBox="0 0 24 24"
21
+ fill="none"
22
+ xmlns="http://www.w3.org/2000/svg"
23
+ >
24
+ <path
25
+ d="M11 19C15.4183 19 19 15.4183 19 11C19 6.58172 15.4183 3 11 3C6.58172 3 3 6.58172 3 11C3 15.4183 6.58172 19 11 19Z"
26
+ :stroke="color"
27
+ stroke-width="2"
28
+ stroke-linecap="round"
29
+ stroke-linejoin="round"
30
+ />
31
+ <path
32
+ d="M21 21L16.65 16.65"
33
+ :stroke="color"
34
+ stroke-width="2"
35
+ stroke-linecap="round"
36
+ stroke-linejoin="round"
37
+ />
38
+ </svg>
39
+ </template>
@@ -27,7 +27,7 @@ const props = withDefaults(defineProps<Props>(), {
27
27
  type: "text",
28
28
  placeholder: "Placeholder",
29
29
  isDisabled: false,
30
- label: "label",
30
+ label: "Text label",
31
31
  size: LauEcomSize.md,
32
32
  name: "input",
33
33
  modelValue: "",
@@ -0,0 +1,207 @@
1
+ <script lang="ts" setup>
2
+ import { computed, ref } from "vue";
3
+ import { LauEcomSize } from "../../enums";
4
+ import {
5
+ LauEcomUpcIconExclamationTriangle,
6
+ LauEcomUpcIconNavCheckmark,
7
+ } from "../LauEcomIcon";
8
+
9
+ interface Props {
10
+ id?: string;
11
+ type?: string;
12
+ placeholder?: string;
13
+ isDisabled?: boolean;
14
+ label?: string;
15
+ size?: LauEcomSize;
16
+ name?: string;
17
+ modelValue?: string | number;
18
+ inputContainerClass?: string;
19
+ inputClass?: string;
20
+ errorMessage?: string;
21
+ hasSuccess?: boolean;
22
+ limit?: number;
23
+ }
24
+
25
+ const props = withDefaults(defineProps<Props>(), {
26
+ id: "lauEcomInput",
27
+ type: "text",
28
+ placeholder: "Placeholder",
29
+ isDisabled: false,
30
+ label: "Text label",
31
+ size: LauEcomSize.md,
32
+ name: "input",
33
+ modelValue: "",
34
+ inputContainerClass: "",
35
+ inputClass: "",
36
+ errorMessage: "",
37
+ hasSuccess: false,
38
+ limit: 50,
39
+ });
40
+
41
+ const emit = defineEmits<{
42
+ "update:modelValue": [value: string];
43
+ }>();
44
+
45
+ const inputValue = ref(props.modelValue);
46
+ const errorMessageValue = ref(props.errorMessage);
47
+
48
+ const handleInput = (event: Event) => {
49
+ const newValue = (event.target as HTMLInputElement).value;
50
+
51
+ if (newValue.length === props.limit) {
52
+ errorMessageValue.value = "Excediste el numero de caracteres";
53
+ inputValue.value = newValue;
54
+ emit("update:modelValue", newValue);
55
+ return;
56
+ } else {
57
+ errorMessageValue.value = props.errorMessage;
58
+ }
59
+
60
+ inputValue.value = newValue;
61
+ emit("update:modelValue", newValue);
62
+ };
63
+
64
+ const labelClasses = computed(() => {
65
+ return {
66
+ "lau-ecom-label": true,
67
+ "lau-ecom-label--disabled": props.isDisabled,
68
+ };
69
+ });
70
+
71
+ const inputContainerClasses = computed(() => {
72
+ return [
73
+ "dsEcom-relative",
74
+ props.inputContainerClass ? props.inputContainerClass : "dsEcom-w-[284px]",
75
+ props.size === LauEcomSize.md ? "dsEcom-h-[42px]" : "dsEcom-h-[46px]",
76
+ ];
77
+ });
78
+
79
+ const inputClasses = computed(() => {
80
+ return [
81
+ "lau-ecom-input core-font-body-reg-04-16px",
82
+ props.inputClass,
83
+ props.size === LauEcomSize.md ? "dsEcom-py-[9px]" : "dsEcom-py-[11px]",
84
+ { "lau-ecom-input--disabled": props.isDisabled },
85
+ { "lau-ecom-input--error": errorMessageValue.value },
86
+ { "lau-ecom-input-success": props.hasSuccess && !errorMessageValue.value },
87
+ props.hasSuccess || errorMessageValue.value
88
+ ? "placeholder:!dsEcom-text-neutral-100"
89
+ : "placeholder:!dsEcom-text-neutral-80",
90
+ ];
91
+ });
92
+
93
+ const successClasses = computed(() => {
94
+ return [
95
+ "lau-ecom-success",
96
+ props.size === LauEcomSize.md ? "dsEcom-top-[10px]" : "dsEcom-top-3",
97
+ ];
98
+ });
99
+ </script>
100
+
101
+ <template>
102
+ <div class="dsEcom-flex dsEcom-flex-col">
103
+ <label v-if="label" :class="labelClasses">
104
+ {{ label }}
105
+ </label>
106
+ <div :class="inputContainerClasses">
107
+ <input
108
+ :id="id"
109
+ :class="inputClasses"
110
+ :type="type"
111
+ :placeholder="placeholder"
112
+ :name="name"
113
+ :disabled="isDisabled"
114
+ :value="inputValue"
115
+ :maxlength="limit"
116
+ @input="handleInput"
117
+ />
118
+ <div v-if="hasSuccess && !errorMessageValue" :class="successClasses">
119
+ <LauEcomUpcIconNavCheckmark
120
+ class="dsEcom-fill-feedback-success-60"
121
+ width="24"
122
+ height="24"
123
+ />
124
+ </div>
125
+ <div
126
+ v-if="errorMessageValue"
127
+ class="lau-ecom-error-message core-font-body-reg-06-12px"
128
+ >
129
+ <div class="dsEcom-flex">
130
+ <LauEcomUpcIconExclamationTriangle
131
+ class="dsEcom-fill-primary-60"
132
+ width="16"
133
+ height="16"
134
+ />
135
+ <p class="dsEcom-ml-1">
136
+ {{ errorMessageValue }}
137
+ </p>
138
+ </div>
139
+
140
+ <span v-if="inputValue.toString().length === limit">
141
+ {{ `${inputValue.toString().length}/${limit}` }}
142
+ </span>
143
+ </div>
144
+ </div>
145
+ </div>
146
+ </template>
147
+
148
+ <style scoped>
149
+ input[type="number"]::-webkit-inner-spin-button,
150
+ input[type="number"]::-webkit-outer-spin-button {
151
+ -webkit-appearance: none;
152
+ margin: 0;
153
+ }
154
+
155
+ .lau-ecom-label {
156
+ @apply dsEcom-block
157
+ dsEcom-text-neutral-100
158
+ dsEcom-font-core-font-family-public-sans
159
+ dsEcom-text-[12px]
160
+ dsEcom-font-core-font-weight-extrabold
161
+ dsEcom-leading-[18px];
162
+ }
163
+
164
+ .lau-ecom-label--disabled {
165
+ @apply !dsEcom-text-neutral-70;
166
+ }
167
+
168
+ .lau-ecom-input {
169
+ @apply dsEcom-w-full
170
+ dsEcom-pl-3
171
+ dsEcom-pr-[44px]
172
+ dsEcom-rounded-sm
173
+ dsEcom-border
174
+ dsEcom-border-neutral-80
175
+ hover:dsEcom-border-stroke-secondary-60
176
+ focus:dsEcom-border-stroke-secondary-60 focus:!dsEcom-text-neutral-100
177
+ focus-visible:dsEcom-outline-none
178
+ disabled:placeholder:dsEcom-text-neutral-70 disabled:dsEcom-bg-neutral-20
179
+ disabled:!dsEcom-border-neutral-70;
180
+ }
181
+
182
+ .lau-ecom-input--disabled {
183
+ @apply !dsEcom-text-neutral-70;
184
+ }
185
+
186
+ .lau-ecom-input--error {
187
+ @apply !dsEcom-border-feedback-error-60;
188
+ }
189
+
190
+ .lau-ecom-input-success {
191
+ @apply !dsEcom-border-feedback-success-60
192
+ placeholder:!dsEcom-text-neutral-100;
193
+ }
194
+
195
+ .lau-ecom-error-message {
196
+ @apply dsEcom-flex
197
+ dsEcom-items-center
198
+ dsEcom-mt-[2px]
199
+ dsEcom-justify-between
200
+ dsEcom-text-primary-60;
201
+ }
202
+
203
+ .lau-ecom-success {
204
+ @apply dsEcom-absolute
205
+ dsEcom-right-3;
206
+ }
207
+ </style>
@@ -0,0 +1,323 @@
1
+ <script lang="ts" setup>
2
+ import { ref, computed, onMounted, onBeforeUnmount, watch, nextTick } from "vue";
3
+ import {
4
+ LauEcomUpcIconSearch,
5
+ LauEcomCoreIconNavClose as LauEcomUpcIconClose,
6
+ } from "../LauEcomIcon";
7
+
8
+ // Log de versión del componente
9
+ console.log('🔍 InputSearch Version: 1.0.20 - Debug Mode');
10
+
11
+ interface Props {
12
+ placeholder?: string;
13
+ isDisabled?: boolean;
14
+ modelValue?: string;
15
+ forceClose?: boolean;
16
+ buttonColorClass?: string;
17
+ buttonTextColorClass?: string;
18
+ buttonClass?: string;
19
+ inputClass?: string;
20
+ containerClass?: string;
21
+ }
22
+
23
+ const props = withDefaults(defineProps<Props>(), {
24
+ placeholder: "Quiero aprender...",
25
+ isDisabled: false,
26
+ modelValue: "",
27
+ forceClose: false,
28
+ buttonColorClass: "dsEcom-bg-primary-60 hover:dsEcom-bg-primary-70",
29
+ buttonTextColorClass: "dsEcom-text-white",
30
+ buttonClass: "",
31
+ inputClass: "dsEcom-h-10 dsEcom-rounded-lg",
32
+ containerClass: ""
33
+ });
34
+
35
+ // Log de props iniciales
36
+ console.log('🔍 InputSearch Props:', {
37
+ placeholder: props.placeholder,
38
+ isDisabled: props.isDisabled,
39
+ modelValue: props.modelValue,
40
+ forceClose: props.forceClose
41
+ });
42
+
43
+ const emit = defineEmits({
44
+ "update:modelValue": (value: string) => true,
45
+ "search": (value: string) => true,
46
+ "click:search-icon": () => true
47
+ });
48
+
49
+ const searchQuery = ref(props.modelValue);
50
+ const isExpanded = ref(false);
51
+ const showOverlay = ref(false);
52
+
53
+ const handleSearch = () => {
54
+ console.log('🔍 Search triggered:', {
55
+ query: searchQuery.value,
56
+ isExpanded: isExpanded.value,
57
+ showOverlay: showOverlay.value
58
+ });
59
+
60
+ if (searchQuery.value && searchQuery.value.trim()) {
61
+ emit("search", searchQuery.value);
62
+ emit("update:modelValue", searchQuery.value);
63
+ emit("click:search-icon");
64
+ closeSearch();
65
+ }
66
+ };
67
+
68
+ const handleInput = () => {
69
+ console.log('🔍 Input changed:', {
70
+ value: searchQuery.value,
71
+ length: searchQuery.value.length,
72
+ isExpanded: isExpanded.value
73
+ });
74
+ emit("update:modelValue", searchQuery.value);
75
+ };
76
+
77
+ const clearSearch = () => {
78
+ console.log('🔍 Clear search triggered');
79
+ searchQuery.value = "";
80
+ emit("update:modelValue", "");
81
+ };
82
+
83
+ const closeSearch = () => {
84
+ console.log('🔍 Close search triggered');
85
+ showOverlay.value = false;
86
+ setTimeout(() => {
87
+ console.log('🔍 Closing search after timeout');
88
+ isExpanded.value = false;
89
+ }, 300);
90
+ };
91
+
92
+ const handleFocus = () => {
93
+ console.log('🔍 Focus triggered:', {
94
+ currentValue: searchQuery.value,
95
+ wasExpanded: isExpanded.value
96
+ });
97
+ isExpanded.value = true;
98
+ showOverlay.value = true;
99
+ };
100
+
101
+ const containerClasses = computed(() => {
102
+ const classes = [
103
+ "dsEcom-transition-transform dsEcom-duration-300 dsEcom-ease-in-out dsEcom-relative",
104
+ {
105
+ "dsEcom-w-[250px] md:dsEcom-w-[350px]": !isExpanded.value
106
+ }
107
+ ];
108
+ console.log('🔍 Container classes updated:', { isExpanded: isExpanded.value });
109
+ return classes;
110
+ });
111
+
112
+ const overlayClasses = computed(() => [
113
+ "dsEcom-fixed dsEcom-inset-0 dsEcom-bg-black dsEcom-transition-opacity dsEcom-duration-300 dsEcom-ease-in-out dsEcom-z-40",
114
+ {
115
+ "dsEcom-opacity-50": showOverlay.value,
116
+ "dsEcom-opacity-0 dsEcom-pointer-events-none": !showOverlay.value
117
+ }
118
+ ]);
119
+
120
+ const originalContainer = ref<HTMLElement | null>(null);
121
+ const expandedContainer = ref<HTMLElement | null>(null);
122
+
123
+ const updateExpandedPosition = () => {
124
+ if (originalContainer.value && expandedContainer.value) {
125
+ const rect = originalContainer.value.getBoundingClientRect();
126
+ const viewportHeight = window.innerHeight;
127
+
128
+ // Si el input original está fuera de la vista (arriba o abajo), posicionamos el expandido en una posición visible
129
+ let topPosition;
130
+ if (rect.top < 0) {
131
+ topPosition = '20px'; // Si está arriba de la vista, lo ponemos cerca del tope
132
+ } else if (rect.top > viewportHeight) {
133
+ topPosition = '20px'; // Si está abajo de la vista, también lo ponemos cerca del tope
134
+ } else {
135
+ topPosition = `${rect.top}px`; // Si está visible, mantenemos su posición actual
136
+ }
137
+
138
+ expandedContainer.value.style.position = 'fixed';
139
+ expandedContainer.value.style.top = topPosition;
140
+ expandedContainer.value.style.left = '50%';
141
+ expandedContainer.value.style.transform = 'translateX(-50%)';
142
+ expandedContainer.value.style.width = '656px';
143
+ expandedContainer.value.style.maxWidth = '90vw';
144
+ }
145
+ };
146
+
147
+ onMounted(() => {
148
+ console.log('🔍 Component mounted');
149
+ window.addEventListener('resize', updateExpandedPosition);
150
+ });
151
+
152
+ onBeforeUnmount(() => {
153
+ console.log('🔍 Component will unmount');
154
+ window.removeEventListener('resize', updateExpandedPosition);
155
+ });
156
+
157
+ watch(isExpanded, (newValue) => {
158
+ console.log('🔍 isExpanded changed:', {
159
+ newValue,
160
+ searchQuery: searchQuery.value,
161
+ showOverlay: showOverlay.value
162
+ });
163
+ if (newValue) {
164
+ nextTick(updateExpandedPosition);
165
+ }
166
+ });
167
+
168
+ watch(() => props.forceClose, (newValue) => {
169
+ console.log('🔍 forceClose prop changed:', newValue);
170
+ if (newValue) {
171
+ closeSearch();
172
+ }
173
+ });
174
+
175
+ watch(() => props.modelValue, (newValue) => {
176
+ console.log('🔍 modelValue prop changed:', {
177
+ newValue,
178
+ currentSearchQuery: searchQuery.value
179
+ });
180
+ if (newValue !== searchQuery.value) {
181
+ searchQuery.value = newValue;
182
+ }
183
+ });
184
+
185
+ const buttonClasses = computed(() => {
186
+ const defaultClasses = "dsEcom-absolute dsEcom-right-0 dsEcom-top-1/2 -dsEcom-translate-y-1/2 dsEcom-p-2 dsEcom-rounded-r-lg dsEcom-transition-all dsEcom-duration-300";
187
+
188
+ // Si hay buttonClass, usamos esas clases directamente
189
+ if (props.buttonClass) {
190
+ return [defaultClasses, props.buttonClass];
191
+ }
192
+
193
+ // Si no, usamos las clases de color tradicionales
194
+ return [
195
+ defaultClasses,
196
+ props.buttonColorClass,
197
+ props.buttonTextColorClass
198
+ ];
199
+ });
200
+ </script>
201
+
202
+ <template>
203
+ <div class="dsEcom-relative">
204
+ <div
205
+ :class="[containerClasses, props.containerClass]"
206
+ ref="originalContainer"
207
+ >
208
+ <div class="dsEcom-relative" :class="{ 'dsEcom-invisible': isExpanded }">
209
+ <input
210
+ v-model="searchQuery"
211
+ type="text"
212
+ :placeholder="placeholder"
213
+ :disabled="isDisabled"
214
+ :class="[
215
+ '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',
216
+ props.inputClass,
217
+ { 'dsEcom-opacity-0': isExpanded }
218
+ ]"
219
+ @focus="handleFocus"
220
+ @input="handleInput"
221
+ @keyup.enter="handleSearch"
222
+ />
223
+ <div class="dsEcom-absolute dsEcom-right-0 dsEcom-inset-y-0 dsEcom-flex dsEcom-items-stretch">
224
+ <button
225
+ v-if="searchQuery.length >= 3"
226
+ @click="clearSearch"
227
+ :class="[
228
+ 'dsEcom-flex dsEcom-items-center dsEcom-px-1.5 dsEcom-text-neutral-100 hover:dsEcom-text-neutral-80 dsEcom-transition-all dsEcom-duration-300',
229
+ props.inputClass
230
+ ]"
231
+ >
232
+ <LauEcomUpcIconClose width="16" height="16" />
233
+ </button>
234
+
235
+ <button
236
+ @click="handleSearch"
237
+ :class="[
238
+ 'dsEcom-flex dsEcom-items-center dsEcom-px-3 dsEcom-transition-all dsEcom-duration-300',
239
+ props.inputClass?.includes('rounded') ? props.inputClass : 'dsEcom-rounded-r-lg',
240
+ props.buttonColorClass,
241
+ props.buttonTextColorClass,
242
+ 'dsEcom-border-0'
243
+ ]"
244
+ style="margin: 1px; height: calc(100% - 2px);"
245
+ >
246
+ <LauEcomUpcIconSearch width="20" height="20" color="currentColor" />
247
+ </button>
248
+ </div>
249
+ </div>
250
+ </div>
251
+
252
+ <!-- Overlay -->
253
+ <div
254
+ v-show="isExpanded"
255
+ :class="overlayClasses"
256
+ @click="closeSearch"
257
+ ></div>
258
+
259
+ <!-- Versión expandida -->
260
+ <div
261
+ v-show="isExpanded"
262
+ class="dsEcom-fixed dsEcom-z-50 dsEcom-bg-white dsEcom-shadow-lg dsEcom-overflow-hidden"
263
+ :class="[props.inputClass?.includes('rounded') ? props.inputClass : 'dsEcom-rounded-lg']"
264
+ ref="expandedContainer"
265
+ >
266
+ <div class="dsEcom-relative">
267
+ <input
268
+ v-model="searchQuery"
269
+ type="text"
270
+ :placeholder="placeholder"
271
+ :disabled="isDisabled"
272
+ :class="[
273
+ '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',
274
+ props.inputClass
275
+ ]"
276
+ @input="handleInput"
277
+ @keyup.enter="handleSearch"
278
+ autofocus
279
+ />
280
+ <div class="dsEcom-absolute dsEcom-right-0 dsEcom-inset-y-0 dsEcom-flex dsEcom-items-stretch">
281
+ <button
282
+ v-if="searchQuery.length >= 3"
283
+ @click="clearSearch"
284
+ :class="[
285
+ 'dsEcom-flex dsEcom-items-center dsEcom-px-1.5 dsEcom-text-neutral-100 hover:dsEcom-text-neutral-80 dsEcom-transition-all dsEcom-duration-300',
286
+ props.inputClass
287
+ ]"
288
+ >
289
+ <LauEcomUpcIconClose width="16" height="16" />
290
+ </button>
291
+
292
+ <button
293
+ @click="handleSearch"
294
+ :class="[
295
+ 'dsEcom-flex dsEcom-items-center dsEcom-px-3 dsEcom-transition-all dsEcom-duration-300',
296
+ { 'dsEcom-rounded-r-lg': !props.inputClass?.includes('rounded') },
297
+ props.buttonColorClass,
298
+ props.buttonTextColorClass,
299
+ 'dsEcom-border-0'
300
+ ]"
301
+ style="margin: 1px; height: calc(100% - 2px);"
302
+ >
303
+ <LauEcomUpcIconSearch width="20" height="20" color="currentColor" />
304
+ </button>
305
+ </div>
306
+ </div>
307
+ </div>
308
+ </div>
309
+ </template>
310
+
311
+ <style scoped>
312
+ .lau-ecom-input {
313
+ transition: all 0.3s ease-in-out;
314
+ }
315
+
316
+ .dsEcom-transform-gpu {
317
+ transform: translateZ(0);
318
+ backface-visibility: hidden;
319
+ perspective: 1000px;
320
+ }
321
+ </style>
322
+
323
+