@squiz/formatted-text-editor 1.12.0-alpha.40 → 1.12.0-alpha.9
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/README.md +56 -18
- package/lib/Editor/Editor.js +9 -3
- package/lib/EditorToolbar/EditorToolbar.js +1 -9
- package/lib/index.css +94 -800
- package/package.json +8 -12
- package/.eslintrc.json +0 -34
- package/CHANGELOG.md +0 -48
- package/build.js +0 -21
- package/cypress/e2e/bold.spec.cy.ts +0 -18
- package/cypress/global.d.ts +0 -9
- package/cypress/support/commands.ts +0 -130
- package/cypress/support/e2e.ts +0 -20
- package/cypress/tsconfig.json +0 -8
- package/cypress.config.ts +0 -7
- package/demo/App.tsx +0 -12
- package/demo/index.html +0 -13
- package/demo/index.scss +0 -1
- package/demo/main.tsx +0 -10
- package/demo/public/favicon-dxp.svg +0 -3
- package/demo/vite-env.d.ts +0 -1
- package/file-transformer.js +0 -1
- package/jest.config.ts +0 -27
- package/lib/EditorToolbar/Tools/Redo/RedoButton.d.ts +0 -2
- package/lib/EditorToolbar/Tools/Redo/RedoButton.js +0 -16
- package/lib/EditorToolbar/Tools/TextType/Heading/HeadingButton.d.ts +0 -5
- package/lib/EditorToolbar/Tools/TextType/Heading/HeadingButton.js +0 -32
- package/lib/EditorToolbar/Tools/TextType/Paragraph/ParagraphButton.d.ts +0 -2
- package/lib/EditorToolbar/Tools/TextType/Paragraph/ParagraphButton.js +0 -17
- package/lib/EditorToolbar/Tools/TextType/Preformatted/PreformattedButton.d.ts +0 -2
- package/lib/EditorToolbar/Tools/TextType/Preformatted/PreformattedButton.js +0 -16
- package/lib/EditorToolbar/Tools/TextType/TextTypeDropdown.d.ts +0 -2
- package/lib/EditorToolbar/Tools/TextType/TextTypeDropdown.js +0 -35
- package/lib/EditorToolbar/Tools/Undo/UndoButton.d.ts +0 -2
- package/lib/EditorToolbar/Tools/Undo/UndoButton.js +0 -16
- package/lib/Extensions/Extensions.d.ts +0 -3
- package/lib/Extensions/Extensions.js +0 -13
- package/lib/Extensions/PreformattedExtension/PreformattedExtension.d.ts +0 -10
- package/lib/Extensions/PreformattedExtension/PreformattedExtension.js +0 -46
- package/lib/ui/DropdownButton/DropdownButton.d.ts +0 -9
- package/lib/ui/DropdownButton/DropdownButton.js +0 -8
- package/lib/ui/ToolbarDropdown/ToolbarDropdown.d.ts +0 -7
- package/lib/ui/ToolbarDropdown/ToolbarDropdown.js +0 -12
- package/postcss.config.js +0 -3
- package/src/Editor/Editor.mock.tsx +0 -40
- package/src/Editor/Editor.spec.tsx +0 -254
- package/src/Editor/Editor.tsx +0 -32
- package/src/Editor/_editor.scss +0 -75
- package/src/EditorToolbar/EditorToolbar.tsx +0 -51
- package/src/EditorToolbar/Tools/Bold/BoldButton.spec.tsx +0 -19
- package/src/EditorToolbar/Tools/Bold/BoldButton.tsx +0 -30
- package/src/EditorToolbar/Tools/Italic/ItalicButton.spec.tsx +0 -19
- package/src/EditorToolbar/Tools/Italic/ItalicButton.tsx +0 -30
- package/src/EditorToolbar/Tools/Redo/RedoButton.spec.tsx +0 -59
- package/src/EditorToolbar/Tools/Redo/RedoButton.tsx +0 -30
- package/src/EditorToolbar/Tools/TextAlign/CenterAlign/CenterAlignButton.tsx +0 -31
- package/src/EditorToolbar/Tools/TextAlign/JustifyAlign/JustifyAlignButton.tsx +0 -31
- package/src/EditorToolbar/Tools/TextAlign/LeftAlign/LeftAlignButton.tsx +0 -31
- package/src/EditorToolbar/Tools/TextAlign/RightAlign/RightAlignButton.tsx +0 -31
- package/src/EditorToolbar/Tools/TextAlign/TextAlignButtons.tsx +0 -21
- package/src/EditorToolbar/Tools/TextType/Heading/HeadingButton.tsx +0 -52
- package/src/EditorToolbar/Tools/TextType/Paragraph/ParagraphButton.tsx +0 -26
- package/src/EditorToolbar/Tools/TextType/Preformatted/PreformattedButton.tsx +0 -30
- package/src/EditorToolbar/Tools/TextType/TextTypeDropdown.tsx +0 -44
- package/src/EditorToolbar/Tools/Underline/Underline.spec.tsx +0 -19
- package/src/EditorToolbar/Tools/Underline/UnderlineButton.tsx +0 -30
- package/src/EditorToolbar/Tools/Undo/UndoButton.spec.tsx +0 -49
- package/src/EditorToolbar/Tools/Undo/UndoButton.tsx +0 -30
- package/src/EditorToolbar/_editor-toolbar.scss +0 -19
- package/src/Extensions/Extensions.tsx +0 -24
- package/src/Extensions/PreformattedExtension/PreformattedExtension.tsx +0 -50
- package/src/FormattedTextEditor.spec.tsx +0 -10
- package/src/FormattedTextEditor.tsx +0 -12
- package/src/index.scss +0 -15
- package/src/index.ts +0 -3
- package/src/ui/DropdownButton/DropdownButton.tsx +0 -28
- package/src/ui/DropdownButton/_dropdown-button.scss +0 -7
- package/src/ui/ToolbarButton/ToolbarButton.tsx +0 -26
- package/src/ui/ToolbarButton/_toolbar-button.scss +0 -37
- package/src/ui/ToolbarDropdown/ToolbarDropdown.tsx +0 -32
- package/src/ui/ToolbarDropdown/_toolbar-dropdown.scss +0 -27
- package/tailwind.config.cjs +0 -62
- package/tsconfig.json +0 -22
- package/vite.config.ts +0 -19
@@ -1,59 +0,0 @@
|
|
1
|
-
import '@testing-library/jest-dom';
|
2
|
-
import { render, screen, fireEvent } from '@testing-library/react';
|
3
|
-
import Editor from '../../../Editor/Editor';
|
4
|
-
import React from 'react';
|
5
|
-
|
6
|
-
describe('Redo button', () => {
|
7
|
-
it('Renders the redo button', () => {
|
8
|
-
render(<Editor />);
|
9
|
-
expect(screen.getByRole('button', { name: 'Redo (shift+cmd+Z)' })).toBeInTheDocument();
|
10
|
-
});
|
11
|
-
|
12
|
-
it('Renders a disabled button if you have not made any changes yet', () => {
|
13
|
-
render(<Editor />);
|
14
|
-
const redo = screen.getByRole('button', { name: 'Redo (shift+cmd+Z)' });
|
15
|
-
expect(redo).toBeDisabled();
|
16
|
-
});
|
17
|
-
|
18
|
-
it('Enables the button when you perform an action and then revert it', () => {
|
19
|
-
const { baseElement } = render(<Editor />);
|
20
|
-
|
21
|
-
// perform some action
|
22
|
-
const leftAlignButton = baseElement.querySelector('button[title="Align left"]') as HTMLButtonElement;
|
23
|
-
expect(leftAlignButton).toBeTruthy();
|
24
|
-
fireEvent.click(leftAlignButton);
|
25
|
-
expect(baseElement.querySelector('p[data-node-text-align="left"]')).toBeTruthy();
|
26
|
-
|
27
|
-
// Revert this action
|
28
|
-
const undo = screen.getByRole('button', { name: 'Undo (cmd+Z)' });
|
29
|
-
fireEvent.click(undo);
|
30
|
-
expect(baseElement.querySelector('p[data-node-text-align="left"]')).toBeFalsy();
|
31
|
-
|
32
|
-
// Check that this enables the redo button
|
33
|
-
const redo = screen.getByRole('button', { name: 'Redo (shift+cmd+Z)' });
|
34
|
-
expect(redo).not.toBeDisabled();
|
35
|
-
});
|
36
|
-
|
37
|
-
it('Reverts this action when clicked', () => {
|
38
|
-
const { baseElement } = render(<Editor />);
|
39
|
-
|
40
|
-
// perform some action
|
41
|
-
const leftAlignButton = baseElement.querySelector('button[title="Align left"]') as HTMLButtonElement;
|
42
|
-
expect(leftAlignButton).toBeTruthy();
|
43
|
-
fireEvent.click(leftAlignButton);
|
44
|
-
expect(baseElement.querySelector('p[data-node-text-align="left"]')).toBeTruthy();
|
45
|
-
|
46
|
-
// Revert this action
|
47
|
-
const undo = screen.getByRole('button', { name: 'Undo (cmd+Z)' });
|
48
|
-
fireEvent.click(undo);
|
49
|
-
expect(baseElement.querySelector('p[data-node-text-align="left"]')).toBeFalsy();
|
50
|
-
|
51
|
-
// Check that this enables the redo button
|
52
|
-
const redo = screen.getByRole('button', { name: 'Redo (shift+cmd+Z)' });
|
53
|
-
expect(redo).not.toBeDisabled();
|
54
|
-
|
55
|
-
// Click the redo button and check that this has reverted the previous action
|
56
|
-
fireEvent.click(redo);
|
57
|
-
expect(baseElement.querySelector('p[data-node-text-align="left"]')).toBeTruthy();
|
58
|
-
});
|
59
|
-
});
|
@@ -1,30 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import { useCommands, useHelpers } from '@remirror/react';
|
3
|
-
import { HistoryExtension } from 'remirror/extensions';
|
4
|
-
import ToolbarButton from '../../../ui/ToolbarButton/ToolbarButton';
|
5
|
-
import RedoRoundedIcon from '@mui/icons-material/RedoRounded';
|
6
|
-
|
7
|
-
const RedoButton = () => {
|
8
|
-
const { redo } = useCommands<HistoryExtension>();
|
9
|
-
const { redoDepth } = useHelpers<HistoryExtension>(true);
|
10
|
-
|
11
|
-
const handleSelect = () => {
|
12
|
-
if (redo.enabled()) {
|
13
|
-
redo();
|
14
|
-
}
|
15
|
-
};
|
16
|
-
|
17
|
-
const enabled = redoDepth() > 0;
|
18
|
-
|
19
|
-
return (
|
20
|
-
<ToolbarButton
|
21
|
-
handleOnClick={handleSelect}
|
22
|
-
isDisabled={!enabled}
|
23
|
-
isActive={false}
|
24
|
-
icon={<RedoRoundedIcon />}
|
25
|
-
label="Redo (shift+cmd+Z)"
|
26
|
-
/>
|
27
|
-
);
|
28
|
-
};
|
29
|
-
|
30
|
-
export default RedoButton;
|
@@ -1,31 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import { useCommands, useChainedCommands } from '@remirror/react';
|
3
|
-
import { NodeFormattingExtension } from '@remirror/extension-node-formatting';
|
4
|
-
import ToolbarButton from '../../../../ui/ToolbarButton/ToolbarButton';
|
5
|
-
import FormatAlignCenterIcon from '@mui/icons-material/FormatAlignCenter';
|
6
|
-
|
7
|
-
const CenterAlignButton = () => {
|
8
|
-
const { centerAlign } = useCommands<NodeFormattingExtension>();
|
9
|
-
const chain = useChainedCommands();
|
10
|
-
|
11
|
-
const handleSelect = () => {
|
12
|
-
if (centerAlign.enabled()) {
|
13
|
-
chain.centerAlign().focus().run();
|
14
|
-
}
|
15
|
-
};
|
16
|
-
|
17
|
-
const active = centerAlign.active?.() || false;
|
18
|
-
const enabled = centerAlign.enabled();
|
19
|
-
|
20
|
-
return (
|
21
|
-
<ToolbarButton
|
22
|
-
handleOnClick={handleSelect}
|
23
|
-
isDisabled={!enabled}
|
24
|
-
isActive={active}
|
25
|
-
icon={<FormatAlignCenterIcon />}
|
26
|
-
label="Align center"
|
27
|
-
/>
|
28
|
-
);
|
29
|
-
};
|
30
|
-
|
31
|
-
export default CenterAlignButton;
|
@@ -1,31 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import { useCommands, useChainedCommands } from '@remirror/react';
|
3
|
-
import { NodeFormattingExtension } from '@remirror/extension-node-formatting';
|
4
|
-
import ToolbarButton from '../../../../ui/ToolbarButton/ToolbarButton';
|
5
|
-
import FormatAlignJustifyIcon from '@mui/icons-material/FormatAlignJustify';
|
6
|
-
|
7
|
-
const JustifyAlignButton = () => {
|
8
|
-
const { justifyAlign } = useCommands<NodeFormattingExtension>();
|
9
|
-
const chain = useChainedCommands();
|
10
|
-
|
11
|
-
const handleSelect = () => {
|
12
|
-
if (justifyAlign.enabled()) {
|
13
|
-
chain.justifyAlign().focus().run();
|
14
|
-
}
|
15
|
-
};
|
16
|
-
|
17
|
-
const active = justifyAlign.active?.() || false;
|
18
|
-
const enabled = justifyAlign.enabled();
|
19
|
-
|
20
|
-
return (
|
21
|
-
<ToolbarButton
|
22
|
-
handleOnClick={handleSelect}
|
23
|
-
isDisabled={!enabled}
|
24
|
-
isActive={active}
|
25
|
-
icon={<FormatAlignJustifyIcon />}
|
26
|
-
label="Justify"
|
27
|
-
/>
|
28
|
-
);
|
29
|
-
};
|
30
|
-
|
31
|
-
export default JustifyAlignButton;
|
@@ -1,31 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import { useCommands, useChainedCommands } from '@remirror/react';
|
3
|
-
import { NodeFormattingExtension } from '@remirror/extension-node-formatting';
|
4
|
-
import ToolbarButton from '../../../../ui/ToolbarButton/ToolbarButton';
|
5
|
-
import FormatAlignLeftIcon from '@mui/icons-material/FormatAlignLeft';
|
6
|
-
|
7
|
-
const LeftAlignButton = () => {
|
8
|
-
const { leftAlign } = useCommands<NodeFormattingExtension>();
|
9
|
-
const chain = useChainedCommands();
|
10
|
-
|
11
|
-
const handleSelect = () => {
|
12
|
-
if (leftAlign.enabled()) {
|
13
|
-
chain.leftAlign().focus().run();
|
14
|
-
}
|
15
|
-
};
|
16
|
-
|
17
|
-
const active = leftAlign.active?.() || false;
|
18
|
-
const enabled = leftAlign.enabled();
|
19
|
-
|
20
|
-
return (
|
21
|
-
<ToolbarButton
|
22
|
-
handleOnClick={handleSelect}
|
23
|
-
isDisabled={!enabled}
|
24
|
-
isActive={active}
|
25
|
-
icon={<FormatAlignLeftIcon />}
|
26
|
-
label="Align left"
|
27
|
-
/>
|
28
|
-
);
|
29
|
-
};
|
30
|
-
|
31
|
-
export default LeftAlignButton;
|
@@ -1,31 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import { useCommands, useChainedCommands } from '@remirror/react';
|
3
|
-
import { NodeFormattingExtension } from '@remirror/extension-node-formatting';
|
4
|
-
import ToolbarButton from '../../../../ui/ToolbarButton/ToolbarButton';
|
5
|
-
import FormatAlignRightIcon from '@mui/icons-material/FormatAlignRight';
|
6
|
-
|
7
|
-
const RightAlignButton = () => {
|
8
|
-
const { rightAlign } = useCommands<NodeFormattingExtension>();
|
9
|
-
const chain = useChainedCommands();
|
10
|
-
|
11
|
-
const handleSelect = () => {
|
12
|
-
if (rightAlign.enabled()) {
|
13
|
-
chain.rightAlign().focus().run();
|
14
|
-
}
|
15
|
-
};
|
16
|
-
|
17
|
-
const active = rightAlign.active?.() || false;
|
18
|
-
const enabled = rightAlign.enabled();
|
19
|
-
|
20
|
-
return (
|
21
|
-
<ToolbarButton
|
22
|
-
handleOnClick={handleSelect}
|
23
|
-
isDisabled={!enabled}
|
24
|
-
isActive={active}
|
25
|
-
icon={<FormatAlignRightIcon />}
|
26
|
-
label="Align right"
|
27
|
-
/>
|
28
|
-
);
|
29
|
-
};
|
30
|
-
|
31
|
-
export default RightAlignButton;
|
@@ -1,21 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import LeftAlignButton from './LeftAlign/LeftAlignButton';
|
3
|
-
import CenterAlignButton from './CenterAlign/CenterAlignButton';
|
4
|
-
import RightAlignButton from './RightAlign/RightAlignButton';
|
5
|
-
import JustifyAlignButton from './JustifyAlign/JustifyAlignButton';
|
6
|
-
import { VerticalDivider } from '@remirror/react-components';
|
7
|
-
|
8
|
-
const TextAlignButtons = () => {
|
9
|
-
return (
|
10
|
-
<>
|
11
|
-
<VerticalDivider className="editor-divider" />
|
12
|
-
<LeftAlignButton />
|
13
|
-
<CenterAlignButton />
|
14
|
-
<RightAlignButton />
|
15
|
-
<JustifyAlignButton />
|
16
|
-
<VerticalDivider className="editor-divider" />
|
17
|
-
</>
|
18
|
-
);
|
19
|
-
};
|
20
|
-
|
21
|
-
export default TextAlignButtons;
|
@@ -1,52 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import { useCommands, useChainedCommands, useActive } from '@remirror/react';
|
3
|
-
import { HeadingExtension } from '@remirror/extension-heading';
|
4
|
-
import DropdownButton from '../../../../ui/DropdownButton/DropdownButton';
|
5
|
-
|
6
|
-
type HeadingButtonProps = {
|
7
|
-
level: number;
|
8
|
-
};
|
9
|
-
|
10
|
-
const HeadingButton = ({ level }: HeadingButtonProps) => {
|
11
|
-
const { toggleHeading } = useCommands<HeadingExtension>();
|
12
|
-
const chain = useChainedCommands();
|
13
|
-
|
14
|
-
const active = useActive<HeadingExtension>();
|
15
|
-
const enabled = toggleHeading.enabled({ level });
|
16
|
-
|
17
|
-
const handleSelect = () => {
|
18
|
-
if (toggleHeading.enabled({ level })) {
|
19
|
-
chain.toggleHeading({ level }).focus().run();
|
20
|
-
}
|
21
|
-
};
|
22
|
-
|
23
|
-
const headingContent = () => {
|
24
|
-
switch (level) {
|
25
|
-
case 1:
|
26
|
-
return <h1>Heading 1</h1>;
|
27
|
-
case 2:
|
28
|
-
return <h2>Heading 2</h2>;
|
29
|
-
case 3:
|
30
|
-
return <h3>Heading 3</h3>;
|
31
|
-
case 4:
|
32
|
-
return <h4>Heading 4</h4>;
|
33
|
-
case 5:
|
34
|
-
return <h5>Heading 5</h5>;
|
35
|
-
case 6:
|
36
|
-
return <h6>Heading 6</h6>;
|
37
|
-
}
|
38
|
-
};
|
39
|
-
|
40
|
-
return (
|
41
|
-
<DropdownButton
|
42
|
-
handleOnClick={handleSelect}
|
43
|
-
isDisabled={!enabled}
|
44
|
-
isActive={active.heading({ level })}
|
45
|
-
label={`Heading ${level}`}
|
46
|
-
>
|
47
|
-
{headingContent()}
|
48
|
-
</DropdownButton>
|
49
|
-
);
|
50
|
-
};
|
51
|
-
|
52
|
-
export default HeadingButton;
|
@@ -1,26 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import { useCommands, useChainedCommands, useActive } from '@remirror/react';
|
3
|
-
import { ParagraphExtension } from '@remirror/extension-paragraph';
|
4
|
-
import DropdownButton from '../../../../ui/DropdownButton/DropdownButton';
|
5
|
-
|
6
|
-
const ParagraphButton = () => {
|
7
|
-
const { convertParagraph } = useCommands<ParagraphExtension>();
|
8
|
-
const chain = useChainedCommands();
|
9
|
-
|
10
|
-
const active = useActive<ParagraphExtension>();
|
11
|
-
const enabled = convertParagraph.enabled();
|
12
|
-
|
13
|
-
const handleSelect = () => {
|
14
|
-
if (convertParagraph.enabled()) {
|
15
|
-
chain.convertParagraph().focus().run();
|
16
|
-
}
|
17
|
-
};
|
18
|
-
|
19
|
-
return (
|
20
|
-
<DropdownButton handleOnClick={handleSelect} isDisabled={!enabled} isActive={active.paragraph()} label="Paragraph">
|
21
|
-
<p>Paragraph</p>
|
22
|
-
</DropdownButton>
|
23
|
-
);
|
24
|
-
};
|
25
|
-
|
26
|
-
export default ParagraphButton;
|
@@ -1,30 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import { useCommands, useActive } from '@remirror/react';
|
3
|
-
import { PreformattedExtension } from '../../../../Extensions/PreformattedExtension/PreformattedExtension';
|
4
|
-
import DropdownButton from '../../../../ui/DropdownButton/DropdownButton';
|
5
|
-
|
6
|
-
const PreformattedButton = () => {
|
7
|
-
const { togglePreformatted } = useCommands<PreformattedExtension>();
|
8
|
-
|
9
|
-
const active = useActive<PreformattedExtension>();
|
10
|
-
const enabled = togglePreformatted.enabled();
|
11
|
-
|
12
|
-
const handleSelect = () => {
|
13
|
-
if (togglePreformatted.enabled()) {
|
14
|
-
togglePreformatted();
|
15
|
-
}
|
16
|
-
};
|
17
|
-
|
18
|
-
return (
|
19
|
-
<DropdownButton
|
20
|
-
handleOnClick={handleSelect}
|
21
|
-
isDisabled={!enabled}
|
22
|
-
isActive={active.preformatted()}
|
23
|
-
label="Preformatted"
|
24
|
-
>
|
25
|
-
<pre>Preformatted</pre>
|
26
|
-
</DropdownButton>
|
27
|
-
);
|
28
|
-
};
|
29
|
-
|
30
|
-
export default PreformattedButton;
|
@@ -1,44 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import HeadingButton from './Heading/HeadingButton';
|
3
|
-
import ParagraphButton from './Paragraph/ParagraphButton';
|
4
|
-
import PreformattedButton from './Preformatted/PreformattedButton';
|
5
|
-
import ToolbarDropdown from '../../../ui/ToolbarDropdown/ToolbarDropdown';
|
6
|
-
import { useActive, VerticalDivider } from '@remirror/react';
|
7
|
-
import { PreformattedExtension } from '../../../Extensions/PreformattedExtension/PreformattedExtension';
|
8
|
-
|
9
|
-
const TextTypeDropdown = () => {
|
10
|
-
const active = useActive<PreformattedExtension>();
|
11
|
-
|
12
|
-
const activeLabel = () => {
|
13
|
-
// Determine if preformatted is active
|
14
|
-
if (active.preformatted()) {
|
15
|
-
return 'Preformatted';
|
16
|
-
}
|
17
|
-
// Determine if a heading is active
|
18
|
-
for (let i = 1; i <= 6; i++) {
|
19
|
-
if (active.heading({ level: i })) {
|
20
|
-
return `Heading ${i}`;
|
21
|
-
}
|
22
|
-
}
|
23
|
-
// Default to paragraph
|
24
|
-
return 'Paragraph';
|
25
|
-
};
|
26
|
-
|
27
|
-
return (
|
28
|
-
<>
|
29
|
-
<ToolbarDropdown label={activeLabel()}>
|
30
|
-
<ParagraphButton />
|
31
|
-
<HeadingButton level={1} />
|
32
|
-
<HeadingButton level={2} />
|
33
|
-
<HeadingButton level={3} />
|
34
|
-
<HeadingButton level={4} />
|
35
|
-
<HeadingButton level={5} />
|
36
|
-
<HeadingButton level={6} />
|
37
|
-
<PreformattedButton />
|
38
|
-
</ToolbarDropdown>
|
39
|
-
<VerticalDivider className="editor-divider" />
|
40
|
-
</>
|
41
|
-
);
|
42
|
-
};
|
43
|
-
|
44
|
-
export default TextTypeDropdown;
|
@@ -1,19 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import '@testing-library/jest-dom';
|
3
|
-
import { render, screen, fireEvent } from '@testing-library/react';
|
4
|
-
import Editor from '../../../Editor/Editor';
|
5
|
-
|
6
|
-
describe('Underline button', () => {
|
7
|
-
it('Renders the underline button', () => {
|
8
|
-
render(<Editor />);
|
9
|
-
expect(screen.getByRole('button', { name: 'Underline (cmd+U)' })).toBeInTheDocument();
|
10
|
-
});
|
11
|
-
|
12
|
-
it('Activates the button if clicked', () => {
|
13
|
-
render(<Editor />);
|
14
|
-
expect(screen.getByRole('button', { name: 'Underline (cmd+U)' }).classList.contains('btn')).toBeTruthy();
|
15
|
-
const underline = screen.getByRole('button', { name: 'Underline (cmd+U)' });
|
16
|
-
fireEvent.click(underline);
|
17
|
-
expect(underline.classList.contains('is-active')).toBeTruthy();
|
18
|
-
});
|
19
|
-
});
|
@@ -1,30 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import { useCommands, useActive, useChainedCommands } from '@remirror/react';
|
3
|
-
import { UnderlineExtension } from '@remirror/extension-underline';
|
4
|
-
import ToolbarButton from '../../../ui/ToolbarButton/ToolbarButton';
|
5
|
-
import FormatUnderlinedRoundedIcon from '@mui/icons-material/FormatUnderlinedRounded';
|
6
|
-
|
7
|
-
const UnderlineButton = () => {
|
8
|
-
const { toggleUnderline } = useCommands();
|
9
|
-
const chain = useChainedCommands();
|
10
|
-
|
11
|
-
const active = useActive<UnderlineExtension>();
|
12
|
-
const enabled = toggleUnderline.enabled();
|
13
|
-
const handleSelect = () => {
|
14
|
-
if (toggleUnderline.enabled()) {
|
15
|
-
chain.toggleUnderline().focus().run();
|
16
|
-
}
|
17
|
-
};
|
18
|
-
|
19
|
-
return (
|
20
|
-
<ToolbarButton
|
21
|
-
handleOnClick={handleSelect}
|
22
|
-
isDisabled={!enabled}
|
23
|
-
isActive={active.underline()}
|
24
|
-
icon={<FormatUnderlinedRoundedIcon />}
|
25
|
-
label="Underline (cmd+U)"
|
26
|
-
/>
|
27
|
-
);
|
28
|
-
};
|
29
|
-
|
30
|
-
export default UnderlineButton;
|
@@ -1,49 +0,0 @@
|
|
1
|
-
import '@testing-library/jest-dom';
|
2
|
-
import { render, screen, fireEvent } from '@testing-library/react';
|
3
|
-
import Editor from '../../../Editor/Editor';
|
4
|
-
import React from 'react';
|
5
|
-
|
6
|
-
describe('Undo button', () => {
|
7
|
-
it('Renders the undo button', () => {
|
8
|
-
render(<Editor />);
|
9
|
-
expect(screen.getByRole('button', { name: 'Undo (cmd+Z)' })).toBeInTheDocument();
|
10
|
-
});
|
11
|
-
|
12
|
-
it('Renders a disabled button if you have not made any changes yet', () => {
|
13
|
-
render(<Editor />);
|
14
|
-
const undo = screen.getByRole('button', { name: 'Undo (cmd+Z)' });
|
15
|
-
expect(undo).toBeDisabled();
|
16
|
-
});
|
17
|
-
|
18
|
-
it('Enables the button when you perform an action', () => {
|
19
|
-
const { baseElement } = render(<Editor />);
|
20
|
-
expect(baseElement.querySelector('p[data-node-text-align="left"]')).toBeFalsy();
|
21
|
-
|
22
|
-
const leftAlignButton = baseElement.querySelector('button[title="Align left"]') as HTMLButtonElement;
|
23
|
-
expect(leftAlignButton).toBeTruthy();
|
24
|
-
|
25
|
-
fireEvent.click(leftAlignButton);
|
26
|
-
expect(baseElement.querySelector('p[data-node-text-align="left"]')).toBeTruthy();
|
27
|
-
const undo = screen.getByRole('button', { name: 'Undo (cmd+Z)' });
|
28
|
-
expect(undo).not.toBeDisabled();
|
29
|
-
});
|
30
|
-
|
31
|
-
it('Reverts this action when clicked', () => {
|
32
|
-
const { baseElement } = render(<Editor />);
|
33
|
-
|
34
|
-
// perform some action
|
35
|
-
expect(baseElement.querySelector('p[data-node-text-align="left"]')).toBeFalsy();
|
36
|
-
const leftAlignButton = baseElement.querySelector('button[title="Align left"]') as HTMLButtonElement;
|
37
|
-
expect(leftAlignButton).toBeTruthy();
|
38
|
-
fireEvent.click(leftAlignButton);
|
39
|
-
expect(baseElement.querySelector('p[data-node-text-align="left"]')).toBeTruthy();
|
40
|
-
|
41
|
-
// Check that this enables the undo button
|
42
|
-
const undo = screen.getByRole('button', { name: 'Undo (cmd+Z)' });
|
43
|
-
expect(undo).not.toBeDisabled();
|
44
|
-
|
45
|
-
// Click the undo button and check that this has reverted the previous action
|
46
|
-
fireEvent.click(undo);
|
47
|
-
expect(baseElement.querySelector('p[data-node-text-align="left"]')).toBeFalsy();
|
48
|
-
});
|
49
|
-
});
|
@@ -1,30 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import { useCommands, useHelpers } from '@remirror/react';
|
3
|
-
import { HistoryExtension } from 'remirror/extensions';
|
4
|
-
import ToolbarButton from '../../../ui/ToolbarButton/ToolbarButton';
|
5
|
-
import UndoRoundedIcon from '@mui/icons-material/UndoRounded';
|
6
|
-
|
7
|
-
const UndoButton = () => {
|
8
|
-
const { undo } = useCommands<HistoryExtension>();
|
9
|
-
const { undoDepth } = useHelpers<HistoryExtension>(true);
|
10
|
-
|
11
|
-
const handleSelect = () => {
|
12
|
-
if (undo.enabled()) {
|
13
|
-
undo();
|
14
|
-
}
|
15
|
-
};
|
16
|
-
|
17
|
-
const enabled = undoDepth() > 0;
|
18
|
-
|
19
|
-
return (
|
20
|
-
<ToolbarButton
|
21
|
-
handleOnClick={handleSelect}
|
22
|
-
isDisabled={!enabled}
|
23
|
-
isActive={false}
|
24
|
-
icon={<UndoRoundedIcon />}
|
25
|
-
label="Undo (cmd+Z)"
|
26
|
-
/>
|
27
|
-
);
|
28
|
-
};
|
29
|
-
|
30
|
-
export default UndoButton;
|
@@ -1,19 +0,0 @@
|
|
1
|
-
.formatted-text-editor .editor-toolbar {
|
2
|
-
@apply bg-white rounded border-gray-200 border-2 border-solid p-1;
|
3
|
-
|
4
|
-
display: flex;
|
5
|
-
justify-items: center;
|
6
|
-
|
7
|
-
> *:not(:first-child) {
|
8
|
-
margin: 0 0 0 2px;
|
9
|
-
}
|
10
|
-
|
11
|
-
.editor-divider {
|
12
|
-
@apply -my-1 mx-1 border;
|
13
|
-
margin-right: 2px;
|
14
|
-
}
|
15
|
-
}
|
16
|
-
|
17
|
-
.remirror-floating-popover {
|
18
|
-
@apply bg-white border-gray-200 p-1 rounded-md shadow border;
|
19
|
-
}
|
@@ -1,24 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
BoldExtension,
|
3
|
-
HeadingExtension,
|
4
|
-
ItalicExtension,
|
5
|
-
NodeFormattingExtension,
|
6
|
-
ParagraphExtension,
|
7
|
-
UnderlineExtension,
|
8
|
-
HistoryExtension,
|
9
|
-
wysiwygPreset,
|
10
|
-
} from 'remirror/extensions';
|
11
|
-
import { PreformattedExtension } from './PreformattedExtension/PreformattedExtension';
|
12
|
-
import { Extension } from '@remirror/core';
|
13
|
-
|
14
|
-
export const Extensions = () => [
|
15
|
-
...(wysiwygPreset() as Extension[]),
|
16
|
-
new BoldExtension(),
|
17
|
-
new HeadingExtension(),
|
18
|
-
new ItalicExtension(),
|
19
|
-
new NodeFormattingExtension(),
|
20
|
-
new ParagraphExtension(),
|
21
|
-
new PreformattedExtension(),
|
22
|
-
new UnderlineExtension(),
|
23
|
-
new HistoryExtension(),
|
24
|
-
];
|
@@ -1,50 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
ApplySchemaAttributes,
|
3
|
-
command,
|
4
|
-
CommandFunction,
|
5
|
-
extension,
|
6
|
-
ExtensionTag,
|
7
|
-
NodeExtension,
|
8
|
-
NodeExtensionSpec,
|
9
|
-
NodeSpecOverride,
|
10
|
-
ProsemirrorNode,
|
11
|
-
toggleBlockItem,
|
12
|
-
} from '@remirror/core';
|
13
|
-
|
14
|
-
@extension({})
|
15
|
-
export class PreformattedExtension extends NodeExtension {
|
16
|
-
get name() {
|
17
|
-
return 'preformatted' as const;
|
18
|
-
}
|
19
|
-
|
20
|
-
createTags() {
|
21
|
-
return [ExtensionTag.Block, ExtensionTag.TextBlock, ExtensionTag.FormattingNode];
|
22
|
-
}
|
23
|
-
|
24
|
-
createNodeSpec(extra: ApplySchemaAttributes, override: NodeSpecOverride): NodeExtensionSpec {
|
25
|
-
return {
|
26
|
-
content: 'inline*',
|
27
|
-
defining: true,
|
28
|
-
draggable: false,
|
29
|
-
...override,
|
30
|
-
attrs: {
|
31
|
-
...extra.defaults(),
|
32
|
-
},
|
33
|
-
parseDOM: [...(override.parseDOM ?? [])],
|
34
|
-
toDOM: (node: ProsemirrorNode) => {
|
35
|
-
return [`pre`, extra.dom(node), 0];
|
36
|
-
},
|
37
|
-
};
|
38
|
-
}
|
39
|
-
|
40
|
-
/**
|
41
|
-
* Toggle the <pre> for the current block.
|
42
|
-
*/
|
43
|
-
@command()
|
44
|
-
togglePreformatted(): CommandFunction {
|
45
|
-
return toggleBlockItem({
|
46
|
-
type: this.type,
|
47
|
-
toggleType: 'paragraph',
|
48
|
-
});
|
49
|
-
}
|
50
|
-
}
|
@@ -1,10 +0,0 @@
|
|
1
|
-
import { render } from '@testing-library/react';
|
2
|
-
import { FormattedTextEditor } from './';
|
3
|
-
import React from 'react';
|
4
|
-
|
5
|
-
describe('<FormattedTextEditor />', () => {
|
6
|
-
it('should render "<FormattedTextEditor />" component', () => {
|
7
|
-
const { baseElement } = render(<FormattedTextEditor />);
|
8
|
-
expect(baseElement).toBeTruthy();
|
9
|
-
});
|
10
|
-
});
|
@@ -1,12 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import Editor from './Editor/Editor';
|
3
|
-
|
4
|
-
const FormattedTextEditor = () => {
|
5
|
-
return (
|
6
|
-
<div className="remirror-theme formatted-text-editor editor-wrapper">
|
7
|
-
<Editor />
|
8
|
-
</div>
|
9
|
-
);
|
10
|
-
};
|
11
|
-
|
12
|
-
export default FormattedTextEditor;
|
package/src/index.scss
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
/* Tailwind base */
|
2
|
-
@import 'tailwindcss/base';
|
3
|
-
@import 'tailwindcss/components';
|
4
|
-
@import 'tailwindcss/utilities';
|
5
|
-
|
6
|
-
/* Remirror base */
|
7
|
-
@import 'remirror/styles/all.css';
|
8
|
-
|
9
|
-
/* Components */
|
10
|
-
@import './Editor/editor';
|
11
|
-
@import './EditorToolbar/editor-toolbar';
|
12
|
-
|
13
|
-
@import './ui/ToolbarButton/toolbar-button';
|
14
|
-
@import './ui/ToolbarDropdown/toolbar-dropdown';
|
15
|
-
@import './ui/DropdownButton/dropdown-button';
|
package/src/index.ts
DELETED