]> BookStack Code Mirror - bookstack/blobdiff - resources/js/wysiwyg/ui/defaults/forms/tables.ts
Merge pull request #5731 from BookStackApp/lexical_jul25
[bookstack] / resources / js / wysiwyg / ui / defaults / forms / tables.ts
index 1c577b72a5094c23aef718d6cb62b40aabe3806b..031e0098368a39f3cebe51b383c26dc6d46d1b76 100644 (file)
@@ -1,15 +1,24 @@
 import {
     EditorFormDefinition,
-    EditorFormFieldDefinition,
+    EditorFormFieldDefinition, EditorFormFields,
     EditorFormTabs,
     EditorSelectFormFieldDefinition
 } from "../../framework/forms";
 import {EditorUiContext} from "../../framework/core";
-import {CustomTableCellNode} from "../../../nodes/custom-table-cell";
 import {EditorFormModal} from "../../framework/modals";
-import {$getSelection, ElementFormatType} from "lexical";
-import {$getTableCellColumnWidth, $getTableCellsFromSelection, $setTableCellColumnWidth} from "../../../utils/tables";
+import {$getSelection} from "lexical";
+import {
+    $forEachTableCell, $getCellPaddingForTable,
+    $getTableCellColumnWidth,
+    $getTableCellsFromSelection, $getTableFromSelection,
+    $getTableRowsFromSelection,
+    $setTableCellColumnWidth
+} from "../../../utils/tables";
 import {formatSizeValue} from "../../../utils/dom";
+import {TableCellNode, TableNode, TableRowNode} from "@lexical/table";
+import {CommonBlockAlignment} from "lexical/nodes/common";
+import {colorFieldBuilder} from "../../framework/blocks/color-field";
+import {$addCaptionToTable, $isCaptionNode, $tableHasCaption} from "@lexical/table/LexicalCaptionNode";
 
 const borderStyleInput: EditorSelectFormFieldDefinition = {
     label: 'Border style',
@@ -54,19 +63,19 @@ const alignmentInput: EditorSelectFormFieldDefinition = {
     }
 };
 
