mirror of
https://github.com/BookStackApp/BookStack.git
synced 2026-01-03 23:42:28 +03:00
Lexical: Added color picker/indicator to form fields
This commit is contained in:
56
resources/js/wysiwyg/ui/framework/blocks/color-field.ts
Normal file
56
resources/js/wysiwyg/ui/framework/blocks/color-field.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import {EditorContainerUiElement, EditorUiBuilderDefinition, EditorUiContext} from "../core";
|
||||
import {EditorFormField, EditorFormFieldDefinition} from "../forms";
|
||||
import {EditorColorPicker} from "./color-picker";
|
||||
import {EditorDropdownButton} from "./dropdown-button";
|
||||
|
||||
import colorDisplayIcon from "@icons/editor/color-display.svg"
|
||||
|
||||
export class EditorColorField extends EditorContainerUiElement {
|
||||
protected input: EditorFormField;
|
||||
protected pickerButton: EditorDropdownButton;
|
||||
|
||||
constructor(input: EditorFormField) {
|
||||
super([]);
|
||||
|
||||
this.input = input;
|
||||
|
||||
this.pickerButton = new EditorDropdownButton({
|
||||
button: { icon: colorDisplayIcon, label: 'Select color'}
|
||||
}, [
|
||||
new EditorColorPicker(this.onColorSelect.bind(this))
|
||||
]);
|
||||
this.addChildren(this.pickerButton, this.input);
|
||||
}
|
||||
|
||||
protected buildDOM(): HTMLElement {
|
||||
const dom = this.input.getDOMElement();
|
||||
dom.append(this.pickerButton.getDOMElement());
|
||||
dom.classList.add('editor-color-field-container');
|
||||
|
||||
const field = dom.querySelector('input') as HTMLInputElement;
|
||||
field.addEventListener('change', () => {
|
||||
this.setIconColor(field.value);
|
||||
});
|
||||
|
||||
return dom;
|
||||
}
|
||||
|
||||
onColorSelect(color: string, context: EditorUiContext): void {
|
||||
this.input.setValue(color);
|
||||
}
|
||||
|
||||
setIconColor(color: string) {
|
||||
const icon = this.getDOMElement().querySelector('svg .editor-icon-color-display');
|
||||
if (icon) {
|
||||
icon.setAttribute('fill', color || 'url(#pattern2)');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function colorFieldBuilder(field: EditorFormFieldDefinition): EditorUiBuilderDefinition {
|
||||
return {
|
||||
build() {
|
||||
return new EditorColorField(new EditorFormField(field));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
import {EditorUiElement} from "../core";
|
||||
import {$getSelection} from "lexical";
|
||||
import {$patchStyleText} from "@lexical/selection";
|
||||
import {EditorUiContext, EditorUiElement} from "../core";
|
||||
import {el} from "../../../utils/dom";
|
||||
|
||||
import removeIcon from "@icons/editor/color-clear.svg";
|
||||
@@ -38,13 +36,15 @@ const colorChoices = [
|
||||
|
||||
const storageKey = 'bs-lexical-custom-colors';
|
||||
|
||||
export type EditorColorPickerCallback = (color: string, context: EditorUiContext) => void;
|
||||
|
||||
export class EditorColorPicker extends EditorUiElement {
|
||||
|
||||
protected styleProperty: string;
|
||||
protected callback: EditorColorPickerCallback;
|
||||
|
||||
constructor(styleProperty: string) {
|
||||
constructor(callback: EditorColorPickerCallback) {
|
||||
super();
|
||||
this.styleProperty = styleProperty;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
buildDOM(): HTMLElement {
|
||||
@@ -131,11 +131,6 @@ export class EditorColorPicker extends EditorUiElement {
|
||||
}
|
||||
|
||||
setColor(color: string) {
|
||||
this.getContext().editor.update(() => {
|
||||
const selection = $getSelection();
|
||||
if (selection) {
|
||||
$patchStyleText(selection, {[this.styleProperty]: color || null});
|
||||
}
|
||||
});
|
||||
this.callback(color, this.getContext());
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,6 @@ export class LinkField extends EditorContainerUiElement {
|
||||
|
||||
updateFormFromHeader(header: HeadingNode) {
|
||||
this.getHeaderIdAndText(header).then(({id, text}) => {
|
||||
console.log('updating form', id, text);
|
||||
const modal = this.getContext().manager.getActiveModal('link');
|
||||
if (modal) {
|
||||
modal.getForm().setValues({
|
||||
@@ -60,7 +59,6 @@ export class LinkField extends EditorContainerUiElement {
|
||||
return new Promise((res) => {
|
||||
this.getContext().editor.update(() => {
|
||||
let id = header.getId();
|
||||
console.log('header', id, header.__id);
|
||||
if (!id) {
|
||||
id = 'header-' + uniqueIdSmall();
|
||||
header.setId(id);
|
||||
|
||||
@@ -19,15 +19,17 @@ export interface EditorSelectFormFieldDefinition extends EditorFormFieldDefiniti
|
||||
valuesByLabel: Record<string, string>
|
||||
}
|
||||
|
||||
export type EditorFormFields = (EditorFormFieldDefinition|EditorUiBuilderDefinition)[];
|
||||
|
||||
interface EditorFormTabDefinition {
|
||||
label: string;
|
||||
contents: EditorFormFieldDefinition[];
|
||||
contents: EditorFormFields;
|
||||
}
|
||||
|
||||
export interface EditorFormDefinition {
|
||||
submitText: string;
|
||||
action: (formData: FormData, context: EditorUiContext) => Promise<boolean>;
|
||||
fields: (EditorFormFieldDefinition|EditorUiBuilderDefinition)[];
|
||||
fields: EditorFormFields;
|
||||
}
|
||||
|
||||
export class EditorFormField extends EditorUiElement {
|
||||
@@ -41,6 +43,7 @@ export class EditorFormField extends EditorUiElement {
|
||||
setValue(value: string) {
|
||||
const input = this.getDOMElement().querySelector('input,select,textarea') as HTMLInputElement;
|
||||
input.value = value;
|
||||
input.dispatchEvent(new Event('change'));
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
@@ -155,11 +158,17 @@ export class EditorForm extends EditorContainerUiElement {
|
||||
export class EditorFormTab extends EditorContainerUiElement {
|
||||
|
||||
protected definition: EditorFormTabDefinition;
|
||||
protected fields: EditorFormField[];
|
||||
protected fields: EditorUiElement[];
|
||||
protected id: string;
|
||||
|
||||
constructor(definition: EditorFormTabDefinition) {
|
||||
const fields = definition.contents.map(fieldDef => new EditorFormField(fieldDef));
|
||||
const fields = definition.contents.map(fieldDef => {
|
||||
if (isUiBuilderDefinition(fieldDef)) {
|
||||
return fieldDef.build();
|
||||
}
|
||||
return new EditorFormField(fieldDef)
|
||||
});
|
||||
|
||||
super(fields);
|
||||
|
||||
this.definition = definition;
|
||||
|
||||
Reference in New Issue
Block a user