@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.
Files changed (189) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/CHANGELOG.md +16 -0
  3. package/dist/api/save.d.ts +1 -1
  4. package/dist/api/save.js +1 -1
  5. package/dist/chunk-3QIETKQW.js +1 -0
  6. package/dist/chunk-4B2NDAA2.js +1 -0
  7. package/dist/chunk-4LQ77YZW.js +1 -0
  8. package/dist/chunk-6EO5B7QP.js +1 -0
  9. package/dist/chunk-6X665P47.js +1 -0
  10. package/dist/chunk-7JRJTNUG.js +1 -0
  11. package/dist/chunk-7LK4O57W.js +1 -0
  12. package/dist/chunk-B6MFPF7L.js +1 -0
  13. package/dist/chunk-BFF3MNBV.js +1 -0
  14. package/dist/chunk-BINIAABY.js +1 -0
  15. package/dist/chunk-DLRFTDUZ.js +1 -0
  16. package/dist/chunk-DXTVYP7D.js +1 -0
  17. package/dist/chunk-EMHRWY75.js +1 -0
  18. package/dist/chunk-FH2LMMJT.js +1 -0
  19. package/dist/chunk-FNNLNVQZ.js +1 -0
  20. package/dist/chunk-GYUEXLD6.js +1 -0
  21. package/dist/chunk-M4ISRNFD.js +1 -0
  22. package/dist/chunk-MZJ4JT73.js +1 -0
  23. package/dist/{chunk-GWUYDDYS.js → chunk-NFA3MZOC.js} +1 -1
  24. package/dist/chunk-NFSXCTUU.js +1 -0
  25. package/dist/chunk-OW5SK4AJ.js +1 -0
  26. package/dist/chunk-PXUVNH4P.js +1 -0
  27. package/dist/chunk-QHE4U3WR.js +1 -0
  28. package/dist/chunk-R2MEEU32.js +1 -0
  29. package/dist/chunk-ROQUYURQ.js +1 -0
  30. package/dist/chunk-SYL4AGHI.js +1 -0
  31. package/dist/chunk-TSWYSURQ.js +1 -0
  32. package/dist/chunk-UBWAGWSM.js +1 -0
  33. package/dist/chunk-WCOTJ6JY.js +1 -0
  34. package/dist/chunk-XSZUCLBY.js +1 -0
  35. package/dist/chunk-Y2A2ULLZ.js +1 -0
  36. package/dist/chunk-YIFLQ5MW.js +1 -0
  37. package/dist/chunk-Z6W7GDHE.js +1 -0
  38. package/dist/chunk-ZHZ4E2MI.js +1 -0
  39. package/dist/components/BaseToolbar/BaseToolbar.css +1 -0
  40. package/dist/components/BaseToolbar/BaseToolbar.css.css +1 -0
  41. package/dist/components/{Toolbar/TextFormatToolbarButton.css.d.ts → BaseToolbar/BaseToolbar.css.d.ts} +0 -1
  42. package/dist/components/BaseToolbar/BaseToolbar.css.js +1 -0
  43. package/dist/components/BaseToolbar/BaseToolbar.d.ts +7 -0
  44. package/dist/components/BaseToolbar/BaseToolbar.js +1 -0
  45. package/dist/components/BaseTooltray/BaseTooltray.css +1 -0
  46. package/dist/components/BaseTooltray/BaseTooltray.css.css +1 -0
  47. package/dist/components/BaseTooltray/BaseTooltray.css.d.ts +6 -0
  48. package/dist/components/BaseTooltray/BaseTooltray.css.js +1 -0
  49. package/dist/components/BaseTooltray/BaseTooltray.d.ts +9 -0
  50. package/dist/components/BaseTooltray/BaseTooltray.js +1 -0
  51. package/dist/components/ContentEditor.js +1 -1
  52. package/dist/components/Dialog.css +1 -0
  53. package/dist/components/Dialog.css.css +1 -0
  54. package/dist/components/Dialog.css.d.ts +4 -0
  55. package/dist/components/Dialog.css.js +1 -0
  56. package/dist/components/Dialog.d.ts +6 -0
  57. package/dist/components/Dialog.js +1 -0
  58. package/dist/components/Editor.css +1 -1
  59. package/dist/components/Editor.d.ts +3 -2
  60. package/dist/components/Editor.js +1 -1
  61. package/dist/components/EditorControls.css +1 -1
  62. package/dist/components/EditorControls.css.css +1 -1
  63. package/dist/components/EditorControls.css.js +1 -1
  64. package/dist/components/EditorControls.d.ts +4 -3
  65. package/dist/components/EditorControls.js +1 -1
  66. package/dist/components/LinkEditor/EditLinkButton.css +1 -0
  67. package/dist/components/LinkEditor/EditLinkButton.d.ts +2 -2
  68. package/dist/components/LinkEditor/EditLinkButton.js +1 -1
  69. package/dist/components/LinkEditor/LinkEditor.css +1 -1
  70. package/dist/components/LinkEditor/LinkEditor.js +1 -1
  71. package/dist/components/LinkEditor/SaveAdornment.css +1 -0
  72. package/dist/components/LinkEditor/SaveAdornment.js +1 -1
  73. package/dist/components/PersistEditDialog/PersistStatus.js +1 -1
  74. package/dist/components/PersistEditDialog/index.css +1 -1
  75. package/dist/components/PersistEditDialog/index.css.css +1 -0
  76. package/dist/components/PersistEditDialog/index.css.d.ts +4 -0
  77. package/dist/components/PersistEditDialog/index.css.js +1 -0
  78. package/dist/components/PersistEditDialog/index.d.ts +5 -2
  79. package/dist/components/PersistEditDialog/index.js +1 -1
  80. package/dist/components/Popper/Popper.js +1 -1
  81. package/dist/components/Toolbar/InsertHorizontalRule.css +1 -0
  82. package/dist/components/Toolbar/InsertHorizontalRule.js +1 -1
  83. package/dist/components/Toolbar/InsertImage.css +1 -1
  84. package/dist/components/Toolbar/InsertImage.js +1 -1
  85. package/dist/components/Toolbar/InsertLink.css +1 -1
  86. package/dist/components/Toolbar/InsertLink.js +1 -1
  87. package/dist/components/Toolbar/InsertTable.css +1 -1
  88. package/dist/components/Toolbar/InsertTable.css.css +1 -1
  89. package/dist/components/Toolbar/InsertTable.css.d.ts +1 -1
  90. package/dist/components/Toolbar/InsertTable.css.js +1 -1
  91. package/dist/components/Toolbar/InsertTable.js +1 -1
  92. package/dist/components/Toolbar/TextFormatTooltray.css +1 -1
  93. package/dist/components/Toolbar/TextFormatTooltray.css.css +1 -1
  94. package/dist/components/Toolbar/TextFormatTooltray.css.d.ts +0 -1
  95. package/dist/components/Toolbar/TextFormatTooltray.css.js +1 -1
  96. package/dist/components/Toolbar/TextFormatTooltray.js +1 -1
  97. package/dist/components/Toolbar/Toolbar.css +1 -1
  98. package/dist/components/Toolbar/Toolbar.js +1 -1
  99. package/dist/components/Toolbar/ToolbarButton.css +1 -0
  100. package/dist/components/Toolbar/ToolbarButton.css.css +1 -0
  101. package/dist/components/Toolbar/ToolbarButton.css.d.ts +4 -0
  102. package/dist/components/Toolbar/ToolbarButton.css.js +1 -0
  103. package/dist/components/Toolbar/ToolbarButton.d.ts +8 -0
  104. package/dist/components/Toolbar/ToolbarButton.js +1 -0
  105. package/dist/components/Toolbar/ToolbarSeparator.css.css +1 -0
  106. package/dist/components/Toolbar/ToolbarSeparator.css.d.ts +4 -0
  107. package/dist/components/Toolbar/ToolbarSeparator.css.js +1 -0
  108. package/dist/components/Toolbar/ToolbarSepartor.css +1 -0
  109. package/dist/components/Toolbar/ToolbarSepartor.d.ts +7 -0
  110. package/dist/components/Toolbar/ToolbarSepartor.js +1 -0
  111. package/dist/index.css +1 -1
  112. package/dist/index.js +1 -1
  113. package/dist/plugins/FloatingToolbarPlugin.css +1 -1
  114. package/dist/plugins/FloatingToolbarPlugin.css.css +1 -0
  115. package/dist/plugins/FloatingToolbarPlugin.css.d.ts +4 -0
  116. package/dist/plugins/FloatingToolbarPlugin.css.js +1 -0
  117. package/dist/plugins/FloatingToolbarPlugin.js +1 -1
  118. package/dist/plugins/MarkdownLinkPlugin.css +1 -1
  119. package/dist/plugins/MarkdownLinkPlugin.js +1 -1
  120. package/dist/plugins/PreviewPlugin.css +1 -1
  121. package/dist/plugins/PreviewPlugin.d.ts +6 -5
  122. package/dist/plugins/PreviewPlugin.js +1 -1
  123. package/dist/plugins/TableActionMenuPlugin.js +1 -1
  124. package/dist/transformers/index.js +1 -1
  125. package/package.json +14 -13
  126. package/src/api/save.ts +4 -4
  127. package/src/components/BaseToolbar/BaseToolbar.css.ts +21 -0
  128. package/src/components/BaseToolbar/BaseToolbar.tsx +13 -0
  129. package/src/components/BaseTooltray/BaseTooltray.css.ts +31 -0
  130. package/src/components/BaseTooltray/BaseTooltray.tsx +22 -0
  131. package/src/components/ContentEditor.tsx +2 -0
  132. package/src/components/Dialog.css.ts +7 -0
  133. package/src/components/Dialog.tsx +12 -0
  134. package/src/components/Editor.tsx +10 -8
  135. package/src/components/EditorControls.css.ts +2 -5
  136. package/src/components/EditorControls.tsx +13 -7
  137. package/src/components/LinkEditor/EditLinkButton.tsx +5 -5
  138. package/src/components/LinkEditor/SaveAdornment.tsx +4 -3
  139. package/src/components/PersistEditDialog/PersistStatus.tsx +7 -2
  140. package/src/components/PersistEditDialog/index.css.ts +14 -0
  141. package/src/components/PersistEditDialog/index.tsx +37 -16
  142. package/src/components/Popper/Popper.tsx +6 -1
  143. package/src/components/Toolbar/InsertHorizontalRule.tsx +2 -2
  144. package/src/components/Toolbar/InsertImage.tsx +9 -8
  145. package/src/components/Toolbar/InsertLink.tsx +9 -8
  146. package/src/components/Toolbar/InsertTable.css.ts +8 -2
  147. package/src/components/Toolbar/InsertTable.tsx +9 -4
  148. package/src/components/Toolbar/TextFormatTooltray.css.ts +0 -5
  149. package/src/components/Toolbar/TextFormatTooltray.tsx +16 -21
  150. package/src/components/Toolbar/Toolbar.tsx +11 -6
  151. package/src/components/Toolbar/ToolbarButton.css.ts +11 -0
  152. package/src/components/Toolbar/ToolbarButton.tsx +41 -0
  153. package/src/components/Toolbar/ToolbarSeparator.css.ts +28 -0
  154. package/src/components/Toolbar/ToolbarSepartor.tsx +13 -0
  155. package/src/components/__tests__/EditorControls.test.tsx +4 -4
  156. package/src/plugins/FloatingToolbarPlugin.css.ts +14 -0
  157. package/src/plugins/FloatingToolbarPlugin.tsx +9 -8
  158. package/src/plugins/PreviewPlugin.tsx +31 -6
  159. package/dist/chunk-4CRC7NS5.js +0 -1
  160. package/dist/chunk-5JA4V4PV.js +0 -1
  161. package/dist/chunk-6TWGPQT5.js +0 -1
  162. package/dist/chunk-B3MUPQQA.js +0 -1
  163. package/dist/chunk-DK6F4XAE.js +0 -1
  164. package/dist/chunk-FFJYM47T.js +0 -1
  165. package/dist/chunk-FI57IKHZ.js +0 -1
  166. package/dist/chunk-HB6ONQSD.js +0 -1
  167. package/dist/chunk-HYOY3SMH.js +0 -1
  168. package/dist/chunk-JJ5K5LVL.js +0 -1
  169. package/dist/chunk-JYGEHLYM.js +0 -1
  170. package/dist/chunk-KD66I56W.js +0 -1
  171. package/dist/chunk-L5I3DIHV.js +0 -1
  172. package/dist/chunk-MJUOPD42.js +0 -1
  173. package/dist/chunk-MOZEUF74.js +0 -1
  174. package/dist/chunk-PMMRU33I.js +0 -1
  175. package/dist/chunk-PZZKTKIE.js +0 -1
  176. package/dist/chunk-R6U5TOP4.js +0 -1
  177. package/dist/chunk-SI5CM3F4.js +0 -1
  178. package/dist/chunk-VO6JTL4J.js +0 -1
  179. package/dist/chunk-WCG3U3X2.js +0 -1
  180. package/dist/chunk-WTMALWJU.js +0 -1
  181. package/dist/chunk-XGBC7YGO.js +0 -1
  182. package/dist/chunk-ZUGL4RMA.js +0 -1
  183. package/dist/components/Toolbar/TextFormatToolbarButton.css +0 -1
  184. package/dist/components/Toolbar/TextFormatToolbarButton.css.css +0 -1
  185. package/dist/components/Toolbar/TextFormatToolbarButton.css.js +0 -1
  186. package/dist/components/Toolbar/TextFormatToolbarButton.d.ts +0 -7
  187. package/dist/components/Toolbar/TextFormatToolbarButton.js +0 -1
  188. package/src/components/Toolbar/TextFormatToolbarButton.css.ts +0 -10
  189. 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 { Dialog as SaltDialog, DialogTitle, DialogContent, DialogActions } from '@salt-ds/lab';
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
- export const PersistDialog = ({ meta }: { meta: any }) => {
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({ sid, name: displayName, email }, meta.route, markdown);
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
- setError('An unexpected error has occurred.');
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
- <SaltDialog onClose={handleClose} open={open} status={error ? 'error' : state} width="50%">
89
- <DialogTitle>{!prHref ? 'Save Changes' : 'Pull Request Created Successfully'}</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
- <Button disabled={isRaising} onClick={handleClose}>
101
- Cancel
102
- </Button>
103
- <Button disabled={isRaising || prHref !== null} onClick={handleRaisePr} variant="cta">
104
- Raise Pull Request
105
- </Button>
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
- </SaltDialog>
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 className={classnames(className, styles.root)} ref={forwardedRef} {...rest}>
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 { TextFormatToolbarButton } from './TextFormatToolbarButton';
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
- <TextFormatToolbarButton active={isOpen} onClick={handleOpen} label="Insert Image">
93
+ <ToolbarButton active={isOpen} onClick={handleOpen} label="Insert Image">
93
94
  <Icon name="addDocument" />
94
- </TextFormatToolbarButton>
95
+ </ToolbarButton>
95
96
 
96
- <SaltDialog onClose={handleClose} open={isOpen} width={600}>
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
- </SaltDialog>
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 { TextFormatToolbarButton } from './TextFormatToolbarButton';
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
- <TextFormatToolbarButton
29
+ <ToolbarButton
29
30
  active={isInsertingLink}
30
31
  onClick={() => setIsInsertingLink(true)}
31
32
  label="Insert Link"
32
33
  >
33
34
  <Icon name="linked" />
34
- </TextFormatToolbarButton>
35
+ </ToolbarButton>
35
36
  );
