@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.
- package/CHANGELOG.md +12 -0
- package/demo/{App.tsx → diff/App.tsx} +3 -2
- package/demo/{AppContext.tsx → diff/AppContext.tsx} +1 -2
- package/demo/diff/index.html +14 -0
- package/demo/{main.tsx → diff/main.tsx} +1 -1
- package/demo/index.html +47 -2
- package/demo/portals/Accordion.tsx +50 -0
- package/demo/portals/App.tsx +150 -0
- package/demo/portals/index.html +13 -0
- package/demo/portals/index.scss +8 -0
- package/demo/portals/index.tsx +12 -0
- package/demo/portals/preview.html +91 -0
- package/demo/portals/preview.tsx +10 -0
- package/lib/Editor/Editor.d.ts +21 -0
- package/lib/Editor/Editor.js +76 -0
- package/lib/Editor/EditorContext.d.ts +10 -0
- package/lib/Editor/EditorContext.js +16 -0
- package/lib/EditorToolbar/FloatingToolbar.d.ts +2 -0
- package/lib/EditorToolbar/FloatingToolbar.js +76 -0
- package/lib/EditorToolbar/Toolbar.d.ts +8 -0
- package/lib/EditorToolbar/Toolbar.js +51 -0
- package/lib/EditorToolbar/Tools/Bold/BoldButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Bold/BoldButton.js +23 -0
- package/lib/EditorToolbar/Tools/ClearFormatting/ClearFormattingButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/ClearFormatting/ClearFormattingButton.js +57 -0
- package/lib/EditorToolbar/Tools/ContentTools/ContentToolsDropdown.d.ts +3 -0
- package/lib/EditorToolbar/Tools/ContentTools/ContentToolsDropdown.js +104 -0
- package/lib/EditorToolbar/Tools/HorizontalLine/HorizontalLineButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/HorizontalLine/HorizontalLineButton.js +25 -0
- package/lib/EditorToolbar/Tools/Image/Form/ImageForm.d.ts +19 -0
- package/lib/EditorToolbar/Tools/Image/Form/ImageForm.js +183 -0
- package/lib/EditorToolbar/Tools/Image/ImageButton.d.ts +6 -0
- package/lib/EditorToolbar/Tools/Image/ImageButton.js +79 -0
- package/lib/EditorToolbar/Tools/Image/ImageModal.d.ts +9 -0
- package/lib/EditorToolbar/Tools/Image/ImageModal.js +26 -0
- package/lib/EditorToolbar/Tools/Italic/ItalicButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Italic/ItalicButton.js +23 -0
- package/lib/EditorToolbar/Tools/Link/Form/LinkForm.d.ts +19 -0
- package/lib/EditorToolbar/Tools/Link/Form/LinkForm.js +63 -0
- package/lib/EditorToolbar/Tools/Link/LinkButton.d.ts +6 -0
- package/lib/EditorToolbar/Tools/Link/LinkButton.js +71 -0
- package/lib/EditorToolbar/Tools/Link/LinkModal.d.ts +9 -0
- package/lib/EditorToolbar/Tools/Link/LinkModal.js +27 -0
- package/lib/EditorToolbar/Tools/Link/RemoveLinkButton.d.ts +4 -0
- package/lib/EditorToolbar/Tools/Link/RemoveLinkButton.js +54 -0
- package/lib/EditorToolbar/Tools/Lists/ListButtons.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Lists/ListButtons.js +14 -0
- package/lib/EditorToolbar/Tools/Lists/OrderedList/OrderedListButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Lists/OrderedList/OrderedListButton.js +22 -0
- package/lib/EditorToolbar/Tools/Lists/UnorderedList/UnorderedListButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Lists/UnorderedList/UnorderedListButton.js +22 -0
- package/lib/EditorToolbar/Tools/Redo/RedoButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Redo/RedoButton.js +22 -0
- package/lib/EditorToolbar/Tools/Table/TableButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Table/TableButton.js +20 -0
- package/lib/EditorToolbar/Tools/TextAlign/CenterAlign/CenterAlignButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextAlign/CenterAlign/CenterAlignButton.js +22 -0
- package/lib/EditorToolbar/Tools/TextAlign/JustifyAlign/JustifyAlignButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextAlign/JustifyAlign/JustifyAlignButton.js +22 -0
- package/lib/EditorToolbar/Tools/TextAlign/LeftAlign/LeftAlignButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextAlign/LeftAlign/LeftAlignButton.js +22 -0
- package/lib/EditorToolbar/Tools/TextAlign/RightAlign/RightAlignButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextAlign/RightAlign/RightAlignButton.js +22 -0
- package/lib/EditorToolbar/Tools/TextAlign/TextAlignButtons.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextAlign/TextAlignButtons.js +21 -0
- package/lib/EditorToolbar/Tools/TextType/CodeBlock/CodeBlockButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextType/CodeBlock/CodeBlockButton.js +22 -0
- package/lib/EditorToolbar/Tools/TextType/Heading/HeadingButton.d.ts +6 -0
- package/lib/EditorToolbar/Tools/TextType/Heading/HeadingButton.js +37 -0
- package/lib/EditorToolbar/Tools/TextType/Paragraph/ParagraphButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextType/Paragraph/ParagraphButton.js +21 -0
- package/lib/EditorToolbar/Tools/TextType/Preformatted/PreformattedButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextType/Preformatted/PreformattedButton.js +22 -0
- package/lib/EditorToolbar/Tools/TextType/TextTypeDropdown.d.ts +3 -0
- package/lib/EditorToolbar/Tools/TextType/TextTypeDropdown.js +46 -0
- package/lib/EditorToolbar/Tools/Underline/UnderlineButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Underline/UnderlineButton.js +23 -0
- package/lib/EditorToolbar/Tools/Undo/UndoButton.d.ts +3 -0
- package/lib/EditorToolbar/Tools/Undo/UndoButton.js +22 -0
- package/lib/EditorToolbar/index.d.ts +2 -0
- package/lib/EditorToolbar/index.js +18 -0
- package/lib/Extensions/ClearFormattingExtension/ClearFormattingExtension.d.ts +5 -0
- package/lib/Extensions/ClearFormattingExtension/ClearFormattingExtension.js +63 -0
- package/lib/Extensions/CodeBlockExtension/CodeBlockExtension.d.ts +15 -0
- package/lib/Extensions/CodeBlockExtension/CodeBlockExtension.js +96 -0
- package/lib/Extensions/CommandsExtension/CommandsExtension.d.ts +20 -0
- package/lib/Extensions/CommandsExtension/CommandsExtension.js +52 -0
- package/lib/Extensions/Extensions.d.ts +18 -0
- package/lib/Extensions/Extensions.js +76 -0
- package/lib/Extensions/FetchUrlExtension/FetchUrlExtension.d.ts +12 -0
- package/lib/Extensions/FetchUrlExtension/FetchUrlExtension.js +69 -0
- package/lib/Extensions/ImageExtension/AssetImageExtension.d.ts +17 -0
- package/lib/Extensions/ImageExtension/AssetImageExtension.js +91 -0
- package/lib/Extensions/ImageExtension/DAMImageExtension.d.ts +17 -0
- package/lib/Extensions/ImageExtension/DAMImageExtension.js +97 -0
- package/lib/Extensions/ImageExtension/ImageExtension.d.ts +7 -0
- package/lib/Extensions/ImageExtension/ImageExtension.js +18 -0
- package/lib/Extensions/LinkExtension/AssetLinkExtension.d.ts +27 -0
- package/lib/Extensions/LinkExtension/AssetLinkExtension.js +101 -0
- package/lib/Extensions/LinkExtension/LinkExtension.d.ts +23 -0
- package/lib/Extensions/LinkExtension/LinkExtension.js +87 -0
- package/lib/Extensions/LinkExtension/common.d.ts +7 -0
- package/lib/Extensions/LinkExtension/common.js +14 -0
- package/lib/Extensions/PreformattedExtension/PreformattedExtension.d.ts +15 -0
- package/lib/Extensions/PreformattedExtension/PreformattedExtension.js +83 -0
- package/lib/Extensions/UnsuportedExtension/UnsupportedNodeExtension.d.ts +10 -0
- package/lib/Extensions/UnsuportedExtension/UnsupportedNodeExtension.js +76 -0
- package/lib/Icons/AiIcon.d.ts +2 -0
- package/lib/Icons/AiIcon.js +60 -0
- package/lib/hooks/index.d.ts +3 -0
- package/lib/hooks/index.js +19 -0
- package/lib/hooks/useExpandedSelection/useExpandedSelection.d.ts +23 -0
- package/lib/hooks/useExpandedSelection/useExpandedSelection.js +37 -0
- package/lib/hooks/useExtensionNames/useExtensionNames.d.ts +1 -0
- package/lib/hooks/useExtensionNames/useExtensionNames.js +16 -0
- package/lib/hooks/useFocus/useFocus.d.ts +6 -0
- package/lib/hooks/useFocus/useFocus.js +57 -0
- package/lib/index.css +5894 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.js +16 -0
- package/lib/types.d.ts +7 -0
- package/lib/types.js +2 -0
- package/lib/ui/Button/Button.d.ts +12 -0
- package/lib/ui/Button/Button.js +13 -0
- package/lib/ui/CollapseBox/CollapseBox.d.ts +7 -0
- package/lib/ui/CollapseBox/CollapseBox.js +48 -0
- package/lib/ui/EditorInput/EditorInput.d.ts +3 -0
- package/lib/ui/EditorInput/EditorInput.js +49 -0
- package/lib/ui/EditorInput/EditorInput.props.d.ts +4 -0
- package/lib/ui/EditorInput/EditorInput.props.js +2 -0
- package/lib/ui/Fields/Checkbox/Checkbox.d.ts +9 -0
- package/lib/ui/Fields/Checkbox/Checkbox.js +47 -0
- package/lib/ui/Fields/Input/Input.d.ts +3 -0
- package/lib/ui/Fields/Input/Input.js +33 -0
- package/lib/ui/Fields/InputContainer/InputContainer.d.ts +9 -0
- package/lib/ui/Fields/InputContainer/InputContainer.js +16 -0
- package/lib/ui/Fields/MatrixAsset/MatrixAsset.d.ts +19 -0
- package/lib/ui/Fields/MatrixAsset/MatrixAsset.js +30 -0
- package/lib/ui/Fields/ResourceBrowserSelector/ResourceBrowserSelector.d.ts +28 -0
- package/lib/ui/Fields/ResourceBrowserSelector/ResourceBrowserSelector.js +88 -0
- package/lib/ui/Modal/FormModal.d.ts +5 -0
- package/lib/ui/Modal/FormModal.js +39 -0
- package/lib/ui/Modal/Modal.d.ts +11 -0
- package/lib/ui/Modal/Modal.js +79 -0
- package/lib/ui/Tabs/Tabs.d.ts +11 -0
- package/lib/ui/Tabs/Tabs.js +46 -0
- package/lib/ui/ToolbarDropdown/ToolbarDropdown.d.ts +7 -0
- package/lib/ui/ToolbarDropdown/ToolbarDropdown.js +48 -0
- package/lib/ui/ToolbarDropdownButton/ToolbarDropdownButton.d.ts +11 -0
- package/lib/ui/ToolbarDropdownButton/ToolbarDropdownButton.js +15 -0
- package/lib/utils/converters/htmlToSquizNode/htmlToSquizNode.d.ts +5 -0
- package/lib/utils/converters/htmlToSquizNode/htmlToSquizNode.js +23 -0
- package/lib/utils/converters/htmlToSquizNode/htmlToSquizNode.props.d.ts +3 -0
- package/lib/utils/converters/htmlToSquizNode/htmlToSquizNode.props.js +2 -0
- package/lib/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.d.ts +11 -0
- package/lib/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.js +235 -0
- package/lib/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.d.ts +9 -0
- package/lib/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.js +208 -0
- package/lib/utils/createToolbarPositioner.d.ts +18 -0
- package/lib/utils/createToolbarPositioner.js +96 -0
- package/lib/utils/getCursorRect.d.ts +2 -0
- package/lib/utils/getCursorRect.js +7 -0
- package/lib/utils/getMarkNamesByGroup.d.ts +2 -0
- package/lib/utils/getMarkNamesByGroup.js +9 -0
- package/lib/utils/getNodeNamesByGroup.d.ts +2 -0
- package/lib/utils/getNodeNamesByGroup.js +9 -0
- package/lib/utils/getShortcutSymbol.d.ts +1 -0
- package/lib/utils/getShortcutSymbol.js +8 -0
- package/lib/utils/undefinedIfEmpty.d.ts +1 -0
- package/lib/utils/undefinedIfEmpty.js +7 -0
- package/lib/utils/validation.d.ts +3 -0
- package/lib/utils/validation.js +16 -0
- package/package.json +1 -1
- package/src/Editor/Editor.spec.tsx +35 -10
- package/src/Editor/Editor.tsx +48 -44
- package/src/Editor/_editor.scss +4 -0
- package/src/EditorToolbar/Toolbar.tsx +8 -4
- package/src/EditorToolbar/Tools/Image/Form/ImageForm.tsx +0 -3
- package/src/EditorToolbar/Tools/TextType/CodeBlock/CodeBlockButton.tsx +3 -3
- package/src/EditorToolbar/_toolbar.scss +3 -2
- package/src/Extensions/CodeBlockExtension/CodeBlockExtension.props.ts +3 -0
- package/src/Extensions/CodeBlockExtension/CodeBlockExtension.spec.ts +59 -0
- package/src/Extensions/CodeBlockExtension/CodeBlockExtension.ts +82 -7
- package/src/Extensions/Extensions.ts +4 -4
- package/src/Extensions/PreformattedExtension/PreformattedExtension.ts +15 -3
- package/src/hooks/index.ts +3 -2
- package/src/hooks/useFocus/useFocus.spec.tsx +48 -0
- package/src/hooks/useFocus/useFocus.ts +71 -0
- package/src/ui/EditorInput/EditorInput.props.ts +5 -0
- package/src/ui/EditorInput/EditorInput.spec.tsx +38 -0
- package/src/ui/EditorInput/EditorInput.tsx +30 -0
- package/src/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.spec.ts +1 -3
- package/src/utils/converters/remirrorNodeToSquizNode/remirrorNodeToSquizNode.ts +0 -4
- package/src/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.spec.ts +1 -4
- package/src/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.ts +0 -5
- package/src/hooks/useFocus.ts +0 -61
- /package/demo/{index.scss → diff/index.scss} +0 -0
- /package/demo/{resources.json → diff/resources.json} +0 -0
- /package/demo/{sources.json → diff/sources.json} +0 -0
- /package/demo/{vite-env.d.ts → diff/vite-env.d.ts} +0 -0
- /package/src/hooks/{useExpandedSelection.ts → useExpandedSelection/useExpandedSelection.ts} +0 -0
- /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,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,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,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,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,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;
|