@squiz/formatted-text-editor 1.40.1-alpha.6 → 1.40.1-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/lib/EditorToolbar/Toolbar.js +3 -0
- package/lib/EditorToolbar/Tools/UnorderedList/UnorderedListButton.d.ts +2 -0
- package/lib/EditorToolbar/Tools/UnorderedList/UnorderedListButton.js +22 -0
- package/lib/Extensions/Extensions.js +2 -0
- package/lib/index.css +5 -0
- package/lib/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.js +2 -0
- package/package.json +4 -4
- package/src/EditorToolbar/Toolbar.tsx +3 -0
- package/src/EditorToolbar/Tools/UnorderedList/UnorderedList.spec.tsx +19 -0
- package/src/EditorToolbar/Tools/UnorderedList/UnorderedListButton.tsx +30 -0
- package/src/Extensions/Extensions.ts +4 -0
- package/src/ui/_typography.scss +7 -0
- package/src/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.spec.ts +118 -0
- package/src/utils/converters/squizNodeToRemirrorNode/squizNodeToRemirrorNode.ts +2 -0
- package/src/utils/getNodeNamesByGroup.spec.ts +10 -1
@@ -9,6 +9,7 @@ const react_components_1 = require("@remirror/react-components");
|
|
9
9
|
const clsx_1 = __importDefault(require("clsx"));
|
10
10
|
const ItalicButton_1 = __importDefault(require("./Tools/Italic/ItalicButton"));
|
11
11
|
const UnderlineButton_1 = __importDefault(require("./Tools/Underline/UnderlineButton"));
|
12
|
+
const UnorderedListButton_1 = __importDefault(require("./Tools/UnorderedList/UnorderedListButton"));
|
12
13
|
const BoldButton_1 = __importDefault(require("./Tools/Bold/BoldButton"));
|
13
14
|
const TextAlignButtons_1 = __importDefault(require("./Tools/TextAlign/TextAlignButtons"));
|
14
15
|
const UndoButton_1 = __importDefault(require("./Tools/Undo/UndoButton"));
|
@@ -31,7 +32,9 @@ const Toolbar = ({ isVisible }) => {
|
|
31
32
|
extensionNames.italic && react_1.default.createElement(ItalicButton_1.default, null),
|
32
33
|
extensionNames.underline && react_1.default.createElement(UnderlineButton_1.default, null),
|
33
34
|
extensionNames.nodeFormatting && react_1.default.createElement(TextAlignButtons_1.default, null),
|
35
|
+
extensionNames.bulletList && react_1.default.createElement(UnorderedListButton_1.default, null),
|
34
36
|
extensionNames.link && (react_1.default.createElement(react_1.default.Fragment, null,
|
37
|
+
react_1.default.createElement(react_components_1.VerticalDivider, null),
|
35
38
|
react_1.default.createElement(LinkButton_1.default, null),
|
36
39
|
react_1.default.createElement(RemoveLinkButton_1.default, null))),
|
37
40
|
extensionNames.image && react_1.default.createElement(ImageButton_1.default, null),
|
@@ -0,0 +1,22 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const react_1 = __importDefault(require("react"));
|
7
|
+
const react_2 = require("@remirror/react");
|
8
|
+
const Button_1 = __importDefault(require("../../../ui/Button/Button"));
|
9
|
+
const FormatListBulletedRounded_1 = __importDefault(require("@mui/icons-material/FormatListBulletedRounded"));
|
10
|
+
const UnorderedListButton = () => {
|
11
|
+
const { toggleBulletList } = (0, react_2.useCommands)();
|
12
|
+
const chain = (0, react_2.useChainedCommands)();
|
13
|
+
const active = (0, react_2.useActive)();
|
14
|
+
const enabled = toggleBulletList.enabled();
|
15
|
+
const handleSelect = () => {
|
16
|
+
if (toggleBulletList.enabled()) {
|
17
|
+
chain.toggleBulletList().focus().run();
|
18
|
+
}
|
19
|
+
};
|
20
|
+
return (react_1.default.createElement(Button_1.default, { handleOnClick: handleSelect, isDisabled: !enabled, isActive: active.bulletList(), icon: react_1.default.createElement(FormatListBulletedRounded_1.default, null), label: "Unordered list" }));
|
21
|
+
};
|
22
|
+
exports.default = UnorderedListButton;
|
@@ -48,6 +48,8 @@ const createExtensions = (context) => {
|
|
48
48
|
}),
|
49
49
|
new UnsupportedNodeExtension_1.UnsupportedNodeExtension(),
|
50
50
|
new ClearFormattingExtension_1.ClearFormattingExtension(),
|
51
|
+
new extensions_1.BulletListExtension(),
|
52
|
+
new extensions_1.ListItemExtension(),
|
51
53
|
];
|
52
54
|
};
|
53
55
|
};
|
package/lib/index.css
CHANGED
@@ -709,6 +709,11 @@
|
|
709
709
|
padding-top: 0.75rem;
|
710
710
|
padding-bottom: 0.75rem;
|
711
711
|
}
|
712
|
+
.squiz-fte-scope .remirror-editor ul {
|
713
|
+
list-style-type: disc;
|
714
|
+
padding: 0 0 0 2.5rem;
|
715
|
+
margin: 1rem 0;
|
716
|
+
}
|
712
717
|
.squiz-fte-scope .squiz-fte-form-group {
|
713
718
|
display: flex;
|
714
719
|
flex-direction: column;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@squiz/formatted-text-editor",
|
3
|
-
"version": "1.40.1-alpha.
|
3
|
+
"version": "1.40.1-alpha.9",
|
4
4
|
"main": "lib/index.js",
|
5
5
|
"types": "lib/index.d.ts",
|
6
6
|
"scripts": {
|
@@ -20,8 +20,8 @@
|
|
20
20
|
"@headlessui/react": "1.7.11",
|
21
21
|
"@mui/icons-material": "5.11.16",
|
22
22
|
"@remirror/react": "2.0.25",
|
23
|
-
"@squiz/dx-json-schema-lib": "1.40.1-alpha.
|
24
|
-
"@squiz/resource-browser": "1.40.1-alpha.
|
23
|
+
"@squiz/dx-json-schema-lib": "1.40.1-alpha.9",
|
24
|
+
"@squiz/resource-browser": "1.40.1-alpha.9",
|
25
25
|
"clsx": "1.2.1",
|
26
26
|
"react-hook-form": "7.43.2",
|
27
27
|
"react-image-size": "2.0.0",
|
@@ -75,5 +75,5 @@
|
|
75
75
|
"volta": {
|
76
76
|
"node": "18.15.0"
|
77
77
|
},
|
78
|
-
"gitHead": "
|
78
|
+
"gitHead": "c613b6cf103eb0e484153adecbef5d589bff872b"
|
79
79
|
}
|
@@ -3,6 +3,7 @@ import { Toolbar as RemirrorToolbar, VerticalDivider } from '@remirror/react-com
|
|
3
3
|
import clsx from 'clsx';
|
4
4
|
import ItalicButton from './Tools/Italic/ItalicButton';
|
5
5
|
import UnderlineButton from './Tools/Underline/UnderlineButton';
|
6
|
+
import UnorderedListButton from './Tools/UnorderedList/UnorderedListButton';
|
6
7
|
import BoldButton from './Tools/Bold/BoldButton';
|
7
8
|
import TextAlignButtons from './Tools/TextAlign/TextAlignButtons';
|
8
9
|
import UndoButton from './Tools/Undo/UndoButton';
|
@@ -38,8 +39,10 @@ export const Toolbar = ({ isVisible }: ToolbarProps) => {
|
|
38
39
|
{extensionNames.italic && <ItalicButton />}
|
39
40
|
{extensionNames.underline && <UnderlineButton />}
|
40
41
|
{extensionNames.nodeFormatting && <TextAlignButtons />}
|
42
|
+
{extensionNames.bulletList && <UnorderedListButton />}
|
41
43
|
{extensionNames.link && (
|
42
44
|
<>
|
45
|
+
<VerticalDivider />
|
43
46
|
<LinkButton />
|
44
47
|
<RemoveLinkButton />
|
45
48
|
</>
|
@@ -0,0 +1,19 @@
|
|
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('Unordered list button', () => {
|
7
|
+
it('Renders the unordered list button', () => {
|
8
|
+
render(<Editor />);
|
9
|
+
expect(screen.getByRole('button', { name: 'Unordered list' })).toBeInTheDocument();
|
10
|
+
});
|
11
|
+
|
12
|
+
it('Activates the button if clicked', () => {
|
13
|
+
render(<Editor />);
|
14
|
+
expect(screen.getByRole('button', { name: 'Unordered list' }).classList.contains('squiz-fte-btn')).toBeTruthy();
|
15
|
+
const ul = screen.getByRole('button', { name: 'Unordered list' });
|
16
|
+
fireEvent.click(ul);
|
17
|
+
expect(ul.classList.contains('squiz-fte-btn--is-active')).toBeTruthy();
|
18
|
+
});
|
19
|
+
});
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { useCommands, useActive, useChainedCommands } from '@remirror/react';
|
3
|
+
import { BulletListExtension } from 'remirror/extensions';
|
4
|
+
import Button from '../../../ui/Button/Button';
|
5
|
+
import FormatListBulletedRoundedIcon from '@mui/icons-material/FormatListBulletedRounded';
|
6
|
+
|
7
|
+
const UnorderedListButton = () => {
|
8
|
+
const { toggleBulletList } = useCommands();
|
9
|
+
const chain = useChainedCommands();
|
10
|
+
|
11
|
+
const active = useActive<BulletListExtension>();
|
12
|
+
const enabled = toggleBulletList.enabled();
|
13
|
+
const handleSelect = () => {
|
14
|
+
if (toggleBulletList.enabled()) {
|
15
|
+
chain.toggleBulletList().focus().run();
|
16
|
+
}
|
17
|
+
};
|
18
|
+
|
19
|
+
return (
|
20
|
+
<Button
|
21
|
+
handleOnClick={handleSelect}
|
22
|
+
isDisabled={!enabled}
|
23
|
+
isActive={active.bulletList()}
|
24
|
+
icon={<FormatListBulletedRoundedIcon />}
|
25
|
+
label="Unordered list"
|
26
|
+
/>
|
27
|
+
);
|
28
|
+
};
|
29
|
+
|
30
|
+
export default UnorderedListButton;
|
@@ -6,6 +6,8 @@ import {
|
|
6
6
|
ParagraphExtension,
|
7
7
|
UnderlineExtension,
|
8
8
|
HistoryExtension,
|
9
|
+
BulletListExtension,
|
10
|
+
ListItemExtension,
|
9
11
|
} from 'remirror/extensions';
|
10
12
|
import { Extension } from '@remirror/core';
|
11
13
|
import { PreformattedExtension } from './PreformattedExtension/PreformattedExtension';
|
@@ -56,6 +58,8 @@ export const createExtensions = (context: EditorContextOptions) => {
|
|
56
58
|
}),
|
57
59
|
new UnsupportedNodeExtension(),
|
58
60
|
new ClearFormattingExtension(),
|
61
|
+
new BulletListExtension(),
|
62
|
+
new ListItemExtension(),
|
59
63
|
];
|
60
64
|
};
|
61
65
|
};
|
package/src/ui/_typography.scss
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
// Add any formatting we want the editor to have for the tools we have added - all default styling has been removed by the reset
|
1
2
|
.remirror-editor {
|
2
3
|
a {
|
3
4
|
@apply text-blue-300;
|
@@ -71,4 +72,10 @@
|
|
71
72
|
padding-bottom: 0.75rem;
|
72
73
|
}
|
73
74
|
}
|
75
|
+
|
76
|
+
ul {
|
77
|
+
list-style-type: disc;
|
78
|
+
padding: 0 0 0 2.5rem;
|
79
|
+
margin: 1rem 0;
|
80
|
+
}
|
74
81
|
}
|
@@ -425,4 +425,122 @@ describe('squizNodeToRemirrorNode', () => {
|
|
425
425
|
});
|
426
426
|
},
|
427
427
|
);
|
428
|
+
|
429
|
+
it('should handle unordered lists', () => {
|
430
|
+
const squizComponentJSON: FormattedText = [
|
431
|
+
{
|
432
|
+
type: 'tag',
|
433
|
+
tag: 'ul',
|
434
|
+
children: [
|
435
|
+
{
|
436
|
+
type: 'tag',
|
437
|
+
tag: 'li',
|
438
|
+
children: [
|
439
|
+
{
|
440
|
+
type: 'tag',
|
441
|
+
tag: 'p',
|
442
|
+
children: [
|
443
|
+
{
|
444
|
+
type: 'text',
|
445
|
+
value: 'chicken',
|
446
|
+
},
|
447
|
+
],
|
448
|
+
},
|
449
|
+
],
|
450
|
+
},
|
451
|
+
{
|
452
|
+
type: 'tag',
|
453
|
+
tag: 'li',
|
454
|
+
children: [
|
455
|
+
{
|
456
|
+
type: 'tag',
|
457
|
+
tag: 'p',
|
458
|
+
children: [
|
459
|
+
{
|
460
|
+
type: 'text',
|
461
|
+
value: 'egg',
|
462
|
+
},
|
463
|
+
],
|
464
|
+
},
|
465
|
+
],
|
466
|
+
},
|
467
|
+
],
|
468
|
+
},
|
469
|
+
];
|
470
|
+
|
471
|
+
const expected: RemirrorJSON = {
|
472
|
+
content: [
|
473
|
+
{
|
474
|
+
attrs: { level: undefined, nodeIndent: null, nodeLineHeight: null, nodeTextAlignment: null, style: '' },
|
475
|
+
type: 'bulletList',
|
476
|
+
marks: undefined,
|
477
|
+
text: undefined,
|
478
|
+
content: [
|
479
|
+
{
|
480
|
+
attrs: { level: undefined, nodeIndent: null, nodeLineHeight: null, nodeTextAlignment: null, style: '' },
|
481
|
+
type: 'listItem',
|
482
|
+
marks: undefined,
|
483
|
+
text: undefined,
|
484
|
+
content: [
|
485
|
+
{
|
486
|
+
attrs: {
|
487
|
+
level: undefined,
|
488
|
+
nodeIndent: null,
|
489
|
+
nodeLineHeight: null,
|
490
|
+
nodeTextAlignment: null,
|
491
|
+
style: '',
|
492
|
+
},
|
493
|
+
marks: undefined,
|
494
|
+
text: undefined,
|
495
|
+
type: 'paragraph',
|
496
|
+
content: [
|
497
|
+
{
|
498
|
+
attrs: undefined,
|
499
|
+
content: undefined,
|
500
|
+
marks: undefined,
|
501
|
+
text: 'chicken',
|
502
|
+
type: 'text',
|
503
|
+
},
|
504
|
+
],
|
505
|
+
},
|
506
|
+
],
|
507
|
+
},
|
508
|
+
{
|
509
|
+
attrs: { level: undefined, nodeIndent: null, nodeLineHeight: null, nodeTextAlignment: null, style: '' },
|
510
|
+
type: 'listItem',
|
511
|
+
marks: undefined,
|
512
|
+
text: undefined,
|
513
|
+
content: [
|
514
|
+
{
|
515
|
+
attrs: {
|
516
|
+
level: undefined,
|
517
|
+
nodeIndent: null,
|
518
|
+
nodeLineHeight: null,
|
519
|
+
nodeTextAlignment: null,
|
520
|
+
style: '',
|
521
|
+
},
|
522
|
+
marks: undefined,
|
523
|
+
text: undefined,
|
524
|
+
type: 'paragraph',
|
525
|
+
content: [
|
526
|
+
{
|
527
|
+
attrs: undefined,
|
528
|
+
content: undefined,
|
529
|
+
marks: undefined,
|
530
|
+
text: 'egg',
|
531
|
+
type: 'text',
|
532
|
+
},
|
533
|
+
],
|
534
|
+
},
|
535
|
+
],
|
536
|
+
},
|
537
|
+
],
|
538
|
+
},
|
539
|
+
],
|
540
|
+
type: 'doc',
|
541
|
+
};
|
542
|
+
|
543
|
+
const result = squizNodeToRemirrorNode(squizComponentJSON);
|
544
|
+
expect(result).toEqual(expected);
|
545
|
+
});
|
428
546
|
});
|
@@ -15,6 +15,15 @@ describe('getNodeNamesByGroup', () => {
|
|
15
15
|
// Nodes in the first array will be transformed to a paragraph when formatting is cleared.
|
16
16
|
// Nodes in the second array will be left as-is.
|
17
17
|
expect(formattingNodeNames).toEqual(['paragraph', 'heading', 'preformatted']);
|
18
|
-
expect(otherNodeNames).toEqual([
|
18
|
+
expect(otherNodeNames).toEqual([
|
19
|
+
'assetImage',
|
20
|
+
'doc',
|
21
|
+
'text',
|
22
|
+
'codeBlock',
|
23
|
+
'image',
|
24
|
+
'unsupportedNode',
|
25
|
+
'bulletList',
|
26
|
+
'listItem',
|
27
|
+
]);
|
19
28
|
});
|
20
29
|
});
|