]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/ui/framework/blocks/color-picker.ts
b068fb4f0bf323e7f5f91890bd95f61b07f1fb7d
[bookstack] / resources / js / wysiwyg / ui / framework / blocks / color-picker.ts
1 import {EditorUiElement} from "../core";
2 import {$getSelection} from "lexical";
3 import {$patchStyleText} from "@lexical/selection";
4 import {el} from "../../../utils/dom";
5
6 import removeIcon from "@icons/editor/color-clear.svg";
7
8 const colorChoices = [
9     '#000000',
10     '#ffffff',
11
12     '#BFEDD2',
13     '#FBEEB8',
14     '#F8CAC6',
15     '#ECCAFA',
16     '#C2E0F4',
17
18     '#2DC26B',
19     '#F1C40F',
20     '#E03E2D',
21     '#B96AD9',
22     '#3598DB',
23
24     '#169179',
25     '#E67E23',
26     '#BA372A',
27     '#843FA1',
28     '#236FA1',
29
30     '#ECF0F1',
31     '#CED4D9',
32     '#95A5A6',
33     '#7E8C8D',
34     '#34495E',
35 ];
36
37 export class EditorColorPicker extends EditorUiElement {
38
39     protected styleProperty: string;
40
41     constructor(styleProperty: string) {
42         super();
43         this.styleProperty = styleProperty;
44     }
45
46     buildDOM(): HTMLElement {
47
48         const colorOptions = colorChoices.map(choice => {
49             return el('div', {
50                 class: 'editor-color-select-option',
51                 style: `background-color: ${choice}`,
52                 'data-color': choice,
53                 'aria-label': choice,
54             });
55         });
56
57         const removeButton = el('div', {
58             class: 'editor-color-select-option',
59             'data-color': '',
60             title: 'Clear color',
61         }, []);
62         removeButton.innerHTML = removeIcon;
63         colorOptions.push(removeButton);
64
65         const colorRows = [];
66         for (let i = 0; i < colorOptions.length; i+=5) {
67             const options = colorOptions.slice(i, i + 5);
68             colorRows.push(el('div', {
69                 class: 'editor-color-select-row',
70             }, options));
71         }
72
73         const wrapper = el('div', {
74             class: 'editor-color-select',
75         }, colorRows);
76
77         wrapper.addEventListener('click', this.onClick.bind(this));
78
79         return wrapper;
80     }
81
82     onClick(event: MouseEvent) {
83         const colorEl = (event.target as HTMLElement).closest('[data-color]') as HTMLElement;
84         if (!colorEl) return;
85
86         const color = colorEl.dataset.color as string;
87         this.getContext().editor.update(() => {
88             const selection = $getSelection();
89             if (selection) {
90                 $patchStyleText(selection, {[this.styleProperty]: color || null});
91             }
92         });
93     }
94 }