@squiz/formatted-text-editor 1.21.1-alpha.20 → 1.21.1-alpha.22

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.
@@ -32,6 +32,19 @@ const EditorToolbar_1 = require("../EditorToolbar");
32
32
  const EditorContext_1 = require("./EditorContext");
33
33
  const Extensions_1 = require("../Extensions/Extensions");
34
34
  const clsx_1 = __importDefault(require("clsx"));
35
+ const WrappedEditor = () => {
36
+ const preventImagePaste = (0, react_1.useCallback)((event) => {
37
+ const { clipboardData } = event;
38
+ const pastedData = clipboardData?.files[0];
39
+ if (pastedData?.type && pastedData?.type.startsWith('image/')) {
40
+ event.preventDefault();
41
+ }
42
+ // Allow other paste event handlers to be run.
43
+ return false;
44
+ }, []);
45
+ (0, react_2.useEditorEvent)('paste', preventImagePaste);
46
+ return react_1.default.createElement(react_2.EditorComponent, null);
47
+ };
35
48
  const Editor = ({ content, editable = true, onChange }) => {
36
49
  const { manager, state, setState } = (0, react_2.useRemirror)({
37
50
  extensions: (0, Extensions_1.createExtensions)((0, react_1.useContext)(EditorContext_1.EditorContext)),
@@ -43,18 +56,11 @@ const Editor = ({ content, editable = true, onChange }) => {
43
56
  setState(parameter.state);
44
57
  onChange?.(parameter);
45
58
  };
46
- const preventImagePaste = (event) => {
47
- const { clipboardData } = event;
48
- const pastedData = clipboardData?.items[0];
49
- if (pastedData?.type && pastedData?.type.startsWith('image/')) {
50
- event.preventDefault();
51
- }
52
- };
53
59
  return (react_1.default.createElement("div", { className: "squiz-fte-scope" },
54
- react_1.default.createElement("div", { className: (0, clsx_1.default)('remirror-theme formatted-text-editor', !editable && 'formatted-text-editor--is-disabled'), onPaste: preventImagePaste },
60
+ react_1.default.createElement("div", { className: (0, clsx_1.default)('remirror-theme formatted-text-editor', !editable && 'formatted-text-editor--is-disabled') },
55
61
  react_1.default.createElement(react_2.Remirror, { manager: manager, state: state, editable: editable, onChange: handleChange, placeholder: "Write something", label: "Text editor" },
56
62
  editable && react_1.default.createElement(EditorToolbar_1.Toolbar, null),
57
- react_1.default.createElement(react_2.EditorComponent, null),
63
+ react_1.default.createElement(WrappedEditor, null),
58
64
  editable && react_1.default.createElement(EditorToolbar_1.FloatingToolbar, null)))));
59
65
  };
60
66
  exports.default = Editor;
@@ -51,7 +51,7 @@ const FloatingToolbar = () => {
51
51
  extensionNames.underline && react_1.default.createElement(UnderlineButton_1.default, { key: "underline" }),
52
52
  ];
53
53
  if (active.image()) {
54
- buttons.push(react_1.default.createElement(react_components_1.VerticalDivider, { key: "image-divider", className: "editor-divider" }), react_1.default.createElement(ImageButton_1.default, { key: "add-image", inPopover: true }));
54
+ buttons = [react_1.default.createElement(ImageButton_1.default, { key: "add-image", inPopover: true })];
55
55
  }
56
56
  else if (marks?.[Extensions_1.MarkName.Link].isExclusivelyActive || marks?.[Extensions_1.MarkName.AssetLink].isExclusivelyActive) {
57
57
  // if all of the selected text is a link show the options to update/remove the link instead of the regular
@@ -64,10 +64,11 @@ const ImageButton = ({ inPopover = false }) => {
64
64
  // Prevent other key handlers being run
65
65
  return true;
66
66
  }, []);
67
+ // when Ctrl+l is pressed show the modal, only registered in the toolbar button instance to avoid the key press
68
+ // being double handled.
67
69
  if (!inPopover) {
68
- // when Ctrl+l is pressed show the modal, only registered in the toolbar button instance to avoid the key press
69
- // being double handled.
70
- (0, react_2.useKeymap)('Mod-l', handleShortcut);
70
+ // disable the shortcut if the button is disabled
71
+ (0, react_2.useKeymap)('Mod-l', disabled ? () => false : handleShortcut);
71
72
  }
72
73
  return (react_1.default.createElement(react_1.default.Fragment, null,
73
74
  react_1.default.createElement(Button_1.default, { handleOnClick: handleClick, isActive: active.image(), icon: react_1.default.createElement(ImageRounded_1.default, null), label: "Image (cmd+L)", isDisabled: disabled }),
@@ -31,7 +31,6 @@ const InsertLinkRounded_1 = __importDefault(require("@mui/icons-material/InsertL
31
31
  const LinkModal_1 = __importDefault(require("./LinkModal"));
32
32
  const Button_1 = __importDefault(require("../../../ui/Button/Button"));
33
33
  const react_2 = require("@remirror/react");
34
- const LinkExtension_1 = require("../../../Extensions/LinkExtension/LinkExtension");
35
34
  const Extensions_1 = require("../../../Extensions/Extensions");
36
35
  const LinkButton = ({ inPopover = false }) => {
37
36
  const [showModal, setShowModal] = (0, react_1.useState)(false);
@@ -44,6 +43,11 @@ const LinkButton = ({ inPopover = false }) => {
44
43
  setShowModal(true);
45
44
  }
46
45
  };
46
+ const handleShortcut = (0, react_1.useCallback)(() => {
47
+ handleClick();
48
+ // Prevent other key handlers being run
49
+ return true;
50
+ }, []);
47
51
  const handleSubmit = (data) => {
48
52
  if (data.linkType === Extensions_1.MarkName.AssetLink) {
49
53
  updateAssetLink({ text: data.text, attrs: data.assetLink, range: data.range });
@@ -53,10 +57,11 @@ const LinkButton = ({ inPopover = false }) => {
53
57
  }
54
58
  setShowModal(false);
55
59
  };
60
+ // when Ctrl+K is pressed show the modal, only registered in the toolbar button instance to avoid the key press
61
+ // being double handled.
56
62
  if (!inPopover) {
57
- // when Ctrl+K is pressed show the modal, only registered in the toolbar button instance to avoid the key press
58
- // being double handled.
59
- (0, react_2.useExtensionEvent)(LinkExtension_1.LinkExtension, 'onShortcut', (0, react_1.useCallback)(() => handleClick(), []));
63
+ // disable the shortcut if the button is disabled
64
+ (0, react_2.useKeymap)('Mod-k', disabled ? () => true : handleShortcut);
60
65
  }
61
66
  return (react_1.default.createElement(react_1.default.Fragment, null,
62
67
  react_1.default.createElement(Button_1.default, { handleOnClick: handleClick, isActive: active.link() || active.assetLink(), icon: react_1.default.createElement(InsertLinkRounded_1.default, null), label: "Link (cmd+K)", isDisabled: disabled }),
package/lib/index.css CHANGED
@@ -737,6 +737,9 @@
737
737
  --tw-border-opacity: 1;
738
738
  border-color: rgb(7 116 210 / var(--tw-border-opacity));
739
739
  }
740
+ .squiz-fte-scope .formatted-text-editor img {
741
+ display: inline;
742
+ }
740
743
  .squiz-fte-scope .editor-toolbar,
741
744
  .squiz-fte-scope__floating-popover {
742
745
  border-bottom-width: 2px;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squiz/formatted-text-editor",
3
- "version": "1.21.1-alpha.20",
3
+ "version": "1.21.1-alpha.22",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "scripts": {
@@ -72,5 +72,5 @@
72
72
  "volta": {
73
73
  "node": "18.15.0"
74
74
  },
75
- "gitHead": "83f7b471dd6dd239c5b25233dcb5696fa96267e7"
75
+ "gitHead": "82a7818468c6bcc2eee98748a0962d233c35f55e"
76
76
  }
@@ -1,10 +1,11 @@
1
- import React, { ClipboardEvent, useContext } from 'react';
2
- import { EditorComponent, Remirror, useRemirror } from '@remirror/react';
1
+ import React, { useContext, useCallback } from 'react';
2
+ import { EditorComponent, Remirror, useRemirror, useEditorEvent } from '@remirror/react';
3
3
  import { RemirrorContentType, RemirrorEventListener, Extension } from '@remirror/core';
4
4
  import { Toolbar, FloatingToolbar } from '../EditorToolbar';
5
5
  import { EditorContext } from './EditorContext';
6
6
  import { createExtensions } from '../Extensions/Extensions';
7
7
  import clsx from 'clsx';
8
+ import { ClipboardEventHandler } from '@remirror/extension-events/dist-types/events-extension';
8
9
 
9
10
  type EditorProps = {
10
11
  content?: RemirrorContentType;
@@ -12,6 +13,22 @@ type EditorProps = {
12
13
  editable?: boolean;
13
14
  };
14
15
 
16
+ const WrappedEditor = () => {
17
+ const preventImagePaste = useCallback((event) => {
18
+ const { clipboardData } = event;
19
+ const pastedData = clipboardData?.files[0];
20
+ if (pastedData?.type && pastedData?.type.startsWith('image/')) {
21
+ event.preventDefault();
22
+ }
23
+
24
+ // Allow other paste event handlers to be run.
25
+ return false;
26
+ }, []) as ClipboardEventHandler;
27
+
28
+ useEditorEvent('paste', preventImagePaste);
29
+ return <EditorComponent />;
30
+ };
31
+
15
32
  const Editor = ({ content, editable = true, onChange }: EditorProps) => {
16
33
  const { manager, state, setState } = useRemirror({
17
34
  extensions: createExtensions(useContext(EditorContext)),
@@ -25,20 +42,9 @@ const Editor = ({ content, editable = true, onChange }: EditorProps) => {
25
42
  onChange?.(parameter);
26
43
  };
27
44
 
28
- const preventImagePaste = (event: ClipboardEvent<HTMLDivElement>) => {
29
- const { clipboardData } = event;
30
- const pastedData = clipboardData?.items[0];
31
- if (pastedData?.type && pastedData?.type.startsWith('image/')) {
32
- event.preventDefault();
33
- }
34
- };
35
-
36
45
  return (
37
46
  <div className="squiz-fte-scope">
38
- <div
39
- className={clsx('remirror-theme formatted-text-editor', !editable && 'formatted-text-editor--is-disabled')}
40
- onPaste={preventImagePaste}
41
- >
47
+ <div className={clsx('remirror-theme formatted-text-editor', !editable && 'formatted-text-editor--is-disabled')}>
42
48
  <Remirror
43
49
  manager={manager}
44
50
  state={state}
@@ -48,7 +54,7 @@ const Editor = ({ content, editable = true, onChange }: EditorProps) => {
48
54
  label="Text editor"
49
55
  >
50
56
  {editable && <Toolbar />}
51
- <EditorComponent />
57
+ <WrappedEditor />
52
58
  {editable && <FloatingToolbar />}
53
59
  </Remirror>
54
60
  </div>
@@ -39,7 +39,13 @@
39
39
  content: attr(data-placeholder);
40
40
  @apply text-gray-500;
41
41
  }
42
+
42
43
  .ProseMirror-selectednode {
43
44
  @apply border-blue-300 border-2 border-solid;
44
45
  }
46
+
47
+ // match the Remirror node
48
+ img {
49
+ display: inline;
50
+ }
45
51
  }
@@ -28,10 +28,7 @@ export const FloatingToolbar = () => {
28
28
  ];
29
29
 
30
30
  if (active.image()) {
31
- buttons.push(
32
- <VerticalDivider key="image-divider" className="editor-divider" />,
33
- <ImageButton key="add-image" inPopover={true} />,
34
- );
31
+ buttons = [<ImageButton key="add-image" inPopover={true} />];
35
32
  } else if (marks?.[MarkName.Link].isExclusivelyActive || marks?.[MarkName.AssetLink].isExclusivelyActive) {
36
33
  // if all of the selected text is a link show the options to update/remove the link instead of the regular
37
34
  // formatting options.
@@ -48,10 +48,11 @@ const ImageButton = ({ inPopover = false }: ImageButtonProps) => {
48
48
  return true;
49
49
  }, []);
50
50
 
51
+ // when Ctrl+l is pressed show the modal, only registered in the toolbar button instance to avoid the key press
52
+ // being double handled.
51
53
  if (!inPopover) {
52
- // when Ctrl+l is pressed show the modal, only registered in the toolbar button instance to avoid the key press
53
- // being double handled.
54
- useKeymap('Mod-l', handleShortcut);
54
+ // disable the shortcut if the button is disabled
55
+ useKeymap('Mod-l', disabled ? () => false : handleShortcut);
55
56
  }
56
57
 
57
58
  return (
@@ -3,7 +3,7 @@ import InsertLinkRoundedIcon from '@mui/icons-material/InsertLinkRounded';
3
3
  import LinkModal from './LinkModal';
4
4
  import { LinkFormData } from './Form/LinkForm';
5
5
  import Button from '../../../ui/Button/Button';
6
- import { useActive, useCommands, useExtensionEvent } from '@remirror/react';
6
+ import { useActive, useCommands, useKeymap } from '@remirror/react';
7
7
  import { LinkExtension } from '../../../Extensions/LinkExtension/LinkExtension';
8
8
  import { CommandsExtension } from '../../../Extensions/CommandsExtension/CommandsExtension';
9
9
  import { AssetLinkExtension } from '../../../Extensions/LinkExtension/AssetLinkExtension';
@@ -25,6 +25,12 @@ const LinkButton = ({ inPopover = false }: LinkButtonProps) => {
25
25
  setShowModal(true);
26
26
  }
27
27
  };
28
+ const handleShortcut = useCallback(() => {
29
+ handleClick();
30
+ // Prevent other key handlers being run
31
+ return true;
32
+ }, []);
33
+
28
34
  const handleSubmit = (data: LinkFormData) => {
29
35
  if (data.linkType === MarkName.AssetLink) {
30
36
  updateAssetLink({ text: data.text, attrs: data.assetLink, range: data.range });
@@ -35,14 +41,11 @@ const LinkButton = ({ inPopover = false }: LinkButtonProps) => {
35
41
  setShowModal(false);
36
42
  };
37
43
 
44
+ // when Ctrl+K is pressed show the modal, only registered in the toolbar button instance to avoid the key press
45
+ // being double handled.
38
46
  if (!inPopover) {
39
- // when Ctrl+K is pressed show the modal, only registered in the toolbar button instance to avoid the key press
40
- // being double handled.
41
- useExtensionEvent(
42
- LinkExtension,
43
- 'onShortcut',
44
- useCallback(() => handleClick(), []),
45
- );
47
+ // disable the shortcut if the button is disabled
48
+ useKeymap('Mod-k', disabled ? () => true : handleShortcut);
46
49
  }
47
50
 
48
51
  return (