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 / attributes.ts

attributes.ts in Tableberg – Simple Gutenberg Table Block 1.1.5, at src/attributes.ts

392 lines 9.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { ElementBindings } from "./dynamic-data/types";
2
3 export interface TablebergBlockAttrs {
4 version?: number;
5 isExample?: boolean;
6 table: TableConfig;
7 rows: RowConfigs;
8 columns: ColumnConfigs;
9 cells: Record<CellKey, Cell>;
10 bindings: Record<string, BindingDefinition>;
11 cellDefaults: CellDefaults;
12 }
13
14 export type RowConfigs = Array<RowConfig | null | undefined>;
15 export type ColumnConfigs = Array<ColumnConfig | null | undefined>;
16
17 export type CellKey = `${number},${number}`;
18
19 export interface Span {
20 rowSpan: number;
21 colSpan: number;
22 }
23
24 export type ElementTypes =
25 | "text"
26 | "button"
27 | "image"
28 | "list"
29 | "styled-list"
30 | "icon"
31 | "ribbon"
32 | "star-rating"
33 | "custom-html";
34
35 export type SortableType = "text" | "number" | "date";
36
37 export interface ColumnConfig {
38 sortable?: SortableType;
39 width?: string;
40 }
41
42 export interface RowConfig {
43 height?: string;
44 // Pro-owned: declared in the free schema for data preservation, but free
45 // never writes it directly. It only excludes such rows from bulk-applied
46 // colours (even/odd, etc.) so the row's own colour can show through.
47 backgroundColor?: string;
48 border?: Border;
49 }
50
51 import {
52 TextElementType,
53 ButtonElementType,
54 ImageElementType,
55 ListElementType,
56 } from "./elements";
57
58 export interface GenericCellElement<
59 TName extends string = string,
60 TAttributes extends Record<string, unknown> = Record<string, unknown>,
61 > {
62 name: TName;
63 attributes: TAttributes;
64 bindings?: ElementBindings;
65 }
66
67 export type CellElement =
68 | TextElementType
69 | ButtonElementType
70 | ImageElementType
71 | ListElementType
72 | GenericCellElement<"styled-list">
73 | GenericCellElement<"icon">
74 | GenericCellElement<"star-rating">
75 | GenericCellElement<"custom-html">;
76
77 export type { TextElementType, TextElementAttributes } from "./elements";
78 export type { ButtonElementType, ButtonElementAttributes } from "./elements";
79 export type { ImageElementType, ImageElementAttributes } from "./elements";
80 export type { ListElementType, ListElementAttributes } from "./elements";
81
82 export interface PaginationConfig {
83 enabled: boolean;
84 pageSize: number;
85 showPageNumbers: boolean;
86 showPrevNext: boolean;
87 }
88
89 export type SearchPosition = "left" | "right";
90
91 export type TableAlignment = "left" | "center" | "right";
92
93 export type TableWidth = "auto" | "wide" | "full" | string;
94
95 export interface CellSpacing {
96 horizontal: string;
97 vertical: string;
98 }
99
100 export interface SearchConfig {
101 enabled: boolean;
102 placeholder: string;
103 highlightColor: string;
104 position: SearchPosition;
105 }
106
107 export type ResponsiveMode = "" | "scroll" | "stack";
108
109 export interface ResponsiveBreakpoint {
110 enabled: boolean;
111 maxWidth: number;
112 mode: ResponsiveMode;
113 transpose: boolean;
114 stackCount: number;
115 repeatFirstCol: boolean;
116 }
117
118 export interface ResponsiveConfig {
119 tablet: ResponsiveBreakpoint;
120 mobile: ResponsiveBreakpoint;
121 }
122
123 export type RibbonType = "bookmark" | "corner" | "side" | "icon" | "badge";
124
125 export interface RibbonAttrs {
126 text: string;
127
128 style: {
129 color: string;
130 background: string;
131 bgGradient: string;
132 fontSize: string;
133 padding: {
134 top: string;
135 right: string;
136 bottom: string;
137 left: string;
138 };
139 borderRadius: {
140 topLeft: string;
141 topRight: string;
142 bottomRight: string;
143 bottomLeft: string;
144 };
145 };
146
147 originX: "left" | "right" | "center";
148 originY: "top" | "bottom" | "center";
149 x: string;
150 y: string;
151
152 rotate: number;
153
154 height: string;
155 width: string;
156
157 iconSize: string;
158 shape: "up" | "down" | "slant-up" | "slant-down";
159 icon: {
160 iconName: string;
161 svg?: {
162 viewBox: string;
163 path: string;
164 };
165 } | null;
166 }
167
168 export type RibbonConfig =
169 | { enabled: false; type?: RibbonType; attrs?: RibbonAttrs }
170 | { enabled: true; type: RibbonType; attrs: RibbonAttrs };
171
172 export type Border = {
173 top: string;
174 right: string;
175 bottom: string;
176 left: string;
177 };
178
179 export interface TableConfig {
180 rows: number;
181 cols: number;
182 className?: string;
183 headerEnabled: boolean;
184 footerEnabled: boolean;
185 stickyHeader?: boolean;
186 stickyFirstCol?: boolean;
187 // Pro-owned table-wide grid mode. Declared here so the value survives
188 // while Pro is inactive; free never enables or renders it.
189 innerBorderType?: "" | "row" | "col";
190 caption?: string;
191 tableWidth?: TableWidth;
192 tableAlignment?: TableAlignment;
193 cellSpacing?: CellSpacing;
194 tableBorder?: Border;
195 margin?: Border;
196 padding?: Border;
197 fixedColumnWidths?: boolean;
198 pagination?: PaginationConfig;
199 search?: SearchConfig;
200 responsive?: ResponsiveConfig;
201 }
202
203 export interface TableCellStylesType {
204 padding: {
205 top: string;
206 right: string;
207 bottom: string;
208 left: string;
209 };
210 backgroundColor: string;
211 // Row-position-based defaults, resolved per cell alongside the plain
212 // `backgroundColor` fallback above: header/footer rows take their own
213 // colour, other rows alternate even/odd. Table-wide, not a per-cell
214 // attribute, so these apply the same with or without pro.
215 headerBackgroundColor: string;
216 footerBackgroundColor: string;
217 evenRowBackgroundColor: string;
218 oddRowBackgroundColor: string;
219 border: Border;
220 borderRadius: {
221 topLeft: string;
222 topRight: string;
223 bottomRight: string;
224 bottomLeft: string;
225 };
226 orientation: "vertical" | "horizontal";
227 elementGap: string;
228 wrap: "wrap" | "nowrap";
229 verticalAlign: "top" | "middle" | "bottom";
230 }
231
232 export interface CellDefaults {
233 styles: TableCellStylesType;
234 }
235
236 export interface Cell {
237 span?: Span;
238 className?: string;
239 elements?: Array<CellElement>;
240 styles?: Partial<TableCellStylesType>;
241 ribbon?: RibbonConfig;
242 // Pro-owned: declared in the free schema for data preservation. Free
243 // never reads or writes it directly.
244 backgroundColor?: string;
245 border?: Border;
246 emptyCell?: boolean;
247 }
248
249 export interface BindingDefinition {
250 key: string;
251 postId?: number;
252 fallback?: string;
253 }
254
255 export interface Structure {
256 rows: number;
257 cols: number;
258 cells: Array<[[number, number], Span]>;
259 columns?: Record<number, ColumnConfig>;
260 rowConfigs?: Record<number, RowConfig>;
261 }
262
263 export interface Data {
264 cells: Array<[[number, number], Array<CellElement>]>;
265 }
266
267 export interface CellStyles extends TableCellStylesType {
268 cells: Array<
269 [
270 [number, number],
271 Partial<TableCellStylesType> & { ribbon?: RibbonConfig },
272 ]
273 >;
274 }
275
276 export const attrVersion = 3;
277
278 export const attrDefaults: TablebergBlockAttrs = {
279 version: 0,
280 isExample: false,
281 table: {
282 rows: 0,
283 cols: 0,
284 className: "",
285 headerEnabled: false,
286 footerEnabled: false,
287 stickyHeader: false,
288 stickyFirstCol: false,
289 innerBorderType: "",
290 caption: "",
291 tableWidth: "auto",
292 tableAlignment: "left",
293 cellSpacing: {
294 horizontal: "0",
295 vertical: "0",
296 },
297 tableBorder: {
298 top: "",
299 right: "",
300 bottom: "",
301 left: "",
302 },
303 margin: {
304 top: "",
305 right: "",
306 bottom: "",
307 left: "",
308 },
309 padding: {
310 top: "",
311 right: "",
312 bottom: "",
313 left: "",
314 },
315 fixedColumnWidths: true,
316 pagination: {
317 enabled: false,
318 pageSize: 10,
319 showPageNumbers: true,
320 showPrevNext: true,
321 },
322 search: {
323 enabled: false,
324 placeholder: "Search...",
325 highlightColor: "",
326 position: "left",
327 },
328 responsive: {
329 tablet: {
330 enabled: false,
331 maxWidth: 700,
332 mode: "scroll",
333 transpose: false,
334 stackCount: 3,
335 repeatFirstCol: false,
336 },
337 mobile: {
338 enabled: false,
339 maxWidth: 375,
340 mode: "scroll",
341 transpose: false,
342 stackCount: 1,
343 repeatFirstCol: false,
344 },
345 },
346 },
347 rows: [],
348 columns: [],
349 cells: {},
350 bindings: {},
351 cellDefaults: {
352 styles: {
353 padding: {
354 top: "var(--wp--preset--spacing--20)",
355 right: "var(--wp--preset--spacing--20)",
356 bottom: "var(--wp--preset--spacing--20)",
357 left: "var(--wp--preset--spacing--20)",
358 },
359 border: {
360 top: "1px solid black",
361 right: "1px solid black",
362 bottom: "1px solid black",
363 left: "1px solid black",
364 },
365 borderRadius: {
366 topLeft: "0px",
367 topRight: "0px",
368 bottomRight: "0px",
369 bottomLeft: "0px",
370 },
371 orientation: "vertical",
372 elementGap: "var(--wp--preset--spacing--20)",
373 wrap: "nowrap",
374 verticalAlign: "middle",
375 backgroundColor: "",
376 headerBackgroundColor: "",
377 footerBackgroundColor: "",
378 evenRowBackgroundColor: "",
379 oddRowBackgroundColor: "",
380 },
381 },
382 };
383
384 export function getCellKey(row: number, col: number): CellKey {
385 return `${row},${col}`;
386 }
387
388 export function parseCellKey(key: string): [number, number] {
389 const [row, col] = key.split(",").map(value => parseInt(value, 10));
390 return [row || 0, col || 0];
391 }
392