use-chisel 0.1.9 → 0.1.10

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 Ze,createElement as Je}from"react";var xe=e=>e?.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase();function Ce(e,a,o=[]){if(a==null)throw new Error("[lucide]: iconNode is required when icon name is used");return{name:xe(e),size:24,node:a,...o.length>0?{aliases:o}:{}}}var he=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 ge=e=>{let a=he(e);return a.charAt(0).toUpperCase()+a.slice(1)};import{forwardRef as Ke,createElement as ye}from"react";var G=(...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 de(e){return e!=null}function Se(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}`)??[],c=[...e.name?[`lucide-${e.name}`]:[],...r],i=a.className?.split(" ").filter(Boolean)??[],L=a.includeDefaultClasses===!1?G(...i):G("lucide",...c,...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,n])=>(d[t(f)]=n,d),{}),..."color"in a&&a.color&&{[t("stroke")]:a.color},..."size"in a&&de(a.size)&&{[t("width")]:a.size,[t("height")]:a.size},..."width"in a&&de(a.width)&&{[t("width")]:a.width},..."height"in a&&de(a.height)&&{[t("height")]:a.height},[t("stroke-width")]:s,...L&&{[t("class")]:L},[t("viewBox")]:`0 0 ${l} ${u}`,...a.hasA11yProp===!1?{[t("aria-hidden")]:"true"}:{},..."attributes"in a&&a.attributes},e.node.map(d=>{let[f,n,x]=d,h=a.nonScalingStroke?{[t("vector-effect")]:"non-scaling-stroke",...n}:n;return x?[f,h,x]:[f,h]})]}function ke(e,a={}){return Se(e,{...a,attributeNames:{...a.attributeNames,class:"className","stroke-width":"strokeWidth","stroke-linecap":"strokeLinecap","stroke-linejoin":"strokeLinejoin","vector-effect":"vectorEffect"}})}var we=e=>{for(let a in e)if(a.startsWith("aria-")||a==="role"||a==="title")return!0;return!1};import{createContext as ze,useContext as Ne,useMemo as Va,createElement as za}from"react";var Xe=ze({});var Pe=()=>Ne(Xe);var Ae=Ke(({color:e,size:a,width:o,height:t,strokeWidth:l,absoluteStrokeWidth:u,nonScalingStroke:r,className:c="",children:i,iconNode:L=[],icon:s={node:L,aliases:[],size:24},...m},d)=>{let{size:f=24,strokeWidth:n=2,absoluteStrokeWidth:x=!1,nonScalingStroke:h=!1,color:R="currentColor",className:S=""}=Pe()??{},F=!!i||we(m),[ae,te,I=[]]=ke(s,{color:e??R,width:o??a??f,height:t??a??f,strokeWidth:l??n,absoluteStrokeWidth:u??x,nonScalingStroke:r??h,className:G(S,c),hasA11yProp:F,attributes:m});return ye(ae,{ref:d,...te},[...I.map(([g,b])=>ye(g,b)),...Array.isArray(i)?i:[i]])});function k(e,a=[],o=[]){let t=typeof e=="string"?Ce(e,a,o):e,l=Ze(({className:u,...r},c)=>Je(Ae,{ref:c,icon:t,className:u,...r}));return t.name&&(l.displayName=ge(t.name)),l}var Qe={name:"arrow-up",size:24,node:[["path",{d:"m5 12 7-7 7 7",key:"hav0vg"}],["path",{d:"M12 19V5",key:"x0mq9r"}]]},W=k(Qe);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"}]]},V=k($e);var _e={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"}]]},z=k(_e);var je={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"}]]},N=k(je);var Ye={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"}]]},X=k(Ye);var ea={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"}]]},K=k(ea);var aa={name:"x",size:24,node:[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]},q=k(aa);import{useEffect as U,useRef as y,useState as Q}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 _(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 le(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 H(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 re(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 j=["image/jpeg","image/png","image/gif","image/webp","image/avif","image/bmp"],Be=["video/mp4","video/webm","video/quicktime"],De=[...j,...Be].join(",");function Me(e){let a=j.includes(e.type);return!a&&!Be.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 ta,useRef as Re,useState as be}from"react";import{createEditor as oa,Editor as C,Element as E,Node as ua,Path as da,Range as se,Transforms as M}from"slate";import{withHistory as la}from"slate-history";import{Editable as ra,Slate as sa,withReact as fa,ReactEditor as Fe}from"slate-react";import{Fragment as qe,jsx as w,jsxs as Ue}from"react/jsx-runtime";function fe(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 ve(e){return{version:1,content:e.map(a=>({type:"paragraph",children:E.isElement(a)?a.children.map(o=>E.isElement(o)?{type:"link",url:o.url,text:ua.string(o)}:{...o}):[{text:a.text}]}))}}function ie(e){return/^(https?:\/\/|mailto:)[^\s]+$/i.test(e)}function ia(e,a){if(!e.selection){let o=window.getSelection(),t=o&&Fe.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 Te(){let e=fa(la(oa()),"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){C.above(e,{at:c,match:L=>E.isElement(L)&&L.type==="link"})||(M.wrapNodes(e,{type:"link",url:i,children:[]},{at:c,split:!0}),M.collapse(e,{edge:"end"}))}function r(){if(!e.selection||!se.isCollapsed(e.selection))return;let c=C.above(e,{match:d=>E.isElement(d)&&d.type==="paragraph"});if(!c)return;let i=e.selection.anchor,s=C.string(e,{anchor:C.start(e,c[1]),focus:i}).match(/\S+$/)?.[0];if(!s||!ie(s))return;let m=C.before(e,i,{distance:s.length,unit:"offset"});if(m){u({anchor:m,focus:i},s);let d=C.above(e,{match:f=>E.isElement(f)&&f.type==="link"});d&&e.selection&&C.isEnd(e,e.selection.anchor,d[1])&&M.select(e,C.start(e,da.next(d[1])))}}return e.insertText=c=>{if(Fe.isComposing(e)){o(c);return}c===" "&&r();let i={"*":"bold",_:"italic","~":"strikethrough","`":"code"}[c];if(i&&e.selection&&se.isCollapsed(e.selection)){let L=C.above(e,{match:s=>E.isElement(s)&&s.type==="paragraph"});if(L){let s=e.selection.anchor,m=C.string(e,{anchor:C.start(e,L[1]),focus:s}),d=m.lastIndexOf(c),f=m.slice(d+1);if(d>=0&&(!d||/[\s*_~`]/.test(m[d-1]))&&f&&f.trim()===f){let n=C.before(e,s,{distance:f.length,unit:"offset"}),x=n&&C.before(e,n,{unit:"offset"});if(n&&x){M.select(e,{anchor:n,focus:s}),C.addMark(e,i,!0),M.collapse(e,{edge:"end"}),M.delete(e,{at:{anchor:x,focus:n}}),C.removeMark(e,i);return}}}}o(c)},e.insertBreak=()=>{r(),l()},e.insertData=c=>{let i=c.getData("text/plain");ie(i)?e.selection&&!se.isCollapsed(e.selection)?u(e.selection,i):M.insertNodes(e,[{type:"link",url:i,children:[{text:i}]},{text:""}]):t(c)},e}function ca({attributes:e,children:a,element:o}){return o.type==="link"?w("a",{...e,href:ie(o.url)?o.url:void 0,onClick:t=>t.preventDefault(),children:a}):w("p",{...e,children:a})}function na({attributes:e,children:a,leaf:o}){let t=w(qe,{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 Z({onFiles:e,disabled:a}){let o=Re(null);return Ue(qe,{children:[w("input",{ref:o,type:"file",accept:De,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(z,{size:16,strokeWidth:1.75})})]})}function J({text:e,defaultBody:a,disabled:o,label:t,placeholder:l,autoFocus:u,onChange:r,onSubmit:c,onFiles:i,uploading:L}){let[s]=be(Te),[m]=be(()=>fe(a??D(e))),d=Re(e);return ta(()=>{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:(n,x)=>x.length===1}),M.insertNodes(s,fe(D(e)),{at:[0]}),M.deselect(s)}),e||(s.history={undos:[],redos:[]}))},[s,e]),Ue(sa,{editor:s,initialValue:m,onChange:f=>{if(!s.operations.some(x=>x.type!=="set_selection"))return;let n=ve(f);d.current=$(n),r(d.current,n)},children:[w(ra,{className:"review-composer-editor",role:"textbox","aria-multiline":"true","aria-label":t,placeholder:l,readOnly:o,autoFocus:u,renderElement:ca,renderLeaf:na,onKeyDown:f=>{if(f.nativeEvent.isComposing)return;let n=f.metaKey||f.ctrlKey;if(f.key==="Enter"){f.preventDefault(),n?s.insertBreak():c();return}let x=n?{b:"bold",i:"italic",e:"code",...f.shiftKey?{s:"strikethrough"}:{}}[f.key.toLowerCase()]:void 0;x&&(f.preventDefault(),ia(s,x))}}),i&&w("div",{className:"chisel-attachment-controls",children:w(Z,{onFiles:i,disabled:o||L})})]})}import{useEffect as pa,useRef as ma,useState as La}from"react";import{Fragment as Oe,jsx as P,jsxs as Y}from"react/jsx-runtime";function Ia({src:e,name:a,mimeType:o,onError:t,close:l}){let u=ma(null);return pa(()=>{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:Y("div",{className:"review-media-lightbox-content",children:[Y("header",{children:[P("span",{children:a}),P("a",{href:e,download:a,"aria-label":`Download ${a}`,title:"Download",children:P(V,{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 ee({src:e,name:a,mimeType:o,onError:t}){let[l,u]=La(!1);return Y(Oe,{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}):Y(Oe,{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(X,{size:20,fill:"currentColor"})})]})}),l&&P(Ia,{src:e,name:a,mimeType:o,onError:t,close:()=>u(!1)})]})}import{Fragment as ka,jsx as p,jsxs as A}from"react/jsx-runtime";function ce(e,a,o){if(e)try{let t=le(e);if(t?.text===a&&$(t.body)===a)return t.body}catch{}return o??D(a)}function ne(e,a,o,t=!1){e&&H(e,t||a.trim()?{text:a,body:o}:null)}function He({body:e}){return p("div",{className:"review-comment-body",children:e.content.map((a,o)=>p("p",{children:a.children.map((t,l)=>{if("type"in t&&t.type==="link")return p("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=p(ka,{children:t.text});return"bold"in t&&t.bold&&(u=p("strong",{children:u})),"italic"in t&&t.italic&&(u=p("em",{children:u})),"strikethrough"in t&&t.strikethrough&&(u=p("s",{children:u})),"code"in t&&t.code&&(u=p("code",{children:u})),p("span",{children:u},l)})},o))})}function xa({attachment:e,loadMedia:a}){let[o,t]=Q(e.previewUrl??""),[l,u]=Q(!1),[r,c]=Q(0),i=y(0);U(()=>{if(e.previewUrl){t(e.previewUrl);return}t("");let s=!0,m=!1,d=new AbortController;async function f(){if(!(m||document.visibilityState==="hidden")){m=!0;try{let h=await a(e.id,d.signal);s&&(t(h),u(!1),i.current=Date.now()+240*1e3)}catch{s&&u(!0)}finally{m=!1}}}function n(){Date.now()>=i.current&&f()}f();let x=window.setInterval(n,60*1e3);return window.addEventListener("focus",n),document.addEventListener("visibilitychange",n),()=>{s=!1,d.abort(),window.clearInterval(x),window.removeEventListener("focus",n),document.removeEventListener("visibilitychange",n)}},[e.id,e.previewUrl,r,a]);function L(){u(!0),Date.now()>=i.current&&c(s=>s+1)}return A("figure",{className:"review-attachment",children:[o&&!l?p(ee,{src:o,name:e.name,mimeType:e.mimeType,onError:L}):p("div",{className:"review-attachment-placeholder",role:"status",children:l?p("button",{type:"button",className:"review-retry-upload",onClick:()=>c(s=>s+1),children:"Retry attachment"}):"Loading attachment\u2026"}),p("figcaption",{children:e.name})]})}function Ee(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:r,onCancelEdit:c,onSaveEdit:i,onDraftChange:L,onEditStyles:s,draftKey:m}){let[d,f]=Q(e.text),n=y(e.body??D(e.text)),x=y(!1),h=y(!1);U(()=>{l?L(d!==e.text||JSON.stringify(n.current)!==JSON.stringify(e.body??D(e.text))):h.current&&m&&H(m,null),h.current=l},[l]),U(()=>{l||(f(e.text),n.current=e.body??D(e.text))},[l,e.text,e.body]);async function R(){if(!(u||x.current||!d.trim()&&!e.attachments?.length)){x.current=!0;try{await i(d.trimEnd(),_(n.current))&&(m&&H(m,null),L(!1))}finally{x.current=!1}}}return A("article",{className:"review-comment","data-activity":a,children:[p("span",{className:"review-comment-avatar",children:e.authorImage?p("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:[p("span",{className:"review-comment-author",children:e.author}),e.pending?p("span",{className:"review-comment-time",role:"status",children:"Sending\u2026"}):p("time",{className:"review-comment-time",dateTime:e.date,title:new Date(e.date).toLocaleString(),children:Ee(e.date)}),t&&!l&&p("button",{type:"button",className:"review-comment-edit","aria-label":"Edit comment",title:"Edit comment",disabled:u,onClick:()=>{let S=m?le(m):null;S&&typeof S.text=="string"&&(f(S.text),n.current=ce(m,S.text)),r()},children:p(N,{size:16})})]}),l?A("form",{className:"review-inline-edit",onSubmit:S=>{S.preventDefault(),R()},children:[p(J,{text:d,defaultBody:n.current,disabled:u,label:"Edit comment",placeholder:"Edit comment\u2026",autoFocus:!0,onSubmit:()=>{R()},onChange:(S,F)=>{f(S),n.current=F,ne(m,S,F,!0),L(S!==e.text||JSON.stringify(F)!==JSON.stringify(e.body??D(e.text)))}}),A("div",{className:"review-inline-edit-actions",children:[s&&p("button",{type:"button",disabled:u,onClick:s,children:"Edit styles"}),p("button",{type:"button",disabled:u,onClick:c,children:"Cancel"}),p("button",{type:"submit",disabled:u||!d.trim()&&!e.attachments?.length,children:"Save"})]})]}):p(He,{body:e.body??D(e.text)}),e.attachments?.length>0&&p("div",{className:"review-attachments",children:e.attachments.map(S=>p(xa,{attachment:S,loadMedia:o},S.id))})]})]})}function ha(e){let a=e.useAttachments(e.disabled,e.existingAttachments?.length??0),o=y(ce(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(),_(o.current),a.tokens,a.previews)&&(e.draftKey&&H(e.draftKey,null),a.clear())}finally{t.current=!1}}}return p("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:[p(J,{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,ne(e.draftKey,u,r),e.onText(u)}}),a.previewsUI,a.controls]}),a.attachments.length>0||!!e.existingAttachments?.length,a.blocked,p(Z,{onFiles:a.upload,disabled:e.disabled||a.uploading}))})}function ga(e){let a=e.useAttachments(e.saving),o=y(ce(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(),_(o.current),a.tokens,a.previews)&&(e.draftKey&&H(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:[p("span",{className:"feedback-avatar feedback-reply-avatar",children:e.replyAuthor?.image?p("img",{src:e.replyAuthor.image,alt:""}):(e.replyAuthor?.name||"You").slice(0,1).toUpperCase()}),A("div",{className:"chisel-reply-field",children:[p(J,{text:e.reply,defaultBody:o.current,disabled:e.saving,label:"Reply",placeholder:"Write a reply\u2026",onSubmit:()=>{l()},onChange:(u,r)=>{o.current=r,ne(e.draftKey,u,r),e.onReplyText(u)}}),a.previewsUI,a.controls,p("div",{className:"chisel-attachment-controls",children:p(Z,{onFiles:a.upload,disabled:e.saving||a.uploading})}),p("button",{type:"submit",className:"chisel-reply-submit","aria-label":"Reply",disabled:e.saving||a.blocked||!e.reply.trim()&&!a.attachments.length,children:p(W,{size:16,strokeWidth:1.75})})]})]})}function Sa(e){let a=e.comment,[o,t]=Q(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 c(d){d&&e.onBeginEdit&&!await e.onBeginEdit()||!d&&l.current&&e.onDiscardEdit&&!await e.onDiscardEdit()||(r(!1),t(d))}function i(d,f){return p(Ca,{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:()=>{c(d.id)},onCancelEdit:()=>{c(null)},onDraftChange:r,onSaveEdit:async(n,x)=>{let h=await e.onEdit?.(f?null:d.id,n,x);return h&&(r(!1),t(null)),!!h}},d.id)}let L=y(null),s=y(new Set),m=y(a.readActivity??0);return U(()=>{if(!e.expanded||!L.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 R of x)R.isIntersecting&&R.intersectionRatio>0&&s.current.add(Number(R.target.dataset.activity));let h=re(Math.max(m.current,a.readActivity??0),d,s.current);h>m.current&&(m.current=h,e.onRead(a.id,h))},{threshold:0});function n(){if(f.disconnect(),document.visibilityState==="visible")for(let x of L.current?.querySelectorAll("[data-activity]")??[])f.observe(x)}return n(),document.addEventListener("visibilitychange",n),()=>{f.disconnect(),document.removeEventListener("visibilitychange",n)}},[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 ",Ee(a.context.capturedAt)]})]}),A("div",{ref:L,className:"review-thread",children:[i(a,!0),e.expanded&&a.replies.map(d=>i(d,!1))]}),e.expanded?!o&&p(ga,{...e}):p("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 Ge,useRef as We}from"react";function wa(e,a){let o=We(new Map),t=We(!1),l=Ge(async()=>{if(!t.current){t.current=!0;try{for(;o.current.size;){let[r,c]=o.current.entries().next().value;try{await e(r,c)}catch(i){if([400,403,404].includes(i.status??0)){o.current.delete(r);continue}throw i}o.current.get(r)===c&&o.current.delete(r),a(r,c)}}catch{}finally{t.current=!1}}},[e,a]),u=Ge((r,c)=>{o.current.set(r,Math.max(c,o.current.get(r)??0)),l()},[l]);return{flush:l,markDisplayed:u}}import{useEffect as Pa,useRef as pe,useState as me}from"react";import{jsx as T,jsxs as Le}from"react/jsx-runtime";function ya(e=!1,a=0,o){let[t,l]=me([]),[u,r]=me(!1),[c,i]=me(""),L=pe(!0),s=pe(!1),m=pe(new Map),d=I=>o.discard(I);Pa(()=>(L.current=!0,()=>{L.current=!1;for(let I of m.current.values())URL.revokeObjectURL(I.preview),d(I).catch(()=>{})}),[]);function f(){L.current&&l([...m.current.values()].map(I=>({...I})))}function n(){for(let I of m.current.values())URL.revokeObjectURL(I.preview);m.current.clear(),L.current&&(l([]),i(""))}async function x(I){let g=m.current.get(I);if(!(!g||s.current||e)){s.current=!0,r(!0);try{await d(g),m.current.delete(I),URL.revokeObjectURL(g.preview),f(),i("")}catch(b){L.current&&i(b instanceof Error?b.message:"The attachment could not be removed.")}finally{s.current=!1,L.current&&r(!1)}}}async function h(I){for(let g of I){if(!L.current)return;let b=g.status==="failed";g.status="uploading",f();try{g.token=await o.send(g,b,()=>L.current),g.status="ready"}catch(B){g.status="failed",L.current&&i(B instanceof Error?B.message:"The upload failed. Your comment is still here.")}finally{L.current||await d(g).catch(()=>{})}f()}}async function R(I){if(!I?.length||s.current||e)return;let g=Array.from(I),b=g.map(B=>Me(B)).find(Boolean);if(b){i(b);return}if(a+m.current.size+g.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(!L.current)return;let oe=g.map(O=>{let ue=crypto.randomUUID(),Ie={id:ue,name:O.name,mimeType:O.type,size:O.size,file:O,bucket:j.includes(O.type)?"chisel-review-images":"chisel-review-videos",path:`${B}/${ue}`,preview:URL.createObjectURL(O),stored:!1,status:"uploading"};return m.current.set(ue,Ie),Ie});f(),await h(oe)}catch(B){L.current&&i(B instanceof Error?B.message:"The upload failed. Your comment is still here.")}finally{s.current=!1,L.current&&r(!1)}}async function S(){if(!(s.current||e)){s.current=!0,r(!0),i("");try{await h([...m.current.values()].filter(I=>I.status==="failed"))}finally{s.current=!1,L.current&&r(!1)}}}let F=t.some(I=>I.status==="failed"),ae=Le("div",{className:"chisel-attachment-controls",children:[u&&T("span",{role:"status",children:"Uploading\u2026"}),F&&Le("button",{type:"button",className:"review-retry-upload",disabled:u||e,onClick:()=>{S()},children:[T(K,{size:16,strokeWidth:1.75}),"Retry upload"]}),c&&T("span",{className:"chisel-attachment-error",role:"alert",children:c})]}),te=t.length>0&&T("div",{className:"chisel-attachment-previews",children:t.map(I=>Le("div",{className:"chisel-attachment-preview","data-state":I.status,children:[T(ee,{src:I.preview,name:I.name,mimeType:I.mimeType}),T("span",{title:I.name,children:I.name}),T("button",{type:"button","aria-label":`Remove ${I.name}`,disabled:u||e,onClick:()=>{x(I.id)},children:T(q,{size:16,strokeWidth:1.75})})]},I.id))});return{attachments:t,uploading:u,blocked:u||F,controls:ae,previewsUI:te,clear:n,upload:R,previews:t.map(({id:I,name:g,mimeType:b,size:B,preview:oe})=>({id:I,name:g,mimeType:b,size:B,previewUrl:oe})),tokens:t.flatMap(I=>I.token?[I.token]:[])}}var Ve=new WeakMap;async function Aa(e,a,o){let t=Ve.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"},Ve.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{Z as ReviewAttachmentButton,He as ReviewBody,ha as ReviewComposer,J as ReviewEditor,Sa as ReviewThread,fe as bodyToEditor,Te as createReviewEditor,re as displayedActivity,ve as editorToBody,Aa as uploadSnapshot,wa as useReadQueue,ya 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";