@waveinno/ui 0.4.0 → 0.6.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.
Files changed (44) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +2 -2
  3. package/dist/components/patterns/index.d.ts +1 -0
  4. package/dist/components/patterns/index.js +1 -1
  5. package/dist/components/patterns/org-chart.d.ts +51 -0
  6. package/dist/components/patterns/org-chart.js +1 -0
  7. package/dist/components/ui/accordion.d.ts +30 -0
  8. package/dist/components/ui/accordion.js +1 -0
  9. package/dist/components/ui/avatar.js +1 -1
  10. package/dist/components/ui/calendar.js +1 -1
  11. package/dist/components/ui/carousel.d.ts +27 -0
  12. package/dist/components/ui/carousel.js +1 -0
  13. package/dist/components/ui/color-picker.d.ts +14 -0
  14. package/dist/components/ui/color-picker.js +1 -0
  15. package/dist/components/ui/confirm-dialog.d.ts +24 -11
  16. package/dist/components/ui/confirm-dialog.js +1 -1
  17. package/dist/components/ui/date-picker.d.ts +18 -1
  18. package/dist/components/ui/date-picker.js +1 -1
  19. package/dist/components/ui/file-upload.d.ts +12 -4
  20. package/dist/components/ui/file-upload.js +1 -1
  21. package/dist/components/ui/hover-card.d.ts +17 -0
  22. package/dist/components/ui/hover-card.js +1 -0
  23. package/dist/components/ui/index.d.ts +10 -0
  24. package/dist/components/ui/index.js +1 -1
  25. package/dist/components/ui/menu.d.ts +24 -0
  26. package/dist/components/ui/menu.js +1 -1
  27. package/dist/components/ui/pagination.d.ts +51 -0
  28. package/dist/components/ui/pagination.js +1 -0
  29. package/dist/components/ui/rating.d.ts +27 -0
  30. package/dist/components/ui/rating.js +1 -0
  31. package/dist/components/ui/scroll-area.d.ts +17 -0
  32. package/dist/components/ui/scroll-area.js +1 -0
  33. package/dist/components/ui/slider.d.ts +18 -6
  34. package/dist/components/ui/slider.js +1 -1
  35. package/dist/components/ui/steps.d.ts +36 -0
  36. package/dist/components/ui/steps.js +1 -0
  37. package/dist/components/ui/tag-input.d.ts +33 -0
  38. package/dist/components/ui/tag-input.js +1 -0
  39. package/dist/components/ui/toast.d.ts +12 -1
  40. package/dist/components/ui/toast.js +1 -1
  41. package/dist/components/ui/tree-view.d.ts +38 -0
  42. package/dist/components/ui/tree-view.js +1 -0
  43. package/dist/styles.css +143 -0
  44. package/package.json +4 -1
