raydit-editor 0.0.2 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,62 +1,25 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
33
- NotionEditor: () => NotionEditor_default
34
- });
35
- module.exports = __toCommonJS(index_exports);
1
+ import React, { useState, useRef, useMemo, useEffect } from 'react';
2
+ import { ReactRenderer, useEditor, EditorContent } from '@tiptap/react';
3
+ import StarterKit from '@tiptap/starter-kit';
4
+ import Placeholder from '@tiptap/extension-placeholder';
5
+ import Underline from '@tiptap/extension-underline';
6
+ import { Color } from '@tiptap/extension-color';
7
+ import Highlight from '@tiptap/extension-highlight';
8
+ import Link2 from '@tiptap/extension-link';
9
+ import { TableRow, TableHeader, TableCell, Table as Table$1 } from '@tiptap/extension-table';
10
+ import { TextStyle } from '@tiptap/extension-text-style';
11
+ import Superscript from '@tiptap/extension-superscript';
12
+ import Subscript from '@tiptap/extension-subscript';
13
+ import TextAlign from '@tiptap/extension-text-align';
14
+ import TaskList from '@tiptap/extension-task-list';
15
+ import TaskItem from '@tiptap/extension-task-item';
16
+ import clsx from 'clsx';
17
+ import { Extension } from '@tiptap/core';
18
+ import Suggestion from '@tiptap/suggestion';
19
+ import { jsx, jsxs } from 'react/jsx-runtime';
20
+ import { Type, Heading1, Heading2, Heading3, List, ListOrdered, Quote, Code, Minus, Table, Link, MoreHorizontal } from 'lucide-react';
36
21
 
37
22
  // src/NotionEditor.tsx
38
- var import_react8 = require("@tiptap/react");
39
- var import_starter_kit = __toESM(require("@tiptap/starter-kit"), 1);
40
- var import_extension_placeholder = __toESM(require("@tiptap/extension-placeholder"), 1);
41
- var import_extension_underline = __toESM(require("@tiptap/extension-underline"), 1);
42
- var import_extension_color = require("@tiptap/extension-color");
43
- var import_extension_highlight = __toESM(require("@tiptap/extension-highlight"), 1);
44
- var import_extension_link = __toESM(require("@tiptap/extension-link"), 1);
45
- var import_extension_table = require("@tiptap/extension-table");
46
- var import_extension_text_style = require("@tiptap/extension-text-style");
47
- var import_extension_superscript = __toESM(require("@tiptap/extension-superscript"), 1);
48
- var import_extension_subscript = __toESM(require("@tiptap/extension-subscript"), 1);
49
- var import_extension_text_align = __toESM(require("@tiptap/extension-text-align"), 1);
50
- var import_extension_task_list = __toESM(require("@tiptap/extension-task-list"), 1);
51
- var import_extension_task_item = __toESM(require("@tiptap/extension-task-item"), 1);
52
- var import_menus = require("@tiptap/react/menus");
53
- var import_react9 = require("react");
54
- var import_clsx = __toESM(require("clsx"), 1);
55
-
56
- // src/slash/SlashExtension.ts
57
- var import_core2 = require("@tiptap/core");
58
- var import_suggestion = __toESM(require("@tiptap/suggestion"), 1);
59
- var import_react2 = require("@tiptap/react");
60
23
 
61
24
  // node_modules/prosemirror-model/dist/index.js
