@papyrus-sdk/ui-react 0.2.9 → 0.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -29,11 +29,12 @@ module.exports = __toCommonJS(ui_react_exports);
29
29
 
30
30
  // components/Topbar.tsx
31
31
  var import_react = require("react");
32
+ var import_react_dom = require("react-dom");
32
33
  var import_core = require("@papyrus-sdk/core");
33
34
  var import_jsx_runtime = require("react/jsx-runtime");
34
35
  var Topbar = ({
35
36
  engine,
36
- showBrand = true,
37
+ showBrand = false,
37
38
  brand,
38
39
  title,
39
40
  showSidebarLeftToggle = true,
@@ -52,6 +53,7 @@ var Topbar = ({
52
53
  pageTheme,
53
54
  setDocumentState,
54
55
  accentColor,
56
+ toolDockOpen,
55
57
  toggleSidebarLeft,
56
58
  toggleSidebarRight,
57
59
  triggerScrollToPage
@@ -60,15 +62,37 @@ var Topbar = ({
60
62
  const zoomTimerRef = (0, import_react.useRef)(null);
61
63
  const pendingZoomRef = (0, import_react.useRef)(null);
62
64
  const [pageInput, setPageInput] = (0, import_react.useState)(currentPage.toString());
63
- const pageDigits = Math.max(2, String(pageCount || 1).length);
64
65
  const [showPageThemes, setShowPageThemes] = (0, import_react.useState)(false);
66
+ const [showMobileMenu, setShowMobileMenu] = (0, import_react.useState)(false);
67
+ const pageDigits = Math.max(2, String(pageCount || 1).length);
65
68
  const isDark = uiTheme === "dark";
69
+ const canUseDOM = typeof document !== "undefined";
70
+ const hasMobileMenu = showZoomControls || showPageThemeSelector || showUIToggle || showUpload;
66
71
  (0, import_react.useEffect)(() => {
67
72
  setPageInput(currentPage.toString());
68
73
  }, [currentPage]);
69
- (0, import_react.useEffect)(() => () => {
70
- if (zoomTimerRef.current) clearTimeout(zoomTimerRef.current);
71
- }, []);
74
+ (0, import_react.useEffect)(
75
+ () => () => {
76
+ if (zoomTimerRef.current) clearTimeout(zoomTimerRef.current);
77
+ },
78
+ []
79
+ );
80
+ (0, import_react.useEffect)(() => {
81
+ if (!hasMobileMenu) setShowMobileMenu(false);
82
+ }, [hasMobileMenu]);
83
+ (0, import_react.useEffect)(() => {
84
+ if (!showMobileMenu || !canUseDOM) return;
85
+ const previousOverflow = document.body.style.overflow;
86
+ const handleKeyDown = (event) => {
87
+ if (event.key === "Escape") setShowMobileMenu(false);
88
+ };
89
+ document.body.style.overflow = "hidden";
90
+ window.addEventListener("keydown", handleKeyDown);
91
+ return () => {
92
+ document.body.style.overflow = previousOverflow;
93
+ window.removeEventListener("keydown", handleKeyDown);
94
+ };
95
+ }, [showMobileMenu, canUseDOM]);
72
96
  const handleZoom = (delta) => {
73
97
  const baseZoom = pendingZoomRef.current ?? zoom;
74
98
  const nextZoom = Math.max(0.2, Math.min(5, baseZoom + delta));
@@ -85,10 +109,31 @@ var Topbar = ({
85
109
  };
86
110
  const handlePageChange = (page) => {
87
111
  if (pageCount <= 0) return;
88
- const p = Math.max(1, Math.min(pageCount, isNaN(page) ? 1 : page));
89
- engine.goToPage(p);
90
- setDocumentState({ currentPage: p });
91
- triggerScrollToPage(p - 1);
112
+ const nextPage = Math.max(1, Math.min(pageCount, isNaN(page) ? 1 : page));
113
+ engine.goToPage(nextPage);
114
+ setDocumentState({ currentPage: nextPage });
115
+ triggerScrollToPage(nextPage - 1);
116
+ };
117
+ const handleFileUpload = async (event) => {
118
+ const file = event.target.files?.[0];
119
+ event.target.value = "";
120
+ if (!file) return;
121
+ setDocumentState({ isLoaded: false });
122
+ try {
123
+ await engine.load(file);
124
+ setDocumentState({
125
+ isLoaded: true,
126
+ pageCount: engine.getPageCount(),
127
+ currentPage: 1,
128
+ outline: await engine.getOutline()
129
+ });
130
+ } catch (err) {
131
+ console.error("Upload failed", err);
132
+ setDocumentState({ isLoaded: true });
133
+ }
134
+ };
135
+ const toggleToolDock = () => {
136
+ setDocumentState({ toolDockOpen: !toolDockOpen });
92
137
  };
93
138
  const themes = [
94
139
  { id: "normal", name: "Original", color: "bg-white" },
@@ -96,100 +141,592 @@ var Topbar = ({
96
141
  { id: "dark", name: "Invertido", color: "bg-gray-800" },
97
142
  { id: "high-contrast", name: "Contraste", color: "bg-black" }
98
143
  ];
144
+ const mobileMenuOverlay = canUseDOM && hasMobileMenu && showMobileMenu ? (0, import_react_dom.createPortal)(
145
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
146
+ "div",
147
+ {
148
+ className: "sm:hidden fixed inset-0 z-[200] bg-black/45",
149
+ onClick: (event) => {
150
+ if (event.target === event.currentTarget)
151
+ setShowMobileMenu(false);
152
+ },
153
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
154
+ "div",
155
+ {
156
+ className: `absolute inset-x-0 bottom-0 rounded-t-2xl border-x border-t p-4 pb-6 shadow-2xl ${isDark ? "bg-[#181a1f] border-[#343a46] text-[#e6e9ef]" : "bg-white border-gray-200 text-gray-900"}`,
157
+ children: [
158
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mx-auto mb-4 h-1.5 w-10 rounded-full bg-gray-400/60" }),
159
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mb-4 flex items-center justify-between", children: [
160
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
161
+ "span",
162
+ {
163
+ className: `text-sm font-semibold ${isDark ? "text-gray-100" : "text-gray-800"}`,
164
+ children: "A\xE7\xF5es r\xE1pidas"
165
+ }
166
+ ),
167
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
168
+ "button",
169
+ {
170
+ className: `p-2 rounded-md ${isDark ? "text-[#d9deea] hover:bg-white/10" : "text-gray-700 hover:bg-gray-100"}`,
171
+ onClick: () => setShowMobileMenu(false),
172
+ "aria-label": "Fechar menu",
173
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
174
+ "svg",
175
+ {
176
+ className: "w-5 h-5",
177
+ fill: "none",
178
+ stroke: "currentColor",
179
+ viewBox: "0 0 24 24",
180
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
181
+ "path",
182
+ {
183
+ strokeLinecap: "round",
184
+ strokeLinejoin: "round",
185
+ strokeWidth: 2,
186
+ d: "M6 18L18 6M6 6l12 12"
187
+ }
188
+ )
189
+ }
190
+ )
191
+ }
192
+ )
193
+ ] }),
194
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-3", children: [
195
+ showZoomControls && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
196
+ "div",
197
+ {
198
+ className: `rounded-xl border p-3 ${isDark ? "bg-[#20242d] border-[#3a4252] text-[#e6e9ef]" : "bg-gray-50 border-gray-200"}`,
199
+ children: [
200
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
201
+ "div",
202
+ {
203
+ className: `mb-2 text-xs ${isDark ? "text-[#b7c0d2]" : "text-gray-600"}`,
204
+ children: "Zoom"
205
+ }
206
+ ),
207
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between gap-3", children: [
208
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
209
+ "button",
210
+ {
211
+ onClick: () => handleZoom(-0.1),
212
+ className: "p-2 rounded-md border",
213
+ style: { color: accentColor, borderColor: accentColor },
214
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
215
+ "svg",
216
+ {
217
+ className: "w-4 h-4",
218
+ fill: "none",
219
+ stroke: "currentColor",
220
+ viewBox: "0 0 24 24",
221
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
222
+ "path",
223
+ {
224
+ strokeLinecap: "round",
225
+ strokeLinejoin: "round",
226
+ strokeWidth: 2,
227
+ d: "M20 12H4"
228
+ }
229
+ )
230
+ }
231
+ )
232
+ }
233
+ ),
234
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
235
+ "span",
236
+ {
237
+ className: `text-sm font-semibold ${isDark ? "text-[#e6e9ef]" : "text-gray-800"}`,
238
+ children: [
239
+ Math.round(zoom * 100),
240
+ "%"
241
+ ]
242
+ }
243
+ ),
244
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
245
+ "button",
246
+ {
247
+ onClick: () => handleZoom(0.1),
248
+ className: "p-2 rounded-md border",
249
+ style: { color: accentColor, borderColor: accentColor },
250
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
251
+ "svg",
252
+ {
253
+ className: "w-4 h-4",
254
+ fill: "none",
255
+ stroke: "currentColor",
256
+ viewBox: "0 0 24 24",
257
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
258
+ "path",
259
+ {
260
+ strokeLinecap: "round",
261
+ strokeLinejoin: "round",
262
+ strokeWidth: 2,
263
+ d: "M12 4v16m8-8H4"
264
+ }
265
+ )
266
+ }
267
+ )
268
+ }
269
+ )
270
+ ] })
271
+ ]
272
+ }
273
+ ),
274
+ showPageThemeSelector && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
275
+ "div",
276
+ {
277
+ className: `rounded-xl border p-3 ${isDark ? "bg-[#20242d] border-[#3a4252] text-[#e6e9ef]" : "bg-gray-50 border-gray-200"}`,
278
+ children: [
279
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
280
+ "div",
281
+ {
282
+ className: `mb-2 text-xs ${isDark ? "text-[#b7c0d2]" : "text-gray-600"}`,
283
+ children: "Tema da p\xE1gina"
284
+ }
285
+ ),
286
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-2 gap-2", children: themes.map((theme) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
287
+ "button",
288
+ {
289
+ onClick: () => {
290
+ setDocumentState({ pageTheme: theme.id });
291
+ },
292
+ className: `rounded-lg border px-2 py-2 text-xs font-semibold ${pageTheme === theme.id ? "text-white" : isDark ? "text-[#dbe1ed] border-[#49556a]" : "text-gray-700 border-gray-300"}`,
293
+ style: pageTheme === theme.id ? {
294
+ backgroundColor: accentColor,
295
+ borderColor: accentColor
296
+ } : void 0,
297
+ children: theme.name
298
+ },
299
+ theme.id
300
+ )) })
301
+ ]
302
+ }
303
+ ),
304
+ showUIToggle && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
305
+ "button",
306
+ {
307
+ onClick: () => {
308
+ setDocumentState({ uiTheme: isDark ? "light" : "dark" });
309
+ },
310
+ className: `w-full rounded-xl border px-3 py-3 text-left text-sm font-medium flex items-center gap-2 ${isDark ? "bg-[#20242d] border-[#3a4252] text-[#e6e9ef]" : "bg-gray-50 border-gray-200 text-gray-800"}`,
311
+ children: [
312
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
313
+ "svg",
314
+ {
315
+ className: "w-4 h-4 shrink-0",
316
+ fill: "none",
317
+ stroke: "currentColor",
318
+ viewBox: "0 0 24 24",
319
+ children: isDark ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
320
+ "path",
321
+ {
322
+ strokeLinecap: "round",
323
+ strokeLinejoin: "round",
324
+ strokeWidth: 2,
325
+ d: "M12 3v1m0 16v1m8-9h1M3 12H2m15.364 6.364l.707.707M5.93 5.93l-.707-.707m12.141 0l-.707.707M5.93 18.07l-.707.707M12 17a5 5 0 100-10 5 5 0 000 10z"
326
+ }
327
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
328
+ "path",
329
+ {
330
+ strokeLinecap: "round",
331
+ strokeLinejoin: "round",
332
+ strokeWidth: 2,
333
+ d: "M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"
334
+ }
335
+ )
336
+ }
337
+ ),
338
+ isDark ? "Mudar para tema claro" : "Mudar para tema escuro"
339
+ ]
340
+ }
341
+ ),
342
+ showUpload && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
343
+ "button",
344
+ {
345
+ onClick: () => {
346
+ setShowMobileMenu(false);
347
+ fileInputRef.current?.click();
348
+ },
349
+ className: "w-full rounded-xl px-3 py-3 text-left text-sm font-semibold text-white flex items-center gap-2",
350
+ style: { backgroundColor: accentColor },
351
+ children: [
352
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
353
+ "svg",
354
+ {
355
+ className: "w-4 h-4 shrink-0",
356
+ fill: "none",
357
+ stroke: "currentColor",
358
+ viewBox: "0 0 24 24",
359
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
360
+ "path",
361
+ {
362
+ strokeLinecap: "round",
363
+ strokeLinejoin: "round",
364
+ strokeWidth: 2,
365
+ d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
366
+ }
367
+ )
368
+ }
369
+ ),
370
+ "Upload de arquivo"
371
+ ]
372
+ }
373
+ )
374
+ ] })
375
+ ]
376
+ }
377
+ )
378
+ }
379
+ ),
380
+ document.body
381
+ ) : null;
99
382
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
100
383
  "div",
