]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/ui/defaults/forms/tables.ts
Lexical: Added cell width fetching, Created custom row node
[bookstack] / resources / js / wysiwyg / ui / defaults / forms / tables.ts
1 import {
2     EditorFormDefinition,
3     EditorFormFieldDefinition,
4     EditorFormTabs,
5     EditorSelectFormFieldDefinition
6 } from "../../framework/forms";
7 import {EditorUiContext} from "../../framework/core";
8 import {CustomTableCellNode} from "../../../nodes/custom-table-cell";
9 import {EditorFormModal} from "../../framework/modals";
10 import {$getSelection, ElementFormatType} from "lexical";
11 import {$getTableCellColumnWidth, $getTableCellsFromSelection, $setTableCellColumnWidth} from "../../../utils/tables";
12 import {formatSizeValue} from "../../../utils/dom";
13
14 const borderStyleInput: EditorSelectFormFieldDefinition = {
15     label: 'Border style',
16     name: 'border_style',
17     type: 'select',
18     valuesByLabel: {
19         'Select...': '',
20         "Solid": 'solid',
21         "Dotted": 'dotted',
22         "Dashed": 'dashed',
23         "Double": 'double',
24         "Groove": 'groove',
25         "Ridge": 'ridge',
26         "Inset": 'inset',
27         "Outset": 'outset',
28         "None": 'none',
29         "Hidden": 'hidden',
30     }
31 };
32
33 const borderColorInput: EditorFormFieldDefinition = {
34     label: 'Border color',
35     name: 'border_color',
36     type: 'text',
37 };
38
39 const backgroundColorInput: EditorFormFieldDefinition = {
40     label: 'Background color',
41     name: 'background_color',
42     type: 'text',
43 };
44
45 const alignmentInput: EditorSelectFormFieldDefinition = {
46     label: 'Alignment',
47     name: 'align',
48     type: 'select',
49     valuesByLabel: {
50         'None': '',
51         'Left': 'left',
52         'Center': 'center',
53         'Right': 'right',
54     }
55 };
56
57 export function $showCellPropertiesForm(cell: CustomTableCellNode, context: EditorUiContext): EditorFormModal {
58     const styles = cell.getStyles();
59     const modalForm = context.manager.createModal('cell_properties');
60     modalForm.show({
61         width: $getTableCellColumnWidth(context.editor, cell),
62         height: styles.get('height') || '',
63         type: cell.getTag(),
64         h_align: cell.getFormatType(),
65         v_align: styles.get('vertical-align') || '',
66         border_width: styles.get('border-width') || '',
67         border_style: styles.get('border-style') || '',
68         border_color: styles.get('border-color') || '',
69         background_color: styles.get('background-color') || '',
70     });
71     return modalForm;
72 }
73
74 export const cellProperties: EditorFormDefinition = {
75     submitText: 'Save',
76     async action(formData, context: EditorUiContext) {
77         context.editor.update(() => {
78             const cells = $getTableCellsFromSelection($getSelection());
79             for (const cell of cells) {
80                 const width = formData.get('width')?.toString() || '';
81
82                 $setTableCellColumnWidth(cell, width);
83                 cell.updateTag(formData.get('type')?.toString() || '');
84                 cell.setFormat((formData.get('h_align')?.toString() || '') as ElementFormatType);
85
86                 const styles = cell.getStyles();
87                 styles.set('height', formatSizeValue(formData.get('height')?.toString() || ''));
88                 styles.set('vertical-align', formData.get('v_align')?.toString() || '');
89                 styles.set('border-width', formatSizeValue(formData.get('border_width')?.toString() || ''));
90                 styles.set('border-style', formData.get('border_style')?.toString() || '');
91                 styles.set('border-color', formData.get('border_color')?.toString() || '');
92                 styles.set('background-color', formData.get('background_color')?.toString() || '');
93
94                 cell.setStyles(styles);
95             }
96         });
97
98         return true;
99     },
100     fields: [
101         {
102             build() {
103                 const generalFields: EditorFormFieldDefinition[] = [
104                     {
105                         label: 'Width', // Colgroup width
106                         name: 'width',
107                         type: 'text',
108                     },
109                     {
110                         label: 'Height', // inline-style: height
111                         name: 'height',
112                         type: 'text',
113                     },
114                     {
115                         label: 'Cell type', // element
116                         name: 'type',
117                         type: 'select',
118                         valuesByLabel: {
119                             'Cell': 'td',
120                             'Header cell': 'th',
121                         }
122                     } as EditorSelectFormFieldDefinition,
123                     {
124                         ...alignmentInput, // class: 'align-right/left/center'
125                         label: 'Horizontal align',
126                         name: 'h_align',
127                     },
128                     {
129                         label: 'Vertical align', // inline-style: vertical-align
130                         name: 'v_align',
131                         type: 'select',
132                         valuesByLabel: {
133                             'None': '',
134                             'Top': 'top',
135                             'Middle': 'middle',
136                             'Bottom': 'bottom',
137                         }
138                     } as EditorSelectFormFieldDefinition,
139                 ];
140
141                 const advancedFields: EditorFormFieldDefinition[] = [
142                     {
143                         label: 'Border width', // inline-style: border-width
144                         name: 'border_width',
145                         type: 'text',
146                     },
147                     borderStyleInput, // inline-style: border-style
148                     borderColorInput, // inline-style: border-color
149                     backgroundColorInput, // inline-style: background-color
150                 ];
151
152                 return new EditorFormTabs([
153                     {
154                         label: 'General',
155                         contents: generalFields,
156                     },
157                     {
158                         label: 'Advanced',
159                         contents: advancedFields,
160                     }
161                 ])
162             }
163         },
164     ],
165 };
166
167 export const rowProperties: EditorFormDefinition = {
168     submitText: 'Save',
169     async action(formData, context: EditorUiContext) {
170         // TODO
171         return true;
172     },
173     fields: [
174         // Removed fields:
175         // Removed 'Row Type' as we don't currently support thead/tfoot elements
176         //  TinyMCE would move rows up/down into these parents when set
177         // Removed 'Alignment' since this was broken in our editor (applied alignment class to whole parent table)
178         {
179             label: 'Height', // style on tr: height
180             name: 'height',
181             type: 'text',
182         },
183         borderStyleInput, // style on tr: height
184         borderColorInput, // style on tr: height
185         backgroundColorInput, // style on tr: height
186     ],
187 };
188 export const tableProperties: EditorFormDefinition = {
189     submitText: 'Save',
190     async action(formData, context: EditorUiContext) {
191         // TODO
192         return true;
193     },
194     fields: [
195         {
196             build() {
197                 const generalFields: EditorFormFieldDefinition[] = [
198                     {
199                         label: 'Width',
200                         name: 'width',
201                         type: 'text',
202                     },
203                     {
204                         label: 'Height',
205                         name: 'height',
206                         type: 'text',
207                     },
208                     {
209                         label: 'Cell spacing',
210                         name: 'cell_spacing',
211                         type: 'text',
212                     },
213                     {
214                         label: 'Cell padding',
215                         name: 'cell_padding',
216                         type: 'text',
217                     },
218                     {
219                         label: 'Border width',
220                         name: 'border_width',
221                         type: 'text',
222                     },
223                     {
224                         label: 'caption',
225                         name: 'height',
226                         type: 'text', // TODO -
227                     },
228                     alignmentInput,
229                 ];
230
231                 const advancedFields: EditorFormFieldDefinition[] = [
232                     borderStyleInput,
233                     borderColorInput,
234                     backgroundColorInput,
235                 ];
236
237                 return new EditorFormTabs([
238                     {
239                         label: 'General',
240                         contents: generalFields,
241                     },
242                     {
243                         label: 'Advanced',
244                         contents: advancedFields,
245                     }
246                 ])
247             }
248         },
249     ],
250 };