playbook_ui 18.1.0.pre.rc.4 → 18.1.0

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/EditorButton.tsx +4 -3
  3. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/MoreExtensionsDropdown.tsx +4 -2
  4. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/Toolbar.tsx +165 -82
  5. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarDropdown.tsx +29 -49
  6. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarFormatItems.tsx +68 -0
  7. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarHistory.tsx +1 -4
  8. data/app/pb_kits/playbook/pb_rich_text_editor/TipTap/ToolbarNodes.tsx +34 -35
  9. data/app/pb_kits/playbook/pb_rich_text_editor/_previewer_mixin.scss +24 -37
  10. data/app/pb_kits/playbook/pb_rich_text_editor/_tiptap_styles.scss +191 -74
  11. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_playground.json +1 -1
  12. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_playground.overrides.json +1 -1
  13. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_extensions.html.erb +5 -0
  14. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_extensions.md +9 -0
  15. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_height.html.erb +12 -0
  16. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_height.md +1 -0
  17. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_min_height.html.erb +12 -0
  18. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_min_height.md +1 -0
  19. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_text_align.html.erb +5 -0
  20. data/app/pb_kits/playbook/pb_rich_text_editor/docs/_rich_text_editor_rails_text_align.md +3 -0
  21. data/app/pb_kits/playbook/pb_rich_text_editor/docs/example.yml +7 -3
  22. data/app/pb_kits/playbook/pb_rich_text_editor/kit.schema.json +14 -6
  23. data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.html.erb +153 -82
  24. data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor.rb +43 -0
  25. data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor_rails.js +288 -85
  26. data/app/pb_kits/playbook/pb_rich_text_editor/rich_text_editor_rails.test.js +178 -0
  27. data/app/pb_kits/playbook/pb_table/_table.tsx +0 -3
  28. data/app/pb_kits/playbook/pb_table/docs/_playground.json +0 -2
  29. data/app/pb_kits/playbook/pb_table/docs/_playground.overrides.json +1 -1
  30. data/app/pb_kits/playbook/pb_table/docs/_sections.yml +0 -1
  31. data/app/pb_kits/playbook/pb_table/docs/example.yml +0 -2
  32. data/app/pb_kits/playbook/pb_table/docs/index.js +0 -1
  33. data/app/pb_kits/playbook/pb_table/kit.schema.json +0 -8
  34. data/app/pb_kits/playbook/pb_table/styles/_all.scss +0 -1
  35. data/app/pb_kits/playbook/pb_table/table.rb +1 -7
  36. data/dist/ai/all-schemas.json +15 -15
  37. data/dist/ai/external-dependencies.json +1 -1
  38. data/dist/ai/forms.json +1 -1
  39. data/dist/ai/index.json +3 -3
  40. data/dist/ai/kits/rich_text_editor.schema.json +15 -7
  41. data/dist/ai/kits/table.schema.json +0 -8
  42. data/dist/ai/playgrounds/rich_text_editor.json +1 -1
  43. data/dist/chunks/_detail-CDUjsRrc.js +5 -0
  44. data/dist/chunks/{_pb_line_graph-BGyCJjgG.js → _pb_line_graph-CUJ7NJIr.js} +1 -1
  45. data/dist/chunks/_table-C9KHGQhb.js +1 -0
  46. data/dist/chunks/_typeahead-CfxZLhd3.js +1 -0
  47. data/dist/chunks/{globalProps-K1DCn3il.js → globalProps-DDcpyjvz.js} +1 -1
  48. data/dist/chunks/lib-D57mygNT.js +29 -0
  49. data/dist/chunks/{time_picker_helper-BZutIzB3.js → time_picker_helper-B_FN8E9Y.js} +1 -1
  50. data/dist/chunks/vendor.js +2 -2
  51. data/dist/playbook-rails-react-bindings.js +1 -1
  52. data/dist/playbook-rails.js +1 -1
  53. data/dist/playbook.css +1 -1
  54. data/lib/playbook/version.rb +1 -1
  55. metadata +19 -12
  56. data/app/pb_kits/playbook/pb_table/docs/_table_single_line.html.erb +0 -55
  57. data/app/pb_kits/playbook/pb_table/docs/_table_single_line.jsx +0 -78
  58. data/app/pb_kits/playbook/pb_table/styles/_single-line.scss +0 -34
  59. data/dist/chunks/_detail-BqqzPTNr.js +0 -5
  60. data/dist/chunks/_table-BrYlBrTH.js +0 -1
  61. data/dist/chunks/_typeahead-KNcX62pc.js +0 -1
  62. data/dist/chunks/lib-7vm9BMqp.js +0 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 81d76f51de9e88ac32f50756b803e8a063264b582bc8e9797ef49e2dfba04867