101
384
  {
102
385
  "data-papyrus-theme": uiTheme,
103
- className: `papyrus-topbar papyrus-theme h-14 border-b flex items-center justify-between px-4 z-50 transition-colors duration-200 ${isDark ? "bg-[#1a1a1a] border-[#333] text-white" : "bg-white border-gray-200 text-gray-800"}`,
386
+ className: `papyrus-topbar papyrus-theme relative h-14 border-b flex items-center px-3 sm:px-4 z-50 transition-colors duration-200 ${isDark ? "bg-[#1a1a1a] border-[#333] text-white" : "bg-white border-gray-200 text-gray-800"}`,
104
387
  children: [
105
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center space-x-3", children: [
106
- showSidebarLeftToggle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: toggleSidebarLeft, className: `p-2 rounded-md ${isDark ? "hover:bg-white/10" : "hover:bg-gray-100"}`, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 12h16M4 18h16" }) }) }),
107
- showBrand && (brand ?? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "font-bold text-lg tracking-tight", style: { color: accentColor }, children: [
108
- "Papyrus",
109
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: isDark ? "text-white" : "text-gray-900", children: "Core" })
110
- ] })),
111
- title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: `text-sm font-semibold truncate max-w-[220px] ${isDark ? "text-gray-200" : "text-gray-700"}`, title: typeof title === "string" ? title : void 0, children: title })
388
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2 min-w-0 z-10", children: [
389
+ showSidebarLeftToggle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
390
+ "button",
391
+ {
392
+ onClick: toggleSidebarLeft,
393
+ className: `p-2 rounded-md ${isDark ? "hover:bg-white/10" : "hover:bg-gray-100"}`,
394
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
395
+ "svg",
396
+ {
397
+ className: "w-5 h-5",
398
+ fill: "none",
399
+ stroke: "currentColor",
400
+ viewBox: "0 0 24 24",
401
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
402
+ "path",
403
+ {
404
+ strokeLinecap: "round",
405
+ strokeLinejoin: "round",
406
+ strokeWidth: 2,
407
+ d: "M4 6h16M4 12h16M4 18h16"
408
+ }
409
+ )
410
+ }
411
+ )
412
+ }
413
+ ),
414
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
415
+ "button",
416
+ {
417
+ onClick: toggleToolDock,
418
+ className: `p-2 rounded-md border transition-colors ${toolDockOpen ? isDark ? "border-[#335ea8] bg-[#1b2f55] text-[#8fb6ff]" : "border-blue-300 bg-blue-50 text-blue-700" : isDark ? "border-[#444] bg-[#2a2a2a] hover:bg-[#333]" : "border-gray-300 bg-white hover:bg-gray-100"}`,
419
+ "aria-label": toolDockOpen ? "Fechar ferramentas" : "Abrir ferramentas",
420
+ title: toolDockOpen ? "Fechar ferramentas" : "Abrir ferramentas",
421
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
422
+ "svg",
423
+ {
424
+ className: "w-5 h-5",
425
+ fill: "none",
426
+ stroke: "currentColor",
427
+ viewBox: "0 0 24 24",
428
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
429
+ "path",
430
+ {
431
+ strokeLinecap: "round",
432
+ strokeLinejoin: "round",
433
+ strokeWidth: 2,
434
+ d: "M16.862 3.487a2.25 2.25 0 013.182 3.182L8.22 18.492a4.5 4.5 0 01-1.897 1.12l-2.692.898.898-2.692a4.5 4.5 0 011.12-1.897L16.862 3.487z"
435
+ }
436
+ )
437
+ }
438
+ )
439
+ }
440
+ ),
441
+ showBrand && (brand ?? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
442
+ "span",
443
+ {
444
+ className: "font-bold text-base tracking-tight",
445
+ style: { color: accentColor },
446
+ children: [
447
+ "Papyrus",
448
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: isDark ? "text-white" : "text-gray-900", children: "Core" })
449
+ ]
450
+ }
451
+ )),
452
+ title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
453
+ "span",
454
+ {
455
+ className: `text-sm font-semibold truncate min-w-0 max-w-[35vw] sm:max-w-[260px] ${isDark ? "text-gray-200" : "text-gray-700"}`,
456
+ title: typeof title === "string" ? title : void 0,
457
+ children: title
458
+ }
459
+ )
112
460
  ] }),
