-
Notifications
You must be signed in to change notification settings - Fork 34
/
Copy pathSelectorsProvider.tsx
103 lines (85 loc) · 2.89 KB
/
SelectorsProvider.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import type { Selector, State, Editor } from 'grapesjs';
import React, { memo, useEffect, useState } from 'react';
import { useEditorInstance } from './context/EditorInstance';
import { isFunction, noop } from './utils';
import { PortalContainerResult, portalContainer } from './utils/react';
import { useEditorOptions } from './context/EditorOptions';
export type SelectorsState = {
/**
* Array of current selectors.
*/
selectors: Selector[],
/**
* Array of available states.
*/
states: State[],
/**
* Current selected state.
*/
selectedState: string,
/**
* Selector strings of currently selected targets.
*/
targets: string[],
/**
* Add new selector to selected targets.
*/
addSelector: (...args: Parameters<Editor['Selectors']['addSelected']>) => void,
/**
* Remove selector from selected targets.
*/
removeSelector: (...args: Parameters<Editor['Selectors']['removeSelected']>) => void,
/**
* Update current state.
*/
setState: (...args: Parameters<Editor['Selectors']['setState']>) => void,
/**
* Default Selectors container.
*/
Container: PortalContainerResult,
};
export type SelectorsResultProps = SelectorsState;
export interface SelectorsProviderProps {
children: (props: SelectorsResultProps) => React.JSX.Element,
}
const SelectorsProvider = memo(function ({ children }: SelectorsProviderProps) {
const { editor } = useEditorInstance();
const options = useEditorOptions();
const [propState, setPropState] = useState<SelectorsState>(() => ({
selectors: [],
states: [],
selectedState: '',
targets: [],
addSelector: noop,
removeSelector: noop,
setState: noop,
Container: () => null,
}));
useEffect(() => {
if (!editor) return;
const { Selectors } = editor;
const event = Selectors.events.custom;
const up = ({ container }: { container: HTMLElement }) => {
setPropState({
selectors: Selectors.getSelected(),
states: Selectors.getStates(),
selectedState: Selectors.getState(),
targets: Selectors.getSelectedTargets().map(t => t.getSelectorsString()),
addSelector: (...args) => Selectors.addSelected(...args),
removeSelector: (...args) => Selectors.removeSelected(...args),
setState: (...args) => Selectors.setState(...args),
Container: portalContainer(container),
});
}
editor.on(event, up);
Selectors.__trgCustom();
return () => {
editor.off(event, up);
};
}, [editor]);
useEffect(() => options.setCustomSelectors(true), []);
return editor ?
(isFunction(children) ? children(propState) : null)
: null;
});
export default SelectorsProvider;