1 import {EditorUiContext, EditorUiElement} from "../core";
2 import {el} from "../../../utils/dom";
4 import removeIcon from "@icons/editor/color-clear.svg";
5 import selectIcon from "@icons/editor/color-select.svg";
6 import {uniqueIdSmall} from "../../../../services/util";
37 const storageKey = 'bs-lexical-custom-colors';
39 export type EditorColorPickerCallback = (color: string, context: EditorUiContext) => void;
41 export class EditorColorPicker extends EditorUiElement {
43 protected callback: EditorColorPickerCallback;
45 constructor(callback: EditorColorPickerCallback) {
47 this.callback = callback;
50 buildDOM(): HTMLElement {
51 const id = uniqueIdSmall();
53 const allChoices = [...colorChoices, ...this.getCustomColorChoices()];
54 const colorOptions = allChoices.map(choice => {
56 class: 'editor-color-select-option',
57 style: `background-color: ${choice}`,
63 const removeButton = el('div', {
64 class: 'editor-color-select-option',
68 removeButton.innerHTML = removeIcon;
69 colorOptions.push(removeButton);
71 const selectButton = el('label', {
72 class: 'editor-color-select-option',
73 for: `color-select-${id}`,
75 title: 'Custom color',
77 selectButton.innerHTML = selectIcon;
78 colorOptions.push(selectButton);
80 const input = el('input', {type: 'color', hidden: 'true', id: `color-select-${id}`}) as HTMLInputElement;
81 colorOptions.push(input);
82 input.addEventListener('change', e => {
84 this.storeCustomColorChoice(input.value);
85 this.setColor(input.value);
91 for (let i = 0; i < colorOptions.length; i+=5) {
92 const options = colorOptions.slice(i, i + 5);
93 colorRows.push(el('div', {
94 class: 'editor-color-select-row',
98 const wrapper = el('div', {
99 class: 'editor-color-select',
102 wrapper.addEventListener('click', this.onClick.bind(this));
107 storeCustomColorChoice(color: string) {
108 if (colorChoices.includes(color)) {
112 const customColors: string[] = this.getCustomColorChoices();
113 if (customColors.includes(color)) {
117 customColors.push(color);
118 window.localStorage.setItem(storageKey, JSON.stringify(customColors));
121 getCustomColorChoices(): string[] {
122 return JSON.parse(window.localStorage.getItem(storageKey) || '[]');
125 onClick(event: MouseEvent) {
126 const colorEl = (event.target as HTMLElement).closest('[data-color]') as HTMLElement;
127 if (!colorEl) return;
129 const color = colorEl.dataset.color as string;
130 this.setColor(color);
133 setColor(color: string) {
134 this.callback(color, this.getContext());