4
- data.tar.gz: 5a214970102ba6d3a2abe9a4e2342aaf4e79b2e1e55b8ad6acdd597580e678ce
3
+ metadata.gz: 4989243cbc32bb750918ef297467d634a7db628b51bbf211895e293f3d14feeb
4
+ data.tar.gz: ee6a1cad85e386cd21a8d584c8715b97070f7a69b9ccb5cdb388f031cc1b7e81
5
5
  SHA512:
6
- metadata.gz: 7ca0873a34437139622dca8b4848cde6f266bfb059caa97af140a2226e327772bea439c0b90140e9dba01f32082ee6cf8ea066ad1c626a77ea5de7e9efcf88a5
7
- data.tar.gz: af0f9628b3defe688b29dacf8beffb13e37235c30e92e1eb6b6cf4af96708ed1c4d0a072704ecb990ae74bd8759b0cbb1dae5a81d2ddea2322cad39a90ebfca3
6
+ metadata.gz: 9823736cae61fe883d0210734d6c12163fae9a4d5e5b1f17ed8da990b5dbad5e816fc49374b672fe04bb3f1e6fc9b7c5704faf39f7119c170cad30954a6393f3
7
+ data.tar.gz: c72caccadf7ab6a8f10fd9ee1197b06c1fba46a684f893b4f5d16525b91e6a69358aa51e1301fd7b9465127b34ac00c678263ed20258b2f90cc603443ea41243
@@ -41,8 +41,9 @@ const EditorButton = ({
41
41
  className="toolbar_button_icon"
42
42
  justify="center"
43
43
  >
44
- <Icon icon={icon}
45
- size="lg"
44
+ <Icon
45
+ icon={icon}
46
+ size="1x"
46
47
  />
47
48
  </Flex>
48
49
  </button>
@@ -50,4 +51,4 @@ const EditorButton = ({
50
51
  );
51
52
  };
52
53
 
53
- export default EditorButton
54
+ export default EditorButton
@@ -30,8 +30,9 @@ const popoverReference = (
30
30
  className="toolbar_button_icon"
31
31
  justify="center"
32
32
  >
33
- <Icon icon="ellipsis"
34
- size="lg"
33
+ <Icon
34
+ icon="ellipsis"
35
+ size="1x"
35
36
  />
36
37
  </Flex>
37
38
  </button>
@@ -40,6 +41,7 @@ const popoverReference = (
40
41
 
41
42
  return (
42
43
  <PbReactPopover
44
+ className='pb_tiptap_toolbar_dropdown_popover'
43
45
  closeOnClick='outside'
44
46
  padding='none'
45
47
  placement="bottom"
@@ -1,37 +1,112 @@
1
- import React from "react";
1
+ import React, { useLayoutEffect, useRef, useState } from "react";
2
2
  import Background from "../../pb_background/_background";
3
3
  import Flex from "../../pb_flex/_flex";
4
- import FlexItem from "../../pb_flex/_flex_item";
5
4
  import SectionSeparator from "../../pb_section_separator/_section_separator";
6
5
 
7
6
  import EditorButton from "./EditorButton";
8
7
  import ToolbarDropdown from "./ToolbarDropdown";
8
+ import ToolbarFormatItems from "./ToolbarFormatItems";
9
9
  import ToolbarNodes from "./ToolbarNodes";
10
10
  import { ToolbarTypes } from "./EditorTypes";
11
11
  import ToolbarHistoryItems from "./ToolbarHistory";
12
12
  import MoreExtensionsDropdown from "./MoreExtensionsDropdown";
13
13
 
14
+ const STACK_HYSTERESIS_PX = 32;
15
+ const STACK_FIT_BUFFER_PX = 8;
16
+
17
+ const ToolbarSeparator = (): React.ReactElement => (
18
+ <div className="toolbar_separator">
19
+ <SectionSeparator orientation="vertical" />
20
+ </div>
21
+ );
22
+
23
+ const childrenWidth = (element: HTMLElement): number =>
24
+ Array.from(element.children).reduce(
25
+ (sum, child) => sum + (child as HTMLElement).offsetWidth,
26
+ 0
27
+ );
28
+
29
+ // Stack when format + tools (+ more) no longer fit beside undo/redo.
30
+ const toolsNeedStack = (root: HTMLElement | null): boolean => {
31
+ if (!root) return false;
32
+
33
+ const format = root.querySelector<HTMLElement>(".toolbar_group_format");
34
+ const tools = root.querySelector<HTMLElement>(".toolbar_group_tools");
35
+ if (!format || !tools) return false;
36
+
37
+ const more = root.querySelector<HTMLElement>(".toolbar_group_more");
38
+ const history = root.querySelector<HTMLElement>(".toolbar_history");
39
+ const { paddingLeft, paddingRight } = window.getComputedStyle(root);
40
+ const rightReserve = Math.max(history?.offsetWidth ?? 0, parseFloat(paddingRight) || 0);
41
+ const available = root.clientWidth - (parseFloat(paddingLeft) || 0) - rightReserve;
42
+ const needed =
43
+ childrenWidth(format) +
44
+ childrenWidth(tools) +
45
+ (more ? childrenWidth(more) : 0) +
46
+ STACK_FIT_BUFFER_PX;
47
+
48
+ return needed > available;
49
+ };
50
+
51
+ const nextStacked = (
52
+ stacked: boolean,
53
+ stackedAtWidth: number,
54
+ needsStack: boolean,
55
+ width: number
56
+ ): { stacked: boolean, stackedAtWidth: number } => {
57
+ if (needsStack) {
58
+ return {
59
+ stacked: true,
60
+ stackedAtWidth: stacked ? Math.min(stackedAtWidth, width) : width,
61
+ };
62
+ }
63
+
64
+ if (stacked && width > stackedAtWidth + STACK_HYSTERESIS_PX) {
65
+ return { stacked: false, stackedAtWidth };
66
+ }
67
+
68
+ return { stacked, stackedAtWidth };
69
+ };
70
+
14
71
  const EditorToolbar = ({ editor, extensions, simple, sticky }: any): React.ReactElement => {
15
- const toolbaritems = [
16
- {
17
- icon: "bold",
18
- text: "Bold",
19
- classname:`toolbar_button ${editor.isActive('bold') ? 'is-active' : ''}`,
20
- onclick:()=>editor.chain().focus().toggleBold().run(),
21
- },
22
- {
23
- icon: "italic",
24
- text: "Italic",
25
- classname:`toolbar_button ${editor.isActive('italic') ? 'is-active' : ''}`,
26
- onclick:() => editor.chain().focus().toggleItalic().run(),
27
- },
28
- {
29
- icon: "strikethrough",
30
- text: "Strikethrough",
31
- classname:`toolbar_button ${editor.isActive('strike') ? 'is-active' : ''}`,
32
- onclick:() => editor.chain().focus().toggleStrike().run(),
33
- },
34
- ]
72
+ const toolbarInnerRef = useRef<HTMLDivElement>(null);
73
+ const stackedAtWidthRef = useRef(0);
74
+ const [toolsStacked, setToolsStacked] = useState(false);
75
+
76
+ useLayoutEffect(() => {
77
+ if (simple) return;
78
+
79
+ const root = toolbarInnerRef.current;
80
+ if (!root) return;
81
+
82
+ const toolbar = root.closest(".toolbar");
83
+
84
+ const sync = () => {
85
+ const width = toolbar?.clientWidth ?? root.clientWidth;
86
+ const needsStack = toolsNeedStack(root);
87
+
88
+ setToolsStacked((stacked) => {
89
+ const next = nextStacked(stacked, stackedAtWidthRef.current, needsStack, width);
90
+ stackedAtWidthRef.current = next.stackedAtWidth;
91
+ return next.stacked;
92
+ });
93
+ };
94
+
95
+ sync();
96
+ const rafId = requestAnimationFrame(sync);
97
+
98
+ if (typeof ResizeObserver === "undefined") {
99
+ return () => cancelAnimationFrame(rafId);
100
+ }
101
+
102
+ const observer = new ResizeObserver(sync);
103
+ observer.observe(toolbar || root);
104
+
105
+ return () => {
106
+ cancelAnimationFrame(rafId);
107
+ observer.disconnect();
108
+ };
109
+ }, [extensions, simple]);
35
110
 
36
111
  const simpleToolbaritems = [
37
112
  {
@@ -48,69 +123,77 @@ const EditorToolbar = ({ editor, extensions, simple, sticky }: any): React.React
48
123
  },
49
124
  ]
50
125
 
126
+ const toolbarClassName = [
127
+ "toolbar",
128
+ toolsStacked && "toolbar_tools_stacked",
129
+ sticky && "pb_rich_text_editor_tiptap_toolbar_sticky",
130
+ ].filter(Boolean).join(" ");
131
+
51
132
  return (
52
- <Background backgroundColor="white"
53
- className={`toolbar ${sticky ? 'pb_rich_text_editor_tiptap_toolbar_sticky' : ''}`}
54
-
133
+ <Background
134
+ backgroundColor="white"
135
+ className={toolbarClassName}
55
136
  >
56
- <Flex flex="0"
57
- justify="between"
58
- paddingX="sm"
59
- paddingY="xxs"
60
- >
61
- {
62
- simple ? (
63
- <>
64
- <Flex className="toolbar_block">
65
- {simpleToolbaritems && simpleToolbaritems.map(
66
- ({ icon, text, classname, onclick}: ToolbarTypes, index: number) => (
67
- <EditorButton
68
- classname={classname}
69
- icon={icon}
70
- key={index}
71
- onclick={onclick}
72
- text={text}
73
- />
74
- )
75
- )}
76
- </Flex>
77
- </>
78
- ) : (
79
- <>
80
- <FlexItem className="toolbar_block"
81
- displayFlex
82
- >
83
- <ToolbarDropdown editor={editor}/>
84
- <SectionSeparator orientation="vertical" />
85
- {toolbaritems && toolbaritems.map(
86
- ({ icon, text, classname, onclick}: ToolbarTypes, index: number) => (
87
- <EditorButton
88
- classname={classname}
89
- icon={icon}
90
- key={index}
91
- onclick={onclick}
92
- text={text}
93
- />
94
- )
95
- )}
96
- <SectionSeparator orientation="vertical" />
97
- <ToolbarNodes editor={editor} />
98
- {
99
- extensions && (
100
- <>
101
- <MoreExtensionsDropdown extensions={extensions}/>
102
- </>
103
- )
104
- }
105
- </FlexItem>
106
- <ToolbarHistoryItems editor={editor} />
107
- </>
108
- )
109
- }
110
-
111
- </Flex>
137
+ {
138
+ simple ? (
139
+ <div className="toolbar_inner">
140
+ <Flex
141
+ align="center"
142
+ className="toolbar_controls"
143
+ wrap
144
+ >
145
+ {simpleToolbaritems && simpleToolbaritems.map(
146
+ ({ icon, text, classname, onclick}: ToolbarTypes, index: number) => (
147
+ <EditorButton
148
+ classname={classname}
149
+ icon={icon}
150
+ key={index}
151
+ onclick={onclick}
152
+ text={text}
153
+ />
154
+ )
155
+ )}
156
+ </Flex>
157
+ <div className="toolbar_history">
158
+ <ToolbarHistoryItems editor={editor} />
159
+ </div>
160
+ </div>
161
+ ) : (
162
+ <div
163
+ className="toolbar_inner"
164
+ ref={toolbarInnerRef}
165
+ >
166
+ <Flex
167
+ align="center"
168
+ className="toolbar_controls"
169
+ wrap
170
+ >
171
+ <div className="toolbar_group toolbar_group_format">
172
+ <ToolbarDropdown editor={editor}/>
173
+ </div>
174
+ <div className="toolbar_group toolbar_group_tools">
175
+ <ToolbarSeparator />
176
+ <ToolbarFormatItems editor={editor} />
177
+ <ToolbarSeparator />
178
+ <ToolbarNodes editor={editor} />
179
+ </div>
180
+ {
181
+ extensions && (
182
+ <div className="toolbar_group toolbar_group_more">
183
+ <ToolbarSeparator />
184
+ <MoreExtensionsDropdown extensions={extensions}/>
185
+ </div>
186
+ )
187
+ }
188
+ </Flex>
189
+ <div className="toolbar_history">
190
+ <ToolbarHistoryItems editor={editor} />
191
+ </div>
192
+ </div>
193
+ )
194
+ }
112
195
  </Background>
113
196
  );
114
197
  };
115
198
 
116
- export default EditorToolbar
199
+ export default EditorToolbar
@@ -60,8 +60,7 @@ const toolbarDropdownItems = [
60
60
  onclick: () => {
61
61
  normalizeListSelection(editor)
62
62
  editor.chain().focus().toggleOrderedList().run()
63
- }
64
- ,
63
+ },
65
64
  },
66
65
  {
67
66
  node: "blockquote",
@@ -70,6 +69,13 @@ const toolbarDropdownItems = [
70
69
  text: "Block Quote",
71
70
  onclick: () => editor.chain().focus().toggleBlockquote().run(),
72
71
  },
72
+ {
73
+ node: "codeBlock",
74
+ icon: "code",
75
+ isActive: editor.isActive("codeBlock"),
76
+ text: "Code Block",
77
+ onclick: () => editor.chain().focus().toggleCodeBlock().run(),
78
+ },
73
79
  ]
74
80
 
75
81
  const handleTogglePopover = () => {
@@ -81,61 +87,36 @@ const toolbarDropdownItems = [
81
87
  }
82
88
 
83
89
  let activeCount = 0;
84
- const activeItems = [];
90
+ const activeLabels = [];
85
91
 
86
- for (const { text, isActive, icon } of toolbarDropdownItems) {
92
+ for (const { text, isActive } of toolbarDropdownItems) {
87
93
  if (isActive) {
88
- activeCount ++
89
- activeItems.push(
90
- <Flex align="center"
91
- gap="xs"
92
- key={icon}
93
- >
94
- <Icon icon={icon}
95
- size="lg"
96
- />
97
- <div>{text}</div>
98
- <Icon
99
- fixedWidth
100
- flip={showPopover ? "vertical" : "none"}
101
- icon="angle-down"
102
- margin-left="xs"
103
- />
104
- </Flex>
105
- );
94
+ activeCount++
95
+ activeLabels.push(text);
106
96
  }
107
97
  }
108
98
 
99
+ const triggerLabel =
100
+ activeCount === 2 ? activeLabels[1] :
101
+ activeCount === 1 ? activeLabels[0] :
102
+ "Paragraph";
103
+
109
104
  const popoverReference = (
110
105
  <Button className="editor-dropdown-button"
111
106
  onClick={handleTogglePopover}
112
107
  variant="secondary"
113
108
  >
114
- {
115
- activeCount === 2 ? (
116
- activeItems[1]
117
- ) : (
118
- activeCount === 1 ? (
119
- activeItems[0] || null
120
- ) : (
121
- <Flex align="center"
122
- gap="xs"
123
- key="paragraph"
124
- >
125
- <Icon icon="paragraph"
126
- size="lg"
127
- />
128
- <div>Paragraph</div>
129
- <Icon
130
- fixedWidth
131
- flip={showPopover ? "vertical" : "none"}
132
- icon="angle-down"
133
- margin-left="xs"
134
- />
135
- </Flex>
136
- )
137
- )
138
- }
109
+ <Flex
110
+ align="center"
111
+ gap="xs"
112
+ >
113
+ <div>{triggerLabel}</div>
114
+ <Icon
115
+ fixedWidth
116
+ flip={showPopover ? "vertical" : "none"}
117
+ icon="angle-down"
118
+ />
119
+ </Flex>
139
120
  </Button>
140
121
  );
141
122
 
@@ -154,11 +135,10 @@ const popoverReference = (
154
135
  paddingTop="xs"
155
136
  variant="subtle"
156
137
  >
157
- {toolbarDropdownItems.map(({ icon, text, onclick, isActive}: ToolbarTypes, index: number) => (
138
+ {toolbarDropdownItems.map(({ text, onclick, isActive}: ToolbarTypes, index: number) => (
158
139
  <NavItem
159
140
  className={`pb_tiptap_toolbar_dropdown_list_item ${isActive ? "is-active" : ""}`}
160
141
  cursor="pointer"
161
- iconLeft={icon}
162
142
  key={`${text}_${index}`}
163
143
  margin='none'
164
144
  onClick={()=> {onclick(); setShowPopover(false)}}
@@ -0,0 +1,68 @@
1
+ import React, {useCallback} from "react";
2
+ import EditorButton from "./EditorButton";
3
+ import { ToolbarTypes } from "./EditorTypes";
4
+
5
+ const ToolbarFormatItems = ({editor}: any): React.ReactElement => {
6
+ const setLink = useCallback(() => {
7
+ const previousUrl = editor.getAttributes("link").href;
8
+ const url = window.prompt("URL", previousUrl);
9
+
10
+ // cancelled
11
+ if (url === null) {
12
+ return;
13
+ }
14
+
15
+ // empty
16
+ if (url === "") {
17
+ editor.chain().focus().extendMarkRange("link").unsetLink().run();
18
+
19
+ return;
20
+ }
21
+
22
+ // update link
23
+ editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
24
+ }, [editor]);
25
+
26
+ const toolbarFormatItems = [
27
+ {
28
+ icon: "bold",
29
+ text: "Bold",
30
+ classname: `toolbar_button ${editor.isActive("bold") ? "is-active" : ""}`,
31
+ onclick: () => editor.chain().focus().toggleBold().run(),
32
+ },
33
+ {
34
+ icon: "italic",
35
+ text: "Italic",
36
+ classname: `toolbar_button ${editor.isActive("italic") ? "is-active" : ""}`,
37
+ onclick: () => editor.chain().focus().toggleItalic().run(),
38
+ },
39
+ {
40
+ icon: "strikethrough",
41
+ text: "Strikethrough",
42
+ classname: `toolbar_button ${editor.isActive("strike") ? "is-active" : ""}`,
43
+ onclick: () => editor.chain().focus().toggleStrike().run(),
44
+ },
45
+ {
46
+ icon: "link",
47
+ text: "Link",
48
+ classname: `toolbar_button ${editor.isActive("link") ? "is-active" : ""}`,
49
+ onclick: setLink,
50
+ },
51
+ ];
52
+
53
+ return (
54
+ <>
55
+ {toolbarFormatItems.map(({ icon, text, classname, onclick }: ToolbarTypes, index: number) => (
56
+ <EditorButton
57
+ classname={classname}
58
+ icon={icon}
59
+ key={index}
60
+ onclick={onclick}
61
+ text={text}
62
+ />
63
+ ))}
64
+ </>
65
+ );
66
+ };
67
+
68
+ export default ToolbarFormatItems;
@@ -1,5 +1,4 @@
1
1
  import React from "react";
2
- import FlexItem from "../../pb_flex/_flex_item";
3
2
  import EditorButton from "./EditorButton";
4
3
  import { ToolbarTypes } from "./EditorTypes";
5
4
 
@@ -24,7 +23,6 @@ const toolbarHistoryItems = [
24
23
 
25
24
  return (
26
25
  <>
27
- <FlexItem displayFlex>
28
26
  {toolbarHistoryItems.map(
29
27
  ({ onclick, classname, disable, icon, text }: ToolbarTypes, index: number) => (
30
28
  <EditorButton
@@ -37,9 +35,8 @@ const toolbarHistoryItems = [
37
35
  />
38
36
  )
39
37
  )}
40
- </FlexItem>
41
38
  </>
42
39
  )
43
40
  }
44
41
 
45
- export default ToolbarHistoryItems
42
+ export default ToolbarHistoryItems
@@ -1,50 +1,49 @@
1
- import React, {useCallback} from "react";
1
+ import React from "react";
2
2
  import EditorButton from "./EditorButton";
3
- import { ToolbarTypes } from "./EditorTypes";
3
+ import { normalizeListSelection } from "./listSelection";
4
4
 
5
5
  const ToolbarNodes = ({editor}: any): React.ReactElement => {
6
-
7
- // eslint-disable-next-line react-hooks/rules-of-hooks
8
- const setLink = useCallback(() => {
9
- const previousUrl = editor.getAttributes("link").href;
10
- const url = window.prompt("URL", previousUrl);
11
-
12
- // cancelled
13
- if (url === null) {
14
- return;
15
- }
16
-
17
- // empty
18
- if (url === "") {
19
- editor.chain().focus().extendMarkRange("link").unsetLink().run();
20
-
21
- return;
22
- }
23
-
24
- // update link
25
- editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
26
- }, [editor]);
27
-
28
- const toolbarNodesItems = [
6
+ const toolbarNodesItems = [
7
+ {
8
+ onclick: () => {
9
+ normalizeListSelection(editor)
10
+ editor.chain().focus().toggleOrderedList().run()
11
+ },
12
+ icon: "list-ol",
13
+ isActive: editor.isActive("orderedList"),
14
+ text: "Ordered List",
15
+ },
16
+ {
17
+ onclick: () => {
18
+ normalizeListSelection(editor)
19
+ editor.chain().focus().toggleBulletList().run()
20
+ },
21
+ icon: "list",
22
+ isActive: editor.isActive("bulletList"),
23
+ text: "Bullet List",
24
+ },
29
25
  {
30
- onclick: () => editor.chain().focus().toggleCodeBlock().run(),
31
- icon: "code",
32
- isActive: editor.isActive("codeBlock"),
33
- text: "Codeblock",
26
+ onclick: () => editor.chain().focus().liftListItem("listItem").run(),
27
+ icon: "dedent",
28
+ isActive: false,
29
+ text: "Dedent",
30
+ disable: !editor.can().chain().focus().liftListItem("listItem").run(),
34
31
  },
35
32
  {
36
- onclick: setLink,
37
- icon: "link",
38
- isActive: editor.isActive("link"),
39
- text: "Link",
33
+ onclick: () => editor.chain().focus().sinkListItem("listItem").run(),
34
+ icon: "indent",
35
+ isActive: false,
36
+ text: "Indent",
37
+ disable: !editor.can().chain().focus().sinkListItem("listItem").run(),
40
38
  },
41
39
  ];
42
40
 
43
41
  return (
44
42
  <>
45
- {toolbarNodesItems.map(({ onclick, icon, text, isActive }: ToolbarTypes, index: number) => (
43
+ {toolbarNodesItems.map(({ onclick, icon, text, isActive, disable }, index) => (
46
44
  <EditorButton
47
45
  classname={`toolbar_button ${isActive ? 'is-active' : ''}`}
46
+ disable={disable}
48
47
  icon={icon}
49
48
  key={index}
50
49
  onclick={onclick}
@@ -56,4 +55,4 @@ return (
56
55
  }
57
56
 
58
57
 
59
- export default ToolbarNodes
58
+ export default ToolbarNodes