@eventuras/scribo 0.8.2 → 0.10.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/dist/App.d.ts +11 -0
  2. package/dist/App.d.ts.map +1 -0
  3. package/dist/MarkdownEditor.d.ts +18 -0
  4. package/dist/MarkdownEditor.d.ts.map +1 -0
  5. package/dist/MarkdownEditor2.js +111 -0
  6. package/dist/MarkdownEditor2.js.map +1 -0
  7. package/dist/MarkdownInput.d.ts +27 -0
  8. package/dist/MarkdownInput.d.ts.map +1 -0
  9. package/dist/MarkdownInput.js +57 -0
  10. package/dist/MarkdownInput.js.map +1 -0
  11. package/dist/callout.js +5 -0
  12. package/dist/context/SharedHistoryContext.d.ts +11 -0
  13. package/dist/context/SharedHistoryContext.d.ts.map +1 -0
  14. package/dist/context/SharedHistoryContext.js +12 -0
  15. package/dist/context/SharedHistoryContext.js.map +1 -0
  16. package/dist/index.d.ts +1 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/main.d.ts +5 -0
  19. package/dist/main.d.ts.map +1 -0
  20. package/dist/main.js +4 -0
  21. package/dist/nodes/EditorNodes.d.ts +4 -0
  22. package/dist/nodes/EditorNodes.d.ts.map +1 -0
  23. package/dist/nodes/EditorNodes.js +39 -0
  24. package/dist/nodes/EditorNodes.js.map +1 -0
  25. package/dist/nodes/callout/CalloutComponent.d.ts +6 -0
  26. package/dist/nodes/callout/CalloutComponent.d.ts.map +1 -0
  27. package/dist/nodes/callout/CalloutComponent.js +53 -0
  28. package/dist/nodes/callout/CalloutComponent.js.map +1 -0
  29. package/dist/nodes/callout/CalloutNode.d.ts +27 -0
  30. package/dist/nodes/callout/CalloutNode.d.ts.map +1 -0
  31. package/dist/nodes/callout/CalloutNode.js +153 -0
  32. package/dist/nodes/callout/CalloutNode.js.map +1 -0
  33. package/dist/nodes/callout/CalloutTransformer.d.ts +3 -0
  34. package/dist/nodes/callout/CalloutTransformer.d.ts.map +1 -0
  35. package/dist/nodes/callout/CalloutTransformer.js +48 -0
  36. package/dist/nodes/callout/CalloutTransformer.js.map +1 -0
  37. package/dist/nodes/callout/calloutPlugin.d.ts +3 -0
  38. package/dist/nodes/callout/calloutPlugin.d.ts.map +1 -0
  39. package/dist/nodes/callout/calloutPlugin.js +34 -0
  40. package/dist/nodes/callout/calloutPlugin.js.map +1 -0
  41. package/dist/nodes/callout/index.d.ts +6 -0
  42. package/dist/nodes/callout/index.d.ts.map +1 -0
  43. package/dist/nodes/schedule/ScheduleItemComponent.d.ts +9 -0
  44. package/dist/nodes/schedule/ScheduleItemComponent.d.ts.map +1 -0
  45. package/dist/nodes/schedule/ScheduleItemComponent.js +167 -0
  46. package/dist/nodes/schedule/ScheduleItemComponent.js.map +1 -0
  47. package/dist/nodes/schedule/ScheduleItemNode.d.ts +31 -0
  48. package/dist/nodes/schedule/ScheduleItemNode.d.ts.map +1 -0
  49. package/dist/nodes/schedule/ScheduleItemNode.js +94 -0
  50. package/dist/nodes/schedule/ScheduleItemNode.js.map +1 -0
  51. package/dist/nodes/schedule/ScheduleTransformer.d.ts +22 -0
  52. package/dist/nodes/schedule/ScheduleTransformer.d.ts.map +1 -0
  53. package/dist/nodes/schedule/ScheduleTransformer.js +60 -0
  54. package/dist/nodes/schedule/ScheduleTransformer.js.map +1 -0
  55. package/dist/nodes/schedule/index.d.ts +5 -0
  56. package/dist/nodes/schedule/index.d.ts.map +1 -0
  57. package/dist/nodes/schedule/schedulePlugin.d.ts +3 -0
  58. package/dist/nodes/schedule/schedulePlugin.d.ts.map +1 -0
  59. package/dist/nodes/schedule/schedulePlugin.js +33 -0
  60. package/dist/nodes/schedule/schedulePlugin.js.map +1 -0
  61. package/dist/plugins/AutoLinkPlugin.d.ts +3 -0
  62. package/dist/plugins/AutoLinkPlugin.d.ts.map +1 -0
  63. package/dist/plugins/AutoLinkPlugin.js +22 -0
  64. package/dist/plugins/AutoLinkPlugin.js.map +1 -0
  65. package/dist/plugins/FloatingLinkEditorPlugin.d.ts +7 -0
  66. package/dist/plugins/FloatingLinkEditorPlugin.d.ts.map +1 -0
  67. package/dist/plugins/FloatingLinkEditorPlugin2.js +302 -0
  68. package/dist/plugins/FloatingLinkEditorPlugin2.js.map +1 -0
  69. package/dist/plugins/HistoryPlugin.d.ts +26 -0
  70. package/dist/plugins/HistoryPlugin.d.ts.map +1 -0
  71. package/dist/plugins/LinkPlugin.d.ts +3 -0
  72. package/dist/plugins/LinkPlugin.d.ts.map +1 -0
  73. package/dist/plugins/LinkPlugin.js +18 -0
  74. package/dist/plugins/LinkPlugin.js.map +1 -0
  75. package/dist/plugins/ToolbarPlugin.d.ts +7 -0
  76. package/dist/plugins/ToolbarPlugin.d.ts.map +1 -0
  77. package/dist/plugins/ToolbarPlugin.js +372 -0
  78. package/dist/plugins/ToolbarPlugin.js.map +1 -0
  79. package/dist/schedule.js +4 -0
  80. package/dist/scribo.css +1977 -0
  81. package/dist/themes/EditorTheme.d.ts +4 -0
  82. package/dist/themes/EditorTheme.d.ts.map +1 -0
  83. package/dist/themes/EditorTheme2.js +107 -0
  84. package/dist/themes/EditorTheme2.js.map +1 -0
  85. package/dist/types.d.ts +26 -0
  86. package/dist/types.d.ts.map +1 -0
  87. package/dist/ui/ContentEditable.d.ts +6 -0
  88. package/dist/ui/ContentEditable.d.ts.map +1 -0
  89. package/dist/ui/ContentEditable2.js +14 -0
  90. package/dist/ui/ContentEditable2.js.map +1 -0
  91. package/dist/ui/DropDown.d.ts +18 -0
  92. package/dist/ui/DropDown.d.ts.map +1 -0
  93. package/dist/ui/DropDown.js +162 -0
  94. package/dist/ui/DropDown.js.map +1 -0
  95. package/dist/ui/Placeholder.d.ts +6 -0
  96. package/dist/ui/Placeholder.d.ts.map +1 -0
  97. package/dist/ui/Placeholder2.js +13 -0
  98. package/dist/ui/Placeholder2.js.map +1 -0
  99. package/dist/utils/environment.d.ts +24 -0
  100. package/dist/utils/environment.d.ts.map +1 -0
  101. package/dist/utils/environment.js +20 -0
  102. package/dist/utils/environment.js.map +1 -0
  103. package/dist/utils/getSelectedNode.d.ts +3 -0
  104. package/dist/utils/getSelectedNode.d.ts.map +1 -0
  105. package/dist/utils/getSelectedNode.js +23 -0
  106. package/dist/utils/getSelectedNode.js.map +1 -0
  107. package/dist/utils/setFloatingElemPosition.d.ts +2 -0
  108. package/dist/utils/setFloatingElemPosition.d.ts.map +1 -0
  109. package/dist/utils/setFloatingElemPositionForLinkEditor.d.ts +2 -0
  110. package/dist/utils/setFloatingElemPositionForLinkEditor.d.ts.map +1 -0
  111. package/dist/utils/setFloatingElemPositionForLinkEditor.js +33 -0
  112. package/dist/utils/setFloatingElemPositionForLinkEditor.js.map +1 -0
  113. package/dist/utils/url.d.ts +11 -0
  114. package/dist/utils/url.d.ts.map +1 -0
  115. package/dist/utils/url.js +33 -0
  116. package/dist/utils/url.js.map +1 -0
  117. package/dist/vite.svg +1 -0
  118. package/package.json +57 -39
  119. package/src/MarkdownEditor.css +130 -27
  120. package/src/MarkdownEditor.tsx +82 -31
  121. package/src/MarkdownInput.tsx +9 -10
  122. package/src/context/SharedHistoryContext.tsx +8 -16
  123. package/src/main.tsx +3 -3
  124. package/src/nodes/EditorNodes.ts +10 -10
  125. package/src/nodes/callout/Callout.css +94 -0
  126. package/src/nodes/callout/CalloutComponent.tsx +61 -0
  127. package/src/nodes/callout/CalloutNode.ts +197 -0
  128. package/src/nodes/callout/CalloutTransformer.ts +87 -0
  129. package/src/nodes/callout/calloutPlugin.ts +37 -0
  130. package/src/nodes/callout/index.ts +5 -0
  131. package/src/nodes/schedule/ScheduleItem.css +140 -0
  132. package/src/nodes/schedule/ScheduleItemComponent.tsx +195 -0
  133. package/src/nodes/schedule/ScheduleItemNode.ts +135 -0
  134. package/src/nodes/schedule/ScheduleTransformer.ts +80 -0
  135. package/src/nodes/schedule/index.ts +4 -0
  136. package/src/nodes/schedule/schedulePlugin.ts +33 -0
  137. package/src/plugins/AutoLinkPlugin.tsx +5 -10
  138. package/src/plugins/FloatingLinkEditorPlugin.tsx +42 -66
  139. package/src/plugins/HistoryPlugin.tsx +20 -30
  140. package/src/plugins/LinkPlugin.tsx +2 -3
  141. package/src/plugins/ToolbarPlugin.tsx +129 -141
  142. package/src/themes/EditorTheme.css +82 -62
  143. package/src/themes/EditorTheme.ts +89 -90
  144. package/src/types.ts +27 -0
  145. package/src/ui/ContentEditable.tsx +5 -5
  146. package/src/ui/DropDown.tsx +23 -41
  147. package/src/ui/Placeholder.tsx +21 -21
  148. package/src/utils/environment.ts +6 -12
  149. package/src/utils/getSelectedNode.ts +3 -5
  150. package/src/utils/setFloatingElemPosition.ts +2 -5
  151. package/src/utils/setFloatingElemPositionForLinkEditor.ts +1 -1
  152. package/src/utils/url.ts +4 -10
  153. package/tsconfig.json +8 -0
  154. package/CHANGELOG.md +0 -59
  155. package/README.md +0 -126
  156. package/RELEASE.md +0 -102
  157. package/eslint.config.js +0 -4
  158. package/src/App.css +0 -35
  159. package/src/App.tsx +0 -42
  160. package/src/index.tsx +0 -13
  161. package/tsconfig.node.json +0 -11
  162. package/vite.config.site.ts +0 -19
  163. package/vite.config.ts +0 -33
  164. /package/{src → dist}/vite-env.d.ts +0 -0
