@iclips/ui 3.0.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/DESIGN.md ADDED
@@ -0,0 +1,246 @@
1
+ ---
2
+ version: 3.0.0
3
+ name: iClips Design Language
4
+ description: The visual language of @iclips/ui 3.0.0 — one purple for action, a lot of grey for structure, and colour only where it means something, set in Inter.
5
+ source: "@iclips/ui 3.0.0 — tokens/*.json, src/styles/tokens.css and the components under src/components/ui"
6
+ scope: Colour, type, radius, buttons and surfaces. Spacing lives in tokens/spacing.json; elevation and motion live in the component styles.
7
+
8
+ colors:
9
+ # semantic tokens — light theme value (dark theme value in the comment)
10
+ background: "#FFFFFF" # dark #1A1F26
11
+ foreground: "#1A1F26" # dark #F2F6FA
12
+ card: "#FFFFFF" # dark #2F3640
13
+ muted: "#E9EEF5" # dark #464E59
14
+ muted-foreground: "#464E59" # dark #C5CDD9
15
+ accent: "#E9EEF5" # hover — dark #464E59
16
+ border: "#DAE1EB" # dark #464E59
17
+ input: "#DAE1EB" # dark #464E59
18
+ primary: "#7F26BF" # dark #DAA6FF (purple-100: passa AA sobre card/popover gray-700)
19
+ primary-foreground: "#FFFFFF" # dark #000000
20
+ secondary: "#F6E9FF" # selection — dark #420F66
21
+ secondary-foreground: "#420F66" # dark #DAA6FF
22
+ ring: "#7F26BF" # dark #BB6DF2
23
+ destructive: "#AB4A43"
24
+ success: "#427748"
25
+ warning: "#E4BB78" # dark #CFA066
26
+ info: "#315687"
27
+
28
+ typography:
29
+ body:
30
+ fontFamily: Inter
31
+ fontSize: 14px
32
+ fontWeight: 400
33
+ caption:
34
+ fontFamily: Inter
35
+ fontSize: 12px
36
+ fontWeight: 400
37
+ label:
38
+ fontFamily: Inter
39
+ fontSize: 14px
40
+ fontWeight: 500
41
+ button:
42
+ fontFamily: Inter
43
+ fontSize: 14px
44
+ fontWeight: 600
45
+ title:
46
+ fontFamily: Inter
47
+ fontWeight: 600
48
+ lineHeight: 1.2
49
+
50
+ rounded:
51
+ sm: 6px
52
+ md: 8px
53
+ lg: 10px
54
+ xl: 14px
55
+ full: 9999px
56
+
57
+ components:
58
+ button-default:
59
+ backgroundColor: "{colors.primary}"
60
+ textColor: "{colors.primary-foreground}"
61
+ typography: "{typography.button}"
62
+ rounded: "{rounded.md}"
63
+ button-secondary:
64
+ backgroundColor: "{colors.secondary}"
65
+ textColor: "{colors.secondary-foreground}"
66
+ typography: "{typography.button}"
67
+ rounded: "{rounded.md}"
68
+ button-outline:
69
+ backgroundColor: "{colors.background}"
70
+ textColor: "{colors.foreground}"
71
+ borderColor: "{colors.border}"
72
+ typography: "{typography.button}"
73
+ rounded: "{rounded.md}"
74
+ button-ghost:
75
+ textColor: "{colors.foreground}"
76
+ typography: "{typography.button}"
77
+ rounded: "{rounded.md}"
78
+ button-link:
79
+ textColor: "{colors.primary}"
80
+ typography: "{typography.button}"
81
+ button-destructive:
82
+ backgroundColor: "color-mix({colors.destructive} 10%)"
83
+ textColor: "{colors.destructive-emphasis}"
84
+ typography: "{typography.button}"
85
+ rounded: "{rounded.md}"
86
+ button-success:
87
+ backgroundColor: "color-mix({colors.success} 10%)"
88
+ textColor: "{colors.success-emphasis}"
89
+ typography: "{typography.button}"
90
+ rounded: "{rounded.md}"
91
+ card:
92
+ backgroundColor: "{colors.card}"
93
+ borderColor: "{colors.border}"
94
+ textColor: "{colors.foreground}"
95
+ rounded: "{rounded.xl}"
96
+ ---
97
+
98
+ > **Precedência.** Este documento resume o que a `@iclips/ui` 3.0.0 entrega. A
99
+ > fonte de verdade são `tokens/*.json` (e o `src/styles/tokens.css` gerado) e o
100
+ > código dos componentes; se algo aqui divergir deles, o código vence e este
101
+ > arquivo está desatualizado. Os nomes em `colors.*`, `rounded.*` e
102
+ > `components.*` acima correspondem aos tokens semânticos e às variantes reais —
103
+ > no código, escreva `bg-primary`, `rounded-md`, `<Button variant="outline">`.
104
+ > A página Storybook `Fundamentos/Cores` mostra cada par com o contraste medido.
105
+
106
+ ## Overview
107
+
108
+ **Um roxo, muito cinza, e cor só onde ela significa algo.** Roxo é ação — botão
109
+ primário, link, seleção, foco. Cinza é estrutura — fundo, card, borda, texto, onde
110
+ fica a maior parte da tela. Vermelho, verde, amarelo e azul são estado — feedback,
111
+ nunca decoração. Nenhuma outra cor existe na lib: só tokens semânticos viram
112
+ classe, e o `npm run lint` reprova cor crua.
113
+
114
+ **Key characteristics**
115
+
116
+ - Quatro camadas de cor com permissão fechada: estrutura (cinza), ação (roxo),
117
+ estado (feedback), categoria (só em gráfico)
118
+ - Uma cor de ação; a hierarquia entre ações vem do preenchimento
119
+ - Hover é cinza; lavanda significa selecionado
120
+ - Peso 600 marca ação e título; o corpo fica em 400
121
+ - Raios de 6 a 10px no que se clica e no que flutua; 14px nos contêineres
122
+
123
+ ## Colours
124
+
125
+ Só existem tokens semânticos como classe. Os primitivos por trás deles — gray
126
+ 50–900, purple 50–500 e 700, e o preenchimento de cada estado — são custom
127
+ properties de fiação, sem classe. Os valores estão no cabeçalho deste arquivo,
128
+ claro e escuro.
129
+
130
+ ### Estrutura — neutros
131
+
132
+ | Token | Uso |
133
+ | --- | --- |
134
+ | `background` / `foreground` | canvas e texto padrão |
135
+ | `card`, `popover` | superfícies elevadas |
136
+ | `muted` / `muted-foreground` | fundo sutil e texto de apoio |
137
+ | `accent` | hover e realce de item de menu — cinza, sem peso |
138
+ | `border`, `input` | divisória e borda de campo |
139
+
140
+ ### Ação — roxo, exclusivo
141
+
142
+ | Token | Uso |
143
+ | --- | --- |
144
+ | `primary` / `primary-foreground` | botão primário, link, foco, progresso |
145
+ | `secondary` / `secondary-foreground` | item selecionado, ação secundária |
146
+ | `ring` | anel de foco |
147
+ | `sidebar-selected` | item ativo da sidebar |
148
+
149
+ Selecionado > focado > sob o cursor: seleção em `secondary` (matiz, tinta e peso
150
+ 500), foco em anel, hover em `accent` cinza. Fundo lavanda decorativo só em tela
151
+ sem lista, tabela, menu ou calendário — onde há o que selecionar, ele se lê como
152
+ seleção.
153
+
154
+ ### Estado — feedback, nunca decoração
155
+
156
+ Estado é sempre suave: o token cru (`destructive`, `success`, `warning`,
157
+ `info`) nunca é fundo. A receita única é
158
+ `bg-<status>/10 text-<status>-emphasis border-<status>/20`, em Button e Badge de
159
+ estado, Alert e selo. A cor cheia fica só no ícone e na borda de campo inválido.
160
+ Status nunca é roxo e sempre vem com ícone ou rótulo.
161
+
162
+ ### Categoria — só dados
163
+
164
+ `chart-1..8` alternam roxo e cinza em luminância, começando pelo roxo. Nunca em
165
+ botão, link, ícone de navegação ou fundo de seção.
166
+
167
+ ## Typography
168
+
169
+ A lib não embarca fonte: o app instala **Inter**, e o `body` usa
170
+ `var(--font-sans)`. A lib não estiliza elementos soltos (`h1`…`h6`, `p`, `label`)
171
+ — só o `body` e os próprios componentes.
172
+
173
+ | Papel | Tamanho | Peso | Onde |
174
+ | --- | --- | --- | --- |
175
+ | `{typography.body}` | 14px (`text-sm`) | 400 | texto de componente, campos, menus |
176
+ | `{typography.caption}` | 12px (`text-xs`) | 400 | badge, ajuda, metadado |
177
+ | `{typography.label}` | 14px | 500 | rótulo, item selecionado |
178
+ | `{typography.button}` | 14px | 600 | todas as variantes do `Button` |
179
+ | `{typography.title}` | — | 600 | `CardTitle` e títulos de seção |
180
+
181
+ **Peso 600 significa ação ou título.** Negrito no corpo do texto não tem papel.
182
+
183
+ ## Shape
184
+
185
+ Tudo deriva de `--radius` (10px).
186
+
187
+ | Token | Valor | Uso |
188
+ | --- | --- | --- |
189
+ | `{rounded.sm}` | 6px | item de menu, chips, tags |
190
+ | `{rounded.md}` | 8px | botão, input, popover, menu, tooltip |
191
+ | `{rounded.lg}` | 10px | dialog |
192
+ | `{rounded.xl}` | 14px | contêiner — `Card` e painéis grandes |
193
+ | `{rounded.full}` | 9999px | avatar, badge, indicadores |
194
+
195
+ Quanto maior a superfície, maior o raio; não há botão em pílula.
196
+
197
+ ## Buttons
198
+
199
+ Sete variantes, todas em `{typography.button}` e `{rounded.md}`, com altura de
200
+ 32 (`sm`), 36 (`default`) ou 40px (`lg`); `icon` é 36×36.
201
+
202
+ - **`default`** — roxo cheio. A ação principal da tela; uma por tela.
203
+ - **`secondary`** — lavanda com texto roxo. Ação secundária.
204
+ - **`outline`** — fundo neutro com borda; hover cinza.
205
+ - **`ghost`** — sem fundo; hover cinza. Barras de ferramenta e ações densas.
206
+ - **`link`** — texto roxo sublinhado no hover.
207
+ - **`destructive`** — suave: tinta vermelha a 10%, texto `destructive-emphasis`,
208
+ borda leve. Excluir, ação irreversível.
209
+ - **`success`** — suave, mesma receita em verde. Confirmar um estado positivo.
210
+
211
+ Clique: no `default` o preenchimento vai a 90% (hover) e 80% (pressionado); no
212
+ `destructive`/`success` a tinta sobe de 10% para 15% (hover) e 20% (pressionado).
213
+ O foco é um anel de 3px em `ring`.
214
+
215
+ ## Surfaces
216
+
217
+ **`card`** — `bg-card` com borda `border` e `{rounded.xl}`. O contêiner padrão;
218
+ a definição vem da borda, não de sombra.
219
+
220
+ Popover, menus e dialog usam `popover` e sombra; o `Tooltip` é neutro invertido
221
+ (`bg-foreground text-background`).
222
+
223
+ ## Do and don't
224
+
225
+ **Do**
226
+
227
+ - Use roxo para a ação principal, links, seleção e foco — e só para isso.
228
+ - Use `text-<status>-emphasis` para texto de estado, sempre com ícone ou rótulo.
229
+ - Use no máximo dois fundos por tela: `muted` e `background`; o terceiro, quando
230
+ existir, é `secondary`.
231
+ - Mantenha um botão `default` por tela; o segundo vira `secondary` ou `outline`.
232
+
233
+ **Don't**
234
+
235
+ - Não escreva cor crua (`bg-gray-100`, `text-purple-600`): ela não gera CSS e o
236
+ lint reprova. Use o token semântico.
237
+ - Não pinte fundo de seção com cor de estado — o badge carrega o estado, não o card.
238
+ - Não use cor de gráfico (`chart-N`) fora de dados.
239
+ - Não use negrito para dar ênfase no corpo do texto.
240
+
241
+ ## Scope and limits
242
+
243
+ Este arquivo cobre **cor, tipo, raio, botões e superfícies** da lib. Espaçamento
244
+ está em `tokens/spacing.json`; elevação e movimento, nos estilos dos
245
+ componentes. A régua de cada componente (anatomia, variantes, acessibilidade)
246
+ está em `src/components/ui/AGENTS.md`.
package/README.md CHANGED
@@ -17,6 +17,10 @@ import { Button, Dialog } from "@iclips/ui";
17
17
  import { DocumentEditor } from "@iclips/ui/editor";
