@squiz/formatted-text-editor 2.3.0 → 2.5.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 (202) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/demo/{App.tsx → diff/App.tsx} +3 -2
  3. package/demo/{AppContext.tsx → diff/AppContext.tsx} +1 -2
  4. package/demo/diff/index.html +14 -0
  5. package/demo/{main.tsx → diff/main.tsx} +1 -1
  6. package/demo/index.html +47 -2
  7. package/demo/portals/Accordion.tsx +50 -0
  8. package/demo/portals/App.tsx +150 -0
  9. package/demo/portals/index.html +13 -0
  10. package/demo/portals/index.scss +8 -0
  11. package/demo/portals/index.tsx +12 -0
  12. package/demo/portals/preview.html +91 -0
  13. package/demo/portals/preview.tsx +10 -0
  14. package/lib/Editor/Editor.d.ts +21 -0
  15. package/lib/Editor/Editor.js +76 -0
  16. package/lib/Editor/EditorContext.d.ts +10 -0
  17. package/lib/Editor/EditorContext.js +16 -0
  18. package/lib/EditorToolbar/FloatingToolbar.d.ts +2 -0
  19. package/lib/EditorToolbar/FloatingToolbar.js +76 -0
  20. package/lib/EditorToolbar/Toolbar.d.ts +8 -0
  21. package/lib/EditorToolbar/Toolbar.js +51 -0
  22. package/lib/EditorToolbar/Tools/Bold/BoldButton.d.ts +3 -0
  23. package/lib/EditorToolbar/Tools/Bold/BoldButton.js +23 -0
  24. package/lib/EditorToolbar/Tools/ClearFormatting/ClearFormattingButton.d.ts +3 -0
  25. package/lib/EditorToolbar/Tools/ClearFormatting/ClearFormattingButton.js +57 -0
  26. package/lib/EditorToolbar/Tools/ContentTools/ContentToolsDropdown.d.ts +3 -0
  27. package/lib/EditorToolbar/Tools/ContentTools/ContentToolsDropdown.js +104 -0
  28. package/lib/EditorToolbar/Tools/HorizontalLine/HorizontalLineButton.d.ts +3 -0
  29. package/lib/EditorToolbar/Tools/HorizontalLine/HorizontalLineButton.js +25 -0
  30. package/lib/EditorToolbar/Tools/Image/Form/ImageForm.d.ts +19 -0
  31. package/lib/EditorToolbar/Tools/Image/Form/ImageForm.js +183 -0
  32. package/lib/EditorToolbar/Tools/Image/ImageButton.d.ts +6 -0
  33. package/lib/EditorToolbar/Tools/Image/ImageButton.js +79 -0
  34. package/lib/EditorToolbar/Tools/Image/ImageModal.d.ts +9 -0
  35. package/lib/EditorToolbar/Tools/Image/ImageModal.js +26 -0
  36. package/lib/EditorToolbar/Tools/Italic/ItalicButton.d.ts +3 -0
  37. package/lib/EditorToolbar/Tools/Italic/ItalicButton.js +23 -0
  38. package/lib/EditorToolbar/Tools/Link/Form/LinkForm.d.ts +19 -0
  39. package/lib/EditorToolbar/Tools/Link/Form/LinkForm.js +63 -0
  40. package/lib/EditorToolbar/Tools/Link/LinkButton.d.ts +6 -0
  41. package/lib/EditorToolbar/Tools/Link/LinkButton.js +71 -0
  42. package/lib/EditorToolbar/Tools/Link/LinkModal.d.ts +9 -0
  43. package/lib/EditorToolbar/Tools/Link/LinkModal.js +27 -0
  44. package/lib/EditorToolbar/Tools/Link/RemoveLinkButton.d.ts +4 -0
  45. package/lib/EditorToolbar/Tools/Link/RemoveLinkButton.js +54 -0
  46. package/lib/EditorToolbar/Tools/Lists/ListButtons.d.ts +3 -0
  47. package/lib/EditorToolbar/Tools/Lists/ListButtons.js +14 -0
  48. package/lib/EditorToolbar/Tools/Lists/OrderedList/OrderedListButton.d.ts +3 -0
  49. package/lib/EditorToolbar/Tools/Lists/OrderedList/OrderedListButton.js +22 -0
  50. package/lib/EditorToolbar/Tools/Lists/UnorderedList/UnorderedListButton.d.ts +3 -0
  51. package/lib/EditorToolbar/Tools/Lists/UnorderedList/UnorderedListButton.js +22 -0
  52. package/lib/EditorToolbar/Tools/Redo/RedoButton.d.ts +3 -0
  53. package/lib/EditorToolbar/Tools/Redo/RedoButton.js +22 -0
  54. package/lib/EditorToolbar/Tools/Table/TableButton.d.ts +3 -0
  55. package/lib/EditorToolbar/Tools/Table/TableButton.js +20 -0
  56. package/lib/EditorToolbar/Tools/TextAlign/CenterAlign/CenterAlignButton.d.ts +3 -0
  57. package/lib/EditorToolbar/Tools/TextAlign/CenterAlign/CenterAlignButton.js +22 -0
  58. package/lib/EditorToolbar/Tools/TextAlign/JustifyAlign/JustifyAlignButton.d.ts +3 -0
  59. package/lib/EditorToolbar/Tools/TextAlign/JustifyAlign/JustifyAlignButton.js +22 -0
  60. package/lib/EditorToolbar/Tools/TextAlign/LeftAlign/LeftAlignButton.d.ts +3 -0
  61. package/lib/EditorToolbar/Tools/TextAlign/LeftAlign/LeftAlignButton.js +22 -0
  62. package/lib/EditorToolbar/Tools/TextAlign/RightAlign/RightAlignButton.d.ts +3 -0
  63. package/lib/EditorToolbar/Tools/TextAlign/RightAlign/RightAlignButton.js +22 -0
  64. package/lib/EditorToolbar/Tools/TextAlign/TextAlignButtons.d.ts +3 -0
  65. package/lib/EditorToolbar/Tools/TextAlign/TextAlignButtons.js +21 -0
  66. package/lib/EditorToolbar/Tools/TextType/CodeBlock/CodeBlockButton.d.ts +3 -0
  67. package/lib/EditorToolbar/Tools/TextType/CodeBlock/CodeBlockButton.js +22 -0
  68. package/lib/EditorToolbar/Tools/TextType/Heading/HeadingButton.d.ts +6 -0
  69. package/lib/EditorToolbar/Tools/TextType/Heading/HeadingButton.js +37 -0
  70. package/lib/EditorToolbar/Tools/TextType/Paragraph/ParagraphButton.d.ts +3 -0
  71. package/lib/EditorToolbar/Tools/TextType/Paragraph/ParagraphButton.js +21 -0
  72. package/lib/EditorToolbar/Tools/TextType/Preformatted/PreformattedButton.d.ts +3 -0
  73. package/lib/EditorToolbar/Tools/TextType/Preformatted/PreformattedButton.js +22 -0
  74. package/lib/EditorToolbar/Tools/TextType/TextTypeDropdown.d.ts +3 -0
  75. package/lib/EditorToolbar/Tools/TextType/TextTypeDropdown.js +46 -0
  76. package/lib/EditorToolbar/Tools/Underline/UnderlineButton.d.ts +3 -0
  77. package/lib/EditorToolbar/Tools/Underline/UnderlineButton.js +23 -0
  78. package/lib/EditorToolbar/Tools/Undo/UndoButton.d.ts +3 -0
  79. package/lib/EditorToolbar/Tools/Undo/UndoButton.js +22 -0
  80. package/lib/EditorToolbar/index.d.ts +2 -0
  81. package/lib/EditorToolbar/index.js +18 -0
  82. package/lib/Extensions/ClearFormattingExtension/ClearFormattingExtension.d.ts +5 -0
  83. package/lib/Extensions/ClearFormattingExtension/ClearFormattingExtension.js +63 -0
  84. package/lib/Extensions/CodeBlockExtension/CodeBlockExtension.d.ts +15 -0
  85. package/lib/Extensions/CodeBlockExtension/CodeBlockExtension.js +96 -0
  86. package/lib/Extensions/CommandsExtension/CommandsExtension.d.ts +20 -0
  87. package/lib/Extensions/CommandsExtension/CommandsExtension.js +52 -0
  88. package/lib/Extensions/Extensions.d.ts +18 -0
  89. package/lib/Extensions/Extensions.js +76 -0
  90. package/lib/Extensions/FetchUrlExtension/FetchUrlExtension.d.ts +12 -0
  91. package/lib/Extensions/FetchUrlExtension/FetchUrlExtension.js +69 -0
  92. package/lib/Extensions/ImageExtension/AssetImageExtension.d.ts +17 -0
  93. package/lib/Extensions/ImageExtension/AssetImageExtension.js +91 -0
  94. package/lib/Extensions/ImageExtension/DAMImageExtension.d.ts +17 -0
  95. package/lib/Extensions/ImageExtension/DAMImageExtension.js +97 -0
  96. package/lib/Extensions/ImageExtension/ImageExtension.d.ts +7 -0
  97. package/lib/Extensions/ImageExtension/ImageExtension.js +18 -0
  98. package/lib/Extensions/LinkExtension/AssetLinkExtension.d.ts +27 -0
  99. package/lib/Extensions/LinkExtension/AssetLinkExtension.js +101 -0
  100. package/lib/Extensions/LinkExtension/LinkExtension.d.ts +23 -0
  101. package/lib/Extensions/LinkExtension/LinkExtension.js +87 -0
  102. package/lib/Extensions/LinkExtension/common.d.ts +7 -0
  103. package/lib/Extensions/LinkExtension/common.js +14 -0
  104. package/lib/Extensions/PreformattedExtension/PreformattedExtension.d.ts +15 -0
  105. package/lib/Extensions/PreformattedExtension/PreformattedExtension.js +83 -0
  106. package/lib/Extensions/UnsuportedExtension/UnsupportedNodeExtension.d.ts +10 -0
  107. package/lib/Extensions/UnsuportedExtension/UnsupportedNodeExtension.js +76 -0
  108. package/lib/Icons/AiIcon.d.ts +2 -0
  109. package/lib/Icons/AiIcon.js +60 -0
  110. package/lib/hooks/index.d.ts +3 -0
  111. package/lib/hooks/index.js +19 -0
  112. package/lib/hooks/useExpandedSelection/useExpandedSelection.d.ts +23 -0
  113. package/lib/hooks/useExpandedSelection/useExpandedSelection.js +37 -0
  114. package/lib/hooks/useExtensionNames/useExtensionNames.d.ts +1 -0
  115. package/lib/hooks/useExtensionNames/useExtensionNames.js +16 -0
  116. package/lib/hooks/useFocus/useFocus.d.ts +6 -0
  117. package/lib/hooks/useFocus/useFocus.js +57 -0
  118. package/lib/index.css +5894 -0
  119. package/lib/index.d.ts +8 -0
  120. package/lib/index.js +16 -0
  121. package/lib/types.d.ts +7 -0
  122. package/lib/types.js +2 -0
  123. package/lib/ui/Button/Button.d.ts +12 -0
  124. package/lib/ui/Button/Button.js +13 -0
  125. package/lib/ui/CollapseBox/CollapseBox.d.ts +7 -0
  126. package/lib/ui/CollapseBox/CollapseBox.js +48 -0
  127. package/lib/ui/EditorInput/EditorInput.d.ts +3 -0
  128. package/lib/ui/EditorInput/EditorInput.js +49 -0
  129. package/lib/ui/EditorInput/EditorInput.props.d.ts +4 -0
  130. package/lib/ui/EditorInput/EditorInput.props.js +2 -0
  131. package/lib/ui/Fields/Checkbox/Checkbox.d.ts +9 -0
  132. package/lib/ui/Fields/Checkbox/Checkbox.js +47 -0
  133. package/lib/ui/Fields/Input/Input.d.ts +3 -0
  134. package/lib/ui/Fields/Input/Input.js +33 -0
  135. package/lib/ui/Fields/InputContainer/InputContainer.d.ts +9 -0
  136. package/lib/ui/Fields/InputContainer/InputContainer.js +16 -0
  137. package/lib/ui/Fields/MatrixAsset/MatrixAsset.d.ts +19 -0
  138. package/lib/ui/Fields/MatrixAsset/MatrixAsset.js +30 -0
  139. package/lib/ui/Fields/ResourceBrowserSelector/ResourceBrowserSelector.d.ts +28 -0
  140. package/lib/ui/Fields/ResourceBrowserSelector/ResourceBrowserSelector.js +88 -0
  141. package/lib/ui/Modal/FormModal.d.ts +5 -0
  142. package/lib/ui/Modal/FormModal.js +39 -0
  143. package/lib/ui/Modal/Modal.d.ts +11 -0
  144. package/lib/ui/Modal/Modal.js +79 -0
  145. package/lib/ui/Tabs/Tabs.d.ts +11 -0
  146. package/lib/ui/Tabs/Tabs.js +46 -0
  147. package/lib/ui/ToolbarDropdown/ToolbarDropdown.d.ts +7 -0
  148. package/lib/ui/ToolbarDropdown/ToolbarDropdown.js +48 -0
  149. package/lib/ui/ToolbarDropdownButton/ToolbarDropdownButton.d.ts +11 -0
  150. package/lib/ui/ToolbarDropdownButton/ToolbarDropdownButton.js +15 -0
  151. package/lib/utils/converters/htmlToSquizNode/htmlToSquizNode.d.ts +5 -0
  152. package/lib/utils/converters/htmlToSquizNode/htmlToSquizNode.js +23 -0
  153. package/lib/utils/converters/htmlToSquizNode/htmlToSquizNode.props.d.ts +3 -0
  154. package/lib/utils/converters/htmlToSquizNode/htmlToSquizNode.props.js +2 -0
  155. package/lib/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.d.ts +11 -0
  156. package/lib/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.js +235 -0
  157. package/lib/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.d.ts +9 -0
  158. package/lib/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.js +208 -0
  159. package/lib/utils/createToolbarPositioner.d.ts +18 -0
  160. package/lib/utils/createToolbarPositioner.js +96 -0
  161. package/lib/utils/getCursorRect.d.ts +2 -0
  162. package/lib/utils/getCursorRect.js +7 -0
  163. package/lib/utils/getMarkNamesByGroup.d.ts +2 -0
  164. package/lib/utils/getMarkNamesByGroup.js +9 -0
  165. package/lib/utils/getNodeNamesByGroup.d.ts +2 -0
  166. package/lib/utils/getNodeNamesByGroup.js +9 -0
  167. package/lib/utils/getShortcutSymbol.d.ts +1 -0
  168. package/lib/utils/getShortcutSymbol.js +8 -0
  169. package/lib/utils/undefinedIfEmpty.d.ts +1 -0
  170. package/lib/utils/undefinedIfEmpty.js +7 -0
  171. package/lib/utils/validation.d.ts +3 -0
  172. package/lib/utils/validation.js +16 -0
  173. package/package.json +1 -1
  174. package/src/Editor/Editor.spec.tsx +35 -10
  175. package/src/Editor/Editor.tsx +48 -44
  176. package/src/Editor/_editor.scss +4 -0
  177. package/src/EditorToolbar/Toolbar.tsx +8 -4
  178. package/src/EditorToolbar/Tools/Image/Form/ImageForm.tsx +0 -3
  179. package/src/EditorToolbar/Tools/TextType/CodeBlock/CodeBlockButton.tsx +3 -3
  180. package/src/EditorToolbar/_toolbar.scss +3 -2
  181. package/src/Extensions/CodeBlockExtension/CodeBlockExtension.props.ts +3 -0
  182. package/src/Extensions/CodeBlockExtension/CodeBlockExtension.spec.ts +59 -0
  183. package/src/Extensions/CodeBlockExtension/CodeBlockExtension.ts +82 -7
  184. package/src/Extensions/Extensions.ts +4 -4
  185. package/src/Extensions/PreformattedExtension/PreformattedExtension.ts +15 -3
  186. package/src/hooks/index.ts +3 -2
  187. package/src/hooks/useFocus/useFocus.spec.tsx +48 -0
  188. package/src/hooks/useFocus/useFocus.ts +71 -0
  189. package/src/ui/EditorInput/EditorInput.props.ts +5 -0
  190. package/src/ui/EditorInput/EditorInput.spec.tsx +38 -0
  191. package/src/ui/EditorInput/EditorInput.tsx +30 -0
  192. package/src/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.spec.ts +1 -3
  193. package/src/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.ts +0 -4
  194. package/src/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.spec.ts +1 -4
  195. package/src/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.ts +0 -5
  196. package/src/hooks/useFocus.ts +0 -61
  197. /package/demo/{index.scss → diff/index.scss} +0 -0
  198. /package/demo/{resources.json → diff/resources.json} +0 -0
  199. /package/demo/{sources.json → diff/sources.json} +0 -0
  200. /package/demo/{vite-env.d.ts → diff/vite-env.d.ts} +0 -0
  201. /package/src/hooks/{useExpandedSelection.ts → useExpandedSelection/useExpandedSelection.ts} +0 -0
  202. /package/src/hooks/{useExtensionNames.ts → useExtensionNames/useExtensionNames.ts} +0 -0
