@squiz/formatted-text-editor 1.40.1-alpha.7 → 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.
@@ -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,2 @@
1
+ declare const UnorderedListButton: () => JSX.Element;
2
+ export default UnorderedListButton;
@@ -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;
@@ -19,6 +19,8 @@ const getNodeType = (node) => {
19
19
  img: 'image',
20
20
  pre: 'preformatted',
21
21
  p: 'paragraph',
22
+ ul: 'bulletList',
23
+ li: 'listItem',
22
24
  a: Extensions_1.NodeName.Text,
23
25
  span: Extensions_1.NodeName.Text,
24
26
  code: Extensions_1.NodeName.CodeBlock,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squiz/formatted-text-editor",
3
- "version": "1.40.1-alpha.7",
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.7",
24
- "@squiz/resource-browser": "1.40.1-alpha.7",
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": "dbd76eb0b1dcd9d0c6c2a95ff02fa75acd427609"
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
  };
@@ -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
  });
@@ -24,6 +24,8 @@ const getNodeType = (node: FormattedNodes): string => {
24
24
  img: 'image',
25
25
  pre: 'preformatted',
26
26
  p: 'paragraph',
27
+ ul: 'bulletList',
28
+ li: 'listItem',
27
29
  a: NodeName.Text,
28
30
  span: NodeName.Text,
29
31
  code: NodeName.CodeBlock,
@@ -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(['assetImage', 'doc', 'text', 'codeBlock', 'image', 'unsupportedNode']);
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
  });