@blakesteve/roster 5.7.0 → 5.9.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.
- package/README.md +169 -5
- package/dist/components/atoms/Avatar/Avatar.cjs +1 -1
- package/dist/components/atoms/Avatar/Avatar.d.ts +4 -0
- package/dist/components/atoms/Avatar/Avatar.js +1 -1
- package/dist/components/atoms/AvatarStrip/AvatarStrip.cjs +1 -1
- package/dist/components/atoms/AvatarStrip/AvatarStrip.d.ts +10 -1
- package/dist/components/atoms/AvatarStrip/AvatarStrip.js +34 -30
- package/dist/components/atoms/Button/button-variants.cjs +1 -1
- package/dist/components/atoms/Button/button-variants.js +5 -3
- package/dist/components/atoms/Eyebrow/eyebrow-variants.cjs +1 -1
- package/dist/components/atoms/Eyebrow/eyebrow-variants.js +8 -4
- package/dist/components/atoms/MultiSelect/MultiSelect.cjs +1 -1
- package/dist/components/atoms/MultiSelect/MultiSelect.d.ts +3 -1
- package/dist/components/atoms/MultiSelect/MultiSelect.js +87 -89
- package/dist/components/atoms/Progress/Progress.cjs +1 -1
- package/dist/components/atoms/Progress/Progress.d.ts +1 -0
- package/dist/components/atoms/Progress/Progress.js +28 -27
- package/dist/components/atoms/Stat/Stat.cjs +1 -1
- package/dist/components/atoms/Stat/Stat.js +5 -5
- package/dist/components/atoms/Stat/stat-variants.cjs +1 -1
- package/dist/components/atoms/Stat/stat-variants.js +10 -8
- package/dist/components/molecules/Breadcrumbs/Breadcrumbs.cjs +1 -1
- package/dist/components/molecules/Breadcrumbs/Breadcrumbs.d.ts +10 -1
- package/dist/components/molecules/Breadcrumbs/Breadcrumbs.js +31 -29
- package/dist/components/molecules/CallToAction/CallToAction.cjs +1 -1
- package/dist/components/molecules/CallToAction/CallToAction.d.ts +8 -1
- package/dist/components/molecules/CallToAction/CallToAction.js +34 -29
- package/dist/components/molecules/Carousel/Carousel.cjs +1 -1
- package/dist/components/molecules/Carousel/Carousel.d.ts +7 -0
- package/dist/components/molecules/Carousel/Carousel.js +155 -155
- package/dist/components/molecules/ErrorState/ErrorState.cjs +1 -1
- package/dist/components/molecules/ErrorState/ErrorState.d.ts +8 -1
- package/dist/components/molecules/ErrorState/ErrorState.js +44 -39
- package/dist/components/molecules/FileUpload/FileUpload.cjs +1 -1
- package/dist/components/molecules/FileUpload/FileUpload.js +23 -22
- package/dist/components/molecules/MediaPreview/MediaPreview.cjs +1 -1
- package/dist/components/molecules/MediaPreview/MediaPreview.d.ts +3 -1
- package/dist/components/molecules/MediaPreview/MediaPreview.js +13 -12
- package/dist/components/molecules/Menu/Menu.cjs +1 -0
- package/dist/components/molecules/Menu/Menu.d.ts +169 -0
- package/dist/components/molecules/Menu/Menu.js +577 -0
- package/dist/components/molecules/Menu/menu-typeahead.cjs +1 -0
- package/dist/components/molecules/Menu/menu-typeahead.d.ts +7 -0
- package/dist/components/molecules/Menu/menu-typeahead.js +13 -0
- package/dist/components/molecules/Pagination/Pagination.cjs +1 -1
- package/dist/components/molecules/Pagination/Pagination.d.ts +1 -0
- package/dist/components/molecules/Pagination/Pagination.js +47 -46
- package/dist/components/molecules/ProgressField/ProgressField.d.ts +1 -0
- package/dist/components/molecules/SkeletonPresets/SkeletonPresets.cjs +1 -1
- package/dist/components/molecules/SkeletonPresets/SkeletonPresets.d.ts +2 -2
- package/dist/components/molecules/SkeletonPresets/SkeletonPresets.js +17 -17
- package/dist/components/molecules/StepProgress/StepProgress.cjs +1 -1
- package/dist/components/molecules/StepProgress/StepProgress.d.ts +1 -0
- package/dist/components/molecules/StepProgress/StepProgress.js +9 -8
- package/dist/components/organisms/Countdown/Countdown.cjs +1 -1
- package/dist/components/organisms/Countdown/Countdown.d.ts +13 -0
- package/dist/components/organisms/Countdown/Countdown.js +54 -47
- package/dist/components/organisms/DataTable/DataTable.cjs +1 -1
- package/dist/components/organisms/DataTable/DataTable.d.ts +5 -3
- package/dist/components/organisms/DataTable/DataTable.js +27 -26
- package/dist/components/organisms/Dialog/Dialog.cjs +1 -1
- package/dist/components/organisms/Dialog/Dialog.d.ts +8 -1
- package/dist/components/organisms/Dialog/Dialog.js +25 -23
- package/dist/components/organisms/Footer/Footer.cjs +1 -1
- package/dist/components/organisms/Footer/Footer.d.ts +9 -0
- package/dist/components/organisms/Footer/Footer.js +21 -23
- package/dist/components/organisms/ModerationQueue/ModerationQueue.cjs +1 -1
- package/dist/components/organisms/ModerationQueue/ModerationQueue.d.ts +40 -1
- package/dist/components/organisms/ModerationQueue/ModerationQueue.js +262 -237
- package/dist/components/organisms/ModerationQueue/QueueEditDialog.cjs +1 -1
- package/dist/components/organisms/ModerationQueue/QueueEditDialog.d.ts +1 -1
- package/dist/components/organisms/ModerationQueue/QueueEditDialog.js +23 -21
- package/dist/components/organisms/ModerationQueue/QueueEditSheet.cjs +1 -1
- package/dist/components/organisms/ModerationQueue/QueueEditSheet.d.ts +1 -1
- package/dist/components/organisms/ModerationQueue/QueueEditSheet.js +22 -20
- package/dist/components/organisms/ModerationQueue/queue-actions.d.ts +29 -10
- package/dist/components/organisms/Navbar/Navbar.cjs +1 -1
- package/dist/components/organisms/Navbar/Navbar.d.ts +39 -4
- package/dist/components/organisms/Navbar/Navbar.js +297 -301
- package/dist/components/organisms/Navbar/navbar-variants.cjs +1 -1
- package/dist/components/organisms/Navbar/navbar-variants.js +4 -2
- package/dist/components/organisms/Sheet/Sheet.cjs +1 -1
- package/dist/components/organisms/Sheet/Sheet.d.ts +8 -1
- package/dist/components/organisms/Sheet/Sheet.js +65 -63
- package/dist/index.d.ts +1 -0
- package/dist/lib/labels.cjs +1 -0
- package/dist/lib/labels.d.ts +7 -0
- package/dist/lib/labels.js +12 -0
- package/dist/meta.json +3 -3
- package/dist/node_modules/@floating-ui/core/dist/floating-ui.core.js +7 -7
- package/dist/node_modules/@floating-ui/dom/dist/floating-ui.dom.js +2 -2
- package/dist/node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.js +5 -5
- package/dist/node_modules/@headlessui/react/dist/components/portal/portal.js +6 -6
- package/dist/node_modules/@headlessui/react/dist/utils/focus-management.cjs +1 -1
- package/dist/node_modules/@headlessui/react/dist/utils/focus-management.js +52 -61
- package/dist/node_modules/@radix-ui/react-popper/dist/index.js +6 -6
- package/dist/roster.cjs +1 -1
- package/dist/roster.css +1 -1
- package/dist/roster.js +127 -116
- package/package.json +2 -1
- package/dist/node_modules/@headlessui/react/dist/components/menu/menu-machine-glue.cjs +0 -1
- package/dist/node_modules/@headlessui/react/dist/components/menu/menu-machine-glue.js +0 -21
- package/dist/node_modules/@headlessui/react/dist/components/menu/menu-machine.cjs +0 -1
- package/dist/node_modules/@headlessui/react/dist/components/menu/menu-machine.js +0 -120
- package/dist/node_modules/@headlessui/react/dist/components/menu/menu.cjs +0 -1
- package/dist/node_modules/@headlessui/react/dist/components/menu/menu.js +0 -197
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),o=require("react"),p=require("../../../lib/utils.cjs"),H=require("../../atoms/Button/Button.cjs"),pt=require("../../atoms/Progress/Progress.cjs"),R=require("./file-rules.cjs"),gt={choose:"Choose photos",dropHint:"or drag them here",dropHere:"Drop to add them",queued:"Waiting",uploading:n=>n===null?"Uploading":`Uploading, ${n}%`,processing:"Finishing up",done:"Uploaded",failed:"Didn't upload.",rejected:"Not added.",remove:n=>`Remove ${n}`,retry:n=>`Try ${n} again`,wrongType:()=>"That type of file isn't accepted.",tooLarge:(n,d)=>`It's over ${R.formatBytes(d)}.`,tooMany:n=>`Only ${n} can be added.`,duplicate:()=>"It's already added.",uploadError:n=>n instanceof Error&&n.message?n.message:"Something went wrong.",size:R.formatBytes,added:n=>`${n} ${n===1?"photo":"photos"} added.`,progress:(n,d)=>`${n} of ${d} uploaded.`,failedNotice:(n,d)=>`${n} didn't upload. ${d}`,rejectedNotice:(n,d)=>`${n} wasn't added. ${d}`,removed:n=>`${n} removed.`};function ht({file:n,status:d}){const[q,M]=o.useState(!1),B=!q&&(n.type.startsWith("image/")||/\.(jpe?g|png|gif|webp|avif|heic|heif)$/i.test(n.name)),N=o.useCallback(L=>{if(!L)return;const w=URL.createObjectURL(n);return L.src=w,()=>URL.revokeObjectURL(w)},[n]),x="rst:h-14 rst:w-14 rst:shrink-0 rst:rounded-md rst:border rst:border-[var(--roster-card-border)]";return B?r.jsx("img",{ref:N,alt:"",onError:()=>M(!0),className:p.cn(x,"rst:object-cover",d==="rejected"&&"rst:opacity-50"),"data-file-thumb":"image"}):r.jsx("span",{"aria-hidden":"true",className:p.cn(x,"rst:flex rst:items-center rst:justify-center rst:text-gray-500 rst:dark:text-gray-400"),"data-file-thumb":"placeholder",children:r.jsxs("svg",{viewBox:"0 0 24 24",width:"24",height:"24",fill:"none",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("rect",{x:"3",y:"5",width:"18",height:"14",rx:"2"}),r.jsx("circle",{cx:"9",cy:"10",r:"1.6"}),r.jsx("path",{d:"m21 15-4.2-4.2a1.6 1.6 0 0 0-2.3 0L7 18"})]})})}const W="rst:cursor-not-allowed rst:opacity-50",S={width:20,height:20,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};function xt({label:n,upload:d,onChange:q,accept:M="image/*",types:B,maxSize:N,maxFiles:x,validate:L,concurrency:w=3,helperText:E,errorMessage:T,disabled:i=!1,strings:Q,className:X}){const c={...gt,...Q},D=o.useId(),I=`${D}-label`,G=`${D}-help`,V=`${D}-error`,[U,Y]=o.useState([]),l=o.useRef(U),Z=o.useRef(0),m=o.useRef(new Map),F=o.useRef(null),_=o.useRef(null),g=o.useRef({upload:d,onChange:q,concurrency:w,t:c,pump:()=>{}}),[z,tt]=o.useState({text:"",n:0}),j=o.useRef([]),v=o.useRef(null),$=o.useCallback((t,s=!1)=>{s&&(j.current=j.current.filter(e=>!e.count)),j.current.push({text:t,count:s}),!v.current&&(v.current=setTimeout(()=>{v.current=null;const e=j.current.map(u=>u.text).join(" ");j.current=[],tt(u=>({text:e,n:u.n+1}))},0))},[]),O=o.useRef(null),[et,rt]=o.useState(0),J=t=>{O.current=t,rt(s=>s+1)};o.useLayoutEffect(()=>{const t=O.current;if(!t)return;O.current=null,(F.current?.querySelector(t)??F.current?.querySelector("[data-file-choose]"))?.focus()},[et]);const y=o.useCallback(t=>{l.current=t,Y(t),g.current.onChange?.(t)},[]),b=o.useCallback((t,s)=>{l.current.some(e=>e.id===t)&&y(l.current.map(e=>e.id===t?{...e,...s}:e))},[y]);function k(){const{concurrency:t}=g.current,s=l.current.filter(u=>u.status==="uploading"||u.status==="processing").length,e=l.current.filter(u=>u.status==="queued").slice(0,Math.max(0,Math.max(1,t)-s));for(const u of e)st(u)}function st(t){const s=new AbortController;m.current.set(t.id,s),b(t.id,{status:"uploading",progress:null,reason:void 0});const e=()=>!s.signal.aborted&&m.current.get(t.id)===s,u={onProgress:a=>{if(!e())return;const f=Math.round(Math.min(1,Math.max(0,Number.isFinite(a)?a:0))*100)/100,h=l.current.find(ft=>ft.id===t.id);h?.status==="uploading"&&h.progress!==f&&b(t.id,{progress:f})},onProcessing:()=>{e()&&b(t.id,{status:"processing"})},signal:s.signal};new Promise(a=>a(g.current.upload(t.file,u))).then(a=>{if(!e())return;m.current.delete(t.id),b(t.id,{status:"done",progress:1,result:a});const f=l.current.filter(h=>h.status!=="rejected");$(g.current.t.progress(f.filter(h=>h.status==="done").length,f.length),!0),k()},a=>{if(!e())return;m.current.delete(t.id);const f=g.current.t.uploadError(a);b(t.id,{status:"failed",reason:f}),$(g.current.t.failedNotice(t.file.name,f)),k()})}o.useLayoutEffect(()=>{g.current={upload:d,onChange:q,concurrency:w,t:c,pump:k}}),o.useEffect(()=>{const t=m.current;return l.current.some(e=>(e.status==="uploading"||e.status==="processing")&&!t.has(e.id))&&(y(l.current.map(e=>(e.status==="uploading"||e.status==="processing")&&!t.has(e.id)?{...e,status:"queued",progress:null}:e)),g.current.pump()),()=>{for(const e of t.values())e.abort();t.clear(),v.current&&clearTimeout(v.current),v.current=null,j.current=[]}},[y]);const nt=B??R.acceptList(M),at=(t,s)=>{if(s.some(u=>R.sameFile(u.file,t)))return c.duplicate(t);const e=L?.(t);if(e)return e;if(!R.matchesType(t,nt))return c.wrongType(t);if(N!==void 0&&t.size>N)return c.tooLarge(t,N);if(x!==void 0&&s.length>=x)return c.tooMany(x)},K=t=>{if(i||t.length===0)return;const s=l.current.filter(a=>a.status!=="rejected"),e=[];for(const a of t){const f=at(a,[...s,...e.filter(h=>h.status!=="rejected")]);e.push({id:`${D}-file-${Z.current++}`,file:a,status:f?"rejected":"queued",progress:null,reason:f})}y([...l.current,...e]);const u=e.filter(a=>a.status==="queued").length;u&&$(c.added(u));for(const a of e)a.reason&&$(c.rejectedNotice(a.file.name,a.reason));k()},ot=t=>{if(i)return;const s=l.current,e=s.findIndex(a=>a.id===t);if(e<0)return;m.current.get(t)?.abort(),m.current.delete(t);const u=s[e+1]??s[e-1];y(s.filter(a=>a.id!==t)),$(c.removed(s[e].file.name)),J(u?`[data-file-remove="${u.id}"]`:"[data-file-choose]"),k()},ct=t=>{i||(b(t,{status:"queued",progress:null,reason:void 0}),J(`[data-file-remove="${t}"]`),k())},[ut,P]=o.useState(0),C=t=>Array.from(t.dataTransfer?.types??[]).includes("Files"),it={onDragEnter:t=>{C(t)&&(t.preventDefault(),P(s=>s+1))},onDragOver:t=>{C(t)&&(t.preventDefault(),t.dataTransfer.dropEffect=i?"none":"copy")},onDragLeave:t=>{C(t)&&P(s=>Math.max(0,s-1))},onDrop:t=>{C(t)&&(t.preventDefault(),P(0),K(Array.from(t.dataTransfer.files)))}},A=ut>0&&!i,dt=t=>{switch(t.status){case"queued":return c.queued;case"uploading":return c.uploading(t.progress===null?null:Math.round(t.progress*100));case"processing":return c.processing;case"done":return c.done;case"failed":return`${c.failed} ${t.reason??""}`.trim();case"rejected":return`${c.rejected} ${t.reason??""}`.trim()}},lt=[E?G:null,T?V:null].filter(Boolean).join(" ")||void 0;return r.jsxs("div",{ref:F,role:"group","aria-labelledby":I,className:p.cn("rst:font-ui rst:w-full",X),"data-file-upload":"",children:[r.jsx("p",{id:I,className:p.cn("rst:mb-1.5 rst:text-left rst:text-sm rst:font-medium rst:leading-none rst:text-[var(--roster-control-text)]",i&&"rst:opacity-70"),children:n}),r.jsxs("div",{...it,"data-file-drop":"","data-dragging":A?"":void 0,className:p.cn("rst:flex rst:flex-col rst:items-center rst:justify-center rst:gap-2 rst:rounded-lg rst:border-2 rst:border-dashed rst:px-4 rst:py-6 rst:text-center rst:transition-colors rst:motion-reduce:transition-none",A?"rst:border-primary-500 rst:bg-primary-500/10":T?"rst:border-error-500 rst:dark:border-error-400":"rst:border-gray-300 rst:dark:border-gray-600"),children:[r.jsx(H.Button,{type:"button",variant:"outline",colorScheme:"neutral",size:"lg",className:p.cn("rst:px-5",i&&W),"aria-disabled":i||void 0,"aria-describedby":lt,onClick:()=>_.current?.click(),"data-file-choose":"",startIcon:r.jsx("svg",{...S,"aria-hidden":"true",children:r.jsx("path",{d:"M12 16V4M7 9l5-5 5 5M5 20h14"})}),children:c.choose}),r.jsx("p",{className:"rst:hidden rst:text-xs rst:text-gray-600 rst:pointer-fine:block rst:dark:text-gray-400","data-file-drop-hint":"",children:A?c.dropHere:c.dropHint}),r.jsx("input",{ref:_,type:"file",hidden:!0,tabIndex:-1,accept:M,multiple:x!==1,disabled:i,onChange:t=>{K(Array.from(t.currentTarget.files??[])),t.currentTarget.value=""},"data-file-input":""})]}),E&&r.jsx("p",{id:G,className:"rst:mt-1.5 rst:text-left rst:text-xs rst:text-gray-500 rst:dark:text-gray-400",children:E}),T&&r.jsx("p",{id:V,className:"rst:mt-1.5 rst:text-left rst:text-xs rst:font-medium rst:text-error-600 rst:dark:text-error-400",children:T}),U.length>0&&r.jsx("ul",{className:"rst:mt-3 rst:flex rst:flex-col rst:gap-2","aria-labelledby":I,children:U.map(t=>{const s=t.status==="failed"||t.status==="rejected",e=t.status==="uploading"||t.status==="processing"||t.status==="queued";return r.jsxs("li",{"data-file-item":t.id,"data-status":t.status,className:"rst:flex rst:items-center rst:gap-3 rst:rounded-md rst:border rst:border-[var(--roster-card-border)] rst:p-2",children:[r.jsx(ht,{file:t.file,status:t.status}),r.jsxs("div",{className:"rst:min-w-0 rst:flex-1 rst:text-left",children:[r.jsx("p",{className:"rst:truncate rst:text-sm rst:font-medium rst:text-[var(--roster-control-text)]",title:t.file.name,children:t.file.name}),r.jsxs("p",{className:p.cn("rst:mt-0.5 rst:flex rst:items-start rst:gap-1 rst:text-xs",s?"rst:text-error-600 rst:dark:text-error-400":"rst:text-gray-600 rst:dark:text-gray-400"),"data-file-status":"",children:[t.status==="done"&&r.jsx("svg",{...S,width:14,height:14,"aria-hidden":"true",className:"rst:mt-px rst:shrink-0 rst:text-success-600 rst:dark:text-success-400",children:r.jsx("path",{d:"M20 6 9 17l-5-5"})}),r.jsxs("span",{children:[r.jsx("span",{className:"rst:tabular-nums",children:c.size(t.file.size)}),r.jsx("span",{"aria-hidden":"true",children:" · "}),dt(t)]})]}),e&&r.jsx("div",{className:"rst:mt-1.5","data-file-progress":"",children:r.jsx(pt.Progress,{size:"sm",value:t.status==="processing"?100:t.status==="uploading"?(t.progress??0)*100:0,busy:t.status==="processing"||t.status==="uploading"&&t.progress===null,announce:!1})})]}),t.status==="failed"&&r.jsx(H.Button,{type:"button",variant:"ghost",colorScheme:"neutral",size:"icon",className:p.cn("rst:h-11 rst:w-11",i&&W),"aria-disabled":i||void 0,"aria-label":c.retry(t.file.name),onClick:()=>ct(t.id),"data-file-retry":t.id,children:r.jsxs("svg",{...S,"aria-hidden":"true",children:[r.jsx("path",{d:"M3 12a9 9 0 1 0 3-6.7L3 8"}),r.jsx("path",{d:"M3 3v5h5"})]})}),r.jsx(H.Button,{type:"button",variant:"ghost",colorScheme:"neutral",size:"icon",className:p.cn("rst:h-11 rst:w-11",i&&W),"aria-disabled":i||void 0,"aria-label":c.remove(t.file.name),onClick:()=>ot(t.id),"data-file-remove":t.id,children:r.jsx("svg",{...S,"aria-hidden":"true",children:r.jsx("path",{d:"M18 6 6 18M6 6l12 12"})})})]},t.id)})}),r.jsxs("div",{role:"status","aria-live":"polite","aria-atomic":"true",className:"rst:sr-only","data-file-live":"","data-file-live-n":z.n,children:[z.text,z.n%2?" ":""]})]})}exports.FileUpload=xt;
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),o=require("react"),p=require("../../../lib/utils.cjs"),pt=require("../../../lib/labels.cjs"),H=require("../../atoms/Button/Button.cjs"),gt=require("../../atoms/Progress/Progress.cjs"),R=require("./file-rules.cjs"),ht={choose:"Choose photos",dropHint:"or drag them here",dropHere:"Drop to add them",queued:"Waiting",uploading:n=>n===null?"Uploading":`Uploading, ${n}%`,processing:"Finishing up",done:"Uploaded",failed:"Didn't upload.",rejected:"Not added.",remove:n=>`Remove ${n}`,retry:n=>`Try ${n} again`,wrongType:()=>"That type of file isn't accepted.",tooLarge:(n,l)=>`It's over ${R.formatBytes(l)}.`,tooMany:n=>`Only ${n} can be added.`,duplicate:()=>"It's already added.",uploadError:n=>n instanceof Error&&n.message?n.message:"Something went wrong.",size:R.formatBytes,added:n=>`${n} ${n===1?"photo":"photos"} added.`,progress:(n,l)=>`${n} of ${l} uploaded.`,failedNotice:(n,l)=>`${n} didn't upload. ${l}`,rejectedNotice:(n,l)=>`${n} wasn't added. ${l}`,removed:n=>`${n} removed.`};function xt({file:n,status:l}){const[q,L]=o.useState(!1),B=!q&&(n.type.startsWith("image/")||/\.(jpe?g|png|gif|webp|avif|heic|heif)$/i.test(n.name)),N=o.useCallback(M=>{if(!M)return;const w=URL.createObjectURL(n);return M.src=w,()=>URL.revokeObjectURL(w)},[n]),x="rst:h-14 rst:w-14 rst:shrink-0 rst:rounded-md rst:border rst:border-[var(--roster-card-border)]";return B?r.jsx("img",{ref:N,alt:"",onError:()=>L(!0),className:p.cn(x,"rst:object-cover",l==="rejected"&&"rst:opacity-50"),"data-file-thumb":"image"}):r.jsx("span",{"aria-hidden":"true",className:p.cn(x,"rst:flex rst:items-center rst:justify-center rst:text-gray-500 rst:dark:text-gray-400"),"data-file-thumb":"placeholder",children:r.jsxs("svg",{viewBox:"0 0 24 24",width:"24",height:"24",fill:"none",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("rect",{x:"3",y:"5",width:"18",height:"14",rx:"2"}),r.jsx("circle",{cx:"9",cy:"10",r:"1.6"}),r.jsx("path",{d:"m21 15-4.2-4.2a1.6 1.6 0 0 0-2.3 0L7 18"})]})})}const W="rst:cursor-not-allowed rst:opacity-50",S={width:20,height:20,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};function mt({label:n,upload:l,onChange:q,accept:L="image/*",types:B,maxSize:N,maxFiles:x,validate:M,concurrency:w=3,helperText:E,errorMessage:T,disabled:i=!1,strings:Q,className:X}){const c=pt.withLabels(ht,Q),D=o.useId(),I=`${D}-label`,G=`${D}-help`,V=`${D}-error`,[U,Y]=o.useState([]),d=o.useRef(U),Z=o.useRef(0),m=o.useRef(new Map),F=o.useRef(null),_=o.useRef(null),g=o.useRef({upload:l,onChange:q,concurrency:w,t:c,pump:()=>{}}),[z,tt]=o.useState({text:"",n:0}),j=o.useRef([]),v=o.useRef(null),$=o.useCallback((t,s=!1)=>{s&&(j.current=j.current.filter(e=>!e.count)),j.current.push({text:t,count:s}),!v.current&&(v.current=setTimeout(()=>{v.current=null;const e=j.current.map(u=>u.text).join(" ");j.current=[],tt(u=>({text:e,n:u.n+1}))},0))},[]),O=o.useRef(null),[et,rt]=o.useState(0),J=t=>{O.current=t,rt(s=>s+1)};o.useLayoutEffect(()=>{const t=O.current;if(!t)return;O.current=null,(F.current?.querySelector(t)??F.current?.querySelector("[data-file-choose]"))?.focus()},[et]);const y=o.useCallback(t=>{d.current=t,Y(t),g.current.onChange?.(t)},[]),b=o.useCallback((t,s)=>{d.current.some(e=>e.id===t)&&y(d.current.map(e=>e.id===t?{...e,...s}:e))},[y]);function k(){const{concurrency:t}=g.current,s=d.current.filter(u=>u.status==="uploading"||u.status==="processing").length,e=d.current.filter(u=>u.status==="queued").slice(0,Math.max(0,Math.max(1,t)-s));for(const u of e)st(u)}function st(t){const s=new AbortController;m.current.set(t.id,s),b(t.id,{status:"uploading",progress:null,reason:void 0});const e=()=>!s.signal.aborted&&m.current.get(t.id)===s,u={onProgress:a=>{if(!e())return;const f=Math.round(Math.min(1,Math.max(0,Number.isFinite(a)?a:0))*100)/100,h=d.current.find(ft=>ft.id===t.id);h?.status==="uploading"&&h.progress!==f&&b(t.id,{progress:f})},onProcessing:()=>{e()&&b(t.id,{status:"processing"})},signal:s.signal};new Promise(a=>a(g.current.upload(t.file,u))).then(a=>{if(!e())return;m.current.delete(t.id),b(t.id,{status:"done",progress:1,result:a});const f=d.current.filter(h=>h.status!=="rejected");$(g.current.t.progress(f.filter(h=>h.status==="done").length,f.length),!0),k()},a=>{if(!e())return;m.current.delete(t.id);const f=g.current.t.uploadError(a);b(t.id,{status:"failed",reason:f}),$(g.current.t.failedNotice(t.file.name,f)),k()})}o.useLayoutEffect(()=>{g.current={upload:l,onChange:q,concurrency:w,t:c,pump:k}}),o.useEffect(()=>{const t=m.current;return d.current.some(e=>(e.status==="uploading"||e.status==="processing")&&!t.has(e.id))&&(y(d.current.map(e=>(e.status==="uploading"||e.status==="processing")&&!t.has(e.id)?{...e,status:"queued",progress:null}:e)),g.current.pump()),()=>{for(const e of t.values())e.abort();t.clear(),v.current&&clearTimeout(v.current),v.current=null,j.current=[]}},[y]);const nt=B??R.acceptList(L),at=(t,s)=>{if(s.some(u=>R.sameFile(u.file,t)))return c.duplicate(t);const e=M?.(t);if(e)return e;if(!R.matchesType(t,nt))return c.wrongType(t);if(N!==void 0&&t.size>N)return c.tooLarge(t,N);if(x!==void 0&&s.length>=x)return c.tooMany(x)},K=t=>{if(i||t.length===0)return;const s=d.current.filter(a=>a.status!=="rejected"),e=[];for(const a of t){const f=at(a,[...s,...e.filter(h=>h.status!=="rejected")]);e.push({id:`${D}-file-${Z.current++}`,file:a,status:f?"rejected":"queued",progress:null,reason:f})}y([...d.current,...e]);const u=e.filter(a=>a.status==="queued").length;u&&$(c.added(u));for(const a of e)a.reason&&$(c.rejectedNotice(a.file.name,a.reason));k()},ot=t=>{if(i)return;const s=d.current,e=s.findIndex(a=>a.id===t);if(e<0)return;m.current.get(t)?.abort(),m.current.delete(t);const u=s[e+1]??s[e-1];y(s.filter(a=>a.id!==t)),$(c.removed(s[e].file.name)),J(u?`[data-file-remove="${u.id}"]`:"[data-file-choose]"),k()},ct=t=>{i||(b(t,{status:"queued",progress:null,reason:void 0}),J(`[data-file-remove="${t}"]`),k())},[ut,P]=o.useState(0),C=t=>Array.from(t.dataTransfer?.types??[]).includes("Files"),it={onDragEnter:t=>{C(t)&&(t.preventDefault(),P(s=>s+1))},onDragOver:t=>{C(t)&&(t.preventDefault(),t.dataTransfer.dropEffect=i?"none":"copy")},onDragLeave:t=>{C(t)&&P(s=>Math.max(0,s-1))},onDrop:t=>{C(t)&&(t.preventDefault(),P(0),K(Array.from(t.dataTransfer.files)))}},A=ut>0&&!i,lt=t=>{switch(t.status){case"queued":return c.queued;case"uploading":return c.uploading(t.progress===null?null:Math.round(t.progress*100));case"processing":return c.processing;case"done":return c.done;case"failed":return`${c.failed} ${t.reason??""}`.trim();case"rejected":return`${c.rejected} ${t.reason??""}`.trim()}},dt=[E?G:null,T?V:null].filter(Boolean).join(" ")||void 0;return r.jsxs("div",{ref:F,role:"group","aria-labelledby":I,className:p.cn("rst:font-ui rst:w-full",X),"data-file-upload":"",children:[r.jsx("p",{id:I,className:p.cn("rst:mb-1.5 rst:text-left rst:text-sm rst:font-medium rst:leading-none rst:text-[var(--roster-control-text)]",i&&"rst:opacity-70"),children:n}),r.jsxs("div",{...it,"data-file-drop":"","data-dragging":A?"":void 0,className:p.cn("rst:flex rst:flex-col rst:items-center rst:justify-center rst:gap-2 rst:rounded-lg rst:border-2 rst:border-dashed rst:px-4 rst:py-6 rst:text-center rst:transition-colors rst:motion-reduce:transition-none",A?"rst:border-primary-500 rst:bg-primary-500/10":T?"rst:border-error-500 rst:dark:border-error-400":"rst:border-gray-300 rst:dark:border-gray-600"),children:[r.jsx(H.Button,{type:"button",variant:"outline",colorScheme:"neutral",size:"lg",className:p.cn("rst:px-5",i&&W),"aria-disabled":i||void 0,"aria-describedby":dt,onClick:()=>_.current?.click(),"data-file-choose":"",startIcon:r.jsx("svg",{...S,"aria-hidden":"true",children:r.jsx("path",{d:"M12 16V4M7 9l5-5 5 5M5 20h14"})}),children:c.choose}),r.jsx("p",{className:"rst:hidden rst:text-xs rst:text-gray-600 rst:pointer-fine:block rst:dark:text-gray-400","data-file-drop-hint":"",children:A?c.dropHere:c.dropHint}),r.jsx("input",{ref:_,type:"file",hidden:!0,tabIndex:-1,accept:L,multiple:x!==1,disabled:i,onChange:t=>{K(Array.from(t.currentTarget.files??[])),t.currentTarget.value=""},"data-file-input":""})]}),E&&r.jsx("p",{id:G,className:"rst:mt-1.5 rst:text-left rst:text-xs rst:text-gray-500 rst:dark:text-gray-400",children:E}),T&&r.jsx("p",{id:V,className:"rst:mt-1.5 rst:text-left rst:text-xs rst:font-medium rst:text-error-600 rst:dark:text-error-400",children:T}),U.length>0&&r.jsx("ul",{className:"rst:mt-3 rst:flex rst:flex-col rst:gap-2","aria-labelledby":I,children:U.map(t=>{const s=t.status==="failed"||t.status==="rejected",e=t.status==="uploading"||t.status==="processing"||t.status==="queued";return r.jsxs("li",{"data-file-item":t.id,"data-status":t.status,className:"rst:flex rst:items-center rst:gap-3 rst:rounded-md rst:border rst:border-[var(--roster-card-border)] rst:p-2",children:[r.jsx(xt,{file:t.file,status:t.status}),r.jsxs("div",{className:"rst:min-w-0 rst:flex-1 rst:text-left",children:[r.jsx("p",{className:"rst:truncate rst:text-sm rst:font-medium rst:text-[var(--roster-control-text)]",title:t.file.name,children:t.file.name}),r.jsxs("p",{className:p.cn("rst:mt-0.5 rst:flex rst:items-start rst:gap-1 rst:text-xs",s?"rst:text-error-600 rst:dark:text-error-400":"rst:text-gray-600 rst:dark:text-gray-400"),"data-file-status":"",children:[t.status==="done"&&r.jsx("svg",{...S,width:14,height:14,"aria-hidden":"true",className:"rst:mt-px rst:shrink-0 rst:text-success-600 rst:dark:text-success-400",children:r.jsx("path",{d:"M20 6 9 17l-5-5"})}),r.jsxs("span",{children:[r.jsx("span",{className:"rst:tabular-nums",children:c.size(t.file.size)}),r.jsx("span",{"aria-hidden":"true",children:" · "}),lt(t)]})]}),e&&r.jsx("div",{className:"rst:mt-1.5","data-file-progress":"",children:r.jsx(gt.Progress,{size:"sm",value:t.status==="processing"?100:t.status==="uploading"?(t.progress??0)*100:0,busy:t.status==="processing"||t.status==="uploading"&&t.progress===null,announce:!1})})]}),t.status==="failed"&&r.jsx(H.Button,{type:"button",variant:"ghost",colorScheme:"neutral",size:"icon",className:p.cn("rst:h-11 rst:w-11",i&&W),"aria-disabled":i||void 0,"aria-label":c.retry(t.file.name),onClick:()=>ct(t.id),"data-file-retry":t.id,children:r.jsxs("svg",{...S,"aria-hidden":"true",children:[r.jsx("path",{d:"M3 12a9 9 0 1 0 3-6.7L3 8"}),r.jsx("path",{d:"M3 3v5h5"})]})}),r.jsx(H.Button,{type:"button",variant:"ghost",colorScheme:"neutral",size:"icon",className:p.cn("rst:h-11 rst:w-11",i&&W),"aria-disabled":i||void 0,"aria-label":c.remove(t.file.name),onClick:()=>ot(t.id),"data-file-remove":t.id,children:r.jsx("svg",{...S,"aria-hidden":"true",children:r.jsx("path",{d:"M18 6 6 18M6 6l12 12"})})})]},t.id)})}),r.jsxs("div",{role:"status","aria-live":"polite","aria-atomic":"true",className:"rst:sr-only","data-file-live":"","data-file-live-n":z.n,children:[z.text,z.n%2?" ":""]})]})}exports.FileUpload=mt;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs as p, jsx as n } from "react/jsx-runtime";
|
|
3
|
-
import { useId as vr, useState as
|
|
3
|
+
import { useId as vr, useState as M, useRef as f, useCallback as U, useLayoutEffect as Y, useEffect as xr } from "react";
|
|
4
4
|
import { cn as g } from "../../../lib/utils.js";
|
|
5
|
+
import { withLabels as yr } from "../../../lib/labels.js";
|
|
5
6
|
import { Button as G } from "../../atoms/Button/Button.js";
|
|
6
|
-
import { Progress as
|
|
7
|
-
import {
|
|
8
|
-
const
|
|
7
|
+
import { Progress as br } from "../../atoms/Progress/Progress.js";
|
|
8
|
+
import { acceptList as kr, formatBytes as Z, sameFile as Nr, matchesType as wr } from "./file-rules.js";
|
|
9
|
+
const $r = {
|
|
9
10
|
choose: "Choose photos",
|
|
10
11
|
dropHint: "or drag them here",
|
|
11
12
|
dropHere: "Drop to add them",
|
|
@@ -29,8 +30,8 @@ const wr = {
|
|
|
29
30
|
rejectedNotice: (s, d) => `${s} wasn't added. ${d}`,
|
|
30
31
|
removed: (s) => `${s} removed.`
|
|
31
32
|
};
|
|
32
|
-
function
|
|
33
|
-
const [T, D] =
|
|
33
|
+
function jr({ file: s, status: d }) {
|
|
34
|
+
const [T, D] = M(!1), B = !T && (s.type.startsWith("image/") || /\.(jpe?g|png|gif|webp|avif|heic|heif)$/i.test(s.name)), $ = U(
|
|
34
35
|
(q) => {
|
|
35
36
|
if (!q) return;
|
|
36
37
|
const j = URL.createObjectURL(s);
|
|
@@ -62,7 +63,7 @@ function $r({ file: s, status: d }) {
|
|
|
62
63
|
);
|
|
63
64
|
}
|
|
64
65
|
const V = "rst:cursor-not-allowed rst:opacity-50", I = { width: 20, height: 20, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" };
|
|
65
|
-
function
|
|
66
|
+
function Er({
|
|
66
67
|
label: s,
|
|
67
68
|
upload: d,
|
|
68
69
|
onChange: T,
|
|
@@ -78,14 +79,14 @@ function Rr({
|
|
|
78
79
|
strings: rr,
|
|
79
80
|
className: tr
|
|
80
81
|
}) {
|
|
81
|
-
const a =
|
|
82
|
-
} }), [A, nr] =
|
|
82
|
+
const a = yr($r, rr), C = vr(), z = `${C}-label`, _ = `${C}-help`, J = `${C}-error`, [F, er] = M([]), u = f(F), sr = f(0), x = f(/* @__PURE__ */ new Map()), O = f(null), K = f(null), h = f({ upload: d, onChange: T, concurrency: j, t: a, pump: () => {
|
|
83
|
+
} }), [A, nr] = M({ text: "", n: 0 }), y = f([]), b = f(null), L = U((r, e = !1) => {
|
|
83
84
|
e && (y.current = y.current.filter((t) => !t.count)), y.current.push({ text: r, count: e }), !b.current && (b.current = setTimeout(() => {
|
|
84
85
|
b.current = null;
|
|
85
86
|
const t = y.current.map((c) => c.text).join(" ");
|
|
86
87
|
y.current = [], nr((c) => ({ text: t, n: c.n + 1 }));
|
|
87
88
|
}, 0));
|
|
88
|
-
}, []), H = f(null), [or, ar] =
|
|
89
|
+
}, []), H = f(null), [or, ar] = M(0), Q = (r) => {
|
|
89
90
|
H.current = r, ar((e) => e + 1);
|
|
90
91
|
};
|
|
91
92
|
Y(() => {
|
|
@@ -124,13 +125,13 @@ function Rr({
|
|
|
124
125
|
if (!t()) return;
|
|
125
126
|
x.current.delete(r.id), N(r.id, { status: "done", progress: 1, result: o });
|
|
126
127
|
const l = u.current.filter((m) => m.status !== "rejected");
|
|
127
|
-
|
|
128
|
+
L(h.current.t.progress(l.filter((m) => m.status === "done").length, l.length), !0), w();
|
|
128
129
|
},
|
|
129
130
|
(o) => {
|
|
130
131
|
if (!t()) return;
|
|
131
132
|
x.current.delete(r.id);
|
|
132
133
|
const l = h.current.t.uploadError(o);
|
|
133
|
-
N(r.id, { status: "failed", reason: l }),
|
|
134
|
+
N(r.id, { status: "failed", reason: l }), L(h.current.t.failedNotice(r.file.name, l)), w();
|
|
134
135
|
}
|
|
135
136
|
);
|
|
136
137
|
}
|
|
@@ -147,11 +148,11 @@ function Rr({
|
|
|
147
148
|
r.clear(), b.current && clearTimeout(b.current), b.current = null, y.current = [];
|
|
148
149
|
};
|
|
149
150
|
}, [k]);
|
|
150
|
-
const ir = B ??
|
|
151
|
-
if (e.some((c) =>
|
|
151
|
+
const ir = B ?? kr(D), dr = (r, e) => {
|
|
152
|
+
if (e.some((c) => Nr(c.file, r))) return a.duplicate(r);
|
|
152
153
|
const t = q?.(r);
|
|
153
154
|
if (t) return t;
|
|
154
|
-
if (!
|
|
155
|
+
if (!wr(r, ir)) return a.wrongType(r);
|
|
155
156
|
if ($ !== void 0 && r.size > $) return a.tooLarge(r, $);
|
|
156
157
|
if (v !== void 0 && e.length >= v) return a.tooMany(v);
|
|
157
158
|
}, X = (r) => {
|
|
@@ -163,8 +164,8 @@ function Rr({
|
|
|
163
164
|
}
|
|
164
165
|
k([...u.current, ...t]);
|
|
165
166
|
const c = t.filter((o) => o.status === "queued").length;
|
|
166
|
-
c &&
|
|
167
|
-
for (const o of t) o.reason &&
|
|
167
|
+
c && L(a.added(c));
|
|
168
|
+
for (const o of t) o.reason && L(a.rejectedNotice(o.file.name, o.reason));
|
|
168
169
|
w();
|
|
169
170
|
}, ur = (r) => {
|
|
170
171
|
if (i) return;
|
|
@@ -172,10 +173,10 @@ function Rr({
|
|
|
172
173
|
if (t < 0) return;
|
|
173
174
|
x.current.get(r)?.abort(), x.current.delete(r);
|
|
174
175
|
const c = e[t + 1] ?? e[t - 1];
|
|
175
|
-
k(e.filter((o) => o.id !== r)),
|
|
176
|
+
k(e.filter((o) => o.id !== r)), L(a.removed(e[t].file.name)), Q(c ? `[data-file-remove="${c.id}"]` : "[data-file-choose]"), w();
|
|
176
177
|
}, lr = (r) => {
|
|
177
178
|
i || (N(r, { status: "queued", progress: null, reason: void 0 }), Q(`[data-file-remove="${r}"]`), w());
|
|
178
|
-
}, [fr, P] =
|
|
179
|
+
}, [fr, P] = M(0), E = (r) => Array.from(r.dataTransfer?.types ?? []).includes("Files"), pr = {
|
|
179
180
|
onDragEnter: (r) => {
|
|
180
181
|
E(r) && (r.preventDefault(), P((e) => e + 1));
|
|
181
182
|
},
|
|
@@ -289,7 +290,7 @@ function Rr({
|
|
|
289
290
|
"data-status": r.status,
|
|
290
291
|
className: "rst:flex rst:items-center rst:gap-3 rst:rounded-md rst:border rst:border-[var(--roster-card-border)] rst:p-2",
|
|
291
292
|
children: [
|
|
292
|
-
/* @__PURE__ */ n(
|
|
293
|
+
/* @__PURE__ */ n(jr, { file: r.file, status: r.status }),
|
|
293
294
|
/* @__PURE__ */ p("div", { className: "rst:min-w-0 rst:flex-1 rst:text-left", children: [
|
|
294
295
|
/* @__PURE__ */ n("p", { className: "rst:truncate rst:text-sm rst:font-medium rst:text-[var(--roster-control-text)]", title: r.file.name, children: r.file.name }),
|
|
295
296
|
/* @__PURE__ */ p(
|
|
@@ -311,7 +312,7 @@ function Rr({
|
|
|
311
312
|
}
|
|
312
313
|
),
|
|
313
314
|
t && /* @__PURE__ */ n("div", { className: "rst:mt-1.5", "data-file-progress": "", children: /* @__PURE__ */ n(
|
|
314
|
-
|
|
315
|
+
br,
|
|
315
316
|
{
|
|
316
317
|
size: "sm",
|
|
317
318
|
value: r.status === "processing" ? 100 : r.status === "uploading" ? (r.progress ?? 0) * 100 : 0,
|
|
@@ -378,5 +379,5 @@ function Rr({
|
|
|
378
379
|
);
|
|
379
380
|
}
|
|
380
381
|
export {
|
|
381
|
-
|
|
382
|
+
Er as FileUpload
|
|
382
383
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),h=require("react"),i=require("../../../lib/utils.cjs");function j({src:e,href:t,alt:s,unavailableLabel:n="Preview unavailable",openLabel:a="Open original",newTabLabel:u="in a new tab",onUnavailable:g,className:o,...x}){const[b,f]=h.useState(null),m=!e||b===e,c="rst:font-ui rst:h-28 rst:w-36 rst:shrink-0 rst:rounded-md rst:border rst:border-[var(--roster-card-border)]";if(m){const d=r.jsxs(r.Fragment,{children:[r.jsx("span",{children:n}),t?r.jsxs("span",{className:"rst:font-semibold rst:underline",children:[a,r.jsx("span",{"aria-hidden":"true",children:" ↗"})]}):null]}),l=i.cn(c,"rst:flex rst:flex-col rst:items-center rst:justify-center rst:gap-1 rst:border-dashed rst:px-2 rst:text-center rst:text-xs rst:text-gray-600 rst:dark:text-gray-300",o);return t?r.jsx("a",{href:t,target:"_blank",rel:"noreferrer",className:i.cn(l,"rst:hover:bg-gray-50 rst:dark:hover:bg-gray-800 rst:focus-visible:outline-hidden rst:focus-visible:ring-2 rst:focus-visible:ring-ring"),"aria-label":`${n}. ${a}, ${u}: ${s}`,children:d}):r.jsx("span",{role:"img","aria-label":`${n}: ${s}`,className:l,children:d})}return r.jsx("img",{...x,src:e,alt:s,className:i.cn(c,"rst:object-cover",o),onError:()=>{f(e),g?.()}})}exports.MediaPreview=j;
|
|
@@ -10,6 +10,8 @@ export interface MediaPreviewProps extends Omit<ImgHTMLAttributes<HTMLImageEleme
|
|
|
10
10
|
unavailableLabel?: string;
|
|
11
11
|
/** The link's own words. */
|
|
12
12
|
openLabel?: string;
|
|
13
|
+
/** Said with the link's name, since its arrow shows it only to the eye: "in a new tab". */
|
|
14
|
+
newTabLabel?: string;
|
|
13
15
|
/** Called once when the thumbnail fails, for an app that keeps a count. */
|
|
14
16
|
onUnavailable?: () => void;
|
|
15
17
|
}
|
|
@@ -23,5 +25,5 @@ export interface MediaPreviewProps extends Omit<ImgHTMLAttributes<HTMLImageEleme
|
|
|
23
25
|
* for a card that says the preview is unavailable and links to the original,
|
|
24
26
|
* in the same footprint, so a row of previews doesn't jump.
|
|
25
27
|
*/
|
|
26
|
-
declare function MediaPreview({ src, href, alt, unavailableLabel, openLabel, onUnavailable, className, ...props }: MediaPreviewProps): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
declare function MediaPreview({ src, href, alt, unavailableLabel, openLabel, newTabLabel, onUnavailable, className, ...props }: MediaPreviewProps): import("react/jsx-runtime").JSX.Element;
|
|
27
29
|
export { MediaPreview };
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as r, jsxs as m, Fragment as
|
|
3
|
-
import { useState as
|
|
2
|
+
import { jsx as r, jsxs as m, Fragment as p } from "react/jsx-runtime";
|
|
3
|
+
import { useState as v } from "react";
|
|
4
4
|
import { cn as i } from "../../../lib/utils.js";
|
|
5
|
-
function
|
|
5
|
+
function j({
|
|
6
6
|
src: e,
|
|
7
7
|
href: t,
|
|
8
8
|
alt: s,
|
|
9
9
|
unavailableLabel: n = "Preview unavailable",
|
|
10
10
|
openLabel: o = "Open original",
|
|
11
|
-
|
|
11
|
+
newTabLabel: g = "in a new tab",
|
|
12
|
+
onUnavailable: u,
|
|
12
13
|
className: a,
|
|
13
|
-
...
|
|
14
|
+
...f
|
|
14
15
|
}) {
|
|
15
|
-
const [
|
|
16
|
-
if (
|
|
17
|
-
const l = /* @__PURE__ */ m(
|
|
16
|
+
const [b, h] = v(null), x = !e || b === e, d = "rst:font-ui rst:h-28 rst:w-36 rst:shrink-0 rst:rounded-md rst:border rst:border-[var(--roster-card-border)]";
|
|
17
|
+
if (x) {
|
|
18
|
+
const l = /* @__PURE__ */ m(p, { children: [
|
|
18
19
|
/* @__PURE__ */ r("span", { children: n }),
|
|
19
20
|
t ? /* @__PURE__ */ m("span", { className: "rst:font-semibold rst:underline", children: [
|
|
20
21
|
o,
|
|
@@ -32,7 +33,7 @@ function $({
|
|
|
32
33
|
target: "_blank",
|
|
33
34
|
rel: "noreferrer",
|
|
34
35
|
className: i(c, "rst:hover:bg-gray-50 rst:dark:hover:bg-gray-800 rst:focus-visible:outline-hidden rst:focus-visible:ring-2 rst:focus-visible:ring-ring"),
|
|
35
|
-
"aria-label": `${n}. ${o},
|
|
36
|
+
"aria-label": `${n}. ${o}, ${g}: ${s}`,
|
|
36
37
|
children: l
|
|
37
38
|
}
|
|
38
39
|
) : /* @__PURE__ */ r("span", { role: "img", "aria-label": `${n}: ${s}`, className: c, children: l });
|
|
@@ -40,16 +41,16 @@ function $({
|
|
|
40
41
|
return /* @__PURE__ */ r(
|
|
41
42
|
"img",
|
|
42
43
|
{
|
|
43
|
-
...
|
|
44
|
+
...f,
|
|
44
45
|
src: e,
|
|
45
46
|
alt: s,
|
|
46
47
|
className: i(d, "rst:object-cover", a),
|
|
47
48
|
onError: () => {
|
|
48
|
-
|
|
49
|
+
h(e), u?.();
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
);
|
|
52
53
|
}
|
|
53
54
|
export {
|
|
54
|
-
|
|
55
|
+
j as MediaPreview
|
|
55
56
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),ge=require("react"),W=require("../../../node_modules/@headlessui/react/dist/components/portal/portal.cjs"),A=require("../../../node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.cjs"),E=require("../../../lib/utils.cjs"),he=require("../../../internal/popup.cjs"),be=require("../../atoms/Button/Button.cjs"),xe=require("./menu-typeahead.cjs"),ye=require("../../../node_modules/@floating-ui/dom/dist/floating-ui.dom.cjs");function ve(e){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const n in e)if(n!=="default"){const o=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(r,n,o.get?o:{enumerable:!0,get:()=>e[n]})}}return r.default=e,Object.freeze(r)}const i=ve(ge);function we({href:e,to:r,children:n,...o}){return c.jsx("a",{href:e,...o,children:n})}const G=i.createContext(null),_=i.createContext(null),V=i.createContext(null);function R(e){const r=i.useContext(G);if(!r)throw new Error(`<${e}> must be inside a <Menu>.`);return r}function K(e){const r=i.useContext(_);if(!r)throw new Error(`<${e}> must be inside <MenuItems> or a <MenuSubmenu>.`);return r}const ke="[data-menu-item]",Y=100,Ie=75,Ee='a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), summary, [tabindex]:not([tabindex="-1"]), [contenteditable]:not([contenteditable="false"])';function L(e){return e?[...e.querySelectorAll(ke)].filter(r=>r.closest("[data-menu-panel]")===e):[]}function S(e){e&&(e.focus({preventScroll:!0}),e.scrollIntoView?.({block:"nearest"}))}function $(e){return!!e&&getComputedStyle(e).direction==="rtl"}function Se(e,r){const n=[...document.querySelectorAll(Ee)].filter(t=>t===e||t.tabIndex>=0&&!t.matches(":disabled")&&!t.closest("[data-menu-panel], [inert]")&&t.getClientRects().length>0&&getComputedStyle(t).visibility!=="hidden"&&!Me(t,r)),o=n.indexOf(e);((r?n[o-1]:n[o+1])??e).focus()}function Me(e,r){if(!(e instanceof HTMLInputElement)||e.type!=="radio"||!e.name)return!1;const n=[...e.ownerDocument.querySelectorAll(`input[type="radio"][name="${CSS.escape(e.name)}"]`)].filter(a=>a.form===e.form&&!a.disabled);return(n.find(a=>a.checked)??(r?n[n.length-1]:n[0]))!==e}const D={x:Number.NaN,y:Number.NaN};let H=!1;function je(){H||typeof window>"u"||(H=!0,window.addEventListener("pointermove",e=>{D.x=e.clientX,D.y=e.clientY},{passive:!0}))}function X(e){return!Number.isNaN(D.x)&&(e.clientX!==D.x||e.clientY!==D.y)}const U=e=>`radial-gradient(farthest-side at 50% ${e==="top"?"0":"100%"}, var(--menu-edge), transparent)`,J={backgroundImage:"var(--menu-edge-top, none), var(--menu-edge-bottom, none)",backgroundPosition:"top, bottom",backgroundSize:"100% 0.5rem",backgroundRepeat:"no-repeat"};function Pe(e){i.useLayoutEffect(()=>{if(!e)return;const r=()=>{const o=e.scrollTop>8,a=e.scrollTop+e.clientHeight<e.scrollHeight-8;e.toggleAttribute("data-more-above",o),e.toggleAttribute("data-more-below",a),e.style.setProperty("--menu-edge-top",o?U("top"):"none"),e.style.setProperty("--menu-edge-bottom",a?U("bottom"):"none")};r(),e.addEventListener("scroll",r,{passive:!0});const n=typeof ResizeObserver>"u"?null:new ResizeObserver(r);return n?.observe(e),()=>{e.removeEventListener("scroll",r),n?.disconnect()}},[e])}function Q(e,r){const[n,o]=e.split("-"),a=r?"right":"left",t=r?"left":"right";return n==="top"||n==="bottom"?`${n==="bottom"?"top":"bottom"} ${o==="end"?t:o==="start"?a:"center"}`:`${o==="end"?"bottom":"top"} ${n==="right"?"left":"right"}`}const Z=E.cn("rst:font-ui",he.POPUP_PANEL,"rst:w-max rst:min-w-48 rst:max-w-[min(20rem,calc(100vw-1rem))] rst:overflow-y-auto rst:overscroll-contain rst:custom-scrollbar","rst:[--menu-edge:rgb(0_0_0/0.18)] rst:dark:[--menu-edge:rgb(0_0_0/0.6)]","rst:transition-[opacity,scale] rst:duration-100 rst:ease-out rst:data-closed:opacity-0 rst:data-closed:scale-95 rst:data-leaving:duration-75 rst:data-leaving:ease-in rst:data-closed:pointer-events-none rst:motion-reduce:transition-none");function ee(e){const[r,n]=i.useState(e),[o,a]=i.useState(!0);return i.useLayoutEffect(()=>{if(e){n(!0);const s=requestAnimationFrame(()=>a(!1));return()=>cancelAnimationFrame(s)}a(!0);const t=window.matchMedia?.("(prefers-reduced-motion: reduce)").matches,d=window.setTimeout(()=>n(!1),t?0:Ie);return()=>window.clearTimeout(d)},[e]),{mounted:r,closed:o,leaving:r&&!e}}function te(e,r,n,o,a,t=!1){const[d,s]=i.useState(null),u=A.useFloating({open:r,strategy:"fixed",transform:!1,placement:n,elements:{reference:e},whileElementsMounted:ye.autoUpdate,middleware:[A.offset(o),A.flip({padding:8}),A.shift({padding:8,crossAxis:t}),A.size({padding:8,apply({availableHeight:f,elements:l}){l.floating.style.maxHeight=`min(var(--anchor-max-height, 100vh), ${Math.max(f,96)}px)`}})]}),{setFloating:p}=u.refs,m=i.useCallback(f=>{a.current=f,s(f),p(f)},[a,p]);return Pe(d),{...u,setPanel:m,panelEl:d}}const re=500;function ne(){const e=i.useRef({text:"",at:0}),r=i.useCallback(()=>e.current.text!==""&&performance.now()-e.current.at<=re,[]);return{typedRef:e,typingAhead:r}}function oe({panelRef:e,typedRef:r,onEscape:n,onBack:o}){const a=R("MenuItems");return t=>{const d=e.current;if(!d||!d.contains(t.target)||(!t.ctrlKey&&!t.metaKey&&!t.altKey&&t.stopPropagation(),t.defaultPrevented))return;const s=L(d),u=s.indexOf(document.activeElement),p=$(d);switch(t.key){case"ArrowDown":t.preventDefault(),t.stopPropagation(),S(s[(u+1)%s.length]);return;case"ArrowUp":t.preventDefault(),t.stopPropagation(),S(s[u<=0?s.length-1:u-1]);return;case"Home":case"PageUp":t.preventDefault(),t.stopPropagation(),S(s[0]);return;case"End":case"PageDown":t.preventDefault(),t.stopPropagation(),S(s[s.length-1]);return;case"Escape":t.preventDefault(),t.stopPropagation(),n();return;case"Tab":{t.preventDefault(),t.stopPropagation();const m=a.triggerRef.current;a.close(!1),m&&Se(m,t.shiftKey);return}case"ArrowLeft":case"ArrowRight":o&&t.key===(p?"ArrowRight":"ArrowLeft")&&(t.preventDefault(),t.stopPropagation(),o());return}if(t.key.length===1&&!t.ctrlKey&&!t.metaKey&&!t.altKey){const m=performance.now(),f=r.current.text!==""&&m-r.current.at<=re;if(t.key===" "&&!f)return;t.preventDefault(),r.current={text:f?r.current.text+t.key:t.key,at:m};const l=s.map(w=>w.dataset.menuText??w.textContent??""),b=xe.nextByTypeahead(l,u,r.current.text);b!==-1&&S(s[b])}}}function Te({children:e,open:r,onOpenChange:n,linkComponent:o=we}){const[a,t]=i.useState(!1),d=r??a,s=i.useId(),u=i.useRef(null),[p,m]=i.useState(null),f=i.useCallback(g=>{u.current=g,m(g)},[]),l=i.useRef("panel"),b=i.useCallback(g=>{r===void 0&&t(g),n?.(g)},[r,n]),w=i.useMemo(()=>({treeId:s,open:d,openWith:g=>{l.current=g,b(!0)},close:g=>{b(!1),g&&u.current?.focus()},triggerRef:u,triggerEl:p,registerTrigger:f,triggerId:`${s}-button`,panelId:`${s}-menu`,focusOnOpen:l,linkComponent:o}),[s,d,b,o,p,f]);return i.useEffect(()=>{if(!d)return;je();const g=I=>{I.target?.closest?.(`[data-menu-tree="${s}"]`)||(b(!1),requestAnimationFrame(()=>{(document.activeElement===document.body||!document.activeElement)&&u.current?.focus({preventScroll:!0})}))};return document.addEventListener("pointerdown",g,!0),()=>document.removeEventListener("pointerdown",g,!0)},[d,s,b]),c.jsx(G.Provider,{value:w,children:e})}const Re=i.forwardRef(function({plain:r=!1,className:n,onClick:o,onKeyDown:a,children:t,...d},s){const{variant:u,colorScheme:p,size:m,isLoading:f,loadingLabel:l,startIcon:b,endIcon:w,surface:g,...I}=d,h=R("MenuButton"),{registerTrigger:M}=h,j=i.useCallback(x=>{M(x),typeof s=="function"?s(x):s&&(s.current=x)},[M,s]),P={id:h.triggerId,"aria-haspopup":"menu","aria-expanded":h.open,"aria-controls":h.open?h.panelId:void 0,"data-menu-tree":h.treeId,onClick:x=>{o?.(x),!x.defaultPrevented&&(h.open?h.close(!1):h.openWith("panel"))},onKeyDown:x=>{if(a?.(x),x.defaultPrevented)return;const y=x.key==="Enter"||x.key===" "||x.key==="ArrowDown"?"first":x.key==="ArrowUp"?"last":null;if(!y)return;x.preventDefault();const k=h.open?document.getElementById(h.panelId):null;if(k){const C=L(k);S(y==="last"?C[C.length-1]:C[0]);return}h.openWith(y)}};return r?c.jsx("button",{ref:j,type:"button",className:n,...I,...P,children:t}):c.jsx(be.Button,{ref:j,className:E.cn("rst:min-h-11 rst:min-w-11",n),variant:u,colorScheme:p,size:m,isLoading:f,loadingLabel:l,startIcon:b,endIcon:w,surface:g,...I,...P,children:t})});function Ce({children:e,align:r="start",offset:n=4,className:o,...a}){const t=R("MenuItems"),{mounted:d,closed:s,leaving:u}=ee(t.open),p=i.useRef(null),m=$(t.triggerEl),{setPanel:f,panelEl:l,floatingStyles:b,placement:w,isPositioned:g}=te(t.triggerEl,d,`bottom-${r}`,n,p),I=se(),{typedRef:h,typingAhead:M}=ne(),j=oe({panelRef:p,typedRef:h,onEscape:()=>t.close(!0)});i.useLayoutEffect(()=>{if(!t.open||!l)return;const y=L(l),k=t.focusOnOpen.current;k==="first"&&y[0]?S(y[0]):k==="last"&&y.length?S(y[y.length-1]):l.focus({preventScroll:!0})},[t.open,l,t.focusOnOpen]),i.useLayoutEffect(()=>{if(!g||!l)return;const y=document.activeElement;y&&y!==l&&l.contains(y)&&y.scrollIntoView?.({block:"nearest"})},[g,l]),i.useLayoutEffect(()=>{!t.open&&l?.contains(document.activeElement)&&t.triggerRef.current?.focus({preventScroll:!0})},[t.open,l,t.triggerRef]);const P=y=>{const k=y.relatedTarget;k&&!k.closest(`[data-menu-tree="${t.treeId}"]`)&&t.close(!1)};if(!d)return null;const x=!!t.triggerEl?.closest(".dark");return c.jsx(W.Portal,{children:c.jsx(_.Provider,{value:{...I,panelRef:p,typingAhead:M},children:c.jsx("div",{ref:f,id:t.panelId,dir:m?"rtl":"ltr",role:"menu","aria-labelledby":a["aria-label"]?void 0:t.triggerId,"aria-label":a["aria-label"],tabIndex:-1,"data-menu-panel":"","data-menu-tree":t.treeId,"data-closed":s?"":void 0,"data-leaving":u?"":void 0,onKeyDown:j,onBlur:P,style:{...b,...J,transformOrigin:Q(w,m)},className:E.cn(x&&"dark",Z,o),children:e})})})}function se(){const[e,r]=i.useState(null),n=i.useRef(!1),o=i.useRef(void 0);return i.useEffect(()=>()=>window.clearTimeout(o.current),[]),{openSubmenu:e,focusFirstInSubmenu:n,setOpenSubmenu:(a,t=!1)=>{window.clearTimeout(o.current),n.current=t,r(a)},hoverItem:a=>{window.clearTimeout(o.current),a===null&&(o.current=window.setTimeout(()=>r(null),Y))}}}const O=E.cn("rst:relative rst:flex rst:w-full rst:min-h-11 rst:items-center rst:gap-2.5 rst:border-0 rst:bg-transparent rst:px-3 rst:py-2 rst:text-start rst:text-sm rst:text-inherit rst:no-underline rst:[font-family:inherit] rst:cursor-pointer rst:select-none rst:outline-none rst:transition-colors","rst:focus:bg-primary-100 rst:focus:text-primary-900 rst:dark:focus:bg-primary-900/30 rst:dark:focus:text-primary-100 rst:forced-colors:focus:outline-solid rst:forced-colors:focus:outline-2 rst:forced-colors:focus:-outline-offset-2","rst:aria-disabled:opacity-50 rst:aria-disabled:cursor-not-allowed"),q="rst:text-error-600 rst:dark:text-error-400 rst:focus:bg-error-50 rst:focus:text-error-700 rst:dark:focus:bg-error-900/30 rst:dark:focus:text-error-300",Ae=()=>c.jsx("svg",{viewBox:"0 0 16 16",width:"16",height:"16",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:c.jsx("path",{d:"M3.5 8.5 6.5 11.5 12.5 4.5"})}),De=()=>c.jsx("svg",{viewBox:"0 0 16 16",width:"16",height:"16","aria-hidden":"true",children:c.jsx("circle",{cx:"8",cy:"8",r:"3.5",fill:"currentColor"})}),Le=()=>c.jsx("svg",{viewBox:"0 0 16 16",width:"16",height:"16",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",className:"rst:rtl:rotate-180",children:c.jsx("path",{d:"M6 3.5 10.5 8 6 12.5"})});function T({icon:e,shortcut:r,description:n,badge:o,children:a},t,d,s){const u=t??e;return c.jsxs(c.Fragment,{children:[u!=null&&c.jsx("span",{"aria-hidden":"true",className:E.cn("rst:flex rst:size-4 rst:shrink-0 rst:items-center rst:justify-center",n!=null&&"rst:self-start rst:mt-0.5"),"data-menu-lead":"",children:u}),c.jsxs("span",{className:"rst:min-w-0 rst:flex-1 rst:break-words","data-menu-label":"",children:[a,n!=null&&c.jsx("span",{id:s,"aria-hidden":"true",className:"rst:block rst:text-xs rst:opacity-75","data-menu-description":"",children:n})]}),o!=null&&c.jsx("span",{className:"rst:flex rst:shrink-0 rst:items-center","data-menu-badge":"",children:o}),r&&c.jsx("span",{"aria-hidden":"true",className:"rst:ms-auto rst:shrink-0 rst:ps-4 rst:text-xs rst:tracking-wide rst:opacity-70","data-menu-shortcut":"",children:r}),d]})}function z({disabled:e,closeOnSelect:r,onChoose:n,spaceKeepsOpen:o}){const a=R("MenuItem"),t=K("MenuItem"),d=(s,u)=>{if(e){s.preventDefault();return}n(s),u&&a.close(!0)};return{onClick:s=>d(s,r),onKeyDown:s=>{if(s.key===" "){if(t.typingAhead())return;s.preventDefault(),d(s,r&&!o)}},onPointerMove:s=>{X(s)&&(t.hoverItem(null),document.activeElement!==s.currentTarget&&s.currentTarget.focus({preventScroll:!0}))}}}function Oe({onSelect:e,href:r,closeOnSelect:n=!0,disabled:o,destructive:a,keyshortcuts:t,textValue:d,className:s,...u}){const p=R("MenuItem"),m=K("MenuItem"),f=i.useId(),l=z({disabled:o,closeOnSelect:n,onChoose:g=>e?.(g)}),b=E.cn(O,a&&q,s),w={role:"menuitem",tabIndex:-1,"aria-disabled":o?!0:void 0,"aria-keyshortcuts":t,"aria-describedby":u.description!=null?f:void 0,"data-menu-item":"","data-menu-text":d,"data-destructive":a?"":void 0};if(r!==void 0){const g=p.linkComponent;return c.jsx(g,{href:r,to:r,className:b,...w,onClick:l.onClick,onPointerMove:l.onPointerMove,onKeyDown:I=>{if(I.key===" "){if(m.typingAhead())return;I.preventDefault(),o||I.currentTarget.click()}},children:T(u,void 0,void 0,f)})}return c.jsx("button",{type:"button",className:b,...w,...l,children:T(u,void 0,void 0,f)})}function Ne({checked:e,onCheckedChange:r,indicator:n,closeOnSelect:o=!0,disabled:a,destructive:t,keyshortcuts:d,textValue:s,className:u,...p}){const m=z({disabled:a,closeOnSelect:o,spaceKeepsOpen:!0,onChoose:()=>r(!e)}),f=i.useId();return c.jsx("button",{type:"button",role:"menuitemcheckbox","aria-checked":e,"aria-describedby":p.description!=null?f:void 0,tabIndex:-1,"aria-disabled":a||void 0,"aria-keyshortcuts":d,"data-menu-item":"","data-menu-text":s,className:E.cn(O,t&&q,u),...m,children:n===void 0?T(p,c.jsx("span",{className:e?void 0:"rst:invisible","data-menu-check":"",children:c.jsx(Ae,{})}),void 0,f):T(p,void 0,c.jsx("span",{"aria-hidden":"true",className:"rst:ms-auto rst:flex rst:shrink-0 rst:items-center",children:n}),f)})}function Be({value:e,onValueChange:r,label:n,children:o,className:a}){return c.jsx(V.Provider,{value:{value:e,onValueChange:r},children:c.jsx(ae,{label:n,className:a,children:o})})}function _e({value:e,closeOnSelect:r=!0,disabled:n,destructive:o,keyshortcuts:a,textValue:t,className:d,...s}){const u=i.useContext(V);if(!u)throw new Error("<MenuRadioItem> must be inside a <MenuRadioGroup>.");const p=u.value===e,m=z({disabled:n,closeOnSelect:r,spaceKeepsOpen:!0,onChoose:()=>u.onValueChange?.(e)}),f=i.useId();return c.jsx("button",{type:"button",role:"menuitemradio","aria-checked":p,"aria-describedby":s.description!=null?f:void 0,tabIndex:-1,"aria-disabled":n||void 0,"aria-keyshortcuts":a,"data-menu-item":"","data-menu-text":t,className:E.cn(O,o&&q,d),...m,children:T(s,c.jsx("span",{className:p?void 0:"rst:invisible","data-menu-check":"",children:c.jsx(De,{})}),void 0,f)})}function ae({label:e,children:r,className:n}){const o=i.useId();return c.jsxs("div",{role:"group","aria-labelledby":e?o:void 0,className:n,children:[e&&c.jsx("div",{id:o,className:"rst:px-3 rst:pt-2 rst:pb-1 rst:text-xs rst:font-semibold rst:text-gray-600 rst:dark:text-gray-400","data-menu-heading":"",children:e}),r]})}function Ke({className:e}){return c.jsx("div",{role:"separator",className:E.cn("rst:my-1 rst:h-[var(--roster-border-width,1px)] rst:bg-[var(--roster-popover-border)]",e)})}function $e({label:e,children:r,icon:n,disabled:o,textValue:a,className:t,panelClassName:d}){const s=R("MenuSubmenu"),u=K("MenuSubmenu"),p=i.useId(),m=`${p}-item`,f=`${p}-menu`,l=u.openSubmenu===m,b=i.useRef(null),[w,g]=i.useState(null),I=i.useCallback(v=>{b.current=v,g(v)},[]),h=i.useRef(null),M=i.useRef(void 0),j=i.useRef("mouse"),{mounted:P,closed:x,leaving:y}=ee(l),k=$(w),{setPanel:C,panelEl:N,floatingStyles:ie,placement:ue}=te(w,P,k?"left-start":"right-start",{mainAxis:0,alignmentAxis:-4},h,!0),ce=se();i.useEffect(()=>()=>window.clearTimeout(M.current),[]);const F=()=>{u.setOpenSubmenu(null),b.current?.focus({preventScroll:!0})},{typedRef:le,typingAhead:de}=ne(),fe=oe({panelRef:h,typedRef:le,onEscape:F,onBack:F});i.useLayoutEffect(()=>{!l||!N||u.focusFirstInSubmenu.current&&S(L(N)[0])},[l,N,u.focusFirstInSubmenu]);const B=v=>{if(!o){if(l&&v&&h.current){S(L(h.current)[0]);return}u.setOpenSubmenu(m,v)}},me=!!s.triggerEl?.closest(".dark");return c.jsxs(c.Fragment,{children:[c.jsx("button",{ref:I,id:m,type:"button",role:"menuitem",tabIndex:-1,"aria-haspopup":"menu","aria-expanded":l,"aria-controls":l?f:void 0,"aria-disabled":o||void 0,"data-menu-item":"","data-menu-text":a,"data-menu-tree":s.treeId,className:E.cn(O,l&&"rst:bg-gray-100 rst:dark:bg-gray-700/50",t),onPointerDown:v=>{j.current=v.pointerType},onClick:()=>l&&j.current!=="mouse"?u.setOpenSubmenu(null):B(!1),onKeyDown:v=>{const pe=k?"ArrowLeft":"ArrowRight";v.key===" "&&u.typingAhead()||(v.key===pe||v.key==="Enter"||v.key===" ")&&(v.preventDefault(),B(!0))},onPointerMove:v=>{X(v)&&(u.hoverItem(m),document.activeElement!==v.currentTarget&&v.currentTarget.focus({preventScroll:!0}),!l&&!o&&(window.clearTimeout(M.current),M.current=window.setTimeout(()=>B(!1),Y)))},onPointerLeave:()=>window.clearTimeout(M.current),children:T({icon:n,children:e},void 0,c.jsx("span",{"aria-hidden":"true",className:"rst:ms-auto rst:flex rst:shrink-0 rst:items-center rst:opacity-70","data-menu-chevron":"",children:c.jsx(Le,{})}))}),P&&c.jsx(W.Portal,{children:c.jsx(_.Provider,{value:{...ce,panelRef:h,typingAhead:de},children:c.jsx("div",{ref:C,id:f,dir:k?"rtl":"ltr",role:"menu","aria-labelledby":m,tabIndex:-1,"data-menu-panel":"","data-menu-tree":s.treeId,"data-closed":x?"":void 0,"data-leaving":y?"":void 0,onKeyDown:fe,onPointerEnter:()=>u.hoverItem(m),style:{...ie,...J,transformOrigin:Q(ue,k)},className:E.cn(me&&"dark",Z,d),children:r})})})]})}exports.Menu=Te;exports.MenuButton=Re;exports.MenuCheckboxItem=Ne;exports.MenuGroup=ae;exports.MenuItem=Oe;exports.MenuItems=Ce;exports.MenuRadioGroup=Be;exports.MenuRadioItem=_e;exports.MenuSeparator=Ke;exports.MenuSubmenu=$e;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { ButtonProps } from '../../atoms/Button/Button';
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
/**
|
|
4
|
+
* The props every link item is rendered with. `href` and `to` carry the same
|
|
5
|
+
* value, so `next/link`, React Router's `Link` and a plain `<a>` all work
|
|
6
|
+
* without a wrapper. The rest must reach the DOM: the role, the tab index and
|
|
7
|
+
* the handlers are what make the link an item of the menu.
|
|
8
|
+
*/
|
|
9
|
+
export interface MenuLinkProps {
|
|
10
|
+
href: string;
|
|
11
|
+
to: string;
|
|
12
|
+
className: string;
|
|
13
|
+
children: React.ReactNode;
|
|
14
|
+
role: "menuitem";
|
|
15
|
+
tabIndex: -1;
|
|
16
|
+
"aria-disabled"?: true;
|
|
17
|
+
"aria-keyshortcuts"?: string;
|
|
18
|
+
"aria-describedby"?: string;
|
|
19
|
+
"data-menu-item": "";
|
|
20
|
+
onClick: (event: React.MouseEvent<HTMLAnchorElement>) => void;
|
|
21
|
+
onKeyDown: (event: React.KeyboardEvent<HTMLAnchorElement>) => void;
|
|
22
|
+
onPointerMove: (event: React.PointerEvent<HTMLAnchorElement>) => void;
|
|
23
|
+
}
|
|
24
|
+
export interface MenuProps {
|
|
25
|
+
/** The trigger (`MenuButton`) and the panel (`MenuItems`). */
|
|
26
|
+
children: React.ReactNode;
|
|
27
|
+
/**
|
|
28
|
+
* Controlled open state. Leave both off to let the menu keep its own. Pass
|
|
29
|
+
* `onOpenChange` with `open`: every way the menu closes itself (Escape,
|
|
30
|
+
* Tab, a press outside, a choice) is a call to it.
|
|
31
|
+
*/
|
|
32
|
+
open?: boolean;
|
|
33
|
+
onOpenChange?: (open: boolean) => void;
|
|
34
|
+
/**
|
|
35
|
+
* Renders every link item (a `MenuItem` with an `href`). Defaults to a plain
|
|
36
|
+
* `<a>`, which inside a router turns each choice into a full page load: pass
|
|
37
|
+
* `next/link` or your router's link, from a client component.
|
|
38
|
+
*/
|
|
39
|
+
linkComponent?: React.ComponentType<MenuLinkProps>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A button that opens a panel of actions: the menu button pattern. Compose it:
|
|
43
|
+
*
|
|
44
|
+
* ```tsx
|
|
45
|
+
* <Menu>
|
|
46
|
+
* <MenuButton>Actions</MenuButton>
|
|
47
|
+
* <MenuItems>
|
|
48
|
+
* <MenuItem icon={<EditIcon />} shortcut="⌘E" onSelect={edit}>Edit</MenuItem>
|
|
49
|
+
* <MenuSeparator />
|
|
50
|
+
* <MenuItem destructive onSelect={remove}>Delete</MenuItem>
|
|
51
|
+
* </MenuItems>
|
|
52
|
+
* </Menu>
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* The keyboard follows the pattern: Enter, Space or Down open it on the first
|
|
56
|
+
* item and Up on the last; arrows move, Home and End jump, a typed letter
|
|
57
|
+
* jumps to the next item starting with it; Escape closes it and puts focus
|
|
58
|
+
* back on the button; Tab closes it and moves on. A submenu opens with the
|
|
59
|
+
* arrow away from the parent and closes with the arrow back.
|
|
60
|
+
*/
|
|
61
|
+
declare function Menu({ children, open: openProp, onOpenChange, linkComponent }: MenuProps): import("react/jsx-runtime").JSX.Element;
|
|
62
|
+
export interface MenuButtonProps extends ButtonProps {
|
|
63
|
+
/**
|
|
64
|
+
* A plain `<button>` with only your `className`, for a trigger drawn its own
|
|
65
|
+
* way: an avatar, an icon. Keep its target at least 44 by 44, with
|
|
66
|
+
* padding or a hit area, if you draw it smaller.
|
|
67
|
+
*/
|
|
68
|
+
plain?: boolean;
|
|
69
|
+
}
|
|
70
|
+
declare const MenuButton: React.ForwardRefExoticComponent<MenuButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
71
|
+
export interface MenuItemsProps {
|
|
72
|
+
children: React.ReactNode;
|
|
73
|
+
/** Which edge of the button the panel lines up with. */
|
|
74
|
+
align?: "start" | "end";
|
|
75
|
+
/** The gap between the button and the panel, in px. */
|
|
76
|
+
offset?: number;
|
|
77
|
+
/** Names the menu when the button's own name shouldn't. By default the button names it. */
|
|
78
|
+
"aria-label"?: string;
|
|
79
|
+
/** Applied to the panel. Its surface reads `--roster-popover-*`; set those to repaint it. */
|
|
80
|
+
className?: string;
|
|
81
|
+
}
|
|
82
|
+
declare function MenuItems({ children, align, offset, className, ...aria }: MenuItemsProps): import("react/jsx-runtime").JSX.Element | null;
|
|
83
|
+
interface ItemContent {
|
|
84
|
+
/** A leading icon. Decorative: the item's words name it. */
|
|
85
|
+
icon?: React.ReactNode;
|
|
86
|
+
/** A second, quieter line under the label: what the item does, or to what. Read as the item's description. */
|
|
87
|
+
description?: React.ReactNode;
|
|
88
|
+
/** A count or a status at the end of the row, read with the item's name. */
|
|
89
|
+
badge?: React.ReactNode;
|
|
90
|
+
/** A keyboard shortcut to show, right-aligned: display only. The app handles the keys. */
|
|
91
|
+
shortcut?: string;
|
|
92
|
+
/** The same shortcut in `aria-keyshortcuts` form ("Control+E"), for assistive technology. */
|
|
93
|
+
keyshortcuts?: string;
|
|
94
|
+
/** Reads as a consequence: red. The words still have to say what it does. */
|
|
95
|
+
destructive?: boolean;
|
|
96
|
+
/** Can be reached by the arrows but not chosen. */
|
|
97
|
+
disabled?: boolean;
|
|
98
|
+
/** What typeahead matches, when the item's text isn't the right thing to match. */
|
|
99
|
+
textValue?: string;
|
|
100
|
+
className?: string;
|
|
101
|
+
children: React.ReactNode;
|
|
102
|
+
}
|
|
103
|
+
export interface MenuItemProps extends ItemContent {
|
|
104
|
+
/** Called when the item is chosen: a click, Enter or Space. */
|
|
105
|
+
onSelect?: (event: React.SyntheticEvent) => void;
|
|
106
|
+
/** Makes it a link item. It navigates through the menu's `linkComponent`. */
|
|
107
|
+
href?: string;
|
|
108
|
+
/** Close the menu once chosen. On by default. */
|
|
109
|
+
closeOnSelect?: boolean;
|
|
110
|
+
}
|
|
111
|
+
/** One action. With `href`, a link. */
|
|
112
|
+
declare function MenuItem({ onSelect, href, closeOnSelect, disabled, destructive, keyshortcuts, textValue, className, ...content }: MenuItemProps): import("react/jsx-runtime").JSX.Element;
|
|
113
|
+
export interface MenuCheckboxItemProps extends ItemContent {
|
|
114
|
+
checked: boolean;
|
|
115
|
+
onCheckedChange: (checked: boolean) => void;
|
|
116
|
+
/**
|
|
117
|
+
* Replaces the leading check mark with an indicator of your own at the end
|
|
118
|
+
* of the row: a switch's track, say. Its state still reaches assistive
|
|
119
|
+
* technology through `aria-checked`.
|
|
120
|
+
*/
|
|
121
|
+
indicator?: React.ReactNode;
|
|
122
|
+
/** Close the menu once chosen by click or Enter. Space always keeps it open. */
|
|
123
|
+
closeOnSelect?: boolean;
|
|
124
|
+
}
|
|
125
|
+
/** An on/off choice: `menuitemcheckbox`. */
|
|
126
|
+
declare function MenuCheckboxItem({ checked, onCheckedChange, indicator, closeOnSelect, disabled, destructive, keyshortcuts, textValue, className, ...content }: MenuCheckboxItemProps): import("react/jsx-runtime").JSX.Element;
|
|
127
|
+
export interface MenuRadioGroupProps {
|
|
128
|
+
value: string | undefined;
|
|
129
|
+
onValueChange: (value: string) => void;
|
|
130
|
+
/** The choice's name, shown above its items and read with them. */
|
|
131
|
+
label?: React.ReactNode;
|
|
132
|
+
children: React.ReactNode;
|
|
133
|
+
className?: string;
|
|
134
|
+
}
|
|
135
|
+
/** One choice among several: its items are `menuitemradio`. */
|
|
136
|
+
declare function MenuRadioGroup({ value, onValueChange, label, children, className }: MenuRadioGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
137
|
+
export interface MenuRadioItemProps extends ItemContent {
|
|
138
|
+
value: string;
|
|
139
|
+
/** Close the menu once chosen by click or Enter. Space always keeps it open. */
|
|
140
|
+
closeOnSelect?: boolean;
|
|
141
|
+
}
|
|
142
|
+
declare function MenuRadioItem({ value, closeOnSelect, disabled, destructive, keyshortcuts, textValue, className, ...content }: MenuRadioItemProps): import("react/jsx-runtime").JSX.Element;
|
|
143
|
+
export interface MenuGroupProps {
|
|
144
|
+
/** Shown above the group's items, and names the group. */
|
|
145
|
+
label?: React.ReactNode;
|
|
146
|
+
children: React.ReactNode;
|
|
147
|
+
className?: string;
|
|
148
|
+
}
|
|
149
|
+
/** Items that belong together, under an optional label. */
|
|
150
|
+
declare function MenuGroup({ label, children, className }: MenuGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
151
|
+
/** A rule between groups of items. */
|
|
152
|
+
declare function MenuSeparator({ className }: {
|
|
153
|
+
className?: string;
|
|
154
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
155
|
+
export interface MenuSubmenuProps extends Omit<ItemContent, "shortcut" | "keyshortcuts" | "children" | "destructive" | "description" | "badge"> {
|
|
156
|
+
/** The item that opens it. */
|
|
157
|
+
label: React.ReactNode;
|
|
158
|
+
/** Its items. */
|
|
159
|
+
children: React.ReactNode;
|
|
160
|
+
/** Applied to the submenu's panel. */
|
|
161
|
+
panelClassName?: string;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* An item that opens a menu of its own beside it. It opens with the arrow away
|
|
165
|
+
* from its parent, Enter, Space, a click, or the pointer resting on it; the
|
|
166
|
+
* arrow back, or Escape, closes it and returns to its item.
|
|
167
|
+
*/
|
|
168
|
+
declare function MenuSubmenu({ label, children, icon, disabled, textValue, className, panelClassName }: MenuSubmenuProps): import("react/jsx-runtime").JSX.Element;
|
|
169
|
+
export { Menu, MenuButton, MenuItems, MenuItem, MenuCheckboxItem, MenuRadioGroup, MenuRadioItem, MenuGroup, MenuSeparator, MenuSubmenu, };
|