@squiz/formatted-text-editor 1.5.1-alpha.6 → 1.12.0-alpha.14

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 (77) hide show
  1. package/.eslintrc.json +6 -1
  2. package/CHANGELOG.md +41 -1
  3. package/README.md +29 -4
  4. package/build.js +11 -0
  5. package/cypress/e2e/bold.spec.cy.ts +18 -0
  6. package/cypress/global.d.ts +9 -0
  7. package/cypress/support/commands.ts +130 -0
  8. package/cypress/support/e2e.ts +20 -0
  9. package/cypress/tsconfig.json +8 -0
  10. package/cypress.config.ts +7 -0
  11. package/{src → demo}/App.tsx +1 -1
  12. package/{index.html → demo/index.html} +1 -1
  13. package/demo/index.scss +11 -0
  14. package/demo/main.tsx +10 -0
  15. package/{lib → demo/public}/favicon-dxp.svg +0 -0
  16. package/{src → demo}/vite-env.d.ts +0 -0
  17. package/file-transformer.js +1 -0
  18. package/jest.config.ts +27 -0
  19. package/lib/Editor/Editor.d.ts +6 -0
  20. package/lib/Editor/Editor.js +26 -0
  21. package/lib/EditorToolbar/EditorToolbar.d.ts +7 -0
  22. package/lib/EditorToolbar/EditorToolbar.js +21 -0
  23. package/lib/EditorToolbar/Tools/Bold/BoldButton.d.ts +2 -0
  24. package/lib/EditorToolbar/Tools/Bold/BoldButton.js +17 -0
  25. package/lib/EditorToolbar/Tools/Italic/ItalicButton.d.ts +2 -0
  26. package/lib/EditorToolbar/Tools/Italic/ItalicButton.js +17 -0
  27. package/lib/EditorToolbar/Tools/TextAlign/CenterAlign/CenterAlignButton.d.ts +2 -0
  28. package/lib/EditorToolbar/Tools/TextAlign/CenterAlign/CenterAlignButton.js +17 -0
  29. package/lib/EditorToolbar/Tools/TextAlign/JustifyAlign/JustifyAlignButton.d.ts +2 -0
  30. package/lib/EditorToolbar/Tools/TextAlign/JustifyAlign/JustifyAlignButton.js +17 -0
  31. package/lib/EditorToolbar/Tools/TextAlign/LeftAlign/LeftAlignButton.d.ts +2 -0
  32. package/lib/EditorToolbar/Tools/TextAlign/LeftAlign/LeftAlignButton.js +17 -0
  33. package/lib/EditorToolbar/Tools/TextAlign/RightAlign/RightAlignButton.d.ts +2 -0
  34. package/lib/EditorToolbar/Tools/TextAlign/RightAlign/RightAlignButton.js +17 -0
  35. package/lib/EditorToolbar/Tools/TextAlign/TextAlignButtons.d.ts +2 -0
  36. package/lib/EditorToolbar/Tools/TextAlign/TextAlignButtons.js +16 -0
  37. package/lib/EditorToolbar/Tools/Underline/UnderlineButton.d.ts +2 -0
  38. package/lib/EditorToolbar/Tools/Underline/UnderlineButton.js +17 -0
  39. package/lib/FormattedTextEditor.d.ts +2 -0
  40. package/lib/FormattedTextEditor.js +7 -0
  41. package/lib/index.css +3849 -0
  42. package/lib/index.d.ts +2 -0
  43. package/lib/index.js +2 -36344
  44. package/lib/ui/ToolbarButton/ToolbarButton.d.ts +10 -0
  45. package/lib/ui/ToolbarButton/ToolbarButton.js +5 -0
  46. package/package.json +47 -30
  47. package/src/Editor/Editor.spec.tsx +88 -0
  48. package/src/Editor/Editor.tsx +44 -0
  49. package/src/Editor/editor.scss +36 -0
  50. package/src/EditorToolbar/EditorToolbar.tsx +40 -0
  51. package/src/EditorToolbar/Tools/Bold/BoldButton.spec.tsx +19 -0
  52. package/src/EditorToolbar/Tools/Bold/BoldButton.tsx +30 -0
  53. package/src/EditorToolbar/Tools/Italic/ItalicButton.spec.tsx +19 -0
  54. package/src/EditorToolbar/Tools/Italic/ItalicButton.tsx +30 -0
  55. package/src/EditorToolbar/Tools/TextAlign/CenterAlign/CenterAlignButton.tsx +31 -0
  56. package/src/EditorToolbar/Tools/TextAlign/JustifyAlign/JustifyAlignButton.tsx +31 -0
  57. package/src/EditorToolbar/Tools/TextAlign/LeftAlign/LeftAlignButton.tsx +31 -0
  58. package/src/EditorToolbar/Tools/TextAlign/RightAlign/RightAlignButton.tsx +31 -0
  59. package/src/EditorToolbar/Tools/TextAlign/TextAlignButtons.tsx +21 -0
  60. package/src/EditorToolbar/Tools/Underline/Underline.spec.tsx +19 -0
  61. package/src/EditorToolbar/Tools/Underline/UnderlineButton.tsx +30 -0
  62. package/src/EditorToolbar/editor-toolbar.scss +26 -0
  63. package/src/FormattedTextEditor.tsx +4 -17
  64. package/src/index.scss +4 -0
  65. package/src/index.ts +3 -0
  66. package/src/ui/ToolbarButton/ToolbarButton.tsx +25 -0
  67. package/src/ui/ToolbarButton/toolbar-button.scss +40 -0
  68. package/tsconfig.json +5 -5
  69. package/vite.config.ts +3 -9
  70. package/lib/style.css +0 -1
  71. package/public/favicon-dxp.svg +0 -3
  72. package/src/Menu.tsx +0 -19
  73. package/src/Toolbar.tsx +0 -10
  74. package/src/index.css +0 -3
  75. package/src/main.tsx +0 -13
  76. package/src/toolbar.css +0 -9
  77. package/tsconfig.node.json +0 -9