113
- (showPageControls || showZoomControls) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center space-x-4", children: [
114
- showPageControls && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: `papyrus-control flex items-center rounded-lg p-1 space-x-1 border ${isDark ? "bg-[#2a2a2a] border-[#444]" : "bg-gray-50 border-gray-200"}`, children: [
115
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => handlePageChange(currentPage - 1), className: "p-1.5 rounded transition-all hover:brightness-110", style: { color: accentColor }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) }) }),
116
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
117
- "input",
118
- {
119
- type: "text",
120
- className: "papyrus-input text-center bg-transparent focus:outline-none font-bold text-sm shrink-0",
121
- style: { width: `${pageDigits + 1.75}ch` },
122
- value: pageInput,
123
- onChange: (e) => setPageInput(e.target.value),
124
- onKeyDown: (e) => e.key === "Enter" && handlePageChange(parseInt(pageInput)),
125
- onBlur: () => handlePageChange(parseInt(pageInput))
126
- }
127
- ),
128
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "opacity-40 px-1", children: "/" }),
129
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "opacity-80 text-sm", children: pageCount > 0 ? pageCount : "\u2014" }),
130
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => handlePageChange(currentPage + 1), className: "p-1.5 rounded transition-all hover:brightness-110", style: { color: accentColor }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) }) })
131
- ] }),
132
- showZoomControls && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: `papyrus-control flex items-center rounded-lg p-1 border ${isDark ? "bg-[#2a2a2a] border-[#444]" : "bg-gray-50 border-gray-200"}`, children: [
133
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => handleZoom(-0.1), className: "p-1.5 rounded hover:brightness-110", style: { color: accentColor }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M20 12H4" }) }) }),
134
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "px-3 text-xs font-bold min-w-[50px] text-center", children: [
135
- Math.round(zoom * 100),
136
- "%"
137
- ] }),
138
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => handleZoom(0.1), className: "p-1.5 rounded hover:brightness-110", style: { color: accentColor }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 4v16m8-8H4" }) }) })
139
- ] })
461
+ (showPageControls || showZoomControls) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "absolute left-1/2 -translate-x-1/2 flex items-center gap-3", children: [
462
+ showPageControls && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
463
+ "div",
464
+ {
465
+ className: `papyrus-control flex items-center rounded-lg p-1 space-x-1 border ${isDark ? "bg-[#2a2a2a] border-[#444]" : "bg-gray-50 border-gray-200"}`,
466
+ children: [
467
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
468
+ "button",
469
+ {
470
+ onClick: () => handlePageChange(currentPage - 1),
471
+ className: "p-1.5 rounded transition-all hover:brightness-110",
472
+ style: { color: accentColor },
473
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
474
+ "svg",
475
+ {
476
+ className: "w-4 h-4",
477
+ fill: "none",
478
+ stroke: "currentColor",
479
+ viewBox: "0 0 24 24",
480
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
481
+ "path",
482
+ {
483
+ strokeLinecap: "round",
484
+ strokeLinejoin: "round",
485
+ strokeWidth: 2,
486
+ d: "M15 19l-7-7 7-7"
487
+ }
488
+ )
489
+ }
490
+ )
491
+ }
492
+ ),
493
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
494
+ "input",
495
+ {
496
+ type: "text",
497
+ className: "papyrus-input text-center bg-transparent focus:outline-none font-bold text-sm shrink-0",
498
+ style: { width: `${pageDigits + 1.75}ch` },
499
+ value: pageInput,
500
+ onChange: (e) => setPageInput(e.target.value),
501
+ onKeyDown: (e) => e.key === "Enter" && handlePageChange(parseInt(pageInput)),
502
+ onBlur: () => handlePageChange(parseInt(pageInput))
503
+ }
504
+ ),
505
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "opacity-40 px-1", children: "/" }),
506
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "opacity-80 text-sm", children: pageCount > 0 ? pageCount : "\u2014" }),
507
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
508
+ "button",
509
+ {
510
+ onClick: () => handlePageChange(currentPage + 1),
511
+ className: "p-1.5 rounded transition-all hover:brightness-110",
512
+ style: { color: accentColor },
513
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
514
+ "svg",
515
+ {
516
+ className: "w-4 h-4",
517
+ fill: "none",
518
+ stroke: "currentColor",
519
+ viewBox: "0 0 24 24",
520
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
521
+ "path",
522
+ {
523
+ strokeLinecap: "round",
524
+ strokeLinejoin: "round",
525
+ strokeWidth: 2,
526
+ d: "M9 5l7 7-7 7"
527
+ }
528
+ )
529
+ }
530
+ )
531
+ }
532
+ )
533
+ ]
534
+ }
535
+ ),
536
+ showZoomControls && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
537
+ "div",
538
+ {
539
+ className: `papyrus-control hidden sm:flex items-center rounded-lg p-1 border ${isDark ? "bg-[#2a2a2a] border-[#444]" : "bg-gray-50 border-gray-200"}`,
540
+ children: [
541
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
542
+ "button",
543
+ {
544
+ onClick: () => handleZoom(-0.1),
545
+ className: "p-1.5 rounded hover:brightness-110",
546
+ style: { color: accentColor },
547
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
548
+ "svg",
549
+ {
550
+ className: "w-4 h-4",
551
+ fill: "none",
552
+ stroke: "currentColor",
553
+ viewBox: "0 0 24 24",
554
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
555
+ "path",
556
+ {
557
+ strokeLinecap: "round",
558
+ strokeLinejoin: "round",
559
+ strokeWidth: 2,
560
+ d: "M20 12H4"
561
+ }
562
+ )
563
+ }
564
+ )
565
+ }
566
+ ),
567
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "px-3 text-xs font-bold min-w-[50px] text-center", children: [
568
+ Math.round(zoom * 100),
569
+ "%"
570
+ ] }),
571
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
572
+ "button",
573
+ {
574
+ onClick: () => handleZoom(0.1),
575
+ className: "p-1.5 rounded hover:brightness-110",
576
+ style: { color: accentColor },
577
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
578
+ "svg",
579
+ {
580
+ className: "w-4 h-4",
581
+ fill: "none",
582
+ stroke: "currentColor",
583
+ viewBox: "0 0 24 24",
584
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
585
+ "path",
586
+ {
587
+ strokeLinecap: "round",
588
+ strokeLinejoin: "round",
589
+ strokeWidth: 2,
590
+ d: "M12 4v16m8-8H4"
591
+ }
592
+ )
593
+ }
594
+ )
595
+ }
596
+ )
597
+ ]
598
+ }
599
+ )
140
600
  ] }),
141
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center space-x-3", children: [
142
- showPageThemeSelector && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative", children: [
601
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "ml-auto flex items-center gap-2 sm:gap-3 z-10", children: [
602
+ showPageThemeSelector && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "relative hidden sm:block", children: [
143
603
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
144
604
  "button",
145
605
  {
146
606
  onClick: () => setShowPageThemes(!showPageThemes),
147
607
  className: `papyrus-control flex items-center space-x-2 px-3 py-1.5 rounded-md text-xs font-bold border transition-all ${isDark ? "bg-[#2a2a2a] border-[#444]" : "bg-gray-50 border-gray-200"}`,
148
608
  children: [
149
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `w-3 h-3 rounded-full border ${themes.find((t) => t.id === pageTheme)?.color}` }),
609
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
610
+ "div",
611
+ {
612
+ className: `w-3 h-3 rounded-full border ${themes.find((t) => t.id === pageTheme)?.color}`
613
+ }
614
+ ),
150
615
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "TEMA" })
151
616
  ]
152
617
  }
153
618
  ),
154
- showPageThemes && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `papyrus-popover absolute top-full right-0 mt-2 w-48 rounded-lg shadow-xl border p-2 z-[60] ${isDark ? "bg-[#2a2a2a] border-[#444]" : "bg-white border-gray-200"}`, children: themes.map((t) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
155
- "button",
156
- {
157
- onClick: () => {
158
- setDocumentState({ pageTheme: t.id });
159
- setShowPageThemes(false);
160
- },
161
- className: `w-full flex items-center space-x-3 px-3 py-2 rounded-md text-sm ${pageTheme === t.id ? "text-white" : isDark ? "hover:bg-white/10 text-gray-300" : "hover:bg-gray-50 text-gray-700"}`,
162
- style: pageTheme === t.id ? { backgroundColor: accentColor } : void 0,
163
- children: [
164
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `w-3 h-3 rounded-full border ${t.color}` }),
165
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t.name })
166
- ]
167
- },
168
- t.id
169
- )) })
170
- ] }),
171
- showUIToggle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => setDocumentState({ uiTheme: isDark ? "light" : "dark" }), className: `p-2 rounded-full ${isDark ? "bg-yellow-500/10 text-yellow-500" : "bg-gray-100 text-gray-500"}`, children: isDark ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414z" }) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" }) }) }),
172
- showUpload && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
173
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
174
- "button",
619
+ showPageThemes && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
620
+ "div",
175
621
  {
176
- onClick: () => fileInputRef.current?.click(),
177
- className: "px-4 py-1.5 text-white rounded-md text-sm font-bold shadow-md active:scale-95",
178
- style: { backgroundColor: accentColor },
179
- children: "UPLOAD"
180
- }
181
- ),
182
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "file", ref: fileInputRef, className: "hidden", accept: ".pdf,.epub,.txt", onChange: async (e) => {
183
- const file = e.target.files?.[0];
184
- if (file) {
185
- setDocumentState({ isLoaded: false });
186
- await engine.load(file);
187
- setDocumentState({ isLoaded: true, pageCount: engine.getPageCount(), currentPage: 1, outline: await engine.getOutline() });
622
+ className: `papyrus-popover absolute top-full right-0 mt-2 w-48 rounded-lg shadow-xl border p-2 z-[60] ${isDark ? "bg-[#2a2a2a] border-[#444]" : "bg-white border-gray-200"}`,
623
+ children: themes.map((theme) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
624
+ "button",
625
+ {
626
+ onClick: () => {
627
+ setDocumentState({ pageTheme: theme.id });
628
+ setShowPageThemes(false);
629
+ },
630
+ className: `w-full flex items-center space-x-3 px-3 py-2 rounded-md text-sm ${pageTheme === theme.id ? "text-white" : isDark ? "hover:bg-white/10 text-gray-300" : "hover:bg-gray-50 text-gray-700"}`,
631
+ style: pageTheme === theme.id ? { backgroundColor: accentColor } : void 0,
632
+ children: [
633
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
634
+ "div",
635
+ {
636
+ className: `w-3 h-3 rounded-full border ${theme.color}`
637
+ }
638
+ ),
639
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: theme.name })
640
+ ]
641
+ },
642
+ theme.id
643
+ ))
188
644
  }
189
- } })
645
+ )
190
646
  ] }),
191
- showSearch && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => toggleSidebarRight("search"), className: `p-2 rounded-md ${isDark ? "hover:bg-white/10" : "hover:bg-gray-100"}`, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }) })
192
- ] })
647
+ showUIToggle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
648
+ "button",
649
+ {
650
+ onClick: () => setDocumentState({ uiTheme: isDark ? "light" : "dark" }),
651
+ className: `hidden sm:inline-flex p-2 rounded-full ${isDark ? "bg-yellow-500/10 text-yellow-500" : "bg-gray-100 text-gray-500"}`,
652
+ children: isDark ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414z" }) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" }) })
653
+ }
654
+ ),
655
+ showUpload && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
656
+ "button",
657
+ {
658
+ onClick: () => fileInputRef.current?.click(),
659
+ className: "hidden sm:inline-flex px-4 py-1.5 text-white rounded-md text-sm font-bold shadow-md active:scale-95",
660
+ style: { backgroundColor: accentColor },
661
+ children: "UPLOAD"
662
+ }
663
+ ),
664
+ showSearch && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
665
+ "button",
666
+ {
667
+ onClick: () => toggleSidebarRight("search"),
668
+ className: `inline-flex p-2 rounded-md ${isDark ? "hover:bg-white/10" : "hover:bg-gray-100"}`,
669
+ "aria-label": "Abrir busca",
670
+ title: "Buscar",
671
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
672
+ "svg",
673
+ {
674
+ className: "w-5 h-5",
675
+ fill: "none",
676
+ stroke: "currentColor",
677
+ viewBox: "0 0 24 24",
678
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
679
+ "path",
680
+ {
681
+ strokeLinecap: "round",
682
+ strokeLinejoin: "round",
683
+ strokeWidth: 2,
684
+ d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
685
+ }
686
+ )
687
+ }
688
+ )
689
+ }
690
+ ),
691
+ hasMobileMenu && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
692
+ "button",
693
+ {
694
+ onClick: () => setShowMobileMenu(true),
695
+ className: `sm:hidden p-2 rounded-md border ${isDark ? "border-[#444] bg-[#2a2a2a] hover:bg-[#333]" : "border-gray-300 bg-white hover:bg-gray-100"}`,
696
+ "aria-label": "Abrir menu",
697
+ title: "Mais op\xE7\xF5es",
698
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
699
+ "svg",
700
+ {
701
+ className: "w-5 h-5",
702
+ fill: "none",
703
+ stroke: "currentColor",
704
+ viewBox: "0 0 24 24",
705
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
706
+ "path",
707
+ {
708
+ strokeLinecap: "round",
709
+ strokeLinejoin: "round",
710
+ strokeWidth: 2,
711
+ d: "M5 12h.01M12 12h.01M19 12h.01"
712
+ }
713
+ )
714
+ }
715
+ )
716
+ }
717
+ ),
718
+ showUpload && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
719
+ "input",
720
+ {
721
+ type: "file",
722
+ ref: fileInputRef,
723
+ className: "hidden",
724
+ accept: ".pdf,.epub,.txt",
725
+ onChange: handleFileUpload
726
+ }
727
+ )
728
+ ] }),
729
+ mobileMenuOverlay
193
730
  ]