@@ -1 +1 @@
1
- "use client";import{Fragment as Q,jsx as r,jsxs as n}from"react/jsx-runtime";import{CloudUpload as j,File as A,FileImage as H,FileSpreadsheet as K,FileText as X,RotateCcw as q,X as E}from"lucide-react";import*as d from"react";import{cn as f}from"../../lib/utils.js";const k=t=>t<1024*1024?`${Math.max(1,Math.round(t/1024))} KB`:`${(t/1024/1024).toFixed(1)} MB`;function G(t,i){return i?i.split(",").some(u=>{const s=u.trim().toLowerCase();return s.startsWith(".")?t.name.toLowerCase().endsWith(s):s.endsWith("/*")?t.type.startsWith(s.slice(0,-1)):t.type===s}):!0}function O({file:t}){const i=t.name.toLowerCase();return t.type.startsWith("image/")?r(H,{}):/\.(csv|xlsx?|ods)$/.test(i)?r(K,{}):/\.(pdf|docx?|txt|md)$/.test(i)?r(X,{}):r(A,{})}function J({file:t}){const[i,u]=d.useState(null);return d.useEffect(()=>{if(!t.type.startsWith("image/"))return;const s=URL.createObjectURL(t);return u(s),()=>URL.revokeObjectURL(s)},[t]),r("span",{className:"grid size-10 shrink-0 place-items-center overflow-hidden rounded-[calc(9px*var(--radius-scale))] border border-border bg-surface text-muted [&_svg]:size-[18px]",children:i?r("img",{src:i,alt:"",className:"size-full object-cover"}):r(O,{file:t})})}function ee({value:t,defaultValue:i=[],onValueChange:u,accept:s,multiple:v=!0,maxSize:m,maxFiles:p,variant:M="dropzone",title:z,hint:W,progress:I,failed:T,onRetry:F,disabled:b,className:B}){const[V,P]=d.useState(i),g=t??V,[_,R]=d.useState([]),[x,y]=d.useState(!1),N=d.useRef(null),h=d.useRef(0),$=e=>{t===void 0&&P(e),u?.(e)},C=e=>{if(!e)return;const a=[],o=[];for(const c of Array.from(e))G(c,s)?m&&c.size>m?o.push({file:c,reason:`Over ${k(m)}`}):a.push(c):o.push({file:c,reason:"Not an accepted type"});let l=v?[...g,...a.filter(c=>!g.some(L=>L.name===c.name&&L.size===c.size))]:a.slice(0,1);p&&l.length>p&&(l.slice(p).forEach(c=>o.push({file:c,reason:`Only ${p} file${p>1?"s":""}`})),l=l.slice(0,p)),R(o),$(l)},S=e=>$(g.filter(a=>a!==e)),w=W??[s?.split(",").map(e=>e.trim().replace(/^\./,"").toUpperCase()).join(", "),m?`up to ${k(m)}`:null].filter(Boolean).join(" \xB7 "),D=r("input",{ref:N,type:"file",className:"sr-only",tabIndex:-1,accept:s,multiple:v,disabled:b,onChange:e=>{C(e.target.files),e.target.value=""}}),U={onDragEnter:e=>{e.preventDefault(),h.current+=1,y(!0)},onDragOver:e=>e.preventDefault(),onDragLeave:()=>{h.current-=1,h.current<=0&&y(!1)},onDrop:e=>{e.preventDefault(),h.current=0,y(!1),b||C(e.dataTransfer.files)}};return n("div",{className:f("w-full space-y-2.5",B),children:[M==="dropzone"?n("button",{type:"button",disabled:b,onClick:()=>N.current?.click(),...U,className:f("group relative flex w-full cursor-pointer flex-col items-center justify-center gap-2 overflow-hidden rounded-[calc(14px*var(--radius-scale))] border-[1.5px] border-dashed border-border2 bg-surface px-6 py-8 text-center outline-none","transition-[border-color,background-color,box-shadow] duration-200 hover:border-primary/50 hover:bg-primary-subtle/30 focus-visible:ring-2 focus-visible:ring-primary/35",x&&"border-primary bg-primary-subtle/50 shadow-[0_0_0_4px_var(--primary-subtle)]",b&&"cursor-not-allowed opacity-50"),children:[r("span",{className:f("grid size-12 place-items-center rounded-[calc(14px*var(--radius-scale))] border border-border bg-raised text-primary shadow-[var(--lit),0_4px_12px_-6px_color-mix(in_srgb,var(--primary)_45%,transparent)] transition-transform duration-300 ease-[cubic-bezier(.3,1.5,.5,1)] [&_svg]:size-[22px]",x?"-translate-y-1 scale-110":"group-hover:-translate-y-0.5"),children:r(j,{})}),r("span",{className:"text-[13.5px] font-semibold text-text",children:x?"Drop to add":z??n(Q,{children:[n("span",{className:"text-primary",children:["Choose ",v?"files":"a file"]})," or drag ",v?"them":"it"," here"]})}),w?r("span",{className:"text-[12px] text-muted",children:w}):null,D]}):n("div",{...U,className:f("flex items-center gap-3 rounded-ctl border border-dashed border-border2 bg-surface p-2 pl-3 transition-colors",x&&"border-primary bg-primary-subtle/50"),children:[r(j,{className:"size-4 shrink-0 text-muted"}),r("span",{className:"min-w-0 flex-1 truncate text-[12.5px] text-muted",children:x?"Drop to add":z??w??"Drag files here"}),r("button",{type:"button",disabled:b,onClick:()=>N.current?.click(),className:"h-7 shrink-0 cursor-pointer rounded-[calc(7px*var(--radius-scale))] border border-border2 bg-raised px-2.5 text-[12px] font-medium text-text shadow-[0_1px_1px_rgba(5,8,22,.05)] transition-colors hover:bg-hover disabled:cursor-not-allowed disabled:opacity-50",children:"Browse"}),D]}),g.length||_.length?n("ul",{className:"space-y-1.5",children:[g.map(e=>{const a=I?.[e.name],o=T?.includes(e.name),l=a!==void 0&&a<100&&!o;return n("li",{className:"flex items-center gap-3 rounded-[calc(11px*var(--radius-scale))] border border-border bg-raised p-2 pr-2.5 animate-[wave-in_220ms_var(--ease)]",children:[r(J,{file:e}),n("span",{className:"min-w-0 flex-1",children:[r("span",{className:"block truncate text-[13px] font-medium text-text",children:e.name}),n("span",{className:f("num flex items-center gap-1.5 text-[11.5px]",o?"text-danger":"text-muted"),children:[k(e.size),o?" \xB7 Upload failed":a===100?" \xB7 Uploaded":l?` \xB7 ${Math.round(a)}%`:null]}),l?r("span",{className:"mt-1.5 block h-1 overflow-hidden rounded-full bg-hover",children:r("span",{className:"block h-full rounded-full bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))] transition-[width] duration-300",style:{width:`${a}%`}})}):null]}),o&&F?r("button",{type:"button",onClick:()=>F(e),"aria-label":`Retry ${e.name}`,className:"grid size-7 cursor-pointer place-items-center rounded-[calc(7px*var(--radius-scale))] text-danger transition-colors hover:bg-danger-subtle [&_svg]:size-3.5",children:r(q,{})}):null,r("button",{type:"button",onClick:()=>S(e),"aria-label":`Remove ${e.name}`,className:"grid size-7 cursor-pointer place-items-center rounded-[calc(7px*var(--radius-scale))] text-muted transition-colors hover:bg-hover hover:text-text [&_svg]:size-3.5",children:r(E,{})})]},`${e.name}-${e.size}-${e.lastModified}`)}),_.map(({file:e,reason:a})=>n("li",{className:"flex items-center gap-3 rounded-[calc(11px*var(--radius-scale))] border border-danger/25 bg-danger-subtle/50 p-2 pr-2.5",role:"alert",children:[r("span",{className:"grid size-10 shrink-0 place-items-center rounded-[calc(9px*var(--radius-scale))] border border-danger/20 bg-raised text-danger [&_svg]:size-[18px]",children:r(O,{file:e})}),n("span",{className:"min-w-0 flex-1",children:[r("span",{className:"block truncate text-[13px] font-medium text-text",children:e.name}),n("span",{className:"text-[11.5px] text-danger",children:[a," \xB7 not added"]})]}),r("button",{type:"button",onClick:()=>R(o=>o.filter(l=>l.file!==e)),"aria-label":`Dismiss ${e.name}`,className:"grid size-7 cursor-pointer place-items-center rounded-[calc(7px*var(--radius-scale))] text-muted transition-colors hover:bg-raised hover:text-text [&_svg]:size-3.5",children:r(E,{})})]},`x-${e.name}-${e.size}`))]}):null]})}export{ee as FileUpload};
1
+ "use client";import{Fragment as ue,jsx as e,jsxs as a}from"react/jsx-runtime";import{Camera as H,CloudUpload as K,File as ae,FileImage as X,FileSpreadsheet as J,FileText as se,ImagePlus as oe,RotateCcw as Q,Trash2 as ne,Upload as S,X as P}from"lucide-react";import*as y from"react";import{cn as c}from"../../lib/utils.js";const F=t=>t<1024*1024?`${Math.max(1,Math.round(t/1024))} KB`:`${(t/1024/1024).toFixed(1)} MB`;function ie(t,s){return s?s.split(",").some(i=>{const n=i.trim().toLowerCase();return n.startsWith(".")?t.name.toLowerCase().endsWith(n):n.endsWith("/*")?t.type.startsWith(n.slice(0,-1)):t.type===n}):!0}function W({file:t}){const s=t.name.toLowerCase();return t.type.startsWith("image/")?e(X,{}):/\.(csv|xlsx?|ods)$/.test(s)?e(J,{}):/\.(pdf|docx?|txt|md)$/.test(s)?e(se,{}):e(ae,{})}function O(t){const[s,i]=y.useState(null);return y.useEffect(()=>{if(!t||!t.type.startsWith("image/"))return i(null);const n=URL.createObjectURL(t);return i(n),()=>URL.revokeObjectURL(n)},[t]),s}function le({file:t}){const s=O(t);return e("span",{className:"grid size-10 shrink-0 place-items-center overflow-hidden rounded-[calc(9px*var(--radius-scale))] border border-border bg-surface text-muted [&_svg]:size-[18px]",children:s?e("img",{src:s,alt:"",className:"size-full object-cover"}):e(W,{file:t})})}function de({value:t,size:s=36}){const i=s/2-3,n=2*Math.PI*i;return a("svg",{width:s,height:s,viewBox:`0 0 ${s} ${s}`,className:"-rotate-90","aria-hidden":!0,children:[e("circle",{cx:s/2,cy:s/2,r:i,fill:"none",stroke:"rgba(255,255,255,.3)",strokeWidth:"3"}),e("circle",{cx:s/2,cy:s/2,r:i,fill:"none",stroke:"#fff",strokeWidth:"3",strokeLinecap:"round",strokeDasharray:n,strokeDashoffset:n*(1-t/100),className:"transition-[stroke-dashoffset] duration-300"})]})}function ce({file:t,progress:s,failed:i,onRemove:n,onRetry:z}){const p=O(t),l=s!==void 0&&s<100&&!i;return a("div",{className:"group/tile relative aspect-square animate-[wm-pop_220ms_var(--ease)] overflow-hidden rounded-[calc(12px*var(--radius-scale))] border border-border bg-surface",children:[p?e("img",{src:p,alt:t.name,className:"size-full object-cover"}):e("span",{className:"grid size-full place-items-center text-muted [&_svg]:size-6",children:e(W,{file:t})}),l?e("span",{className:"absolute inset-0 grid place-items-center bg-ink/45 backdrop-blur-[2px]",children:e(de,{value:s})}):null,i?e("button",{type:"button",onClick:z,"aria-label":`Retry ${t.name}`,className:"absolute inset-0 grid cursor-pointer place-items-center bg-danger/70 text-white [&_svg]:size-5",children:e(Q,{})}):null,e("button",{type:"button",onClick:n,"aria-label":`Remove ${t.name}`,className:"absolute right-1.5 top-1.5 grid size-6 cursor-pointer place-items-center rounded-full bg-ink/70 text-white opacity-0 backdrop-blur transition-opacity group-hover/tile:opacity-100 focus-visible:opacity-100 [&_svg]:size-3.5",children:e(P,{})}),e("span",{className:"pointer-events-none absolute inset-x-0 bottom-0 truncate bg-gradient-to-t from-black/60 to-transparent px-2 pb-1.5 pt-4 text-[11px] font-medium text-white opacity-0 transition-opacity group-hover/tile:opacity-100",children:t.name})]})}function ge({value:t,defaultValue:s=[],onValueChange:i,accept:n,multiple:z,maxSize:p,maxFiles:l,variant:h="dropzone",title:v,hint:j,progress:R,failed:C,onRetry:u,currentUrl:Y,disabled:f,className:L}){const $=h==="avatar"?!1:z??!0,[Z,ee]=y.useState(s),m=t??Z,[U,T]=y.useState([]),[d,E]=y.useState(!1),B=y.useRef(null),D=y.useRef(0),I=r=>{t===void 0&&ee(r),i?.(r)},A=r=>{if(!r)return;const o=[],b=[];for(const x of Array.from(r))ie(x,n)?p&&x.size>p?b.push({file:x,reason:`Over ${F(p)}`}):o.push(x):b.push({file:x,reason:"Not an accepted type"});let g=$?[...m,...o.filter(x=>!m.some(G=>G.name===x.name&&G.size===x.size))]:o.slice(0,1).length?o.slice(0,1):m;l&&g.length>l&&(g.slice(l).forEach(x=>b.push({file:x,reason:`Only ${l} file${l>1?"s":""}`})),g=g.slice(0,l)),T(b),I(g)},V=r=>I(m.filter(o=>o!==r)),_=()=>B.current?.click(),M=n?.split(",").map(r=>r.trim().replace(/^\./,"").replace("/*","").toUpperCase()),N=j??[M?.join(", "),p?`up to ${F(p)}`:null].filter(Boolean).join(" \xB7 "),k=e("input",{ref:B,type:"file",className:"sr-only",tabIndex:-1,accept:n,multiple:$,disabled:f,onChange:r=>{A(r.target.files),r.target.value=""}}),w={onDragEnter:r=>{r.preventDefault(),D.current+=1,E(!0)},onDragOver:r=>r.preventDefault(),onDragLeave:()=>{D.current-=1,D.current<=0&&E(!1)},onDrop:r=>{r.preventDefault(),D.current=0,E(!1),f||A(r.dataTransfer.files)}},q=U.map(({file:r,reason:o})=>a("li",{className:"flex items-center gap-3 rounded-[calc(11px*var(--radius-scale))] border border-danger/25 bg-danger-subtle/50 p-2 pr-2.5",role:"alert",children:[e("span",{className:"grid size-10 shrink-0 place-items-center rounded-[calc(9px*var(--radius-scale))] border border-danger/20 bg-raised text-danger [&_svg]:size-[18px]",children:e(W,{file:r})}),a("span",{className:"min-w-0 flex-1",children:[e("span",{className:"block truncate text-[13px] font-medium text-text",children:r.name}),a("span",{className:"text-[11.5px] text-danger",children:[o," \xB7 not added"]})]}),e("button",{type:"button",onClick:()=>T(b=>b.filter(g=>g.file!==r)),"aria-label":`Dismiss ${r.name}`,className:"grid size-7 cursor-pointer place-items-center rounded-[calc(7px*var(--radius-scale))] text-muted transition-colors hover:bg-raised hover:text-text [&_svg]:size-3.5",children:e(P,{})})]},`x-${r.name}-${r.size}`));if(h==="avatar")return e(pe,{file:m[0],currentUrl:Y,picker:k,open:_,dropProps:w,over:d,disabled:f,title:v,hint:N,onRemove:()=>I([]),rejected:U[0]?.reason,className:L});if(h==="gallery"){const r=l!==void 0&&m.length>=l;return a("div",{className:c("w-full space-y-2.5",L),...w,children:[a("div",{className:c("grid grid-cols-3 gap-2.5 rounded-[calc(14px*var(--radius-scale))] transition-[box-shadow] sm:grid-cols-4",d&&"shadow-[0_0_0_3px_var(--primary-subtle)]"),children:[m.map(o=>e(ce,{file:o,progress:R?.[o.name],failed:C?.includes(o.name),onRemove:()=>V(o),onRetry:u?()=>u(o):void 0},`${o.name}-${o.size}-${o.lastModified}`)),r?null:a("button",{type:"button",disabled:f,onClick:_,className:c("group/add grid aspect-square cursor-pointer place-items-center rounded-[calc(12px*var(--radius-scale))] border-[1.5px] border-dashed border-border2 bg-surface text-muted outline-none transition-[border-color,background-color,color]","hover:border-primary/50 hover:bg-primary-subtle/40 hover:text-primary focus-visible:ring-2 focus-visible:ring-primary/35",d&&"border-primary bg-primary-subtle/50 text-primary"),children:[a("span",{className:"flex flex-col items-center gap-1.5 px-2 text-center",children:[e(oe,{className:"size-6 transition-transform duration-300 ease-[cubic-bezier(.3,1.5,.5,1)] group-hover/add:-translate-y-0.5 group-hover/add:scale-110"}),e("span",{className:"text-[11.5px] font-medium",children:d?"Drop to add":v??"Add photos"}),l?a("span",{className:"num text-[10.5px] text-muted",children:[m.length,"/",l]}):null]}),k]})]}),U.length?e("ul",{className:"space-y-1.5",children:q}):null]})}const re=m.length||U.length?a("ul",{className:"space-y-1.5",children:[m.map(r=>{const o=R?.[r.name],b=C?.includes(r.name),g=o!==void 0&&o<100&&!b;return a("li",{className:"flex animate-[wave-in_220ms_var(--ease)] items-center gap-3 rounded-[calc(11px*var(--radius-scale))] border border-border bg-raised p-2 pr-2.5",children:[e(le,{file:r}),a("span",{className:"min-w-0 flex-1",children:[e("span",{className:"block truncate text-[13px] font-medium text-text",children:r.name}),a("span",{className:c("num flex items-center gap-1.5 text-[11.5px]",b?"text-danger":"text-muted"),children:[F(r.size),b?" \xB7 Upload failed":o===100?" \xB7 Uploaded":g?` \xB7 ${Math.round(o)}%`:null]}),g?e("span",{className:"mt-1.5 block h-1 overflow-hidden rounded-full bg-hover",children:e("span",{className:"block h-full rounded-full bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))] transition-[width] duration-300",style:{width:`${o}%`}})}):null]}),b&&u?e("button",{type:"button",onClick:()=>u(r),"aria-label":`Retry ${r.name}`,className:"grid size-7 cursor-pointer place-items-center rounded-[calc(7px*var(--radius-scale))] text-danger transition-colors hover:bg-danger-subtle [&_svg]:size-3.5",children:e(Q,{})}):null,e("button",{type:"button",onClick:()=>V(r),"aria-label":`Remove ${r.name}`,className:"grid size-7 cursor-pointer place-items-center rounded-[calc(7px*var(--radius-scale))] text-muted transition-colors hover:bg-hover hover:text-text [&_svg]:size-3.5",children:e(P,{})})]},`${r.name}-${r.size}-${r.lastModified}`)}),q]}):null,te=d?"Drop to add":v??a(ue,{children:[a("span",{className:"text-primary",children:["Choose ",$?"files":"a file"]})," or drag ",$?"them":"it"," here"]});return a("div",{className:c("w-full space-y-2.5",L),children:[h==="dropzone"?a("button",{type:"button",disabled:f,onClick:_,...w,className:c("group relative flex w-full cursor-pointer flex-col items-center justify-center gap-2 overflow-hidden rounded-[calc(14px*var(--radius-scale))] border-[1.5px] border-dashed border-border2 bg-surface px-6 py-8 text-center outline-none","transition-[border-color,background-color,box-shadow] duration-200 hover:border-primary/50 hover:bg-primary-subtle/30 focus-visible:ring-2 focus-visible:ring-primary/35",d&&"border-primary bg-primary-subtle/50 shadow-[0_0_0_4px_var(--primary-subtle)]",f&&"cursor-not-allowed opacity-50"),children:[e("span",{className:c("grid size-12 place-items-center rounded-[calc(14px*var(--radius-scale))] border border-border bg-raised text-primary shadow-[var(--lit),0_4px_12px_-6px_color-mix(in_srgb,var(--primary)_45%,transparent)] transition-transform duration-300 ease-[cubic-bezier(.3,1.5,.5,1)] [&_svg]:size-[22px]",d?"-translate-y-1 scale-110":"group-hover:-translate-y-0.5"),children:e(K,{})}),e("span",{className:"text-[13.5px] font-semibold text-text",children:te}),N?e("span",{className:"text-[12px] text-muted",children:N}):null,k]}):h==="card"?a("div",{...w,className:c("group/card relative isolate overflow-hidden rounded-[calc(18px*var(--radius-scale))] p-[1.5px]",f&&"pointer-events-none opacity-50"),children:[e("span",{"aria-hidden":!0,className:c("absolute inset-[-60%] -z-10 bg-[conic-gradient(from_0deg,var(--brand-1),var(--brand-2),transparent_35%,transparent_65%,var(--brand-1))] transition-opacity duration-300",d?"animate-[spin_2.4s_linear_infinite] opacity-100":"opacity-0 group-hover/card:opacity-60")}),e("span",{"aria-hidden":!0,className:c("absolute inset-0 -z-10 rounded-[inherit] border border-border transition-opacity",d&&"opacity-0")}),a("div",{className:"relative flex flex-col items-center gap-3 rounded-[calc(16.5px*var(--radius-scale))] bg-[radial-gradient(120%_90%_at_50%_0%,var(--primary-subtle),transparent_60%),var(--raised)] px-6 py-10 text-center",children:[a("span",{className:"relative mb-1 h-14 w-16","aria-hidden":!0,children:[e("span",{className:"absolute left-0 top-2 grid size-11 -rotate-12 place-items-center rounded-[calc(10px*var(--radius-scale))] border border-border bg-raised text-muted shadow-[0_4px_12px_-6px_rgba(5,8,22,.3)] transition-transform duration-500 ease-[cubic-bezier(.3,1.5,.5,1)] group-hover/card:-translate-x-1 group-hover/card:-rotate-[18deg] [&_svg]:size-5",children:e(J,{})}),e("span",{className:"absolute right-0 top-2 grid size-11 rotate-12 place-items-center rounded-[calc(10px*var(--radius-scale))] border border-border bg-raised text-muted shadow-[0_4px_12px_-6px_rgba(5,8,22,.3)] transition-transform duration-500 ease-[cubic-bezier(.3,1.5,.5,1)] group-hover/card:translate-x-1 group-hover/card:rotate-[18deg] [&_svg]:size-5",children:e(X,{})}),e("span",{className:c("absolute left-1/2 top-0 grid size-12 -translate-x-1/2 place-items-center rounded-[calc(12px*var(--radius-scale))] bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] text-white shadow-[inset_0_1px_0_rgba(255,255,255,.3),0_10px_22px_-10px_var(--brand-1)] transition-transform duration-500 ease-[cubic-bezier(.3,1.5,.5,1)] group-hover/card:-translate-y-1 [&_svg]:size-6",d&&"-translate-y-2 scale-110"),children:e(S,{})})]}),e("p",{className:"disp text-[16px] font-semibold text-text",children:d?"Drop to upload":v??"Drag and drop files"}),a("p",{className:"text-[12.5px] text-muted",children:["or"," ",e("button",{type:"button",onClick:_,className:"cursor-pointer font-semibold text-primary underline-offset-4 hover:underline",children:"browse your computer"}),p?` \xB7 up to ${F(p)} each`:""]}),M?.length?e("div",{className:"flex flex-wrap justify-center gap-1.5",children:M.map(r=>e("span",{className:"rounded-full border border-border bg-surface px-2 py-0.5 font-mono text-[10.5px] font-medium text-muted",children:r},r))}):null,k]})]}):h==="button"?a("div",{...w,className:"flex items-center gap-3",children:[a("button",{type:"button",disabled:f,onClick:_,className:c("inline-flex h-ctl cursor-pointer items-center gap-2 rounded-ctl border border-border2 bg-raised px-3.5 text-[13px] font-medium text-text shadow-[var(--lit),0_1px_2px_rgba(5,8,22,.06)] outline-none transition-colors hover:bg-hover focus-visible:ring-2 focus-visible:ring-primary/35 disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:size-4",d&&"border-primary bg-primary-subtle text-primary"),children:[e(S,{})," ",d?"Drop to add":v??($?"Upload files":"Upload a file")]}),N?e("span",{className:"text-[12px] text-muted",children:N}):null,k]}):a("div",{...w,className:c("flex items-center gap-3 rounded-ctl border border-dashed border-border2 bg-surface p-2 pl-3 transition-colors",d&&"border-primary bg-primary-subtle/50"),children:[e(K,{className:"size-4 shrink-0 text-muted"}),e("span",{className:"min-w-0 flex-1 truncate text-[12.5px] text-muted",children:d?"Drop to add":v??(N||"Drag files here")}),e("button",{type:"button",disabled:f,onClick:_,className:"h-7 shrink-0 cursor-pointer rounded-[calc(7px*var(--radius-scale))] border border-border2 bg-raised px-2.5 text-[12px] font-medium text-text shadow-[0_1px_1px_rgba(5,8,22,.05)] transition-colors hover:bg-hover disabled:cursor-not-allowed disabled:opacity-50",children:"Browse"}),k]}),re]})}function pe({file:t,currentUrl:s,picker:i,open:n,dropProps:z,over:p,disabled:l,title:h,hint:v,onRemove:j,rejected:R,className:C}){const u=O(t)??s??null;return a("div",{className:c("flex items-center gap-4",C),...z,children:[a("button",{type:"button",onClick:n,disabled:l,"aria-label":u?"Change photo":"Add a photo",className:c("group/av relative grid size-20 shrink-0 cursor-pointer place-items-center overflow-hidden rounded-full outline-none ring-offset-2 ring-offset-[var(--canvas)] transition-[box-shadow] focus-visible:ring-2 focus-visible:ring-primary/50",u?"shadow-[0_0_0_3px_var(--raised),0_0_0_5px_color-mix(in_srgb,var(--primary)_35%,transparent)]":"border-[1.5px] border-dashed border-border2 bg-surface text-muted hover:border-primary/50 hover:text-primary",p&&"shadow-[0_0_0_3px_var(--raised),0_0_0_6px_var(--primary)]"),children:[u?e("img",{src:u,alt:"",className:"size-full object-cover"}):e(H,{className:"size-6"}),u?e("span",{className:"absolute inset-0 grid place-items-center bg-ink/55 text-white opacity-0 backdrop-blur-[1px] transition-opacity group-hover/av:opacity-100 [&_svg]:size-5",children:e(H,{})}):null,i]}),a("div",{className:"min-w-0 space-y-1.5",children:[e("p",{className:"text-[13.5px] font-semibold text-text",children:h??"Profile photo"}),R?e("p",{className:"text-[12px] text-danger",children:R}):v?e("p",{className:"text-[12px] text-muted",children:v}):null,a("div",{className:"flex gap-2",children:[e("button",{type:"button",onClick:n,disabled:l,className:"h-7 cursor-pointer rounded-[calc(7px*var(--radius-scale))] border border-border2 bg-raised px-2.5 text-[12px] font-medium text-text transition-colors hover:bg-hover",children:u?"Change":"Upload"}),t?a("button",{type:"button",onClick:j,className:"inline-flex h-7 cursor-pointer items-center gap-1 rounded-[calc(7px*var(--radius-scale))] px-2 text-[12px] font-medium text-danger transition-colors hover:bg-danger-subtle [&_svg]:size-3.5",children:[e(ne,{})," Remove"]}):null]})]})]})}export{ge as FileUpload};
@@ -0,0 +1,17 @@
1
+ import * as HoverCardPrimitive from "@radix-ui/react-hover-card";
2
+ import * as React from "react";
3
+ /**
4
+ * HoverCard — a preview of what a link or name points to, on hover or focus:
5
+ * a person, a site, a vehicle. For sighted mouse users it saves a click; it
6
+ * must never hold the only way to do something (touch has no hover).
7
+ *
8
+ * Looks: `default` (raised), `glass` (frosted, over maps and media), `dark`
9
+ * (ink). `arrow` points at the trigger.
10
+ */
11
+ export declare const HoverCard: ({ openDelay, closeDelay, ...props }: React.ComponentProps<typeof HoverCardPrimitive.Root>) => React.JSX.Element;
12
+ export declare const HoverCardTrigger: React.ForwardRefExoticComponent<HoverCardPrimitive.HoverCardTriggerProps & React.RefAttributes<HTMLAnchorElement>>;
13
+ export type HoverCardVariant = "default" | "glass" | "dark";
14
+ export declare const HoverCardContent: React.ForwardRefExoticComponent<Omit<HoverCardPrimitive.HoverCardContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
15
+ variant?: HoverCardVariant;
16
+ arrow?: boolean;
17
+ } & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as t,jsxs as C}from"react/jsx-runtime";import*as r from"@radix-ui/react-hover-card";import*as b from"react";import{cn as v}from"../../lib/utils.js";const g=({openDelay:o=250,closeDelay:a=120,...e})=>t(r.Root,{openDelay:o,closeDelay:a,...e}),m=r.Trigger,n={default:{box:"border-border bg-raised",arrow:"fill-[var(--raised)]"},glass:{box:"border-white/40 bg-raised/70 backdrop-blur-xl backdrop-saturate-150 dark:border-white/10",arrow:"fill-[var(--raised)] opacity-80"},dark:{box:"border-white/10 bg-ink text-[#d6d8e6] [--text:#f5f6fa] [--body:#d6d8e6] [--muted:#9aa1bd] [--border:rgba(255,255,255,.1)] [--hover:rgba(255,255,255,.08)] [--surface:rgba(255,255,255,.05)]",arrow:"fill-[var(--ink)]"}},f=b.forwardRef(({className:o,align:a="center",sideOffset:e=8,variant:d="default",arrow:i=!1,children:l,...s},p)=>t(r.Portal,{children:C(r.Content,{ref:p,"data-pop":"",align:a,sideOffset:i?e+2:e,collisionPadding:12,className:v("z-50 w-72 rounded-dlg border p-4 text-[13px] shadow-elev3 outline-none",n[d].box,o),...s,children:[l,i?t(r.Arrow,{width:14,height:7,className:n[d].arrow}):null]})}));f.displayName="HoverCardContent";export{g as HoverCard,f as HoverCardContent,m as HoverCardTrigger};
@@ -1,11 +1,14 @@
1
1
  /** Primitives: small, unopinionated building blocks (Radix underneath where it helps). */
