automoby-kit 1.0.72 → 1.0.74

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.
@@ -0,0 +1 @@
1
+ "use client";"use strict";var e=require("react/jsx-runtime"),t=require("react"),r=require("./utils.js"),a=require("./contexts.js");const ChevronDownIcon=({className:t})=>e.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:t,children:e.jsx("path",{d:"M6 9L12 15L18 9",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})}),l=t.forwardRef(({label:l,placeholder:s="انتخاب کنید",options:n,value:o,defaultValue:i,onChange:u,disabled:d=!1,error:c=!1,helperText:x,className:p,...m},b)=>{const[h,v]=t.useState(!1),[g,f]=t.useState(-1),[w,j]=t.useState(i||""),y=t.useRef(null),k=t.useRef(null),N=t.useId(),D=a.useMobile(),E=void 0!==o,L=E?o:w,S=n.find(e=>e.value===L),$=Boolean(S);t.useEffect(()=>{const handleClickOutside=e=>{y.current&&!y.current.contains(e.target)&&(v(!1),f(-1))};return document.addEventListener("mousedown",handleClickOutside),()=>document.removeEventListener("mousedown",handleClickOutside)},[]);const handleSelect=e=>{E||j(e),u?.(e),v(!1),f(-1)},q=D?"min-w-[204px] w-full":"min-w-[229px] w-full",C=D?"h-12 px-3 py-[13px] gap-2":"h-14 px-4 py-[15px] gap-3",I=D?"text-sm":"text-base",M=D?"w-5 h-5":"w-6 h-6",R=D?"py-[13px] px-3 gap-4":"py-4 px-4 gap-4",A=D?"text-sm":"text-base";return e.jsxs("div",{className:r("relative",q,p),...m,children:[e.jsxs("div",{ref:b,role:"combobox","aria-expanded":h,"aria-haspopup":"listbox","aria-controls":`${N}-listbox`,"aria-labelledby":`${N}-label`,tabIndex:d?-1:0,className:r("relative flex items-center justify-between bg-white border rounded-md cursor-pointer transition-colors duration-200",C,{"border-neutral-light hover:border-neutral-main":!c&&!d,"border-error":c,"border-neutral-light bg-neutral-lighter cursor-not-allowed":d,"border-primary":h&&!c}),onClick:()=>{d||(v(!h),f(h?-1:0))},onKeyDown:e=>{if(!d)switch(e.key){case"Enter":case" ":e.preventDefault(),h?g>=0&&handleSelect(n[g].value):(v(!0),f(0));break;case"Escape":case"Tab":v(!1),f(-1);break;case"ArrowDown":e.preventDefault(),h?f(e=>e<n.length-1?e+1:e):(v(!0),f(0));break;case"ArrowUp":e.preventDefault(),h&&f(e=>e>0?e-1:e)}},children:[e.jsx("div",{className:"flex-1 text-right",children:e.jsx("span",{className:r("block transition-colors",I,{"text-neutral-main":!$&&!d||d,"text-neutral-darker":$&&!d}),children:S?S.label:s})}),e.jsx(ChevronDownIcon,{className:r("transition-transform duration-200 text-neutral-main",M,{"rotate-180":h,"text-neutral-light":d})}),$&&e.jsx("div",{className:r("absolute -top-2 bg-white px-1 text-neutral-main transition-all duration-200",D?"right-2 text-xs":"right-3 text-sm"),id:`${N}-label`,children:l})]}),h&&e.jsx("div",{className:r("absolute top-full left-0 right-0 z-50 mt-1 bg-white border border-neutral-light rounded-md shadow-lg",R),children:e.jsx("ul",{ref:k,role:"listbox",id:`${N}-listbox`,"aria-labelledby":`${N}-label`,className:"flex flex-col items-end",children:n.map((t,a)=>e.jsx("li",{role:"option","aria-selected":t.value===L,className:r("w-full cursor-pointer text-right py-2 transition-colors duration-150",A,{"bg-primary-lightest":a===g,"text-neutral-darker":t.value!==L,"text-primary font-medium":t.value===L}),onClick:()=>handleSelect(t.value),onKeyDown:e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),handleSelect(t.value))},onMouseEnter:()=>f(a),tabIndex:-1,children:t.label},t.value))})}),x&&e.jsx("div",{className:r("mt-1 text-xs text-right",{"text-error":c,"text-neutral-main":!c}),children:x})]})});l.displayName="Select",exports.Select=l;
package/dist/cjs/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("./Typography.js"),r=require("./Button.js"),s=require("./Input.js"),o=require("./Tabs.js"),a=require("./Drawer.js"),i=require("./Backdrop.js"),t=require("./Breadcrumb.js"),l=require("./Pagination.js"),n=require("./Accordion.js"),c=require("./Divider.js"),d=require("./RadioGroup.js"),u=require("./chunks/Chips-Ws80QAgh.js"),x=require("./Menu.js"),p=require("react/jsx-runtime"),b=require("react"),m=require("./utils.js"),h=require("./contexts.js");require("react-dom"),require("./chunks/chevron-left-Do__K6cA.js"),require("./chunks/createLucideIcon-BqJVOzoK.js");const j=b.forwardRef(({isOpen:e=!1,onClose:r,title:s,content:o,buttons:a,showCloseButton:t=!0,size:l="md",className:n,children:c},d)=>{const handleClose=()=>{r&&r()},x=m("bg-white rounded-[10px] shadow-lg mx-4",{sm:"max-w-sm",md:"max-w-md",lg:"max-w-lg",xl:"max-w-xl"}[l],n);return p.jsx(i.Backdrop,{isOpen:e,onClick:handleClose,blur:!0,children:p.jsx("div",{ref:d,className:x,onClick:e=>e.stopPropagation(),onKeyDown:e=>{"Escape"===e.key&&r&&r()},role:"dialog","aria-modal":"true","aria-labelledby":s?"dialog-title":void 0,children:p.jsxs("div",{className:"flex flex-col p-6 gap-8",children:[s&&p.jsx("div",{className:"flex flex-col gap-2.5",children:p.jsx("div",{className:"flex items-center justify-between pb-4 border-b border-[#ebeaf0]",children:p.jsxs("div",{className:"flex items-center justify-between gap-3 w-full flex-row-reverse",children:[p.jsx("div",{className:"text-[#590d8b] text-xl font-extrabold leading-8",children:s}),t&&p.jsx("button",{type:"button",onClick:handleClose,className:"p-1 rounded-full hover:bg-gray-100 transition-colors","aria-label":"Close dialog",children:p.jsx(u.X,{className:"w-6 h-6 text-[#a4a2bb]"})})]})})}),o&&p.jsx("div",{className:"flex flex-col gap-4",children:o}),c&&!o&&p.jsx("div",{className:"flex flex-col gap-4",children:c}),a&&p.jsx("div",{className:"flex flex-col gap-1.5",children:a})]})})})});j.displayName="Dialog";const g=b.forwardRef(({variant:e="primary",icon:r,children:s,className:o,...a},i)=>{const t=m("h-14 px-4 py-[13px] rounded-md font-bold text-base leading-[1.8] flex items-center justify-center gap-2 transition-colors",{"bg-[#590d8b] text-white hover:bg-[#4a0a75]":"primary"===e,"bg-white text-[#1a1922] border border-[#ebeaf0] hover:bg-gray-50":"secondary"===e},o);return p.jsxs("button",{type:"button",ref:i,className:t,...a,children:[s,r&&p.jsx("span",{className:"w-5 h-5",children:r})]})});g.displayName="DialogButton";const f=e.Typography,v=r.Button,y=s.Input,w=o.Tabs,q=a.Drawer,N=i.Backdrop,B=t.Breadcrumb,k=l.Pagination,D=n.Accordion,C=c.Divider,T=d.RadioGroup,M=u.Chips,P=x.Menu;exports.MobileProvider=h.MobileProvider,exports.useMobile=h.useMobile,exports.useTablet=h.useTablet,exports.Accordion=D,exports.Backdrop=N,exports.Breadcrumb=B,exports.Button=v,exports.Chips=M,exports.Dialog=j,exports.DialogButton=g,exports.Divider=C,exports.Drawer=q,exports.Input=y,exports.Menu=P,exports.Pagination=k,exports.RadioGroup=T,exports.Tabs=w,exports.Typography=f;
1
+ "use strict";var e=require("./Typography.js"),r=require("./Button.js"),a=require("./Input.js"),s=require("./Tabs.js"),t=require("./Drawer.js"),l=require("./Backdrop.js"),i=require("./Breadcrumb.js"),o=require("./Pagination.js"),n=require("./Accordion.js"),c=require("./Divider.js"),d=require("./RadioGroup.js"),u=require("./chunks/Chips-Ws80QAgh.js"),p=require("./Menu.js"),m=require("react/jsx-runtime"),x=require("react"),h=require("./utils.js"),g=require("./chunks/createLucideIcon-BqJVOzoK.js"),b=require("./Select.js"),f=require("./contexts.js");require("react-dom"),require("./chunks/chevron-left-Do__K6cA.js");const j=g.createLucideIcon("plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]]);const y=x.forwardRef(({value:r,onChange:a,label:s="ارسال عکس",instruction:t,maxSize:l=10485760,accept:i="image/jpeg,image/jpg,image/png",maxCount:o,onRejected:n,disabled:c=!1,className:d,addButtonText:p="اضافه",removeButtonAriaLabel:g="حذف عکس"},b)=>{const f=x.useMemo(()=>function(e){if(!e||"*"===e)return/.*/;const r=e.split(",").map(e=>e.trim().replace(/^[^/]+\//,"").replace(/^\*\./,"")).filter(Boolean);if(0===r.length)return/.*/;const a=r.map(e=>e.replace(".","\\.")).join("|");return new RegExp(`\\.(${a})$`,"i")}(i),[i]),y=x.useId(),v=x.useMemo(()=>r.map(e=>e.type.startsWith("image/")?URL.createObjectURL(e):null),[r]);x.useEffect(()=>()=>{v.forEach(e=>e&&URL.revokeObjectURL(e))},[v]);const w=x.useCallback(e=>{const s=e.target.files?Array.from(e.target.files):[];e.target.value="";const t=r.length,{rejected:i,valid:c}=s.reduce((e,r)=>null!=o&&t+e.valid.length>=o?(e.rejected.push({file:r,reason:"count"}),e):r.size>l?(e.rejected.push({file:r,reason:"size"}),e):f.test(r.name)?(e.valid.push(r),e):(e.rejected.push({file:r,reason:"type"}),e),{rejected:[],valid:[]});if(c.length>0){const e=null!=o?[...r,...c].slice(0,o):[...r,...c];a(e)}i.length>0&&n?.(i)},[r,a,l,f,o,n]),N=x.useCallback(e=>{if(c)return;const s=r.filter((r,a)=>a!==e);a(s)},[r,a,c]),q=null!=o&&r.length>=o;return m.jsxs("div",{ref:b,className:h("",d),children:[s&&m.jsx(e.Typography,{variant:"body-s-medium",color:"neutral-darker",className:"mb-1",children:s}),null!=t&&m.jsx(e.Typography,{variant:"body-xs-medium",color:"neutral-main",className:"mb-2",children:t}),m.jsxs("div",{className:"flex flex-wrap gap-2 items-center",children:[r.map((r,a)=>m.jsxs("div",{className:"relative w-16 h-16 rounded-lg bg-neutral-light overflow-hidden group",children:[r.type.startsWith("image/")&&v[a]?m.jsx("img",{src:v[a],alt:"",className:"w-full h-full object-cover"}):m.jsx("div",{className:"w-full h-full flex items-center justify-center",children:m.jsx(e.Typography,{variant:"body-xs-medium",children:"فایل"})}),!c&&m.jsx("button",{type:"button",onClick:()=>N(a),className:"absolute top-0.5 left-0.5 w-5 h-5 rounded-full bg-neutral-darker/70 text-white flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity","aria-label":g,children:m.jsx(u.X,{className:"w-3 h-3"})})]},`${r.name}-${r.size}-${r.lastModified}`)),!c&&!q&&m.jsxs("label",{htmlFor:y,className:"w-16 h-16 rounded-lg border-2 border-dashed border-neutral-main flex items-center justify-center cursor-pointer hover:border-primary-main hover:bg-primary-main/5 transition-colors",children:[m.jsx("input",{id:y,type:"file",accept:i,multiple:!0,className:"sr-only",onChange:w}),m.jsxs("div",{className:"flex flex-col items-center gap-0.5",children:[m.jsx(j,{className:"w-5 h-5 text-neutral-main"}),m.jsx(e.Typography,{variant:"body-xs-medium",color:"neutral-main",children:p})]})]})]})]})});y.displayName="ImageUpload";const v=x.forwardRef(({isOpen:e=!1,onClose:r,title:a,content:s,buttons:t,showCloseButton:i=!0,size:o="md",className:n,children:c},d)=>{const handleClose=()=>{r&&r()},p=h("bg-white rounded-[10px] shadow-lg mx-4",{sm:"max-w-sm",md:"max-w-md",lg:"max-w-lg",xl:"max-w-xl"}[o],n);return m.jsx(l.Backdrop,{isOpen:e,onClick:handleClose,blur:!0,children:m.jsx("div",{ref:d,className:p,onClick:e=>e.stopPropagation(),onKeyDown:e=>{"Escape"===e.key&&r&&r()},role:"dialog","aria-modal":"true","aria-labelledby":a?"dialog-title":void 0,children:m.jsxs("div",{className:"flex flex-col p-6 gap-8",children:[a&&m.jsx("div",{className:"flex flex-col gap-2.5",children:m.jsx("div",{className:"flex items-center justify-between pb-4 border-b border-[#ebeaf0]",children:m.jsxs("div",{className:"flex items-center justify-between gap-3 w-full flex-row-reverse",children:[m.jsx("div",{className:"text-[#590d8b] text-xl font-extrabold leading-8",children:a}),i&&m.jsx("button",{type:"button",onClick:handleClose,className:"p-1 rounded-full hover:bg-gray-100 transition-colors","aria-label":"Close dialog",children:m.jsx(u.X,{className:"w-6 h-6 text-[#a4a2bb]"})})]})})}),s&&m.jsx("div",{className:"flex flex-col gap-4",children:s}),c&&!s&&m.jsx("div",{className:"flex flex-col gap-4",children:c}),t&&m.jsx("div",{className:"flex flex-col gap-1.5",children:t})]})})})});v.displayName="Dialog";const w=x.forwardRef(({variant:e="primary",icon:r,children:a,className:s,...t},l)=>{const i=h("h-14 px-4 py-[13px] rounded-md font-bold text-base leading-[1.8] flex items-center justify-center gap-2 transition-colors",{"bg-[#590d8b] text-white hover:bg-[#4a0a75]":"primary"===e,"bg-white text-[#1a1922] border border-[#ebeaf0] hover:bg-gray-50":"secondary"===e},s);return m.jsxs("button",{type:"button",ref:l,className:i,...t,children:[a,r&&m.jsx("span",{className:"w-5 h-5",children:r})]})});w.displayName="DialogButton";const N=e.Typography,q=r.Button,k=a.Input,B=s.Tabs,C=t.Drawer,T=l.Backdrop,M=i.Breadcrumb,R=o.Pagination,D=n.Accordion,I=c.Divider,L=d.RadioGroup,P=u.Chips,U=p.Menu,z=y,A=b.Select;exports.MobileProvider=f.MobileProvider,exports.useMobile=f.useMobile,exports.useTablet=f.useTablet,exports.Accordion=D,exports.Backdrop=T,exports.Breadcrumb=M,exports.Button=q,exports.Chips=P,exports.Dialog=v,exports.DialogButton=w,exports.Divider=I,exports.Drawer=C,exports.ImageUpload=z,exports.Input=k,exports.Menu=U,exports.Pagination=R,exports.RadioGroup=L,exports.Select=A,exports.Tabs=B,exports.Typography=N;
@@ -0,0 +1 @@
1
+ "use client";import{jsxs as e,jsx as t}from"react/jsx-runtime";import r,{useState as a,useRef as l,useId as o,useEffect as n}from"react";import i from"./utils.js";import{useMobile as s}from"./contexts.js";const ChevronDownIcon=({className:e})=>t("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",className:e,children:t("path",{d:"M6 9L12 15L18 9",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})}),d=r.forwardRef(({label:r,placeholder:d="انتخاب کنید",options:u,value:c,defaultValue:m,onChange:p,disabled:x=!1,error:h=!1,helperText:b,className:g,...v},f)=>{const[w,y]=a(!1),[k,N]=a(-1),[D,E]=a(m||""),L=l(null),j=l(null),$=o(),C=s(),A=void 0!==c,B=A?c:D,I=u.find(e=>e.value===B),K=Boolean(I);n(()=>{const handleClickOutside=e=>{L.current&&!L.current.contains(e.target)&&(y(!1),N(-1))};return document.addEventListener("mousedown",handleClickOutside),()=>document.removeEventListener("mousedown",handleClickOutside)},[]);const handleSelect=e=>{A||E(e),p?.(e),y(!1),N(-1)},M=C?"h-12 px-3 py-[13px] gap-2":"h-14 px-4 py-[15px] gap-3",T=C?"text-sm":"text-base",z=C?"w-5 h-5":"w-6 h-6",R=C?"py-[13px] px-3 gap-4":"py-4 px-4 gap-4",S=C?"text-sm":"text-base";return e("div",{className:i("relative",C?"min-w-[204px] w-full":"min-w-[229px] w-full",g),...v,children:[e("div",{ref:f,role:"combobox","aria-expanded":w,"aria-haspopup":"listbox","aria-controls":`${$}-listbox`,"aria-labelledby":`${$}-label`,tabIndex:x?-1:0,className:i("relative flex items-center justify-between bg-white border rounded-md cursor-pointer transition-colors duration-200",M,{"border-neutral-light hover:border-neutral-main":!h&&!x,"border-error":h,"border-neutral-light bg-neutral-lighter cursor-not-allowed":x,"border-primary":w&&!h}),onClick:()=>{x||(y(!w),N(w?-1:0))},onKeyDown:e=>{if(!x)switch(e.key){case"Enter":case" ":e.preventDefault(),w?k>=0&&handleSelect(u[k].value):(y(!0),N(0));break;case"Escape":case"Tab":y(!1),N(-1);break;case"ArrowDown":e.preventDefault(),w?N(e=>e<u.length-1?e+1:e):(y(!0),N(0));break;case"ArrowUp":e.preventDefault(),w&&N(e=>e>0?e-1:e)}},children:[t("div",{className:"flex-1 text-right",children:t("span",{className:i("block transition-colors",T,{"text-neutral-main":!K&&!x||x,"text-neutral-darker":K&&!x}),children:I?I.label:d})}),t(ChevronDownIcon,{className:i("transition-transform duration-200 text-neutral-main",z,{"rotate-180":w,"text-neutral-light":x})}),K&&t("div",{className:i("absolute -top-2 bg-white px-1 text-neutral-main transition-all duration-200",C?"right-2 text-xs":"right-3 text-sm"),id:`${$}-label`,children:r})]}),w&&t("div",{className:i("absolute top-full left-0 right-0 z-50 mt-1 bg-white border border-neutral-light rounded-md shadow-lg",R),children:t("ul",{ref:j,role:"listbox",id:`${$}-listbox`,"aria-labelledby":`${$}-label`,className:"flex flex-col items-end",children:u.map((e,r)=>t("li",{role:"option","aria-selected":e.value===B,className:i("w-full cursor-pointer text-right py-2 transition-colors duration-150",S,{"bg-primary-lightest":r===k,"text-neutral-darker":e.value!==B,"text-primary font-medium":e.value===B}),onClick:()=>handleSelect(e.value),onKeyDown:t=>{"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),handleSelect(e.value))},onMouseEnter:()=>N(r),tabIndex:-1,children:e.label},e.value))})}),b&&t("div",{className:i("mt-1 text-xs text-right",{"text-error":h,"text-neutral-main":!h}),children:b})]})});d.displayName="Select";export{d as Select};
package/dist/esm/index.js CHANGED
@@ -1 +1 @@
1
- import{Typography as e}from"./Typography.js";import{Button as r}from"./Button.js";import{Input as o}from"./Input.js";import{Tabs as a}from"./Tabs.js";import{Drawer as t}from"./Drawer.js";import{Backdrop as s}from"./Backdrop.js";import{Breadcrumb as i}from"./Breadcrumb.js";import{Pagination as l}from"./Pagination.js";import{Accordion as n}from"./Accordion.js";import{Divider as m}from"./Divider.js";import{RadioGroup as c}from"./RadioGroup.js";import{X as d,C as p}from"./chunks/Chips-Dg1jNlMl.js";import{Menu as f}from"./Menu.js";import{jsx as b,jsxs as u}from"react/jsx-runtime";import x from"react";import h from"./utils.js";export{MobileProvider,useMobile,useTablet}from"./contexts.js";import"react-dom";import"./chunks/chevron-left-4HSuTes3.js";import"./chunks/createLucideIcon-DGp0SoUT.js";const g=x.forwardRef(({isOpen:e=!1,onClose:r,title:o,content:a,buttons:t,showCloseButton:i=!0,size:l="md",className:n,children:m},c)=>{const handleClose=()=>{r&&r()},p=h("bg-white rounded-[10px] shadow-lg mx-4",{sm:"max-w-sm",md:"max-w-md",lg:"max-w-lg",xl:"max-w-xl"}[l],n);return b(s,{isOpen:e,onClick:handleClose,blur:!0,children:b("div",{ref:c,className:p,onClick:e=>e.stopPropagation(),onKeyDown:e=>{"Escape"===e.key&&r&&r()},role:"dialog","aria-modal":"true","aria-labelledby":o?"dialog-title":void 0,children:u("div",{className:"flex flex-col p-6 gap-8",children:[o&&b("div",{className:"flex flex-col gap-2.5",children:b("div",{className:"flex items-center justify-between pb-4 border-b border-[#ebeaf0]",children:u("div",{className:"flex items-center justify-between gap-3 w-full flex-row-reverse",children:[b("div",{className:"text-[#590d8b] text-xl font-extrabold leading-8",children:o}),i&&b("button",{type:"button",onClick:handleClose,className:"p-1 rounded-full hover:bg-gray-100 transition-colors","aria-label":"Close dialog",children:b(d,{className:"w-6 h-6 text-[#a4a2bb]"})})]})})}),a&&b("div",{className:"flex flex-col gap-4",children:a}),m&&!a&&b("div",{className:"flex flex-col gap-4",children:m}),t&&b("div",{className:"flex flex-col gap-1.5",children:t})]})})})});g.displayName="Dialog";const j=x.forwardRef(({variant:e="primary",icon:r,children:o,className:a,...t},s)=>{const i=h("h-14 px-4 py-[13px] rounded-md font-bold text-base leading-[1.8] flex items-center justify-center gap-2 transition-colors",{"bg-[#590d8b] text-white hover:bg-[#4a0a75]":"primary"===e,"bg-white text-[#1a1922] border border-[#ebeaf0] hover:bg-gray-50":"secondary"===e},a);return u("button",{type:"button",ref:s,className:i,...t,children:[o,r&&b("span",{className:"w-5 h-5",children:r})]})});j.displayName="DialogButton";const w=e,y=r,v=o,N=a,k=t,B=s,C=i,D=l,T=n,M=m,P=c,R=p,I=f;export{T as Accordion,B as Backdrop,C as Breadcrumb,y as Button,R as Chips,g as Dialog,j as DialogButton,M as Divider,k as Drawer,v as Input,I as Menu,D as Pagination,P as RadioGroup,N as Tabs,w as Typography};
1
+ import{Typography as e}from"./Typography.js";import{Button as r}from"./Button.js";import{Input as a}from"./Input.js";import{Tabs as t}from"./Tabs.js";import{Drawer as l}from"./Drawer.js";import{Backdrop as o}from"./Backdrop.js";import{Breadcrumb as i}from"./Breadcrumb.js";import{Pagination as s}from"./Pagination.js";import{Accordion as n}from"./Accordion.js";import{Divider as c}from"./Divider.js";import{RadioGroup as m}from"./RadioGroup.js";import{X as d,C as p}from"./chunks/Chips-Dg1jNlMl.js";import{Menu as u}from"./Menu.js";import{jsxs as f,jsx as h}from"react/jsx-runtime";import b,{useMemo as g,useId as x,useEffect as v,useCallback as y}from"react";import j from"./utils.js";import{c as w}from"./chunks/createLucideIcon-DGp0SoUT.js";import{Select as N}from"./Select.js";export{MobileProvider,useMobile,useTablet}from"./contexts.js";import"react-dom";import"./chunks/chevron-left-4HSuTes3.js";const k=w("plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]]);const C=b.forwardRef(({value:r,onChange:a,label:t="ارسال عکس",instruction:l,maxSize:o=10485760,accept:i="image/jpeg,image/jpg,image/png",maxCount:s,onRejected:n,disabled:c=!1,className:m,addButtonText:p="اضافه",removeButtonAriaLabel:u="حذف عکس"},b)=>{const w=g(()=>function(e){if(!e||"*"===e)return/.*/;const r=e.split(",").map(e=>e.trim().replace(/^[^/]+\//,"").replace(/^\*\./,"")).filter(Boolean);if(0===r.length)return/.*/;const a=r.map(e=>e.replace(".","\\.")).join("|");return new RegExp(`\\.(${a})$`,"i")}(i),[i]),N=x(),C=g(()=>r.map(e=>e.type.startsWith("image/")?URL.createObjectURL(e):null),[r]);v(()=>()=>{C.forEach(e=>e&&URL.revokeObjectURL(e))},[C]);const B=y(e=>{const t=e.target.files?Array.from(e.target.files):[];e.target.value="";const l=r.length,{rejected:i,valid:c}=t.reduce((e,r)=>null!=s&&l+e.valid.length>=s?(e.rejected.push({file:r,reason:"count"}),e):r.size>o?(e.rejected.push({file:r,reason:"size"}),e):w.test(r.name)?(e.valid.push(r),e):(e.rejected.push({file:r,reason:"type"}),e),{rejected:[],valid:[]});if(c.length>0){const e=null!=s?[...r,...c].slice(0,s):[...r,...c];a(e)}i.length>0&&n?.(i)},[r,a,o,w,s,n]),R=y(e=>{if(c)return;const t=r.filter((r,a)=>a!==e);a(t)},[r,a,c]),D=null!=s&&r.length>=s;return f("div",{ref:b,className:j("",m),children:[t&&h(e,{variant:"body-s-medium",color:"neutral-darker",className:"mb-1",children:t}),null!=l&&h(e,{variant:"body-xs-medium",color:"neutral-main",className:"mb-2",children:l}),f("div",{className:"flex flex-wrap gap-2 items-center",children:[r.map((r,a)=>f("div",{className:"relative w-16 h-16 rounded-lg bg-neutral-light overflow-hidden group",children:[r.type.startsWith("image/")&&C[a]?h("img",{src:C[a],alt:"",className:"w-full h-full object-cover"}):h("div",{className:"w-full h-full flex items-center justify-center",children:h(e,{variant:"body-xs-medium",children:"فایل"})}),!c&&h("button",{type:"button",onClick:()=>R(a),className:"absolute top-0.5 left-0.5 w-5 h-5 rounded-full bg-neutral-darker/70 text-white flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity","aria-label":u,children:h(d,{className:"w-3 h-3"})})]},`${r.name}-${r.size}-${r.lastModified}`)),!c&&!D&&f("label",{htmlFor:N,className:"w-16 h-16 rounded-lg border-2 border-dashed border-neutral-main flex items-center justify-center cursor-pointer hover:border-primary-main hover:bg-primary-main/5 transition-colors",children:[h("input",{id:N,type:"file",accept:i,multiple:!0,className:"sr-only",onChange:B}),f("div",{className:"flex flex-col items-center gap-0.5",children:[h(k,{className:"w-5 h-5 text-neutral-main"}),h(e,{variant:"body-xs-medium",color:"neutral-main",children:p})]})]})]})]})});C.displayName="ImageUpload";const B=b.forwardRef(({isOpen:e=!1,onClose:r,title:a,content:t,buttons:l,showCloseButton:i=!0,size:s="md",className:n,children:c},m)=>{const handleClose=()=>{r&&r()},p=j("bg-white rounded-[10px] shadow-lg mx-4",{sm:"max-w-sm",md:"max-w-md",lg:"max-w-lg",xl:"max-w-xl"}[s],n);return h(o,{isOpen:e,onClick:handleClose,blur:!0,children:h("div",{ref:m,className:p,onClick:e=>e.stopPropagation(),onKeyDown:e=>{"Escape"===e.key&&r&&r()},role:"dialog","aria-modal":"true","aria-labelledby":a?"dialog-title":void 0,children:f("div",{className:"flex flex-col p-6 gap-8",children:[a&&h("div",{className:"flex flex-col gap-2.5",children:h("div",{className:"flex items-center justify-between pb-4 border-b border-[#ebeaf0]",children:f("div",{className:"flex items-center justify-between gap-3 w-full flex-row-reverse",children:[h("div",{className:"text-[#590d8b] text-xl font-extrabold leading-8",children:a}),i&&h("button",{type:"button",onClick:handleClose,className:"p-1 rounded-full hover:bg-gray-100 transition-colors","aria-label":"Close dialog",children:h(d,{className:"w-6 h-6 text-[#a4a2bb]"})})]})})}),t&&h("div",{className:"flex flex-col gap-4",children:t}),c&&!t&&h("div",{className:"flex flex-col gap-4",children:c}),l&&h("div",{className:"flex flex-col gap-1.5",children:l})]})})})});B.displayName="Dialog";const R=b.forwardRef(({variant:e="primary",icon:r,children:a,className:t,...l},o)=>{const i=j("h-14 px-4 py-[13px] rounded-md font-bold text-base leading-[1.8] flex items-center justify-center gap-2 transition-colors",{"bg-[#590d8b] text-white hover:bg-[#4a0a75]":"primary"===e,"bg-white text-[#1a1922] border border-[#ebeaf0] hover:bg-gray-50":"secondary"===e},t);return f("button",{type:"button",ref:o,className:i,...l,children:[a,r&&h("span",{className:"w-5 h-5",children:r})]})});R.displayName="DialogButton";const D=e,M=r,L=a,T=t,z=l,U=o,$=i,A=s,I=n,O=c,P=m,E=p,S=u,G=C,W=N;export{I as Accordion,U as Backdrop,$ as Breadcrumb,M as Button,E as Chips,B as Dialog,R as DialogButton,O as Divider,z as Drawer,G as ImageUpload,L as Input,S as Menu,A as Pagination,P as RadioGroup,W as Select,T as Tabs,D as Typography};
@@ -0,0 +1,131 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import React, { useState, useRef, useId, useEffect } from 'react';
3
+ import cn from './utils.js';
4
+ import { useMobile } from './contexts.js';
5
+
6
+ const ChevronDownIcon = ({ className }) => (jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: className, children: jsx("path", { d: "M6 9L12 15L18 9", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }));
7
+ const Select = React.forwardRef(({ label, placeholder = 'انتخاب کنید', options, value: controlledValue, defaultValue, onChange, disabled = false, error = false, helperText, className, ...props }, ref) => {
8
+ const [isOpen, setIsOpen] = useState(false);
9
+ const [focusedIndex, setFocusedIndex] = useState(-1);
10
+ const [internalValue, setInternalValue] = useState(defaultValue || '');
11
+ const selectRef = useRef(null);
12
+ const listRef = useRef(null);
13
+ const id = useId();
14
+ const isMobile = useMobile();
15
+ // Determine if component is controlled or uncontrolled
16
+ const isControlled = controlledValue !== undefined;
17
+ const value = isControlled ? controlledValue : internalValue;
18
+ const selectedOption = options.find((option) => option.value === value);
19
+ const hasValue = Boolean(selectedOption);
20
+ // Close dropdown when clicking outside
21
+ useEffect(() => {
22
+ const handleClickOutside = (event) => {
23
+ if (selectRef.current &&
24
+ !selectRef.current.contains(event.target)) {
25
+ setIsOpen(false);
26
+ setFocusedIndex(-1);
27
+ }
28
+ };
29
+ document.addEventListener('mousedown', handleClickOutside);
30
+ return () => document.removeEventListener('mousedown', handleClickOutside);
31
+ }, []);
32
+ const handleSelect = (optionValue) => {
33
+ // Update internal state for uncontrolled component
34
+ if (!isControlled) {
35
+ setInternalValue(optionValue);
36
+ }
37
+ // Call onChange callback
38
+ onChange?.(optionValue);
39
+ // Close dropdown
40
+ setIsOpen(false);
41
+ setFocusedIndex(-1);
42
+ };
43
+ // Handle keyboard navigation
44
+ const handleKeyDown = (event) => {
45
+ if (disabled)
46
+ return;
47
+ switch (event.key) {
48
+ case 'Enter':
49
+ case ' ':
50
+ event.preventDefault();
51
+ if (!isOpen) {
52
+ setIsOpen(true);
53
+ setFocusedIndex(0);
54
+ }
55
+ else if (focusedIndex >= 0) {
56
+ handleSelect(options[focusedIndex].value);
57
+ }
58
+ break;
59
+ case 'Escape':
60
+ setIsOpen(false);
61
+ setFocusedIndex(-1);
62
+ break;
63
+ case 'ArrowDown':
64
+ event.preventDefault();
65
+ if (!isOpen) {
66
+ setIsOpen(true);
67
+ setFocusedIndex(0);
68
+ }
69
+ else {
70
+ setFocusedIndex((prev) => prev < options.length - 1 ? prev + 1 : prev);
71
+ }
72
+ break;
73
+ case 'ArrowUp':
74
+ event.preventDefault();
75
+ if (isOpen) {
76
+ setFocusedIndex((prev) => (prev > 0 ? prev - 1 : prev));
77
+ }
78
+ break;
79
+ case 'Tab':
80
+ setIsOpen(false);
81
+ setFocusedIndex(-1);
82
+ break;
83
+ }
84
+ };
85
+ const handleToggle = () => {
86
+ if (!disabled) {
87
+ setIsOpen(!isOpen);
88
+ setFocusedIndex(isOpen ? -1 : 0);
89
+ }
90
+ };
91
+ // Responsive dimensions and styles
92
+ const containerClasses = isMobile
93
+ ? 'min-w-[204px] w-full'
94
+ : 'min-w-[229px] w-full';
95
+ const inputClasses = isMobile
96
+ ? 'h-12 px-3 py-[13px] gap-2'
97
+ : 'h-14 px-4 py-[15px] gap-3';
98
+ const textClasses = isMobile ? 'text-sm' : 'text-base';
99
+ const iconClasses = isMobile ? 'w-5 h-5' : 'w-6 h-6';
100
+ const dropdownClasses = isMobile
101
+ ? 'py-[13px] px-3 gap-4'
102
+ : 'py-4 px-4 gap-4';
103
+ const optionClasses = isMobile ? 'text-sm' : 'text-base';
104
+ return (jsxs("div", { className: cn('relative', containerClasses, className), ...props, children: [jsxs("div", { ref: ref, role: "combobox", "aria-expanded": isOpen, "aria-haspopup": "listbox", "aria-controls": `${id}-listbox`, "aria-labelledby": `${id}-label`, tabIndex: disabled ? -1 : 0, className: cn('relative flex items-center justify-between bg-white border rounded-md cursor-pointer transition-colors duration-200', inputClasses, {
105
+ 'border-neutral-light hover:border-neutral-main': !error && !disabled,
106
+ 'border-error': error,
107
+ 'border-neutral-light bg-neutral-lighter cursor-not-allowed': disabled,
108
+ 'border-primary': isOpen && !error,
109
+ }), onClick: handleToggle, onKeyDown: handleKeyDown, children: [jsx("div", { className: "flex-1 text-right", children: jsx("span", { className: cn('block transition-colors', textClasses, {
110
+ 'text-neutral-main': (!hasValue && !disabled) || disabled,
111
+ 'text-neutral-darker': hasValue && !disabled,
112
+ }), children: selectedOption ? selectedOption.label : placeholder }) }), jsx(ChevronDownIcon, { className: cn('transition-transform duration-200 text-neutral-main', iconClasses, {
113
+ 'rotate-180': isOpen,
114
+ 'text-neutral-light': disabled,
115
+ }) }), hasValue && (jsx("div", { className: cn('absolute -top-2 bg-white px-1 text-neutral-main transition-all duration-200', isMobile ? 'right-2 text-xs' : 'right-3 text-sm'), id: `${id}-label`, children: label }))] }), isOpen && (jsx("div", { className: cn('absolute top-full left-0 right-0 z-50 mt-1 bg-white border border-neutral-light rounded-md shadow-lg', dropdownClasses), children: jsx("ul", { ref: listRef, role: "listbox", id: `${id}-listbox`, "aria-labelledby": `${id}-label`, className: "flex flex-col items-end", children: options.map((option, index) => (jsx("li", { role: "option", "aria-selected": option.value === value, className: cn('w-full cursor-pointer text-right py-2 transition-colors duration-150', optionClasses, {
116
+ 'bg-primary-lightest': index === focusedIndex,
117
+ 'text-neutral-darker': option.value !== value,
118
+ 'text-primary font-medium': option.value === value,
119
+ }), onClick: () => handleSelect(option.value), onKeyDown: (e) => {
120
+ if (e.key === 'Enter' || e.key === ' ') {
121
+ e.preventDefault();
122
+ handleSelect(option.value);
123
+ }
124
+ }, onMouseEnter: () => setFocusedIndex(index), tabIndex: -1, children: option.label }, option.value))) }) })), helperText && (jsx("div", { className: cn('mt-1 text-xs text-right', {
125
+ 'text-error': error,
126
+ 'text-neutral-main': !error,
127
+ }), children: helperText }))] }));
128
+ });
129
+ Select.displayName = 'Select';
130
+
131
+ export { Select };
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ export interface ImageUploadRejected {
3
+ file: File;
4
+ reason: 'size' | 'type' | 'count';
5
+ }
6
+ export interface ImageUploadProps {
7
+ /** Current list of files (controlled). */
8
+ value: File[];
9
+ /** Called when the list of files changes. */
10
+ onChange: (files: File[]) => void;
11
+ /** Label above the upload area. */
12
+ label?: string;
13
+ /** Instruction or hint text below the label. */
14
+ instruction?: string;
15
+ /** Maximum file size in bytes (default: 10MB). */
16
+ maxSize?: number;
17
+ /** Accept attribute for the file input (default: image/jpeg, image/jpg, image/png). */
18
+ accept?: string;
19
+ /** Maximum number of files allowed. New files are ignored when at limit. */
20
+ maxCount?: number;
21
+ /** Called when one or more files are rejected (e.g. too large or wrong type). */
22
+ onRejected?: (rejected: ImageUploadRejected[]) => void;
23
+ /** Disable adding/removing files. */
24
+ disabled?: boolean;
25
+ /** Optional class for the root wrapper. */
26
+ className?: string;
27
+ /** Text for the add button (default: "اضافه" for RTL). */
28
+ addButtonText?: string;
29
+ /** Aria label for the remove button. */
30
+ removeButtonAriaLabel?: string;
31
+ }
32
+ export declare const ImageUpload: React.ForwardRefExoticComponent<ImageUploadProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,92 @@
1
+ import React from 'react';
2
+ import { ImageUploadProps } from './ImageUpload';
3
+ type StoryArgs = ImageUploadProps;
4
+ declare const _default: {
5
+ title: string;
6
+ component: React.ForwardRefExoticComponent<ImageUploadProps & React.RefAttributes<HTMLDivElement>>;
7
+ parameters: {
8
+ docs: {
9
+ description: {
10
+ component: string;
11
+ };
12
+ };
13
+ };
14
+ argTypes: {
15
+ value: {
16
+ table: {
17
+ disable: boolean;
18
+ };
19
+ };
20
+ onChange: {
21
+ table: {
22
+ disable: boolean;
23
+ };
24
+ };
25
+ label: {
26
+ name: string;
27
+ control: {
28
+ type: string;
29
+ };
30
+ };
31
+ instruction: {
32
+ name: string;
33
+ control: {
34
+ type: string;
35
+ };
36
+ };
37
+ maxSize: {
38
+ name: string;
39
+ control: {
40
+ type: string;
41
+ };
42
+ };
43
+ maxCount: {
44
+ name: string;
45
+ control: {
46
+ type: string;
47
+ };
48
+ };
49
+ disabled: {
50
+ name: string;
51
+ control: {
52
+ type: string;
53
+ };
54
+ };
55
+ addButtonText: {
56
+ name: string;
57
+ control: {
58
+ type: string;
59
+ };
60
+ };
61
+ onRejected: {
62
+ table: {
63
+ disable: boolean;
64
+ };
65
+ };
66
+ };
67
+ args: {
68
+ label: string;
69
+ instruction: string;
70
+ maxSize: number;
71
+ maxCount: undefined;
72
+ disabled: boolean;
73
+ addButtonText: string;
74
+ };
75
+ };
76
+ export default _default;
77
+ export declare const Default: {
78
+ ({ instruction, ...rest }: StoryArgs): import("react/jsx-runtime").JSX.Element;
79
+ storyName: string;
80
+ };
81
+ export declare const WithMaxCount: {
82
+ ({ ...args }: StoryArgs): import("react/jsx-runtime").JSX.Element;
83
+ storyName: string;
84
+ };
85
+ export declare const WithRejectedCallback: {
86
+ ({ ...args }: StoryArgs): import("react/jsx-runtime").JSX.Element;
87
+ storyName: string;
88
+ };
89
+ export declare const Disabled: {
90
+ ({ ...args }: StoryArgs): import("react/jsx-runtime").JSX.Element;
91
+ storyName: string;
92
+ };
@@ -19,6 +19,8 @@ export declare const Divider: import("react").ForwardRefExoticComponent<import("
19
19
  export declare const RadioGroup: import("react").ForwardRefExoticComponent<import("./components/RadioGroup/RadioGroup").RadioGroupProps & import("react").RefAttributes<HTMLDivElement>>;
20
20
  export declare const Chips: import("react").ForwardRefExoticComponent<import("./components/Chips/Chips").ChipsProps & import("react").RefAttributes<HTMLDivElement>>;
21
21
  export declare const Menu: import("react").ForwardRefExoticComponent<import("./components/Menu/Menu").MenuProps & import("react").RefAttributes<HTMLDivElement>>;
22
+ export declare const ImageUpload: import("react").ForwardRefExoticComponent<import("./components/ImageUpload/ImageUpload").ImageUploadProps & import("react").RefAttributes<HTMLDivElement>>;
23
+ export declare const Select: import("react").ForwardRefExoticComponent<import("./components/Select/Select").SelectProps & import("react").RefAttributes<HTMLDivElement>>;
22
24
  export type { TypographyProps, TypographyVariant, } from './components/Typography/Typography';
23
25
  export type { ButtonProps, ButtonVariant, ButtonSize, } from './components/Button/Button';
24
26
  export type { InputProps } from './components/Input/Input';
@@ -33,6 +35,8 @@ export type { DividerProps } from './components/Divider/Divider';
33
35
  export type { RadioGroupProps, RadioOption, } from './components/RadioGroup/RadioGroup';
34
36
  export type { ChipsProps } from './components/Chips/Chips';
35
37
  export type { MenuProps, MenuItem } from './components/Menu/Menu';
38
+ export type { ImageUploadProps, ImageUploadRejected, } from './components/ImageUpload/ImageUpload';
39
+ export type { SelectProps, SelectOption } from './components/Select/Select';
36
40
  export { MobileProvider } from './contexts/MobileContext';
37
41
  export { useMobile } from './contexts/MobileContext';
38
42
  export { useTablet } from './contexts/MobileContext';
@@ -11,13 +11,96 @@ import { Divider as Divider$1 } from './Divider.js';
11
11
  import { RadioGroup as RadioGroup$1 } from './RadioGroup.js';
12
12
  import { X, C as Chips$1 } from './Chips-DfvV08WT.js';
13
13
  import { Menu as Menu$1 } from './Menu.js';
14
- import { jsx, jsxs } from 'react/jsx-runtime';
15
- import React from 'react';
14
+ import { jsxs, jsx } from 'react/jsx-runtime';
15
+ import React, { useMemo, useId, useEffect, useCallback } from 'react';
16
16
  import cn from './utils.js';
17
+ import { c as createLucideIcon } from './createLucideIcon-D-q73LTT.js';
18
+ import { Select as Select$1 } from './Select.js';
17
19
  export { MobileProvider, useMobile, useTablet } from './contexts.js';
18
20
  import 'react-dom';
19
21
  import './chevron-left-Ck6O99eF.js';
20
- import './createLucideIcon-D-q73LTT.js';
22
+
23
+ /**
24
+ * @license lucide-react v0.522.0 - ISC
25
+ *
26
+ * This source code is licensed under the ISC license.
27
+ * See the LICENSE file in the root directory of this source tree.
28
+ */
29
+
30
+
31
+ const __iconNode = [
32
+ ["path", { d: "M5 12h14", key: "1ays0h" }],
33
+ ["path", { d: "M12 5v14", key: "s699le" }]
34
+ ];
35
+ const Plus = createLucideIcon("plus", __iconNode);
36
+
37
+ const DEFAULT_MAX_SIZE_BYTES = 10 * 1024 * 1024; // 10MB
38
+ const DEFAULT_ACCEPT = 'image/jpeg,image/jpg,image/png';
39
+ function getAcceptRegex(accept) {
40
+ if (!accept || accept === '*')
41
+ return /.*/;
42
+ const extensions = accept
43
+ .split(',')
44
+ .map((s) => s
45
+ .trim()
46
+ .replace(/^[^/]+\//, '')
47
+ .replace(/^\*\./, ''))
48
+ .filter(Boolean);
49
+ if (extensions.length === 0)
50
+ return /.*/;
51
+ const pattern = extensions.map((ext) => ext.replace('.', '\\.')).join('|');
52
+ return new RegExp(`\\.(${pattern})$`, 'i');
53
+ }
54
+ const ImageUpload$1 = React.forwardRef(({ value, onChange, label = 'ارسال عکس', instruction, maxSize = DEFAULT_MAX_SIZE_BYTES, accept = DEFAULT_ACCEPT, maxCount, onRejected, disabled = false, className, addButtonText = 'اضافه', removeButtonAriaLabel = 'حذف عکس', }, ref) => {
55
+ const acceptRegex = useMemo(() => getAcceptRegex(accept), [accept]);
56
+ const inputId = useId();
57
+ const objectUrls = useMemo(() => value.map((file) => file.type.startsWith('image/') ? URL.createObjectURL(file) : null), [value]);
58
+ useEffect(() => {
59
+ return () => {
60
+ objectUrls.forEach((url) => url && URL.revokeObjectURL(url));
61
+ };
62
+ }, [objectUrls]);
63
+ const handleFileChange = useCallback((e) => {
64
+ const files = e.target.files ? Array.from(e.target.files) : [];
65
+ e.target.value = '';
66
+ const currentCount = value.length;
67
+ const { rejected, valid } = files.reduce((acc, file) => {
68
+ if (maxCount != null &&
69
+ currentCount + acc.valid.length >= maxCount) {
70
+ acc.rejected.push({ file, reason: 'count' });
71
+ return acc;
72
+ }
73
+ if (file.size > maxSize) {
74
+ acc.rejected.push({ file, reason: 'size' });
75
+ return acc;
76
+ }
77
+ if (!acceptRegex.test(file.name)) {
78
+ acc.rejected.push({ file, reason: 'type' });
79
+ return acc;
80
+ }
81
+ acc.valid.push(file);
82
+ return acc;
83
+ }, { rejected: [], valid: [] });
84
+ if (valid.length > 0) {
85
+ const next = maxCount != null
86
+ ? [...value, ...valid].slice(0, maxCount)
87
+ : [...value, ...valid];
88
+ onChange(next);
89
+ }
90
+ if (rejected.length > 0) {
91
+ onRejected?.(rejected);
92
+ }
93
+ }, [value, onChange, maxSize, acceptRegex, maxCount, onRejected]);
94
+ const removeImage = useCallback((index) => {
95
+ if (disabled)
96
+ return;
97
+ const next = value.filter((_, i) => i !== index);
98
+ onChange(next);
99
+ }, [value, onChange, disabled]);
100
+ const atLimit = maxCount != null && value.length >= maxCount;
101
+ return (jsxs("div", { ref: ref, className: cn('', className), children: [label && (jsx(Typography$1, { variant: "body-s-medium", color: "neutral-darker", className: "mb-1", children: label })), instruction != null && (jsx(Typography$1, { variant: "body-xs-medium", color: "neutral-main", className: "mb-2", children: instruction })), jsxs("div", { className: "flex flex-wrap gap-2 items-center", children: [value.map((file, index) => (jsxs("div", { className: "relative w-16 h-16 rounded-lg bg-neutral-light overflow-hidden group", children: [file.type.startsWith('image/') && objectUrls[index] ? (jsx("img", { src: objectUrls[index], alt: "", className: "w-full h-full object-cover" })) : (jsx("div", { className: "w-full h-full flex items-center justify-center", children: jsx(Typography$1, { variant: "body-xs-medium", children: "\u0641\u0627\u06CC\u0644" }) })), !disabled && (jsx("button", { type: "button", onClick: () => removeImage(index), className: "absolute top-0.5 left-0.5 w-5 h-5 rounded-full bg-neutral-darker/70 text-white flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity", "aria-label": removeButtonAriaLabel, children: jsx(X, { className: "w-3 h-3" }) }))] }, `${file.name}-${file.size}-${file.lastModified}`))), !disabled && !atLimit && (jsxs("label", { htmlFor: inputId, className: "w-16 h-16 rounded-lg border-2 border-dashed border-neutral-main flex items-center justify-center cursor-pointer hover:border-primary-main hover:bg-primary-main/5 transition-colors", children: [jsx("input", { id: inputId, type: "file", accept: accept, multiple: true, className: "sr-only", onChange: handleFileChange }), jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [jsx(Plus, { className: "w-5 h-5 text-neutral-main" }), jsx(Typography$1, { variant: "body-xs-medium", color: "neutral-main", children: addButtonText })] })] }))] })] }));
102
+ });
103
+ ImageUpload$1.displayName = 'ImageUpload';
21
104
 
22
105
  const Dialog = React.forwardRef(({ isOpen = false, onClose, title, content, buttons, showCloseButton = true, size = 'md', className, children, }, ref) => {
23
106
  const handleClose = () => {
@@ -64,5 +147,7 @@ const Divider = Divider$1;
64
147
  const RadioGroup = RadioGroup$1;
65
148
  const Chips = Chips$1;
66
149
  const Menu = Menu$1;
150
+ const ImageUpload = ImageUpload$1;
151
+ const Select = Select$1;
67
152
 
68
- export { Accordion, Backdrop, Breadcrumb, Button, Chips, Dialog, DialogButton, Divider, Drawer, Input, Menu, Pagination, RadioGroup, Tabs, Typography };
153
+ export { Accordion, Backdrop, Breadcrumb, Button, Chips, Dialog, DialogButton, Divider, Drawer, ImageUpload, Input, Menu, Pagination, RadioGroup, Select, Tabs, Typography };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "automoby-kit",
3
- "version": "1.0.72",
3
+ "version": "1.0.74",
4
4
  "description": "A comprehensive React UI component library - created in war 2025",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -79,6 +79,11 @@
79
79
  "require": "./dist/cjs/Menu.js",
80
80
  "types": "./dist/types/components/Menu/Menu.d.ts"
81
81
  },
82
+ "./Select": {
83
+ "import": "./dist/esm/Select.js",
84
+ "require": "./dist/cjs/Select.js",
85
+ "types": "./dist/types/components/Select/Select.d.ts"
86
+ },
82
87
  "./contexts": {
83
88
  "import": "./dist/esm/contexts.js",
84
89
  "require": "./dist/cjs/contexts.js",