@toptal/picasso-rich-text-editor 100.0.10 → 100.1.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/dist-package/src/LexicalEditor/hooks/useOnFocus/use-on-focus.d.ts +1 -0
- package/dist-package/src/LexicalEditor/hooks/useOnFocus/use-on-focus.d.ts.map +1 -1
- package/dist-package/src/LexicalEditor/hooks/useOnFocus/use-on-focus.js +29 -4
- package/dist-package/src/LexicalEditor/hooks/useOnFocus/use-on-focus.js.map +1 -1
- package/dist-package/src/LexicalEditor/utils/cleanup-html-output.d.ts.map +1 -1
- package/dist-package/src/LexicalEditor/utils/cleanup-html-output.js +10 -1
- package/dist-package/src/LexicalEditor/utils/cleanup-html-output.js.map +1 -1
- package/dist-package/src/index.d.ts +1 -1
- package/dist-package/src/index.d.ts.map +1 -1
- package/dist-package/src/index.js.map +1 -1
- package/dist-package/src/plugins/LinkPlugin/LinkPlugin.d.ts +5 -3
- package/dist-package/src/plugins/LinkPlugin/LinkPlugin.d.ts.map +1 -1
- package/dist-package/src/plugins/LinkPlugin/LinkPlugin.js +7 -3
- package/dist-package/src/plugins/LinkPlugin/LinkPlugin.js.map +1 -1
- package/dist-package/src/plugins/LinkPlugin/LinkPluginButton.d.ts +6 -4
- package/dist-package/src/plugins/LinkPlugin/LinkPluginButton.d.ts.map +1 -1
- package/dist-package/src/plugins/LinkPlugin/LinkPluginButton.js +5 -47
- package/dist-package/src/plugins/LinkPlugin/LinkPluginButton.js.map +1 -1
- package/dist-package/src/plugins/LinkPlugin/LinkPluginModal.d.ts +24 -0
- package/dist-package/src/plugins/LinkPlugin/LinkPluginModal.d.ts.map +1 -0
- package/dist-package/src/plugins/LinkPlugin/LinkPluginModal.js +51 -0
- package/dist-package/src/plugins/LinkPlugin/LinkPluginModal.js.map +1 -0
- package/dist-package/src/plugins/LinkPlugin/use-link-plugin.d.ts +15 -0
- package/dist-package/src/plugins/LinkPlugin/use-link-plugin.d.ts.map +1 -0
- package/dist-package/src/plugins/LinkPlugin/use-link-plugin.js +140 -0
- package/dist-package/src/plugins/LinkPlugin/use-link-plugin.js.map +1 -0
- package/dist-package/src/plugins/index.d.ts +2 -1
- package/dist-package/src/plugins/index.d.ts.map +1 -1
- package/dist-package/src/plugins/index.js.map +1 -1
- package/dist-package/src/utils/html-to-hast.js +1 -1
- package/dist-package/src/utils/html-to-hast.js.map +1 -1
- package/package.json +4 -2
- package/src/LexicalEditor/hooks/useOnFocus/test.ts +115 -1
- package/src/LexicalEditor/hooks/useOnFocus/use-on-focus.ts +41 -7
- package/src/LexicalEditor/utils/cleanup-html-output.test.ts +9 -0
- package/src/LexicalEditor/utils/cleanup-html-output.ts +11 -0
- package/src/index.ts +6 -1
- package/src/plugins/LinkPlugin/LinkPlugin.tsx +29 -4
- package/src/plugins/LinkPlugin/LinkPluginButton.tsx +16 -61
- package/src/plugins/LinkPlugin/LinkPluginModal.test.tsx +172 -0
- package/src/plugins/LinkPlugin/LinkPluginModal.tsx +142 -0
- package/src/plugins/LinkPlugin/use-link-plugin.ts +193 -0
- package/src/plugins/index.ts +2 -1
- package/src/utils/__tests__/html-to-hast.test.tsx +23 -0
- package/src/utils/html-to-hast.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-on-focus.d.ts","sourceRoot":"","sources":["../../../../../src/LexicalEditor/hooks/useOnFocus/use-on-focus.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-on-focus.d.ts","sourceRoot":"","sources":["../../../../../src/LexicalEditor/hooks/useOnFocus/use-on-focus.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,yBAAyB,oBAAoB,CAAA;AAE1D,MAAM,MAAM,KAAK,GAAG;IAClB,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,CAAA;IAChD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;CACpB,CAAA;AAED,KAAK,MAAM,GAAG;IACZ,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,KAAK,IAAI,CAAA;IAC1D,UAAU,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,KAAK,IAAI,CAAA;CAC1D,CAAA;AA6BD,QAAA,MAAM,UAAU,uCAIb,KAAK,KAAG,MAiCV,CAAA;AAED,eAAe,UAAU,CAAA"}
|
|
@@ -1,17 +1,42 @@
|
|
|
1
|
-
import { useCallback, useState } from 'react';
|
|
1
|
+
import { useCallback, useRef, useState } from 'react';
|
|
2
2
|
import { noop } from '@toptal/picasso-utils';
|
|
3
|
+
// Plugin dialogs render in a portal outside the editor, but moving focus into
|
|
4
|
+
// one is still part of editing, so it must not blur the editor
|
|
5
|
+
export const INTERNAL_DIALOG_ATTRIBUTE = 'data-rte-dialog';
|
|
6
|
+
const isDialogElement = (element) => {
|
|
7
|
+
var _a;
|
|
8
|
+
return Boolean(element.closest(`[${INTERNAL_DIALOG_ATTRIBUTE}]`)) ||
|
|
9
|
+
// Base UI puts the dialog's focus guards beside it, not inside it
|
|
10
|
+
(element.hasAttribute('data-base-ui-focus-guard') &&
|
|
11
|
+
Boolean((_a = element.parentElement) === null || _a === void 0 ? void 0 : _a.querySelector(`:scope > [${INTERNAL_DIALOG_ATTRIBUTE}]`)));
|
|
12
|
+
};
|
|
13
|
+
const isInternalElement = (e, internalRefs) => {
|
|
14
|
+
var _a;
|
|
15
|
+
const focusElement = e.relatedTarget;
|
|
16
|
+
if (!focusElement) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return (Boolean((_a = e.currentTarget) === null || _a === void 0 ? void 0 : _a.contains(focusElement)) ||
|
|
20
|
+
internalRefs.some(ref => { var _a; return (_a = ref.current) === null || _a === void 0 ? void 0 : _a.contains(focusElement); }) ||
|
|
21
|
+
(focusElement instanceof Element && isDialogElement(focusElement)));
|
|
22
|
+
};
|
|
3
23
|
const useOnFocus = ({ onFocus = noop, onBlur = noop, internalRefs = [], }) => {
|
|
4
24
|
const [focused, setFocused] = useState(false);
|
|
25
|
+
// Focus coming back from the toolbar or a dialog is not a new focus
|
|
26
|
+
const focusedRef = useRef(false);
|
|
5
27
|
const handleFocus = useCallback(() => {
|
|
28
|
+
if (focusedRef.current) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
focusedRef.current = true;
|
|
6
32
|
setFocused(true);
|
|
7
33
|
onFocus();
|
|
8
34
|
}, [onFocus]);
|
|
9
35
|
const handleBlur = useCallback((e) => {
|
|
10
|
-
|
|
11
|
-
const isInternalElement = internalRefs.some(ref => ref.current && ref.current.contains(focusElement));
|
|
12
|
-
if (isInternalElement) {
|
|
36
|
+
if (isInternalElement(e, internalRefs)) {
|
|
13
37
|
return;
|
|
14
38
|
}
|
|
39
|
+
focusedRef.current = false;
|
|
15
40
|
setFocused(false);
|
|
16
41
|
onBlur();
|
|
17
42
|
}, [onBlur]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-on-focus.js","sourceRoot":"","sources":["../../../../../src/LexicalEditor/hooks/useOnFocus/use-on-focus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"use-on-focus.js","sourceRoot":"","sources":["../../../../../src/LexicalEditor/hooks/useOnFocus/use-on-focus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AAE5C,8EAA8E;AAC9E,+DAA+D;AAC/D,MAAM,CAAC,MAAM,yBAAyB,GAAG,iBAAiB,CAAA;AAc1D,MAAM,eAAe,GAAG,CAAC,OAAgB,EAAE,EAAE;;IAC3C,OAAA,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,yBAAyB,GAAG,CAAC,CAAC;QAC1D,kEAAkE;QAClE,CAAC,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC;YAC/C,OAAO,CACL,MAAA,OAAO,CAAC,aAAa,0CAAE,aAAa,CAClC,aAAa,yBAAyB,GAAG,CAC1C,CACF,CAAC,CAAA;CAAA,CAAA;AAEN,MAAM,iBAAiB,GAAG,CACxB,CAAmC,EACnC,YAA+C,EAC/C,EAAE;;IACF,MAAM,YAAY,GAAG,CAAC,CAAC,aAA4B,CAAA;IAEnD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,CACL,OAAO,CAAC,MAAA,CAAC,CAAC,aAAa,0CAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;QAChD,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,WAAC,OAAA,MAAA,GAAG,CAAC,OAAO,0CAAE,QAAQ,CAAC,YAAY,CAAC,CAAA,EAAA,CAAC;QAC7D,CAAC,YAAY,YAAY,OAAO,IAAI,eAAe,CAAC,YAAY,CAAC,CAAC,CACnE,CAAA;AACH,CAAC,CAAA;AAED,MAAM,UAAU,GAAG,CAAC,EAClB,OAAO,GAAG,IAAI,EACd,MAAM,GAAG,IAAI,EACb,YAAY,GAAG,EAAE,GACX,EAAU,EAAE;IAClB,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC7C,oEAAoE;IACpE,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAEhC,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;QACnC,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;YACvB,OAAM;QACR,CAAC;QAED,UAAU,CAAC,OAAO,GAAG,IAAI,CAAA;QACzB,UAAU,CAAC,IAAI,CAAC,CAAA;QAChB,OAAO,EAAE,CAAA;IACX,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;IAEb,MAAM,UAAU,GAAG,WAAW,CAC5B,CAAC,CAAmC,EAAE,EAAE;QACtC,IAAI,iBAAiB,CAAC,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC;YACvC,OAAM;QACR,CAAC;QAED,UAAU,CAAC,OAAO,GAAG,KAAK,CAAA;QAC1B,UAAU,CAAC,KAAK,CAAC,CAAA;QACjB,MAAM,EAAE,CAAA;IACV,CAAC,EACD,CAAC,MAAM,CAAC,CACT,CAAA;IAED,OAAO;QACL,OAAO;QACP,WAAW;QACX,UAAU;KACX,CAAA;AACH,CAAC,CAAA;AAED,eAAe,UAAU,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cleanup-html-output.d.ts","sourceRoot":"","sources":["../../../../src/LexicalEditor/utils/cleanup-html-output.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cleanup-html-output.d.ts","sourceRoot":"","sources":["../../../../src/LexicalEditor/utils/cleanup-html-output.ts"],"names":[],"mappings":"AA4HA,eAAO,MAAM,iBAAiB,SAAU,MAAM,KAAG,MAchD,CAAA"}
|
|
@@ -79,13 +79,22 @@ const hoistNestedLists = (htmlDoc) => {
|
|
|
79
79
|
});
|
|
80
80
|
return htmlDoc;
|
|
81
81
|
};
|
|
82
|
+
// A link that opens in a new tab must not get access to this page through
|
|
83
|
+
// window.opener, whatever produced it (the dialog or pasted HTML)
|
|
84
|
+
const secureNewTabLinks = (htmlDoc) => {
|
|
85
|
+
htmlDoc.querySelectorAll('a[target="_blank"]').forEach(link => {
|
|
86
|
+
link.setAttribute('rel', 'noopener noreferrer');
|
|
87
|
+
});
|
|
88
|
+
return htmlDoc;
|
|
89
|
+
};
|
|
82
90
|
export const cleanupHtmlOutput = (html) => {
|
|
83
91
|
const parser = new DOMParser();
|
|
84
92
|
const htmlDoc = parser.parseFromString(html, 'text/html');
|
|
85
93
|
const [newHtml] = [htmlDoc]
|
|
86
94
|
.map(removeExtraTags)
|
|
87
95
|
.map(replaceItalicTag)
|
|
88
|
-
.map(hoistNestedLists)
|
|
96
|
+
.map(hoistNestedLists)
|
|
97
|
+
.map(secureNewTabLinks);
|
|
89
98
|
const result = newHtml.body.innerHTML;
|
|
90
99
|
return result;
|
|
91
100
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cleanup-html-output.js","sourceRoot":"","sources":["../../../../src/LexicalEditor/utils/cleanup-html-output.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cleanup-html-output.js","sourceRoot":"","sources":["../../../../src/LexicalEditor/utils/cleanup-html-output.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,6 @@ export type { RichTextEditorProps, RichTextEditorChangeHandler, } from './RichTe
|
|
|
3
3
|
export { default as RichText } from './RichText';
|
|
4
4
|
export type { RichTextProps, ASTType } from './RichText';
|
|
5
5
|
export { ImagePlugin, EmojiPlugin, LinkPlugin, CodePlugin, CodeBlockPlugin, } from './plugins';
|
|
6
|
-
export type { UploadedImage, CustomEmoji, CustomEmojiGroup } from './plugins';
|
|
6
|
+
export type { UploadedImage, CustomEmoji, CustomEmojiGroup, LinkPluginProps, } from './plugins';
|
|
7
7
|
export * from './utils';
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAC5D,YAAY,EACV,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,YAAY,CAAA;AAChD,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACxD,OAAO,EACL,WAAW,EACX,WAAW,EACX,UAAU,EACV,UAAU,EACV,eAAe,GAChB,MAAM,WAAW,CAAA;AAClB,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAC5D,YAAY,EACV,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,YAAY,CAAA;AAChD,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACxD,OAAO,EACL,WAAW,EACX,WAAW,EACX,UAAU,EACV,UAAU,EACV,eAAe,GAChB,MAAM,WAAW,CAAA;AAClB,YAAY,EACV,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,eAAe,GAChB,MAAM,WAAW,CAAA;AAClB,cAAc,SAAS,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAK5D,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,YAAY,CAAA;AAEhD,OAAO,EACL,WAAW,EACX,WAAW,EACX,UAAU,EACV,UAAU,EACV,eAAe,GAChB,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAK5D,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,YAAY,CAAA;AAEhD,OAAO,EACL,WAAW,EACX,WAAW,EACX,UAAU,EACV,UAAU,EACV,eAAe,GAChB,MAAM,WAAW,CAAA;AAOlB,cAAc,SAAS,CAAA"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type { BaseProps } from '@toptal/picasso-shared';
|
|
1
2
|
import type { RTEPlugin } from '../api';
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
export interface Props extends BaseProps {
|
|
4
|
+
/** Where a new link opens: `_blank` checks "Open in new tab" in the dialog */
|
|
5
|
+
defaultTarget?: '_self' | '_blank';
|
|
6
|
+
}
|
|
5
7
|
declare const LinkPlugin: RTEPlugin<Props>;
|
|
6
8
|
export default LinkPlugin;
|
|
7
9
|
//# sourceMappingURL=LinkPlugin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkPlugin.d.ts","sourceRoot":"","sources":["../../../../src/plugins/LinkPlugin/LinkPlugin.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LinkPlugin.d.ts","sourceRoot":"","sources":["../../../../src/plugins/LinkPlugin/LinkPlugin.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAEvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAQvC,MAAM,WAAW,KAAM,SAAQ,SAAS;IACtC,8EAA8E;IAC9E,aAAa,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;CACnC;AAED,QAAA,MAAM,UAAU,EAAE,SAAS,CAAC,KAAK,CA8BhC,CAAA;AASD,eAAe,UAAU,CAAA"}
|
|
@@ -3,12 +3,16 @@ import { LinkPlugin as LexicalLinkPlugin } from '@lexical/react/LexicalLinkPlugi
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { RTEPluginMeta, Toolbar } from '../api';
|
|
5
5
|
import LinkPluginButton from './LinkPluginButton';
|
|
6
|
+
import LinkPluginModal from './LinkPluginModal';
|
|
7
|
+
import { useLinkPlugin } from './use-link-plugin';
|
|
6
8
|
const PLUGIN_NAME = 'link';
|
|
7
|
-
const LinkPlugin = ({ 'data-testid': testId }) => {
|
|
9
|
+
const LinkPlugin = ({ defaultTarget = '_self', className, style, 'data-testid': testId, }) => {
|
|
10
|
+
const { open, editing, initialValues, show, close, submit, remove } = useLinkPlugin({ defaultTarget });
|
|
8
11
|
return (React.createElement(React.Fragment, null,
|
|
9
12
|
React.createElement(Toolbar, { keyName: PLUGIN_NAME },
|
|
10
|
-
React.createElement(LinkPluginButton, { "data-testid": testId })),
|
|
11
|
-
React.createElement(LexicalLinkPlugin, null)
|
|
13
|
+
React.createElement(LinkPluginButton, { onClick: show, className: className, style: style, "data-testid": testId })),
|
|
14
|
+
React.createElement(LexicalLinkPlugin, null),
|
|
15
|
+
React.createElement(LinkPluginModal, { open: open, editing: editing, initialValues: initialValues, onClose: close, onSubmit: submit, onRemove: remove })));
|
|
12
16
|
};
|
|
13
17
|
LinkPlugin[RTEPluginMeta] = {
|
|
14
18
|
name: PLUGIN_NAME,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkPlugin.js","sourceRoot":"","sources":["../../../../src/plugins/LinkPlugin/LinkPlugin.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,UAAU,IAAI,iBAAiB,EAAE,MAAM,kCAAkC,CAAA;AAClF,OAAO,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"LinkPlugin.js","sourceRoot":"","sources":["../../../../src/plugins/LinkPlugin/LinkPlugin.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,UAAU,IAAI,iBAAiB,EAAE,MAAM,kCAAkC,CAAA;AAClF,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,gBAAgB,MAAM,oBAAoB,CAAA;AACjD,OAAO,eAAe,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEjD,MAAM,WAAW,GAAG,MAAM,CAAA;AAO1B,MAAM,UAAU,GAAqB,CAAC,EACpC,aAAa,GAAG,OAAO,EACvB,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,GACf,EAAE,EAAE;IACV,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GACjE,aAAa,CAAC,EAAE,aAAa,EAAE,CAAC,CAAA;IAElC,OAAO,CACL;QACE,oBAAC,OAAO,IAAC,OAAO,EAAE,WAAW;YAC3B,oBAAC,gBAAgB,IACf,OAAO,EAAE,IAAI,EACb,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,KAAK,iBACC,MAAM,GACnB,CACM;QACV,oBAAC,iBAAiB,OAAG;QACrB,oBAAC,eAAe,IACd,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE,KAAK,EACd,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GAChB,CACD,CACJ,CAAA;AACH,CAAC,CAAA;AAED,UAAU,CAAC,aAAa,CAAC,GAAG;IAC1B,IAAI,EAAE,WAAW;IACjB,OAAO,EAAE;QACP,KAAK,EAAE,CAAC,QAAQ,CAAC;KAClB;CACF,CAAA;AAED,eAAe,UAAU,CAAA"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import type { BaseProps } from '@toptal/picasso-shared';
|
|
2
|
+
export interface Props extends BaseProps {
|
|
3
|
+
/** Called when the button is clicked */
|
|
4
|
+
onClick: () => void;
|
|
5
|
+
}
|
|
6
|
+
declare const LinkPluginButton: ({ "data-testid": testId, className, style, onClick, }: Props) => JSX.Element;
|
|
5
7
|
export default LinkPluginButton;
|
|
6
8
|
//# sourceMappingURL=LinkPluginButton.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkPluginButton.d.ts","sourceRoot":"","sources":["../../../../src/plugins/LinkPlugin/LinkPluginButton.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LinkPluginButton.d.ts","sourceRoot":"","sources":["../../../../src/plugins/LinkPlugin/LinkPluginButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAQvD,MAAM,WAAW,KAAM,SAAQ,SAAS;IACtC,wCAAwC;IACxC,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAED,QAAA,MAAM,gBAAgB,0DAKnB,KAAK,gBA4BP,CAAA;AAED,eAAe,gBAAgB,CAAA"}
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import { $isLinkNode
|
|
2
|
-
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
1
|
+
import { $isLinkNode } from '@lexical/link';
|
|
3
2
|
import { Link16 } from '@toptal/picasso-icons';
|
|
4
|
-
import { $
|
|
5
|
-
import React, {
|
|
3
|
+
import { $getSelection, $isRangeSelection } from 'lexical';
|
|
4
|
+
import React, { useState } from 'react';
|
|
6
5
|
import { getSelectedNode } from '../../LexicalEditor/utils/get-selected-node';
|
|
7
6
|
import { useRTEPluginContext, useRTEUpdate } from '../api';
|
|
8
7
|
import RichTextEditorButton from '../../RichTextEditorButton';
|
|
9
|
-
|
|
10
|
-
const LinkPluginButton = ({ 'data-testid': testId }) => {
|
|
8
|
+
const LinkPluginButton = ({ 'data-testid': testId, className, style, onClick, }) => {
|
|
11
9
|
const [active, setActive] = useState(false);
|
|
12
|
-
const [editor] = useLexicalComposerContext();
|
|
13
10
|
const { disabled, focused, disabledFormatting } = useRTEPluginContext();
|
|
14
11
|
useRTEUpdate(() => {
|
|
15
12
|
const selection = $getSelection();
|
|
@@ -19,47 +16,8 @@ const LinkPluginButton = ({ 'data-testid': testId }) => {
|
|
|
19
16
|
setActive(Boolean($isLinkNode(node) || $isLinkNode(parent)));
|
|
20
17
|
}
|
|
21
18
|
});
|
|
22
|
-
const onLinkClick = useCallback(() => {
|
|
23
|
-
if (active) {
|
|
24
|
-
return editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);
|
|
25
|
-
}
|
|
26
|
-
editor.update(() => {
|
|
27
|
-
const selection = $getSelection();
|
|
28
|
-
if ($isRangeSelection(selection)) {
|
|
29
|
-
const isEmptySelection = selection.anchor.is(selection.focus);
|
|
30
|
-
const url = window.prompt('URL');
|
|
31
|
-
if (url != null) {
|
|
32
|
-
if (!validateUrl(url)) {
|
|
33
|
-
return window.alert('Not a valid URL');
|
|
34
|
-
}
|
|
35
|
-
const sanitizedUrl = sanitizeUrl(url);
|
|
36
|
-
// When nothing is selected, we create a new Link node without dispatching
|
|
37
|
-
// any commands to the original Lexical Link plugin
|
|
38
|
-
if (isEmptySelection) {
|
|
39
|
-
// The only way to reliably insert a link is to first create a dummy text node
|
|
40
|
-
selection.insertNodes([$createTextNode(sanitizedUrl)]);
|
|
41
|
-
// Once created, node becomes selected
|
|
42
|
-
const node = getSelectedNode(selection);
|
|
43
|
-
const text = node.getTextContent();
|
|
44
|
-
// Then we create a target Link node and replace the dummy text node with it
|
|
45
|
-
const linkNode = $createLinkNode(sanitizedUrl, {
|
|
46
|
-
rel: 'noreferrer',
|
|
47
|
-
});
|
|
48
|
-
linkNode.append($createTextNode(text));
|
|
49
|
-
node.replace(linkNode);
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
// If we have a selection of any kind, pass the creation of the Link node to the plugin
|
|
53
|
-
editor.dispatchCommand(TOGGLE_LINK_COMMAND, {
|
|
54
|
-
url: sanitizedUrl,
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
}, [editor, active]);
|
|
61
19
|
const isDisabled = disabled || !focused || disabledFormatting;
|
|
62
|
-
return (React.createElement(RichTextEditorButton, { icon: React.createElement(Link16, null), onClick:
|
|
20
|
+
return (React.createElement(RichTextEditorButton, { icon: React.createElement(Link16, null), onClick: onClick, active: isDisabled ? false : active, disabled: isDisabled, className: className, style: style, "data-testid": testId }));
|
|
63
21
|
};
|
|
64
22
|
export default LinkPluginButton;
|
|
65
23
|
//# sourceMappingURL=LinkPluginButton.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkPluginButton.js","sourceRoot":"","sources":["../../../../src/plugins/LinkPlugin/LinkPluginButton.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"LinkPluginButton.js","sourceRoot":"","sources":["../../../../src/plugins/LinkPlugin/LinkPluginButton.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAE9C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAC1D,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEvC,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAA;AAC7E,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAC1D,OAAO,oBAAoB,MAAM,4BAA4B,CAAA;AAO7D,MAAM,gBAAgB,GAAG,CAAC,EACxB,aAAa,EAAE,MAAM,EACrB,SAAS,EACT,KAAK,EACL,OAAO,GACD,EAAE,EAAE;IACV,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC3C,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,kBAAkB,EAAE,GAAG,mBAAmB,EAAE,CAAA;IAEvE,YAAY,CAAC,GAAG,EAAE;QAChB,MAAM,SAAS,GAAG,aAAa,EAAE,CAAA;QAEjC,IAAI,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,eAAe,CAAC,SAAS,CAAC,CAAA;YACvC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA;YAE/B,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QAC9D,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,MAAM,UAAU,GAAG,QAAQ,IAAI,CAAC,OAAO,IAAI,kBAAkB,CAAA;IAE7D,OAAO,CACL,oBAAC,oBAAoB,IACnB,IAAI,EAAE,oBAAC,MAAM,OAAG,EAChB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EACnC,QAAQ,EAAE,UAAU,EACpB,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,KAAK,iBACC,MAAM,GACnB,CACH,CAAA;AACH,CAAC,CAAA;AAED,eAAe,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import type { BaseProps } from '@toptal/picasso-shared';
|
|
3
|
+
export type LinkValues = {
|
|
4
|
+
text: string;
|
|
5
|
+
url: string;
|
|
6
|
+
openInNewTab: boolean;
|
|
7
|
+
};
|
|
8
|
+
export interface Props extends BaseProps {
|
|
9
|
+
/** Whether the dialog is shown */
|
|
10
|
+
open: boolean;
|
|
11
|
+
/** Values the form opens with: the selected text, or the link being edited */
|
|
12
|
+
initialValues: LinkValues;
|
|
13
|
+
/** Whether an existing link is being edited, which offers removing it */
|
|
14
|
+
editing: boolean;
|
|
15
|
+
/** Called when the dialog is dismissed without saving */
|
|
16
|
+
onClose: () => void;
|
|
17
|
+
/** Called with the entered values when the link is saved */
|
|
18
|
+
onSubmit: (values: LinkValues) => void;
|
|
19
|
+
/** Called when the edited link is removed */
|
|
20
|
+
onRemove: () => void;
|
|
21
|
+
}
|
|
22
|
+
declare const LinkPluginModal: ({ open, initialValues, editing, onClose, onSubmit, onRemove, className, style, "data-testid": testId, }: Props) => ReactElement;
|
|
23
|
+
export default LinkPluginModal;
|
|
24
|
+
//# sourceMappingURL=LinkPluginModal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinkPluginModal.d.ts","sourceRoot":"","sources":["../../../../src/plugins/LinkPlugin/LinkPluginModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAOzC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAKvD,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,YAAY,EAAE,OAAO,CAAA;CACtB,CAAA;AAED,MAAM,WAAW,KAAM,SAAQ,SAAS;IACtC,kCAAkC;IAClC,IAAI,EAAE,OAAO,CAAA;IACb,8EAA8E;IAC9E,aAAa,EAAE,UAAU,CAAA;IACzB,yEAAyE;IACzE,OAAO,EAAE,OAAO,CAAA;IAChB,yDAAyD;IACzD,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,4DAA4D;IAC5D,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAA;IACtC,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,IAAI,CAAA;CACrB;AAED,QAAA,MAAM,eAAe,4GAUlB,KAAK,KAAG,YAgGV,CAAA;AAED,eAAe,eAAe,CAAA"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Button } from '@toptal/picasso-button';
|
|
3
|
+
import { Checkbox } from '@toptal/picasso-checkbox';
|
|
4
|
+
import { FormCompound as Form } from '@toptal/picasso-form';
|
|
5
|
+
import { Input } from '@toptal/picasso-input';
|
|
6
|
+
import { ModalCompound as Modal } from '@toptal/picasso-modal';
|
|
7
|
+
import { INTERNAL_DIALOG_ATTRIBUTE } from '../../LexicalEditor/hooks/useOnFocus/use-on-focus';
|
|
8
|
+
import { validateUrl } from './utils/url';
|
|
9
|
+
const LinkPluginModal = ({ open, initialValues, editing, onClose, onSubmit, onRemove, className, style, 'data-testid': testId, }) => {
|
|
10
|
+
const [values, setValues] = useState(initialValues);
|
|
11
|
+
const [urlError, setUrlError] = useState(false);
|
|
12
|
+
const [shownValues, setShownValues] = useState(initialValues);
|
|
13
|
+
// Reset the form during render, not in an effect: the fields mount with the
|
|
14
|
+
// dialog, and their autoFocus must see the values it opened with
|
|
15
|
+
if (shownValues !== initialValues) {
|
|
16
|
+
setShownValues(initialValues);
|
|
17
|
+
setValues(initialValues);
|
|
18
|
+
setUrlError(false);
|
|
19
|
+
}
|
|
20
|
+
// With text selected only the URL is missing, so start there
|
|
21
|
+
const focusUrl = Boolean(initialValues.text);
|
|
22
|
+
const handleSave = () => {
|
|
23
|
+
const url = values.url.trim();
|
|
24
|
+
if (!validateUrl(url)) {
|
|
25
|
+
setUrlError(true);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
onSubmit(Object.assign(Object.assign({}, values), { url }));
|
|
29
|
+
};
|
|
30
|
+
return (React.createElement(Modal, { onClose: onClose, open: open, size: 'small', className: className, style: style, "data-testid": testId, [INTERNAL_DIALOG_ATTRIBUTE]: '' },
|
|
31
|
+
React.createElement(Modal.Title, null, editing ? 'Edit link' : 'Add link'),
|
|
32
|
+
React.createElement(Modal.Content, null,
|
|
33
|
+
React.createElement(Form.Field, null,
|
|
34
|
+
React.createElement(Form.Label, { htmlFor: 'rte-link-text' }, "Text"),
|
|
35
|
+
React.createElement(Input, { id: 'rte-link-text', value: values.text, onChange: event => setValues(Object.assign(Object.assign({}, values), { text: event.target.value })), width: 'full', autoFocus: !focusUrl })),
|
|
36
|
+
React.createElement(Form.Field, null,
|
|
37
|
+
React.createElement(Form.Label, { htmlFor: 'rte-link-url' }, "Link"),
|
|
38
|
+
React.createElement(Input, { id: 'rte-link-url', value: values.url, onChange: event => {
|
|
39
|
+
setValues(Object.assign(Object.assign({}, values), { url: event.target.value }));
|
|
40
|
+
setUrlError(false);
|
|
41
|
+
}, status: urlError ? 'error' : undefined, width: 'full', autoFocus: focusUrl }),
|
|
42
|
+
urlError && React.createElement(Form.Error, null, "Enter a valid URL")),
|
|
43
|
+
React.createElement(Form.Field, null,
|
|
44
|
+
React.createElement(Checkbox, { label: 'Open in new tab', checked: values.openInNewTab, onChange: (_event, checked) => setValues(Object.assign(Object.assign({}, values), { openInNewTab: checked })) }))),
|
|
45
|
+
React.createElement(Modal.Actions, null,
|
|
46
|
+
editing && (React.createElement(Button, { variant: 'secondary', onClick: onRemove }, "Remove link")),
|
|
47
|
+
React.createElement(Button, { variant: 'secondary', onClick: onClose }, "Cancel"),
|
|
48
|
+
React.createElement(Button, { variant: 'primary', disabled: !values.url.trim(), onClick: handleSave }, "Save"))));
|
|
49
|
+
};
|
|
50
|
+
export default LinkPluginModal;
|
|
51
|
+
//# sourceMappingURL=LinkPluginModal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinkPluginModal.js","sourceRoot":"","sources":["../../../../src/plugins/LinkPlugin/LinkPluginModal.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { LinkValues } from './LinkPluginModal';
|
|
2
|
+
type Options = {
|
|
3
|
+
defaultTarget: '_self' | '_blank';
|
|
4
|
+
};
|
|
5
|
+
export declare const useLinkPlugin: ({ defaultTarget }: Options) => {
|
|
6
|
+
open: boolean;
|
|
7
|
+
editing: boolean;
|
|
8
|
+
initialValues: LinkValues;
|
|
9
|
+
show: () => void;
|
|
10
|
+
close: () => void;
|
|
11
|
+
submit: ({ text, url, openInNewTab }: LinkValues) => void;
|
|
12
|
+
remove: () => void;
|
|
13
|
+
};
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=use-link-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-link-plugin.d.ts","sourceRoot":"","sources":["../../../../src/plugins/LinkPlugin/use-link-plugin.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAmEnD,KAAK,OAAO,GAAG;IACb,aAAa,EAAE,OAAO,GAAG,QAAQ,CAAA;CAClC,CAAA;AAED,eAAO,MAAM,aAAa,sBAAuB,OAAO;;;;;;0CAuEtB,UAAU;;CAmC3C,CAAA"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { $createLinkNode, $isLinkNode, toggleLink } from '@lexical/link';
|
|
2
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
3
|
+
import { $findMatchingParent } from '@lexical/utils';
|
|
4
|
+
import { $createTextNode, $getNodeByKey, $getSelection, $isRangeSelection, $setSelection, } from 'lexical';
|
|
5
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
6
|
+
import { getSelectedNode } from '../../LexicalEditor/utils/get-selected-node';
|
|
7
|
+
import { sanitizeUrl } from './utils/url';
|
|
8
|
+
const linkAttributes = (openInNewTab) => openInNewTab
|
|
9
|
+
? { target: '_blank', rel: 'noopener noreferrer' }
|
|
10
|
+
: { target: null, rel: 'noreferrer' };
|
|
11
|
+
const $getEditedLink = (key) => {
|
|
12
|
+
const node = key ? $getNodeByKey(key) : null;
|
|
13
|
+
return $isLinkNode(node) ? node : null;
|
|
14
|
+
};
|
|
15
|
+
const $getLinkAt = (node) => {
|
|
16
|
+
const link = $findMatchingParent(node, $isLinkNode);
|
|
17
|
+
return $isLinkNode(link) ? link : null;
|
|
18
|
+
};
|
|
19
|
+
const $updateLink = (link, { href, attributes, label }) => {
|
|
20
|
+
link.setURL(href);
|
|
21
|
+
link.setTarget(attributes.target);
|
|
22
|
+
link.setRel(attributes.rel);
|
|
23
|
+
if (label === link.getTextContent()) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const oldChildren = link.getChildren();
|
|
27
|
+
const textNode = $createTextNode(label);
|
|
28
|
+
// Append before removing: a link left without children removes itself
|
|
29
|
+
link.append(textNode);
|
|
30
|
+
oldChildren.forEach(child => child.remove());
|
|
31
|
+
textNode.select();
|
|
32
|
+
};
|
|
33
|
+
const $insertLink = (selection, { href, attributes, label }) => {
|
|
34
|
+
$setSelection(selection);
|
|
35
|
+
// Keep the selection's formatting when only a URL is attached to it
|
|
36
|
+
if (!selection.isCollapsed() && label === selection.getTextContent()) {
|
|
37
|
+
toggleLink(href, attributes);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
// Inserting a text node first and then swapping it for the link is the
|
|
41
|
+
// only reliable way to place a link at the selection
|
|
42
|
+
selection.insertNodes([$createTextNode(label)]);
|
|
43
|
+
const placeholder = getSelectedNode(selection);
|
|
44
|
+
const linkNode = $createLinkNode(href, attributes);
|
|
45
|
+
linkNode.append($createTextNode(label));
|
|
46
|
+
placeholder.replace(linkNode);
|
|
47
|
+
};
|
|
48
|
+
export const useLinkPlugin = ({ defaultTarget }) => {
|
|
49
|
+
const [editor] = useLexicalComposerContext();
|
|
50
|
+
const [open, setOpen] = useState(false);
|
|
51
|
+
const [editing, setEditing] = useState(false);
|
|
52
|
+
const emptyValues = {
|
|
53
|
+
text: '',
|
|
54
|
+
url: '',
|
|
55
|
+
openInNewTab: defaultTarget === '_blank',
|
|
56
|
+
};
|
|
57
|
+
const [initialValues, setInitialValues] = useState(emptyValues);
|
|
58
|
+
// The dialog takes focus from the editor, so the selection it applies to is
|
|
59
|
+
// captured on show and restored when it closes.
|
|
60
|
+
const selectionRef = useRef(null);
|
|
61
|
+
const linkKeyRef = useRef(null);
|
|
62
|
+
const wasOpenRef = useRef(false);
|
|
63
|
+
// Return focus to the editor once the dialog is gone; focusing it while the
|
|
64
|
+
// dialog is still mounted would be pulled back into the dialog
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (wasOpenRef.current && !open) {
|
|
67
|
+
editor.focus();
|
|
68
|
+
}
|
|
69
|
+
wasOpenRef.current = open;
|
|
70
|
+
}, [editor, open]);
|
|
71
|
+
const show = useCallback(() => {
|
|
72
|
+
editor.getEditorState().read(() => {
|
|
73
|
+
var _a;
|
|
74
|
+
const selection = $getSelection();
|
|
75
|
+
if (!$isRangeSelection(selection)) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// Either end of the selection can sit in a link, e.g. a selection that
|
|
79
|
+
// starts inside one and ends after it
|
|
80
|
+
const link = (_a = $getLinkAt(selection.anchor.getNode())) !== null && _a !== void 0 ? _a : $getLinkAt(selection.focus.getNode());
|
|
81
|
+
selectionRef.current = selection.clone();
|
|
82
|
+
linkKeyRef.current = link ? link.getKey() : null;
|
|
83
|
+
setEditing(Boolean(link));
|
|
84
|
+
setInitialValues(link
|
|
85
|
+
? {
|
|
86
|
+
text: link.getTextContent(),
|
|
87
|
+
url: link.getURL(),
|
|
88
|
+
openInNewTab: link.getTarget() === '_blank',
|
|
89
|
+
}
|
|
90
|
+
: {
|
|
91
|
+
text: selection.getTextContent(),
|
|
92
|
+
url: '',
|
|
93
|
+
openInNewTab: defaultTarget === '_blank',
|
|
94
|
+
});
|
|
95
|
+
setOpen(true);
|
|
96
|
+
});
|
|
97
|
+
}, [editor, defaultTarget]);
|
|
98
|
+
const close = useCallback(() => {
|
|
99
|
+
editor.update(() => {
|
|
100
|
+
var _a;
|
|
101
|
+
const selection = (_a = selectionRef.current) === null || _a === void 0 ? void 0 : _a.clone();
|
|
102
|
+
if (selection) {
|
|
103
|
+
$setSelection(selection);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
setOpen(false);
|
|
107
|
+
}, [editor]);
|
|
108
|
+
const submit = useCallback(({ text, url, openInNewTab }) => {
|
|
109
|
+
editor.update(() => {
|
|
110
|
+
var _a;
|
|
111
|
+
const href = sanitizeUrl(url);
|
|
112
|
+
const spec = {
|
|
113
|
+
href,
|
|
114
|
+
attributes: linkAttributes(openInNewTab),
|
|
115
|
+
label: text || href,
|
|
116
|
+
};
|
|
117
|
+
const link = $getEditedLink(linkKeyRef.current);
|
|
118
|
+
const selection = (_a = selectionRef.current) === null || _a === void 0 ? void 0 : _a.clone();
|
|
119
|
+
if (link) {
|
|
120
|
+
$updateLink(link, spec);
|
|
121
|
+
}
|
|
122
|
+
else if (selection) {
|
|
123
|
+
$insertLink(selection, spec);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
setOpen(false);
|
|
127
|
+
}, [editor]);
|
|
128
|
+
const remove = useCallback(() => {
|
|
129
|
+
editor.update(() => {
|
|
130
|
+
const link = $getEditedLink(linkKeyRef.current);
|
|
131
|
+
if (link) {
|
|
132
|
+
link.getChildren().forEach(child => link.insertBefore(child));
|
|
133
|
+
link.remove();
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
setOpen(false);
|
|
137
|
+
}, [editor]);
|
|
138
|
+
return { open, editing, initialValues, show, close, submit, remove };
|
|
139
|
+
};
|
|
140
|
+
//# sourceMappingURL=use-link-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-link-plugin.js","sourceRoot":"","sources":["../../../../src/plugins/LinkPlugin/use-link-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,8 @@ export { default as EditorMaxIndentLevelPlugin } from './EditorMaxIndentLevelPlu
|
|
|
2
2
|
export { default as EmojiPlugin } from './EmojiPlugin';
|
|
3
3
|
export type { CustomEmoji, CustomEmojiGroup } from './EmojiPlugin';
|
|
4
4
|
export { default as HeadingsReplacementPlugin } from './HeadingsReplacementPlugin';
|
|
5
|
-
export { default as LinkPlugin
|
|
5
|
+
export { default as LinkPlugin } from './LinkPlugin';
|
|
6
|
+
export type { Props as LinkPluginProps } from './LinkPlugin';
|
|
6
7
|
export { default as ListPlugin } from './ListPlugin';
|
|
7
8
|
export { default as TextLengthPlugin } from './TextLengthPlugin';
|
|
8
9
|
export { default as TriggerInitialOnChangePlugin } from './TriggerInitialOnChangePlugin';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,8BAA8B,CAAA;AACpF,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAA;AACtD,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,6BAA6B,CAAA;AAClF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,KAAK,IAAI,eAAe,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,8BAA8B,CAAA;AACpF,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAA;AACtD,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,6BAA6B,CAAA;AAClF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,cAAc,CAAA;AACpD,YAAY,EAAE,KAAK,IAAI,eAAe,EAAE,MAAM,cAAc,CAAA;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,EAAE,OAAO,IAAI,4BAA4B,EAAE,MAAM,gCAAgC,CAAA;AACxF,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,2BAA2B,CAAA;AAC9E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAC9D,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,8BAA8B,CAAA;AACpF,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAA;AAEtD,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,6BAA6B,CAAA;AAClF,OAAO,EAAE,OAAO,IAAI,UAAU,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,0BAA0B,EAAE,MAAM,8BAA8B,CAAA;AACpF,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAA;AAEtD,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,6BAA6B,CAAA;AAClF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,cAAc,CAAA;AAEpD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAChE,OAAO,EAAE,OAAO,IAAI,4BAA4B,EAAE,MAAM,gCAAgC,CAAA;AACxF,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,2BAA2B,CAAA;AAC9E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html-to-hast.js","sourceRoot":"","sources":["../../../src/utils/html-to-hast.ts"],"names":[],"mappings":"AACA,OAAO,YAAY,MAAM,oBAAoB,CAAA;AAC7C,OAAO,WAAW,MAAM,oBAAoB,CAAA;AAI5C,MAAM,CAAC,MAAM,kBAAkB,GAAW;IACxC,aAAa,EAAE,KAAK;IACpB,aAAa,EAAE,KAAK;IACpB,SAAS,EAAE;QACT,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;KACjB;IACD,UAAU,EAAE;QACV,CAAC,EAAE,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"html-to-hast.js","sourceRoot":"","sources":["../../../src/utils/html-to-hast.ts"],"names":[],"mappings":"AACA,OAAO,YAAY,MAAM,oBAAoB,CAAA;AAC7C,OAAO,WAAW,MAAM,oBAAoB,CAAA;AAI5C,MAAM,CAAC,MAAM,kBAAkB,GAAW;IACxC,aAAa,EAAE,KAAK;IACpB,aAAa,EAAE,KAAK;IACpB,SAAS,EAAE;QACT,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;KACjB;IACD,UAAU,EAAE;QACV,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC;QAC5B,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC;QACrC,GAAG,EAAE,EAAE;KACR;IACD,QAAQ,EAAE;QACR,IAAI;QACJ,GAAG;QACH,IAAI;QACJ,QAAQ;QACR,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,GAAG;QACH,KAAK;QACL,MAAM;QACN,KAAK;KACN;IACD,KAAK,EAAE,CAAC,QAAQ,CAAC;CAClB,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,EAAE;IACjC,MAAM,GAAG,GAAG,IAAI,SAAS,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;IAC9D,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,kBAAkB,CAEtD,CAAA;IAEhB,MAAM,GAAG,GAAY;QACnB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;KACjE,CAAA;IAED,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA;AAED,eAAe,SAAS,CAAA"}
|