18
18
  ```
19
19
 
20
+ **Para agentes de IA (e para quem monta tela):** o guia de uso — qual componente
21
+ em cada situação, com código pronto — vem no pacote, na versão instalada, em
22
+ `node_modules/@iclips/ui/docs/`. Comece por `docs/README.md`.
23
+
20
24
  O JS já é tree-shakeable (um módulo por componente). Falta só o CSS — dois modos:
21
25
 
22
26
  ### Modo A — CSS pré-compilado (qualquer stack, sem Tailwind)
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),_=require("react"),F=require("date-fns"),K=require("date-fns/locale"),o=require("../utils.cjs"),w=require("../primitives/avatar.cjs"),l=require("../primitives/button.cjs"),M=require("../primitives/badge.cjs"),f=require("../overlays/tooltip.cjs"),z=require("../primitives/separator.cjs"),n=require("lucide-react"),R=require("@tiptap/react"),$=require("@tiptap/starter-kit"),W=require("@tiptap/extension-underline"),G=require("@tiptap/extension-link"),V=require("@tiptap/extension-image"),X=require("@tiptap/extension-mention"),J=require("@tiptap/extension-task-list"),Q=require("@tiptap/extension-task-item"),Y=require("@tiptap/extension-file-handler"),Z=require("@tiptap/extension-highlight"),ee=require("@tiptap/extension-typography"),I=require("@tiptap/extensions"),te=require("@tiptap/extension-table"),B=require("@tiptap/extension-details"),se=require("@tiptap/extension-drag-handle-react"),re=require("tippy.js"),ie=require("./mention-list.cjs"),L=require("emoji-picker-react"),p=require("../overlays/popover.cjs");function ae(t){const u=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const c in t)if(c!=="default"){const a=Object.getOwnPropertyDescriptor(t,c);Object.defineProperty(u,c,a.get?a:{enumerable:!0,get:()=>t[c]})}}return u.default=t,Object.freeze(u)}const v=ae(_),ne=({role:t})=>{const u={internal:{label:"Equipe iClips",className:"bg-primary/10 text-primary border-primary/20"},client:{label:"Cliente",className:"bg-info/10 text-info-emphasis border-info/20"},freelancer:{label:"Freelancer",className:"bg-warning/10 text-warning-emphasis border-warning/20"}},{label:c,className:a}=u[t];return e.jsx(M.Badge,{variant:"outline",className:o.cn("text-[10px] h-5 px-1.5 font-medium border-0",a),children:c})},oe=({editor:t,visible:u,features:c={}})=>!t||!u?null:e.jsxs("div",{className:"flex items-center gap-1 border-b p-1 bg-muted/20 animate-in slide-in-from-bottom-2 duration-200",children:[e.jsx(l.Button,{variant:"ghost",size:"icon",className:o.cn("h-7 w-7",t.isActive("bold")&&"bg-muted text-primary"),onClick:()=>t.chain().focus().toggleBold().run(),title:"Negrito (Ctrl+B)","aria-label":"Negrito",children:e.jsx(n.Bold,{className:"h-3.5 w-3.5"})}),e.jsx(l.Button,{variant:"ghost",size:"icon",className:o.cn("h-7 w-7",t.isActive("italic")&&"bg-muted text-primary"),onClick:()=>t.chain().focus().toggleItalic().run(),title:"Itálico (Ctrl+I)","aria-label":"Itálico",children:e.jsx(n.Italic,{className:"h-3.5 w-3.5"})}),e.jsx(l.Button,{variant:"ghost",size:"icon",className:o.cn("h-7 w-7",t.isActive("underline")&&"bg-muted text-primary"),onClick:()=>t.chain().focus().toggleUnderline().run(),title:"Sublinhado (Ctrl+U)","aria-label":"Sublinhado",children:e.jsx(n.Underline,{className:"h-3.5 w-3.5"})}),e.jsx(z.Separator,{orientation:"vertical",className:"h-4 mx-1"}),e.jsx(l.Button,{variant:"ghost",size:"icon",className:o.cn("h-7 w-7",t.isActive("bulletList")&&"bg-muted text-primary"),onClick:()=>t.chain().focus().toggleBulletList().run(),"aria-label":"Lista com marcadores",children:e.jsx(n.List,{className:"h-3.5 w-3.5"})}),e.jsx(l.Button,{variant:"ghost",size:"icon",className:o.cn("h-7 w-7",t.isActive("orderedList")&&"bg-muted text-primary"),onClick:()=>t.chain().focus().toggleOrderedList().run(),"aria-label":"Lista numerada",children:e.jsx(n.ListOrdered,{className:"h-3.5 w-3.5"})}),e.jsx(l.Button,{variant:"ghost",size:"icon",className:o.cn("h-7 w-7",t.isActive("taskList")&&"bg-muted text-primary"),onClick:()=>t.chain().focus().toggleTaskList().run(),title:"Lista de tarefas","aria-label":"Lista de tarefas",children:e.jsx(n.ListChecks,{className:"h-3.5 w-3.5"})}),e.jsx(z.Separator,{orientation:"vertical",className:"h-4 mx-1"}),e.jsx(l.Button,{variant:"ghost",size:"icon",className:o.cn("h-7 w-7",t.isActive("highlight")&&"bg-muted text-primary"),onClick:()=>t.chain().focus().toggleHighlight().run(),title:"Marca-texto","aria-label":"Marca-texto",children:e.jsx(n.Highlighter,{className:"h-3.5 w-3.5"})}),c.table&&e.jsx(l.Button,{variant:"ghost",size:"icon",className:o.cn("h-7 w-7",t.isActive("table")&&"bg-muted text-primary"),onClick:()=>t.chain().focus().insertTable({rows:3,cols:3,withHeaderRow:!0}).run(),title:"Inserir tabela 3x3","aria-label":"Inserir tabela",children:e.jsx(n.Table,{className:"h-3.5 w-3.5"})}),c.details&&e.jsx(l.Button,{variant:"ghost",size:"icon",className:o.cn("h-7 w-7",t.isActive("details")&&"bg-muted text-primary"),onClick:()=>t.chain().focus().setDetails().run(),title:"Bloco recolhivel","aria-label":"Bloco recolhivel",children:e.jsx(n.ChevronsDownUp,{className:"h-3.5 w-3.5"})}),e.jsx(l.Button,{variant:"ghost",size:"icon",className:o.cn("h-7 w-7",t.isActive("link")&&"bg-muted text-primary"),"aria-label":"Inserir link",onClick:()=>{const a=t.getAttributes("link").href,h=window.prompt("URL",a);if(h!==null){if(h===""){t.chain().focus().extendMarkRange("link").unsetLink().run();return}t.chain().focus().extendMarkRange("link").setLink({href:h}).run()}},children:e.jsx(n.Link,{className:"h-3.5 w-3.5"})})]}),le=({currentUser:t,onSubmit:u,users:c=[],maxLength:a,placeholder:h="Escreva um comentario... use @ para mencionar",onImageUpload:j,features:i={},extensions:C})=>{const[N,k]=v.useState(!1),[y,q]=v.useState(!1),[g,x]=v.useState([]),[E,S]=v.useState(!0),P=v.useRef(null),A=v.useCallback(async(s,r,d)=>{for(const b of r){const T=j?await j(b):URL.createObjectURL(b);s.chain().insertContentAt(d??s.state.selection.anchor,{type:"image",attrs:{src:T}}).focus().run()}},[j]),H=v.useMemo(()=>[$.configure({link:!1,underline:!1}),W,G.configure({openOnClick:!1}),V,X.configure({HTMLAttributes:{class:"bg-secondary text-secondary-foreground rounded-sm px-1 py-0.5 font-medium decoration-clone"},suggestion:{items:({query:s})=>c.filter(r=>r.name.toLowerCase().startsWith(s.toLowerCase())).slice(0,5),render:()=>{let s=null,r=null;return{onStart:d=>{s=new R.ReactRenderer(ie.MentionList,{props:d,editor:d.editor}),d.clientRect&&(r=re("body",{getReferenceClientRect:d.clientRect,appendTo:()=>document.body,content:s.element,showOnCreate:!0,interactive:!0,trigger:"manual",placement:"bottom-start"}))},onUpdate(d){s==null||s.updateProps(d),d.clientRect&&(r==null||r[0].setProps({getReferenceClientRect:d.clientRect}))},onKeyDown(d){var b,T;return d.event.key==="Escape"?(r==null||r[0].hide(),!0):!!((T=(b=s==null?void 0:s.ref)==null?void 0:b.onKeyDown)!=null&&T.call(b,d))},onExit(){r==null||r[0].destroy(),s==null||s.destroy()}}}}}),J,Q.configure({nested:!0,a11y:{checkboxLabel:(s,r)=>`${r?"Concluido":"Pendente"}: ${s.textContent||"tarefa vazia"}`}}),Z,ee,I.Placeholder.configure({placeholder:h}),...a?[I.CharacterCount.configure({limit:a})]:[],Y.configure({allowedMimeTypes:["image/png","image/jpeg","image/gif","image/webp"],onDrop:(s,r,d)=>{A(s,r,d)},onPaste:(s,r)=>{A(s,r)}}),...i.table?[te.TableKit.configure({table:{resizable:!0}})]:[],...i.details?[B.Details,B.DetailsSummary,B.DetailsContent]:[],...C??[]],[c,a,h,A,i.table,i.details,C]),m=R.useEditor({extensions:H,content:"",onUpdate:({editor:s})=>{S(s.isEmpty)},editorProps:{attributes:{class:"prose prose-sm dark:prose-invert max-w-none focus:outline-none min-h-[80px] px-3 py-2 text-sm"}}}),O=s=>{if(s.target.files&&s.target.files[0]){const r=s.target.files[0],d=URL.createObjectURL(r),b={id:Math.random().toString(36).substr(2,9),name:r.name,url:d,type:r.type.startsWith("image/")?"image":"file"};x([...g,b]),s.target.value=""}},D=s=>{x(g.filter(r=>r.id!==s))},U=()=>{!m||m.isEmpty&&g.length===0||(u({content:m.getHTML(),isRevisionRequest:N,attachments:g}),m.commands.clearContent(),x([]),k(!1),S(!0))};return e.jsxs("div",{className:"flex gap-3 items-start",children:[e.jsxs(w.Avatar,{className:"h-8 w-8 mt-1 border",children:[e.jsx(w.AvatarImage,{src:t.avatar}),e.jsx(w.AvatarFallback,{children:t.name.substring(0,2).toUpperCase()})]}),e.jsxs("div",{className:o.cn("flex-1 rounded-xl border bg-background shadow-sm overflow-hidden transition-colors",N&&"border-destructive/40 ring-1 ring-destructive/20"),children:[e.jsx(oe,{editor:m,visible:y,features:i}),i.dragHandle&&e.jsx(se.DragHandle,{editor:m,children:e.jsx(n.GripVertical,{className:"text-muted-foreground h-4 w-4 cursor-grab"})}),e.jsx(R.EditorContent,{editor:m}),g.length>0&&e.jsx("div",{className:"px-3 pb-2 flex flex-wrap gap-2",children:g.map(s=>e.jsxs("div",{className:"relative group",children:[s.type==="image"?e.jsx("div",{className:"h-16 w-16 rounded-md border overflow-hidden relative",children:e.jsx("img",{src:s.url,alt:s.name,className:"h-full w-full object-cover"})}):e.jsx("div",{className:"h-16 w-16 rounded-md border bg-muted flex items-center justify-center",children:e.jsx(n.Paperclip,{className:"h-6 w-6 text-muted-foreground"})}),e.jsx("button",{onClick:()=>D(s.id),className:"absolute -top-1.5 -right-1.5 border bg-background text-destructive-emphasis hover:bg-destructive/10 rounded-full p-0.5 opacity-100 md:opacity-0 md:group-hover:opacity-100 md:group-focus-within:opacity-100 transition-opacity shadow-sm",children:e.jsx(n.X,{className:"h-3 w-3"})})]},s.id))}),e.jsxs("div",{className:"flex items-center justify-between p-2 bg-muted/10 border-t",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs(f.Tooltip,{children:[e.jsx(f.TooltipTrigger,{asChild:!0,children:e.jsx(l.Button,{variant:"ghost",size:"icon",className:o.cn("h-8 w-8 transition-colors",y?"bg-muted text-foreground":"text-muted-foreground hover:text-foreground"),onClick:()=>q(!y),"aria-label":"Opções de formatação",children:e.jsx(n.Type,{className:"h-4 w-4"})})}),e.jsx(f.TooltipContent,{children:"Opções de formatação"})]}),e.jsx("div",{className:"w-px h-4 bg-border mx-1"}),e.jsxs(p.Popover,{children:[e.jsx(p.PopoverTrigger,{asChild:!0,children:e.jsx(l.Button,{variant:"ghost",size:"icon",className:"h-8 w-8 text-muted-foreground hover:text-foreground","aria-label":"Inserir emoji",children:e.jsx(n.Smile,{className:"h-4 w-4"})})}),e.jsx(p.PopoverContent,{className:"w-auto p-0 border-none",align:"start",side:"top",children:e.jsx(L,{onEmojiClick:s=>m==null?void 0:m.chain().focus().insertContent(s.emoji).run(),width:300,height:350})})]}),e.jsx("input",{type:"file",className:"hidden",ref:P,onChange:O,accept:"image/*,.pdf,.doc,.docx"}),e.jsxs(f.Tooltip,{children:[e.jsx(f.TooltipTrigger,{asChild:!0,children:e.jsx(l.Button,{variant:"ghost",size:"icon",className:"h-8 w-8 text-muted-foreground hover:text-foreground",onClick:()=>{var s;return(s=P.current)==null?void 0:s.click()},"aria-label":"Anexar arquivo",children:e.jsx(n.Paperclip,{className:"h-4 w-4"})})}),e.jsx(f.TooltipContent,{children:"Anexar arquivo"})]}),e.jsxs(f.Tooltip,{children:[e.jsx(f.TooltipTrigger,{asChild:!0,children:e.jsxs(l.Button,{variant:"ghost",size:"sm",className:o.cn("h-8 gap-2 px-2 transition-colors",N?"bg-destructive/10 text-destructive-emphasis hover:bg-destructive/20":"text-muted-foreground hover:text-foreground"),onClick:()=>k(!N),children:[e.jsx(n.AlertCircle,{className:"h-4 w-4"}),e.jsx("span",{className:"text-xs font-medium",children:"Solicitar Refação"})]})}),e.jsx(f.TooltipContent,{children:"Marca este comentário como um pedido de alteração"})]})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[a&&m&&e.jsxs("span",{className:o.cn("text-xs tabular-nums",m.storage.characterCount.characters()>=a?"text-destructive":"text-muted-foreground"),"aria-live":"polite",children:[m.storage.characterCount.characters(),"/",a]}),e.jsxs(l.Button,{size:"sm",onClick:U,disabled:E&&g.length===0,children:["Enviar ",e.jsx(n.Send,{className:"h-3.5 w-3.5 ml-2"})]})]})]})]})]})},ce=({comment:t,currentUserId:u,onDelete:c,onReact:a})=>{var j;const h=t.isRevisionRequest;return e.jsxs("div",{className:o.cn("group flex gap-3 p-4 rounded-lg transition-colors",h?"bg-destructive/5 border border-destructive/20":"hover:bg-muted/20"),children:[e.jsxs(w.Avatar,{className:"h-8 w-8 mt-0.5 border",children:[e.jsx(w.AvatarImage,{src:t.user.avatar}),e.jsx(w.AvatarFallback,{children:t.user.name.substring(0,2).toUpperCase()})]}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center justify-between mb-1.5",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("span",{className:"font-semibold text-sm text-foreground",children:t.user.name}),e.jsx(ne,{role:t.user.role}),e.jsx("span",{className:"text-xs text-foreground/65",children:F.format(t.createdAt,"dd MMM 'às' HH:mm",{locale:K.ptBR})})]}),e.jsxs("div",{className:"flex items-center gap-2 opacity-100 md:opacity-0 md:group-hover:opacity-100 md:group-focus-within:opacity-100 transition-opacity has-[[data-state=open]]:opacity-100",children:[e.jsxs(p.Popover,{children:[e.jsx(p.PopoverTrigger,{asChild:!0,children:e.jsx(l.Button,{variant:"ghost",size:"icon",className:"h-6 w-6 relative before:absolute before:-inset-1 before:content-[''] text-muted-foreground hover:text-foreground","aria-label":"Reagir com emoji",children:e.jsx(n.Smile,{className:"h-3.5 w-3.5","aria-hidden":"true"})})}),e.jsx(p.PopoverContent,{className:"w-auto p-0 border-none",align:"end",children:e.jsx(L,{onEmojiClick:i=>a==null?void 0:a(t.id,i.emoji),width:300,height:350})})]}),c&&e.jsx(l.Button,{variant:"ghost",size:"icon",className:"h-6 w-6 relative before:absolute before:-inset-1 before:content-[''] text-muted-foreground hover:text-destructive-emphasis",onClick:()=>c(t.id),"aria-label":"Excluir comentário",children:e.jsx(n.Trash2,{className:"h-3.5 w-3.5","aria-hidden":"true"})})]})]}),h&&e.jsxs("div",{className:"inline-flex items-center gap-1.5 px-2 py-1 rounded-md bg-destructive/10 text-destructive-emphasis text-xs font-medium mb-2",children:[e.jsx(n.AlertCircle,{className:"h-3.5 w-3.5"}),"Solicitação de Refação"]}),e.jsx("div",{className:"prose prose-sm dark:prose-invert max-w-none text-sm text-foreground/90 leading-relaxed break-words [&_p]:mb-2 [&_p:last-child]:mb-0",dangerouslySetInnerHTML:{__html:t.content}}),t.attachments&&t.attachments.length>0&&e.jsx("div",{className:"mt-3 flex flex-wrap gap-2",children:t.attachments.map(i=>e.jsx("div",{className:"group/att relative rounded-lg border overflow-hidden bg-background hover:shadow-sm transition-all cursor-pointer",onClick:()=>window.open(i.url,"_blank"),children:i.type==="image"?e.jsxs("div",{className:"h-32 aspect-[4/3]",children:[e.jsx("img",{src:i.url,alt:i.name,className:"h-full w-full object-cover"}),e.jsx("div",{className:"absolute inset-0 bg-foreground/0 group-hover/att:bg-foreground/10 transition-colors"})]}):e.jsxs("div",{className:"h-12 px-3 flex items-center gap-2 bg-muted/30",children:[e.jsx(n.Paperclip,{className:"h-4 w-4 text-muted-foreground"}),e.jsx("span",{className:"text-xs font-medium truncate max-w-[150px]",children:i.name})]})},i.id))}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2 items-center",children:[(j=t.reactions)==null?void 0:j.map(i=>e.jsxs("button",{onClick:()=>a==null?void 0:a(t.id,i.emoji),className:o.cn("inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full text-xs font-medium border transition-colors",i.users.includes(u)?"bg-secondary border-secondary text-secondary-foreground":"bg-muted/30 border-transparent hover:bg-muted/50 text-muted-foreground"),children:[e.jsx("span",{children:i.emoji}),e.jsx("span",{children:i.users.length})]},i.emoji)),a&&e.jsxs(p.Popover,{children:[e.jsx(p.PopoverTrigger,{asChild:!0,children:e.jsx(l.Button,{variant:"ghost",size:"icon",className:"h-6 w-6 rounded-full text-muted-foreground hover:text-foreground hover:bg-muted/50","aria-label":"Adicionar reação",children:e.jsx(n.Plus,{className:"h-3.5 w-3.5"})})}),e.jsx(p.PopoverContent,{className:"w-auto p-0 border-none",align:"start",children:e.jsx(L,{onEmojiClick:i=>a(t.id,i.emoji),width:300,height:350})})]})]})]})]})},de=({comments:t,currentUser:u,users:c=[],onAddComment:a,onDeleteComment:h,onReact:j,maxLength:i,placeholder:C,onImageUpload:N,features:k,extensions:y,className:q})=>{const g=x=>{a({content:x.content,user:u,isRevisionRequest:x.isRevisionRequest,attachments:x.attachments})};return e.jsxs("div",{className:o.cn("flex flex-col h-full",q),children:[e.jsxs("div",{className:"px-4 py-3 border-b flex items-center justify-between bg-card",children:[e.jsx("h3",{className:"font-semibold text-base",children:"Comentários da Atividade"}),e.jsx(M.Badge,{variant:"secondary",className:"bg-muted text-muted-foreground hover:bg-muted",children:t.length})]}),e.jsx("div",{className:"flex-1 overflow-y-auto p-4 space-y-2 bg-muted/5",children:t.length===0?e.jsxs("div",{className:"h-full flex flex-col items-center justify-center text-muted-foreground min-h-[200px]",children:[e.jsx("div",{className:"bg-muted rounded-full p-3 mb-3",children:e.jsx(n.MoreHorizontal,{className:"h-6 w-6","aria-hidden":"true"})}),e.jsx("p",{className:"text-sm font-medium text-foreground/70",children:"Nenhum comentário ainda"}),e.jsx("p",{className:"text-xs",children:"Inicie a conversa sobre esta tarefa"})]}):t.map(x=>e.jsx(ce,{comment:x,currentUserId:u.id,onDelete:h,onReact:j},x.id))}),e.jsx("div",{className:"p-4 border-t bg-card",children:e.jsx(le,{currentUser:u,onSubmit:g,users:c,maxLength:i,placeholder:C,onImageUpload:N,features:k,extensions:y})})]})};exports.CommentThread=de;
2
+ //# sourceMappingURL=comment-thread.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comment-thread.cjs","sources":["../../../../src/components/ui/data/comment-thread.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { format } from \"date-fns\";\nimport { ptBR } from \"date-fns/locale\";\nimport { cn } from \"../utils\";\nimport { Avatar, AvatarFallback, AvatarImage } from \"../primitives/avatar\";\nimport { Button } from \"../primitives/button\";\nimport { Badge } from \"../primitives/badge\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"../overlays/tooltip\";\nimport { Separator } from \"../primitives/separator\";\nimport { \n Bold, \n Italic, \n Underline as UnderlineIcon, \n List, \n ListOrdered, \n Link as LinkIcon,\n Send,\n Paperclip,\n AlertCircle,\n MoreHorizontal,\n Trash2,\n Type,\n X,\n Smile,\n Plus,\n ListChecks,\n Highlighter,\n Table as TableIcon,\n ChevronsDownUp,\n GripVertical\n} from \"lucide-react\";\n\n// Tiptap Imports\nimport { useEditor, EditorContent, Editor, ReactRenderer } from '@tiptap/react';\nimport type { Instance as TippyInstance } from 'tippy.js';\nimport StarterKit from '@tiptap/starter-kit';\nimport Underline from '@tiptap/extension-underline';\nimport Link from '@tiptap/extension-link';\nimport TiptapImage from '@tiptap/extension-image';\nimport Mention from '@tiptap/extension-mention';\nimport TaskList from '@tiptap/extension-task-list';\nimport TaskItem from '@tiptap/extension-task-item';\nimport FileHandler from '@tiptap/extension-file-handler';\nimport Highlight from '@tiptap/extension-highlight';\nimport Typography from '@tiptap/extension-typography';\nimport { CharacterCount, Placeholder } from '@tiptap/extensions';\nimport { TableKit } from '@tiptap/extension-table';\nimport { Details, DetailsContent, DetailsSummary } from '@tiptap/extension-details';\nimport { DragHandle } from '@tiptap/extension-drag-handle-react';\nimport type { AnyExtension } from '@tiptap/react';\nimport tippy from 'tippy.js';\nimport { MentionList } from './mention-list';\nimport Picker from 'emoji-picker-react';\nimport { Popover, PopoverContent, PopoverTrigger } from \"../overlays/popover\";\n\n// ==========================================\n// TIPOS\n// ==========================================\n\nexport type UserRole = 'internal' | 'client' | 'freelancer';\n\nexport interface CommentUser {\n id: string;\n name: string;\n avatar?: string;\n role: UserRole;\n}\n\nexport interface CommentReaction {\n emoji: string;\n users: string[]; // Array de IDs de usuários que reagiram\n}\n\nexport interface CommentAttachment {\n id: string;\n url: string;\n name: string;\n type: 'image' | 'file';\n}\n\nexport interface Comment {\n id: string;\n content: string; // Conteúdo HTML\n user: CommentUser;\n createdAt: Date;\n isRevisionRequest?: boolean;\n attachments?: CommentAttachment[];\n reactions?: CommentReaction[];\n}\n\n/** Extensoes opcionais do editor. Todas desligadas por padrao — quem consome liga o que usa. */\nexport interface CommentEditorFeatures {\n /** Tabela, com botao de inserir 3x3 na barra. */\n table?: boolean;\n /** Bloco recolhivel (<details>), com botao na barra. */\n details?: boolean;\n /** Alca para arrastar blocos, na margem esquerda do editor. */\n dragHandle?: boolean;\n}\n\nexport interface CommentThreadProps {\n comments: Comment[];\n currentUser: CommentUser;\n users?: CommentUser[]; // Lista de usuários mencionáveis\n onAddComment: (comment: Omit<Comment, \"id\" | \"createdAt\">) => void;\n onDeleteComment?: (id: string) => void;\n onReact?: (commentId: string, emoji: string) => void;\n /** Limite de caracteres do editor. Sem valor, nao ha limite nem contador. */\n maxLength?: number;\n /** Texto exibido no editor vazio. */\n placeholder?: string;\n /** Sobe a imagem colada/arrastada e devolve a URL final. Sem isso, usa URL local. */\n onImageUpload?: (file: File) => Promise<string>;\n /** Liga extensoes opcionais do editor. Ver `CommentEditorFeatures`. */\n features?: CommentEditorFeatures;\n /**\n * Extensoes tiptap extras. Escape hatch para o que a lib nao embute de\n * proposito — `@tiptap/extension-mathematics` puxa katex (~270KB), entao\n * quem precisa instala e passa aqui.\n */\n extensions?: AnyExtension[];\n className?: string;\n}\n\n// ==========================================\n// COMPONENTES AUXILIARES\n// ==========================================\n\nconst RoleBadge = ({ role }: { role: UserRole }) => {\n const config = {\n internal: { label: \"Equipe iClips\", className: \"bg-primary/10 text-primary border-primary/20\" },\n client: { label: \"Cliente\", className: \"bg-info/10 text-info-emphasis border-info/20\" },\n freelancer: { label: \"Freelancer\", className: \"bg-warning/10 text-warning-emphasis border-warning/20\" },\n };\n\n const { label, className } = config[role];\n\n return (\n <Badge variant=\"outline\" className={cn(\"text-[10px] h-5 px-1.5 font-medium border-0\", className)}>\n {label}\n </Badge>\n );\n};\n\n// ==========================================\n// EDITOR TOOLBAR\n// ==========================================\n\nconst EditorToolbar = ({\n editor,\n visible,\n features = {},\n}: { editor: Editor | null, visible: boolean, features?: CommentEditorFeatures }) => {\n if (!editor) return null;\n\n if (!visible) return null;\n\n return (\n <div className=\"flex items-center gap-1 border-b p-1 bg-muted/20 animate-in slide-in-from-bottom-2 duration-200\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('bold') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().toggleBold().run()}\n title=\"Negrito (Ctrl+B)\"\n aria-label=\"Negrito\"\n >\n <Bold className=\"h-3.5 w-3.5\" />\n </Button>\n \n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('italic') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().toggleItalic().run()}\n title=\"Itálico (Ctrl+I)\"\n aria-label=\"Itálico\"\n >\n <Italic className=\"h-3.5 w-3.5\" />\n </Button>\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('underline') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().toggleUnderline().run()}\n title=\"Sublinhado (Ctrl+U)\"\n aria-label=\"Sublinhado\"\n >\n <UnderlineIcon className=\"h-3.5 w-3.5\" />\n </Button>\n\n <Separator orientation=\"vertical\" className=\"h-4 mx-1\" />\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('bulletList') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().toggleBulletList().run()}\n aria-label=\"Lista com marcadores\"\n >\n <List className=\"h-3.5 w-3.5\" />\n </Button>\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('orderedList') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().toggleOrderedList().run()}\n aria-label=\"Lista numerada\"\n >\n <ListOrdered className=\"h-3.5 w-3.5\" />\n </Button>\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('taskList') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().toggleTaskList().run()}\n title=\"Lista de tarefas\"\n aria-label=\"Lista de tarefas\"\n >\n <ListChecks className=\"h-3.5 w-3.5\" />\n </Button>\n\n <Separator orientation=\"vertical\" className=\"h-4 mx-1\" />\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('highlight') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().toggleHighlight().run()}\n title=\"Marca-texto\"\n aria-label=\"Marca-texto\"\n >\n <Highlighter className=\"h-3.5 w-3.5\" />\n </Button>\n\n {features.table && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('table') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()}\n title=\"Inserir tabela 3x3\"\n aria-label=\"Inserir tabela\"\n >\n <TableIcon className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n\n {features.details && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('details') && \"bg-muted text-primary\")}\n onClick={() => editor.chain().focus().setDetails().run()}\n title=\"Bloco recolhivel\"\n aria-label=\"Bloco recolhivel\"\n >\n <ChevronsDownUp className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"h-7 w-7\", editor.isActive('link') && \"bg-muted text-primary\")}\n aria-label=\"Inserir link\"\n onClick={() => {\n const previousUrl = editor.getAttributes('link').href;\n const url = window.prompt('URL', previousUrl);\n if (url === null) return;\n if (url === '') {\n editor.chain().focus().extendMarkRange('link').unsetLink().run();\n return;\n }\n editor.chain().focus().extendMarkRange('link').setLink({ href: url }).run();\n }}\n >\n <LinkIcon className=\"h-3.5 w-3.5\" />\n </Button>\n </div>\n );\n};\n\n// ==========================================\n// COMMENT EDITOR AREA\n// ==========================================\n\nconst CommentEditor = ({ \n currentUser, \n onSubmit,\n users = [],\n maxLength,\n placeholder = 'Escreva um comentario... use @ para mencionar',\n onImageUpload,\n features = {},\n extensions: extraExtensions\n}: { \n currentUser: CommentUser;\n onSubmit: (data: { content: string; isRevisionRequest: boolean; attachments: CommentAttachment[] }) => void;\n users?: CommentUser[];\n maxLength?: number;\n placeholder?: string;\n onImageUpload?: (file: File) => Promise<string>;\n features?: CommentEditorFeatures;\n extensions?: AnyExtension[];\n}) => {\n const [isRevision, setIsRevision] = React.useState(false);\n const [showToolbar, setShowToolbar] = React.useState(false);\n const [attachments, setAttachments] = React.useState<CommentAttachment[]>([]);\n const [isEditorEmpty, setIsEditorEmpty] = React.useState(true);\n const fileInputRef = React.useRef<HTMLInputElement>(null);\n\n // Insere imagens coladas/arrastadas. Sem `onImageUpload`, usa URL local do\n // proprio browser - suficiente para preview, nao persiste.\n const insertImages = React.useCallback(\n async (editor: Editor, files: File[], pos?: number) => {\n for (const file of files) {\n const src = onImageUpload ? await onImageUpload(file) : URL.createObjectURL(file);\n editor\n .chain()\n .insertContentAt(pos ?? editor.state.selection.anchor, { type: 'image', attrs: { src } })\n .focus()\n .run();\n }\n },\n [onImageUpload],\n );\n\n const extensions = React.useMemo(() => [\n StarterKit.configure({\n link: false,\n underline: false,\n }),\n Underline,\n Link.configure({\n openOnClick: false,\n }),\n TiptapImage,\n Mention.configure({\n HTMLAttributes: {\n class: 'bg-secondary text-secondary-foreground rounded-sm px-1 py-0.5 font-medium decoration-clone',\n },\n suggestion: {\n items: ({ query }: { query: string }) => {\n return users\n .filter(item => item.name.toLowerCase().startsWith(query.toLowerCase()))\n .slice(0, 5);\n },\n render: () => {\n // Formato mínimo dos props do ciclo de vida do suggestion do tiptap\n // (o tipo completo `SuggestionProps` vive em `@tiptap/suggestion`, dep\n // transitiva sem entrada direta no package.json).\n type MentionRenderProps = {\n editor: Editor;\n clientRect?: (() => DOMRect | null) | null;\n event?: KeyboardEvent;\n };\n let component: ReactRenderer | null = null;\n let popup: TippyInstance[] | null = null;\n\n return {\n onStart: (props: MentionRenderProps) => {\n component = new ReactRenderer(MentionList, {\n props,\n editor: props.editor,\n });\n\n if (!props.clientRect) {\n return;\n }\n\n popup = tippy('body', {\n // tiptap tipa como `() => DOMRect | null`; tippy exige não-nulo.\n getReferenceClientRect: props.clientRect as () => DOMRect,\n appendTo: () => document.body,\n content: component.element,\n showOnCreate: true,\n interactive: true,\n trigger: 'manual',\n placement: 'bottom-start',\n });\n },\n onUpdate(props: MentionRenderProps) {\n component?.updateProps(props);\n\n if (!props.clientRect) {\n return;\n }\n\n popup?.[0].setProps({\n getReferenceClientRect: props.clientRect as () => DOMRect,\n });\n },\n onKeyDown(props: { event: KeyboardEvent }) {\n if (props.event.key === 'Escape') {\n popup?.[0].hide();\n\n return true;\n }\n\n return Boolean(\n (component?.ref as { onKeyDown?: (p: { event: KeyboardEvent }) => boolean } | undefined)?.onKeyDown?.(props),\n );\n },\n onExit() {\n popup?.[0].destroy();\n component?.destroy();\n },\n };\n },\n },\n }),\n TaskList,\n TaskItem.configure({\n nested: true,\n // Sem isso o checkbox nasce sem nome acessivel: o <label> que o tiptap\n // gera envolve o input mas nao tem texto. Violacao critica no axe.\n a11y: {\n checkboxLabel: (node, checked) =>\n `${checked ? 'Concluido' : 'Pendente'}: ${node.textContent || 'tarefa vazia'}`,\n },\n }),\n Highlight,\n Typography,\n Placeholder.configure({ placeholder }),\n ...(maxLength ? [CharacterCount.configure({ limit: maxLength })] : []),\n FileHandler.configure({\n allowedMimeTypes: ['image/png', 'image/jpeg', 'image/gif', 'image/webp'],\n onDrop: (editor, files, pos) => {\n void insertImages(editor, files, pos);\n },\n onPaste: (editor, files) => {\n void insertImages(editor, files);\n },\n }),\n ...(features.table ? [TableKit.configure({ table: { resizable: true } })] : []),\n ...(features.details ? [Details, DetailsSummary, DetailsContent] : []),\n ...(extraExtensions ?? []),\n ], [users, maxLength, placeholder, insertImages, features.table, features.details, extraExtensions]);\n\n const editor = useEditor({\n extensions,\n content: '',\n onUpdate: ({ editor }) => {\n setIsEditorEmpty(editor.isEmpty);\n },\n editorProps: {\n attributes: {\n class: 'prose prose-sm dark:prose-invert max-w-none focus:outline-none min-h-[80px] px-3 py-2 text-sm',\n },\n },\n });\n\n const handleAttach = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (e.target.files && e.target.files[0]) {\n const file = e.target.files[0];\n const url = URL.createObjectURL(file);\n \n const newAttachment: CommentAttachment = {\n id: Math.random().toString(36).substr(2, 9),\n name: file.name,\n url,\n type: file.type.startsWith('image/') ? 'image' : 'file'\n };\n \n setAttachments([...attachments, newAttachment]);\n // Reset input\n e.target.value = '';\n }\n };\n\n const removeAttachment = (id: string) => {\n setAttachments(attachments.filter(a => a.id !== id));\n };\n\n const handleSubmit = () => {\n if (!editor || (editor.isEmpty && attachments.length === 0)) return;\n \n onSubmit({\n content: editor.getHTML(),\n isRevisionRequest: isRevision,\n attachments\n });\n\n editor.commands.clearContent();\n setAttachments([]);\n setIsRevision(false);\n // Manually reset empty state since clearContent triggers update but we want to be sure\n setIsEditorEmpty(true);\n };\n\n return (\n <div className=\"flex gap-3 items-start\">\n <Avatar className=\"h-8 w-8 mt-1 border\">\n <AvatarImage src={currentUser.avatar} />\n <AvatarFallback>{currentUser.name.substring(0, 2).toUpperCase()}</AvatarFallback>\n </Avatar>\n\n <div className={cn(\n \"flex-1 rounded-xl border bg-background shadow-sm overflow-hidden transition-colors\",\n isRevision && \"border-destructive/40 ring-1 ring-destructive/20\"\n )}>\n <EditorToolbar editor={editor} visible={showToolbar} features={features} />\n \n {features.dragHandle && (\n <DragHandle editor={editor}>\n <GripVertical className=\"text-muted-foreground h-4 w-4 cursor-grab\" />\n </DragHandle>\n )}\n <EditorContent editor={editor} />\n\n {/* Attachments Preview Area */}\n {attachments.length > 0 && (\n <div className=\"px-3 pb-2 flex flex-wrap gap-2\">\n {attachments.map(att => (\n <div key={att.id} className=\"relative group\">\n {att.type === 'image' ? (\n <div className=\"h-16 w-16 rounded-md border overflow-hidden relative\">\n <img src={att.url} alt={att.name} className=\"h-full w-full object-cover\" />\n </div>\n ) : (\n <div className=\"h-16 w-16 rounded-md border bg-muted flex items-center justify-center\">\n <Paperclip className=\"h-6 w-6 text-muted-foreground\" />\n </div>\n )}\n <button \n onClick={() => removeAttachment(att.id)}\n className=\"absolute -top-1.5 -right-1.5 border bg-background text-destructive-emphasis hover:bg-destructive/10 rounded-full p-0.5 opacity-100 md:opacity-0 md:group-hover:opacity-100 md:group-focus-within:opacity-100 transition-opacity shadow-sm\"\n >\n <X className=\"h-3 w-3\" />\n </button>\n </div>\n ))}\n </div>\n )}\n\n <div className=\"flex items-center justify-between p-2 bg-muted/10 border-t\">\n <div className=\"flex items-center gap-2\">\n <Tooltip>\n <TooltipTrigger asChild>\n <Button \n variant=\"ghost\" \n size=\"icon\" \n className={cn(\n \"h-8 w-8 transition-colors\",\n showToolbar ? \"bg-muted text-foreground\" : \"text-muted-foreground hover:text-foreground\"\n )}\n onClick={() => setShowToolbar(!showToolbar)}\n aria-label=\"Opções de formatação\"\n >\n <Type className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Opções de formatação</TooltipContent>\n </Tooltip>\n\n <div className=\"w-px h-4 bg-border mx-1\" />\n\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-muted-foreground hover:text-foreground\"\n aria-label=\"Inserir emoji\"\n >\n <Smile className=\"h-4 w-4\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0 border-none\" align=\"start\" side=\"top\">\n <Picker \n onEmojiClick={(emojiData) => editor?.chain().focus().insertContent(emojiData.emoji).run()}\n width={300}\n height={350}\n />\n </PopoverContent>\n </Popover>\n\n <input \n type=\"file\" \n className=\"hidden\" \n ref={fileInputRef}\n onChange={handleAttach}\n accept=\"image/*,.pdf,.doc,.docx\"\n />\n <Tooltip>\n <TooltipTrigger asChild>\n <Button \n variant=\"ghost\" \n size=\"icon\" \n className=\"h-8 w-8 text-muted-foreground hover:text-foreground\"\n onClick={() => fileInputRef.current?.click()}\n aria-label=\"Anexar arquivo\"\n >\n <Paperclip className=\"h-4 w-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent>Anexar arquivo</TooltipContent>\n </Tooltip>\n\n <Tooltip>\n <TooltipTrigger asChild>\n <Button \n variant=\"ghost\" \n size=\"sm\" \n className={cn(\n \"h-8 gap-2 px-2 transition-colors\",\n isRevision\n ? \"bg-destructive/10 text-destructive-emphasis hover:bg-destructive/20\"\n : \"text-muted-foreground hover:text-foreground\"\n )}\n onClick={() => setIsRevision(!isRevision)}\n >\n <AlertCircle className=\"h-4 w-4\" />\n <span className=\"text-xs font-medium\">Solicitar Refação</span>\n </Button>\n </TooltipTrigger>\n <TooltipContent>Marca este comentário como um pedido de alteração</TooltipContent>\n </Tooltip>\n </div>\n\n <div className=\"flex items-center gap-3\">\n {maxLength && editor && (\n <span\n className={cn(\n \"text-xs tabular-nums\",\n editor.storage.characterCount.characters() >= maxLength\n ? \"text-destructive\"\n : \"text-muted-foreground\"\n )}\n aria-live=\"polite\"\n >\n {editor.storage.characterCount.characters()}/{maxLength}\n </span>\n )}\n <Button\n size=\"sm\"\n onClick={handleSubmit}\n disabled={isEditorEmpty && attachments.length === 0}\n >\n Enviar <Send className=\"h-3.5 w-3.5 ml-2\" />\n </Button>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\n// ==========================================\n// SINGLE COMMENT ITEM\n// ==========================================\n\nconst CommentItem = ({ \n comment, \n currentUserId,\n onDelete, \n onReact \n}: { \n comment: Comment; \n currentUserId: string;\n onDelete?: (id: string) => void;\n onReact?: (commentId: string, emoji: string) => void;\n}) => {\n const isRevision = comment.isRevisionRequest;\n\n return (\n <div className={cn(\n \"group flex gap-3 p-4 rounded-lg transition-colors\",\n isRevision ? \"bg-destructive/5 border border-destructive/20\" : \"hover:bg-muted/20\"\n )}>\n <Avatar className=\"h-8 w-8 mt-0.5 border\">\n <AvatarImage src={comment.user.avatar} />\n <AvatarFallback>{comment.user.name.substring(0, 2).toUpperCase()}</AvatarFallback>\n </Avatar>\n\n <div className=\"flex-1 min-w-0\">\n {/* Header */}\n <div className=\"flex items-center justify-between mb-1.5\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <span className=\"font-semibold text-sm text-foreground\">{comment.user.name}</span>\n <RoleBadge role={comment.user.role} />\n <span className=\"text-xs text-foreground/65\">\n {format(comment.createdAt, \"dd MMM 'às' HH:mm\", { locale: ptBR })}\n </span>\n </div>\n \n <div className=\"flex items-center gap-2 opacity-100 md:opacity-0 md:group-hover:opacity-100 md:group-focus-within:opacity-100 transition-opacity has-[[data-state=open]]:opacity-100\">\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6 relative before:absolute before:-inset-1 before:content-[''] text-muted-foreground hover:text-foreground\"\n aria-label=\"Reagir com emoji\"\n >\n <Smile className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0 border-none\" align=\"end\">\n <Picker \n onEmojiClick={(emojiData) => onReact?.(comment.id, emojiData.emoji)}\n width={300}\n height={350}\n />\n </PopoverContent>\n </Popover>\n\n {onDelete && (\n <Button \n variant=\"ghost\" \n size=\"icon\" \n className=\"h-6 w-6 relative before:absolute before:-inset-1 before:content-[''] text-muted-foreground hover:text-destructive-emphasis\"\n onClick={() => onDelete(comment.id)}\n aria-label=\"Excluir comentário\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n </Button>\n )}\n </div>\n </div>\n\n {/* Revision Badge */}\n {isRevision && (\n <div className=\"inline-flex items-center gap-1.5 px-2 py-1 rounded-md bg-destructive/10 text-destructive-emphasis text-xs font-medium mb-2\">\n <AlertCircle className=\"h-3.5 w-3.5\" />\n Solicitação de Refação\n </div>\n )}\n\n {/* Content */}\n <div \n className=\"prose prose-sm dark:prose-invert max-w-none text-sm text-foreground/90 leading-relaxed break-words [&_p]:mb-2 [&_p:last-child]:mb-0\"\n dangerouslySetInnerHTML={{ __html: comment.content }}\n />\n\n {/* Attachments Display */}\n {comment.attachments && comment.attachments.length > 0 && (\n <div className=\"mt-3 flex flex-wrap gap-2\">\n {comment.attachments.map(att => (\n <div \n key={att.id} \n className=\"group/att relative rounded-lg border overflow-hidden bg-background hover:shadow-sm transition-all cursor-pointer\"\n onClick={() => window.open(att.url, '_blank')}\n >\n {att.type === 'image' ? (\n <div className=\"h-32 aspect-[4/3]\">\n <img src={att.url} alt={att.name} className=\"h-full w-full object-cover\" />\n <div className=\"absolute inset-0 bg-foreground/0 group-hover/att:bg-foreground/10 transition-colors\" />\n </div>\n ) : (\n <div className=\"h-12 px-3 flex items-center gap-2 bg-muted/30\">\n <Paperclip className=\"h-4 w-4 text-muted-foreground\" />\n <span className=\"text-xs font-medium truncate max-w-[150px]\">{att.name}</span>\n </div>\n )}\n </div>\n ))}\n </div>\n )}\n\n {/* Reactions */}\n <div className=\"mt-3 flex flex-wrap gap-2 items-center\">\n {comment.reactions?.map((reaction) => (\n <button\n key={reaction.emoji}\n onClick={() => onReact?.(comment.id, reaction.emoji)}\n className={cn(\n \"inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full text-xs font-medium border transition-colors\",\n reaction.users.includes(currentUserId)\n ? \"bg-secondary border-secondary text-secondary-foreground\"\n : \"bg-muted/30 border-transparent hover:bg-muted/50 text-muted-foreground\"\n )}\n >\n <span>{reaction.emoji}</span>\n <span>{reaction.users.length}</span>\n </button>\n ))}\n \n {onReact && (\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6 rounded-full text-muted-foreground hover:text-foreground hover:bg-muted/50\"\n aria-label=\"Adicionar reação\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0 border-none\" align=\"start\">\n <Picker \n onEmojiClick={(emojiData) => onReact(comment.id, emojiData.emoji)}\n width={300}\n height={350}\n />\n </PopoverContent>\n </Popover>\n )}\n </div>\n </div>\n </div>\n );\n};\n\n// ==========================================\n// MAIN COMPONENT\n// ==========================================\n\nexport const CommentThread = ({ \n comments, \n currentUser, \n users = [],\n onAddComment, \n onDeleteComment,\n onReact,\n maxLength,\n placeholder,\n onImageUpload,\n features,\n extensions,\n className \n}: CommentThreadProps) => {\n \n const handleSubmit = (data: { content: string; isRevisionRequest: boolean; attachments: CommentAttachment[] }) => {\n onAddComment({\n content: data.content,\n user: currentUser,\n isRevisionRequest: data.isRevisionRequest,\n attachments: data.attachments\n });\n };\n\n return (\n <div className={cn(\"flex flex-col h-full\", className)}>\n {/* Header */}\n <div className=\"px-4 py-3 border-b flex items-center justify-between bg-card\">\n <h3 className=\"font-semibold text-base\">Comentários da Atividade</h3>\n <Badge variant=\"secondary\" className=\"bg-muted text-muted-foreground hover:bg-muted\">\n {comments.length}\n </Badge>\n </div>\n\n {/* Scrollable List */}\n <div className=\"flex-1 overflow-y-auto p-4 space-y-2 bg-muted/5\">\n {comments.length === 0 ? (\n <div className=\"h-full flex flex-col items-center justify-center text-muted-foreground min-h-[200px]\">\n <div className=\"bg-muted rounded-full p-3 mb-3\">\n <MoreHorizontal className=\"h-6 w-6\" aria-hidden=\"true\" />\n </div>\n <p className=\"text-sm font-medium text-foreground/70\">Nenhum comentário ainda</p>\n <p className=\"text-xs\">Inicie a conversa sobre esta tarefa</p>\n </div>\n ) : (\n comments.map((comment) => (\n <CommentItem \n key={comment.id} \n comment={comment} \n currentUserId={currentUser.id}\n onDelete={onDeleteComment} \n onReact={onReact}\n />\n ))\n )}\n </div>\n\n {/* Input Area */}\n <div className=\"p-4 border-t bg-card\">\n <CommentEditor \n currentUser={currentUser} \n onSubmit={handleSubmit}\n users={users}\n maxLength={maxLength}\n placeholder={placeholder}\n onImageUpload={onImageUpload}\n features={features}\n extensions={extensions}\n />\n </div>\n </div>\n );\n};\n\nexport default CommentThread;"],"names":["RoleBadge","role","config","label","className","jsx","Badge","cn","EditorToolbar","editor","visible","features","jsxs","Button","Bold","Italic","UnderlineIcon","Separator","List","ListOrdered","ListChecks","Highlighter","TableIcon","ChevronsDownUp","previousUrl","url","LinkIcon","CommentEditor","currentUser","onSubmit","users","maxLength","placeholder","onImageUpload","extraExtensions","isRevision","setIsRevision","React","showToolbar","setShowToolbar","attachments","setAttachments","isEditorEmpty","setIsEditorEmpty","fileInputRef","insertImages","files","pos","file","src","extensions","StarterKit","Underline","Link","TiptapImage","Mention","query","item","component","popup","props","ReactRenderer","MentionList","tippy","_b","_a","TaskList","TaskItem","node","checked","Highlight","Typography","Placeholder","CharacterCount","FileHandler","TableKit","Details","DetailsSummary","DetailsContent","useEditor","handleAttach","e","newAttachment","removeAttachment","id","a","handleSubmit","Avatar","AvatarImage","AvatarFallback","DragHandle","GripVertical","EditorContent","att","Paperclip","X","Tooltip","TooltipTrigger","Type","TooltipContent","Popover","PopoverTrigger","Smile","PopoverContent","Picker","emojiData","AlertCircle","Send","CommentItem","comment","currentUserId","onDelete","onReact","format","ptBR","Trash2","reaction","Plus","CommentThread","comments","onAddComment","onDeleteComment","data","MoreHorizontal"],"mappings":"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"}