@adamosuiteservices/ui 2.15.0 → 2.15.1

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.
@@ -20,5 +20,6 @@ export type FileUploadProps = ComponentProps<"div"> & Readonly<{
20
20
  disabled?: boolean;
21
21
  "aria-invalid"?: boolean;
22
22
  labels?: FileUploadLabels;
23
+ input?: ComponentProps<"input">;
23
24
  }>;
24
- export declare function FileUpload({ className, selectedFile, selectedFiles, onFileSelect, onFilesSelect, onInvalidFile, acceptedExtensions, maxSizeInMB, maxFiles, multiple, filesPosition, invalid, disabled, "aria-invalid": ariaInvalid, labels, ...props }: FileUploadProps): import("react/jsx-runtime").JSX.Element;
25
+ export declare function FileUpload({ className, selectedFile, selectedFiles, onFileSelect, onFilesSelect, onInvalidFile, acceptedExtensions, maxSizeInMB, maxFiles, multiple, filesPosition, invalid, disabled, "aria-invalid": ariaInvalid, labels, input, ...props }: FileUploadProps): import("react/jsx-runtime").JSX.Element;
@@ -1,8 +1,8 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./jsx-runtime-BB_1_6y_.cjs"),z=require("./button-DVrteFz9.cjs"),k=require("./icon-DPMQJBkA.cjs"),v=require("./typography-Bj8oEDuE.cjs"),h=require("./index-DoxiiusW.cjs"),D=require("react");function K({isDragging:a,isMultiple:o,invalid:r,disabled:t,accept:d,acceptedExtensions:l,maxSizeInMB:c,maxFiles:u,labels:x,onDragOver:N,onDragLeave:R,onDrop:C,onFileChange:w}){return e.jsxRuntimeExports.jsxs("div",{onDragOver:t?void 0:N,onDragLeave:t?void 0:R,onDrop:t?void 0:C,className:h.cn(`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./jsx-runtime-BB_1_6y_.cjs"),I=require("./button-DVrteFz9.cjs"),z=require("./icon-DPMQJBkA.cjs"),R=require("./typography-Bj8oEDuE.cjs"),g=require("./index-DoxiiusW.cjs"),N=require("react");function Q({isDragging:a,isMultiple:i,invalid:s,disabled:t,accept:m,acceptedExtensions:l,maxSizeInMB:c,maxFiles:f,labels:u,input:y,onDragOver:b,onDragLeave:$,onDrop:w,onFileChange:C}){const p=y?.id||`file-upload-${Math.random().toString(36).substring(2,11)}`;return e.jsxRuntimeExports.jsxs("div",{onDragOver:t?void 0:b,onDragLeave:t?void 0:$,onDrop:t?void 0:w,className:g.cn(`
2
2
  adm:flex adm:flex-col adm:items-center adm:gap-6 adm:rounded-2xl
3
3
  adm:border-2
4
- `,"adm:border-dashed adm:bg-background adm:p-6 adm:transition-colors",{"adm:border-primary":a&&!r&&!t,"adm:border-destructive":r&&!t,"adm:border-input":!a&&!r,"adm:cursor-not-allowed adm:opacity-50":t}),children:[e.jsxRuntimeExports.jsx("div",{className:h.cn("adm:flex adm:items-center adm:justify-center adm:rounded-xl adm:p-2.5",r&&!t?"adm:bg-destructive/10":"adm:bg-primary-50"),children:e.jsxRuntimeExports.jsx(k.Icon,{symbol:"text_snippet",className:r&&!t?"adm:text-destructive":"adm:text-primary"})}),e.jsxRuntimeExports.jsxs("div",{className:"adm:flex adm:flex-col adm:items-center adm:gap-2",children:[e.jsxRuntimeExports.jsx(v.Typography,{color:r&&!t?"destructive":void 0,children:x?.dragDrop||(o?"Drag and drop your files here or":"Drag and drop your file here or")}),e.jsxRuntimeExports.jsxs("label",{htmlFor:"file-upload",children:[e.jsxRuntimeExports.jsx("input",{id:"file-upload",type:"file",accept:d,multiple:o,onChange:w,disabled:t,className:"adm:hidden"}),e.jsxRuntimeExports.jsx(z.Button,{asChild:!0,type:"button",variant:"link",className:h.cn("adm:cursor-pointer",t&&`
4
+ `,"adm:border-dashed adm:bg-background adm:p-6 adm:transition-colors",{"adm:border-primary":a&&!s&&!t,"adm:border-destructive":s&&!t,"adm:border-input":!a&&!s,"adm:cursor-not-allowed adm:opacity-50":t}),children:[e.jsxRuntimeExports.jsx("div",{className:g.cn("adm:flex adm:items-center adm:justify-center adm:rounded-xl adm:p-2.5",s&&!t?"adm:bg-destructive/10":"adm:bg-primary-50"),children:e.jsxRuntimeExports.jsx(z.Icon,{symbol:"text_snippet",className:s&&!t?"adm:text-destructive":"adm:text-primary"})}),e.jsxRuntimeExports.jsxs("div",{className:"adm:flex adm:flex-col adm:items-center adm:gap-2",children:[e.jsxRuntimeExports.jsx(R.Typography,{color:s&&!t?"destructive":void 0,children:u?.dragDrop||(i?"Drag and drop your files here or":"Drag and drop your file here or")}),e.jsxRuntimeExports.jsxs("label",{htmlFor:p,children:[e.jsxRuntimeExports.jsx("input",{...y,id:p,type:"file",accept:m,multiple:i,onChange:C,disabled:t,className:"adm:hidden"}),e.jsxRuntimeExports.jsx(I.Button,{asChild:!0,type:"button",variant:"link",className:g.cn("adm:cursor-pointer",t&&`
5
5
  adm:pointer-events-none
6
- `),disabled:t,children:e.jsxRuntimeExports.jsx("span",{children:x?.selectFile||(o?"Select files":"Select the file")})})]})]}),e.jsxRuntimeExports.jsx(v.Typography,{className:"adm:text-center",color:r&&!t?"destructive":"muted",children:x?.fileRequirements||`Allowed files: ${l.join(", ")}. Maximum size ${c} MB${o?`. Up to ${u} files`:""}.`})]})}function P({file:a,invalid:o,onRemove:r}){return e.jsxRuntimeExports.jsxs("div",{className:h.cn("adm:flex adm:items-center adm:gap-4 adm:rounded-2xl adm:border adm:p-6",o?"adm:border-destructive adm:bg-destructive/5":"adm:border-input adm:bg-muted"),children:[e.jsxRuntimeExports.jsx("div",{className:h.cn("adm:flex adm:items-center adm:justify-center adm:rounded-xl adm:p-2.5",o?"adm:bg-destructive/10":"adm:bg-primary-50"),children:e.jsxRuntimeExports.jsx(k.Icon,{symbol:"text_snippet",className:o?"adm:text-destructive":"adm:text-primary"})}),e.jsxRuntimeExports.jsxs("div",{className:`
6
+ `),disabled:t,children:e.jsxRuntimeExports.jsx("span",{children:u?.selectFile||(i?"Select files":"Select the file")})})]})]}),e.jsxRuntimeExports.jsx(R.Typography,{className:"adm:text-center",color:s&&!t?"destructive":"muted",children:u?.fileRequirements||(l&&l.length>0?`Allowed files: ${l.join(", ")}. Maximum size ${c} MB${i?`. Up to ${f} files`:""}.`:`Maximum size ${c} MB${i?`. Up to ${f} files`:""}.`)})]})}function W({file:a,invalid:i,disabled:s,onRemove:t}){return e.jsxRuntimeExports.jsxs("div",{className:g.cn("adm:flex adm:items-center adm:gap-4 adm:rounded-2xl adm:border adm:p-6",i&&!s?"adm:border-destructive adm:bg-destructive/5":"adm:border-input adm:bg-muted",s&&"adm:cursor-not-allowed adm:opacity-50"),children:[e.jsxRuntimeExports.jsx("div",{className:g.cn("adm:flex adm:items-center adm:justify-center adm:rounded-xl adm:p-2.5",i&&!s?"adm:bg-destructive/10":"adm:bg-primary-50"),children:e.jsxRuntimeExports.jsx(z.Icon,{symbol:"text_snippet",className:i&&!s?"adm:text-destructive":"adm:text-primary"})}),e.jsxRuntimeExports.jsxs("div",{className:`
7
7
  adm:flex adm:min-w-0 adm:flex-1 adm:items-start adm:gap-3
8
- `,children:[e.jsxRuntimeExports.jsx("div",{className:"adm:min-w-0 adm:flex-1",children:e.jsxRuntimeExports.jsx(v.Typography,{className:"adm:truncate adm:font-semibold",children:a.name})}),e.jsxRuntimeExports.jsxs(v.Typography,{className:"adm:shrink-0",color:"muted",children:[(a.size/1024/1024).toFixed(1)," MB"]})]}),e.jsxRuntimeExports.jsx(z.Button,{variant:"destructive-medium",onClick:r,type:"button",children:e.jsxRuntimeExports.jsx(k.Icon,{symbol:"delete",className:"adm:text-destructive"})})]})}function q({files:a,isMultiple:o,invalid:r,labels:t,onRemoveFile:d,onClearAll:l}){return a.length===0?null:e.jsxRuntimeExports.jsxs("div",{className:"adm:flex adm:flex-col adm:gap-3",children:[o&&a.length>1&&e.jsxRuntimeExports.jsxs("div",{className:"adm:flex adm:items-center adm:justify-between",children:[e.jsxRuntimeExports.jsx(v.Typography,{className:"adm:text-sm adm:font-medium",color:r?"destructive":void 0,children:t?.filesSelected?.(a.length)||`${a.length} file${a.length!==1?"s":""} selected`}),e.jsxRuntimeExports.jsx(z.Button,{variant:"ghost",size:"sm",onClick:l,type:"button",children:"Clear all"})]}),a.map((c,u)=>e.jsxRuntimeExports.jsx(P,{file:c,invalid:r,onRemove:()=>d(u)},`${c.name}-${u}`))]})}function Q({className:a,selectedFile:o,selectedFiles:r,onFileSelect:t,onFilesSelect:d,onInvalidFile:l,acceptedExtensions:c=[".xls",".xlsx",".numbers"],maxSizeInMB:u=50,maxFiles:x=10,multiple:N=!1,filesPosition:R="below",invalid:C=!1,disabled:w=!1,"aria-invalid":I,labels:y,...O}){const[B,A]=D.useState(!1),[L,U]=D.useState(!1),g=D.useRef(null);D.useEffect(()=>{const s=()=>{if(g.current){const i=g.current.closest("fieldset");U(i?.disabled??!1)}};s();const n=new MutationObserver(s);if(g.current){const i=g.current.closest("fieldset");i&&n.observe(i,{attributes:!0,attributeFilter:["disabled"]})}return()=>n.disconnect()},[]);const V=c.join(","),_=u*1024*1024,m=N||r!==void 0||d!==void 0,f=m?r||[]:o?[o]:[],E=C||I,p=w||L,M=s=>{p||(s.preventDefault(),A(!0))},G=s=>{p||(s.preventDefault(),A(!1))},H=s=>{if(!p)if(s.preventDefault(),A(!1),m){const i=Array.from(s.dataTransfer.files).filter(b);if(i.length>0){const $=[...r||[],...i].slice(0,x);d&&d($)}}else{const n=s.dataTransfer.files[0];n&&b(n)&&t&&t(n)}},J=s=>{if(!p){if(m){const i=(s.target.files?Array.from(s.target.files):[]).filter(b);if(i.length>0){const $=[...r||[],...i].slice(0,x);d&&d($)}}else{const n=s.target.files?.[0];n&&b(n)&&t&&t(n)}s.target.value=""}},F=s=>{if(!p)if(m){const n=f.filter((i,j)=>j!==s);d&&d(n)}else t&&t(null)},b=s=>{const n=s.name.substring(s.name.lastIndexOf(".")),i=c.includes(n.toLowerCase()),j=s.size<=_;return!i&&l?l(s,"extension"):!j&&l&&l(s,"size"),i&&j},T=()=>{p||(m?d&&d([]):t&&t(null))};return e.jsxRuntimeExports.jsxs("div",{ref:g,className:h.cn("adm:flex adm:flex-col adm:gap-4",a),...O,children:[m&&R==="above"&&e.jsxRuntimeExports.jsx(q,{files:f,isMultiple:m,invalid:E,labels:y,onRemoveFile:F,onClearAll:T}),(m||f.length===0)&&e.jsxRuntimeExports.jsx(K,{isDragging:B,isMultiple:m,invalid:E,disabled:p,accept:V,acceptedExtensions:c,maxSizeInMB:u,maxFiles:x,labels:y,onDragOver:M,onDragLeave:G,onDrop:H,onFileChange:J}),!m&&f.length>0&&e.jsxRuntimeExports.jsx(q,{files:f,isMultiple:m,invalid:E,labels:y,onRemoveFile:F,onClearAll:T}),m&&R==="below"&&e.jsxRuntimeExports.jsx(q,{files:f,isMultiple:m,invalid:E,labels:y,onRemoveFile:F,onClearAll:T})]})}exports.FileUpload=Q;
8
+ `,children:[e.jsxRuntimeExports.jsx("div",{className:"adm:min-w-0 adm:flex-1",children:e.jsxRuntimeExports.jsx(R.Typography,{className:"adm:truncate adm:font-semibold",children:a.name})}),e.jsxRuntimeExports.jsxs(R.Typography,{className:"adm:shrink-0",color:"muted",children:[(a.size/1024/1024).toFixed(1)," MB"]})]}),e.jsxRuntimeExports.jsx(I.Button,{variant:"destructive-medium",onClick:t,type:"button",disabled:s,children:e.jsxRuntimeExports.jsx(z.Icon,{symbol:"delete",className:"adm:text-destructive"})})]})}function k({files:a,isMultiple:i,invalid:s,disabled:t,labels:m,onRemoveFile:l,onClearAll:c}){return a.length===0?null:e.jsxRuntimeExports.jsxs("div",{className:"adm:flex adm:flex-col adm:gap-3",children:[i&&a.length>1&&e.jsxRuntimeExports.jsxs("div",{className:"adm:flex adm:items-center adm:justify-between",children:[e.jsxRuntimeExports.jsx(R.Typography,{className:"adm:text-sm adm:font-medium",color:s&&!t?"destructive":void 0,children:m?.filesSelected?.(a.length)||`${a.length} file${a.length!==1?"s":""} selected`}),e.jsxRuntimeExports.jsx(I.Button,{variant:"ghost",size:"sm",onClick:c,type:"button",disabled:t,children:"Clear all"})]}),a.map((f,u)=>e.jsxRuntimeExports.jsx(W,{file:f,invalid:s,disabled:t,onRemove:()=>l(u)},`${f.name}-${u}`))]})}function X({className:a,selectedFile:i,selectedFiles:s,onFileSelect:t,onFilesSelect:m,onInvalidFile:l,acceptedExtensions:c,maxSizeInMB:f=50,maxFiles:u=10,multiple:y=!1,filesPosition:b="below",invalid:$=!1,disabled:w=!1,"aria-invalid":C,labels:p,input:O,...B}){const[L,A]=N.useState(!1),[U,M]=N.useState(!1),v=N.useRef(null);N.useEffect(()=>{const r=()=>{if(v.current){const o=v.current.closest("fieldset");M(o?.disabled??!1)}};r();const n=new MutationObserver(r);if(v.current){const o=v.current.closest("fieldset");o&&n.observe(o,{attributes:!0,attributeFilter:["disabled"]})}return()=>n.disconnect()},[]);const V=c?.join(",")||"",_=f*1024*1024,d=y||s!==void 0||m!==void 0,j=d?s||[]:i?[i]:[],E=$||C,x=w||U,G=r=>{x||(r.preventDefault(),A(!0))},H=r=>{x||(r.preventDefault(),A(!1))},J=r=>{if(!x)if(r.preventDefault(),A(!1),d){const o=Array.from(r.dataTransfer.files).filter(D);if(o.length>0){const F=[...s||[],...o].slice(0,u);m&&m(F)}}else{const n=r.dataTransfer.files[0];n&&D(n)&&t&&t(n)}},K=r=>{if(!x){if(d){const o=(r.target.files?Array.from(r.target.files):[]).filter(D);if(o.length>0){const F=[...s||[],...o].slice(0,u);m&&m(F)}}else{const n=r.target.files?.[0];n&&D(n)&&t&&t(n)}r.target.value=""}},T=r=>{if(!x)if(d){const n=j.filter((o,h)=>h!==r);m&&m(n)}else t&&t(null)},D=r=>{const n=r.name.substring(r.name.lastIndexOf(".")),o=!c||c.length===0||c.includes(n.toLowerCase()),h=r.size<=_;return!o&&l?l(r,"extension"):!h&&l&&l(r,"size"),o&&h},q=()=>{x||(d?m&&m([]):t&&t(null))};return e.jsxRuntimeExports.jsxs("div",{ref:v,className:g.cn("adm:flex adm:flex-col adm:gap-4",a),...B,children:[d&&b==="above"&&e.jsxRuntimeExports.jsx(k,{files:j,isMultiple:d,invalid:E,disabled:x,labels:p,onRemoveFile:T,onClearAll:q}),(d||j.length===0)&&e.jsxRuntimeExports.jsx(Q,{isDragging:L,isMultiple:d,invalid:E,disabled:x,accept:V,acceptedExtensions:c,maxSizeInMB:f,maxFiles:u,labels:p,input:O,onDragOver:G,onDragLeave:H,onDrop:J,onFileChange:K}),!d&&j.length>0&&e.jsxRuntimeExports.jsx(k,{files:j,isMultiple:d,invalid:E,disabled:x,labels:p,onRemoveFile:T,onClearAll:q}),d&&b==="below"&&e.jsxRuntimeExports.jsx(k,{files:j,isMultiple:d,invalid:E,disabled:x,labels:p,onRemoveFile:T,onClearAll:q})]})}exports.FileUpload=X;
@@ -1,30 +1,32 @@
1
1
  import { j as e } from "./jsx-runtime-BzflLqGi.js";
2
- import { B as L } from "./button-B0lWuG-D.js";
3
- import { I } from "./icon-DKAhvlX_.js";
4
- import { T as j } from "./typography-MnY0LQoZ.js";
2
+ import { B as O } from "./button-B0lWuG-D.js";
3
+ import { I as L } from "./icon-DKAhvlX_.js";
4
+ import { T as y } from "./typography-MnY0LQoZ.js";
5
5
  import { c as v } from "./index-CRiPKpXj.js";
6
- import { useState as O, useRef as K, useEffect as Q } from "react";
7
- function W({
6
+ import { useState as B, useRef as W, useEffect as X } from "react";
7
+ function Y({
8
8
  isDragging: n,
9
- isMultiple: i,
10
- invalid: s,
11
- disabled: t,
9
+ isMultiple: d,
10
+ invalid: a,
11
+ disabled: r,
12
12
  accept: m,
13
13
  acceptedExtensions: l,
14
14
  maxSizeInMB: c,
15
- maxFiles: f,
16
- labels: u,
17
- onDragOver: C,
18
- onDragLeave: b,
19
- onDrop: w,
15
+ maxFiles: x,
16
+ labels: f,
17
+ input: b,
18
+ onDragOver: D,
19
+ onDragLeave: w,
20
+ onDrop: C,
20
21
  onFileChange: A
21
22
  }) {
23
+ const p = b?.id || `file-upload-${Math.random().toString(36).substring(2, 11)}`;
22
24
  return /* @__PURE__ */ e.jsxs(
23
25
  "div",
24
26
  {
25
- onDragOver: t ? void 0 : C,
26
- onDragLeave: t ? void 0 : b,
27
- onDrop: t ? void 0 : w,
27
+ onDragOver: r ? void 0 : D,
28
+ onDragLeave: r ? void 0 : w,
29
+ onDrop: r ? void 0 : C,
28
30
  className: v(
29
31
  `
30
32
  adm:flex adm:flex-col adm:items-center adm:gap-6 adm:rounded-2xl
@@ -32,10 +34,10 @@ function W({
32
34
  `,
33
35
  "adm:border-dashed adm:bg-background adm:p-6 adm:transition-colors",
34
36
  {
35
- "adm:border-primary": n && !s && !t,
36
- "adm:border-destructive": s && !t,
37
- "adm:border-input": !n && !s,
38
- "adm:cursor-not-allowed adm:opacity-50": t
37
+ "adm:border-primary": n && !a && !r,
38
+ "adm:border-destructive": a && !r,
39
+ "adm:border-input": !n && !a,
40
+ "adm:cursor-not-allowed adm:opacity-50": r
39
41
  }
40
42
  ),
41
43
  children: [
@@ -44,59 +46,61 @@ function W({
44
46
  {
45
47
  className: v(
46
48
  "adm:flex adm:items-center adm:justify-center adm:rounded-xl adm:p-2.5",
47
- s && !t ? "adm:bg-destructive/10" : "adm:bg-primary-50"
49
+ a && !r ? "adm:bg-destructive/10" : "adm:bg-primary-50"
48
50
  ),
49
51
  children: /* @__PURE__ */ e.jsx(
50
- I,
52
+ L,
51
53
  {
52
54
  symbol: "text_snippet",
53
- className: s && !t ? "adm:text-destructive" : "adm:text-primary"
55
+ className: a && !r ? "adm:text-destructive" : "adm:text-primary"
54
56
  }
55
57
  )
56
58
  }
57
59
  ),
58
60
  /* @__PURE__ */ e.jsxs("div", { className: "adm:flex adm:flex-col adm:items-center adm:gap-2", children: [
59
- /* @__PURE__ */ e.jsx(j, { color: s && !t ? "destructive" : void 0, children: u?.dragDrop || (i ? "Drag and drop your files here or" : "Drag and drop your file here or") }),
60
- /* @__PURE__ */ e.jsxs("label", { htmlFor: "file-upload", children: [
61
+ /* @__PURE__ */ e.jsx(y, { color: a && !r ? "destructive" : void 0, children: f?.dragDrop || (d ? "Drag and drop your files here or" : "Drag and drop your file here or") }),
62
+ /* @__PURE__ */ e.jsxs("label", { htmlFor: p, children: [
61
63
  /* @__PURE__ */ e.jsx(
62
64
  "input",
63
65
  {
64
- id: "file-upload",
66
+ ...b,
67
+ id: p,
65
68
  type: "file",
66
69
  accept: m,
67
- multiple: i,
70
+ multiple: d,
68
71
  onChange: A,
69
- disabled: t,
72
+ disabled: r,
70
73
  className: "adm:hidden"
71
74
  }
72
75
  ),
73
76
  /* @__PURE__ */ e.jsx(
74
- L,
77
+ O,
75
78
  {
76
79
  asChild: !0,
77
80
  type: "button",
78
81
  variant: "link",
79
- className: v("adm:cursor-pointer", t && `
82
+ className: v("adm:cursor-pointer", r && `
80
83
  adm:pointer-events-none
81
84
  `),
82
- disabled: t,
83
- children: /* @__PURE__ */ e.jsx("span", { children: u?.selectFile || (i ? "Select files" : "Select the file") })
85
+ disabled: r,
86
+ children: /* @__PURE__ */ e.jsx("span", { children: f?.selectFile || (d ? "Select files" : "Select the file") })
84
87
  }
85
88
  )
86
89
  ] })
