@jpmorganchase/mosaic-content-editor-plugin 0.1.0-beta.37 → 0.1.0-beta.39
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/.turbo/turbo-build.log +2 -2
- package/CHANGELOG.md +16 -0
- package/dist/api/save.d.ts +1 -1
- package/dist/api/save.js +1 -1
- package/dist/chunk-3QIETKQW.js +1 -0
- package/dist/chunk-4B2NDAA2.js +1 -0
- package/dist/chunk-4LQ77YZW.js +1 -0
- package/dist/chunk-6EO5B7QP.js +1 -0
- package/dist/chunk-6X665P47.js +1 -0
- package/dist/chunk-7JRJTNUG.js +1 -0
- package/dist/chunk-7LK4O57W.js +1 -0
- package/dist/chunk-B6MFPF7L.js +1 -0
- package/dist/chunk-BFF3MNBV.js +1 -0
- package/dist/chunk-BINIAABY.js +1 -0
- package/dist/chunk-DLRFTDUZ.js +1 -0
- package/dist/chunk-DXTVYP7D.js +1 -0
- package/dist/chunk-EMHRWY75.js +1 -0
- package/dist/chunk-FH2LMMJT.js +1 -0
- package/dist/chunk-FNNLNVQZ.js +1 -0
- package/dist/chunk-GYUEXLD6.js +1 -0
- package/dist/chunk-M4ISRNFD.js +1 -0
- package/dist/chunk-MZJ4JT73.js +1 -0
- package/dist/{chunk-GWUYDDYS.js → chunk-NFA3MZOC.js} +1 -1
- package/dist/chunk-NFSXCTUU.js +1 -0
- package/dist/chunk-OW5SK4AJ.js +1 -0
- package/dist/chunk-PXUVNH4P.js +1 -0
- package/dist/chunk-QHE4U3WR.js +1 -0
- package/dist/chunk-R2MEEU32.js +1 -0
- package/dist/chunk-ROQUYURQ.js +1 -0
- package/dist/chunk-SYL4AGHI.js +1 -0
- package/dist/chunk-TSWYSURQ.js +1 -0
- package/dist/chunk-UBWAGWSM.js +1 -0
- package/dist/chunk-WCOTJ6JY.js +1 -0
- package/dist/chunk-XSZUCLBY.js +1 -0
- package/dist/chunk-Y2A2ULLZ.js +1 -0
- package/dist/chunk-YIFLQ5MW.js +1 -0
- package/dist/chunk-Z6W7GDHE.js +1 -0
- package/dist/chunk-ZHZ4E2MI.js +1 -0
- package/dist/components/BaseToolbar/BaseToolbar.css +1 -0
- package/dist/components/BaseToolbar/BaseToolbar.css.css +1 -0
- package/dist/components/{Toolbar/TextFormatToolbarButton.css.d.ts → BaseToolbar/BaseToolbar.css.d.ts} +0 -1
- package/dist/components/BaseToolbar/BaseToolbar.css.js +1 -0
- package/dist/components/BaseToolbar/BaseToolbar.d.ts +7 -0
- package/dist/components/BaseToolbar/BaseToolbar.js +1 -0
- package/dist/components/BaseTooltray/BaseTooltray.css +1 -0
- package/dist/components/BaseTooltray/BaseTooltray.css.css +1 -0
- package/dist/components/BaseTooltray/BaseTooltray.css.d.ts +6 -0
- package/dist/components/BaseTooltray/BaseTooltray.css.js +1 -0
- package/dist/components/BaseTooltray/BaseTooltray.d.ts +9 -0
- package/dist/components/BaseTooltray/BaseTooltray.js +1 -0
- package/dist/components/ContentEditor.js +1 -1
- package/dist/components/Dialog.css +1 -0
- package/dist/components/Dialog.css.css +1 -0
- package/dist/components/Dialog.css.d.ts +4 -0
- package/dist/components/Dialog.css.js +1 -0
- package/dist/components/Dialog.d.ts +6 -0
- package/dist/components/Dialog.js +1 -0
- package/dist/components/Editor.css +1 -1
- package/dist/components/Editor.d.ts +3 -2
- package/dist/components/Editor.js +1 -1
- package/dist/components/EditorControls.css +1 -1
- package/dist/components/EditorControls.css.css +1 -1
- package/dist/components/EditorControls.css.js +1 -1
- package/dist/components/EditorControls.d.ts +4 -3
- package/dist/components/EditorControls.js +1 -1
- package/dist/components/LinkEditor/EditLinkButton.css +1 -0
- package/dist/components/LinkEditor/EditLinkButton.d.ts +2 -2
- package/dist/components/LinkEditor/EditLinkButton.js +1 -1
- package/dist/components/LinkEditor/LinkEditor.css +1 -1
- package/dist/components/LinkEditor/LinkEditor.js +1 -1
- package/dist/components/LinkEditor/SaveAdornment.css +1 -0
- package/dist/components/LinkEditor/SaveAdornment.js +1 -1
- package/dist/components/PersistEditDialog/PersistStatus.js +1 -1
- package/dist/components/PersistEditDialog/index.css +1 -1
- package/dist/components/PersistEditDialog/index.css.css +1 -0
- package/dist/components/PersistEditDialog/index.css.d.ts +4 -0
- package/dist/components/PersistEditDialog/index.css.js +1 -0
- package/dist/components/PersistEditDialog/index.d.ts +5 -2
- package/dist/components/PersistEditDialog/index.js +1 -1
- package/dist/components/Popper/Popper.js +1 -1
- package/dist/components/Toolbar/InsertHorizontalRule.css +1 -0
- package/dist/components/Toolbar/InsertHorizontalRule.js +1 -1
- package/dist/components/Toolbar/InsertImage.css +1 -1
- package/dist/components/Toolbar/InsertImage.js +1 -1
- package/dist/components/Toolbar/InsertLink.css +1 -1
- package/dist/components/Toolbar/InsertLink.js +1 -1
- package/dist/components/Toolbar/InsertTable.css +1 -1
- package/dist/components/Toolbar/InsertTable.css.css +1 -1
- package/dist/components/Toolbar/InsertTable.css.d.ts +1 -1
- package/dist/components/Toolbar/InsertTable.css.js +1 -1
- package/dist/components/Toolbar/InsertTable.js +1 -1
- package/dist/components/Toolbar/TextFormatTooltray.css +1 -1
- package/dist/components/Toolbar/TextFormatTooltray.css.css +1 -1
- package/dist/components/Toolbar/TextFormatTooltray.css.d.ts +0 -1
- package/dist/components/Toolbar/TextFormatTooltray.css.js +1 -1
- package/dist/components/Toolbar/TextFormatTooltray.js +1 -1
- package/dist/components/Toolbar/Toolbar.css +1 -1
- package/dist/components/Toolbar/Toolbar.js +1 -1
- package/dist/components/Toolbar/ToolbarButton.css +1 -0
- package/dist/components/Toolbar/ToolbarButton.css.css +1 -0
- package/dist/components/Toolbar/ToolbarButton.css.d.ts +4 -0
- package/dist/components/Toolbar/ToolbarButton.css.js +1 -0
- package/dist/components/Toolbar/ToolbarButton.d.ts +8 -0
- package/dist/components/Toolbar/ToolbarButton.js +1 -0
- package/dist/components/Toolbar/ToolbarSeparator.css.css +1 -0
- package/dist/components/Toolbar/ToolbarSeparator.css.d.ts +4 -0
- package/dist/components/Toolbar/ToolbarSeparator.css.js +1 -0
- package/dist/components/Toolbar/ToolbarSepartor.css +1 -0
- package/dist/components/Toolbar/ToolbarSepartor.d.ts +7 -0
- package/dist/components/Toolbar/ToolbarSepartor.js +1 -0
- package/dist/index.css +1 -1
- package/dist/index.js +1 -1
- package/dist/plugins/FloatingToolbarPlugin.css +1 -1
- package/dist/plugins/FloatingToolbarPlugin.css.css +1 -0
- package/dist/plugins/FloatingToolbarPlugin.css.d.ts +4 -0
- package/dist/plugins/FloatingToolbarPlugin.css.js +1 -0
- package/dist/plugins/FloatingToolbarPlugin.js +1 -1
- package/dist/plugins/MarkdownLinkPlugin.css +1 -1
- package/dist/plugins/MarkdownLinkPlugin.js +1 -1
- package/dist/plugins/PreviewPlugin.css +1 -1
- package/dist/plugins/PreviewPlugin.d.ts +6 -5
- package/dist/plugins/PreviewPlugin.js +1 -1
- package/dist/plugins/TableActionMenuPlugin.js +1 -1
- package/dist/transformers/index.js +1 -1
- package/package.json +14 -13
- package/src/api/save.ts +4 -4
- package/src/components/BaseToolbar/BaseToolbar.css.ts +21 -0
- package/src/components/BaseToolbar/BaseToolbar.tsx +13 -0
- package/src/components/BaseTooltray/BaseTooltray.css.ts +31 -0
- package/src/components/BaseTooltray/BaseTooltray.tsx +22 -0
- package/src/components/ContentEditor.tsx +2 -0
- package/src/components/Dialog.css.ts +7 -0
- package/src/components/Dialog.tsx +12 -0
- package/src/components/Editor.tsx +10 -8
- package/src/components/EditorControls.css.ts +2 -5
- package/src/components/EditorControls.tsx +13 -7
- package/src/components/LinkEditor/EditLinkButton.tsx +5 -5
- package/src/components/LinkEditor/SaveAdornment.tsx +4 -3
- package/src/components/PersistEditDialog/PersistStatus.tsx +7 -2
- package/src/components/PersistEditDialog/index.css.ts +14 -0
- package/src/components/PersistEditDialog/index.tsx +37 -16
- package/src/components/Popper/Popper.tsx +6 -1
- package/src/components/Toolbar/InsertHorizontalRule.tsx +2 -2
- package/src/components/Toolbar/InsertImage.tsx +9 -8
- package/src/components/Toolbar/InsertLink.tsx +9 -8
- package/src/components/Toolbar/InsertTable.css.ts +8 -2
- package/src/components/Toolbar/InsertTable.tsx +9 -4
- package/src/components/Toolbar/TextFormatTooltray.css.ts +0 -5
- package/src/components/Toolbar/TextFormatTooltray.tsx +16 -21
- package/src/components/Toolbar/Toolbar.tsx +11 -6
- package/src/components/Toolbar/ToolbarButton.css.ts +11 -0
- package/src/components/Toolbar/ToolbarButton.tsx +41 -0
- package/src/components/Toolbar/ToolbarSeparator.css.ts +28 -0
- package/src/components/Toolbar/ToolbarSepartor.tsx +13 -0
- package/src/components/__tests__/EditorControls.test.tsx +4 -4
- package/src/plugins/FloatingToolbarPlugin.css.ts +14 -0
- package/src/plugins/FloatingToolbarPlugin.tsx +9 -8
- package/src/plugins/PreviewPlugin.tsx +31 -6
- package/dist/chunk-4CRC7NS5.js +0 -1
- package/dist/chunk-5JA4V4PV.js +0 -1
- package/dist/chunk-6TWGPQT5.js +0 -1
- package/dist/chunk-B3MUPQQA.js +0 -1
- package/dist/chunk-DK6F4XAE.js +0 -1
- package/dist/chunk-FFJYM47T.js +0 -1
- package/dist/chunk-FI57IKHZ.js +0 -1
- package/dist/chunk-HB6ONQSD.js +0 -1
- package/dist/chunk-HYOY3SMH.js +0 -1
- package/dist/chunk-JJ5K5LVL.js +0 -1
- package/dist/chunk-JYGEHLYM.js +0 -1
- package/dist/chunk-KD66I56W.js +0 -1
- package/dist/chunk-L5I3DIHV.js +0 -1
- package/dist/chunk-MJUOPD42.js +0 -1
- package/dist/chunk-MOZEUF74.js +0 -1
- package/dist/chunk-PMMRU33I.js +0 -1
- package/dist/chunk-PZZKTKIE.js +0 -1
- package/dist/chunk-R6U5TOP4.js +0 -1
- package/dist/chunk-SI5CM3F4.js +0 -1
- package/dist/chunk-VO6JTL4J.js +0 -1
- package/dist/chunk-WCG3U3X2.js +0 -1
- package/dist/chunk-WTMALWJU.js +0 -1
- package/dist/chunk-XGBC7YGO.js +0 -1
- package/dist/chunk-ZUGL4RMA.js +0 -1
- package/dist/components/Toolbar/TextFormatToolbarButton.css +0 -1
- package/dist/components/Toolbar/TextFormatToolbarButton.css.css +0 -1
- package/dist/components/Toolbar/TextFormatToolbarButton.css.js +0 -1
- package/dist/components/Toolbar/TextFormatToolbarButton.d.ts +0 -7
- package/dist/components/Toolbar/TextFormatToolbarButton.js +0 -1
- package/src/components/Toolbar/TextFormatToolbarButton.css.ts +0 -10
- package/src/components/Toolbar/TextFormatToolbarButton.tsx +0 -29
|
@@ -2,12 +2,14 @@ import React, { FC, useState } from 'react';
|
|
|
2
2
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
3
3
|
import { $convertToMarkdownString } from '@lexical/markdown';
|
|
4
4
|
import { Link, P2, Button } from '@jpmorganchase/mosaic-components';
|
|
5
|
-
import {
|
|
5
|
+
import { ButtonBar, DialogTitle, DialogContent, DialogActions } from '@salt-ds/lab';
|
|
6
6
|
|
|
7
7
|
import { useEditorUser, usePageState } from '../../store';
|
|
8
8
|
import { save } from '../../api/save';
|
|
9
9
|
import transformers from '../../transformers';
|
|
10
10
|
import { PersistStatus } from './PersistStatus';
|
|
11
|
+
import { Dialog } from '../Dialog';
|
|
12
|
+
import style from './index.css';
|
|
11
13
|
|
|
12
14
|
interface InfoProps {
|
|
13
15
|
isRaising: boolean;
|
|
@@ -30,7 +32,12 @@ const Info: FC<InfoProps> = ({ isRaising, prHref, error }) =>
|
|
|
30
32
|
</>
|
|
31
33
|
) : null;
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
interface PersistDialogProps {
|
|
36
|
+
meta: any;
|
|
37
|
+
persistUrl?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const PersistDialog = ({ meta, persistUrl }: PersistDialogProps) => {
|
|
34
41
|
const { pageState, setPageState } = usePageState();
|
|
35
42
|
const { user } = useEditorUser();
|
|
36
43
|
const [editor] = useLexicalComposerContext();
|
|
@@ -54,9 +61,14 @@ export const PersistDialog = ({ meta }: { meta: any }) => {
|
|
|
54
61
|
try {
|
|
55
62
|
editor.update(async () => {
|
|
56
63
|
const markdown = $convertToMarkdownString(transformers);
|
|
57
|
-
if (markdown && user) {
|
|
64
|
+
if (markdown && user && persistUrl) {
|
|
58
65
|
const { sid, displayName, email } = user;
|
|
59
|
-
const response = await save(
|
|
66
|
+
const response = await save(
|
|
67
|
+
{ sid, name: displayName, email },
|
|
68
|
+
meta.route,
|
|
69
|
+
markdown,
|
|
70
|
+
persistUrl
|
|
71
|
+
);
|
|
60
72
|
|
|
61
73
|
if (response.ok) {
|
|
62
74
|
const data = await response.json();
|
|
@@ -70,23 +82,26 @@ export const PersistDialog = ({ meta }: { meta: any }) => {
|
|
|
70
82
|
}
|
|
71
83
|
}
|
|
72
84
|
|
|
73
|
-
if (response.status === 500) {
|
|
74
|
-
|
|
85
|
+
if (response.status === 500 || response.status === 404) {
|
|
86
|
+
const errorText = await response.text();
|
|
87
|
+
setError(errorText);
|
|
75
88
|
setPrHref(null);
|
|
76
89
|
setIsRaising(false);
|
|
77
90
|
}
|
|
78
91
|
}
|
|
79
92
|
});
|
|
80
93
|
} catch (e) {
|
|
81
|
-
setError('Sorry');
|
|
94
|
+
setError('Sorry - an unexpected error has occurred');
|
|
82
95
|
setPrHref(null);
|
|
83
96
|
setIsRaising(false);
|
|
84
97
|
}
|
|
85
98
|
};
|
|
86
99
|
|
|
87
100
|
return (
|
|
88
|
-
<
|
|
89
|
-
<DialogTitle
|
|
101
|
+
<Dialog onClose={handleClose} open={open} status={error ? 'error' : state}>
|
|
102
|
+
<DialogTitle className={style.title}>
|
|
103
|
+
{!prHref ? 'Save Changes' : 'Pull Request Created Successfully'}
|
|
104
|
+
</DialogTitle>
|
|
90
105
|
<DialogContent>
|
|
91
106
|
{(isRaising || error) && !prHref && <PersistStatus isRaising={isRaising} error={error} />}
|
|
92
107
|
<Info isRaising={isRaising} prHref={prHref} error={error} />
|
|
@@ -97,13 +112,19 @@ export const PersistDialog = ({ meta }: { meta: any }) => {
|
|
|
97
112
|
)}
|
|
98
113
|
</DialogContent>
|
|
99
114
|
<DialogActions>
|
|
100
|
-
<
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
115
|
+
<ButtonBar>
|
|
116
|
+
<Button disabled={isRaising} onClick={handleClose}>
|
|
117
|
+
{!prHref ? 'Cancel' : 'Done'}
|
|
118
|
+
</Button>
|
|
119
|
+
<Button
|
|
120
|
+
disabled={persistUrl === undefined || isRaising || prHref !== null}
|
|
121
|
+
onClick={handleRaisePr}
|
|
122
|
+
variant="cta"
|
|
123
|
+
>
|
|
124
|
+
Raise Pull Request
|
|
125
|
+
</Button>
|
|
126
|
+
</ButtonBar>
|
|
106
127
|
</DialogActions>
|
|
107
|
-
</
|
|
128
|
+
</Dialog>
|
|
108
129
|
);
|
|
109
130
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { forwardRef, HTMLAttributes, ReactNode } from 'react';
|
|
2
2
|
import { Portal, useWindow } from '@salt-ds/lab';
|
|
3
|
+
import { themeClassName } from '@jpmorganchase/mosaic-theme';
|
|
3
4
|
import classnames from 'clsx';
|
|
4
5
|
|
|
5
6
|
import styles from './Popper.css';
|
|
@@ -23,7 +24,11 @@ export const Popper = forwardRef<HTMLDivElement, PopperProps>(function Popper(pr
|
|
|
23
24
|
|
|
24
25
|
return (
|
|
25
26
|
<Portal>
|
|
26
|
-
<Window
|
|
27
|
+
<Window
|
|
28
|
+
className={classnames(className, themeClassName, styles.root)}
|
|
29
|
+
ref={forwardedRef}
|
|
30
|
+
{...rest}
|
|
31
|
+
>
|
|
27
32
|
{children}
|
|
28
33
|
</Window>
|
|
29
34
|
</Portal>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { ToolbarButton } from '@salt-ds/lab';
|
|
3
2
|
import { Icon } from '@jpmorganchase/mosaic-components';
|
|
4
3
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
5
4
|
import { INSERT_HORIZONTAL_RULE_COMMAND } from '@lexical/react/LexicalHorizontalRuleNode';
|
|
5
|
+
import { ToolbarButton } from './ToolbarButton';
|
|
6
6
|
|
|
7
7
|
export const InsertHorizontalRule = () => {
|
|
8
8
|
const [editor] = useLexicalComposerContext();
|
|
@@ -11,7 +11,7 @@ export const InsertHorizontalRule = () => {
|
|
|
11
11
|
editor.dispatchCommand(INSERT_HORIZONTAL_RULE_COMMAND, undefined);
|
|
12
12
|
};
|
|
13
13
|
return (
|
|
14
|
-
<ToolbarButton onClick={handleClick}>
|
|
14
|
+
<ToolbarButton onClick={handleClick} label="Insert Divider">
|
|
15
15
|
<Icon name="minimize" />
|
|
16
16
|
</ToolbarButton>
|
|
17
17
|
);
|
|
@@ -4,14 +4,15 @@ import { Button, Icon } from '@jpmorganchase/mosaic-components';
|
|
|
4
4
|
import { string, object } from 'yup';
|
|
5
5
|
import {
|
|
6
6
|
ButtonBar,
|
|
7
|
-
Dialog as SaltDialog,
|
|
8
7
|
DialogTitle,
|
|
9
8
|
DialogContent,
|
|
10
|
-
DialogActions
|
|
9
|
+
DialogActions,
|
|
10
|
+
FormField,
|
|
11
|
+
Input
|
|
11
12
|
} from '@salt-ds/lab';
|
|
12
|
-
import { FormField, Input } from '@salt-ds/lab';
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import { ToolbarButton } from './ToolbarButton';
|
|
15
|
+
import { Dialog } from '../Dialog';
|
|
15
16
|
import {
|
|
16
17
|
INSERT_MARKDOWN_IMAGE_COMMAND,
|
|
17
18
|
InsertImagePayload
|
|
@@ -89,11 +90,11 @@ export const InsertImage = () => {
|
|
|
89
90
|
|
|
90
91
|
return (
|
|
91
92
|
<>
|
|
92
|
-
<
|
|
93
|
+
<ToolbarButton active={isOpen} onClick={handleOpen} label="Insert Image">
|
|
93
94
|
<Icon name="addDocument" />
|
|
94
|
-
</
|
|
95
|
+
</ToolbarButton>
|
|
95
96
|
|
|
96
|
-
<
|
|
97
|
+
<Dialog onClose={handleClose} open={isOpen} width={600}>
|
|
97
98
|
<form onSubmit={handleSubmit} noValidate>
|
|
98
99
|
<DialogTitle>Insert Image</DialogTitle>
|
|
99
100
|
<DialogContent>
|
|
@@ -126,7 +127,7 @@ export const InsertImage = () => {
|
|
|
126
127
|
</ButtonBar>
|
|
127
128
|
</DialogActions>
|
|
128
129
|
</form>
|
|
129
|
-
</
|
|
130
|
+
</Dialog>
|
|
130
131
|
</>
|
|
131
132
|
);
|
|
132
133
|
};
|
|
@@ -2,20 +2,21 @@ import React, { useEffect, useState } from 'react';
|
|
|
2
2
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
3
3
|
import { Button, Icon } from '@jpmorganchase/mosaic-components';
|
|
4
4
|
import { string, object } from 'yup';
|
|
5
|
-
import { FormField, Input } from '@salt-ds/lab';
|
|
6
5
|
import {
|
|
6
|
+
FormField,
|
|
7
|
+
Input,
|
|
7
8
|
ButtonBar,
|
|
8
|
-
Dialog as SaltDialog,
|
|
9
9
|
DialogTitle,
|
|
10
10
|
DialogContent,
|
|
11
11
|
DialogActions
|
|
12
12
|
} from '@salt-ds/lab';
|
|
13
13
|
import { $getSelection, $isRangeSelection } from 'lexical';
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import { ToolbarButton } from './ToolbarButton';
|
|
16
|
+
import { Dialog } from '../Dialog';
|
|
16
17
|
import { INSERT_MARKDOWN_LINK_COMMAND, InsertLinkPayload } from '../../plugins/MarkdownLinkPlugin';
|
|
17
|
-
import styles from './InsertLink.css';
|
|
18
18
|
import { useIsInsertingLink } from '../../store';
|
|
19
|
+
import styles from './InsertLink.css';
|
|
19
20
|
|
|
20
21
|
const validationSchema = object({
|
|
21
22
|
url: string().required('Url is required'),
|
|
@@ -25,13 +26,13 @@ const validationSchema = object({
|
|
|
25
26
|
export const InsertLinkButton = () => {
|
|
26
27
|
const { isInsertingLink, setIsInsertingLink } = useIsInsertingLink();
|
|
27
28
|
return (
|
|
28
|
-
<
|
|
29
|
+
<ToolbarButton
|
|
29
30
|
active={isInsertingLink}
|
|
30
31
|
onClick={() => setIsInsertingLink(true)}
|
|
31
32
|
label="Insert Link"
|
|
32
33
|
>
|
|
33
34
|
<Icon name="linked" />
|
|
34
|
-
</
|
|
35
|
+
</ToolbarButton>
|
|
35
36
|
);
|
|
36
37
|
};
|
|
37
38
|
|
|
@@ -110,7 +111,7 @@ export const InsertLinkDialog = () => {
|
|
|
110
111
|
};
|
|
111
112
|
|
|
112
113
|
return (
|
|
113
|
-
<
|
|
114
|
+
<Dialog onClose={handleClose} open={isInsertingLink} width={600}>
|
|
114
115
|
<form onSubmit={handleSubmit} noValidate>
|
|
115
116
|
<DialogTitle>Insert Link</DialogTitle>
|
|
116
117
|
<DialogContent>
|
|
@@ -140,6 +141,6 @@ export const InsertLinkDialog = () => {
|
|
|
140
141
|
</ButtonBar>
|
|
141
142
|
</DialogActions>
|
|
142
143
|
</form>
|
|
143
|
-
</
|
|
144
|
+
</Dialog>
|
|
144
145
|
);
|
|
145
146
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { style } from '@vanilla-extract/css';
|
|
1
|
+
import { globalStyle, style } from '@vanilla-extract/css';
|
|
2
2
|
import {
|
|
3
3
|
selectableColor,
|
|
4
4
|
table,
|
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
foregroundColor
|
|
9
9
|
} from '@jpmorganchase/mosaic-theme';
|
|
10
10
|
|
|
11
|
+
const button = style({ width: vars.space.horizontal.x10 });
|
|
12
|
+
|
|
11
13
|
export default {
|
|
12
14
|
tableContainer: style({
|
|
13
15
|
position: 'relative',
|
|
@@ -42,5 +44,9 @@ export default {
|
|
|
42
44
|
foregroundColor({ variant: 'high' })
|
|
43
45
|
]),
|
|
44
46
|
popper: style([style({ zIndex: 1600 }), backgroundColor({ variant: 'regular' })]),
|
|
45
|
-
|
|
47
|
+
button
|
|
46
48
|
};
|
|
49
|
+
|
|
50
|
+
globalStyle(`${button} > *:not(:first-child)`, {
|
|
51
|
+
marginLeft: vars.space.horizontal.x1
|
|
52
|
+
});
|
|
@@ -6,7 +6,7 @@ import { INSERT_TABLE_COMMAND } from '@lexical/table';
|
|
|
6
6
|
import { useFloatingUI } from '@salt-ds/core';
|
|
7
7
|
import { useDismiss, useInteractions } from '@floating-ui/react';
|
|
8
8
|
import { Popper } from '../Popper/Popper';
|
|
9
|
-
import {
|
|
9
|
+
import { ToolbarButton } from './ToolbarButton';
|
|
10
10
|
import styles from './InsertTable.css';
|
|
11
11
|
|
|
12
12
|
interface IndexableEntity {
|
|
@@ -143,11 +143,16 @@ export const InsertTable: FC<InsertTableProps> = ({
|
|
|
143
143
|
|
|
144
144
|
return (
|
|
145
145
|
<>
|
|
146
|
-
<
|
|
146
|
+
<ToolbarButton
|
|
147
|
+
className={styles.button}
|
|
148
|
+
ref={reference}
|
|
149
|
+
onClick={togglePopper}
|
|
150
|
+
active={isOpen}
|
|
151
|
+
label="Insert Table"
|
|
152
|
+
>
|
|
147
153
|
<Icon name="grid" />
|
|
148
|
-
<div className={styles.spacer} />
|
|
149
154
|
<Icon name="chevronDown" />
|
|
150
|
-
</
|
|
155
|
+
</ToolbarButton>
|
|
151
156
|
<Popper
|
|
152
157
|
className={styles.popper}
|
|
153
158
|
ref={floating}
|
|
@@ -2,11 +2,6 @@ import { style } from '@vanilla-extract/css';
|
|
|
2
2
|
import { vars, code } from '@jpmorganchase/mosaic-theme';
|
|
3
3
|
|
|
4
4
|
export default {
|
|
5
|
-
// Salt wraps all Tooltray items in a Formfields which adds default padding
|
|
6
|
-
// Tooltray needs refactoring so the user can compose Formfields themselves.
|
|
7
|
-
root: style({
|
|
8
|
-
margin: '-8px 0px 0px 0px'
|
|
9
|
-
}),
|
|
10
5
|
icon: style({
|
|
11
6
|
width: '14px',
|
|
12
7
|
fontSize: '12px'
|
|
@@ -15,8 +15,8 @@ import { $isHeadingNode } from '@lexical/rich-text';
|
|
|
15
15
|
import { $isCodeNode } from '@lexical/code';
|
|
16
16
|
import { Icon } from '@jpmorganchase/mosaic-components';
|
|
17
17
|
|
|
18
|
-
import { Tooltray } from '
|
|
19
|
-
import {
|
|
18
|
+
import { BaseTooltray as Tooltray } from '../BaseTooltray/BaseTooltray';
|
|
19
|
+
import { ToolbarButton } from './ToolbarButton';
|
|
20
20
|
import styles from './TextFormatTooltray.css';
|
|
21
21
|
import { InsertBlockDropdown } from './InsertBlockDropdown';
|
|
22
22
|
|
|
@@ -88,31 +88,26 @@ export function TextFormatTooltray({ floating = false }) {
|
|
|
88
88
|
);
|
|
89
89
|
|
|
90
90
|
return (
|
|
91
|
-
|
|
92
|
-
{!floating
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
91
|
+
<>
|
|
92
|
+
{!floating && (
|
|
93
|
+
<Tooltray>
|
|
94
|
+
<InsertBlockDropdown editor={activeEditor} type={blockType} />
|
|
95
|
+
</Tooltray>
|
|
96
|
+
)}
|
|
97
|
+
<Tooltray>
|
|
98
|
+
<ToolbarButton active={isBold} onClick={() => handleFormat('bold')} label="Bold">
|
|
96
99
|
<span className={classnames(styles.icon, styles.bold)}>B</span>
|
|
97
|
-
</
|
|
98
|
-
<
|
|
99
|
-
active={isItalic}
|
|
100
|
-
onClick={() => handleFormat('italic')}
|
|
101
|
-
label="Italic"
|
|
102
|
-
>
|
|
100
|
+
</ToolbarButton>
|
|
101
|
+
<ToolbarButton active={isItalic} onClick={() => handleFormat('italic')} label="Italic">
|
|
103
102
|
<span className={classnames(styles.icon, styles.italic)}>I</span>
|
|
104
|
-
</
|
|
105
|
-
<
|
|
106
|
-
active={isCode}
|
|
107
|
-
onClick={() => handleFormat('code')}
|
|
108
|
-
label="Inline Code"
|
|
109
|
-
>
|
|
103
|
+
</ToolbarButton>
|
|
104
|
+
<ToolbarButton active={isCode} onClick={() => handleFormat('code')} label="Inline Code">
|
|
110
105
|
<span className={classnames(styles.code)}>
|
|
111
106
|
<Icon name="chevronLeft" />
|
|
112
107
|
<Icon name="chevronRight" />
|
|
113
108
|
</span>
|
|
114
|
-
</
|
|
109
|
+
</ToolbarButton>
|
|
115
110
|
</Tooltray>
|
|
116
|
-
|
|
111
|
+
</>
|
|
117
112
|
);
|
|
118
113
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Toolbar as SaltToolbar, ToolbarButton, Tooltray } from '@salt-ds/lab';
|
|
3
2
|
import { Icon } from '@jpmorganchase/mosaic-components';
|
|
4
|
-
|
|
5
3
|
import { useEditHistory } from '../../hooks/useEditHistory';
|
|
6
4
|
import { usePageState } from '../../store';
|
|
7
5
|
import { SaveButton } from '../SaveButton';
|
|
@@ -10,13 +8,17 @@ import { InsertTable } from './InsertTable';
|
|
|
10
8
|
import { InsertImage } from './InsertImage';
|
|
11
9
|
import { InsertLinkButton } from './InsertLink';
|
|
12
10
|
import { InsertHorizontalRule } from './InsertHorizontalRule';
|
|
11
|
+
import { BaseToolbar } from '../BaseToolbar/BaseToolbar';
|
|
12
|
+
import { BaseTooltray as Tooltray } from '../BaseTooltray/BaseTooltray';
|
|
13
|
+
import { ToolbarButton } from './ToolbarButton';
|
|
14
|
+
import { ToolbarSeparator } from './ToolbarSepartor';
|
|
13
15
|
|
|
14
16
|
const Toolbar = () => {
|
|
15
17
|
const { canRedo, canUndo, redoEdit, undoEdit } = useEditHistory();
|
|
16
18
|
const { setPageState } = usePageState();
|
|
17
19
|
|
|
18
20
|
return (
|
|
19
|
-
<
|
|
21
|
+
<BaseToolbar aria-label="page editing toolbar">
|
|
20
22
|
<Tooltray aria-label="history tooltray">
|
|
21
23
|
<ToolbarButton label="Undo" disabled={!canUndo} onClick={undoEdit}>
|
|
22
24
|
<Icon name="undo" />
|
|
@@ -24,6 +26,7 @@ const Toolbar = () => {
|
|
|
24
26
|
<ToolbarButton label="Redo" disabled={!canRedo} onClick={redoEdit}>
|
|
25
27
|
<Icon name="redo" />
|
|
26
28
|
</ToolbarButton>
|
|
29
|
+
<ToolbarSeparator />
|
|
27
30
|
</Tooltray>
|
|
28
31
|
<TextFormatTooltray />
|
|
29
32
|
<Tooltray aria-label="text format tooltray">
|
|
@@ -31,16 +34,18 @@ const Toolbar = () => {
|
|
|
31
34
|
<InsertTable />
|
|
32
35
|
<InsertImage />
|
|
33
36
|
<InsertHorizontalRule />
|
|
37
|
+
<ToolbarSeparator />
|
|
34
38
|
</Tooltray>
|
|
35
|
-
<Tooltray aria-label="stop editing tooltray"
|
|
39
|
+
<Tooltray aria-label="stop editing tooltray" align="right">
|
|
36
40
|
<ToolbarButton label="Cancel Editing" onClick={() => setPageState('VIEW')}>
|
|
37
41
|
<Icon name="delete" />
|
|
38
42
|
</ToolbarButton>
|
|
43
|
+
<ToolbarSeparator />
|
|
39
44
|
</Tooltray>
|
|
40
|
-
<Tooltray aria-label="copy tooltray"
|
|
45
|
+
<Tooltray aria-label="copy tooltray">
|
|
41
46
|
<SaveButton />
|
|
42
47
|
</Tooltray>
|
|
43
|
-
</
|
|
48
|
+
</BaseToolbar>
|
|
44
49
|
);
|
|
45
50
|
};
|
|
46
51
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React, { forwardRef, Ref } from 'react';
|
|
2
|
+
import classnames from 'clsx';
|
|
3
|
+
import { Button, type ButtonProps, Label } from '@jpmorganchase/mosaic-components';
|
|
4
|
+
|
|
5
|
+
import styles from './ToolbarButton.css';
|
|
6
|
+
|
|
7
|
+
export interface ToolbarButtonProps extends ButtonProps {
|
|
8
|
+
active?: boolean;
|
|
9
|
+
label?: string;
|
|
10
|
+
disableTooltip?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const ToolbarButton = forwardRef(
|
|
14
|
+
(
|
|
15
|
+
{
|
|
16
|
+
active,
|
|
17
|
+
className,
|
|
18
|
+
onClick,
|
|
19
|
+
children,
|
|
20
|
+
label,
|
|
21
|
+
disabled,
|
|
22
|
+
disableTooltip = disabled,
|
|
23
|
+
...rest
|
|
24
|
+
}: ToolbarButtonProps,
|
|
25
|
+
ref: Ref<HTMLButtonElement>
|
|
26
|
+
) => (
|
|
27
|
+
<Label tooltip={!disableTooltip} TooltipProps={{ title: label, placement: 'bottom' }}>
|
|
28
|
+
<Button
|
|
29
|
+
aria-label={label}
|
|
30
|
+
ref={ref}
|
|
31
|
+
onClick={onClick}
|
|
32
|
+
className={classnames(className, styles.root)}
|
|
33
|
+
variant={active ? 'regular' : 'secondary'}
|
|
34
|
+
disabled={disabled}
|
|
35
|
+
{...rest}
|
|
36
|
+
>
|
|
37
|
+
{children}
|
|
38
|
+
</Button>
|
|
39
|
+
</Label>
|
|
40
|
+
)
|
|
41
|
+
);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { style } from '@vanilla-extract/css';
|
|
2
|
+
import { vars, beforeElementColorSprinkles } from '@jpmorganchase/mosaic-theme';
|
|
3
|
+
|
|
4
|
+
const beforeElementBackground = beforeElementColorSprinkles({
|
|
5
|
+
backgroundColor: {
|
|
6
|
+
lightMode: vars.color.dark.neutral.foreground.low,
|
|
7
|
+
darkMode: vars.color.light.neutral.foreground.low
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
root: style([
|
|
13
|
+
beforeElementBackground,
|
|
14
|
+
style({
|
|
15
|
+
selectors: {
|
|
16
|
+
'&:before': {
|
|
17
|
+
content: '""',
|
|
18
|
+
position: 'absolute',
|
|
19
|
+
background: 'inherit',
|
|
20
|
+
top: '6px',
|
|
21
|
+
right: 0,
|
|
22
|
+
width: '1px',
|
|
23
|
+
height: vars.space.vertical.x6
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
])
|
|
28
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React, { type ReactNode } from 'react';
|
|
2
|
+
import classnames from 'clsx';
|
|
3
|
+
|
|
4
|
+
import styles from './ToolbarSeparator.css';
|
|
5
|
+
|
|
6
|
+
interface ToolbarSeparatorProps {
|
|
7
|
+
className?: string;
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const ToolbarSeparator = ({ className, ...rest }: ToolbarSeparatorProps) => (
|
|
12
|
+
<div className={classnames(className, styles.root)} {...rest} />
|
|
13
|
+
);
|
|
@@ -23,7 +23,7 @@ describe('GIVEN an EditorControls component', () => {
|
|
|
23
23
|
});
|
|
24
24
|
});
|
|
25
25
|
test('THEN the edit button is disabled', () => {
|
|
26
|
-
render(<EditorControls
|
|
26
|
+
render(<EditorControls enabled={false} />);
|
|
27
27
|
const tooltips = screen.queryAllByRole('tooltip');
|
|
28
28
|
expect(tooltips.length).toBe(0);
|
|
29
29
|
});
|
|
@@ -31,7 +31,7 @@ describe('GIVEN an EditorControls component', () => {
|
|
|
31
31
|
|
|
32
32
|
describe('WHEN logged in', () => {
|
|
33
33
|
test('THEN the edit button is enabled', () => {
|
|
34
|
-
render(<EditorControls
|
|
34
|
+
render(<EditorControls enabled />);
|
|
35
35
|
const button = screen.getByRole('button');
|
|
36
36
|
expect(button).not.toBeDisabled();
|
|
37
37
|
});
|
|
@@ -44,7 +44,7 @@ describe('GIVEN an EditorControls component', () => {
|
|
|
44
44
|
});
|
|
45
45
|
});
|
|
46
46
|
test('THEN editing is started', async () => {
|
|
47
|
-
render(<EditorControls
|
|
47
|
+
render(<EditorControls enabled />);
|
|
48
48
|
const button = screen.getByLabelText('start editing');
|
|
49
49
|
await userEvent.click(button);
|
|
50
50
|
expect(startEditingSpy).toHaveBeenCalledTimes(1);
|
|
@@ -59,7 +59,7 @@ describe('GIVEN an EditorControls component', () => {
|
|
|
59
59
|
});
|
|
60
60
|
});
|
|
61
61
|
test('THEN editing is stopped', async () => {
|
|
62
|
-
render(<EditorControls
|
|
62
|
+
render(<EditorControls enabled />);
|
|
63
63
|
const button = screen.getByLabelText('cancel editing');
|
|
64
64
|
await userEvent.click(button);
|
|
65
65
|
expect(stopEditingSpy).toHaveBeenCalledTimes(1);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { vars } from '@jpmorganchase/mosaic-theme';
|
|
2
|
+
import { globalStyle, style } from '@vanilla-extract/css';
|
|
3
|
+
|
|
4
|
+
const toolbar = style({
|
|
5
|
+
minWidth: '100px'
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export default {
|
|
9
|
+
toolbar
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
globalStyle(`${toolbar} > *:not(:first-child)`, {
|
|
13
|
+
marginLeft: vars.space.horizontal.none
|
|
14
|
+
});
|
|
@@ -7,13 +7,14 @@ import {
|
|
|
7
7
|
COMMAND_PRIORITY_LOW,
|
|
8
8
|
SELECTION_CHANGE_COMMAND
|
|
9
9
|
} from 'lexical';
|
|
10
|
-
import {
|
|
11
|
-
import { flip, inline } from '@floating-ui/react';
|
|
10
|
+
import { flip, inline, useInteractions, useDismiss } from '@floating-ui/react';
|
|
12
11
|
import { useFloatingUI, UseFloatingUIProps } from '@salt-ds/core';
|
|
13
|
-
import { useInteractions, useDismiss } from '@floating-ui/react';
|
|
14
12
|
import { Popper } from '../components/Popper/Popper';
|
|
15
13
|
import { TextFormatTooltray } from '../components/Toolbar/TextFormatTooltray';
|
|
16
14
|
import { InsertLinkButton } from '../components/Toolbar/InsertLink';
|
|
15
|
+
import { BaseToolbar as Toolbar } from '../components/BaseToolbar/BaseToolbar';
|
|
16
|
+
import { BaseTooltray as Tooltray } from '../components/BaseTooltray/BaseTooltray';
|
|
17
|
+
import styles from './FloatingToolbarPlugin.css';
|
|
17
18
|
|
|
18
19
|
export function FloatingToolbarPlugin(): JSX.Element | null {
|
|
19
20
|
const [editor] = useLexicalComposerContext();
|
|
@@ -50,7 +51,7 @@ export function FloatingToolbarPlugin(): JSX.Element | null {
|
|
|
50
51
|
const selection = $getSelection();
|
|
51
52
|
const nativeSelection = window.getSelection();
|
|
52
53
|
const anchorEl = nativeSelection?.anchorNode?.parentElement;
|
|
53
|
-
if ($isRangeSelection(selection) && anchorEl) {
|
|
54
|
+
if ($isRangeSelection(selection) && anchorEl && !nativeSelection?.isCollapsed) {
|
|
54
55
|
reference(anchorEl);
|
|
55
56
|
const getRange = nativeSelection.getRangeAt(0);
|
|
56
57
|
const { x, y, height } = getRange.getBoundingClientRect();
|
|
@@ -89,12 +90,12 @@ export function FloatingToolbarPlugin(): JSX.Element | null {
|
|
|
89
90
|
}
|
|
90
91
|
return (
|
|
91
92
|
<Popper ref={floating} open={open} style={style} {...getFloatingProps({})}>
|
|
92
|
-
<
|
|
93
|
+
<Toolbar aria-label="page editing toolbar" className={styles.toolbar}>
|
|
93
94
|
<TextFormatTooltray floating />
|
|
94
|
-
<
|
|
95
|
+
<Tooltray aria-label="text format tooltray">
|
|
95
96
|
<InsertLinkButton />
|
|
96
|
-
</
|
|
97
|
-
</
|
|
97
|
+
</Tooltray>
|
|
98
|
+
</Toolbar>
|
|
98
99
|
</Popper>
|
|
99
100
|
);
|
|
100
101
|
}
|