@velo-sci/notebook-react 0.6.1 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +826 -741
- package/dist/index.js +825 -740
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -123,12 +123,12 @@ function useNotebookEvent(type, handler) {
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
// src/components/SciNotebook.tsx
|
|
126
|
-
var
|
|
126
|
+
var import_react14 = __toESM(require("react"), 1);
|
|
127
127
|
var import_notebook_core = require("@velo-sci/notebook-core");
|
|
128
|
-
var
|
|
128
|
+
var import_notebook_renderer2 = require("@velo-sci/notebook-renderer");
|
|
129
129
|
|
|
130
130
|
// src/components/Cell.tsx
|
|
131
|
-
var
|
|
131
|
+
var import_react10 = require("react");
|
|
132
132
|
|
|
133
133
|
// src/components/FloatingToolbar.tsx
|
|
134
134
|
var import_react2 = require("react");
|
|
@@ -259,10 +259,11 @@ function parseInlineStyle(css) {
|
|
|
259
259
|
|
|
260
260
|
// src/components/MathEditor.tsx
|
|
261
261
|
var import_react3 = require("react");
|
|
262
|
-
|
|
262
|
+
|
|
263
|
+
// src/components/math-categories.ts
|
|
263
264
|
var MATH_CATEGORIES = [
|
|
264
265
|
{
|
|
265
|
-
name: "
|
|
266
|
+
name: "Structures",
|
|
266
267
|
icon: "\u2B1A",
|
|
267
268
|
blocks: [
|
|
268
269
|
{ label: "a/b", latex: "\\frac{\u25A2}{\u25A2}", cursor: 6 },
|
|
@@ -279,7 +280,7 @@ var MATH_CATEGORIES = [
|
|
|
279
280
|
]
|
|
280
281
|
},
|
|
281
282
|
{
|
|
282
|
-
name: "
|
|
283
|
+
name: "Integrals",
|
|
283
284
|
icon: "\u222B",
|
|
284
285
|
blocks: [
|
|
285
286
|
{ label: "\u222B", latex: "\\int{\u25A2}\\,d{\u25A2}", cursor: 5 },
|
|
@@ -290,7 +291,7 @@ var MATH_CATEGORIES = [
|
|
|
290
291
|
]
|
|
291
292
|
},
|
|
292
293
|
{
|
|
293
|
-
name: "
|
|
294
|
+
name: "Summations",
|
|
294
295
|
icon: "\u2211",
|
|
295
296
|
blocks: [
|
|
296
297
|
{ label: "\u2211", latex: "\\sum_{\u25A2}^{\u25A2}{\u25A2}", cursor: 5 },
|
|
@@ -307,11 +308,11 @@ var MATH_CATEGORIES = [
|
|
|
307
308
|
{ label: "3\xD73", latex: "\\begin{pmatrix} \u25A2 & \u25A2 & \u25A2 \\\\ \u25A2 & \u25A2 & \u25A2 \\\\ \u25A2 & \u25A2 & \u25A2 \\end{pmatrix}", cursor: 16 },
|
|
308
309
|
{ label: "[2\xD72]", latex: "\\begin{bmatrix} \u25A2 & \u25A2 \\\\ \u25A2 & \u25A2 \\end{bmatrix}", cursor: 16 },
|
|
309
310
|
{ label: "|2\xD72|", latex: "\\begin{vmatrix} \u25A2 & \u25A2 \\\\ \u25A2 & \u25A2 \\end{vmatrix}", cursor: 16 },
|
|
310
|
-
{ label: "cases", latex: "\\begin{cases} \u25A2 & \\text{
|
|
311
|
+
{ label: "cases", latex: "\\begin{cases} \u25A2 & \\text{if } \u25A2 \\\\ \u25A2 & \\text{if } \u25A2 \\end{cases}", cursor: 14 }
|
|
311
312
|
]
|
|
312
313
|
},
|
|
313
314
|
{
|
|
314
|
-
name: "
|
|
315
|
+
name: "Greek",
|
|
315
316
|
icon: "\u03B1",
|
|
316
317
|
blocks: [
|
|
317
318
|
{ label: "\u03B1", latex: "\\alpha" },
|
|
@@ -342,7 +343,7 @@ var MATH_CATEGORIES = [
|
|
|
342
343
|
]
|
|
343
344
|
},
|
|
344
345
|
{
|
|
345
|
-
name: "
|
|
346
|
+
name: "Operators",
|
|
346
347
|
icon: "\xB1",
|
|
347
348
|
blocks: [
|
|
348
349
|
{ label: "\xB1", latex: "\\pm" },
|
|
@@ -374,7 +375,7 @@ var MATH_CATEGORIES = [
|
|
|
374
375
|
]
|
|
375
376
|
},
|
|
376
377
|
{
|
|
377
|
-
name: "
|
|
378
|
+
name: "Arrows",
|
|
378
379
|
icon: "\u2192",
|
|
379
380
|
blocks: [
|
|
380
381
|
{ label: "\u2192", latex: "\\rightarrow" },
|
|
@@ -389,7 +390,7 @@ var MATH_CATEGORIES = [
|
|
|
389
390
|
]
|
|
390
391
|
},
|
|
391
392
|
{
|
|
392
|
-
name: "
|
|
393
|
+
name: "Functions",
|
|
393
394
|
icon: "f(x)",
|
|
394
395
|
blocks: [
|
|
395
396
|
{ label: "sin", latex: "\\sin{\u25A2}", cursor: 5 },
|
|
@@ -405,7 +406,7 @@ var MATH_CATEGORIES = [
|
|
|
405
406
|
]
|
|
406
407
|
},
|
|
407
408
|
{
|
|
408
|
-
name: "
|
|
409
|
+
name: "Delimiters",
|
|
409
410
|
icon: "()",
|
|
410
411
|
blocks: [
|
|
411
412
|
{ label: "(\u2026)", latex: "\\left( \u25A2 \\right)", cursor: 7 },
|
|
@@ -418,9 +419,12 @@ var MATH_CATEGORIES = [
|
|
|
418
419
|
]
|
|
419
420
|
}
|
|
420
421
|
];
|
|
422
|
+
|
|
423
|
+
// src/components/MathEditor.tsx
|
|
424
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
421
425
|
function renderLatexPreview(latex) {
|
|
422
426
|
const clean = latex.replace(/^\$\$\s*/, "").replace(/\s*\$\$$/, "").trim();
|
|
423
|
-
if (!clean) return '<span class="sci-nb-math-preview-empty">
|
|
427
|
+
if (!clean) return '<span class="sci-nb-math-preview-empty">Empty formula</span>';
|
|
424
428
|
if (typeof globalThis !== "undefined" && globalThis.katex) {
|
|
425
429
|
try {
|
|
426
430
|
return globalThis.katex.renderToString(clean, {
|
|
@@ -430,14 +434,13 @@ function renderLatexPreview(latex) {
|
|
|
430
434
|
} catch {
|
|
431
435
|
}
|
|
432
436
|
}
|
|
433
|
-
|
|
434
|
-
}
|
|
435
|
-
function escapeHtml(s) {
|
|
436
|
-
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
437
|
+
const escaped = clean.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
438
|
+
return `<code class="sci-nb-math-preview-code">${escaped}</code>`;
|
|
437
439
|
}
|
|
438
440
|
var MathEditor = ({ cellId, source, onExit }) => {
|
|
439
441
|
const engine = useSciNotebook();
|
|
440
442
|
const textareaRef = (0, import_react3.useRef)(null);
|
|
443
|
+
const containerRef = (0, import_react3.useRef)(null);
|
|
441
444
|
const [activeCategory, setActiveCategory] = (0, import_react3.useState)(0);
|
|
442
445
|
const [showRaw, setShowRaw] = (0, import_react3.useState)(false);
|
|
443
446
|
const innerLatex = source.replace(/^\$\$\s*/, "").replace(/\s*\$\$$/, "").trim();
|
|
@@ -474,15 +477,42 @@ $$`);
|
|
|
474
477
|
}
|
|
475
478
|
});
|
|
476
479
|
}, [innerLatex, updateSource]);
|
|
480
|
+
const exitAndNext = (0, import_react3.useCallback)(() => {
|
|
481
|
+
onExit();
|
|
482
|
+
const cells = engine.getCells();
|
|
483
|
+
const idx = cells.findIndex((c) => c.id === cellId);
|
|
484
|
+
if (idx < cells.length - 1) {
|
|
485
|
+
engine.focusCell(cells[idx + 1].id);
|
|
486
|
+
engine.setEditMode(cells[idx + 1].id);
|
|
487
|
+
}
|
|
488
|
+
}, [engine, cellId, onExit]);
|
|
477
489
|
const handleKeyDown = (0, import_react3.useCallback)((e) => {
|
|
478
490
|
if (e.key === "Escape") {
|
|
479
491
|
e.preventDefault();
|
|
492
|
+
e.stopPropagation();
|
|
480
493
|
onExit();
|
|
481
494
|
} else if (e.key === "Enter" && e.shiftKey) {
|
|
482
495
|
e.preventDefault();
|
|
496
|
+
e.stopPropagation();
|
|
497
|
+
exitAndNext();
|
|
498
|
+
} else if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
|
|
499
|
+
e.preventDefault();
|
|
500
|
+
e.stopPropagation();
|
|
483
501
|
onExit();
|
|
484
502
|
}
|
|
485
|
-
}, [onExit]);
|
|
503
|
+
}, [onExit, exitAndNext]);
|
|
504
|
+
(0, import_react3.useEffect)(() => {
|
|
505
|
+
if (showRaw && textareaRef.current) {
|
|
506
|
+
textareaRef.current.focus();
|
|
507
|
+
} else if (containerRef.current) {
|
|
508
|
+
containerRef.current.focus();
|
|
509
|
+
}
|
|
510
|
+
}, [showRaw]);
|
|
511
|
+
(0, import_react3.useEffect)(() => {
|
|
512
|
+
if (containerRef.current) {
|
|
513
|
+
containerRef.current.focus();
|
|
514
|
+
}
|
|
515
|
+
}, []);
|
|
486
516
|
(0, import_react3.useEffect)(() => {
|
|
487
517
|
if (showRaw && textareaRef.current) {
|
|
488
518
|
const ta = textareaRef.current;
|
|
@@ -491,82 +521,97 @@ $$`);
|
|
|
491
521
|
}
|
|
492
522
|
}, [innerLatex, showRaw]);
|
|
493
523
|
const category = MATH_CATEGORIES[activeCategory];
|
|
494
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "sci-nb-math-tab-label", children: cat.name })
|
|
504
|
-
]
|
|
505
|
-
},
|
|
506
|
-
cat.name
|
|
507
|
-
)) }),
|
|
508
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sci-nb-math-palette", children: category.blocks.map((block, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
509
|
-
"button",
|
|
510
|
-
{
|
|
511
|
-
className: "sci-nb-math-block",
|
|
512
|
-
onClick: () => insertBlock(block),
|
|
513
|
-
title: block.latex,
|
|
514
|
-
children: block.label
|
|
515
|
-
},
|
|
516
|
-
i
|
|
517
|
-
)) }),
|
|
518
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "sci-nb-math-editor-area", children: [
|
|
519
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "sci-nb-math-mode-toggle", children: [
|
|
520
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
524
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
525
|
+
"div",
|
|
526
|
+
{
|
|
527
|
+
ref: containerRef,
|
|
528
|
+
className: "sci-nb-math-editor",
|
|
529
|
+
onKeyDown: handleKeyDown,
|
|
530
|
+
tabIndex: -1,
|
|
531
|
+
children: [
|
|
532
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sci-nb-math-tabs", children: MATH_CATEGORIES.map((cat, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
521
533
|
"button",
|
|
522
534
|
{
|
|
523
|
-
className: `sci-nb-math-
|
|
524
|
-
onClick: () =>
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
535
|
+
className: `sci-nb-math-tab ${i === activeCategory ? "sci-nb-math-tab--active" : ""}`,
|
|
536
|
+
onClick: () => setActiveCategory(i),
|
|
537
|
+
title: cat.name,
|
|
538
|
+
tabIndex: -1,
|
|
539
|
+
children: [
|
|
540
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "sci-nb-math-tab-icon", children: cat.icon }),
|
|
541
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "sci-nb-math-tab-label", children: cat.name })
|
|
542
|
+
]
|
|
543
|
+
},
|
|
544
|
+
cat.name
|
|
545
|
+
)) }),
|
|
546
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "sci-nb-math-palette", children: category.blocks.map((block, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
529
547
|
"button",
|
|
530
548
|
{
|
|
531
|
-
className:
|
|
532
|
-
onClick: () =>
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
{
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
549
|
+
className: "sci-nb-math-block",
|
|
550
|
+
onClick: () => insertBlock(block),
|
|
551
|
+
title: block.latex,
|
|
552
|
+
tabIndex: -1,
|
|
553
|
+
children: block.label
|
|
554
|
+
},
|
|
555
|
+
i
|
|
556
|
+
)) }),
|
|
557
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "sci-nb-math-editor-area", children: [
|
|
558
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "sci-nb-math-mode-toggle", children: [
|
|
559
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
560
|
+
"button",
|
|
561
|
+
{
|
|
562
|
+
className: `sci-nb-math-mode-btn ${!showRaw ? "sci-nb-math-mode-btn--active" : ""}`,
|
|
563
|
+
onClick: () => setShowRaw(false),
|
|
564
|
+
tabIndex: -1,
|
|
565
|
+
children: "Preview"
|
|
566
|
+
}
|
|
567
|
+
),
|
|
568
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
569
|
+
"button",
|
|
570
|
+
{
|
|
571
|
+
className: `sci-nb-math-mode-btn ${showRaw ? "sci-nb-math-mode-btn--active" : ""}`,
|
|
572
|
+
onClick: () => setShowRaw(true),
|
|
573
|
+
tabIndex: -1,
|
|
574
|
+
children: "LaTeX"
|
|
575
|
+
}
|
|
576
|
+
)
|
|
577
|
+
] }),
|
|
578
|
+
showRaw ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
579
|
+
"textarea",
|
|
580
|
+
{
|
|
581
|
+
ref: textareaRef,
|
|
582
|
+
className: "sci-nb-math-raw",
|
|
583
|
+
value: innerLatex,
|
|
584
|
+
onChange: handleRawChange,
|
|
585
|
+
placeholder: "Type LaTeX here...",
|
|
586
|
+
spellCheck: false,
|
|
587
|
+
autoFocus: true
|
|
588
|
+
}
|
|
589
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "sci-nb-math-visual", children: [
|
|
590
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
591
|
+
"div",
|
|
592
|
+
{
|
|
593
|
+
className: "sci-nb-math-preview",
|
|
594
|
+
dangerouslySetInnerHTML: { __html: renderLatexPreview(source) }
|
|
595
|
+
}
|
|
596
|
+
),
|
|
597
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "sci-nb-math-visual-hint", children: [
|
|
598
|
+
"Click the blocks above to build your formula. Switch to ",
|
|
599
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "LaTeX" }),
|
|
600
|
+
" mode to edit directly."
|
|
601
|
+
] })
|
|
602
|
+
] })
|
|
603
|
+
] }),
|
|
604
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "sci-nb-cell-hint", children: [
|
|
605
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("kbd", { children: "Esc" }),
|
|
606
|
+
" exit \xB7 ",
|
|
607
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("kbd", { children: "Shift+Enter" }),
|
|
608
|
+
" next \xB7 ",
|
|
609
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("kbd", { children: "Ctrl+Enter" }),
|
|
610
|
+
" render"
|
|
560
611
|
] })
|
|
561
|
-
]
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("kbd", { children: "Esc" }),
|
|
565
|
-
" salir \xB7 ",
|
|
566
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("kbd", { children: "Shift+Enter" }),
|
|
567
|
-
" siguiente"
|
|
568
|
-
] })
|
|
569
|
-
] });
|
|
612
|
+
]
|
|
613
|
+
}
|
|
614
|
+
);
|
|
570
615
|
};
|
|
571
616
|
|
|
572
617
|
// src/components/ImageCell.tsx
|
|
@@ -664,7 +709,7 @@ var ImageCell = ({ cellId, source, metadata, onExit }) => {
|
|
|
664
709
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "12", cy: "12", r: "2.5" }),
|
|
665
710
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M4 22l6-6 4 4 4-4 10 10", strokeLinejoin: "round" })
|
|
666
711
|
] }),
|
|
667
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: "
|
|
712
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: "Drag, paste (Ctrl+V) or click to select" }),
|
|
668
713
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
669
714
|
"input",
|
|
670
715
|
{
|
|
@@ -703,7 +748,7 @@ var ImageCell = ({ cellId, source, metadata, onExit }) => {
|
|
|
703
748
|
type: "text",
|
|
704
749
|
value: data.alt,
|
|
705
750
|
onChange: (e) => save({ alt: e.target.value }),
|
|
706
|
-
placeholder: "
|
|
751
|
+
placeholder: "Image description"
|
|
707
752
|
}
|
|
708
753
|
)
|
|
709
754
|
] }),
|
|
@@ -715,13 +760,13 @@ var ImageCell = ({ cellId, source, metadata, onExit }) => {
|
|
|
715
760
|
type: "text",
|
|
716
761
|
value: data.caption,
|
|
717
762
|
onChange: (e) => save({ caption: e.target.value }),
|
|
718
|
-
placeholder: "
|
|
763
|
+
placeholder: "Caption (optional)"
|
|
719
764
|
}
|
|
720
765
|
)
|
|
721
766
|
] }),
|
|
722
767
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "sci-nb-image-row", children: [
|
|
723
768
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "sci-nb-image-field sci-nb-image-field--small", children: [
|
|
724
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { children: "
|
|
769
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { children: "Width" }),
|
|
725
770
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("select", { value: data.width, onChange: (e) => save({ width: e.target.value }), children: [
|
|
726
771
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "25%", children: "25%" }),
|
|
727
772
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "50%", children: "50%" }),
|
|
@@ -731,38 +776,38 @@ var ImageCell = ({ cellId, source, metadata, onExit }) => {
|
|
|
731
776
|
] })
|
|
732
777
|
] }),
|
|
733
778
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "sci-nb-image-field sci-nb-image-field--small", children: [
|
|
734
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { children: "
|
|
779
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { children: "Align" }),
|
|
735
780
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("select", { value: data.align, onChange: (e) => save({ align: e.target.value }), children: [
|
|
736
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "left", children: "
|
|
737
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "center", children: "
|
|
738
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "right", children: "
|
|
781
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "left", children: "Left" }),
|
|
782
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "center", children: "Center" }),
|
|
783
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "right", children: "Right" })
|
|
739
784
|
] })
|
|
740
785
|
] }),
|
|
741
|
-
hasSrc && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { className: "sci-nb-image-clear", onClick: () => save({ src: "" }), children: "
|
|
786
|
+
hasSrc && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { className: "sci-nb-image-clear", onClick: () => save({ src: "" }), children: "Remove image" })
|
|
742
787
|
] })
|
|
743
788
|
] }),
|
|
744
789
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "sci-nb-cell-hint", children: [
|
|
745
790
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("kbd", { children: "Esc" }),
|
|
746
|
-
"
|
|
791
|
+
" exit"
|
|
747
792
|
] })
|
|
748
793
|
] });
|
|
749
794
|
};
|
|
750
795
|
function renderImagePreview(source, metadata) {
|
|
751
796
|
const data = parseImageSource(source, metadata);
|
|
752
797
|
if (!data.src) {
|
|
753
|
-
return '<div class="sci-nb-image-empty"><span class="sci-nb-placeholder">Click
|
|
798
|
+
return '<div class="sci-nb-image-empty"><span class="sci-nb-placeholder">Click to add image</span></div>';
|
|
754
799
|
}
|
|
755
800
|
const alignStyle = `text-align:${data.align}`;
|
|
756
801
|
const widthStyle = `max-width:${data.width};width:auto;max-height:400px`;
|
|
757
802
|
let html = `<div class="sci-nb-image-view" style="${alignStyle}">`;
|
|
758
803
|
html += `<img src="${escapeAttr(data.src)}" alt="${escapeAttr(data.alt)}" style="${widthStyle}" />`;
|
|
759
804
|
if (data.caption) {
|
|
760
|
-
html += `<p class="sci-nb-image-caption">${
|
|
805
|
+
html += `<p class="sci-nb-image-caption">${escapeHtml(data.caption)}</p>`;
|
|
761
806
|
}
|
|
762
807
|
html += `</div>`;
|
|
763
808
|
return html;
|
|
764
809
|
}
|
|
765
|
-
function
|
|
810
|
+
function escapeHtml(s) {
|
|
766
811
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
767
812
|
}
|
|
768
813
|
function escapeAttr(s) {
|
|
@@ -888,22 +933,22 @@ var EmbedCell = ({ cellId, source, metadata, onExit }) => {
|
|
|
888
933
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { children: "Sandbox" }),
|
|
889
934
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("select", { value: data.sandbox, onChange: (e) => save({ sandbox: e.target.value }), children: [
|
|
890
935
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "allow-scripts allow-same-origin allow-popups", children: "Standard" }),
|
|
891
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "allow-scripts", children: "
|
|
892
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "", children: "
|
|
936
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "allow-scripts", children: "Scripts only" }),
|
|
937
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: "", children: "Restricted" })
|
|
893
938
|
] })
|
|
894
939
|
] })
|
|
895
940
|
] })
|
|
896
941
|
] }),
|
|
897
942
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "sci-nb-cell-hint", children: [
|
|
898
943
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("kbd", { children: "Esc" }),
|
|
899
|
-
"
|
|
944
|
+
" exit"
|
|
900
945
|
] })
|
|
901
946
|
] });
|
|
902
947
|
};
|
|
903
948
|
function renderEmbedPreview(source, metadata) {
|
|
904
949
|
const data = parseEmbedSource(source, metadata);
|
|
905
950
|
if (!data.url) {
|
|
906
|
-
return '<div class="sci-nb-embed-empty"><span class="sci-nb-placeholder">Click
|
|
951
|
+
return '<div class="sci-nb-embed-empty"><span class="sci-nb-placeholder">Click to add embedded content</span></div>';
|
|
907
952
|
}
|
|
908
953
|
const titleAttr = data.title ? ` title="${escapeAttr2(data.title)}"` : "";
|
|
909
954
|
return `<div class="sci-nb-embed-view" style="height:${data.height}">
|
|
@@ -918,14 +963,14 @@ function escapeAttr2(s) {
|
|
|
918
963
|
var import_react6 = require("react");
|
|
919
964
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
920
965
|
var DEFAULT_COMMANDS = [
|
|
921
|
-
{ type: "markdown", label: "
|
|
922
|
-
{ type: "code", label: "
|
|
923
|
-
{ type: "latex", label: "
|
|
924
|
-
{ type: "image", label: "
|
|
966
|
+
{ type: "markdown", label: "Text", description: "Markdown formatted text block", icon: "M", keywords: ["text", "markdown", "paragraph"] },
|
|
967
|
+
{ type: "code", label: "Code", description: "Code block with syntax highlighting", icon: "</>", keywords: ["code", "script", "program"] },
|
|
968
|
+
{ type: "latex", label: "Formula", description: "Visual LaTeX formula editor", icon: "\u2211", keywords: ["latex", "math", "formula", "equation"] },
|
|
969
|
+
{ type: "image", label: "Image", description: "Image with drag & drop, URL, caption", icon: "\u{1F5BC}", keywords: ["image", "picture", "photo", "img"] },
|
|
925
970
|
{ type: "embed", label: "Embed", description: "YouTube, CodePen, Desmos, iframe", icon: "\u29C9", keywords: ["embed", "iframe", "youtube", "video", "codepen"] },
|
|
926
|
-
{ type: "table", label: "
|
|
927
|
-
{ type: "mermaid", label: "
|
|
928
|
-
{ type: "raw", label: "Raw", description: "
|
|
971
|
+
{ type: "table", label: "Table", description: "Editable table with rows and columns", icon: "\u25A6", keywords: ["table", "grid", "spreadsheet"] },
|
|
972
|
+
{ type: "mermaid", label: "Diagram", description: "Mermaid diagram (flowchart, sequence, etc.)", icon: "\u25C7", keywords: ["mermaid", "diagram", "flowchart", "chart"] },
|
|
973
|
+
{ type: "raw", label: "Raw", description: "Plain unformatted text", icon: "T", keywords: ["raw", "plain", "text"] }
|
|
929
974
|
];
|
|
930
975
|
var SlashCommand = ({
|
|
931
976
|
position,
|
|
@@ -980,7 +1025,7 @@ var SlashCommand = ({
|
|
|
980
1025
|
className: "sci-nb-slash-menu",
|
|
981
1026
|
style: { top: position.top, left: position.left },
|
|
982
1027
|
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "sci-nb-slash-empty", children: [
|
|
983
|
-
'
|
|
1028
|
+
'No results for "/',
|
|
984
1029
|
query,
|
|
985
1030
|
'"'
|
|
986
1031
|
] })
|
|
@@ -994,7 +1039,7 @@ var SlashCommand = ({
|
|
|
994
1039
|
className: "sci-nb-slash-menu",
|
|
995
1040
|
style: { top: position.top, left: position.left },
|
|
996
1041
|
children: [
|
|
997
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "sci-nb-slash-header", children: "
|
|
1042
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "sci-nb-slash-header", children: "Insert block" }),
|
|
998
1043
|
filtered.map((cmd, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
999
1044
|
"button",
|
|
1000
1045
|
{
|
|
@@ -1047,6 +1092,8 @@ function toMarkdownTable(data) {
|
|
|
1047
1092
|
var TableCell = ({ cellId, source, onExit }) => {
|
|
1048
1093
|
const engine = useSciNotebook();
|
|
1049
1094
|
const [data, setData] = (0, import_react7.useState)(() => parseMarkdownTable(source));
|
|
1095
|
+
const [hoverCol, setHoverCol] = (0, import_react7.useState)(null);
|
|
1096
|
+
const [hoverRow, setHoverRow] = (0, import_react7.useState)(null);
|
|
1050
1097
|
const syncToEngine = (0, import_react7.useCallback)((newData) => {
|
|
1051
1098
|
setData(newData);
|
|
1052
1099
|
engine.updateCellSource(cellId, toMarkdownTable(newData));
|
|
@@ -1085,142 +1132,104 @@ var TableCell = ({ cellId, source, onExit }) => {
|
|
|
1085
1132
|
if (e.key === "Escape") {
|
|
1086
1133
|
e.preventDefault();
|
|
1087
1134
|
onExit();
|
|
1088
|
-
} else if (e.key === "Tab" && !e.shiftKey) {
|
|
1089
1135
|
}
|
|
1090
1136
|
}, [onExit]);
|
|
1091
1137
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "sci-nb-table-editor", onKeyDown: handleKeyDown, children: [
|
|
1092
1138
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "sci-nb-table-toolbar", children: [
|
|
1093
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: addRow, children: "+
|
|
1094
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: addColumn, children: "+
|
|
1139
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: addRow, children: "+ Row" }),
|
|
1140
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: addColumn, children: "+ Column" })
|
|
1095
1141
|
] }),
|
|
1096
1142
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("table", { children: [
|
|
1097
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime6.
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1143
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("tr", { children: data.headers.map((h, ci) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1144
|
+
"th",
|
|
1145
|
+
{
|
|
1146
|
+
className: "sci-nb-table-header-cell",
|
|
1147
|
+
onMouseEnter: () => setHoverCol(ci),
|
|
1148
|
+
onMouseLeave: () => setHoverCol(null),
|
|
1149
|
+
children: [
|
|
1150
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1151
|
+
"input",
|
|
1152
|
+
{
|
|
1153
|
+
value: h,
|
|
1154
|
+
onChange: (e) => updateHeader(ci, e.target.value),
|
|
1155
|
+
placeholder: `Col ${ci + 1}`
|
|
1156
|
+
}
|
|
1157
|
+
),
|
|
1158
|
+
data.headers.length > 1 && hoverCol === ci && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1159
|
+
"button",
|
|
1160
|
+
{
|
|
1161
|
+
className: "sci-nb-table-delete-btn",
|
|
1162
|
+
onClick: () => removeColumn(ci),
|
|
1163
|
+
title: "Delete column",
|
|
1164
|
+
children: "\u2715"
|
|
1165
|
+
}
|
|
1166
|
+
)
|
|
1167
|
+
]
|
|
1168
|
+
},
|
|
1169
|
+
ci
|
|
1170
|
+
)) }) }),
|
|
1171
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("tbody", { children: data.rows.map((row, ri) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1172
|
+
"tr",
|
|
1173
|
+
{
|
|
1174
|
+
onMouseEnter: () => setHoverRow(ri),
|
|
1175
|
+
onMouseLeave: () => setHoverRow(null),
|
|
1176
|
+
children: row.map((cell, ci) => {
|
|
1177
|
+
const isLastCol = ci === row.length - 1;
|
|
1178
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1179
|
+
"td",
|
|
1180
|
+
{
|
|
1181
|
+
className: isLastCol ? "sci-nb-table-row-end" : "",
|
|
1182
|
+
children: [
|
|
1183
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1184
|
+
"input",
|
|
1185
|
+
{
|
|
1186
|
+
value: cell,
|
|
1187
|
+
onChange: (e) => updateCell(ri, ci, e.target.value),
|
|
1188
|
+
placeholder: "..."
|
|
1189
|
+
}
|
|
1190
|
+
),
|
|
1191
|
+
isLastCol && data.rows.length > 1 && hoverRow === ri && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1192
|
+
"button",
|
|
1193
|
+
{
|
|
1194
|
+
className: "sci-nb-table-delete-btn",
|
|
1195
|
+
onClick: () => removeRow(ri),
|
|
1196
|
+
title: "Delete row",
|
|
1197
|
+
children: "\u2715"
|
|
1198
|
+
}
|
|
1199
|
+
)
|
|
1200
|
+
]
|
|
1201
|
+
},
|
|
1202
|
+
ci
|
|
1203
|
+
);
|
|
1204
|
+
})
|
|
1205
|
+
},
|
|
1206
|
+
ri
|
|
1207
|
+
)) })
|
|
1128
1208
|
] }),
|
|
1129
1209
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "sci-nb-cell-hint", children: [
|
|
1130
1210
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("kbd", { children: "Tab" }),
|
|
1131
|
-
"
|
|
1211
|
+
" next cell \xB7 ",
|
|
1132
1212
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("kbd", { children: "Esc" }),
|
|
1133
|
-
"
|
|
1213
|
+
" exit"
|
|
1134
1214
|
] })
|
|
1135
1215
|
] });
|
|
1136
1216
|
};
|
|
1137
1217
|
function renderTablePreview(source) {
|
|
1138
1218
|
const data = parseMarkdownTable(source);
|
|
1139
|
-
if (data.headers.length === 0) return "<p>
|
|
1140
|
-
const ths = data.headers.map((h) => `<th>${
|
|
1219
|
+
if (data.headers.length === 0) return "<p>Empty table</p>";
|
|
1220
|
+
const ths = data.headers.map((h) => `<th>${escapeHtml2(h)}</th>`).join("");
|
|
1141
1221
|
const trs = data.rows.map(
|
|
1142
|
-
(row) => `<tr>${row.map((c) => `<td>${
|
|
1222
|
+
(row) => `<tr>${row.map((c) => `<td>${escapeHtml2(c)}</td>`).join("")}</tr>`
|
|
1143
1223
|
).join("");
|
|
1144
1224
|
return `<table class="sci-nb-rendered-table"><thead><tr>${ths}</tr></thead><tbody>${trs}</tbody></table>`;
|
|
1145
1225
|
}
|
|
1146
|
-
function
|
|
1226
|
+
function escapeHtml2(s) {
|
|
1147
1227
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
1148
1228
|
}
|
|
1149
1229
|
|
|
1150
|
-
// src/components/CellOutput.tsx
|
|
1151
|
-
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1152
|
-
var CellOutputDisplay = ({ outputs }) => {
|
|
1153
|
-
if (!outputs || outputs.length === 0) return null;
|
|
1154
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "sci-nb-cell-outputs", children: outputs.map((output, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `sci-nb-output sci-nb-output--${output.outputType}`, children: renderOutput(output) }, i)) });
|
|
1155
|
-
};
|
|
1156
|
-
function renderOutput(output) {
|
|
1157
|
-
switch (output.outputType) {
|
|
1158
|
-
case "stream":
|
|
1159
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { className: `sci-nb-output-stream sci-nb-output-stream--${output.name}`, children: output.text });
|
|
1160
|
-
case "display": {
|
|
1161
|
-
if (output.data["text/html"]) {
|
|
1162
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1163
|
-
"div",
|
|
1164
|
-
{
|
|
1165
|
-
className: "sci-nb-output-html",
|
|
1166
|
-
dangerouslySetInnerHTML: { __html: output.data["text/html"] }
|
|
1167
|
-
}
|
|
1168
|
-
);
|
|
1169
|
-
}
|
|
1170
|
-
if (output.data["image/svg+xml"]) {
|
|
1171
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1172
|
-
"div",
|
|
1173
|
-
{
|
|
1174
|
-
className: "sci-nb-output-svg",
|
|
1175
|
-
dangerouslySetInnerHTML: { __html: output.data["image/svg+xml"] }
|
|
1176
|
-
}
|
|
1177
|
-
);
|
|
1178
|
-
}
|
|
1179
|
-
if (output.data["image/png"]) {
|
|
1180
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1181
|
-
"img",
|
|
1182
|
-
{
|
|
1183
|
-
className: "sci-nb-output-image",
|
|
1184
|
-
src: `data:image/png;base64,${output.data["image/png"]}`,
|
|
1185
|
-
alt: "Output"
|
|
1186
|
-
}
|
|
1187
|
-
);
|
|
1188
|
-
}
|
|
1189
|
-
if (output.data["image/jpeg"]) {
|
|
1190
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1191
|
-
"img",
|
|
1192
|
-
{
|
|
1193
|
-
className: "sci-nb-output-image",
|
|
1194
|
-
src: `data:image/jpeg;base64,${output.data["image/jpeg"]}`,
|
|
1195
|
-
alt: "Output"
|
|
1196
|
-
}
|
|
1197
|
-
);
|
|
1198
|
-
}
|
|
1199
|
-
if (output.data["application/json"]) {
|
|
1200
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { className: "sci-nb-output-json", children: JSON.stringify(JSON.parse(output.data["application/json"]), null, 2) });
|
|
1201
|
-
}
|
|
1202
|
-
if (output.data["text/plain"]) {
|
|
1203
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { className: "sci-nb-output-text", children: output.data["text/plain"] });
|
|
1204
|
-
}
|
|
1205
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { className: "sci-nb-output-text", children: "[Display output]" });
|
|
1206
|
-
}
|
|
1207
|
-
case "error":
|
|
1208
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "sci-nb-output-error", children: [
|
|
1209
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("strong", { className: "sci-nb-output-error-name", children: [
|
|
1210
|
-
output.name,
|
|
1211
|
-
": "
|
|
1212
|
-
] }),
|
|
1213
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "sci-nb-output-error-msg", children: output.message }),
|
|
1214
|
-
output.traceback && output.traceback.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { className: "sci-nb-output-traceback", children: output.traceback.join("\n") })
|
|
1215
|
-
] });
|
|
1216
|
-
default:
|
|
1217
|
-
return null;
|
|
1218
|
-
}
|
|
1219
|
-
}
|
|
1220
|
-
|
|
1221
1230
|
// src/components/MermaidCell.tsx
|
|
1222
1231
|
var import_react8 = require("react");
|
|
1223
|
-
var
|
|
1232
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1224
1233
|
var mermaidIdCounter = 0;
|
|
1225
1234
|
var MermaidPreview = ({ source, onClick }) => {
|
|
1226
1235
|
const [svg, setSvg] = (0, import_react8.useState)(null);
|
|
@@ -1263,29 +1272,29 @@ var MermaidPreview = ({ source, onClick }) => {
|
|
|
1263
1272
|
}, [source]);
|
|
1264
1273
|
const mermaid = globalThis.mermaid;
|
|
1265
1274
|
if (!source.trim()) {
|
|
1266
|
-
return /* @__PURE__ */ (0,
|
|
1275
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "sci-nb-mermaid-preview", onClick, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "sci-nb-placeholder", children: "Empty diagram \u2014 write Mermaid syntax" }) });
|
|
1267
1276
|
}
|
|
1268
1277
|
if (!mermaid) {
|
|
1269
|
-
return /* @__PURE__ */ (0,
|
|
1270
|
-
/* @__PURE__ */ (0,
|
|
1271
|
-
/* @__PURE__ */ (0,
|
|
1272
|
-
"Mermaid
|
|
1273
|
-
/* @__PURE__ */ (0,
|
|
1274
|
-
"
|
|
1275
|
-
/* @__PURE__ */ (0,
|
|
1278
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "sci-nb-mermaid-preview", onClick, children: [
|
|
1279
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { className: "sci-nb-code", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { className: "language-mermaid", children: source }) }),
|
|
1280
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { fontSize: 11, color: "#94a3b8", textAlign: "center", padding: 4 }, children: [
|
|
1281
|
+
"Mermaid not available. Import ",
|
|
1282
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { children: "mermaid" }),
|
|
1283
|
+
" and expose it as ",
|
|
1284
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { children: "globalThis.mermaid" }),
|
|
1276
1285
|
"."
|
|
1277
1286
|
] })
|
|
1278
1287
|
] });
|
|
1279
1288
|
}
|
|
1280
1289
|
if (error) {
|
|
1281
|
-
return /* @__PURE__ */ (0,
|
|
1282
|
-
/* @__PURE__ */ (0,
|
|
1290
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "sci-nb-mermaid-error", onClick, children: [
|
|
1291
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: "Mermaid error:" }),
|
|
1283
1292
|
" ",
|
|
1284
1293
|
error
|
|
1285
1294
|
] });
|
|
1286
1295
|
}
|
|
1287
1296
|
if (svg) {
|
|
1288
|
-
return /* @__PURE__ */ (0,
|
|
1297
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1289
1298
|
"div",
|
|
1290
1299
|
{
|
|
1291
1300
|
ref: containerRef,
|
|
@@ -1293,125 +1302,361 @@ var MermaidPreview = ({ source, onClick }) => {
|
|
|
1293
1302
|
onClick,
|
|
1294
1303
|
dangerouslySetInnerHTML: { __html: svg }
|
|
1295
1304
|
}
|
|
1296
|
-
);
|
|
1305
|
+
);
|
|
1306
|
+
}
|
|
1307
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "sci-nb-mermaid-preview", onClick, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "sci-nb-placeholder", children: "Rendering diagram..." }) });
|
|
1308
|
+
};
|
|
1309
|
+
function initMermaid(mermaidLib, config) {
|
|
1310
|
+
globalThis.mermaid = mermaidLib;
|
|
1311
|
+
mermaidLib.initialize({
|
|
1312
|
+
startOnLoad: false,
|
|
1313
|
+
theme: "default",
|
|
1314
|
+
securityLevel: "loose",
|
|
1315
|
+
...config
|
|
1316
|
+
});
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
// src/components/CodeEditor.tsx
|
|
1320
|
+
var import_react9 = require("react");
|
|
1321
|
+
var import_notebook_renderer = require("@velo-sci/notebook-renderer");
|
|
1322
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1323
|
+
var CodeEditor = ({
|
|
1324
|
+
source,
|
|
1325
|
+
language,
|
|
1326
|
+
onChange,
|
|
1327
|
+
onKeyDown,
|
|
1328
|
+
placeholder
|
|
1329
|
+
}) => {
|
|
1330
|
+
const textareaRef = (0, import_react9.useRef)(null);
|
|
1331
|
+
const preRef = (0, import_react9.useRef)(null);
|
|
1332
|
+
const [highlighted, setHighlighted] = (0, import_react9.useState)("");
|
|
1333
|
+
(0, import_react9.useEffect)(() => {
|
|
1334
|
+
const html = (0, import_notebook_renderer.highlightCodeTokens)(source, language || "text");
|
|
1335
|
+
const match = html.match(/<code[^>]*>([\s\S]*)<\/code>/);
|
|
1336
|
+
setHighlighted(match ? match[1] : html);
|
|
1337
|
+
}, [source, language]);
|
|
1338
|
+
const syncScroll = (0, import_react9.useCallback)(() => {
|
|
1339
|
+
if (textareaRef.current && preRef.current) {
|
|
1340
|
+
preRef.current.scrollTop = textareaRef.current.scrollTop;
|
|
1341
|
+
preRef.current.scrollLeft = textareaRef.current.scrollLeft;
|
|
1342
|
+
}
|
|
1343
|
+
}, []);
|
|
1344
|
+
(0, import_react9.useEffect)(() => {
|
|
1345
|
+
if (textareaRef.current) {
|
|
1346
|
+
const ta = textareaRef.current;
|
|
1347
|
+
ta.style.height = "auto";
|
|
1348
|
+
ta.style.height = `${Math.max(40, ta.scrollHeight)}px`;
|
|
1349
|
+
}
|
|
1350
|
+
}, [source]);
|
|
1351
|
+
(0, import_react9.useEffect)(() => {
|
|
1352
|
+
textareaRef.current?.focus();
|
|
1353
|
+
}, []);
|
|
1354
|
+
const handleChange = (0, import_react9.useCallback)((e) => {
|
|
1355
|
+
onChange(e.target.value);
|
|
1356
|
+
}, [onChange]);
|
|
1357
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "sci-nb-code-editor-wrap", children: [
|
|
1358
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1359
|
+
"pre",
|
|
1360
|
+
{
|
|
1361
|
+
ref: preRef,
|
|
1362
|
+
className: "sci-nb-code-editor-highlight sci-nb-code--highlighted",
|
|
1363
|
+
"aria-hidden": "true",
|
|
1364
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("code", { className: `language-${language || "text"}`, children: [
|
|
1365
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { dangerouslySetInnerHTML: { __html: highlighted || " " } }),
|
|
1366
|
+
"\n"
|
|
1367
|
+
] })
|
|
1368
|
+
}
|
|
1369
|
+
),
|
|
1370
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1371
|
+
"textarea",
|
|
1372
|
+
{
|
|
1373
|
+
ref: textareaRef,
|
|
1374
|
+
className: "sci-nb-code-editor-input",
|
|
1375
|
+
value: source,
|
|
1376
|
+
onChange: handleChange,
|
|
1377
|
+
onKeyDown,
|
|
1378
|
+
onScroll: syncScroll,
|
|
1379
|
+
placeholder,
|
|
1380
|
+
spellCheck: false,
|
|
1381
|
+
autoComplete: "off",
|
|
1382
|
+
autoCapitalize: "off",
|
|
1383
|
+
rows: 1
|
|
1384
|
+
}
|
|
1385
|
+
)
|
|
1386
|
+
] });
|
|
1387
|
+
};
|
|
1388
|
+
|
|
1389
|
+
// src/components/CellRenderers.tsx
|
|
1390
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1391
|
+
function renderEditMode(cell, cellId, engine, textareaRef, handleSourceChange, handleKeyDown, placeholder, exitEdit, slashState, onSlashSelect, onSlashClose) {
|
|
1392
|
+
if (cell.type === "latex") {
|
|
1393
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MathEditor, { cellId, source: cell.source, onExit: exitEdit });
|
|
1394
|
+
}
|
|
1395
|
+
if (cell.type === "image") {
|
|
1396
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ImageCell, { cellId, source: cell.source, metadata: cell.metadata, onExit: exitEdit });
|
|
1397
|
+
}
|
|
1398
|
+
if (cell.type === "embed") {
|
|
1399
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(EmbedCell, { cellId, source: cell.source, metadata: cell.metadata, onExit: exitEdit });
|
|
1400
|
+
}
|
|
1401
|
+
if (cell.type === "table") {
|
|
1402
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TableCell, { cellId, source: cell.source, metadata: cell.metadata, onExit: exitEdit });
|
|
1403
|
+
}
|
|
1404
|
+
if (cell.type === "code") {
|
|
1405
|
+
const lang = cell.metadata.language || "javascript";
|
|
1406
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
1407
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1408
|
+
CodeEditor,
|
|
1409
|
+
{
|
|
1410
|
+
cellId,
|
|
1411
|
+
source: cell.source,
|
|
1412
|
+
language: lang,
|
|
1413
|
+
onChange: (val) => engine.updateCellSource(cellId, val),
|
|
1414
|
+
onKeyDown: handleKeyDown,
|
|
1415
|
+
placeholder
|
|
1416
|
+
}
|
|
1417
|
+
),
|
|
1418
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "sci-nb-cell-hint", children: [
|
|
1419
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("kbd", { children: "Shift+Enter" }),
|
|
1420
|
+
" next \xB7 ",
|
|
1421
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("kbd", { children: "Esc" }),
|
|
1422
|
+
" exit"
|
|
1423
|
+
] })
|
|
1424
|
+
] });
|
|
1425
|
+
}
|
|
1426
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
1427
|
+
cell.type === "markdown" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FloatingToolbar, { cellId, textareaRef }),
|
|
1428
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1429
|
+
"textarea",
|
|
1430
|
+
{
|
|
1431
|
+
ref: textareaRef,
|
|
1432
|
+
className: "sci-nb-editor",
|
|
1433
|
+
value: cell.source,
|
|
1434
|
+
onChange: handleSourceChange,
|
|
1435
|
+
onKeyDown: handleKeyDown,
|
|
1436
|
+
placeholder,
|
|
1437
|
+
spellCheck: cell.type === "markdown",
|
|
1438
|
+
rows: 1
|
|
1439
|
+
}
|
|
1440
|
+
),
|
|
1441
|
+
slashState && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1442
|
+
SlashCommand,
|
|
1443
|
+
{
|
|
1444
|
+
position: slashState.pos,
|
|
1445
|
+
query: slashState.query,
|
|
1446
|
+
onSelect: onSlashSelect,
|
|
1447
|
+
onClose: onSlashClose
|
|
1448
|
+
}
|
|
1449
|
+
),
|
|
1450
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "sci-nb-cell-hint", children: [
|
|
1451
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("kbd", { children: "/" }),
|
|
1452
|
+
" commands \xB7 ",
|
|
1453
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("kbd", { children: "Shift+Enter" }),
|
|
1454
|
+
" next \xB7 ",
|
|
1455
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("kbd", { children: "Esc" }),
|
|
1456
|
+
" exit"
|
|
1457
|
+
] })
|
|
1458
|
+
] });
|
|
1459
|
+
}
|
|
1460
|
+
function renderViewMode(cell, renderedHtml, isEmpty, placeholder, enterEdit) {
|
|
1461
|
+
if (cell.type === "image") {
|
|
1462
|
+
const html = renderImagePreview(cell.source, cell.metadata);
|
|
1463
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "sci-nb-preview", onClick: enterEdit, dangerouslySetInnerHTML: { __html: html } });
|
|
1464
|
+
}
|
|
1465
|
+
if (cell.type === "embed") {
|
|
1466
|
+
const html = renderEmbedPreview(cell.source, cell.metadata);
|
|
1467
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "sci-nb-preview sci-nb-preview--embed", onClick: enterEdit, dangerouslySetInnerHTML: { __html: html } });
|
|
1468
|
+
}
|
|
1469
|
+
if (cell.type === "table") {
|
|
1470
|
+
const html = renderTablePreview(cell.source);
|
|
1471
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "sci-nb-preview", onClick: enterEdit, dangerouslySetInnerHTML: { __html: html } });
|
|
1472
|
+
}
|
|
1473
|
+
if (cell.type === "mermaid") {
|
|
1474
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MermaidPreview, { source: cell.source, onClick: enterEdit });
|
|
1475
|
+
}
|
|
1476
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1477
|
+
"div",
|
|
1478
|
+
{
|
|
1479
|
+
className: `sci-nb-preview ${isEmpty ? "sci-nb-preview--empty" : ""}`,
|
|
1480
|
+
onClick: enterEdit,
|
|
1481
|
+
dangerouslySetInnerHTML: isEmpty ? { __html: `<span class="sci-nb-placeholder">${placeholder}</span>` } : { __html: renderedHtml }
|
|
1482
|
+
}
|
|
1483
|
+
);
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
// src/components/CellOutput.tsx
|
|
1487
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1488
|
+
var CellOutputDisplay = ({ outputs }) => {
|
|
1489
|
+
if (!outputs || outputs.length === 0) return null;
|
|
1490
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "sci-nb-cell-outputs", children: outputs.map((output, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: `sci-nb-output sci-nb-output--${output.outputType}`, children: renderOutput(output) }, i)) });
|
|
1491
|
+
};
|
|
1492
|
+
function renderOutput(output) {
|
|
1493
|
+
switch (output.outputType) {
|
|
1494
|
+
case "stream":
|
|
1495
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("pre", { className: `sci-nb-output-stream sci-nb-output-stream--${output.name}`, children: output.text });
|
|
1496
|
+
case "display": {
|
|
1497
|
+
if (output.data["text/html"]) {
|
|
1498
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1499
|
+
"div",
|
|
1500
|
+
{
|
|
1501
|
+
className: "sci-nb-output-html",
|
|
1502
|
+
dangerouslySetInnerHTML: { __html: output.data["text/html"] }
|
|
1503
|
+
}
|
|
1504
|
+
);
|
|
1505
|
+
}
|
|
1506
|
+
if (output.data["image/svg+xml"]) {
|
|
1507
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1508
|
+
"div",
|
|
1509
|
+
{
|
|
1510
|
+
className: "sci-nb-output-svg",
|
|
1511
|
+
dangerouslySetInnerHTML: { __html: output.data["image/svg+xml"] }
|
|
1512
|
+
}
|
|
1513
|
+
);
|
|
1514
|
+
}
|
|
1515
|
+
if (output.data["image/png"]) {
|
|
1516
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1517
|
+
"img",
|
|
1518
|
+
{
|
|
1519
|
+
className: "sci-nb-output-image",
|
|
1520
|
+
src: `data:image/png;base64,${output.data["image/png"]}`,
|
|
1521
|
+
alt: "Output"
|
|
1522
|
+
}
|
|
1523
|
+
);
|
|
1524
|
+
}
|
|
1525
|
+
if (output.data["image/jpeg"]) {
|
|
1526
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1527
|
+
"img",
|
|
1528
|
+
{
|
|
1529
|
+
className: "sci-nb-output-image",
|
|
1530
|
+
src: `data:image/jpeg;base64,${output.data["image/jpeg"]}`,
|
|
1531
|
+
alt: "Output"
|
|
1532
|
+
}
|
|
1533
|
+
);
|
|
1534
|
+
}
|
|
1535
|
+
if (output.data["application/json"]) {
|
|
1536
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("pre", { className: "sci-nb-output-json", children: JSON.stringify(JSON.parse(output.data["application/json"]), null, 2) });
|
|
1537
|
+
}
|
|
1538
|
+
if (output.data["text/plain"]) {
|
|
1539
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("pre", { className: "sci-nb-output-text", children: output.data["text/plain"] });
|
|
1540
|
+
}
|
|
1541
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("pre", { className: "sci-nb-output-text", children: "[Display output]" });
|
|
1542
|
+
}
|
|
1543
|
+
case "error":
|
|
1544
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "sci-nb-output-error", children: [
|
|
1545
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("strong", { className: "sci-nb-output-error-name", children: [
|
|
1546
|
+
output.name,
|
|
1547
|
+
": "
|
|
1548
|
+
] }),
|
|
1549
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "sci-nb-output-error-msg", children: output.message }),
|
|
1550
|
+
output.traceback && output.traceback.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("pre", { className: "sci-nb-output-traceback", children: output.traceback.join("\n") })
|
|
1551
|
+
] });
|
|
1552
|
+
default:
|
|
1553
|
+
return null;
|
|
1297
1554
|
}
|
|
1298
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "sci-nb-mermaid-preview", onClick, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "sci-nb-placeholder", children: "Renderizando diagrama..." }) });
|
|
1299
|
-
};
|
|
1300
|
-
function initMermaid(mermaidLib, config) {
|
|
1301
|
-
globalThis.mermaid = mermaidLib;
|
|
1302
|
-
mermaidLib.initialize({
|
|
1303
|
-
startOnLoad: false,
|
|
1304
|
-
theme: "default",
|
|
1305
|
-
securityLevel: "loose",
|
|
1306
|
-
...config
|
|
1307
|
-
});
|
|
1308
1555
|
}
|
|
1309
1556
|
|
|
1310
1557
|
// src/components/Cell.tsx
|
|
1311
|
-
var
|
|
1558
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1312
1559
|
var CELL_TYPES = [
|
|
1313
1560
|
{ value: "markdown", label: "Markdown", icon: "M" },
|
|
1314
1561
|
{ value: "code", label: "Code", icon: "</>" },
|
|
1315
1562
|
{ value: "raw", label: "Raw", icon: "T" },
|
|
1316
1563
|
{ value: "latex", label: "LaTeX", icon: "\u2211" },
|
|
1317
|
-
{ value: "image", label: "
|
|
1564
|
+
{ value: "image", label: "Image", icon: "\u{1F5BC}" },
|
|
1318
1565
|
{ value: "embed", label: "Embed", icon: "\u29C9" }
|
|
1319
1566
|
];
|
|
1320
1567
|
var PLACEHOLDERS = {
|
|
1321
|
-
markdown: "
|
|
1322
|
-
code: "
|
|
1323
|
-
raw: "
|
|
1324
|
-
latex: "
|
|
1325
|
-
image: "Click
|
|
1326
|
-
embed: "Click
|
|
1568
|
+
markdown: "Write markdown here... (click to edit)",
|
|
1569
|
+
code: "Write code here...",
|
|
1570
|
+
raw: "Raw text...",
|
|
1571
|
+
latex: "Write LaTeX here... e.g. \\int_0^1 x^2 dx",
|
|
1572
|
+
image: "Click to add image",
|
|
1573
|
+
embed: "Click to add embedded content"
|
|
1327
1574
|
};
|
|
1328
1575
|
var Cell = ({ cellId, pipeline, index, totalCells }) => {
|
|
1329
1576
|
const cell = useCell(cellId);
|
|
1330
1577
|
const engine = useSciNotebook();
|
|
1331
|
-
const textareaRef = (0,
|
|
1332
|
-
const cellRef = (0,
|
|
1333
|
-
const [showTypeMenu, setShowTypeMenu] = (0,
|
|
1334
|
-
const [hovered, setHovered] = (0,
|
|
1335
|
-
const [slashState, setSlashState] = (0,
|
|
1336
|
-
const [dragOver, setDragOver] = (0,
|
|
1337
|
-
const [isDragging, setIsDragging] = (0,
|
|
1338
|
-
const rendered = (0,
|
|
1578
|
+
const textareaRef = (0, import_react10.useRef)(null);
|
|
1579
|
+
const cellRef = (0, import_react10.useRef)(null);
|
|
1580
|
+
const [showTypeMenu, setShowTypeMenu] = (0, import_react10.useState)(false);
|
|
1581
|
+
const [hovered, setHovered] = (0, import_react10.useState)(false);
|
|
1582
|
+
const [slashState, setSlashState] = (0, import_react10.useState)(null);
|
|
1583
|
+
const [dragOver, setDragOver] = (0, import_react10.useState)(null);
|
|
1584
|
+
const [isDragging, setIsDragging] = (0, import_react10.useState)(false);
|
|
1585
|
+
const rendered = (0, import_react10.useMemo)(() => {
|
|
1339
1586
|
if (!cell) return { html: "", cellId: "", renderTime: 0, cached: false };
|
|
1340
1587
|
return pipeline.render(cell);
|
|
1341
1588
|
}, [cell?.source, cell?.type, cell?.metadata, pipeline]);
|
|
1342
|
-
(0,
|
|
1589
|
+
(0, import_react10.useEffect)(() => {
|
|
1343
1590
|
if (cell?.editing && textareaRef.current) {
|
|
1344
1591
|
const ta = textareaRef.current;
|
|
1345
1592
|
ta.style.height = "auto";
|
|
1346
1593
|
ta.style.height = `${Math.max(40, ta.scrollHeight)}px`;
|
|
1347
1594
|
}
|
|
1348
1595
|
}, [cell?.source, cell?.editing]);
|
|
1349
|
-
(0,
|
|
1350
|
-
if (cell?.editing && textareaRef.current)
|
|
1351
|
-
textareaRef.current.focus();
|
|
1352
|
-
}
|
|
1596
|
+
(0, import_react10.useEffect)(() => {
|
|
1597
|
+
if (cell?.editing && textareaRef.current) textareaRef.current.focus();
|
|
1353
1598
|
}, [cell?.editing]);
|
|
1354
|
-
(0,
|
|
1599
|
+
(0, import_react10.useEffect)(() => {
|
|
1355
1600
|
if (!showTypeMenu) return;
|
|
1356
1601
|
const handler = (e) => {
|
|
1357
|
-
if (cellRef.current && !cellRef.current.contains(e.target))
|
|
1358
|
-
setShowTypeMenu(false);
|
|
1359
|
-
}
|
|
1602
|
+
if (cellRef.current && !cellRef.current.contains(e.target)) setShowTypeMenu(false);
|
|
1360
1603
|
};
|
|
1361
1604
|
document.addEventListener("mousedown", handler);
|
|
1362
1605
|
return () => document.removeEventListener("mousedown", handler);
|
|
1363
1606
|
}, [showTypeMenu]);
|
|
1364
|
-
const handleSourceChange = (0,
|
|
1607
|
+
const handleSourceChange = (0, import_react10.useCallback)((e) => {
|
|
1365
1608
|
const val = e.target.value;
|
|
1366
1609
|
engine.updateCellSource(cellId, val);
|
|
1367
1610
|
const ta = e.target;
|
|
1368
1611
|
const cursor = ta.selectionStart;
|
|
1369
1612
|
const textBefore = val.slice(0, cursor);
|
|
1370
1613
|
const lastNewline = textBefore.lastIndexOf("\n");
|
|
1371
|
-
const
|
|
1372
|
-
const currentLine = textBefore.slice(lineStart);
|
|
1614
|
+
const currentLine = textBefore.slice(lastNewline + 1);
|
|
1373
1615
|
if (currentLine.startsWith("/")) {
|
|
1374
|
-
const query = currentLine.slice(1);
|
|
1375
1616
|
const rect = ta.getBoundingClientRect();
|
|
1376
|
-
const lineHeight = 22;
|
|
1377
1617
|
const lines = textBefore.split("\n").length;
|
|
1378
|
-
setSlashState({
|
|
1379
|
-
query,
|
|
1380
|
-
pos: { top: rect.top + lines * lineHeight + 4 - ta.scrollTop, left: rect.left + 8 }
|
|
1381
|
-
});
|
|
1618
|
+
setSlashState({ query: currentLine.slice(1), pos: { top: rect.top + lines * 22 + 4 - ta.scrollTop, left: rect.left + 8 } });
|
|
1382
1619
|
} else {
|
|
1383
1620
|
setSlashState(null);
|
|
1384
1621
|
}
|
|
1385
1622
|
}, [engine, cellId]);
|
|
1386
|
-
const enterEdit = (0,
|
|
1623
|
+
const enterEdit = (0, import_react10.useCallback)(() => {
|
|
1387
1624
|
engine.setEditMode(cellId);
|
|
1388
1625
|
engine.focusCell(cellId);
|
|
1389
1626
|
}, [engine, cellId]);
|
|
1390
|
-
const exitEdit = (0,
|
|
1627
|
+
const exitEdit = (0, import_react10.useCallback)(() => {
|
|
1391
1628
|
engine.setViewMode(cellId);
|
|
1392
1629
|
}, [engine, cellId]);
|
|
1393
|
-
const handleSlashSelect = (0,
|
|
1630
|
+
const handleSlashSelect = (0, import_react10.useCallback)((type) => {
|
|
1394
1631
|
const val = cell?.source || "";
|
|
1395
1632
|
const ta = textareaRef.current;
|
|
1396
1633
|
if (ta) {
|
|
1397
1634
|
const cursor = ta.selectionStart;
|
|
1398
1635
|
const textBefore = val.slice(0, cursor);
|
|
1399
|
-
const
|
|
1400
|
-
|
|
1401
|
-
const cleaned = val.slice(0, lineStart) + val.slice(cursor);
|
|
1402
|
-
engine.updateCellSource(cellId, cleaned.trim());
|
|
1636
|
+
const lineStart = textBefore.lastIndexOf("\n") + 1;
|
|
1637
|
+
engine.updateCellSource(cellId, (val.slice(0, lineStart) + val.slice(cursor)).trim());
|
|
1403
1638
|
}
|
|
1404
1639
|
engine.setCellType(cellId, type);
|
|
1405
1640
|
setSlashState(null);
|
|
1406
1641
|
}, [engine, cellId, cell?.source]);
|
|
1407
|
-
const
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1642
|
+
const wrapSelection = (0, import_react10.useCallback)((before, after) => {
|
|
1643
|
+
const ta = textareaRef.current;
|
|
1644
|
+
if (!ta) return;
|
|
1645
|
+
const { selectionStart: start, selectionEnd: end, value: val } = ta;
|
|
1646
|
+
engine.updateCellSource(cellId, val.substring(0, start) + before + val.substring(start, end) + after + val.substring(end));
|
|
1647
|
+
requestAnimationFrame(() => {
|
|
1648
|
+
if (textareaRef.current) {
|
|
1649
|
+
textareaRef.current.selectionStart = start + before.length;
|
|
1650
|
+
textareaRef.current.selectionEnd = end + before.length;
|
|
1414
1651
|
}
|
|
1652
|
+
});
|
|
1653
|
+
}, [engine, cellId]);
|
|
1654
|
+
const handleKeyDown = (0, import_react10.useCallback)((e) => {
|
|
1655
|
+
if (slashState && ["ArrowDown", "ArrowUp", "Enter"].includes(e.key)) return;
|
|
1656
|
+
if (slashState && e.key === "Escape") {
|
|
1657
|
+
e.preventDefault();
|
|
1658
|
+
setSlashState(null);
|
|
1659
|
+
return;
|
|
1415
1660
|
}
|
|
1416
1661
|
if (e.key === "Escape") {
|
|
1417
1662
|
e.preventDefault();
|
|
@@ -1432,30 +1677,24 @@ var Cell = ({ cellId, pipeline, index, totalCells }) => {
|
|
|
1432
1677
|
e.preventDefault();
|
|
1433
1678
|
const ta = e.currentTarget;
|
|
1434
1679
|
const start = ta.selectionStart;
|
|
1435
|
-
|
|
1436
|
-
const val = ta.value;
|
|
1437
|
-
const newVal = val.substring(0, start) + " " + val.substring(end);
|
|
1438
|
-
engine.updateCellSource(cellId, newVal);
|
|
1680
|
+
engine.updateCellSource(cellId, ta.value.substring(0, start) + " " + ta.value.substring(ta.selectionEnd));
|
|
1439
1681
|
requestAnimationFrame(() => {
|
|
1440
1682
|
if (textareaRef.current) {
|
|
1441
|
-
textareaRef.current.selectionStart = start + 2;
|
|
1442
|
-
textareaRef.current.selectionEnd = start + 2;
|
|
1683
|
+
textareaRef.current.selectionStart = textareaRef.current.selectionEnd = start + 2;
|
|
1443
1684
|
}
|
|
1444
1685
|
});
|
|
1445
1686
|
} else if (e.key === "Tab" && e.shiftKey) {
|
|
1446
1687
|
e.preventDefault();
|
|
1447
1688
|
const ta = e.currentTarget;
|
|
1448
1689
|
const start = ta.selectionStart;
|
|
1449
|
-
const
|
|
1450
|
-
const before = val.substring(0, start);
|
|
1690
|
+
const before = ta.value.substring(0, start);
|
|
1451
1691
|
const trimmed = before.replace(/ $/, "");
|
|
1452
1692
|
if (trimmed !== before) {
|
|
1453
|
-
engine.updateCellSource(cellId, trimmed + val.substring(start));
|
|
1454
1693
|
const diff = before.length - trimmed.length;
|
|
1694
|
+
engine.updateCellSource(cellId, trimmed + ta.value.substring(start));
|
|
1455
1695
|
requestAnimationFrame(() => {
|
|
1456
1696
|
if (textareaRef.current) {
|
|
1457
|
-
textareaRef.current.selectionStart = start - diff;
|
|
1458
|
-
textareaRef.current.selectionEnd = start - diff;
|
|
1697
|
+
textareaRef.current.selectionStart = textareaRef.current.selectionEnd = start - diff;
|
|
1459
1698
|
}
|
|
1460
1699
|
});
|
|
1461
1700
|
}
|
|
@@ -1466,27 +1705,12 @@ var Cell = ({ cellId, pipeline, index, totalCells }) => {
|
|
|
1466
1705
|
e.preventDefault();
|
|
1467
1706
|
wrapSelection("*", "*");
|
|
1468
1707
|
}
|
|
1469
|
-
}, [engine, cellId, exitEdit]);
|
|
1470
|
-
const wrapSelection = (0, import_react9.useCallback)((before, after) => {
|
|
1471
|
-
const ta = textareaRef.current;
|
|
1472
|
-
if (!ta) return;
|
|
1473
|
-
const start = ta.selectionStart;
|
|
1474
|
-
const end = ta.selectionEnd;
|
|
1475
|
-
const val = ta.value;
|
|
1476
|
-
const newVal = val.substring(0, start) + before + val.substring(start, end) + after + val.substring(end);
|
|
1477
|
-
engine.updateCellSource(cellId, newVal);
|
|
1478
|
-
requestAnimationFrame(() => {
|
|
1479
|
-
if (textareaRef.current) {
|
|
1480
|
-
textareaRef.current.selectionStart = start + before.length;
|
|
1481
|
-
textareaRef.current.selectionEnd = end + before.length;
|
|
1482
|
-
}
|
|
1483
|
-
});
|
|
1484
|
-
}, [engine, cellId]);
|
|
1708
|
+
}, [engine, cellId, exitEdit, slashState, wrapSelection]);
|
|
1485
1709
|
if (!cell) return null;
|
|
1486
1710
|
const isEditing = !!cell.editing;
|
|
1487
1711
|
const isEmpty = !cell.source.trim();
|
|
1488
1712
|
const placeholder = PLACEHOLDERS[cell.type] || "Click to edit...";
|
|
1489
|
-
return /* @__PURE__ */ (0,
|
|
1713
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1490
1714
|
"div",
|
|
1491
1715
|
{
|
|
1492
1716
|
ref: cellRef,
|
|
@@ -1513,18 +1737,14 @@ var Cell = ({ cellId, pipeline, index, totalCells }) => {
|
|
|
1513
1737
|
e.preventDefault();
|
|
1514
1738
|
e.dataTransfer.dropEffect = "move";
|
|
1515
1739
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
1516
|
-
|
|
1517
|
-
setDragOver(e.clientY < midY ? "top" : "bottom");
|
|
1740
|
+
setDragOver(e.clientY < rect.top + rect.height / 2 ? "top" : "bottom");
|
|
1518
1741
|
},
|
|
1519
1742
|
onDragLeave: () => setDragOver(null),
|
|
1520
1743
|
onDrop: (e) => {
|
|
1521
1744
|
e.preventDefault();
|
|
1522
|
-
const
|
|
1745
|
+
const did = e.dataTransfer.getData("text/plain");
|
|
1523
1746
|
setDragOver(null);
|
|
1524
|
-
if (
|
|
1525
|
-
const targetIdx = dragOver === "top" ? index : index + 1;
|
|
1526
|
-
engine.moveCell(draggedId, targetIdx);
|
|
1527
|
-
}
|
|
1747
|
+
if (did && did !== cellId) engine.moveCell(did, dragOver === "top" ? index : index + 1);
|
|
1528
1748
|
},
|
|
1529
1749
|
"data-testid": `cell-${cell.id}`,
|
|
1530
1750
|
"data-editing": String(isEditing),
|
|
@@ -1537,35 +1757,27 @@ var Cell = ({ cellId, pipeline, index, totalCells }) => {
|
|
|
1537
1757
|
onMouseLeave: () => setHovered(false),
|
|
1538
1758
|
onClick: () => engine.focusCell(cellId),
|
|
1539
1759
|
children: [
|
|
1540
|
-
/* @__PURE__ */ (0,
|
|
1541
|
-
/* @__PURE__ */ (0,
|
|
1542
|
-
/* @__PURE__ */ (0,
|
|
1543
|
-
/* @__PURE__ */ (0,
|
|
1544
|
-
/* @__PURE__ */ (0,
|
|
1545
|
-
/* @__PURE__ */ (0,
|
|
1546
|
-
/* @__PURE__ */ (0,
|
|
1547
|
-
/* @__PURE__ */ (0,
|
|
1760
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "sci-nb-cell-gutter", children: [
|
|
1761
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "sci-nb-cell-handle", title: "Drag to reorder", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { width: "12", height: "20", viewBox: "0 0 12 20", fill: "currentColor", children: [
|
|
1762
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "3", cy: "4", r: "1.5" }),
|
|
1763
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "9", cy: "4", r: "1.5" }),
|
|
1764
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "3", cy: "10", r: "1.5" }),
|
|
1765
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "9", cy: "10", r: "1.5" }),
|
|
1766
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "3", cy: "16", r: "1.5" }),
|
|
1767
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: "9", cy: "16", r: "1.5" })
|
|
1548
1768
|
] }) }),
|
|
1549
|
-
/* @__PURE__ */ (0,
|
|
1769
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "sci-nb-cell-index", children: [
|
|
1550
1770
|
"[",
|
|
1551
1771
|
index + 1,
|
|
1552
1772
|
"]"
|
|
1553
1773
|
] })
|
|
1554
1774
|
] }),
|
|
1555
|
-
/* @__PURE__ */ (0,
|
|
1556
|
-
/* @__PURE__ */ (0,
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
e.stopPropagation();
|
|
1562
|
-
setShowTypeMenu(!showTypeMenu);
|
|
1563
|
-
},
|
|
1564
|
-
title: "Change cell type",
|
|
1565
|
-
children: CELL_TYPES.find((ct) => ct.value === cell.type)?.icon || cell.type.slice(0, 2).toUpperCase()
|
|
1566
|
-
}
|
|
1567
|
-
),
|
|
1568
|
-
showTypeMenu && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "sci-nb-type-menu", children: CELL_TYPES.map((ct) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1775
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "sci-nb-cell-badge-wrap", children: [
|
|
1776
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { className: "sci-nb-cell-badge", onClick: (e) => {
|
|
1777
|
+
e.stopPropagation();
|
|
1778
|
+
setShowTypeMenu(!showTypeMenu);
|
|
1779
|
+
}, title: "Change cell type", children: CELL_TYPES.find((ct) => ct.value === cell.type)?.icon || cell.type.slice(0, 2).toUpperCase() }),
|
|
1780
|
+
showTypeMenu && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "sci-nb-type-menu", children: CELL_TYPES.map((ct) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1569
1781
|
"button",
|
|
1570
1782
|
{
|
|
1571
1783
|
className: `sci-nb-type-option ${cell.type === ct.value ? "sci-nb-type-option--active" : ""}`,
|
|
@@ -1575,173 +1787,46 @@ var Cell = ({ cellId, pipeline, index, totalCells }) => {
|
|
|
1575
1787
|
setShowTypeMenu(false);
|
|
1576
1788
|
},
|
|
1577
1789
|
children: [
|
|
1578
|
-
/* @__PURE__ */ (0,
|
|
1790
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "sci-nb-type-option-icon", children: ct.icon }),
|
|
1579
1791
|
ct.label
|
|
1580
1792
|
]
|
|
1581
1793
|
},
|
|
1582
1794
|
ct.value
|
|
1583
1795
|
)) })
|
|
1584
1796
|
] }),
|
|
1585
|
-
/* @__PURE__ */ (0,
|
|
1586
|
-
isEditing ? renderEditMode(cell, cellId, textareaRef, handleSourceChange, handleKeyDown, placeholder, exitEdit, slashState, handleSlashSelect, () => setSlashState(null)) : renderViewMode(cell, rendered.html, isEmpty, placeholder, enterEdit),
|
|
1587
|
-
cell.outputs && cell.outputs.length > 0 && /* @__PURE__ */ (0,
|
|
1797
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "sci-nb-cell-content", children: [
|
|
1798
|
+
isEditing ? renderEditMode(cell, cellId, engine, textareaRef, handleSourceChange, handleKeyDown, placeholder, exitEdit, slashState, handleSlashSelect, () => setSlashState(null)) : renderViewMode(cell, rendered.html, isEmpty, placeholder, enterEdit),
|
|
1799
|
+
cell.outputs && cell.outputs.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CellOutputDisplay, { outputs: cell.outputs })
|
|
1588
1800
|
] }),
|
|
1589
|
-
/* @__PURE__ */ (0,
|
|
1590
|
-
/* @__PURE__ */ (0,
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
engine.moveCell(cellId, index + 1);
|
|
1610
|
-
},
|
|
1611
|
-
disabled: index >= totalCells - 1,
|
|
1612
|
-
title: "Move down",
|
|
1613
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M7 3v8M7 11l-4-4M7 11l4-4", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
1614
|
-
}
|
|
1615
|
-
),
|
|
1616
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1617
|
-
"button",
|
|
1618
|
-
{
|
|
1619
|
-
className: "sci-nb-btn",
|
|
1620
|
-
onClick: (e) => {
|
|
1621
|
-
e.stopPropagation();
|
|
1622
|
-
engine.duplicateCell(cellId);
|
|
1623
|
-
},
|
|
1624
|
-
title: "Duplicate cell",
|
|
1625
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
|
|
1626
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5" }),
|
|
1627
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M10 2H3.5A1.5 1.5 0 002 3.5V10" })
|
|
1628
|
-
] })
|
|
1629
|
-
}
|
|
1630
|
-
),
|
|
1631
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1632
|
-
"button",
|
|
1633
|
-
{
|
|
1634
|
-
className: "sci-nb-btn sci-nb-btn--danger",
|
|
1635
|
-
onClick: (e) => {
|
|
1636
|
-
e.stopPropagation();
|
|
1637
|
-
engine.deleteCell(cellId);
|
|
1638
|
-
},
|
|
1639
|
-
title: "Delete cell",
|
|
1640
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M3 4h8M5.5 4V3a1 1 0 011-1h1a1 1 0 011 1v1M6 6.5v3M8 6.5v3M4 4l.5 7a1.5 1.5 0 001.5 1.5h2A1.5 1.5 0 0010 11l.5-7", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
1641
|
-
}
|
|
1642
|
-
)
|
|
1801
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "sci-nb-cell-actions", children: [
|
|
1802
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { className: "sci-nb-btn", onClick: (e) => {
|
|
1803
|
+
e.stopPropagation();
|
|
1804
|
+
engine.moveCell(cellId, index - 1);
|
|
1805
|
+
}, disabled: index === 0, title: "Move up", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M7 11V3M7 3L3 7M7 3l4 4", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
|
|
1806
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { className: "sci-nb-btn", onClick: (e) => {
|
|
1807
|
+
e.stopPropagation();
|
|
1808
|
+
engine.moveCell(cellId, index + 1);
|
|
1809
|
+
}, disabled: index >= totalCells - 1, title: "Move down", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M7 3v8M7 11l-4-4M7 11l4-4", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
|
|
1810
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { className: "sci-nb-btn", onClick: (e) => {
|
|
1811
|
+
e.stopPropagation();
|
|
1812
|
+
engine.duplicateCell(cellId);
|
|
1813
|
+
}, title: "Duplicate cell", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
|
|
1814
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5" }),
|
|
1815
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M10 2H3.5A1.5 1.5 0 002 3.5V10" })
|
|
1816
|
+
] }) }),
|
|
1817
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { className: "sci-nb-btn sci-nb-btn--danger", onClick: (e) => {
|
|
1818
|
+
e.stopPropagation();
|
|
1819
|
+
engine.deleteCell(cellId);
|
|
1820
|
+
}, title: "Delete cell", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M3 4h8M5.5 4V3a1 1 0 011-1h1a1 1 0 011 1v1M6 6.5v3M8 6.5v3M4 4l.5 7a1.5 1.5 0 001.5 1.5h2A1.5 1.5 0 0010 11l.5-7", strokeLinecap: "round", strokeLinejoin: "round" }) }) })
|
|
1643
1821
|
] })
|
|
1644
1822
|
]
|
|
1645
1823
|
}
|
|
1646
1824
|
);
|
|
1647
1825
|
};
|
|
1648
|
-
function renderEditMode(cell, cellId, textareaRef, handleSourceChange, handleKeyDown, placeholder, exitEdit, slashState, onSlashSelect, onSlashClose) {
|
|
1649
|
-
if (cell.type === "latex") {
|
|
1650
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MathEditor, { cellId, source: cell.source, onExit: exitEdit });
|
|
1651
|
-
}
|
|
1652
|
-
if (cell.type === "image") {
|
|
1653
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ImageCell, { cellId, source: cell.source, metadata: cell.metadata, onExit: exitEdit });
|
|
1654
|
-
}
|
|
1655
|
-
if (cell.type === "embed") {
|
|
1656
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(EmbedCell, { cellId, source: cell.source, metadata: cell.metadata, onExit: exitEdit });
|
|
1657
|
-
}
|
|
1658
|
-
if (cell.type === "table") {
|
|
1659
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TableCell, { cellId, source: cell.source, metadata: cell.metadata, onExit: exitEdit });
|
|
1660
|
-
}
|
|
1661
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
1662
|
-
cell.type === "markdown" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FloatingToolbar, { cellId, textareaRef }),
|
|
1663
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1664
|
-
"textarea",
|
|
1665
|
-
{
|
|
1666
|
-
ref: textareaRef,
|
|
1667
|
-
className: "sci-nb-editor",
|
|
1668
|
-
value: cell.source,
|
|
1669
|
-
onChange: handleSourceChange,
|
|
1670
|
-
onKeyDown: handleKeyDown,
|
|
1671
|
-
placeholder,
|
|
1672
|
-
spellCheck: cell.type === "markdown",
|
|
1673
|
-
rows: 1
|
|
1674
|
-
}
|
|
1675
|
-
),
|
|
1676
|
-
slashState && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1677
|
-
SlashCommand,
|
|
1678
|
-
{
|
|
1679
|
-
position: slashState.pos,
|
|
1680
|
-
query: slashState.query,
|
|
1681
|
-
onSelect: onSlashSelect,
|
|
1682
|
-
onClose: onSlashClose
|
|
1683
|
-
}
|
|
1684
|
-
),
|
|
1685
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "sci-nb-cell-hint", children: [
|
|
1686
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("kbd", { children: "/" }),
|
|
1687
|
-
" comandos \xB7 ",
|
|
1688
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("kbd", { children: "Shift+Enter" }),
|
|
1689
|
-
" siguiente \xB7 ",
|
|
1690
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("kbd", { children: "Esc" }),
|
|
1691
|
-
" salir"
|
|
1692
|
-
] })
|
|
1693
|
-
] });
|
|
1694
|
-
}
|
|
1695
|
-
function renderViewMode(cell, renderedHtml, isEmpty, placeholder, enterEdit) {
|
|
1696
|
-
if (cell.type === "image") {
|
|
1697
|
-
const html = renderImagePreview(cell.source, cell.metadata);
|
|
1698
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1699
|
-
"div",
|
|
1700
|
-
{
|
|
1701
|
-
className: "sci-nb-preview",
|
|
1702
|
-
onClick: enterEdit,
|
|
1703
|
-
dangerouslySetInnerHTML: { __html: html }
|
|
1704
|
-
}
|
|
1705
|
-
);
|
|
1706
|
-
}
|
|
1707
|
-
if (cell.type === "embed") {
|
|
1708
|
-
const html = renderEmbedPreview(cell.source, cell.metadata);
|
|
1709
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1710
|
-
"div",
|
|
1711
|
-
{
|
|
1712
|
-
className: "sci-nb-preview sci-nb-preview--embed",
|
|
1713
|
-
onClick: enterEdit,
|
|
1714
|
-
dangerouslySetInnerHTML: { __html: html }
|
|
1715
|
-
}
|
|
1716
|
-
);
|
|
1717
|
-
}
|
|
1718
|
-
if (cell.type === "table") {
|
|
1719
|
-
const html = renderTablePreview(cell.source);
|
|
1720
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1721
|
-
"div",
|
|
1722
|
-
{
|
|
1723
|
-
className: "sci-nb-preview",
|
|
1724
|
-
onClick: enterEdit,
|
|
1725
|
-
dangerouslySetInnerHTML: { __html: html }
|
|
1726
|
-
}
|
|
1727
|
-
);
|
|
1728
|
-
}
|
|
1729
|
-
if (cell.type === "mermaid") {
|
|
1730
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MermaidPreview, { source: cell.source, onClick: enterEdit });
|
|
1731
|
-
}
|
|
1732
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1733
|
-
"div",
|
|
1734
|
-
{
|
|
1735
|
-
className: `sci-nb-preview ${isEmpty ? "sci-nb-preview--empty" : ""}`,
|
|
1736
|
-
onClick: enterEdit,
|
|
1737
|
-
dangerouslySetInnerHTML: isEmpty ? { __html: `<span class="sci-nb-placeholder">${placeholder}</span>` } : { __html: renderedHtml }
|
|
1738
|
-
}
|
|
1739
|
-
);
|
|
1740
|
-
}
|
|
1741
1826
|
|
|
1742
1827
|
// src/components/InsertHandle.tsx
|
|
1743
|
-
var
|
|
1744
|
-
var
|
|
1828
|
+
var import_react11 = require("react");
|
|
1829
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1745
1830
|
var INSERT_TYPES = [
|
|
1746
1831
|
{ type: "markdown", label: "Markdown", icon: "M" },
|
|
1747
1832
|
{ type: "code", label: "Code", icon: "</>" },
|
|
@@ -1752,9 +1837,9 @@ var INSERT_TYPES = [
|
|
|
1752
1837
|
];
|
|
1753
1838
|
var InsertHandle = ({ index }) => {
|
|
1754
1839
|
const engine = useSciNotebook();
|
|
1755
|
-
const [open, setOpen] = (0,
|
|
1756
|
-
const menuRef = (0,
|
|
1757
|
-
(0,
|
|
1840
|
+
const [open, setOpen] = (0, import_react11.useState)(false);
|
|
1841
|
+
const menuRef = (0, import_react11.useRef)(null);
|
|
1842
|
+
(0, import_react11.useEffect)(() => {
|
|
1758
1843
|
if (!open) return;
|
|
1759
1844
|
const onClickOutside = (e) => {
|
|
1760
1845
|
if (menuRef.current && !menuRef.current.contains(e.target)) {
|
|
@@ -1775,27 +1860,27 @@ var InsertHandle = ({ index }) => {
|
|
|
1775
1860
|
}
|
|
1776
1861
|
});
|
|
1777
1862
|
};
|
|
1778
|
-
return /* @__PURE__ */ (0,
|
|
1779
|
-
/* @__PURE__ */ (0,
|
|
1863
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "sci-nb-insert-handle", ref: menuRef, children: [
|
|
1864
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "sci-nb-insert-line", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1780
1865
|
"button",
|
|
1781
1866
|
{
|
|
1782
1867
|
className: "sci-nb-insert-btn",
|
|
1783
1868
|
onClick: () => setOpen(!open),
|
|
1784
1869
|
title: "Insert cell",
|
|
1785
|
-
children: /* @__PURE__ */ (0,
|
|
1786
|
-
/* @__PURE__ */ (0,
|
|
1787
|
-
/* @__PURE__ */ (0,
|
|
1870
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: [
|
|
1871
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("line", { x1: "8", y1: "3", x2: "8", y2: "13", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
|
|
1872
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("line", { x1: "3", y1: "8", x2: "13", y2: "8", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
1788
1873
|
] })
|
|
1789
1874
|
}
|
|
1790
1875
|
) }),
|
|
1791
|
-
open && /* @__PURE__ */ (0,
|
|
1876
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "sci-nb-insert-menu", children: INSERT_TYPES.map((ct) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
1792
1877
|
"button",
|
|
1793
1878
|
{
|
|
1794
1879
|
className: "sci-nb-insert-option",
|
|
1795
1880
|
onClick: () => handleInsert(ct.type),
|
|
1796
1881
|
children: [
|
|
1797
|
-
/* @__PURE__ */ (0,
|
|
1798
|
-
/* @__PURE__ */ (0,
|
|
1882
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "sci-nb-insert-option-icon", children: ct.icon }),
|
|
1883
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: ct.label })
|
|
1799
1884
|
]
|
|
1800
1885
|
},
|
|
1801
1886
|
ct.type
|
|
@@ -1804,12 +1889,12 @@ var InsertHandle = ({ index }) => {
|
|
|
1804
1889
|
};
|
|
1805
1890
|
|
|
1806
1891
|
// src/components/TOCSidebar.tsx
|
|
1807
|
-
var
|
|
1808
|
-
var
|
|
1892
|
+
var import_react12 = require("react");
|
|
1893
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1809
1894
|
var TOCSidebar = ({ focusedCellId }) => {
|
|
1810
1895
|
const notebook = useNotebook();
|
|
1811
1896
|
const engine = useSciNotebook();
|
|
1812
|
-
const items = (0,
|
|
1897
|
+
const items = (0, import_react12.useMemo)(() => {
|
|
1813
1898
|
if (!notebook) return [];
|
|
1814
1899
|
const result = [];
|
|
1815
1900
|
for (const cell of notebook.cells) {
|
|
@@ -1828,16 +1913,16 @@ var TOCSidebar = ({ focusedCellId }) => {
|
|
|
1828
1913
|
}
|
|
1829
1914
|
return result;
|
|
1830
1915
|
}, [notebook]);
|
|
1831
|
-
const handleClick = (0,
|
|
1916
|
+
const handleClick = (0, import_react12.useCallback)((cellId) => {
|
|
1832
1917
|
engine.focusCell(cellId);
|
|
1833
1918
|
engine.setEditMode(cellId);
|
|
1834
1919
|
const el = document.querySelector(`[data-testid="cell-${cellId}"]`);
|
|
1835
1920
|
if (el) el.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
1836
1921
|
}, [engine]);
|
|
1837
1922
|
if (items.length === 0) return null;
|
|
1838
|
-
return /* @__PURE__ */ (0,
|
|
1839
|
-
/* @__PURE__ */ (0,
|
|
1840
|
-
items.map((item, i) => /* @__PURE__ */ (0,
|
|
1923
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("nav", { className: "sci-nb-toc", children: [
|
|
1924
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "sci-nb-toc-title", children: "Contenido" }),
|
|
1925
|
+
items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1841
1926
|
"button",
|
|
1842
1927
|
{
|
|
1843
1928
|
className: [
|
|
@@ -1855,21 +1940,21 @@ var TOCSidebar = ({ focusedCellId }) => {
|
|
|
1855
1940
|
};
|
|
1856
1941
|
|
|
1857
1942
|
// src/components/FindReplace.tsx
|
|
1858
|
-
var
|
|
1859
|
-
var
|
|
1943
|
+
var import_react13 = require("react");
|
|
1944
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1860
1945
|
var FindReplace = ({ onClose }) => {
|
|
1861
1946
|
const notebook = useNotebook();
|
|
1862
1947
|
const engine = useSciNotebook();
|
|
1863
|
-
const [query, setQuery] = (0,
|
|
1864
|
-
const [replacement, setReplacement] = (0,
|
|
1865
|
-
const [showReplace, setShowReplace] = (0,
|
|
1866
|
-
const [caseSensitive, setCaseSensitive] = (0,
|
|
1867
|
-
const [currentIdx, setCurrentIdx] = (0,
|
|
1868
|
-
const inputRef = (0,
|
|
1869
|
-
(0,
|
|
1948
|
+
const [query, setQuery] = (0, import_react13.useState)("");
|
|
1949
|
+
const [replacement, setReplacement] = (0, import_react13.useState)("");
|
|
1950
|
+
const [showReplace, setShowReplace] = (0, import_react13.useState)(false);
|
|
1951
|
+
const [caseSensitive, setCaseSensitive] = (0, import_react13.useState)(false);
|
|
1952
|
+
const [currentIdx, setCurrentIdx] = (0, import_react13.useState)(0);
|
|
1953
|
+
const inputRef = (0, import_react13.useRef)(null);
|
|
1954
|
+
(0, import_react13.useEffect)(() => {
|
|
1870
1955
|
inputRef.current?.focus();
|
|
1871
1956
|
}, []);
|
|
1872
|
-
const matches = (0,
|
|
1957
|
+
const matches = (0, import_react13.useMemo)(() => {
|
|
1873
1958
|
if (!query || !notebook) return [];
|
|
1874
1959
|
const result = [];
|
|
1875
1960
|
const q = caseSensitive ? query : query.toLowerCase();
|
|
@@ -1885,27 +1970,27 @@ var FindReplace = ({ onClose }) => {
|
|
|
1885
1970
|
}
|
|
1886
1971
|
return result;
|
|
1887
1972
|
}, [query, notebook, caseSensitive]);
|
|
1888
|
-
(0,
|
|
1973
|
+
(0, import_react13.useEffect)(() => {
|
|
1889
1974
|
setCurrentIdx(0);
|
|
1890
1975
|
}, [query, caseSensitive]);
|
|
1891
|
-
const navigateToMatch = (0,
|
|
1976
|
+
const navigateToMatch = (0, import_react13.useCallback)((match) => {
|
|
1892
1977
|
engine.focusCell(match.cellId);
|
|
1893
1978
|
const el = document.querySelector(`[data-testid="cell-${match.cellId}"]`);
|
|
1894
1979
|
if (el) el.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
1895
1980
|
}, [engine]);
|
|
1896
|
-
const goNext = (0,
|
|
1981
|
+
const goNext = (0, import_react13.useCallback)(() => {
|
|
1897
1982
|
if (matches.length === 0) return;
|
|
1898
1983
|
const next = (currentIdx + 1) % matches.length;
|
|
1899
1984
|
setCurrentIdx(next);
|
|
1900
1985
|
navigateToMatch(matches[next]);
|
|
1901
1986
|
}, [matches, currentIdx, navigateToMatch]);
|
|
1902
|
-
const goPrev = (0,
|
|
1987
|
+
const goPrev = (0, import_react13.useCallback)(() => {
|
|
1903
1988
|
if (matches.length === 0) return;
|
|
1904
1989
|
const prev = (currentIdx - 1 + matches.length) % matches.length;
|
|
1905
1990
|
setCurrentIdx(prev);
|
|
1906
1991
|
navigateToMatch(matches[prev]);
|
|
1907
1992
|
}, [matches, currentIdx, navigateToMatch]);
|
|
1908
|
-
const replaceCurrent = (0,
|
|
1993
|
+
const replaceCurrent = (0, import_react13.useCallback)(() => {
|
|
1909
1994
|
if (matches.length === 0) return;
|
|
1910
1995
|
const match = matches[currentIdx];
|
|
1911
1996
|
if (!match) return;
|
|
@@ -1914,7 +1999,7 @@ var FindReplace = ({ onClose }) => {
|
|
|
1914
1999
|
const newSource = cell.source.slice(0, match.index) + replacement + cell.source.slice(match.index + match.length);
|
|
1915
2000
|
engine.updateCellSource(match.cellId, newSource);
|
|
1916
2001
|
}, [matches, currentIdx, replacement, notebook, engine]);
|
|
1917
|
-
const replaceAll = (0,
|
|
2002
|
+
const replaceAll = (0, import_react13.useCallback)(() => {
|
|
1918
2003
|
if (matches.length === 0 || !notebook) return;
|
|
1919
2004
|
const byCellId = /* @__PURE__ */ new Map();
|
|
1920
2005
|
for (const m of matches) {
|
|
@@ -1933,7 +2018,7 @@ var FindReplace = ({ onClose }) => {
|
|
|
1933
2018
|
engine.updateCellSource(cellId, src);
|
|
1934
2019
|
}
|
|
1935
2020
|
}, [matches, replacement, notebook, engine]);
|
|
1936
|
-
const handleKeyDown = (0,
|
|
2021
|
+
const handleKeyDown = (0, import_react13.useCallback)((e) => {
|
|
1937
2022
|
if (e.key === "Escape") {
|
|
1938
2023
|
e.preventDefault();
|
|
1939
2024
|
onClose();
|
|
@@ -1946,21 +2031,21 @@ var FindReplace = ({ onClose }) => {
|
|
|
1946
2031
|
setShowReplace((v) => !v);
|
|
1947
2032
|
}
|
|
1948
2033
|
}, [onClose, goNext, goPrev]);
|
|
1949
|
-
return /* @__PURE__ */ (0,
|
|
1950
|
-
/* @__PURE__ */ (0,
|
|
2034
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "sci-nb-find-bar", onKeyDown: handleKeyDown, children: [
|
|
2035
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1951
2036
|
"input",
|
|
1952
2037
|
{
|
|
1953
2038
|
ref: inputRef,
|
|
1954
2039
|
type: "text",
|
|
1955
2040
|
value: query,
|
|
1956
2041
|
onChange: (e) => setQuery(e.target.value),
|
|
1957
|
-
placeholder: "
|
|
2042
|
+
placeholder: "Search..."
|
|
1958
2043
|
}
|
|
1959
2044
|
),
|
|
1960
|
-
/* @__PURE__ */ (0,
|
|
1961
|
-
/* @__PURE__ */ (0,
|
|
1962
|
-
/* @__PURE__ */ (0,
|
|
1963
|
-
/* @__PURE__ */ (0,
|
|
2045
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "sci-nb-find-count", children: matches.length > 0 ? `${currentIdx + 1}/${matches.length}` : query ? "0" : "" }),
|
|
2046
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { onClick: goPrev, title: "Previous (Shift+Enter)", children: "\u25B2" }),
|
|
2047
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { onClick: goNext, title: "Next (Enter)", children: "\u25BC" }),
|
|
2048
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1964
2049
|
"button",
|
|
1965
2050
|
{
|
|
1966
2051
|
onClick: () => setCaseSensitive((v) => !v),
|
|
@@ -1969,29 +2054,29 @@ var FindReplace = ({ onClose }) => {
|
|
|
1969
2054
|
children: "Aa"
|
|
1970
2055
|
}
|
|
1971
2056
|
),
|
|
1972
|
-
/* @__PURE__ */ (0,
|
|
2057
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("button", { onClick: () => setShowReplace((v) => !v), title: "Replace (Ctrl+H)", children: [
|
|
1973
2058
|
showReplace ? "\u25BE" : "\u25B8",
|
|
1974
|
-
"
|
|
2059
|
+
" Replace"
|
|
1975
2060
|
] }),
|
|
1976
|
-
showReplace && /* @__PURE__ */ (0,
|
|
1977
|
-
/* @__PURE__ */ (0,
|
|
2061
|
+
showReplace && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
2062
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1978
2063
|
"input",
|
|
1979
2064
|
{
|
|
1980
2065
|
type: "text",
|
|
1981
2066
|
value: replacement,
|
|
1982
2067
|
onChange: (e) => setReplacement(e.target.value),
|
|
1983
|
-
placeholder: "
|
|
2068
|
+
placeholder: "Replace with..."
|
|
1984
2069
|
}
|
|
1985
2070
|
),
|
|
1986
|
-
/* @__PURE__ */ (0,
|
|
1987
|
-
/* @__PURE__ */ (0,
|
|
2071
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { onClick: replaceCurrent, title: "Replace current", children: "1" }),
|
|
2072
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { onClick: replaceAll, title: "Replace all", children: "\u2200" })
|
|
1988
2073
|
] }),
|
|
1989
|
-
/* @__PURE__ */ (0,
|
|
2074
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { onClick: onClose, title: "Close (Esc)", children: "\u2715" })
|
|
1990
2075
|
] });
|
|
1991
2076
|
};
|
|
1992
2077
|
|
|
1993
2078
|
// src/components/SciNotebook.tsx
|
|
1994
|
-
var
|
|
2079
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1995
2080
|
var SciNotebook = ({
|
|
1996
2081
|
notebook: initialNotebook,
|
|
1997
2082
|
engine: providedEngine,
|
|
@@ -2007,7 +2092,7 @@ var SciNotebook = ({
|
|
|
2007
2092
|
engineRef,
|
|
2008
2093
|
showTOC: showTOCProp = false
|
|
2009
2094
|
}) => {
|
|
2010
|
-
const engine = (0,
|
|
2095
|
+
const engine = (0, import_react14.useMemo)(() => {
|
|
2011
2096
|
if (providedEngine) return providedEngine;
|
|
2012
2097
|
if (initialContent && !initialNotebook) {
|
|
2013
2098
|
const cells2 = parseInitialContent(initialContent);
|
|
@@ -2026,37 +2111,37 @@ var SciNotebook = ({
|
|
|
2026
2111
|
}
|
|
2027
2112
|
return (0, import_notebook_core.createNotebook)({ notebook: initialNotebook, config: { plugins } });
|
|
2028
2113
|
}, [providedEngine]);
|
|
2029
|
-
(0,
|
|
2114
|
+
(0, import_react14.useEffect)(() => {
|
|
2030
2115
|
if (engineRef) engineRef.current = engine;
|
|
2031
2116
|
return () => {
|
|
2032
2117
|
if (engineRef) engineRef.current = null;
|
|
2033
2118
|
};
|
|
2034
2119
|
}, [engine, engineRef]);
|
|
2035
|
-
const [notebook, setNotebook] = (0,
|
|
2036
|
-
(0,
|
|
2120
|
+
const [notebook, setNotebook] = (0, import_react14.useState)(initialNotebook || engine.getNotebook());
|
|
2121
|
+
(0, import_react14.useEffect)(() => {
|
|
2037
2122
|
const unsub = engine.on("notebook:updated", (payload) => {
|
|
2038
2123
|
setNotebook(payload.data.notebook);
|
|
2039
2124
|
if (onChange) onChange(payload.data.notebook);
|
|
2040
2125
|
});
|
|
2041
2126
|
return unsub;
|
|
2042
2127
|
}, [engine, onChange]);
|
|
2043
|
-
(0,
|
|
2128
|
+
(0, import_react14.useEffect)(() => {
|
|
2044
2129
|
if (!onCellFocus) return;
|
|
2045
2130
|
return engine.on("cell:focused", (payload) => {
|
|
2046
2131
|
onCellFocus(payload.data.cellId);
|
|
2047
2132
|
});
|
|
2048
2133
|
}, [engine, onCellFocus]);
|
|
2049
|
-
const pipeline = (0,
|
|
2134
|
+
const pipeline = (0, import_react14.useMemo)(() => new import_notebook_renderer2.RenderPipeline(), []);
|
|
2050
2135
|
const cells = notebook.cells;
|
|
2051
|
-
const [showFind, setShowFind] = (0,
|
|
2052
|
-
const [showTOC, setShowTOC] = (0,
|
|
2053
|
-
const [focusedCellId, setFocusedCellId] = (0,
|
|
2054
|
-
(0,
|
|
2136
|
+
const [showFind, setShowFind] = (0, import_react14.useState)(false);
|
|
2137
|
+
const [showTOC, setShowTOC] = (0, import_react14.useState)(showTOCProp);
|
|
2138
|
+
const [focusedCellId, setFocusedCellId] = (0, import_react14.useState)(null);
|
|
2139
|
+
(0, import_react14.useEffect)(() => {
|
|
2055
2140
|
return engine.on("cell:focused", (payload) => {
|
|
2056
2141
|
setFocusedCellId(payload.data.cellId);
|
|
2057
2142
|
});
|
|
2058
2143
|
}, [engine]);
|
|
2059
|
-
const handleGlobalKeyDown = (0,
|
|
2144
|
+
const handleGlobalKeyDown = (0, import_react14.useCallback)((e) => {
|
|
2060
2145
|
if (readOnly) return;
|
|
2061
2146
|
if ((e.ctrlKey || e.metaKey) && e.key === "f") {
|
|
2062
2147
|
e.preventDefault();
|
|
@@ -2065,7 +2150,7 @@ var SciNotebook = ({
|
|
|
2065
2150
|
}
|
|
2066
2151
|
engine.handleKeyDown(e.nativeEvent);
|
|
2067
2152
|
}, [engine, readOnly]);
|
|
2068
|
-
return /* @__PURE__ */ (0,
|
|
2153
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(NotebookContext.Provider, { value: engine, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2069
2154
|
"div",
|
|
2070
2155
|
{
|
|
2071
2156
|
className: `sci-nb ${className || ""}`,
|
|
@@ -2074,10 +2159,10 @@ var SciNotebook = ({
|
|
|
2074
2159
|
onKeyDown: handleGlobalKeyDown,
|
|
2075
2160
|
tabIndex: 0,
|
|
2076
2161
|
children: [
|
|
2077
|
-
showToolbar && /* @__PURE__ */ (0,
|
|
2078
|
-
/* @__PURE__ */ (0,
|
|
2079
|
-
/* @__PURE__ */ (0,
|
|
2080
|
-
/* @__PURE__ */ (0,
|
|
2162
|
+
showToolbar && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "sci-nb-toolbar", children: [
|
|
2163
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "sci-nb-toolbar-group", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "sci-nb-toolbar-title", children: notebook.title }) }),
|
|
2164
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "sci-nb-toolbar-group", children: [
|
|
2165
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2081
2166
|
"button",
|
|
2082
2167
|
{
|
|
2083
2168
|
className: "sci-nb-toolbar-btn",
|
|
@@ -2085,12 +2170,12 @@ var SciNotebook = ({
|
|
|
2085
2170
|
disabled: !engine.canUndo(),
|
|
2086
2171
|
title: "Undo (Ctrl+Z)",
|
|
2087
2172
|
children: [
|
|
2088
|
-
/* @__PURE__ */ (0,
|
|
2173
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M3 7h6a3 3 0 010 6H7M3 7l3-3M3 7l3 3", strokeLinecap: "round", strokeLinejoin: "round" }) }),
|
|
2089
2174
|
"Undo"
|
|
2090
2175
|
]
|
|
2091
2176
|
}
|
|
2092
2177
|
),
|
|
2093
|
-
/* @__PURE__ */ (0,
|
|
2178
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2094
2179
|
"button",
|
|
2095
2180
|
{
|
|
2096
2181
|
className: "sci-nb-toolbar-btn",
|
|
@@ -2099,12 +2184,12 @@ var SciNotebook = ({
|
|
|
2099
2184
|
title: "Redo (Ctrl+Shift+Z)",
|
|
2100
2185
|
children: [
|
|
2101
2186
|
"Redo",
|
|
2102
|
-
/* @__PURE__ */ (0,
|
|
2187
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "M11 7H5a3 3 0 000 6h2M11 7l-3-3M11 7l-3 3", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
2103
2188
|
]
|
|
2104
2189
|
}
|
|
2105
2190
|
),
|
|
2106
|
-
/* @__PURE__ */ (0,
|
|
2107
|
-
/* @__PURE__ */ (0,
|
|
2191
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "sci-nb-toolbar-sep" }),
|
|
2192
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2108
2193
|
"button",
|
|
2109
2194
|
{
|
|
2110
2195
|
className: "sci-nb-toolbar-btn",
|
|
@@ -2113,7 +2198,7 @@ var SciNotebook = ({
|
|
|
2113
2198
|
children: "Edit All"
|
|
2114
2199
|
}
|
|
2115
2200
|
),
|
|
2116
|
-
/* @__PURE__ */ (0,
|
|
2201
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2117
2202
|
"button",
|
|
2118
2203
|
{
|
|
2119
2204
|
className: "sci-nb-toolbar-btn",
|
|
@@ -2122,17 +2207,17 @@ var SciNotebook = ({
|
|
|
2122
2207
|
children: "View All"
|
|
2123
2208
|
}
|
|
2124
2209
|
),
|
|
2125
|
-
/* @__PURE__ */ (0,
|
|
2126
|
-
/* @__PURE__ */ (0,
|
|
2210
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "sci-nb-toolbar-sep" }),
|
|
2211
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2127
2212
|
"button",
|
|
2128
2213
|
{
|
|
2129
2214
|
className: "sci-nb-toolbar-btn",
|
|
2130
2215
|
onClick: () => setShowFind((v) => !v),
|
|
2131
2216
|
title: "Find & Replace (Ctrl+F)",
|
|
2132
|
-
children: "
|
|
2217
|
+
children: "Find"
|
|
2133
2218
|
}
|
|
2134
2219
|
),
|
|
2135
|
-
/* @__PURE__ */ (0,
|
|
2220
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2136
2221
|
"button",
|
|
2137
2222
|
{
|
|
2138
2223
|
className: `sci-nb-toolbar-btn ${showTOC ? "sci-nb-toolbar-btn--active" : ""}`,
|
|
@@ -2143,23 +2228,23 @@ var SciNotebook = ({
|
|
|
2143
2228
|
)
|
|
2144
2229
|
] })
|
|
2145
2230
|
] }),
|
|
2146
|
-
showFind && /* @__PURE__ */ (0,
|
|
2147
|
-
/* @__PURE__ */ (0,
|
|
2148
|
-
showTOC && /* @__PURE__ */ (0,
|
|
2149
|
-
/* @__PURE__ */ (0,
|
|
2150
|
-
cells.length === 0 && /* @__PURE__ */ (0,
|
|
2151
|
-
/* @__PURE__ */ (0,
|
|
2152
|
-
/* @__PURE__ */ (0,
|
|
2153
|
-
/* @__PURE__ */ (0,
|
|
2154
|
-
/* @__PURE__ */ (0,
|
|
2155
|
-
/* @__PURE__ */ (0,
|
|
2231
|
+
showFind && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(FindReplace, { onClose: () => setShowFind(false) }),
|
|
2232
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "sci-nb-layout", style: { display: "flex", gap: 16 }, children: [
|
|
2233
|
+
showTOC && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TOCSidebar, { focusedCellId }),
|
|
2234
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "sci-nb-cells", style: { flex: 1 }, children: [
|
|
2235
|
+
cells.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "sci-nb-empty", children: [
|
|
2236
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "sci-nb-empty-icon", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("svg", { width: "48", height: "48", viewBox: "0 0 48 48", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: [
|
|
2237
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("rect", { x: "8", y: "6", width: "32", height: "36", rx: "4" }),
|
|
2238
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("line", { x1: "14", y1: "14", x2: "34", y2: "14" }),
|
|
2239
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("line", { x1: "14", y1: "22", x2: "28", y2: "22" }),
|
|
2240
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("line", { x1: "14", y1: "30", x2: "22", y2: "30" })
|
|
2156
2241
|
] }) }),
|
|
2157
|
-
/* @__PURE__ */ (0,
|
|
2158
|
-
/* @__PURE__ */ (0,
|
|
2242
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { children: "Empty notebook. Add a cell to get started." }),
|
|
2243
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(InsertHandle, { index: 0 })
|
|
2159
2244
|
] }),
|
|
2160
|
-
cells.length > 0 && /* @__PURE__ */ (0,
|
|
2161
|
-
cells.map((cell, idx) => /* @__PURE__ */ (0,
|
|
2162
|
-
/* @__PURE__ */ (0,
|
|
2245
|
+
cells.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(InsertHandle, { index: 0 }),
|
|
2246
|
+
cells.map((cell, idx) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react14.default.Fragment, { children: [
|
|
2247
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2163
2248
|
Cell,
|
|
2164
2249
|
{
|
|
2165
2250
|
cellId: cell.id,
|
|
@@ -2168,7 +2253,7 @@ var SciNotebook = ({
|
|
|
2168
2253
|
totalCells: cells.length
|
|
2169
2254
|
}
|
|
2170
2255
|
),
|
|
2171
|
-
/* @__PURE__ */ (0,
|
|
2256
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(InsertHandle, { index: idx + 1 })
|
|
2172
2257
|
] }, cell.id))
|
|
2173
2258
|
] })
|
|
2174
2259
|
] })
|
|
@@ -2190,8 +2275,8 @@ function parseInitialContent(content) {
|
|
|
2190
2275
|
}
|
|
2191
2276
|
|
|
2192
2277
|
// src/components/LatexAutocomplete.tsx
|
|
2193
|
-
var
|
|
2194
|
-
var
|
|
2278
|
+
var import_react15 = require("react");
|
|
2279
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2195
2280
|
var LATEX_COMMANDS = [
|
|
2196
2281
|
// Structures
|
|
2197
2282
|
{ cmd: "\\frac{}{}", desc: "Fracci\xF3n", category: "struct" },
|
|
@@ -2323,19 +2408,19 @@ var LatexAutocomplete = ({
|
|
|
2323
2408
|
onSelect,
|
|
2324
2409
|
onClose
|
|
2325
2410
|
}) => {
|
|
2326
|
-
const [selectedIndex, setSelectedIndex] = (0,
|
|
2327
|
-
const menuRef = (0,
|
|
2328
|
-
const filtered = (0,
|
|
2411
|
+
const [selectedIndex, setSelectedIndex] = (0, import_react15.useState)(0);
|
|
2412
|
+
const menuRef = (0, import_react15.useRef)(null);
|
|
2413
|
+
const filtered = (0, import_react15.useMemo)(() => {
|
|
2329
2414
|
if (!query) return LATEX_COMMANDS.slice(0, 12);
|
|
2330
2415
|
const q = query.toLowerCase();
|
|
2331
2416
|
return LATEX_COMMANDS.filter(
|
|
2332
2417
|
(c) => c.cmd.toLowerCase().includes(q) || c.desc.toLowerCase().includes(q)
|
|
2333
2418
|
).slice(0, 10);
|
|
2334
2419
|
}, [query]);
|
|
2335
|
-
(0,
|
|
2420
|
+
(0, import_react15.useEffect)(() => {
|
|
2336
2421
|
setSelectedIndex(0);
|
|
2337
2422
|
}, [query]);
|
|
2338
|
-
(0,
|
|
2423
|
+
(0, import_react15.useEffect)(() => {
|
|
2339
2424
|
const handleKey = (e) => {
|
|
2340
2425
|
if (e.key === "ArrowDown") {
|
|
2341
2426
|
e.preventDefault();
|
|
@@ -2360,23 +2445,23 @@ var LatexAutocomplete = ({
|
|
|
2360
2445
|
return () => document.removeEventListener("keydown", handleKey, true);
|
|
2361
2446
|
}, [filtered, selectedIndex, onSelect, onClose]);
|
|
2362
2447
|
if (filtered.length === 0) return null;
|
|
2363
|
-
return /* @__PURE__ */ (0,
|
|
2448
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2364
2449
|
"div",
|
|
2365
2450
|
{
|
|
2366
2451
|
ref: menuRef,
|
|
2367
2452
|
className: "sci-nb-slash-menu",
|
|
2368
2453
|
style: { top: position.top, left: position.left, minWidth: 220 },
|
|
2369
|
-
children: filtered.map((item, i) => /* @__PURE__ */ (0,
|
|
2454
|
+
children: filtered.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
2370
2455
|
"button",
|
|
2371
2456
|
{
|
|
2372
2457
|
className: `sci-nb-slash-item ${i === selectedIndex ? "sci-nb-slash-item--active" : ""}`,
|
|
2373
2458
|
onMouseEnter: () => setSelectedIndex(i),
|
|
2374
2459
|
onClick: () => onSelect(item.cmd),
|
|
2375
2460
|
children: [
|
|
2376
|
-
/* @__PURE__ */ (0,
|
|
2377
|
-
/* @__PURE__ */ (0,
|
|
2378
|
-
/* @__PURE__ */ (0,
|
|
2379
|
-
/* @__PURE__ */ (0,
|
|
2461
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "sci-nb-slash-icon", style: { fontFamily: "monospace", fontSize: 11 }, children: item.desc.length <= 2 ? item.desc : item.cmd.slice(0, 4) }),
|
|
2462
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "sci-nb-slash-text", children: [
|
|
2463
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "sci-nb-slash-label", style: { fontFamily: "monospace", fontSize: 12 }, children: item.cmd }),
|
|
2464
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "sci-nb-slash-desc", children: item.desc })
|
|
2380
2465
|
] })
|
|
2381
2466
|
]
|
|
2382
2467
|
},
|
|
@@ -2387,15 +2472,15 @@ var LatexAutocomplete = ({
|
|
|
2387
2472
|
};
|
|
2388
2473
|
|
|
2389
2474
|
// src/components/GhostText.tsx
|
|
2390
|
-
var
|
|
2391
|
-
var
|
|
2475
|
+
var import_react16 = require("react");
|
|
2476
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2392
2477
|
var GhostText = ({
|
|
2393
2478
|
text,
|
|
2394
2479
|
textareaRef,
|
|
2395
2480
|
onAccept,
|
|
2396
2481
|
onDismiss
|
|
2397
2482
|
}) => {
|
|
2398
|
-
const handleKeyDown = (0,
|
|
2483
|
+
const handleKeyDown = (0, import_react16.useCallback)((e) => {
|
|
2399
2484
|
if (e.key === "Tab" && !e.shiftKey) {
|
|
2400
2485
|
e.preventDefault();
|
|
2401
2486
|
e.stopPropagation();
|
|
@@ -2405,7 +2490,7 @@ var GhostText = ({
|
|
|
2405
2490
|
onDismiss();
|
|
2406
2491
|
}
|
|
2407
2492
|
}, [onAccept, onDismiss]);
|
|
2408
|
-
(0,
|
|
2493
|
+
(0, import_react16.useEffect)(() => {
|
|
2409
2494
|
const ta2 = textareaRef.current;
|
|
2410
2495
|
if (!ta2) return;
|
|
2411
2496
|
ta2.addEventListener("keydown", handleKeyDown, true);
|
|
@@ -2423,7 +2508,7 @@ var GhostText = ({
|
|
|
2423
2508
|
const left = lines[lines.length - 1].length * charWidth;
|
|
2424
2509
|
const firstLine = text.split("\n")[0];
|
|
2425
2510
|
const hasMore = text.includes("\n");
|
|
2426
|
-
return /* @__PURE__ */ (0,
|
|
2511
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
2427
2512
|
"div",
|
|
2428
2513
|
{
|
|
2429
2514
|
className: "sci-nb-ghost-text",
|
|
@@ -2441,15 +2526,15 @@ var GhostText = ({
|
|
|
2441
2526
|
children: [
|
|
2442
2527
|
firstLine,
|
|
2443
2528
|
hasMore ? "..." : "",
|
|
2444
|
-
/* @__PURE__ */ (0,
|
|
2529
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { fontSize: 10, opacity: 0.5, marginLeft: 8 }, children: "Tab \u21B9" })
|
|
2445
2530
|
]
|
|
2446
2531
|
}
|
|
2447
2532
|
);
|
|
2448
2533
|
};
|
|
2449
2534
|
|
|
2450
2535
|
// src/components/ChatSidebar.tsx
|
|
2451
|
-
var
|
|
2452
|
-
var
|
|
2536
|
+
var import_react17 = require("react");
|
|
2537
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2453
2538
|
var ChatSidebar = ({
|
|
2454
2539
|
onSend,
|
|
2455
2540
|
systemPrompt,
|
|
@@ -2457,23 +2542,23 @@ var ChatSidebar = ({
|
|
|
2457
2542
|
onClose
|
|
2458
2543
|
}) => {
|
|
2459
2544
|
const engine = useSciNotebook();
|
|
2460
|
-
const [messages, setMessages] = (0,
|
|
2545
|
+
const [messages, setMessages] = (0, import_react17.useState)(() => {
|
|
2461
2546
|
if (systemPrompt) {
|
|
2462
2547
|
return [{ role: "system", content: systemPrompt, timestamp: Date.now() }];
|
|
2463
2548
|
}
|
|
2464
2549
|
return [];
|
|
2465
2550
|
});
|
|
2466
|
-
const [input, setInput] = (0,
|
|
2467
|
-
const [loading, setLoading] = (0,
|
|
2468
|
-
const messagesEndRef = (0,
|
|
2469
|
-
const inputRef = (0,
|
|
2470
|
-
(0,
|
|
2551
|
+
const [input, setInput] = (0, import_react17.useState)("");
|
|
2552
|
+
const [loading, setLoading] = (0, import_react17.useState)(false);
|
|
2553
|
+
const messagesEndRef = (0, import_react17.useRef)(null);
|
|
2554
|
+
const inputRef = (0, import_react17.useRef)(null);
|
|
2555
|
+
(0, import_react17.useEffect)(() => {
|
|
2471
2556
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
2472
2557
|
}, [messages]);
|
|
2473
|
-
(0,
|
|
2558
|
+
(0, import_react17.useEffect)(() => {
|
|
2474
2559
|
inputRef.current?.focus();
|
|
2475
2560
|
}, []);
|
|
2476
|
-
const handleSend = (0,
|
|
2561
|
+
const handleSend = (0, import_react17.useCallback)(async () => {
|
|
2477
2562
|
const text = input.trim();
|
|
2478
2563
|
if (!text || loading) return;
|
|
2479
2564
|
const userMsg = { role: "user", content: text, timestamp: Date.now() };
|
|
@@ -2511,17 +2596,17 @@ var ChatSidebar = ({
|
|
|
2511
2596
|
setLoading(false);
|
|
2512
2597
|
}
|
|
2513
2598
|
}, [input, messages, loading, onSend]);
|
|
2514
|
-
const handleKeyDown = (0,
|
|
2599
|
+
const handleKeyDown = (0, import_react17.useCallback)((e) => {
|
|
2515
2600
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
2516
2601
|
e.preventDefault();
|
|
2517
2602
|
handleSend();
|
|
2518
2603
|
}
|
|
2519
2604
|
}, [handleSend]);
|
|
2520
2605
|
const visibleMessages = messages.filter((m) => m.role !== "system");
|
|
2521
|
-
return /* @__PURE__ */ (0,
|
|
2522
|
-
/* @__PURE__ */ (0,
|
|
2523
|
-
/* @__PURE__ */ (0,
|
|
2524
|
-
onClose && /* @__PURE__ */ (0,
|
|
2606
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "sci-nb-chat-sidebar", children: [
|
|
2607
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "sci-nb-chat-header", children: [
|
|
2608
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: "AI Assistant" }),
|
|
2609
|
+
onClose && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2525
2610
|
"button",
|
|
2526
2611
|
{
|
|
2527
2612
|
onClick: onClose,
|
|
@@ -2530,11 +2615,11 @@ var ChatSidebar = ({
|
|
|
2530
2615
|
}
|
|
2531
2616
|
)
|
|
2532
2617
|
] }),
|
|
2533
|
-
/* @__PURE__ */ (0,
|
|
2534
|
-
visibleMessages.length === 0 && /* @__PURE__ */ (0,
|
|
2535
|
-
visibleMessages.map((msg, i) => /* @__PURE__ */ (0,
|
|
2536
|
-
/* @__PURE__ */ (0,
|
|
2537
|
-
msg.role === "assistant" && onApply && /* @__PURE__ */ (0,
|
|
2618
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "sci-nb-chat-messages", children: [
|
|
2619
|
+
visibleMessages.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { textAlign: "center", color: "#94a3b8", padding: 24 }, children: "Ask me anything about your notebook..." }),
|
|
2620
|
+
visibleMessages.map((msg, i) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: `sci-nb-chat-msg sci-nb-chat-msg--${msg.role}`, children: [
|
|
2621
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { children: msg.content }),
|
|
2622
|
+
msg.role === "assistant" && onApply && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2538
2623
|
"button",
|
|
2539
2624
|
{
|
|
2540
2625
|
onClick: () => onApply(msg.content),
|
|
@@ -2551,11 +2636,11 @@ var ChatSidebar = ({
|
|
|
2551
2636
|
}
|
|
2552
2637
|
)
|
|
2553
2638
|
] }, i)),
|
|
2554
|
-
loading && /* @__PURE__ */ (0,
|
|
2555
|
-
/* @__PURE__ */ (0,
|
|
2639
|
+
loading && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "sci-nb-chat-msg sci-nb-chat-msg--assistant", style: { opacity: 0.6 }, children: "Thinking..." }),
|
|
2640
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { ref: messagesEndRef })
|
|
2556
2641
|
] }),
|
|
2557
|
-
/* @__PURE__ */ (0,
|
|
2558
|
-
/* @__PURE__ */ (0,
|
|
2642
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "sci-nb-chat-input", children: [
|
|
2643
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2559
2644
|
"input",
|
|
2560
2645
|
{
|
|
2561
2646
|
ref: inputRef,
|
|
@@ -2567,14 +2652,14 @@ var ChatSidebar = ({
|
|
|
2567
2652
|
disabled: loading
|
|
2568
2653
|
}
|
|
2569
2654
|
),
|
|
2570
|
-
/* @__PURE__ */ (0,
|
|
2655
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { onClick: handleSend, disabled: loading || !input.trim(), children: "Send" })
|
|
2571
2656
|
] })
|
|
2572
2657
|
] });
|
|
2573
2658
|
};
|
|
2574
2659
|
|
|
2575
2660
|
// src/components/ImageResize.tsx
|
|
2576
|
-
var
|
|
2577
|
-
var
|
|
2661
|
+
var import_react18 = require("react");
|
|
2662
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
2578
2663
|
var ImageResize = ({
|
|
2579
2664
|
src,
|
|
2580
2665
|
alt = "",
|
|
@@ -2583,12 +2668,12 @@ var ImageResize = ({
|
|
|
2583
2668
|
onResize,
|
|
2584
2669
|
children
|
|
2585
2670
|
}) => {
|
|
2586
|
-
const containerRef = (0,
|
|
2587
|
-
const imgRef = (0,
|
|
2588
|
-
const [dragging, setDragging] = (0,
|
|
2589
|
-
const [width, setWidth] = (0,
|
|
2590
|
-
const startRef = (0,
|
|
2591
|
-
const handleMouseDown = (0,
|
|
2671
|
+
const containerRef = (0, import_react18.useRef)(null);
|
|
2672
|
+
const imgRef = (0, import_react18.useRef)(null);
|
|
2673
|
+
const [dragging, setDragging] = (0, import_react18.useState)(false);
|
|
2674
|
+
const [width, setWidth] = (0, import_react18.useState)(null);
|
|
2675
|
+
const startRef = (0, import_react18.useRef)({ x: 0, w: 0 });
|
|
2676
|
+
const handleMouseDown = (0, import_react18.useCallback)((e) => {
|
|
2592
2677
|
e.preventDefault();
|
|
2593
2678
|
e.stopPropagation();
|
|
2594
2679
|
const img = imgRef.current;
|
|
@@ -2596,7 +2681,7 @@ var ImageResize = ({
|
|
|
2596
2681
|
startRef.current = { x: e.clientX, w: img.offsetWidth };
|
|
2597
2682
|
setDragging(true);
|
|
2598
2683
|
}, []);
|
|
2599
|
-
(0,
|
|
2684
|
+
(0, import_react18.useEffect)(() => {
|
|
2600
2685
|
if (!dragging) return;
|
|
2601
2686
|
const handleMouseMove = (e) => {
|
|
2602
2687
|
const dx = e.clientX - startRef.current.x;
|
|
@@ -2624,8 +2709,8 @@ var ImageResize = ({
|
|
|
2624
2709
|
position: "relative",
|
|
2625
2710
|
display: "inline-block"
|
|
2626
2711
|
};
|
|
2627
|
-
return /* @__PURE__ */ (0,
|
|
2628
|
-
/* @__PURE__ */ (0,
|
|
2712
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { ref: containerRef, className: "sci-nb-image-resizable", style, children: [
|
|
2713
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2629
2714
|
"img",
|
|
2630
2715
|
{
|
|
2631
2716
|
ref: imgRef,
|
|
@@ -2636,7 +2721,7 @@ var ImageResize = ({
|
|
|
2636
2721
|
}
|
|
2637
2722
|
),
|
|
2638
2723
|
children,
|
|
2639
|
-
/* @__PURE__ */ (0,
|
|
2724
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2640
2725
|
"div",
|
|
2641
2726
|
{
|
|
2642
2727
|
className: "sci-nb-image-resize-handle sci-nb-image-resize-handle--se",
|
|
@@ -2647,28 +2732,28 @@ var ImageResize = ({
|
|
|
2647
2732
|
};
|
|
2648
2733
|
|
|
2649
2734
|
// src/components/VirtualRenderer.tsx
|
|
2650
|
-
var
|
|
2651
|
-
var
|
|
2735
|
+
var import_react19 = require("react");
|
|
2736
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
2652
2737
|
var VirtualRenderer = ({
|
|
2653
2738
|
cells,
|
|
2654
2739
|
pipeline,
|
|
2655
2740
|
estimatedHeight = 120,
|
|
2656
2741
|
overscan = 5
|
|
2657
2742
|
}) => {
|
|
2658
|
-
const containerRef = (0,
|
|
2659
|
-
const [visibleRange, setVisibleRange] = (0,
|
|
2660
|
-
const cellHeights = (0,
|
|
2661
|
-
const getHeight = (0,
|
|
2743
|
+
const containerRef = (0, import_react19.useRef)(null);
|
|
2744
|
+
const [visibleRange, setVisibleRange] = (0, import_react19.useState)({ start: 0, end: 20 });
|
|
2745
|
+
const cellHeights = (0, import_react19.useRef)(/* @__PURE__ */ new Map());
|
|
2746
|
+
const getHeight = (0, import_react19.useCallback)((index) => {
|
|
2662
2747
|
return cellHeights.current.get(index) ?? estimatedHeight;
|
|
2663
2748
|
}, [estimatedHeight]);
|
|
2664
|
-
const totalHeight = (0,
|
|
2749
|
+
const totalHeight = (0, import_react19.useMemo)(() => {
|
|
2665
2750
|
let h = 0;
|
|
2666
2751
|
for (let i = 0; i < cells.length; i++) {
|
|
2667
2752
|
h += getHeight(i) + 32;
|
|
2668
2753
|
}
|
|
2669
2754
|
return h;
|
|
2670
2755
|
}, [cells.length, getHeight]);
|
|
2671
|
-
(0,
|
|
2756
|
+
(0, import_react19.useEffect)(() => {
|
|
2672
2757
|
const container = containerRef.current;
|
|
2673
2758
|
if (!container) return;
|
|
2674
2759
|
const handleScroll = () => {
|
|
@@ -2697,7 +2782,7 @@ var VirtualRenderer = ({
|
|
|
2697
2782
|
container.addEventListener("scroll", handleScroll, { passive: true });
|
|
2698
2783
|
return () => container.removeEventListener("scroll", handleScroll);
|
|
2699
2784
|
}, [cells.length, getHeight, overscan]);
|
|
2700
|
-
const measureRef = (0,
|
|
2785
|
+
const measureRef = (0, import_react19.useCallback)((index) => {
|
|
2701
2786
|
return (el) => {
|
|
2702
2787
|
if (!el) return;
|
|
2703
2788
|
const observer = new ResizeObserver((entries) => {
|
|
@@ -2711,7 +2796,7 @@ var VirtualRenderer = ({
|
|
|
2711
2796
|
observer.observe(el);
|
|
2712
2797
|
};
|
|
2713
2798
|
}, []);
|
|
2714
|
-
const topOffset = (0,
|
|
2799
|
+
const topOffset = (0, import_react19.useMemo)(() => {
|
|
2715
2800
|
let h = 0;
|
|
2716
2801
|
for (let i = 0; i < visibleRange.start; i++) {
|
|
2717
2802
|
h += getHeight(i) + 32;
|
|
@@ -2719,18 +2804,18 @@ var VirtualRenderer = ({
|
|
|
2719
2804
|
return h;
|
|
2720
2805
|
}, [visibleRange.start, getHeight]);
|
|
2721
2806
|
const visibleCells = cells.slice(visibleRange.start, visibleRange.end);
|
|
2722
|
-
return /* @__PURE__ */ (0,
|
|
2807
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2723
2808
|
"div",
|
|
2724
2809
|
{
|
|
2725
2810
|
ref: containerRef,
|
|
2726
2811
|
className: "sci-nb-virtual-container",
|
|
2727
2812
|
style: { height: "100%", overflow: "auto", position: "relative" },
|
|
2728
|
-
children: /* @__PURE__ */ (0,
|
|
2729
|
-
visibleRange.start === 0 && /* @__PURE__ */ (0,
|
|
2813
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { height: totalHeight, position: "relative" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { position: "absolute", top: topOffset, left: 0, right: 0 }, children: [
|
|
2814
|
+
visibleRange.start === 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(InsertHandle, { index: 0 }),
|
|
2730
2815
|
visibleCells.map((cell, i) => {
|
|
2731
2816
|
const realIndex = visibleRange.start + i;
|
|
2732
|
-
return /* @__PURE__ */ (0,
|
|
2733
|
-
/* @__PURE__ */ (0,
|
|
2817
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { ref: measureRef(realIndex), children: [
|
|
2818
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2734
2819
|
Cell,
|
|
2735
2820
|
{
|
|
2736
2821
|
cellId: cell.id,
|
|
@@ -2739,7 +2824,7 @@ var VirtualRenderer = ({
|
|
|
2739
2824
|
totalCells: cells.length
|
|
2740
2825
|
}
|
|
2741
2826
|
),
|
|
2742
|
-
/* @__PURE__ */ (0,
|
|
2827
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(InsertHandle, { index: realIndex + 1 })
|
|
2743
2828
|
] }, cell.id);
|
|
2744
2829
|
})
|
|
2745
2830
|
] }) })
|
|
@@ -2748,8 +2833,8 @@ var VirtualRenderer = ({
|
|
|
2748
2833
|
};
|
|
2749
2834
|
|
|
2750
2835
|
// src/components/AIRewrite.tsx
|
|
2751
|
-
var
|
|
2752
|
-
var
|
|
2836
|
+
var import_react20 = require("react");
|
|
2837
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
2753
2838
|
var AIRewrite = ({
|
|
2754
2839
|
selectedText,
|
|
2755
2840
|
position,
|
|
@@ -2757,15 +2842,15 @@ var AIRewrite = ({
|
|
|
2757
2842
|
onAccept,
|
|
2758
2843
|
onReject
|
|
2759
2844
|
}) => {
|
|
2760
|
-
const [state, setState] = (0,
|
|
2761
|
-
const [instruction, setInstruction] = (0,
|
|
2762
|
-
const [result, setResult] = (0,
|
|
2763
|
-
const [error, setError] = (0,
|
|
2764
|
-
const inputRef = (0,
|
|
2765
|
-
(0,
|
|
2845
|
+
const [state, setState] = (0, import_react20.useState)("prompt");
|
|
2846
|
+
const [instruction, setInstruction] = (0, import_react20.useState)("");
|
|
2847
|
+
const [result, setResult] = (0, import_react20.useState)("");
|
|
2848
|
+
const [error, setError] = (0, import_react20.useState)(null);
|
|
2849
|
+
const inputRef = (0, import_react20.useRef)(null);
|
|
2850
|
+
(0, import_react20.useEffect)(() => {
|
|
2766
2851
|
inputRef.current?.focus();
|
|
2767
2852
|
}, []);
|
|
2768
|
-
const handleSubmit = (0,
|
|
2853
|
+
const handleSubmit = (0, import_react20.useCallback)(async () => {
|
|
2769
2854
|
if (!instruction.trim()) return;
|
|
2770
2855
|
setState("loading");
|
|
2771
2856
|
setError(null);
|
|
@@ -2778,7 +2863,7 @@ var AIRewrite = ({
|
|
|
2778
2863
|
setState("prompt");
|
|
2779
2864
|
}
|
|
2780
2865
|
}, [instruction, selectedText, onRewrite]);
|
|
2781
|
-
const handleKeyDown = (0,
|
|
2866
|
+
const handleKeyDown = (0, import_react20.useCallback)((e) => {
|
|
2782
2867
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
2783
2868
|
e.preventDefault();
|
|
2784
2869
|
handleSubmit();
|
|
@@ -2787,15 +2872,15 @@ var AIRewrite = ({
|
|
|
2787
2872
|
onReject();
|
|
2788
2873
|
}
|
|
2789
2874
|
}, [handleSubmit, onReject]);
|
|
2790
|
-
const handleAccept = (0,
|
|
2875
|
+
const handleAccept = (0, import_react20.useCallback)(() => {
|
|
2791
2876
|
onAccept(result);
|
|
2792
2877
|
}, [result, onAccept]);
|
|
2793
|
-
const handleRetry = (0,
|
|
2878
|
+
const handleRetry = (0, import_react20.useCallback)(() => {
|
|
2794
2879
|
setState("prompt");
|
|
2795
2880
|
setResult("");
|
|
2796
2881
|
inputRef.current?.focus();
|
|
2797
2882
|
}, []);
|
|
2798
|
-
return /* @__PURE__ */ (0,
|
|
2883
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
2799
2884
|
"div",
|
|
2800
2885
|
{
|
|
2801
2886
|
className: "sci-nb-ai-rewrite",
|
|
@@ -2806,13 +2891,13 @@ var AIRewrite = ({
|
|
|
2806
2891
|
zIndex: 100
|
|
2807
2892
|
},
|
|
2808
2893
|
children: [
|
|
2809
|
-
state === "prompt" && /* @__PURE__ */ (0,
|
|
2810
|
-
/* @__PURE__ */ (0,
|
|
2811
|
-
/* @__PURE__ */ (0,
|
|
2812
|
-
/* @__PURE__ */ (0,
|
|
2894
|
+
state === "prompt" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "sci-nb-ai-rewrite-prompt", children: [
|
|
2895
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "sci-nb-ai-rewrite-selected", children: [
|
|
2896
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "sci-nb-ai-rewrite-label", children: "Selected:" }),
|
|
2897
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "sci-nb-ai-rewrite-text", children: selectedText.length > 80 ? selectedText.slice(0, 80) + "..." : selectedText })
|
|
2813
2898
|
] }),
|
|
2814
|
-
/* @__PURE__ */ (0,
|
|
2815
|
-
/* @__PURE__ */ (0,
|
|
2899
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "sci-nb-ai-rewrite-input-row", children: [
|
|
2900
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2816
2901
|
"input",
|
|
2817
2902
|
{
|
|
2818
2903
|
ref: inputRef,
|
|
@@ -2824,7 +2909,7 @@ var AIRewrite = ({
|
|
|
2824
2909
|
className: "sci-nb-ai-rewrite-input"
|
|
2825
2910
|
}
|
|
2826
2911
|
),
|
|
2827
|
-
/* @__PURE__ */ (0,
|
|
2912
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2828
2913
|
"button",
|
|
2829
2914
|
{
|
|
2830
2915
|
onClick: handleSubmit,
|
|
@@ -2833,24 +2918,24 @@ var AIRewrite = ({
|
|
|
2833
2918
|
children: "Rewrite"
|
|
2834
2919
|
}
|
|
2835
2920
|
),
|
|
2836
|
-
/* @__PURE__ */ (0,
|
|
2921
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: onReject, className: "sci-nb-ai-rewrite-btn", children: "Cancel" })
|
|
2837
2922
|
] }),
|
|
2838
|
-
error && /* @__PURE__ */ (0,
|
|
2923
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "sci-nb-ai-rewrite-error", children: error })
|
|
2839
2924
|
] }),
|
|
2840
|
-
state === "loading" && /* @__PURE__ */ (0,
|
|
2841
|
-
state === "preview" && /* @__PURE__ */ (0,
|
|
2842
|
-
/* @__PURE__ */ (0,
|
|
2843
|
-
/* @__PURE__ */ (0,
|
|
2844
|
-
/* @__PURE__ */ (0,
|
|
2845
|
-
/* @__PURE__ */ (0,
|
|
2925
|
+
state === "loading" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "sci-nb-ai-rewrite-loading", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "Rewriting..." }) }),
|
|
2926
|
+
state === "preview" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "sci-nb-ai-rewrite-preview", children: [
|
|
2927
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "sci-nb-ai-rewrite-diff", children: [
|
|
2928
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "sci-nb-ai-rewrite-diff-old", children: [
|
|
2929
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "sci-nb-ai-rewrite-diff-label", children: "Original:" }),
|
|
2930
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { children: selectedText })
|
|
2846
2931
|
] }),
|
|
2847
|
-
/* @__PURE__ */ (0,
|
|
2848
|
-
/* @__PURE__ */ (0,
|
|
2849
|
-
/* @__PURE__ */ (0,
|
|
2932
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "sci-nb-ai-rewrite-diff-new", children: [
|
|
2933
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "sci-nb-ai-rewrite-diff-label", children: "Rewritten:" }),
|
|
2934
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { children: result })
|
|
2850
2935
|
] })
|
|
2851
2936
|
] }),
|
|
2852
|
-
/* @__PURE__ */ (0,
|
|
2853
|
-
/* @__PURE__ */ (0,
|
|
2937
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "sci-nb-ai-rewrite-actions", children: [
|
|
2938
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2854
2939
|
"button",
|
|
2855
2940
|
{
|
|
2856
2941
|
onClick: handleAccept,
|
|
@@ -2858,8 +2943,8 @@ var AIRewrite = ({
|
|
|
2858
2943
|
children: "Accept"
|
|
2859
2944
|
}
|
|
2860
2945
|
),
|
|
2861
|
-
/* @__PURE__ */ (0,
|
|
2862
|
-
/* @__PURE__ */ (0,
|
|
2946
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: handleRetry, className: "sci-nb-ai-rewrite-btn", children: "Retry" }),
|
|
2947
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { onClick: onReject, className: "sci-nb-ai-rewrite-btn", children: "Reject" })
|
|
2863
2948
|
] })
|
|
2864
2949
|
] })
|
|
2865
2950
|
]
|
|
@@ -2868,22 +2953,22 @@ var AIRewrite = ({
|
|
|
2868
2953
|
};
|
|
2869
2954
|
|
|
2870
2955
|
// src/components/AICellGenerate.tsx
|
|
2871
|
-
var
|
|
2872
|
-
var
|
|
2956
|
+
var import_react21 = require("react");
|
|
2957
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
2873
2958
|
var AICellGenerate = ({
|
|
2874
2959
|
onGenerate,
|
|
2875
2960
|
onAccept,
|
|
2876
2961
|
onCancel
|
|
2877
2962
|
}) => {
|
|
2878
|
-
const [state, setState] = (0,
|
|
2879
|
-
const [prompt, setPrompt] = (0,
|
|
2880
|
-
const [cells, setCells] = (0,
|
|
2881
|
-
const [error, setError] = (0,
|
|
2882
|
-
const inputRef = (0,
|
|
2883
|
-
(0,
|
|
2963
|
+
const [state, setState] = (0, import_react21.useState)("prompt");
|
|
2964
|
+
const [prompt, setPrompt] = (0, import_react21.useState)("");
|
|
2965
|
+
const [cells, setCells] = (0, import_react21.useState)([]);
|
|
2966
|
+
const [error, setError] = (0, import_react21.useState)(null);
|
|
2967
|
+
const inputRef = (0, import_react21.useRef)(null);
|
|
2968
|
+
(0, import_react21.useEffect)(() => {
|
|
2884
2969
|
inputRef.current?.focus();
|
|
2885
2970
|
}, []);
|
|
2886
|
-
const handleGenerate = (0,
|
|
2971
|
+
const handleGenerate = (0, import_react21.useCallback)(async () => {
|
|
2887
2972
|
if (!prompt.trim()) return;
|
|
2888
2973
|
setState("loading");
|
|
2889
2974
|
setError(null);
|
|
@@ -2896,7 +2981,7 @@ var AICellGenerate = ({
|
|
|
2896
2981
|
setState("prompt");
|
|
2897
2982
|
}
|
|
2898
2983
|
}, [prompt, onGenerate]);
|
|
2899
|
-
const handleKeyDown = (0,
|
|
2984
|
+
const handleKeyDown = (0, import_react21.useCallback)((e) => {
|
|
2900
2985
|
if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
|
|
2901
2986
|
e.preventDefault();
|
|
2902
2987
|
handleGenerate();
|
|
@@ -2905,10 +2990,10 @@ var AICellGenerate = ({
|
|
|
2905
2990
|
onCancel();
|
|
2906
2991
|
}
|
|
2907
2992
|
}, [handleGenerate, onCancel]);
|
|
2908
|
-
const handleAccept = (0,
|
|
2993
|
+
const handleAccept = (0, import_react21.useCallback)(() => {
|
|
2909
2994
|
onAccept(cells);
|
|
2910
2995
|
}, [cells, onAccept]);
|
|
2911
|
-
const handleRegenerate = (0,
|
|
2996
|
+
const handleRegenerate = (0, import_react21.useCallback)(() => {
|
|
2912
2997
|
setState("prompt");
|
|
2913
2998
|
setCells([]);
|
|
2914
2999
|
inputRef.current?.focus();
|
|
@@ -2921,13 +3006,13 @@ var AICellGenerate = ({
|
|
|
2921
3006
|
mermaid: "Mermaid",
|
|
2922
3007
|
raw: "Raw"
|
|
2923
3008
|
};
|
|
2924
|
-
return /* @__PURE__ */ (0,
|
|
2925
|
-
state === "prompt" && /* @__PURE__ */ (0,
|
|
2926
|
-
/* @__PURE__ */ (0,
|
|
2927
|
-
/* @__PURE__ */ (0,
|
|
2928
|
-
/* @__PURE__ */ (0,
|
|
3009
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "sci-nb-ai-generate", children: [
|
|
3010
|
+
state === "prompt" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "sci-nb-ai-generate-prompt", children: [
|
|
3011
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "sci-nb-ai-generate-header", children: [
|
|
3012
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("path", { d: "M8 1v14M1 8h14", strokeLinecap: "round" }) }),
|
|
3013
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: "Generate cells with AI" })
|
|
2929
3014
|
] }),
|
|
2930
|
-
/* @__PURE__ */ (0,
|
|
3015
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2931
3016
|
"textarea",
|
|
2932
3017
|
{
|
|
2933
3018
|
ref: inputRef,
|
|
@@ -2939,8 +3024,8 @@ var AICellGenerate = ({
|
|
|
2939
3024
|
rows: 3
|
|
2940
3025
|
}
|
|
2941
3026
|
),
|
|
2942
|
-
/* @__PURE__ */ (0,
|
|
2943
|
-
/* @__PURE__ */ (0,
|
|
3027
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "sci-nb-ai-generate-actions", children: [
|
|
3028
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2944
3029
|
"button",
|
|
2945
3030
|
{
|
|
2946
3031
|
onClick: handleGenerate,
|
|
@@ -2949,24 +3034,24 @@ var AICellGenerate = ({
|
|
|
2949
3034
|
children: "Generate (Ctrl+Enter)"
|
|
2950
3035
|
}
|
|
2951
3036
|
),
|
|
2952
|
-
/* @__PURE__ */ (0,
|
|
3037
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { onClick: onCancel, className: "sci-nb-ai-rewrite-btn", children: "Cancel" })
|
|
2953
3038
|
] }),
|
|
2954
|
-
error && /* @__PURE__ */ (0,
|
|
3039
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "sci-nb-ai-rewrite-error", children: error })
|
|
2955
3040
|
] }),
|
|
2956
|
-
state === "loading" && /* @__PURE__ */ (0,
|
|
2957
|
-
state === "preview" && /* @__PURE__ */ (0,
|
|
2958
|
-
/* @__PURE__ */ (0,
|
|
3041
|
+
state === "loading" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "sci-nb-ai-generate-loading", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: "Generating cells..." }) }),
|
|
3042
|
+
state === "preview" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "sci-nb-ai-generate-preview", children: [
|
|
3043
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "sci-nb-ai-generate-header", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { children: [
|
|
2959
3044
|
"Generated ",
|
|
2960
3045
|
cells.length,
|
|
2961
3046
|
" cell",
|
|
2962
3047
|
cells.length !== 1 ? "s" : ""
|
|
2963
3048
|
] }) }),
|
|
2964
|
-
/* @__PURE__ */ (0,
|
|
2965
|
-
/* @__PURE__ */ (0,
|
|
2966
|
-
/* @__PURE__ */ (0,
|
|
3049
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "sci-nb-ai-generate-cells", children: cells.map((cell, i) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "sci-nb-ai-generate-cell", children: [
|
|
3050
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "sci-nb-ai-generate-cell-badge", children: CELL_TYPE_LABELS[cell.type] || cell.type }),
|
|
3051
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("pre", { className: "sci-nb-ai-generate-cell-source", children: cell.source.length > 200 ? cell.source.slice(0, 200) + "..." : cell.source })
|
|
2967
3052
|
] }, i)) }),
|
|
2968
|
-
/* @__PURE__ */ (0,
|
|
2969
|
-
/* @__PURE__ */ (0,
|
|
3053
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "sci-nb-ai-generate-actions", children: [
|
|
3054
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
2970
3055
|
"button",
|
|
2971
3056
|
{
|
|
2972
3057
|
onClick: handleAccept,
|
|
@@ -2979,8 +3064,8 @@ var AICellGenerate = ({
|
|
|
2979
3064
|
]
|
|
2980
3065
|
}
|
|
2981
3066
|
),
|
|
2982
|
-
/* @__PURE__ */ (0,
|
|
2983
|
-
/* @__PURE__ */ (0,
|
|
3067
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { onClick: handleRegenerate, className: "sci-nb-ai-rewrite-btn", children: "Regenerate" }),
|
|
3068
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { onClick: onCancel, className: "sci-nb-ai-rewrite-btn", children: "Cancel" })
|
|
2984
3069
|
] })
|
|
2985
3070
|
] })
|
|
2986
3071
|
] });
|