@jpmorganchase/mosaic-content-editor-plugin 0.1.0-beta.72 → 0.1.0-beta.73

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 (70) hide show
  1. package/package.json +6 -3
  2. package/.turbo/turbo-build.log +0 -4
  3. package/CHANGELOG.md +0 -687
  4. package/src/components/ActionMenu/ActionMenu.css.ts +0 -9
  5. package/src/components/ActionMenu/ActionMenu.tsx +0 -26
  6. package/src/components/BaseToolbar/BaseToolbar.css.ts +0 -21
  7. package/src/components/BaseToolbar/BaseToolbar.tsx +0 -13
  8. package/src/components/BaseTooltray/BaseTooltray.css.ts +0 -31
  9. package/src/components/BaseTooltray/BaseTooltray.tsx +0 -22
  10. package/src/components/ContentEditor.tsx +0 -14
  11. package/src/components/Dialog.css.ts +0 -7
  12. package/src/components/Dialog.tsx +0 -12
  13. package/src/components/Editor.css.ts +0 -64
  14. package/src/components/Editor.tsx +0 -145
  15. package/src/components/EditorControls.css.ts +0 -6
  16. package/src/components/EditorControls.tsx +0 -37
  17. package/src/components/LinkEditor/EditLinkButton.tsx +0 -9
  18. package/src/components/LinkEditor/LinkEditor.css.ts +0 -15
  19. package/src/components/LinkEditor/LinkEditor.tsx +0 -136
  20. package/src/components/LinkEditor/SaveAdornment.tsx +0 -17
  21. package/src/components/PersistEditDialog/PersistStatus.css.ts +0 -21
  22. package/src/components/PersistEditDialog/PersistStatus.tsx +0 -57
  23. package/src/components/PersistEditDialog/__tests__/index.test.tsx +0 -90
  24. package/src/components/PersistEditDialog/index.css.ts +0 -14
  25. package/src/components/PersistEditDialog/index.tsx +0 -152
  26. package/src/components/Popper/Popper.css.ts +0 -12
  27. package/src/components/Popper/Popper.tsx +0 -36
  28. package/src/components/SaveButton.tsx +0 -23
  29. package/src/components/ScrollableSection/ScrollableSection.css.ts +0 -10
  30. package/src/components/ScrollableSection/ScrollableSection.tsx +0 -20
  31. package/src/components/StatusBanner.tsx +0 -16
  32. package/src/components/Toolbar/InsertBlockDropdown.tsx +0 -134
  33. package/src/components/Toolbar/InsertHorizontalRule.tsx +0 -18
  34. package/src/components/Toolbar/InsertImage.css.ts +0 -7
  35. package/src/components/Toolbar/InsertImage.tsx +0 -138
  36. package/src/components/Toolbar/InsertLink.css.ts +0 -7
  37. package/src/components/Toolbar/InsertLink.tsx +0 -148
  38. package/src/components/Toolbar/InsertTable.css.ts +0 -52
  39. package/src/components/Toolbar/InsertTable.tsx +0 -196
  40. package/src/components/Toolbar/TextFormatTooltray.css.ts +0 -22
  41. package/src/components/Toolbar/TextFormatTooltray.tsx +0 -113
  42. package/src/components/Toolbar/Toolbar.tsx +0 -52
  43. package/src/components/Toolbar/ToolbarButton.css.ts +0 -11
  44. package/src/components/Toolbar/ToolbarButton.tsx +0 -41
  45. package/src/components/Toolbar/ToolbarSeparator.css.ts +0 -28
  46. package/src/components/Toolbar/ToolbarSepartor.tsx +0 -13
  47. package/src/components/__tests__/EditorControls.test.tsx +0 -69
  48. package/src/components/__tests__/StatusBanner.test.tsx +0 -33
  49. package/src/hooks/useEditHistory.ts +0 -49
  50. package/src/hooks/useWorkflowFeed.ts +0 -69
  51. package/src/index.ts +0 -5
  52. package/src/nodes/index.ts +0 -23
  53. package/src/plugins/FloatingToolbarPlugin.css.ts +0 -14
  54. package/src/plugins/FloatingToolbarPlugin.tsx +0 -101
  55. package/src/plugins/HorizontalRulePlugin.tsx +0 -39
  56. package/src/plugins/MarkdownImagePlugin.tsx +0 -58
  57. package/src/plugins/MarkdownLinkPlugin.tsx +0 -69
  58. package/src/plugins/PreviewPlugin.tsx +0 -71
  59. package/src/plugins/TableActionMenuPlugin.css.ts +0 -29
  60. package/src/plugins/TableActionMenuPlugin.tsx +0 -274
  61. package/src/store/__tests__/index.test.ts +0 -171
  62. package/src/store/index.ts +0 -84
  63. package/src/theme/index.css.ts +0 -39
  64. package/src/theme/index.ts +0 -22
  65. package/src/transformers/horizontalRule.ts +0 -25
  66. package/src/transformers/index.ts +0 -6
  67. package/src/transformers/link.ts +0 -3
  68. package/src/transformers/tableRule.ts +0 -193
  69. package/src/utils/getSelectedNode.ts +0 -16
  70. package/tsconfig.json +0 -8
