Skip to content

Commit c091f67

Browse files
committed
Lexical: Added color format custom color select
Includes tracking of selected colors via localstorage for display.
1 parent 7f5fd16 commit c091f67

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed
Lines changed: 1 addition & 0 deletions
Loading

resources/js/wysiwyg/ui/framework/blocks/color-picker.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import {$patchStyleText} from "@lexical/selection";
44
import {el} from "../../../utils/dom";
55

66
import removeIcon from "@icons/editor/color-clear.svg";
7+
import selectIcon from "@icons/editor/color-select.svg";
8+
import {uniqueIdSmall} from "../../../../services/util";
79

810
const colorChoices = [
911
'#000000',
@@ -34,6 +36,8 @@ const colorChoices = [
3436
'#34495E',
3537
];
3638

39+
const storageKey = 'bs-lexical-custom-colors';
40+
3741
export class EditorColorPicker extends EditorUiElement {
3842

3943
protected styleProperty: string;
@@ -44,8 +48,10 @@ export class EditorColorPicker extends EditorUiElement {
4448
}
4549

4650
buildDOM(): HTMLElement {
51+
const id = uniqueIdSmall();
4752

48-
const colorOptions = colorChoices.map(choice => {
53+
const allChoices = [...colorChoices, ...this.getCustomColorChoices()];
54+
const colorOptions = allChoices.map(choice => {
4955
return el('div', {
5056
class: 'editor-color-select-option',
5157
style: `background-color: ${choice}`,
@@ -62,6 +68,25 @@ export class EditorColorPicker extends EditorUiElement {
6268
removeButton.innerHTML = removeIcon;
6369
colorOptions.push(removeButton);
6470

71+
const selectButton = el('label', {
72+
class: 'editor-color-select-option',
73+
for: `color-select-${id}`,
74+
'data-color': '',
75+
title: 'Custom color',
76+
}, []);
77+
selectButton.innerHTML = selectIcon;
78+
colorOptions.push(selectButton);
79+
80+
const input = el('input', {type: 'color', hidden: 'true', id: `color-select-${id}`}) as HTMLInputElement;
81+
colorOptions.push(input);
82+
input.addEventListener('change', e => {
83+
if (input.value) {
84+
this.storeCustomColorChoice(input.value);
85+
this.setColor(input.value);
86+
this.rebuildDOM();
87+
}
88+
});
89+
6590
const colorRows = [];
6691
for (let i = 0; i < colorOptions.length; i+=5) {
6792
const options = colorOptions.slice(i, i + 5);
@@ -79,11 +104,33 @@ export class EditorColorPicker extends EditorUiElement {
79104
return wrapper;
80105
}
81106

107+
storeCustomColorChoice(color: string) {
108+
if (colorChoices.includes(color)) {
109+
return;
110+
}
111+
112+
const customColors: string[] = this.getCustomColorChoices();
113+
if (customColors.includes(color)) {
114+
return;
115+
}
116+
117+
customColors.push(color);
118+
window.localStorage.setItem(storageKey, JSON.stringify(customColors));
119+
}
120+
121+
getCustomColorChoices(): string[] {
122+
return JSON.parse(window.localStorage.getItem(storageKey) || '[]');
123+
}
124+
82125
onClick(event: MouseEvent) {
83126
const colorEl = (event.target as HTMLElement).closest('[data-color]') as HTMLElement;
84127
if (!colorEl) return;
85128

86129
const color = colorEl.dataset.color as string;
130+
this.setColor(color);
131+
}
132+
133+
setColor(color: string) {
87134
this.getContext().editor.update(() => {
88135
const selection = $getSelection();
89136
if (selection) {

resources/js/wysiwyg/ui/framework/core.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ export abstract class EditorUiElement {
5353
return this.dom;
5454
}
5555

56+
rebuildDOM(): HTMLElement {
57+
const newDOM = this.buildDOM();
58+
this.dom?.replaceWith(newDOM);
59+
this.dom = newDOM;
60+
return this.dom;
61+
}
62+
5663
trans(text: string) {
5764
return this.getContext().translate(text);
5865
}

0 commit comments

Comments
 (0)