194
731
  }
195
732
  );
@@ -224,14 +761,17 @@ var Thumbnail = ({ engine, pageIndex, active, isDark, accentColor, onClick }) =>
224
761
  return;
225
762
  }
226
763
  const root = target.closest(".custom-scrollbar");
227
- const observer = new IntersectionObserver((entries) => {
228
- entries.forEach((entry) => {
229
- if (entry.isIntersecting) {
230
- setIsVisible(true);
231
- observer.disconnect();
232
- }
233
- });
234
- }, { root: root ?? null, rootMargin: "200px" });
764
+ const observer = new IntersectionObserver(
765
+ (entries) => {
766
+ entries.forEach((entry) => {
767
+ if (entry.isIntersecting) {
768
+ setIsVisible(true);
769
+ observer.disconnect();
770
+ }
771
+ });
772
+ },
773
+ { root: root ?? null, rootMargin: "200px" }
774
+ );
235
775
  observer.observe(target);
236
776
  return () => observer.disconnect();
237
777
  }, []);
@@ -252,31 +792,46 @@ var Thumbnail = ({ engine, pageIndex, active, isDark, accentColor, onClick }) =>
252
792
  className: `p-3 cursor-pointer transition-all rounded-lg border-2 ${active ? "shadow-sm" : "border-transparent"}`,
253
793
  style: active ? { borderColor: accentColor, backgroundColor: accentSoft } : void 0,
254
794
  children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col items-center", children: [
255
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `shadow-lg rounded overflow-hidden mb-2 border ${isDark ? "border-[#333]" : "border-gray-200"}`, children: [
256
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
257
- "canvas",
258
- {
259
- ref: canvasRef,
260
- className: "max-w-full h-auto bg-white",
261
- style: { display: renderTargetType === "element" ? "none" : "block" }
262
- }
263
- ),
264
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
265
- "div",
266
- {
267
- ref: htmlRef,
268
- className: "bg-white",
269
- style: {
270
- width: 90,
271
- height: 120,
272
- display: renderTargetType === "element" ? "block" : "none",
273
- overflow: "hidden"
274
- },
275
- children: renderTargetType === "element" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "w-full h-full flex items-center justify-center text-[10px] font-semibold text-gray-500", children: "HTML" })
276
- }
277
- )
278
- ] }),
279
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `text-[11px] font-bold ${active ? "" : isDark ? "text-gray-500" : "text-gray-400"}`, style: active ? { color: accentColor } : void 0, children: pageIndex + 1 })
795
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
796
+ "div",
797
+ {
798
+ className: `shadow-lg rounded overflow-hidden mb-2 border ${isDark ? "border-[#333]" : "border-gray-200"}`,
799
+ children: [
800
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
801
+ "canvas",
802
+ {
803
+ ref: canvasRef,
804
+ className: "max-w-full h-auto bg-white",
805
+ style: {
806
+ display: renderTargetType === "element" ? "none" : "block"
807
+ }
808
+ }
809
+ ),
810
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
811
+ "div",
812
+ {
813
+ ref: htmlRef,
814
+ className: "bg-white",
815
+ style: {
816
+ width: 90,
817
+ height: 120,
818
+ display: renderTargetType === "element" ? "block" : "none",
819
+ overflow: "hidden"
820
+ },
821
+ children: renderTargetType === "element" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "w-full h-full flex items-center justify-center text-[10px] font-semibold text-gray-500", children: "HTML" })
822
+ }
823
+ )
824
+ ]
825
+ }
826
+ ),
827
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
828
+ "span",
829
+ {
830
+ className: `text-[11px] font-bold ${active ? "" : isDark ? "text-gray-500" : "text-gray-400"}`,
831
+ style: active ? { color: accentColor } : void 0,
832
+ children: pageIndex + 1
833
+ }
834
+ )
280
835
  ] })
281
836
  }
282
837
  );
@@ -286,8 +841,11 @@ var OutlineNode = ({ item, engine, isDark, accentColor, depth = 0 }) => {
286
841
  const [expanded, setExpanded] = (0, import_react2.useState)(true);
287
842
  const accentSoft = withAlpha(accentColor, 0.2);
288
843
  const matchesSearch = outlineSearchQuery === "" || item.title.toLowerCase().includes(outlineSearchQuery.toLowerCase());
289
- const hasMatchingChildren = item.children?.some((child) => child.title.toLowerCase().includes(outlineSearchQuery.toLowerCase()));
290
- if (!matchesSearch && !hasMatchingChildren && outlineSearchQuery !== "") return null;
844
+ const hasMatchingChildren = item.children?.some(
845
+ (child) => child.title.toLowerCase().includes(outlineSearchQuery.toLowerCase())
846
+ );
847
+ if (!matchesSearch && !hasMatchingChildren && outlineSearchQuery !== "")
848
+ return null;
291
849
  const handleClick = () => {
292
850
  if (item.pageIndex >= 0) {
293
851
  engine.goToPage(item.pageIndex + 1);
@@ -306,12 +864,32 @@ var OutlineNode = ({ item, engine, isDark, accentColor, depth = 0 }) => {
306
864
  "button",
307
865
  {
308
866
  className: `mr-1 text-gray-400 transition-transform p-1`,
309
- style: { color: accentColor, transform: expanded ? "rotate(90deg)" : "rotate(0deg)" },
867
+ style: {
868
+ color: accentColor,
869
+ transform: expanded ? "rotate(90deg)" : "rotate(0deg)"
870
+ },
310
871
  onClick: (e) => {
311
872
  e.stopPropagation();
312
873
  setExpanded(!expanded);
313
874
  },
314
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "w-3 h-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 3, d: "M9 5l7 7-7 7" }) })
875
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
876
+ "svg",
877
+ {
878
+ className: "w-3 h-3",
879
+ fill: "none",
880
+ stroke: "currentColor",
881
+ viewBox: "0 0 24 24",
882
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
883
+ "path",
884
+ {
885
+ strokeLinecap: "round",
886
+ strokeLinejoin: "round",
887
+ strokeWidth: 3,
888
+ d: "M9 5l7 7-7 7"
889
+ }
890
+ )
891
+ }
892
+ )
315
893
  }
316
894
  ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "w-5" }),
317
895
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -325,7 +903,17 @@ var OutlineNode = ({ item, engine, isDark, accentColor, depth = 0 }) => {
325
903
  ]
326
904
  }
327
905
  ),
328
- expanded && item.children && item.children.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex flex-col", children: item.children.map((child, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(OutlineNode, { item: child, engine, isDark, accentColor, depth: depth + 1 }, i)) })
906
+ expanded && item.children && item.children.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex flex-col", children: item.children.map((child, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
907
+ OutlineNode,
908
+ {
909
+ item: child,
910
+ engine,
911
+ isDark,
912
+ accentColor,
913
+ depth: depth + 1
914
+ },
915
+ i
916
+ )) })
329
917
  ] });
330
918
  };