package/.eslintrc.json CHANGED
@@ -1,9 +1,14 @@
1
1
  {
2
+ "env": {
3
+ "jest/globals": true,
4
+ "cypress/globals": true
5
+ },
6
+ "plugins": ["cypress"],
2
7
  "extends": [
3
8
  // By extending from a plugin config, we can get recommended rules without having to add them manually.
4
- "eslint:recommended",
5
9
  "plugin:react/recommended",
6
10
  "plugin:jsx-a11y/recommended",
11
+ "plugin:cypress/recommended",
7
12
  // This disables the formatting rules in ESLint that Prettier is going to be responsible for handling.
8
13
  // Make sure it"s always the last config, so it gets the chance to override other configs.
9
14
  "eslint-config-prettier"
package/CHANGELOG.md CHANGED
@@ -3,6 +3,46 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
- ## [1.5.1-alpha.5](https://gitlab.squiz.net/developer-experience/cmp/compare/v1.5.1-alpha.4...v1.5.1-alpha.5) (2023-01-31)
6
+ ## [1.6.1-alpha.5](https://gitlab.squiz.net/developer-experience/cmp/compare/v1.6.1-alpha.3...v1.6.1-alpha.5) (2023-02-02)
7
+
8
+ **Note:** Version bump only for package @squiz/formatted-text-editor
9
+
10
+
11
+
12
+
13
+
14
+ ## [1.6.1-alpha.4](https://gitlab.squiz.net/developer-experience/cmp/compare/v1.6.1-alpha.3...v1.6.1-alpha.4) (2023-02-02)
15
+
16
+ **Note:** Version bump only for package @squiz/formatted-text-editor
17
+
18
+
19
+
20
+
21
+
22
+ ## [1.6.1-alpha.3](https://gitlab.squiz.net/developer-experience/cmp/compare/v1.6.1-alpha.2...v1.6.1-alpha.3) (2023-02-02)
23
+
24
+ **Note:** Version bump only for package @squiz/formatted-text-editor
25
+
26
+
27
+
28
+
29
+
30
+ ## [1.6.1-alpha.2](https://gitlab.squiz.net/developer-experience/cmp/compare/v1.6.0...v1.6.1-alpha.2) (2023-02-02)
31
+
32
+ **Note:** Version bump only for package @squiz/formatted-text-editor
33
+
34
+
35
+
36
+
37
+
38
+ ## [1.6.1-alpha.1](https://gitlab.squiz.net/developer-experience/cmp/compare/v1.6.0...v1.6.1-alpha.1) (2023-02-02)
39
+
40
+ **Note:** Version bump only for package @squiz/formatted-text-editor
41
+
42
+
43
+
44
+
45
+
46
+ ## [1.6.1-alpha.0](https://gitlab.squiz.net/developer-experience/cmp/compare/v1.6.0...v1.6.1-alpha.0) (2023-02-02)
7
47
 
8
48
  **Note:** Version bump only for package @squiz/formatted-text-editor
package/README.md CHANGED
@@ -25,13 +25,38 @@ npm run dev
25
25
  ```
26
26
  This will expose `http://localhost:5173/` and this can be viewed in the browser.
27
27
 
28
+ > TIP: Make sure you have already installed the node modules at the root level of the repo.
28
29
 
29
30
  ## WIP: Contributing
30
31
 
31
- ### WIP: Testing
32
+ ## Testing
32
33
 
33
- ## Publish package to NPM
34
+ Tests must be written when contributing to this package. Tests are automatically run in CI and test failure will result in unmerged code.
34
35
 
35
- This package will automatically be compiled and published to NPM as part of the monorepo CI publishing processes.
36
+ ### Unit testing
36
37
 
37
- It is possible to manually compile the package using `npm run compile`. This will not publish the package to NPM.
38
+ This package using Jest to perform Unit testing. In addition to Jest we are using a few Testing Library utilities:
39
+
40
+ - [React testing library](https://testing-library.com/docs/react-testing-library/intro/) - Enables React component testing
41
+ - [Jest DOM](https://testing-library.com/docs/ecosystem-jest-dom/) - Enables custom matchers
42
+
43
+ Tests should be co-located with componentry and should strive for maximum coverage.
44
+
45
+ To run tests locally you can run:
46
+ ```sh
47
+ npm run test
48
+ ```
49
+ Or if you'd like to "watch" for changes:
50
+ ```sh
51
+ npm run test:watch
52
+ ```
53
+
54
+ ### End to end testing
55
+
56
+ This package uses [Cypress](https://docs.cypress.io/) for end to end testing.
57
+
58
+ To run tests locally you can run:
59
+ ```sh
60
+ npm run test:e2e
61
+ ```
62
+ Cypress is configured to look at a preview dev environment on `http://localhost:8080`.
package/build.js ADDED
@@ -0,0 +1,11 @@
1
+ const esbuild = require('esbuild');
2
+ const { sassPlugin } = require('esbuild-sass-plugin');
3
+
4
+ esbuild
5
+ .build({
6
+ entryPoints: ['src/index.scss'],
7
+ bundle: true,
8
+ outdir: 'lib',
9
+ plugins: [sassPlugin({ type: 'css' })],
10
+ })
11
+ .catch(() => process.exit(1));
@@ -0,0 +1,18 @@
1
+ describe('The formatted text editor renders', () => {
2
+ it('Should toggle bold on highlighted text', () => {
3
+ cy.visit('/');
4
+
5
+ cy.get('.ProseMirror.remirror-editor')
6
+ .clear()
7
+ .type('It was the best of times it was the worst of times.')
8
+ .setSelection('best of times');
9
+
10
+ cy.findAllByRole('button', { name: 'Bold (cmd+B)' }).first().click();
11
+
12
+ cy.get('strong').should('include.text', 'best of times');
13
+
14
+ cy.findAllByRole('button', { name: 'Bold (cmd+B)' }).first().click();
15
+
16
+ cy.get('strong').should('not.exist');
17
+ });
18
+ });
@@ -0,0 +1,9 @@
1
+ /// <reference types="cypress" />
2
+
3
+ declare namespace Cypress {
4
+ interface Chainable {
5
+ // Custom command
6
+ selection(subject: any, fn?: any): void;
7
+ setSelection(subject: any, query?: any, endQuery?: any): void;
8
+ }
9
+ }
@@ -0,0 +1,130 @@
1
+ // eslint-disable-next-line @typescript-eslint/triple-slash-reference
2
+ /// <reference path="../global.d.ts" />
3
+
4
+ import '@testing-library/cypress/add-commands';
5
+
6
+ // ***********************************************
7
+ // This example commands.ts shows you how to
8
+ // create various custom commands and overwrite
9
+ // existing commands.
10
+ //
11
+ // For more comprehensive examples of custom
12
+ // commands please read more here:
13
+ // https://on.cypress.io/custom-commands
14
+ // ***********************************************
15
+ //
16
+ //
17
+ // -- This is a parent command --
18
+ // Cypress.Commands.add('login', (email, password) => { ... })
19
+ //
20
+ //
21
+ // -- This is a child command --
22
+ // Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
23
+ //
24
+ //
25
+ // -- This is a dual command --
26
+ // Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
27
+ //
28
+ //
29
+ // -- This will overwrite an existing command --
30
+ // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
31
+ //
32
+ // declare global {
33
+ // namespace Cypress {
34
+ // interface Chainable {
35
+ // login(email: string, password: string): Chainable<void>
36
+ // drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
37
+ // dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
38
+ // visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
39
+ // }
40
+ // }
41
+ // }
42
+
43
+ /**
44
+ * Credits
45
+ * @Bkucera: https://github.com/cypress-io/cypress/issues/2839#issuecomment-447012818
46
+ * @Phrogz: https://stackoverflow.com/a/10730777/1556245
47
+ *
48
+ * Usage
49
+ * ```
50
+ * // Types "foo" and then selects "fo"
51
+ * cy.get('input')
52
+ * .type('foo')
53
+ * .setSelection('fo')
54
+ *
55
+ * // Types "foo", "bar", "baz", and "qux" on separate lines, then selects "foo", "bar", and "baz"
56
+ * cy.get('textarea')
57
+ * .type('foo{enter}bar{enter}baz{enter}qux{enter}')
58
+ * .setSelection('foo', 'baz')
59
+ *
60
+ * // Types "foo" and then sets the cursor before the last letter
61
+ * cy.get('input')
62
+ * .type('foo')
63
+ * .setCursorAfter('fo')
64
+ *
65
+ * // Types "foo" and then sets the cursor at the beginning of the word
66
+ * cy.get('input')
67
+ * .type('foo')
68
+ * .setCursorBefore('foo')
69
+ *
70
+ * // `setSelection` can alternatively target starting and ending nodes using query strings,
71
+ * // plus specific offsets. The queries are processed via `Element.querySelector`.
72
+ * cy.get('body')
73
+ * .setSelection({
74
+ * anchorQuery: 'ul > li > p', // required
75
+ * anchorOffset: 2 // default: 0
76
+ * focusQuery: 'ul > li > p:last-child', // default: anchorQuery
77
+ * focusOffset: 0 // default: 0
78
+ * })
79
+ */
80
+
81
+ // Low level command reused by `setSelection` and low level command `setCursor`
82
+ Cypress.Commands.add('selection', { prevSubject: true }, (subject, fn) => {
83
+ cy.wrap(subject).trigger('mousedown').then(fn).trigger('mouseup');
84
+
85
+ cy.document().trigger('selectionchange');
86
+ return cy.wrap(subject);
87
+ });
88
+
89
+ Cypress.Commands.add('setSelection', { prevSubject: true }, (subject, query, endQuery) => {
90
+ return cy.wrap(subject).selection(($el: any[]) => {
91
+ if (typeof query === 'string') {
92
+ const anchorNode = getTextNode($el[0], query);
93
+ const focusNode = endQuery ? getTextNode($el[0], endQuery) : anchorNode;
94
+ const anchorOffset = anchorNode.wholeText.indexOf(query);
95
+ const focusOffset = endQuery
96
+ ? focusNode.wholeText.indexOf(endQuery) + endQuery.length
97
+ : anchorOffset + query.length;
98
+ setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset);
99
+ } else if (typeof query === 'object') {
100
+ const el = $el[0];
101
+ const anchorNode = getTextNode(el.querySelector(query.anchorQuery));
102
+ const anchorOffset = query.anchorOffset || 0;
103
+ const focusNode = query.focusQuery ? getTextNode(el.querySelector(query.focusQuery)) : anchorNode;
104
+ const focusOffset = query.focusOffset || 0;
105
+ setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset);
106
+ }
107
+ });
108
+ });
109
+
110
+ // Helper functions
111
+ function getTextNode(el: HTMLElement, match?: any) {
112
+ const walk = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null);
113
+ if (!match) {
114
+ return walk.nextNode();
115
+ }
116
+
117
+ // const nodes = [];
118
+ let node;
119
+ while ((node = walk.nextNode())) {
120
+ if (node.wholeText.includes(match)) {
121
+ return node;
122
+ }
123
+ }
124
+ }
125
+
126
+ function setBaseAndExtent(...args) {
127
+ const document = args[0].ownerDocument;
128
+ document.getSelection().removeAllRanges();
129
+ document.getSelection().setBaseAndExtent(...args);
130
+ }
@@ -0,0 +1,20 @@
1
+ // ***********************************************************
2
+ // This example support/e2e.ts is processed and
3
+ // loaded automatically before your test files.
4
+ //
5
+ // This is a great place to put global configuration and
6
+ // behavior that modifies Cypress.
7
+ //
8
+ // You can change the location of this file or turn off
9
+ // automatically serving support files with the
10
+ // 'supportFile' configuration option.
11
+ //
12
+ // You can read more here:
13
+ // https://on.cypress.io/configuration
14
+ // ***********************************************************
15
+
16
+ // Import commands.js using ES2015 syntax:
17
+ import './commands';
18
+
19
+ // Alternatively you can use CommonJS syntax:
20
+ // require('./commands')
@@ -0,0 +1,8 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es5",
4
+ "lib": ["es5", "dom"],
5
+ "types": ["cypress", "@testing-library/cypress", "node"]
6
+ },
7
+ "include": ["**/*.ts"]
8
+ }
@@ -0,0 +1,7 @@
1
+ import { defineConfig } from 'cypress';
2
+
3
+ export default defineConfig({
4
+ e2e: {
5
+ baseUrl: 'http://localhost:8080',
6
+ },
7
+ });
@@ -1,4 +1,4 @@
1
- import FormattedTextEditor from './FormattedTextEditor';
1
+ import FormattedTextEditor from '../src/FormattedTextEditor';
2
2
 
