3 EditorFormFieldDefinition, EditorFormFields,
5 EditorSelectFormFieldDefinition
6 } from "../../framework/forms";
7 import {EditorUiContext} from "../../framework/core";
8 import {EditorFormModal} from "../../framework/modals";
9 import {$getSelection} from "lexical";
11 $forEachTableCell, $getCellPaddingForTable,
12 $getTableCellColumnWidth,
13 $getTableCellsFromSelection, $getTableFromSelection,
14 $getTableRowsFromSelection,
15 $setTableCellColumnWidth
16 } from "../../../utils/tables";
17 import {formatSizeValue} from "../../../utils/dom";
18 import {TableCellNode, TableNode, TableRowNode} from "@lexical/table";
19 import {CommonBlockAlignment} from "lexical/nodes/common";
20 import {colorFieldBuilder} from "../../framework/blocks/color-field";
21 import {$addCaptionToTable, $isCaptionNode, $tableHasCaption} from "@lexical/table/LexicalCaptionNode";
23 const borderStyleInput: EditorSelectFormFieldDefinition = {
24 label: 'Border style',
42 const borderColorInput: EditorFormFieldDefinition = {
43 label: 'Border color',
48 const backgroundColorInput: EditorFormFieldDefinition = {
49 label: 'Background color',
50 name: 'background_color',
54 const alignmentInput: EditorSelectFormFieldDefinition = {
66 export function $showCellPropertiesForm(cell: TableCellNode, context: EditorUiContext): EditorFormModal {
67 const styles = cell.getStyles();
68 const modalForm = context.manager.createModal('cell_properties');
70 width: $getTableCellColumnWidth(context.editor, cell),
71 height: styles.get('height') || '',
73 h_align: cell.getAlignment(),
74 v_align: styles.get('vertical-align') || '',
75 border_width: styles.get('border-width') || '',
76 border_style: styles.get('border-style') || '',
77 border_color: styles.get('border-color') || '',
78 background_color: styles.get('background-color') || '',
83 export const cellProperties: EditorFormDefinition = {
85 async action(formData, context: EditorUiContext) {
86 context.editor.update(() => {
87 const cells = $getTableCellsFromSelection($getSelection());
88 for (const cell of cells) {
89 const width = formData.get('width')?.toString() || '';
91 $setTableCellColumnWidth(cell, width);
92 cell.updateTag(formData.get('type')?.toString() || '');
93 cell.setAlignment((formData.get('h_align')?.toString() || '') as CommonBlockAlignment);
95 const styles = cell.getStyles();
96 styles.set('height', formatSizeValue(formData.get('height')?.toString() || ''));
97 styles.set('vertical-align', formData.get('v_align')?.toString() || '');
98 styles.set('border-width', formatSizeValue(formData.get('border_width')?.toString() || ''));
99 styles.set('border-style', formData.get('border_style')?.toString() || '');
100 styles.set('border-color', formData.get('border_color')?.toString() || '');
101 styles.set('background-color', formData.get('background_color')?.toString() || '');
103 cell.setStyles(styles);
112 const generalFields: EditorFormFieldDefinition[] = [
114 label: 'Width', // Colgroup width
119 label: 'Height', // inline-style: height
124 label: 'Cell type', // element
131 } as EditorSelectFormFieldDefinition,
133 ...alignmentInput, // class: 'align-right/left/center'
134 label: 'Horizontal align',
138 label: 'Vertical align', // inline-style: vertical-align
147 } as EditorSelectFormFieldDefinition,
150 const advancedFields: EditorFormFields = [
152 label: 'Border width', // inline-style: border-width
153 name: 'border_width',
156 borderStyleInput, // inline-style: border-style
157 colorFieldBuilder(borderColorInput),
158 colorFieldBuilder(backgroundColorInput),
161 return new EditorFormTabs([
164 contents: generalFields,
168 contents: advancedFields,
176 export function $showRowPropertiesForm(row: TableRowNode, context: EditorUiContext): EditorFormModal {
177 const styles = row.getStyles();
178 const modalForm = context.manager.createModal('row_properties');
180 height: styles.get('height') || '',
181 border_style: styles.get('border-style') || '',
182 border_color: styles.get('border-color') || '',
183 background_color: styles.get('background-color') || '',
188 export const rowProperties: EditorFormDefinition = {
190 async action(formData, context: EditorUiContext) {
191 context.editor.update(() => {
192 const rows = $getTableRowsFromSelection($getSelection());
193 for (const row of rows) {
194 const styles = row.getStyles();
195 styles.set('height', formatSizeValue(formData.get('height')?.toString() || ''));
196 styles.set('border-style', formData.get('border_style')?.toString() || '');
197 styles.set('border-color', formData.get('border_color')?.toString() || '');
198 styles.set('background-color', formData.get('background_color')?.toString() || '');
199 row.setStyles(styles);
206 // Removed 'Row Type' as we don't currently support thead/tfoot elements
207 // TinyMCE would move rows up/down into these parents when set
208 // Removed 'Alignment' since this was broken in our editor (applied alignment class to whole parent table)
210 label: 'Height', // style on tr: height
214 borderStyleInput, // style on tr: height
215 colorFieldBuilder(borderColorInput),
216 colorFieldBuilder(backgroundColorInput),
220 export function $showTablePropertiesForm(table: TableNode, context: EditorUiContext): EditorFormModal {
221 const styles = table.getStyles();
222 const modalForm = context.manager.createModal('table_properties');
225 width: styles.get('width') || '',
226 height: styles.get('height') || '',
227 cell_spacing: styles.get('cell-spacing') || '',
228 cell_padding: $getCellPaddingForTable(table),
229 border_width: styles.get('border-width') || '',
230 border_style: styles.get('border-style') || '',
231 border_color: styles.get('border-color') || '',
232 background_color: styles.get('background-color') || '',
233 caption: $tableHasCaption(table) ? 'true' : '',
234 align: table.getAlignment(),
239 export const tableProperties: EditorFormDefinition = {
241 async action(formData, context: EditorUiContext) {
242 context.editor.update(() => {
243 const table = $getTableFromSelection($getSelection());
248 const styles = table.getStyles();
249 styles.set('width', formatSizeValue(formData.get('width')?.toString() || ''));
250 styles.set('height', formatSizeValue(formData.get('height')?.toString() || ''));
251 styles.set('cell-spacing', formatSizeValue(formData.get('cell_spacing')?.toString() || ''));
252 styles.set('border-width', formatSizeValue(formData.get('border_width')?.toString() || ''));
253 styles.set('border-style', formData.get('border_style')?.toString() || '');
254 styles.set('border-color', formData.get('border_color')?.toString() || '');
255 styles.set('background-color', formData.get('background_color')?.toString() || '');
256 table.setStyles(styles);
258 table.setAlignment(formData.get('align') as CommonBlockAlignment);
260 const cellPadding = (formData.get('cell_padding')?.toString() || '');
262 const cellPaddingFormatted = formatSizeValue(cellPadding);
263 $forEachTableCell(table, (cell: TableCellNode) => {
264 const styles = cell.getStyles();
265 styles.set('padding', cellPaddingFormatted);
266 cell.setStyles(styles);
270 const showCaption = Boolean(formData.get('caption')?.toString() || '');
271 const hasCaption = $tableHasCaption(table);
272 if (showCaption && !hasCaption) {
273 $addCaptionToTable(table, context.translate('Caption'));
274 } else if (!showCaption && hasCaption) {
275 for (const child of table.getChildren()) {
276 if ($isCaptionNode(child)) {
287 const generalFields: EditorFormFieldDefinition[] = [
289 label: 'Width', // Style - width
294 label: 'Height', // Style - height
299 label: 'Cell spacing', // Style - border-spacing
300 name: 'cell_spacing',
304 label: 'Cell padding', // Style - padding on child cells?
305 name: 'cell_padding',
309 label: 'Border width', // Style - border-width
310 name: 'border_width',
314 label: 'Show caption', // Caption element
318 alignmentInput, // alignment class
321 const advancedFields: EditorFormFields = [
323 colorFieldBuilder(borderColorInput),
324 colorFieldBuilder(backgroundColorInput),
327 return new EditorFormTabs([
330 contents: generalFields,
334 contents: advancedFields,