mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-02-24 20:18:41 +08:00
Lexical: Linked table form to have caption toggle option
This commit is contained in:
parent
8a66365d48
commit
958b537a49
@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
$createTextNode,
|
||||||
DOMConversionMap,
|
DOMConversionMap,
|
||||||
DOMExportOutput,
|
DOMExportOutput,
|
||||||
EditorConfig,
|
EditorConfig,
|
||||||
@ -7,6 +8,7 @@ import {
|
|||||||
LexicalNode,
|
LexicalNode,
|
||||||
SerializedElementNode
|
SerializedElementNode
|
||||||
} from "lexical";
|
} from "lexical";
|
||||||
|
import {TableNode} from "@lexical/table/LexicalTableNode";
|
||||||
|
|
||||||
|
|
||||||
export class CaptionNode extends ElementNode {
|
export class CaptionNode extends ElementNode {
|
||||||
@ -72,3 +74,19 @@ export function $createCaptionNode(): CaptionNode {
|
|||||||
export function $isCaptionNode(node: LexicalNode | null | undefined): node is CaptionNode {
|
export function $isCaptionNode(node: LexicalNode | null | undefined): node is CaptionNode {
|
||||||
return node instanceof 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);
|
||||||
|
}
|
@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
## Secondary Todo
|
## 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)
|
- 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
|
- Deep check of translation coverage
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ import {formatSizeValue} from "../../../utils/dom";
|
|||||||
import {TableCellNode, TableNode, TableRowNode} from "@lexical/table";
|
import {TableCellNode, TableNode, TableRowNode} from "@lexical/table";
|
||||||
import {CommonBlockAlignment} from "lexical/nodes/common";
|
import {CommonBlockAlignment} from "lexical/nodes/common";
|
||||||
import {colorFieldBuilder} from "../../framework/blocks/color-field";
|
import {colorFieldBuilder} from "../../framework/blocks/color-field";
|
||||||
|
import {$addCaptionToTable, $isCaptionNode, $tableHasCaption} from "@lexical/table/LexicalCaptionNode";
|
||||||
|
|
||||||
const borderStyleInput: EditorSelectFormFieldDefinition = {
|
const borderStyleInput: EditorSelectFormFieldDefinition = {
|
||||||
label: 'Border style',
|
label: 'Border style',
|
||||||
@ -219,6 +220,7 @@ export const rowProperties: EditorFormDefinition = {
|
|||||||
export function $showTablePropertiesForm(table: TableNode, context: EditorUiContext): EditorFormModal {
|
export function $showTablePropertiesForm(table: TableNode, context: EditorUiContext): EditorFormModal {
|
||||||
const styles = table.getStyles();
|
const styles = table.getStyles();
|
||||||
const modalForm = context.manager.createModal('table_properties');
|
const modalForm = context.manager.createModal('table_properties');
|
||||||
|
|
||||||
modalForm.show({
|
modalForm.show({
|
||||||
width: styles.get('width') || '',
|
width: styles.get('width') || '',
|
||||||
height: styles.get('height') || '',
|
height: styles.get('height') || '',
|
||||||
@ -228,7 +230,7 @@ export function $showTablePropertiesForm(table: TableNode, context: EditorUiCont
|
|||||||
border_style: styles.get('border-style') || '',
|
border_style: styles.get('border-style') || '',
|
||||||
border_color: styles.get('border-color') || '',
|
border_color: styles.get('border-color') || '',
|
||||||
background_color: styles.get('background-color') || '',
|
background_color: styles.get('background-color') || '',
|
||||||
// caption: '', TODO
|
caption: $tableHasCaption(table) ? 'true' : '',
|
||||||
align: table.getAlignment(),
|
align: table.getAlignment(),
|
||||||
});
|
});
|
||||||
return modalForm;
|
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;
|
return true;
|
||||||
},
|
},
|
||||||
@ -299,9 +311,9 @@ export const tableProperties: EditorFormDefinition = {
|
|||||||
type: 'text',
|
type: 'text',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'caption', // Caption element
|
label: 'Show caption', // Caption element
|
||||||
name: 'caption',
|
name: 'caption',
|
||||||
type: 'text', // TODO -
|
type: 'checkbox',
|
||||||
},
|
},
|
||||||
alignmentInput, // alignment class
|
alignmentInput, // alignment class
|
||||||
];
|
];
|
||||||
|
@ -11,7 +11,7 @@ import {el} from "../../utils/dom";
|
|||||||
export interface EditorFormFieldDefinition {
|
export interface EditorFormFieldDefinition {
|
||||||
label: string;
|
label: string;
|
||||||
name: string;
|
name: string;
|
||||||
type: 'text' | 'select' | 'textarea';
|
type: 'text' | 'select' | 'textarea' | 'checkbox';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EditorSelectFormFieldDefinition extends EditorFormFieldDefinition {
|
export interface EditorSelectFormFieldDefinition extends EditorFormFieldDefinition {
|
||||||
@ -42,7 +42,11 @@ export class EditorFormField extends EditorUiElement {
|
|||||||
|
|
||||||
setValue(value: string) {
|
setValue(value: string) {
|
||||||
const input = this.getDOMElement().querySelector('input,select,textarea') as HTMLInputElement;
|
const input = this.getDOMElement().querySelector('input,select,textarea') as HTMLInputElement;
|
||||||
|
if (this.definition.type === 'checkbox') {
|
||||||
|
input.checked = Boolean(value);
|
||||||
|
} else {
|
||||||
input.value = value;
|
input.value = value;
|
||||||
|
}
|
||||||
input.dispatchEvent(new Event('change'));
|
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);
|
input = el('select', {id, name: this.definition.name, class: 'editor-form-field-input'}, optionElems);
|
||||||
} else if (this.definition.type === 'textarea') {
|
} else if (this.definition.type === 'textarea') {
|
||||||
input = el('textarea', {id, name: this.definition.name, class: 'editor-form-field-input'});
|
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 {
|
} else {
|
||||||
input = el('input', {id, name: this.definition.name, class: 'editor-form-field-input'});
|
input = el('input', {id, name: this.definition.name, class: 'editor-form-field-input'});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user