87
90
  ] }),
88
- /* @__PURE__ */ e.jsx(j, { className: "adm:text-center", color: s && !t ? "destructive" : "muted", children: u?.fileRequirements || `Allowed files: ${l.join(", ")}. Maximum size ${c} MB${i ? `. Up to ${f} files` : ""}.` })
91
+ /* @__PURE__ */ e.jsx(y, { className: "adm:text-center", color: a && !r ? "destructive" : "muted", children: f?.fileRequirements || (l && l.length > 0 ? `Allowed files: ${l.join(", ")}. Maximum size ${c} MB${d ? `. Up to ${x} files` : ""}.` : `Maximum size ${c} MB${d ? `. Up to ${x} files` : ""}.`) })
89
92
  ]
90
93
  }
91
94
  );
92
95
  }
93
- function X({ file: n, invalid: i, onRemove: s }) {
96
+ function Z({ file: n, invalid: d, disabled: a, onRemove: r }) {
94
97
  return /* @__PURE__ */ e.jsxs(
95
98
  "div",
96
99
  {
97
100
  className: v(
98
101
  "adm:flex adm:items-center adm:gap-4 adm:rounded-2xl adm:border adm:p-6",
99
- i ? "adm:border-destructive adm:bg-destructive/5" : "adm:border-input adm:bg-muted"
102
+ d && !a ? "adm:border-destructive adm:bg-destructive/5" : "adm:border-input adm:bg-muted",
103
+ a && "adm:cursor-not-allowed adm:opacity-50"
100
104
  ),
101
105
  children: [
102
106
  /* @__PURE__ */ e.jsx(
@@ -104,13 +108,13 @@ function X({ file: n, invalid: i, onRemove: s }) {
104
108
  {
105
109
  className: v(
106
110
  "adm:flex adm:items-center adm:justify-center adm:rounded-xl adm:p-2.5",
107
- i ? "adm:bg-destructive/10" : "adm:bg-primary-50"
111
+ d && !a ? "adm:bg-destructive/10" : "adm:bg-primary-50"
108
112
  ),
109
113
  children: /* @__PURE__ */ e.jsx(
110
- I,
114
+ L,
111
115
  {
112
116
  symbol: "text_snippet",
113
- className: i ? "adm:text-destructive" : "adm:text-primary"
117
+ className: d && !a ? "adm:text-destructive" : "adm:text-primary"
114
118
  }
115
119
  )
116
120
  }
@@ -122,8 +126,8 @@ function X({ file: n, invalid: i, onRemove: s }) {
122
126
  adm:flex adm:min-w-0 adm:flex-1 adm:items-start adm:gap-3
123
127
  `,
124
128
  children: [
125
- /* @__PURE__ */ e.jsx("div", { className: "adm:min-w-0 adm:flex-1", children: /* @__PURE__ */ e.jsx(j, { className: "adm:truncate adm:font-semibold", children: n.name }) }),
126
- /* @__PURE__ */ e.jsxs(j, { className: "adm:shrink-0", color: "muted", children: [
129
+ /* @__PURE__ */ e.jsx("div", { className: "adm:min-w-0 adm:flex-1", children: /* @__PURE__ */ e.jsx(y, { className: "adm:truncate adm:font-semibold", children: n.name }) }),
130
+ /* @__PURE__ */ e.jsxs(y, { className: "adm:shrink-0", color: "muted", children: [
127
131
  (n.size / 1024 / 1024).toFixed(1),
128
132
  " MB"
129
133
  ] })
@@ -131,175 +135,183 @@ function X({ file: n, invalid: i, onRemove: s }) {
131
135
  }
132
136
  ),
133
137
  /* @__PURE__ */ e.jsx(
134
- L,
138
+ O,
135
139
  {
136
140
  variant: "destructive-medium",
137
- onClick: s,
141
+ onClick: r,
138
142
  type: "button",
139
- children: /* @__PURE__ */ e.jsx(I, { symbol: "delete", className: "adm:text-destructive" })
143
+ disabled: a,
144
+ children: /* @__PURE__ */ e.jsx(L, { symbol: "delete", className: "adm:text-destructive" })
140
145
  }
141
146
  )
142
147
  ]
143
148
  }
144
149
  );
145
150
  }
146
- function z({ files: n, isMultiple: i, invalid: s, labels: t, onRemoveFile: m, onClearAll: l }) {
151
+ function I({ files: n, isMultiple: d, invalid: a, disabled: r, labels: m, onRemoveFile: l, onClearAll: c }) {
147
152
  return n.length === 0 ? null : /* @__PURE__ */ e.jsxs("div", { className: "adm:flex adm:flex-col adm:gap-3", children: [
148
- i && n.length > 1 && /* @__PURE__ */ e.jsxs("div", { className: "adm:flex adm:items-center adm:justify-between", children: [
149
- /* @__PURE__ */ e.jsx(j, { className: "adm:text-sm adm:font-medium", color: s ? "destructive" : void 0, children: t?.filesSelected?.(n.length) || `${n.length} file${n.length !== 1 ? "s" : ""} selected` }),
153
+ d && n.length > 1 && /* @__PURE__ */ e.jsxs("div", { className: "adm:flex adm:items-center adm:justify-between", children: [
154
+ /* @__PURE__ */ e.jsx(y, { className: "adm:text-sm adm:font-medium", color: a && !r ? "destructive" : void 0, children: m?.filesSelected?.(n.length) || `${n.length} file${n.length !== 1 ? "s" : ""} selected` }),
150
155
  /* @__PURE__ */ e.jsx(
151
- L,
156
+ O,
152
157
  {
153
158
  variant: "ghost",
154
159
  size: "sm",
155
- onClick: l,
160
+ onClick: c,
156
161
  type: "button",
162
+ disabled: r,
157
163
  children: "Clear all"
158
164
  }
159
165
  )
160
166
  ] }),
161
- n.map((c, f) => /* @__PURE__ */ e.jsx(
162
- X,
167
+ n.map((x, f) => /* @__PURE__ */ e.jsx(
168
+ Z,
163
169
  {
164
- file: c,
165
- invalid: s,
166
- onRemove: () => m(f)
170
+ file: x,
171
+ invalid: a,
172
+ disabled: r,
173
+ onRemove: () => l(f)
167
174
  },
168
- `${c.name}-${f}`
175
+ `${x.name}-${f}`
169
176
  ))
170
177
  ] });
171
178
  }
172
- function re({
179
+ function ae({
173
180
  className: n,
174
- selectedFile: i,
175
- selectedFiles: s,
176
- onFileSelect: t,
181
+ selectedFile: d,
182
+ selectedFiles: a,
183
+ onFileSelect: r,
177
184
  onFilesSelect: m,
178
185
  onInvalidFile: l,
179
- acceptedExtensions: c = [".xls", ".xlsx", ".numbers"],
180
- maxSizeInMB: f = 50,
181
- maxFiles: u = 10,
182
- multiple: C = !1,
183
- filesPosition: b = "below",
186
+ acceptedExtensions: c,
187
+ maxSizeInMB: x = 50,
188
+ maxFiles: f = 10,
189
+ multiple: b = !1,
190
+ filesPosition: D = "below",
184
191
  invalid: w = !1,
185
- disabled: A = !1,
186
- "aria-invalid": B,
187
- labels: y,
188
- ...T
192
+ disabled: C = !1,
193
+ "aria-invalid": A,
194
+ labels: p,
195
+ input: T,
196
+ ...U
189
197
  }) {
190
- const [V, R] = O(!1), [_, E] = O(!1), g = K(null);
191
- Q(() => {
192
- const r = () => {
193
- if (g.current) {
194
- const d = g.current.closest("fieldset");
195
- E(d?.disabled ?? !1);
198
+ const [V, R] = B(!1), [_, M] = B(!1), j = W(null);
199
+ X(() => {
200
+ const t = () => {
201
+ if (j.current) {
202
+ const i = j.current.closest("fieldset");
203
+ M(i?.disabled ?? !1);
196
204
  }
197
205
  };
198
- r();
199
- const a = new MutationObserver(r);
200
- if (g.current) {
201
- const d = g.current.closest("fieldset");
202
- d && a.observe(d, { attributes: !0, attributeFilter: ["disabled"] });
206
+ t();
207
+ const s = new MutationObserver(t);
208
+ if (j.current) {
209
+ const i = j.current.closest("fieldset");
210
+ i && s.observe(i, { attributes: !0, attributeFilter: ["disabled"] });
203
211
  }
204
- return () => a.disconnect();
212
+ return () => s.disconnect();
205
213
  }, []);
206
- const U = c.join(","), q = f * 1024 * 1024, o = C || s !== void 0 || m !== void 0, p = o ? s || [] : i ? [i] : [], D = w || B, x = A || _, M = (r) => {
207
- x || (r.preventDefault(), R(!0));
208
- }, G = (r) => {
209
- x || (r.preventDefault(), R(!1));
210
- }, H = (r) => {
211
- if (!x)
212
- if (r.preventDefault(), R(!1), o) {
213
- const d = Array.from(r.dataTransfer.files).filter(N);
214
- if (d.length > 0) {
215
- const k = [...s || [], ...d].slice(0, u);
216
- m && m(k);
214
+ const q = c?.join(",") || "", G = x * 1024 * 1024, o = b || a !== void 0 || m !== void 0, h = o ? a || [] : d ? [d] : [], N = w || A, u = C || _, H = (t) => {
215
+ u || (t.preventDefault(), R(!0));
216
+ }, J = (t) => {
217
+ u || (t.preventDefault(), R(!1));
218
+ }, K = (t) => {
219
+ if (!u)
220
+ if (t.preventDefault(), R(!1), o) {
221
+ const i = Array.from(t.dataTransfer.files).filter($);
222
+ if (i.length > 0) {
223
+ const F = [...a || [], ...i].slice(0, f);
224
+ m && m(F);
217
225
  }
218
226
  } else {
219
- const a = r.dataTransfer.files[0];
220
- a && N(a) && t && t(a);
227
+ const s = t.dataTransfer.files[0];
228
+ s && $(s) && r && r(s);
221
229
  }
222
- }, J = (r) => {
223
- if (!x) {
230
+ }, Q = (t) => {
231
+ if (!u) {
224
232
  if (o) {
225
- const d = (r.target.files ? Array.from(r.target.files) : []).filter(N);
226
- if (d.length > 0) {
227
- const k = [...s || [], ...d].slice(0, u);
228
- m && m(k);
233
+ const i = (t.target.files ? Array.from(t.target.files) : []).filter($);
234
+ if (i.length > 0) {
235
+ const F = [...a || [], ...i].slice(0, f);
236
+ m && m(F);
229
237
  }
230
238
  } else {
231
- const a = r.target.files?.[0];
232
- a && N(a) && t && t(a);
239
+ const s = t.target.files?.[0];
240
+ s && $(s) && r && r(s);
233
241
  }
234
- r.target.value = "";
242
+ t.target.value = "";
235
243
  }
236
- }, $ = (r) => {
237
- if (!x)
244
+ }, k = (t) => {
245
+ if (!u)
238
246
  if (o) {
239
- const a = p.filter((d, h) => h !== r);
240
- m && m(a);
247
+ const s = h.filter((i, g) => g !== t);
248
+ m && m(s);
241
249
  } else
242
- t && t(null);
243
- }, N = (r) => {
244
- const a = r.name.substring(r.name.lastIndexOf(".")), d = c.includes(a.toLowerCase()), h = r.size <= q;
245
- return !d && l ? l(r, "extension") : !h && l && l(r, "size"), d && h;
246
- }, F = () => {
247
- x || (o ? m && m([]) : t && t(null));
250
+ r && r(null);
251
+ }, $ = (t) => {
252
+ const s = t.name.substring(t.name.lastIndexOf(".")), i = !c || c.length === 0 || c.includes(s.toLowerCase()), g = t.size <= G;
253
+ return !i && l ? l(t, "extension") : !g && l && l(t, "size"), i && g;
254
+ }, z = () => {
255
+ u || (o ? m && m([]) : r && r(null));
248
256
  };
249
- return /* @__PURE__ */ e.jsxs("div", { ref: g, className: v("adm:flex adm:flex-col adm:gap-4", n), ...T, children: [
250
- o && b === "above" && /* @__PURE__ */ e.jsx(
251
- z,
257
+ return /* @__PURE__ */ e.jsxs("div", { ref: j, className: v("adm:flex adm:flex-col adm:gap-4", n), ...U, children: [
258
+ o && D === "above" && /* @__PURE__ */ e.jsx(
259
+ I,
252
260
  {
253
- files: p,
261
+ files: h,
254
262
  isMultiple: o,
255
- invalid: D,
256
- labels: y,
257
- onRemoveFile: $,
258
- onClearAll: F
263
+ invalid: N,
264
+ disabled: u,
265
+ labels: p,
266
+ onRemoveFile: k,
267
+ onClearAll: z
259
268
  }
260
269
  ),
261
- (o || p.length === 0) && /* @__PURE__ */ e.jsx(
262
- W,
270
+ (o || h.length === 0) && /* @__PURE__ */ e.jsx(
271
+ Y,
263
272
  {
264
273
  isDragging: V,
265
274
  isMultiple: o,
266
- invalid: D,
267
- disabled: x,
268
- accept: U,
275
+ invalid: N,
276
+ disabled: u,
277
+ accept: q,
269
278
  acceptedExtensions: c,
270
- maxSizeInMB: f,
271
- maxFiles: u,
272
- labels: y,
273
- onDragOver: M,
274
- onDragLeave: G,
275
- onDrop: H,
276
- onFileChange: J
279
+ maxSizeInMB: x,
280
+ maxFiles: f,
281
+ labels: p,
282
+ input: T,
283
+ onDragOver: H,
284
+ onDragLeave: J,
285
+ onDrop: K,
286
+ onFileChange: Q
277
287
  }
278
288
  ),
279
- !o && p.length > 0 && /* @__PURE__ */ e.jsx(
280
- z,
289
+ !o && h.length > 0 && /* @__PURE__ */ e.jsx(
290
+ I,
281
291
  {
282
- files: p,
292
+ files: h,
283
293
  isMultiple: o,
284
- invalid: D,
285
- labels: y,
286
- onRemoveFile: $,
287
- onClearAll: F
294
+ invalid: N,
295
+ disabled: u,
296
+ labels: p,
297
+ onRemoveFile: k,
298
+ onClearAll: z
288
299
  }
289
300
  ),
290
- o && b === "below" && /* @__PURE__ */ e.jsx(
291
- z,
301
+ o && D === "below" && /* @__PURE__ */ e.jsx(
302
+ I,
292
303
  {
293
- files: p,
304
+ files: h,
294
305
  isMultiple: o,
295
- invalid: D,
296
- labels: y,
297
- onRemoveFile: $,
298
- onClearAll: F
306
+ invalid: N,
307
+ disabled: u,
308
+ labels: p,
309
+ onRemoveFile: k,
310
+ onClearAll: z
299
311
  }
300
312
  )
301
313
  ] });
302
314
  }
303
315
  export {
304
- re as FileUpload
316
+ ae as FileUpload
305
317
  };
@@ -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.15.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",