@luis-angel-martin-dzul/input-styles 0.0.29 → 0.0.32

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/README.md CHANGED
@@ -6,7 +6,7 @@ Incluye componentes de inputs, selects, botones, paginación y más, estilizados
6
6
 
7
7
  ------
8
8
 
9
- ![Última actualización](https://img.shields.io/badge/Actualizado-28%20de%20Agosto%20del%2026-blue)
9
+ ![Última actualización](https://img.shields.io/badge/Actualizado-16%20de%20Septiembre%20del%2026-blue)
10
10
  ![Versión](https://img.shields.io/badge/versión-0.0.29-indigo)
11
11
 
12
12
  ------
@@ -281,6 +281,9 @@ La mayoría de los componentes comparten las siguientes props:
281
281
  | Prop | Tipo | Default | Descripción |
282
282
  | ---- | ---- | ------- | ----------- |
283
283
  | `modelValue` | `String \| Number \| Boolean` | — | Valor del campo (v-model). |
284
+ | `id` | `String` | `null` | Id propio del control. Si se omite, se genera automáticamente (uuid) y se mantiene enlazado con el `<label for>`. |
285
+ | `name` | `String` | `null` | Atributo `name` nativo del control (`input` / `textarea` / `file` / `button`). Útil para envío de formularios, autocompletado y accesibilidad. |
286
+ | `autofocus` | `Boolean` | `false` | Enfoca el campo automáticamente al montarse. |
284
287
  | `label` | `String` | `''` | Texto del label del campo. |
285
288
  | `description` | `String` | `''` | Texto de ayuda debajo del campo. Cambia de color según el estado de validación. |
286
289
  | `placeholder` | `String` | `''` | Placeholder del input. |
@@ -317,6 +320,11 @@ Input de texto genérico. Soporta tipos `text`, `email`, `search`, `tel`, `url`
317
320
  | Prop | Tipo | Default | Descripción |
318
321
  | ---- | ---- | ------- | ----------- |
319
322
  | `modelValue` | `String \| Number` | `''` | Valor del campo. |
323
+ | `name` | `String` | `null` | Atributo `name` nativo del `<input>`. |
324
+ | `id` | `String` | `null` | Id propio; si se omite se genera y se enlaza al `<label>`. |
325
+ | `autocomplete` | `String` | `null` | Atributo `autocomplete` nativo (ej: `email`, `username`, `off`). |
326
+ | `autofocus` | `Boolean` | `false` | Enfoca el campo al montarse. |
327
+ | `readonly` | `Boolean` | `false` | Solo lectura: no editable, pero se envía en el formulario. |
320
328
  | `label` | `String` | `''` | |
321
329
  | `description` | `String` | `''` | |
322
330
  | `placeholder` | `String` | `''` | |
@@ -351,6 +359,11 @@ Input numérico con control preciso de dígitos, decimales, rango y formato de v
351
359
  | Prop | Tipo | Default | Descripción |
352
360
  | ---- | ---- | ------- | ----------- |
353
361
  | `modelValue` | `String \| Number` | `''` | Valor del campo. |
362
+ | `name` | `String` | `null` | Atributo `name` nativo del `<input>`. |
363
+ | `id` | `String` | `null` | Id propio; si se omite se genera y se enlaza al `<label>`. |
364
+ | `autocomplete` | `String` | `null` | Atributo `autocomplete` nativo. |
365
+ | `autofocus` | `Boolean` | `false` | Enfoca el campo al montarse. |
366
+ | `readonly` | `Boolean` | `false` | Solo lectura: bloquea la edición y los botones ▲/▼, pero se envía en el formulario. |
354
367
  | `label` | `String` | `''` | |
355
368
  | `description` | `String` | `''` | |
356
369
  | `placeholder` | `String` | `''` | |
@@ -392,6 +405,11 @@ Input de contraseña con toggle para mostrar/ocultar el texto.
392
405
  | Prop | Tipo | Default | Descripción |
393
406
  | ---- | ---- | ------- | ----------- |
394
407
  | `modelValue` | `String \| Number` | `''` | Valor del campo. |
408
+ | `name` | `String` | `null` | Atributo `name` nativo del `<input>`. |
409
+ | `id` | `String` | `null` | Id propio; si se omite se genera y se enlaza al `<label>`. |
410
+ | `autocomplete` | `String` | `null` | Atributo `autocomplete` nativo (ej: `current-password`, `new-password`). |
411
+ | `autofocus` | `Boolean` | `false` | Enfoca el campo al montarse. |
412
+ | `readonly` | `Boolean` | `false` | Solo lectura: no editable, pero se envía en el formulario. |
395
413
  | `label` | `String` | `''` | |
396
414
  | `description` | `String` | `''` | |
397
415
  | `placeholder` | `String` | `''` | |
@@ -421,6 +439,11 @@ Input de contraseña con toggle para mostrar/ocultar el texto.
421
439
  | Prop | Tipo | Default | Descripción |
422
440
  | ---- | ---- | ------- | ----------- |
423
441
  | `modelValue` | `String` | `''` | Valor del campo. |
442
+ | `name` | `String` | `null` | Atributo `name` nativo del `<textarea>`. |
443
+ | `id` | `String` | `null` | Id propio; si se omite se genera y se enlaza al `<label>`. |
444
+ | `autocomplete` | `String` | `null` | Atributo `autocomplete` nativo. |
445
+ | `autofocus` | `Boolean` | `false` | Enfoca el campo al montarse. |
446
+ | `readonly` | `Boolean` | `false` | Solo lectura: no editable, pero se envía en el formulario. |
424
447
  | `label` | `String` | `''` | |
425
448
  | `description` | `String` | `''` | |
426
449
  | `placeholder` | `String` | `''` | |
@@ -474,6 +497,9 @@ const ubicaciones = [
474
497
  | `modelValue` | `String \| Number \| Object` | — | Valor seleccionado. |
475
498
  | `list` | `Array` | `[]` | Array de opciones. Acepta lista plana `{ value, text }` o agrupada `{ label, options: [...] }`. El `value` es opcional: si se omite, se usa el `text` como valor. |
476
499
  | `returnValue` | `String` | `'value'` | Qué se emite al seleccionar: `'value'` (item.value), `'text'` (item.text) u `'object'` (el item completo). |
500
+ | `name` | `String` | `null` | Atributo `name` nativo del `<input>`. |
501
+ | `id` | `String` | `null` | Id propio; si se omite se genera y se enlaza al `<label>`. |
502
+ | `autofocus` | `Boolean` | `false` | Enfoca el campo al montarse. |
477
503
  | `label` | `String` | `''` | |
478
504
  | `description` | `String` | `''` | |
479
505
  | `wrapOptions` | `Boolean` | `false` | `true` = permite que el texto de cada opción haga salto de línea; `false` = lo trunca con elipsis. |
@@ -536,6 +562,9 @@ const paises = [
536
562
  | `list` | `Array` | `[]` | Array de opciones. Acepta lista plana `{ value, text }` o agrupada `{ label, options: [...] }`. El `value` es opcional: si se omite, se usa el `text` como valor. |
537
563
  | `returnValue` | `String` | `'value'` | Qué se emite al seleccionar: `'value'` (item.value), `'text'` (item.text) u `'object'` (el item completo). |
538
564
  | `loading` | `Boolean` | `false` | Cuando es `true`, oculta las opciones y muestra "Buscando coincidencias...". Úsalo mientras resuelves una búsqueda asíncrona. |
565
+ | `name` | `String` | `null` | Atributo `name` nativo del `<input>`. |
566
+ | `id` | `String` | `null` | Id propio; si se omite se genera y se enlaza al `<label>`. |
567
+ | `autofocus` | `Boolean` | `false` | Enfoca el campo al montarse. |
539
568
  | `label` | `String` | `''` | |
540
569
  | `description` | `String` | `''` | |
541
570
  | `placeholder` | `String` | `''` | |
@@ -576,7 +605,10 @@ Checkbox estilizado con label y descripción.
576
605
 
577
606
  | Prop | Tipo | Default | Descripción |
578
607
  | ---- | ---- | ------- | ----------- |
579
- | `modelValue` | `Boolean` | `false` | Estado del checkbox. |
608
+ | `modelValue` | `Boolean \| Array \| String \| Number` | `false` | Estado del check (modo simple) o array de valores seleccionados (modo grupo). |
609
+ | `value` | `String \| Number \| Boolean` | `null` | Valor que aporta este checkbox al grupo. Se usa cuando `modelValue` es un `Array` (checkbox múltiple nativo). |
610
+ | `name` | `String` | `null` | Atributo `name` nativo del `<input>`. Comparte el mismo `name` entre las casillas del grupo. |
611
+ | `id` | `String` | `null` | Id propio del `<input>`; si se omite se genera automáticamente. |
580
612
  | `label` | `String` | `''` | |
581
613
  | `description` | `String` | `''` | |
582
614
  | `disabled` | `Boolean` | `false` | |
@@ -584,6 +616,32 @@ Checkbox estilizado con label y descripción.
584
616
  | `validate` | `Boolean \| null` | `null` | |
585
617
  | `mclass` | `String` | `null` | Clases adicionales del cuadro del checkbox. |
586
618
 
619
+ **Dos modos de uso:**
620
+
621
+ - **Modo simple (por defecto):** con `modelValue` booleano, se comporta como un check `true`/`false`.
622
+
623
+ ```vue
624
+ <InputCheckStyle v-model="acepto" label="Acepto los términos" />
625
+ ```
626
+
627
+ - **Modo grupo nativo:** enlaza varias casillas a un `v-model` de tipo **array**, cada una con su `value` y el mismo `name`. Marcar/desmarcar agrega o quita el `value` del array, y en un `<form>` nativo el navegador envía un `name=<value>` por cada casilla marcada (`FormData.getAll`).
628
+
629
+ ```vue
630
+ <form @submit.prevent="onSubmit">
631
+ <InputCheckStyle v-model="perms" name="perm" value="read" label="Leer" />
632
+ <InputCheckStyle v-model="perms" name="perm" value="write" label="Escribir" />
633
+ <InputCheckStyle v-model="perms" name="perm" value="delete" label="Eliminar" />
634
+ </form>
635
+ ```
636
+
637
+ ```js
638
+ // perms === ['read', 'write'] → FormData del <form>: perm=read, perm=write
639
+ data() { return { perms: ['read', 'write'] } },
640
+ onSubmit(e) { console.log(new FormData(e.target).getAll('perm')) }
641
+ ```
642
+
643
+ **Eventos:** `update:modelValue` y `change` emiten el array actualizado (modo grupo) o el booleano (modo simple).
644
+
587
645
  ------
588
646
 
589
647
  ## InputRadioStyle
@@ -599,7 +657,10 @@ Radio button estilizado con label y descripción.
599
657
 
600
658
  | Prop | Tipo | Default | Descripción |
601
659
  | ---- | ---- | ------- | ----------- |
602
- | `modelValue` | `Boolean` | `false` | Estado del radio. |
660
+ | `modelValue` | `String \| Number \| Boolean` | `false` | Valor seleccionado del grupo (modo grupo) o estado del toggle (modo booleano). |
661
+ | `value` | `String \| Number \| Boolean` | `null` | Valor que representa este radio dentro del grupo. Si se define, actúa como radio nativo real (`type="radio"`); si se omite, se comporta como toggle booleano. |
662
+ | `name` | `String` | `null` | Atributo `name` nativo del `<input>`. **Requerido** para agrupar varios radios en modo nativo. |
663
+ | `id` | `String` | `null` | Id propio del `<input>`; si se omite se genera automáticamente. |
603
664
  | `label` | `String` | `''` | |
604
665
  | `description` | `String` | `''` | |
605
666
  | `disabled` | `Boolean` | `false` | |
@@ -607,6 +668,31 @@ Radio button estilizado con label y descripción.
607
668
  | `validate` | `Boolean \| null` | `null` | |
608
669
  | `mclass` | `String` | `null` | Clases adicionales del círculo del radio. |
609
670
 
671
+ **Dos modos de uso:**
672
+
673
+ - **Modo booleano (por defecto):** sin `value`, se comporta como un toggle `true`/`false`. Útil para una sola opción.
674
+
675
+ ```vue
676
+ <InputRadioStyle v-model="acepto" label="Acepto" />
677
+ ```
678
+
679
+ - **Modo grupo nativo:** al definir `value` en cada radio y compartir el mismo `name`, se comportan como un grupo de radios reales (`type="radio"`): seleccionar uno deselecciona los demás, `v-model` guarda el `value` elegido y en un `<form>` nativo el navegador envía `name=<value seleccionado>`.
680
+
681
+ ```vue
682
+ <form @submit.prevent="onSubmit">
683
+ <InputRadioStyle v-model="plan" name="plan" value="free" label="Free" />
684
+ <InputRadioStyle v-model="plan" name="plan" value="pro" label="Pro" />
685
+ <InputRadioStyle v-model="plan" name="plan" value="enterprise" label="Enterprise" />
686
+ </form>
687
+ ```
688
+
689
+ ```js
690
+ // plan === 'pro' → FormData del <form> contiene plan=pro
691
+ onSubmit(e) { console.log(new FormData(e.target).get('plan')) }
692
+ ```
693
+
694
+ **Eventos:** `update:modelValue` y `change` emiten el `value` seleccionado (modo grupo) o el booleano (modo toggle).
695
+
610
696
  ------
611
697
 
612
698
  ## InputSwitchStyle
@@ -623,6 +709,8 @@ Toggle switch estilizado.
623
709
  | Prop | Tipo | Default | Descripción |
624
710
  | ---- | ---- | ------- | ----------- |
625
711
  | `modelValue` | `Boolean` | `false` | Estado del switch. |
712
+ | `name` | `String` | `null` | Atributo `name` nativo del `<input>`. |
713
+ | `id` | `String` | `null` | Id propio del `<input>`; si se omite se genera automáticamente. |
626
714
  | `label` | `String` | `''` | |
627
715
  | `description` | `String` | `''` | |
628
716
  | `disabled` | `Boolean` | `false` | |
@@ -651,6 +739,9 @@ El calendario incluye vistas de días, meses y años, y un botón **Hoy** para n
651
739
  | Prop | Tipo | Default | Descripción |
652
740
  | ---- | ---- | ------- | ----------- |
653
741
  | `modelValue` | `String \| Date` | — | Valor de la fecha en formato `YYYY-MM-DD` o `Date`. |
742
+ | `name` | `String` | `null` | Atributo `name` nativo del `<input>`. |
743
+ | `id` | `String` | `null` | Id propio; si se omite se genera y se enlaza al `<label>`. |
744
+ | `autofocus` | `Boolean` | `false` | Enfoca el campo al montarse. |
654
745
  | `label` | `String` | `''` | |
655
746
  | `description` | `String` | `''` | |
656
747
  | `min` | `String` | `'1900-01-01'` | Fecha mínima seleccionable en el calendario (formato `YYYY-MM-DD`). |
@@ -692,6 +783,9 @@ Selector de hora con picker de columnas scrollables. Soporta formato 12h (AM/PM)
692
783
  | Prop | Tipo | Default | Descripción |
693
784
  | ---- | ---- | ------- | ----------- |
694
785
  | `modelValue` | `String` | — | Valor de la hora en formato `HH:mm`. |
786
+ | `name` | `String` | `null` | Atributo `name` nativo del `<input>`. |
787
+ | `id` | `String` | `null` | Id propio; si se omite se genera y se enlaza al `<label>`. |
788
+ | `autofocus` | `Boolean` | `false` | Enfoca el campo al montarse. |
695
789
  | `label` | `String` | `''` | |
696
790
  | `description` | `String` | `''` | |
697
791
  | `min` | `String` | `null` | Hora mínima (ej: `'08:00'`). |
@@ -724,6 +818,9 @@ Selector combinado de fecha y hora con máscara `dd/mm/aaaa hh:mm` (o `dd/mm/aaa
724
818
  | Prop | Tipo | Default | Descripción |
725
819
  | ---- | ---- | ------- | ----------- |
726
820
  | `modelValue` | `String \| Date` | — | Valor en formato `YYYY-MM-DDTHH:mm:00.000` o `Date`. |
821
+ | `name` | `String` | `null` | Atributo `name` nativo del `<input>`. |
822
+ | `id` | `String` | `null` | Id propio; si se omite se genera y se enlaza al `<label>`. |
823
+ | `autofocus` | `Boolean` | `false` | Enfoca el campo al montarse. |
727
824
  | `label` | `String` | `''` | |
728
825
  | `description` | `String` | `''` | |
729
826
  | `min` | `String` | `'1900-01-01'` | Fecha mínima seleccionable (formato `YYYY-MM-DD`). |
@@ -770,6 +867,8 @@ Botón para adjuntar archivos con validación de tamaño y formato.
770
867
  | Prop | Tipo | Default | Descripción |
771
868
  | ---- | ---- | ------- | ----------- |
772
869
  | `modelValue` | `File` | `null` | Archivo seleccionado. |
870
+ | `name` | `String` | `null` | Atributo `name` nativo del `<input type="file">`. |
871
+ | `id` | `String` | `null` | Id propio del `<input type="file">`. |
773
872
  | `disabled` | `Boolean` | `false` | Deshabilita el botón. |
774
873
  | `formats` | `Array` | `[]` | Extensiones permitidas (ej: `['pdf', 'xlsx', 'png']`). Array vacío = todos los formatos. |
775
874
  | `maxSizeMB` | `String \| Number` | `5` | Tamaño máximo del archivo en MB. |
@@ -824,6 +923,9 @@ Botón genérico con bloqueo automático anti-doble-clic.
824
923
  | Prop | Tipo | Default | Descripción |
825
924
  | ---- | ---- | ------- | ----------- |
826
925
  | `type` | `String` | `'button'` | Tipo del botón: `'button'` o `'submit'`. |
926
+ | `name` | `String` | `null` | Atributo `name` nativo del `<button>`. |
927
+ | `id` | `String` | `null` | Id propio del `<button>`. |
928
+ | `autofocus` | `Boolean` | `false` | Enfoca el botón al montarse. |
827
929
  | `class` | `String` | `''` | Clases CSS del botón (TailwindCSS). |
828
930
  | `disabled` | `Boolean` | `false` | Deshabilita el botón. |
829
931
  | `delay` | `String` | `'1.5'` | Segundos de bloqueo automático tras hacer clic (anti-doble-clic). |
@@ -833,6 +935,8 @@ Botón genérico con bloqueo automático anti-doble-clic.
833
935
 
834
936
  Acepta contenido mediante `<slot>` (texto, íconos, etc.).
835
937
 
938
+ > **Nota:** con `type="submit"` funciona como botón de envío nativo dentro de un `<form>`. El bloqueo anti-doble-clic se aplica de forma diferida para no cancelar el envío nativo del formulario.
939
+
836
940
  ------
837
941
 
838
942
  ## LoaderStyle
@@ -997,6 +1101,7 @@ UtilStyle.getUUID()
997
1101
  | `formatDateTimeShort(dateString, hour12?)` | `String, Boolean` | Fecha y hora en formato corto en español (ej: `9 jul 2026, 12:00 p. m.`). `hour12` (default `true`) alterna entre 12h y 24h. |
998
1102
  | `formatDateTimeLong(dateString, hour12?)` | `String, Boolean` | Fecha y hora en formato largo en español (ej: `9 de julio de 2026, 12:00 p. m.`). `hour12` (default `true`) alterna entre 12h y 24h. |
999
1103
  | `getDateTimeNow()` | — | Fecha y hora actual (zona `America/Mexico_City`) en formato `YYYY-MM-DDTHH:mm:ss`. |
1104
+ | `porcentaje(valor, total)` | `Number, Number` | Calcula el porcentaje de `valor` respecto a `total` (ej: `50`). Retorna `0` si `total` es `0` o negativo. |
1000
1105
  | `blockKeyNumber(event)` | `Event` | Bloquea las teclas `e`, `E`, `+`, `-` en un `@keydown`. |
1001
1106
  | `blockKeys(event, keys)` | `Event, Array` | Bloquea las teclas indicadas en un `@keydown`. |
1002
1107
  | `validateTel(value, required?)` | `String, Boolean` | Valida un teléfono con formato `999 9 99 99 99`. Acepta prefijo de región opcional `+XXX 999 9 99 99 99` (XXX = 1 a 3 dígitos). Retorna `true` o mensaje de error. |
@@ -1,2 +1,2 @@
1
- .alert-container{z-index:99999;flex-direction:column;gap:10px;width:340px;display:flex;position:fixed;top:20px;right:20px}.alert{opacity:0;background-color:#f9fafb;border:1px solid #0000;border-radius:.375rem;align-items:center;gap:12px;padding:12px 16px;transition:opacity .25s,transform .25s;display:flex;transform:translate(40px);box-shadow:0 2px 6px #0000001f}.alert.show{opacity:1;transform:translate(0)}.alert.hide{opacity:0;transform:translate(40px)}.alert-icon{justify-content:center;align-items:center;width:26px;display:flex}.alert-icon svg{width:22px;height:22px;display:block}.alert-icon svg path{fill:currentColor!important}.alert-texts{flex:1}.alert-title{text-overflow:ellipsis;font-size:14px;font-weight:700;overflow:hidden}.alert-message{-webkit-box-orient:vertical;margin-top:2px;font-size:13px;display:-webkit-box;overflow:hidden}.alert-close{cursor:pointer;border-radius:.5rem;justify-content:center;align-items:center;width:28px;height:28px;font-size:18px;font-weight:700;transition:all .2s;display:flex}.alert-close:hover{background:#d1d5db}.alert-success{color:#065f46;background-color:#ecfdf5;border-color:#b4dfc6}.alert-error{color:#991b1b;background-color:#fef2f2;border-color:#f0c5c5}.alert-warning{color:#92400e;background-color:#fffbeb;border-color:#f0dfa5}.alert-info{color:#1e40af;background-color:#eff6ff;border-color:#c7daf5}.alert-neutral{color:#374151;background-color:#f3f4f6;border-color:#cbd5e1}.dialog-overlay{z-index:99998;opacity:0;background:#00000073;justify-content:center;align-items:center;width:100%;height:100%;transition:opacity .25s;display:flex;position:fixed;top:0;left:0}.dialog-overlay.show{opacity:1}.dialog-box{background:#fff;border-radius:.5rem;flex-direction:column;width:400px;max-width:90%;max-height:90vh;padding:1rem;transition:transform .25s;display:flex;transform:translateY(-20px);box-shadow:0 25px 50px -12px #00000040}.dialog-overlay.show .dialog-box{transform:translateY(0)}.dialog-box.fixed-width{width:380px;max-width:90%}.dialog-title{color:#1f2937;font-size:18px;font-weight:700}.dialog-description{color:#374151;white-space:pre-line;margin-bottom:10px;font-size:14px}.dialog-buttons{gap:10px;margin-top:10px;display:flex}.dialog-buttons.two-buttons{grid-template-columns:1fr 1fr;gap:10px;display:grid}.dialog-buttons.one-button{display:flex}.dialog-buttons.one-button .dialog-btn{flex:1}.dialog-btn{cursor:pointer;text-align:center;justify-content:center;align-items:center;gap:6px;font-size:14px;font-weight:600;transition:all .2s;display:inline-flex}.dialog-buttons .dialog-btn{flex:1}.btn-blue{color:#fff;cursor:pointer;background-color:#0284c7;border:none;border-radius:.125rem;padding:.25rem .5rem;font-size:.75rem;transition:background-color .2s}.btn-blue:hover{background-color:#0ea5e9}.btn-blue:disabled{color:#6b7280;cursor:not-allowed;background-color:#7dd3fc}.btn-white{color:#374151;cursor:pointer;background-color:#fff;border:1px solid #d1d5db;border-radius:.125rem;padding:.25rem .5rem;font-size:.75rem;transition:background-color .2s}.btn-white:hover{background-color:#f3f4f6}.btn-white:disabled{color:#6b7280;cursor:not-allowed;background-color:#d1d5db}.dialog-btn-cancel{color:#374151;cursor:pointer;background-color:#fff;border:1px solid #d1d5db;border-radius:.125rem;padding:.25rem .5rem;font-size:.75rem;transition:background-color .2s}.dialog-btn-cancel:hover{background-color:#f3f4f6}.dialog-btn-cancel:disabled{color:#6b7280;cursor:not-allowed;background-color:#d1d5db}.dialog-btn-accept{color:#fff;cursor:pointer;background-color:#0284c7;border:none;border-radius:.125rem;padding:.25rem .5rem;font-size:.75rem;transition:background-color .2s}.dialog-btn-accept:hover{background-color:#0ea5e9}.dialog-btn-accept:disabled{color:#6b7280;cursor:not-allowed;background-color:#7dd3fc}.dialog-loading-layout{gap:16px;min-height:60px;margin-top:16px;display:flex}.dialog-loading-icon{flex-shrink:0;align-items:center;min-height:60px;display:flex}.dialog-loading-spinner{border:3px solid #e5e7eb;border-top-color:#0d9488;border-radius:50%;width:40px;height:40px;animation:.8s linear infinite dialog-spin}.dialog-loading-texts{flex-direction:column;flex:1;justify-content:center;gap:4px;display:flex}.dialog-loading-title{color:#1f2937;font-size:15px;font-weight:600;line-height:1.4}.dialog-loading-message{color:#6b7280;font-size:13px;line-height:1.4}@keyframes dialog-spin{to{transform:rotate(360deg)}}@keyframes dialogShake{0%{transform:translateY(0)}30%{transform:translateY(-6px)}60%{transform:translateY(3px)}to{transform:translateY(0)}}.dialog-shake{animation:.25s dialogShake}.dialog-box:has(.dialog-loading-layout) .dialog-title{display:none}.dialog-box:has(.dialog-loading-layout) .dialog-description{display:none}.dialog-box:has(.dialog-loading-layout:only-child){padding:1rem}.dialog-box:has(.dialog-loading-layout):not(:has(.dialog-buttons)){padding-bottom:1rem}.dialog-box:has(.dialog-loading-layout:first-child:last-child) .dialog-loading-layout{margin-top:0}input[type=date][data-v-756569d8]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=datetime-local][data-v-756569d8]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=time][data-v-756569d8]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=date][data-v-756569d8],input[type=datetime-local][data-v-756569d8],input[type=time][data-v-756569d8]{appearance:none;-moz-appearance:textfield}input[type=date][data-v-f9c04d0f]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=datetime-local][data-v-f9c04d0f]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=time][data-v-f9c04d0f]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=date][data-v-f9c04d0f],input[type=datetime-local][data-v-f9c04d0f],input[type=time][data-v-f9c04d0f]{appearance:none;-moz-appearance:textfield}input[type=date][data-v-3968f4d1]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=datetime-local][data-v-3968f4d1]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=time][data-v-3968f4d1]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=date][data-v-3968f4d1],input[type=datetime-local][data-v-3968f4d1],input[type=time][data-v-3968f4d1]{appearance:none;-moz-appearance:textfield}
1
+ .alert-container{z-index:99999;flex-direction:column;gap:10px;width:340px;display:flex;position:fixed;top:20px;right:20px}.alert{opacity:0;background-color:#f9fafb;border:1px solid #0000;border-radius:.375rem;align-items:center;gap:12px;padding:12px 16px;transition:opacity .25s,transform .25s;display:flex;transform:translate(40px);box-shadow:0 2px 6px #0000001f}.alert.show{opacity:1;transform:translate(0)}.alert.hide{opacity:0;transform:translate(40px)}.alert-icon{justify-content:center;align-items:center;width:26px;display:flex}.alert-icon svg{width:22px;height:22px;display:block}.alert-icon svg path{fill:currentColor!important}.alert-texts{flex:1}.alert-title{text-overflow:ellipsis;font-size:14px;font-weight:700;overflow:hidden}.alert-message{-webkit-box-orient:vertical;margin-top:2px;font-size:13px;display:-webkit-box;overflow:hidden}.alert-close{cursor:pointer;border-radius:.5rem;justify-content:center;align-items:center;width:28px;height:28px;font-size:18px;font-weight:700;transition:all .2s;display:flex}.alert-close:hover{background:#d1d5db}.alert-success{color:#065f46;background-color:#ecfdf5;border-color:#b4dfc6}.alert-error{color:#991b1b;background-color:#fef2f2;border-color:#f0c5c5}.alert-warning{color:#92400e;background-color:#fffbeb;border-color:#f0dfa5}.alert-info{color:#1e40af;background-color:#eff6ff;border-color:#c7daf5}.alert-neutral{color:#374151;background-color:#f3f4f6;border-color:#cbd5e1}.dialog-overlay{z-index:99998;opacity:0;background:#00000073;justify-content:center;align-items:center;width:100%;height:100%;transition:opacity .25s;display:flex;position:fixed;top:0;left:0}.dialog-overlay.show{opacity:1}.dialog-box{background:#fff;border-radius:.5rem;flex-direction:column;width:400px;max-width:90%;max-height:90vh;padding:1rem;transition:transform .25s;display:flex;transform:translateY(-20px);box-shadow:0 25px 50px -12px #00000040}.dialog-overlay.show .dialog-box{transform:translateY(0)}.dialog-box.fixed-width{width:380px;max-width:90%}.dialog-title{color:#1f2937;font-size:18px;font-weight:700}.dialog-description{color:#374151;white-space:pre-line;margin-bottom:10px;font-size:14px}.dialog-buttons{gap:10px;margin-top:10px;display:flex}.dialog-buttons.two-buttons{grid-template-columns:1fr 1fr;gap:10px;display:grid}.dialog-buttons.one-button{display:flex}.dialog-buttons.one-button .dialog-btn{flex:1}.dialog-btn{cursor:pointer;text-align:center;justify-content:center;align-items:center;gap:6px;font-size:14px;font-weight:600;transition:all .2s;display:inline-flex}.dialog-buttons .dialog-btn{flex:1}.btn-blue{color:#fff;cursor:pointer;background-color:#0284c7;border:none;border-radius:.125rem;padding:.25rem .5rem;font-size:.75rem;transition:background-color .2s}.btn-blue:hover{background-color:#0ea5e9}.btn-blue:disabled{color:#6b7280;cursor:not-allowed;background-color:#7dd3fc}.btn-white{color:#374151;cursor:pointer;background-color:#fff;border:1px solid #d1d5db;border-radius:.125rem;padding:.25rem .5rem;font-size:.75rem;transition:background-color .2s}.btn-white:hover{background-color:#f3f4f6}.btn-white:disabled{color:#6b7280;cursor:not-allowed;background-color:#d1d5db}.dialog-btn-cancel{color:#374151;cursor:pointer;background-color:#fff;border:1px solid #d1d5db;border-radius:.125rem;padding:.25rem .5rem;font-size:.75rem;transition:background-color .2s}.dialog-btn-cancel:hover{background-color:#f3f4f6}.dialog-btn-cancel:disabled{color:#6b7280;cursor:not-allowed;background-color:#d1d5db}.dialog-btn-accept{color:#fff;cursor:pointer;background-color:#0284c7;border:none;border-radius:.125rem;padding:.25rem .5rem;font-size:.75rem;transition:background-color .2s}.dialog-btn-accept:hover{background-color:#0ea5e9}.dialog-btn-accept:disabled{color:#6b7280;cursor:not-allowed;background-color:#7dd3fc}.dialog-loading-layout{gap:16px;min-height:60px;margin-top:16px;display:flex}.dialog-loading-icon{flex-shrink:0;align-items:center;min-height:60px;display:flex}.dialog-loading-spinner{border:3px solid #e5e7eb;border-top-color:#0d9488;border-radius:50%;width:40px;height:40px;animation:.8s linear infinite dialog-spin}.dialog-loading-texts{flex-direction:column;flex:1;justify-content:center;gap:4px;display:flex}.dialog-loading-title{color:#1f2937;font-size:15px;font-weight:600;line-height:1.4}.dialog-loading-message{color:#6b7280;font-size:13px;line-height:1.4}@keyframes dialog-spin{to{transform:rotate(360deg)}}@keyframes dialogShake{0%{transform:translateY(0)}30%{transform:translateY(-6px)}60%{transform:translateY(3px)}to{transform:translateY(0)}}.dialog-shake{animation:.25s dialogShake}.dialog-box:has(.dialog-loading-layout) .dialog-title{display:none}.dialog-box:has(.dialog-loading-layout) .dialog-description{display:none}.dialog-box:has(.dialog-loading-layout:only-child){padding:1rem}.dialog-box:has(.dialog-loading-layout):not(:has(.dialog-buttons)){padding-bottom:1rem}.dialog-box:has(.dialog-loading-layout:first-child:last-child) .dialog-loading-layout{margin-top:0}input[type=date][data-v-6906d068]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=datetime-local][data-v-6906d068]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=time][data-v-6906d068]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=date][data-v-6906d068],input[type=datetime-local][data-v-6906d068],input[type=time][data-v-6906d068]{appearance:none;-moz-appearance:textfield}input[type=date][data-v-0b52f379]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=datetime-local][data-v-0b52f379]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=time][data-v-0b52f379]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=date][data-v-0b52f379],input[type=datetime-local][data-v-0b52f379],input[type=time][data-v-0b52f379]{appearance:none;-moz-appearance:textfield}input[type=date][data-v-b6006f07]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=datetime-local][data-v-b6006f07]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=time][data-v-b6006f07]::-webkit-calendar-picker-indicator{-webkit-appearance:none;display:none}input[type=date][data-v-b6006f07],input[type=datetime-local][data-v-b6006f07],input[type=time][data-v-b6006f07]{appearance:none;-moz-appearance:textfield}
2
2
  /*$vite$:1*/