@adamosuiteservices/ui 2.15.0 → 2.16.0

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.
@@ -191,6 +191,14 @@ disabled?: boolean
191
191
 
192
192
  Deshabilita el componente, impidiendo toda interacción del usuario. Por defecto: `false`
193
193
 
194
+ **Comportamiento**:
195
+
196
+ - El área de drag & drop se muestra deshabilitada con opacidad reducida
197
+ - Los archivos seleccionados también se muestran deshabilitados
198
+ - Los botones de eliminar archivos individuales están deshabilitados
199
+ - El botón "Clear all" (en modo múltiple) está deshabilitado
200
+ - Los estados de error visual no se muestran cuando está deshabilitado
201
+
194
202
  **Ejemplo**:
195
203
 
196
204
  ```tsx
@@ -199,6 +207,42 @@ Deshabilita el componente, impidiendo toda interacción del usuario. Por defecto
199
207
 
200
208
  **Nota**: El componente también detecta automáticamente si está dentro de un `<fieldset disabled>` y se deshabilitará automáticamente.
201
209
 
210
+ #### input
211
+
212
+ ```tsx
213
+ input?: ComponentProps<"input">
214
+ ```
215
+
216
+ Props personalizadas para el elemento `<input type="file">` interno. Útil para personalizar el ID, name, data attributes, y otros atributos HTML.
217
+
218
+ **Comportamiento**:
219
+ - Si no se proporciona un `id`, se genera automáticamente con formato `file-upload-{random}`
220
+ - Las props críticas (`type`, `accept`, `multiple`, `onChange`, `disabled`, `className`) siempre se mantienen para garantizar el funcionamiento correcto
221
+ - Puedes sobrescribir cualquier otra prop HTML del input
222
+
223
+ **Ejemplo**:
224
+
225
+ ```tsx
226
+ // ID personalizado para asociar con label
227
+ <FileUpload
228
+ selectedFile={file}
229
+ onFileSelect={setFile}
230
+ input={{ id: "document-upload" }}
231
+ />
232
+
233
+ // Con múltiples atributos para integración con formularios
234
+ <FileUpload
235
+ selectedFile={file}
236
+ onFileSelect={setFile}
237
+ input={{
238
+ id: "invoice-file",
239
+ name: "invoice",
240
+ "data-testid": "invoice-input",
241
+ "aria-describedby": "invoice-help",
242
+ }}
243
+ />
244
+ ```
245
+
202
246
  #### onInvalidFile
203
247
 
204
248
  ```tsx
@@ -458,6 +502,26 @@ function DisabledExample() {
458
502
  </FieldGroup>
459
503
  );
460
504
  }
