PluginProbe
Tableberg – Simple Gutenberg Table Block / 1.2.0
Tableberg – Simple Gutenberg Table Block v1.2.0
1.2.0 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 All 43 releases
tableberg / src / attributes.ts

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

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