2
+ export * from "./accordion";
2
3
  export * from "./alert";
3
4
  export * from "./avatar";
4
5
  export * from "./badge";
5
6
  export * from "./button";
6
7
  export * from "./calendar";
7
8
  export * from "./card";
9
+ export * from "./carousel";
8
10
  export * from "./checkbox";
11
+ export * from "./color-picker";
9
12
  export * from "./combobox";
10
13
  export * from "./confirm-dialog";
11
14
  export * from "./date-picker";
@@ -13,16 +16,20 @@ export * from "./dialog";
13
16
  export * from "./dropdown-menu";
14
17
  export * from "./file-upload";
15
18
  export * from "./form-field";
19
+ export * from "./hover-card";
16
20
  export * from "./input";
17
21
  export * from "./kbd";
18
22
  export * from "./label";
19
23
  export * from "./menu";
20
24
  export * from "./number-input";
25
+ export * from "./pagination";
21
26
  export * from "./password-input";
22
27
  export * from "./pin-input";
23
28
  export * from "./popover";
24
29
  export * from "./progress";
25
30
  export * from "./radio-group";
31
+ export * from "./rating";
32
+ export * from "./scroll-area";
26
33
  export * from "./segmented";
27
34
  export * from "./select";
28
35
  export * from "./separator";
@@ -30,8 +37,11 @@ export * from "./sheet";
30
37
  export * from "./skeleton";
31
38
  export * from "./slider";
32
39
  export * from "./spinner";
40
+ export * from "./steps";
33
41
  export * from "./switch";
34
42
  export * from "./tabs";
43
+ export * from "./tag-input";
35
44
  export * from "./time-picker";
36
45
  export * from "./toast";
37
46
  export * from "./tooltip";
47
+ export * from "./tree-view";
@@ -1 +1 @@
1
- export*from"./alert.js";export*from"./avatar.js";export*from"./badge.js";export*from"./button.js";export*from"./calendar.js";export*from"./card.js";export*from"./checkbox.js";export*from"./combobox.js";export*from"./confirm-dialog.js";export*from"./date-picker.js";export*from"./dialog.js";export*from"./dropdown-menu.js";export*from"./file-upload.js";export*from"./form-field.js";export*from"./input.js";export*from"./kbd.js";export*from"./label.js";export*from"./menu.js";export*from"./number-input.js";export*from"./password-input.js";export*from"./pin-input.js";export*from"./popover.js";export*from"./progress.js";export*from"./radio-group.js";export*from"./segmented.js";export*from"./select.js";export*from"./separator.js";export*from"./sheet.js";export*from"./skeleton.js";export*from"./slider.js";export*from"./spinner.js";export*from"./switch.js";export*from"./tabs.js";export*from"./time-picker.js";export*from"./toast.js";export*from"./tooltip.js";
1
+ export*from"./accordion.js";export*from"./alert.js";export*from"./avatar.js";export*from"./badge.js";export*from"./button.js";export*from"./calendar.js";export*from"./card.js";export*from"./carousel.js";export*from"./checkbox.js";export*from"./color-picker.js";export*from"./combobox.js";export*from"./confirm-dialog.js";export*from"./date-picker.js";export*from"./dialog.js";export*from"./dropdown-menu.js";export*from"./file-upload.js";export*from"./form-field.js";export*from"./hover-card.js";export*from"./input.js";export*from"./kbd.js";export*from"./label.js";export*from"./menu.js";export*from"./number-input.js";export*from"./pagination.js";export*from"./password-input.js";export*from"./pin-input.js";export*from"./popover.js";export*from"./progress.js";export*from"./radio-group.js";export*from"./rating.js";export*from"./scroll-area.js";export*from"./segmented.js";export*from"./select.js";export*from"./separator.js";export*from"./sheet.js";export*from"./skeleton.js";export*from"./slider.js";export*from"./spinner.js";export*from"./steps.js";export*from"./switch.js";export*from"./tabs.js";export*from"./tag-input.js";export*from"./time-picker.js";export*from"./toast.js";export*from"./tooltip.js";export*from"./tree-view.js";
@@ -18,6 +18,14 @@ import * as React from "react";
18
18
  * second-line `description`, a `count`, a `badge` and a `shortcut`; MenuSub
19
19
  * folds a branch away and opens itself when it holds the chosen item. Arrow
20
20
  * keys, Home and End move between items; → and ← open and close a branch.
21
+ *
22
+ * Collapsing: `collapsible` puts a toggle in the heading row (or place a
23
+ * MenuCollapseTrigger yourself), `collapsed` / `onCollapsedChange` control it.
24
+ * `collapsedMode="icons"` (default) narrows the menu to its icons, each with
25
+ * its name in a tooltip and its count on the icon; items without an icon show
26
+ * their initial. `collapsedMode="hidden"` folds the menu away entirely, as the
27
+ * AppShell's panel does, for a toggle that lives outside it (on a rail, in a
28
+ * top bar). Give the menu a width (`className="w-60"`) and it animates.
21
29
  */
22
30
  export type MenuLook = "soft" | "line" | "raised" | "gradient" | "dark" | "panel" | "rail";
23
31
  export interface MenuProps extends Omit<React.HTMLAttributes<HTMLElement>, "defaultValue" | "onChange"> {
@@ -28,6 +36,15 @@ export interface MenuProps extends Omit<React.HTMLAttributes<HTMLElement>, "defa
28
36
  onValueChange?: (value: string) => void;
29
37
  /** On top of the list: a title, or in the rail, the product mark. */
30
38
  heading?: React.ReactNode;
39
+ /** A collapse toggle in the heading row. */
40
+ collapsible?: boolean;
41
+ collapsed?: boolean;
42
+ defaultCollapsed?: boolean;
43
+ onCollapsedChange?: (collapsed: boolean) => void;
44
+ /** `icons`: narrow to the icons. `hidden`: fold away entirely (toggle it from outside). */
45
+ collapsedMode?: "icons" | "hidden";
46
+ /** ⌘B / Ctrl+B toggles it. Off by default: AppShell already uses ⌘B for its panel. */
47
+ collapseShortcut?: boolean;
31
48
  }
32
49
  export declare const Menu: React.ForwardRefExoticComponent<MenuProps & React.RefAttributes<HTMLElement>>;