505
+
506
+ // Con archivo ya seleccionado
507
+ function DisabledWithFileExample() {
508
+ const mockFile = new File(["content"], "report.xlsx", {
509
+ type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
510
+ });
511
+ const [file, setFile] = useState<File | null>(mockFile);
512
+
513
+ return (
514
+ <FieldGroup className="adm:max-w-xl">
515
+ <Field>
516
+ <FieldLabel>Upload document (Disabled)</FieldLabel>
517
+ <FileUpload selectedFile={file} onFileSelect={setFile} disabled />
518
+ <FieldDescription>
519
+ File is selected but cannot be removed while disabled
520
+ </FieldDescription>
521
+ </Field>
522
+ </FieldGroup>
523
+ );
524
+ }
461
525
  ```
462
526
 
463
527
  ### Dentro de Fieldset Disabled
@@ -494,6 +558,44 @@ function FieldsetExample() {
494
558
 
495
559
  **Nota**: El componente detecta automáticamente cuando está dentro de un `<fieldset disabled>` o `<FieldSet disabled>` y se deshabilita automáticamente.
496
560
 
561
+ ### Con Props de Input Personalizadas
562
+
563
+ ```tsx
564
+ import {
565
+ Field,
566
+ FieldLabel,
567
+ FieldDescription,
568
+ FieldGroup,
569
+ } from "@adamosuiteservices/ui/field";
570
+
571
+ function CustomInputPropsExample() {
572
+ const [file, setFile] = useState<File | null>(null);
573
+
574
+ return (
575
+ <FieldGroup className="adm:max-w-xl">
576
+ <Field>
577
+ <FieldLabel htmlFor="custom-document-upload">
578
+ Upload document
579
+ </FieldLabel>
580
+ <FileUpload
581
+ selectedFile={file}
582
+ onFileSelect={setFile}
583
+ input={{
584
+ id: "custom-document-upload",
585
+ name: "document",
586
+ "data-testid": "file-input",
587
+ "aria-describedby": "upload-description",
588
+ }}
589
+ />
590
+ <FieldDescription id="upload-description">
591
+ Custom input props allow you to set ID, name, and other attributes
592
+ </FieldDescription>
593
+ </Field>
594
+ </FieldGroup>
595
+ );
596
+ }
597
+ ```
598
+
497
599
  ### Archivos de Excel (Por Defecto)
498
600
 
499
601
  ````tsx
@@ -598,7 +700,7 @@ Cuando el usuario arrastra archivos sobre el área:
598
700
 
599
701
  ### Estado Inválido
600
702
 
601
- Cuando `invalid={true}`:
703
+ Cuando `invalid={true}` o `aria-invalid={true}`:
602
704
  - Borde: `border-destructive`
603
705
  - Fondo: `bg-destructive/5`
604
706
  - Icono de documento: `text-destructive` con fondo `bg-destructive/10`
@@ -606,6 +708,22 @@ Cuando `invalid={true}`:
606
708
  - Contador de archivos: `text-destructive`
607
709
  - Tarjetas de archivos: borde y fondo con colores destructivos
608
710
 
711
+ ### Estado Deshabilitado
712
+
713
+ Cuando `disabled={true}` o está dentro de `<fieldset disabled>`:
714
+
715
+ **Área de drag & drop**:
716
+ - Opacidad: `opacity-50`
717
+ - Cursor: `cursor-not-allowed`
718
+ - Los estados de error visual no se aplican
719
+
720
+ **Archivos seleccionados**:
721
+ - Opacidad: `opacity-50`
722
+ - Cursor: `cursor-not-allowed`
723
+ - Botón de eliminar deshabilitado
724
+ - Botón "Clear all" deshabilitado (modo múltiple)
725
+ - Los colores destructivos no se muestran aunque `invalid={true}`
726
+
609
727
  ## Validación
610
728
 
611
729
  El componente valida automáticamente:
@@ -861,6 +979,7 @@ export type FileUploadProps = ComponentProps<"div"> & Readonly<{
861
979
  acceptedExtensions?: string[]
862
980
  maxSizeInMB?: number
863
981
  labels?: FileUploadLabels
982
+ input?: ComponentProps<"input">
864
983
  }>
865
984
  ### FormData para Upload
866
985
 
@@ -942,7 +1061,7 @@ const uploadFile = async (file: File) => {
942
1061
  "metadata",
943
1062
  JSON.stringify({
944
1063
  uploadedAt: new Date().toISOString(),
945
- })
1064
+ }),
946
1065
  );
947
1066
 
948
1067
  const response = await fetch("/api/upload", {
@@ -978,6 +1097,7 @@ const uploadWithProgress = async (file: File) => {
978
1097
  | Labels customizables | ❌ No | ✅ Sí (i18n friendly) |
979
1098
  | aria-invalid | ⚠️ Manual | ✅ Integrado |
980
1099
  | Fieldset disabled | ⚠️ Nativo pero sin estilos | ✅ Detectado automáticamente |
1100
+ | Archivos deshabilitados | ❌ No soportado | ✅ Visual feedback completo |
981
1101
 
982
1102
  ## Notas
983
1103
 
@@ -988,7 +1108,9 @@ const uploadWithProgress = async (file: File) => {
988
1108
  - Los archivos no se almacenan automáticamente - manejar el upload con los callbacks
989
1109
  - El componente es completamente controlado - el padre maneja el estado de los archivos
990
1110
  - El input file es reutilizable: después de seleccionar, se resetea para permitir seleccionar el mismo archivo de nuevo
1111
+ - **Generación automática de ID**: Si no se proporciona un `id` en la prop `input`, se genera automáticamente con formato `file-upload-{random}` para garantizar accesibilidad
991
1112
  - **Detección automática de fieldset**: El componente detecta cuando está dentro de un `<fieldset disabled>` usando MutationObserver y se deshabilita automáticamente
1113
+ - **Archivos seleccionados y disabled**: Cuando el componente está deshabilitado, los archivos seleccionados se muestran visualmente deshabilitados y no pueden ser removidos
992
1114
  - Usar con los componentes Field (`Field`, `FieldLabel`, `FieldError`, etc.) para una mejor experiencia de formulario
993
1115
  ```tsx
994
1116
  <FileUpload
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adamosuiteservices/ui",
3
- "version": "2.15.0",
3
+ "version": "2.16.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",