@june-ai/june-ui 0.2.5 → 0.2.7
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/CHANGELOG.md +7 -0
- package/dist/block-automount.js +2 -0
- package/dist/{chunk-CZE533PM.js → chunk-VFZI3SEL.js} +186 -9
- package/dist/{document-engine-IAY2T6B3.js → document-engine-RKD5SLXR.js} +1 -1
- package/dist/index.cjs +1134 -679
- package/dist/index.d.cts +44 -1
- package/dist/index.d.ts +44 -1
- package/dist/index.js +889 -615
- package/dist/june.css +43 -19
- package/package.json +6 -3
package/dist/index.cjs
CHANGED
|
@@ -145,6 +145,184 @@ var init_document_utils = __esm({
|
|
|
145
145
|
}
|
|
146
146
|
});
|
|
147
147
|
|
|
148
|
+
// src/components/document-editor/document-pagination.ts
|
|
149
|
+
function gapWidget(height) {
|
|
150
|
+
return () => {
|
|
151
|
+
const el = document.createElement("div");
|
|
152
|
+
el.className = "june-doc__page-gap";
|
|
153
|
+
el.contentEditable = "false";
|
|
154
|
+
el.setAttribute("aria-hidden", "true");
|
|
155
|
+
el.style.height = `${height}px`;
|
|
156
|
+
return el;
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function build(doc, breaks) {
|
|
160
|
+
return import_view.DecorationSet.create(
|
|
161
|
+
doc,
|
|
162
|
+
breaks.map(
|
|
163
|
+
(b) => import_view.Decoration.widget(b.pos, gapWidget(b.height), {
|
|
164
|
+
side: -1,
|
|
165
|
+
ignoreSelection: true,
|
|
166
|
+
key: `jd-gap-${b.pos}-${Math.round(b.height)}`
|
|
167
|
+
})
|
|
168
|
+
)
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
function collectUnits(doc) {
|
|
172
|
+
const units = [];
|
|
173
|
+
const walk = (parent, start, inheritedBreak) => {
|
|
174
|
+
parent.forEach((child, offset, index) => {
|
|
175
|
+
const pos = start + offset;
|
|
176
|
+
const breakPos = index === 0 && inheritedBreak !== null ? inheritedBreak : pos;
|
|
177
|
+
if (SPLITTABLE.has(child.type.name) && child.childCount > 0) {
|
|
178
|
+
walk(child, pos + 1, breakPos);
|
|
179
|
+
} else {
|
|
180
|
+
units.push({ pos, breakPos, node: child });
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
};
|
|
184
|
+
walk(doc, 0, null);
|
|
185
|
+
return units;
|
|
186
|
+
}
|
|
187
|
+
function measure(view, cfg) {
|
|
188
|
+
const prose = view.dom;
|
|
189
|
+
const proseRect = prose.getBoundingClientRect();
|
|
190
|
+
const scale = prose.offsetWidth ? proseRect.width / prose.offsetWidth : 1;
|
|
191
|
+
if (!scale || !proseRect.width) return { breaks: [], pages: 1 };
|
|
192
|
+
const gaps = [...prose.querySelectorAll(".june-doc__page-gap")].map((g) => {
|
|
193
|
+
const r = g.getBoundingClientRect();
|
|
194
|
+
return { top: (r.top - proseRect.top) / scale, height: r.height / scale };
|
|
195
|
+
});
|
|
196
|
+
const gapsAbove = (y) => gaps.reduce((sum, g) => g.top <= y + 0.5 ? sum + g.height : sum, 0);
|
|
197
|
+
const contentH = Math.max(80, cfg.pageHeight - cfg.padTop - cfg.padBottom);
|
|
198
|
+
const stride = cfg.pageHeight + cfg.gap;
|
|
199
|
+
const breaks = /* @__PURE__ */ new Map();
|
|
200
|
+
let pageStart = 0;
|
|
201
|
+
let added = 0;
|
|
202
|
+
let force = false;
|
|
203
|
+
for (const unit of collectUnits(view.state.doc)) {
|
|
204
|
+
const el = view.nodeDOM(unit.pos);
|
|
205
|
+
if (!(el instanceof HTMLElement)) continue;
|
|
206
|
+
const r = el.getBoundingClientRect();
|
|
207
|
+
const rawTop = (r.top - proseRect.top) / scale;
|
|
208
|
+
const natural = rawTop - gapsAbove(rawTop);
|
|
209
|
+
const h = r.height / scale;
|
|
210
|
+
let top = natural + added;
|
|
211
|
+
let bottom = top + h;
|
|
212
|
+
const overflows = bottom > pageStart + contentH + 0.5 && top > pageStart + 1;
|
|
213
|
+
if (force || overflows) {
|
|
214
|
+
const target = pageStart + stride;
|
|
215
|
+
if (top < target) {
|
|
216
|
+
const spacer = target - top;
|
|
217
|
+
breaks.set(unit.breakPos, (breaks.get(unit.breakPos) ?? 0) + spacer);
|
|
218
|
+
added += spacer;
|
|
219
|
+
top = target;
|
|
220
|
+
bottom = top + h;
|
|
221
|
+
}
|
|
222
|
+
pageStart = target;
|
|
223
|
+
while (top >= pageStart + stride) pageStart += stride;
|
|
224
|
+
force = false;
|
|
225
|
+
}
|
|
226
|
+
while (bottom > pageStart + contentH + 0.5) pageStart += stride;
|
|
227
|
+
if (unit.node.type.name === "pageBreak") force = true;
|
|
228
|
+
}
|
|
229
|
+
const pages = Math.max(1, Math.round(pageStart / stride) + 1 + (force ? 1 : 0));
|
|
230
|
+
return {
|
|
231
|
+
breaks: [...breaks].map(([pos, height]) => ({ pos, height: Math.round(height * 10) / 10 })).sort((a, b) => a.pos - b.pos),
|
|
232
|
+
pages
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
function setPaginationConfig(editor, cfg) {
|
|
236
|
+
if (editor.isDestroyed) return;
|
|
237
|
+
const prev = configs.get(editor.view);
|
|
238
|
+
configs.set(editor.view, cfg);
|
|
239
|
+
if (!prev || prev.enabled !== cfg.enabled || prev.pageHeight !== cfg.pageHeight || prev.gap !== cfg.gap || prev.padTop !== cfg.padTop || prev.padBottom !== cfg.padBottom) {
|
|
240
|
+
remeasurePagination(editor);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
function remeasurePagination(editor) {
|
|
244
|
+
if (editor.isDestroyed) return;
|
|
245
|
+
const s = paginationKey.getState(editor.state);
|
|
246
|
+
if (!s) return;
|
|
247
|
+
editor.view.dispatch(editor.state.tr.setMeta(paginationKey, { remeasure: true }).setMeta("addToHistory", false));
|
|
248
|
+
}
|
|
249
|
+
function getPageCount(editor) {
|
|
250
|
+
return editor && paginationKey.getState(editor.state)?.pages || 1;
|
|
251
|
+
}
|
|
252
|
+
var import_core, import_state, import_view, paginationKey, configs, SPLITTABLE, same2, DocumentPagination;
|
|
253
|
+
var init_document_pagination = __esm({
|
|
254
|
+
"src/components/document-editor/document-pagination.ts"() {
|
|
255
|
+
"use strict";
|
|
256
|
+
import_core = require("@tiptap/core");
|
|
257
|
+
import_state = require("@tiptap/pm/state");
|
|
258
|
+
import_view = require("@tiptap/pm/view");
|
|
259
|
+
paginationKey = new import_state.PluginKey("juneDocPagination");
|
|
260
|
+
configs = /* @__PURE__ */ new WeakMap();
|
|
261
|
+
SPLITTABLE = /* @__PURE__ */ new Set(["bulletList", "orderedList", "listItem", "blockquote"]);
|
|
262
|
+
same2 = (a, b) => a.length === b.length && a.every((x, i) => x.pos === b[i].pos && Math.abs(x.height - b[i].height) < 1);
|
|
263
|
+
DocumentPagination = import_core.Extension.create({
|
|
264
|
+
name: "juneDocPagination",
|
|
265
|
+
addProseMirrorPlugins() {
|
|
266
|
+
return [
|
|
267
|
+
new import_state.Plugin({
|
|
268
|
+
key: paginationKey,
|
|
269
|
+
state: {
|
|
270
|
+
init: () => ({ breaks: [], pages: 1, decorations: import_view.DecorationSet.empty, epoch: 0 }),
|
|
271
|
+
apply(tr, prev, _old, state) {
|
|
272
|
+
const meta = tr.getMeta(paginationKey);
|
|
273
|
+
if (meta?.remeasure) return { ...prev, epoch: prev.epoch + 1 };
|
|
274
|
+
if (meta?.breaks) {
|
|
275
|
+
return { ...prev, breaks: meta.breaks, pages: meta.pages ?? prev.pages, decorations: build(state.doc, meta.breaks) };
|
|
276
|
+
}
|
|
277
|
+
if (tr.docChanged) {
|
|
278
|
+
const breaks = prev.breaks.map((b) => ({ ...b, pos: tr.mapping.map(b.pos, -1) })).filter((b) => b.pos >= 0 && b.pos <= state.doc.content.size);
|
|
279
|
+
return { ...prev, breaks, decorations: prev.decorations.map(tr.mapping, tr.doc) };
|
|
280
|
+
}
|
|
281
|
+
return prev;
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
props: {
|
|
285
|
+
decorations: (state) => paginationKey.getState(state)?.decorations
|
|
286
|
+
},
|
|
287
|
+
view(view) {
|
|
288
|
+
let frame = null;
|
|
289
|
+
let rounds = 0;
|
|
290
|
+
const schedule = (reset) => {
|
|
291
|
+
if (reset) rounds = 0;
|
|
292
|
+
if (frame !== null || typeof window === "undefined") return;
|
|
293
|
+
const raf = window.requestAnimationFrame ?? ((cb) => window.setTimeout(() => cb(0), 16));
|
|
294
|
+
frame = raf(() => {
|
|
295
|
+
frame = null;
|
|
296
|
+
if (view.isDestroyed) return;
|
|
297
|
+
const cfg = configs.get(view);
|
|
298
|
+
const current = paginationKey.getState(view.state);
|
|
299
|
+
if (!current) return;
|
|
300
|
+
const next = cfg?.enabled ? measure(view, cfg) : { breaks: [], pages: 1 };
|
|
301
|
+
if (same2(next.breaks, current.breaks) && next.pages === current.pages) return;
|
|
302
|
+
if (++rounds > 4) return;
|
|
303
|
+
view.dispatch(view.state.tr.setMeta(paginationKey, next).setMeta("addToHistory", false));
|
|
304
|
+
});
|
|
305
|
+
};
|
|
306
|
+
schedule(true);
|
|
307
|
+
return {
|
|
308
|
+
update(v, prevState) {
|
|
309
|
+
const pg = paginationKey.getState(v.state);
|
|
310
|
+
const prevPg = paginationKey.getState(prevState);
|
|
311
|
+
if (v.state.doc !== prevState.doc || pg?.epoch !== prevPg?.epoch) schedule(true);
|
|
312
|
+
else if (pg !== prevPg) schedule(false);
|
|
313
|
+
},
|
|
314
|
+
destroy() {
|
|
315
|
+
frame = null;
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
})
|
|
320
|
+
];
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
|
|
148
326
|
// src/components/document-editor/document-search.ts
|
|
149
327
|
function findMatches(doc, term, caseSensitive) {
|
|
150
328
|
if (!term) return [];
|
|
@@ -174,13 +352,13 @@ function findMatches(doc, term, caseSensitive) {
|
|
|
174
352
|
});
|
|
175
353
|
return out;
|
|
176
354
|
}
|
|
177
|
-
function
|
|
355
|
+
function build2(doc, term, caseSensitive, current) {
|
|
178
356
|
const matches = findMatches(doc, term, caseSensitive);
|
|
179
357
|
const active = matches.length ? Math.min(Math.max(current, 0), matches.length - 1) : -1;
|
|
180
|
-
const decorations =
|
|
358
|
+
const decorations = import_view2.DecorationSet.create(
|
|
181
359
|
doc,
|
|
182
360
|
matches.map(
|
|
183
|
-
(m, i) =>
|
|
361
|
+
(m, i) => import_view2.Decoration.inline(m.from, m.to, {
|
|
184
362
|
class: i === active ? "june-doc__match june-doc__match--active" : "june-doc__match"
|
|
185
363
|
})
|
|
186
364
|
)
|
|
@@ -226,27 +404,27 @@ function replaceAll(editor, replacement) {
|
|
|
226
404
|
}).run();
|
|
227
405
|
return matches.length;
|
|
228
406
|
}
|
|
229
|
-
var
|
|
407
|
+
var import_core2, import_state2, import_view2, searchKey, DocumentSearch;
|
|
230
408
|
var init_document_search = __esm({
|
|
231
409
|
"src/components/document-editor/document-search.ts"() {
|
|
232
410
|
"use strict";
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
searchKey = new
|
|
237
|
-
DocumentSearch =
|
|
411
|
+
import_core2 = require("@tiptap/core");
|
|
412
|
+
import_state2 = require("@tiptap/pm/state");
|
|
413
|
+
import_view2 = require("@tiptap/pm/view");
|
|
414
|
+
searchKey = new import_state2.PluginKey("juneDocSearch");
|
|
415
|
+
DocumentSearch = import_core2.Extension.create({
|
|
238
416
|
name: "juneDocSearch",
|
|
239
417
|
addProseMirrorPlugins() {
|
|
240
418
|
return [
|
|
241
|
-
new
|
|
419
|
+
new import_state2.Plugin({
|
|
242
420
|
key: searchKey,
|
|
243
421
|
state: {
|
|
244
|
-
init: () => ({ term: "", caseSensitive: false, current: -1, matches: [], decorations:
|
|
422
|
+
init: () => ({ term: "", caseSensitive: false, current: -1, matches: [], decorations: import_view2.DecorationSet.empty }),
|
|
245
423
|
apply(tr, prev, _old, state) {
|
|
246
424
|
const meta = tr.getMeta(searchKey);
|
|
247
425
|
if (!meta && !tr.docChanged) return prev;
|
|
248
426
|
if (!meta && !prev.term) return prev;
|
|
249
|
-
return
|
|
427
|
+
return build2(
|
|
250
428
|
state.doc,
|
|
251
429
|
meta?.term ?? prev.term,
|
|
252
430
|
meta?.caseSensitive ?? prev.caseSensitive,
|
|
@@ -288,14 +466,16 @@ function createDocumentExtensions() {
|
|
|
288
466
|
}),
|
|
289
467
|
PageBreak,
|
|
290
468
|
DocumentSearch,
|
|
469
|
+
DocumentPagination,
|
|
470
|
+
// inactive until the live editor sets a page geometry
|
|
291
471
|
import_markdown.Markdown
|
|
292
472
|
];
|
|
293
473
|
}
|
|
294
|
-
var
|
|
474
|
+
var import_core3, import_extension_highlight, import_extension_image, import_extension_subscript, import_extension_superscript, import_extension_table, import_extension_text_align, import_extension_text_style, import_markdown, import_starter_kit, PageBreak;
|
|
295
475
|
var init_document_extensions = __esm({
|
|
296
476
|
"src/components/document-editor/document-extensions.ts"() {
|
|
297
477
|
"use strict";
|
|
298
|
-
|
|
478
|
+
import_core3 = require("@tiptap/core");
|
|
299
479
|
import_extension_highlight = __toESM(require("@tiptap/extension-highlight"), 1);
|
|
300
480
|
import_extension_image = __toESM(require("@tiptap/extension-image"), 1);
|
|
301
481
|
import_extension_subscript = __toESM(require("@tiptap/extension-subscript"), 1);
|
|
@@ -305,8 +485,9 @@ var init_document_extensions = __esm({
|
|
|
305
485
|
import_extension_text_style = require("@tiptap/extension-text-style");
|
|
306
486
|
import_markdown = require("@tiptap/markdown");
|
|
307
487
|
import_starter_kit = __toESM(require("@tiptap/starter-kit"), 1);
|
|
488
|
+
init_document_pagination();
|
|
308
489
|
init_document_search();
|
|
309
|
-
PageBreak =
|
|
490
|
+
PageBreak = import_core3.Node.create({
|
|
310
491
|
name: "pageBreak",
|
|
311
492
|
group: "block",
|
|
312
493
|
atom: true,
|
|
@@ -317,7 +498,7 @@ var init_document_extensions = __esm({
|
|
|
317
498
|
renderHTML({ HTMLAttributes }) {
|
|
318
499
|
return [
|
|
319
500
|
"div",
|
|
320
|
-
(0,
|
|
501
|
+
(0, import_core3.mergeAttributes)(HTMLAttributes, {
|
|
321
502
|
"data-page-break": "true",
|
|
322
503
|
class: "june-doc__page-break",
|
|
323
504
|
style: "break-after: page; page-break-after: always;"
|
|
@@ -348,7 +529,7 @@ __export(document_engine_exports, {
|
|
|
348
529
|
});
|
|
349
530
|
function scratchEditor() {
|
|
350
531
|
if (!scratch || scratch.isDestroyed) {
|
|
351
|
-
scratch = new
|
|
532
|
+
scratch = new import_core4.Editor({ extensions: createDocumentExtensions(), content: "" });
|
|
352
533
|
}
|
|
353
534
|
return scratch;
|
|
354
535
|
}
|
|
@@ -374,11 +555,11 @@ function load(doc) {
|
|
|
374
555
|
editor.commands.setContent(doc, { emitUpdate: false });
|
|
375
556
|
return editor;
|
|
376
557
|
}
|
|
377
|
-
var
|
|
558
|
+
var import_core4, scratch, docToHtml, docToMarkdown, docToText;
|
|
378
559
|
var init_document_engine = __esm({
|
|
379
560
|
"src/components/document-editor/document-engine.ts"() {
|
|
380
561
|
"use strict";
|
|
381
|
-
|
|
562
|
+
import_core4 = require("@tiptap/core");
|
|
382
563
|
init_errors();
|
|
383
564
|
init_document_extensions();
|
|
384
565
|
init_document_utils();
|
|
@@ -418,17 +599,21 @@ __export(index_exports, {
|
|
|
418
599
|
getDefaultDocumentStore: () => getDefaultDocumentStore,
|
|
419
600
|
getDocumentEditorInstructions: () => getDocumentEditorInstructions,
|
|
420
601
|
getDocumentEditorRules: () => getDocumentEditorRules,
|
|
602
|
+
isDocumentEcho: () => isDocumentEcho,
|
|
421
603
|
isJuneError: () => isJuneError,
|
|
422
604
|
jsonFieldExtractor: () => jsonFieldExtractor,
|
|
423
605
|
juneLibrary: () => juneLibrary,
|
|
424
606
|
lightTheme: () => lightTheme,
|
|
425
607
|
listDocumentExporters: () => listDocumentExporters,
|
|
426
608
|
mergeDocuments: () => mergeDocuments,
|
|
609
|
+
readDocumentFromProgram: () => readDocumentFromProgram,
|
|
427
610
|
registerDocumentExporter: () => registerDocumentExporter,
|
|
611
|
+
rememberDocumentEcho: () => rememberDocumentEcho,
|
|
428
612
|
runAction: () => runAction,
|
|
429
613
|
serializeDocumentsForAgent: () => serializeDocumentsForAgent,
|
|
430
614
|
sseToText: () => sseToText,
|
|
431
615
|
toJuneError: () => toJuneError,
|
|
616
|
+
updateDocumentInProgram: () => updateDocumentInProgram,
|
|
432
617
|
useDocumentOptions: () => useDocumentOptions,
|
|
433
618
|
useJuneRuntime: () => useJuneRuntime,
|
|
434
619
|
useJuneStream: () => useJuneStream,
|
|
@@ -438,6 +623,53 @@ __export(index_exports, {
|
|
|
438
623
|
});
|
|
439
624
|
module.exports = __toCommonJS(index_exports);
|
|
440
625
|
|
|
626
|
+
// src/openui/disable-devtools.tsx
|
|
627
|
+
var import_devtools = require("@openuidev/devtools");
|
|
628
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
629
|
+
var AUTO_MOUNT_FLAG = /* @__PURE__ */ Symbol.for("openui.devtools.autoMount");
|
|
630
|
+
var BLOCKED_BY_JUNE = /* @__PURE__ */ Symbol.for("openui.devtools.blockedByJune");
|
|
631
|
+
var flags = globalThis;
|
|
632
|
+
var scheduledByOpenUI = flags[AUTO_MOUNT_FLAG] === true && flags[BLOCKED_BY_JUNE] !== true;
|
|
633
|
+
flags[AUTO_MOUNT_FLAG] = true;
|
|
634
|
+
flags[BLOCKED_BY_JUNE] = true;
|
|
635
|
+
var DEVTOOLS_BUNDLE = "https://cdn.jsdelivr.net/npm/@openuidev/devtools@0/dist/devtools.browser.js";
|
|
636
|
+
var ALIAS_CACHE_MS = 5 * 60 * 1e3;
|
|
637
|
+
function claimDisabledDevtools() {
|
|
638
|
+
if (typeof document === "undefined") return () => {
|
|
639
|
+
};
|
|
640
|
+
const url = `${DEVTOOLS_BUNDLE}?t=${Math.floor(Date.now() / ALIAS_CACHE_MS)}`;
|
|
641
|
+
let cancelled = false;
|
|
642
|
+
let unmount = () => {
|
|
643
|
+
cancelled = true;
|
|
644
|
+
};
|
|
645
|
+
void Promise.all([
|
|
646
|
+
import(
|
|
647
|
+
/* @vite-ignore */
|
|
648
|
+
url
|
|
649
|
+
),
|
|
650
|
+
import("react"),
|
|
651
|
+
import("react-dom"),
|
|
652
|
+
import("react-dom/client")
|
|
653
|
+
]).then(([devtools, react, reactDom, reactDomClient]) => {
|
|
654
|
+
if (cancelled) return;
|
|
655
|
+
unmount = devtools.mountOpenUIDevtools({
|
|
656
|
+
React: react,
|
|
657
|
+
ReactDOM: reactDom,
|
|
658
|
+
ReactDOMClient: reactDomClient,
|
|
659
|
+
loadReactLang: () => import("@openuidev/react-lang"),
|
|
660
|
+
props: { enabled: false }
|
|
661
|
+
});
|
|
662
|
+
}).catch(() => {
|
|
663
|
+
});
|
|
664
|
+
return () => unmount();
|
|
665
|
+
}
|
|
666
|
+
if (scheduledByOpenUI && process.env.NODE_ENV === "development" && process.env.VITEST !== "true" && typeof document !== "undefined") {
|
|
667
|
+
claimDisabledDevtools();
|
|
668
|
+
}
|
|
669
|
+
function OpenUIDevtoolsGate() {
|
|
670
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_devtools.OpenUIDevtools, { enabled: false });
|
|
671
|
+
}
|
|
672
|
+
|
|
441
673
|
// src/renderer/renderer.tsx
|
|
442
674
|
var import_react_lang = require("@openuidev/react-lang");
|
|
443
675
|
var import_react5 = require("react");
|
|
@@ -516,6 +748,318 @@ function useDocumentValue(store, id, selector) {
|
|
|
516
748
|
return (0, import_react.useSyncExternalStore)(store.subscribe, read, read);
|
|
517
749
|
}
|
|
518
750
|
|
|
751
|
+
// src/components/document-editor/document-merge.ts
|
|
752
|
+
init_document_utils();
|
|
753
|
+
var MAX_CELLS = 4e6;
|
|
754
|
+
function matchIndices(a, b) {
|
|
755
|
+
const n = a.length;
|
|
756
|
+
const m = b.length;
|
|
757
|
+
if (n * m > MAX_CELLS) return null;
|
|
758
|
+
const dp = Array.from({ length: n + 1 }, () => new Uint32Array(m + 1));
|
|
759
|
+
for (let i2 = n - 1; i2 >= 0; i2--) {
|
|
760
|
+
for (let j2 = m - 1; j2 >= 0; j2--) {
|
|
761
|
+
dp[i2][j2] = a[i2] === b[j2] ? dp[i2 + 1][j2 + 1] + 1 : Math.max(dp[i2 + 1][j2], dp[i2][j2 + 1]);
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
const matches = /* @__PURE__ */ new Map();
|
|
765
|
+
let i = 0;
|
|
766
|
+
let j = 0;
|
|
767
|
+
while (i < n && j < m) {
|
|
768
|
+
if (a[i] === b[j]) {
|
|
769
|
+
matches.set(i, j);
|
|
770
|
+
i++;
|
|
771
|
+
j++;
|
|
772
|
+
} else if (dp[i + 1][j] >= dp[i][j + 1]) i++;
|
|
773
|
+
else j++;
|
|
774
|
+
}
|
|
775
|
+
return matches;
|
|
776
|
+
}
|
|
777
|
+
var same = (x, y) => x.length === y.length && x.every((v, i) => v === y[i]);
|
|
778
|
+
function mergeBlocks(base, local, incoming) {
|
|
779
|
+
if (same(local, base)) return { blocks: incoming, conflicts: 0 };
|
|
780
|
+
if (same(incoming, base) || same(local, incoming)) return { blocks: local, conflicts: 0 };
|
|
781
|
+
const ml = matchIndices(base, local);
|
|
782
|
+
const mn = matchIndices(base, incoming);
|
|
783
|
+
if (!ml || !mn) return { blocks: null, conflicts: 1 };
|
|
784
|
+
const anchors = [...ml.keys()].filter((i) => mn.has(i)).sort((x, y) => x - y);
|
|
785
|
+
const out = [];
|
|
786
|
+
let conflicts = 0;
|
|
787
|
+
let pb = -1;
|
|
788
|
+
let pl = -1;
|
|
789
|
+
let pn = -1;
|
|
790
|
+
const region = (bEnd, lEnd, nEnd) => {
|
|
791
|
+
const B = base.slice(pb + 1, bEnd);
|
|
792
|
+
const L = local.slice(pl + 1, lEnd);
|
|
793
|
+
const N = incoming.slice(pn + 1, nEnd);
|
|
794
|
+
if (B.length === L.length && L.length === N.length) {
|
|
795
|
+
for (let k = 0; k < B.length; k++) {
|
|
796
|
+
if (L[k] === B[k]) out.push(N[k]);
|
|
797
|
+
else if (N[k] === B[k] || N[k] === L[k]) out.push(L[k]);
|
|
798
|
+
else {
|
|
799
|
+
conflicts++;
|
|
800
|
+
out.push(L[k]);
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
805
|
+
if (same(L, B)) out.push(...N);
|
|
806
|
+
else if (same(N, B) || same(L, N)) out.push(...L);
|
|
807
|
+
else {
|
|
808
|
+
conflicts++;
|
|
809
|
+
out.push(...L);
|
|
810
|
+
}
|
|
811
|
+
};
|
|
812
|
+
for (const a of anchors) {
|
|
813
|
+
const la = ml.get(a);
|
|
814
|
+
const na = mn.get(a);
|
|
815
|
+
region(a, la, na);
|
|
816
|
+
out.push(local[la]);
|
|
817
|
+
pb = a;
|
|
818
|
+
pl = la;
|
|
819
|
+
pn = na;
|
|
820
|
+
}
|
|
821
|
+
region(base.length, local.length, incoming.length);
|
|
822
|
+
return { blocks: out, conflicts };
|
|
823
|
+
}
|
|
824
|
+
function mergeDocuments(base, local, incoming) {
|
|
825
|
+
const toBlocks = (d) => (d.content ?? []).map((node) => JSON.stringify(node));
|
|
826
|
+
const { blocks: blocks2, conflicts } = mergeBlocks(toBlocks(base), toBlocks(local), toBlocks(incoming));
|
|
827
|
+
if (!blocks2) return { doc: local, conflicts: Math.max(1, conflicts) };
|
|
828
|
+
if (blocks2.length === 0) return { doc: emptyDoc(), conflicts };
|
|
829
|
+
return { doc: { type: "doc", content: blocks2.map((b) => JSON.parse(b)) }, conflicts };
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
// src/components/document-editor/document-store.ts
|
|
833
|
+
init_document_utils();
|
|
834
|
+
var incomingKey = (doc) => JSON.stringify([doc.title, docKey(doc.json)]);
|
|
835
|
+
function createDocumentStore() {
|
|
836
|
+
const records = /* @__PURE__ */ new Map();
|
|
837
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
838
|
+
const emit = () => listeners.forEach((listener) => listener());
|
|
839
|
+
const put = (record) => {
|
|
840
|
+
records.set(record.id, record);
|
|
841
|
+
emit();
|
|
842
|
+
};
|
|
843
|
+
const fresh2 = (doc) => ({
|
|
844
|
+
id: doc.id,
|
|
845
|
+
title: doc.title,
|
|
846
|
+
documentType: doc.documentType,
|
|
847
|
+
status: doc.status,
|
|
848
|
+
json: doc.json,
|
|
849
|
+
baseJson: doc.json,
|
|
850
|
+
baseTitle: doc.title,
|
|
851
|
+
lastIncomingKey: incomingKey(doc),
|
|
852
|
+
revision: 0,
|
|
853
|
+
origin: "external",
|
|
854
|
+
pending: null,
|
|
855
|
+
updatedAt: Date.now()
|
|
856
|
+
});
|
|
857
|
+
return {
|
|
858
|
+
get: (id) => records.get(id),
|
|
859
|
+
list: () => [...records.values()],
|
|
860
|
+
subscribe: (listener) => {
|
|
861
|
+
listeners.add(listener);
|
|
862
|
+
return () => {
|
|
863
|
+
listeners.delete(listener);
|
|
864
|
+
};
|
|
865
|
+
},
|
|
866
|
+
receive(incoming) {
|
|
867
|
+
const current = records.get(incoming.id);
|
|
868
|
+
if (!current) {
|
|
869
|
+
put(fresh2(incoming));
|
|
870
|
+
return "created";
|
|
871
|
+
}
|
|
872
|
+
const key = incomingKey(incoming);
|
|
873
|
+
if (current.lastIncomingKey === key) return "unchanged";
|
|
874
|
+
const userEditedBody = docKey(current.json) !== docKey(current.baseJson);
|
|
875
|
+
const userEditedTitle = current.title !== current.baseTitle;
|
|
876
|
+
const title = userEditedTitle ? current.title : incoming.title;
|
|
877
|
+
const meta = {
|
|
878
|
+
documentType: incoming.documentType ?? current.documentType,
|
|
879
|
+
status: incoming.status ?? current.status
|
|
880
|
+
};
|
|
881
|
+
if (!userEditedBody) {
|
|
882
|
+
put({
|
|
883
|
+
...current,
|
|
884
|
+
...meta,
|
|
885
|
+
title,
|
|
886
|
+
baseTitle: incoming.title,
|
|
887
|
+
json: incoming.json,
|
|
888
|
+
baseJson: incoming.json,
|
|
889
|
+
lastIncomingKey: key,
|
|
890
|
+
revision: current.revision + 1,
|
|
891
|
+
origin: "external",
|
|
892
|
+
pending: null,
|
|
893
|
+
updatedAt: Date.now()
|
|
894
|
+
});
|
|
895
|
+
return "applied";
|
|
896
|
+
}
|
|
897
|
+
const { doc, conflicts } = mergeDocuments(current.baseJson, current.json, incoming.json);
|
|
898
|
+
if (conflicts === 0) {
|
|
899
|
+
put({
|
|
900
|
+
...current,
|
|
901
|
+
...meta,
|
|
902
|
+
title,
|
|
903
|
+
baseTitle: incoming.title,
|
|
904
|
+
json: doc,
|
|
905
|
+
baseJson: incoming.json,
|
|
906
|
+
lastIncomingKey: key,
|
|
907
|
+
revision: current.revision + 1,
|
|
908
|
+
origin: "external",
|
|
909
|
+
pending: null,
|
|
910
|
+
updatedAt: Date.now()
|
|
911
|
+
});
|
|
912
|
+
return "merged";
|
|
913
|
+
}
|
|
914
|
+
put({
|
|
915
|
+
...current,
|
|
916
|
+
...meta,
|
|
917
|
+
lastIncomingKey: key,
|
|
918
|
+
pending: { json: incoming.json, title: incoming.title, merged: doc, conflicts }
|
|
919
|
+
});
|
|
920
|
+
return "conflict";
|
|
921
|
+
},
|
|
922
|
+
hydrate(doc) {
|
|
923
|
+
put(fresh2(doc));
|
|
924
|
+
},
|
|
925
|
+
edit(id, json, origin) {
|
|
926
|
+
const current = records.get(id);
|
|
927
|
+
if (!current || docKey(current.json) === docKey(json)) return;
|
|
928
|
+
put({ ...current, json, origin, revision: current.revision + 1, updatedAt: Date.now() });
|
|
929
|
+
},
|
|
930
|
+
setTitle(id, title) {
|
|
931
|
+
const current = records.get(id);
|
|
932
|
+
if (!current || current.title === title) return;
|
|
933
|
+
put({ ...current, title, updatedAt: Date.now() });
|
|
934
|
+
},
|
|
935
|
+
resolve(id, choice) {
|
|
936
|
+
const current = records.get(id);
|
|
937
|
+
const pending = current?.pending;
|
|
938
|
+
if (!current || !pending) return;
|
|
939
|
+
if (choice === "keep") {
|
|
940
|
+
put({ ...current, baseJson: pending.json, baseTitle: pending.title, pending: null });
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
943
|
+
const json = choice === "merge" ? pending.merged : pending.json;
|
|
944
|
+
const title = choice === "merge" ? current.title : pending.title;
|
|
945
|
+
put({
|
|
946
|
+
...current,
|
|
947
|
+
title,
|
|
948
|
+
json,
|
|
949
|
+
baseJson: pending.json,
|
|
950
|
+
baseTitle: pending.title,
|
|
951
|
+
revision: current.revision + 1,
|
|
952
|
+
origin: "external",
|
|
953
|
+
pending: null,
|
|
954
|
+
updatedAt: Date.now()
|
|
955
|
+
});
|
|
956
|
+
},
|
|
957
|
+
remove(id) {
|
|
958
|
+
if (records.delete(id)) emit();
|
|
959
|
+
}
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
var echoes = /* @__PURE__ */ new WeakMap();
|
|
963
|
+
var ECHO_MEMORY = 8;
|
|
964
|
+
function rememberDocumentEcho(store, id, content) {
|
|
965
|
+
let byId = echoes.get(store);
|
|
966
|
+
if (!byId) echoes.set(store, byId = /* @__PURE__ */ new Map());
|
|
967
|
+
const list2 = byId.get(id) ?? [];
|
|
968
|
+
list2.push(content);
|
|
969
|
+
if (list2.length > ECHO_MEMORY) list2.shift();
|
|
970
|
+
byId.set(id, list2);
|
|
971
|
+
}
|
|
972
|
+
function isDocumentEcho(store, id, content) {
|
|
973
|
+
return !!content && !!echoes.get(store)?.get(id)?.includes(content);
|
|
974
|
+
}
|
|
975
|
+
var defaultStore = null;
|
|
976
|
+
function getDefaultDocumentStore() {
|
|
977
|
+
if (!defaultStore) defaultStore = createDocumentStore();
|
|
978
|
+
return defaultStore;
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
// src/utils/update-document-program.ts
|
|
982
|
+
function readString(src, i) {
|
|
983
|
+
if (src[i] !== '"') return null;
|
|
984
|
+
let j = i + 1;
|
|
985
|
+
let value = "";
|
|
986
|
+
while (j < src.length) {
|
|
987
|
+
const ch = src[j];
|
|
988
|
+
if (ch === '"') return { start: i, end: j + 1, value };
|
|
989
|
+
if (ch === "\\") {
|
|
990
|
+
const next = src[j + 1];
|
|
991
|
+
if (next === void 0) return null;
|
|
992
|
+
if (next === "u" && /^[0-9a-fA-F]{4}$/.test(src.slice(j + 2, j + 6))) {
|
|
993
|
+
value += String.fromCharCode(parseInt(src.slice(j + 2, j + 6), 16));
|
|
994
|
+
j += 6;
|
|
995
|
+
continue;
|
|
996
|
+
}
|
|
997
|
+
value += next === "n" ? "\n" : next === "t" ? " " : next === "r" ? "\r" : next === "b" ? "\b" : next === "f" ? "\f" : next;
|
|
998
|
+
j += 2;
|
|
999
|
+
continue;
|
|
1000
|
+
}
|
|
1001
|
+
value += ch;
|
|
1002
|
+
j++;
|
|
1003
|
+
}
|
|
1004
|
+
return null;
|
|
1005
|
+
}
|
|
1006
|
+
var skipSpace = (src, i) => {
|
|
1007
|
+
while (i < src.length && /\s/.test(src[i])) i++;
|
|
1008
|
+
return i;
|
|
1009
|
+
};
|
|
1010
|
+
var toLangString = (value) => JSON.stringify(value);
|
|
1011
|
+
function updateDocumentInProgram(program, documentId, update, componentName = "DocumentEditor") {
|
|
1012
|
+
const re = new RegExp(`\\b${componentName}\\s*\\(`, "g");
|
|
1013
|
+
let match;
|
|
1014
|
+
while (match = re.exec(program)) {
|
|
1015
|
+
const args = [];
|
|
1016
|
+
let i = match.index + match[0].length;
|
|
1017
|
+
for (let n = 0; n < 3; n++) {
|
|
1018
|
+
i = skipSpace(program, i);
|
|
1019
|
+
const tok = readString(program, i);
|
|
1020
|
+
if (!tok) break;
|
|
1021
|
+
args.push(tok);
|
|
1022
|
+
i = skipSpace(program, tok.end);
|
|
1023
|
+
if (program[i] === ",") i++;
|
|
1024
|
+
else break;
|
|
1025
|
+
}
|
|
1026
|
+
if (args[0]?.value !== documentId) continue;
|
|
1027
|
+
const edits = [];
|
|
1028
|
+
if (update.title !== void 0 && args[1] && args[1].value !== update.title) {
|
|
1029
|
+
edits.push({ start: args[1].start, end: args[1].end, text: toLangString(update.title) });
|
|
1030
|
+
}
|
|
1031
|
+
if (update.content !== void 0 && args[2] && args[2].value !== update.content) {
|
|
1032
|
+
edits.push({ start: args[2].start, end: args[2].end, text: toLangString(update.content) });
|
|
1033
|
+
}
|
|
1034
|
+
if (!args[2] && update.content !== void 0) return null;
|
|
1035
|
+
let out = program;
|
|
1036
|
+
for (const e of edits.sort((a, b) => b.start - a.start)) {
|
|
1037
|
+
out = out.slice(0, e.start) + e.text + out.slice(e.end);
|
|
1038
|
+
}
|
|
1039
|
+
return out;
|
|
1040
|
+
}
|
|
1041
|
+
return null;
|
|
1042
|
+
}
|
|
1043
|
+
function readDocumentFromProgram(program, documentId, componentName = "DocumentEditor") {
|
|
1044
|
+
const re = new RegExp(`\\b${componentName}\\s*\\(`, "g");
|
|
1045
|
+
let match;
|
|
1046
|
+
while (match = re.exec(program)) {
|
|
1047
|
+
const args = [];
|
|
1048
|
+
let i = match.index + match[0].length;
|
|
1049
|
+
for (let n = 0; n < 3; n++) {
|
|
1050
|
+
i = skipSpace(program, i);
|
|
1051
|
+
const tok = readString(program, i);
|
|
1052
|
+
if (!tok) break;
|
|
1053
|
+
args.push(tok);
|
|
1054
|
+
i = skipSpace(program, tok.end);
|
|
1055
|
+
if (program[i] === ",") i++;
|
|
1056
|
+
else break;
|
|
1057
|
+
}
|
|
1058
|
+
if (args[0]?.value === documentId && args[1] && args[2]) return { title: args[1].value, content: args[2].value };
|
|
1059
|
+
}
|
|
1060
|
+
return null;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
519
1063
|
// src/core/context.ts
|
|
520
1064
|
var import_react2 = require("react");
|
|
521
1065
|
var JuneContext = (0, import_react2.createContext)({
|
|
@@ -555,7 +1099,7 @@ var lightTheme = {
|
|
|
555
1099
|
};
|
|
556
1100
|
|
|
557
1101
|
// src/themes/theme-provider.tsx
|
|
558
|
-
var
|
|
1102
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
559
1103
|
var QUERY = "(prefers-color-scheme: dark)";
|
|
560
1104
|
function subscribe(onChange) {
|
|
561
1105
|
if (typeof window === "undefined" || !window.matchMedia) return () => {
|
|
@@ -598,7 +1142,7 @@ function JuneThemeProvider({
|
|
|
598
1142
|
() => ({ mode: mode ?? "system", theme: resolved }),
|
|
599
1143
|
[mode, resolved]
|
|
600
1144
|
);
|
|
601
|
-
return /* @__PURE__ */ (0,
|
|
1145
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(JuneContext.Provider, { value: context, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
602
1146
|
"div",
|
|
603
1147
|
{
|
|
604
1148
|
className: className ? `june-ui-root ${className}` : "june-ui-root",
|
|
@@ -1020,7 +1564,7 @@ function splitResponse(source, options = {}) {
|
|
|
1020
1564
|
|
|
1021
1565
|
// src/renderer/error-boundary.tsx
|
|
1022
1566
|
var import_react4 = require("react");
|
|
1023
|
-
var
|
|
1567
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1024
1568
|
function keysChanged(a = [], b = []) {
|
|
1025
1569
|
return a.length !== b.length || a.some((v, i) => !Object.is(v, b[i]));
|
|
1026
1570
|
}
|
|
@@ -1049,12 +1593,12 @@ var JuneErrorBoundary = class extends import_react4.Component {
|
|
|
1049
1593
|
const { fallback } = this.props;
|
|
1050
1594
|
if (typeof fallback === "function") return fallback({ error, reset: this.reset });
|
|
1051
1595
|
if (fallback !== void 0) return fallback;
|
|
1052
|
-
return /* @__PURE__ */ (0,
|
|
1596
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { role: "alert", "data-june-error": "", children: "Something went wrong while rendering this UI." });
|
|
1053
1597
|
}
|
|
1054
1598
|
};
|
|
1055
1599
|
|
|
1056
1600
|
// src/renderer/renderer.tsx
|
|
1057
|
-
var
|
|
1601
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1058
1602
|
function JuneRenderer(props) {
|
|
1059
1603
|
const {
|
|
1060
1604
|
library,
|
|
@@ -1074,14 +1618,43 @@ function JuneRenderer(props) {
|
|
|
1074
1618
|
onError,
|
|
1075
1619
|
onJuneError,
|
|
1076
1620
|
documents,
|
|
1621
|
+
onResponseChange,
|
|
1622
|
+
responseChangeDelay = 300,
|
|
1077
1623
|
loadingFallback = null,
|
|
1078
1624
|
emptyFallback = null,
|
|
1079
1625
|
errorFallback,
|
|
1080
1626
|
resetKeys,
|
|
1081
1627
|
...rendererProps
|
|
1082
1628
|
} = props;
|
|
1083
|
-
const latest = (0, import_react5.useRef)({ actions, confirmAction, parseActionEvent, onAction, onError, onJuneError });
|
|
1084
|
-
latest.current = { actions, confirmAction, parseActionEvent, onAction, onError, onJuneError };
|
|
1629
|
+
const latest = (0, import_react5.useRef)({ actions, confirmAction, parseActionEvent, onAction, onError, onJuneError, onResponseChange, responseChangeDelay, response });
|
|
1630
|
+
latest.current = { actions, confirmAction, parseActionEvent, onAction, onError, onJuneError, onResponseChange, responseChangeDelay, response };
|
|
1631
|
+
const syncTimers = (0, import_react5.useRef)(/* @__PURE__ */ new Map());
|
|
1632
|
+
(0, import_react5.useEffect)(() => {
|
|
1633
|
+
const timers = syncTimers.current;
|
|
1634
|
+
return () => {
|
|
1635
|
+
timers.forEach(clearTimeout);
|
|
1636
|
+
timers.clear();
|
|
1637
|
+
};
|
|
1638
|
+
}, []);
|
|
1639
|
+
const syncProgram = (0, import_react5.useCallback)(async (change, store) => {
|
|
1640
|
+
const l = latest.current;
|
|
1641
|
+
if (!l.onResponseChange || typeof l.response !== "string") return;
|
|
1642
|
+
const record = store.get(change.documentId);
|
|
1643
|
+
const title = record?.title ?? change.title;
|
|
1644
|
+
const json = record?.json ?? change.json;
|
|
1645
|
+
try {
|
|
1646
|
+
const { docToMarkdown: docToMarkdown2 } = await Promise.resolve().then(() => (init_document_engine(), document_engine_exports));
|
|
1647
|
+
const markdown = docToMarkdown2(json);
|
|
1648
|
+
const program = latest.current.response;
|
|
1649
|
+
if (typeof program !== "string") return;
|
|
1650
|
+
const next = updateDocumentInProgram(program, change.documentId, { title, content: markdown });
|
|
1651
|
+
if (next === null || next === program) return;
|
|
1652
|
+
rememberDocumentEcho(store, change.documentId, markdown);
|
|
1653
|
+
latest.current.onResponseChange?.(next, { documentId: change.documentId, title, markdown, source: change.source });
|
|
1654
|
+
} catch (error) {
|
|
1655
|
+
latest.current.onJuneError?.(toJuneError(error, "DOCUMENT_ERROR", "Updating the program failed"));
|
|
1656
|
+
}
|
|
1657
|
+
}, []);
|
|
1085
1658
|
const handleAction = (0, import_react5.useCallback)((event) => {
|
|
1086
1659
|
const l = latest.current;
|
|
1087
1660
|
l.onAction?.(event);
|
|
@@ -1120,12 +1693,27 @@ function JuneRenderer(props) {
|
|
|
1120
1693
|
const documentOptions = (0, import_react5.useMemo)(
|
|
1121
1694
|
() => ({
|
|
1122
1695
|
...documents,
|
|
1696
|
+
onDocumentChange: (change) => {
|
|
1697
|
+
documents?.onDocumentChange?.(change);
|
|
1698
|
+
if (!latest.current.onResponseChange || change.source === "ai") return;
|
|
1699
|
+
const store = documents?.store ?? getDefaultDocumentStore();
|
|
1700
|
+
const timers = syncTimers.current;
|
|
1701
|
+
const prev = timers.get(change.documentId);
|
|
1702
|
+
if (prev) clearTimeout(prev);
|
|
1703
|
+
timers.set(
|
|
1704
|
+
change.documentId,
|
|
1705
|
+
setTimeout(() => {
|
|
1706
|
+
timers.delete(change.documentId);
|
|
1707
|
+
void syncProgram(change, store);
|
|
1708
|
+
}, Math.max(0, latest.current.responseChangeDelay))
|
|
1709
|
+
);
|
|
1710
|
+
},
|
|
1123
1711
|
onError: (error) => {
|
|
1124
1712
|
documents?.onError?.(error);
|
|
1125
1713
|
latest.current.onJuneError?.(error);
|
|
1126
1714
|
}
|
|
1127
1715
|
}),
|
|
1128
|
-
[documents]
|
|
1716
|
+
[documents, syncProgram]
|
|
1129
1717
|
);
|
|
1130
1718
|
const parts = (0, import_react5.useMemo)(
|
|
1131
1719
|
() => mixedContent && response ? splitResponse(response, { streaming: isStreaming }) : null,
|
|
@@ -1140,31 +1728,34 @@ function JuneRenderer(props) {
|
|
|
1140
1728
|
const before = parts?.before ?? [];
|
|
1141
1729
|
const after = parts?.after ?? [];
|
|
1142
1730
|
const hasText = before.length + after.length > 0;
|
|
1143
|
-
const text = (value, index, key) => /* @__PURE__ */ (0,
|
|
1144
|
-
return /* @__PURE__ */ (0,
|
|
1145
|
-
|
|
1146
|
-
{
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1731
|
+
const text = (value, index, key) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react5.Fragment, { children: renderText ? renderText(value, index) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "june-text", children: value }) }, key);
|
|
1732
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(JuneThemeProvider, { mode: theme, vars: themeVars, className, style, children: [
|
|
1733
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(OpenUIDevtoolsGate, {}),
|
|
1734
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(JuneRuntimeContext.Provider, { value: runtime, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(JuneDocumentContext.Provider, { value: documentOptions, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1735
|
+
JuneErrorBoundary,
|
|
1736
|
+
{
|
|
1737
|
+
fallback: errorFallback,
|
|
1738
|
+
onError: handleBoundaryError,
|
|
1739
|
+
resetKeys: resetKeys ?? [response],
|
|
1740
|
+
children: [
|
|
1741
|
+
before.map((t, i) => text(t, i, `b${i}`)),
|
|
1742
|
+
hasUi && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1743
|
+
import_react_lang.Renderer,
|
|
1744
|
+
{
|
|
1745
|
+
...rendererProps,
|
|
1746
|
+
library,
|
|
1747
|
+
response: uiText,
|
|
1748
|
+
isStreaming,
|
|
1749
|
+
onAction: handleAction,
|
|
1750
|
+
onError: handleParserErrors
|
|
1751
|
+
}
|
|
1752
|
+
),
|
|
1753
|
+
after.map((t, i) => text(t, before.length + i, `a${i}`)),
|
|
1754
|
+
!hasUi && !hasText && (isStreaming ? loadingFallback : emptyFallback)
|
|
1755
|
+
]
|
|
1756
|
+
}
|
|
1757
|
+
) }) })
|
|
1758
|
+
] });
|
|
1168
1759
|
}
|
|
1169
1760
|
|
|
1170
1761
|
// src/components/library.ts
|
|
@@ -1505,18 +2096,18 @@ var import_react_lang3 = require("@openuidev/react-lang");
|
|
|
1505
2096
|
var import_v4 = require("zod/v4");
|
|
1506
2097
|
|
|
1507
2098
|
// src/components/document-editor/document-draft.tsx
|
|
1508
|
-
var
|
|
2099
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1509
2100
|
function DocumentDraft({ title, words, state }) {
|
|
1510
2101
|
if (state === "empty") {
|
|
1511
|
-
return /* @__PURE__ */ (0,
|
|
1512
|
-
}
|
|
1513
|
-
return /* @__PURE__ */ (0,
|
|
1514
|
-
title ? /* @__PURE__ */ (0,
|
|
1515
|
-
/* @__PURE__ */ (0,
|
|
1516
|
-
/* @__PURE__ */ (0,
|
|
1517
|
-
/* @__PURE__ */ (0,
|
|
1518
|
-
/* @__PURE__ */ (0,
|
|
1519
|
-
/* @__PURE__ */ (0,
|
|
2102
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "june-doc june-doc--draft", role: "alert", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "june-doc__draft-text", children: "No document content was received." }) });
|
|
2103
|
+
}
|
|
2104
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "june-doc june-doc--draft", role: "status", "aria-live": "polite", children: [
|
|
2105
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "june-doc__draft-title", children: title }) : null,
|
|
2106
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "june-doc__draft-text", children: state === "drafting" ? `Drafting document\u2026${words ? ` ${words} words so far` : ""}` : "Loading editor\u2026" }),
|
|
2107
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "june-doc__pulse", "aria-hidden": "true", children: [
|
|
2108
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", {}),
|
|
2109
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", {}),
|
|
2110
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", {})
|
|
1520
2111
|
] })
|
|
1521
2112
|
] });
|
|
1522
2113
|
}
|
|
@@ -1535,208 +2126,208 @@ var import_react8 = require("@tiptap/react");
|
|
|
1535
2126
|
var import_react9 = require("react");
|
|
1536
2127
|
|
|
1537
2128
|
// src/components/document-editor/document-icons.tsx
|
|
1538
|
-
var
|
|
2129
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1539
2130
|
var PATHS = {
|
|
1540
|
-
undo: /* @__PURE__ */ (0,
|
|
1541
|
-
/* @__PURE__ */ (0,
|
|
1542
|
-
/* @__PURE__ */ (0,
|
|
2131
|
+
undo: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2132
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M9 14 4 9l5-5" }),
|
|
2133
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M4 9h10.5a5.5 5.5 0 0 1 0 11H11" })
|
|
1543
2134
|
] }),
|
|
1544
|
-
redo: /* @__PURE__ */ (0,
|
|
1545
|
-
/* @__PURE__ */ (0,
|
|
1546
|
-
/* @__PURE__ */ (0,
|
|
2135
|
+
redo: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2136
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m15 14 5-5-5-5" }),
|
|
2137
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M20 9H9.5a5.5 5.5 0 0 0 0 11H13" })
|
|
1547
2138
|
] }),
|
|
1548
|
-
bold: /* @__PURE__ */ (0,
|
|
1549
|
-
italic: /* @__PURE__ */ (0,
|
|
1550
|
-
/* @__PURE__ */ (0,
|
|
1551
|
-
/* @__PURE__ */ (0,
|
|
1552
|
-
/* @__PURE__ */ (0,
|
|
2139
|
+
bold: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8" }),
|
|
2140
|
+
italic: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2141
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "19", x2: "10", y1: "4", y2: "4" }),
|
|
2142
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "14", x2: "5", y1: "20", y2: "20" }),
|
|
2143
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "15", x2: "9", y1: "4", y2: "20" })
|
|
1553
2144
|
] }),
|
|
1554
|
-
underline: /* @__PURE__ */ (0,
|
|
1555
|
-
/* @__PURE__ */ (0,
|
|
1556
|
-
/* @__PURE__ */ (0,
|
|
2145
|
+
underline: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2146
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M6 4v6a6 6 0 0 0 12 0V4" }),
|
|
2147
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "4", x2: "20", y1: "20", y2: "20" })
|
|
1557
2148
|
] }),
|
|
1558
|
-
strike: /* @__PURE__ */ (0,
|
|
1559
|
-
/* @__PURE__ */ (0,
|
|
1560
|
-
/* @__PURE__ */ (0,
|
|
1561
|
-
/* @__PURE__ */ (0,
|
|
2149
|
+
strike: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2150
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M16 4H9a3 3 0 0 0-2.83 4" }),
|
|
2151
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M14 12a4 4 0 0 1 0 8H6" }),
|
|
2152
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "4", x2: "20", y1: "12", y2: "12" })
|
|
1562
2153
|
] }),
|
|
1563
|
-
code: /* @__PURE__ */ (0,
|
|
1564
|
-
/* @__PURE__ */ (0,
|
|
1565
|
-
/* @__PURE__ */ (0,
|
|
2154
|
+
code: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2155
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m16 18 6-6-6-6" }),
|
|
2156
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m8 6-6 6 6 6" })
|
|
1566
2157
|
] }),
|
|
1567
|
-
codeBlock: /* @__PURE__ */ (0,
|
|
1568
|
-
/* @__PURE__ */ (0,
|
|
1569
|
-
/* @__PURE__ */ (0,
|
|
1570
|
-
/* @__PURE__ */ (0,
|
|
2158
|
+
codeBlock: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2159
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
|
|
2160
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m10 9-3 3 3 3" }),
|
|
2161
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m14 15 3-3-3-3" })
|
|
1571
2162
|
] }),
|
|
1572
|
-
superscript: /* @__PURE__ */ (0,
|
|
1573
|
-
/* @__PURE__ */ (0,
|
|
1574
|
-
/* @__PURE__ */ (0,
|
|
1575
|
-
/* @__PURE__ */ (0,
|
|
2163
|
+
superscript: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2164
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m4 19 8-8" }),
|
|
2165
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m12 19-8-8" }),
|
|
2166
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M20 12h-4c0-1.5.44-2 1.5-2.5S20 8.33 20 7c0-.47-.17-.93-.48-1.29a2.11 2.11 0 0 0-2.62-.44c-.42.24-.74.62-.9 1.07" })
|
|
1576
2167
|
] }),
|
|
1577
|
-
subscript: /* @__PURE__ */ (0,
|
|
1578
|
-
/* @__PURE__ */ (0,
|
|
1579
|
-
/* @__PURE__ */ (0,
|
|
1580
|
-
/* @__PURE__ */ (0,
|
|
2168
|
+
subscript: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2169
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m4 5 8 8" }),
|
|
2170
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m12 5-8 8" }),
|
|
2171
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M20 19h-4c0-1.5.44-2 1.5-2.5S20 15.33 20 14c0-.47-.17-.93-.48-1.29a2.11 2.11 0 0 0-2.62-.44c-.42.24-.74.62-.9 1.07" })
|
|
1581
2172
|
] }),
|
|
1582
|
-
alignLeft: /* @__PURE__ */ (0,
|
|
1583
|
-
/* @__PURE__ */ (0,
|
|
1584
|
-
/* @__PURE__ */ (0,
|
|
1585
|
-
/* @__PURE__ */ (0,
|
|
2173
|
+
alignLeft: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2174
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M15 12H3" }),
|
|
2175
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M17 18H3" }),
|
|
2176
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 6H3" })
|
|
1586
2177
|
] }),
|
|
1587
|
-
alignCenter: /* @__PURE__ */ (0,
|
|
1588
|
-
/* @__PURE__ */ (0,
|
|
1589
|
-
/* @__PURE__ */ (0,
|
|
1590
|
-
/* @__PURE__ */ (0,
|
|
2178
|
+
alignCenter: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2179
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M17 12H7" }),
|
|
2180
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M19 18H5" }),
|
|
2181
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 6H3" })
|
|
1591
2182
|
] }),
|
|
1592
|
-
alignRight: /* @__PURE__ */ (0,
|
|
1593
|
-
/* @__PURE__ */ (0,
|
|
1594
|
-
/* @__PURE__ */ (0,
|
|
1595
|
-
/* @__PURE__ */ (0,
|
|
2183
|
+
alignRight: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2184
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 12H9" }),
|
|
2185
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 18H7" }),
|
|
2186
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 6H3" })
|
|
1596
2187
|
] }),
|
|
1597
|
-
alignJustify: /* @__PURE__ */ (0,
|
|
1598
|
-
/* @__PURE__ */ (0,
|
|
1599
|
-
/* @__PURE__ */ (0,
|
|
1600
|
-
/* @__PURE__ */ (0,
|
|
2188
|
+
alignJustify: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2189
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 12h18" }),
|
|
2190
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 18h18" }),
|
|
2191
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 6h18" })
|
|
1601
2192
|
] }),
|
|
1602
|
-
list: /* @__PURE__ */ (0,
|
|
1603
|
-
/* @__PURE__ */ (0,
|
|
1604
|
-
/* @__PURE__ */ (0,
|
|
1605
|
-
/* @__PURE__ */ (0,
|
|
1606
|
-
/* @__PURE__ */ (0,
|
|
1607
|
-
/* @__PURE__ */ (0,
|
|
1608
|
-
/* @__PURE__ */ (0,
|
|
2193
|
+
list: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2194
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 12h.01" }),
|
|
2195
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 18h.01" }),
|
|
2196
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 6h.01" }),
|
|
2197
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M8 12h13" }),
|
|
2198
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M8 18h13" }),
|
|
2199
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M8 6h13" })
|
|
1609
2200
|
] }),
|
|
1610
|
-
listOrdered: /* @__PURE__ */ (0,
|
|
1611
|
-
/* @__PURE__ */ (0,
|
|
1612
|
-
/* @__PURE__ */ (0,
|
|
1613
|
-
/* @__PURE__ */ (0,
|
|
1614
|
-
/* @__PURE__ */ (0,
|
|
1615
|
-
/* @__PURE__ */ (0,
|
|
1616
|
-
/* @__PURE__ */ (0,
|
|
2201
|
+
listOrdered: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2202
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M10 12h11" }),
|
|
2203
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M10 18h11" }),
|
|
2204
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M10 6h11" }),
|
|
2205
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M4 10h2" }),
|
|
2206
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M4 6h1v4" }),
|
|
2207
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M6 18H4c0-1 2-2 2-3s-1-1.5-2-1" })
|
|
1617
2208
|
] }),
|
|
1618
|
-
outdent: /* @__PURE__ */ (0,
|
|
1619
|
-
/* @__PURE__ */ (0,
|
|
1620
|
-
/* @__PURE__ */ (0,
|
|
1621
|
-
/* @__PURE__ */ (0,
|
|
1622
|
-
/* @__PURE__ */ (0,
|
|
2209
|
+
outdent: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2210
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 12H11" }),
|
|
2211
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 18H11" }),
|
|
2212
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 6H11" }),
|
|
2213
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m7 8-4 4 4 4" })
|
|
1623
2214
|
] }),
|
|
1624
|
-
indent: /* @__PURE__ */ (0,
|
|
1625
|
-
/* @__PURE__ */ (0,
|
|
1626
|
-
/* @__PURE__ */ (0,
|
|
1627
|
-
/* @__PURE__ */ (0,
|
|
1628
|
-
/* @__PURE__ */ (0,
|
|
2215
|
+
indent: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2216
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 12H11" }),
|
|
2217
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 18H11" }),
|
|
2218
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 6H11" }),
|
|
2219
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m3 8 4 4-4 4" })
|
|
1629
2220
|
] }),
|
|
1630
|
-
quote: /* @__PURE__ */ (0,
|
|
1631
|
-
/* @__PURE__ */ (0,
|
|
1632
|
-
/* @__PURE__ */ (0,
|
|
1633
|
-
/* @__PURE__ */ (0,
|
|
1634
|
-
/* @__PURE__ */ (0,
|
|
2221
|
+
quote: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2222
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M17 6H3" }),
|
|
2223
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 12H8" }),
|
|
2224
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 18H8" }),
|
|
2225
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 12v6" })
|
|
1635
2226
|
] }),
|
|
1636
|
-
pilcrow: /* @__PURE__ */ (0,
|
|
1637
|
-
/* @__PURE__ */ (0,
|
|
1638
|
-
/* @__PURE__ */ (0,
|
|
1639
|
-
/* @__PURE__ */ (0,
|
|
2227
|
+
pilcrow: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2228
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M13 4v16" }),
|
|
2229
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M17 4v16" }),
|
|
2230
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M19 4H9.5a4.5 4.5 0 0 0 0 9H13" })
|
|
1640
2231
|
] }),
|
|
1641
|
-
pageBreak: /* @__PURE__ */ (0,
|
|
1642
|
-
/* @__PURE__ */ (0,
|
|
1643
|
-
/* @__PURE__ */ (0,
|
|
1644
|
-
/* @__PURE__ */ (0,
|
|
2232
|
+
pageBreak: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2233
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "3", x2: "21", y1: "12", y2: "12" }),
|
|
2234
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("polyline", { points: "8 8 12 4 16 8" }),
|
|
2235
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("polyline", { points: "16 16 12 20 8 16" })
|
|
1645
2236
|
] }),
|
|
1646
|
-
divider: /* @__PURE__ */ (0,
|
|
1647
|
-
/* @__PURE__ */ (0,
|
|
1648
|
-
/* @__PURE__ */ (0,
|
|
1649
|
-
/* @__PURE__ */ (0,
|
|
2237
|
+
divider: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2238
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 12h18" }),
|
|
2239
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M8 6h8", opacity: ".45" }),
|
|
2240
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M8 18h8", opacity: ".45" })
|
|
1650
2241
|
] }),
|
|
1651
|
-
layout: /* @__PURE__ */ (0,
|
|
1652
|
-
/* @__PURE__ */ (0,
|
|
1653
|
-
/* @__PURE__ */ (0,
|
|
1654
|
-
/* @__PURE__ */ (0,
|
|
2242
|
+
layout: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2243
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
|
|
2244
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
|
|
2245
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
|
|
1655
2246
|
] }),
|
|
1656
|
-
search: /* @__PURE__ */ (0,
|
|
1657
|
-
/* @__PURE__ */ (0,
|
|
1658
|
-
/* @__PURE__ */ (0,
|
|
2247
|
+
search: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2248
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "11", cy: "11", r: "8" }),
|
|
2249
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m21 21-4.3-4.3" })
|
|
1659
2250
|
] }),
|
|
1660
|
-
palette: /* @__PURE__ */ (0,
|
|
1661
|
-
/* @__PURE__ */ (0,
|
|
1662
|
-
/* @__PURE__ */ (0,
|
|
1663
|
-
/* @__PURE__ */ (0,
|
|
1664
|
-
/* @__PURE__ */ (0,
|
|
1665
|
-
/* @__PURE__ */ (0,
|
|
2251
|
+
palette: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2252
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "13.5", cy: "6.5", r: ".5", fill: "currentColor" }),
|
|
2253
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "17.5", cy: "10.5", r: ".5", fill: "currentColor" }),
|
|
2254
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "8.5", cy: "7.5", r: ".5", fill: "currentColor" }),
|
|
2255
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "6.5", cy: "12.5", r: ".5", fill: "currentColor" }),
|
|
2256
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.93 0 1.65-.75 1.65-1.69 0-.44-.18-.84-.44-1.13-.29-.29-.44-.65-.44-1.13a1.64 1.64 0 0 1 1.67-1.67h2c3.05 0 5.55-2.5 5.55-5.55C21.97 6.01 17.46 2 12 2z" })
|
|
1666
2257
|
] }),
|
|
1667
|
-
highlighter: /* @__PURE__ */ (0,
|
|
1668
|
-
/* @__PURE__ */ (0,
|
|
1669
|
-
/* @__PURE__ */ (0,
|
|
2258
|
+
highlighter: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2259
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m9 11-6 6v3h9l3-3" }),
|
|
2260
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m22 12-4.6 4.6a2 2 0 0 1-2.8 0l-5.2-5.2a2 2 0 0 1 0-2.8L14 4" })
|
|
1670
2261
|
] }),
|
|
1671
|
-
link: /* @__PURE__ */ (0,
|
|
1672
|
-
/* @__PURE__ */ (0,
|
|
1673
|
-
/* @__PURE__ */ (0,
|
|
2262
|
+
link: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2263
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
|
|
2264
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
|
|
1674
2265
|
] }),
|
|
1675
|
-
image: /* @__PURE__ */ (0,
|
|
1676
|
-
/* @__PURE__ */ (0,
|
|
1677
|
-
/* @__PURE__ */ (0,
|
|
1678
|
-
/* @__PURE__ */ (0,
|
|
2266
|
+
image: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2267
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }),
|
|
2268
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "9", cy: "9", r: "2" }),
|
|
2269
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m21 15-3.09-3.09a2 2 0 0 0-2.82 0L6 21" })
|
|
1679
2270
|
] }),
|
|
1680
|
-
table: /* @__PURE__ */ (0,
|
|
1681
|
-
/* @__PURE__ */ (0,
|
|
1682
|
-
/* @__PURE__ */ (0,
|
|
1683
|
-
/* @__PURE__ */ (0,
|
|
1684
|
-
/* @__PURE__ */ (0,
|
|
2271
|
+
table: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2272
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M12 3v18" }),
|
|
2273
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2" }),
|
|
2274
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 9h18" }),
|
|
2275
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 15h18" })
|
|
1685
2276
|
] }),
|
|
1686
|
-
eraser: /* @__PURE__ */ (0,
|
|
1687
|
-
/* @__PURE__ */ (0,
|
|
1688
|
-
/* @__PURE__ */ (0,
|
|
1689
|
-
/* @__PURE__ */ (0,
|
|
2277
|
+
eraser: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2278
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21" }),
|
|
2279
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M22 21H7" }),
|
|
2280
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m5 11 9 9" })
|
|
1690
2281
|
] }),
|
|
1691
|
-
save: /* @__PURE__ */ (0,
|
|
1692
|
-
/* @__PURE__ */ (0,
|
|
1693
|
-
/* @__PURE__ */ (0,
|
|
1694
|
-
/* @__PURE__ */ (0,
|
|
2282
|
+
save: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2283
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z" }),
|
|
2284
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7" }),
|
|
2285
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M7 3v4a1 1 0 0 0 1 1h7" })
|
|
1695
2286
|
] }),
|
|
1696
|
-
download: /* @__PURE__ */ (0,
|
|
1697
|
-
/* @__PURE__ */ (0,
|
|
1698
|
-
/* @__PURE__ */ (0,
|
|
1699
|
-
/* @__PURE__ */ (0,
|
|
2287
|
+
download: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2288
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
2289
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("polyline", { points: "7 10 12 15 17 10" }),
|
|
2290
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "12", x2: "12", y1: "15", y2: "3" })
|
|
1700
2291
|
] }),
|
|
1701
|
-
chevronDown: /* @__PURE__ */ (0,
|
|
1702
|
-
chevronUp: /* @__PURE__ */ (0,
|
|
1703
|
-
close: /* @__PURE__ */ (0,
|
|
1704
|
-
/* @__PURE__ */ (0,
|
|
1705
|
-
/* @__PURE__ */ (0,
|
|
2292
|
+
chevronDown: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m6 9 6 6 6-6" }),
|
|
2293
|
+
chevronUp: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m18 15-6-6-6 6" }),
|
|
2294
|
+
close: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2295
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M18 6 6 18" }),
|
|
2296
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m6 6 12 12" })
|
|
1706
2297
|
] }),
|
|
1707
|
-
maximize: /* @__PURE__ */ (0,
|
|
1708
|
-
/* @__PURE__ */ (0,
|
|
1709
|
-
/* @__PURE__ */ (0,
|
|
1710
|
-
/* @__PURE__ */ (0,
|
|
1711
|
-
/* @__PURE__ */ (0,
|
|
2298
|
+
maximize: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2299
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M8 3H5a2 2 0 0 0-2 2v3" }),
|
|
2300
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 8V5a2 2 0 0 0-2-2h-3" }),
|
|
2301
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3 16v3a2 2 0 0 0 2 2h3" }),
|
|
2302
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M16 21h3a2 2 0 0 0 2-2v-3" })
|
|
1712
2303
|
] }),
|
|
1713
|
-
copy: /* @__PURE__ */ (0,
|
|
1714
|
-
/* @__PURE__ */ (0,
|
|
1715
|
-
/* @__PURE__ */ (0,
|
|
2304
|
+
copy: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2305
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { width: "14", height: "14", x: "8", y: "8", rx: "2" }),
|
|
2306
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" })
|
|
1716
2307
|
] }),
|
|
1717
|
-
file: /* @__PURE__ */ (0,
|
|
1718
|
-
/* @__PURE__ */ (0,
|
|
1719
|
-
/* @__PURE__ */ (0,
|
|
2308
|
+
file: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2309
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
2310
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
|
|
1720
2311
|
] }),
|
|
1721
|
-
plus: /* @__PURE__ */ (0,
|
|
1722
|
-
/* @__PURE__ */ (0,
|
|
1723
|
-
/* @__PURE__ */ (0,
|
|
2312
|
+
plus: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2313
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M5 12h14" }),
|
|
2314
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M12 5v14" })
|
|
1724
2315
|
] }),
|
|
1725
|
-
minus: /* @__PURE__ */ (0,
|
|
1726
|
-
check: /* @__PURE__ */ (0,
|
|
1727
|
-
sparkles: /* @__PURE__ */ (0,
|
|
1728
|
-
/* @__PURE__ */ (0,
|
|
1729
|
-
/* @__PURE__ */ (0,
|
|
1730
|
-
/* @__PURE__ */ (0,
|
|
2316
|
+
minus: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M5 12h14" }),
|
|
2317
|
+
check: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M20 6 9 17l-5-5" }),
|
|
2318
|
+
sparkles: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2319
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M9.94 14.06 8 20l-1.94-5.94L0 12l6.06-1.94L8 4l1.94 6.06L16 12z", transform: "translate(3 -1) scale(.85)" }),
|
|
2320
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M20 3v4" }),
|
|
2321
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M22 5h-4" })
|
|
1731
2322
|
] }),
|
|
1732
|
-
upload: /* @__PURE__ */ (0,
|
|
1733
|
-
/* @__PURE__ */ (0,
|
|
1734
|
-
/* @__PURE__ */ (0,
|
|
1735
|
-
/* @__PURE__ */ (0,
|
|
2323
|
+
upload: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2324
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
2325
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("polyline", { points: "17 8 12 3 7 8" }),
|
|
2326
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "12", x2: "12", y1: "3", y2: "15" })
|
|
1736
2327
|
] })
|
|
1737
2328
|
};
|
|
1738
2329
|
function Icon({ name, size = 16 }) {
|
|
1739
|
-
return /* @__PURE__ */ (0,
|
|
2330
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1740
2331
|
"svg",
|
|
1741
2332
|
{
|
|
1742
2333
|
className: "june-doc__icon",
|
|
@@ -1757,7 +2348,7 @@ function Icon({ name, size = 16 }) {
|
|
|
1757
2348
|
|
|
1758
2349
|
// src/components/document-editor/document-popover.tsx
|
|
1759
2350
|
var import_react7 = require("react");
|
|
1760
|
-
var
|
|
2351
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1761
2352
|
function Dropdown({ trigger, children, align = "start", className, onOpen }) {
|
|
1762
2353
|
const [open, setOpen] = (0, import_react7.useState)(false);
|
|
1763
2354
|
const anchor = (0, import_react7.useRef)(null);
|
|
@@ -1774,7 +2365,7 @@ function Dropdown({ trigger, children, align = "start", className, onOpen }) {
|
|
|
1774
2365
|
return !v;
|
|
1775
2366
|
});
|
|
1776
2367
|
const close = () => setOpen(false);
|
|
1777
|
-
return /* @__PURE__ */ (0,
|
|
2368
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1778
2369
|
"div",
|
|
1779
2370
|
{
|
|
1780
2371
|
ref: anchor,
|
|
@@ -1787,7 +2378,7 @@ function Dropdown({ trigger, children, align = "start", className, onOpen }) {
|
|
|
1787
2378
|
},
|
|
1788
2379
|
children: [
|
|
1789
2380
|
trigger({ open, toggle }),
|
|
1790
|
-
open ? /* @__PURE__ */ (0,
|
|
2381
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `june-doc__pop june-doc__pop--${align}${className ? ` ${className}` : ""}`, children: children(close) }) : null
|
|
1791
2382
|
]
|
|
1792
2383
|
}
|
|
1793
2384
|
);
|
|
@@ -1795,7 +2386,7 @@ function Dropdown({ trigger, children, align = "start", className, onOpen }) {
|
|
|
1795
2386
|
|
|
1796
2387
|
// src/components/document-editor/document-toolbar.tsx
|
|
1797
2388
|
init_document_utils();
|
|
1798
|
-
var
|
|
2389
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1799
2390
|
var FONT_FAMILIES = [
|
|
1800
2391
|
{ label: "Default", value: "" },
|
|
1801
2392
|
{ label: "Arial", value: "Arial, Helvetica, sans-serif" },
|
|
@@ -1842,7 +2433,7 @@ var HIGHLIGHT_COLORS = [
|
|
|
1842
2433
|
];
|
|
1843
2434
|
var MAX_IMAGE_BYTES = 8 * 1024 * 1024;
|
|
1844
2435
|
function Btn({ label, icon, active, disabled, toggle, onClick, children, className, text }) {
|
|
1845
|
-
return /* @__PURE__ */ (0,
|
|
2436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1846
2437
|
"button",
|
|
1847
2438
|
{
|
|
1848
2439
|
type: "button",
|
|
@@ -1855,29 +2446,29 @@ function Btn({ label, icon, active, disabled, toggle, onClick, children, classNa
|
|
|
1855
2446
|
onMouseDown: (e) => e.preventDefault(),
|
|
1856
2447
|
onClick,
|
|
1857
2448
|
children: [
|
|
1858
|
-
icon ? /* @__PURE__ */ (0,
|
|
1859
|
-
children ?? (text ? /* @__PURE__ */ (0,
|
|
2449
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: icon }) : null,
|
|
2450
|
+
children ?? (text ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: label }) : null)
|
|
1860
2451
|
]
|
|
1861
2452
|
}
|
|
1862
2453
|
);
|
|
1863
2454
|
}
|
|
1864
2455
|
function Group({ label, children }) {
|
|
1865
|
-
return /* @__PURE__ */ (0,
|
|
1866
|
-
label ? /* @__PURE__ */ (0,
|
|
2456
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__group", role: "group", "aria-label": label, children: [
|
|
2457
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "june-doc__group-label", "aria-hidden": "true", children: label }) : null,
|
|
1867
2458
|
children
|
|
1868
2459
|
] });
|
|
1869
2460
|
}
|
|
1870
2461
|
function Field({ label, children }) {
|
|
1871
|
-
return /* @__PURE__ */ (0,
|
|
1872
|
-
/* @__PURE__ */ (0,
|
|
2462
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "june-doc__field", children: [
|
|
2463
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "june-doc__field-label", children: label }),
|
|
1873
2464
|
children
|
|
1874
2465
|
] });
|
|
1875
2466
|
}
|
|
1876
2467
|
function ColorPicker({ label, icon, colors, current, disabled, resetLabel, onPick, onReset }) {
|
|
1877
|
-
return /* @__PURE__ */ (0,
|
|
2468
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1878
2469
|
Dropdown,
|
|
1879
2470
|
{
|
|
1880
|
-
trigger: ({ open, toggle }) => /* @__PURE__ */ (0,
|
|
2471
|
+
trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1881
2472
|
"button",
|
|
1882
2473
|
{
|
|
1883
2474
|
type: "button",
|
|
@@ -1890,14 +2481,14 @@ function ColorPicker({ label, icon, colors, current, disabled, resetLabel, onPic
|
|
|
1890
2481
|
onMouseDown: (e) => e.preventDefault(),
|
|
1891
2482
|
onClick: toggle,
|
|
1892
2483
|
children: [
|
|
1893
|
-
/* @__PURE__ */ (0,
|
|
1894
|
-
/* @__PURE__ */ (0,
|
|
2484
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: icon }),
|
|
2485
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "june-doc__color-bar", style: { background: current ?? "transparent" } })
|
|
1895
2486
|
]
|
|
1896
2487
|
}
|
|
1897
2488
|
),
|
|
1898
|
-
children: (close) => /* @__PURE__ */ (0,
|
|
1899
|
-
/* @__PURE__ */ (0,
|
|
1900
|
-
/* @__PURE__ */ (0,
|
|
2489
|
+
children: (close) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__swatches-wrap", role: "dialog", "aria-label": label, children: [
|
|
2490
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "june-doc__pop-title", children: label }),
|
|
2491
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "june-doc__swatches", children: colors.map((c) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1901
2492
|
"button",
|
|
1902
2493
|
{
|
|
1903
2494
|
type: "button",
|
|
@@ -1914,8 +2505,8 @@ function ColorPicker({ label, icon, colors, current, disabled, resetLabel, onPic
|
|
|
1914
2505
|
},
|
|
1915
2506
|
c
|
|
1916
2507
|
)) }),
|
|
1917
|
-
/* @__PURE__ */ (0,
|
|
1918
|
-
/* @__PURE__ */ (0,
|
|
2508
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__pop-row", children: [
|
|
2509
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1919
2510
|
"button",
|
|
1920
2511
|
{
|
|
1921
2512
|
type: "button",
|
|
@@ -1928,9 +2519,9 @@ function ColorPicker({ label, icon, colors, current, disabled, resetLabel, onPic
|
|
|
1928
2519
|
children: resetLabel
|
|
1929
2520
|
}
|
|
1930
2521
|
),
|
|
1931
|
-
/* @__PURE__ */ (0,
|
|
1932
|
-
/* @__PURE__ */ (0,
|
|
1933
|
-
/* @__PURE__ */ (0,
|
|
2522
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "june-doc__custom-color", title: "Custom color", children: [
|
|
2523
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Custom" }),
|
|
2524
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1934
2525
|
"input",
|
|
1935
2526
|
{
|
|
1936
2527
|
type: "color",
|
|
@@ -1961,9 +2552,9 @@ function LinkPanel({
|
|
|
1961
2552
|
editor.chain().focus().extendMarkRange("link").unsetLink().run();
|
|
1962
2553
|
close();
|
|
1963
2554
|
};
|
|
1964
|
-
return /* @__PURE__ */ (0,
|
|
1965
|
-
/* @__PURE__ */ (0,
|
|
1966
|
-
/* @__PURE__ */ (0,
|
|
2555
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__form", role: "dialog", "aria-label": "Edit link", children: [
|
|
2556
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "june-doc__pop-title", children: "Link" }),
|
|
2557
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1967
2558
|
"input",
|
|
1968
2559
|
{
|
|
1969
2560
|
"aria-label": "Link address",
|
|
@@ -1980,10 +2571,10 @@ function LinkPanel({
|
|
|
1980
2571
|
}
|
|
1981
2572
|
}
|
|
1982
2573
|
),
|
|
1983
|
-
/* @__PURE__ */ (0,
|
|
1984
|
-
isLink ? /* @__PURE__ */ (0,
|
|
1985
|
-
/* @__PURE__ */ (0,
|
|
1986
|
-
/* @__PURE__ */ (0,
|
|
2574
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__pop-row june-doc__pop-row--end", children: [
|
|
2575
|
+
isLink ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--ghost", onClick: remove, children: "Remove" }) : null,
|
|
2576
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "june-doc__btn", onClick: close, children: "Cancel" }),
|
|
2577
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--primary", onClick: apply, children: "Apply" })
|
|
1987
2578
|
] })
|
|
1988
2579
|
] });
|
|
1989
2580
|
}
|
|
@@ -2012,9 +2603,9 @@ function ImagePanel({ editor, close, onNotice }) {
|
|
|
2012
2603
|
reader.onerror = () => onNotice("The image could not be read");
|
|
2013
2604
|
reader.readAsDataURL(f);
|
|
2014
2605
|
};
|
|
2015
|
-
return /* @__PURE__ */ (0,
|
|
2016
|
-
/* @__PURE__ */ (0,
|
|
2017
|
-
/* @__PURE__ */ (0,
|
|
2606
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__form", role: "dialog", "aria-label": "Insert image", children: [
|
|
2607
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "june-doc__pop-title", children: "Image" }),
|
|
2608
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2018
2609
|
"button",
|
|
2019
2610
|
{
|
|
2020
2611
|
type: "button",
|
|
@@ -2026,12 +2617,12 @@ function ImagePanel({ editor, close, onNotice }) {
|
|
|
2026
2617
|
fromFile(e.dataTransfer.files[0]);
|
|
2027
2618
|
},
|
|
2028
2619
|
children: [
|
|
2029
|
-
/* @__PURE__ */ (0,
|
|
2030
|
-
/* @__PURE__ */ (0,
|
|
2620
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: "upload", size: 18 }),
|
|
2621
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Upload or drop an image" })
|
|
2031
2622
|
]
|
|
2032
2623
|
}
|
|
2033
2624
|
),
|
|
2034
|
-
/* @__PURE__ */ (0,
|
|
2625
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2035
2626
|
"input",
|
|
2036
2627
|
{
|
|
2037
2628
|
ref: file,
|
|
@@ -2041,8 +2632,8 @@ function ImagePanel({ editor, close, onNotice }) {
|
|
|
2041
2632
|
onChange: (e) => fromFile(e.target.files?.[0])
|
|
2042
2633
|
}
|
|
2043
2634
|
),
|
|
2044
|
-
/* @__PURE__ */ (0,
|
|
2045
|
-
/* @__PURE__ */ (0,
|
|
2635
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "june-doc__or", children: "or" }),
|
|
2636
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2046
2637
|
"input",
|
|
2047
2638
|
{
|
|
2048
2639
|
"aria-label": "Image address",
|
|
@@ -2053,7 +2644,7 @@ function ImagePanel({ editor, close, onNotice }) {
|
|
|
2053
2644
|
onKeyDown: (e) => e.key === "Enter" && fromUrl()
|
|
2054
2645
|
}
|
|
2055
2646
|
),
|
|
2056
|
-
/* @__PURE__ */ (0,
|
|
2647
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2057
2648
|
"input",
|
|
2058
2649
|
{
|
|
2059
2650
|
"aria-label": "Alternative text",
|
|
@@ -2063,24 +2654,24 @@ function ImagePanel({ editor, close, onNotice }) {
|
|
|
2063
2654
|
onChange: (e) => setAlt(e.target.value)
|
|
2064
2655
|
}
|
|
2065
2656
|
),
|
|
2066
|
-
/* @__PURE__ */ (0,
|
|
2067
|
-
/* @__PURE__ */ (0,
|
|
2068
|
-
/* @__PURE__ */ (0,
|
|
2657
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__pop-row june-doc__pop-row--end", children: [
|
|
2658
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "june-doc__btn", onClick: close, children: "Cancel" }),
|
|
2659
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--primary", disabled: !url.trim(), onClick: fromUrl, children: "Insert" })
|
|
2069
2660
|
] })
|
|
2070
2661
|
] });
|
|
2071
2662
|
}
|
|
2072
2663
|
function TablePanel({ editor, close }) {
|
|
2073
2664
|
const [hover, setHover] = (0, import_react9.useState)([0, 0]);
|
|
2074
2665
|
const N = 8;
|
|
2075
|
-
return /* @__PURE__ */ (0,
|
|
2076
|
-
/* @__PURE__ */ (0,
|
|
2666
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__form", role: "dialog", "aria-label": "Insert table", children: [
|
|
2667
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__pop-title", children: [
|
|
2077
2668
|
"Table ",
|
|
2078
2669
|
hover[0] ? `${hover[0]} \xD7 ${hover[1]}` : ""
|
|
2079
2670
|
] }),
|
|
2080
|
-
/* @__PURE__ */ (0,
|
|
2671
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "june-doc__grid", onMouseLeave: () => setHover([0, 0]), children: Array.from({ length: N * N }, (_, i) => {
|
|
2081
2672
|
const r = Math.floor(i / N) + 1;
|
|
2082
2673
|
const c = i % N + 1;
|
|
2083
|
-
return /* @__PURE__ */ (0,
|
|
2674
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2084
2675
|
"button",
|
|
2085
2676
|
{
|
|
2086
2677
|
type: "button",
|
|
@@ -2162,34 +2753,34 @@ function DocumentToolbar(props) {
|
|
|
2162
2753
|
const fontKnown = FONT_FAMILIES.some((f) => f.value === s?.fontFamily);
|
|
2163
2754
|
const sizes = s?.fontSize && !FONT_SIZES.includes(Number(s.fontSize)) ? [...FONT_SIZES, Number(s.fontSize)].sort((a, b) => a - b) : FONT_SIZES;
|
|
2164
2755
|
if (!editable) return null;
|
|
2165
|
-
return /* @__PURE__ */ (0,
|
|
2166
|
-
/* @__PURE__ */ (0,
|
|
2167
|
-
/* @__PURE__ */ (0,
|
|
2168
|
-
/* @__PURE__ */ (0,
|
|
2169
|
-
/* @__PURE__ */ (0,
|
|
2756
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__ribbon", role: "toolbar", "aria-label": "Document formatting", children: [
|
|
2757
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__row", children: [
|
|
2758
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "History", children: [
|
|
2759
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Undo", icon: "undo", disabled: off || !s?.canUndo, onClick: () => run()?.undo().run() }),
|
|
2760
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Redo", icon: "redo", disabled: off || !s?.canRedo, onClick: () => run()?.redo().run() })
|
|
2170
2761
|
] }),
|
|
2171
|
-
/* @__PURE__ */ (0,
|
|
2172
|
-
/* @__PURE__ */ (0,
|
|
2173
|
-
/* @__PURE__ */ (0,
|
|
2174
|
-
/* @__PURE__ */ (0,
|
|
2175
|
-
/* @__PURE__ */ (0,
|
|
2176
|
-
/* @__PURE__ */ (0,
|
|
2177
|
-
/* @__PURE__ */ (0,
|
|
2178
|
-
/* @__PURE__ */ (0,
|
|
2762
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "Format", children: [
|
|
2763
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Bold", icon: "bold", toggle: true, active: s?.bold, disabled: off, onClick: () => run()?.toggleBold().run() }),
|
|
2764
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Italic", icon: "italic", toggle: true, active: s?.italic, disabled: off, onClick: () => run()?.toggleItalic().run() }),
|
|
2765
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Underline", icon: "underline", toggle: true, active: s?.underline, disabled: off, onClick: () => run()?.toggleUnderline().run() }),
|
|
2766
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Strikethrough", icon: "strike", toggle: true, active: s?.strike, disabled: off, onClick: () => run()?.toggleStrike().run() }),
|
|
2767
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Inline code", icon: "code", toggle: true, active: s?.code, disabled: off, onClick: () => run()?.toggleCode().run() }),
|
|
2768
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Superscript", icon: "superscript", toggle: true, active: s?.sup, disabled: off, onClick: () => run()?.toggleSuperscript().run() }),
|
|
2769
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Subscript", icon: "subscript", toggle: true, active: s?.sub, disabled: off, onClick: () => run()?.toggleSubscript().run() })
|
|
2179
2770
|
] }),
|
|
2180
|
-
/* @__PURE__ */ (0,
|
|
2181
|
-
/* @__PURE__ */ (0,
|
|
2182
|
-
/* @__PURE__ */ (0,
|
|
2183
|
-
/* @__PURE__ */ (0,
|
|
2184
|
-
/* @__PURE__ */ (0,
|
|
2771
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "Align", children: [
|
|
2772
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Align left", icon: "alignLeft", toggle: true, active: s?.left, disabled: off, onClick: () => run()?.setTextAlign("left").run() }),
|
|
2773
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Align center", icon: "alignCenter", toggle: true, active: s?.center, disabled: off, onClick: () => run()?.setTextAlign("center").run() }),
|
|
2774
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Align right", icon: "alignRight", toggle: true, active: s?.right, disabled: off, onClick: () => run()?.setTextAlign("right").run() }),
|
|
2775
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Justify", icon: "alignJustify", toggle: true, active: s?.justify, disabled: off, onClick: () => run()?.setTextAlign("justify").run() })
|
|
2185
2776
|
] }),
|
|
2186
|
-
/* @__PURE__ */ (0,
|
|
2187
|
-
/* @__PURE__ */ (0,
|
|
2188
|
-
/* @__PURE__ */ (0,
|
|
2189
|
-
/* @__PURE__ */ (0,
|
|
2190
|
-
/* @__PURE__ */ (0,
|
|
2777
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "Lists", children: [
|
|
2778
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Bullet list", icon: "list", toggle: true, active: s?.bullet, disabled: off, onClick: () => run()?.toggleBulletList().run() }),
|
|
2779
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Numbered list", icon: "listOrdered", toggle: true, active: s?.ordered, disabled: off, onClick: () => run()?.toggleOrderedList().run() }),
|
|
2780
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Decrease indent", icon: "outdent", disabled: off || !s?.canLift, onClick: () => run()?.liftListItem("listItem").run() }),
|
|
2781
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Increase indent", icon: "indent", disabled: off || !s?.canSink, onClick: () => run()?.sinkListItem("listItem").run() })
|
|
2191
2782
|
] }),
|
|
2192
|
-
/* @__PURE__ */ (0,
|
|
2783
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2193
2784
|
"button",
|
|
2194
2785
|
{
|
|
2195
2786
|
type: "button",
|
|
@@ -2200,22 +2791,22 @@ function DocumentToolbar(props) {
|
|
|
2200
2791
|
onClick: onToggleExpanded,
|
|
2201
2792
|
children: [
|
|
2202
2793
|
expanded ? "Less" : "More",
|
|
2203
|
-
/* @__PURE__ */ (0,
|
|
2794
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: expanded ? "chevronUp" : "chevronDown", size: 14 })
|
|
2204
2795
|
]
|
|
2205
2796
|
}
|
|
2206
2797
|
)
|
|
2207
2798
|
] }),
|
|
2208
|
-
expanded ? /* @__PURE__ */ (0,
|
|
2209
|
-
/* @__PURE__ */ (0,
|
|
2210
|
-
/* @__PURE__ */ (0,
|
|
2211
|
-
/* @__PURE__ */ (0,
|
|
2212
|
-
/* @__PURE__ */ (0,
|
|
2213
|
-
/* @__PURE__ */ (0,
|
|
2214
|
-
/* @__PURE__ */ (0,
|
|
2215
|
-
/* @__PURE__ */ (0,
|
|
2216
|
-
/* @__PURE__ */ (0,
|
|
2799
|
+
expanded ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "june-doc__row june-doc__row--secondary", children: [
|
|
2800
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "Style", children: [
|
|
2801
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Field, { label: "Style", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("select", { className: "june-doc__select", "aria-label": "Text style", disabled: off, value: style, onChange: (e) => setStyle(e.target.value), children: [
|
|
2802
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "p", children: "Paragraph" }),
|
|
2803
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "1", children: "Heading 1" }),
|
|
2804
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "2", children: "Heading 2" }),
|
|
2805
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "3", children: "Heading 3" }),
|
|
2806
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "quote", children: "Quote" }),
|
|
2807
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "code", children: "Code block" })
|
|
2217
2808
|
] }) }),
|
|
2218
|
-
/* @__PURE__ */ (0,
|
|
2809
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Field, { label: "Font", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2219
2810
|
"select",
|
|
2220
2811
|
{
|
|
2221
2812
|
className: "june-doc__select june-doc__select--font",
|
|
@@ -2228,12 +2819,12 @@ function DocumentToolbar(props) {
|
|
|
2228
2819
|
else run()?.unsetFontFamily().run();
|
|
2229
2820
|
},
|
|
2230
2821
|
children: [
|
|
2231
|
-
FONT_FAMILIES.map((f) => /* @__PURE__ */ (0,
|
|
2232
|
-
!fontKnown && s?.fontFamily ? /* @__PURE__ */ (0,
|
|
2822
|
+
FONT_FAMILIES.map((f) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: f.value, style: { fontFamily: f.value || void 0 }, children: f.label }, f.label)),
|
|
2823
|
+
!fontKnown && s?.fontFamily ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: s.fontFamily, children: s.fontFamily.split(",")[0].replace(/['"]/g, "") }) : null
|
|
2233
2824
|
]
|
|
2234
2825
|
}
|
|
2235
2826
|
) }),
|
|
2236
|
-
/* @__PURE__ */ (0,
|
|
2827
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Field, { label: "Size", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2237
2828
|
"select",
|
|
2238
2829
|
{
|
|
2239
2830
|
className: "june-doc__select june-doc__select--size",
|
|
@@ -2246,21 +2837,21 @@ function DocumentToolbar(props) {
|
|
|
2246
2837
|
else run()?.unsetFontSize().run();
|
|
2247
2838
|
},
|
|
2248
2839
|
children: [
|
|
2249
|
-
/* @__PURE__ */ (0,
|
|
2250
|
-
sizes.map((n) => /* @__PURE__ */ (0,
|
|
2840
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "", children: "Auto" }),
|
|
2841
|
+
sizes.map((n) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: String(n), children: n }, n))
|
|
2251
2842
|
]
|
|
2252
2843
|
}
|
|
2253
2844
|
) })
|
|
2254
2845
|
] }),
|
|
2255
|
-
/* @__PURE__ */ (0,
|
|
2256
|
-
/* @__PURE__ */ (0,
|
|
2257
|
-
/* @__PURE__ */ (0,
|
|
2258
|
-
/* @__PURE__ */ (0,
|
|
2259
|
-
/* @__PURE__ */ (0,
|
|
2260
|
-
/* @__PURE__ */ (0,
|
|
2846
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Show formatting marks", icon: "pilcrow", toggle: true, active: showMarks, onClick: onToggleMarks, text: true, className: "june-doc__btn--marks", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Paragraph" }) }),
|
|
2847
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "Document", children: [
|
|
2848
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Insert page break", icon: "pageBreak", disabled: off, onClick: () => run()?.setPageBreak().run() }),
|
|
2849
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Insert divider", icon: "divider", disabled: off, onClick: () => run()?.setHorizontalRule().run() }),
|
|
2850
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: layout === "page" ? "Switch to full-width layout" : "Switch to page layout", icon: "layout", toggle: true, active: layout === "fluid", onClick: onToggleLayout }),
|
|
2851
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Find and replace", icon: "search", toggle: true, active: findOpen, onClick: onToggleFind })
|
|
2261
2852
|
] }),
|
|
2262
|
-
/* @__PURE__ */ (0,
|
|
2263
|
-
/* @__PURE__ */ (0,
|
|
2853
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "Color", children: [
|
|
2854
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2264
2855
|
ColorPicker,
|
|
2265
2856
|
{
|
|
2266
2857
|
label: "Text color",
|
|
@@ -2273,7 +2864,7 @@ function DocumentToolbar(props) {
|
|
|
2273
2864
|
onReset: () => run()?.unsetColor().run()
|
|
2274
2865
|
}
|
|
2275
2866
|
),
|
|
2276
|
-
/* @__PURE__ */ (0,
|
|
2867
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2277
2868
|
ColorPicker,
|
|
2278
2869
|
{
|
|
2279
2870
|
label: "Highlight",
|
|
@@ -2287,34 +2878,34 @@ function DocumentToolbar(props) {
|
|
|
2287
2878
|
}
|
|
2288
2879
|
)
|
|
2289
2880
|
] }),
|
|
2290
|
-
/* @__PURE__ */ (0,
|
|
2291
|
-
editor ? /* @__PURE__ */ (0,
|
|
2881
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "Insert", children: [
|
|
2882
|
+
editor ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2292
2883
|
Dropdown,
|
|
2293
2884
|
{
|
|
2294
|
-
trigger: ({ open, toggle }) => /* @__PURE__ */ (0,
|
|
2295
|
-
children: (close) => /* @__PURE__ */ (0,
|
|
2885
|
+
trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Link", icon: "link", toggle: true, active: s?.link || open, disabled: off, onClick: toggle }),
|
|
2886
|
+
children: (close) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LinkPanel, { editor, href: s?.linkHref ?? "", isLink: !!s?.link, close })
|
|
2296
2887
|
}
|
|
2297
2888
|
) : null,
|
|
2298
|
-
editor ? /* @__PURE__ */ (0,
|
|
2299
|
-
editor ? /* @__PURE__ */ (0,
|
|
2889
|
+
editor ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Dropdown, { trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Insert image", icon: "image", active: open, disabled: off, onClick: toggle }), children: (close) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ImagePanel, { editor, close, onNotice }) }) : null,
|
|
2890
|
+
editor ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Dropdown, { trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Insert table", icon: "table", active: open, disabled: off, onClick: toggle }), children: (close) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TablePanel, { editor, close }) }) : null
|
|
2300
2891
|
] }),
|
|
2301
|
-
/* @__PURE__ */ (0,
|
|
2892
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Group, { label: "Actions", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Clear formatting", icon: "eraser", disabled: off, onClick: () => run()?.unsetAllMarks().clearNodes().run() }) })
|
|
2302
2893
|
] }) : null,
|
|
2303
|
-
s?.inTable ? /* @__PURE__ */ (0,
|
|
2304
|
-
/* @__PURE__ */ (0,
|
|
2305
|
-
/* @__PURE__ */ (0,
|
|
2306
|
-
/* @__PURE__ */ (0,
|
|
2307
|
-
/* @__PURE__ */ (0,
|
|
2308
|
-
/* @__PURE__ */ (0,
|
|
2309
|
-
/* @__PURE__ */ (0,
|
|
2310
|
-
/* @__PURE__ */ (0,
|
|
2311
|
-
/* @__PURE__ */ (0,
|
|
2894
|
+
s?.inTable ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "june-doc__row june-doc__row--context", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Group, { label: "Table", children: [
|
|
2895
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Add row below", disabled: off, onClick: () => run()?.addRowAfter().run(), children: "+ Row" }),
|
|
2896
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Add column right", disabled: off, onClick: () => run()?.addColumnAfter().run(), children: "+ Column" }),
|
|
2897
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Delete row", disabled: off, onClick: () => run()?.deleteRow().run(), children: "\u2212 Row" }),
|
|
2898
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Delete column", disabled: off, onClick: () => run()?.deleteColumn().run(), children: "\u2212 Column" }),
|
|
2899
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Merge cells", disabled: off || !s?.canMerge, onClick: () => run()?.mergeCells().run(), children: "Merge" }),
|
|
2900
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Split cell", disabled: off || !s?.canSplit, onClick: () => run()?.splitCell().run(), children: "Split" }),
|
|
2901
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Toggle header row", disabled: off, onClick: () => run()?.toggleHeaderRow().run(), children: "Header row" }),
|
|
2902
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Btn, { label: "Delete table", disabled: off, onClick: () => run()?.deleteTable().run(), className: "june-doc__btn--danger", children: "Delete table" })
|
|
2312
2903
|
] }) }) : null
|
|
2313
2904
|
] });
|
|
2314
2905
|
}
|
|
2315
2906
|
|
|
2316
2907
|
// src/components/document-editor/document-bubble.tsx
|
|
2317
|
-
var
|
|
2908
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2318
2909
|
function DocumentBubbleMenu({ editor }) {
|
|
2319
2910
|
const s = (0, import_react10.useEditorState)({
|
|
2320
2911
|
editor,
|
|
@@ -2330,7 +2921,7 @@ function DocumentBubbleMenu({ editor }) {
|
|
|
2330
2921
|
})
|
|
2331
2922
|
});
|
|
2332
2923
|
const run = () => editor.chain().focus();
|
|
2333
|
-
return /* @__PURE__ */ (0,
|
|
2924
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2334
2925
|
import_menus.BubbleMenu,
|
|
2335
2926
|
{
|
|
2336
2927
|
editor,
|
|
@@ -2343,13 +2934,13 @@ function DocumentBubbleMenu({ editor }) {
|
|
|
2343
2934
|
return state.doc.textBetween(state.selection.from, state.selection.to).trim().length > 0;
|
|
2344
2935
|
},
|
|
2345
2936
|
children: [
|
|
2346
|
-
/* @__PURE__ */ (0,
|
|
2347
|
-
/* @__PURE__ */ (0,
|
|
2348
|
-
/* @__PURE__ */ (0,
|
|
2349
|
-
/* @__PURE__ */ (0,
|
|
2350
|
-
/* @__PURE__ */ (0,
|
|
2351
|
-
/* @__PURE__ */ (0,
|
|
2352
|
-
/* @__PURE__ */ (0,
|
|
2937
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Btn, { label: "Bold", icon: "bold", toggle: true, active: s.bold, onClick: () => run().toggleBold().run() }),
|
|
2938
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Btn, { label: "Italic", icon: "italic", toggle: true, active: s.italic, onClick: () => run().toggleItalic().run() }),
|
|
2939
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Btn, { label: "Underline", icon: "underline", toggle: true, active: s.underline, onClick: () => run().toggleUnderline().run() }),
|
|
2940
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Btn, { label: "Strikethrough", icon: "strike", toggle: true, active: s.strike, onClick: () => run().toggleStrike().run() }),
|
|
2941
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "june-doc__bubble-sep", "aria-hidden": "true" }),
|
|
2942
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Dropdown, { trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Btn, { label: "Link", icon: "link", toggle: true, active: s.link || open, onClick: toggle }), children: (close) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(LinkPanel, { editor, href: s.linkHref, isLink: s.link, close }) }),
|
|
2943
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2353
2944
|
ColorPicker,
|
|
2354
2945
|
{
|
|
2355
2946
|
label: "Text color",
|
|
@@ -2361,7 +2952,7 @@ function DocumentBubbleMenu({ editor }) {
|
|
|
2361
2952
|
onReset: () => run().unsetColor().run()
|
|
2362
2953
|
}
|
|
2363
2954
|
),
|
|
2364
|
-
/* @__PURE__ */ (0,
|
|
2955
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2365
2956
|
ColorPicker,
|
|
2366
2957
|
{
|
|
2367
2958
|
label: "Highlight",
|
|
@@ -2373,8 +2964,8 @@ function DocumentBubbleMenu({ editor }) {
|
|
|
2373
2964
|
onReset: () => run().unsetHighlight().run()
|
|
2374
2965
|
}
|
|
2375
2966
|
),
|
|
2376
|
-
/* @__PURE__ */ (0,
|
|
2377
|
-
/* @__PURE__ */ (0,
|
|
2967
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "june-doc__bubble-sep", "aria-hidden": "true" }),
|
|
2968
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Btn, { label: "Clear formatting", icon: "eraser", onClick: () => run().unsetAllMarks().run() })
|
|
2378
2969
|
]
|
|
2379
2970
|
}
|
|
2380
2971
|
);
|
|
@@ -2383,60 +2974,117 @@ function DocumentBubbleMenu({ editor }) {
|
|
|
2383
2974
|
// src/components/document-editor/document-content.tsx
|
|
2384
2975
|
var import_react11 = require("@tiptap/react");
|
|
2385
2976
|
var import_react12 = require("react");
|
|
2386
|
-
|
|
2977
|
+
init_document_pagination();
|
|
2978
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2979
|
+
var PAGE_WIDTH = 794;
|
|
2387
2980
|
var PAGE_HEIGHT = 1123;
|
|
2388
|
-
var
|
|
2981
|
+
var PAGE_GAP = 28;
|
|
2982
|
+
var CANVAS_PAD_X = 24;
|
|
2983
|
+
var useIsoLayoutEffect = typeof window === "undefined" ? import_react12.useEffect : import_react12.useLayoutEffect;
|
|
2984
|
+
function geometry(width) {
|
|
2985
|
+
const ratio = width / PAGE_WIDTH;
|
|
2986
|
+
const height = Math.round(PAGE_HEIGHT * ratio);
|
|
2987
|
+
const padX = Math.round(Math.min(96, Math.max(20, width * 0.12)));
|
|
2988
|
+
const padY = Math.round(Math.min(96, Math.max(36, 96 * ratio)));
|
|
2989
|
+
return { width, height, padX, padY };
|
|
2990
|
+
}
|
|
2389
2991
|
function DocumentContent({ editor, layout = "page", zoom = 1, showMarks = false, onMetrics }) {
|
|
2390
2992
|
const canvas = (0, import_react12.useRef)(null);
|
|
2391
2993
|
const sheet = (0, import_react12.useRef)(null);
|
|
2994
|
+
const [avail, setAvail] = (0, import_react12.useState)(PAGE_WIDTH);
|
|
2995
|
+
const [sheetH, setSheetH] = (0, import_react12.useState)(0);
|
|
2392
2996
|
const [pages, setPages] = (0, import_react12.useState)(1);
|
|
2393
2997
|
const metricsRef = (0, import_react12.useRef)(onMetrics);
|
|
2394
2998
|
metricsRef.current = onMetrics;
|
|
2395
2999
|
const last = (0, import_react12.useRef)({ page: 0, pages: 0 });
|
|
3000
|
+
const paged = layout === "page";
|
|
3001
|
+
const width = paged ? Math.max(260, Math.min(PAGE_WIDTH, Math.floor(avail / zoom))) : Math.max(260, Math.floor(avail / zoom));
|
|
3002
|
+
const g = geometry(width);
|
|
3003
|
+
const stride = g.height + PAGE_GAP;
|
|
3004
|
+
useIsoLayoutEffect(() => {
|
|
3005
|
+
const c = canvas.current;
|
|
3006
|
+
if (!c) return;
|
|
3007
|
+
const read = () => {
|
|
3008
|
+
const cs = typeof getComputedStyle === "function" ? getComputedStyle(c) : null;
|
|
3009
|
+
const padX = cs ? (parseFloat(cs.paddingLeft) || 0) + (parseFloat(cs.paddingRight) || 0) : CANVAS_PAD_X * 2;
|
|
3010
|
+
const w = c.clientWidth - padX;
|
|
3011
|
+
if (w > 0) setAvail(w);
|
|
3012
|
+
};
|
|
3013
|
+
read();
|
|
3014
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
3015
|
+
const ro = new ResizeObserver(read);
|
|
3016
|
+
ro.observe(c);
|
|
3017
|
+
return () => ro.disconnect();
|
|
3018
|
+
}, []);
|
|
3019
|
+
(0, import_react12.useEffect)(() => {
|
|
3020
|
+
if (!editor) return;
|
|
3021
|
+
setPaginationConfig(editor, {
|
|
3022
|
+
enabled: paged,
|
|
3023
|
+
pageHeight: g.height,
|
|
3024
|
+
gap: PAGE_GAP,
|
|
3025
|
+
padTop: g.padY,
|
|
3026
|
+
padBottom: g.padY
|
|
3027
|
+
});
|
|
3028
|
+
}, [editor, paged, g.height, g.padY, width]);
|
|
2396
3029
|
(0, import_react12.useEffect)(() => {
|
|
2397
3030
|
const c = canvas.current;
|
|
2398
|
-
const
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
const
|
|
2402
|
-
const
|
|
2403
|
-
const total = layout === "page" ? Math.max(1, Math.ceil((contentH + PAGE_PAD_Y * 2) / PAGE_HEIGHT)) : 1;
|
|
2404
|
-
const cRect = c.getBoundingClientRect();
|
|
2405
|
-
const pRect = p.getBoundingClientRect();
|
|
2406
|
-
const y = cRect.top + c.clientHeight * 0.35 - pRect.top;
|
|
2407
|
-
const page = Math.min(total, Math.max(1, Math.floor(y / (PAGE_HEIGHT * zoom)) + 1));
|
|
3031
|
+
const s = sheet.current;
|
|
3032
|
+
if (!editor || !c || !s) return;
|
|
3033
|
+
const prose = editor.view.dom;
|
|
3034
|
+
const report = () => {
|
|
3035
|
+
const total = paged ? getPageCount(editor) : 1;
|
|
2408
3036
|
setPages(total);
|
|
3037
|
+
setSheetH(s.offsetHeight);
|
|
3038
|
+
const cRect = c.getBoundingClientRect();
|
|
3039
|
+
const sRect = s.getBoundingClientRect();
|
|
3040
|
+
const y = (cRect.top + c.clientHeight * 0.35 - sRect.top) / zoom;
|
|
3041
|
+
const page = paged ? Math.min(total, Math.max(1, Math.floor(y / stride) + 1)) : 1;
|
|
2409
3042
|
if (last.current.page !== page || last.current.pages !== total) {
|
|
2410
3043
|
last.current = { page, pages: total };
|
|
2411
3044
|
metricsRef.current?.({ page, pages: total });
|
|
2412
3045
|
}
|
|
2413
3046
|
};
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
3047
|
+
report();
|
|
3048
|
+
editor.on("transaction", report);
|
|
3049
|
+
c.addEventListener("scroll", report, { passive: true });
|
|
3050
|
+
const onLoad = () => remeasurePagination(editor);
|
|
3051
|
+
prose.addEventListener("load", onLoad, true);
|
|
3052
|
+
const ro = typeof ResizeObserver !== "undefined" ? new ResizeObserver(report) : null;
|
|
3053
|
+
ro?.observe(s);
|
|
2420
3054
|
return () => {
|
|
2421
|
-
|
|
3055
|
+
editor.off("transaction", report);
|
|
3056
|
+
c.removeEventListener("scroll", report);
|
|
3057
|
+
prose.removeEventListener("load", onLoad, true);
|
|
2422
3058
|
ro?.disconnect();
|
|
2423
|
-
editor?.off("update", measure);
|
|
2424
3059
|
};
|
|
2425
|
-
}, [editor,
|
|
2426
|
-
const
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
3060
|
+
}, [editor, paged, zoom, stride]);
|
|
3061
|
+
const minHeight = paged ? pages * g.height + (pages - 1) * PAGE_GAP : void 0;
|
|
3062
|
+
const sheetStyle = {
|
|
3063
|
+
width,
|
|
3064
|
+
minHeight,
|
|
3065
|
+
transform: zoom === 1 ? void 0 : `scale(${zoom})`,
|
|
3066
|
+
"--jd-pad-x": `${g.padX}px`,
|
|
3067
|
+
"--jd-pad-y": `${g.padY}px`
|
|
3068
|
+
};
|
|
3069
|
+
const zoomerStyle = {
|
|
3070
|
+
width: width * zoom,
|
|
3071
|
+
height: zoom === 1 ? void 0 : Math.max(sheetH, minHeight ?? 0) * zoom
|
|
3072
|
+
};
|
|
3073
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { ref: canvas, className: "june-doc__content june-doc__canvas", "data-layout": layout, "data-marks": showMarks || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "june-doc__zoomer", style: zoomerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { ref: sheet, className: "june-doc__sheet", style: sheetStyle, children: [
|
|
3074
|
+
paged ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "june-doc__pages", "aria-hidden": "true", children: Array.from({ length: pages }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "june-doc__page", style: { top: i * stride, height: g.height }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "june-doc__page-num", children: [
|
|
3075
|
+
i + 1,
|
|
3076
|
+
" / ",
|
|
3077
|
+
pages
|
|
3078
|
+
] }) }, i)) }) : null,
|
|
3079
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react11.EditorContent, { editor })
|
|
3080
|
+
] }) }) });
|
|
2433
3081
|
}
|
|
2434
3082
|
|
|
2435
3083
|
// src/components/document-editor/document-findbar.tsx
|
|
2436
3084
|
var import_react13 = require("@tiptap/react");
|
|
2437
3085
|
var import_react14 = require("react");
|
|
2438
3086
|
init_document_search();
|
|
2439
|
-
var
|
|
3087
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2440
3088
|
function DocumentFindBar({ editor, editable, onClose, onNotice }) {
|
|
2441
3089
|
const [term, setTerm] = (0, import_react14.useState)(() => {
|
|
2442
3090
|
const { from, to, empty } = editor.state.selection;
|
|
@@ -2464,7 +3112,7 @@ function DocumentFindBar({ editor, editable, onClose, onNotice }) {
|
|
|
2464
3112
|
}, [editor]);
|
|
2465
3113
|
const count = info?.count ?? 0;
|
|
2466
3114
|
const current = info?.current ?? -1;
|
|
2467
|
-
return /* @__PURE__ */ (0,
|
|
3115
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2468
3116
|
"div",
|
|
2469
3117
|
{
|
|
2470
3118
|
className: "june-doc__findbar",
|
|
@@ -2477,9 +3125,9 @@ function DocumentFindBar({ editor, editable, onClose, onNotice }) {
|
|
|
2477
3125
|
}
|
|
2478
3126
|
},
|
|
2479
3127
|
children: [
|
|
2480
|
-
/* @__PURE__ */ (0,
|
|
2481
|
-
/* @__PURE__ */ (0,
|
|
2482
|
-
/* @__PURE__ */ (0,
|
|
3128
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "june-doc__find-field", children: [
|
|
3129
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { name: "search", size: 14 }),
|
|
3130
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2483
3131
|
"input",
|
|
2484
3132
|
{
|
|
2485
3133
|
ref: input,
|
|
@@ -2496,11 +3144,11 @@ function DocumentFindBar({ editor, editable, onClose, onNotice }) {
|
|
|
2496
3144
|
}
|
|
2497
3145
|
}
|
|
2498
3146
|
),
|
|
2499
|
-
/* @__PURE__ */ (0,
|
|
3147
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "june-doc__find-count", "aria-live": "polite", children: term ? count ? `${current + 1} of ${count}` : "No results" : "" })
|
|
2500
3148
|
] }),
|
|
2501
|
-
/* @__PURE__ */ (0,
|
|
2502
|
-
/* @__PURE__ */ (0,
|
|
2503
|
-
/* @__PURE__ */ (0,
|
|
3149
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon", "aria-label": "Previous match", title: "Previous (Shift+Enter)", disabled: !count, onClick: () => gotoMatch(editor, -1), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { name: "chevronUp" }) }),
|
|
3150
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon", "aria-label": "Next match", title: "Next (Enter)", disabled: !count, onClick: () => gotoMatch(editor, 1), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { name: "chevronDown" }) }),
|
|
3151
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2504
3152
|
"button",
|
|
2505
3153
|
{
|
|
2506
3154
|
type: "button",
|
|
@@ -2513,9 +3161,9 @@ function DocumentFindBar({ editor, editable, onClose, onNotice }) {
|
|
|
2513
3161
|
children: "Aa"
|
|
2514
3162
|
}
|
|
2515
3163
|
),
|
|
2516
|
-
editable ? /* @__PURE__ */ (0,
|
|
2517
|
-
/* @__PURE__ */ (0,
|
|
2518
|
-
/* @__PURE__ */ (0,
|
|
3164
|
+
editable ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
3165
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "june-doc__find-sep", "aria-hidden": "true" }),
|
|
3166
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2519
3167
|
"input",
|
|
2520
3168
|
{
|
|
2521
3169
|
className: "june-doc__input june-doc__replace-input",
|
|
@@ -2531,8 +3179,8 @@ function DocumentFindBar({ editor, editable, onClose, onNotice }) {
|
|
|
2531
3179
|
}
|
|
2532
3180
|
}
|
|
2533
3181
|
),
|
|
2534
|
-
/* @__PURE__ */ (0,
|
|
2535
|
-
/* @__PURE__ */ (0,
|
|
3182
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "june-doc__btn", disabled: !count, onClick: () => replaceCurrent(editor, replacement), children: "Replace" }),
|
|
3183
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2536
3184
|
"button",
|
|
2537
3185
|
{
|
|
2538
3186
|
type: "button",
|
|
@@ -2546,16 +3194,16 @@ function DocumentFindBar({ editor, editable, onClose, onNotice }) {
|
|
|
2546
3194
|
}
|
|
2547
3195
|
)
|
|
2548
3196
|
] }) : null,
|
|
2549
|
-
/* @__PURE__ */ (0,
|
|
3197
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon june-doc__btn--ghost june-doc__find-close", "aria-label": "Close find", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { name: "close" }) })
|
|
2550
3198
|
]
|
|
2551
3199
|
}
|
|
2552
3200
|
);
|
|
2553
3201
|
}
|
|
2554
3202
|
|
|
2555
3203
|
// src/components/document-editor/document-title.tsx
|
|
2556
|
-
var
|
|
3204
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2557
3205
|
function DocumentTitle({ value, disabled, onChange }) {
|
|
2558
|
-
return /* @__PURE__ */ (0,
|
|
3206
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2559
3207
|
"input",
|
|
2560
3208
|
{
|
|
2561
3209
|
className: "june-doc__title",
|
|
@@ -2569,7 +3217,7 @@ function DocumentTitle({ value, disabled, onChange }) {
|
|
|
2569
3217
|
}
|
|
2570
3218
|
|
|
2571
3219
|
// src/components/document-editor/document-header.tsx
|
|
2572
|
-
var
|
|
3220
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2573
3221
|
var FORMATS = {
|
|
2574
3222
|
docx: { label: "Word document", hint: ".docx", icon: "file" },
|
|
2575
3223
|
pdf: { label: "PDF", hint: "Print / Save as PDF", icon: "file" },
|
|
@@ -2578,36 +3226,37 @@ var FORMATS = {
|
|
|
2578
3226
|
txt: { label: "Plain text", hint: ".txt", icon: "file" }
|
|
2579
3227
|
};
|
|
2580
3228
|
function DocumentHeader(props) {
|
|
2581
|
-
const { title, editable, isDraft, fullscreen, onToggleFullscreen, onTitle, exportFormats, canSave, saveState, onExport, onCopy, onSave } = props;
|
|
2582
|
-
return /* @__PURE__ */ (0,
|
|
2583
|
-
fullscreen ? /* @__PURE__ */ (0,
|
|
2584
|
-
/* @__PURE__ */ (0,
|
|
2585
|
-
isDraft ? /* @__PURE__ */ (0,
|
|
2586
|
-
/* @__PURE__ */ (0,
|
|
3229
|
+
const { title, editable, isDraft, fullscreen, onToggleFullscreen, onTitle, exportFormats, canSave, showSave = canSave, saveState, onExport, onCopy, onSave } = props;
|
|
3230
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "june-doc__header", children: [
|
|
3231
|
+
fullscreen ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon june-doc__btn--ghost", "aria-label": "Close full screen", title: "Close (Esc)", onClick: onToggleFullscreen, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: "close", size: 18 }) }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "june-doc__doc-icon", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: "file", size: 16 }) }),
|
|
3232
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DocumentTitle, { value: title, disabled: !editable, onChange: onTitle }),
|
|
3233
|
+
isDraft ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "june-doc__badge", children: [
|
|
3234
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: "sparkles", size: 12 }),
|
|
2587
3235
|
"AI draft"
|
|
2588
3236
|
] }) : null,
|
|
2589
|
-
/* @__PURE__ */ (0,
|
|
2590
|
-
|
|
3237
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "june-doc__header-actions", children: [
|
|
3238
|
+
showSave ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2591
3239
|
"button",
|
|
2592
3240
|
{
|
|
2593
3241
|
type: "button",
|
|
2594
|
-
className: "june-doc__btn june-doc__btn--outline",
|
|
3242
|
+
className: "june-doc__btn june-doc__btn--outline june-doc__save",
|
|
3243
|
+
"data-state": saveState,
|
|
2595
3244
|
"aria-label": "Save",
|
|
2596
3245
|
title: "Save (Ctrl+S)",
|
|
2597
3246
|
disabled: saveState === "saving" || saveState === "saved" || saveState === "idle",
|
|
2598
3247
|
onClick: onSave,
|
|
2599
3248
|
children: [
|
|
2600
|
-
/* @__PURE__ */ (0,
|
|
2601
|
-
/* @__PURE__ */ (0,
|
|
3249
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: saveState === "saved" ? "check" : "save" }),
|
|
3250
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: saveState === "saving" ? "Saving\u2026" : saveState === "saved" ? "Saved" : "Save" })
|
|
2602
3251
|
]
|
|
2603
3252
|
}
|
|
2604
3253
|
) : null,
|
|
2605
|
-
/* @__PURE__ */ (0,
|
|
3254
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2606
3255
|
Dropdown,
|
|
2607
3256
|
{
|
|
2608
3257
|
align: "end",
|
|
2609
3258
|
className: "june-doc__menu",
|
|
2610
|
-
trigger: ({ open, toggle }) => /* @__PURE__ */ (0,
|
|
3259
|
+
trigger: ({ open, toggle }) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2611
3260
|
"button",
|
|
2612
3261
|
{
|
|
2613
3262
|
type: "button",
|
|
@@ -2617,15 +3266,15 @@ function DocumentHeader(props) {
|
|
|
2617
3266
|
"aria-expanded": open,
|
|
2618
3267
|
onClick: toggle,
|
|
2619
3268
|
children: [
|
|
2620
|
-
/* @__PURE__ */ (0,
|
|
2621
|
-
/* @__PURE__ */ (0,
|
|
3269
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Download" }),
|
|
3270
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: "chevronDown", size: 14 })
|
|
2622
3271
|
]
|
|
2623
3272
|
}
|
|
2624
3273
|
),
|
|
2625
|
-
children: (close) => /* @__PURE__ */ (0,
|
|
3274
|
+
children: (close) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { role: "menu", "aria-label": "Download options", children: [
|
|
2626
3275
|
exportFormats.map((f) => {
|
|
2627
3276
|
const meta = FORMATS[f] ?? { label: f.toUpperCase(), hint: "", icon: "file" };
|
|
2628
|
-
return /* @__PURE__ */ (0,
|
|
3277
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2629
3278
|
"button",
|
|
2630
3279
|
{
|
|
2631
3280
|
type: "button",
|
|
@@ -2636,16 +3285,16 @@ function DocumentHeader(props) {
|
|
|
2636
3285
|
onExport(f);
|
|
2637
3286
|
},
|
|
2638
3287
|
children: [
|
|
2639
|
-
/* @__PURE__ */ (0,
|
|
2640
|
-
/* @__PURE__ */ (0,
|
|
2641
|
-
/* @__PURE__ */ (0,
|
|
3288
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: meta.icon }),
|
|
3289
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "june-doc__menu-label", children: meta.label }),
|
|
3290
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "june-doc__menu-hint", children: meta.hint })
|
|
2642
3291
|
]
|
|
2643
3292
|
},
|
|
2644
3293
|
f
|
|
2645
3294
|
);
|
|
2646
3295
|
}),
|
|
2647
|
-
exportFormats.length ? /* @__PURE__ */ (0,
|
|
2648
|
-
/* @__PURE__ */ (0,
|
|
3296
|
+
exportFormats.length ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "june-doc__menu-sep", role: "separator" }) : null,
|
|
3297
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2649
3298
|
"button",
|
|
2650
3299
|
{
|
|
2651
3300
|
type: "button",
|
|
@@ -2657,15 +3306,15 @@ function DocumentHeader(props) {
|
|
|
2657
3306
|
onCopy();
|
|
2658
3307
|
},
|
|
2659
3308
|
children: [
|
|
2660
|
-
/* @__PURE__ */ (0,
|
|
2661
|
-
/* @__PURE__ */ (0,
|
|
3309
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: "copy" }),
|
|
3310
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "june-doc__menu-label", children: "Copy to clipboard" })
|
|
2662
3311
|
]
|
|
2663
3312
|
}
|
|
2664
3313
|
)
|
|
2665
3314
|
] })
|
|
2666
3315
|
}
|
|
2667
3316
|
),
|
|
2668
|
-
/* @__PURE__ */ (0,
|
|
3317
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2669
3318
|
"button",
|
|
2670
3319
|
{
|
|
2671
3320
|
type: "button",
|
|
@@ -2674,7 +3323,7 @@ function DocumentHeader(props) {
|
|
|
2674
3323
|
title: fullscreen ? "Exit full screen" : "Open full screen",
|
|
2675
3324
|
"aria-pressed": fullscreen,
|
|
2676
3325
|
onClick: onToggleFullscreen,
|
|
2677
|
-
children: /* @__PURE__ */ (0,
|
|
3326
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { name: "maximize" })
|
|
2678
3327
|
}
|
|
2679
3328
|
)
|
|
2680
3329
|
] })
|
|
@@ -3105,223 +3754,6 @@ ${docToText2(doc.json)}`;
|
|
|
3105
3754
|
// src/components/document-editor/document-editor.tsx
|
|
3106
3755
|
init_document_extensions();
|
|
3107
3756
|
|
|
3108
|
-
// src/components/document-editor/document-merge.ts
|
|
3109
|
-
init_document_utils();
|
|
3110
|
-
var MAX_CELLS = 4e6;
|
|
3111
|
-
function matchIndices(a, b) {
|
|
3112
|
-
const n = a.length;
|
|
3113
|
-
const m = b.length;
|
|
3114
|
-
if (n * m > MAX_CELLS) return null;
|
|
3115
|
-
const dp = Array.from({ length: n + 1 }, () => new Uint32Array(m + 1));
|
|
3116
|
-
for (let i2 = n - 1; i2 >= 0; i2--) {
|
|
3117
|
-
for (let j2 = m - 1; j2 >= 0; j2--) {
|
|
3118
|
-
dp[i2][j2] = a[i2] === b[j2] ? dp[i2 + 1][j2 + 1] + 1 : Math.max(dp[i2 + 1][j2], dp[i2][j2 + 1]);
|
|
3119
|
-
}
|
|
3120
|
-
}
|
|
3121
|
-
const matches = /* @__PURE__ */ new Map();
|
|
3122
|
-
let i = 0;
|
|
3123
|
-
let j = 0;
|
|
3124
|
-
while (i < n && j < m) {
|
|
3125
|
-
if (a[i] === b[j]) {
|
|
3126
|
-
matches.set(i, j);
|
|
3127
|
-
i++;
|
|
3128
|
-
j++;
|
|
3129
|
-
} else if (dp[i + 1][j] >= dp[i][j + 1]) i++;
|
|
3130
|
-
else j++;
|
|
3131
|
-
}
|
|
3132
|
-
return matches;
|
|
3133
|
-
}
|
|
3134
|
-
var same = (x, y) => x.length === y.length && x.every((v, i) => v === y[i]);
|
|
3135
|
-
function mergeBlocks(base, local, incoming) {
|
|
3136
|
-
if (same(local, base)) return { blocks: incoming, conflicts: 0 };
|
|
3137
|
-
if (same(incoming, base) || same(local, incoming)) return { blocks: local, conflicts: 0 };
|
|
3138
|
-
const ml = matchIndices(base, local);
|
|
3139
|
-
const mn = matchIndices(base, incoming);
|
|
3140
|
-
if (!ml || !mn) return { blocks: null, conflicts: 1 };
|
|
3141
|
-
const anchors = [...ml.keys()].filter((i) => mn.has(i)).sort((x, y) => x - y);
|
|
3142
|
-
const out = [];
|
|
3143
|
-
let conflicts = 0;
|
|
3144
|
-
let pb = -1;
|
|
3145
|
-
let pl = -1;
|
|
3146
|
-
let pn = -1;
|
|
3147
|
-
const region = (bEnd, lEnd, nEnd) => {
|
|
3148
|
-
const B = base.slice(pb + 1, bEnd);
|
|
3149
|
-
const L = local.slice(pl + 1, lEnd);
|
|
3150
|
-
const N = incoming.slice(pn + 1, nEnd);
|
|
3151
|
-
if (B.length === L.length && L.length === N.length) {
|
|
3152
|
-
for (let k = 0; k < B.length; k++) {
|
|
3153
|
-
if (L[k] === B[k]) out.push(N[k]);
|
|
3154
|
-
else if (N[k] === B[k] || N[k] === L[k]) out.push(L[k]);
|
|
3155
|
-
else {
|
|
3156
|
-
conflicts++;
|
|
3157
|
-
out.push(L[k]);
|
|
3158
|
-
}
|
|
3159
|
-
}
|
|
3160
|
-
return;
|
|
3161
|
-
}
|
|
3162
|
-
if (same(L, B)) out.push(...N);
|
|
3163
|
-
else if (same(N, B) || same(L, N)) out.push(...L);
|
|
3164
|
-
else {
|
|
3165
|
-
conflicts++;
|
|
3166
|
-
out.push(...L);
|
|
3167
|
-
}
|
|
3168
|
-
};
|
|
3169
|
-
for (const a of anchors) {
|
|
3170
|
-
const la = ml.get(a);
|
|
3171
|
-
const na = mn.get(a);
|
|
3172
|
-
region(a, la, na);
|
|
3173
|
-
out.push(local[la]);
|
|
3174
|
-
pb = a;
|
|
3175
|
-
pl = la;
|
|
3176
|
-
pn = na;
|
|
3177
|
-
}
|
|
3178
|
-
region(base.length, local.length, incoming.length);
|
|
3179
|
-
return { blocks: out, conflicts };
|
|
3180
|
-
}
|
|
3181
|
-
function mergeDocuments(base, local, incoming) {
|
|
3182
|
-
const toBlocks = (d) => (d.content ?? []).map((node) => JSON.stringify(node));
|
|
3183
|
-
const { blocks: blocks2, conflicts } = mergeBlocks(toBlocks(base), toBlocks(local), toBlocks(incoming));
|
|
3184
|
-
if (!blocks2) return { doc: local, conflicts: Math.max(1, conflicts) };
|
|
3185
|
-
if (blocks2.length === 0) return { doc: emptyDoc(), conflicts };
|
|
3186
|
-
return { doc: { type: "doc", content: blocks2.map((b) => JSON.parse(b)) }, conflicts };
|
|
3187
|
-
}
|
|
3188
|
-
|
|
3189
|
-
// src/components/document-editor/document-store.ts
|
|
3190
|
-
init_document_utils();
|
|
3191
|
-
var incomingKey = (doc) => JSON.stringify([doc.title, docKey(doc.json)]);
|
|
3192
|
-
function createDocumentStore() {
|
|
3193
|
-
const records = /* @__PURE__ */ new Map();
|
|
3194
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
3195
|
-
const emit = () => listeners.forEach((listener) => listener());
|
|
3196
|
-
const put = (record) => {
|
|
3197
|
-
records.set(record.id, record);
|
|
3198
|
-
emit();
|
|
3199
|
-
};
|
|
3200
|
-
const fresh2 = (doc) => ({
|
|
3201
|
-
id: doc.id,
|
|
3202
|
-
title: doc.title,
|
|
3203
|
-
documentType: doc.documentType,
|
|
3204
|
-
status: doc.status,
|
|
3205
|
-
json: doc.json,
|
|
3206
|
-
baseJson: doc.json,
|
|
3207
|
-
baseTitle: doc.title,
|
|
3208
|
-
lastIncomingKey: incomingKey(doc),
|
|
3209
|
-
revision: 0,
|
|
3210
|
-
origin: "external",
|
|
3211
|
-
pending: null,
|
|
3212
|
-
updatedAt: Date.now()
|
|
3213
|
-
});
|
|
3214
|
-
return {
|
|
3215
|
-
get: (id) => records.get(id),
|
|
3216
|
-
list: () => [...records.values()],
|
|
3217
|
-
subscribe: (listener) => {
|
|
3218
|
-
listeners.add(listener);
|
|
3219
|
-
return () => {
|
|
3220
|
-
listeners.delete(listener);
|
|
3221
|
-
};
|
|
3222
|
-
},
|
|
3223
|
-
receive(incoming) {
|
|
3224
|
-
const current = records.get(incoming.id);
|
|
3225
|
-
if (!current) {
|
|
3226
|
-
put(fresh2(incoming));
|
|
3227
|
-
return "created";
|
|
3228
|
-
}
|
|
3229
|
-
const key = incomingKey(incoming);
|
|
3230
|
-
if (current.lastIncomingKey === key) return "unchanged";
|
|
3231
|
-
const userEditedBody = docKey(current.json) !== docKey(current.baseJson);
|
|
3232
|
-
const userEditedTitle = current.title !== current.baseTitle;
|
|
3233
|
-
const title = userEditedTitle ? current.title : incoming.title;
|
|
3234
|
-
const meta = {
|
|
3235
|
-
documentType: incoming.documentType ?? current.documentType,
|
|
3236
|
-
status: incoming.status ?? current.status
|
|
3237
|
-
};
|
|
3238
|
-
if (!userEditedBody) {
|
|
3239
|
-
put({
|
|
3240
|
-
...current,
|
|
3241
|
-
...meta,
|
|
3242
|
-
title,
|
|
3243
|
-
baseTitle: incoming.title,
|
|
3244
|
-
json: incoming.json,
|
|
3245
|
-
baseJson: incoming.json,
|
|
3246
|
-
lastIncomingKey: key,
|
|
3247
|
-
revision: current.revision + 1,
|
|
3248
|
-
origin: "external",
|
|
3249
|
-
pending: null,
|
|
3250
|
-
updatedAt: Date.now()
|
|
3251
|
-
});
|
|
3252
|
-
return "applied";
|
|
3253
|
-
}
|
|
3254
|
-
const { doc, conflicts } = mergeDocuments(current.baseJson, current.json, incoming.json);
|
|
3255
|
-
if (conflicts === 0) {
|
|
3256
|
-
put({
|
|
3257
|
-
...current,
|
|
3258
|
-
...meta,
|
|
3259
|
-
title,
|
|
3260
|
-
baseTitle: incoming.title,
|
|
3261
|
-
json: doc,
|
|
3262
|
-
baseJson: incoming.json,
|
|
3263
|
-
lastIncomingKey: key,
|
|
3264
|
-
revision: current.revision + 1,
|
|
3265
|
-
origin: "external",
|
|
3266
|
-
pending: null,
|
|
3267
|
-
updatedAt: Date.now()
|
|
3268
|
-
});
|
|
3269
|
-
return "merged";
|
|
3270
|
-
}
|
|
3271
|
-
put({
|
|
3272
|
-
...current,
|
|
3273
|
-
...meta,
|
|
3274
|
-
lastIncomingKey: key,
|
|
3275
|
-
pending: { json: incoming.json, title: incoming.title, merged: doc, conflicts }
|
|
3276
|
-
});
|
|
3277
|
-
return "conflict";
|
|
3278
|
-
},
|
|
3279
|
-
hydrate(doc) {
|
|
3280
|
-
put(fresh2(doc));
|
|
3281
|
-
},
|
|
3282
|
-
edit(id, json, origin) {
|
|
3283
|
-
const current = records.get(id);
|
|
3284
|
-
if (!current || docKey(current.json) === docKey(json)) return;
|
|
3285
|
-
put({ ...current, json, origin, revision: current.revision + 1, updatedAt: Date.now() });
|
|
3286
|
-
},
|
|
3287
|
-
setTitle(id, title) {
|
|
3288
|
-
const current = records.get(id);
|
|
3289
|
-
if (!current || current.title === title) return;
|
|
3290
|
-
put({ ...current, title, updatedAt: Date.now() });
|
|
3291
|
-
},
|
|
3292
|
-
resolve(id, choice) {
|
|
3293
|
-
const current = records.get(id);
|
|
3294
|
-
const pending = current?.pending;
|
|
3295
|
-
if (!current || !pending) return;
|
|
3296
|
-
if (choice === "keep") {
|
|
3297
|
-
put({ ...current, baseJson: pending.json, baseTitle: pending.title, pending: null });
|
|
3298
|
-
return;
|
|
3299
|
-
}
|
|
3300
|
-
const json = choice === "merge" ? pending.merged : pending.json;
|
|
3301
|
-
const title = choice === "merge" ? current.title : pending.title;
|
|
3302
|
-
put({
|
|
3303
|
-
...current,
|
|
3304
|
-
title,
|
|
3305
|
-
json,
|
|
3306
|
-
baseJson: pending.json,
|
|
3307
|
-
baseTitle: pending.title,
|
|
3308
|
-
revision: current.revision + 1,
|
|
3309
|
-
origin: "external",
|
|
3310
|
-
pending: null,
|
|
3311
|
-
updatedAt: Date.now()
|
|
3312
|
-
});
|
|
3313
|
-
},
|
|
3314
|
-
remove(id) {
|
|
3315
|
-
if (records.delete(id)) emit();
|
|
3316
|
-
}
|
|
3317
|
-
};
|
|
3318
|
-
}
|
|
3319
|
-
var defaultStore = null;
|
|
3320
|
-
function getDefaultDocumentStore() {
|
|
3321
|
-
if (!defaultStore) defaultStore = createDocumentStore();
|
|
3322
|
-
return defaultStore;
|
|
3323
|
-
}
|
|
3324
|
-
|
|
3325
3757
|
// src/components/document-editor/document-types.ts
|
|
3326
3758
|
var ALL_EXPORT_FORMATS = [
|
|
3327
3759
|
"html",
|
|
@@ -3333,7 +3765,7 @@ var ALL_EXPORT_FORMATS = [
|
|
|
3333
3765
|
|
|
3334
3766
|
// src/components/document-editor/document-editor.tsx
|
|
3335
3767
|
init_document_utils();
|
|
3336
|
-
var
|
|
3768
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
3337
3769
|
var snapshotOf = (r) => ({
|
|
3338
3770
|
documentId: r.id,
|
|
3339
3771
|
title: r.title,
|
|
@@ -3431,8 +3863,13 @@ function DocumentEditorImpl(props) {
|
|
|
3431
3863
|
saveRef.current = async () => {
|
|
3432
3864
|
const record = store.get(documentId);
|
|
3433
3865
|
const onSave = optionsRef.current.onSave;
|
|
3434
|
-
if (!record
|
|
3866
|
+
if (!record) return;
|
|
3435
3867
|
const key = JSON.stringify([record.title, docKey(record.json)]);
|
|
3868
|
+
if (!onSave) {
|
|
3869
|
+
lastSavedKey.current = key;
|
|
3870
|
+
setSaveState("saved");
|
|
3871
|
+
return;
|
|
3872
|
+
}
|
|
3436
3873
|
if (key === lastSavedKey.current) {
|
|
3437
3874
|
setSaveState("saved");
|
|
3438
3875
|
return;
|
|
@@ -3453,11 +3890,22 @@ function DocumentEditorImpl(props) {
|
|
|
3453
3890
|
optionsRef.current.onError?.(toJuneError(error, "DOCUMENT_ERROR", "Saving the document failed"));
|
|
3454
3891
|
}
|
|
3455
3892
|
};
|
|
3456
|
-
const markDirty = (0, import_react16.useCallback)(
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3893
|
+
const markDirty = (0, import_react16.useCallback)(
|
|
3894
|
+
(userEdit = true) => {
|
|
3895
|
+
if (!optionsRef.current.onSave) {
|
|
3896
|
+
if (userEdit) setSaveState("dirty");
|
|
3897
|
+
return;
|
|
3898
|
+
}
|
|
3899
|
+
setSaveState("dirty");
|
|
3900
|
+
autosave?.();
|
|
3901
|
+
},
|
|
3902
|
+
[autosave]
|
|
3903
|
+
);
|
|
3904
|
+
(0, import_react16.useEffect)(() => {
|
|
3905
|
+
if (saveState !== "saved" || options.onSave) return;
|
|
3906
|
+
const t = setTimeout(() => setSaveState((s) => s === "saved" ? "idle" : s), 2500);
|
|
3907
|
+
return () => clearTimeout(t);
|
|
3908
|
+
}, [saveState, options.onSave]);
|
|
3461
3909
|
const [initialJson] = (0, import_react16.useState)(() => store.get(documentId)?.json ?? parsed.json ?? emptyDoc());
|
|
3462
3910
|
const extensions = (0, import_react16.useMemo)(() => createDocumentExtensions(), []);
|
|
3463
3911
|
const onUpdateRef = (0, import_react16.useRef)(() => {
|
|
@@ -3483,10 +3931,12 @@ function DocumentEditorImpl(props) {
|
|
|
3483
3931
|
onUpdate: ({ editor: ed }) => onUpdateRef.current(ed.getJSON())
|
|
3484
3932
|
});
|
|
3485
3933
|
(0, import_react16.useEffect)(() => {
|
|
3486
|
-
editor
|
|
3934
|
+
if (!editor || editor.isEditable === editable) return;
|
|
3935
|
+
editor.setEditable(editable);
|
|
3487
3936
|
}, [editor, editable]);
|
|
3488
3937
|
(0, import_react16.useEffect)(() => {
|
|
3489
3938
|
if (!parsed.json) return;
|
|
3939
|
+
if (isDocumentEcho(store, documentId, contentKey)) return;
|
|
3490
3940
|
const outcome = store.receive({
|
|
3491
3941
|
id: documentId,
|
|
3492
3942
|
title: titleProp,
|
|
@@ -3496,7 +3946,7 @@ function DocumentEditorImpl(props) {
|
|
|
3496
3946
|
});
|
|
3497
3947
|
if (outcome === "applied" || outcome === "merged") {
|
|
3498
3948
|
emitChange(outcome === "applied" ? "ai" : "merge");
|
|
3499
|
-
markDirty();
|
|
3949
|
+
markDirty(false);
|
|
3500
3950
|
} else if (outcome === "conflict") {
|
|
3501
3951
|
const record = store.get(documentId);
|
|
3502
3952
|
optionsRef.current.onConflict?.({
|
|
@@ -3567,18 +4017,18 @@ function DocumentEditorImpl(props) {
|
|
|
3567
4017
|
};
|
|
3568
4018
|
const formats = (exportFormats ?? [...ALL_EXPORT_FORMATS]).filter((f) => listDocumentExporters().includes(f));
|
|
3569
4019
|
if (parsed.error && !store.get(documentId)) {
|
|
3570
|
-
return /* @__PURE__ */ (0,
|
|
3571
|
-
/* @__PURE__ */ (0,
|
|
3572
|
-
/* @__PURE__ */ (0,
|
|
3573
|
-
/* @__PURE__ */ (0,
|
|
3574
|
-
/* @__PURE__ */ (0,
|
|
4020
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "june-doc june-doc--error", "data-theme": resolvedTheme, role: "alert", children: [
|
|
4021
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "june-doc__draft-text", children: "This document could not be displayed." }),
|
|
4022
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("details", { children: [
|
|
4023
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("summary", { children: "Show raw content" }),
|
|
4024
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("pre", { className: "june-doc__raw", children: contentKey })
|
|
3575
4025
|
] })
|
|
3576
4026
|
] });
|
|
3577
4027
|
}
|
|
3578
|
-
if (!editor) return /* @__PURE__ */ (0,
|
|
4028
|
+
if (!editor) return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DocumentDraft, { title, state: "loading" });
|
|
3579
4029
|
const isDraft = recordStatus === "draft";
|
|
3580
4030
|
const classes = ["june-doc", fullscreen ? "june-doc--fullscreen" : "", className ?? ""].filter(Boolean).join(" ");
|
|
3581
|
-
return /* @__PURE__ */ (0,
|
|
4031
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3582
4032
|
"div",
|
|
3583
4033
|
{
|
|
3584
4034
|
className: classes,
|
|
@@ -3600,7 +4050,7 @@ function DocumentEditorImpl(props) {
|
|
|
3600
4050
|
}
|
|
3601
4051
|
},
|
|
3602
4052
|
children: [
|
|
3603
|
-
/* @__PURE__ */ (0,
|
|
4053
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3604
4054
|
DocumentHeader,
|
|
3605
4055
|
{
|
|
3606
4056
|
title,
|
|
@@ -3611,27 +4061,28 @@ function DocumentEditorImpl(props) {
|
|
|
3611
4061
|
onTitle: handleTitle,
|
|
3612
4062
|
exportFormats: formats,
|
|
3613
4063
|
canSave: !!options.onSave,
|
|
4064
|
+
showSave: !!options.onSave || editable && saveState !== "idle",
|
|
3614
4065
|
saveState,
|
|
3615
4066
|
onExport: (f) => void handleExport(f),
|
|
3616
4067
|
onCopy: () => void handleCopy(),
|
|
3617
4068
|
onSave: () => void saveRef.current()
|
|
3618
4069
|
}
|
|
3619
4070
|
),
|
|
3620
|
-
pending ? /* @__PURE__ */ (0,
|
|
3621
|
-
/* @__PURE__ */ (0,
|
|
4071
|
+
pending ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "june-doc__banner", role: "status", children: [
|
|
4072
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { children: [
|
|
3622
4073
|
"The assistant suggested changes that overlap your edits (",
|
|
3623
4074
|
pending.conflicts,
|
|
3624
4075
|
" ",
|
|
3625
4076
|
pending.conflicts === 1 ? "section" : "sections",
|
|
3626
4077
|
")."
|
|
3627
4078
|
] }),
|
|
3628
|
-
/* @__PURE__ */ (0,
|
|
3629
|
-
/* @__PURE__ */ (0,
|
|
3630
|
-
/* @__PURE__ */ (0,
|
|
3631
|
-
/* @__PURE__ */ (0,
|
|
4079
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "june-doc__banner-actions", children: [
|
|
4080
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "june-doc__btn", onClick: () => resolve("merge"), children: "Merge, keep my edits" }),
|
|
4081
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "june-doc__btn", onClick: () => resolve("replace"), children: "Use AI version" }),
|
|
4082
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "june-doc__btn", onClick: () => resolve("keep"), children: "Keep mine" })
|
|
3632
4083
|
] })
|
|
3633
4084
|
] }) : null,
|
|
3634
|
-
/* @__PURE__ */ (0,
|
|
4085
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3635
4086
|
DocumentToolbar,
|
|
3636
4087
|
{
|
|
3637
4088
|
editor,
|
|
@@ -3647,33 +4098,33 @@ function DocumentEditorImpl(props) {
|
|
|
3647
4098
|
onNotice: flash
|
|
3648
4099
|
}
|
|
3649
4100
|
),
|
|
3650
|
-
findOpen ? /* @__PURE__ */ (0,
|
|
3651
|
-
editable ? /* @__PURE__ */ (0,
|
|
3652
|
-
/* @__PURE__ */ (0,
|
|
3653
|
-
/* @__PURE__ */ (0,
|
|
3654
|
-
/* @__PURE__ */ (0,
|
|
3655
|
-
layout === "page" ? /* @__PURE__ */ (0,
|
|
3656
|
-
/* @__PURE__ */ (0,
|
|
4101
|
+
findOpen ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DocumentFindBar, { editor, editable, onClose: () => setFindOpen(false), onNotice: flash }) : null,
|
|
4102
|
+
editable ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DocumentBubbleMenu, { editor }) : null,
|
|
4103
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DocumentContent, { editor, layout, zoom, showMarks, onMetrics: setMetrics }),
|
|
4104
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "june-doc__footer", children: [
|
|
4105
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "june-doc__stats", children: [
|
|
4106
|
+
layout === "page" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
4107
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { children: [
|
|
3657
4108
|
"Page ",
|
|
3658
4109
|
metrics.page,
|
|
3659
4110
|
" of ",
|
|
3660
4111
|
metrics.pages
|
|
3661
4112
|
] }),
|
|
3662
|
-
/* @__PURE__ */ (0,
|
|
4113
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "june-doc__stats-sep", "aria-hidden": "true" })
|
|
3663
4114
|
] }) : null,
|
|
3664
|
-
/* @__PURE__ */ (0,
|
|
4115
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { children: [
|
|
3665
4116
|
words,
|
|
3666
4117
|
" words"
|
|
3667
4118
|
] })
|
|
3668
4119
|
] }),
|
|
3669
|
-
/* @__PURE__ */ (0,
|
|
3670
|
-
/* @__PURE__ */ (0,
|
|
3671
|
-
/* @__PURE__ */ (0,
|
|
3672
|
-
/* @__PURE__ */ (0,
|
|
4120
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "june-doc__status", "aria-live": "polite", "data-state": notice ? "notice" : saveState, children: notice ?? SAVE_LABEL[saveState] }),
|
|
4121
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "june-doc__zoom", role: "group", "aria-label": "Zoom", children: [
|
|
4122
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon june-doc__btn--ghost", "aria-label": "Zoom out", disabled: zoom <= ZOOM_STEPS[0], onClick: () => setZoom(stepZoom(zoom, -1)), children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { name: "minus", size: 14 }) }),
|
|
4123
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("button", { type: "button", className: "june-doc__zoom-value", "aria-label": "Reset zoom", title: "Reset zoom", onClick: () => setZoom(1), children: [
|
|
3673
4124
|
Math.round(zoom * 100),
|
|
3674
4125
|
"%"
|
|
3675
4126
|
] }),
|
|
3676
|
-
/* @__PURE__ */ (0,
|
|
4127
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "june-doc__btn june-doc__btn--icon june-doc__btn--ghost", "aria-label": "Zoom in", disabled: zoom >= ZOOM_STEPS[ZOOM_STEPS.length - 1], onClick: () => setZoom(stepZoom(zoom, 1)), children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { name: "plus", size: 14 }) })
|
|
3677
4128
|
] })
|
|
3678
4129
|
] })
|
|
3679
4130
|
]
|
|
@@ -3682,7 +4133,7 @@ function DocumentEditorImpl(props) {
|
|
|
3682
4133
|
}
|
|
3683
4134
|
|
|
3684
4135
|
// src/components/document-editor/document-component.tsx
|
|
3685
|
-
var
|
|
4136
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3686
4137
|
var DOCUMENT_COMPONENT_DESCRIPTION = 'Custom component. An editable document. DocumentEditor(documentId, title, content, documentType?, status?, editable?, exportFormats?). Place it in the root container (Card or Stack). "content" is the full document body as one Markdown string. Reuse documentId when revising the same document. Use it only when the user asks to create or revise a document.';
|
|
3687
4138
|
var documentProps = import_v4.z.object({
|
|
3688
4139
|
documentId: import_v4.z.string().describe("Stable id. Reuse it when revising the same document."),
|
|
@@ -3696,12 +4147,12 @@ var documentProps = import_v4.z.object({
|
|
|
3696
4147
|
function DocumentEditor(props) {
|
|
3697
4148
|
const { isStreaming } = useJuneRuntime();
|
|
3698
4149
|
if (props.generating || isStreaming) {
|
|
3699
|
-
return /* @__PURE__ */ (0,
|
|
4150
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(DocumentDraft, { title: props.title, state: "drafting" });
|
|
3700
4151
|
}
|
|
3701
|
-
return /* @__PURE__ */ (0,
|
|
4152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(DocumentEditorImpl, { ...props });
|
|
3702
4153
|
}
|
|
3703
4154
|
function OpenUIDocument({ props }) {
|
|
3704
|
-
return /* @__PURE__ */ (0,
|
|
4155
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3705
4156
|
DocumentEditor,
|
|
3706
4157
|
{
|
|
3707
4158
|
documentId: props.documentId,
|
|
@@ -3789,9 +4240,9 @@ var import_react_ui = require("@openuidev/react-ui");
|
|
|
3789
4240
|
var juneLibrary = withDocumentEditor(import_react_ui.openuiLibrary);
|
|
3790
4241
|
|
|
3791
4242
|
// src/core/JuneUI.tsx
|
|
3792
|
-
var
|
|
4243
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3793
4244
|
function JuneUI({ library = juneLibrary, ...props }) {
|
|
3794
|
-
return /* @__PURE__ */ (0,
|
|
4245
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(JuneRenderer, { library, ...props });
|
|
3795
4246
|
}
|
|
3796
4247
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3797
4248
|
0 && (module.exports = {
|
|
@@ -3821,17 +4272,21 @@ function JuneUI({ library = juneLibrary, ...props }) {
|
|
|
3821
4272
|
getDefaultDocumentStore,
|
|
3822
4273
|
getDocumentEditorInstructions,
|
|
3823
4274
|
getDocumentEditorRules,
|
|
4275
|
+
isDocumentEcho,
|
|
3824
4276
|
isJuneError,
|
|
3825
4277
|
jsonFieldExtractor,
|
|
3826
4278
|
juneLibrary,
|
|
3827
4279
|
lightTheme,
|
|
3828
4280
|
listDocumentExporters,
|
|
3829
4281
|
mergeDocuments,
|
|
4282
|
+
readDocumentFromProgram,
|
|
3830
4283
|
registerDocumentExporter,
|
|
4284
|
+
rememberDocumentEcho,
|
|
3831
4285
|
runAction,
|
|
3832
4286
|
serializeDocumentsForAgent,
|
|
3833
4287
|
sseToText,
|
|
3834
4288
|
toJuneError,
|
|
4289
|
+
updateDocumentInProgram,
|
|
3835
4290
|
useDocumentOptions,
|
|
3836
4291
|
useJuneRuntime,
|
|
3837
4292
|
useJuneStream,
|