33
50
  interface ItemContent {
@@ -71,4 +88,11 @@ export declare function MenuGroup({ label, action, className, children, }: {
71
88
  export declare function MenuSeparator({ className }: {
72
89
  className?: string;
73
90
  }): React.JSX.Element;
91
+ /**
92
+ * The collapse toggle, for a menu with `collapsible` (it draws one in the
93
+ * heading row) or wherever you place it inside a Menu.
94
+ */
95
+ export declare function MenuCollapseTrigger({ className }: {
96
+ className?: string;
97
+ }): React.JSX.Element;
74
98
  export {};
@@ -1 +1 @@
1
- "use client";import{Fragment as D,jsx as o,jsxs as M}from"react/jsx-runtime";import{Slot as V}from"@radix-ui/react-slot";import{ChevronRight as q}from"lucide-react";import*as r from"react";import{cn as u}from"../../lib/utils.js";const S={soft:{root:"",indicator:"-z-10 rounded-[calc(9px*var(--radius-scale))] bg-primary-subtle ring-1 ring-inset ring-primary/10",item:["text-body hover:bg-hover hover:text-text","text-primary"],icon:["text-muted group-hover/item:text-text","text-primary"],tile:["border-border bg-surface","border-primary/20 bg-raised shadow-[0_2px_6px_-2px_color-mix(in_srgb,var(--primary)_35%,transparent)]"],description:["text-muted","text-primary/70"],count:["bg-hover text-muted","bg-primary text-white"],kbd:["border-border bg-surface text-muted","border-primary/20 bg-raised text-primary"]},line:{root:"pl-3 before:absolute before:inset-y-1 before:left-[5px] before:w-px before:bg-border",indicator:"z-[1] rounded-full bg-[linear-gradient(180deg,var(--brand-2),var(--brand-1))] shadow-[0_0_0_3px_var(--canvas),0_0_12px_color-mix(in_srgb,var(--brand-2)_55%,transparent)]",item:["text-muted hover:bg-hover/70 hover:text-text","bg-[linear-gradient(90deg,var(--primary-subtle),transparent_85%)] text-text"],icon:["text-muted group-hover/item:text-text","text-primary"],tile:["border-border bg-surface","border-primary/20 bg-primary-subtle"],description:["text-muted","text-muted"],count:["bg-hover text-muted","bg-primary-subtle text-primary"],kbd:["border-border bg-surface text-muted","border-border bg-raised text-text"]},raised:{root:"rounded-[calc(14px*var(--radius-scale))] border border-border bg-surface p-1.5 shadow-[inset_0_1px_2px_rgba(5,8,22,.04)]",indicator:"-z-10 rounded-[calc(10px*var(--radius-scale))] bg-raised ring-1 ring-border/70 shadow-[var(--lit),0_1px_2px_rgba(5,8,22,.06),0_6px_16px_-6px_rgba(5,8,22,.16)]",item:["text-muted hover:bg-raised/60 hover:text-text","text-text"],icon:["text-muted group-hover/item:text-text","text-primary"],tile:["border-border bg-raised","border-primary/15 bg-primary-subtle"],description:["text-muted","text-muted"],count:["bg-hover text-muted","bg-primary-subtle text-primary"],kbd:["border-border bg-raised text-muted","border-border bg-surface text-text"]},gradient:{root:"",indicator:"-z-10 rounded-[calc(10px*var(--radius-scale))] bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] shadow-[inset_0_1px_0_rgba(255,255,255,.25),0_8px_20px_-8px_color-mix(in_srgb,var(--brand-1)_70%,transparent)]",item:["text-body hover:bg-hover hover:text-text","text-white"],icon:["text-muted group-hover/item:text-text","text-white"],tile:["border-border bg-surface","border-white/20 bg-white/15 shadow-[inset_0_1px_0_rgba(255,255,255,.2)]"],description:["text-muted","text-white/75"],count:["bg-hover text-muted","bg-white/20 text-white"],kbd:["border-border bg-surface text-muted","border-white/25 bg-white/10 text-white/85"]},dark:{root:"rounded-[calc(16px*var(--radius-scale))] border border-white/10 p-1.5 text-white bg-[var(--ink)] bg-[image:radial-gradient(120%_70%_at_0%_0%,color-mix(in_srgb,var(--brand-2)_30%,transparent),transparent_60%),radial-gradient(90%_60%_at_100%_100%,color-mix(in_srgb,var(--brand-1)_18%,transparent),transparent_60%)] shadow-[inset_0_1px_0_rgba(255,255,255,.06),0_18px_40px_-16px_rgba(5,8,22,.6)] [--hover:rgba(255,255,255,.06)] [--surface:rgba(255,255,255,.05)] [--raised:rgba(255,255,255,.08)] [--text:#f5f6fa] [--body:#c9cce0] [--muted:#8d93b3] [--border:rgba(255,255,255,.1)] [--primary:#a5a8ff] [--primary-subtle:rgba(139,143,248,.16)] [--danger:#f87171] [--danger-subtle:rgba(239,68,68,.16)] [--canvas:var(--ink)]",indicator:"-z-10 rounded-[calc(10px*var(--radius-scale))] bg-white/[.07] ring-1 ring-inset ring-white/10 shadow-[inset_0_1px_0_rgba(255,255,255,.08)] before:absolute before:inset-y-2 before:left-0 before:w-[3px] before:rounded-r-full before:bg-[#a5a8ff] before:shadow-[0_0_12px_2px_rgba(139,143,248,.65)]",item:["text-body hover:bg-hover hover:text-text","text-white"],icon:["text-muted group-hover/item:text-text","text-[#a5a8ff]"],tile:["border-border bg-surface","border-[#a5a8ff]/30 bg-[#a5a8ff]/15"],description:["text-muted","text-white/55"],count:["bg-white/[.06] text-muted","bg-[#a5a8ff]/20 text-white"],kbd:["border-border bg-surface text-muted","border-white/15 bg-white/10 text-white/70"]},panel:{root:"rounded-[calc(14px*var(--radius-scale))] border border-border bg-surface px-2.5 py-3",indicator:"-z-10 rounded-ctl bg-primary-subtle",item:["font-normal text-body hover:bg-hover hover:text-text","text-primary"],icon:["text-muted group-hover/item:text-text","text-primary"],tile:["border-border bg-raised","border-primary/20 bg-raised"],description:["text-muted","text-primary/70"],count:["bg-transparent px-0 text-[12px] font-normal text-muted","bg-transparent px-0 text-[12px] font-normal text-primary"],kbd:["border-border bg-raised text-muted","border-primary/20 bg-raised text-primary"]},rail:{root:"w-[72px] items-center rounded-[calc(14px*var(--radius-scale))] border border-border bg-surface py-2",indicator:"-z-10 rounded-ctl bg-primary-subtle before:absolute before:inset-y-2.5 before:left-[var(--bar-x)] before:w-[3px] before:rounded-r-[3px] before:bg-primary",item:["text-muted hover:bg-hover hover:text-text","text-primary"],icon:["",""],tile:["",""],description:["",""],count:["bg-raised text-body ring-2 ring-surface","bg-primary text-white ring-2 ring-surface"],kbd:["",""],rail:!0}},P=r.createContext({look:"soft",value:void 0,select:()=>{}}),O=r.createContext(null),I="[data-menu-item]",z='[data-menu-sub-body][data-state="closed"]';function K(t){let a=t.querySelector(`${I}[data-active]`),n=a?.closest(z)??null;for(;a&&n&&t.contains(n);)a=n.parentElement?.querySelector(":scope > [data-menu-trigger]")??null,n=n.parentElement?.closest(z)??null;return a}function $(t,a){let n=0,c=0,i=t;for(;i&&i!==a;)n+=i.offsetLeft,c+=i.offsetTop,i=i.offsetParent;return i===a?{x:n,y:c,w:t.offsetWidth,h:t.offsetHeight}:null}const j=r.forwardRef(({variant:t="soft",value:a,defaultValue:n,onValueChange:c,heading:i,className:_,children:N,onKeyDown:v,...E},s)=>{const d=r.useRef(null),[H,l]=r.useState(n),L=a!==void 0?a:H,[x,f]=r.useState(null),b=r.useCallback(e=>{a===void 0&&l(e),c?.(e)},[a,c]),R=r.useMemo(()=>({look:t,value:L,select:b}),[t,L,b]);r.useLayoutEffect(()=>{const e=d.current;if(!e)return;const h=()=>{const T=K(e),p=T?$(T,e):null;f(g=>g&&p&&g.x===p.x&&g.y===p.y&&g.w===p.w&&g.h===p.h?g:p)};h();const C=new MutationObserver(h);C.observe(e,{subtree:!0,childList:!0,attributes:!0,attributeFilter:["data-active","data-state"]});const m=new ResizeObserver(h);return m.observe(e),e.addEventListener("transitionend",h),()=>{C.disconnect(),m.disconnect(),e.removeEventListener("transitionend",h)}},[t]);const y=e=>{v?.(e);const h=d.current;if(e.defaultPrevented||!h)return;const C=document.activeElement,m=Array.from(h.querySelectorAll(I)).filter(g=>!g.closest("[inert]")&&!g.hasAttribute("disabled")&&g.getAttribute("aria-disabled")!=="true"),T=C?m.indexOf(C):-1;if(T<0)return;let p;e.key==="ArrowDown"?p=m[(T+1)%m.length]:e.key==="ArrowUp"?p=m[(T-1+m.length)%m.length]:e.key==="Home"?p=m[0]:e.key==="End"?p=m[m.length-1]:e.key==="ArrowLeft"&&(p=C.closest("[data-menu-sub-body]")?.parentElement?.querySelector(":scope > [data-menu-trigger]")),p&&(e.preventDefault(),p.focus())},k=S[t],w=t==="line";return o(P.Provider,{value:R,children:M("nav",{ref:e=>{d.current=e,typeof s=="function"?s(e):s&&(s.current=e)},"data-variant":t,className:u("relative isolate flex flex-col gap-0.5 text-[13px]",k.root,_),onKeyDown:y,...E,children:[i?k.rail?o("div",{className:"mb-3 grid shrink-0 place-items-center",children:i}):o("h2",{className:"px-2.5 pb-2.5 pt-1.5 text-[13px] font-semibold leading-[18px] text-text",children:i}):null,N,x?o("span",{"aria-hidden":!0,className:u("pointer-events-none absolute left-0 top-0 transition-[transform,width,height] duration-300 ease-[cubic-bezier(.3,.7,.2,1)]",k.indicator),style:w?{transform:`translate3d(4px, ${x.y+7}px, 0)`,width:3,height:Math.max(x.h-14,8)}:{transform:`translate3d(${x.x}px, ${x.y}px, 0)`,width:x.w,height:x.h,"--bar-x":`${-x.x}px`}}):null]})})});j.displayName="Menu";function A({label:t,icon:a,description:n,badge:c,count:i,shortcut:_,on:N,danger:v,trailing:E}){const s=S[r.useContext(P).look],d=N?1:0;return s.rail?M(D,{children:[a,o("span",{className:"w-full truncate px-0.5 text-center text-[10px] font-medium leading-3",children:t}),i!==void 0?o("span",{className:u("num absolute right-1 top-1 min-w-4 rounded-full px-1 text-center text-[9.5px] font-semibold leading-4 transition-colors",s.count[d]),children:i}):null]}):M(D,{children:[a?n?o("span",{className:u("grid size-8 shrink-0 place-items-center rounded-[calc(9px*var(--radius-scale))] border transition-colors",v?"border-danger/20 bg-danger-subtle text-danger":u(s.tile[d],s.icon[d])),children:a}):o("span",{className:u("grid shrink-0 place-items-center transition-colors",v?"text-danger":s.icon[d]),children:a}):null,M("span",{className:"min-w-0 flex-1",children:[M("span",{className:"flex items-center gap-2",children:[o("span",{className:"truncate",children:t}),c]}),n?o("span",{className:u("mt-0.5 block truncate text-[11.5px] font-normal leading-4",v?"text-danger/70":s.description[d]),children:n}):null]}),i!==void 0?o("span",{className:u("num min-w-5 shrink-0 rounded-full px-1.5 text-center text-[10.5px] font-semibold leading-[18px] transition-colors",s.count[d]),children:i}):null,_?o("kbd",{className:u("shrink-0 rounded-[calc(5px*var(--radius-scale))] border px-1.5 py-px font-sans text-[10.5px] font-medium transition-colors",s.kbd[d]),children:_}):null,E]})}const F="mx-auto min-h-14 w-[60px] flex-col justify-center gap-[3px] px-0.5 py-1.5 [&_svg]:size-[19px]",B="group/item relative flex min-h-item w-full cursor-pointer select-none items-center gap-2.5 rounded-[calc(9px*var(--radius-scale))] px-2.5 py-1.5 text-left font-medium outline-none transition-[color,background-color] duration-150 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary/45 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0",G=r.forwardRef(({value:t,active:a,danger:n,asChild:c,icon:i,description:_,badge:N,count:v,shortcut:E,className:s,children:d,onClick:H,...l},L)=>{const x=r.useContext(P),f=r.useContext(O),b=!n&&(a??(t!==void 0&&x.value===t)),R=S[x.look];r.useEffect(()=>{if(!(!b||!f))return f.reveal(),f.mark(1),()=>f.mark(-1)},[b,f]);const y={"data-menu-item":"","data-active":b?"":void 0,"aria-current":b?"page":void 0,className:u(B,R.rail&&F,n?"text-danger hover:bg-danger-subtle":R.item[b?1:0],s),onClick:w=>{H?.(w),!w.defaultPrevented&&t!==void 0&&x.select(t)}},k=w=>o(A,{label:w,icon:i,description:_,badge:N,count:v,shortcut:E,on:b,danger:n});return c&&r.isValidElement(d)?o(V,{ref:L,...y,...l,children:r.cloneElement(d,void 0,k(d.props.children))}):o("button",{ref:L,type:"button",...y,...l,children:k(d)})});G.displayName="MenuItem";function J({label:t,defaultOpen:a=!1,open:n,onOpenChange:c,disabled:i,className:_,children:N,...v}){const E=r.useContext(P),s=r.useContext(O),[d,H]=r.useState(a),l=n??d,[L,x]=r.useState(0),f=r.useId(),b=r.useCallback(e=>{n===void 0&&H(e),c?.(e)},[n,c]),R=r.useMemo(()=>({reveal:()=>{b(!0),s?.reveal()},mark:e=>x(h=>h+e)}),[b,s]),y=L>0;r.useEffect(()=>{if(!(!y||!s))return s.mark(1),()=>s.mark(-1)},[y,s]);const k=S[E.look],w=y&&!l;return M("div",{"data-menu-sub":"",className:_,children:[o("button",{type:"button","data-menu-item":"","data-menu-trigger":"","data-state":l?"open":"closed","aria-expanded":l,"aria-controls":f,disabled:i,className:u(B,k.item[w?1:0],y&&l&&"text-text"),onClick:()=>b(!l),onKeyDown:e=>{e.key==="ArrowRight"?(e.preventDefault(),l?document.getElementById(f)?.querySelector(I)?.focus():b(!0)):e.key==="ArrowLeft"&&l&&(e.preventDefault(),b(!1))},children:o(A,{label:t,...v,on:w,trailing:o(q,{className:u("!size-3.5 shrink-0 opacity-60 transition-transform duration-200",l&&"rotate-90"),"aria-hidden":!0})})}),o("div",{id:f,"data-menu-sub-body":"","data-state":l?"open":"closed",inert:!l,className:u("grid transition-[grid-template-rows,opacity] duration-300 ease-[var(--ease)]",l?"grid-rows-[1fr] opacity-100":"grid-rows-[0fr] opacity-0"),children:o("div",{className:"min-h-0 overflow-hidden",children:o("div",{className:"relative ml-[18px] flex flex-col gap-0.5 py-0.5 pl-3 before:absolute before:inset-y-1 before:left-0 before:w-px before:bg-border",children:o(O.Provider,{value:R,children:N})})})})]})}function Q({label:t,action:a,className:n,children:c}){const i=r.useId();return S[r.useContext(P).look].rail?o("div",{role:"group","aria-label":typeof t=="string"?t:void 0,className:u("flex w-full flex-col items-center gap-0.5 [&:not(:first-child)]:before:my-1.5 [&:not(:first-child)]:before:h-px [&:not(:first-child)]:before:w-8 [&:not(:first-child)]:before:bg-border2",n),children:c}):M("div",{role:"group","aria-labelledby":t?i:void 0,className:u("flex flex-col gap-0.5 [&:not(:first-child)]:mt-2",n),children:[t?M("div",{className:"flex items-center justify-between gap-2 px-2.5 pb-1 pt-1.5",children:[o("p",{id:i,className:"ov",children:t}),a]}):null,c]})}function X({className:t}){return o("div",{role:"separator",className:u("mx-1 my-1.5 h-px shrink-0 bg-border",t)})}export{j as Menu,Q as MenuGroup,G as MenuItem,X as MenuSeparator,J as MenuSub};
1
+ "use client";import{Fragment as j,jsx as t,jsxs as w}from"react/jsx-runtime";import{Slot as re}from"@radix-ui/react-slot";import{ChevronRight as ne,PanelLeftClose as oe,PanelLeftOpen as ae}from"lucide-react";import*as o from"react";import{useHotkey as ie}from"../../hooks/use-hotkey.js";import{cn as l}from"../../lib/utils.js";import{Tooltip as q,TooltipProvider as se}from"./tooltip.js";const A={soft:{root:"",indicator:"-z-10 rounded-[calc(9px*var(--radius-scale))] bg-primary-subtle ring-1 ring-inset ring-primary/10",item:["text-body hover:bg-hover hover:text-text","text-primary"],icon:["text-muted group-hover/item:text-text","text-primary"],tile:["border-border bg-surface","border-primary/20 bg-raised shadow-[0_2px_6px_-2px_color-mix(in_srgb,var(--primary)_35%,transparent)]"],description:["text-muted","text-primary/70"],count:["bg-hover text-muted","bg-primary text-white"],kbd:["border-border bg-surface text-muted","border-primary/20 bg-raised text-primary"]},line:{root:"pl-3 before:absolute before:inset-y-1 before:left-[5px] before:w-px before:bg-border",indicator:"z-[1] rounded-full bg-[linear-gradient(180deg,var(--brand-2),var(--brand-1))] shadow-[0_0_0_3px_var(--canvas),0_0_12px_color-mix(in_srgb,var(--brand-2)_55%,transparent)]",item:["text-muted hover:bg-hover/70 hover:text-text","bg-[linear-gradient(90deg,var(--primary-subtle),transparent_85%)] text-text"],icon:["text-muted group-hover/item:text-text","text-primary"],tile:["border-border bg-surface","border-primary/20 bg-primary-subtle"],description:["text-muted","text-muted"],count:["bg-hover text-muted","bg-primary-subtle text-primary"],kbd:["border-border bg-surface text-muted","border-border bg-raised text-text"]},raised:{root:"rounded-[calc(14px*var(--radius-scale))] border border-border bg-surface p-1.5 shadow-[inset_0_1px_2px_rgba(5,8,22,.04)]",indicator:"-z-10 rounded-[calc(10px*var(--radius-scale))] bg-raised ring-1 ring-border/70 shadow-[var(--lit),0_1px_2px_rgba(5,8,22,.06),0_6px_16px_-6px_rgba(5,8,22,.16)]",item:["text-muted hover:bg-raised/60 hover:text-text","text-text"],icon:["text-muted group-hover/item:text-text","text-primary"],tile:["border-border bg-raised","border-primary/15 bg-primary-subtle"],description:["text-muted","text-muted"],count:["bg-hover text-muted","bg-primary-subtle text-primary"],kbd:["border-border bg-raised text-muted","border-border bg-surface text-text"]},gradient:{root:"",indicator:"-z-10 rounded-[calc(10px*var(--radius-scale))] bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] shadow-[inset_0_1px_0_rgba(255,255,255,.25),0_8px_20px_-8px_color-mix(in_srgb,var(--brand-1)_70%,transparent)]",item:["text-body hover:bg-hover hover:text-text","text-white"],icon:["text-muted group-hover/item:text-text","text-white"],tile:["border-border bg-surface","border-white/20 bg-white/15 shadow-[inset_0_1px_0_rgba(255,255,255,.2)]"],description:["text-muted","text-white/75"],count:["bg-hover text-muted","bg-white/20 text-white"],kbd:["border-border bg-surface text-muted","border-white/25 bg-white/10 text-white/85"]},dark:{root:"rounded-[calc(16px*var(--radius-scale))] border border-white/10 p-1.5 text-white bg-[var(--ink)] bg-[image:radial-gradient(120%_70%_at_0%_0%,color-mix(in_srgb,var(--brand-2)_30%,transparent),transparent_60%),radial-gradient(90%_60%_at_100%_100%,color-mix(in_srgb,var(--brand-1)_18%,transparent),transparent_60%)] shadow-[inset_0_1px_0_rgba(255,255,255,.06),0_18px_40px_-16px_rgba(5,8,22,.6)] [--hover:rgba(255,255,255,.06)] [--surface:rgba(255,255,255,.05)] [--raised:rgba(255,255,255,.08)] [--text:#f5f6fa] [--body:#c9cce0] [--muted:#8d93b3] [--border:rgba(255,255,255,.1)] [--primary:#a5a8ff] [--primary-subtle:rgba(139,143,248,.16)] [--danger:#f87171] [--danger-subtle:rgba(239,68,68,.16)] [--canvas:var(--ink)]",indicator:"-z-10 rounded-[calc(10px*var(--radius-scale))] bg-white/[.07] ring-1 ring-inset ring-white/10 shadow-[inset_0_1px_0_rgba(255,255,255,.08)] before:absolute before:inset-y-2 before:left-0 before:w-[3px] before:rounded-r-full before:bg-[#a5a8ff] before:shadow-[0_0_12px_2px_rgba(139,143,248,.65)]",item:["text-body hover:bg-hover hover:text-text","text-white"],icon:["text-muted group-hover/item:text-text","text-[#a5a8ff]"],tile:["border-border bg-surface","border-[#a5a8ff]/30 bg-[#a5a8ff]/15"],description:["text-muted","text-white/55"],count:["bg-white/[.06] text-muted","bg-[#a5a8ff]/20 text-white"],kbd:["border-border bg-surface text-muted","border-white/15 bg-white/10 text-white/70"]},panel:{root:"rounded-[calc(14px*var(--radius-scale))] border border-border bg-surface px-2.5 py-3",indicator:"-z-10 rounded-ctl bg-primary-subtle",item:["font-normal text-body hover:bg-hover hover:text-text","text-primary"],icon:["text-muted group-hover/item:text-text","text-primary"],tile:["border-border bg-raised","border-primary/20 bg-raised"],description:["text-muted","text-primary/70"],count:["bg-transparent px-0 text-[12px] font-normal text-muted","bg-transparent px-0 text-[12px] font-normal text-primary"],kbd:["border-border bg-raised text-muted","border-primary/20 bg-raised text-primary"]},rail:{root:"w-[72px] items-center rounded-[calc(14px*var(--radius-scale))] border border-border bg-surface py-2",indicator:"-z-10 rounded-ctl bg-primary-subtle before:absolute before:inset-y-2.5 before:left-[var(--bar-x)] before:w-[3px] before:rounded-r-[3px] before:bg-primary",item:["text-muted hover:bg-hover hover:text-text","text-primary"],icon:["",""],tile:["",""],description:["",""],count:["bg-raised text-body ring-2 ring-surface","bg-primary text-white ring-2 ring-surface"],kbd:["",""],rail:!0}},B=o.createContext({look:"soft",value:void 0,select:()=>{},collapsed:!1,iconsOnly:!1,setCollapsed:()=>{},shortcut:!1}),K=o.createContext(null),$="[data-menu-item]",W='[data-menu-sub-body][data-state="closed"]';function le(e){let r=e.querySelector(`${$}[data-active]`),n=r?.closest(W)??null;for(;r&&n&&e.contains(n);)r=n.parentElement?.querySelector(":scope > [data-menu-trigger]")??null,n=n.parentElement?.closest(W)??null;return r}function de(e,r){let n=0,c=0,a=e;for(;a&&a!==r;)n+=a.offsetLeft,c+=a.offsetTop,a=a.offsetParent;return a===r?{x:n,y:c,w:e.offsetWidth,h:e.offsetHeight}:null}const ce=o.forwardRef(({variant:e="soft",value:r,defaultValue:n,onValueChange:c,heading:a,collapsible:f,collapsed:_,defaultCollapsed:h=!1,onCollapsedChange:g,collapsedMode:p="icons",collapseShortcut:i=!1,className:u,children:k,onKeyDown:O,...C},m)=>{const b=o.useRef(null),[H,E]=o.useState(n),R=r!==void 0?r:H,[d,T]=o.useState(null),v=!!A[e].rail,[N,D]=o.useState(h),S=!v&&(_??N),P=S&&p==="icons",U=S&&p==="hidden",X=!v&&(f||_!==void 0||h||i),V=o.useCallback(s=>{_===void 0&&D(s),g?.(s)},[_,g]);ie({key:"b",mod:!0},()=>V(!S),i&&!v);const F=o.useCallback(s=>{r===void 0&&E(s),c?.(s)},[r,c]),Z=o.useMemo(()=>({look:e,value:R,select:F,collapsed:S,iconsOnly:P,setCollapsed:V,shortcut:i}),[e,R,F,S,P,V,i]);o.useLayoutEffect(()=>{const s=b.current;if(!s)return;const L=()=>{const I=le(s),x=I?de(I,s):null;T(M=>M&&x&&M.x===x.x&&M.y===x.y&&M.w===x.w&&M.h===x.h?M:x)};L();const z=new MutationObserver(L);z.observe(s,{subtree:!0,childList:!0,attributes:!0,attributeFilter:["data-active","data-state"]});const y=new ResizeObserver(L);return y.observe(s),s.addEventListener("transitionend",L),()=>{z.disconnect(),y.disconnect(),s.removeEventListener("transitionend",L)}},[e]);const ee=s=>{O?.(s);const L=b.current;if(s.defaultPrevented||!L)return;const z=document.activeElement,y=Array.from(L.querySelectorAll($)).filter(M=>!M.closest("[inert]")&&!M.hasAttribute("disabled")&&M.getAttribute("aria-disabled")!=="true"),I=z?y.indexOf(z):-1;if(I<0)return;let x;s.key==="ArrowDown"?x=y[(I+1)%y.length]:s.key==="ArrowUp"?x=y[(I-1+y.length)%y.length]:s.key==="Home"?x=y[0]:s.key==="End"?x=y[y.length-1]:s.key==="ArrowLeft"&&(x=z.closest("[data-menu-sub-body]")?.parentElement?.querySelector(":scope > [data-menu-trigger]")),x&&(s.preventDefault(),x.focus())},G=A[e],te=e==="line";return t(B.Provider,{value:Z,children:w("nav",{ref:s=>{b.current=s,typeof m=="function"?m(s):m&&(m.current=s)},"data-variant":e,"data-collapsed":S?p:void 0,inert:U,className:l("relative isolate flex flex-col gap-0.5 text-[13px]",G.root,X&&"overflow-hidden transition-[width,padding,opacity,border-color] duration-300 ease-[var(--ease)]",u,P&&"!w-16 shrink-0",U&&"!w-0 shrink-0 !border-transparent !px-0 opacity-0"),onKeyDown:ee,...C,children:[w(se,{delayDuration:150,children:[v?a?t("div",{className:"mb-3 grid shrink-0 place-items-center",children:a}):null:a||f?w("div",{className:l("flex min-h-8 shrink-0 items-center gap-2 pb-2 pl-2.5 pr-1",P&&"justify-center px-0"),children:[a&&!P?t("h2",{className:"min-w-0 flex-1 truncate text-[13px] font-semibold leading-[18px] text-text",children:a}):null,!a&&!P?t("span",{className:"flex-1"}):null,f?t(pe,{}):null]}):null,k]}),d?t("span",{"aria-hidden":!0,className:l("pointer-events-none absolute left-0 top-0 transition-[transform,width,height] duration-300 ease-[cubic-bezier(.3,.7,.2,1)]",G.indicator),style:te?{transform:`translate3d(4px, ${d.y+7}px, 0)`,width:3,height:Math.max(d.h-14,8)}:{transform:`translate3d(${d.x}px, ${d.y}px, 0)`,width:d.w,height:d.h,"--bar-x":`${-d.x}px`}}):null]})})});ce.displayName="Menu";function Y({label:e,icon:r,description:n,badge:c,count:a,shortcut:f,on:_,danger:h,trailing:g}){const p=o.useContext(B),i=A[p.look],u=_?1:0;if(p.iconsOnly){const k=typeof e=="string"?e.trim().charAt(0).toUpperCase():"\u2022";return w(j,{children:[w("span",{className:"relative grid shrink-0 place-items-center",children:[r?n?t("span",{className:l("grid size-8 place-items-center rounded-[calc(9px*var(--radius-scale))] border transition-colors",h?"border-danger/20 bg-danger-subtle text-danger":l(i.tile[u],i.icon[u])),children:r}):t("span",{className:l("grid place-items-center transition-colors",h?"text-danger":i.icon[u]),children:r}):t("span",{className:l("grid size-6 place-items-center rounded-[calc(7px*var(--radius-scale))] text-[11.5px] font-semibold",_?"bg-white/15":"bg-hover"),children:k}),a!==void 0?t("span",{className:l("num absolute -right-2.5 -top-2 min-w-4 rounded-full px-1 text-center text-[9px] font-semibold leading-4 ring-2 ring-[var(--canvas)]",i.count[u]),children:a}):null]}),t("span",{className:"sr-only",children:e})]})}return i.rail?w(j,{children:[r,t("span",{className:"w-full truncate px-0.5 text-center text-[10px] font-medium leading-3",children:e}),a!==void 0?t("span",{className:l("num absolute right-1 top-1 min-w-4 rounded-full px-1 text-center text-[9.5px] font-semibold leading-4 transition-colors",i.count[u]),children:a}):null]}):w(j,{children:[r?n?t("span",{className:l("grid size-8 shrink-0 place-items-center rounded-[calc(9px*var(--radius-scale))] border transition-colors",h?"border-danger/20 bg-danger-subtle text-danger":l(i.tile[u],i.icon[u])),children:r}):t("span",{className:l("grid shrink-0 place-items-center transition-colors",h?"text-danger":i.icon[u]),children:r}):null,w("span",{className:"min-w-0 flex-1",children:[w("span",{className:"flex items-center gap-2",children:[t("span",{className:"truncate",children:e}),c]}),n?t("span",{className:l("mt-0.5 block truncate text-[11.5px] font-normal leading-4",h?"text-danger/70":i.description[u]),children:n}):null]}),a!==void 0?t("span",{className:l("num min-w-5 shrink-0 rounded-full px-1.5 text-center text-[10.5px] font-semibold leading-[18px] transition-colors",i.count[u]),children:a}):null,f?t("kbd",{className:l("shrink-0 rounded-[calc(5px*var(--radius-scale))] border px-1.5 py-px font-sans text-[10.5px] font-medium transition-colors",i.kbd[u]),children:f}):null,g]})}const ue="mx-auto min-h-14 w-[60px] flex-col justify-center gap-[3px] px-0.5 py-1.5 [&_svg]:size-[19px]",J="justify-center gap-0 px-0",Q="group/item relative flex min-h-item w-full cursor-pointer select-none items-center gap-2.5 rounded-[calc(9px*var(--radius-scale))] px-2.5 py-1.5 text-left font-medium outline-none transition-[color,background-color] duration-150 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary/45 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0",be=o.forwardRef(({value:e,active:r,danger:n,asChild:c,icon:a,description:f,badge:_,count:h,shortcut:g,className:p,children:i,onClick:u,...k},O)=>{const C=o.useContext(B),m=o.useContext(K),b=!n&&(r??(e!==void 0&&C.value===e)),H=A[C.look];o.useEffect(()=>{if(!(!b||!m))return m.reveal(),m.mark(1),()=>m.mark(-1)},[b,m]);const E={"data-menu-item":"","data-active":b?"":void 0,"aria-current":b?"page":void 0,className:l(Q,H.rail&&ue,C.iconsOnly&&J,n?"text-danger hover:bg-danger-subtle":H.item[b?1:0],p),onClick:v=>{u?.(v),!v.defaultPrevented&&e!==void 0&&C.select(e)}},R=v=>t(Y,{label:v,icon:a,description:f,badge:_,count:h,shortcut:g,on:b,danger:n}),d=c&&o.isValidElement(i)?i.props.children:i,T=c&&o.isValidElement(i)?t(re,{ref:O,...E,...k,children:o.cloneElement(i,void 0,R(i.props.children))}):t("button",{ref:O,type:"button",...E,...k,children:R(i)});return C.iconsOnly&&typeof d=="string"?t(q,{label:d,side:"right",children:T}):T});be.displayName="MenuItem";function ve({label:e,defaultOpen:r=!1,open:n,onOpenChange:c,disabled:a,className:f,children:_,...h}){const g=o.useContext(B),p=o.useContext(K),[i,u]=o.useState(r),k=n??i,[O,C]=o.useState(0),m=o.useId(),b=o.useCallback(N=>{n===void 0&&u(N),c?.(N)},[n,c]),H=o.useMemo(()=>({reveal:()=>{b(!0),p?.reveal()},mark:N=>C(D=>D+N)}),[b,p]),E=O>0;o.useEffect(()=>{if(!(!E||!p))return p.mark(1),()=>p.mark(-1)},[E,p]);const R=A[g.look],d=k&&!g.iconsOnly,T=E&&!d,v=t("button",{type:"button","data-menu-item":"","data-menu-trigger":"","data-state":d?"open":"closed","aria-expanded":d,"aria-controls":m,disabled:a,className:l(Q,g.iconsOnly&&J,R.item[T?1:0],E&&d&&"text-text"),onClick:()=>{g.iconsOnly?(g.setCollapsed(!1),b(!0)):b(!k)},onKeyDown:N=>{N.key==="ArrowRight"?(N.preventDefault(),k?document.getElementById(m)?.querySelector($)?.focus():b(!0)):N.key==="ArrowLeft"&&k&&(N.preventDefault(),b(!1))},children:t(Y,{label:e,...h,on:T,trailing:t(ne,{className:l("!size-3.5 shrink-0 opacity-60 transition-transform duration-200",d&&"rotate-90"),"aria-hidden":!0})})});return w("div",{"data-menu-sub":"",className:f,children:[g.iconsOnly&&typeof e=="string"?t(q,{label:e,side:"right",children:v}):v,t("div",{id:m,"data-menu-sub-body":"","data-state":d?"open":"closed",inert:!d,className:l("grid transition-[grid-template-rows,opacity] duration-300 ease-[var(--ease)]",d?"grid-rows-[1fr] opacity-100":"grid-rows-[0fr] opacity-0"),children:t("div",{className:"min-h-0 overflow-hidden",children:t("div",{className:"relative ml-[18px] flex flex-col gap-0.5 py-0.5 pl-3 before:absolute before:inset-y-1 before:left-0 before:w-px before:bg-border",children:t(K.Provider,{value:H,children:_})})})})]})}function ye({label:e,action:r,className:n,children:c}){const a=o.useId(),f=o.useContext(B);return f.iconsOnly?t("div",{role:"group","aria-label":typeof e=="string"?e:void 0,className:l("flex flex-col gap-0.5 [&:not(:first-child)]:before:mx-auto [&:not(:first-child)]:before:my-2 [&:not(:first-child)]:before:h-px [&:not(:first-child)]:before:w-6 [&:not(:first-child)]:before:bg-border",n),children:c}):A[f.look].rail?t("div",{role:"group","aria-label":typeof e=="string"?e:void 0,className:l("flex w-full flex-col items-center gap-0.5 [&:not(:first-child)]:before:my-1.5 [&:not(:first-child)]:before:h-px [&:not(:first-child)]:before:w-8 [&:not(:first-child)]:before:bg-border2",n),children:c}):w("div",{role:"group","aria-labelledby":e?a:void 0,className:l("flex flex-col gap-0.5 [&:not(:first-child)]:mt-2",n),children:[e?w("div",{className:"flex items-center justify-between gap-2 px-2.5 pb-1 pt-1.5",children:[t("p",{id:a,className:"ov",children:e}),r]}):null,c]})}function we({className:e}){return t("div",{role:"separator",className:l("mx-1 my-1.5 h-px shrink-0 bg-border",e)})}function pe({className:e}){const r=o.useContext(B),n=r.collapsed?"Expand menu":"Collapse menu";return t(q,{label:n,shortcut:r.shortcut?"\u2318B":void 0,side:"right",children:t("button",{type:"button","aria-label":n,"aria-expanded":!r.collapsed,onClick:()=>r.setCollapsed(!r.collapsed),className:l("grid size-7 shrink-0 cursor-pointer place-items-center rounded-[calc(7px*var(--radius-scale))] text-muted outline-none transition-colors hover:bg-hover hover:text-text focus-visible:ring-2 focus-visible:ring-primary/45 [&_svg]:size-4",e),children:r.collapsed?t(ae,{}):t(oe,{})})})}export{ce as Menu,pe as MenuCollapseTrigger,ye as MenuGroup,be as MenuItem,we as MenuSeparator,ve as MenuSub};
@@ -0,0 +1,51 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Pagination — moving through a long list a page at a time.
4
+ *
5
+ * The page numbers keep their shape as you move: first, last, the pages
6
+ * beside the current one, and an ellipsis for the rest, so the row never
7
+ * jumps in width. Give `total` and it says "21–40 of 312"; give `pageSizes`
8
+ * and the reader picks how many per page.
9
+ *
10
+ * Looks:
11
+ * outline — the default: bordered buttons. Tables and lists.
12
+ * pill — one track, the current page lifted in it and sliding.
13
+ * gradient — the current page in the brand gradient, words on the arrows. Galleries, catalogues.
14
+ * underline — numbers on a line, a gradient bar sliding under the current one. Quiet pages.
15
+ * dots — a dot per page, the current one stretched. Onboarding, cards, short sets.
16
+ * jumper — "Page [ 4 ] of 120": type a number and go. Very long lists.
17
+ * minimal — previous, "Page 3 of 16", next. Narrow places and phones.
18
+ */
19
+ export type PaginationVariant = "outline" | "pill" | "gradient" | "underline" | "dots" | "jumper" | "minimal";
20
+ /**
21
+ * The numbers to draw: page numbers and "gap" markers, always the same number
22
+ * of slots once there are enough pages. Exported for custom layouts.
23
+ */
24
+ export declare function pageRange(page: number, count: number, siblings?: number, boundaries?: number): (number | "gap")[];
25
+ export interface PaginationProps {
26
+ page: number;
27
+ onPageChange: (page: number) => void;
28
+ /** Number of pages. Or give `total` and `pageSize`. */
29
+ pageCount?: number;
30
+ /** Number of rows in all; shows "21–40 of 312". */
31
+ total?: number;
32
+ pageSize?: number;
33
+ /** Offer these page sizes; needs `onPageSizeChange`. */
34
+ pageSizes?: number[];
35
+ onPageSizeChange?: (size: number) => void;
36
+ variant?: PaginationVariant;
37
+ siblings?: number;
38
+ /** First / last page buttons. */
39
+ edges?: boolean;
40
+ size?: "sm" | "md";
41
+ labels?: {
42
+ previous?: string;
43
+ next?: string;
44
+ page?: string;
45
+ of?: string;
46
+ perPage?: string;
47
+ goTo?: string;
48
+ };
49
+ className?: string;
50
+ }
51
+ export declare function Pagination({ page, onPageChange, pageCount, total, pageSize, pageSizes, onPageSizeChange, variant, siblings, edges, size, labels, className, }: PaginationProps): React.JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as a,jsxs as u}from"react/jsx-runtime";import{ChevronLeft as q,ChevronRight as z,ChevronsLeft as B,ChevronsRight as G}from"lucide-react";import*as v from"react";import{cn as d}from"../../lib/utils.js";function W(o,s,c=1,r=1){const m=(b,x)=>x<b?[]:Array.from({length:x-b+1},(k,M)=>b+M),y=m(1,Math.min(r,s)),p=m(Math.max(s-r+1,r+1),s),n=Math.max(Math.min(o-c,s-r-c*2-1),r+2),w=Math.min(Math.max(o+c,r+c*2+2),p.length>0?p[0]-2:s-1);return[...y,...n>r+2?["gap"]:r+1<s-r?[r+1]:[],...m(n,w),...w<s-r-1?["gap"]:s-r>r?[s-r]:[],...p]}function K({page:o,onPageChange:s,pageCount:c,total:r,pageSize:m=20,pageSizes:y,onPageSizeChange:p,variant:n="outline",siblings:w=1,edges:b=!1,size:x="md",labels:k,className:M}){const l=Math.max(1,c??(r!==void 0?Math.ceil(r/m):1)),g=e=>s(Math.min(l,Math.max(1,e))),i={previous:"Previous",next:"Next",page:"Page",of:"of",perPage:"per page",goTo:"Go to page",...k},S=x==="sm"?"h-8 min-w-8 text-[12.5px]":"h-9 min-w-9 text-[13px]",R=W(o,l,w),P=n==="pill"||n==="underline",T=v.useRef(null),[f,F]=v.useState(null);v.useLayoutEffect(()=>{if(!P)return;const e=T.current?.querySelector('[aria-current="page"]');F(e?{x:e.offsetLeft,w:e.offsetWidth}:null)},[P,o,l,x]);const[C,N]=v.useState(String(o));v.useEffect(()=>N(String(o)),[o]);const $=d("inline-flex cursor-pointer items-center justify-center gap-1 rounded-ctl px-2 font-medium outline-none transition-[background-color,color,border-color,box-shadow,transform] duration-150","focus-visible:ring-2 focus-visible:ring-primary/40 disabled:pointer-events-none disabled:opacity-40 [&_svg]:size-4",S),_=(e,t)=>{const L=t?e<0?1:l:o+e,V=e<0?o<=1:o>=l,j=t?e<0?B:G:e<0?q:z,D=t?e<0?"First page":"Last page":e<0?i.previous:i.next,E=!t&&(n==="minimal"||n==="gradient");return u("button",{type:"button","aria-label":D,disabled:V,onClick:()=>g(L),className:d($,n==="outline"||n==="jumper"?"border border-border bg-raised text-body shadow-[var(--lit)] hover:bg-hover hover:text-text":n==="dots"?"rounded-full border border-border bg-raised text-body shadow-[var(--lit)] hover:bg-hover hover:text-text":"text-body hover:bg-hover hover:text-text",E&&"px-3"),children:[e<0?a(j,{}):null,E?a("span",{className:"hidden sm:inline",children:D}):null,e>0?a(j,{}):null]})},I=r!==void 0?(o-1)*m+1:0,A=r!==void 0?Math.min(r,o*m):0,H=e=>{const t=e===o;return a("button",{type:"button","aria-label":`${i.page} ${e}`,"aria-current":t?"page":void 0,onClick:()=>g(e),className:d($,"num",n==="pill"&&"h-7 min-w-7 rounded-[calc(8px*var(--radius-scale))]",n==="outline"&&(t?"border border-primary bg-primary text-white shadow-[0_4px_12px_-4px_color-mix(in_srgb,var(--primary)_60%,transparent)]":"border border-border bg-raised text-body shadow-[var(--lit)] hover:bg-hover hover:text-text"),n==="pill"&&(t?"text-text":"text-muted hover:text-text"),n==="gradient"&&(t?"scale-105 rounded-full bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] text-white shadow-[inset_0_1px_0_rgba(255,255,255,.25),0_6px_16px_-6px_var(--brand-1)]":"rounded-full text-body hover:bg-hover hover:text-text"),n==="underline"&&(t?"font-semibold text-primary":"text-muted hover:text-text")),children:e},e)};let h;if(n==="minimal")h=u("span",{className:"num px-2 text-[13px] text-muted",children:[i.page," ",a("span",{className:"font-semibold text-text",children:o})," ",i.of," ",l]});else if(n==="jumper")h=u("form",{className:"flex items-center gap-2 px-1 text-[13px] text-muted",onSubmit:e=>{e.preventDefault();const t=parseInt(C,10);Number.isFinite(t)?g(t):N(String(o))},children:[i.page,a("input",{value:C,inputMode:"numeric","aria-label":i.goTo,onChange:e=>N(e.target.value.replace(/\D/g,"")),onBlur:()=>{const e=parseInt(C,10);Number.isFinite(e)&&e!==o?g(e):N(String(o))},className:d("num rounded-ctl border border-border2 bg-raised text-center font-semibold text-text outline-none transition-[border-color,box-shadow] focus:border-primary focus:ring-2 focus:ring-primary/20",x==="sm"?"h-8 w-11":"h-9 w-12")}),i.of," ",a("span",{className:"num font-semibold text-text",children:l})]});else if(n==="dots"){const e=l<=12?Array.from({length:l},(t,L)=>L+1):R.filter(t=>t!=="gap");h=a("div",{className:"flex items-center gap-1.5 px-2",children:e.map(t=>a("button",{type:"button","aria-label":`${i.page} ${t}`,"aria-current":t===o?"page":void 0,onClick:()=>g(t),className:d("h-2 cursor-pointer rounded-full outline-none transition-[width,background-color] duration-300 ease-[var(--ease)] focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2",t===o?"w-6 bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))]":"w-2 bg-border2 hover:bg-muted")},t))})}else h=u("div",{ref:T,className:d("relative isolate flex items-center gap-1",n==="pill"&&"rounded-[calc(11px*var(--radius-scale))] border border-border bg-hover p-1",n==="underline"&&"border-b border-border"),children:[P&&f?a("span",{"aria-hidden":!0,className:d("absolute left-0 transition-[transform,width] duration-300 ease-[cubic-bezier(.3,.7,.2,1)]",n==="pill"?"inset-y-1 -z-10 rounded-[calc(8px*var(--radius-scale))] bg-raised shadow-[var(--lit),0_1px_2px_rgba(5,8,22,.08),0_2px_8px_-2px_rgba(5,8,22,.16)]":"-bottom-px h-0.5 rounded-full bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))]"),style:{transform:`translateX(${n==="underline"?f.x+6:f.x}px)`,width:n==="underline"?f.w-12:f.w}}):null,R.map((e,t)=>e==="gap"?a("span",{"aria-hidden":!0,className:d("grid place-items-center text-muted",S),children:"\u2026"},`g${t}`):H(e))]});return u("nav",{"aria-label":"Pagination",className:d("flex flex-wrap items-center justify-between gap-x-4 gap-y-2",M),children:[r!==void 0?u("p",{className:"num text-[12.5px] text-muted",children:[u("span",{className:"font-medium text-text",children:[r===0?0:I.toLocaleString(),"\u2013",A.toLocaleString()]})," ",i.of," ",r.toLocaleString()]}):null,u("div",{className:"flex items-center gap-1",children:[b?_(-1,!0):null,_(-1),h,_(1),b?_(1,!0):null]}),y&&p?u("label",{className:"flex items-center gap-2 text-[12.5px] text-muted",children:[a("select",{value:m,onChange:e=>p(Number(e.target.value)),className:"h-8 cursor-pointer rounded-ctl border border-border2 bg-raised pl-2 pr-6 text-[12.5px] text-text outline-none focus:border-primary focus:ring-2 focus:ring-primary/20",children:y.map(e=>a("option",{value:e,children:e},e))}),i.perPage]}):null]})}export{K as Pagination,W as pageRange};
@@ -0,0 +1,27 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Rating — a score out of five (or `max`): a review of a car park, how a
4
+ * session went.
5
+ *
6
+ * Hovering previews the score before it is given; arrows, Home and End set it
7
+ * from the keyboard (it is a slider to a screen reader). `allowHalf` takes
8
+ * half steps. `readOnly` draws a score, with `count` for "4.6 (128)".
9
+ * `labels` names each score ("Poor" … "Excellent") beside the stars.
10
+ */
11
+ export interface RatingProps {
12
+ value?: number;
13
+ defaultValue?: number;
14
+ onValueChange?: (value: number) => void;
15
+ max?: number;
16
+ allowHalf?: boolean;
17
+ readOnly?: boolean;
18
+ icon?: "star" | "heart";
19
+ size?: "sm" | "md" | "lg";
20
+ /** One word per whole score, from 1. */
21
+ labels?: string[];
22
+ /** Read-only: the number of ratings behind the score. */
23
+ count?: number;
24
+ "aria-label"?: string;
25
+ className?: string;
26
+ }
27
+ export declare function Rating({ value, defaultValue, onValueChange, max, allowHalf, readOnly, icon, size, labels, count, "aria-label": ariaLabel, className, }: RatingProps): React.JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as r,jsxs as f}from"react/jsx-runtime";import{Heart as E,Star as I}from"lucide-react";import*as P from"react";import{cn as l}from"../../lib/utils.js";const T={sm:14,md:20,lg:28};function X({value:p,defaultValue:A=0,onValueChange:C,max:i=5,allowHalf:h=!1,readOnly:t=!1,icon:g="star",size:v="md",labels:u,count:x,"aria-label":H="Rating",className:L}){const[S,_]=P.useState(A),n=p??S,[b,w]=P.useState(null),m=b??n,N=h?.5:1,M=g==="heart"?E:I,o=T[v],D=g==="heart"?"text-rose-500":"text-amber-400",a=s=>{const e=Math.min(i,Math.max(0,s));p===void 0&&_(e),C?.(e)},R=(s,e)=>{if(!h)return e+1;const c=s.currentTarget.getBoundingClientRect();return s.clientX-c.left<c.width/2?e+.5:e+1},$=u&&m>0?u[Math.ceil(m)-1]:null;return f("div",{className:l("inline-flex items-center gap-2",L),children:[r("div",{role:t?"img":"slider","aria-label":t?`${n} out of ${i}`:H,"aria-valuemin":t?void 0:0,"aria-valuemax":t?void 0:i,"aria-valuenow":t?void 0:n,"aria-valuetext":t?void 0:`${n} of ${i}${u&&n?`, ${u[Math.ceil(n)-1]}`:""}`,tabIndex:t?void 0:0,onKeyDown:s=>{if(t)return;const e=s.key;if(e==="ArrowRight"||e==="ArrowUp")a(n+N);else if(e==="ArrowLeft"||e==="ArrowDown")a(n-N);else if(e==="Home")a(0);else if(e==="End")a(i);else return;s.preventDefault()},onPointerLeave:()=>w(null),className:l("inline-flex items-center rounded-[6px] outline-none focus-visible:ring-2 focus-visible:ring-primary/40",v==="sm"?"gap-0.5":"gap-1"),children:Array.from({length:i},(s,e)=>{const c=Math.max(0,Math.min(1,m-e));return f("span",{onPointerMove:t?void 0:d=>w(R(d,e)),onClick:t?void 0:d=>{const k=R(d,e);a(k===n?0:k)},className:l("relative inline-grid shrink-0 place-items-center",!t&&"cursor-pointer transition-transform duration-150 hover:scale-110 active:scale-95"),style:{width:o,height:o},children:[r(M,{className:"text-border2",style:{width:o,height:o},strokeWidth:1.6}),r("span",{className:"absolute inset-0 overflow-hidden transition-[width] duration-150",style:{width:`${c*100}%`},children:r(M,{className:l(D,"drop-shadow-[0_1px_2px_rgba(245,158,11,.35)]"),fill:"currentColor",style:{width:o,height:o},strokeWidth:1.6})})]},e)})}),t?f("span",{className:"num text-[13px] text-muted",children:[r("span",{className:"font-semibold text-text",children:n.toFixed(1)}),x!==void 0?` (${x.toLocaleString()})`:null]}):$?r("span",{className:l("text-[12.5px] font-medium transition-colors",b!==null?"text-muted":"text-text"),children:$}):null]})}export{X as Rating};
@@ -0,0 +1,17 @@
1
+ import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
2
+ import * as React from "react";
3
+ /**
4
+ * ScrollArea — a box that scrolls with a thin scrollbar of the system's own,
5
+ * the same on every OS, over the content instead of beside it (no layout
6
+ * shift when it appears).
7
+ *
8
+ * `fade` softens the edges that have more to show, so it is obvious the list
9
+ * goes on; the fade goes away at the end you have reached.
10
+ */
11
+ export interface ScrollAreaProps extends React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> {
12
+ orientation?: "vertical" | "horizontal" | "both";
13
+ fade?: boolean;
14
+ /** Class for the scrolling viewport (padding goes here). */
15
+ viewportClassName?: string;
16
+ }
17
+ export declare const ScrollArea: React.ForwardRefExoticComponent<ScrollAreaProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as t,jsxs as w}from"react/jsx-runtime";import*as r from"@radix-ui/react-scroll-area";import*as a from"react";import{cn as f}from"../../lib/utils.js";function v({orientation:o}){return t(r.Scrollbar,{orientation:o,className:f("z-10 flex touch-none select-none p-0.5 transition-[background-color,opacity] duration-200 hover:bg-hover/60","data-[state=hidden]:opacity-0 data-[state=visible]:opacity-100",o==="vertical"?"h-full w-2.5":"h-2.5 flex-col"),children:t(r.Thumb,{className:"relative flex-1 rounded-full bg-border2 transition-colors hover:bg-muted/60 before:absolute before:left-1/2 before:top-1/2 before:size-full before:min-h-11 before:min-w-11 before:-translate-x-1/2 before:-translate-y-1/2"})})}const A=a.forwardRef(({className:o,children:b,orientation:p="vertical",fade:n=!1,viewportClassName:h,type:g="hover",...S},R)=>{const m=a.useRef(null),[l,x]=a.useState({top:!1,bottom:!1,left:!1,right:!1});a.useEffect(()=>{const e=m.current;if(!n||!e)return;const i=()=>x({top:e.scrollTop>2,bottom:e.scrollTop+e.clientHeight<e.scrollHeight-2,left:e.scrollLeft>2,right:e.scrollLeft+e.clientWidth<e.scrollWidth-2});i(),e.addEventListener("scroll",i,{passive:!0});const c=new ResizeObserver(i);return c.observe(e),e.firstElementChild&&c.observe(e.firstElementChild),()=>{e.removeEventListener("scroll",i),c.disconnect()}},[n]);const d=p!=="horizontal",u=p!=="vertical",s=n?[d?`linear-gradient(to bottom, ${l.top?"transparent":"#000"}, #000 28px, #000 calc(100% - 28px), ${l.bottom?"transparent":"#000"})`:null,u?`linear-gradient(to right, ${l.left?"transparent":"#000"}, #000 28px, #000 calc(100% - 28px), ${l.right?"transparent":"#000"})`:null].filter(Boolean).join(", "):void 0;return w(r.Root,{ref:R,type:g,className:f("relative overflow-hidden",o),...S,children:[t(r.Viewport,{ref:m,className:f("size-full rounded-[inherit]",h),style:s?{maskImage:s,WebkitMaskImage:s,maskComposite:"intersect",WebkitMaskComposite:"source-in"}:void 0,children:b}),d?t(v,{orientation:"vertical"}):null,u?t(v,{orientation:"horizontal"}):null,t(r.Corner,{})]})});A.displayName="ScrollArea";export{A as ScrollArea};
@@ -3,13 +3,21 @@ import * as React from "react";
3
3
  /**
4
4
  * Slider — a value along a range, or a range itself (pass two values).
5
5
  *
6
- * The value rides above the thumb while it is held, hovered or focused, so the
7
- * number is read where the eye already is; `showValue="always"` keeps it up.
8
- * `marks` put ticks under the track (with labels when given) for the stops
9
- * that mean something: 0, the free hour, the cap. `variant="gradient"` fills
10
- * the range in the brand gradient, for the one slider a screen is about.
6
+ * Smooth by default: while dragged the thumb follows the pointer exactly and
7
+ * the value it reports snaps to `step`; let go and the thumb settles onto the
8
+ * step. Clicks on the track and arrow keys glide rather than jump. The value
9
+ * rides above the thumb while it is held, hovered or focused
10
+ * (`showValue="always"` keeps it up); `marks` put labelled ticks under it.
11
+ *
12
+ * Looks:
13
+ * default — a slim track and a ringed thumb. Forms.
14
+ * gradient — the brand gradient with a soft glow. The one slider a screen is about.
15
+ * fat — a thick pill that fills, the value inside it (volume, brightness, capacity).
16
+ * glow — luminous fill and thumb, for dark panels and hero controls.
17
+ * stepped — a dot for every step: few, discrete choices (1–10, hours of a shift).
18
+ * minimal — a hairline and a small dot that grows when touched. Dense settings.
11
19
  */
