@squiz/formatted-text-editor 2.3.0 → 2.4.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.
Files changed (157) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/lib/Editor/Editor.d.ts +16 -0
  3. package/lib/Editor/Editor.js +85 -0
  4. package/lib/Editor/EditorContext.d.ts +10 -0
  5. package/lib/Editor/EditorContext.js +16 -0
  6. package/lib/EditorToolbar/FloatingToolbar.d.ts +2 -0
  7. package/lib/EditorToolbar/FloatingToolbar.js +76 -0
  8. package/lib/EditorToolbar/Toolbar.d.ts +7 -0
  9. package/lib/EditorToolbar/Toolbar.js +49 -0
  10. package/lib/EditorToolbar/Tools/Bold/BoldButton.d.ts +3 -0
  11. package/lib/EditorToolbar/Tools/Bold/BoldButton.js +23 -0
  12. package/lib/EditorToolbar/Tools/ClearFormatting/ClearFormattingButton.d.ts +3 -0
  13. package/lib/EditorToolbar/Tools/ClearFormatting/ClearFormattingButton.js +57 -0
  14. package/lib/EditorToolbar/Tools/ContentTools/ContentToolsDropdown.d.ts +3 -0
  15. package/lib/EditorToolbar/Tools/ContentTools/ContentToolsDropdown.js +104 -0
  16. package/lib/EditorToolbar/Tools/HorizontalLine/HorizontalLineButton.d.ts +3 -0
  17. package/lib/EditorToolbar/Tools/HorizontalLine/HorizontalLineButton.js +25 -0
  18. package/lib/EditorToolbar/Tools/Image/Form/ImageForm.d.ts +19 -0
  19. package/lib/EditorToolbar/Tools/Image/Form/ImageForm.js +186 -0
  20. package/lib/EditorToolbar/Tools/Image/ImageButton.d.ts +6 -0
  21. package/lib/EditorToolbar/Tools/Image/ImageButton.js +79 -0
  22. package/lib/EditorToolbar/Tools/Image/ImageModal.d.ts +9 -0
  23. package/lib/EditorToolbar/Tools/Image/ImageModal.js +26 -0
  24. package/lib/EditorToolbar/Tools/Italic/ItalicButton.d.ts +3 -0
  25. package/lib/EditorToolbar/Tools/Italic/ItalicButton.js +23 -0
  26. package/lib/EditorToolbar/Tools/Link/Form/LinkForm.d.ts +19 -0
  27. package/lib/EditorToolbar/Tools/Link/Form/LinkForm.js +63 -0
  28. package/lib/EditorToolbar/Tools/Link/LinkButton.d.ts +6 -0
  29. package/lib/EditorToolbar/Tools/Link/LinkButton.js +71 -0
  30. package/lib/EditorToolbar/Tools/Link/LinkModal.d.ts +9 -0
  31. package/lib/EditorToolbar/Tools/Link/LinkModal.js +27 -0
  32. package/lib/EditorToolbar/Tools/Link/RemoveLinkButton.d.ts +4 -0
  33. package/lib/EditorToolbar/Tools/Link/RemoveLinkButton.js +54 -0
  34. package/lib/EditorToolbar/Tools/Lists/ListButtons.d.ts +3 -0
  35. package/lib/EditorToolbar/Tools/Lists/ListButtons.js +14 -0
  36. package/lib/EditorToolbar/Tools/Lists/OrderedList/OrderedListButton.d.ts +3 -0
  37. package/lib/EditorToolbar/Tools/Lists/OrderedList/OrderedListButton.js +22 -0
  38. package/lib/EditorToolbar/Tools/Lists/UnorderedList/UnorderedListButton.d.ts +3 -0
  39. package/lib/EditorToolbar/Tools/Lists/UnorderedList/UnorderedListButton.js +22 -0
  40. package/lib/EditorToolbar/Tools/Redo/RedoButton.d.ts +3 -0
  41. package/lib/EditorToolbar/Tools/Redo/RedoButton.js +22 -0
  42. package/lib/EditorToolbar/Tools/Table/TableButton.d.ts +3 -0
  43. package/lib/EditorToolbar/Tools/Table/TableButton.js +20 -0
  44. package/lib/EditorToolbar/Tools/TextAlign/CenterAlign/CenterAlignButton.d.ts +3 -0
  45. package/lib/EditorToolbar/Tools/TextAlign/CenterAlign/CenterAlignButton.js +22 -0
  46. package/lib/EditorToolbar/Tools/TextAlign/JustifyAlign/JustifyAlignButton.d.ts +3 -0
  47. package/lib/EditorToolbar/Tools/TextAlign/JustifyAlign/JustifyAlignButton.js +22 -0
  48. package/lib/EditorToolbar/Tools/TextAlign/LeftAlign/LeftAlignButton.d.ts +3 -0
  49. package/lib/EditorToolbar/Tools/TextAlign/LeftAlign/LeftAlignButton.js +22 -0
  50. package/lib/EditorToolbar/Tools/TextAlign/RightAlign/RightAlignButton.d.ts +3 -0
  51. package/lib/EditorToolbar/Tools/TextAlign/RightAlign/RightAlignButton.js +22 -0
  52. package/lib/EditorToolbar/Tools/TextAlign/TextAlignButtons.d.ts +3 -0
  53. package/lib/EditorToolbar/Tools/TextAlign/TextAlignButtons.js +21 -0
  54. package/lib/EditorToolbar/Tools/TextType/CodeBlock/CodeBlockButton.d.ts +3 -0
  55. package/lib/EditorToolbar/Tools/TextType/CodeBlock/CodeBlockButton.js +22 -0
  56. package/lib/EditorToolbar/Tools/TextType/Heading/HeadingButton.d.ts +6 -0
  57. package/lib/EditorToolbar/Tools/TextType/Heading/HeadingButton.js +37 -0
  58. package/lib/EditorToolbar/Tools/TextType/Paragraph/ParagraphButton.d.ts +3 -0
  59. package/lib/EditorToolbar/Tools/TextType/Paragraph/ParagraphButton.js +21 -0
  60. package/lib/EditorToolbar/Tools/TextType/Preformatted/PreformattedButton.d.ts +3 -0
  61. package/lib/EditorToolbar/Tools/TextType/Preformatted/PreformattedButton.js +22 -0
  62. package/lib/EditorToolbar/Tools/TextType/TextTypeDropdown.d.ts +3 -0
  63. package/lib/EditorToolbar/Tools/TextType/TextTypeDropdown.js +46 -0
  64. package/lib/EditorToolbar/Tools/Underline/UnderlineButton.d.ts +3 -0
  65. package/lib/EditorToolbar/Tools/Underline/UnderlineButton.js +23 -0
  66. package/lib/EditorToolbar/Tools/Undo/UndoButton.d.ts +3 -0
  67. package/lib/EditorToolbar/Tools/Undo/UndoButton.js +22 -0
  68. package/lib/EditorToolbar/index.d.ts +2 -0
  69. package/lib/EditorToolbar/index.js +18 -0
  70. package/lib/Extensions/ClearFormattingExtension/ClearFormattingExtension.d.ts +5 -0
  71. package/lib/Extensions/ClearFormattingExtension/ClearFormattingExtension.js +63 -0
  72. package/lib/Extensions/CodeBlockExtension/CodeBlockExtension.d.ts +5 -0
  73. package/lib/Extensions/CodeBlockExtension/CodeBlockExtension.js +30 -0
  74. package/lib/Extensions/CommandsExtension/CommandsExtension.d.ts +20 -0
  75. package/lib/Extensions/CommandsExtension/CommandsExtension.js +52 -0
  76. package/lib/Extensions/Extensions.d.ts +18 -0
  77. package/lib/Extensions/Extensions.js +76 -0
  78. package/lib/Extensions/FetchUrlExtension/FetchUrlExtension.d.ts +12 -0
  79. package/lib/Extensions/FetchUrlExtension/FetchUrlExtension.js +69 -0
  80. package/lib/Extensions/ImageExtension/AssetImageExtension.d.ts +17 -0
  81. package/lib/Extensions/ImageExtension/AssetImageExtension.js +91 -0
  82. package/lib/Extensions/ImageExtension/DAMImageExtension.d.ts +17 -0
  83. package/lib/Extensions/ImageExtension/DAMImageExtension.js +97 -0
  84. package/lib/Extensions/ImageExtension/ImageExtension.d.ts +7 -0
  85. package/lib/Extensions/ImageExtension/ImageExtension.js +18 -0
  86. package/lib/Extensions/LinkExtension/AssetLinkExtension.d.ts +27 -0
  87. package/lib/Extensions/LinkExtension/AssetLinkExtension.js +101 -0
  88. package/lib/Extensions/LinkExtension/LinkExtension.d.ts +23 -0
  89. package/lib/Extensions/LinkExtension/LinkExtension.js +87 -0
  90. package/lib/Extensions/LinkExtension/common.d.ts +7 -0
  91. package/lib/Extensions/LinkExtension/common.js +14 -0
  92. package/lib/Extensions/PreformattedExtension/PreformattedExtension.d.ts +12 -0
  93. package/lib/Extensions/PreformattedExtension/PreformattedExtension.js +76 -0
  94. package/lib/Extensions/UnsuportedExtension/UnsupportedNodeExtension.d.ts +10 -0
  95. package/lib/Extensions/UnsuportedExtension/UnsupportedNodeExtension.js +76 -0
  96. package/lib/Icons/AiIcon.d.ts +2 -0
  97. package/lib/Icons/AiIcon.js +60 -0
  98. package/lib/hooks/index.d.ts +2 -0
  99. package/lib/hooks/index.js +18 -0
  100. package/lib/hooks/useExpandedSelection.d.ts +23 -0
  101. package/lib/hooks/useExpandedSelection.js +37 -0
  102. package/lib/hooks/useExtensionNames.d.ts +1 -0
  103. package/lib/hooks/useExtensionNames.js +16 -0
  104. package/lib/hooks/useFocus.d.ts +8 -0
  105. package/lib/hooks/useFocus.js +43 -0
  106. package/lib/index.css +5889 -0
  107. package/lib/index.d.ts +8 -0
  108. package/lib/index.js +16 -0
  109. package/lib/types.d.ts +7 -0
  110. package/lib/types.js +2 -0
  111. package/lib/ui/Button/Button.d.ts +12 -0
  112. package/lib/ui/Button/Button.js +13 -0
  113. package/lib/ui/CollapseBox/CollapseBox.d.ts +7 -0
  114. package/lib/ui/CollapseBox/CollapseBox.js +48 -0
  115. package/lib/ui/Fields/Checkbox/Checkbox.d.ts +9 -0
  116. package/lib/ui/Fields/Checkbox/Checkbox.js +47 -0
  117. package/lib/ui/Fields/Input/Input.d.ts +3 -0
  118. package/lib/ui/Fields/Input/Input.js +33 -0
  119. package/lib/ui/Fields/InputContainer/InputContainer.d.ts +9 -0
  120. package/lib/ui/Fields/InputContainer/InputContainer.js +16 -0
  121. package/lib/ui/Fields/MatrixAsset/MatrixAsset.d.ts +19 -0
  122. package/lib/ui/Fields/MatrixAsset/MatrixAsset.js +30 -0
  123. package/lib/ui/Fields/ResourceBrowserSelector/ResourceBrowserSelector.d.ts +28 -0
  124. package/lib/ui/Fields/ResourceBrowserSelector/ResourceBrowserSelector.js +88 -0
  125. package/lib/ui/Modal/FormModal.d.ts +5 -0
  126. package/lib/ui/Modal/FormModal.js +39 -0
  127. package/lib/ui/Modal/Modal.d.ts +11 -0
  128. package/lib/ui/Modal/Modal.js +79 -0
  129. package/lib/ui/Tabs/Tabs.d.ts +11 -0
  130. package/lib/ui/Tabs/Tabs.js +46 -0
  131. package/lib/ui/ToolbarDropdown/ToolbarDropdown.d.ts +7 -0
  132. package/lib/ui/ToolbarDropdown/ToolbarDropdown.js +48 -0
  133. package/lib/ui/ToolbarDropdownButton/ToolbarDropdownButton.d.ts +11 -0
  134. package/lib/ui/ToolbarDropdownButton/ToolbarDropdownButton.js +15 -0
  135. package/lib/utils/converters/htmlToSquizNode/htmlToSquizNode.d.ts +5 -0
  136. package/lib/utils/converters/htmlToSquizNode/htmlToSquizNode.js +23 -0
  137. package/lib/utils/converters/htmlToSquizNode/htmlToSquizNode.props.d.ts +3 -0
  138. package/lib/utils/converters/htmlToSquizNode/htmlToSquizNode.props.js +2 -0
  139. package/lib/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.d.ts +11 -0
  140. package/lib/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.js +238 -0
  141. package/lib/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.d.ts +9 -0
  142. package/lib/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.js +214 -0
  143. package/lib/utils/createToolbarPositioner.d.ts +18 -0
  144. package/lib/utils/createToolbarPositioner.js +96 -0
  145. package/lib/utils/getCursorRect.d.ts +2 -0
  146. package/lib/utils/getCursorRect.js +7 -0
  147. package/lib/utils/getMarkNamesByGroup.d.ts +2 -0
  148. package/lib/utils/getMarkNamesByGroup.js +9 -0
  149. package/lib/utils/getNodeNamesByGroup.d.ts +2 -0
  150. package/lib/utils/getNodeNamesByGroup.js +9 -0
  151. package/lib/utils/getShortcutSymbol.d.ts +1 -0
  152. package/lib/utils/getShortcutSymbol.js +8 -0
  153. package/lib/utils/undefinedIfEmpty.d.ts +1 -0
  154. package/lib/utils/undefinedIfEmpty.js +7 -0
  155. package/lib/utils/validation.d.ts +3 -0
  156. package/lib/utils/validation.js +16 -0
  157. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Change Log
