PluginProbe
Tableberg – Simple Gutenberg Table Block / 0.0.2
Tableberg – Simple Gutenberg Table Block v0.0.2
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 / index.tsx

index.tsx in Tableberg – Simple Gutenberg Table Block 0.0.2, at src/index.tsx

223 lines 6.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * WordPress Imports
3 */
4 //@ts-ignore
5 import { useEffect } from "@wordpress/element";
6 import { Placeholder, TextControl, Button } from "@wordpress/components";
7 import { blockTable } from "@wordpress/icons";
8 import { useDispatch, useSelect } from "@wordpress/data";
9 import {
10 useBlockProps,
11 useInnerBlocksProps,
12 store as blockEditorStore,
13 BlockIcon,
14 } from "@wordpress/block-editor";
15 import {
16 BlockEditProps,
17 InnerBlockTemplate,
18 // @ts-ignore
19 createBlocksFromInnerBlocksTemplate,
20 registerBlockType,
21 } from "@wordpress/blocks";
22 /**
23 * Internal Imports
24 */
25 import "./style.scss";
26 import metadata from "./block.json";
27 import { FormEvent, useState } from "react";
28 import Inspector from "./inspector";
29 import { TablebergBlockAttrs } from "./types";
30 import { getStyles } from "./get-styles";
31 import classNames from "classnames";
32 import { getStyleClass } from "./get-classes";
33
34 const ALLOWED_BLOCKS = ["tableberg/row"];
35
36 function edit(props: BlockEditProps<TablebergBlockAttrs>) {
37 const {
38 attributes: {
39 hasTableCreated,
40 enableTableFooter,
41 enableTableHeader,
42 cols,
43 },
44 setAttributes,
45 clientId,
46 } = props;
47
48 const blockProps = useBlockProps({
49 className: classNames(getStyleClass(props.attributes)),
50 style: getStyles(props.attributes),
51 });
52
53 // @ts-ignore
54 const innerBlocksProps = useInnerBlocksProps(blockProps, {
55 // @ts-ignore false can obviously be assigned to renderAppender as does wordpress in their own blocks. Need to make a pr to @types/wordpress__block-editor.
56 renderAppender: false,
57 allowedBlocks: ALLOWED_BLOCKS,
58 });
59
60 //@ts-ignore
61 const { block } = useSelect((select) => {
62 return {
63 //@ts-ignore
64 block: select(blockEditorStore).getBlock(clientId),
65 };
66 });
67
68 const { replaceInnerBlocks, insertBlocks, removeBlock } =
69 useDispatch(blockEditorStore);
70
71 const [initialRowCount, setInitialRowCount] = useState<number | "">(2);
72 const [initialColCount, setInitialColCount] = useState<number | "">(2);
73
74 useEffect(() => {
75 if (enableTableHeader) {
76 const tableHeaderTemplate = [
77 [
78 "tableberg/row",
79 { isHeader: true },
80 new Array(initialColCount)
81 .fill(0)
82 .map(() => ["tableberg/cell", { tagName: "th" }, []]),
83 ],
84 ];
85 insertBlocks(
86 createBlocksFromInnerBlocksTemplate(tableHeaderTemplate),
87 0,
88 clientId
89 );
90 } else {
91 const firstBlock = block.innerBlocks[0];
92 const isHeader = firstBlock?.attributes?.isHeader;
93
94 if (isHeader) {
95 removeBlock(firstBlock.clientId);
96 }
97 }
98 }, [enableTableHeader]);
99 useEffect(() => {
100 if (enableTableFooter) {
101 const tableHeaderTemplate = [
102 [
103 "tableberg/row",
104 { isFooter: true },
105 new Array(initialColCount)
106 .fill(0)
107 .map(() => ["tableberg/cell", { tagName: "th" }, []]),
108 ],
109 ];
110 insertBlocks(
111 createBlocksFromInnerBlocksTemplate(tableHeaderTemplate),
112 block?.innerBlocks?.length + 1,
113 clientId
114 );
115 } else {
116 const firstBlock = block.innerBlocks[0];
117 const isHeader = firstBlock?.attributes?.isHeader;
118
119 if (isHeader) {
120 removeBlock(firstBlock.clientId);
121 }
122 }
123 }, [enableTableFooter]);
124
125 function onCreateTable(event: FormEvent) {
126 event.preventDefault();
127
128 if (initialRowCount === "" || initialColCount === "") return;
129
130 const initialInnerBlocks: InnerBlockTemplate[] = Array.from(
131 { length: initialRowCount },
132 () => [
133 "tableberg/row",
134 {},
135 Array.from({ length: initialColCount }, () => [
136 "tableberg/cell",
137 ]),
138 ]
139 );
140
141 replaceInnerBlocks(
142 clientId,
143 createBlocksFromInnerBlocksTemplate(initialInnerBlocks)
144 );
145 setAttributes({
146 hasTableCreated: true,
147 rows: initialColCount,
148 cols: initialColCount,
149 });
150 }
151
152 function onChangeInitialColCount(count: string) {
153 const value = count === "" ? "" : parseInt(count, 10) || 2;
154 setInitialColCount(value);
155 }
156
157 function onChangeInitialRowCount(count: string) {
158 const value = count === "" ? "" : parseInt(count, 10) || 2;
159 setInitialRowCount(value);
160 }
161
162 const placeholder = (
163 <Placeholder
164 label={"Create Tableberg Table"}
165 icon={<BlockIcon icon={blockTable} showColors />}
166 instructions={"Create a complex table with all types of element"}
167 >
168 <form
169 className="blocks-table__placeholder-form"
170 onSubmit={onCreateTable}
171 >
172 <TextControl
173 __nextHasNoMarginBottom
174 type="number"
175 label={"Column count"}
176 value={initialColCount}
177 onChange={onChangeInitialColCount}
178 min="1"
179 className="blocks-table__placeholder-input"
180 />
181 <TextControl
182 __nextHasNoMarginBottom
183 type="number"
184 label={"Row count"}
185 value={initialRowCount}
186 onChange={onChangeInitialRowCount}
187 min="1"
188 className="blocks-table__placeholder-input"
189 />
190 <Button
191 className="blocks-table__placeholder-button"
192 variant="primary"
193 type="submit"
194 >
195 {"Create Table"}
196 </Button>
197 </form>
198 </Placeholder>
199 );
200
201 return (
202 <>
203 {hasTableCreated ? <table {...innerBlocksProps} /> : placeholder}
204 <Inspector {...props} />
205 </>
206 );
207 }
208
209 function save() {
210 const blockProps = useBlockProps.save();
211 const innerBlocksProps = useInnerBlocksProps.save(blockProps);
212 return <table {...innerBlocksProps} />;
213 }
214
215 //@ts-ignore
216 registerBlockType(metadata.name, {
217 title: metadata.title,
218 category: metadata.category,
219 attributes: metadata.attributes,
220 edit,
221 save,
222 });
223