331
919
  var SidebarLeft = ({ engine }) => {
@@ -349,39 +937,129 @@ var SidebarLeft = ({ engine }) => {
349
937
  "div",
350
938
  {
351
939
  "data-papyrus-theme": uiTheme,
352
- className: `papyrus-sidebar-left papyrus-theme w-72 border-r flex flex-col h-full shrink-0 overflow-hidden transition-colors duration-200 ${isDark ? "bg-[#2a2a2a] border-[#3a3a3a]" : "bg-[#fcfcfc] border-gray-200"}`,
940
+ className: `papyrus-sidebar-left papyrus-theme absolute left-0 top-0 bottom-0 z-[120] w-[85vw] max-w-72 border-r flex flex-col h-full overflow-hidden transition-colors duration-200 ${isDark ? "bg-[#2a2a2a] border-[#3a3a3a]" : "bg-[#fcfcfc] border-gray-200"}`,
353
941
  children: [
354
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `p-4 border-b flex flex-col space-y-4 ${isDark ? "border-[#3a3a3a]" : "border-gray-100"}`, children: [
355
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center justify-between", children: [
356
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { className: `text-sm font-bold uppercase tracking-widest ${isDark ? "text-gray-100" : "text-gray-800"}`, children: sidebarLeftTab === "thumbnails" ? "Thumbnails" : "Sum\xE1rio" }),
357
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: () => setDocumentState({ sidebarLeftOpen: false }), className: "text-gray-400 hover:text-gray-600", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
358
- ] }),
359
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex gap-1", children: [
360
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
361
- "button",
362
- {
363
- onClick: () => setSidebarLeftTab("thumbnails"),
364
- className: `p-2 rounded-md ${sidebarLeftTab === "thumbnails" ? isDark ? "bg-white/10 text-white" : "bg-white shadow-sm border border-gray-200" : "text-gray-400"}`,
365
- style: sidebarLeftTab === "thumbnails" && !isDark ? { color: accentColor } : void 0,
366
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2 2V6z" }) })
367
- }
368
- ),
369
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
370
- "button",
371
- {
372
- onClick: () => setSidebarLeftTab("summary"),
373
- className: `p-2 rounded-md ${sidebarLeftTab === "summary" ? isDark ? "bg-white/10 text-white" : "bg-white shadow-sm border border-gray-200" : "text-gray-400"}`,
374
- style: sidebarLeftTab === "summary" && !isDark ? { color: accentColor } : void 0,
375
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 12h16M4 18h7" }) })
376
- }
377
- )
378
- ] })
379
- ] }),
380
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3", children: sidebarLeftTab === "thumbnails" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "space-y-1", children: Array.from({ length: pageCount }).map((_, idx) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Thumbnail, { engine, pageIndex: idx, isDark, accentColor, active: currentPage === idx + 1, onClick: () => {
381
- engine.goToPage(idx + 1);
382
- setDocumentState({ currentPage: idx + 1 });
383
- triggerScrollToPage(idx);
384
- } }, idx)) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex flex-col space-y-0.5", children: outline.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(OutlineNode, { item, engine, isDark, accentColor }, i)) }) })
942
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
943
+ "div",
944
+ {
945
+ className: `p-4 border-b flex flex-col space-y-4 ${isDark ? "border-[#3a3a3a]" : "border-gray-100"}`,
946
+ children: [
947
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center justify-between", children: [
948
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
949
+ "h3",
950
+ {
951
+ className: `text-sm font-bold uppercase tracking-widest ${isDark ? "text-gray-100" : "text-gray-800"}`,
952
+ children: sidebarLeftTab === "thumbnails" ? "Thumbnails" : "Sum\xE1rio"
953
+ }
954
+ ),
955
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
956
+ "button",
957
+ {
958
+ onClick: () => setDocumentState({ sidebarLeftOpen: false }),
959
+ className: "text-gray-400 hover:text-gray-600",
960
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
961
+ "svg",
962
+ {
963
+ className: "w-4 h-4",
964
+ fill: "none",
965
+ stroke: "currentColor",
966
+ viewBox: "0 0 24 24",
967
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
968
+ "path",
969
+ {
970
+ strokeLinecap: "round",
971
+ strokeLinejoin: "round",
972
+ strokeWidth: 2,
973
+ d: "M6 18L18 6M6 6l12 12"
974
+ }
975
+ )
976
+ }
977
+ )
978
+ }
979
+ )
980
+ ] }),
981
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex gap-1", children: [
982
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
983
+ "button",
984
+ {
985
+ onClick: () => setSidebarLeftTab("thumbnails"),
986
+ className: `p-2 rounded-md ${sidebarLeftTab === "thumbnails" ? isDark ? "bg-white/10 text-white" : "bg-white shadow-sm border border-gray-200" : "text-gray-400"}`,
987
+ style: sidebarLeftTab === "thumbnails" && !isDark ? { color: accentColor } : void 0,
988
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
989
+ "svg",
990
+ {
991
+ className: "w-5 h-5",
992
+ fill: "none",
993
+ stroke: "currentColor",
994
+ viewBox: "0 0 24 24",
995
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
996
+ "path",
997
+ {
998
+ strokeLinecap: "round",
999
+ strokeLinejoin: "round",
1000
+ strokeWidth: 2,
1001
+ d: "M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2 2V6z"
1002
+ }
1003
+ )
1004
+ }
1005
+ )
1006
+ }
1007
+ ),
1008
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1009
+ "button",
1010
+ {
1011
+ onClick: () => setSidebarLeftTab("summary"),
1012
+ className: `p-2 rounded-md ${sidebarLeftTab === "summary" ? isDark ? "bg-white/10 text-white" : "bg-white shadow-sm border border-gray-200" : "text-gray-400"}`,
1013
+ style: sidebarLeftTab === "summary" && !isDark ? { color: accentColor } : void 0,
1014
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1015
+ "svg",
1016
+ {
1017
+ className: "w-5 h-5",
1018
+ fill: "none",
1019
+ stroke: "currentColor",
1020
+ viewBox: "0 0 24 24",
1021
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1022
+ "path",
1023
+ {
1024
+ strokeLinecap: "round",
1025
+ strokeLinejoin: "round",
1026
+ strokeWidth: 2,
1027
+ d: "M4 6h16M4 12h16M4 18h7"
1028
+ }
1029
+ )
1030
+ }
1031
+ )
1032
+ }
1033
+ )
1034
+ ] })
1035
+ ]
1036
+ }
1037
+ ),
1038
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-3", children: sidebarLeftTab === "thumbnails" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "space-y-1", children: Array.from({ length: pageCount }).map((_, idx) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1039
+ Thumbnail,
1040
+ {
1041
+ engine,
1042
+ pageIndex: idx,
1043
+ isDark,
1044
+ accentColor,
1045
+ active: currentPage === idx + 1,
1046
+ onClick: () => {
1047
+ engine.goToPage(idx + 1);
1048
+ setDocumentState({ currentPage: idx + 1 });
1049
+ triggerScrollToPage(idx);
1050
+ }
1051
+ },
1052
+ idx
1053
+ )) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex flex-col space-y-0.5", children: outline.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1054
+ OutlineNode,
1055
+ {
1056
+ item,
1057
+ engine,
1058
+ isDark,
1059
+ accentColor
1060
+ },
1061
+ i
1062
+ )) }) })
385
1063
  ]
386
1064
  }
387
1065
  );
@@ -437,31 +1115,61 @@ var SidebarRight = ({ engine }) => {
437
1115
  "div",
438
1116
  {
439
1117
  "data-papyrus-theme": uiTheme,
440
- className: `papyrus-sidebar-right papyrus-theme w-80 border-l flex flex-col h-full shrink-0 transition-colors duration-200 shadow-2xl z-40 ${isDark ? "bg-[#1a1a1a] border-[#333]" : "bg-white border-gray-200"}`,
1118
+ className: `papyrus-sidebar-right papyrus-theme absolute right-0 top-0 bottom-0 z-[120] w-[88vw] max-w-80 border-l flex flex-col h-full transition-colors duration-200 shadow-2xl ${isDark ? "bg-[#1a1a1a] border-[#333]" : "bg-white border-gray-200"}`,
441
1119
  children: [
442
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `p-4 border-b flex items-center justify-between shrink-0 ${isDark ? "border-[#333]" : "border-gray-100"}`, children: [
443
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex space-x-6", children: [
444
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
445
- "button",
446
- {
447
- onClick: () => toggleSidebarRight("search"),
448
- className: `text-[10px] font-black uppercase tracking-widest pb-1 transition-all ${sidebarRightTab === "search" ? "border-b-2" : "text-gray-400"}`,
449
- style: sidebarRightTab === "search" ? { color: accentColor, borderColor: accentColor } : void 0,
450
- children: "Busca"
451
- }
452
- ),
453
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
454
- "button",
455
- {
456
- onClick: () => toggleSidebarRight("annotations"),
457
- className: `text-[10px] font-black uppercase tracking-widest pb-1 transition-all ${sidebarRightTab === "annotations" ? "border-b-2" : "text-gray-400"}`,
458
- style: sidebarRightTab === "annotations" ? { color: accentColor, borderColor: accentColor } : void 0,
459
- children: "Notas"
460
- }
461
- )
462
- ] }),
463
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { onClick: () => toggleSidebarRight(), className: "papyrus-unstyled-button text-gray-400 hover:text-red-500 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
464
- ] }),
1120
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1121
+ "div",
1122
+ {
1123
+ className: `p-4 border-b flex items-center justify-between shrink-0 ${isDark ? "border-[#333]" : "border-gray-100"}`,
1124
+ children: [
1125
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex space-x-6", children: [
1126
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1127
+ "button",
1128
+ {
1129
+ onClick: () => toggleSidebarRight("search"),
1130
+ className: `text-[10px] font-black uppercase tracking-widest pb-1 transition-all ${sidebarRightTab === "search" ? "border-b-2" : "text-gray-400"}`,
1131
+ style: sidebarRightTab === "search" ? { color: accentColor, borderColor: accentColor } : void 0,
1132
+ children: "Busca"
1133
+ }
1134
+ ),
1135
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1136
+ "button",
1137
+ {
1138
+ onClick: () => toggleSidebarRight("annotations"),
1139
+ className: `text-[10px] font-black uppercase tracking-widest pb-1 transition-all ${sidebarRightTab === "annotations" ? "border-b-2" : "text-gray-400"}`,
1140
+ style: sidebarRightTab === "annotations" ? { color: accentColor, borderColor: accentColor } : void 0,
1141
+ children: "Notas"
1142
+ }
1143
+ )
1144
+ ] }),
1145
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1146
+ "button",
1147
+ {
1148
+ onClick: () => toggleSidebarRight(),
1149
+ className: "papyrus-unstyled-button text-gray-400 hover:text-red-500 transition-colors",
1150
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1151
+ "svg",
1152
+ {
1153
+ className: "w-4 h-4",
1154
+ fill: "none",
1155
+ stroke: "currentColor",
1156
+ viewBox: "0 0 24 24",
1157
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1158
+ "path",
1159
+ {
1160
+ strokeLinecap: "round",
1161
+ strokeLinejoin: "round",
1162
+ strokeWidth: 2,
1163
+ d: "M6 18L18 6M6 6l12 12"
1164
+ }
1165
+ )
1166
+ }
1167
+ )
1168
+ }
1169
+ )
1170
+ ]
1171
+ }
1172
+ ),
465
1173
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex-1 overflow-y-auto p-4 custom-scrollbar bg-opacity-50", children: sidebarRightTab === "search" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "space-y-4", children: [
466
1174
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { onSubmit: handleSearch, className: "relative mb-6", children: [
467
1175
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
@@ -475,10 +1183,41 @@ var SidebarRight = ({ engine }) => {
475
1183
  }
476
1184
  ),
477
1185
  resultsCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "absolute right-9 top-2.5 text-[10px] font-bold text-gray-400", children: resultsCount }),