@@ -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,8 @@
1
+ import React from 'react';
2
+ type ToolbarProps = {
3
+ isVisible: boolean;
4
+ enableTableTool: boolean;
5
+ container?: Element | null;
6
+ };
7
+ export declare const Toolbar: ({ isVisible, enableTableTool, container }: ToolbarProps) => React.JSX.Element;
8
+ export {};
@@ -0,0 +1,51 @@
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 react_dom_1 = require("react-dom");
27
+ const Toolbar = ({ isVisible, enableTableTool, container }) => {
28
+ const extensionNames = (0, hooks_1.useExtensionNames)();
29
+ const toolbar = (react_1.default.createElement(react_components_1.Toolbar, { className: (0, clsx_1.default)('editor-toolbar header-toolbar', isVisible && 'show-toolbar', container && 'fte-portal-toolbar'), role: "toolbar", tabIndex: 0 },
30
+ react_1.default.createElement("div", { className: "editor-toolbar__tools" },
31
+ extensionNames.history && (react_1.default.createElement(react_1.default.Fragment, null,
32
+ react_1.default.createElement(UndoButton_1.default, null),
33
+ react_1.default.createElement(RedoButton_1.default, null),
34
+ react_1.default.createElement(react_components_1.VerticalDivider, null))),
35
+ extensionNames.heading && extensionNames.paragraph && extensionNames.preformatted && react_1.default.createElement(TextTypeDropdown_1.default, null),
36
+ extensionNames.bold && react_1.default.createElement(BoldButton_1.default, null),
37
+ extensionNames.italic && react_1.default.createElement(ItalicButton_1.default, null),
38
+ extensionNames.underline && react_1.default.createElement(UnderlineButton_1.default, null),
39
+ extensionNames.nodeFormatting && react_1.default.createElement(TextAlignButtons_1.default, null),
40
+ extensionNames.listItem && react_1.default.createElement(ListButtons_1.default, null),
41
+ extensionNames.horizontalRule && react_1.default.createElement(HorizontalLineButton_1.default, null),
42
+ extensionNames.link && (react_1.default.createElement(react_1.default.Fragment, null,
43
+ react_1.default.createElement(LinkButton_1.default, null),
44
+ react_1.default.createElement(RemoveLinkButton_1.default, null))),
45
+ extensionNames.image && react_1.default.createElement(ImageButton_1.default, null),
46
+ extensionNames.clearFormatting && react_1.default.createElement(ClearFormattingButton_1.default, null),
47
+ enableTableTool && extensionNames.table && react_1.default.createElement(TableButton_1.default, null),
48
+ react_1.default.createElement(ContentToolsDropdown_1.default, null))));
49
+ return container ? (0, react_dom_1.createPortal)(toolbar, container) : toolbar;
50
+ };
51
+ 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;
@@ -0,0 +1,183 @@
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_hook_form_1 = require("react-hook-form");
31
+ const react_image_size_1 = require("react-image-size");
32
+ const clsx_1 = __importDefault(require("clsx"));
33
+ const Input_1 = require("../../../../ui/Fields/Input/Input");
34
+ const Button_1 = __importDefault(require("../../../../ui/Button/Button"));
35
+ const LinkOff_1 = __importDefault(require("@mui/icons-material/LinkOff"));
36
+ const InsertLinkRounded_1 = __importDefault(require("@mui/icons-material/InsertLinkRounded"));
37
+ const Extensions_1 = require("../../../../Extensions/Extensions");
38
+ const validation_1 = require("../../../../utils/validation");
39
+ const Tabs_1 = require("../../../../ui/Tabs/Tabs");
40
+ const ResourceBrowserSelector_1 = require("../../../../ui/Fields/ResourceBrowserSelector/ResourceBrowserSelector");
41
+ var ViewTypes;
42
+ (function (ViewTypes) {
43
+ ViewTypes["Resource"] = "Resource";
44
+ ViewTypes["URL"] = "URL";
45
+ })(ViewTypes || (ViewTypes = {}));
46
+ const imageTypeOptions = {
47
+ [ViewTypes.Resource]: { label: 'From source' },
48
+ [ViewTypes.URL]: { label: 'From URL' },
49
+ };
50
+ const ImageForm = ({ data, onSubmit }) => {
51
+ const { control, register, handleSubmit, setValue, watch, formState: { errors }, } = (0, react_hook_form_1.useForm)({
52
+ defaultValues: data,
53
+ });
54
+ const imageType = watch('imageType');
55
+ const [viewType, setViewType] = (0, react_1.useState)(ViewTypes.Resource);
56
+ const [aspectRatioFromWidth, setAspectRatioFromWidth] = (0, react_1.useState)(9 / 16);
57
+ const [aspectRatioFromHeight, setAspectRatioFromHeight] = (0, react_1.useState)(16 / 9);
58
+ const [aspectRatioLocked, setAspectRatioLocked] = (0, react_1.useState)(true);
59
+ const setDimensionsFromURL = async (e) => {
60
+ try {
61
+ const { width, height } = await (0, react_image_size_1.getImageSize)(e.target.value);
62
+ setValue('image.width', width);
63
+ setValue('image.height', height);
64
+ setAspectRatioFromWidth(height / width);
65
+ setAspectRatioFromHeight(width / height);
66
+ }
67
+ catch (error) {
68
+ // swallow the error for fetching the image size, will occur if the URL does not point to an image.
69
+ // will be handled by validation when attempting to add the image.
70
+ }
71
+ };
72
+ const validateIsNotImage = async (src) => {
73
+ try {
74
+ await (0, react_image_size_1.getImageSize)(src);
75
+ return false;
76
+ }
77
+ catch (error) {
78
+ return true;
79
+ }
80
+ };
81
+ const calculateDimensions = (event) => {
82
+ if (aspectRatioLocked) {
83
+ const currentTarget = event?.target;
84
+ const type = currentTarget.name;
85
+ const currentValue = currentTarget.value;
86
+ const otherValue = type === 'image.width' ? 'image.height' : 'image.width';
87
+ const aspectRatio = type === 'image.width' ? aspectRatioFromWidth : aspectRatioFromHeight;
88
+ const newValue = Math.round(aspectRatio * Number(currentValue) * 100) / 100;
89
+ setValue(otherValue, newValue);
90
+ }
91
+ };
92
+ const toggleAspectRatio = () => {
93
+ setAspectRatioLocked(!aspectRatioLocked);
94
+ };
95
+ (0, react_1.useEffect)(() => {
96
+ if (imageType === Extensions_1.NodeName.Image) {
97
+ setViewType(ViewTypes.URL);
98
+ }
99
+ else {
100
+ setViewType(ViewTypes.Resource);
101
+ }
102
+ }, [imageType, setViewType]);
103
+ const handleChangeViewType = (0, react_1.useCallback)((value) => {
104
+ setViewType(value);
105
+ // If its the URL field type we know what the imageType should be
106
+ if (value === ViewTypes.URL) {
107
+ setValue('imageType', Extensions_1.NodeName.Image);
108
+ }
109
+ else {
110
+ // Need a value here and this is the assumed default elsewhere
111
+ // Will be set again later once Resource Browser returns a resource value
112
+ setValue('imageType', Extensions_1.NodeName.AssetImage);
113
+ }
114
+ }, [setViewType, setValue]);
115
+ return (react_1.default.createElement("form", { className: "squiz-fte-form", onSubmit: handleSubmit(onSubmit) },
116
+ react_1.default.createElement("div", { className: "squiz-fte-form-group mb-4" },
117
+ react_1.default.createElement(Tabs_1.Tabs, { value: imageType === Extensions_1.NodeName.Image ? ViewTypes.URL : ViewTypes.Resource, options: imageTypeOptions, onChange: handleChangeViewType })),
118
+ viewType === ViewTypes.URL && (react_1.default.createElement(react_1.default.Fragment, null,
119
+ react_1.default.createElement("div", { className: "squiz-fte-form-group mb-2" },
120
+ react_1.default.createElement(Input_1.Input, { label: "Source", required: true, error: errors?.image?.src?.message, ...register('image.src', {
121
+ onChange: setDimensionsFromURL,
122
+ required: 'Source is required',
123
+ validate: {
124
+ isValidImage: async (value) => {
125
+ if (value && validation_1.regexDataURI.test(value)) {
126
+ return 'Must not be a data URI';
127
+ }
128
+ if (value && (await validateIsNotImage(value))) {
129
+ return 'Must be a valid image URL';
130
+ }
131
+ },
132
+ noEmptySpaces: validation_1.noEmptySpacesValidation,
133
+ },
134
+ }) })),
135
+ react_1.default.createElement("div", { className: "flex flex-row" },
136
+ react_1.default.createElement("div", { className: "squiz-fte-form-group mb-2" },
137
+ react_1.default.createElement(Input_1.Input, { label: "Width", type: "number", required: true, error: errors?.image?.width?.message, ...register('image.width', {
138
+ onChange: calculateDimensions,
139
+ required: 'Width is required',
140
+ validate: {
141
+ isValidWidth: (value) => {
142
+ if (value && !(value > 0)) {
143
+ return 'Must be higher than 0';
144
+ }
145
+ },
146
+ },
147
+ }) })),
148
+ react_1.default.createElement("div", { className: "flex mx-1 mb-2" },
149
+ react_1.default.createElement(Button_1.default, { handleOnClick: toggleAspectRatio, isActive: false, icon: aspectRatioLocked ? react_1.default.createElement(InsertLinkRounded_1.default, null) : react_1.default.createElement(LinkOff_1.default, null), label: "Constrain properties", isDisabled: false, className: (0, clsx_1.default)('my-auto', !errors?.image?.height && !errors?.image?.width && 'mb-0') })),
150
+ react_1.default.createElement("div", { className: "squiz-fte-form-group mb-2" },
151
+ react_1.default.createElement(Input_1.Input, { label: "Height", type: "number", required: true, error: errors?.image?.height?.message, ...register('image.height', {
152
+ onChange: calculateDimensions,
153
+ required: 'Height is required',
154
+ validate: {
155
+ isValidHeight: (value) => {
156
+ if (value && !(value > 0)) {
157
+ return 'Must be higher than 0';
158
+ }
159
+ },
160
+ },
161
+ }) }))),
162
+ react_1.default.createElement("div", { className: "squiz-fte-form-group mb-2" },
163
+ react_1.default.createElement(Input_1.Input, { label: "Alternative description", error: errors?.image?.alt?.message, ...register('image.alt') })))),
164
+ viewType === ViewTypes.Resource && (react_1.default.createElement("div", { className: "squiz-fte-form-group mb-2" },
165
+ react_1.default.createElement(react_hook_form_1.Controller, { control: control, name: "resourceImage", rules: {
166
+ validate: (value) => {
167
+ const matrixValidation = (0, validation_1.hasProperties)('An image must be selected', [
168
+ 'matrixIdentifier',
169
+ 'matrixAssetId',
170
+ ])(value);
171
+ const damValidation = (0, validation_1.hasProperties)('An image must be selected', [
172
+ 'damObjectId',
173
+ 'damSystemIdentifier',
174
+ ])(value);
175
+ // One of the two needs to validate
176
+ return matrixValidation && damValidation;
177
+ },
178
+ }, render: ({ field: { onChange, value }, fieldState: { error } }) => (react_1.default.createElement(ResourceBrowserSelector_1.ResourceBrowserSelector, { modalTitle: "Insert image", allowedTypes: ['image'], value: value, onChange: (value) => {
179
+ setValue('imageType', value.target.value.nodeType);
180
+ onChange(value);
181
+ }, error: error?.message })) })))));
182
+ };
183
+ exports.default = ImageForm;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ type ImageButtonProps = {
3
+ inPopover?: boolean;
4
+ };
5
+ declare const ImageButton: ({ inPopover }: ImageButtonProps) => React.JSX.Element;
6
+ export default ImageButton;