-export function $showCellPropertiesForm(cell: CustomTableCellNode, context: EditorUiContext): EditorFormModal {
+export function $showCellPropertiesForm(cell: TableCellNode, context: EditorUiContext): EditorFormModal {
     const styles = cell.getStyles();
     const modalForm = context.manager.createModal('cell_properties');
     modalForm.show({
         width: $getTableCellColumnWidth(context.editor, cell),
         height: styles.get('height') || '',
         type: cell.getTag(),
-        h_align: cell.getFormatType(),
+        h_align: cell.getAlignment(),
         v_align: styles.get('vertical-align') || '',
         border_width: styles.get('border-width') || '',
         border_style: styles.get('border-style') || '',
         border_color: styles.get('border-color') || '',
-        background_color: styles.get('background-color') || '',
+        background_color: cell.getBackgroundColor() || styles.get('background-color') || '',
     });
     return modalForm;
 }
@@ -81,7 +90,8 @@ export const cellProperties: EditorFormDefinition = {
 
                 $setTableCellColumnWidth(cell, width);
                 cell.updateTag(formData.get('type')?.toString() || '');
-                cell.setFormat((formData.get('h_align')?.toString() || '') as ElementFormatType);
+                cell.setAlignment((formData.get('h_align')?.toString() || '') as CommonBlockAlignment);
+                cell.setBackgroundColor(formData.get('background_color')?.toString() || '');
 
                 const styles = cell.getStyles();
                 styles.set('height', formatSizeValue(formData.get('height')?.toString() || ''));
@@ -89,7 +99,6 @@ export const cellProperties: EditorFormDefinition = {
                 styles.set('border-width', formatSizeValue(formData.get('border_width')?.toString() || ''));
                 styles.set('border-style', formData.get('border_style')?.toString() || '');
                 styles.set('border-color', formData.get('border_color')?.toString() || '');
-                styles.set('background-color', formData.get('background_color')?.toString() || '');
 
                 cell.setStyles(styles);
             }
@@ -138,15 +147,15 @@ export const cellProperties: EditorFormDefinition = {
                     } as EditorSelectFormFieldDefinition,
                 ];
 
-                const advancedFields: EditorFormFieldDefinition[] = [
+                const advancedFields: EditorFormFields = [
                     {
                         label: 'Border width', // inline-style: border-width
                         name: 'border_width',
                         type: 'text',
                     },
                     borderStyleInput, // inline-style: border-style
-                    borderColorInput, // inline-style: border-color
-                    backgroundColorInput, // inline-style: background-color
+                    colorFieldBuilder(borderColorInput),
+                    colorFieldBuilder(backgroundColorInput),
                 ];
 
                 return new EditorFormTabs([
@@ -164,10 +173,32 @@ export const cellProperties: EditorFormDefinition = {
     ],
 };
 
+export function $showRowPropertiesForm(row: TableRowNode, context: EditorUiContext): EditorFormModal {
+    const styles = row.getStyles();
+    const modalForm = context.manager.createModal('row_properties');
+    modalForm.show({
+        height: styles.get('height') || '',
+        border_style: styles.get('border-style') || '',
+        border_color: styles.get('border-color') || '',
+        background_color: styles.get('background-color') || '',
+    });
+    return modalForm;
+}
+
 export const rowProperties: EditorFormDefinition = {
     submitText: 'Save',
     async action(formData, context: EditorUiContext) {
-        // TODO
+        context.editor.update(() => {
+            const rows = $getTableRowsFromSelection($getSelection());
+            for (const row of rows) {
+                const styles = row.getStyles();
+                styles.set('height', formatSizeValue(formData.get('height')?.toString() || ''));
+                styles.set('border-style', formData.get('border_style')?.toString() || '');
+                styles.set('border-color', formData.get('border_color')?.toString() || '');
+                styles.set('background-color', formData.get('background_color')?.toString() || '');
+                row.setStyles(styles);
+            }
+        });
         return true;
     },
     fields: [
@@ -181,14 +212,73 @@ export const rowProperties: EditorFormDefinition = {
             type: 'text',
         },
         borderStyleInput, // style on tr: height
-        borderColorInput, // style on tr: height
-        backgroundColorInput, // style on tr: height
+        colorFieldBuilder(borderColorInput),
+        colorFieldBuilder(backgroundColorInput),
     ],
 };
+
+export function $showTablePropertiesForm(table: TableNode, context: EditorUiContext): EditorFormModal {
+    const styles = table.getStyles();
+    const modalForm = context.manager.createModal('table_properties');
+
+    modalForm.show({
+        width: styles.get('width') || '',
+        height: styles.get('height') || '',
+        cell_spacing: styles.get('cell-spacing') || '',
+        cell_padding: $getCellPaddingForTable(table),
+        border_width: styles.get('border-width') || '',
+        border_style: styles.get('border-style') || '',
+        border_color: styles.get('border-color') || '',
+        background_color: styles.get('background-color') || '',
+        caption: $tableHasCaption(table) ? 'true' : '',
+        align: table.getAlignment(),
+    });
+    return modalForm;
+}
+
 export const tableProperties: EditorFormDefinition = {
     submitText: 'Save',
     async action(formData, context: EditorUiContext) {
-        // TODO
+        context.editor.update(() => {
+            const table = $getTableFromSelection($getSelection());
+            if (!table) {
+                return;
+            }
+
+            const styles = table.getStyles();
+            styles.set('width', formatSizeValue(formData.get('width')?.toString() || ''));
+            styles.set('height', formatSizeValue(formData.get('height')?.toString() || ''));
+            styles.set('cell-spacing', formatSizeValue(formData.get('cell_spacing')?.toString() || ''));
+            styles.set('border-width', formatSizeValue(formData.get('border_width')?.toString() || ''));
+            styles.set('border-style', formData.get('border_style')?.toString() || '');
+            styles.set('border-color', formData.get('border_color')?.toString() || '');
+            styles.set('background-color', formData.get('background_color')?.toString() || '');
+            table.setStyles(styles);
+
+            table.setAlignment(formData.get('align') as CommonBlockAlignment);
+
+            const cellPadding = (formData.get('cell_padding')?.toString() || '');
+            if (cellPadding) {
+                const cellPaddingFormatted = formatSizeValue(cellPadding);
+                $forEachTableCell(table, (cell: TableCellNode) => {
+                    const styles = cell.getStyles();
+                    styles.set('padding', cellPaddingFormatted);
+                    cell.setStyles(styles);
+                });
+            }
+
+            const showCaption = Boolean(formData.get('caption')?.toString() || '');
+            const hasCaption = $tableHasCaption(table);
+            if (showCaption && !hasCaption) {
+                $addCaptionToTable(table, context.translate('Caption'));
+            } else if (!showCaption && hasCaption) {
+                for (const child of table.getChildren()) {
+                    if ($isCaptionNode(child)) {
+                        child.remove();
+                    }
+                }
+            }
+        });
         return true;
     },
     fields: [
@@ -196,42 +286,42 @@ export const tableProperties: EditorFormDefinition = {
             build() {
                 const generalFields: EditorFormFieldDefinition[] = [
                     {
-                        label: 'Width',
+                        label: 'Width', // Style - width
                         name: 'width',
                         type: 'text',
                     },
                     {
-                        label: 'Height',
+                        label: 'Height', // Style - height
                         name: 'height',
                         type: 'text',
                     },
                     {
-                        label: 'Cell spacing',
+                        label: 'Cell spacing', // Style - border-spacing
                         name: 'cell_spacing',
                         type: 'text',
                     },
                     {
-                        label: 'Cell padding',
+                        label: 'Cell padding', // Style - padding on child cells?
                         name: 'cell_padding',
                         type: 'text',
                     },
                     {
-                        label: 'Border width',
+                        label: 'Border width', // Style - border-width
                         name: 'border_width',
                         type: 'text',
                     },
                     {
-                        label: 'caption',
-                        name: 'height',
-                        type: 'text', // TODO -
+                        label: 'Show caption', // Caption element
+                        name: 'caption',
+                        type: 'checkbox',
                     },
-                    alignmentInput,
+                    alignmentInput, // alignment class
                 ];
 
-                const advancedFields: EditorFormFieldDefinition[] = [
+                const advancedFields: EditorFormFields = [
                     borderStyleInput,
-                    borderColorInput,
-                    backgroundColorInput,
+                    colorFieldBuilder(borderColorInput),
+                    colorFieldBuilder(backgroundColorInput),
                 ];
 
                 return new EditorFormTabs([