478
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "papyrus-unstyled-button absolute right-3 top-2.5 text-gray-400 transition-colors", style: { color: accentColor }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2.5, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }) })
1186
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1187
+ "button",
1188
+ {
1189
+ type: "submit",
1190
+ className: "papyrus-unstyled-button absolute right-3 top-2.5 text-gray-400 transition-colors",
1191
+ style: { color: accentColor },
1192
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1193
+ "svg",
1194
+ {
1195
+ className: "w-4 h-4",
1196
+ fill: "none",
1197
+ stroke: "currentColor",
1198
+ viewBox: "0 0 24 24",
1199
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1200
+ "path",
1201
+ {
1202
+ strokeLinecap: "round",
1203
+ strokeLinejoin: "round",
1204
+ strokeWidth: 2.5,
1205
+ d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
1206
+ }
1207
+ )
1208
+ }
1209
+ )
1210
+ }
1211
+ )
479
1212
  ] }),
480
1213
  isSearching && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex flex-col items-center justify-center py-12 space-y-3", children: [
481
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "w-6 h-6 border-2 border-t-transparent rounded-full animate-spin", style: { borderColor: accentColor } }),
1214
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1215
+ "div",
1216
+ {
1217
+ className: "w-6 h-6 border-2 border-t-transparent rounded-full animate-spin",
1218
+ style: { borderColor: accentColor }
1219
+ }
1220
+ ),
482
1221
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-[10px] font-bold text-gray-500 uppercase", children: "Varrendo documento..." })
483
1222
  ] }),
484
1223
  !isSearching && searchResults.map((res, idx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
@@ -487,11 +1226,17 @@ var SidebarRight = ({ engine }) => {
487
1226
  onClick: () => {
488
1227
  const page = res.pageIndex + 1;
489
1228
  engine.goToPage(page);
490
- setDocumentState({ activeSearchIndex: idx, currentPage: page });
1229
+ setDocumentState({
1230
+ activeSearchIndex: idx,
1231
+ currentPage: page
1232
+ });
491
1233
  triggerScrollToPage(res.pageIndex);
492
1234
  },
493
1235
  className: `p-4 rounded-xl border-2 cursor-pointer transition-all group hover:scale-[1.02] ${idx === activeSearchIndex ? "shadow-lg" : isDark ? "border-[#333] hover:border-[#555] bg-[#222]" : "border-gray-50 hover:border-gray-200 bg-gray-50/50 hover:bg-white"}`,
494
- style: idx === activeSearchIndex ? { borderColor: accentColor, backgroundColor: accentSoft } : void 0,
1236
+ style: idx === activeSearchIndex ? {
1237
+ borderColor: accentColor,
1238
+ backgroundColor: accentSoft
1239
+ } : void 0,
495
1240
  children: [
496
1241
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [
497
1242
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
@@ -513,15 +1258,29 @@ var SidebarRight = ({ engine }) => {
513
1258
  fill: "none",
514
1259
  stroke: "currentColor",
515
1260
  viewBox: "0 0 24 24",
516
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 3, d: "M9 5l7 7-7 7" })
1261
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1262
+ "path",
1263
+ {
1264
+ strokeLinecap: "round",
1265
+ strokeLinejoin: "round",
1266
+ strokeWidth: 3,
1267
+ d: "M9 5l7 7-7 7"
1268
+ }
1269
+ )
517
1270
  }
518
1271
  )
519
1272
  ] }),
520
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: `text-[11px] font-medium leading-relaxed italic ${isDark ? "text-gray-400" : "text-gray-600"}`, children: [
521
- "...",
522
- res.text,
523
- "..."
524
- ] })
1273
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1274
+ "p",
1275
+ {
1276
+ className: `text-[11px] font-medium leading-relaxed italic ${isDark ? "text-gray-400" : "text-gray-600"}`,
1277
+ children: [
1278
+ "...",
1279
+ res.text,
1280
+ "..."
1281
+ ]
1282
+ }
1283
+ )
525
1284
  ]
526
1285
  },
527
1286
  idx
@@ -532,21 +1291,67 @@ var SidebarRight = ({ engine }) => {
532
1291
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex-1 h-px bg-current ml-3 opacity-10" })
533
1292
  ] }),
534
1293
  annotations.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "text-center py-20", children: [
535
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "w-12 h-12 bg-gray-500/10 rounded-full flex items-center justify-center mx-auto mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { className: "w-6 h-6 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" }) }) }),
1294
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "w-12 h-12 bg-gray-500/10 rounded-full flex items-center justify-center mx-auto mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1295
+ "svg",
1296
+ {
1297
+ className: "w-6 h-6 text-gray-400",
1298
+ fill: "none",
1299
+ stroke: "currentColor",
1300
+ viewBox: "0 0 24 24",
1301
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1302
+ "path",
1303
+ {
1304
+ strokeLinecap: "round",
1305
+ strokeLinejoin: "round",
1306
+ strokeWidth: 2,
1307
+ d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
1308
+ }
1309
+ )
1310
+ }
1311
+ ) }),
536
1312
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-[10px] font-bold text-gray-400 uppercase tracking-widest", children: "Sem anota\xE7\xF5es" })
537
- ] }) : annotations.map((ann) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `p-4 rounded-xl border group transition-all cursor-pointer ${isDark ? "bg-[#222] border-[#333] hover:border-[#444]" : "bg-white border-gray-100 shadow-sm hover:shadow-md"}`, children: [
538
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center justify-between mb-3", children: [
539
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center space-x-2", children: [
540
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "w-2.5 h-2.5 rounded-full", style: { backgroundColor: ann.color } }),
541
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "text-[10px] font-black", style: { color: accentColor }, children: [
542
- "P",
543
- ann.pageIndex + 1
544
- ] })
545
- ] }),
546
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-[9px] text-gray-400 font-bold", children: new Date(ann.createdAt).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) })
547
- ] }),
548
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: `text-[11px] font-bold uppercase tracking-tight ${isDark ? "text-gray-200" : "text-gray-700"}`, children: ann.type })
549
- ] }, ann.id))
1313
+ ] }) : annotations.map((ann) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1314
+ "div",
1315
+ {
1316
+ className: `p-4 rounded-xl border group transition-all cursor-pointer ${isDark ? "bg-[#222] border-[#333] hover:border-[#444]" : "bg-white border-gray-100 shadow-sm hover:shadow-md"}`,
1317
+ children: [
1318
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center justify-between mb-3", children: [
1319
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center space-x-2", children: [
1320
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1321
+ "div",
1322
+ {
1323
+ className: "w-2.5 h-2.5 rounded-full",
1324
+ style: { backgroundColor: ann.color }
1325
+ }
1326
+ ),
1327
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1328
+ "span",
1329
+ {
1330
+ className: "text-[10px] font-black",
1331
+ style: { color: accentColor },
1332
+ children: [
1333
+ "P",
1334
+ ann.pageIndex + 1
1335
+ ]
1336
+ }
1337
+ )
1338
+ ] }),
1339
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-[9px] text-gray-400 font-bold", children: new Date(ann.createdAt).toLocaleTimeString([], {
1340
+ hour: "2-digit",
1341
+ minute: "2-digit"
1342
+ }) })
1343
+ ] }),
1344
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1345
+ "p",
1346
+ {
1347
+ className: `text-[11px] font-bold uppercase tracking-tight ${isDark ? "text-gray-200" : "text-gray-700"}`,
1348
+ children: ann.type
1349
+ }
1350
+ )
1351
+ ]
1352
+ },
1353
+ ann.id
1354
+ ))
550
1355
  ] }) })
551
1356
  ]
552
1357
  }
@@ -1214,8 +2019,22 @@ var PageRenderer_default = PageRenderer;
1214
2019
  // components/Viewer.tsx
1215
2020
  var import_jsx_runtime5 = require("react/jsx-runtime");
1216
2021
  var BASE_OVERSCAN = 6;
