diff --git a/resources/js/wysiwyg/lexical/table/LexicalCaptionNode.ts b/resources/js/wysiwyg/lexical/table/LexicalCaptionNode.ts index 08c6870e69f..d9d83562c29 100644 --- a/resources/js/wysiwyg/lexical/table/LexicalCaptionNode.ts +++ b/resources/js/wysiwyg/lexical/table/LexicalCaptionNode.ts @@ -1,4 +1,5 @@ import { + $createTextNode, DOMConversionMap, DOMExportOutput, EditorConfig, @@ -7,6 +8,7 @@ import { LexicalNode, SerializedElementNode } from "lexical"; +import {TableNode} from "@lexical/table/LexicalTableNode"; export class CaptionNode extends ElementNode { @@ -71,4 +73,20 @@ export function $createCaptionNode(): CaptionNode { export function $isCaptionNode(node: LexicalNode | null | undefined): node is CaptionNode { return node instanceof CaptionNode; +} + +export function $tableHasCaption(table: TableNode): boolean { + for (const child of table.getChildren()) { + if ($isCaptionNode(child)) { + return true; + } + } + return false; +} + +export function $addCaptionToTable(table: TableNode, text: string = ''): void { + const caption = $createCaptionNode(); + const textNode = $createTextNode(text || ' '); + caption.append(textNode); + table.append(caption); } \ No newline at end of file diff --git a/resources/js/wysiwyg/todo.md b/resources/js/wysiwyg/todo.md index 695e8cb69ed..1d42ba3e447 100644 --- a/resources/js/wysiwyg/todo.md +++ b/resources/js/wysiwyg/todo.md @@ -10,7 +10,6 @@ ## Secondary Todo -- Table caption text support - Support media src conversions (https://github.com/tinymce/tinymce/blob/release/6.6/modules/tinymce/src/plugins/media/main/ts/core/UrlPatterns.ts) - Deep check of translation coverage diff --git a/resources/js/wysiwyg/ui/defaults/forms/tables.ts b/resources/js/wysiwyg/ui/defaults/forms/tables.ts index b592d7c67e6..5b484310d9a 100644 --- a/resources/js/wysiwyg/ui/defaults/forms/tables.ts +++ b/resources/js/wysiwyg/ui/defaults/forms/tables.ts @@ -18,6 +18,7 @@ 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', @@ -219,6 +220,7 @@ export const rowProperties: EditorFormDefinition = { 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') || '', @@ -228,7 +230,7 @@ export function $showTablePropertiesForm(table: TableNode, context: EditorUiCont border_style: styles.get('border-style') || '', border_color: styles.get('border-color') || '', background_color: styles.get('background-color') || '', - // caption: '', TODO + caption: $tableHasCaption(table) ? 'true' : '', align: table.getAlignment(), }); return modalForm; @@ -265,7 +267,17 @@ export const tableProperties: EditorFormDefinition = { }); } - // TODO - cell caption + 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; }, @@ -299,9 +311,9 @@ export const tableProperties: EditorFormDefinition = { type: 'text', }, { - label: 'caption', // Caption element + label: 'Show caption', // Caption element name: 'caption', - type: 'text', // TODO - + type: 'checkbox', }, alignmentInput, // alignment class ]; diff --git a/resources/js/wysiwyg/ui/framework/forms.ts b/resources/js/wysiwyg/ui/framework/forms.ts index 771ab0bdfe5..08edb214e2a 100644 --- a/resources/js/wysiwyg/ui/framework/forms.ts +++ b/resources/js/wysiwyg/ui/framework/forms.ts @@ -11,7 +11,7 @@ import {el} from "../../utils/dom"; export interface EditorFormFieldDefinition { label: string; name: string; - type: 'text' | 'select' | 'textarea'; + type: 'text' | 'select' | 'textarea' | 'checkbox'; } export interface EditorSelectFormFieldDefinition extends EditorFormFieldDefinition { @@ -42,7 +42,11 @@ export class EditorFormField extends EditorUiElement { setValue(value: string) { const input = this.getDOMElement().querySelector('input,select,textarea') as HTMLInputElement; - input.value = value; + if (this.definition.type === 'checkbox') { + input.checked = Boolean(value); + } else { + input.value = value; + } input.dispatchEvent(new Event('change')); } @@ -61,6 +65,8 @@ export class EditorFormField extends EditorUiElement { input = el('select', {id, name: this.definition.name, class: 'editor-form-field-input'}, optionElems); } else if (this.definition.type === 'textarea') { input = el('textarea', {id, name: this.definition.name, class: 'editor-form-field-input'}); + } else if (this.definition.type === 'checkbox') { + input = el('input', {id, name: this.definition.name, type: 'checkbox', class: 'editor-form-field-input-checkbox', value: 'true'}); } else { input = el('input', {id, name: this.definition.name, class: 'editor-form-field-input'}); }