aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/frontend/src/editor/PanelStore.ts
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-08-16 21:14:50 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-08-16 21:14:50 +0200
commit19cd11118cde7160cd447c81bc965007c0437479 (patch)
tree5fea613e7a46d69380995368a68cc72f186078a4 /subprojects/frontend/src/editor/PanelStore.ts
parentchore(deps): bump frontend dependencies (diff)
downloadrefinery-19cd11118cde7160cd447c81bc965007c0437479.tar.gz
refinery-19cd11118cde7160cd447c81bc965007c0437479.tar.zst
refinery-19cd11118cde7160cd447c81bc965007c0437479.zip
refactor(frondend): improve editor store and theme
Also bumps frontend dependencies.
Diffstat (limited to 'subprojects/frontend/src/editor/PanelStore.ts')
-rw-r--r--subprojects/frontend/src/editor/PanelStore.ts90
1 files changed, 90 insertions, 0 deletions
diff --git a/subprojects/frontend/src/editor/PanelStore.ts b/subprojects/frontend/src/editor/PanelStore.ts
new file mode 100644
index 00000000..653d309c
--- /dev/null
+++ b/subprojects/frontend/src/editor/PanelStore.ts
@@ -0,0 +1,90 @@
1import type { Command } from '@codemirror/view';
2import { action, makeObservable, observable } from 'mobx';
3
4import getLogger from '../utils/getLogger';
5
6import type EditorStore from './EditorStore';
7
8const log = getLogger('editor.PanelStore');
9
10export default class PanelStore {
11 state = false;
12
13 constructor(
14 private readonly panelId: string,
15 private readonly openCommand: Command,
16 private readonly closeCommand: Command,
17 private readonly store: EditorStore,
18 ) {
19 makeObservable(this, {
20 state: observable,
21 open: action,
22 close: action,
23 toggle: action,
24 synchronizeStateToView: action,
25 });
26 }
27
28 open(): boolean {
29 return this.setState(true);
30 }
31
32 close(): boolean {
33 return this.setState(false);
34 }
35
36 toggle(): void {
37 this.setState(!this.state);
38 }
39
40 private setState(newState: boolean): boolean {
41 if (this.state === newState) {
42 return false;
43 }
44 log.debug('Show', this.panelId, 'panel', newState);
45 if (newState) {
46 this.doOpen();
47 } else {
48 this.doClose();
49 }
50 this.state = newState;
51 return true;
52 }
53
54 synchronizeStateToView(): void {
55 this.doClose();
56 if (this.state) {
57 this.doOpen();
58 }
59 }
60
61 private doOpen(): void {
62 if (!this.store.doCommand(this.openCommand)) {
63 return;
64 }
65 const { view } = this.store;
66 if (view === undefined) {
67 return;
68 }
69 const buttonQuery = `.cm-${this.panelId}.cm-panel button[name="close"]`;
70 const closeButton = view.dom.querySelector(buttonQuery);
71 if (closeButton !== null) {
72 log.debug('Addig close button callback to', this.panelId, 'panel');
73 // We must remove the event listener from the button that dispatches a transaction
74 // without going through `EditorStore`. This listened is added by CodeMirror,
75 // and we can only remove it by cloning the DOM node: https://stackoverflow.com/a/9251864
76 const closeButtonWithoutListeners = closeButton.cloneNode(true);
77 closeButtonWithoutListeners.addEventListener('click', (event) => {
78 this.close();
79 event.preventDefault();
80 });
81 closeButton.replaceWith(closeButtonWithoutListeners);
82 } else {
83 log.error('Opened', this.panelId, 'panel has no close button');
84 }
85 }
86
87 private doClose(): void {
88 this.store.doCommand(this.closeCommand);
89 }
90}