2022
+ var MIN_ZOOM = 0.2;
2023
+ var MAX_ZOOM = 5;
1217
2024
  var Viewer = ({ engine }) => {
1218
- const { pageCount, currentPage, zoom, activeTool, uiTheme, scrollToPageSignal, setDocumentState, accentColor, annotationColor, setAnnotationColor } = (0, import_core5.useViewerStore)();
2025
+ const {
2026
+ pageCount,
2027
+ currentPage,
2028
+ zoom,
2029
+ activeTool,
2030
+ uiTheme,
2031
+ scrollToPageSignal,
2032
+ setDocumentState,
2033
+ accentColor,
2034
+ annotationColor,
2035
+ setAnnotationColor,
2036
+ toolDockOpen
2037
+ } = (0, import_core5.useViewerStore)();
1219
2038
  const isDark = uiTheme === "dark";
1220
2039
  const viewerRef = (0, import_react5.useRef)(null);
1221
2040
  const colorPickerRef = (0, import_react5.useRef)(null);
@@ -1224,6 +2043,13 @@ var Viewer = ({ engine }) => {
1224
2043
  const frameRef = (0, import_react5.useRef)(null);
1225
2044
  const jumpRef = (0, import_react5.useRef)(false);
1226
2045
  const jumpTimerRef = (0, import_react5.useRef)(null);
2046
+ const pinchRef = (0, import_react5.useRef)({
2047
+ active: false,
2048
+ startDistance: 0,
2049
+ startZoom: 1,
2050
+ pendingZoom: null,
2051
+ rafId: null
2052
+ });
1227
2053
  const [availableWidth, setAvailableWidth] = (0, import_react5.useState)(null);
1228
2054
  const [basePageSize, setBasePageSize] = (0, import_react5.useState)(null);
1229
2055
  const [pageSizes, setPageSizes] = (0, import_react5.useState)({});
@@ -1231,7 +2057,16 @@ var Viewer = ({ engine }) => {
1231
2057
  const isCompact = availableWidth !== null && availableWidth < 820;
1232
2058
  const paddingY = isCompact ? "py-10" : "py-16";
1233
2059
  const toolDockPosition = isCompact ? "bottom-4" : "bottom-8";
1234
- const colorPalette = ["#fbbf24", "#f97316", "#ef4444", "#22c55e", "#06b6d4", "#3b82f6", "#8b5cf6", "#111827"];
2060
+ const colorPalette = [
2061
+ "#fbbf24",
2062
+ "#f97316",
2063
+ "#ef4444",
2064
+ "#22c55e",
2065
+ "#06b6d4",
2066
+ "#3b82f6",
2067
+ "#8b5cf6",
2068
+ "#111827"
2069
+ ];
1235
2070
  (0, import_react5.useEffect)(() => {
1236
2071
  if (!colorPickerOpen) return;
1237
2072
  const handleClick = (event) => {
@@ -1243,6 +2078,17 @@ var Viewer = ({ engine }) => {
1243
2078
  document.addEventListener("mousedown", handleClick);
1244
2079
  return () => document.removeEventListener("mousedown", handleClick);
1245
2080
  }, [colorPickerOpen]);
2081
+ (0, import_react5.useEffect)(() => {
2082
+ if (!toolDockOpen && colorPickerOpen) setColorPickerOpen(false);
2083
+ }, [toolDockOpen, colorPickerOpen]);
2084
+ (0, import_react5.useEffect)(
2085
+ () => () => {
2086
+ if (pinchRef.current.rafId != null) {
2087
+ cancelAnimationFrame(pinchRef.current.rafId);
2088
+ }
2089
+ },
2090
+ []
2091
+ );
1246
2092
  (0, import_react5.useEffect)(() => {
1247
2093
  const element = viewerRef.current;
1248
2094
  if (!element) return;
@@ -1289,7 +2135,10 @@ var Viewer = ({ engine }) => {
1289
2135
  if (target) {
1290
2136
  targetTop = target.offsetTop;
1291
2137
  } else if (basePageSize && availableWidth) {
1292
- const fitScale = Math.min(1, Math.max(0, availableWidth - 48) / basePageSize.width);
2138
+ const fitScale = Math.min(
2139
+ 1,
2140
+ Math.max(0, availableWidth - 48) / basePageSize.width
2141
+ );
1293
2142
  const estimatedPageHeight = basePageSize.height * fitScale * zoom + 64;
1294
2143
  targetTop = Math.max(0, estimatedPageHeight * scrollToPageSignal);
1295
2144
  } else if (pageCount > 1) {
@@ -1308,7 +2157,14 @@ var Viewer = ({ engine }) => {
1308
2157
  }, 250);
1309
2158
  }
1310
2159
  setDocumentState({ scrollToPageSignal: null });
1311
- }, [scrollToPageSignal, setDocumentState, basePageSize, availableWidth, zoom, pageCount]);
2160
+ }, [
2161
+ scrollToPageSignal,
2162
+ setDocumentState,
2163
+ basePageSize,
2164
+ availableWidth,
2165
+ zoom,
2166
+ pageCount
2167
+ ]);
1312
2168
  (0, import_react5.useEffect)(() => {
1313
2169
  setPageSizes({});
1314
2170
  }, [zoom]);
@@ -1331,18 +2187,23 @@ var Viewer = ({ engine }) => {
1331
2187
  const shouldSwitch = bestPage !== currentPage && (currentRatio <= 0 || bestRatio >= currentRatio + 0.1 || bestRatio >= 0.75);
1332
2188
  if (shouldSwitch) setDocumentState({ currentPage: bestPage });
1333
2189
  };
1334
- const observer = new IntersectionObserver((entries) => {
1335
- entries.forEach((entry) => {
1336
- const pageIndex = parseInt(entry.target.getAttribute("data-page-index") || "0");
1337
- if (!Number.isFinite(pageIndex)) return;
1338
- intersectionRatiosRef.current[pageIndex] = entry.isIntersecting ? entry.intersectionRatio : 0;
1339
- });
1340
- if (frameRef.current != null) cancelAnimationFrame(frameRef.current);
1341
- frameRef.current = requestAnimationFrame(() => {
1342
- frameRef.current = null;
1343
- flushCurrentPage();
1344
- });
1345
- }, { root, threshold: [0.25, 0.5, 0.75] });
2190
+ const observer = new IntersectionObserver(
2191
+ (entries) => {
2192
+ entries.forEach((entry) => {
2193
+ const pageIndex = parseInt(
2194
+ entry.target.getAttribute("data-page-index") || "0"
2195
+ );
2196
+ if (!Number.isFinite(pageIndex)) return;
2197
+ intersectionRatiosRef.current[pageIndex] = entry.isIntersecting ? entry.intersectionRatio : 0;
2198
+ });
2199
+ if (frameRef.current != null) cancelAnimationFrame(frameRef.current);
2200
+ frameRef.current = requestAnimationFrame(() => {
2201
+ frameRef.current = null;
2202
+ flushCurrentPage();
2203
+ });
2204
+ },
2205
+ { root, threshold: [0.25, 0.5, 0.75] }
2206
+ );
1346
2207
  const pageElements = root.querySelectorAll(".page-container");
1347
2208
  pageElements.forEach((el) => observer.observe(el));
1348
2209
  return () => {
@@ -1360,7 +2221,10 @@ var Viewer = ({ engine }) => {
1360
2221
  const virtualEnd = Math.min(pageCount - 1, virtualAnchor + virtualOverscan);
1361
2222
  const fallbackSize = (0, import_react5.useMemo)(() => {
1362
2223
  if (basePageSize && availableWidth) {
1363
- const fitScale = Math.min(1, Math.max(0, availableWidth - 48) / basePageSize.width);
2224
+ const fitScale = Math.min(
2225
+ 1,
2226
+ Math.max(0, availableWidth - 48) / basePageSize.width
2227
+ );
1364
2228
  return {
1365
2229
  width: Math.round(basePageSize.width * fitScale * zoom),
1366
2230
  height: Math.round(basePageSize.height * fitScale * zoom)
@@ -1374,31 +2238,103 @@ var Viewer = ({ engine }) => {
1374
2238
  }, [basePageSize, availableWidth, zoom]);
1375
2239
  const averagePageHeight = (0, import_react5.useMemo)(() => {
1376
2240
  const heights = Object.values(pageSizes).map((size) => size.height);
1377
- if (!heights.length) return availableWidth ? Math.max(680, availableWidth * 1.3) : 1100;
2241
+ if (!heights.length)
2242
+ return availableWidth ? Math.max(680, availableWidth * 1.3) : 1100;
1378
2243
  return Math.round(heights.reduce((sum, h) => sum + h, 0) / heights.length);
1379
2244
  }, [pageSizes, availableWidth]);
1380
2245
  const pages = Array.from({ length: pageCount }).map((_, i) => i);
1381
2246
  const handlePageMeasured = (pageIndex, size) => {
1382
2247
  setPageSizes((prev) => {
1383
2248
  const current = prev[pageIndex];
1384
- if (current && current.width === size.width && current.height === size.height) return prev;
2249
+ if (current && current.width === size.width && current.height === size.height)
2250
+ return prev;
1385
2251
  return { ...prev, [pageIndex]: size };
1386
2252
  });
1387
2253
  };
1388
2254
  const tools = [
1389
2255
  { id: "select", name: "Select", icon: "M15 15l-2 5L9 9l11 4-5 2zm0 0l5 5" },
1390
- { id: "highlight", name: "Highlight", icon: "M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" },
1391
- { id: "underline", name: "Underline", icon: "M6 3v6a6 6 0 0012 0V3M4 21h16" },
1392
- { id: "squiggly", name: "Squiggly", icon: "M3 17c2-4 4-4 6 0s4 4 6 0 4-4 6 0" },
2256
+ {
2257
+ id: "highlight",
2258
+ name: "Highlight",
2259
+ icon: "M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"
2260
+ },
2261
+ {
2262
+ id: "underline",
2263
+ name: "Underline",
2264
+ icon: "M6 3v6a6 6 0 0012 0V3M4 21h16"
2265
+ },
2266
+ {
2267
+ id: "squiggly",
2268
+ name: "Squiggly",
2269
+ icon: "M3 17c2-4 4-4 6 0s4 4 6 0 4-4 6 0"
2270
+ },
1393
2271
  { id: "strikeout", name: "Strike", icon: "M4 12h16M8 6h8M8 18h8" },
1394
2272
  { id: "ink", name: "Freehand", icon: "M4 19c4-6 7-9 10-9 3 0 5 2 6 5" },
1395
- { id: "comment", name: "Note", icon: "M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z" }
2273
+ {
2274
+ id: "comment",
2275
+ name: "Note",
2276
+ icon: "M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"
2277
+ }
1396
2278
  ];
2279
+ const getTouchDistance = (touchA, touchB) => {
2280
+ const dx = touchA.clientX - touchB.clientX;
2281
+ const dy = touchA.clientY - touchB.clientY;
2282
+ return Math.sqrt(dx * dx + dy * dy);
2283
+ };
2284
+ const flushPinchZoom = () => {
2285
+ const nextZoom = pinchRef.current.pendingZoom;
2286
+ pinchRef.current.pendingZoom = null;
2287
+ pinchRef.current.rafId = null;
2288
+ if (nextZoom == null) return;
2289
+ engine.setZoom(nextZoom);
2290
+ setDocumentState({ zoom: nextZoom });
2291
+ };
2292
+ const handleTouchStart = (event) => {
2293
+ if (event.touches.length < 2) return;
2294
+ const touchA = event.touches[0];
2295
+ const touchB = event.touches[1];
2296
+ pinchRef.current.active = true;
2297
+ pinchRef.current.startDistance = getTouchDistance(touchA, touchB);
2298
+ pinchRef.current.startZoom = zoom;
2299
+ event.preventDefault();
2300
+ };
2301
+ const handleTouchMove = (event) => {
2302
+ if (!pinchRef.current.active || event.touches.length < 2) return;
2303
+ const touchA = event.touches[0];
2304
+ const touchB = event.touches[1];
2305
+ const nextDistance = getTouchDistance(touchA, touchB);
2306
+ if (!pinchRef.current.startDistance) return;
2307
+ const scale = nextDistance / pinchRef.current.startDistance;
2308
+ const nextZoom = Math.max(
2309
+ MIN_ZOOM,
2310
+ Math.min(MAX_ZOOM, pinchRef.current.startZoom * scale)
2311
+ );
2312
+ pinchRef.current.pendingZoom = nextZoom;
2313
+ if (pinchRef.current.rafId == null) {
2314
+ pinchRef.current.rafId = requestAnimationFrame(flushPinchZoom);
2315
+ }
2316
+ event.preventDefault();
2317
+ };
2318
+ const handleTouchEnd = (event) => {
2319
+ if (event.touches.length >= 2) return;
2320
+ pinchRef.current.active = false;
2321
+ pinchRef.current.startDistance = 0;
2322
+ pinchRef.current.startZoom = zoom;
2323
+ if (pinchRef.current.pendingZoom != null && pinchRef.current.rafId == null) {
2324
+ engine.setZoom(pinchRef.current.pendingZoom);
2325
+ setDocumentState({ zoom: pinchRef.current.pendingZoom });
2326
+ pinchRef.current.pendingZoom = null;
2327
+ }
2328
+ };
1397
2329
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1398
2330
  "div",
1399
2331
  {
1400
2332
  ref: viewerRef,
1401
2333
  "data-papyrus-theme": uiTheme,
2334
+ onTouchStart: handleTouchStart,
2335
+ onTouchMove: handleTouchMove,
2336
+ onTouchEnd: handleTouchEnd,
2337
+ onTouchCancel: handleTouchEnd,
1402
2338
  className: `papyrus-viewer papyrus-theme min-w-0 w-full flex-1 overflow-y-scroll overflow-x-hidden flex flex-col items-center ${paddingY} relative custom-scrollbar scroll-smooth ${isDark ? "bg-[#121212]" : "bg-[#e9ecef]"}`,
1403
2339
  children: [
1404
2340
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex flex-col items-center gap-6 w-full min-w-0", children: pages.map((idx) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
@@ -1430,65 +2366,109 @@ var Viewer = ({ engine }) => {
1430
2366
  },
1431
2367
  idx
1432
2368
  )) }),
1433
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: `papyrus-tool-dock sticky ${toolDockPosition} w-full flex justify-center pointer-events-none z-[70]`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `pointer-events-auto shadow-2xl rounded-2xl p-2 flex items-center border z-[80] ${isDark ? "bg-[#2a2a2a]/90 border-[#3a3a3a] backdrop-blur-xl" : "bg-white/95 border-gray-100 backdrop-blur-md"}`, children: [
1434
- tools.map((tool) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1435
- "button",
1436
- {
1437
- title: tool.name,
1438
- "aria-label": tool.name,
1439
- onClick: () => setDocumentState({ activeTool: tool.id }),
1440
- className: `w-10 h-10 rounded-xl flex items-center justify-center transition-all ${activeTool === tool.id ? "text-white shadow-lg" : "text-gray-400"}`,
1441
- style: activeTool === tool.id ? { backgroundColor: accentColor } : void 0,
1442
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: tool.icon }) })
1443
- },
1444
- tool.id
1445
- )),
1446
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "w-px h-7 mx-2 bg-white/10" }),
1447
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: colorPickerRef, className: "relative", children: [
1448
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1449
- "button",
2369
+ toolDockOpen && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2370
+ "div",
2371
+ {
2372
+ className: `papyrus-tool-dock sticky ${toolDockPosition} w-full flex justify-center pointer-events-none z-[70]`,
2373
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2374
+ "div",
1450
2375
  {
1451
- title: "Cor do marcador",
1452
- "aria-label": "Cor do marcador",
1453
- onClick: () => setColorPickerOpen((prev) => !prev),
1454
- className: "w-9 h-9 rounded-full flex items-center justify-center border transition-all cursor-pointer relative",
1455
- style: { borderColor: annotationColor },
1456
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w-5 h-5 rounded-full", style: { backgroundColor: annotationColor } })
1457
- }
1458
- ),
1459
- colorPickerOpen && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `absolute bottom-full left-1/2 -translate-x-1/2 mb-3 w-48 rounded-xl border p-3 shadow-2xl overflow-hidden ${isDark ? "bg-[#1f1f1f] border-[#333]" : "bg-white border-gray-200"}`, children: [
1460
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "grid grid-cols-4 gap-2 mb-3", children: colorPalette.map((color) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1461
- "button",
1462
- {
1463
- onClick: () => {
1464
- setAnnotationColor(color);
1465
- setColorPickerOpen(false);
1466
- },
1467
- className: "w-7 h-7 rounded-full border transition-all",
1468
- style: { backgroundColor: color, borderColor: color === annotationColor ? "#fff" : "transparent" }
1469
- },
1470
- color
1471
- )) }),
1472
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2 w-full", children: [
1473
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-[10px] uppercase tracking-widest text-gray-400 shrink-0", children: "Hex" }),
1474
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1475
- "input",
1476
- {
1477
- type: "text",
1478
- value: annotationColor.toUpperCase(),
1479
- onChange: (e) => {
1480
- const next = e.target.value.trim();
1481
- if (next.startsWith("#") && (next.length === 4 || next.length === 7)) {
1482
- setAnnotationColor(next);
1483
- }
2376
+ className: `pointer-events-auto shadow-2xl rounded-2xl p-2 flex items-center border z-[80] ${isDark ? "bg-[#2a2a2a]/90 border-[#3a3a3a] backdrop-blur-xl" : "bg-white/95 border-gray-100 backdrop-blur-md"}`,
2377
+ children: [
2378
+ tools.map((tool) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2379
+ "button",
2380
+ {
2381
+ title: tool.name,
2382
+ "aria-label": tool.name,
2383
+ onClick: () => setDocumentState({ activeTool: tool.id }),
2384
+ className: `w-10 h-10 rounded-xl flex items-center justify-center transition-all ${activeTool === tool.id ? "text-white shadow-lg" : "text-gray-400"}`,
2385
+ style: activeTool === tool.id ? { backgroundColor: accentColor } : void 0,
2386
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2387
+ "svg",
2388
+ {
2389
+ className: "w-5 h-5",
2390
+ fill: "none",
2391
+ stroke: "currentColor",
2392
+ viewBox: "0 0 24 24",
2393
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2394
+ "path",
2395
+ {
2396
+ strokeLinecap: "round",
2397
+ strokeLinejoin: "round",
2398
+ strokeWidth: 2,
2399
+ d: tool.icon
2400
+ }
2401
+ )
2402
+ }
2403
+ )
1484
2404
  },
1485
- className: `flex-1 min-w-0 w-full text-xs rounded-md px-2 py-1 border ${isDark ? "bg-[#2a2a2a] border-[#444] text-white" : "bg-gray-100 border-gray-200 text-gray-700"}`
1486
- }
1487
- )
1488
- ] })
1489
- ] })
1490
- ] })
1491
- ] }) })
2405
+ tool.id
2406
+ )),
2407
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "w-px h-7 mx-2 bg-white/10" }),
2408
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: colorPickerRef, className: "relative", children: [
2409
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2410
+ "button",
2411
+ {
2412
+ title: "Cor do marcador",
2413
+ "aria-label": "Cor do marcador",
2414
+ onClick: () => setColorPickerOpen((prev) => !prev),
2415
+ className: "w-9 h-9 rounded-full flex items-center justify-center border transition-all cursor-pointer relative",
2416
+ style: { borderColor: annotationColor },
2417
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2418
+ "span",
2419
+ {
2420
+ className: "w-5 h-5 rounded-full",
2421
+ style: { backgroundColor: annotationColor }
2422
+ }
2423
+ )
2424
+ }
2425
+ ),
2426
+ colorPickerOpen && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2427
+ "div",
2428
+ {
2429
+ className: `absolute bottom-full left-1/2 -translate-x-1/2 mb-3 w-48 rounded-xl border p-3 shadow-2xl overflow-hidden ${isDark ? "bg-[#1f1f1f] border-[#333]" : "bg-white border-gray-200"}`,
2430
+ children: [
2431
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "grid grid-cols-4 gap-2 mb-3", children: colorPalette.map((color) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2432
+ "button",
2433
+ {
2434
+ onClick: () => {
2435
+ setAnnotationColor(color);
2436
+ setColorPickerOpen(false);
2437
+ },
2438
+ className: "w-7 h-7 rounded-full border transition-all",
2439
+ style: {
2440
+ backgroundColor: color,
2441
+ borderColor: color === annotationColor ? "#fff" : "transparent"
2442
+ }
2443
+ },
2444
+ color
2445
+ )) }),
2446
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2 w-full", children: [
2447
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-[10px] uppercase tracking-widest text-gray-400 shrink-0", children: "Hex" }),
2448
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2449
+ "input",
2450
+ {
2451
+ type: "text",
2452
+ value: annotationColor.toUpperCase(),
2453
+ onChange: (e) => {
2454
+ const next = e.target.value.trim();
2455
+ if (next.startsWith("#") && (next.length === 4 || next.length === 7)) {
2456
+ setAnnotationColor(next);
2457
+ }
2458
+ },
2459
+ className: `flex-1 min-w-0 w-full text-xs rounded-md px-2 py-1 border ${isDark ? "bg-[#2a2a2a] border-[#444] text-white" : "bg-gray-100 border-gray-200 text-gray-700"}`
2460
+ }
2461
+ )
2462
+ ] })
2463
+ ]
2464
+ }
2465
+ )
2466
+ ] })
2467
+ ]
2468
+ }
2469
+ )
2470
+ }
2471
+ )
1492
2472
  ]
1493
2473
  }
1494
2474
  );