use-chisel 0.1.9 → 0.1.11

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.
@@ -1,6 +1,6 @@
1
- "use client";import{forwardRef as Ge,createElement as We}from"react";var ce=e=>e?.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase();function ne(e,a,o=[]){if(a==null)throw new Error("[lucide]: iconNode is required when icon name is used");return{name:ce(e),size:24,node:a,...o.length>0?{aliases:o}:{}}}var pe=e=>{let a="",o=!1;for(let t of e){if(t==="-"||t==="_"||t<=" "){o=a.length>0;continue}a.length===0?a+=t.toLowerCase():a+=o?t.toUpperCase():t,o=!1}return a};var me=e=>{let a=pe(e);return a.charAt(0).toUpperCase()+a.slice(1)};import{forwardRef as Ee,createElement as he}from"react";var O=(...e)=>e.filter((a,o,t)=>!!a&&a.trim()!==""&&t.indexOf(a)===o).join(" ").trim();var F={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round"};function te(e){return e!=null}function Le(e,a={}){let o=a.attributeNames??{},t=d=>o[d]??d,l=e.size??e.width??F.width,u=e.size??e.height??F.height,f=e.aliases?.filter(d=>typeof d=="string"&&d.trim()!=="").map(d=>`lucide-${d}`)??[],c=[...e.name?[`lucide-${e.name}`]:[],...f],i=a.className?.split(" ").filter(Boolean)??[],p=a.includeDefaultClasses===!1?O(...i):O("lucide",...c,...i),r=a.absoluteStrokeWidth?Number(a.strokeWidth??F["stroke-width"])*Number(e.size??e.width??F.width)/Number(a.size??a.width??F.width):a.strokeWidth??F["stroke-width"];return["svg",{...Object.entries(F).reduce((d,[s,m])=>(d[t(s)]=m,d),{}),..."color"in a&&a.color&&{[t("stroke")]:a.color},..."size"in a&&te(a.size)&&{[t("width")]:a.size,[t("height")]:a.size},..."width"in a&&te(a.width)&&{[t("width")]:a.width},..."height"in a&&te(a.height)&&{[t("height")]:a.height},[t("stroke-width")]:r,...p&&{[t("class")]:p},[t("viewBox")]:`0 0 ${l} ${u}`,...a.hasA11yProp===!1?{[t("aria-hidden")]:"true"}:{},..."attributes"in a&&a.attributes},e.node.map(d=>{let[s,m,x]=d,C=a.nonScalingStroke?{[t("vector-effect")]:"non-scaling-stroke",...m}:m;return x?[s,C,x]:[s,C]})]}function Ie(e,a={}){return Le(e,{...a,attributeNames:{...a.attributeNames,class:"className","stroke-width":"strokeWidth","stroke-linecap":"strokeLinecap","stroke-linejoin":"strokeLinejoin","vector-effect":"vectorEffect"}})}var xe=e=>{for(let a in e)if(a.startsWith("aria-")||a==="role"||a==="title")return!0;return!1};import{createContext as Ue,useContext as Oe,useMemo as Ta,createElement as qa}from"react";var He=Ue({});var Ce=()=>Oe(He);var ge=Ee(({color:e,size:a,width:o,height:t,strokeWidth:l,absoluteStrokeWidth:u,nonScalingStroke:f,className:c="",children:i,iconNode:p=[],icon:r={node:p,aliases:[],size:24},...I},d)=>{let{size:s=24,strokeWidth:m=2,absoluteStrokeWidth:x=!1,nonScalingStroke:C=!1,color:R="currentColor",className:_=""}=Ce()??{},X=!!i||xe(I),[j,Y,L=[]]=Ie(r,{color:e??R,width:o??a??s,height:t??a??s,strokeWidth:l??m,absoluteStrokeWidth:u??x,nonScalingStroke:f??C,className:O(_,c),hasA11yProp:X,attributes:I});return he(j,{ref:d,...Y},[...L.map(([g,D])=>he(g,D)),...Array.isArray(i)?i:[i]])});function P(e,a=[],o=[]){let t=typeof e=="string"?ne(e,a,o):e,l=Ge(({className:u,...f},c)=>We(ge,{ref:c,icon:t,className:u,...f}));return t.name&&(l.displayName=me(t.name)),l}var Ve={name:"arrow-up",size:24,node:[["path",{d:"m5 12 7-7 7 7",key:"hav0vg"}],["path",{d:"M12 19V5",key:"x0mq9r"}]]},H=P(Ve);var ze={name:"paperclip",size:24,node:[["path",{d:"m16 6-8.414 8.586a2 2 0 0 0 2.829 2.829l8.414-8.586a4 4 0 1 0-5.657-5.657l-8.379 8.551a6 6 0 1 0 8.485 8.485l8.379-8.551",key:"1miecu"}]]},E=P(ze);var Ne={name:"pencil",size:24,node:[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]]},G=P(Ne);var Xe={name:"play",size:24,node:[["path",{d:"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",key:"10ikf1"}]]},W=P(Xe);var Ke={name:"rotate-cw",size:24,node:[["path",{d:"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8",key:"1p45f6"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}]]},V=P(Ke);var Ze={name:"x",size:24,node:[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]},v=P(Ze);import{useEffect as U,useRef as B,useState as N}from"react";function A(e){return{version:1,content:e.split(`
2
- `).map(a=>({type:"paragraph",children:[{text:a}]}))}}function Se(e){return e.content.map(a=>a.children.map(o=>"type"in o?o.text||o.url:o.text).join("")).join(`
3
- `)}function K(e){let a=e.content.slice();for(;a.length;){let o=a[a.length-1],t=o.children.slice();for(;t.length;){let l=t[t.length-1],u="type"in l?l.text||l.url:l.text,f=u.trimEnd();if(f)return t[t.length-1]=f===u?l:{...l,text:f},a[a.length-1]={...o,children:t},{...e,content:a};t.pop()}a.pop()}return A("")}function oe(e,a,o){let t=e;for(let l of[...a].sort((u,f)=>u-f))if(!(l<=t)){if(!o.has(l))break;t=l}return t}var Z=["image/jpeg","image/png","image/gif","image/webp","image/avif","image/bmp"],ke=["video/mp4","video/webm","video/quicktime"],we=[...Z,...ke].join(",");function Pe(e){let a=Z.includes(e.type);return!a&&!ke.includes(e.type)?"Choose a JPG, PNG, GIF, WebP, AVIF, BMP, MP4, WebM, or MOV file.":!Number.isSafeInteger(e.size)||e.size<=0?"This file is empty or invalid.":e.size>(a?5242880:20971520)?`${a?"Images must be 5 MB":"Videos must be 20 MB"} or smaller.`:null}import{useEffect as Je,useRef as ye,useState as Ae}from"react";import{createEditor as Qe,Editor as h,Element as q,Node as $e,Path as _e,Range as ue,Transforms as y}from"slate";import{withHistory as je}from"slate-history";import{Editable as Ye,Slate as ea,withReact as aa,ReactEditor as Be}from"slate-react";import{Fragment as Re,jsx as S,jsxs as Fe}from"react/jsx-runtime";function de(e){return e.content.length?e.content.map(a=>({type:"paragraph",children:a.children.length?a.children.map(o=>"type"in o&&o.type==="link"?{type:"link",url:o.url,children:[{text:o.text||o.url}]}:{...o}):[{text:""}]})):[{type:"paragraph",children:[{text:""}]}]}function De(e){return{version:1,content:e.map(a=>({type:"paragraph",children:q.isElement(a)?a.children.map(o=>q.isElement(o)?{type:"link",url:o.url,text:$e.string(o)}:{...o}):[{text:a.text}]}))}}function le(e){return/^(https?:\/\/|mailto:)[^\s]+$/i.test(e)}function ta(e,a){if(!e.selection){let o=window.getSelection(),t=o&&Be.toSlateRange(e,o,{exactMatch:!1,suppressThrow:!0});y.select(e,t??h.end(e,[]))}h.marks(e)?.[a]?h.removeMark(e,a):h.addMark(e,a,!0)}function Me(){let e=aa(je(Qe()),"application/x-chisel-review-fragment"),{isInline:a,insertText:o,insertData:t,insertBreak:l}=e;e.isInline=c=>c.type==="link"||a(c);function u(c,i){h.above(e,{at:c,match:p=>q.isElement(p)&&p.type==="link"})||(y.wrapNodes(e,{type:"link",url:i,children:[]},{at:c,split:!0}),y.collapse(e,{edge:"end"}))}function f(){if(!e.selection||!ue.isCollapsed(e.selection))return;let c=h.above(e,{match:d=>q.isElement(d)&&d.type==="paragraph"});if(!c)return;let i=e.selection.anchor,r=h.string(e,{anchor:h.start(e,c[1]),focus:i}).match(/\S+$/)?.[0];if(!r||!le(r))return;let I=h.before(e,i,{distance:r.length,unit:"offset"});if(I){u({anchor:I,focus:i},r);let d=h.above(e,{match:s=>q.isElement(s)&&s.type==="link"});d&&e.selection&&h.isEnd(e,e.selection.anchor,d[1])&&y.select(e,h.start(e,_e.next(d[1])))}}return e.insertText=c=>{if(Be.isComposing(e)){o(c);return}c===" "&&f();let i={"*":"bold",_:"italic","~":"strikethrough","`":"code"}[c];if(i&&e.selection&&ue.isCollapsed(e.selection)){let p=h.above(e,{match:r=>q.isElement(r)&&r.type==="paragraph"});if(p){let r=e.selection.anchor,I=h.string(e,{anchor:h.start(e,p[1]),focus:r}),d=I.lastIndexOf(c),s=I.slice(d+1);if(d>=0&&(!d||/[\s*_~`]/.test(I[d-1]))&&s&&s.trim()===s){let m=h.before(e,r,{distance:s.length,unit:"offset"}),x=m&&h.before(e,m,{unit:"offset"});if(m&&x){y.select(e,{anchor:m,focus:r}),h.addMark(e,i,!0),y.collapse(e,{edge:"end"}),y.delete(e,{at:{anchor:x,focus:m}}),h.removeMark(e,i);return}}}}o(c)},e.insertBreak=()=>{f(),l()},e.insertData=c=>{let i=c.getData("text/plain");le(i)?e.selection&&!ue.isCollapsed(e.selection)?u(e.selection,i):y.insertNodes(e,[{type:"link",url:i,children:[{text:i}]},{text:""}]):t(c)},e}function oa({attributes:e,children:a,element:o}){return o.type==="link"?S("a",{...e,href:le(o.url)?o.url:void 0,onClick:t=>t.preventDefault(),children:a}):S("p",{...e,children:a})}function ua({attributes:e,children:a,leaf:o}){let t=S(Re,{children:a});return o.bold&&(t=S("strong",{children:t})),o.italic&&(t=S("em",{children:t})),o.strikethrough&&(t=S("s",{children:t})),o.code&&(t=S("code",{children:t})),S("span",{...e,children:t})}function J({onFiles:e,disabled:a}){let o=ye(null);return Fe(Re,{children:[S("input",{ref:o,type:"file",accept:we,multiple:!0,hidden:!0,onChange:t=>{e(t.target.files),t.target.value=""}}),S("button",{type:"button",className:"review-retry-upload","aria-label":"Attach image or video",title:"Images up to 5 MB \xB7 Videos up to 20 MB",disabled:a,onClick:()=>o.current?.click(),children:S(E,{size:16,strokeWidth:1.75})})]})}function z({text:e,defaultBody:a,disabled:o,label:t,placeholder:l,autoFocus:u,onChange:f,onSubmit:c,onFiles:i,uploading:p}){let[r]=Ae(Me),[I]=Ae(()=>de(a??A(e))),d=ye(e);return Je(()=>{if(e===d.current)return;let s=d.current;d.current=e,s&&e.startsWith(s)?y.insertText(r,e.slice(s.length),{at:h.end(r,[])}):(h.withoutNormalizing(r,()=>{y.removeNodes(r,{at:[],match:(m,x)=>x.length===1}),y.insertNodes(r,de(A(e)),{at:[0]}),y.deselect(r)}),e||(r.history={undos:[],redos:[]}))},[r,e]),Fe(ea,{editor:r,initialValue:I,onChange:s=>{if(!r.operations.some(x=>x.type!=="set_selection"))return;let m=De(s);d.current=Se(m),f(d.current,m)},children:[S(Ye,{className:"review-composer-editor",role:"textbox","aria-multiline":"true","aria-label":t,placeholder:l,readOnly:o,autoFocus:u,renderElement:oa,renderLeaf:ua,onKeyDown:s=>{if(s.nativeEvent.isComposing)return;let m=s.metaKey||s.ctrlKey;if(s.key==="Enter"){s.preventDefault(),m?r.insertBreak():c();return}let x=m?{b:"bold",i:"italic",e:"code",...s.shiftKey?{s:"strikethrough"}:{}}[s.key.toLowerCase()]:void 0;x&&(s.preventDefault(),ta(r,x))}}),i&&S("div",{className:"chisel-attachment-controls",children:S(J,{onFiles:i,disabled:o||p})})]})}import{useEffect as da,useRef as la,useState as ra}from"react";import{Fragment as be,jsx as k,jsxs as Q}from"react/jsx-runtime";function sa({src:e,name:a,mimeType:o,onError:t,close:l}){let u=la(null);return da(()=>{u.current?.showModal()},[]),k("dialog",{ref:u,className:"review-media-lightbox","aria-label":`Preview ${a}`,onCancel:f=>{f.preventDefault(),l()},onClick:f=>{f.target===f.currentTarget&&l()},children:Q("div",{className:"review-media-lightbox-content",children:[Q("header",{children:[k("span",{children:a}),k("a",{href:e,download:a,"aria-label":`Download ${a}`,children:"Download"}),k("button",{type:"button","aria-label":"Close preview",onClick:l,children:k(v,{size:20})})]}),o.startsWith("image/")?k("img",{src:e,alt:a,onError:t}):k("video",{src:e,controls:!0,autoPlay:!0,playsInline:!0,"aria-label":a,onError:t})]})})}function $({src:e,name:a,mimeType:o,onError:t}){let[l,u]=ra(!1);return Q(be,{children:[k("button",{type:"button",className:"review-media-thumbnail","aria-label":`Preview ${a}`,onClick:()=>u(!0),children:o.startsWith("image/")?k("img",{src:e,alt:a,loading:"lazy",onError:t}):Q(be,{children:[k("video",{src:e,muted:!0,playsInline:!0,preload:"metadata","aria-hidden":"true",onError:t}),k("span",{className:"review-media-play","aria-hidden":"true",children:k(W,{size:20,fill:"currentColor"})})]})}),l&&k(sa,{src:e,name:a,mimeType:o,onError:t,close:()=>u(!1)})]})}import{Fragment as La,jsx as n,jsxs as M}from"react/jsx-runtime";function ve({body:e}){return n("div",{className:"review-comment-body",children:e.content.map((a,o)=>n("p",{children:a.children.map((t,l)=>{if("type"in t&&t.type==="link")return n("a",{href:/^(https?:|mailto:)/i.test(t.url)?t.url:void 0,target:"_blank",rel:"noopener noreferrer",children:t.text||t.url},l);if(!("text"in t))return null;let u=n(La,{children:t.text});return"bold"in t&&t.bold&&(u=n("strong",{children:u})),"italic"in t&&t.italic&&(u=n("em",{children:u})),"strikethrough"in t&&t.strikethrough&&(u=n("s",{children:u})),"code"in t&&t.code&&(u=n("code",{children:u})),n("span",{children:u},l)})},o))})}function fa({attachment:e,loadMedia:a}){let[o,t]=N(e.previewUrl??""),[l,u]=N(!1),[f,c]=N(0),i=B(0);U(()=>{if(e.previewUrl){t(e.previewUrl);return}t("");let r=!0,I=!1,d=new AbortController;async function s(){if(!(I||document.visibilityState==="hidden")){I=!0;try{let C=await a(e.id,d.signal);r&&(t(C),u(!1),i.current=Date.now()+240*1e3)}catch{r&&u(!0)}finally{I=!1}}}function m(){Date.now()>=i.current&&s()}s();let x=window.setInterval(m,60*1e3);return window.addEventListener("focus",m),document.addEventListener("visibilitychange",m),()=>{r=!1,d.abort(),window.clearInterval(x),window.removeEventListener("focus",m),document.removeEventListener("visibilitychange",m)}},[e.id,e.previewUrl,f,a]);function p(){u(!0),Date.now()>=i.current&&c(r=>r+1)}return M("figure",{className:"review-attachment",children:[o&&!l?n($,{src:o,name:e.name,mimeType:e.mimeType,onError:p}):n("div",{className:"review-attachment-placeholder",role:"status",children:l?n("button",{type:"button",className:"review-retry-upload",onClick:()=>c(r=>r+1),children:"Retry attachment"}):"Loading attachment\u2026"}),n("figcaption",{children:e.name})]})}function ia(e){let a=Math.max(0,Math.floor((Date.now()-Date.parse(e))/6e4));return a<1?"Just now":a<60?`${a}m`:a<1440?`${Math.floor(a/60)}h`:new Date(e).toLocaleDateString(void 0,{month:"short",day:"numeric"})}function ca({comment:e,activity:a,loadMedia:o,editable:t,editing:l,saving:u,onStartEdit:f,onCancelEdit:c,onSaveEdit:i,onDraftChange:p,onEditStyles:r}){let[I,d]=N(e.text),s=B(e.body??A(e.text)),m=B(!1);U(()=>{l||(d(e.text),s.current=e.body??A(e.text))},[l,e.text,e.body]);async function x(){if(!(u||m.current||!I.trim()&&!e.attachments?.length)){m.current=!0;try{await i(I.trimEnd(),K(s.current))&&p(!1)}finally{m.current=!1}}}return M("article",{className:"review-comment","data-activity":a,children:[n("span",{className:"review-comment-avatar",children:e.authorImage?n("img",{src:e.authorImage,alt:""}):e.author.slice(0,1).toUpperCase()}),M("div",{className:"review-comment-content",children:[M("header",{className:"review-comment-header",children:[n("span",{className:"review-comment-author",children:e.author}),e.pending?n("span",{className:"review-comment-time",role:"status",children:"Sending\u2026"}):n("time",{className:"review-comment-time",dateTime:e.date,title:new Date(e.date).toLocaleString(),children:ia(e.date)}),t&&!l&&n("button",{type:"button",className:"review-comment-edit","aria-label":"Edit comment",title:"Edit comment",disabled:u,onClick:f,children:n(G,{size:16})})]}),l?M("form",{className:"review-inline-edit",onSubmit:C=>{C.preventDefault(),x()},children:[n(z,{text:I,defaultBody:s.current,disabled:u,label:"Edit comment",placeholder:"Edit comment\u2026",autoFocus:!0,onSubmit:()=>{x()},onChange:(C,R)=>{d(C),s.current=R,p(C!==e.text||JSON.stringify(R)!==JSON.stringify(e.body??A(e.text)))}}),M("div",{className:"review-inline-edit-actions",children:[r&&n("button",{type:"button",disabled:u,onClick:r,children:"Edit styles"}),n("button",{type:"button",disabled:u,onClick:c,children:"Cancel"}),n("button",{type:"submit",disabled:u||!I.trim()&&!e.attachments?.length,children:"Save"})]})]}):n(ve,{body:e.body??A(e.text)}),e.attachments?.length>0&&n("div",{className:"review-attachments",children:e.attachments.map(C=>n(fa,{attachment:C,loadMedia:o},C.id))})]})]})}function na(e){let a=e.useAttachments(e.disabled,e.existingAttachments?.length??0),o=B(e.defaultBody??A(e.text)),t=B(!1);U(()=>(e.onAttachmentDraftChange?.(a.uploading||a.attachments.length>0),()=>e.onAttachmentDraftChange?.(!1)),[a.uploading,a.attachments.length,e.onAttachmentDraftChange]);async function l(){if(!(e.disabled||a.blocked||t.current||!e.text.trim()&&!a.attachments.length&&!e.existingAttachments?.length)){t.current=!0;try{await e.onSubmit(e.text.trimEnd(),K(o.current),a.tokens,a.previews)&&a.clear()}finally{t.current=!1}}}return n("form",{className:"review-composer chisel-review-composer","aria-label":e.commentId?"Edit comment":"New comment",onSubmit:u=>{u.preventDefault(),l()},onPasteCapture:u=>{u.clipboardData.files.length&&(u.preventDefault(),u.stopPropagation(),a.upload(u.clipboardData.files))},onDragOver:u=>{u.dataTransfer.types.includes("Files")&&u.preventDefault()},onDropCapture:u=>{u.dataTransfer.files.length&&(u.preventDefault(),u.stopPropagation(),a.upload(u.dataTransfer.files))},children:e.renderContent(M("div",{className:"chisel-composer-input",children:[n(z,{text:e.text,defaultBody:e.defaultBody,disabled:e.disabled,label:"Comment",placeholder:"Leave a comment\u2026",autoFocus:!0,onSubmit:()=>{l()},onChange:(u,f)=>{o.current=f,e.onText(u)}}),a.previewsUI,a.controls]}),a.attachments.length>0||!!e.existingAttachments?.length,a.blocked,n(J,{onFiles:a.upload,disabled:e.disabled||a.uploading}))})}function pa(e){let a=e.useAttachments(e.saving),o=B(A(e.reply)),t=B(!1);U(()=>(e.onAttachmentDraftChange?.(a.uploading||a.attachments.length>0),()=>e.onAttachmentDraftChange?.(!1)),[a.uploading,a.attachments.length,e.onAttachmentDraftChange]);async function l(){if(!(e.saving||a.blocked||t.current||!e.reply.trim()&&!a.attachments.length)){t.current=!0;try{await e.onReply(e.reply.trimEnd(),K(o.current),a.tokens,a.previews)&&(o.current=A(""),a.clear())}finally{t.current=!1}}}return M("form",{className:"review-composer chisel-review-reply","aria-label":"Reply to thread",hidden:e.submittingReply,onSubmit:u=>{u.preventDefault(),l()},onPasteCapture:u=>{u.clipboardData.files.length&&(u.preventDefault(),u.stopPropagation(),a.upload(u.clipboardData.files))},onDragOver:u=>{u.dataTransfer.types.includes("Files")&&u.preventDefault()},onDropCapture:u=>{u.dataTransfer.files.length&&(u.preventDefault(),u.stopPropagation(),a.upload(u.dataTransfer.files))},children:[n("span",{className:"feedback-avatar feedback-reply-avatar",children:e.replyAuthor?.image?n("img",{src:e.replyAuthor.image,alt:""}):(e.replyAuthor?.name||"You").slice(0,1).toUpperCase()}),M("div",{className:"chisel-reply-field",children:[n(z,{text:e.reply,disabled:e.saving,label:"Reply",placeholder:"Write a reply\u2026",onFiles:a.upload,uploading:a.uploading,onSubmit:()=>{l()},onChange:(u,f)=>{o.current=f,e.onReplyText(u)}}),a.previewsUI,a.controls,n("button",{type:"submit",className:"chisel-reply-submit","aria-label":"Reply",disabled:e.saving||a.blocked||!e.reply.trim()&&!a.attachments.length,children:n(H,{size:16,strokeWidth:1.75})})]})]})}function ma(e){let a=e.comment,[o,t]=N(null),l=B(!1),u=B(e.onEditDraftChange);u.current=e.onEditDraftChange,U(()=>()=>{u.current?.(!1)},[]);function f(d){l.current=d,e.onEditDraftChange?.(d)}async function c(d){d&&e.onBeginEdit&&!await e.onBeginEdit()||!d&&l.current&&e.onDiscardEdit&&!await e.onDiscardEdit()||(f(!1),t(d))}function i(d,s){return n(ca,{comment:d,activity:s?a.rootActivity:d.activity,loadMedia:e.loadMedia,editable:!!(e.expanded&&e.onEdit&&e.userId&&d.authorId===e.userId&&!d.pending),editing:o===d.id,saving:e.saving,onEditStyles:s?e.onEditStyles:void 0,onStartEdit:()=>{c(d.id)},onCancelEdit:()=>{c(null)},onDraftChange:f,onSaveEdit:async(m,x)=>{let C=await e.onEdit?.(s?null:d.id,m,x);return C&&(f(!1),t(null)),!!C}},d.id)}let p=B(null),r=B(new Set),I=B(a.readActivity??0);return U(()=>{if(!e.expanded||!p.current||a.pending||a.readActivity===null)return;let d=[a.rootActivity,...a.replies.map(x=>x.activity)],s=new IntersectionObserver(x=>{if(document.visibilityState!=="visible")return;for(let R of x)R.isIntersecting&&R.intersectionRatio>0&&r.current.add(Number(R.target.dataset.activity));let C=oe(Math.max(I.current,a.readActivity??0),d,r.current);C>I.current&&(I.current=C,e.onRead(a.id,C))},{threshold:0});function m(){if(s.disconnect(),document.visibilityState==="visible")for(let x of p.current?.querySelectorAll("[data-activity]")??[])s.observe(x)}return m(),document.addEventListener("visibilitychange",m),()=>{s.disconnect(),document.removeEventListener("visibilitychange",m)}},[a,e.expanded,e.onRead]),M("div",{className:"chisel-review-thread-content",children:[M("div",{ref:p,className:"review-thread",children:[i(a,!0),e.expanded&&a.replies.map(d=>i(d,!1))]}),e.expanded?!o&&n(pa,{...e}):n("button",{type:"button",className:"chisel-expand-thread",onClick:e.onExpand,children:a.replies.length?`${a.replies.length} ${a.replies.length===1?"reply":"replies"}`:"Reply\u2026"})]})}import{useCallback as Te,useRef as qe}from"react";function Ia(e,a){let o=qe(new Map),t=qe(!1),l=Te(async()=>{if(!t.current){t.current=!0;try{for(;o.current.size;){let[f,c]=o.current.entries().next().value;try{await e(f,c)}catch(i){if([400,403,404].includes(i.status??0)){o.current.delete(f);continue}throw i}o.current.get(f)===c&&o.current.delete(f),a(f,c)}}catch{}finally{t.current=!1}}},[e,a]),u=Te((f,c)=>{o.current.set(f,Math.max(c,o.current.get(f)??0)),l()},[l]);return{flush:l,markDisplayed:u}}import{useEffect as xa,useRef as re,useState as se}from"react";import{jsx as b,jsxs as fe}from"react/jsx-runtime";function Ca(e=!1,a=0,o){let[t,l]=se([]),[u,f]=se(!1),[c,i]=se(""),p=re(!0),r=re(!1),I=re(new Map),d=L=>o.discard(L);xa(()=>(p.current=!0,()=>{p.current=!1;for(let L of I.current.values())URL.revokeObjectURL(L.preview),d(L).catch(()=>{})}),[]);function s(){p.current&&l([...I.current.values()].map(L=>({...L})))}function m(){for(let L of I.current.values())URL.revokeObjectURL(L.preview);I.current.clear(),p.current&&(l([]),i(""))}async function x(L){let g=I.current.get(L);if(!(!g||r.current||e)){r.current=!0,f(!0);try{await d(g),I.current.delete(L),URL.revokeObjectURL(g.preview),s(),i("")}catch(D){p.current&&i(D instanceof Error?D.message:"The attachment could not be removed.")}finally{r.current=!1,p.current&&f(!1)}}}async function C(L){for(let g of L){if(!p.current)return;let D=g.status==="failed";g.status="uploading",s();try{g.token=await o.send(g,D,()=>p.current),g.status="ready"}catch(w){g.status="failed",p.current&&i(w instanceof Error?w.message:"The upload failed. Your comment is still here.")}finally{p.current||await d(g).catch(()=>{})}s()}}async function R(L){if(!L?.length||r.current||e)return;let g=Array.from(L),D=g.map(w=>Pe(w)).find(Boolean);if(D){i(D);return}if(a+I.current.size+g.length>20){i("Attach up to 20 files per comment.");return}r.current=!0,f(!0),i("");try{let w=await o.userId();if(!w)throw new Error("Sign in again to attach files.");if(!p.current)return;let ee=g.map(T=>{let ae=crypto.randomUUID(),ie={id:ae,name:T.name,mimeType:T.type,size:T.size,file:T,bucket:Z.includes(T.type)?"chisel-review-images":"chisel-review-videos",path:`${w}/${ae}`,preview:URL.createObjectURL(T),stored:!1,status:"uploading"};return I.current.set(ae,ie),ie});s(),await C(ee)}catch(w){p.current&&i(w instanceof Error?w.message:"The upload failed. Your comment is still here.")}finally{r.current=!1,p.current&&f(!1)}}async function _(){if(!(r.current||e)){r.current=!0,f(!0),i("");try{await C([...I.current.values()].filter(L=>L.status==="failed"))}finally{r.current=!1,p.current&&f(!1)}}}let X=t.some(L=>L.status==="failed"),j=fe("div",{className:"chisel-attachment-controls",children:[u&&b("span",{role:"status",children:"Uploading\u2026"}),X&&fe("button",{type:"button",className:"review-retry-upload",disabled:u||e,onClick:()=>{_()},children:[b(V,{size:16,strokeWidth:1.75}),"Retry upload"]}),c&&b("span",{className:"chisel-attachment-error",role:"alert",children:c})]}),Y=t.length>0&&b("div",{className:"chisel-attachment-previews",children:t.map(L=>fe("div",{className:"chisel-attachment-preview","data-state":L.status,children:[b($,{src:L.preview,name:L.name,mimeType:L.mimeType}),b("span",{title:L.name,children:L.name}),b("button",{type:"button","aria-label":`Remove ${L.name}`,disabled:u||e,onClick:()=>{x(L.id)},children:b(v,{size:16,strokeWidth:1.75})})]},L.id))});return{attachments:t,uploading:u,blocked:u||X,controls:j,previewsUI:Y,clear:m,upload:R,previews:t.map(({id:L,name:g,mimeType:D,size:w,preview:ee})=>({id:L,name:g,mimeType:D,size:w,previewUrl:ee})),tokens:t.flatMap(L=>L.token?[L.token]:[])}}export{J as ReviewAttachmentButton,ve as ReviewBody,na as ReviewComposer,z as ReviewEditor,ma as ReviewThread,de as bodyToEditor,Me as createReviewEditor,oe as displayedActivity,De as editorToBody,Ia as useReadQueue,Ca as useReviewAttachments};
1
+ "use client";import{forwardRef as Je,createElement as Qe}from"react";var Ce=e=>e?.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase();function he(e,a,o=[]){if(a==null)throw new Error("[lucide]: iconNode is required when icon name is used");return{name:Ce(e),size:24,node:a,...o.length>0?{aliases:o}:{}}}var ge=e=>{let a="",o=!1;for(let t of e){if(t==="-"||t==="_"||t<=" "){o=a.length>0;continue}a.length===0?a+=t.toLowerCase():a+=o?t.toUpperCase():t,o=!1}return a};var Se=e=>{let a=ge(e);return a.charAt(0).toUpperCase()+a.slice(1)};import{forwardRef as Ze,createElement as Ae}from"react";var W=(...e)=>e.filter((a,o,t)=>!!a&&a.trim()!==""&&t.indexOf(a)===o).join(" ").trim();var v={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round"};function re(e){return e!=null}function ke(e,a={}){let o=a.attributeNames??{},t=d=>o[d]??d,l=e.size??e.width??v.width,u=e.size??e.height??v.height,r=e.aliases?.filter(d=>typeof d=="string"&&d.trim()!=="").map(d=>`lucide-${d}`)??[],n=[...e.name?[`lucide-${e.name}`]:[],...r],i=a.className?.split(" ").filter(Boolean)??[],I=a.includeDefaultClasses===!1?W(...i):W("lucide",...n,...i),s=a.absoluteStrokeWidth?Number(a.strokeWidth??v["stroke-width"])*Number(e.size??e.width??v.width)/Number(a.size??a.width??v.width):a.strokeWidth??v["stroke-width"];return["svg",{...Object.entries(v).reduce((d,[f,c])=>(d[t(f)]=c,d),{}),..."color"in a&&a.color&&{[t("stroke")]:a.color},..."size"in a&&re(a.size)&&{[t("width")]:a.size,[t("height")]:a.size},..."width"in a&&re(a.width)&&{[t("width")]:a.width},..."height"in a&&re(a.height)&&{[t("height")]:a.height},[t("stroke-width")]:s,...I&&{[t("class")]:I},[t("viewBox")]:`0 0 ${l} ${u}`,...a.hasA11yProp===!1?{[t("aria-hidden")]:"true"}:{},..."attributes"in a&&a.attributes},e.node.map(d=>{let[f,c,x]=d,g=a.nonScalingStroke?{[t("vector-effect")]:"non-scaling-stroke",...c}:c;return x?[f,g,x]:[f,g]})]}function we(e,a={}){return ke(e,{...a,attributeNames:{...a.attributeNames,class:"className","stroke-width":"strokeWidth","stroke-linecap":"strokeLinecap","stroke-linejoin":"strokeLinejoin","vector-effect":"vectorEffect"}})}var Pe=e=>{for(let a in e)if(a.startsWith("aria-")||a==="role"||a==="title")return!0;return!1};import{createContext as Ne,useContext as Xe,useMemo as za,createElement as Na}from"react";var Ke=Ne({});var ye=()=>Xe(Ke);var Be=Ze(({color:e,size:a,width:o,height:t,strokeWidth:l,absoluteStrokeWidth:u,nonScalingStroke:r,className:n="",children:i,iconNode:I=[],icon:s={node:I,aliases:[],size:24},...L},d)=>{let{size:f=24,strokeWidth:c=2,absoluteStrokeWidth:x=!1,nonScalingStroke:g=!1,color:b="currentColor",className:O=""}=ye()??{},S=!!i||Pe(L),[F,oe,ue=[]]=we(s,{color:e??b,width:o??a??f,height:t??a??f,strokeWidth:l??c,absoluteStrokeWidth:u??x,nonScalingStroke:r??g,className:W(O,n),hasA11yProp:S,attributes:L});return Ae(F,{ref:d,...oe},[...ue.map(([p,h])=>Ae(p,h)),...Array.isArray(i)?i:[i]])});function k(e,a=[],o=[]){let t=typeof e=="string"?he(e,a,o):e,l=Je(({className:u,...r},n)=>Qe(Be,{ref:n,icon:t,className:u,...r}));return t.name&&(l.displayName=Se(t.name)),l}var $e={name:"arrow-up",size:24,node:[["path",{d:"m5 12 7-7 7 7",key:"hav0vg"}],["path",{d:"M12 19V5",key:"x0mq9r"}]]},V=k($e);var _e={name:"download",size:24,node:[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]]},z=k(_e);var je={name:"paperclip",size:24,node:[["path",{d:"m16 6-8.414 8.586a2 2 0 0 0 2.829 2.829l8.414-8.586a4 4 0 1 0-5.657-5.657l-8.379 8.551a6 6 0 1 0 8.485 8.485l8.379-8.551",key:"1miecu"}]]},N=k(je);var Ye={name:"pencil",size:24,node:[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]]},X=k(Ye);var ea={name:"play",size:24,node:[["path",{d:"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",key:"10ikf1"}]]},K=k(ea);var aa={name:"rotate-cw",size:24,node:[["path",{d:"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8",key:"1p45f6"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}]]},Z=k(aa);var ta={name:"x",size:24,node:[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]},q=k(ta);import{useEffect as U,useRef as y,useState as $}from"react";function D(e){return{version:1,content:e.split(`
2
+ `).map(a=>({type:"paragraph",children:[{text:a}]}))}}function _(e){return e.content.map(a=>a.children.map(o=>"type"in o?o.text||o.url:o.text).join("")).join(`
3
+ `)}function j(e){let a=e.content.slice();for(;a.length;){let o=a[a.length-1],t=o.children.slice();for(;t.length;){let l=t[t.length-1],u="type"in l?l.text||l.url:l.text,r=u.trimEnd();if(r)return t[t.length-1]=r===u?l:{...l,text:r},a[a.length-1]={...o,children:t},{...e,content:a};t.pop()}a.pop()}return D("")}function se(e){try{let a=JSON.parse(localStorage.getItem(e)??"null");return a?.version===1&&Date.now()-a.time<7*864e5?a.value:null}catch{return null}}function E(e,a){try{return a===null?localStorage.removeItem(e):localStorage.setItem(e,JSON.stringify({version:1,time:Date.now(),value:a})),!0}catch{return!1}}function fe(e,a,o){let t=e;for(let l of[...a].sort((u,r)=>u-r))if(!(l<=t)){if(!o.has(l))break;t=l}return t}var Y=["image/jpeg","image/png","image/gif","image/webp","image/avif","image/bmp"],De=["video/mp4","video/webm","video/quicktime"],Me=[...Y,...De].join(",");function be(e){let a=Y.includes(e.type);return!a&&!De.includes(e.type)?"Choose a JPG, PNG, GIF, WebP, AVIF, BMP, MP4, WebM, or MOV file.":!Number.isSafeInteger(e.size)||e.size<=0?"This file is empty or invalid.":e.size>(a?5242880:20971520)?`${a?"Images must be 5 MB":"Videos must be 20 MB"} or smaller.`:null}import{useEffect as oa,useRef as Fe,useState as Re}from"react";import{createEditor as ua,Editor as C,Element as G,Node as da,Path as la,Range as ie,Transforms as M}from"slate";import{withHistory as ra}from"slate-history";import{Editable as sa,Slate as fa,withReact as ia,ReactEditor as ve}from"slate-react";import{Fragment as Ue,jsx as w,jsxs as Oe}from"react/jsx-runtime";function ce(e){return e.content.length?e.content.map(a=>({type:"paragraph",children:a.children.length?a.children.map(o=>"type"in o&&o.type==="link"?{type:"link",url:o.url,children:[{text:o.text||o.url}]}:{...o}):[{text:""}]})):[{type:"paragraph",children:[{text:""}]}]}function Te(e){return{version:1,content:e.map(a=>({type:"paragraph",children:G.isElement(a)?a.children.map(o=>G.isElement(o)?{type:"link",url:o.url,text:da.string(o)}:{...o}):[{text:a.text}]}))}}function ne(e){return/^(https?:\/\/|mailto:)[^\s]+$/i.test(e)}function ca(e,a){if(!e.selection){let o=window.getSelection(),t=o&&ve.toSlateRange(e,o,{exactMatch:!1,suppressThrow:!0});M.select(e,t??C.end(e,[]))}C.marks(e)?.[a]?C.removeMark(e,a):C.addMark(e,a,!0)}function qe(){let e=ia(ra(ua()),"application/x-chisel-review-fragment"),{isInline:a,insertText:o,insertData:t,insertBreak:l}=e;e.isInline=n=>n.type==="link"||a(n);function u(n,i){C.above(e,{at:n,match:I=>G.isElement(I)&&I.type==="link"})||(M.wrapNodes(e,{type:"link",url:i,children:[]},{at:n,split:!0}),M.collapse(e,{edge:"end"}))}function r(){if(!e.selection||!ie.isCollapsed(e.selection))return;let n=C.above(e,{match:d=>G.isElement(d)&&d.type==="paragraph"});if(!n)return;let i=e.selection.anchor,s=C.string(e,{anchor:C.start(e,n[1]),focus:i}).match(/\S+$/)?.[0];if(!s||!ne(s))return;let L=C.before(e,i,{distance:s.length,unit:"offset"});if(L){u({anchor:L,focus:i},s);let d=C.above(e,{match:f=>G.isElement(f)&&f.type==="link"});d&&e.selection&&C.isEnd(e,e.selection.anchor,d[1])&&M.select(e,C.start(e,la.next(d[1])))}}return e.insertText=n=>{if(ve.isComposing(e)){o(n);return}n===" "&&r();let i={"*":"bold",_:"italic","~":"strikethrough","`":"code"}[n];if(i&&e.selection&&ie.isCollapsed(e.selection)){let I=C.above(e,{match:s=>G.isElement(s)&&s.type==="paragraph"});if(I){let s=e.selection.anchor,L=C.string(e,{anchor:C.start(e,I[1]),focus:s}),d=L.lastIndexOf(n),f=L.slice(d+1);if(d>=0&&(!d||/[\s*_~`]/.test(L[d-1]))&&f&&f.trim()===f){let c=C.before(e,s,{distance:f.length,unit:"offset"}),x=c&&C.before(e,c,{unit:"offset"});if(c&&x){M.select(e,{anchor:c,focus:s}),C.addMark(e,i,!0),M.collapse(e,{edge:"end"}),M.delete(e,{at:{anchor:x,focus:c}}),C.removeMark(e,i);return}}}}o(n)},e.insertBreak=()=>{r(),l()},e.insertData=n=>{let i=n.getData("text/plain");ne(i)?e.selection&&!ie.isCollapsed(e.selection)?u(e.selection,i):M.insertNodes(e,[{type:"link",url:i,children:[{text:i}]},{text:""}]):t(n)},e}function na({attributes:e,children:a,element:o}){return o.type==="link"?w("a",{...e,href:ne(o.url)?o.url:void 0,onClick:t=>t.preventDefault(),children:a}):w("p",{...e,children:a})}function pa({attributes:e,children:a,leaf:o}){let t=w(Ue,{children:a});return o.bold&&(t=w("strong",{children:t})),o.italic&&(t=w("em",{children:t})),o.strikethrough&&(t=w("s",{children:t})),o.code&&(t=w("code",{children:t})),w("span",{...e,children:t})}function J({onFiles:e,disabled:a}){let o=Fe(null);return Oe(Ue,{children:[w("input",{ref:o,type:"file",accept:Me,multiple:!0,hidden:!0,onChange:t=>{e(t.target.files),t.target.value=""}}),w("button",{type:"button",className:"review-retry-upload","aria-label":"Attach image or video",title:"Images up to 5 MB \xB7 Videos up to 20 MB",disabled:a,onClick:()=>o.current?.click(),children:w(N,{size:16,strokeWidth:1.75})})]})}function Q({text:e,defaultBody:a,disabled:o,label:t,placeholder:l,autoFocus:u,onChange:r,onSubmit:n,onFiles:i,uploading:I}){let[s]=Re(qe),[L]=Re(()=>ce(a??D(e))),d=Fe(e);return oa(()=>{if(e===d.current)return;let f=d.current;d.current=e,f&&e.startsWith(f)?M.insertText(s,e.slice(f.length),{at:C.end(s,[])}):(C.withoutNormalizing(s,()=>{M.removeNodes(s,{at:[],match:(c,x)=>x.length===1}),M.insertNodes(s,ce(D(e)),{at:[0]}),M.deselect(s)}),e||(s.history={undos:[],redos:[]}))},[s,e]),Oe(fa,{editor:s,initialValue:L,onChange:f=>{if(!s.operations.some(x=>x.type!=="set_selection"))return;let c=Te(f);d.current=_(c),r(d.current,c)},children:[w(sa,{className:"review-composer-editor",role:"textbox","aria-multiline":"true","aria-label":t,placeholder:l,readOnly:o,autoFocus:u,renderElement:na,renderLeaf:pa,onKeyDown:f=>{if(f.nativeEvent.isComposing)return;let c=f.metaKey||f.ctrlKey;if(f.key==="Enter"){f.preventDefault(),c?s.insertBreak():n();return}let x=c?{b:"bold",i:"italic",e:"code",...f.shiftKey?{s:"strikethrough"}:{}}[f.key.toLowerCase()]:void 0;x&&(f.preventDefault(),ca(s,x))}}),i&&w("div",{className:"chisel-attachment-controls",children:w(J,{onFiles:i,disabled:o||I})})]})}import{useEffect as ma,useRef as La,useState as Ia}from"react";import{Fragment as He,jsx as P,jsxs as ee}from"react/jsx-runtime";function xa({src:e,name:a,mimeType:o,onError:t,close:l}){let u=La(null);return ma(()=>{u.current?.showModal()},[]),P("dialog",{ref:u,className:"review-media-lightbox","aria-label":`Preview ${a}`,onCancel:r=>{r.preventDefault(),l()},onClick:r=>{r.target===r.currentTarget&&l()},children:ee("div",{className:"review-media-lightbox-content",children:[ee("header",{children:[P("span",{children:a}),P("a",{href:e,download:a,"aria-label":`Download ${a}`,title:"Download",children:P(z,{size:20,"aria-hidden":"true"})}),P("button",{type:"button","aria-label":"Close preview",onClick:l,children:P(q,{size:20})})]}),o.startsWith("image/")?P("img",{src:e,alt:a,onError:t}):P("video",{src:e,controls:!0,autoPlay:!0,playsInline:!0,"aria-label":a,onError:t})]})})}function ae({src:e,name:a,mimeType:o,onError:t}){let[l,u]=Ia(!1);return ee(He,{children:[P("button",{type:"button",className:"review-media-thumbnail","aria-label":`Preview ${a}`,onClick:()=>u(!0),children:o.startsWith("image/")?P("img",{src:e,alt:a,loading:"lazy",onError:t}):ee(He,{children:[P("video",{src:e,muted:!0,playsInline:!0,preload:"metadata","aria-hidden":"true",onError:t}),P("span",{className:"review-media-play","aria-hidden":"true",children:P(K,{size:20,fill:"currentColor"})})]})}),l&&P(xa,{src:e,name:a,mimeType:o,onError:t,close:()=>u(!1)})]})}import{Fragment as wa,jsx as m,jsxs as A}from"react/jsx-runtime";function pe(e,a,o){if(e)try{let t=se(e);if(t?.text===a&&_(t.body)===a)return t.body}catch{}return o??D(a)}function me(e,a,o,t=!1){e&&E(e,t||a.trim()?{text:a,body:o}:null)}function Ee({body:e}){return m("div",{className:"review-comment-body",children:e.content.map((a,o)=>m("p",{children:a.children.map((t,l)=>{if("type"in t&&t.type==="link")return m("a",{href:/^(https?:|mailto:)/i.test(t.url)?t.url:void 0,target:"_blank",rel:"noopener noreferrer",children:t.text||t.url},l);if(!("text"in t))return null;let u=m(wa,{children:t.text});return"bold"in t&&t.bold&&(u=m("strong",{children:u})),"italic"in t&&t.italic&&(u=m("em",{children:u})),"strikethrough"in t&&t.strikethrough&&(u=m("s",{children:u})),"code"in t&&t.code&&(u=m("code",{children:u})),m("span",{children:u},l)})},o))})}function Ca({attachment:e,loadMedia:a}){let[o,t]=$(e.previewUrl??""),[l,u]=$(!1),[r,n]=$(0),i=y(0);U(()=>{if(e.previewUrl){t(e.previewUrl);return}t("");let s=!0,L=!1,d=new AbortController;async function f(){if(!(L||document.visibilityState==="hidden")){L=!0;try{let g=await a(e.id,d.signal);s&&(t(g),u(!1),i.current=Date.now()+240*1e3)}catch{s&&u(!0)}finally{L=!1}}}function c(){Date.now()>=i.current&&f()}f();let x=window.setInterval(c,60*1e3);return window.addEventListener("focus",c),document.addEventListener("visibilitychange",c),()=>{s=!1,d.abort(),window.clearInterval(x),window.removeEventListener("focus",c),document.removeEventListener("visibilitychange",c)}},[e.id,e.previewUrl,r,a]);function I(){u(!0),Date.now()>=i.current&&n(s=>s+1)}return A("figure",{className:"review-attachment",children:[o&&!l?m(ae,{src:o,name:e.name,mimeType:e.mimeType,onError:I}):m("div",{className:"review-attachment-placeholder",role:"status",children:l?m("button",{type:"button",className:"review-retry-upload",onClick:()=>n(s=>s+1),children:"Retry attachment"}):"Loading attachment\u2026"}),m("figcaption",{children:e.name})]})}function Ge(e){let a=Math.max(0,Math.floor((Date.now()-Date.parse(e))/6e4));return a<1?"Just now":a<60?`${a}m`:a<1440?`${Math.floor(a/60)}h`:new Date(e).toLocaleDateString(void 0,{month:"short",day:"numeric"})}function ha({comment:e,activity:a,loadMedia:o,editable:t,editing:l,saving:u,onStartEdit:r,onCancelEdit:n,onSaveEdit:i,onDraftChange:I,onEditStyles:s,draftKey:L}){let[d,f]=$(e.text),c=y(e.body??D(e.text)),x=y(!1),g=l&&!(u&&x.current),b=y(!1);U(()=>{l?I(d!==e.text||JSON.stringify(c.current)!==JSON.stringify(e.body??D(e.text))):b.current&&L&&E(L,null),b.current=l},[l]),U(()=>{l||(f(e.text),c.current=e.body??D(e.text))},[l,e.text,e.body]);async function O(){if(!(u||x.current||!d.trim()&&!e.attachments?.length)){x.current=!0;try{await i(d.trimEnd(),j(c.current))&&(L&&E(L,null),I(!1))}finally{x.current=!1}}}return A("article",{className:"review-comment","data-activity":a,children:[m("span",{className:"review-comment-avatar",children:e.authorImage?m("img",{src:e.authorImage,alt:""}):e.author.slice(0,1).toUpperCase()}),A("div",{className:"review-comment-content",children:[A("header",{className:"review-comment-header",children:[m("span",{className:"review-comment-author",children:e.author}),e.pending?m("span",{className:"review-comment-time",role:"status",children:"Sending\u2026"}):m("time",{className:"review-comment-time",dateTime:e.date,title:new Date(e.date).toLocaleString(),children:Ge(e.date)}),t&&!l&&m("button",{type:"button",className:"review-comment-edit","aria-label":"Edit comment",title:"Edit comment",disabled:u,onClick:()=>{let S=L?se(L):null;S&&typeof S.text=="string"&&(f(S.text),c.current=pe(L,S.text)),r()},children:m(X,{size:16})})]}),g?A("form",{className:"review-inline-edit",onSubmit:S=>{S.preventDefault(),O()},children:[m(Q,{text:d,defaultBody:c.current,disabled:u,label:"Edit comment",placeholder:"Edit comment\u2026",autoFocus:!0,onSubmit:()=>{O()},onChange:(S,F)=>{f(S),c.current=F,me(L,S,F,!0),I(S!==e.text||JSON.stringify(F)!==JSON.stringify(e.body??D(e.text)))}}),A("div",{className:"review-inline-edit-actions",children:[s&&m("button",{type:"button",disabled:u,onClick:s,children:"Edit styles"}),m("button",{type:"button",disabled:u,onClick:n,children:"Cancel"}),m("button",{type:"submit",disabled:u||!d.trim()&&!e.attachments?.length,children:"Save"})]})]}):m(Ee,{body:e.body??D(e.text)}),e.attachments?.length>0&&m("div",{className:"review-attachments",children:e.attachments.map(S=>m(Ca,{attachment:S,loadMedia:o},S.id))})]})]})}function ga(e){let a=e.useAttachments(e.disabled,e.existingAttachments?.length??0),o=y(pe(e.draftKey,e.text,e.defaultBody)),t=y(!1);U(()=>(e.onAttachmentDraftChange?.(a.uploading||a.attachments.length>0),()=>e.onAttachmentDraftChange?.(!1)),[a.uploading,a.attachments.length,e.onAttachmentDraftChange]);async function l(){if(!(e.disabled||a.blocked||t.current||!e.text.trim()&&!a.attachments.length&&!e.existingAttachments?.length)){t.current=!0;try{await e.onSubmit(e.text.trimEnd(),j(o.current),a.tokens,a.previews)&&(e.draftKey&&E(e.draftKey,null),a.clear())}finally{t.current=!1}}}return m("form",{className:"review-composer chisel-review-composer","aria-label":e.commentId?"Edit comment":"New comment",onSubmit:u=>{u.preventDefault(),l()},onPasteCapture:u=>{u.clipboardData.files.length&&(u.preventDefault(),u.stopPropagation(),a.upload(u.clipboardData.files))},onDragOver:u=>{u.dataTransfer.types.includes("Files")&&u.preventDefault()},onDropCapture:u=>{u.dataTransfer.files.length&&(u.preventDefault(),u.stopPropagation(),a.upload(u.dataTransfer.files))},children:e.renderContent(A("div",{className:"chisel-composer-input",children:[m(Q,{text:e.text,defaultBody:o.current,disabled:e.disabled,label:"Comment",placeholder:"Leave a comment\u2026",autoFocus:!0,onSubmit:()=>{l()},onChange:(u,r)=>{o.current=r,me(e.draftKey,u,r),e.onText(u)}}),a.previewsUI,a.controls]}),a.attachments.length>0||!!e.existingAttachments?.length,a.blocked,m(J,{onFiles:a.upload,disabled:e.disabled||a.uploading}))})}function Sa(e){let a=e.useAttachments(e.saving),o=y(pe(e.draftKey,e.reply)),t=y(!1);U(()=>(e.onAttachmentDraftChange?.(a.uploading||a.attachments.length>0),()=>e.onAttachmentDraftChange?.(!1)),[a.uploading,a.attachments.length,e.onAttachmentDraftChange]);async function l(){if(!(e.saving||a.blocked||t.current||!e.reply.trim()&&!a.attachments.length)){t.current=!0;try{await e.onReply(e.reply.trimEnd(),j(o.current),a.tokens,a.previews)&&(e.draftKey&&E(e.draftKey,null),o.current=D(""),a.clear())}finally{t.current=!1}}}return A("form",{className:"review-composer chisel-review-reply","aria-label":"Reply to thread",hidden:e.submittingReply,onSubmit:u=>{u.preventDefault(),l()},onPasteCapture:u=>{u.clipboardData.files.length&&(u.preventDefault(),u.stopPropagation(),a.upload(u.clipboardData.files))},onDragOver:u=>{u.dataTransfer.types.includes("Files")&&u.preventDefault()},onDropCapture:u=>{u.dataTransfer.files.length&&(u.preventDefault(),u.stopPropagation(),a.upload(u.dataTransfer.files))},children:[m("span",{className:"feedback-avatar feedback-reply-avatar",children:e.replyAuthor?.image?m("img",{src:e.replyAuthor.image,alt:""}):(e.replyAuthor?.name||"You").slice(0,1).toUpperCase()}),A("div",{className:"chisel-reply-field",children:[m(Q,{text:e.reply,defaultBody:o.current,disabled:e.saving,label:"Reply",placeholder:"Write a reply\u2026",onSubmit:()=>{l()},onChange:(u,r)=>{o.current=r,me(e.draftKey,u,r),e.onReplyText(u)}}),a.previewsUI,a.controls,m("div",{className:"chisel-attachment-controls",children:m(J,{onFiles:a.upload,disabled:e.saving||a.uploading})}),m("button",{type:"submit",className:"chisel-reply-submit","aria-label":"Reply",disabled:e.saving||a.blocked||!e.reply.trim()&&!a.attachments.length,children:m(V,{size:16,strokeWidth:1.75})})]})]})}function ka(e){let a=e.comment,[o,t]=$(null),l=y(!1),u=y(e.onEditDraftChange);u.current=e.onEditDraftChange,U(()=>()=>{u.current?.(!1)},[]);function r(d){l.current=d,e.onEditDraftChange?.(d)}async function n(d){d&&e.onBeginEdit&&!await e.onBeginEdit()||!d&&l.current&&e.onDiscardEdit&&!await e.onDiscardEdit()||(r(!1),t(d))}function i(d,f){return m(ha,{draftKey:e.draftKey?`${e.draftKey}:edit:${d.id}`:void 0,comment:d,activity:f?a.rootActivity:d.activity,loadMedia:e.loadMedia,editable:!!(e.expanded&&e.onEdit&&e.userId&&d.authorId===e.userId&&!d.pending),editing:o===d.id,saving:e.saving,onEditStyles:f?e.onEditStyles:void 0,onStartEdit:()=>{n(d.id)},onCancelEdit:()=>{n(null)},onDraftChange:r,onSaveEdit:async(c,x)=>{let g=await e.onEdit?.(f?null:d.id,c,x);return g&&(r(!1),t(null)),!!g}},d.id)}let I=y(null),s=y(new Set),L=y(a.readActivity??0);return U(()=>{if(!e.expanded||!I.current||a.pending||a.readActivity===null)return;let d=[a.rootActivity,...a.replies.map(x=>x.activity)],f=new IntersectionObserver(x=>{if(document.visibilityState!=="visible")return;for(let b of x)b.isIntersecting&&b.intersectionRatio>0&&s.current.add(Number(b.target.dataset.activity));let g=fe(Math.max(L.current,a.readActivity??0),d,s.current);g>L.current&&(L.current=g,e.onRead(a.id,g))},{threshold:0});function c(){if(f.disconnect(),document.visibilityState==="visible")for(let x of I.current?.querySelectorAll("[data-activity]")??[])f.observe(x)}return c(),document.addEventListener("visibilitychange",c),()=>{f.disconnect(),document.removeEventListener("visibilitychange",c)}},[a,e.expanded,e.onRead]),A("div",{className:"chisel-review-thread-content",children:[e.expanded&&a.context&&A("p",{className:"review-capture-context",children:[a.context.width," \xD7 ",a.context.height,"px \xB7 ",a.breakpoint??"desktop",a.context.deployment?` \xB7 ${a.context.deployment}`:"",A("time",{dateTime:a.context.capturedAt,title:new Date(a.context.capturedAt).toLocaleString(),children:[" \xB7 ",Ge(a.context.capturedAt)]})]}),A("div",{ref:I,className:"review-thread",children:[i(a,!0),e.expanded&&a.replies.map(d=>i(d,!1))]}),e.expanded?!o&&m(Sa,{...e}):m("button",{type:"button",className:"chisel-expand-thread",onClick:e.onExpand,children:a.replies.length?`${a.replies.length} ${a.replies.length===1?"reply":"replies"}`:"Reply\u2026"})]})}import{useCallback as We,useRef as Ve}from"react";function Pa(e,a){let o=Ve(new Map),t=Ve(!1),l=We(async()=>{if(!t.current){t.current=!0;try{for(;o.current.size;){let[r,n]=o.current.entries().next().value;try{await e(r,n)}catch(i){if([400,403,404].includes(i.status??0)){o.current.delete(r);continue}throw i}o.current.get(r)===n&&o.current.delete(r),a(r,n)}}catch{}finally{t.current=!1}}},[e,a]),u=We((r,n)=>{o.current.set(r,Math.max(n,o.current.get(r)??0)),l()},[l]);return{flush:l,markDisplayed:u}}import{useEffect as ya,useRef as te,useState as Le}from"react";import{jsx as T,jsxs as Ie}from"react/jsx-runtime";function Aa(e=!1,a=0,o){let[t,l]=Le([]),[u,r]=Le(!1),[n,i]=Le(""),I=te(!0),s=te(!1),L=te(new Map),d=te(null),f=p=>o.discard(p);ya(()=>(I.current=!0,()=>{I.current=!1;for(let p of L.current.values())URL.revokeObjectURL(p.preview),f(p).catch(()=>{})}),[]);function c(){I.current&&l([...L.current.values()].filter(p=>p.id!==d.current).map(p=>({...p})))}function x(){for(let p of L.current.values())URL.revokeObjectURL(p.preview);L.current.clear(),I.current&&(l([]),i(""))}async function g(p){let h=L.current.get(p);if(!(!h||s.current||e)){s.current=!0,r(!0),d.current=p,c();try{await f(h),L.current.delete(p),URL.revokeObjectURL(h.preview),c(),i("")}catch(R){I.current&&i(R instanceof Error?R.message:"The attachment could not be removed.")}finally{d.current=null,s.current=!1,c(),I.current&&r(!1)}}}async function b(p){for(let h of p){if(!I.current)return;let R=h.status==="failed";h.status="uploading",c();try{h.token=await o.send(h,R,()=>I.current),h.status="ready"}catch(B){h.status="failed",I.current&&i(B instanceof Error?B.message:"The upload failed. Your comment is still here.")}finally{I.current||await f(h).catch(()=>{})}c()}}async function O(p){if(!p?.length||s.current||e)return;let h=Array.from(p),R=h.map(B=>be(B)).find(Boolean);if(R){i(R);return}if(a+L.current.size+h.length>20){i("Attach up to 20 files per comment.");return}s.current=!0,r(!0),i("");try{let B=await o.userId();if(!B)throw new Error("Sign in again to attach files.");if(!I.current)return;let de=h.map(H=>{let le=crypto.randomUUID(),xe={id:le,name:H.name,mimeType:H.type,size:H.size,file:H,bucket:Y.includes(H.type)?"chisel-review-images":"chisel-review-videos",path:`${B}/${le}`,preview:URL.createObjectURL(H),stored:!1,status:"uploading"};return L.current.set(le,xe),xe});c(),await b(de)}catch(B){I.current&&i(B instanceof Error?B.message:"The upload failed. Your comment is still here.")}finally{s.current=!1,I.current&&r(!1)}}async function S(){if(!(s.current||e)){s.current=!0,r(!0),i("");try{await b([...L.current.values()].filter(p=>p.status==="failed"))}finally{s.current=!1,I.current&&r(!1)}}}let F=t.some(p=>p.status==="failed"),oe=Ie("div",{className:"chisel-attachment-controls",children:[u&&T("span",{role:"status",children:"Uploading\u2026"}),F&&Ie("button",{type:"button",className:"review-retry-upload",disabled:u||e,onClick:()=>{S()},children:[T(Z,{size:16,strokeWidth:1.75}),"Retry upload"]}),n&&T("span",{className:"chisel-attachment-error",role:"alert",children:n})]}),ue=t.length>0&&T("div",{className:"chisel-attachment-previews",children:t.map(p=>Ie("div",{className:"chisel-attachment-preview","data-state":p.status,children:[T(ae,{src:p.preview,name:p.name,mimeType:p.mimeType}),T("span",{title:p.name,children:p.name}),T("button",{type:"button","aria-label":`Remove ${p.name}`,disabled:u||e,onClick:()=>{g(p.id)},children:T(q,{size:16,strokeWidth:1.75})})]},p.id))});return{attachments:t,uploading:u,blocked:u||F,controls:oe,previewsUI:ue,clear:x,upload:O,previews:t.map(({id:p,name:h,mimeType:R,size:B,preview:de})=>({id:p,name:h,mimeType:R,size:B,previewUrl:de})),tokens:t.flatMap(p=>p.token?[p.token]:[])}}var ze=new WeakMap;async function Ba(e,a,o){let t=ze.get(e);if(!t){let u=await a.userId();if(!u)throw new Error("Sign in again to save the snapshot.");let r=crypto.randomUUID();t={id:r,name:e.name,mimeType:e.type,size:e.size,file:e,bucket:"chisel-review-images",path:`${u}/${r}`,preview:"",stored:!1,status:"uploading"},ze.set(e,t)}let l=t.token??await a.send(t,t.stored,()=>!0);if(!l)throw new Error("The snapshot upload was incomplete.");t.token=l,await o(l)}export{J as ReviewAttachmentButton,Ee as ReviewBody,ga as ReviewComposer,Q as ReviewEditor,ka as ReviewThread,ce as bodyToEditor,qe as createReviewEditor,fe as displayedActivity,Te as editorToBody,Ba as uploadSnapshot,Pa as useReadQueue,Aa as useReviewAttachments};
4
4
  /*! Bundled license information:
5
5
 
6
6
  lucide-react/dist/esm/shared/src/utils/toKebabCase.mjs:
@@ -16,6 +16,7 @@ lucide-react/dist/esm/context.mjs:
16
16
  lucide-react/dist/esm/Icon.mjs:
17
17
  lucide-react/dist/esm/createLucideIcon.mjs:
18
18
  lucide-react/dist/esm/icons/arrow-up.mjs:
19
+ lucide-react/dist/esm/icons/download.mjs:
19
20
  lucide-react/dist/esm/icons/paperclip.mjs:
20
21
  lucide-react/dist/esm/icons/pencil.mjs:
21
22
  lucide-react/dist/esm/icons/play.mjs:
@@ -0,0 +1,3 @@
1
+ export type PreviewBreakpoint = "desktop" | "tablet" | "mobile";
2
+ export declare function breakpointAt(width: number): PreviewBreakpoint;
3
+ export declare function visibleAtBreakpoint(source: PreviewBreakpoint | undefined, viewport: PreviewBreakpoint): boolean;
@@ -7,11 +7,12 @@ export type WorkspaceComposerProps = {
7
7
  onText(value: string): void;
8
8
  disabled: boolean;
9
9
  commentId?: string;
10
+ draftKey?: string;
10
11
  onAttachmentDraftChange?(hasDraft: boolean): void;
11
12
  onSubmit(text: string, body?: unknown, attachmentTokens?: string[], attachments?: WorkspaceAttachment[]): Promise<boolean>;
12
13
  renderContent(editor: ReactNode, hasAttachments?: boolean, uploading?: boolean, actions?: ReactNode): ReactNode;
13
14
  };
14
- export default function CommentBox({ target, text, onText, onCancel, onPost, style, changes, editing, commentId, renderComposer, hasExistingAttachments, onDraftChange, hidden }: {
15
+ export default function CommentBox({ target, text, onText, onCancel, onPost, style, changes, editing, commentId, renderComposer, hasExistingAttachments, onDraftChange, hidden, draftKey, onDiscard }: {
15
16
  target: Element | null;
16
17
  text: string;
17
18
  onText(value: string): void;
@@ -25,4 +26,6 @@ export default function CommentBox({ target, text, onText, onCancel, onPost, sty
25
26
  commentId?: string;
26
27
  renderComposer?: (props: WorkspaceComposerProps) => ReactNode;
27
28
  onDraftChange?(hasDraft: boolean): void;
29
+ draftKey?: string;
30
+ onDiscard?(): Promise<boolean>;
28
31
  }): import("react").JSX.Element;
@@ -1,4 +1,5 @@
1
1
  import type { StyleChange } from "./style-changes";
2
+ import type { PreviewBreakpoint } from "./breakpoints";
2
3
  export type CommentArea = {
3
4
  x: number;
4
5
  y: number;
@@ -28,6 +29,13 @@ export type WorkspaceAttachment = {
28
29
  size: number;
29
30
  previewUrl?: string;
30
31
  };
32
+ export type CommentContext = {
33
+ width: number;
34
+ height: number;
35
+ url: string;
36
+ capturedAt: string;
37
+ deployment?: string;
38
+ };
31
39
  export type WorkspaceReply = {
32
40
  id?: string;
33
41
  text: string;
@@ -42,6 +50,12 @@ export type WorkspaceReply = {
42
50
  export type WorkspaceComment = CommentAnchor & {
43
51
  id: string;
44
52
  path: string;
53
+ breakpoint?: PreviewBreakpoint;
54
+ context?: CommentContext;
55
+ status?: "open" | "ready" | "resolved";
56
+ statusBy?: string;
57
+ statusAt?: string;
58
+ reviewRoundId?: string;
45
59
  text: string;
46
60
  author: string;
47
61
  authorId?: string;
@@ -82,6 +96,14 @@ export type CommentMutation = {
82
96
  type: "resolve";
83
97
  id: string;
84
98
  resolved: boolean;
99
+ } | {
100
+ type: "status";
101
+ id: string;
102
+ status: "open" | "ready" | "resolved";
103
+ } | {
104
+ type: "snapshot";
105
+ id: string;
106
+ attachmentTokens: string[];
85
107
  };
86
108
  export type CommentStore = {
87
109
  list(): Promise<WorkspaceComment[]>;
@@ -0,0 +1,20 @@
1
+ export type ReviewProject = {
2
+ siteId: string;
3
+ name: string;
4
+ role: string;
5
+ reviewURL: string | null;
6
+ reviewers: {
7
+ email: string;
8
+ role: string;
9
+ }[];
10
+ round: {
11
+ id: string;
12
+ deployment: string;
13
+ reviewURL: string;
14
+ createdAt: string;
15
+ outstanding: number;
16
+ approvals: number;
17
+ approvedByMe: boolean;
18
+ } | null;
19
+ };
20
+ export type ManageReview = (action: string, payload?: Record<string, unknown>) => Promise<ReviewProject>;
@@ -0,0 +1,4 @@
1
+ import type { WorkspaceComment } from "./comments";
2
+ export declare function publicReviewURL(value: string): string | null;
3
+ export declare function commentURL(base: string, comment: WorkspaceComment): string;
4
+ export declare function feedbackMarkdown(comments: WorkspaceComment[], base: string): string;
@@ -1,5 +1,6 @@
1
1
  import { type ReactNode } from "react";
2
2
  import { type WorkspaceComposerProps } from "./comment-box";
3
+ import type { ManageReview } from "./project-controls";
3
4
  import { type WorkspaceAttachment, type WorkspaceComment as Comment, type CommentStore } from "./comments";
4
5
  export type WorkspaceUser = {
5
6
  id: string;
@@ -26,6 +27,7 @@ export type WorkspaceThreadProps = {
26
27
  saving: boolean;
27
28
  canResolve: boolean;
28
29
  submittingReply?: boolean;
30
+ draftKey?: string;
29
31
  userId?: string;
30
32
  onEdit?(replyId: string | null, text: string, body: unknown): Promise<boolean>;
31
33
  onEditDraftChange?(hasDraft: boolean): void;
@@ -45,7 +47,7 @@ export type WorkspaceCommentUI = {
45
47
  renderThread(props: WorkspaceThreadProps): ReactNode;
46
48
  };
47
49
  export declare function elementSelector(element: Element): string;
48
- export default function ChiselWorkspace({ user, validateSession, signOut, commentStore, canManageComments, getReviewLink, collaboration, commentUI }: {
50
+ export default function ChiselWorkspace({ user, validateSession, signOut, commentStore, canManageComments, getReviewLink, collaboration, commentUI, projectId, manageReview, accountURL, agentURL, saveSnapshot, getAttachmentURL }: {
49
51
  user: WorkspaceUser;
50
52
  validateSession: () => Promise<boolean>;
51
53
  signOut: () => Promise<void>;
@@ -54,4 +56,10 @@ export default function ChiselWorkspace({ user, validateSession, signOut, commen
54
56
  getReviewLink?: (rotate?: boolean) => Promise<string>;
55
57
  collaboration?: WorkspaceCollaboration;
56
58
  commentUI?: WorkspaceCommentUI;
59
+ projectId?: string;
60
+ manageReview?: ManageReview;
61
+ accountURL?: string;
62
+ agentURL?: string;
63
+ saveSnapshot?: (id: string, file: File) => Promise<void>;
64
+ getAttachmentURL?: (id: string) => Promise<string>;
57
65
  }): import("react").JSX.Element;
@@ -2,5 +2,6 @@ export { default as ChiselWorkspace } from "./workspace/workspace";
2
2
  export type { WorkspaceUser, WorkspaceCollaboration, WorkspaceCommentUI, WorkspaceThreadProps } from "./workspace/workspace";
3
3
  export { ChiselPreview } from "./workspace/preview";
4
4
  export { ChiselWorkspaceStyles } from "./workspace/styles";
5
- export type { CommentStore, CommentMutation, CommentArea, WorkspaceComment, WorkspaceReply, WorkspaceAttachment } from "./workspace/comments";
5
+ export type { CommentStore, CommentMutation, CommentArea, CommentContext, WorkspaceComment, WorkspaceReply, WorkspaceAttachment } from "./workspace/comments";
6
+ export type { ManageReview, ReviewProject } from "./workspace/project-controls";
6
7
  export type { WorkspaceComposerProps } from "./workspace/comment-box";