@rcarls/rc-markdown-editor 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # @rcarls/rc-markdown-editor
2
2
 
3
- Headless markdown editor web component extending
4
- [@rcarls/rc-textarea](../rc-textarea/), built with Lit.
3
+ Rich/source Markdown editor with a formatting toolbar, backed by `rc-textarea`.
4
+
5
+ Docs: [https://richardcarls.github.io/rc-webcomponents/components/rc-markdown-editor](https://richardcarls.github.io/rc-webcomponents/components/rc-markdown-editor).
5
6
 
6
7
  Part of the [rc-webcomponents](https://github.com/richardcarls/rc-webcomponents) library.
7
8
 
@@ -10,6 +11,10 @@ Part of the [rc-webcomponents](https://github.com/richardcarls/rc-webcomponents)
10
11
  Full API, usage examples, and keyboard/accessibility notes are on the
11
12
  [rc-webcomponents docs site](https://richardcarls.github.io/rc-webcomponents/).
12
13
 
14
+ ## Attributions
15
+
16
+ The `rc-markdown-editor` toolbar uses icons from [Bootstrap Icons](https://icons.getbootstrap.com/) by the Bootstrap Authors, licensed under the [MIT License](https://github.com/twbs/icons/blob/main/LICENSE).
17
+
13
18
  ## License
14
19
 
15
20
  MIT
@@ -29,6 +29,39 @@
29
29
  "kind": "javascript-module",
30
30
  "path": "src/formatting.ts",
31
31
  "declarations": [
32
+ {
33
+ "kind": "function",
34
+ "name": "setCodeBlockLanguage",
35
+ "return": {
36
+ "type": {
37
+ "text": "string | null"
38
+ }
39
+ },
40
+ "parameters": [
41
+ {
42
+ "name": "value",
43
+ "type": {
44
+ "text": "string"
45
+ },
46
+ "description": "Full source editor value."
47
+ },
48
+ {
49
+ "name": "selectionStart",
50
+ "type": {
51
+ "text": "number"
52
+ },
53
+ "description": "Cursor offset used to locate the containing fence."
54
+ },
55
+ {
56
+ "name": "language",
57
+ "type": {
58
+ "text": "string"
59
+ },
60
+ "description": "Language string to write (empty string removes the token)."
61
+ }
62
+ ],
63
+ "description": "Replaces the language token on the opening fence of the code block containing\n`selectionStart`. Returns the updated string, or `null` if the cursor is not\ninside a fenced code block."
64
+ },
32
65
  {
33
66
  "kind": "function",
34
67
  "name": "getFormatsFromDecorations",
@@ -61,6 +94,14 @@
61
94
  }
62
95
  ],
63
96
  "exports": [
97
+ {
98
+ "kind": "js",
99
+ "name": "setCodeBlockLanguage",
100
+ "declaration": {
101
+ "name": "setCodeBlockLanguage",
102
+ "module": "src/formatting.ts"
103
+ }
104
+ },
64
105
  {
65
106
  "kind": "js",
66
107
  "name": "getFormatsFromDecorations",
@@ -164,7 +205,7 @@
164
205
  "declarations": [
165
206
  {
166
207
  "kind": "class",
167
- "description": "Formatting toolbar for `<rc-markdown-editor>`. Renders into its own light DOM\nso the parent shadow stylesheet can reach `rc-editor-toolbar button` directly.\n\nActive-format properties are set by the parent editor and reflected as\n`aria-pressed` on the corresponding buttons. Heading level is shown via a\n`<select>`. Code-block language is shown via a `<input>` when active.",
208
+ "description": "Formatting toolbar for `<rc-markdown-editor>`. Renders into its own light DOM\nso the parent shadow stylesheet can reach `rc-editor-toolbar button` directly.\n\nActive-format properties are set by the parent editor and reflected as\n`aria-pressed` on the corresponding buttons. Heading level is shown via an\n`<rc-select>`. Code-block language is shown via a `<input>` when active.",
168
209
  "name": "RcEditorToolbar",
169
210
  "members": [
170
211
  {
@@ -227,6 +268,16 @@
227
268
  "attribute": "active-code",
228
269
  "reflects": true
229
270
  },
271
+ {
272
+ "kind": "field",
273
+ "name": "activeLink",
274
+ "type": {
275
+ "text": "boolean"
276
+ },
277
+ "default": "false",
278
+ "attribute": "active-link",
279
+ "reflects": true
280
+ },
230
281
  {
231
282
  "kind": "field",
232
283
  "name": "activeHeading",
@@ -303,14 +354,13 @@
303
354
  "type": {
304
355
  "text": "string"
305
356
  },
306
- "privacy": "private",
307
- "default": "''",
308
- "description": "Tracks the in-progress language input value before commit."
357
+ "privacy": "protected",
358
+ "default": "''"
309
359
  },
310
360
  {
311
361
  "kind": "method",
312
362
  "name": "_dispatch",
313
- "privacy": "private",
363
+ "privacy": "protected",
314
364
  "parameters": [
315
365
  {
316
366
  "name": "action",
@@ -330,27 +380,27 @@
330
380
  {
331
381
  "kind": "field",
332
382
  "name": "_onClick",
333
- "privacy": "private"
383
+ "privacy": "protected"
334
384
  },
335
385
  {
336
386
  "kind": "field",
337
387
  "name": "_onHeadingChange",
338
- "privacy": "private"
388
+ "privacy": "protected"
339
389
  },
340
390
  {
341
391
  "kind": "field",
342
392
  "name": "_onLangInput",
343
- "privacy": "private"
393
+ "privacy": "protected"
344
394
  },
345
395
  {
346
396
  "kind": "field",
347
397
  "name": "_onLangCommit",
348
- "privacy": "private"
398
+ "privacy": "protected"
349
399
  },
350
400
  {
351
401
  "kind": "field",
352
402
  "name": "_onLangKeyDown",
353
- "privacy": "private"
403
+ "privacy": "protected"
354
404
  }
355
405
  ],
356
406
  "events": [
@@ -412,6 +462,14 @@
412
462
  "default": "false",
413
463
  "fieldName": "activeCode"
414
464
  },
465
+ {
466
+ "name": "active-link",
467
+ "type": {
468
+ "text": "boolean"
469
+ },
470
+ "default": "false",
471
+ "fieldName": "activeLink"
472
+ },
415
473
  {
416
474
  "name": "active-heading",
417
475
  "type": {
@@ -496,7 +554,7 @@
496
554
  "declarations": [
497
555
  {
498
556
  "kind": "class",
499
- "description": "Markdown-backed rich-text editor with two first-class modes:\n\n- **Rich mode (default)**: A `contenteditable` div shows micromark-rendered\n HTML. DOM mutations are converted back to markdown via turndown and\n written to the backing `<textarea>` for form participation.\n- **Source mode**: An `<rc-textarea>` instance shows the markdown source\n with live decorations. Toggle via `source-mode` attribute or Ctrl+Shift+S.\n\nConsumer markup follows the same progressive-enhancement contract as\n`<rc-textarea>`:\n\n```html\n<rc-markdown-editor>\n <label for=\"body\">Content</label>\n <textarea id=\"body\" name=\"body\"></textarea>\n</rc-markdown-editor>\n```",
557
+ "description": "Rich/source Markdown editor with a formatting toolbar, backed by rc-textarea.\n\n- **Rich mode (default)**: A `contenteditable` div shows micromark-rendered\n HTML. DOM mutations are converted back to markdown via turndown and\n written to the backing `<textarea>` for form participation.\n- **Source mode**: An `<rc-textarea>` instance shows the markdown source\n with live decorations. Toggle via `source-mode` attribute or Ctrl+Shift+S.\n\nConsumer markup follows the same progressive-enhancement contract as\n`<rc-textarea>`:\n\n```html\n<rc-markdown-editor>\n <label for=\"body\">Content</label>\n <textarea id=\"body\" name=\"body\"></textarea>\n</rc-markdown-editor>\n```",
500
558
  "name": "RcMarkdownEditor",
501
559
  "members": [
502
560
  {
@@ -607,27 +665,27 @@
607
665
  },
608
666
  {
609
667
  "kind": "field",
610
- "name": "_richView",
668
+ "name": "_$richView",
611
669
  "type": {
612
670
  "text": "HTMLDivElement"
613
671
  },
614
- "privacy": "private"
672
+ "privacy": "protected"
615
673
  },
616
674
  {
617
675
  "kind": "field",
618
- "name": "_sourceEditor",
676
+ "name": "_$sourceEditor",
619
677
  "type": {
620
678
  "text": "RCTextarea"
621
679
  },
622
- "privacy": "private"
680
+ "privacy": "protected"
623
681
  },
624
682
  {
625
683
  "kind": "field",
626
- "name": "_toolbarEl",
684
+ "name": "_$toolbar",
627
685
  "type": {
628
686
  "text": "HTMLElement | undefined"
629
687
  },
630
- "privacy": "private"
688
+ "privacy": "protected"
631
689
  },
632
690
  {
633
691
  "kind": "field",
@@ -635,16 +693,16 @@
635
693
  "type": {
636
694
  "text": "MutationObserver | null"
637
695
  },
638
- "privacy": "private",
696
+ "privacy": "protected",
639
697
  "default": "null"
640
698
  },
641
699
  {
642
700
  "kind": "field",
643
- "name": "_savedRichRange",
701
+ "name": "_$savedRange",
644
702
  "type": {
645
703
  "text": "Range | null"
646
704
  },
647
- "privacy": "private",
705
+ "privacy": "protected",
648
706
  "default": "null"
649
707
  },
650
708
  {
@@ -653,7 +711,7 @@
653
711
  "type": {
654
712
  "text": "ActiveFormats"
655
713
  },
656
- "privacy": "private",
714
+ "privacy": "protected",
657
715
  "default": "{}"
658
716
  },
659
717
  {
@@ -662,7 +720,7 @@
662
720
  "type": {
663
721
  "text": "ReturnType<typeof setTimeout> | null"
664
722
  },
665
- "privacy": "private",
723
+ "privacy": "protected",
666
724
  "default": "null"
667
725
  },
668
726
  {
@@ -671,7 +729,7 @@
671
729
  "type": {
672
730
  "text": "RCTextareaPluginAPI | null"
673
731
  },
674
- "privacy": "private",
732
+ "privacy": "protected",
675
733
  "default": "null"
676
734
  },
677
735
  {
@@ -680,7 +738,7 @@
680
738
  "type": {
681
739
  "text": "boolean"
682
740
  },
683
- "privacy": "private",
741
+ "privacy": "protected",
684
742
  "default": "false"
685
743
  },
686
744
  {
@@ -689,22 +747,65 @@
689
747
  "type": {
690
748
  "text": "boolean"
691
749
  },
692
- "privacy": "private",
750
+ "privacy": "protected",
693
751
  "default": "false"
694
752
  },
695
753
  {
696
754
  "kind": "field",
697
- "name": "_skipNextModeSwitch",
755
+ "name": "_cachedTree",
756
+ "type": {
757
+ "text": "ReturnType<typeof fromMarkdown> | null"
758
+ },
759
+ "privacy": "protected",
760
+ "default": "null"
761
+ },
762
+ {
763
+ "kind": "field",
764
+ "name": "_firstUpdatedDone",
698
765
  "type": {
699
766
  "text": "boolean"
700
767
  },
701
- "privacy": "private",
768
+ "privacy": "protected",
702
769
  "default": "false"
703
770
  },
771
+ {
772
+ "kind": "field",
773
+ "name": "_$linkPopover",
774
+ "type": {
775
+ "text": "HTMLDivElement | undefined"
776
+ },
777
+ "privacy": "protected"
778
+ },
779
+ {
780
+ "kind": "field",
781
+ "name": "_$linkPopoverInput",
782
+ "type": {
783
+ "text": "HTMLInputElement | undefined"
784
+ },
785
+ "privacy": "protected"
786
+ },
787
+ {
788
+ "kind": "field",
789
+ "name": "_linkPopoverOpen",
790
+ "type": {
791
+ "text": "boolean"
792
+ },
793
+ "privacy": "protected",
794
+ "default": "false"
795
+ },
796
+ {
797
+ "kind": "field",
798
+ "name": "_linkPopoverHref",
799
+ "type": {
800
+ "text": "string"
801
+ },
802
+ "privacy": "protected",
803
+ "default": "''"
804
+ },
704
805
  {
705
806
  "kind": "method",
706
807
  "name": "_setRichViewContent",
707
- "privacy": "private",
808
+ "privacy": "protected",
708
809
  "parameters": [
709
810
  {
710
811
  "name": "markdown",
@@ -717,7 +818,7 @@
717
818
  {
718
819
  "kind": "method",
719
820
  "name": "_renderMarkdown",
720
- "privacy": "private",
821
+ "privacy": "protected",
721
822
  "return": {
722
823
  "type": {
723
824
  "text": "string"
@@ -735,41 +836,32 @@
735
836
  {
736
837
  "kind": "method",
737
838
  "name": "_scheduleMarkdownSync",
738
- "privacy": "private"
839
+ "privacy": "protected"
739
840
  },
740
841
  {
741
842
  "kind": "method",
742
843
  "name": "_syncMarkdownFromRichView",
743
- "privacy": "private"
844
+ "privacy": "protected"
744
845
  },
745
846
  {
746
847
  "kind": "method",
747
848
  "name": "_switchToSource",
748
- "privacy": "private"
849
+ "privacy": "protected"
749
850
  },
750
851
  {
751
852
  "kind": "method",
752
853
  "name": "_switchToRich",
753
- "privacy": "private"
754
- },
755
- {
756
- "kind": "field",
757
- "name": "_cachedTree",
758
- "type": {
759
- "text": "ReturnType<typeof fromMarkdown> | null"
760
- },
761
- "privacy": "private",
762
- "default": "null"
854
+ "privacy": "protected"
763
855
  },
764
856
  {
765
857
  "kind": "method",
766
858
  "name": "_setupSourcePlugin",
767
- "privacy": "private"
859
+ "privacy": "protected"
768
860
  },
769
861
  {
770
862
  "kind": "method",
771
863
  "name": "_getCodeBlockLanguage",
772
- "privacy": "private",
864
+ "privacy": "protected",
773
865
  "return": {
774
866
  "type": {
775
867
  "text": "string | null"
@@ -793,17 +885,17 @@
793
885
  {
794
886
  "kind": "field",
795
887
  "name": "_onSourceChange",
796
- "privacy": "private"
888
+ "privacy": "protected"
797
889
  },
798
890
  {
799
891
  "kind": "field",
800
892
  "name": "_onToolbarAction",
801
- "privacy": "private"
893
+ "privacy": "protected"
802
894
  },
803
895
  {
804
896
  "kind": "method",
805
897
  "name": "_applyRichFormat",
806
- "privacy": "private",
898
+ "privacy": "protected",
807
899
  "parameters": [
808
900
  {
809
901
  "name": "action",
@@ -816,7 +908,7 @@
816
908
  {
817
909
  "kind": "method",
818
910
  "name": "_applySourceFormat",
819
- "privacy": "private",
911
+ "privacy": "protected",
820
912
  "parameters": [
821
913
  {
822
914
  "name": "action",
@@ -829,7 +921,7 @@
829
921
  {
830
922
  "kind": "method",
831
923
  "name": "_setSourceHeadingLevel",
832
- "privacy": "private",
924
+ "privacy": "protected",
833
925
  "parameters": [
834
926
  {
835
927
  "name": "level",
@@ -843,7 +935,7 @@
843
935
  {
844
936
  "kind": "method",
845
937
  "name": "_setSourceCodeBlockLanguage",
846
- "privacy": "private",
938
+ "privacy": "protected",
847
939
  "parameters": [
848
940
  {
849
941
  "name": "lang",
@@ -857,7 +949,7 @@
857
949
  {
858
950
  "kind": "method",
859
951
  "name": "_setRichCodeBlockLanguage",
860
- "privacy": "private",
952
+ "privacy": "protected",
861
953
  "parameters": [
862
954
  {
863
955
  "name": "lang",
@@ -866,12 +958,12 @@
866
958
  }
867
959
  }
868
960
  ],
869
- "description": "Updates the data-lang attribute on the <pre> at the cursor in rich mode."
961
+ "description": "Updates the `data-lang` attribute on the `<pre>` at the cursor in rich mode."
870
962
  },
871
963
  {
872
964
  "kind": "method",
873
965
  "name": "_toggleLinePrefix",
874
- "privacy": "private",
966
+ "privacy": "protected",
875
967
  "parameters": [
876
968
  {
877
969
  "name": "prefix",
@@ -880,18 +972,18 @@
880
972
  }
881
973
  }
882
974
  ],
883
- "description": "Toggles a line prefix (e.g. `'# '`, `'> '`, `'- '`) on the cursor's line."
975
+ "description": "Toggles a line prefix (e.g. `'> '`, `'- '`) on the cursor's line."
884
976
  },
885
977
  {
886
978
  "kind": "method",
887
979
  "name": "_toggleSourceCodeFence",
888
- "privacy": "private",
980
+ "privacy": "protected",
889
981
  "description": "Wraps the current selection (or cursor line) with a fenced code block."
890
982
  },
891
983
  {
892
984
  "kind": "method",
893
985
  "name": "_wrapRichSelection",
894
- "privacy": "private",
986
+ "privacy": "protected",
895
987
  "parameters": [
896
988
  {
897
989
  "name": "tag",
@@ -904,37 +996,87 @@
904
996
  {
905
997
  "kind": "method",
906
998
  "name": "_toggleRichCodeBlock",
907
- "privacy": "private"
999
+ "privacy": "protected"
908
1000
  },
909
1001
  {
910
1002
  "kind": "field",
911
1003
  "name": "_onKeyDown",
912
- "privacy": "private"
1004
+ "privacy": "protected"
913
1005
  },
914
1006
  {
915
1007
  "kind": "field",
916
1008
  "name": "_onSelectionChange",
917
- "privacy": "private"
1009
+ "privacy": "protected"
918
1010
  },
919
1011
  {
920
1012
  "kind": "method",
921
1013
  "name": "_pushToolbarState",
922
- "privacy": "private"
1014
+ "privacy": "protected"
923
1015
  },
924
1016
  {
925
1017
  "kind": "method",
926
1018
  "name": "_syncNativeTextarea",
927
- "privacy": "private"
1019
+ "privacy": "protected"
928
1020
  },
929
1021
  {
930
1022
  "kind": "method",
931
1023
  "name": "_connectLabel",
932
- "privacy": "private"
1024
+ "privacy": "protected"
1025
+ },
1026
+ {
1027
+ "kind": "field",
1028
+ "name": "_onRichViewClick",
1029
+ "privacy": "protected"
1030
+ },
1031
+ {
1032
+ "kind": "field",
1033
+ "name": "_onDocumentClick",
1034
+ "privacy": "protected"
1035
+ },
1036
+ {
1037
+ "kind": "method",
1038
+ "name": "_expandRichSelectionToWord",
1039
+ "privacy": "protected",
1040
+ "return": {
1041
+ "type": {
1042
+ "text": "void"
1043
+ }
1044
+ }
1045
+ },
1046
+ {
1047
+ "kind": "method",
1048
+ "name": "_positionLinkPopover",
1049
+ "privacy": "protected",
1050
+ "return": {
1051
+ "type": {
1052
+ "text": "void"
1053
+ }
1054
+ }
1055
+ },
1056
+ {
1057
+ "kind": "field",
1058
+ "name": "_applyLink",
1059
+ "privacy": "protected"
1060
+ },
1061
+ {
1062
+ "kind": "field",
1063
+ "name": "_removeLink",
1064
+ "privacy": "protected"
1065
+ },
1066
+ {
1067
+ "kind": "field",
1068
+ "name": "_openLinkHref",
1069
+ "privacy": "protected"
1070
+ },
1071
+ {
1072
+ "kind": "field",
1073
+ "name": "_onLinkPopoverKeyDown",
1074
+ "privacy": "protected"
933
1075
  },
934
1076
  {
935
1077
  "kind": "method",
936
1078
  "name": "_dispatchChange",
937
- "privacy": "private",
1079
+ "privacy": "protected",
938
1080
  "parameters": [
939
1081
  {
940
1082
  "name": "value",
@@ -947,7 +1089,7 @@
947
1089
  {
948
1090
  "kind": "method",
949
1091
  "name": "_dispatchModeChange",
950
- "privacy": "private",
1092
+ "privacy": "protected",
951
1093
  "parameters": [
952
1094
  {
953
1095
  "name": "mode",