3
3
  function App() {
4
4
  return (
@@ -8,6 +8,6 @@
8
8
  </head>
9
9
  <body>
10
10
  <div id="root"></div>
11
- <script type="module" src="/src/main.tsx"></script>
11
+ <script type="module" src="./main.tsx"></script>
12
12
  </body>
13
13
  </html>
@@ -0,0 +1,11 @@
1
+ /* Global variables */
2
+ :root {
3
+ --grey-200: #ededed;
4
+ --grey-300: #e0e0e0;
5
+ --grey-600: #707070;
6
+ --blue-100: #e6f1fa;
7
+ --blue-300: #0774d2;
8
+ --border-radius: 4px;
9
+ }
10
+
11
+ @import '../src/index.scss';
package/demo/main.tsx ADDED
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom/client';
3
+ import App from './App';
4
+ import './index.scss';
5
+
6
+ ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
7
+ <React.StrictMode>
8
+ <App />
9
+ </React.StrictMode>,
10
+ );
File without changes
File without changes
@@ -0,0 +1 @@
1
+ module.exports = {};
package/jest.config.ts ADDED
@@ -0,0 +1,27 @@
1
+ export default {
2
+ preset: 'ts-jest',
3
+ maxWorkers: 1,
4
+ clearMocks: true,
5
+ collectCoverage: true,
6
+ collectCoverageFrom: ['src/**/*.{ts,tsx}'],
7
+ errorOnDeprecated: true,
8
+ fakeTimers: {
9
+ enableGlobally: true,
10
+ },
11
+ resetMocks: true,
12
+ resetModules: true,
13
+ testEnvironment: 'jsdom',
14
+ moduleNameMapper: {
15
+ '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|css|scss)$':
16
+ '<rootDir>/file-transformer.js',
17
+ },
18
+ // TODO: enable once directory structure is sorted and we have tests/more complete code being written.
19
+ // coverageThreshold: {
20
+ // global: {
21
+ // branches: 90,
22
+ // functions: 90,
23
+ // lines: 90,
24
+ // statements: 90,
25
+ // },
26
+ // },
27
+ };
@@ -0,0 +1,6 @@
1
+ import { RemirrorContentType } from '@remirror/core';
2
+ type EditorProps = {
3
+ content?: RemirrorContentType;
4
+ };
5
+ declare const Editor: ({ content }: EditorProps) => JSX.Element;
6
+ export default Editor;
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import { BoldExtension, ItalicExtension, NodeFormattingExtension, UnderlineExtension, wysiwygPreset, } from 'remirror/extensions';
3
+ import { EditorComponent, Remirror, useRemirror } from '@remirror/react';
4
+ import { EditorToolbar } from '../EditorToolbar/EditorToolbar';
5
+ const Editor = ({ content }) => {
6
+ const { manager, state, setState } = useRemirror({
7
+ extensions: () => [
8
+ ...wysiwygPreset(),
9
+ new BoldExtension(),
10
+ new ItalicExtension(),
11
+ new NodeFormattingExtension(),
12
+ new UnderlineExtension(),
13
+ ],
14
+ content,
15
+ selection: 'start',
16
+ stringHandler: 'html',
17
+ });
18
+ const handleChange = (parameter) => {
19
+ setState(parameter.state);
20
+ };
21
+ return (React.createElement(Remirror, { manager: manager, state: state, onChange: handleChange, placeholder: "Write something" },
22
+ React.createElement(EditorToolbar, { manager: manager }),
23
+ React.createElement(EditorComponent, null),
24
+ React.createElement(EditorToolbar, { manager: manager, isPopover: true })));
25
+ };
26
+ export default Editor;
@@ -0,0 +1,7 @@
1
+ import { RemirrorManager } from 'remirror';
2
+ type EditorToolbarProps = {
3
+ manager: RemirrorManager<any>;
4
+ isPopover?: boolean;
5
+ };
6
+ export declare const EditorToolbar: ({ manager, isPopover }: EditorToolbarProps) => JSX.Element;
7
+ export {};
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import { Toolbar, FloatingToolbar } from '@remirror/react-components';
3
+ import ItalicButton from './Tools/Italic/ItalicButton';
4
+ import UnderlineButton from './Tools/Underline/UnderlineButton';
5
+ import BoldButton from './Tools/Bold/BoldButton';
6
+ import TextAlignButtons from './Tools/TextAlign/TextAlignButtons';
7
+ // The editor main toolbar
8
+ export const EditorToolbar = ({ manager, isPopover }) => {
9
+ const extensionNames = {};
10
+ manager.extensions.forEach((extension) => {
11
+ extensionNames[extension.name] = true;
12
+ });
13
+ return (React.createElement(React.Fragment, null, !isPopover ? (React.createElement(Toolbar, { className: "remirror-toolbar editor-toolbar" },
14
+ extensionNames.bold && React.createElement(BoldButton, null),
15
+ extensionNames.italic && React.createElement(ItalicButton, null),
16
+ extensionNames.underline && React.createElement(UnderlineButton, null),
17
+ extensionNames.nodeFormatting && React.createElement(TextAlignButtons, null))) : (React.createElement(FloatingToolbar, { className: "remirror-floating-popover" },
18
+ extensionNames.bold && React.createElement(BoldButton, null),
19
+ extensionNames.italic && React.createElement(ItalicButton, null),
20
+ extensionNames.underline && React.createElement(UnderlineButton, null)))));
21
+ };
@@ -0,0 +1,2 @@
1
+ declare const BoldButton: () => JSX.Element;
2
+ export default BoldButton;
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { useCommands, useActive, useChainedCommands } from '@remirror/react';
3
+ import ToolbarButton from '../../../ui/ToolbarButton/ToolbarButton';
4
+ import FormatBoldRoundedIcon from '@mui/icons-material/FormatBoldRounded';
5
+ const BoldButton = () => {
6
+ const { toggleBold } = useCommands();
7
+ const chain = useChainedCommands();
8
+ const active = useActive();
9
+ const enabled = toggleBold.enabled();
10
+ const handleSelect = () => {
11
+ if (toggleBold.enabled()) {
12
+ chain.toggleBold().focus().run();
13
+ }
14
+ };
15
+ return (React.createElement(ToolbarButton, { handleOnClick: handleSelect, isDisabled: !enabled, isActive: active.bold(), icon: React.createElement(FormatBoldRoundedIcon, null), label: "Bold (cmd+B)" }));
16
+ };
17
+ export default BoldButton;
@@ -0,0 +1,2 @@
1
+ declare const ItalicButton: () => JSX.Element;
2
+ export default ItalicButton;
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { useCommands, useActive, useChainedCommands } from '@remirror/react';
3
+ import ToolbarButton from '../../../ui/ToolbarButton/ToolbarButton';
4
+ import FormatItalicRoundedIcon from '@mui/icons-material/FormatItalicRounded';
5
+ const ItalicButton = () => {
6
+ const { toggleItalic } = useCommands();
7
+ const chain = useChainedCommands();
8
+ const active = useActive();
9
+ const enabled = toggleItalic.enabled();
10
+ const handleSelect = () => {
11
+ if (toggleItalic.enabled()) {
12
+ chain.toggleItalic().focus().run();
13
+ }
14
+ };
15
+ return (React.createElement(ToolbarButton, { handleOnClick: handleSelect, isDisabled: !enabled, isActive: active.italic(), icon: React.createElement(FormatItalicRoundedIcon, null), label: "Italic (cmd+I)" }));
16
+ };
17
+ export default ItalicButton;
@@ -0,0 +1,2 @@
1
+ declare const CenterAlignButton: () => JSX.Element;
2
+ export default CenterAlignButton;
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { useCommands, useChainedCommands } from '@remirror/react';
3
+ import ToolbarButton from '../../../../ui/ToolbarButton/ToolbarButton';
4
+ import FormatAlignCenterIcon from '@mui/icons-material/FormatAlignCenter';
5
+ const CenterAlignButton = () => {
6
+ const { centerAlign } = useCommands();
7
+ const chain = useChainedCommands();
8
+ const handleSelect = () => {
9
+ if (centerAlign.enabled()) {
10
+ chain.centerAlign().focus().run();
11
+ }
12
+ };
13
+ const active = centerAlign.active?.() || false;
14
+ const enabled = centerAlign.enabled();
15
+ return (React.createElement(ToolbarButton, { handleOnClick: handleSelect, isDisabled: !enabled, isActive: active, icon: React.createElement(FormatAlignCenterIcon, null), label: "Align center" }));
16
+ };
17
+ export default CenterAlignButton;
@@ -0,0 +1,2 @@
1
+ declare const JustifyAlignButton: () => JSX.Element;
2
+ export default JustifyAlignButton;
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { useCommands, useChainedCommands } from '@remirror/react';
3
+ import ToolbarButton from '../../../../ui/ToolbarButton/ToolbarButton';
4
+ import FormatAlignJustifyIcon from '@mui/icons-material/FormatAlignJustify';
5
+ const JustifyAlignButton = () => {
6
+ const { justifyAlign } = useCommands();
7
+ const chain = useChainedCommands();
8
+ const handleSelect = () => {
9
+ if (justifyAlign.enabled()) {
10
+ chain.justifyAlign().focus().run();
11
+ }
12
+ };
13
+ const active = justifyAlign.active?.() || false;
14
+ const enabled = justifyAlign.enabled();
15
+ return (React.createElement(ToolbarButton, { handleOnClick: handleSelect, isDisabled: !enabled, isActive: active, icon: React.createElement(FormatAlignJustifyIcon, null), label: "Justify" }));
16
+ };
17
+ export default JustifyAlignButton;
@@ -0,0 +1,2 @@
1
+ declare const LeftAlignButton: () => JSX.Element;
2
+ export default LeftAlignButton;
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { useCommands, useChainedCommands } from '@remirror/react';
3
+ import ToolbarButton from '../../../../ui/ToolbarButton/ToolbarButton';
4
+ import FormatAlignLeftIcon from '@mui/icons-material/FormatAlignLeft';
5
+ const LeftAlignButton = () => {
6
+ const { leftAlign } = useCommands();
7
+ const chain = useChainedCommands();
8
+ const handleSelect = () => {
9
+ if (leftAlign.enabled()) {
10
+ chain.leftAlign().focus().run();
11
+ }
12
+ };
13
+ const active = leftAlign.active?.() || false;
14
+ const enabled = leftAlign.enabled();
15
+ return (React.createElement(ToolbarButton, { handleOnClick: handleSelect, isDisabled: !enabled, isActive: active, icon: React.createElement(FormatAlignLeftIcon, null), label: "Align left" }));
16
+ };
17
+ export default LeftAlignButton;
@@ -0,0 +1,2 @@
1
+ declare const RightAlignButton: () => JSX.Element;
2
+ export default RightAlignButton;
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { useCommands, useChainedCommands } from '@remirror/react';
3
+ import ToolbarButton from '../../../../ui/ToolbarButton/ToolbarButton';
4
+ import FormatAlignRightIcon from '@mui/icons-material/FormatAlignRight';
5
+ const RightAlignButton = () => {
6
+ const { rightAlign } = useCommands();
7
+ const chain = useChainedCommands();
8
+ const handleSelect = () => {
9
+ if (rightAlign.enabled()) {
10
+ chain.rightAlign().focus().run();
11
+ }
12
+ };
13
+ const active = rightAlign.active?.() || false;
14
+ const enabled = rightAlign.enabled();
15
+ return (React.createElement(ToolbarButton, { handleOnClick: handleSelect, isDisabled: !enabled, isActive: active, icon: React.createElement(FormatAlignRightIcon, null), label: "Align right" }));
16
+ };
17
+ export default RightAlignButton;
@@ -0,0 +1,2 @@
1
+ declare const TextAlignButtons: () => JSX.Element;
2
+ export default TextAlignButtons;
@@ -0,0 +1,16 @@
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
+ const TextAlignButtons = () => {
8
+ return (React.createElement(React.Fragment, null,
9
+ React.createElement(VerticalDivider, { className: "editor-divider" }),
10
+ React.createElement(LeftAlignButton, null),
11
+ React.createElement(CenterAlignButton, null),
12
+ React.createElement(RightAlignButton, null),
13
+ React.createElement(JustifyAlignButton, null),
14
+ React.createElement(VerticalDivider, { className: "editor-divider" })));
15
+ };
16
+ export default TextAlignButtons;
@@ -0,0 +1,2 @@
1
+ declare const UnderlineButton: () => JSX.Element;
2
+ export default UnderlineButton;
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { useCommands, useActive, useChainedCommands } from '@remirror/react';
3
+ import ToolbarButton from '../../../ui/ToolbarButton/ToolbarButton';
4
+ import FormatUnderlinedRoundedIcon from '@mui/icons-material/FormatUnderlinedRounded';
5
+ const UnderlineButton = () => {
6
+ const { toggleUnderline } = useCommands();
7
+ const chain = useChainedCommands();
8
+ const active = useActive();
9
+ const enabled = toggleUnderline.enabled();
10
+ const handleSelect = () => {
11
+ if (toggleUnderline.enabled()) {
12
+ chain.toggleUnderline().focus().run();
13
+ }
14
+ };
15
+ return (React.createElement(ToolbarButton, { handleOnClick: handleSelect, isDisabled: !enabled, isActive: active.underline(), icon: React.createElement(FormatUnderlinedRoundedIcon, null), label: "Underline (cmd+U)" }));
16
+ };
17
+ export default UnderlineButton;
@@ -0,0 +1,2 @@
1
+ declare const FormattedTextEditor: () => JSX.Element;
2
+ export default FormattedTextEditor;