36
37
  };
37
38
 
@@ -110,7 +111,7 @@ export const InsertLinkDialog = () => {
110
111
  };
111
112
 
112
113
  return (
113
- <SaltDialog onClose={handleClose} open={isInsertingLink} width={600}>
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
- </SaltDialog>
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
- spacer: style({ marginLeft: vars.space.horizontal.x1 })
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 { TextFormatToolbarButton } from './TextFormatToolbarButton';
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
- <TextFormatToolbarButton ref={reference} onClick={togglePopper} active={isOpen}>
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
- </TextFormatToolbarButton>
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 '@salt-ds/lab';
19
- import { TextFormatToolbarButton } from './TextFormatToolbarButton';
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
- <div className={styles.root}>
92
- {!floating ? <span /> : null}
93
- <Tooltray data-collapsible="instant">
94
- {!floating && <InsertBlockDropdown editor={activeEditor} type={blockType} />}
95
- <TextFormatToolbarButton active={isBold} onClick={() => handleFormat('bold')} label="Bold">
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
- </TextFormatToolbarButton>
98
- <TextFormatToolbarButton
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
- </TextFormatToolbarButton>
105
- <TextFormatToolbarButton
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
- </TextFormatToolbarButton>
109
+ </ToolbarButton>
115
110
  </Tooltray>
116
- </div>
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
- <SaltToolbar aria-label="page editing toolbar" style={{ minWidth: '100px' }}>
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" alignEnd>
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" data-pad-start>
45
+ <Tooltray aria-label="copy tooltray">
41
46
  <SaveButton />
42
47
  </Tooltray>
43
- </SaltToolbar>
48
+ </BaseToolbar>
44
49
  );
45
50
  };
46
51
 
@@ -0,0 +1,11 @@
1
+ import { style } from '@vanilla-extract/css';
2
+ import { vars } from '@jpmorganchase/mosaic-theme';
3
+
4
+ export default {
5
+ root: style({
6
+ width: '28px',
7
+ height: '28px',
8
+ lineHeight: 1,
9
+ padding: vars.space.horizontal.none
10
+ })
11
+ };
@@ -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 isLoggedIn={false} />);
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 isLoggedIn />);
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 isLoggedIn />);
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 isLoggedIn />);
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 { Toolbar as SaltToolbar, Tooltray as SaltTooltray } from '@salt-ds/lab';
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
- <SaltToolbar aria-label="page editing toolbar" style={{ minWidth: '100px' }}>
93
+ <Toolbar aria-label="page editing toolbar" className={styles.toolbar}>
93
94
  <TextFormatTooltray floating />
94
- <SaltTooltray aria-label="text format tooltray">
95
+ <Tooltray aria-label="text format tooltray">
95
96
  <InsertLinkButton />
96
- </SaltTooltray>
97
- </SaltToolbar>
97
+ </Tooltray>
98
+ </Toolbar>
98
99
  </Popper>
99
100
  );
100
101
  }