PluginProbe
Tableberg – Simple Gutenberg Table Block / 1.1.5
Tableberg – Simple Gutenberg Table Block v1.1.5
1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.5 1.0.4 1.0.3 1.0.2 1.0.1 trunk 0.0.2 0.2.1 0.3.2 0.3.3 0.4.1 0.5.0 0.5.1 0.5.2 0.5.3 0.5.4 0.5.5 0.5.6 0.5.7 All 42 releases
tableberg / src / components / ElementOptionsButton.tsx

ElementOptionsButton.tsx in Tableberg – Simple Gutenberg Table Block 1.1.5, at src/components/ElementOptionsButton.tsx

237 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import {
2 MenuGroup,
3 MenuItem,
4 ToolbarDropdownMenu,
5 } from "@wordpress/components";
6 import { BlockControls } from "@wordpress/block-editor";
7 import { __ } from "@wordpress/i18n";
8 import { moreVertical } from "@wordpress/icons";
9
10 import { createElement } from "../elements";
11 import {
12 applyElementStyleClipboardPayload,
13 parseElementStyleClipboardPayload,
14 readClipboardText,
15 serializeElementClipboardPayload,
16 serializeElementStyleClipboardPayload,
17 writeClipboardText,
18 } from "../hooks/block-editor-compat/elementClipboard";
19 import { CellKey } from "../attributes";
20 import { useTableStore } from "../store";
21
22 function getShortcutRepresentation(name: string): string | undefined {
23 const store = window.wp?.keyboardShortcuts?.store;
24 const select = window.wp?.data?.select;
25
26 if (!store || !select) {
27 return undefined;
28 }
29
30 return select(store).getShortcutRepresentation?.(name);
31 }
32
33 export function ElementOptionsButton({
34 cellCoords,
35 elementIndex,
36 }: {
37 cellCoords: CellKey;
38 elementIndex: number;
39 }) {
40 const cells = useTableStore(state => state.cells);
41 const insertElementInCell = useTableStore(
42 state => state.insertElementInCell
43 );
44 const duplicateElementInCell = useTableStore(
45 state => state.duplicateElementInCell
46 );
47 const removeElementFromCell = useTableStore(
48 state => state.removeElementFromCell
49 );
50 const updateCellElement = useTableStore(state => state.updateCellElement);
51
52 const selectedElement = cells[cellCoords]?.elements?.[elementIndex] || null;
53 const shortcuts = {
54 copy: getShortcutRepresentation("core/block-editor/copy"),
55 cut: getShortcutRepresentation("core/block-editor/cut"),
56 duplicate: getShortcutRepresentation("core/block-editor/duplicate"),
57 insertBefore: getShortcutRepresentation(
58 "core/block-editor/insert-before"
59 ),
60 insertAfter: getShortcutRepresentation(
61 "core/block-editor/insert-after"
62 ),
63 remove: getShortcutRepresentation("core/block-editor/remove"),
64 };
65
66 if (!selectedElement) {
67 return null;
68 }
69
70 const insertTextElement = (targetIndex: number) => {
71 const textElement = createElement("text");
72
73 if (!textElement) {
74 return;
75 }
76
77 insertElementInCell(cellCoords, targetIndex, textElement);
78 };
79
80 return (
81 <ToolbarDropdownMenu
82 icon={moreVertical}
83 label={__("Element options", "tableberg")}
84 toggleProps={{
85 title: __("Element options", "tableberg"),
86 showTooltip: true,
87 }}
88 popoverProps={{ placement: "bottom-start" }}
89 >
90 {({ onClose }) => (
91 <>
92 <MenuGroup>
93 <MenuItem
94 shortcut={shortcuts.copy}
95 onClick={() => {
96 void writeClipboardText(
97 serializeElementClipboardPayload(
98 selectedElement
99 )
100 );
101 onClose();
102 }}
103 >
104 {__("Copy", "tableberg")}
105 </MenuItem>
106 <MenuItem
107 onClick={() => {
108 void writeClipboardText(
109 serializeElementStyleClipboardPayload(
110 selectedElement
111 )
112 );
113 onClose();
114 }}
115 >
116 {__("Copy styles", "tableberg")}
117 </MenuItem>
118 <MenuItem
119 onClick={() => {
120 void (async () => {
121 const clipboardText =
122 await readClipboardText();
123 const stylePayload =
124 parseElementStyleClipboardPayload(
125 clipboardText
126 );
127
128 if (!stylePayload) {
129 return;
130 }
131
132 const styledElement =
133 applyElementStyleClipboardPayload(
134 selectedElement,
135 stylePayload
136 );
137
138 updateCellElement(
139 cellCoords,
140 elementIndex,
141 {
142 attributes:
143 styledElement.attributes,
144 }
145 );
146 })();
147 onClose();
148 }}
149 >
150 {__("Paste styles", "tableberg")}
151 </MenuItem>
152 <MenuItem
153 shortcut={shortcuts.cut}
154 onClick={() => {
155 void (async () => {
156 await writeClipboardText(
157 serializeElementClipboardPayload(
158 selectedElement
159 )
160 );
161 removeElementFromCell(
162 cellCoords,
163 elementIndex
164 );
165 })();
166 onClose();
167 }}
168 >
169 {__("Cut", "tableberg")}
170 </MenuItem>
171 <MenuItem
172 shortcut={shortcuts.duplicate}
173 onClick={() => {
174 duplicateElementInCell(
175 cellCoords,
176 elementIndex
177 );
178 onClose();
179 }}
180 >
181 {__("Duplicate", "tableberg")}
182 </MenuItem>
183 </MenuGroup>
184 <MenuGroup>
185 <MenuItem
186 shortcut={shortcuts.insertBefore}
187 onClick={() => {
188 insertTextElement(elementIndex);
189 onClose();
190 }}
191 >
192 {__("Add before", "tableberg")}
193 </MenuItem>
194 <MenuItem
195 shortcut={shortcuts.insertAfter}
196 onClick={() => {
197 insertTextElement(elementIndex + 1);
198 onClose();
199 }}
200 >
201 {__("Add after", "tableberg")}
202 </MenuItem>
203 </MenuGroup>
204 <MenuGroup>
205 <MenuItem
206 shortcut={shortcuts.remove}
207 onClick={() => {
208 removeElementFromCell(cellCoords, elementIndex);
209 onClose();
210 }}
211 >
212 {__("Delete", "tableberg")}
213 </MenuItem>
214 </MenuGroup>
215 </>
216 )}
217 </ToolbarDropdownMenu>
218 );
219 }
220
221 export function ElementOptionsBlockControls({
222 cellCoords,
223 elementIndex,
224 }: {
225 cellCoords: CellKey;
226 elementIndex: number;
227 }) {
228 return (
229 <BlockControls group="other">
230 <ElementOptionsButton
231 cellCoords={cellCoords}
232 elementIndex={elementIndex}
233 />
234 </BlockControls>
235 );
236 }
237