2
2
 
3
+ ## 2.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 0d281a8: test changeset to trigger job
8
+
3
9
  ## 2.3.0
4
10
 
5
11
  ### Minor Changes
@@ -0,0 +1,16 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { RemirrorContentType, RemirrorEventListener, Extension } from '@remirror/core';
3
+ type EditorProps = {
4
+ className?: string;
5
+ content?: RemirrorContentType;
6
+ onChange?: RemirrorEventListener<Extension>;
7
+ editable?: boolean;
8
+ border?: boolean;
9
+ children?: ReactNode;
10
+ isFocused?: boolean;
11
+ label?: string;
12
+ attributes?: Record<string, string>;
13
+ enableTableTool?: boolean;
14
+ };
15
+ declare const Editor: ({ content, className, border, editable, onChange, children, isFocused, attributes, enableTableTool, }: EditorProps) => React.JSX.Element;
16
+ export default Editor;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ const react_1 = __importStar(require("react"));
30
+ const react_2 = require("@remirror/react");
31
+ const clsx_1 = __importDefault(require("clsx"));
32
+ const EditorToolbar_1 = require("../EditorToolbar");
33
+ const EditorContext_1 = require("./EditorContext");
34
+ const Extensions_1 = require("../Extensions/Extensions");
35
+ const useFocus_1 = __importDefault(require("../hooks/useFocus"));
36
+ const extension_react_tables_1 = require("@remirror/extension-react-tables");
37
+ const WrappedEditor = () => {
38
+ const preventImagePaste = (0, react_1.useCallback)((event) => {
39
+ const { clipboardData } = event;
40
+ const pastedData = clipboardData?.files[0];
41
+ if (pastedData?.type &&
42
+ pastedData?.type.startsWith('image/') &&
43
+ // Still allow paste of any text that came through (Word, etc)
44
+ !clipboardData?.types.includes('text/plain')) {
45
+ event.preventDefault();
46
+ }
47
+ // Allow other paste event handlers to be run.
48
+ return false;
49
+ }, []);
50
+ (0, react_2.useEditorEvent)('paste', preventImagePaste);
51
+ return react_1.default.createElement(react_2.EditorComponent, null);
52
+ };
53
+ const Editor = ({ content, className, border = true, editable = true, onChange, children, isFocused, attributes, enableTableTool = false, }) => {
54
+ const { manager, state, setState } = (0, react_2.useRemirror)({
55
+ extensions: (0, Extensions_1.createExtensions)((0, react_1.useContext)(EditorContext_1.EditorContext)),
56
+ content,
57
+ selection: 'start',
58
+ stringHandler: 'html',
59
+ });
60
+ const handleChange = (parameter) => {
61
+ setState(parameter.state);
62
+ onChange?.(parameter);
63
+ };
64
+ const { isVisible, handleFocus, handleBlur, wrapperRef } = (0, useFocus_1.default)(isFocused || false);
65
+ // On initial load, check if we need to focus the actual text content
66
+ (0, react_1.useEffect)(() => {
67
+ if (isFocused) {
68
+ manager.view.dom.focus();
69
+ }
70
+ // TODO: May want to come back to this and see if there's a better solution
71
+ // We have to add a type button attribute to the delete buttons so they don't cause a submit by accident.
72
+ const tableDeleteButtons = document.querySelectorAll('.remirror-table-delete-inner-button');
73
+ tableDeleteButtons.forEach((button) => {
74
+ button.setAttribute('type', 'button');
75
+ });
76
+ }, []);
77
+ return (react_1.default.createElement("div", { ref: wrapperRef, onBlur: handleBlur, onFocusCapture: handleFocus, className: (0, clsx_1.default)('squiz-fte-scope', 'squiz-fte-scope__editor', !editable && 'squiz-fte-scope__editor--is-disabled', border && 'squiz-fte-scope__editor--bordered', className) },
78
+ react_1.default.createElement(react_2.Remirror, { manager: manager, initialContent: state, editable: editable, onChange: handleChange, placeholder: "Write something", label: "Text editor", attributes: attributes },
79
+ editable && react_1.default.createElement(EditorToolbar_1.Toolbar, { isVisible: isVisible, enableTableTool: enableTableTool }),
80
+ children && react_1.default.createElement("div", { className: "squiz-fte-scope__editor__children" }, children),
81
+ react_1.default.createElement(WrappedEditor, null),
82
+ enableTableTool && react_1.default.createElement(extension_react_tables_1.TableComponents, { enableTableCellMenu: false }),
83
+ editable && isVisible && react_1.default.createElement(EditorToolbar_1.FloatingToolbar, null))));
84
+ };
85
+ exports.default = Editor;
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { ResolveNodeToUrl } from '../types';
3
+ export type EditorContextOptions = {
4
+ matrix: {
5
+ matrixDomain: string;
6
+ };
7
+ resolveNodeToUrl: ResolveNodeToUrl;
8
+ };
9
+ export declare const defaultEditorContext: EditorContextOptions;
10
+ export declare const EditorContext: React.Context<EditorContextOptions>;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EditorContext = exports.defaultEditorContext = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ exports.defaultEditorContext = {
9
+ matrix: {
10
+ matrixDomain: '',
11
+ },
12
+ resolveNodeToUrl: () => {
13
+ throw new Error('resolveNodeToUrl has not been configured.');
14
+ },
15
+ };
16
+ exports.EditorContext = react_1.default.createContext(exports.defaultEditorContext);
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const FloatingToolbar: () => React.JSX.Element;
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.FloatingToolbar = void 0;
30
+ const react_1 = __importStar(require("react"));
31
+ const ItalicButton_1 = __importDefault(require("./Tools/Italic/ItalicButton"));
32
+ const UnderlineButton_1 = __importDefault(require("./Tools/Underline/UnderlineButton"));
33
+ const BoldButton_1 = __importDefault(require("./Tools/Bold/BoldButton"));
34
+ const hooks_1 = require("../hooks");
35
+ const RemoveLinkButton_1 = __importDefault(require("./Tools/Link/RemoveLinkButton"));
36
+ const LinkButton_1 = __importDefault(require("./Tools/Link/LinkButton"));
37
+ const react_2 = require("@remirror/react");
38
+ const react_components_1 = require("@remirror/react-components");
39
+ const createToolbarPositioner_1 = require("../utils/createToolbarPositioner");
40
+ const ImageButton_1 = __importDefault(require("./Tools/Image/ImageButton"));
41
+ const Extensions_1 = require("../Extensions/Extensions");
42
+ const ClearFormattingButton_1 = __importDefault(require("./Tools/ClearFormatting/ClearFormattingButton"));
43
+ const FloatingToolbar = () => {
44
+ const watchedMarks = [Extensions_1.MarkName.Link, Extensions_1.MarkName.AssetLink];
45
+ const extensionNames = (0, hooks_1.useExtensionNames)();
46
+ const positioner = (0, react_1.useMemo)(() => (0, createToolbarPositioner_1.createToolbarPositioner)({ types: watchedMarks }), []);
47
+ const { clearFormatting } = (0, react_2.useCommands)();
48
+ const active = (0, react_2.useActive)();
49
+ const { data: { marks }, } = (0, react_2.usePositioner)(positioner, []);
50
+ let buttons = [
51
+ extensionNames.bold && react_1.default.createElement(BoldButton_1.default, { key: "bold" }),
52
+ extensionNames.italic && react_1.default.createElement(ItalicButton_1.default, { key: "italic" }),
53
+ extensionNames.underline && react_1.default.createElement(UnderlineButton_1.default, { key: "underline" }),
54
+ ];
55
+ if (active.image() || active.assetImage() || active.DAMImage()) {
56
+ buttons = [react_1.default.createElement(ImageButton_1.default, { key: "add-image", inPopover: true })];
57
+ }
58
+ else if (marks?.[Extensions_1.MarkName.Link].isExclusivelyActive || marks?.[Extensions_1.MarkName.AssetLink].isExclusivelyActive) {
59
+ // if all of the selected text is a link show the options to update/remove the link instead of the regular
60
+ // formatting options.
61
+ buttons = [
62
+ react_1.default.createElement(LinkButton_1.default, { key: "update-link", inPopover: true }),
63
+ react_1.default.createElement(RemoveLinkButton_1.default, { key: "remove-link", inPopover: true }),
64
+ ];
65
+ }
66
+ else if (!marks?.[Extensions_1.MarkName.Link].isActive && !marks?.[Extensions_1.MarkName.AssetLink].isActive) {
67
+ // if none of the selected text is a link show the option to create a link.
68
+ buttons.push(react_1.default.createElement(react_components_1.VerticalDivider, { key: "link-divider" }), react_1.default.createElement(LinkButton_1.default, { key: "add-link", inPopover: true }));
69
+ }
70
+ // Clear formatting will always be the last button in the toolbar
71
+ if (extensionNames.clearFormatting && clearFormatting.enabled()) {
72
+ buttons.push(react_1.default.createElement(ClearFormattingButton_1.default, { key: "clearFormatting" }));
73
+ }
74
+ return (react_1.default.createElement(react_2.FloatingToolbar, { className: "squiz-fte-scope squiz-fte-scope__floating-popover", positioner: positioner, tabIndex: 0, role: 'toolbar' }, buttons));
75
+ };
76
+ exports.FloatingToolbar = FloatingToolbar;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ type ToolbarProps = {
3
+ isVisible: boolean;
4
+ enableTableTool: boolean;
5
+ };
6
+ export declare const Toolbar: ({ isVisible, enableTableTool }: ToolbarProps) => React.JSX.Element;
7
+ export {};
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Toolbar = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const react_components_1 = require("@remirror/react-components");
9
+ const clsx_1 = __importDefault(require("clsx"));
10
+ const ItalicButton_1 = __importDefault(require("./Tools/Italic/ItalicButton"));
11
+ const UnderlineButton_1 = __importDefault(require("./Tools/Underline/UnderlineButton"));
12
+ const BoldButton_1 = __importDefault(require("./Tools/Bold/BoldButton"));
13
+ const TextAlignButtons_1 = __importDefault(require("./Tools/TextAlign/TextAlignButtons"));
14
+ const UndoButton_1 = __importDefault(require("./Tools/Undo/UndoButton"));
15
+ const RedoButton_1 = __importDefault(require("./Tools/Redo/RedoButton"));
16
+ const TextTypeDropdown_1 = __importDefault(require("./Tools/TextType/TextTypeDropdown"));
17
+ const LinkButton_1 = __importDefault(require("./Tools/Link/LinkButton"));
18
+ const ImageButton_1 = __importDefault(require("./Tools/Image/ImageButton"));
19
+ const RemoveLinkButton_1 = __importDefault(require("./Tools/Link/RemoveLinkButton"));
20
+ const ClearFormattingButton_1 = __importDefault(require("./Tools/ClearFormatting/ClearFormattingButton"));
21
+ const ListButtons_1 = __importDefault(require("./Tools/Lists/ListButtons"));
22
+ const HorizontalLineButton_1 = __importDefault(require("./Tools/HorizontalLine/HorizontalLineButton"));
23
+ const TableButton_1 = __importDefault(require("./Tools/Table/TableButton"));
24
+ const ContentToolsDropdown_1 = __importDefault(require("./Tools/ContentTools/ContentToolsDropdown"));
25
+ const hooks_1 = require("../hooks");
26
+ const Toolbar = ({ isVisible, enableTableTool }) => {
27
+ const extensionNames = (0, hooks_1.useExtensionNames)();
28
+ return (react_1.default.createElement(react_components_1.Toolbar, { className: (0, clsx_1.default)('editor-toolbar header-toolbar', isVisible && 'show-toolbar'), role: "toolbar", tabIndex: 0 },
29
+ react_1.default.createElement("div", { className: "editor-toolbar__tools" },
30
+ extensionNames.history && (react_1.default.createElement(react_1.default.Fragment, null,
31
+ react_1.default.createElement(UndoButton_1.default, null),
32
+ react_1.default.createElement(RedoButton_1.default, null),
33
+ react_1.default.createElement(react_components_1.VerticalDivider, null))),
34
+ extensionNames.heading && extensionNames.paragraph && extensionNames.preformatted && react_1.default.createElement(TextTypeDropdown_1.default, null),
35
+ extensionNames.bold && react_1.default.createElement(BoldButton_1.default, null),
36
+ extensionNames.italic && react_1.default.createElement(ItalicButton_1.default, null),
37
+ extensionNames.underline && react_1.default.createElement(UnderlineButton_1.default, null),
38
+ extensionNames.nodeFormatting && react_1.default.createElement(TextAlignButtons_1.default, null),
39
+ extensionNames.listItem && react_1.default.createElement(ListButtons_1.default, null),
40
+ extensionNames.horizontalRule && react_1.default.createElement(HorizontalLineButton_1.default, null),
41
+ extensionNames.link && (react_1.default.createElement(react_1.default.Fragment, null,
42
+ react_1.default.createElement(LinkButton_1.default, null),
43
+ react_1.default.createElement(RemoveLinkButton_1.default, null))),
44
+ extensionNames.image && react_1.default.createElement(ImageButton_1.default, null),
45
+ extensionNames.clearFormatting && react_1.default.createElement(ClearFormattingButton_1.default, null),
46
+ enableTableTool && extensionNames.table && react_1.default.createElement(TableButton_1.default, null),
47
+ react_1.default.createElement(ContentToolsDropdown_1.default, null))));
48
+ };
49
+ exports.Toolbar = Toolbar;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const BoldButton: () => React.JSX.Element;
3
+ export default BoldButton;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const react_2 = require("@remirror/react");
8
+ const Button_1 = __importDefault(require("../../../ui/Button/Button"));
9
+ const FormatBoldRounded_1 = __importDefault(require("@mui/icons-material/FormatBoldRounded"));
10
+ const getShortcutSymbol_1 = require("../../../utils/getShortcutSymbol");
11
+ const BoldButton = () => {
12
+ const { toggleBold } = (0, react_2.useCommands)();
13
+ const chain = (0, react_2.useChainedCommands)();
14
+ const active = (0, react_2.useActive)();
15
+ const enabled = toggleBold.enabled();
16
+ const handleSelect = () => {
17
+ if (toggleBold.enabled()) {
18
+ chain.toggleBold().focus().run();
19
+ }
20
+ };
21
+ return (react_1.default.createElement(Button_1.default, { handleOnClick: handleSelect, isDisabled: !enabled, isActive: active.bold(), icon: react_1.default.createElement(FormatBoldRounded_1.default, null), label: `Bold (${(0, getShortcutSymbol_1.getShortcutSymbol)()}+B)` }));
22
+ };
23
+ exports.default = BoldButton;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const ClearFormattingButton: () => React.JSX.Element;
3
+ export default ClearFormattingButton;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ const react_1 = __importStar(require("react"));
30
+ const react_2 = require("@remirror/react");
31
+ const react_components_1 = require("@remirror/react-components");
32
+ const FormatClearRounded_1 = __importDefault(require("@mui/icons-material/FormatClearRounded"));
33
+ const Button_1 = __importDefault(require("../../../ui/Button/Button"));
34
+ const getShortcutSymbol_1 = require("../../../utils/getShortcutSymbol");
35
+ const ClearFormattingButton = () => {
36
+ const { clearFormatting } = (0, react_2.useCommands)();
37
+ const { selection } = (0, react_2.useEditorState)();
38
+ // Checks wether we have specific content selected or not
39
+ const contentSelected = !selection.empty;
40
+ const handleSelect = () => {
41
+ if (clearFormatting.enabled()) {
42
+ clearFormatting();
43
+ }
44
+ };
45
+ const handleShortcut = (0, react_1.useCallback)(() => {
46
+ handleSelect();
47
+ // Prevent other key handlers being run
48
+ return true;
49
+ }, []);
50
+ // When Ctrl+\ is pressed clear formatting, only registered in the toolbar button instance to avoid the key press
51
+ // being double handled.
52
+ (0, react_2.useKeymap)('Mod-\\', handleShortcut);
53
+ return (react_1.default.createElement(react_1.default.Fragment, null,
54
+ react_1.default.createElement(react_components_1.VerticalDivider, null),
55
+ react_1.default.createElement(Button_1.default, { handleOnClick: handleSelect, isDisabled: false, isActive: false, icon: react_1.default.createElement(FormatClearRounded_1.default, null), label: `${contentSelected ? 'Clear formatting from selection' : 'Clear all formatting'} (${(0, getShortcutSymbol_1.getShortcutSymbol)()}+\\)` })));
56
+ };
57
+ exports.default = ClearFormattingButton;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const ContentToolsDropdown: () => React.JSX.Element | null;
3
+ export default ContentToolsDropdown;
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const model_1 = require("@remirror/pm/model");
7
+ const react_1 = require("@remirror/react");
8
+ const dxp_ai_client_react_1 = require("@squiz/dxp-ai-client-react");
9
+ const sds_1 = require("@squiz/sds");
10
+ const prosemirror_model_1 = require("prosemirror-model");
11
+ const react_2 = __importDefault(require("react"));
12
+ const AiIcon_1 = require("../../../Icons/AiIcon");
13
+ const dxp_content_tools_modal_1 = require("@squiz/dxp-content-tools-modal");
14
+ const ContentToolsDropdown = () => {
15
+ const aiService = (0, dxp_ai_client_react_1.useAiService)();
16
+ const { contentTools } = aiService;
17
+ const { updateActiveDialog } = (0, sds_1.useDialogStore)();
18
+ const { isSelectionEmpty, getHTML } = (0, react_1.useHelpers)();
19
+ const { getState, view } = (0, react_1.useRemirrorContext)();
20
+ // No content tools to show, don't show dropdown at all
21
+ if (!contentTools || contentTools?.length === 0) {
22
+ return null;
23
+ }
24
+ const hasContent = getState().doc.textContent.length > 0;
25
+ const getSelectedRichText = () => {
26
+ const { from, to } = getState().selection;
27
+ const fragment = getState().doc.slice(from, to).content;
28
+ const div = document.createElement('div');
29
+ fragment.forEach((node) => {
30
+ div.appendChild(model_1.DOMSerializer.fromSchema(getState().schema).serializeNode(node));
31
+ });
32
+ return div.innerHTML;
33
+ };
34
+ const onInsertAfter = (content) => {
35
+ const schema = getState().schema;
36
+ const doc = getState().doc;
37
+ const tr = getState().tr;
38
+ // Parse the HTML string into a document fragment
39
+ const element = document.createElement('div');
40
+ element.innerHTML = content;
41
+ const newContent = prosemirror_model_1.DOMParser.fromSchema(schema).parse(element);
42
+ // Append the new content to the existing document
43
+ const newTransaction = tr.insert(doc.content.size, newContent.content);
44
+ view.dispatch(newTransaction);
45
+ };
46
+ const onReplace = (content) => {
47
+ const schema = getState().schema;
48
+ const { from, to, empty } = getState().selection;
49
+ const { tr } = getState();
50
+ // Parse the HTML string into a document fragment
51
+ const element = document.createElement('div');
52
+ element.innerHTML = content;
53
+ const newContent = prosemirror_model_1.DOMParser.fromSchema(schema).parse(element);
54
+ if (empty) {
55
+ // If there is no selection, replace the entire document content
56
+ const newTransaction = tr.replaceWith(0, getState().doc.content.size, newContent.content);
57
+ view.dispatch(newTransaction);
58
+ }
59
+ else {
60
+ // Replace the selected content with the new content
61
+ const newTransaction = tr.replaceWith(from, to, newContent.content);
62
+ view.dispatch(newTransaction);
63
+ }
64
+ };
65
+ const dropdownItems = contentTools?.map((item) => {
66
+ return {
67
+ items: [
68
+ {
69
+ action: () => {
70
+ // If we don't have a selection, use all text
71
+ const richContent = isSelectionEmpty() ? getHTML() : getSelectedRichText(); // NOTE: selected rich text may not work as expected
72
+ const dialogProps = {
73
+ classes: ['dxp-ctm-dialog'],
74
+ dialogContent: {
75
+ renderContent: (dialogContentProps) => {
76
+ return (react_2.default.createElement(dxp_content_tools_modal_1.ModalContent, { aiServiceOverride: aiService, content: richContent, contentTool: item, dialogContentProps: dialogContentProps, onInsertAfter: onInsertAfter, onReplace: onReplace }));
77
+ },
78
+ },
79
+ dialogSize: sds_1.DIALOG_SIZE_XL,
80
+ heading: `Rewrite content to ... ${item.name}`,
81
+ icon: dxp_content_tools_modal_1.ICON_DXP_AI,
82
+ footer: react_2.default.createElement(dxp_content_tools_modal_1.ModalFooter, { contentTool: item }),
83
+ stateHandler: sds_1.useDialogStore,
84
+ showFullScreenButton: true,
85
+ };
86
+ updateActiveDialog(dialogProps);
87
+ },
88
+ key: item.id,
89
+ label: react_2.default.createElement("span", null, item.name),
90
+ },
91
+ ],
92
+ key: item.id,
93
+ };
94
+ });
95
+ return (react_2.default.createElement(react_2.default.Fragment, null,
96
+ react_2.default.createElement(react_1.VerticalDivider, null),
97
+ hasContent && (react_2.default.createElement(sds_1.Dropdown, { title: "Content tools", "aria-label": "Content tools", buttonProps: {
98
+ format: sds_1.BUTTON_FORMAT_TRANSPARENT,
99
+ icon: AiIcon_1.ICON_AI,
100
+ theme: sds_1.BUTTON_THEME_DEFAULT,
101
+ }, className: "content-tools-dropdown", dropdownPosition: sds_1.DROPDOWN_POSITION_RIGHT, heading: 'Rewrite to...', sections: dropdownItems ?? [], disabled: !hasContent })),
102
+ !hasContent && react_2.default.createElement("div", { className: "content-tools-dropdown--disabled" }, AiIcon_1.ICON_AI)));
103
+ };
104
+ exports.default = ContentToolsDropdown;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const HorizontalLineButton: () => React.JSX.Element;
3
+ export default HorizontalLineButton;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const react_2 = require("@remirror/react");
8
+ const react_components_1 = require("@remirror/react-components");
9
+ const Button_1 = __importDefault(require("../../../ui/Button/Button"));
10
+ const HorizontalRuleRounded_1 = __importDefault(require("@mui/icons-material/HorizontalRuleRounded"));
11
+ const HorizontalLineButton = () => {
12
+ const { insertHorizontalRule } = (0, react_2.useCommands)();
13
+ const chain = (0, react_2.useChainedCommands)();
14
+ const active = (0, react_2.useActive)();
15
+ const enabled = insertHorizontalRule.enabled();
16
+ const handleSelect = () => {
17
+ if (insertHorizontalRule.enabled()) {
18
+ chain.insertHorizontalRule().focus().run();
19
+ }
20
+ };
21
+ return (react_1.default.createElement(react_1.default.Fragment, null,
22
+ react_1.default.createElement(Button_1.default, { handleOnClick: handleSelect, isDisabled: !enabled, isActive: active.italic(), icon: react_1.default.createElement(HorizontalRuleRounded_1.default, null), label: "Horizontal line" }),
23
+ react_1.default.createElement(react_components_1.VerticalDivider, null)));
24
+ };
25
+ exports.default = HorizontalLineButton;
@@ -0,0 +1,19 @@
1
+ import { ReactElement } from 'react';
2
+ import { SubmitHandler } from 'react-hook-form';
3
+ import { ImageAttributes } from '@remirror/extension-image/dist-types/image-extension';
4
+ import { NodeName } from '../../../../Extensions/Extensions';
5
+ import { AssetImageAttributes } from '../../../../Extensions/ImageExtension/AssetImageExtension';
6
+ import { DAMImageAttributes } from '../../../../Extensions/ImageExtension/DAMImageExtension';
7
+ import { DeepPartial } from '../../../../types';
8
+ export type ImageFormData = {
9
+ imageType: NodeName;
10
+ image: Pick<ImageAttributes, 'src' | 'alt' | 'width' | 'height'>;
11
+ resourceImage: AssetImageAttributes & DAMImageAttributes;
12
+ };
13
+ export type FormProps = {
14
+ data: DeepPartial<ImageFormData>;
15
+ onSubmit: SubmitHandler<ImageFormData>;
16
+ };
17
+ export type Dimensions = 'image.width' | 'image.height';
18
+ declare const ImageForm: ({ data, onSubmit }: FormProps) => ReactElement;
19
+ export default ImageForm;