12
- export type SliderVariant = "default" | "gradient";
20
+ export type SliderVariant = "default" | "gradient" | "fat" | "glow" | "stepped" | "minimal";
13
21
  export interface SliderProps extends Omit<React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>, "children"> {
14
22
  variant?: SliderVariant;
15
23
  /** Ticks under the track. */
@@ -20,5 +28,9 @@ export interface SliderProps extends Omit<React.ComponentPropsWithoutRef<typeof
20
28
  /** The value over the thumb: while used (default), always, or never. */
21
29
  showValue?: "active" | "always" | "never";
22
30
  format?: (value: number) => string;
31
+ /** Follow the pointer between steps while dragging (default), or move in steps. */
32
+ smooth?: boolean;
33
+ /** `fat` only: an icon at the start of the fill. */
34
+ icon?: React.ReactNode;
23
35
  }
24
36
  export declare const Slider: React.ForwardRefExoticComponent<SliderProps & React.RefAttributes<HTMLSpanElement>>;
@@ -1 +1 @@
1
- "use client";import{jsx as t,jsxs as v}from"react/jsx-runtime";import*as n from"@radix-ui/react-slider";import*as f from"react";import{cn as r}from"../../lib/utils.js";const N=18,P=f.forwardRef(({className:g,variant:h="default",marks:i,showValue:s="active",format:x=p=>p.toLocaleString(),value:u,defaultValue:d,onValueChange:_,min:o=0,max:b=100,...c},y)=>{const[p,w]=f.useState(d??[o]),a=u??p,m=e=>(e-o)/(b-o||1)*100,S=e=>`calc(${m(e)}% + ${N/2*(1-m(e)/50)}px)`,R=i?.some(e=>e.label!==void 0);return v(n.Root,{ref:y,value:u,defaultValue:d,onValueChange:e=>{u===void 0&&w(e),_?.(e)},min:o,max:b,className:r("relative flex w-full touch-none select-none items-center py-2 data-[disabled]:opacity-50",s==="always"&&"mt-7",i&&(R?"mb-6":"mb-2"),g),...c,children:[t(n.Track,{className:"relative h-1.5 w-full grow overflow-hidden rounded-full bg-hover shadow-[inset_0_1px_2px_rgba(5,8,22,.08)]",children:t(n.Range,{className:r("absolute h-full rounded-full",h==="gradient"?"bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))] shadow-[0_0_10px_color-mix(in_srgb,var(--brand-2)_45%,transparent)]":"bg-primary")})}),i?.map(e=>{const l=a.length>1?e.value>=a[0]&&e.value<=a[a.length-1]:e.value<=a[0];return v("span",{"aria-hidden":!0,className:"pointer-events-none absolute top-full -translate-x-1/2",style:{left:S(e.value)},children:[t("span",{className:r("mx-auto -mt-1.5 block h-1.5 w-px",l?"bg-primary/50":"bg-border2")}),e.label!==void 0?t("span",{className:"num mt-1 block whitespace-nowrap text-[11px] text-muted",children:e.label}):null]},e.value)}),a.map((e,l)=>t(n.Thumb,{"aria-label":a.length>1?l===0?"Minimum":"Maximum":c["aria-label"],className:r("group/thumb relative block size-[18px] cursor-grab rounded-full border-2 border-primary bg-white outline-none active:cursor-grabbing","shadow-[0_1px_3px_rgba(5,8,22,.25),0_0_0_0_var(--primary-subtle)] transition-[box-shadow,transform] duration-150","hover:shadow-[0_1px_3px_rgba(5,8,22,.25),0_0_0_6px_var(--primary-subtle)] focus-visible:shadow-[0_1px_3px_rgba(5,8,22,.25),0_0_0_6px_var(--primary-subtle)] active:scale-110"),children:s!=="never"?t("span",{className:r("num pointer-events-none absolute bottom-full left-1/2 mb-2.5 -translate-x-1/2 whitespace-nowrap rounded-[calc(7px*var(--radius-scale))] bg-[var(--ink)] px-2 py-1 text-[11.5px] font-semibold leading-none text-white shadow-elev2","after:absolute after:left-1/2 after:top-full after:-translate-x-1/2 after:border-4 after:border-transparent after:border-t-[var(--ink)]","transition-[opacity,transform] duration-150",s==="always"?"opacity-100":"translate-y-1 opacity-0 group-hover/thumb:translate-y-0 group-hover/thumb:opacity-100 group-focus-visible/thumb:translate-y-0 group-focus-visible/thumb:opacity-100 group-active/thumb:translate-y-0 group-active/thumb:opacity-100"),children:x(e)}):null},l))]})});P.displayName="Slider";export{P as Slider};
1
+ "use client";import{jsx as s,jsxs as m}from"react/jsx-runtime";import*as f from"@radix-ui/react-slider";import*as u from"react";import{cn as l}from"../../lib/utils.js";const K={default:18,gradient:18,fat:0,glow:18,stepped:12,minimal:12},W={default:"h-1.5 bg-hover shadow-[inset_0_1px_2px_rgba(5,8,22,.08)]",gradient:"h-1.5 bg-hover shadow-[inset_0_1px_2px_rgba(5,8,22,.08)]",fat:"h-9 rounded-[calc(12px*var(--radius-scale))] bg-hover shadow-[inset_0_1px_3px_rgba(5,8,22,.1)]",glow:"h-2 bg-[color-mix(in_srgb,var(--brand-1)_14%,var(--hover))]",stepped:"h-1 bg-hover",minimal:"h-0.5 bg-border2"},Z={default:"bg-primary",gradient:"bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))] shadow-[0_0_10px_color-mix(in_srgb,var(--brand-2)_45%,transparent)]",fat:"bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))] shadow-[inset_0_1px_0_rgba(255,255,255,.25)]",glow:"bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))] shadow-[0_0_14px_2px_color-mix(in_srgb,var(--brand-2)_60%,transparent),0_0_4px_color-mix(in_srgb,var(--brand-1)_80%,transparent)]",stepped:"bg-primary",minimal:"bg-text"},q={default:"size-[18px] rounded-full border-2 border-primary bg-white shadow-[0_1px_3px_rgba(5,8,22,.25)] hover:shadow-[0_1px_3px_rgba(5,8,22,.25),0_0_0_6px_var(--primary-subtle)] focus-visible:shadow-[0_1px_3px_rgba(5,8,22,.25),0_0_0_6px_var(--primary-subtle)]",gradient:"size-[18px] rounded-full border-2 border-white bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] shadow-[0_2px_8px_color-mix(in_srgb,var(--brand-1)_55%,transparent)] hover:shadow-[0_2px_8px_color-mix(in_srgb,var(--brand-1)_55%,transparent),0_0_0_6px_var(--primary-subtle)] focus-visible:shadow-[0_2px_8px_color-mix(in_srgb,var(--brand-1)_55%,transparent),0_0_0_6px_var(--primary-subtle)]",fat:"h-9 w-3 -translate-x-1.5 rounded-full before:absolute before:inset-y-2.5 before:left-1/2 before:w-1 before:-translate-x-1/2 before:rounded-full before:bg-white/85 before:shadow-[0_1px_2px_rgba(5,8,22,.3)]",glow:"size-[18px] rounded-full bg-white shadow-[0_0_0_3px_color-mix(in_srgb,var(--brand-2)_55%,transparent),0_0_16px_4px_color-mix(in_srgb,var(--brand-2)_55%,transparent)] hover:shadow-[0_0_0_5px_color-mix(in_srgb,var(--brand-2)_45%,transparent),0_0_22px_6px_color-mix(in_srgb,var(--brand-2)_60%,transparent)]",stepped:"h-5 w-3 rounded-full border-2 border-primary bg-white shadow-[0_1px_3px_rgba(5,8,22,.25)] hover:shadow-[0_1px_3px_rgba(5,8,22,.25),0_0_0_5px_var(--primary-subtle)]",minimal:"size-3 rounded-full bg-text shadow-[0_0_0_3px_var(--canvas)] hover:scale-150 focus-visible:scale-150 active:scale-150"},J=u.forwardRef(({className:T,variant:t="default",marks:c,showValue:h="active",format:x=w=>w.toLocaleString(),smooth:v=!0,icon:V,value:N,defaultValue:L,onValueChange:A,onValueCommit:F,min:r=0,max:_=100,step:o=1,orientation:k="horizontal",...z},B)=>{const[w,D]=u.useState(L??[r]),y=N??w,[H,S]=u.useState(null),[d,R]=u.useState(!1),a=H??y,n=k==="vertical",p=t==="fat",O=(String(o).split(".")[1]??"").length,b=e=>Number(Math.min(_,Math.max(r,Math.round((e-r)/o)*o+r)).toFixed(O)),U=e=>{e.length===y.length&&e.every((i,g)=>i===y[g])||(N===void 0&&D(e),A?.(e))};u.useEffect(()=>{if(!d)return;const e=()=>{R(!1),S(null)};return window.addEventListener("pointerup",e),window.addEventListener("pointercancel",e),()=>{window.removeEventListener("pointerup",e),window.removeEventListener("pointercancel",e)}},[d]);const P=e=>(e-r)/(_-r||1)*100,$=K[t]/2,M=e=>`calc(${P(e)}% + ${$*(1-P(e)/50)}px)`,G=c?.some(e=>e.label!==void 0),C=Math.round((_-r)/o),E=e=>a.length>1?e>=a[0]-1e-9&&e<=a[a.length-1]+1e-9:e<=a[0]+1e-9,I=e=>h==="never"||p?null:s("span",{className:l("num pointer-events-none absolute whitespace-nowrap rounded-[7px] bg-ink px-2 py-1 text-[11.5px] font-semibold leading-none text-white shadow-elev2","transition-[opacity,transform] duration-200 ease-[cubic-bezier(.3,1.4,.5,1)]",n?"left-full top-1/2 ml-3 -translate-y-1/2 after:absolute after:right-full after:top-1/2 after:-translate-y-1/2 after:border-4 after:border-transparent after:border-r-[var(--ink)]":"bottom-full left-1/2 mb-2.5 -translate-x-1/2 after:absolute after:left-1/2 after:top-full after:-translate-x-1/2 after:border-4 after:border-transparent after:border-t-[var(--ink)]",h==="always"||d?"opacity-100":"scale-75 opacity-0 group-hover/thumb:scale-100 group-hover/thumb:opacity-100 group-focus-visible/thumb:scale-100 group-focus-visible/thumb:opacity-100"),children:x(b(e))});return m(f.Root,{ref:B,value:a,min:r,max:_,step:v&&d?o/50:o,orientation:k,"data-dragging":d?"":void 0,onPointerDownCapture:()=>{v&&R(!0)},onValueChange:e=>{v&&d&&S(e),U(e.map(b))},onValueCommit:e=>{R(!1),S(null),F?.(e.map(b))},className:l("group/slider relative flex touch-none select-none items-center data-[disabled]:opacity-50",n?"h-full min-h-40 w-fit flex-col px-2":"w-full py-2",h==="always"&&!p&&!n&&"mt-7",c&&!n&&(G?"mb-6":"mb-2"),"[&>span:has(>[role=slider])]:transition-[left,bottom] [&>span:has(>[role=slider])]:duration-200 [&>span:has(>[role=slider])]:ease-[cubic-bezier(.3,.7,.2,1)]","data-[dragging]:[&>span:has(>[role=slider])]:transition-none",T),...z,children:[m(f.Track,{className:l("relative grow overflow-hidden rounded-full",W[t],n&&"!h-full w-1.5"),children:[s(f.Range,{className:l("absolute transition-[left,right,top,bottom] duration-200 ease-[cubic-bezier(.3,.7,.2,1)] group-data-[dragging]/slider:transition-none",n?"w-full":"h-full",p?"rounded-[inherit]":"rounded-full",Z[t])}),p?m("span",{className:"pointer-events-none absolute inset-y-0 left-3 flex items-center gap-2 text-[13px] font-semibold text-white [&_svg]:size-4",children:[V,s("span",{className:"num drop-shadow-[0_1px_1px_rgba(5,8,22,.3)]",children:x(b(a[a.length-1]??r))})]}):null]}),t==="stepped"&&C<=40&&!n?Array.from({length:C+1},(e,i)=>{const g=r+i*o;return s("span",{"aria-hidden":!0,className:l("pointer-events-none absolute top-1/2 size-1.5 -translate-x-1/2 -translate-y-1/2 rounded-full transition-colors duration-200",E(g)?"bg-primary":"bg-border2"),style:{left:M(g)}},i)}):null,c&&!n?c.map(e=>m("span",{"aria-hidden":!0,className:"pointer-events-none absolute top-full -translate-x-1/2",style:{left:M(e.value)},children:[s("span",{className:l("mx-auto -mt-1.5 block h-1.5 w-px",E(e.value)?"bg-primary/50":"bg-border2")}),e.label!==void 0?s("span",{className:"num mt-1 block whitespace-nowrap text-[11px] text-muted",children:e.label}):null]},e.value)):null,a.map((e,i)=>s(f.Thumb,{"aria-label":a.length>1?i===0?"Minimum":"Maximum":z["aria-label"],"aria-valuetext":x(b(e)),className:l("group/thumb relative block cursor-grab outline-none transition-[box-shadow,transform] duration-150 active:cursor-grabbing",t!=="fat"&&t!=="minimal"&&"active:scale-110",p&&"focus-visible:ring-2 focus-visible:ring-white/70",q[t]),children:I(e)},i))]})});J.displayName="Slider";export{J as Slider};
@@ -0,0 +1,36 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Steps — where a person is in a flow of a few parts: sign-up, adding a site,
4
+ * a booking. Done steps carry a tick, the current one is ringed, the rest wait.
5
+ *
6
+ * Looks:
7
+ * circle — the default: a numbered disc per step on a line that fills.
8
+ * glow — gradient discs, the current one pulsing with light. Onboarding, hero flows.
9
+ * dot — small markers: many steps, or a narrow column.
10
+ * bar — segments that fill, labels under them. A wizard's header.
11
+ * card — a card per step, the current one lifted. Set-up screens with room.
12
+ * chevron — arrow-shaped segments joined end to end. Checkout and process flows.
13
+ * circle, glow and dot also run vertically, with each step's description (and,
14
+ * if given, its `content`) beside its marker. Pass `onStepClick` and finished
15
+ * steps become links back.
16
+ */
17
+ export type StepsVariant = "circle" | "glow" | "dot" | "bar" | "card" | "chevron";
18
+ export interface StepItem {
19
+ title: React.ReactNode;
20
+ description?: React.ReactNode;
21
+ /** Replaces the number in the disc. */
22
+ icon?: React.ReactNode;
23
+ /** Vertical only: shown under the current step. */
24
+ content?: React.ReactNode;
25
+ }
26
+ export interface StepsProps {
27
+ steps: StepItem[];
28
+ /** Index of the current step, from 0. Equal to steps.length when all are done. */
29
+ current: number;
30
+ variant?: StepsVariant;
31
+ orientation?: "horizontal" | "vertical";
32
+ /** Makes finished steps clickable. */
33
+ onStepClick?: (index: number) => void;
34
+ className?: string;
35
+ }
36
+ export declare function Steps({ steps, current, variant, orientation, onStepClick, className }: StepsProps): React.JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{Fragment as _,jsx as e,jsxs as l}from"react/jsx-runtime";import{Check as x}from"lucide-react";import{cn as n}from"../../lib/utils.js";function N({state:o,index:d,icon:i,variant:b}){return b==="dot"?l("span",{className:"relative grid size-4 shrink-0 place-items-center",children:[o==="current"?e("span",{className:"absolute inset-0 animate-ping rounded-full bg-primary/30 [animation-duration:2s]"}):null,e("span",{className:n("relative rounded-full transition-all duration-300",o==="todo"?"size-2.5 border-2 border-border2 bg-raised":"size-3 bg-primary shadow-[0_0_0_4px_var(--primary-subtle)]")})]}):b==="glow"?l("span",{className:"relative grid size-9 shrink-0 place-items-center",children:[o==="current"?l(_,{children:[e("span",{className:"absolute inset-0 animate-ping rounded-full bg-[color-mix(in_srgb,var(--brand-2)_35%,transparent)] [animation-duration:2.2s]"}),e("span",{className:"absolute -inset-1 rounded-full bg-[conic-gradient(from_0deg,var(--brand-1),var(--brand-2),var(--brand-1))] opacity-60 blur-[6px]"})]}):null,e("span",{className:n("relative grid size-9 place-items-center rounded-full text-[12.5px] font-semibold transition-[background,box-shadow,color] duration-300 [&_svg]:size-4",o==="todo"?"border border-border2 bg-raised text-muted":"bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] text-white shadow-[inset_0_1px_0_rgba(255,255,255,.3),0_6px_16px_-6px_var(--brand-1)]",o==="current"&&"ring-[3px] ring-[var(--raised)]"),children:o==="done"?e(x,{strokeWidth:3,className:"animate-[wm-pop_220ms_var(--ease)]"}):i??e("span",{className:"num",children:d+1})})]}):e("span",{className:n("relative grid size-8 shrink-0 place-items-center rounded-full border text-[12.5px] font-semibold transition-[background-color,border-color,color,box-shadow] duration-300 [&_svg]:size-4",o==="done"&&"border-transparent bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] text-white shadow-[inset_0_1px_0_rgba(255,255,255,.25),0_4px_10px_-4px_color-mix(in_srgb,var(--brand-1)_70%,transparent)]",o==="current"&&"border-primary bg-raised text-primary shadow-[0_0_0_4px_var(--primary-subtle)]",o==="todo"&&"border-border2 bg-raised text-muted"),children:o==="done"?e(x,{strokeWidth:3,className:"animate-[wm-pop_220ms_var(--ease)]"}):i??e("span",{className:"num",children:d+1})})}function R({steps:o,current:d,variant:i="circle",orientation:b="horizontal",onStepClick:p,className:u}){const m=a=>a<d?"done":a===d?"current":"todo",g=(a,t)=>{const r=m(a),s=!!p&&r==="done",c=l(_,{children:[e("span",{className:n("block text-[13px] font-semibold leading-5",r==="todo"?"text-muted":"text-text"),children:t.title}),t.description?e("span",{className:"block text-[12px] leading-[17px] text-muted",children:t.description}):null]});return s?e("button",{type:"button",onClick:()=>p(a),className:"cursor-pointer rounded-[6px] text-left outline-none hover:[&>span:first-child]:text-primary focus-visible:ring-2 focus-visible:ring-primary/40",children:c}):e("div",{children:c})};if(i==="card")return e("ol",{className:n("grid gap-3",u),style:{gridTemplateColumns:`repeat(${o.length}, minmax(0, 1fr))`},children:o.map((a,t)=>{const r=m(t),s=!!p&&r==="done";return e("li",{"aria-current":r==="current"?"step":void 0,className:"min-w-0",children:l(s?"button":"div",{...s?{type:"button",onClick:()=>p(t)}:{},className:n("relative flex h-full w-full flex-col gap-2 overflow-hidden rounded-[calc(14px*var(--radius-scale))] border p-3.5 text-left outline-none transition-[border-color,box-shadow,transform,background-color] duration-300",s&&"cursor-pointer hover:border-primary/40 focus-visible:ring-2 focus-visible:ring-primary/40",r==="current"&&"-translate-y-0.5 border-primary bg-raised shadow-[0_0_0_3px_var(--primary-subtle),0_12px_28px_-16px_color-mix(in_srgb,var(--primary)_60%,transparent)]",r==="done"&&"border-border bg-raised",r==="todo"&&"border-dashed border-border2 bg-surface"),children:[r==="current"?e("span",{"aria-hidden":!0,className:"absolute inset-x-0 top-0 h-[3px] bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))]"}):null,l("span",{className:"flex items-center justify-between gap-2",children:[l("span",{className:n("text-[10.5px] font-semibold uppercase tracking-[0.08em]",r==="todo"?"text-placeholder":"text-primary"),children:["Step ",t+1]}),r==="done"?e("span",{className:"grid size-5 place-items-center rounded-full bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] text-white [&_svg]:size-3",children:e(x,{strokeWidth:3.5})}):r==="current"?e("span",{className:"size-2 animate-pulse rounded-full bg-primary"}):null]}),a.icon?e("span",{className:n("[&_svg]:size-5",r==="todo"?"text-muted":"text-primary"),children:a.icon}):null,l("span",{children:[e("span",{className:n("block text-[13.5px] font-semibold leading-5",r==="todo"?"text-muted":"text-text"),children:a.title}),a.description?e("span",{className:"block text-[12px] leading-[17px] text-muted",children:a.description}):null]})]})},t)})});if(i==="chevron")return e("ol",{className:n("flex w-full",u),children:o.map((t,r)=>{const s=m(r),c=r===0,f=r===o.length-1,w=`polygon(0 0, ${f?"100%":"calc(100% - 14px)"} 0, 100% 50%, ${f?"100%":"calc(100% - 14px)"} 100%, 0 100%, ${c?"0":"14px"} 50%)`,v=!!p&&s==="done";return e("li",{"aria-current":s==="current"?"step":void 0,className:n("relative min-w-0 flex-1",!c&&"-ml-1.5"),style:{zIndex:o.length-r},children:l("button",{type:"button",disabled:!v,onClick:v?()=>p(r):void 0,style:{clipPath:w},className:n("flex h-12 w-full items-center gap-2.5 text-left outline-none transition-[background,color,filter] duration-300 disabled:cursor-default",c?"pl-4":"pl-7",f?"pr-4":"pr-6",v&&"cursor-pointer hover:brightness-95",s==="current"&&"bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] text-white",s==="done"&&"bg-primary-subtle text-primary",s==="todo"&&"bg-hover text-muted"),children:[e("span",{className:n("grid size-6 shrink-0 place-items-center rounded-full text-[11.5px] font-semibold [&_svg]:size-3.5",s==="current"?"bg-white/20 text-white":s==="done"?"bg-primary text-white":"border border-border2 bg-raised"),children:s==="done"?e(x,{strokeWidth:3.5}):e("span",{className:"num",children:r+1})}),l("span",{className:"min-w-0",children:[e("span",{className:"block truncate text-[13px] font-semibold",children:t.title}),t.description?e("span",{className:n("block truncate text-[11px]",s==="current"?"text-white/80":"text-muted"),children:t.description}):null]})]})},r)})});if(i==="bar")return e("ol",{className:n("grid gap-3",u),style:{gridTemplateColumns:`repeat(${o.length}, minmax(0, 1fr))`},children:o.map((a,t)=>{const r=m(t);return l("li",{"aria-current":r==="current"?"step":void 0,className:"min-w-0",children:[e("span",{className:"block h-1.5 overflow-hidden rounded-full bg-hover",children:e("span",{className:n("block h-full rounded-full bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))] transition-[width] duration-500 ease-[var(--ease)]",r==="todo"?"w-0":r==="current"?"w-1/2":"w-full")})}),l("span",{className:n("mt-2 block text-[11px] font-semibold uppercase tracking-[0.06em]",r==="todo"?"text-placeholder":"text-primary"),children:["Step ",t+1]}),e("div",{className:"mt-0.5",children:g(t,a)})]},t)})});if(b==="vertical")return e("ol",{className:n("relative",u),children:o.map((a,t)=>{const r=m(t),s=t===o.length-1;return l("li",{"aria-current":r==="current"?"step":void 0,className:"relative flex gap-3.5 pb-6 last:pb-0",children:[s?null:e("span",{"aria-hidden":!0,className:n("absolute w-0.5 overflow-hidden rounded-full bg-border",i==="dot"?"bottom-0 left-[7px] top-5":i==="glow"?"bottom-1 left-[17px] top-11":"bottom-1 left-[15px] top-10"),children:e("span",{className:n("block w-full bg-[linear-gradient(180deg,var(--brand-1),var(--brand-2))] transition-[height] duration-500 ease-[var(--ease)]",r==="done"?"h-full":"h-0")})}),e(N,{state:r,index:t,icon:a.icon,variant:i}),l("div",{className:n("min-w-0 flex-1",i==="circle"?"pt-1.5":i==="glow"?"pt-2":"-mt-0.5"),children:[g(t,a),a.content&&r==="current"?e("div",{className:"mt-3 animate-[wave-in_220ms_var(--ease)]",children:a.content}):null]})]},t)})});const h=(a,t)=>e("span",{className:n("relative h-0.5 flex-1 overflow-hidden bg-border",t&&"invisible"),children:e("span",{className:n("absolute inset-y-0 left-0 bg-[linear-gradient(90deg,var(--brand-1),var(--brand-2))] transition-[width] duration-500 ease-[var(--ease)]",a?"w-full":"w-0")})});return e("ol",{className:n("flex items-start",u),children:o.map((a,t)=>{const r=m(t);return l("li",{"aria-current":r==="current"?"step":void 0,className:"flex min-w-0 flex-1 flex-col items-center text-center",children:[l("div",{className:"flex w-full items-center gap-1.5",children:[h(t<=d,t===0),e(N,{state:r,index:t,icon:a.icon,variant:i}),h(t<d,t===o.length-1)]}),e("div",{className:"mt-2 max-w-[180px] px-1",children:g(t,a)})]},t)})})}export{R as Steps};
@@ -0,0 +1,33 @@
1
+ import * as React from "react";
2
+ import { type InputState } from "./input";
3
+ /**
4
+ * TagInput — a field that holds several short values: plates on a pass,
5
+ * emails to notify, labels on a site.
6
+ *
7
+ * Enter, comma or Tab turns the text into a tag; a pasted list ("a, b, c" or
8
+ * one per line) becomes several at once. Backspace in an empty field first
9
+ * marks the last tag, then removes it, so nothing goes by accident. Duplicates
10
+ * are refused, `max` caps the count, and `validate` can reject a value with a
11
+ * reason that shows under the field. `suggestions` offers completions as you type.
12
+ *
13
+ * Tag looks: `soft` (default), `outline`, `solid`.
14
+ */
15
+ export type TagVariant = "soft" | "outline" | "solid";
16
+ export interface TagInputProps {
17
+ value?: string[];
18
+ defaultValue?: string[];
19
+ onValueChange?: (tags: string[]) => void;
20
+ placeholder?: string;
21
+ suggestions?: string[];
22
+ max?: number;
23
+ /** Return a reason to refuse a tag, or nothing to accept it. */
24
+ validate?: (tag: string) => string | void | undefined | null;
25
+ /** Change a tag before it is added: trim, upper-case a plate. */
26
+ transform?: (tag: string) => string;
27
+ variant?: TagVariant;
28
+ state?: InputState;
29
+ disabled?: boolean;
30
+ "aria-label"?: string;
31
+ className?: string;
32
+ }
33
+ export declare function TagInput({ value, defaultValue, onValueChange, placeholder, suggestions, max, validate, transform, variant, state, disabled, "aria-label": ariaLabel, className, }: TagInputProps): React.JSX.Element;
@@ -0,0 +1 @@
1
+ "use client";import{jsx as i,jsxs as g}from"react/jsx-runtime";import{Plus as O,X}from"lucide-react";import*as o from"react";import{cn as f}from"../../lib/utils.js";const J={soft:"bg-primary-subtle text-primary",outline:"border border-border2 bg-raised text-text",solid:"bg-[linear-gradient(135deg,var(--brand-1),var(--brand-2))] text-white shadow-[inset_0_1px_0_rgba(255,255,255,.2)]"};function Z({value:C,defaultValue:P=[],onValueChange:V,placeholder:z="Add\u2026",suggestions:l,max:s,validate:R,transform:$=v=>v.trim(),variant:I="soft",state:h="default",disabled:T,"aria-label":U,className:B}){const[v,F]=o.useState(P),r=C??v,[a,m]=o.useState(""),[_,u]=o.useState(!1),[d,w]=o.useState(null),[y,k]=o.useState(0),[q,L]=o.useState(!1),N=o.useRef(null),S=o.useId(),A=o.useId(),D=e=>{C===void 0&&F(e),V?.(e)},E=s!==void 0&&r.length>=s,b=e=>{const t=[...r];let n=null;for(const H of e){const p=$(H);if(!p)continue;if(s!==void 0&&t.length>=s){n=`Up to ${s}`;break}if(t.some(K=>K.toLowerCase()===p.toLowerCase())){n=`\u201C${p}\u201D is already in`;continue}const M=R?.(p);if(M){n=M;continue}t.push(p)}w(n),t.length!==r.length&&D(t)},c=o.useMemo(()=>{if(!l||!a.trim())return[];const e=a.trim().toLowerCase();return l.filter(t=>t.toLowerCase().includes(e)&&!r.some(n=>n.toLowerCase()===t.toLowerCase())).slice(0,6)},[l,a,r]),x=q&&c.length>0,G=e=>{D(r.filter((t,n)=>n!==e)),w(null),N.current?.focus()};return g("div",{className:f("relative w-full",B),children:[g("div",{onClick:()=>N.current?.focus(),className:f("flex min-h-ctl w-full cursor-text flex-wrap items-center gap-1.5 rounded-ctl border border-border2 bg-raised px-1.5 py-1 transition-[border-color,box-shadow] duration-150","focus-within:border-primary focus-within:ring-2 focus-within:ring-primary/20",(h==="error"||d)&&"border-danger focus-within:border-danger focus-within:ring-danger/20",h==="success"&&"border-success",T&&"pointer-events-none bg-hover opacity-60"),children:[r.map((e,t)=>g("span",{className:f("inline-flex h-6 max-w-full animate-[wm-pop_180ms_var(--ease)] items-center gap-1 rounded-[calc(6px*var(--radius-scale))] pl-2 pr-0.5 text-[12.5px] font-medium transition-shadow",J[I],_&&t===r.length-1&&"ring-2 ring-danger/60 ring-offset-1 ring-offset-[var(--raised)]"),children:[i("span",{className:"truncate",children:e}),i("button",{type:"button","aria-label":`Remove ${e}`,onClick:n=>{n.stopPropagation(),G(t)},className:f("grid size-5 cursor-pointer place-items-center rounded-[5px] opacity-70 transition-[opacity,background-color] hover:opacity-100",I==="solid"?"hover:bg-white/20":"hover:bg-black/5 dark:hover:bg-white/10"),children:i(X,{className:"size-3"})})]},e)),i("input",{ref:N,value:a,disabled:T||E,"aria-label":U,"aria-invalid":!!d||h==="error"||void 0,"aria-describedby":d?A:void 0,role:l?"combobox":void 0,"aria-expanded":l?x:void 0,"aria-controls":l?S:void 0,placeholder:E?`Up to ${s}`:r.length?"":z,onFocus:()=>L(!0),onBlur:()=>{L(!1),u(!1),a.trim()&&(b([a]),m(""))},onChange:e=>{m(e.target.value),u(!1),k(0),d&&w(null)},onPaste:e=>{const t=e.clipboardData.getData("text");/[,\n;]/.test(t)&&(e.preventDefault(),b(t.split(/[,\n;]+/)))},onKeyDown:e=>{if(x&&(e.key==="ArrowDown"||e.key==="ArrowUp")){e.preventDefault(),k(t=>(t+(e.key==="ArrowDown"?1:-1)+c.length)%c.length);return}if(e.key==="Enter"||e.key===","||e.key==="Tab"&&a.trim()){if(!a.trim()&&e.key!==",")return;e.preventDefault(),b([x&&e.key==="Enter"?c[y]:a]),m("")}else e.key==="Backspace"&&!a&&r.length?(e.preventDefault(),_?(D(r.slice(0,-1)),u(!1)):u(!0)):e.key==="Escape"&&u(!1)},className:"h-6 min-w-[80px] flex-1 bg-transparent px-1 text-[13px] text-text outline-none placeholder:text-placeholder disabled:cursor-not-allowed"}),s!==void 0?g("span",{className:"num ml-auto shrink-0 px-1 text-[11px] text-muted",children:[r.length,"/",s]}):null]}),x?i("ul",{id:S,role:"listbox",className:"absolute inset-x-0 top-full z-30 mt-1 overflow-hidden rounded-[calc(10px*var(--radius-scale))] border border-border bg-raised p-1 shadow-elev3 animate-[wave-in_160ms_var(--ease)]",children:c.map((e,t)=>g("li",{role:"option","aria-selected":t===y,onMouseDown:n=>{n.preventDefault(),b([e]),m("")},onMouseEnter:()=>k(t),className:f("flex cursor-pointer items-center gap-2 rounded-[calc(7px*var(--radius-scale))] px-2.5 py-1.5 text-[13px]",t===y?"bg-hover text-text":"text-body"),children:[i(O,{className:"size-3.5 text-muted"})," ",e]},e))}):null,d?i("p",{id:A,role:"alert",className:"mt-1.5 text-[12px] text-danger",children:d}):null]})}export{Z as TagInput};