@@ -1,9 +0,0 @@
1
- import { style } from '@vanilla-extract/css';
2
-
3
- import { POPPER_Z_INDEX } from '../Popper/Popper.css';
4
-
5
- export default {
6
- menu: style({
7
- zIndex: POPPER_Z_INDEX + 1
8
- })
9
- };
@@ -1,26 +0,0 @@
1
- import React from 'react';
2
- import { MenuButton, MenuDescriptor } from '@salt-ds/lab';
3
- import { Icon } from '@jpmorganchase/mosaic-components';
4
-
5
- import type { CascadingMenuProps } from '@salt-ds/lab';
6
-
7
- export type ActionMenuSource = MenuDescriptor;
8
-
9
- interface ActionMenuProps {
10
- initialSource: CascadingMenuProps['initialSource'];
11
- onItemClick: CascadingMenuProps['onItemClick'];
12
- }
13
-
14
- export function ActionMenu({ initialSource, onItemClick }: ActionMenuProps) {
15
- return (
16
- <MenuButton
17
- hideCaret
18
- CascadingMenuProps={{
19
- initialSource,
20
- onItemClick
21
- }}
22
- >
23
- <Icon name="menu" />
24
- </MenuButton>
25
- );
26
- }
@@ -1,21 +0,0 @@
1
- import { globalStyle, style } from '@vanilla-extract/css';
2
- import { backgroundColor, vars } from '@jpmorganchase/mosaic-theme';
3
-
4
- const root = style([
5
- backgroundColor({ variant: 'emphasis' }),
6
- style({
7
- overflow: 'hidden',
8
- position: 'relative',
9
- display: 'flex',
10
- alignItems: 'center',
11
- padding: vars.space.horizontal.x1,
12
- height: '44px'
13
- })
14
- ]);
15
- export default {
16
- root
17
- };
18
-
19
- globalStyle(`${root} > *:not(:first-child)`, {
20
- marginLeft: vars.space.horizontal.x2
21
- });
@@ -1,13 +0,0 @@
1
- import React, { type ReactNode } from 'react';
2
- import classnames from 'clsx';
3
-
4
- import styles from './BaseToolbar.css';
5
-
6
- interface BaseToolbarProps {
7
- className?: string;
8
- children?: ReactNode;
9
- }
10
-
11
- export const BaseToolbar = ({ className, ...rest }: BaseToolbarProps) => (
12
- <div className={classnames(className, styles.root)} {...rest} />
13
- );
@@ -1,31 +0,0 @@
1
- import { globalStyle, style } from '@vanilla-extract/css';
2
- import { vars } from '@jpmorganchase/mosaic-theme';
3
-
4
- const root = style({
5
- background: 'inherit',
6
- display: 'flex',
7
- justifyContent: 'center',
8
- flexShrink: 0,
9
- flexGrow: 0,
10
- position: 'relative',
11
- overflow: 'hidden',
12
- padding: vars.space.horizontal.x1
13
- });
14
-
15
- export default {
16
- alignLeft: style({
17
- marginRight: 'auto'
18
- }),
19
- alignRight: style({
20
- selectors: {
21
- [`${root}&`]: {
22
- marginLeft: 'auto!important'
23
- }
24
- }
25
- }),
26
- root
27
- };
28
-
29
- globalStyle(`${root} > *:not(:first-child)`, {
30
- marginLeft: vars.space.horizontal.x1
31
- });
@@ -1,22 +0,0 @@
1
- import React, { type ReactNode } from 'react';
2
- import classnames from 'clsx';
3
-
4
- import styles from './BaseTooltray.css';
5
-
6
- type Alignment = 'left' | 'right';
7
-
8
- interface BaseTooltrayProps {
9
- className?: string;
10
- children?: ReactNode;
11
- align?: Alignment;
12
- }
13
-
14
- export const BaseTooltray = ({ className, align, ...rest }: BaseTooltrayProps) => (
15
- <div
16
- className={classnames(className, styles.root, {
17
- [styles.alignLeft]: align === 'left',
18
- [styles.alignRight]: align === 'right'
19
- })}
20
- {...rest}
21
- />
22
- );
@@ -1,14 +0,0 @@
1
- import * as React from 'react';
2
- import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
3
- import { ContentEditable } from '@lexical/react/LexicalContentEditable';
4
- import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary';
5
-
6
- const ContentEditor = () => (
7
- <RichTextPlugin
8
- contentEditable={<ContentEditable />}
9
- placeholder={<div>Enter some text...</div>}
10
- ErrorBoundary={LexicalErrorBoundary}
11
- />
12
- );
13
-
14
- export default ContentEditor;
@@ -1,7 +0,0 @@
1
- import { style } from '@vanilla-extract/css';
2
-
3
- export default {
4
- root: style({
5
- minWidth: 500
6
- })
7
- };
@@ -1,12 +0,0 @@
1
- import React from 'react';
2
- import { Dialog as SaltDialog, type DialogProps as SaltDialogProps } from '@salt-ds/core';
3
- import { themeClassName } from '@jpmorganchase/mosaic-theme';
4
- import classnames from 'clsx';
5
-
6
- import style from './Dialog.css';
7
-
8
- interface DialogProps extends SaltDialogProps {}
9
-
10
- export const Dialog = ({ className, ...props }: DialogProps) => (
11
- <SaltDialog className={classnames(themeClassName, style.root, className)} {...props} />
12
- );
@@ -1,64 +0,0 @@
1
- import { globalStyle, style } from '@vanilla-extract/css';
2
- import {
3
- vars,
4
- backgroundColor,
5
- neutralBorder,
6
- navigableBorder,
7
- config
8
- } from '@jpmorganchase/mosaic-theme';
9
-
10
- globalStyle('div[contenteditable]', {
11
- outline: 'none'
12
- });
13
-
14
- export default {
15
- root: style({
16
- display: 'grid',
17
- gridTemplateColumns: '1fr',
18
- gridTemplateRows: 'auto 1fr',
19
- gridTemplateAreas: '"toolbar" "editor" '
20
- }),
21
- toolbarContainer: style([
22
- style({
23
- gridArea: 'toolbar',
24
- position: 'sticky',
25
- top: `${config.appHeader.height}px`,
26
- zIndex: 2
27
- }),
28
- neutralBorder({
29
- variant: 'low',
30
- borderWidth: 'thin'
31
- })
32
- ]),
33
- editorRoot: style({
34
- display: 'flex',
35
- marginTop: vars.space.vertical.x3,
36
- flexWrap: 'wrap',
37
- gridArea: 'editor'
38
- }),
39
- splitter: style({
40
- display: 'flex',
41
- flexDirection: 'row'
42
- }),
43
- gutter: style([
44
- {
45
- backgroundRepeat: 'no-repeat',
46
- backgroundPosition: '50%',
47
- backgroundImage:
48
- 'url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==")',
49
- cursor: 'col-resize'
50
- },
51
- backgroundColor({ variant: 'emphasis' })
52
- ]),
53
- unfocused: neutralBorder({
54
- variant: 'low',
55
- borderTopWidth: 'thin',
56
- borderLeftWidth: 'thin',
57
- borderRightWidth: 'thin',
58
- borderBottomWidth: 'none'
59
- }),
60
- focused: navigableBorder({
61
- variant: 'focusRing',
62
- borderWidth: 'medium'
63
- })
64
- };
@@ -1,145 +0,0 @@
1
- import React, { ComponentType, FC, useRef, useState } from 'react';
2
- import classnames from 'clsx';
3
- import matter from 'gray-matter';
4
- import { LexicalComposer } from '@lexical/react/LexicalComposer';
5
- import { ListPlugin } from '@lexical/react/LexicalListPlugin';
6
- import { TablePlugin } from '@lexical/react/LexicalTablePlugin';
7
- import { LinkPlugin } from '@lexical/react/LexicalLinkPlugin';
8
- import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin';
9
- import { MarkdownShortcutPlugin } from '@lexical/react/LexicalMarkdownShortcutPlugin';
10
- import Split from 'react-split';
11
- import { $convertFromMarkdownString } from '@lexical/markdown';
12
-
13
- import transformers from '../transformers';
14
- import ContentEditor from './ContentEditor';
15
- import { nodes } from '../nodes';
16
- import { useEditorUser, usePreviewContent } from '../store';
17
- import { PreviewPlugin } from '../plugins/PreviewPlugin';
18
- import styles from './Editor.css';
19
- import Toolbar from './Toolbar/Toolbar';
20
- import theme from '../theme';
21
- import { PersistDialog } from './PersistEditDialog';
22
- import StatusBanner from './StatusBanner';
23
- import { MarkdownImagePlugin } from '../plugins/MarkdownImagePlugin';
24
- import { MarkdownLinkPlugin } from '../plugins/MarkdownLinkPlugin';
25
- import { LinkEditor } from './LinkEditor/LinkEditor';
26
- import { ScrollableSection } from './ScrollableSection/ScrollableSection';
27
- import HorizontalRulePlugin from '../plugins/HorizontalRulePlugin';
28
- import { FloatingToolbarPlugin } from '../plugins/FloatingToolbarPlugin';
29
- import { TableActionMenuPlugin } from '../plugins/TableActionMenuPlugin';
30
-
31
- function onError(error: Error) {
32
- console.error(error);
33
- }
34
-
35
- const initialConfig = {
36
- namespace: 'mosaic-content-editor',
37
- onError,
38
- nodes,
39
- theme
40
- };
41
-
42
- interface PreviewComponentProps {
43
- source: any;
44
- meta?: any;
45
- components: any;
46
- }
47
-
48
- interface EditorProps extends PreviewComponentProps {
49
- content: string;
50
- PreviewComponent?: ComponentType<PreviewComponentProps>;
51
- previewUrl?: string;
52
- persistUrl?: string;
53
- user?: any;
54
- }
55
-
56
- const gutter = () => {
57
- const gutter = document.createElement('div');
58
- gutter.className = styles.gutter;
59
- return gutter;
60
- };
61
-
62
- const Editor: FC<EditorProps> = ({
63
- components,
64
- content,
65
- persistUrl,
66
- PreviewComponent,
67
- previewUrl,
68
- source,
69
- user
70
- }) => {
71
- const previewContent = usePreviewContent() || source;
72
- const { setUser } = useEditorUser();
73
- const [focused, setFocused] = useState(false);
74
- const containerRef = useRef<HTMLDivElement | null>(null);
75
- const { data: meta, content: markdown } = matter(content);
76
-
77
- const handleEditorFocus = () => {
78
- setFocused(true);
79
- setUser(user);
80
- };
81
-
82
- const handleEditorBlur = () => {
83
- setFocused(false);
84
- };
85
-
86
- return (
87
- <LexicalComposer
88
- initialConfig={{
89
- ...initialConfig,
90
- editorState: () => $convertFromMarkdownString(markdown, transformers)
91
- }}
92
- >
93
- <div className={styles.root} onFocus={handleEditorFocus} onBlur={handleEditorBlur}>
94
- <div className={styles.toolbarContainer}>
95
- <Toolbar />
96
- <PersistDialog meta={meta} persistUrl={persistUrl} />
97
- <StatusBanner />
98
- </div>
99
- <div className={styles.editorRoot}>
100
- <Split
101
- className={styles.splitter}
102
- cursor="col-resize"
103
- direction="horizontal"
104
- dragInterval={1}
105
- expandToMin={false}
106
- gutter={gutter}
107
- gutterAlign="center"
108
- minSize={100}
109
- sizes={[50, 50]}
110
- snapOffset={30}
111
- >
112
- <ScrollableSection
113
- className={classnames({
114
- [styles.focused]: focused,
115
- [styles.unfocused]: !focused
116
- })}
117
- ref={containerRef}
118
- >
119
- <ContentEditor />
120
- </ScrollableSection>
121
- <ScrollableSection>
122
- {PreviewComponent && (
123
- <PreviewComponent source={previewContent} meta={meta} components={components} />
124
- )}
125
- </ScrollableSection>
126
- </Split>
127
- <HistoryPlugin />
128
- <ListPlugin />
129
- <TablePlugin />
130
- <LinkPlugin />
131
- <MarkdownShortcutPlugin transformers={transformers} />
132
- {previewUrl ? <PreviewPlugin previewUrl={previewUrl} /> : null}
133
- <MarkdownImagePlugin />
134
- <MarkdownLinkPlugin />
135
- <LinkEditor />
136
- <HorizontalRulePlugin />
137
- <FloatingToolbarPlugin />
138
- <TableActionMenuPlugin />
139
- </div>
140
- </div>
141
- </LexicalComposer>
142
- );
143
- };
144
-
145
- export default Editor;
@@ -1,6 +0,0 @@
1
- import { style } from '@vanilla-extract/css';
2
- import { backgroundColor, vars } from '@jpmorganchase/mosaic-theme';
3
-
4
- export default {
5
- root: style([backgroundColor({ variant: 'regular' }), style({ height: vars.space.vertical.x8 })])
6
- };
@@ -1,37 +0,0 @@
1
- import React from 'react';
2
- import { Icon } from '@jpmorganchase/mosaic-components';
3
- import { BaseToolbar as Toolbar } from './BaseToolbar/BaseToolbar';
4
- import { BaseTooltray as Tooltray } from './BaseTooltray/BaseTooltray';
5
- import { ToolbarButton } from './Toolbar/ToolbarButton';
6
-
7
- import { default as useContentEditor } from '../store';
8
- import styles from './EditorControls.css';
9
-
10
- export interface EditorControlsProps {
11
- enabled?: boolean;
12
- }
13
-
14
- export const EditorControls = ({ enabled = false }: EditorControlsProps) => {
15
- const { pageState, startEditing, stopEditing } = useContentEditor();
16
- const isEditing = pageState === 'EDIT';
17
-
18
- const handleClick = () => (!isEditing ? startEditing() : stopEditing());
19
-
20
- const enabledLabel = isEditing ? 'Cancel Editing' : 'Edit Page';
21
- const overflowLabel = !enabled ? 'Login Required to Edit' : enabledLabel;
22
-
23
- return (
24
- <Toolbar aria-label="editor-controls" className={styles.root}>
25
- <Tooltray aria-label="page editor controls tooltray">
26
- <ToolbarButton
27
- aria-label={isEditing ? 'cancel editing' : 'start editing'}
28
- onClick={handleClick}
29
- disabled={!enabled}
30
- label={overflowLabel}
31
- >
32
- <Icon name={isEditing ? 'delete' : 'edit'} />
33
- </ToolbarButton>
34
- </Tooltray>
35
- </Toolbar>
36
- );
37
- };
@@ -1,9 +0,0 @@
1
- import React from 'react';
2
- import { Icon } from '@jpmorganchase/mosaic-components';
3
- import { ToolbarButton, type ToolbarButtonProps } from '../Toolbar/ToolbarButton';
4
-
5
- export const EditLinkButton = (props: ToolbarButtonProps) => (
6
- <ToolbarButton {...props} aria-label="Edit link" disableTooltip variant="regular">
7
- <Icon name="edit" />
8
- </ToolbarButton>
9
- );
@@ -1,15 +0,0 @@
1
- import { style } from '@vanilla-extract/css';
2
- import { vars, neutralBorder } from '@jpmorganchase/mosaic-theme';
3
-
4
- export default {
5
- popper: style([
6
- style({
7
- padding: vars.space.vertical.x1,
8
- marginLeft: vars.space.horizontal.x2
9
- }),
10
- neutralBorder({
11
- variant: 'low',
12
- borderWidth: 'thin'
13
- })
14
- ])
15
- };
@@ -1,136 +0,0 @@
1
- import { mergeRegister } from '@lexical/utils';
2
- import {
3
- $getSelection,
4
- $isRangeSelection,
5
- COMMAND_PRIORITY_LOW,
6
- RangeSelection,
7
- SELECTION_CHANGE_COMMAND
8
- } from 'lexical';
9
- import React, { ChangeEvent, useCallback, useEffect, useRef, useState } from 'react';
10
- import { $isLinkNode, TOGGLE_LINK_COMMAND } from '@lexical/link';
11
- import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
12
- import { useFloatingUI, Input } from '@salt-ds/core';
13
- import { useDismiss, useInteractions } from '@floating-ui/react';
14
-
15
- import styles from './LinkEditor.css';
16
- import { SaveAdornment } from './SaveAdornment';
17
- import { EditLinkButton } from './EditLinkButton';
18
- import { Popper } from '../Popper/Popper';
19
- import { getSelectedNode } from '../../utils/getSelectedNode';
20
-
21
- export function LinkEditor() {
22
- const [editor] = useLexicalComposerContext();
23
- const inputRef = useRef<HTMLInputElement>(null);
24
- const [linkUrl, setLinkUrl] = useState('');
25
- const [isEdit, setIsEdit] = useState(false);
26
- const [lastSelection, setLastSelection] = useState<RangeSelection | null>(null);
27
-
28
- const reset = () => {
29
- setLinkUrl('');
30
- setIsEdit(false);
31
- setLastSelection(null);
32
- };
33
-
34
- const { context, floating, reference, strategy, x, y } = useFloatingUI({
35
- placement: 'right',
36
- strategy: 'absolute',
37
- open: linkUrl.length > 0,
38
- onOpenChange: reset
39
- });
40
- const { getFloatingProps } = useInteractions([
41
- useDismiss(context, {
42
- ancestorScroll: true
43
- })
44
- ]);
45
-
46
- const updateLinkEditor = useCallback(() => {
47
- const selection = $getSelection();
48
- if ($isRangeSelection(selection)) {
49
- const node = getSelectedNode(selection);
50
- const parent = node.getParent();
51
- if ($isLinkNode(parent)) {
52
- reference(editor.getElementByKey(parent.getKey()));
53
- setLinkUrl(parent.getURL());
54
- setLastSelection(selection);
55
- } else if ($isLinkNode(node)) {
56
- reference(editor.getElementByKey(node.getKey()));
57
- setLinkUrl(node.getURL());
58
- setLastSelection(selection);
59
- } else {
60
- // no links to edit on this selection
61
- reset();
62
- }
63
- }
64
- setIsEdit(false);
65
- return true;
66
- }, [editor, reference]);
67
-
68
- useEffect(
69
- () =>
70
- mergeRegister(
71
- editor.registerUpdateListener(({ editorState }) => {
72
- editorState.read(() => {
73
- updateLinkEditor();
74
- });
75
- }),
76
-
77
- editor.registerCommand(
78
- SELECTION_CHANGE_COMMAND,
79
- () => {
80
- updateLinkEditor();
81
- return true;
82
- },
83
- COMMAND_PRIORITY_LOW
84
- )
85
- ),
86
- [editor, updateLinkEditor]
87
- );
88
-
89
- useEffect(() => {
90
- editor.getEditorState().read(() => {
91
- updateLinkEditor();
92
- });
93
- }, [editor, updateLinkEditor]);
94
-
95
- const handleSave = () => {
96
- if (lastSelection !== null) {
97
- if (linkUrl !== '') {
98
- editor.dispatchCommand(TOGGLE_LINK_COMMAND, linkUrl);
99
- setIsEdit(false);
100
- }
101
- }
102
- };
103
-
104
- const handleEdit = () => setIsEdit(true);
105
-
106
- return (
107
- <Popper
108
- className={styles.popper}
109
- ref={floating}
110
- open={linkUrl.length > 0}
111
- style={{ top: y ?? '', left: x ?? '', position: strategy }}
112
- {...getFloatingProps({})}
113
- >
114
- {!isEdit ? (
115
- <EditLinkButton onClick={handleEdit} />
116
- ) : (
117
- <Input
118
- endAdornment={<SaveAdornment onSave={handleSave} />}
119
- ref={inputRef}
120
- value={linkUrl}
121
- onChange={(event: ChangeEvent<HTMLInputElement>) => {
122
- setLinkUrl(event.target.value);
123
- }}
124
- onKeyDown={event => {
125
- if (event.key === 'Enter') {
126
- event.preventDefault();
127
- handleSave();
128
- } else if (event.key === 'Escape') {
129
- event.preventDefault();
130
- }
131
- }}
132
- />
133
- )}
134
- </Popper>
135
- );
136
- }
@@ -1,17 +0,0 @@
1
- import React from 'react';
2
- import { Icon } from '@jpmorganchase/mosaic-components';
3
- import type { ButtonProps } from '@jpmorganchase/mosaic-components';
4
- import { StaticInputAdornment } from '@salt-ds/lab';
5
- import { ToolbarButton } from '../Toolbar/ToolbarButton';
6
-
7
- interface SaveAdornmentProps {
8
- onSave: ButtonProps['onClick'];
9
- }
10
-
11
- export const SaveAdornment = ({ onSave }: SaveAdornmentProps) => (
12
- <StaticInputAdornment>
13
- <ToolbarButton onClick={onSave} aria-label="save link changes" disableTooltip variant="regular">
14
- <Icon name="save" />
15
- </ToolbarButton>
16
- </StaticInputAdornment>
17
- );
@@ -1,21 +0,0 @@
1
- import { style } from '@vanilla-extract/css';
2
- import { vars } from '@jpmorganchase/mosaic-theme';
3
-
4
- export default {
5
- step: style({
6
- padding: vars.space.vertical.x2,
7
- opacity: vars.opacity.light.disabled
8
- }),
9
- stepActive: style({
10
- fontSize: vars.fontSize.s80,
11
- fontStyle: vars.fontWeight.semibold,
12
- opacity: 1
13
- }),
14
- stepComplete: style({
15
- opacity: 1
16
- }),
17
- stepText: style({
18
- marginLeft: vars.space.horizontal.x2,
19
- marginRight: vars.space.horizontal.x2
20
- })
21
- };
@@ -1,57 +0,0 @@
1
- import React, { FC, ReactNode } from 'react';
2
- import classnames from 'clsx';
3
- import { P2, P6 } from '@jpmorganchase/mosaic-components';
4
-
5
- import styles from './PersistStatus.css';
6
- import { SourceWorkflowMessageEvent } from '@jpmorganchase/mosaic-types';
7
-
8
- interface StepProps {
9
- children?: ReactNode;
10
- isComplete: boolean;
11
- isCurrent: boolean;
12
- }
13
-
14
- const Step: FC<StepProps> = ({ children, isComplete, isCurrent }) => (
15
- <div
16
- className={classnames(styles.step, {
17
- [styles.stepComplete]: isComplete,
18
- [styles.stepActive]: isCurrent
19
- })}
20
- >
21
- <span role="img" aria-label={isComplete ? 'emoji with party hat' : 'hourglass'}>
22
- {isComplete ? '🥳' : '⌛'}
23
- </span>
24
-
25
- <span className={styles.stepText}>{children}</span>
26
- </div>
27
- );
28
-
29
- interface StatusProps {
30
- error: string | null;
31
- progress: SourceWorkflowMessageEvent[];
32
- }
33
-
34
- export const PersistStatus = ({ error, progress }: StatusProps) => {
35
- if (error) {
36
- return (
37
- <>
38
- <P2>😢 Sorry something has went wrong. Please try again later.</P2>
39
- <P6>Error - {error}</P6>
40
- </>
41
- );
42
- }
43
-
44
- return (
45
- <>
46
- {progress.map((message, index) => (
47
- <Step
48
- key={`step -${index}`}
49
- isComplete={index < progress.length - 1}
50
- isCurrent={progress.length - 1 === index}
51
- >
52
- {message.message}
53
- </Step>
54
- ))}
55
- </>
56
- );
57
- };