@@ -6,19 +6,11 @@
6
6
  *
7
7
  */
8
8
 
9
- import type {JSX} from 'react';
10
-
11
- import {isDOMNode} from 'lexical';
9
+ import { isDOMNode } from 'lexical';
10
+ import type { JSX } from 'react';
12
11
  import * as React from 'react';
13
- import {
14
- ReactNode,
15
- useCallback,
16
- useEffect,
17
- useMemo,
18
- useRef,
19
- useState,
20
- } from 'react';
21
- import {createPortal} from 'react-dom';
12
+ import { type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react';
13
+ import { createPortal } from 'react-dom';
22
14
 
23
15
  type DropDownContextType = {
24
16
  registerItem: (ref: React.RefObject<HTMLButtonElement>) => void;
@@ -47,21 +39,16 @@ export function DropDownItem({
47
39
  throw new Error('DropDownItem must be used within a DropDown');
48
40
  }
49
41
 
50
- const {registerItem} = dropDownContext;
42
+ const { registerItem } = dropDownContext;
51
43
 
52
44
  useEffect(() => {
53
- if (ref && ref.current) {
45
+ if (ref?.current) {
54
46
  registerItem(ref as React.RefObject<HTMLButtonElement>);
55
47
  }
56
48
  }, [ref, registerItem]);
57
49
 
58
50
  return (
59
- <button
60
- className={className}
61
- onClick={onClick}
62
- ref={ref}
63
- title={title}
64
- type="button">
51
+ <button className={className} onClick={onClick} ref={ref} title={title} type="button">
65
52
  {children}
66
53
  </button>
67
54
  );
@@ -71,20 +58,19 @@ function DropDownItems({
71
58
  children,
72
59
  dropDownRef,
73
60
  onClose,
74
- }: {
61
+ }: Readonly<{
75
62
  children: React.ReactNode;
76
63
  dropDownRef: React.Ref<HTMLDivElement>;
77
64
  onClose: () => void;
78
- }) {
65
+ }>) {
79
66
  const [items, setItems] = useState<React.RefObject<HTMLButtonElement>[]>();
80
- const [highlightedItem, setHighlightedItem] =
81
- useState<React.RefObject<HTMLButtonElement>>();
67
+ const [highlightedItem, setHighlightedItem] = useState<React.RefObject<HTMLButtonElement>>();
82
68
 
83
69
  const registerItem = useCallback(
84
70
  (itemRef: React.RefObject<HTMLButtonElement>) => {
85
71
  setItems((prev) => (prev ? [...prev, itemRef] : [itemRef]));
86
72
  },
87
- [setItems],
73
+ [setItems]
88
74
  );
89
75
 
90
76
  const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
@@ -122,7 +108,7 @@ function DropDownItems({
122
108
  () => ({
123
109
  registerItem,
124
110
  }),
125
- [registerItem],
111
+ [registerItem]
126
112
  );
127
113
 
128
114
  useEffect(() => {
@@ -130,7 +116,7 @@ function DropDownItems({
130
116
  setHighlightedItem(items[0]);
131
117
  }
132
118
 
133
- if (highlightedItem && highlightedItem.current) {
119
+ if (highlightedItem?.current) {
134
120
  highlightedItem.current.focus();
135
121
  }
136
122
  }, [items, highlightedItem]);
@@ -167,7 +153,7 @@ export default function DropDown({
167
153
 
168
154
  const handleClose = () => {
169
155
  setShowDropDown(false);
170
- if (buttonRef && buttonRef.current) {
156
+ if (buttonRef?.current) {
171
157
  buttonRef.current.focus();
172
158
  }
173
159
  };
@@ -177,12 +163,9 @@ export default function DropDown({
177
163
  const dropDown = dropDownRef.current;
178
164
 
179
165
  if (showDropDown && button !== null && dropDown !== null) {
180
- const {top, left} = button.getBoundingClientRect();
166
+ const { top, left } = button.getBoundingClientRect();
181
167
  dropDown.style.top = `${top + button.offsetHeight + dropDownPadding}px`;
182
- dropDown.style.left = `${Math.min(
183
- left,
184
- window.innerWidth - dropDown.offsetWidth - 20,
185
- )}px`;
168
+ dropDown.style.left = `${Math.min(left, window.innerWidth - dropDown.offsetWidth - 20)}px`;
186
169
  }
187
170
  }, [dropDownRef, buttonRef, showDropDown]);
188
171
 
@@ -196,7 +179,7 @@ export default function DropDown({
196
179
  return;
197
180
  }
198
181
  if (stopCloseOnClickSelf) {
199
- if (dropDownRef.current && dropDownRef.current.contains(target)) {
182
+ if (dropDownRef.current?.contains(target)) {
200
183
  return;
201
184
  }
202
185
  }
@@ -218,7 +201,7 @@ export default function DropDown({
218
201
  const button = buttonRef.current;
219
202
  const dropDown = dropDownRef.current;
220
203
  if (button !== null && dropDown !== null) {
221
- const {top} = button.getBoundingClientRect();
204
+ const { top } = button.getBoundingClientRect();
222
205
  const newPosition = top + button.offsetHeight + dropDownPadding;
223
206
  if (newPosition !== dropDown.getBoundingClientRect().top) {
224
207
  dropDown.style.top = `${newPosition}px`;
@@ -242,11 +225,10 @@ export default function DropDown({
242
225
  aria-label={buttonAriaLabel || buttonLabel}
243
226
  className={buttonClassName}
244
227
  onClick={() => setShowDropDown(!showDropDown)}
245
- ref={buttonRef}>
228
+ ref={buttonRef}
229
+ >
246
230
  {buttonIconClassName && <span className={buttonIconClassName} />}
247
- {buttonLabel && (
248
- <span className="text dropdown-button-text">{buttonLabel}</span>
249
- )}
231
+ {buttonLabel && <span className="text dropdown-button-text">{buttonLabel}</span>}
250
232
  <i className="chevron-down" />
251
233
  </button>
252
234
 
@@ -255,8 +237,8 @@ export default function DropDown({
255
237
  <DropDownItems dropDownRef={dropDownRef} onClose={handleClose}>
256
238
  {children}
257
239
  </DropDownItems>,
258
- document.body,
240
+ document.body
259
241
  )}
260
242
  </>
261
243
  );
262
- }
244
+ }
@@ -1,21 +1,21 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- */
8
- import type {JSX} from 'react';
9
- import "./Placeholder.css";
10
-
11
- import { ReactNode } from "react";
12
-
13
- export default function Placeholder({
14
- children,
15
- className,
16
- }: {
17
- children: ReactNode;
18
- className?: string;
19
- }): JSX.Element {
20
- return <div className={className || "Placeholder__root"}>{children}</div>;
21
- }
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import type { JSX } from 'react';
9
+ import './Placeholder.css';
10
+
11
+ import type { ReactNode } from 'react';
12
+
13
+ export default function Placeholder({
14
+ children,
15
+ className,
16
+ }: Readonly<{
17
+ children: ReactNode;
18
+ className?: string;
19
+ }>): JSX.Element {
20
+ return <div className={className || 'Placeholder__root'}>{children}</div>;
21
+ }
@@ -7,9 +7,7 @@
7
7
  */
8
8
 
9
9
  export const CAN_USE_DOM: boolean =
10
- typeof window !== "undefined" &&
11
- typeof window.document !== "undefined" &&
12
- typeof window.document.createElement !== "undefined";
10
+ typeof window !== 'undefined' && typeof window.document?.createElement !== 'undefined';
13
11
 
14
12
  declare global {
15
13
  interface Document {
@@ -21,8 +19,7 @@ declare global {
21
19
  }
22
20
  }
23
21
 
24
- const documentMode =
25
- CAN_USE_DOM && "documentMode" in document ? document.documentMode : null;
22
+ const documentMode = CAN_USE_DOM && 'documentMode' in document ? document.documentMode : null;
26
23
 
27
24
  //TODO forcing false on this to stop mismatch render between ssr and clientside
28
25
  export const IS_APPLE = false;
@@ -32,22 +29,19 @@ export const IS_FIREFOX: boolean =
32
29
  CAN_USE_DOM && /^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent);
33
30
 
34
31
  export const CAN_USE_BEFORE_INPUT: boolean =
35
- CAN_USE_DOM && "InputEvent" in window && !documentMode
36
- ? "getTargetRanges" in new window.InputEvent("input")
32
+ CAN_USE_DOM && 'InputEvent' in window && !documentMode
33
+ ? 'getTargetRanges' in new window.InputEvent('input')
37
34
  : false;
38
35
 
39
36
  export const IS_SAFARI: boolean =
40
37
  CAN_USE_DOM && /Version\/[\d.]+.*Safari/.test(navigator.userAgent);
41
38
 
42
39
  export const IS_IOS: boolean =
43
- CAN_USE_DOM &&
44
- /iPad|iPhone|iPod/.test(navigator.userAgent) &&
45
- !window.MSStream;
40
+ CAN_USE_DOM && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
46
41
 
47
42
  // Keep these in case we need to use them in the future.
48
43
  // export const IS_WINDOWS: boolean = CAN_USE_DOM && /Win/.test(navigator.platform);
49
- export const IS_CHROME: boolean =
50
- CAN_USE_DOM && /^(?=.*Chrome).*/i.test(navigator.userAgent);
44
+ export const IS_CHROME: boolean = CAN_USE_DOM && /^(?=.*Chrome).*/i.test(navigator.userAgent);
51
45
  // export const canUseTextInputEvent: boolean = CAN_USE_DOM && 'TextEvent' in window && !documentMode;
52
46
 
53
47
  export const IS_APPLE_WEBKIT =
@@ -6,12 +6,10 @@
6
6
  *
7
7
  * source: https://github.com/facebook/lexical/blob/main/packages/lexical-playground/src/utils/getSelectedNode.ts
8
8
  */
9
- import { $isAtNodeEnd } from "@lexical/selection";
10
- import { ElementNode, RangeSelection, TextNode } from "lexical";
9
+ import { $isAtNodeEnd } from '@lexical/selection';
10
+ import type { ElementNode, RangeSelection, TextNode } from 'lexical';
11
11
 
12
- export function getSelectedNode(
13
- selection: RangeSelection,
14
- ): TextNode | ElementNode {
12
+ export function getSelectedNode(selection: RangeSelection): TextNode | ElementNode {
15
13
  const anchor = selection.anchor;
16
14
  const focus = selection.focus;
17
15
  const anchorNode = selection.anchor.getNode();
@@ -14,7 +14,7 @@ export function setFloatingElemPosition(
14
14
  anchorElem: HTMLElement,
15
15
  isLink: boolean = false,
16
16
  verticalGap: number = VERTICAL_GAP,
17
- horizontalOffset: number = HORIZONTAL_OFFSET,
17
+ horizontalOffset: number = HORIZONTAL_OFFSET
18
18
  ): void {
19
19
  const scrollerElem = anchorElem.parentElement;
20
20
 
@@ -33,10 +33,7 @@ export function setFloatingElemPosition(
33
33
 
34
34
  if (top < editorScrollerRect.top) {
35
35
  // adjusted height for link element if the element is at top
36
- top +=
37
- floatingElemRect.height +
38
- targetRect.height +
39
- verticalGap * (isLink ? 9 : 2);
36
+ top += floatingElemRect.height + targetRect.height + verticalGap * (isLink ? 9 : 2);
40
37
  }
41
38
 
42
39
  if (left + floatingElemRect.width > editorScrollerRect.right) {
@@ -13,7 +13,7 @@ export function setFloatingElemPositionForLinkEditor(
13
13
  floatingElem: HTMLElement,
14
14
  anchorElem: HTMLElement,
15
15
  verticalGap: number = VERTICAL_GAP,
16
- horizontalOffset: number = HORIZONTAL_OFFSET,
16
+ horizontalOffset: number = HORIZONTAL_OFFSET
17
17
  ): void {
18
18
  const scrollerElem = anchorElem.parentElement;
19
19
 
package/src/utils/url.ts CHANGED
@@ -7,20 +7,14 @@
7
7
  * Source: https://github.com/facebook/lexical/blob/main/packages/lexical-playground/src/utils/url.ts
8
8
  */
9
9
 
10
- const SUPPORTED_URL_PROTOCOLS = new Set([
11
- "http:",
12
- "https:",
13
- "mailto:",
14
- "sms:",
15
- "tel:",
16
- ]);
10
+ const SUPPORTED_URL_PROTOCOLS = new Set(['http:', 'https:', 'mailto:', 'sms:', 'tel:']);
17
11
 
18
12
  export function sanitizeUrl(url: string): string {
19
13
  try {
20
14
  const parsedUrl = new URL(url);
21
15
  // eslint-disable-next-line no-script-url
22
16
  if (!SUPPORTED_URL_PROTOCOLS.has(parsedUrl.protocol)) {
23
- return "about:blank";
17
+ return 'about:blank';
24
18
  }
25
19
  } catch {
26
20
  return url;
@@ -30,10 +24,10 @@ export function sanitizeUrl(url: string): string {
30
24
 
31
25
  // Source: https://stackoverflow.com/a/8234912/2013580
32
26
  const urlRegExp = new RegExp(
33
- /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[\w]*))?)/,
27
+ /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-]*)?\??(?:[-+=&;%@.\w]*)#?(?:\w*))?)/
34
28
  );
35
29
  export function validateUrl(url: string): boolean {
36
30
  // TODO Fix UI for link insertion; it should never default to an invalid URL such as https://.
37
31
  // Maybe show a dialog where they user can type the URL before inserting it.
38
- return url === "https://" || urlRegExp.test(url);
32
+ return url === 'https://' || urlRegExp.test(url);
39
33
  }
package/tsconfig.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "@eventuras/typescript-config/react-library.json",
3
+ "compilerOptions": {
4
+ "rootDir": "src"
5
+ },
6
+ "include": ["src"],
7
+ "exclude": ["node_modules", "dist"]
8
+ }
package/CHANGELOG.md DELETED
@@ -1,59 +0,0 @@
1
- # @eventuras/scribo
2
-
3
- ## 0.8.2
4
-
5
- ### Patch Changes
6
-
7
- - chore: update deps
8
-
9
- ## 0.8.1
10
-
11
- ### Patch Changes
12
-
13
- - chore: update dependencies across frontend packages
14
-
15
- ## 0.8.0
16
-
17
- ### Minor Changes
18
-
19
- ### 🧱 Features
20
-
21
- - feat(scribo): auto heigh expanding (6ca2322) [@eventuras/scribo]
22
-
23
- ### 🐞 Bug Fixes
24
-
25
- - fix(scribo): import MarkdownEditor.css for styling (d1eec7a) [@eventuras/scribo]
26
- - fix(scribo): disable swc in scribo (ebce6db) [@eventuras/scribo]
27
-
28
- ### ♻️ Refactoring
29
-
30
- - refactor(scribo): merge markdowninput into scribo with flexible styling (373587e) [@eventuras/scribo]
31
-
32
- ### 🧹 Maintenance
33
-
34
- - chore(scribo): externalize Lexical packages in build configuration (7c7caaf) [@eventuras/scribo]
35
- - chore(convertoapi,docsite,web,markdown,scribo,sdk): upgrade deps (b2de638) [@eventuras/scribo]
36
-
37
- ### ⚙️ CI/CD
38
-
39
- - ci(scribo): implement automated release workflow for Scribo (36d6ba1) [@eventuras/scribo]
40
-
41
- ## 0.7.1
42
-
43
- ### Patch Changes
44
-
45
- - - chore(convertoapi,docsite,web,markdown,scribo,sdk): upgrade deps (51e931b) [@eventuras/scribo]
46
-
47
- ## 0.7.0
48
-
49
- ### Minor Changes
50
-
51
- - ## Initial history (pre-Changesets)
52
- - chore(scribo): upgrade lexical (f78dfa1)
53
- - chore(scribo): update packages (3475e0f)
54
- - feat(scribo): use readme as default content of editor page (428fc2b)
55
- - fix(scribo): add dependency (101954b)
56
- - feat(scribo): cache npm files for scribo build (a065b61)
57
- - feat(scribo): add undo/redo to markdown editor (b2482cc)
58
- - feat(scribo): adds links and link editing to editor (afe159d)
59
- - feat(scribo): set up scribo demo site (a467bc2)
package/README.md DELETED
@@ -1,126 +0,0 @@
1
- # Scribo markdown editor
2
-
3
- Markdown editor built on [Lexical framework](https://lexical.dev/). Intended to be used as part of eventuras, but also packed as a standalone component. Scribo is a WYSIWYG editor with markdown export.
4
-
5
- The editor should provide simple and intuitive editing of markdown text, with a focus on the most common use cases.
6
-
7
- Test the [scribo editor online demo](https://scribo.losol.no/).
8
-
9
- > **Lexical version**: we are keeping the lexical version in sync with the [lexical version used in Payload CMS](https://github.com/payloadcms/payload/blob/main/packages/richtext-lexical/package.json), to prevent multiple versions making trouble.
10
-
11
- ## Installation
12
-
13
- ```bash
14
- pnpm add @eventuras/scribo
15
- ```
16
-
17
- ## Usage
18
-
19
- **Important**: You must import the CSS file for Scribo to display correctly:
20
-
21
- ### MarkdownEditor (WYSIWYG Editor)
22
-
23
- ```tsx
24
- import "@eventuras/scribo/style.css";
25
- import { MarkdownEditor } from "@eventuras/scribo";
26
-
27
- function MyComponent() {
28
- return <MarkdownEditor defaultValue="# Hello World" />;
29
- }
30
- ```
31
-
32
- ### MarkdownInput (Form-ready Input)
33
-
34
- For use with native HTML forms (FormData API):
35
-
36
- ```tsx
37
- import "@eventuras/scribo/style.css";
38
- import { MarkdownInput } from "@eventuras/scribo";
39
-
40
- function MyForm() {
41
- return (
42
- <form>
43
- <MarkdownInput
44
- name="description"
45
- label="Description"
46
- placeholder="Enter markdown..."
47
- defaultValue="# Hello"
48
- maxLength={500}
49
- className="mb-4"
50
- labelClassName="font-bold"
51
- editorClassName="border rounded"
52
- errorClassName="text-red-500"
53
- />
54
- <button type="submit">Submit</button>
55
- </form>
56
- );
57
- }
58
- ```
59
-
60
- The `MarkdownInput` component is framework-agnostic and provides:
61
-
62
- - Hidden input for FormData submission
63
- - Optional label and validation
64
- - Flexible styling via className props
65
- - Character limit validation
66
-
67
- ### Peer Dependencies
68
-
69
- Scribo requires the following peer dependencies:
70
-
71
- ```bash
72
- pnpm add react react-dom lexical @lexical/code @lexical/hashtag @lexical/link @lexical/list @lexical/mark @lexical/markdown @lexical/overflow @lexical/react @lexical/rich-text @lexical/selection @lexical/table @lexical/utils prismjs
73
- ```
74
-
75
- **Prism.js for syntax highlighting:**
76
- Scribo uses Prism.js for code syntax highlighting but does not bundle it. You need to install `prismjs` and import the language grammars you need in your application.
77
-
78
- Example:
79
-
80
- ```tsx
81
- import "prismjs";
82
- import "prismjs/components/prism-javascript";
83
- import "prismjs/components/prism-typescript";
84
- import "prismjs/components/prism-css";
85
- // Import other languages as needed
86
- ```
87
-
88
- ## Develop
89
-
90
- To start developing Scribo, run the following commands:
91
-
92
- ```bash
93
- pnpm install
94
- vite dev
95
- ```
96
-
97
- ## Release
98
-
99
- Quick release process:
100
-
101
- ```bash
102
- # 1. Create changeset (choose one)
103
- pnpm changeset # Manual (recommended)
104
- pnpm changeset:suggest # Auto-generate from commits
105
-
106
- # 2. Version package
107
- pnpm changeset:version
108
-
109
- # 3. Commit and push (create PR to main)
110
- git checkout -b release/scribo-v0.x.x
111
- git add .
112
- git commit -m "chore(scribo): release v0.x.x"
113
- git push origin release/scribo-v0.x.x
114
-
115
- # 4. Merge PR to main, then automated workflow will publish to npm and create GitHub release
116
- ```
117
-
118
- For detailed release instructions, including setup and troubleshooting, see [RELEASE.md](./RELEASE.md).
119
-
120
- ## Credits
121
-
122
- Scribo is built on the [Lexical framework](https://lexical.dev/), and most of the code in the repo is done by [Meta under MIT license](https://github.com/facebook/lexical).
123
-
124
- ## Learn More
125
-
126
- - [Lexical](https://lexical.dev/)
package/RELEASE.md DELETED
@@ -1,102 +0,0 @@
1
- # Release Instructions for @eventuras/scribo
2
-
3
- This document explains how to configure the automated release workflow for `@eventuras/scribo`.
4
-
5
- ## Release Process
6
-
7
- ### Standard Release
8
-
9
- 1. **Create changesets** for your changes:
10
-
11
- ```bash
12
- # Option A: Manual (recommended for better changelog messages)
13
- pnpm changeset
14
-
15
- # Option B: Auto-generate from commits (review and edit after)
16
- pnpm changeset:suggest
17
- ```
18
-
19
- > **Tip**: `changeset:suggest` analyzes your git commits since the last release and automatically generates changeset files. Review the generated changesets and edit them for clarity if needed.
20
-
21
- 2. **Version the package** when ready:
22
-
23
- ```bash
24
- pnpm changeset:version
25
- ```
26
-
27
- 3. **Commit and push** the version bump:
28
-
29
- ```bash
30
- git add .
31
- git commit -m "chore(scribo): release v0.x.x"
32
- git push origin main
33
- ```
34
-
35
- 4. **Automated workflow** will:
36
- - ✅ Build the package
37
- - ✅ Publish to npm with provenance
38
- - ✅ Create Git tag `@eventuras/scribo@x.x.x`
39
- - ✅ Create GitHub Release with changelog
40
-
41
- ### Manual Release
42
-
43
- If the automated workflow fails or you need to publish manually:
44
-
45
- ```bash
46
- cd libs/scribo
47
- pnpm build
48
- npm login --scope @eventuras --auth-type web
49
- npm publish --access public
50
- ```
51
-
52
- ## Release Setup
53
-
54
- ### NPM Trusted Publishing Setup (Recommended)
55
-
56
- Scribo uses **npm trusted publishing with OIDC** for secure, token-free publishing.
57
-
58
- #### Configure Trusted Publisher on npmjs.com
59
-
60
- 1. Log in to [npmjs.com](https://www.npmjs.com)
61
- 2. Navigate to `@eventuras/scribo` package settings
62
- 3. Find **Trusted Publisher** section
63
- 4. Click **GitHub Actions**
64
- 5. Configure:
65
- - **Organization or user**: `losol`
66
- - **Repository**: `eventuras`
67
- - **Workflow filename**: `scribo-release.yml` (include `.yml` extension)
68
- - **Environment name**: `scribo-npm`
69
- 6. Click **Add trusted publisher**
70
-
71
- #### Set Up GitHub Environment
72
-
73
- The workflow uses a GitHub environment for deployment protection (optional but recommended):
74
-
75
- 1. Go to your GitHub repository
76
- 2. Navigate to **Settings** → **Environments**
77
- 3. Click **New environment**
78
- 4. Name: `scribo-npm`
79
- 5. (Optional) Add protection rules:
80
- - Required reviewers if you want manual approval
81
- - Deployment branches: Select "Selected branches" and add `main`
82
- 6. Click **Create environment**
83
-
84
- > **Note**: With trusted publishing, you don't need to add any secrets to this environment. The workflow uses OIDC authentication automatically.
85
-
86
- ### Legacy: Token-Based Publishing (Not Recommended)
87
-
88
- If you cannot use trusted publishing, you can fall back to traditional npm tokens:
89
-
90
- 1. Create a granular access token on npmjs.com with write access to `@eventuras/scribo`
91
- 2. Add it as `NODE_AUTH_TOKEN` secret in the `scribo-npm` environment
92
- 3. Update the workflow to include `NODE_AUTH_TOKEN` environment variable in the publish step
93
-
94
- However, trusted publishing is strongly recommended for better security.
95
-
96
-
97
- ## Workflow Trigger
98
-
99
- The release workflow (`.github/workflows/scribo-release.yml`) triggers automatically when:
100
-
101
- - Changes are pushed to the `main` branch
102
- - The file `libs/scribo/package.json` is modified
package/eslint.config.js DELETED
@@ -1,4 +0,0 @@
1
- /** @type {import("eslint").Linter.Config} */
2
- module.exports = {
3
- extends: ['@eventuras/eslint-config/react-library.js'],
4
- };
package/src/App.css DELETED
@@ -1,35 +0,0 @@
1
- body {
2
- margin: 0;
3
- background: #eee;
4
- font-family: Arial, Helvetica, sans-serif;
5
- }
6
-
7
- h1 {
8
- text-align: center;
9
- margin: 20px 0;
10
- }
11
-
12
- .editor-container {
13
- display: flex;
14
- flex-direction: column;
15
- }
16
-
17
- .markdown-output {
18
- white-space: pre-wrap;
19
- overflow: auto;
20
- }
21
-
22
- @media (min-width: 768px) {
23
- .editor-container {
24
- flex-direction: row;
25
- }
26
-
27
- .markdown-editor,
28
- .markdown-output {
29
- flex: 1;
30
- margin: 10px;
31
- padding: 20px;
32
- border: 1px solid #ccc;
33
- border-radius: 5px;
34
- }
35
- }