62
25
  function findDiffStart(a, b, pos) {
@@ -381,1523 +344,147 @@ var Fragment = class _Fragment {
381
344
  if (!joined)
382
345
  joined = array.slice(0, i);
383
346
  joined[joined.length - 1] = node.withText(joined[joined.length - 1].text + node.text);
384
- } else if (joined) {
385
- joined.push(node);
386
- }
387
- }
388
- return new _Fragment(joined || array, size);
389
- }
390
- /**
391
- Create a fragment from something that can be interpreted as a
392
- set of nodes. For `null`, it returns the empty fragment. For a
393
- fragment, the fragment itself. For a node or array of nodes, a
394
- fragment containing those nodes.
395
- */
396
- static from(nodes) {
397
- if (!nodes)
398
- return _Fragment.empty;
399
- if (nodes instanceof _Fragment)
400
- return nodes;
401
- if (Array.isArray(nodes))
402
- return this.fromArray(nodes);
403
- if (nodes.attrs)
404
- return new _Fragment([nodes], nodes.nodeSize);
405
- throw new RangeError("Can not convert " + nodes + " to a Fragment" + (nodes.nodesBetween ? " (looks like multiple versions of prosemirror-model were loaded)" : ""));
406
- }
407
- };
408
- Fragment.empty = new Fragment([], 0);
409
- var found = { index: 0, offset: 0 };
410
- function retIndex(index, offset2) {
411
- found.index = index;
412
- found.offset = offset2;
413
- return found;
414
- }
415
- function compareDeep(a, b) {
416
- if (a === b)
417
- return true;
418
- if (!(a && typeof a == "object") || !(b && typeof b == "object"))
419
- return false;
420
- let array = Array.isArray(a);
421
- if (Array.isArray(b) != array)
422
- return false;
423
- if (array) {
424
- if (a.length != b.length)
425
- return false;
426
- for (let i = 0; i < a.length; i++)
427
- if (!compareDeep(a[i], b[i]))
428
- return false;
429
- } else {
430
- for (let p in a)
431
- if (!(p in b) || !compareDeep(a[p], b[p]))
432
- return false;
433
- for (let p in b)
434
- if (!(p in a))
435
- return false;
436
- }
437
- return true;
438
- }
439
- var Mark = class _Mark {
440
- /**
441
- @internal
442
- */
443
- constructor(type, attrs) {
444
- this.type = type;
445
- this.attrs = attrs;
446
- }
447
- /**
448
- Given a set of marks, create a new set which contains this one as
449
- well, in the right position. If this mark is already in the set,
450
- the set itself is returned. If any marks that are set to be
451
- [exclusive](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) with this mark are present,
452
- those are replaced by this one.
453
- */
454
- addToSet(set) {
455
- let copy, placed = false;
456
- for (let i = 0; i < set.length; i++) {
457
- let other = set[i];
458
- if (this.eq(other))
459
- return set;
460
- if (this.type.excludes(other.type)) {
461
- if (!copy)
462
- copy = set.slice(0, i);
463
- } else if (other.type.excludes(this.type)) {
464
- return set;
465
- } else {
466
- if (!placed && other.type.rank > this.type.rank) {
467
- if (!copy)
468
- copy = set.slice(0, i);
469
- copy.push(this);
470
- placed = true;
471
- }
472
- if (copy)
473
- copy.push(other);
474
- }
475
- }
476
- if (!copy)
477
- copy = set.slice();
478
- if (!placed)
479
- copy.push(this);
480
- return copy;
481
- }
482
- /**
483
- Remove this mark from the given set, returning a new set. If this
484
- mark is not in the set, the set itself is returned.
485
- */
486
- removeFromSet(set) {
487
- for (let i = 0; i < set.length; i++)
488
- if (this.eq(set[i]))
489
- return set.slice(0, i).concat(set.slice(i + 1));
490
- return set;
491
- }
492
- /**
493
- Test whether this mark is in the given set of marks.
494
- */
495
- isInSet(set) {
496
- for (let i = 0; i < set.length; i++)
497
- if (this.eq(set[i]))
498
- return true;
499
- return false;
500
- }
501
- /**
502
- Test whether this mark has the same type and attributes as
503
- another mark.
504
- */
505
- eq(other) {
506
- return this == other || this.type == other.type && compareDeep(this.attrs, other.attrs);
507
- }
508
- /**
509
- Convert this mark to a JSON-serializeable representation.
510
- */
511
- toJSON() {
512
- let obj = { type: this.type.name };
513
- for (let _ in this.attrs) {
514
- obj.attrs = this.attrs;
515
- break;
516
- }
517
- return obj;
518
- }
519
- /**
520
- Deserialize a mark from JSON.
521
- */
522
- static fromJSON(schema, json) {
523
- if (!json)
524
- throw new RangeError("Invalid input for Mark.fromJSON");
525
- let type = schema.marks[json.type];
526
- if (!type)
527
- throw new RangeError(`There is no mark type ${json.type} in this schema`);
528
- let mark = type.create(json.attrs);
529
- type.checkAttrs(mark.attrs);
530
- return mark;
531
- }
532
- /**
533
- Test whether two sets of marks are identical.
534
- */
535
- static sameSet(a, b) {
536
- if (a == b)
537
- return true;
538
- if (a.length != b.length)
539
- return false;
540
- for (let i = 0; i < a.length; i++)
541
- if (!a[i].eq(b[i]))
542
- return false;
543
- return true;
544
- }
545
- /**
546
- Create a properly sorted mark set from null, a single mark, or an
547
- unsorted array of marks.
548
- */
549
- static setFrom(marks) {
550
- if (!marks || Array.isArray(marks) && marks.length == 0)
551
- return _Mark.none;
552
- if (marks instanceof _Mark)
553
- return [marks];
554
- let copy = marks.slice();
555
- copy.sort((a, b) => a.type.rank - b.type.rank);
556
- return copy;
557
- }
558
- };
559
- Mark.none = [];
560
- var ReplaceError = class extends Error {
561
- };
562
- var Slice = class _Slice {
563
- /**
564
- Create a slice. When specifying a non-zero open depth, you must
565
- make sure that there are nodes of at least that depth at the
566
- appropriate side of the fragment—i.e. if the fragment is an
567
- empty paragraph node, `openStart` and `openEnd` can't be greater
568
- than 1.
569
-
570
- It is not necessary for the content of open nodes to conform to
571
- the schema's content constraints, though it should be a valid
572
- start/end/middle for such a node, depending on which sides are
573
- open.
574
- */
575
- constructor(content, openStart, openEnd) {
576
- this.content = content;
577
- this.openStart = openStart;
578
- this.openEnd = openEnd;
579
- }
580
- /**
581
- The size this slice would add when inserted into a document.
582
- */
583
- get size() {
584
- return this.content.size - this.openStart - this.openEnd;
585
- }
586
- /**
587
- @internal
588
- */
589
- insertAt(pos, fragment) {
590
- let content = insertInto(this.content, pos + this.openStart, fragment);
591
- return content && new _Slice(content, this.openStart, this.openEnd);
592
- }
593
- /**
594
- @internal
595
- */
596
- removeBetween(from, to) {
597
- return new _Slice(removeRange(this.content, from + this.openStart, to + this.openStart), this.openStart, this.openEnd);
598
- }
599
- /**
600
- Tests whether this slice is equal to another slice.
601
- */
602
- eq(other) {
603
- return this.content.eq(other.content) && this.openStart == other.openStart && this.openEnd == other.openEnd;
604
- }
605
- /**
606
- @internal
607
- */
608
- toString() {
609
- return this.content + "(" + this.openStart + "," + this.openEnd + ")";
610
- }
611
- /**
612
- Convert a slice to a JSON-serializable representation.
613
- */
614
- toJSON() {
615
- if (!this.content.size)
616
- return null;
617
- let json = { content: this.content.toJSON() };
618
- if (this.openStart > 0)
619
- json.openStart = this.openStart;
620
- if (this.openEnd > 0)
621
- json.openEnd = this.openEnd;
622
- return json;
623
- }
624
- /**
625
- Deserialize a slice from its JSON representation.
626
- */
627
- static fromJSON(schema, json) {
628
- if (!json)
629
- return _Slice.empty;
630
- let openStart = json.openStart || 0, openEnd = json.openEnd || 0;
631
- if (typeof openStart != "number" || typeof openEnd != "number")
632
- throw new RangeError("Invalid input for Slice.fromJSON");
633
- return new _Slice(Fragment.fromJSON(schema, json.content), openStart, openEnd);
634
- }
635
- /**
636
- Create a slice from a fragment by taking the maximum possible
637
- open value on both side of the fragment.
638
- */
639
- static maxOpen(fragment, openIsolating = true) {
640
- let openStart = 0, openEnd = 0;
641
- for (let n = fragment.firstChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.firstChild)
642
- openStart++;
643
- for (let n = fragment.lastChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.lastChild)
644
- openEnd++;
645
- return new _Slice(fragment, openStart, openEnd);
646
- }
647
- };
648
- Slice.empty = new Slice(Fragment.empty, 0, 0);
649
- function removeRange(content, from, to) {
650
- let { index, offset: offset2 } = content.findIndex(from), child = content.maybeChild(index);
651
- let { index: indexTo, offset: offsetTo } = content.findIndex(to);
652
- if (offset2 == from || child.isText) {
653
- if (offsetTo != to && !content.child(indexTo).isText)
654
- throw new RangeError("Removing non-flat range");
655
- return content.cut(0, from).append(content.cut(to));
656
- }
657
- if (index != indexTo)
658
- throw new RangeError("Removing non-flat range");
659
- return content.replaceChild(index, child.copy(removeRange(child.content, from - offset2 - 1, to - offset2 - 1)));
660
- }
661
- function insertInto(content, dist, insert, parent) {
662
- let { index, offset: offset2 } = content.findIndex(dist), child = content.maybeChild(index);
663
- if (offset2 == dist || child.isText) {
664
- if (parent && !parent.canReplace(index, index, insert))
665
- return null;
666
- return content.cut(0, dist).append(insert).append(content.cut(dist));
667
- }
668
- let inner = insertInto(child.content, dist - offset2 - 1, insert, child);
669
- return inner && content.replaceChild(index, child.copy(inner));
670
- }
671
- function replace($from, $to, slice) {
672
- if (slice.openStart > $from.depth)
673
- throw new ReplaceError("Inserted content deeper than insertion position");
674
- if ($from.depth - slice.openStart != $to.depth - slice.openEnd)
675
- throw new ReplaceError("Inconsistent open depths");
676
- return replaceOuter($from, $to, slice, 0);
677
- }
678
- function replaceOuter($from, $to, slice, depth) {
679
- let index = $from.index(depth), node = $from.node(depth);
680
- if (index == $to.index(depth) && depth < $from.depth - slice.openStart) {
681
- let inner = replaceOuter($from, $to, slice, depth + 1);
682
- return node.copy(node.content.replaceChild(index, inner));
683
- } else if (!slice.content.size) {
684
- return close(node, replaceTwoWay($from, $to, depth));
685
- } else if (!slice.openStart && !slice.openEnd && $from.depth == depth && $to.depth == depth) {
686
- let parent = $from.parent, content = parent.content;
687
- return close(parent, content.cut(0, $from.parentOffset).append(slice.content).append(content.cut($to.parentOffset)));
688
- } else {
689
- let { start: start2, end: end2 } = prepareSliceForReplace(slice, $from);
690
- return close(node, replaceThreeWay($from, start2, end2, $to, depth));
691
- }
692
- }
693
- function checkJoin(main2, sub) {
694
- if (!sub.type.compatibleContent(main2.type))
695
- throw new ReplaceError("Cannot join " + sub.type.name + " onto " + main2.type.name);
696
- }
697
- function joinable($before, $after, depth) {
698
- let node = $before.node(depth);
699
- checkJoin(node, $after.node(depth));
700
- return node;
701
- }
702
- function addNode(child, target) {
703
- let last = target.length - 1;
704
- if (last >= 0 && child.isText && child.sameMarkup(target[last]))
705
- target[last] = child.withText(target[last].text + child.text);
706
- else
707
- target.push(child);
708
- }
709
- function addRange($start, $end, depth, target) {
710
- let node = ($end || $start).node(depth);
711
- let startIndex = 0, endIndex = $end ? $end.index(depth) : node.childCount;
712
- if ($start) {
713
- startIndex = $start.index(depth);
714
- if ($start.depth > depth) {
715
- startIndex++;
716
- } else if ($start.textOffset) {
717
- addNode($start.nodeAfter, target);
718
- startIndex++;
719
- }
720
- }
721
- for (let i = startIndex; i < endIndex; i++)
722
- addNode(node.child(i), target);
723
- if ($end && $end.depth == depth && $end.textOffset)
724
- addNode($end.nodeBefore, target);
725
- }
726
- function close(node, content) {
727
- node.type.checkContent(content);
728
- return node.copy(content);
729
- }
730
- function replaceThreeWay($from, $start, $end, $to, depth) {
731
- let openStart = $from.depth > depth && joinable($from, $start, depth + 1);
732
- let openEnd = $to.depth > depth && joinable($end, $to, depth + 1);
733
- let content = [];
734
- addRange(null, $from, depth, content);
735
- if (openStart && openEnd && $start.index(depth) == $end.index(depth)) {
736
- checkJoin(openStart, openEnd);
737
- addNode(close(openStart, replaceThreeWay($from, $start, $end, $to, depth + 1)), content);
738
- } else {
739
- if (openStart)
740
- addNode(close(openStart, replaceTwoWay($from, $start, depth + 1)), content);
741
- addRange($start, $end, depth, content);
742
- if (openEnd)
743
- addNode(close(openEnd, replaceTwoWay($end, $to, depth + 1)), content);
744
- }
745
- addRange($to, null, depth, content);
746
- return new Fragment(content);
747
- }
748
- function replaceTwoWay($from, $to, depth) {
749
- let content = [];
750
- addRange(null, $from, depth, content);
751
- if ($from.depth > depth) {
752
- let type = joinable($from, $to, depth + 1);
753
- addNode(close(type, replaceTwoWay($from, $to, depth + 1)), content);
754
- }
755
- addRange($to, null, depth, content);
756
- return new Fragment(content);
757
- }
758
- function prepareSliceForReplace(slice, $along) {
759
- let extra = $along.depth - slice.openStart, parent = $along.node(extra);
760
- let node = parent.copy(slice.content);
761
- for (let i = extra - 1; i >= 0; i--)
762
- node = $along.node(i).copy(Fragment.from(node));
763
- return {
764
- start: node.resolveNoCache(slice.openStart + extra),
765
- end: node.resolveNoCache(node.content.size - slice.openEnd - extra)
766
- };
767
- }
768
- var ResolvedPos = class _ResolvedPos {
769
- /**
770
- @internal
771
- */
772
- constructor(pos, path, parentOffset) {
773
- this.pos = pos;
774
- this.path = path;
775
- this.parentOffset = parentOffset;
776
- this.depth = path.length / 3 - 1;
777
- }
778
- /**
779
- @internal
780
- */
781
- resolveDepth(val) {
782
- if (val == null)
783
- return this.depth;
784
- if (val < 0)
785
- return this.depth + val;
786
- return val;
787
- }
788
- /**
789
- The parent node that the position points into. Note that even if
790
- a position points into a text node, that node is not considered
791
- the parent—text nodes are ‘flat’ in this model, and have no content.
792
- */
793
- get parent() {
794
- return this.node(this.depth);
795
- }
796
- /**
797
- The root node in which the position was resolved.
798
- */
799
- get doc() {
800
- return this.node(0);
801
- }
802
- /**
803
- The ancestor node at the given level. `p.node(p.depth)` is the
804
- same as `p.parent`.
805
- */
806
- node(depth) {
807
- return this.path[this.resolveDepth(depth) * 3];
808
- }
809
- /**
810
- The index into the ancestor at the given level. If this points
811
- at the 3rd node in the 2nd paragraph on the top level, for
812
- example, `p.index(0)` is 1 and `p.index(1)` is 2.
813
- */
814
- index(depth) {
815
- return this.path[this.resolveDepth(depth) * 3 + 1];
816
- }
817
- /**
818
- The index pointing after this position into the ancestor at the
819
- given level.
820
- */
821
- indexAfter(depth) {
822
- depth = this.resolveDepth(depth);
823
- return this.index(depth) + (depth == this.depth && !this.textOffset ? 0 : 1);
824
- }
825
- /**
826
- The (absolute) position at the start of the node at the given
827
- level.
828
- */
829
- start(depth) {
830
- depth = this.resolveDepth(depth);
831
- return depth == 0 ? 0 : this.path[depth * 3 - 1] + 1;
832
- }
833
- /**
834
- The (absolute) position at the end of the node at the given
835
- level.
836
- */
837
- end(depth) {
838
- depth = this.resolveDepth(depth);
839
- return this.start(depth) + this.node(depth).content.size;
840
- }
841
- /**
842
- The (absolute) position directly before the wrapping node at the
843
- given level, or, when `depth` is `this.depth + 1`, the original
844
- position.
845
- */
846
- before(depth) {
847
- depth = this.resolveDepth(depth);
848
- if (!depth)
849
- throw new RangeError("There is no position before the top-level node");
850
- return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1];
851
- }
852
- /**
853
- The (absolute) position directly after the wrapping node at the
854
- given level, or the original position when `depth` is `this.depth + 1`.
855
- */
856
- after(depth) {
857
- depth = this.resolveDepth(depth);
858
- if (!depth)
859
- throw new RangeError("There is no position after the top-level node");
860
- return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1] + this.path[depth * 3].nodeSize;
861
- }
862
- /**
863
- When this position points into a text node, this returns the
864
- distance between the position and the start of the text node.
865
- Will be zero for positions that point between nodes.
866
- */
867
- get textOffset() {
868
- return this.pos - this.path[this.path.length - 1];
869
- }
870
- /**
871
- Get the node directly after the position, if any. If the position
872
- points into a text node, only the part of that node after the
873
- position is returned.
874
- */
875
- get nodeAfter() {
876
- let parent = this.parent, index = this.index(this.depth);
877
- if (index == parent.childCount)
878
- return null;
879
- let dOff = this.pos - this.path[this.path.length - 1], child = parent.child(index);
880
- return dOff ? parent.child(index).cut(dOff) : child;
881
- }
882
- /**
883
- Get the node directly before the position, if any. If the
884
- position points into a text node, only the part of that node
885
- before the position is returned.
886
- */
887
- get nodeBefore() {
888
- let index = this.index(this.depth);
889
- let dOff = this.pos - this.path[this.path.length - 1];
890
- if (dOff)
891
- return this.parent.child(index).cut(0, dOff);
892
- return index == 0 ? null : this.parent.child(index - 1);
893
- }
894
- /**
895
- Get the position at the given index in the parent node at the
896
- given depth (which defaults to `this.depth`).
897
- */
898
- posAtIndex(index, depth) {
899
- depth = this.resolveDepth(depth);
900
- let node = this.path[depth * 3], pos = depth == 0 ? 0 : this.path[depth * 3 - 1] + 1;
901
- for (let i = 0; i < index; i++)
902
- pos += node.child(i).nodeSize;
903
- return pos;
904
- }
905
- /**
906
- Get the marks at this position, factoring in the surrounding
907
- marks' [`inclusive`](https://prosemirror.net/docs/ref/#model.MarkSpec.inclusive) property. If the
908
- position is at the start of a non-empty node, the marks of the
909
- node after it (if any) are returned.
910
- */
911
- marks() {
912
- let parent = this.parent, index = this.index();
913
- if (parent.content.size == 0)
914
- return Mark.none;
915
- if (this.textOffset)
916
- return parent.child(index).marks;
917
- let main2 = parent.maybeChild(index - 1), other = parent.maybeChild(index);
918
- if (!main2) {
919
- let tmp = main2;
920
- main2 = other;
921
- other = tmp;
922
- }
923
- let marks = main2.marks;
924
- for (var i = 0; i < marks.length; i++)
925
- if (marks[i].type.spec.inclusive === false && (!other || !marks[i].isInSet(other.marks)))
926
- marks = marks[i--].removeFromSet(marks);
927
- return marks;
928
- }
929
- /**
930
- Get the marks after the current position, if any, except those
931
- that are non-inclusive and not present at position `$end`. This
932
- is mostly useful for getting the set of marks to preserve after a
933
- deletion. Will return `null` if this position is at the end of
934
- its parent node or its parent node isn't a textblock (in which
935
- case no marks should be preserved).
936
- */
937
- marksAcross($end) {
938
- let after = this.parent.maybeChild(this.index());
939
- if (!after || !after.isInline)
940
- return null;
941
- let marks = after.marks, next = $end.parent.maybeChild($end.index());
942
- for (var i = 0; i < marks.length; i++)
943
- if (marks[i].type.spec.inclusive === false && (!next || !marks[i].isInSet(next.marks)))
944
- marks = marks[i--].removeFromSet(marks);
945
- return marks;
946
- }
947
- /**
948
- The depth up to which this position and the given (non-resolved)
949
- position share the same parent nodes.
950
- */
951
- sharedDepth(pos) {
952
- for (let depth = this.depth; depth > 0; depth--)
953
- if (this.start(depth) <= pos && this.end(depth) >= pos)
954
- return depth;
955
- return 0;
956
- }
957
- /**
958
- Returns a range based on the place where this position and the
959
- given position diverge around block content. If both point into
960
- the same textblock, for example, a range around that textblock
961
- will be returned. If they point into different blocks, the range
962
- around those blocks in their shared ancestor is returned. You can
963
- pass in an optional predicate that will be called with a parent
964
- node to see if a range into that parent is acceptable.
965
- */
966
- blockRange(other = this, pred) {
967
- if (other.pos < this.pos)
968
- return other.blockRange(this);
969
- for (let d = this.depth - (this.parent.inlineContent || this.pos == other.pos ? 1 : 0); d >= 0; d--)
970
- if (other.pos <= this.end(d) && (!pred || pred(this.node(d))))
971
- return new NodeRange(this, other, d);
972
- return null;
973
- }
974
- /**
975
- Query whether the given position shares the same parent node.
976
- */
977
- sameParent(other) {
978
- return this.pos - this.parentOffset == other.pos - other.parentOffset;
979
- }
980
- /**
981
- Return the greater of this and the given position.
982
- */
983
- max(other) {
984
- return other.pos > this.pos ? other : this;
985
- }
986
- /**
987
- Return the smaller of this and the given position.
988
- */
989
- min(other) {
990
- return other.pos < this.pos ? other : this;
991
- }
992
- /**
993
- @internal
994
- */
995
- toString() {
996
- let str = "";
997
- for (let i = 1; i <= this.depth; i++)
998
- str += (str ? "/" : "") + this.node(i).type.name + "_" + this.index(i - 1);
999
- return str + ":" + this.parentOffset;
1000
- }
1001
- /**
1002
- @internal
1003
- */
1004
- static resolve(doc, pos) {
1005
- if (!(pos >= 0 && pos <= doc.content.size))
1006
- throw new RangeError("Position " + pos + " out of range");
1007
- let path = [];
1008
- let start2 = 0, parentOffset = pos;
1009
- for (let node = doc; ; ) {
1010
- let { index, offset: offset2 } = node.content.findIndex(parentOffset);
1011
- let rem = parentOffset - offset2;
1012
- path.push(node, index, start2 + offset2);
1013
- if (!rem)
1014
- break;
1015
- node = node.child(index);
1016
- if (node.isText)
1017
- break;
1018
- parentOffset = rem - 1;
1019
- start2 += offset2 + 1;
1020
- }
1021
- return new _ResolvedPos(pos, path, parentOffset);
1022
- }
1023
- /**
1024
- @internal
1025
- */
1026
- static resolveCached(doc, pos) {
1027
- let cache = resolveCache.get(doc);
1028
- if (cache) {
1029
- for (let i = 0; i < cache.elts.length; i++) {
1030
- let elt = cache.elts[i];
1031
- if (elt.pos == pos)
1032
- return elt;
1033
- }
1034
- } else {
1035
- resolveCache.set(doc, cache = new ResolveCache());
1036
- }
1037
- let result = cache.elts[cache.i] = _ResolvedPos.resolve(doc, pos);
1038
- cache.i = (cache.i + 1) % resolveCacheSize;
1039
- return result;
1040
- }
1041
- };
1042
- var ResolveCache = class {
1043
- constructor() {
1044
- this.elts = [];
1045
- this.i = 0;
1046
- }
1047
- };
1048
- var resolveCacheSize = 12;
1049
- var resolveCache = /* @__PURE__ */ new WeakMap();
1050
- var NodeRange = class {
1051
- /**
1052
- Construct a node range. `$from` and `$to` should point into the
1053
- same node until at least the given `depth`, since a node range
1054
- denotes an adjacent set of nodes in a single parent node.
1055
- */
1056
- constructor($from, $to, depth) {
1057
- this.$from = $from;
1058
- this.$to = $to;
1059
- this.depth = depth;
1060
- }
1061
- /**
1062
- The position at the start of the range.
1063
- */
1064
- get start() {
1065
- return this.$from.before(this.depth + 1);
1066
- }
1067
- /**
1068
- The position at the end of the range.
1069
- */
1070
- get end() {
1071
- return this.$to.after(this.depth + 1);
1072
- }
1073
- /**
1074
- The parent node that the range points into.
1075
- */
1076
- get parent() {
1077
- return this.$from.node(this.depth);
1078
- }
1079
- /**
1080
- The start index of the range in the parent node.
1081
- */
1082
- get startIndex() {
1083
- return this.$from.index(this.depth);
1084
- }
1085
- /**
1086
- The end index of the range in the parent node.
1087
- */
1088
- get endIndex() {
1089
- return this.$to.indexAfter(this.depth);
1090
- }
1091
- };
1092
- var emptyAttrs = /* @__PURE__ */ Object.create(null);
1093
- var Node = class _Node {
1094
- /**
1095
- @internal
1096
- */
1097
- constructor(type, attrs, content, marks = Mark.none) {
1098
- this.type = type;
1099
- this.attrs = attrs;
1100
- this.marks = marks;
1101
- this.content = content || Fragment.empty;
1102
- }
1103
- /**
1104
- The array of this node's child nodes.
1105
- */
1106
- get children() {
1107
- return this.content.content;
1108
- }
1109
- /**
1110
- The size of this node, as defined by the integer-based [indexing
1111
- scheme](https://prosemirror.net/docs/guide/#doc.indexing). For text nodes, this is the
1112
- amount of characters. For other leaf nodes, it is one. For
1113
- non-leaf nodes, it is the size of the content plus two (the
1114
- start and end token).
1115
- */
1116
- get nodeSize() {
1117
- return this.isLeaf ? 1 : 2 + this.content.size;
1118
- }
1119
- /**
1120
- The number of children that the node has.
1121
- */
1122
- get childCount() {
1123
- return this.content.childCount;
1124
- }
1125
- /**
1126
- Get the child node at the given index. Raises an error when the
1127
- index is out of range.
1128
- */
1129
- child(index) {
1130
- return this.content.child(index);
1131
- }
1132
- /**
1133
- Get the child node at the given index, if it exists.
1134
- */
1135
- maybeChild(index) {
1136
- return this.content.maybeChild(index);
1137
- }
1138
- /**
1139
- Call `f` for every child node, passing the node, its offset
1140
- into this parent node, and its index.
1141
- */
1142
- forEach(f) {
1143
- this.content.forEach(f);
1144
- }
1145
- /**
1146
- Invoke a callback for all descendant nodes recursively between
1147
- the given two positions that are relative to start of this
1148
- node's content. The callback is invoked with the node, its
1149
- position relative to the original node (method receiver),
1150
- its parent node, and its child index. When the callback returns
1151
- false for a given node, that node's children will not be
1152
- recursed over. The last parameter can be used to specify a
1153
- starting position to count from.
1154
- */
1155
- nodesBetween(from, to, f, startPos = 0) {
1156
- this.content.nodesBetween(from, to, f, startPos, this);
1157
- }
1158
- /**
1159
- Call the given callback for every descendant node. Doesn't
1160
- descend into a node when the callback returns `false`.
1161
- */
1162
- descendants(f) {
1163
- this.nodesBetween(0, this.content.size, f);
1164
- }
1165
- /**
1166
- Concatenates all the text nodes found in this fragment and its
1167
- children.
1168
- */
1169
- get textContent() {
1170
- return this.isLeaf && this.type.spec.leafText ? this.type.spec.leafText(this) : this.textBetween(0, this.content.size, "");
1171
- }
1172
- /**
1173
- Get all text between positions `from` and `to`. When
1174
- `blockSeparator` is given, it will be inserted to separate text
1175
- from different block nodes. If `leafText` is given, it'll be
1176
- inserted for every non-text leaf node encountered, otherwise
1177
- [`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec.leafText) will be used.
1178
- */
1179
- textBetween(from, to, blockSeparator, leafText) {
1180
- return this.content.textBetween(from, to, blockSeparator, leafText);
1181
- }
1182
- /**
1183
- Returns this node's first child, or `null` if there are no
1184
- children.
1185
- */
1186
- get firstChild() {
1187
- return this.content.firstChild;
1188
- }
1189
- /**
1190
- Returns this node's last child, or `null` if there are no
1191
- children.
1192
- */
1193
- get lastChild() {
1194
- return this.content.lastChild;
1195
- }
1196
- /**
1197
- Test whether two nodes represent the same piece of document.
1198
- */
1199
- eq(other) {
1200
- return this == other || this.sameMarkup(other) && this.content.eq(other.content);
1201
- }
1202
- /**
1203
- Compare the markup (type, attributes, and marks) of this node to
1204
- those of another. Returns `true` if both have the same markup.
1205
- */
1206
- sameMarkup(other) {
1207
- return this.hasMarkup(other.type, other.attrs, other.marks);
1208
- }
1209
- /**
1210
- Check whether this node's markup correspond to the given type,
1211
- attributes, and marks.
1212
- */
1213
- hasMarkup(type, attrs, marks) {
1214
- return this.type == type && compareDeep(this.attrs, attrs || type.defaultAttrs || emptyAttrs) && Mark.sameSet(this.marks, marks || Mark.none);
1215
- }
1216
- /**
1217
- Create a new node with the same markup as this node, containing
1218
- the given content (or empty, if no content is given).
1219
- */
1220
- copy(content = null) {
1221
- if (content == this.content)
1222
- return this;
1223
- return new _Node(this.type, this.attrs, content, this.marks);
1224
- }
1225
- /**
1226
- Create a copy of this node, with the given set of marks instead
1227
- of the node's own marks.
1228
- */
1229
- mark(marks) {
1230
- return marks == this.marks ? this : new _Node(this.type, this.attrs, this.content, marks);
1231
- }
1232
- /**
1233
- Create a copy of this node with only the content between the
1234
- given positions. If `to` is not given, it defaults to the end of
1235
- the node.
1236
- */
1237
- cut(from, to = this.content.size) {
1238
- if (from == 0 && to == this.content.size)
1239
- return this;
1240
- return this.copy(this.content.cut(from, to));
1241
- }
1242
- /**
1243
- Cut out the part of the document between the given positions, and
1244
- return it as a `Slice` object.
1245
- */
1246
- slice(from, to = this.content.size, includeParents = false) {
1247
- if (from == to)
1248
- return Slice.empty;
1249
- let $from = this.resolve(from), $to = this.resolve(to);
1250
- let depth = includeParents ? 0 : $from.sharedDepth(to);
1251
- let start2 = $from.start(depth), node = $from.node(depth);
1252
- let content = node.content.cut($from.pos - start2, $to.pos - start2);
1253
- return new Slice(content, $from.depth - depth, $to.depth - depth);
1254
- }
1255
- /**
1256
- Replace the part of the document between the given positions with
1257
- the given slice. The slice must 'fit', meaning its open sides
1258
- must be able to connect to the surrounding content, and its
1259
- content nodes must be valid children for the node they are placed
1260
- into. If any of this is violated, an error of type
1261
- [`ReplaceError`](https://prosemirror.net/docs/ref/#model.ReplaceError) is thrown.
1262
- */
1263
- replace(from, to, slice) {
1264
- return replace(this.resolve(from), this.resolve(to), slice);
1265
- }
1266
- /**
1267
- Find the node directly after the given position.
1268
- */
1269
- nodeAt(pos) {
1270
- for (let node = this; ; ) {
1271
- let { index, offset: offset2 } = node.content.findIndex(pos);
1272
- node = node.maybeChild(index);
1273
- if (!node)
1274
- return null;
1275
- if (offset2 == pos || node.isText)
1276
- return node;
1277
- pos -= offset2 + 1;
1278
- }
1279
- }
1280
- /**
1281
- Find the (direct) child node after the given offset, if any,
1282
- and return it along with its index and offset relative to this
1283
- node.
1284
- */
1285
- childAfter(pos) {
1286
- let { index, offset: offset2 } = this.content.findIndex(pos);
1287
- return { node: this.content.maybeChild(index), index, offset: offset2 };
1288
- }
1289
- /**
1290
- Find the (direct) child node before the given offset, if any,
1291
- and return it along with its index and offset relative to this
1292
- node.
1293
- */
1294
- childBefore(pos) {
1295
- if (pos == 0)
1296
- return { node: null, index: 0, offset: 0 };
1297
- let { index, offset: offset2 } = this.content.findIndex(pos);
1298
- if (offset2 < pos)
1299
- return { node: this.content.child(index), index, offset: offset2 };
1300
- let node = this.content.child(index - 1);
1301
- return { node, index: index - 1, offset: offset2 - node.nodeSize };
1302
- }
1303
- /**
1304
- Resolve the given position in the document, returning an
1305
- [object](https://prosemirror.net/docs/ref/#model.ResolvedPos) with information about its context.
1306
- */
1307
- resolve(pos) {
1308
- return ResolvedPos.resolveCached(this, pos);
1309
- }
1310
- /**
1311
- @internal
1312
- */
1313
- resolveNoCache(pos) {
1314
- return ResolvedPos.resolve(this, pos);
1315
- }
1316
- /**
1317
- Test whether a given mark or mark type occurs in this document
1318
- between the two given positions.
1319
- */
1320
- rangeHasMark(from, to, type) {
1321
- let found2 = false;
1322
- if (to > from)
1323
- this.nodesBetween(from, to, (node) => {
1324
- if (type.isInSet(node.marks))
1325
- found2 = true;
1326
- return !found2;
1327
- });
1328
- return found2;
1329
- }
1330
- /**
1331
- True when this is a block (non-inline node)
1332
- */
1333
- get isBlock() {
1334
- return this.type.isBlock;
1335
- }
1336
- /**
1337
- True when this is a textblock node, a block node with inline
1338
- content.
1339
- */
1340
- get isTextblock() {
1341
- return this.type.isTextblock;
1342
- }
1343
- /**
1344
- True when this node allows inline content.
1345
- */
1346
- get inlineContent() {
1347
- return this.type.inlineContent;
1348
- }
1349
- /**
1350
- True when this is an inline node (a text node or a node that can
1351
- appear among text).
1352
- */
1353
- get isInline() {
1354
- return this.type.isInline;
1355
- }
1356
- /**
1357
- True when this is a text node.
1358
- */
1359
- get isText() {
1360
- return this.type.isText;
1361
- }
1362
- /**
1363
- True when this is a leaf node.
1364
- */
1365
- get isLeaf() {
1366
- return this.type.isLeaf;
1367
- }
1368
- /**
1369
- True when this is an atom, i.e. when it does not have directly
1370
- editable content. This is usually the same as `isLeaf`, but can
1371
- be configured with the [`atom` property](https://prosemirror.net/docs/ref/#model.NodeSpec.atom)
1372
- on a node's spec (typically used when the node is displayed as
1373
- an uneditable [node view](https://prosemirror.net/docs/ref/#view.NodeView)).
1374
- */
1375
- get isAtom() {
1376
- return this.type.isAtom;
1377
- }
1378
- /**
1379
- Return a string representation of this node for debugging
1380
- purposes.
1381
- */
1382
- toString() {
1383
- if (this.type.spec.toDebugString)
1384
- return this.type.spec.toDebugString(this);
1385
- let name = this.type.name;
1386
- if (this.content.size)
1387
- name += "(" + this.content.toStringInner() + ")";
1388
- return wrapMarks(this.marks, name);
1389
- }
1390
- /**
1391
- Get the content match in this node at the given index.
1392
- */
1393
- contentMatchAt(index) {
1394
- let match = this.type.contentMatch.matchFragment(this.content, 0, index);
1395
- if (!match)
1396
- throw new Error("Called contentMatchAt on a node with invalid content");
1397
- return match;
1398
- }
1399
- /**
1400
- Test whether replacing the range between `from` and `to` (by
1401
- child index) with the given replacement fragment (which defaults
1402
- to the empty fragment) would leave the node's content valid. You
1403
- can optionally pass `start` and `end` indices into the
1404
- replacement fragment.
1405
- */
1406
- canReplace(from, to, replacement = Fragment.empty, start2 = 0, end2 = replacement.childCount) {
1407
- let one = this.contentMatchAt(from).matchFragment(replacement, start2, end2);
1408
- let two = one && one.matchFragment(this.content, to);
1409
- if (!two || !two.validEnd)
1410
- return false;
1411
- for (let i = start2; i < end2; i++)
1412
- if (!this.type.allowsMarks(replacement.child(i).marks))
1413
- return false;
1414
- return true;
1415
- }
1416
- /**
1417
- Test whether replacing the range `from` to `to` (by index) with
1418
- a node of the given type would leave the node's content valid.
1419
- */
1420
- canReplaceWith(from, to, type, marks) {
1421
- if (marks && !this.type.allowsMarks(marks))
1422
- return false;
1423
- let start2 = this.contentMatchAt(from).matchType(type);
1424
- let end2 = start2 && start2.matchFragment(this.content, to);
1425
- return end2 ? end2.validEnd : false;
1426
- }
1427
- /**
1428
- Test whether the given node's content could be appended to this
1429
- node. If that node is empty, this will only return true if there
1430
- is at least one node type that can appear in both nodes (to avoid
1431
- merging completely incompatible nodes).
1432
- */
1433
- canAppend(other) {
1434
- if (other.content.size)
1435
- return this.canReplace(this.childCount, this.childCount, other.content);
1436
- else
1437
- return this.type.compatibleContent(other.type);
1438
- }
1439
- /**
1440
- Check whether this node and its descendants conform to the
1441
- schema, and raise an exception when they do not.
1442
- */
1443
- check() {
1444
- this.type.checkContent(this.content);
1445
- this.type.checkAttrs(this.attrs);
1446
- let copy = Mark.none;
1447
- for (let i = 0; i < this.marks.length; i++) {
1448
- let mark = this.marks[i];
1449
- mark.type.checkAttrs(mark.attrs);
1450
- copy = mark.addToSet(copy);
1451
- }
1452
- if (!Mark.sameSet(copy, this.marks))
1453
- throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map((m) => m.type.name)}`);
1454
- this.content.forEach((node) => node.check());
1455
- }
1456
- /**
1457
- Return a JSON-serializeable representation of this node.
1458
- */
1459
- toJSON() {
1460
- let obj = { type: this.type.name };
1461
- for (let _ in this.attrs) {
1462
- obj.attrs = this.attrs;
1463
- break;
1464
- }
1465
- if (this.content.size)
1466
- obj.content = this.content.toJSON();
1467
- if (this.marks.length)
1468
- obj.marks = this.marks.map((n) => n.toJSON());
1469
- return obj;
1470
- }
1471
- /**
1472
- Deserialize a node from its JSON representation.
1473
- */
1474
- static fromJSON(schema, json) {
1475
- if (!json)
1476
- throw new RangeError("Invalid input for Node.fromJSON");
1477
- let marks = void 0;
1478
- if (json.marks) {
1479
- if (!Array.isArray(json.marks))
1480
- throw new RangeError("Invalid mark data for Node.fromJSON");
1481
- marks = json.marks.map(schema.markFromJSON);
1482
- }
1483
- if (json.type == "text") {
1484
- if (typeof json.text != "string")
1485
- throw new RangeError("Invalid text node in JSON");
1486
- return schema.text(json.text, marks);
1487
- }
1488
- let content = Fragment.fromJSON(schema, json.content);
1489
- let node = schema.nodeType(json.type).create(json.attrs, content, marks);
1490
- node.type.checkAttrs(node.attrs);
1491
- return node;
1492
- }
1493
- };
1494
- Node.prototype.text = void 0;
1495
- function wrapMarks(marks, str) {
1496
- for (let i = marks.length - 1; i >= 0; i--)
1497
- str = marks[i].type.name + "(" + str + ")";
1498
- return str;
1499
- }
1500
- var ContentMatch = class _ContentMatch {
1501
- /**
1502
- @internal
1503
- */
1504
- constructor(validEnd) {
1505
- this.validEnd = validEnd;
1506
- this.next = [];
1507
- this.wrapCache = [];
1508
- }
1509
- /**
1510
- @internal
1511
- */
1512
- static parse(string, nodeTypes) {
1513
- let stream = new TokenStream(string, nodeTypes);
1514
- if (stream.next == null)
1515
- return _ContentMatch.empty;
1516
- let expr = parseExpr(stream);
1517
- if (stream.next)
1518
- stream.err("Unexpected trailing text");
1519
- let match = dfa(nfa(expr));
1520
- checkForDeadEnds(match, stream);
1521
- return match;
1522
- }
1523
- /**
1524
- Match a node type, returning a match after that node if
1525
- successful.
1526
- */
1527
- matchType(type) {
1528
- for (let i = 0; i < this.next.length; i++)
1529
- if (this.next[i].type == type)
1530
- return this.next[i].next;
1531
- return null;
347
+ } else if (joined) {
348
+ joined.push(node);
349
+ }
350
+ }
351
+ return new _Fragment(joined || array, size);
1532
352
  }
1533
353
  /**
1534
- Try to match a fragment. Returns the resulting match when
1535
- successful.
354
+ Create a fragment from something that can be interpreted as a
355
+ set of nodes. For `null`, it returns the empty fragment. For a
356
+ fragment, the fragment itself. For a node or array of nodes, a
357
+ fragment containing those nodes.
1536
358
  */
1537
- matchFragment(frag, start2 = 0, end2 = frag.childCount) {
1538
- let cur = this;
1539
- for (let i = start2; cur && i < end2; i++)
1540
- cur = cur.matchType(frag.child(i).type);
1541
- return cur;
359
+ static from(nodes) {
360
+ if (!nodes)
361
+ return _Fragment.empty;
362
+ if (nodes instanceof _Fragment)
363
+ return nodes;
364
+ if (Array.isArray(nodes))
365
+ return this.fromArray(nodes);
366
+ if (nodes.attrs)
367
+ return new _Fragment([nodes], nodes.nodeSize);
368
+ throw new RangeError("Can not convert " + nodes + " to a Fragment" + (nodes.nodesBetween ? " (looks like multiple versions of prosemirror-model were loaded)" : ""));
1542
369
  }
370
+ };
371
+ Fragment.empty = new Fragment([], 0);
372
+ var found = { index: 0, offset: 0 };
373
+ function retIndex(index, offset2) {
374
+ found.index = index;
375
+ found.offset = offset2;
376
+ return found;
377
+ }
378
+ var ReplaceError = class extends Error {
379
+ };
380
+ var Slice = class _Slice {
1543
381
  /**
1544
- @internal
382
+ Create a slice. When specifying a non-zero open depth, you must
383
+ make sure that there are nodes of at least that depth at the
384
+ appropriate side of the fragment—i.e. if the fragment is an
385
+ empty paragraph node, `openStart` and `openEnd` can't be greater
386
+ than 1.
387
+
388
+ It is not necessary for the content of open nodes to conform to
389
+ the schema's content constraints, though it should be a valid
390
+ start/end/middle for such a node, depending on which sides are
391
+ open.
1545
392
  */
1546
- get inlineContent() {
1547
- return this.next.length != 0 && this.next[0].type.isInline;
393
+ constructor(content, openStart, openEnd) {
394
+ this.content = content;
395
+ this.openStart = openStart;
396
+ this.openEnd = openEnd;
1548
397
  }
1549
398
  /**
1550
- Get the first matching node type at this match position that can
1551
- be generated.
399
+ The size this slice would add when inserted into a document.
1552
400
  */
1553
- get defaultType() {
1554
- for (let i = 0; i < this.next.length; i++) {
1555
- let { type } = this.next[i];
1556
- if (!(type.isText || type.hasRequiredAttrs()))
1557
- return type;
1558
- }
1559
- return null;
401
+ get size() {
402
+ return this.content.size - this.openStart - this.openEnd;
1560
403
  }
1561
404
  /**
1562
405
  @internal
1563
406
  */
1564
- compatible(other) {
1565
- for (let i = 0; i < this.next.length; i++)
1566
- for (let j = 0; j < other.next.length; j++)
1567
- if (this.next[i].type == other.next[j].type)
1568
- return true;
1569
- return false;
407
+ insertAt(pos, fragment) {
408
+ let content = insertInto(this.content, pos + this.openStart, fragment);
409
+ return content && new _Slice(content, this.openStart, this.openEnd);
1570
410
  }
1571
411
  /**
1572
- Try to match the given fragment, and if that fails, see if it can
1573
- be made to match by inserting nodes in front of it. When
1574
- successful, return a fragment of inserted nodes (which may be
1575
- empty if nothing had to be inserted). When `toEnd` is true, only
1576
- return a fragment if the resulting match goes to the end of the
1577
- content expression.
412
+ @internal
1578
413
  */
1579
- fillBefore(after, toEnd = false, startIndex = 0) {
1580
- let seen = [this];
1581
- function search(match, types) {
1582
- let finished = match.matchFragment(after, startIndex);
1583
- if (finished && (!toEnd || finished.validEnd))
1584
- return Fragment.from(types.map((tp) => tp.createAndFill()));
1585
- for (let i = 0; i < match.next.length; i++) {
1586
- let { type, next } = match.next[i];
1587
- if (!(type.isText || type.hasRequiredAttrs()) && seen.indexOf(next) == -1) {
1588
- seen.push(next);
1589
- let found2 = search(next, types.concat(type));
1590
- if (found2)
1591
- return found2;
1592
- }
1593
- }
1594
- return null;
1595
- }
1596
- return search(this, []);
414
+ removeBetween(from, to) {
415
+ return new _Slice(removeRange(this.content, from + this.openStart, to + this.openStart), this.openStart, this.openEnd);
1597
416
  }
1598
417
  /**
1599
- Find a set of wrapping node types that would allow a node of the
1600
- given type to appear at this position. The result may be empty
1601
- (when it fits directly) and will be null when no such wrapping
1602
- exists.
418
+ Tests whether this slice is equal to another slice.
1603
419
  */
1604
- findWrapping(target) {
1605
- for (let i = 0; i < this.wrapCache.length; i += 2)
1606
- if (this.wrapCache[i] == target)
1607
- return this.wrapCache[i + 1];
1608
- let computed = this.computeWrapping(target);
1609
- this.wrapCache.push(target, computed);
1610
- return computed;
420
+ eq(other) {
421
+ return this.content.eq(other.content) && this.openStart == other.openStart && this.openEnd == other.openEnd;
1611
422
  }
1612
423
  /**
1613
424
  @internal
1614
425
  */
1615
- computeWrapping(target) {
1616
- let seen = /* @__PURE__ */ Object.create(null), active = [{ match: this, type: null, via: null }];
1617
- while (active.length) {
1618
- let current = active.shift(), match = current.match;
1619
- if (match.matchType(target)) {
1620
- let result = [];
1621
- for (let obj = current; obj.type; obj = obj.via)
1622
- result.push(obj.type);
1623
- return result.reverse();
1624
- }
1625
- for (let i = 0; i < match.next.length; i++) {
1626
- let { type, next } = match.next[i];
1627
- if (!type.isLeaf && !type.hasRequiredAttrs() && !(type.name in seen) && (!current.type || next.validEnd)) {
1628
- active.push({ match: type.contentMatch, type, via: current });
1629
- seen[type.name] = true;
1630
- }
1631
- }
1632
- }
1633
- return null;
426
+ toString() {
427
+ return this.content + "(" + this.openStart + "," + this.openEnd + ")";
1634
428
  }
1635
429
  /**
1636
- The number of outgoing edges this node has in the finite
1637
- automaton that describes the content expression.
430
+ Convert a slice to a JSON-serializable representation.
1638
431
  */
1639
- get edgeCount() {
1640
- return this.next.length;
432
+ toJSON() {
433
+ if (!this.content.size)
434
+ return null;
435
+ let json = { content: this.content.toJSON() };
436
+ if (this.openStart > 0)
437
+ json.openStart = this.openStart;
438
+ if (this.openEnd > 0)
439
+ json.openEnd = this.openEnd;
440
+ return json;
1641
441
  }
1642
442
  /**
1643
- Get the _n_​th outgoing edge from this node in the finite
1644
- automaton that describes the content expression.
443
+ Deserialize a slice from its JSON representation.
1645
444
  */
1646
- edge(n) {
1647
- if (n >= this.next.length)
1648
- throw new RangeError(`There's no ${n}th edge in this content match`);
1649
- return this.next[n];
445
+ static fromJSON(schema, json) {
446
+ if (!json)
447
+ return _Slice.empty;
448
+ let openStart = json.openStart || 0, openEnd = json.openEnd || 0;
449
+ if (typeof openStart != "number" || typeof openEnd != "number")
450
+ throw new RangeError("Invalid input for Slice.fromJSON");
451
+ return new _Slice(Fragment.fromJSON(schema, json.content), openStart, openEnd);
1650
452
  }
1651
453
  /**
1652
- @internal
454
+ Create a slice from a fragment by taking the maximum possible
455
+ open value on both side of the fragment.
1653
456
  */
1654
- toString() {
1655
- let seen = [];
1656
- function scan(m) {
1657
- seen.push(m);
1658
- for (let i = 0; i < m.next.length; i++)
1659
- if (seen.indexOf(m.next[i].next) == -1)
1660
- scan(m.next[i].next);
1661
- }
1662
- scan(this);
1663
- return seen.map((m, i) => {
1664
- let out = i + (m.validEnd ? "*" : " ") + " ";
1665
- for (let i2 = 0; i2 < m.next.length; i2++)
1666
- out += (i2 ? ", " : "") + m.next[i2].type.name + "->" + seen.indexOf(m.next[i2].next);
1667
- return out;
1668
- }).join("\n");
1669
- }
1670
- };
1671
- ContentMatch.empty = new ContentMatch(true);
1672
- var TokenStream = class {
1673
- constructor(string, nodeTypes) {
1674
- this.string = string;
1675
- this.nodeTypes = nodeTypes;
1676
- this.inline = null;
1677
- this.pos = 0;
1678
- this.tokens = string.split(/\s*(?=\b|\W|$)/);
1679
- if (this.tokens[this.tokens.length - 1] == "")
1680
- this.tokens.pop();
1681
- if (this.tokens[0] == "")
1682
- this.tokens.shift();
1683
- }
1684
- get next() {
1685
- return this.tokens[this.pos];
1686
- }
1687
- eat(tok) {
1688
- return this.next == tok && (this.pos++ || true);
1689
- }
1690
- err(str) {
1691
- throw new SyntaxError(str + " (in content expression '" + this.string + "')");
457
+ static maxOpen(fragment, openIsolating = true) {
458
+ let openStart = 0, openEnd = 0;
459
+ for (let n = fragment.firstChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.firstChild)
460
+ openStart++;
461
+ for (let n = fragment.lastChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.lastChild)
462
+ openEnd++;
463
+ return new _Slice(fragment, openStart, openEnd);
1692
464
  }
1693
465
  };
1694
- function parseExpr(stream) {
1695
- let exprs = [];
1696
- do {
1697
- exprs.push(parseExprSeq(stream));
1698
- } while (stream.eat("|"));
1699
- return exprs.length == 1 ? exprs[0] : { type: "choice", exprs };
1700
- }
1701
- function parseExprSeq(stream) {
1702
- let exprs = [];
1703
- do {
1704
- exprs.push(parseExprSubscript(stream));
1705
- } while (stream.next && stream.next != ")" && stream.next != "|");
1706
- return exprs.length == 1 ? exprs[0] : { type: "seq", exprs };
1707
- }
1708
- function parseExprSubscript(stream) {
1709
- let expr = parseExprAtom(stream);
1710
- for (; ; ) {
1711
- if (stream.eat("+"))
1712
- expr = { type: "plus", expr };
1713
- else if (stream.eat("*"))
1714
- expr = { type: "star", expr };
1715
- else if (stream.eat("?"))
1716
- expr = { type: "opt", expr };
1717
- else if (stream.eat("{"))
1718
- expr = parseExprRange(stream, expr);
1719
- else
1720
- break;
1721
- }
1722
- return expr;
1723
- }
1724
- function parseNum(stream) {
1725
- if (/\D/.test(stream.next))
1726
- stream.err("Expected number, got '" + stream.next + "'");
1727
- let result = Number(stream.next);
1728
- stream.pos++;
1729
- return result;
1730
- }
1731
- function parseExprRange(stream, expr) {
1732
- let min2 = parseNum(stream), max2 = min2;
1733
- if (stream.eat(",")) {
1734
- if (stream.next != "}")
1735
- max2 = parseNum(stream);
1736
- else
1737
- max2 = -1;
1738
- }
1739
- if (!stream.eat("}"))
1740
- stream.err("Unclosed braced range");
1741
- return { type: "range", min: min2, max: max2, expr };
1742
- }
1743
- function resolveName(stream, name) {
1744
- let types = stream.nodeTypes, type = types[name];
1745
- if (type)
1746
- return [type];
1747
- let result = [];
1748
- for (let typeName in types) {
1749
- let type2 = types[typeName];
1750
- if (type2.isInGroup(name))
1751
- result.push(type2);
1752
- }
1753
- if (result.length == 0)
1754
- stream.err("No node type or group '" + name + "' found");
1755
- return result;
1756
- }
1757
- function parseExprAtom(stream) {
1758
- if (stream.eat("(")) {
1759
- let expr = parseExpr(stream);
1760
- if (!stream.eat(")"))
1761
- stream.err("Missing closing paren");
1762
- return expr;
1763
- } else if (!/\W/.test(stream.next)) {
1764
- let exprs = resolveName(stream, stream.next).map((type) => {
1765
- if (stream.inline == null)
1766
- stream.inline = type.isInline;
1767
- else if (stream.inline != type.isInline)
1768
- stream.err("Mixing inline and block content");
1769
- return { type: "name", value: type };
1770
- });
1771
- stream.pos++;
1772
- return exprs.length == 1 ? exprs[0] : { type: "choice", exprs };
1773
- } else {
1774
- stream.err("Unexpected token '" + stream.next + "'");
1775
- }
1776
- }
1777
- function nfa(expr) {
1778
- let nfa2 = [[]];
1779
- connect(compile(expr, 0), node());
1780
- return nfa2;
1781
- function node() {
1782
- return nfa2.push([]) - 1;
1783
- }
1784
- function edge(from, to, term) {
1785
- let edge2 = { term, to };
1786
- nfa2[from].push(edge2);
1787
- return edge2;
1788
- }
1789
- function connect(edges, to) {
1790
- edges.forEach((edge2) => edge2.to = to);
1791
- }
1792
- function compile(expr2, from) {
1793
- if (expr2.type == "choice") {
1794
- return expr2.exprs.reduce((out, expr3) => out.concat(compile(expr3, from)), []);
1795
- } else if (expr2.type == "seq") {
1796
- for (let i = 0; ; i++) {
1797
- let next = compile(expr2.exprs[i], from);
1798
- if (i == expr2.exprs.length - 1)
1799
- return next;
1800
- connect(next, from = node());
1801
- }
1802
- } else if (expr2.type == "star") {
1803
- let loop = node();
1804
- edge(from, loop);
1805
- connect(compile(expr2.expr, loop), loop);
1806
- return [edge(loop)];
1807
- } else if (expr2.type == "plus") {
1808
- let loop = node();
1809
- connect(compile(expr2.expr, from), loop);
1810
- connect(compile(expr2.expr, loop), loop);
1811
- return [edge(loop)];
1812
- } else if (expr2.type == "opt") {
1813
- return [edge(from)].concat(compile(expr2.expr, from));
1814
- } else if (expr2.type == "range") {
1815
- let cur = from;
1816
- for (let i = 0; i < expr2.min; i++) {
1817
- let next = node();
1818
- connect(compile(expr2.expr, cur), next);
1819
- cur = next;
1820
- }
1821
- if (expr2.max == -1) {
1822
- connect(compile(expr2.expr, cur), cur);
1823
- } else {
1824
- for (let i = expr2.min; i < expr2.max; i++) {
1825
- let next = node();
1826
- edge(cur, next);
1827
- connect(compile(expr2.expr, cur), next);
1828
- cur = next;
1829
- }
1830
- }
1831
- return [edge(cur)];
1832
- } else if (expr2.type == "name") {
1833
- return [edge(from, void 0, expr2.value)];
1834
- } else {
1835
- throw new Error("Unknown expr type");
1836
- }
1837
- }
1838
- }
1839
- function cmp(a, b) {
1840
- return b - a;
1841
- }
1842
- function nullFrom(nfa2, node) {
1843
- let result = [];
1844
- scan(node);
1845
- return result.sort(cmp);
1846
- function scan(node2) {
1847
- let edges = nfa2[node2];
1848
- if (edges.length == 1 && !edges[0].term)
1849
- return scan(edges[0].to);
1850
- result.push(node2);
1851
- for (let i = 0; i < edges.length; i++) {
1852
- let { term, to } = edges[i];
1853
- if (!term && result.indexOf(to) == -1)
1854
- scan(to);
1855
- }
1856
- }
1857
- }
1858
- function dfa(nfa2) {
1859
- let labeled = /* @__PURE__ */ Object.create(null);
1860
- return explore(nullFrom(nfa2, 0));
1861
- function explore(states) {
1862
- let out = [];
1863
- states.forEach((node) => {
1864
- nfa2[node].forEach(({ term, to }) => {
1865
- if (!term)
1866
- return;
1867
- let set;
1868
- for (let i = 0; i < out.length; i++)
1869
- if (out[i][0] == term)
1870
- set = out[i][1];
1871
- nullFrom(nfa2, to).forEach((node2) => {
1872
- if (!set)
1873
- out.push([term, set = []]);
1874
- if (set.indexOf(node2) == -1)
1875
- set.push(node2);
1876
- });
1877
- });
1878
- });
1879
- let state = labeled[states.join(",")] = new ContentMatch(states.indexOf(nfa2.length - 1) > -1);
1880
- for (let i = 0; i < out.length; i++) {
1881
- let states2 = out[i][1].sort(cmp);
1882
- state.next.push({ type: out[i][0], next: labeled[states2.join(",")] || explore(states2) });
1883
- }
1884
- return state;
466
+ Slice.empty = new Slice(Fragment.empty, 0, 0);
467
+ function removeRange(content, from, to) {
468
+ let { index, offset: offset2 } = content.findIndex(from), child = content.maybeChild(index);
469
+ let { index: indexTo, offset: offsetTo } = content.findIndex(to);
470
+ if (offset2 == from || child.isText) {
471
+ if (offsetTo != to && !content.child(indexTo).isText)
472
+ throw new RangeError("Removing non-flat range");
473
+ return content.cut(0, from).append(content.cut(to));
1885
474
  }
475
+ if (index != indexTo)
476
+ throw new RangeError("Removing non-flat range");
477
+ return content.replaceChild(index, child.copy(removeRange(child.content, from - offset2 - 1, to - offset2 - 1)));
1886
478
  }
1887
- function checkForDeadEnds(match, stream) {
1888
- for (let i = 0, work = [match]; i < work.length; i++) {
1889
- let state = work[i], dead = !state.validEnd, nodes = [];
1890
- for (let j = 0; j < state.next.length; j++) {
1891
- let { type, next } = state.next[j];
1892
- nodes.push(type.name);
1893
- if (dead && !(type.isText || type.hasRequiredAttrs()))
1894
- dead = false;
1895
- if (work.indexOf(next) == -1)
1896
- work.push(next);
1897
- }
1898
- if (dead)
1899
- stream.err("Only non-generatable nodes (" + nodes.join(", ") + ") in a required position (see https://prosemirror.net/docs/guide/#generatable)");
479
+ function insertInto(content, dist, insert, parent) {
480
+ let { index, offset: offset2 } = content.findIndex(dist), child = content.maybeChild(index);
481
+ if (offset2 == dist || child.isText) {
482
+ if (parent && !parent.canReplace(index, index, insert))
483
+ return null;
484
+ return content.cut(0, dist).append(insert).append(content.cut(dist));
1900
485
  }
486
+ let inner = insertInto(child.content, dist - offset2 - 1, insert, child);
487
+ return inner && content.replaceChild(index, child.copy(inner));
1901
488
  }
1902
489
 
1903
490
  // node_modules/prosemirror-transform/dist/index.js
@@ -3032,7 +1619,7 @@ var FieldDesc = class {
3032
1619
  this.apply = bind(desc.apply, self);
3033
1620
  }
3034
1621
  };
3035
- var baseFields = [
1622
+ [
3036
1623
  new FieldDesc("doc", {
3037
1624
  init(config) {
3038
1625
  return config.doc || config.schema.topNodeType.createAndFill();
@@ -3889,7 +2476,6 @@ function computeOffsets(_ref) {
3889
2476
  case end:
3890
2477
  offsets[mainAxis] = offsets[mainAxis] + (reference2[len] / 2 - element[len] / 2);
3891
2478
  break;
3892
- default:
3893
2479
  }
3894
2480
  }
3895
2481
  return offsets;
@@ -3910,7 +2496,6 @@ function detectOverflow(state, options) {
3910
2496
  var popperOffsets2 = computeOffsets({
3911
2497
  reference: referenceClientRect,
3912
2498
  element: popperRect,
3913
- strategy: "absolute",
3914
2499
  placement
3915
2500
  });
3916
2501
  var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets2));
@@ -4167,7 +2752,6 @@ function popperOffsets(_ref) {
4167
2752
  state.modifiersData[name] = computeOffsets({
4168
2753
  reference: state.rects.reference,
4169
2754
  element: state.rects.popper,
4170
- strategy: "absolute",
4171
2755
  placement: state.placement
4172
2756
  });
4173
2757
  }
@@ -5806,7 +4390,7 @@ function tippy(targets, optionalProps) {
5806
4390
  tippy.defaultProps = defaultProps;
5807
4391
  tippy.setDefaultProps = setDefaultProps;
5808
4392
  tippy.currentInput = currentInput;
5809
- var applyStylesModifier = Object.assign({}, applyStyles_default, {
4393
+ Object.assign({}, applyStyles_default, {
5810
4394
  effect: function effect4(_ref) {
5811
4395
  var state = _ref.state;
5812
4396
  var initialStyles = {
@@ -5832,15 +4416,11 @@ tippy.setDefaultProps({
5832
4416
  render
5833
4417
  });
5834
4418
  var tippy_esm_default = tippy;
5835
-
5836
- // src/slash/SlashMenu.tsx
5837
- var import_react = require("react");
5838
- var import_jsx_runtime = require("react/jsx-runtime");
5839
4419
  function SlashMenu({ items, command }) {
5840
- const [query, setQuery] = (0, import_react.useState)("");
5841
- const [activeIndex, setActiveIndex] = (0, import_react.useState)(0);
5842
- const containerRef = (0, import_react.useRef)(null);
5843
- const filtered = (0, import_react.useMemo)(() => {
4420
+ const [query, setQuery] = useState("");
4421
+ const [activeIndex, setActiveIndex] = useState(0);
4422
+ const containerRef = useRef(null);
4423
+ const filtered = useMemo(() => {
5844
4424
  return items.filter(
5845
4425
  (item) => {
5846
4426
  var _a;
@@ -5848,7 +4428,7 @@ function SlashMenu({ items, command }) {
5848
4428
  }
5849
4429
  );
5850
4430
  }, [items, query]);
5851
- const grouped = (0, import_react.useMemo)(() => {
4431
+ const grouped = useMemo(() => {
5852
4432
  return filtered.reduce((acc, item) => {
5853
4433
  var _a, _b;
5854
4434
  (_b = acc[_a = item.category]) != null ? _b : acc[_a] = [];
@@ -5857,14 +4437,14 @@ function SlashMenu({ items, command }) {
5857
4437
  }, {});
5858
4438
  }, [filtered]);
5859
4439
  const flatItems = Object.values(grouped).flat();
5860
- (0, import_react.useEffect)(() => {
4440
+ useEffect(() => {
5861
4441
  var _a;
5862
4442
  const el = (_a = containerRef.current) == null ? void 0 : _a.querySelector(
5863
4443
  `[data-index="${activeIndex}"]`
5864
4444
  );
5865
4445
  el == null ? void 0 : el.scrollIntoView({ block: "nearest" });
5866
4446
  }, [activeIndex]);
5867
- (0, import_react.useEffect)(() => {
4447
+ useEffect(() => {
5868
4448
  const handler = (e) => {
5869
4449
  if (e.key === "ArrowDown") {
5870
4450
  e.preventDefault();
@@ -5884,27 +4464,27 @@ function SlashMenu({ items, command }) {
5884
4464
  return () => window.removeEventListener("keydown", handler);
5885
4465
  }, [flatItems, activeIndex, command]);
5886
4466
  let globalIndex = -1;
5887
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-80 rounded-xl border bg-white shadow-2xl dark:bg-black", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4467
+ return /* @__PURE__ */ jsx("div", { className: "w-80 rounded-xl border bg-white shadow-2xl dark:bg-black", children: /* @__PURE__ */ jsx(
5888
4468
  "div",
5889
4469
  {
5890
4470
  ref: containerRef,
5891
4471
  className: "max-h-[360px] overflow-y-auto p-2",
5892
- children: Object.entries(grouped).map(([category, commands]) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
5893
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-2 py-1 text-xs font-semibold text-gray-500 dark:text-gray-800", children: category }),
4472
+ children: Object.entries(grouped).map(([category, commands]) => /* @__PURE__ */ jsxs("div", { children: [
4473
+ /* @__PURE__ */ jsx("div", { className: "px-2 py-1 text-xs font-semibold text-gray-500 dark:text-gray-800", children: category }),
5894
4474
  commands.map((item) => {
5895
4475
  globalIndex += 1;
5896
4476
  const isActive = globalIndex === activeIndex;
5897
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
4477
+ return /* @__PURE__ */ jsxs(
5898
4478
  "button",
5899
4479
  {
5900
4480
  "data-index": globalIndex,
5901
4481
  onClick: () => command(item),
5902
4482
  className: `flex w-full items-center gap-3 rounded-md px-3 py-2 text-left ${isActive ? "bg-gray-100" : "hover:bg-gray-100"}`,
5903
4483
  children: [
5904
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-gray-500", children: item.icon }),
5905
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
5906
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-sm font-medium", children: item.title }),
5907
- item.description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-xs text-gray-500", children: item.description })
4484
+ /* @__PURE__ */ jsx("div", { className: "text-gray-500", children: item.icon }),
4485
+ /* @__PURE__ */ jsxs("div", { children: [
4486
+ /* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: item.title }),
4487
+ item.description && /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: item.description })
5908
4488
  ] })
5909
4489
  ]
5910
4490
  },
@@ -5915,10 +4495,6 @@ function SlashMenu({ items, command }) {
5915
4495
  }
5916
4496
  ) });
5917
4497
  }
5918
-
5919
- // src/commands/slash-commands.tsx
5920
- var import_lucide_react = require("lucide-react");
5921
- var import_jsx_runtime2 = require("react/jsx-runtime");
5922
4498
  var slashCommands = [
5923
4499
  /* ================= AI ================= */
5924
4500
  // {
@@ -5961,7 +4537,7 @@ var slashCommands = [
5961
4537
  title: "Text",
5962
4538
  description: "Normal paragraph",
5963
4539
  category: "Style",
5964
- icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Type, { size: 16 }),
4540
+ icon: /* @__PURE__ */ jsx(Type, { size: 16 }),
5965
4541
  keywords: ["paragraph", "text"],
5966
4542
  command: ({ editor, range }) => editor.chain().focus().deleteRange(range).setParagraph().run()
5967
4543
  },
@@ -5970,7 +4546,7 @@ var slashCommands = [
5970
4546
  title: "Heading 1",
5971
4547
  description: "Big section heading",
5972
4548
  category: "Style",
5973
- icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Heading1, { size: 16 }),
4549
+ icon: /* @__PURE__ */ jsx(Heading1, { size: 16 }),
5974
4550
  keywords: ["h1", "title"],
5975
4551
  command: ({ editor, range }) => editor.chain().focus().deleteRange(range).setHeading({ level: 1 }).run()
5976
4552
  },
@@ -5979,7 +4555,7 @@ var slashCommands = [
5979
4555
  title: "Heading 2",
5980
4556
  description: "Medium section heading",
5981
4557
  category: "Style",
5982
- icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Heading2, { size: 16 }),
4558
+ icon: /* @__PURE__ */ jsx(Heading2, { size: 16 }),
5983
4559
  keywords: ["h2"],
5984
4560
  command: ({ editor, range }) => editor.chain().focus().deleteRange(range).setHeading({ level: 2 }).run()
5985
4561
  },
@@ -5988,7 +4564,7 @@ var slashCommands = [
5988
4564
  title: "Heading 3",
5989
4565
  description: "Small section heading",
5990
4566
  category: "Style",
5991
- icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Heading3, { size: 16 }),
4567
+ icon: /* @__PURE__ */ jsx(Heading3, { size: 16 }),
5992
4568
  keywords: ["h3"],
5993
4569
  command: ({ editor, range }) => editor.chain().focus().deleteRange(range).setHeading({ level: 3 }).run()
5994
4570
  },
@@ -5996,7 +4572,7 @@ var slashCommands = [
5996
4572
  id: "bullet-list",
5997
4573
  title: "Bullet List",
5998
4574
  category: "Style",
5999
- icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.List, { size: 16 }),
4575
+ icon: /* @__PURE__ */ jsx(List, { size: 16 }),
6000
4576
  keywords: ["ul", "bullet"],
6001
4577
  command: ({ editor, range }) => editor.chain().focus().deleteRange(range).toggleBulletList().run()
6002
4578
  },
@@ -6004,7 +4580,7 @@ var slashCommands = [
6004
4580
  id: "ordered-list",
6005
4581
  title: "Numbered List",
6006
4582
  category: "Style",
6007
- icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.ListOrdered, { size: 16 }),
4583
+ icon: /* @__PURE__ */ jsx(ListOrdered, { size: 16 }),
6008
4584
  keywords: ["ol", "number"],
6009
4585
  command: ({ editor, range }) => editor.chain().focus().deleteRange(range).toggleOrderedList().run()
6010
4586
  },
@@ -6020,7 +4596,7 @@ var slashCommands = [
6020
4596
  id: "blockquote",
6021
4597
  title: "Quote",
6022
4598
  category: "Style",
6023
- icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Quote, { size: 16 }),
4599
+ icon: /* @__PURE__ */ jsx(Quote, { size: 16 }),
6024
4600
  keywords: ["quote"],
6025
4601
  command: ({ editor, range }) => editor.chain().focus().deleteRange(range).toggleBlockquote().run()
6026
4602
  },
@@ -6028,7 +4604,7 @@ var slashCommands = [
6028
4604
  id: "code-block",
6029
4605
  title: "Code Block",
6030
4606
  category: "Style",
6031
- icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Code, { size: 16 }),
4607
+ icon: /* @__PURE__ */ jsx(Code, { size: 16 }),
6032
4608
  keywords: ["code", "pre"],
6033
4609
  command: ({ editor, range }) => editor.chain().focus().deleteRange(range).toggleCodeBlock().run()
6034
4610
  },
@@ -6037,7 +4613,7 @@ var slashCommands = [
6037
4613
  id: "divider",
6038
4614
  title: "Divider",
6039
4615
  category: "Insert",
6040
- icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Minus, { size: 16 }),
4616
+ icon: /* @__PURE__ */ jsx(Minus, { size: 16 }),
6041
4617
  keywords: ["hr", "separator"],
6042
4618
  command: ({ editor, range }) => editor.chain().focus().deleteRange(range).setHorizontalRule().run()
6043
4619
  },
@@ -6045,7 +4621,7 @@ var slashCommands = [
6045
4621
  id: "table",
6046
4622
  title: "Table",
6047
4623
  category: "Insert",
6048
- icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Table, { size: 16 }),
4624
+ icon: /* @__PURE__ */ jsx(Table, { size: 16 }),
6049
4625
  keywords: ["table", "grid"],
6050
4626
  command: ({ editor, range }) => editor.chain().focus().deleteRange(range).insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()
6051
4627
  },
@@ -6071,7 +4647,7 @@ var slashCommands = [
6071
4647
  id: "link",
6072
4648
  title: "Link",
6073
4649
  category: "Media",
6074
- icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Link, { size: 16 }),
4650
+ icon: /* @__PURE__ */ jsx(Link, { size: 16 }),
6075
4651
  keywords: ["url"],
6076
4652
  command: ({ editor, range }) => editor.chain().focus().deleteRange(range).setLink({ href: "https://example.com" }).run()
6077
4653
  }
@@ -6099,12 +4675,12 @@ function getSafeClientRect(clientRect) {
6099
4675
  };
6100
4676
  }
6101
4677
  var SlashPluginKey = new PluginKey("slash-command");
6102
- var SlashExtension = import_core2.Extension.create({
4678
+ var SlashExtension = Extension.create({
6103
4679
  name: "slash-command",
6104
4680
  addProseMirrorPlugins() {
6105
4681
  const editor = this.editor;
6106
4682
  return [
6107
- (0, import_suggestion.default)({
4683
+ Suggestion({
6108
4684
  pluginKey: SlashPluginKey,
6109
4685
  editor,
6110
4686
  char: "/",
@@ -6138,7 +4714,7 @@ var SlashExtension = import_core2.Extension.create({
6138
4714
  items = props.items;
6139
4715
  selectCommand = props.command;
6140
4716
  if (!editor) return;
6141
- component = new import_react2.ReactRenderer(SlashMenu, {
4717
+ component = new ReactRenderer(SlashMenu, {
6142
4718
  props: {
6143
4719
  ...props,
6144
4720
  selectedIndex
@@ -6197,422 +4773,9 @@ var SlashExtension = import_core2.Extension.create({
6197
4773
  ];
6198
4774
  }
6199
4775
  });
6200
-
6201
- // src/SelectionToolbar.tsx
6202
- var import_react3 = require("react");
6203
- var import_lucide_react2 = require("lucide-react");
6204
- var import_jsx_runtime3 = require("react/jsx-runtime");
6205
- function SelectionToolbar({ editor }) {
6206
- const [showColors, setShowColors] = (0, import_react3.useState)(false);
6207
- const [showHighlights, setShowHighlights] = (0, import_react3.useState)(false);
6208
- const [showTurnInto, setShowTurnInto] = (0, import_react3.useState)(false);
6209
- const [showMore, setShowMore] = (0, import_react3.useState)(false);
6210
- (0, import_react3.useEffect)(() => {
6211
- if (!editor) return;
6212
- const closeMenu = () => {
6213
- setShowTurnInto(false);
6214
- setShowColors(false);
6215
- setShowHighlights(false);
6216
- setShowMore(false);
6217
- };
6218
- editor.on("selectionUpdate", closeMenu);
6219
- editor.on("blur", closeMenu);
6220
- return () => {
6221
- editor.off("selectionUpdate", closeMenu);
6222
- editor.off("blur", closeMenu);
6223
- };
6224
- }, [editor]);
6225
- const colors = [
6226
- { name: "Default", value: "#000000" },
6227
- { name: "Gray", value: "#6B7280" },
6228
- { name: "Red", value: "#EF4444" },
6229
- { name: "Orange", value: "#F97316" },
6230
- { name: "Yellow", value: "#EAB308" },
6231
- { name: "Green", value: "#10B981" },
6232
- { name: "Blue", value: "#3B82F6" },
6233
- { name: "Purple", value: "#8B5CF6" }
6234
- ];
6235
- const highlights = [
6236
- { name: "None", value: "transparent" },
6237
- { name: "Gray", value: "#F3F4F6" },
6238
- { name: "Red", value: "#FEE2E2" },
6239
- { name: "Orange", value: "#FFEDD5" },
6240
- { name: "Yellow", value: "#FEF3C7" },
6241
- { name: "Green", value: "#D1FAE5" },
6242
- { name: "Blue", value: "#DBEAFE" },
6243
- { name: "Purple", value: "#EDE9FE" }
6244
- ];
6245
- const setLink = () => {
6246
- const previousUrl = editor.getAttributes("link").href;
6247
- const url = window.prompt("Enter URL:", previousUrl);
6248
- if (url === null) {
6249
- return;
6250
- }
6251
- if (url === "") {
6252
- editor.chain().focus().extendMarkRange("link").unsetLink().run();
6253
- return;
6254
- }
6255
- editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
6256
- };
6257
- const currentBlockLabel = () => {
6258
- if (editor.isActive("heading", { level: 1 })) return "Heading 1";
6259
- if (editor.isActive("heading", { level: 2 })) return "Heading 2";
6260
- if (editor.isActive("heading", { level: 3 })) return "Heading 3";
6261
- if (editor.isActive("bulletList")) return "Bulleted list";
6262
- if (editor.isActive("orderedList")) return "Numbered list";
6263
- if (editor.isActive("taskList")) return "To-do list";
6264
- if (editor.isActive("blockquote")) return "Blockquote";
6265
- if (editor.isActive("codeBlock")) return "Code block";
6266
- return "Text";
6267
- };
6268
- const turnIntoItems = [
6269
- {
6270
- label: "Text",
6271
- icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Type, { size: 16 }),
6272
- isActive: () => editor.isActive("paragraph") && !editor.isActive("bulletList") && !editor.isActive("orderedList") && !editor.isActive("taskList"),
6273
- action: () => {
6274
- editor.chain().focus().clearNodes().setParagraph().run();
6275
- }
6276
- },
6277
- {
6278
- label: "Heading 1",
6279
- icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Heading1, { size: 16 }),
6280
- isActive: () => editor.isActive("heading", { level: 1 }),
6281
- action: () => editor.chain().focus().toggleHeading({ level: 1 }).run()
6282
- },
6283
- {
6284
- label: "Heading 2",
6285
- icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Heading2, { size: 16 }),
6286
- isActive: () => editor.isActive("heading", { level: 2 }),
6287
- action: () => editor.chain().focus().toggleHeading({ level: 2 }).run()
6288
- },
6289
- {
6290
- label: "Heading 3",
6291
- icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Heading3, { size: 16 }),
6292
- isActive: () => editor.isActive("heading", { level: 3 }),
6293
- action: () => editor.chain().focus().toggleHeading({ level: 3 }).run()
6294
- },
6295
- {
6296
- label: "To-do list",
6297
- icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.CheckSquare, { size: 16 }),
6298
- isActive: () => editor.isActive("taskList"),
6299
- action: () => {
6300
- if (editor.isActive("taskList")) {
6301
- editor.chain().focus().liftListItem("taskItem").run();
6302
- } else {
6303
- editor.chain().focus().toggleTaskList().run();
6304
- }
6305
- }
6306
- },
6307
- {
6308
- label: "Blockquote",
6309
- icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Quote, { size: 16 }),
6310
- isActive: () => editor.isActive("blockquote"),
6311
- action: () => editor.chain().focus().toggleBlockquote().run()
6312
- },
6313
- {
6314
- label: "Code block",
6315
- icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Code2, { size: 16 }),
6316
- isActive: () => editor.isActive("codeBlock"),
6317
- action: () => editor.chain().focus().toggleCodeBlock().run()
6318
- }
6319
- ];
6320
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-1 rounded-lg border border-gray-200 bg-white p-1 shadow-xl", children: [
6321
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6322
- "button",
6323
- {
6324
- onClick: () => {
6325
- if (editor.isActive("bulletList")) {
6326
- editor.chain().focus().liftListItem("listItem").run();
6327
- } else {
6328
- editor.chain().focus().toggleBulletList().run();
6329
- }
6330
- },
6331
- className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("bulletList") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
6332
- title: "Bullet List",
6333
- type: "button",
6334
- onMouseDown: (e) => e.preventDefault(),
6335
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.List, { size: 16 })
6336
- }
6337
- ),
6338
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6339
- "button",
6340
- {
6341
- onClick: () => {
6342
- if (editor.isActive("orderedList")) {
6343
- editor.chain().focus().liftListItem("listItem").run();
6344
- } else {
6345
- editor.chain().focus().toggleOrderedList().run();
6346
- }
6347
- },
6348
- className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("orderedList") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
6349
- title: "Numbered List",
6350
- type: "button",
6351
- onMouseDown: (e) => e.preventDefault(),
6352
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.ListOrdered, { size: 16 })
6353
- }
6354
- ),
6355
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-1 h-6 w-px bg-gray-300" }),
6356
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative", children: [
6357
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
6358
- "button",
6359
- {
6360
- onMouseDown: (e) => e.preventDefault(),
6361
- onClick: () => setShowTurnInto((v) => !v),
6362
- className: "rounded-md px-2 py-1 text-sm text-gray-700 hover:bg-gray-100",
6363
- children: [
6364
- currentBlockLabel(),
6365
- " \u25BE"
6366
- ]
6367
- }
6368
- ),
6369
- showTurnInto && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "absolute left-0 top-full z-50 mt-2 w-52 rounded-lg border bg-white shadow-xl", children: [
6370
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "px-3 py-2 text-xs font-semibold text-gray-500", children: "Turn into" }),
6371
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "p-1", children: turnIntoItems.map((item) => {
6372
- const active = item.isActive();
6373
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
6374
- "button",
6375
- {
6376
- onMouseDown: (e) => e.preventDefault(),
6377
- onClick: () => {
6378
- item.action();
6379
- setShowTurnInto(false);
6380
- },
6381
- className: `flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors ${active ? "bg-gray-100 text-blue-600" : "text-gray-700 hover:bg-gray-100"}`,
6382
- children: [
6383
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "flex h-5 w-5 items-center justify-center", children: item.icon }),
6384
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: item.label })
6385
- ]
6386
- },
6387
- item.label
6388
- );
6389
- }) })
6390
- ] })
6391
- ] }),
6392
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-1 h-6 w-px bg-gray-300" }),
6393
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6394
- "button",
6395
- {
6396
- onClick: () => editor.chain().focus().toggleBold().run(),
6397
- className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("bold") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
6398
- title: "Bold (Ctrl+B)",
6399
- type: "button",
6400
- onMouseDown: (e) => e.preventDefault(),
6401
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Bold, { size: 16 })
6402
- }
6403
- ),
6404
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6405
- "button",
6406
- {
6407
- onClick: () => editor.chain().focus().toggleItalic().run(),
6408
- className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("italic") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
6409
- title: "Italic (Ctrl+I)",
6410
- type: "button",
6411
- onMouseDown: (e) => e.preventDefault(),
6412
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Italic, { size: 16 })
6413
- }
6414
- ),
6415
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6416
- "button",
6417
- {
6418
- onClick: () => editor.chain().focus().toggleUnderline().run(),
6419
- className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("underline") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
6420
- title: "Underline (Ctrl+U)",
6421
- type: "button",
6422
- onMouseDown: (e) => e.preventDefault(),
6423
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Underline, { size: 16 })
6424
- }
6425
- ),
6426
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6427
- "button",
6428
- {
6429
- onClick: () => editor.chain().focus().toggleStrike().run(),
6430
- className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("strike") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
6431
- title: "Strikethrough",
6432
- type: "button",
6433
- onMouseDown: (e) => e.preventDefault(),
6434
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Strikethrough, { size: 16 })
6435
- }
6436
- ),
6437
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6438
- "button",
6439
- {
6440
- onClick: () => editor.chain().focus().toggleCode().run(),
6441
- className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("code") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
6442
- title: "Code",
6443
- type: "button",
6444
- onMouseDown: (e) => e.preventDefault(),
6445
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Code, { size: 16 })
6446
- }
6447
- ),
6448
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-1 h-6 w-px bg-gray-300" }),
6449
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6450
- "button",
6451
- {
6452
- onClick: setLink,
6453
- className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("link") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
6454
- title: "Add Link",
6455
- type: "button",
6456
- onMouseDown: (e) => e.preventDefault(),
6457
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Link2, { size: 16 })
6458
- }
6459
- ),
6460
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative", children: [
6461
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6462
- "button",
6463
- {
6464
- onClick: () => {
6465
- setShowColors(!showColors);
6466
- setShowHighlights(false);
6467
- },
6468
- className: "rounded p-1.5 text-gray-700 transition-colors hover:bg-gray-100",
6469
- title: "Text Color",
6470
- type: "button",
6471
- onMouseDown: (e) => e.preventDefault(),
6472
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Type, { size: 16 })
6473
- }
6474
- ),
6475
- showColors && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "absolute left-0 top-full z-50 mt-2 flex gap-1 rounded-lg border bg-white p-2 shadow-xl", children: colors.map((color) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6476
- "button",
6477
- {
6478
- onClick: () => {
6479
- editor.chain().focus().setMark("textStyle", { color: color.value }).run();
6480
- setShowColors(false);
6481
- },
6482
- className: "h-6 w-6 rounded border border-gray-300 transition-transform hover:scale-110",
6483
- style: { backgroundColor: color.value },
6484
- title: color.name,
6485
- type: "button",
6486
- onMouseDown: (e) => e.preventDefault()
6487
- },
6488
- color.value
6489
- )) })
6490
- ] }),
6491
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative", children: [
6492
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6493
- "button",
6494
- {
6495
- onClick: () => {
6496
- setShowHighlights(!showHighlights);
6497
- setShowColors(false);
6498
- },
6499
- className: `rounded p-1.5 transition-colors hover:bg-gray-100 ${editor.isActive("highlight") ? "bg-gray-100 text-blue-600" : "text-gray-700"}`,
6500
- title: "Highlight",
6501
- type: "button",
6502
- onMouseDown: (e) => e.preventDefault(),
6503
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Highlighter, { size: 16 })
6504
- }
6505
- ),
6506
- showHighlights && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "absolute left-0 top-full z-50 mt-2 flex gap-1 rounded-lg border bg-white p-2 shadow-xl", children: highlights.map((highlight) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6507
- "button",
6508
- {
6509
- onClick: () => {
6510
- if (highlight.value === "transparent") {
6511
- editor.chain().focus().unsetMark("highlight").run();
6512
- } else {
6513
- editor.chain().focus().setMark("highlight", { color: highlight.value }).run();
6514
- }
6515
- setShowHighlights(false);
6516
- },
6517
- className: "h-6 w-6 rounded border border-gray-300 transition-transform hover:scale-110",
6518
- style: { backgroundColor: highlight.value },
6519
- title: highlight.name,
6520
- type: "button",
6521
- onMouseDown: (e) => e.preventDefault()
6522
- },
6523
- highlight.value
6524
- )) })
6525
- ] }),
6526
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-1 h-6 w-px bg-gray-300" }),
6527
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative", children: [
6528
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6529
- "button",
6530
- {
6531
- onMouseDown: (e) => e.preventDefault(),
6532
- onClick: () => setShowMore((v) => !v),
6533
- className: "rounded p-1.5 hover:bg-gray-100",
6534
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.MoreVertical, { size: 16 })
6535
- }
6536
- ),
6537
- showMore && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "absolute right-0 top-full z-50 mt-2 w-56 rounded-lg border bg-white shadow-xl", children: [
6538
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "px-3 py-2 text-xs font-semibold text-gray-500", children: "More" }),
6539
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "p-1", children: [
6540
- {
6541
- label: "Align left",
6542
- icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.AlignLeft, { size: 16 }),
6543
- isActive: () => editor.isActive({ textAlign: "left" }),
6544
- action: () => editor.chain().focus().setTextAlign("left").run()
6545
- },
6546
- {
6547
- label: "Align center",
6548
- icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.AlignCenter, { size: 16 }),
6549
- isActive: () => editor.isActive({ textAlign: "center" }),
6550
- action: () => editor.chain().focus().setTextAlign("center").run()
6551
- },
6552
- {
6553
- label: "Align right",
6554
- icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.AlignRight, { size: 16 }),
6555
- isActive: () => editor.isActive({ textAlign: "right" }),
6556
- action: () => editor.chain().focus().setTextAlign("right").run()
6557
- },
6558
- {
6559
- label: "Justify",
6560
- icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.AlignJustify, { size: 16 }),
6561
- isActive: () => editor.isActive({ textAlign: "justify" }),
6562
- action: () => editor.chain().focus().setTextAlign("justify").run()
6563
- },
6564
- { divider: true },
6565
- {
6566
- label: "Superscript",
6567
- icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-sm font-semibold", children: "x\xB2" }),
6568
- isActive: () => editor.isActive("superscript"),
6569
- action: () => editor.chain().focus().toggleSuperscript().run()
6570
- },
6571
- {
6572
- label: "Subscript",
6573
- icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-sm font-semibold", children: "x\u2082" }),
6574
- isActive: () => editor.isActive("subscript"),
6575
- action: () => editor.chain().focus().toggleSubscript().run()
6576
- }
6577
- ].map((item, index) => {
6578
- if ("divider" in item) {
6579
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
6580
- "div",
6581
- {
6582
- className: "my-1 h-px bg-gray-200"
6583
- },
6584
- `divider-${index}`
6585
- );
6586
- }
6587
- const active = item.isActive();
6588
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
6589
- "button",
6590
- {
6591
- onMouseDown: (e) => e.preventDefault(),
6592
- onClick: () => {
6593
- item.action();
6594
- setShowMore(false);
6595
- },
6596
- className: `flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors ${active ? "bg-gray-100 text-blue-600" : "text-gray-700 hover:bg-gray-100"}`,
6597
- children: [
6598
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "flex h-5 w-5 items-center justify-center", children: item.icon }),
6599
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: item.label })
6600
- ]
6601
- },
6602
- item.label
6603
- );
6604
- }) })
6605
- ] })
6606
- ] })
6607
- ] });
6608
- }
6609
- var SelectionToolbar_default = SelectionToolbar;
6610
-
6611
- // src/table/useRowHover.ts
6612
- var import_react4 = require("react");
6613
4776
  function useRowHover(editor) {
6614
- const [rowEl, setRowEl] = (0, import_react4.useState)(null);
6615
- (0, import_react4.useEffect)(() => {
4777
+ const [rowEl, setRowEl] = useState(null);
4778
+ useEffect(() => {
6616
4779
  if (!editor) return;
6617
4780
  const root = editor.view.dom;
6618
4781
  const onMouseMove = (e) => {
@@ -6632,44 +4795,37 @@ function useRowHover(editor) {
6632
4795
  return rowEl;
6633
4796
  }
6634
4797
 
6635
- // src/table/RowAddButton.tsx
6636
- var import_lucide_react3 = require("lucide-react");
6637
-
6638
4798
  // src/table/selectTableCell.ts
6639
4799
  function selectCellByDom(editor, cell) {
6640
4800
  const view = editor.view;
6641
4801
  const pos = view.posAtDOM(cell, 0);
6642
4802
  editor.commands.setTextSelection(pos);
6643
4803
  }
6644
-
6645
- // src/table/RowAddButton.tsx
6646
- var import_react5 = __toESM(require("react"), 1);
6647
- var import_jsx_runtime4 = require("react/jsx-runtime");
6648
4804
  function RowTableMenu(editor, onClose) {
6649
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "w-56 rounded-lg border bg-white p-1 shadow-xl", children: [
6650
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4805
+ return /* @__PURE__ */ jsxs("div", { className: "w-56 rounded-lg border bg-white p-1 shadow-xl", children: [
4806
+ /* @__PURE__ */ jsx(
6651
4807
  MenuItem,
6652
4808
  {
6653
4809
  label: "Add row above",
6654
4810
  onClick: () => editor.commands.addRowBefore()
6655
4811
  }
6656
4812
  ),
6657
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4813
+ /* @__PURE__ */ jsx(
6658
4814
  MenuItem,
6659
4815
  {
6660
4816
  label: "Add row below",
6661
4817
  onClick: () => editor.commands.addRowAfter()
6662
4818
  }
6663
4819
  ),
6664
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4820
+ /* @__PURE__ */ jsx(
6665
4821
  MenuItem,
6666
4822
  {
6667
4823
  label: "Delete row",
6668
4824
  onClick: () => editor.commands.deleteRow()
6669
4825
  }
6670
4826
  ),
6671
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "my-1 border-t" }),
6672
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4827
+ /* @__PURE__ */ jsx("div", { className: "my-1 border-t" }),
4828
+ /* @__PURE__ */ jsx(
6673
4829
  MenuItem,
6674
4830
  {
6675
4831
  label: "Delete table",
@@ -6687,7 +4843,7 @@ function MenuItem({
6687
4843
  onClick,
6688
4844
  danger
6689
4845
  }) {
6690
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4846
+ return /* @__PURE__ */ jsx(
6691
4847
  "button",
6692
4848
  {
6693
4849
  onClick,
@@ -6697,12 +4853,12 @@ function MenuItem({
6697
4853
  );
6698
4854
  }
6699
4855
  function RowAddButton({ editor, row }) {
6700
- const [showRowMenu, setShowRowMenu] = import_react5.default.useState(false);
4856
+ const [showRowMenu, setShowRowMenu] = React.useState(false);
6701
4857
  const firstCell = row.querySelector("td, th");
6702
4858
  if (!firstCell) return null;
6703
4859
  const rect = row.getBoundingClientRect();
6704
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "relative", children: [
6705
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4860
+ return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
4861
+ /* @__PURE__ */ jsx(
6706
4862
  "button",
6707
4863
  {
6708
4864
  style: {
@@ -6719,10 +4875,10 @@ function RowAddButton({ editor, row }) {
6719
4875
  setShowRowMenu((v) => !v);
6720
4876
  selectCellByDom(editor, firstCell);
6721
4877
  },
6722
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react3.MoreHorizontal, { size: 14 })
4878
+ children: /* @__PURE__ */ jsx(MoreHorizontal, { size: 14 })
6723
4879
  }
6724
4880
  ),
6725
- showRowMenu && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4881
+ showRowMenu && /* @__PURE__ */ jsx(
6726
4882
  "div",
6727
4883
  {
6728
4884
  className: "z-[1000]",
@@ -6740,12 +4896,9 @@ function RowAddButton({ editor, row }) {
6740
4896
  )
6741
4897
  ] });
6742
4898
  }
6743
-
6744
- // src/table/useColumnHover.ts
6745
- var import_react6 = require("react");
6746
4899
  function useColumnHover(editor) {
6747
- const [hovered, setHovered] = (0, import_react6.useState)(null);
6748
- (0, import_react6.useEffect)(() => {
4900
+ const [hovered, setHovered] = useState(null);
4901
+ useEffect(() => {
6749
4902
  if (!editor) return;
6750
4903
  const root = editor.view.dom;
6751
4904
  const onMouseMove = (e) => {
@@ -6773,36 +4926,31 @@ function useColumnHover(editor) {
6773
4926
  }, [editor]);
6774
4927
  return hovered;
6775
4928
  }
6776
-
6777
- // src/table/ColumnAddButton.tsx
6778
- var import_lucide_react4 = require("lucide-react");
6779
- var import_react7 = __toESM(require("react"), 1);
6780
- var import_jsx_runtime5 = require("react/jsx-runtime");
6781
4929
  function ColumnTableMenu(editor, onClose) {
6782
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "w-56 rounded-lg border bg-white p-1 shadow-xl", children: [
6783
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4930
+ return /* @__PURE__ */ jsxs("div", { className: "w-56 rounded-lg border bg-white p-1 shadow-xl", children: [
4931
+ /* @__PURE__ */ jsx(
6784
4932
  MenuItem2,
6785
4933
  {
6786
4934
  label: "Add column left",
6787
4935
  onClick: () => editor.commands.addColumnBefore()
6788
4936
  }
6789
4937
  ),
6790
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4938
+ /* @__PURE__ */ jsx(
6791
4939
  MenuItem2,
6792
4940
  {
6793
4941
  label: "Add column right",
6794
4942
  onClick: () => editor.commands.addColumnAfter()
6795
4943
  }
6796
4944
  ),
6797
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4945
+ /* @__PURE__ */ jsx(
6798
4946
  MenuItem2,
6799
4947
  {
6800
4948
  label: "Delete column",
6801
4949
  onClick: () => editor.commands.deleteColumn()
6802
4950
  }
6803
4951
  ),
6804
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "my-1 border-t" }),
6805
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4952
+ /* @__PURE__ */ jsx("div", { className: "my-1 border-t" }),
4953
+ /* @__PURE__ */ jsx(
6806
4954
  MenuItem2,
6807
4955
  {
6808
4956
  label: "Delete table",
@@ -6820,7 +4968,7 @@ function MenuItem2({
6820
4968
  onClick,
6821
4969
  danger
6822
4970
  }) {
6823
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4971
+ return /* @__PURE__ */ jsx(
6824
4972
  "button",
6825
4973
  {
6826
4974
  onClick,
@@ -6834,15 +4982,15 @@ function MenuItem2({
6834
4982
  );
6835
4983
  }
6836
4984
  function ColumnAddButton({ editor, table, columnIndex }) {
6837
- const [showColumnMenu, setShowColumnMenu] = import_react7.default.useState(false);
4985
+ const [showColumnMenu, setShowColumnMenu] = React.useState(false);
6838
4986
  const firstRow = table.querySelector("tr");
6839
4987
  if (!firstRow) return null;
6840
4988
  const cells = Array.from(firstRow.children);
6841
4989
  const cell = cells[columnIndex];
6842
4990
  if (!cell) return null;
6843
4991
  const rect = cell.getBoundingClientRect();
6844
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "relative", children: [
6845
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4992
+ return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
4993
+ /* @__PURE__ */ jsx(
6846
4994
  "button",
6847
4995
  {
6848
4996
  style: {
@@ -6859,10 +5007,10 @@ function ColumnAddButton({ editor, table, columnIndex }) {
6859
5007
  setShowColumnMenu((v) => !v);
6860
5008
  selectCellByDom(editor, cell);
6861
5009
  },
6862
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.MoreHorizontal, { size: 14 })
5010
+ children: /* @__PURE__ */ jsx(MoreHorizontal, { size: 14 })
6863
5011
  }
6864
5012
  ),
6865
- showColumnMenu && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
5013
+ showColumnMenu && /* @__PURE__ */ jsx(
6866
5014
  "div",
6867
5015
  {
6868
5016
  className: "fixed z-[1000]",
@@ -6876,10 +5024,7 @@ function ColumnAddButton({ editor, table, columnIndex }) {
6876
5024
  )
6877
5025
  ] });
6878
5026
  }
6879
-
6880
- // src/NotionEditor.tsx
6881
- var import_jsx_runtime6 = require("react/jsx-runtime");
6882
- var DynamicPlaceholder = import_extension_placeholder.default.configure({
5027
+ var DynamicPlaceholder = Placeholder.configure({
6883
5028
  placeholder: ({ node }) => {
6884
5029
  var _a;
6885
5030
  const type = node.type.name;
@@ -6921,51 +5066,51 @@ var NotionEditor = ({
6921
5066
  showToolbar = true,
6922
5067
  showTableControls = true
6923
5068
  }) => {
6924
- const lastSavedRef = (0, import_react9.useRef)("");
6925
- const isDirtyRef = (0, import_react9.useRef)(false);
6926
- const editor = (0, import_react8.useEditor)({
5069
+ const lastSavedRef = useRef("");
5070
+ const isDirtyRef = useRef(false);
5071
+ const editor = useEditor({
6927
5072
  autofocus: autoFocus,
6928
5073
  editable: !disabled,
6929
5074
  extensions: [
6930
- import_starter_kit.default.configure({
5075
+ StarterKit.configure({
6931
5076
  heading: {
6932
5077
  levels: [1, 2, 3]
6933
5078
  }
6934
5079
  }),
6935
5080
  DynamicPlaceholder,
6936
- import_extension_placeholder.default.configure({
5081
+ Placeholder.configure({
6937
5082
  placeholder,
6938
5083
  showOnlyWhenEditable: true,
6939
5084
  includeChildren: false
6940
5085
  }),
6941
5086
  SlashExtension,
6942
- import_extension_underline.default,
6943
- import_extension_text_style.TextStyle,
6944
- import_extension_color.Color,
6945
- import_extension_superscript.default,
6946
- import_extension_subscript.default,
6947
- import_extension_text_align.default.configure({
5087
+ Underline,
5088
+ TextStyle,
5089
+ Color,
5090
+ Superscript,
5091
+ Subscript,
5092
+ TextAlign.configure({
6948
5093
  types: ["heading", "paragraph"]
6949
5094
  }),
6950
- import_extension_highlight.default.configure({
5095
+ Highlight.configure({
6951
5096
  multicolor: true
6952
5097
  }),
6953
- import_extension_link.default.configure({
5098
+ Link2.configure({
6954
5099
  openOnClick: false,
6955
5100
  HTMLAttributes: {
6956
5101
  class: "text-blue-600 underline cursor-pointer hover:text-blue-800"
6957
5102
  }
6958
5103
  }),
6959
- import_extension_table.Table.configure({
5104
+ Table$1.configure({
6960
5105
  resizable: true,
6961
5106
  lastColumnResizable: true,
6962
5107
  allowTableNodeSelection: true
6963
5108
  }),
6964
- import_extension_table.TableRow,
6965
- import_extension_table.TableHeader,
6966
- import_extension_table.TableCell,
6967
- import_extension_task_list.default,
6968
- import_extension_task_item.default.configure({
5109
+ TableRow,
5110
+ TableHeader,
5111
+ TableCell,
5112
+ TaskList,
5113
+ TaskItem.configure({
6969
5114
  nested: true,
6970
5115
  HTMLAttributes: {
6971
5116
  class: "task-item"
@@ -6998,23 +5143,22 @@ var NotionEditor = ({
6998
5143
  });
6999
5144
  }
7000
5145
  });
7001
- (0, import_react9.useEffect)(() => {
5146
+ useEffect(() => {
7002
5147
  if (!editor) return;
7003
5148
  const currentHTML = editor.getHTML();
7004
5149
  if (content !== void 0 && content !== currentHTML) {
7005
5150
  editor.commands.setContent(content || "");
7006
5151
  }
7007
5152
  }, [content, editor]);
7008
- (0, import_react9.useEffect)(() => {
5153
+ useEffect(() => {
7009
5154
  editor == null ? void 0 : editor.setEditable(!disabled);
7010
5155
  }, [disabled, editor]);
7011
5156
  const hoveredRow = useRowHover(editor);
7012
5157
  const hoveredColumn = useColumnHover(editor);
7013
5158
  if (!editor) return null;
7014
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: (0, import_clsx.default)("relative rounded-lg border bg-white", className), children: [
7015
- showToolbar && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_menus.BubbleMenu, { editor, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SelectionToolbar_default, { editor }) }),
7016
- showTableControls && editor && hoveredRow && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RowAddButton, { editor, row: hoveredRow }),
7017
- showTableControls && editor && hoveredColumn && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
5159
+ return /* @__PURE__ */ jsxs("div", { className: clsx("relative rounded-lg border bg-white", className), children: [
5160
+ showTableControls && editor && hoveredRow && /* @__PURE__ */ jsx(RowAddButton, { editor, row: hoveredRow }),
5161
+ showTableControls && editor && hoveredColumn && /* @__PURE__ */ jsx(
7018
5162
  ColumnAddButton,
7019
5163
  {
7020
5164
  editor,
@@ -7022,11 +5166,11 @@ var NotionEditor = ({
7022
5166
  columnIndex: hoveredColumn.columnIndex
7023
5167
  }
7024
5168
  ),
7025
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
7026
- import_react8.EditorContent,
5169
+ /* @__PURE__ */ jsx(
5170
+ EditorContent,
7027
5171
  {
7028
5172
  editor,
7029
- className: (0, import_clsx.default)(
5173
+ className: clsx(
7030
5174
  "prose max-w-none border border-gray-300 p-6",
7031
5175
  disabled && "cursor-not-allowed opacity-60",
7032
5176
  editorClassName
@@ -7036,8 +5180,7 @@ var NotionEditor = ({
7036
5180
  ] });
7037
5181
  };
7038
5182
  var NotionEditor_default = NotionEditor;
7039
- // Annotate the CommonJS export names for ESM import in node:
7040
- 0 && (module.exports = {
7041
- NotionEditor
7042
- });
7043
- //# sourceMappingURL=index.cjs.map
5183
+
5184
+ export { NotionEditor_default as NotionEditor };
5185
+ //# sourceMappingURL=index.mjs.map
5186
+ //# sourceMappingURL=index.mjs.map