@lofcz/platejs-toggle 52.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) Ziad Beyens, Dylan Schiemann, Joe Anderson, Felix Feng
4
+
5
+ Unless otherwise specified in a LICENSE file within an individual package directory,
6
+ this license applies to all files in this repository outside of those package directories.
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ of this software and associated documentation files (the "Software"), to deal
10
+ in the Software without restriction, including without limitation the rights
11
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ copies of the Software, and to permit persons to whom the Software is
13
+ furnished to do so, subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in
16
+ all copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # Plate toggle plugin
2
+
3
+ This package implements the toggle plugin for Plate.
4
+ It's similar to the indent list plugin, in that it relies on the indent of siblings.
5
+
6
+ ## Documentation
7
+
8
+ Check out [Toggle](https://platejs.org/docs/toggle).
9
+
10
+ ## Ideas to improve this plugin
11
+
12
+ 1. Adding an option `initialValue` of open `toggleIds` and a callback `onChange`, for instance to store the state of open toggles in local storage and remember the state upon browser refresh.
13
+ 2. Adding an option `defaultOpen`. Currently, toggles are closed on initial rendering.
14
+ 3. Adding an option to specify how to get the indent value of elements, right now we are relying on this being the default `KEY_ELEMENT` from the `indent` plugin
15
+ 4. An option to specify how to get the id of elements, right now we are using the default id attribute from the `node-id` plugin.
16
+ 5. Adding a placeholder below the toggle, like Notion does, when the toggle is expanded without any elements below.
17
+ 6. Make toggle button more accessible
18
+ 7. When indenting an element right of a closed toggle, it becomes hidden. This makes sense, but a nicer UI would be to open the toggle in that case, like Notion does.
19
+
20
+ ## License
21
+
22
+ [MIT](../../LICENSE)
@@ -0,0 +1,17 @@
1
+ import { PluginConfig } from "platejs";
2
+
3
+ //#region src/lib/BaseTogglePlugin.d.ts
4
+ type BaseToggleConfig = PluginConfig<'toggle', {
5
+ openIds?: Set<string>;
6
+ }, {
7
+ toggle: {
8
+ toggleIds: (ids: string[], force?: boolean | null) => void;
9
+ };
10
+ }, {}, {
11
+ isOpen?: (toggleId: string) => boolean;
12
+ someClosed?: (toggleIds: string[]) => boolean;
13
+ }>;
14
+ declare const BaseTogglePlugin: any;
15
+ //#endregion
16
+ export { BaseTogglePlugin as n, BaseToggleConfig as t };
17
+ //# sourceMappingURL=BaseTogglePlugin-CrydL5tg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseTogglePlugin-CrydL5tg.d.ts","names":[],"sources":["../src/lib/BaseTogglePlugin.ts"],"sourcesContent":[],"mappings":";;;KAEY,gBAAA,GAAmB;YAGjB;AAHd,CAAA,EAAA;EAiBa,MAAA,EAAA;;;;;;;cAAA"}
@@ -0,0 +1,8 @@
1
+ import { n as BaseTogglePlugin, t as BaseToggleConfig } from "./BaseTogglePlugin-CrydL5tg";
2
+ import { SlateEditor } from "platejs";
3
+
4
+ //#region src/lib/queries/someToggle.d.ts
5
+ declare const someToggle: (editor: SlateEditor) => any;
6
+ //#endregion
7
+ export { BaseToggleConfig, BaseTogglePlugin, someToggle };
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/lib/queries/someToggle.ts"],"sourcesContent":[],"mappings":";;;;cAEa,qBAAsB"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ import { n as BaseTogglePlugin, t as someToggle } from "./someToggle-BUWI6X7B.js";
2
+
3
+ export { BaseTogglePlugin, someToggle };
@@ -0,0 +1,84 @@
1
+ import { t as BaseToggleConfig } from "../BaseTogglePlugin-CrydL5tg";
2
+ import { ExtendConfig, NodeEntry, SlateEditor, TIndentElement, Value } from "platejs";
3
+ import { OverrideEditor, RenderNodeWrapper, UseHooks } from "platejs/react";
4
+ import { Atom } from "jotai";
5
+
6
+ //#region src/react/toggleIndexAtom.d.ts
7
+ declare const buildToggleIndex: (elements: Value) => Map<string, string[]>;
8
+ declare const editorAtom: Atom<{
9
+ editor: {
10
+ children: TIndentElement[];
11
+ };
12
+ version: number;
13
+ }>;
14
+ declare const useIsVisible: (elementId: string) => any;
15
+ declare const toggleIndexAtom: Atom<Map<string, string[]>>;
16
+ declare const useToggleIndex: () => any;
17
+ //#endregion
18
+ //#region src/react/TogglePlugin.d.ts
19
+ type ToggleConfig = ExtendConfig<BaseToggleConfig, {
20
+ toggleIndex?: ReturnType<typeof buildToggleIndex>;
21
+ }>;
22
+ /** Enables support for toggleable elements in the editor. */
23
+ declare const TogglePlugin: any;
24
+ //#endregion
25
+ //#region src/react/renderToggleAboveNodes.d.ts
26
+ declare const renderToggleAboveNodes: RenderNodeWrapper;
27
+ //#endregion
28
+ //#region src/react/useHooksToggle.d.ts
29
+ declare const useHooksToggle: UseHooks<ToggleConfig>;
30
+ //#endregion
31
+ //#region src/react/withToggle.d.ts
32
+ declare const withToggle: OverrideEditor<ToggleConfig>;
33
+ //#endregion
34
+ //#region src/react/hooks/useToggleButton.d.ts
35
+ declare const useToggleButtonState: (toggleId: string) => {
36
+ open: any;
37
+ toggleId: string;
38
+ };
39
+ declare const useToggleButton: (state: ReturnType<typeof useToggleButtonState>) => {
40
+ buttonProps: {
41
+ onClick: (e: React.MouseEvent) => void;
42
+ onMouseDown: (e: React.MouseEvent) => void;
43
+ };
44
+ open: any;
45
+ toggleId: string;
46
+ };
47
+ //#endregion
48
+ //#region src/react/hooks/useToggleToolbarButton.d.ts
49
+ declare const useToggleToolbarButtonState: () => {
50
+ pressed: any;
51
+ };
52
+ declare const useToggleToolbarButton: ({
53
+ pressed
54
+ }: ReturnType<typeof useToggleToolbarButtonState>) => {
55
+ props: {
56
+ pressed: any;
57
+ onClick: () => void;
58
+ onMouseDown: (e: React.MouseEvent<HTMLButtonElement>) => void;
59
+ };
60
+ };
61
+ //#endregion
62
+ //#region src/react/queries/findElementIdsHiddenInToggle.d.ts
63
+ declare const findElementIdsHiddenInToggle: (openToggleIds: Set<string>, elements: TIndentElement[]) => string[];
64
+ //#endregion
65
+ //#region src/react/queries/getEnclosingToggleIds.d.ts
66
+ declare function getEnclosingToggleIds(editor: SlateEditor, elementId: string): string[];
67
+ //#endregion
68
+ //#region src/react/queries/getLastEntryEnclosedInToggle.d.ts
69
+ declare const getLastEntryEnclosedInToggle: (editor: SlateEditor, toggleId: string) => NodeEntry | undefined;
70
+ //#endregion
71
+ //#region src/react/queries/isInClosedToggle.d.ts
72
+ declare const isInClosedToggle: (editor: SlateEditor, elementId: string) => any;
73
+ //#endregion
74
+ //#region src/react/transforms/moveCurrentBlockAfterPreviousSelectable.d.ts
75
+ declare const moveCurrentBlockAfterPreviousSelectable: (editor: SlateEditor) => boolean | undefined;
76
+ //#endregion
77
+ //#region src/react/transforms/moveNextSelectableAfterCurrentBlock.d.ts
78
+ declare const moveNextSelectableAfterCurrentBlock: (editor: SlateEditor) => false | undefined;
79
+ //#endregion
80
+ //#region src/react/transforms/openNextToggles.d.ts
81
+ declare const openNextToggles: (editor: SlateEditor) => void;
82
+ //#endregion
83
+ export { ToggleConfig, TogglePlugin, buildToggleIndex, editorAtom, findElementIdsHiddenInToggle, getEnclosingToggleIds, getLastEntryEnclosedInToggle, isInClosedToggle, moveCurrentBlockAfterPreviousSelectable, moveNextSelectableAfterCurrentBlock, openNextToggles, renderToggleAboveNodes, toggleIndexAtom, useHooksToggle, useIsVisible, useToggleButton, useToggleButtonState, useToggleIndex, useToggleToolbarButton, useToggleToolbarButtonState, withToggle };
84
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/react/toggleIndexAtom.ts","../../src/react/TogglePlugin.tsx","../../src/react/renderToggleAboveNodes.tsx","../../src/react/useHooksToggle.ts","../../src/react/withToggle.ts","../../src/react/hooks/useToggleButton.ts","../../src/react/hooks/useToggleToolbarButton.ts","../../src/react/queries/findElementIdsHiddenInToggle.ts","../../src/react/queries/getEnclosingToggleIds.ts","../../src/react/queries/getLastEntryEnclosedInToggle.ts","../../src/react/queries/isInClosedToggle.ts","../../src/react/transforms/moveCurrentBlockAfterPreviousSelectable.ts","../../src/react/transforms/moveNextSelectableAfterCurrentBlock.ts","../../src/react/transforms/openNextToggles.ts"],"sourcesContent":[],"mappings":";;;;;;cAoBa,6BAA8B,UAAQ;cA4BtC,YAA8C;;cACrC;EA7BT,CAAA;EA4BA,OAAA,EAAA,MAGX;AAKF,CAAA,CAAA;AAkBa,cAlBA,YAkBsB,EAAA,CAAA,SAAD,EAAA,MAAA,EAAA,GAAA,GAAA;AAIrB,cAJA,eAKwC,EALvB,IAKuB,CALlB,GAKkB,CAAA,MAAA,EAAA,MAAA,EAAA,CAAA,CAAA;cADxC;;;KChED,YAAA,GAAe,aACzB;gBAEgB,kBAAkB;;ADGpC;AA4Ba,cC1BA,YD2BS,EAAA,GAAA;;;cExCT,wBAAwB;;;cCDxB,gBAAgB,SAAS;;;cCKzB,YAAY,eAAe;;;cCT3B;;;;cASA,yBACJ,kBAAkB;;ILMd,OAAA,EAAA,CAAA,CAAA,EKCM,KAAA,CAAM,ULDkB,EAAA,GAAQ,IAAG;IA4BzC,WAGX,EAAA,CAAA,CAAA,EK1BqB,KAAA,CAAM,ULwBP,EAAA,GADqC,IAAI;EAQlD,CAAA;EAkBA,IAAA,EAAA,GAAA;EAIA,QAAA,EAAA,MAAA;;;;cMxEA;;;cAQA;;GAEV,kBAAkB;;;INIR,OAAA,EAAA,GAAA,GA0BZ,IAAA;IAEY,WAGX,EAAA,CAAA,CAAA,EMvBqB,KAAA,CAAM,UNqBP,CMrBkB,iBNoBuB,CAAA,EAAA,GAAA,IAAA;EAQlD,CAAA;AAkBb,CAAA;;;cOtEa,8CACI,uBACL;;;iBCFI,qBAAA,SACN;;;cCCG,uCACH,kCAEP;;;cCJU,2BAA4B;;;cCA5B,kDACH;;;cCDG,8CAA+C;;;cCC/C,0BAA2B"}
@@ -0,0 +1,343 @@
1
+ import { n as BaseTogglePlugin, t as someToggle } from "../someToggle-BUWI6X7B.js";
2
+ import { ElementApi, KEYS, NodeApi, getEditorPlugin } from "platejs";
3
+ import { atom, plateStore, toTPlatePlugin, useEditorPlugin, useEditorRef, useEditorSelector, usePlateStore, usePluginOption, useStoreAtomValue } from "platejs/react";
4
+ import { c } from "react-compiler-runtime";
5
+ import React, { useEffect } from "react";
6
+ import { indent } from "@platejs/indent";
7
+ import last from "lodash/last.js";
8
+
9
+ //#region src/react/toggleIndexAtom.ts
10
+ const ListPluginKey = "listStyleType";
11
+ const buildToggleIndex = (elements) => {
12
+ const result = /* @__PURE__ */ new Map();
13
+ let currentEnclosingToggles = [];
14
+ elements.forEach((element) => {
15
+ const elementIndent = element[KEYS.indent] || 0;
16
+ const elementIndentWithListCorrection = element[ListPluginKey] && element[KEYS.indent] ? elementIndent - 1 : elementIndent;
17
+ const enclosingToggles = currentEnclosingToggles.filter(([_, indent$1]) => indent$1 < elementIndentWithListCorrection);
18
+ currentEnclosingToggles = enclosingToggles;
19
+ result.set(element.id, enclosingToggles.map(([toggleId]) => toggleId));
20
+ if (element.type === KEYS.toggle) currentEnclosingToggles.push([element.id, elementIndent]);
21
+ });
22
+ return result;
23
+ };
24
+ const editorAtom = plateStore.atom.trackedEditor;
25
+ const useIsVisible = (elementId) => {
26
+ const $ = c(3);
27
+ const openIds = usePluginOption(TogglePlugin, "openIds");
28
+ let t0;
29
+ if ($[0] !== elementId || $[1] !== openIds) {
30
+ t0 = atom((get) => {
31
+ return (get(toggleIndexAtom).get(elementId) || []).every((enclosedId) => openIds.has(enclosedId));
32
+ });
33
+ $[0] = elementId;
34
+ $[1] = openIds;
35
+ $[2] = t0;
36
+ } else t0 = $[2];
37
+ const isVisibleAtom = t0;
38
+ return useStoreAtomValue(usePlateStore(), isVisibleAtom);
39
+ };
40
+ const toggleIndexAtom = atom((get) => buildToggleIndex(get(editorAtom).editor.children));
41
+ const useToggleIndex = () => {
42
+ return useStoreAtomValue(usePlateStore(), toggleIndexAtom);
43
+ };
44
+
45
+ //#endregion
46
+ //#region src/react/renderToggleAboveNodes.tsx
47
+ const renderToggleAboveNodes = () => ToggleAboveNodes;
48
+ const ToggleAboveNodes = (t0) => {
49
+ const $ = c(2);
50
+ const { children, element } = t0;
51
+ if (useIsVisible(element.id)) return children;
52
+ let t1;
53
+ if ($[0] !== children) {
54
+ t1 = /* @__PURE__ */ React.createElement("div", { style: hiddenStyle }, children);
55
+ $[0] = children;
56
+ $[1] = t1;
57
+ } else t1 = $[1];
58
+ return t1;
59
+ };
60
+ const hiddenStyle = {
61
+ height: 0,
62
+ margin: 0,
63
+ overflow: "hidden",
64
+ visibility: "hidden"
65
+ };
66
+
67
+ //#endregion
68
+ //#region src/react/useHooksToggle.ts
69
+ const useHooksToggle = (t0) => {
70
+ const $ = c(7);
71
+ const { editor, setOption } = t0;
72
+ const toggleIndex = useToggleIndex();
73
+ let t1;
74
+ if ($[0] !== setOption || $[1] !== toggleIndex) {
75
+ t1 = () => {
76
+ setOption("toggleIndex", toggleIndex);
77
+ };
78
+ $[0] = setOption;
79
+ $[1] = toggleIndex;
80
+ $[2] = t1;
81
+ } else t1 = $[2];
82
+ let t2;
83
+ if ($[3] !== editor || $[4] !== setOption || $[5] !== toggleIndex) {
84
+ t2 = [
85
+ editor,
86
+ setOption,
87
+ toggleIndex
88
+ ];
89
+ $[3] = editor;
90
+ $[4] = setOption;
91
+ $[5] = toggleIndex;
92
+ $[6] = t2;
93
+ } else t2 = $[6];
94
+ useEffect(t1, t2);
95
+ };
96
+
97
+ //#endregion
98
+ //#region src/react/queries/findElementIdsHiddenInToggle.ts
99
+ const findElementIdsHiddenInToggle = (openToggleIds, elements) => {
100
+ const toggleIndex = buildToggleIndex(elements);
101
+ return elements.filter((element) => {
102
+ return (toggleIndex.get(element.id) || []).some((toggleId) => !openToggleIds.has(toggleId));
103
+ }).map((element) => element.id);
104
+ };
105
+
106
+ //#endregion
107
+ //#region src/react/queries/getEnclosingToggleIds.ts
108
+ function getEnclosingToggleIds(editor, elementId) {
109
+ return editor.getOptions(TogglePlugin).toggleIndex?.get(elementId) || [];
110
+ }
111
+
112
+ //#endregion
113
+ //#region src/react/queries/getLastEntryEnclosedInToggle.ts
114
+ const getLastEntryEnclosedInToggle = (editor, toggleId) => {
115
+ const toggleIndex = buildToggleIndex(editor.children);
116
+ return last(editor.children.map((node, index) => [node, [index]]).filter(([node]) => (toggleIndex.get(node.id) || []).includes(toggleId)));
117
+ };
118
+
119
+ //#endregion
120
+ //#region src/react/queries/isInClosedToggle.ts
121
+ const isInClosedToggle = (editor, elementId) => {
122
+ const enclosingToggleIds = getEnclosingToggleIds(editor, elementId);
123
+ return getEditorPlugin(editor, TogglePlugin).getOption("someClosed", enclosingToggleIds);
124
+ };
125
+
126
+ //#endregion
127
+ //#region src/react/transforms/moveCurrentBlockAfterPreviousSelectable.ts
128
+ const moveCurrentBlockAfterPreviousSelectable = (editor) => {
129
+ const { selection } = editor;
130
+ if (!selection) return;
131
+ const aboveBlock = editor.api.block();
132
+ if (!aboveBlock) return;
133
+ if (!editor.api.isAt({ start: true })) return;
134
+ const beforePoint = editor.api.before(selection);
135
+ if (!beforePoint) return;
136
+ const blockBefore = editor.api.block({ at: beforePoint });
137
+ if (!blockBefore) return;
138
+ if (!isInClosedToggle(editor, blockBefore[0].id)) return;
139
+ const previousSelectableBlock = editor.api.previous({ match: (node) => ElementApi.isElement(node) && !isInClosedToggle(editor, node.id) });
140
+ if (!previousSelectableBlock) return false;
141
+ const afterSelectableBlock = [previousSelectableBlock[1][0] + 1];
142
+ editor.tf.moveNodes({
143
+ at: aboveBlock[1],
144
+ to: afterSelectableBlock
145
+ });
146
+ };
147
+
148
+ //#endregion
149
+ //#region src/react/transforms/moveNextSelectableAfterCurrentBlock.ts
150
+ const moveNextSelectableAfterCurrentBlock = (editor) => {
151
+ const { selection } = editor;
152
+ if (!selection) return;
153
+ const aboveBlock = editor.api.block();
154
+ if (!aboveBlock) return;
155
+ if (!editor.api.isAt({ end: true })) return;
156
+ const afterPoint = editor.api.after(selection);
157
+ if (!afterPoint) return;
158
+ const blockAfter = editor.api.block({ at: afterPoint });
159
+ if (!blockAfter) return;
160
+ if (!isInClosedToggle(editor, blockAfter[0].id)) return;
161
+ const nextSelectableBlock = editor.api.next({ match: (node) => ElementApi.isElement(node) && !isInClosedToggle(editor, node.id) });
162
+ if (!nextSelectableBlock) return false;
163
+ const afterCurrentBlock = [aboveBlock[1][0] + 1];
164
+ editor.tf.moveNodes({
165
+ at: nextSelectableBlock[1],
166
+ to: afterCurrentBlock
167
+ });
168
+ };
169
+
170
+ //#endregion
171
+ //#region src/react/transforms/openNextToggles.ts
172
+ const openNextToggles = (editor) => {
173
+ const nodeEntries = Array.from(editor.api.nodes({
174
+ block: true,
175
+ mode: "lowest"
176
+ }));
177
+ editor.getApi(TogglePlugin).toggle.toggleIds(nodeEntries.map(([node]) => node.id), true);
178
+ };
179
+
180
+ //#endregion
181
+ //#region src/react/withToggle.ts
182
+ const withToggle = ({ api: { isSelectable }, editor, getOption, tf: { deleteBackward, deleteForward, insertBreak } }) => ({
183
+ api: { isSelectable(element) {
184
+ if (NodeApi.isNode(element) && isInClosedToggle(editor, element.id)) return false;
185
+ return isSelectable(element);
186
+ } },
187
+ transforms: {
188
+ deleteBackward(unit) {
189
+ if (moveCurrentBlockAfterPreviousSelectable(editor) === false) return;
190
+ deleteBackward(unit);
191
+ },
192
+ deleteForward(unit) {
193
+ if (moveNextSelectableAfterCurrentBlock(editor) === false) return;
194
+ deleteForward(unit);
195
+ },
196
+ insertBreak() {
197
+ const currentBlockEntry = editor.api.block();
198
+ if (!currentBlockEntry || currentBlockEntry[0].type !== KEYS.toggle) return insertBreak();
199
+ const toggleId = currentBlockEntry[0].id;
200
+ const isOpen = getOption("isOpen", toggleId);
201
+ editor.tf.withoutNormalizing(() => {
202
+ if (isOpen) {
203
+ insertBreak();
204
+ editor.tf.toggleBlock(KEYS.toggle);
205
+ indent(editor);
206
+ } else {
207
+ const lastEntryEnclosedInToggle = getLastEntryEnclosedInToggle(editor, toggleId);
208
+ insertBreak();
209
+ if (lastEntryEnclosedInToggle) {
210
+ const newlyInsertedTogglePath = [currentBlockEntry[1][0] + 1];
211
+ const afterLastEntryEncloseInToggle = [lastEntryEnclosedInToggle[1][0] + 1];
212
+ editor.tf.moveNodes({
213
+ at: newlyInsertedTogglePath,
214
+ to: afterLastEntryEncloseInToggle
215
+ });
216
+ }
217
+ }
218
+ });
219
+ }
220
+ }
221
+ });
222
+
223
+ //#endregion
224
+ //#region src/react/TogglePlugin.tsx
225
+ /** Enables support for toggleable elements in the editor. */
226
+ const TogglePlugin = toTPlatePlugin(BaseTogglePlugin, {
227
+ options: { toggleIndex: /* @__PURE__ */ new Map() },
228
+ render: { aboveNodes: renderToggleAboveNodes },
229
+ useHooks: useHooksToggle
230
+ }).overrideEditor(withToggle);
231
+
232
+ //#endregion
233
+ //#region src/react/hooks/useToggleButton.ts
234
+ const useToggleButtonState = (toggleId) => {
235
+ const $ = c(6);
236
+ const openIds = usePluginOption(BaseTogglePlugin, "openIds");
237
+ let t0;
238
+ if ($[0] !== openIds || $[1] !== toggleId) {
239
+ t0 = openIds.has(toggleId);
240
+ $[0] = openIds;
241
+ $[1] = toggleId;
242
+ $[2] = t0;
243
+ } else t0 = $[2];
244
+ let t1;
245
+ if ($[3] !== t0 || $[4] !== toggleId) {
246
+ t1 = {
247
+ open: t0,
248
+ toggleId
249
+ };
250
+ $[3] = t0;
251
+ $[4] = toggleId;
252
+ $[5] = t1;
253
+ } else t1 = $[5];
254
+ return t1;
255
+ };
256
+ const useToggleButton = (state) => {
257
+ const $ = c(6);
258
+ const { api } = useEditorPlugin(BaseTogglePlugin);
259
+ let t0;
260
+ if ($[0] !== api || $[1] !== state) {
261
+ t0 = {
262
+ onClick: (e) => {
263
+ e.preventDefault();
264
+ api.toggle.toggleIds([state.toggleId]);
265
+ },
266
+ onMouseDown: _temp$1
267
+ };
268
+ $[0] = api;
269
+ $[1] = state;
270
+ $[2] = t0;
271
+ } else t0 = $[2];
272
+ let t1;
273
+ if ($[3] !== state || $[4] !== t0) {
274
+ t1 = {
275
+ ...state,
276
+ buttonProps: t0
277
+ };
278
+ $[3] = state;
279
+ $[4] = t0;
280
+ $[5] = t1;
281
+ } else t1 = $[5];
282
+ return t1;
283
+ };
284
+ function _temp$1(e_0) {
285
+ e_0.preventDefault();
286
+ }
287
+
288
+ //#endregion
289
+ //#region src/react/hooks/useToggleToolbarButton.ts
290
+ const useToggleToolbarButtonState = () => {
291
+ const $ = c(3);
292
+ let t0;
293
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
294
+ t0 = [];
295
+ $[0] = t0;
296
+ } else t0 = $[0];
297
+ const pressed = useEditorSelector(_temp, t0);
298
+ let t1;
299
+ if ($[1] !== pressed) {
300
+ t1 = { pressed };
301
+ $[1] = pressed;
302
+ $[2] = t1;
303
+ } else t1 = $[2];
304
+ return t1;
305
+ };
306
+ const useToggleToolbarButton = (t0) => {
307
+ const $ = c(5);
308
+ const { pressed } = t0;
309
+ const editor = useEditorRef();
310
+ let t1;
311
+ if ($[0] !== editor) {
312
+ t1 = () => {
313
+ openNextToggles(editor);
314
+ editor.tf.toggleBlock(KEYS.toggle);
315
+ editor.tf.collapse();
316
+ editor.tf.focus();
317
+ };
318
+ $[0] = editor;
319
+ $[1] = t1;
320
+ } else t1 = $[1];
321
+ let t2;
322
+ if ($[2] !== pressed || $[3] !== t1) {
323
+ t2 = { props: {
324
+ pressed,
325
+ onClick: t1,
326
+ onMouseDown: _temp2
327
+ } };
328
+ $[2] = pressed;
329
+ $[3] = t1;
330
+ $[4] = t2;
331
+ } else t2 = $[4];
332
+ return t2;
333
+ };
334
+ function _temp(editor) {
335
+ return someToggle(editor);
336
+ }
337
+ function _temp2(e) {
338
+ e.preventDefault();
339
+ }
340
+
341
+ //#endregion
342
+ export { TogglePlugin, buildToggleIndex, editorAtom, findElementIdsHiddenInToggle, getEnclosingToggleIds, getLastEntryEnclosedInToggle, isInClosedToggle, moveCurrentBlockAfterPreviousSelectable, moveNextSelectableAfterCurrentBlock, openNextToggles, renderToggleAboveNodes, toggleIndexAtom, useHooksToggle, useIsVisible, useToggleButton, useToggleButtonState, useToggleIndex, useToggleToolbarButton, useToggleToolbarButtonState, withToggle };
343
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["useMemo","Atom","TIndentElement","Value","KEYS","atom","plateStore","usePlateStore","usePluginOption","useStoreAtomValue","TogglePlugin","ListPluginKey","buildToggleIndex","elements","Map","result","currentEnclosingToggles","forEach","element","elementIndent","indent","elementIndentWithListCorrection","enclosingToggles","filter","_","set","id","map","toggleId","type","toggle","push","editorAtom","trackedEditor","editor","children","version","useIsVisible","elementId","$","_c","openIds","t0","get","toggleIndex","toggleIndexAtom","enclosedInToggleIds","every","enclosedId","has","isVisibleAtom","useToggleIndex","React","RenderNodeWrapper","RenderNodeWrapperFunction","useIsVisible","renderToggleAboveNodes","ToggleAboveNodes","t0","$","_c","children","element","isVisible","id","t1","hiddenStyle","CSSProperties","height","margin","overflow","visibility","useEffect","UseHooks","ToggleConfig","useToggleIndex","useHooksToggle","t0","$","_c","editor","setOption","toggleIndex","t1","t2","TIndentElement","buildToggleIndex","findElementIdsHiddenInToggle","openToggleIds","Set","elements","toggleIndex","filter","element","enclosingToggleIds","get","id","some","toggleId","has","map","SlateEditor","TogglePlugin","getEnclosingToggleIds","editor","elementId","getOptions","toggleIndex","get","NodeEntry","SlateEditor","last","buildToggleIndex","getLastEntryEnclosedInToggle","editor","toggleId","toggleIndex","children","entriesInToggle","map","node","index","filter","get","id","includes","SlateEditor","getEditorPlugin","TogglePlugin","getEnclosingToggleIds","isInClosedToggle","editor","elementId","enclosingToggleIds","getOption","SlateEditor","ElementApi","isInClosedToggle","moveCurrentBlockAfterPreviousSelectable","editor","selection","aboveBlock","api","block","isAt","start","beforePoint","before","blockBefore","at","id","previousSelectableBlock","previous","match","node","isElement","afterSelectableBlock","tf","moveNodes","to","SlateEditor","ElementApi","isInClosedToggle","moveNextSelectableAfterCurrentBlock","editor","selection","aboveBlock","api","block","isAt","end","afterPoint","after","blockAfter","at","id","nextSelectableBlock","next","match","node","isElement","afterCurrentBlock","tf","moveNodes","to","SlateEditor","TogglePlugin","openNextToggles","editor","nodeEntries","Array","from","api","nodes","block","mode","getApi","toggle","toggleIds","map","node","id","OverrideEditor","indent","SlateEditor","TIndentElement","KEYS","NodeApi","ToggleConfig","getLastEntryEnclosedInToggle","isInClosedToggle","moveCurrentBlockAfterPreviousSelectable","moveNextSelectableAfterCurrentBlock","withToggle","api","isSelectable","editor","getOption","tf","deleteBackward","deleteForward","insertBreak","element","isNode","id","transforms","unit","currentBlockEntry","block","type","toggle","toggleId","isOpen","withoutNormalizing","toggleBlock","lastEntryEnclosedInToggle","newlyInsertedTogglePath","afterLastEntryEncloseInToggle","moveNodes","at","to","ExtendConfig","toTPlatePlugin","buildToggleIndex","BaseToggleConfig","BaseTogglePlugin","renderToggleAboveNodes","useHooksToggle","withToggle","ToggleConfig","toggleIndex","ReturnType","TogglePlugin","options","Map","render","aboveNodes","useHooks","overrideEditor","useEditorPlugin","usePluginOption","BaseTogglePlugin","useToggleButtonState","toggleId","$","_c","openIds","t0","has","t1","open","useToggleButton","state","api","onClick","e","preventDefault","toggle","toggleIds","onMouseDown","_temp","buttonProps","e_0","KEYS","useEditorRef","useEditorSelector","someToggle","openNextToggles","useToggleToolbarButtonState","$","_c","t0","Symbol","for","pressed","_temp","t1","useToggleToolbarButton","editor","tf","toggleBlock","toggle","collapse","focus","t2","props","onClick","onMouseDown","_temp2","e","preventDefault"],"sources":["../../src/react/toggleIndexAtom.ts","../../src/react/renderToggleAboveNodes.tsx","../../src/react/useHooksToggle.ts","../../src/react/queries/findElementIdsHiddenInToggle.ts","../../src/react/queries/getEnclosingToggleIds.ts","../../src/react/queries/getLastEntryEnclosedInToggle.ts","../../src/react/queries/isInClosedToggle.ts","../../src/react/transforms/moveCurrentBlockAfterPreviousSelectable.ts","../../src/react/transforms/moveNextSelectableAfterCurrentBlock.ts","../../src/react/transforms/openNextToggles.ts","../../src/react/withToggle.ts","../../src/react/TogglePlugin.tsx","../../src/react/hooks/useToggleButton.ts","../../src/react/hooks/useToggleToolbarButton.ts"],"sourcesContent":["import { useMemo } from 'react';\n\nimport type { Atom } from 'jotai';\nimport type { TIndentElement, Value } from 'platejs';\n\nimport { KEYS } from 'platejs';\nimport {\n atom,\n plateStore,\n usePlateStore,\n usePluginOption,\n useStoreAtomValue,\n} from 'platejs/react';\n\nimport { TogglePlugin } from './TogglePlugin';\n\n// Duplicate constant instead of importing from \"plate-list\" to avoid a dependency.\nconst ListPluginKey = 'listStyleType';\n\n// Returns, for each child, the enclosing toggle ids\nexport const buildToggleIndex = (elements: Value): Map<string, string[]> => {\n const result = new Map<string, string[]>();\n let currentEnclosingToggles: [string, number][] = []; // [toggleId, indent][]\n elements.forEach((element) => {\n const elementIndent = (element[KEYS.indent] as number) || 0;\n // For some reason, indent lists have a min indent of 1, even though they are not indented\n const elementIndentWithListCorrection =\n element[ListPluginKey] && element[KEYS.indent]\n ? elementIndent - 1\n : elementIndent;\n\n const enclosingToggles = currentEnclosingToggles.filter(\n ([_, indent]) => indent < elementIndentWithListCorrection\n );\n currentEnclosingToggles = enclosingToggles;\n result.set(\n element.id as string,\n enclosingToggles.map(([toggleId]) => toggleId)\n );\n\n if (element.type === KEYS.toggle) {\n currentEnclosingToggles.push([element.id as string, elementIndent]);\n }\n });\n\n return result;\n};\n\nexport const editorAtom = plateStore.atom.trackedEditor as Atom<{\n editor: { children: TIndentElement[] };\n version: number;\n}>;\n\n// Due to a limitation of jotai-x, it's not possible to derive a state from both `toggleControllerStore` and plateStore`.\n// In order minimize re-renders, we subscribe to both separately, but only re-render unnecessarily when opening or closing a toggle,\n// which is less frequent than changing the editor's children.\nexport const useIsVisible = (elementId: string) => {\n const openIds = usePluginOption(TogglePlugin, 'openIds')!;\n const isVisibleAtom = useMemo(\n () =>\n atom((get) => {\n const toggleIndex = get(toggleIndexAtom);\n const enclosedInToggleIds = toggleIndex.get(elementId) || [];\n\n return enclosedInToggleIds.every((enclosedId) =>\n openIds.has(enclosedId)\n );\n }),\n [elementId, openIds]\n );\n\n return useStoreAtomValue(usePlateStore(), isVisibleAtom);\n};\n\nexport const toggleIndexAtom: Atom<Map<string, string[]>> = atom((get) =>\n buildToggleIndex(get(editorAtom).editor.children as TIndentElement[])\n);\n\nexport const useToggleIndex = () =>\n useStoreAtomValue(usePlateStore(), toggleIndexAtom);\n","import React from 'react';\n\nimport type {\n RenderNodeWrapper,\n RenderNodeWrapperFunction,\n} from 'platejs/react';\n\nimport { useIsVisible } from './toggleIndexAtom';\n\nexport const renderToggleAboveNodes: RenderNodeWrapper = () => ToggleAboveNodes;\n\nconst ToggleAboveNodes: RenderNodeWrapperFunction = ({ children, element }) => {\n const isVisible = useIsVisible(element.id as string);\n\n if (isVisible) return children;\n\n return <div style={hiddenStyle}>{children}</div>;\n};\n\nconst hiddenStyle: React.CSSProperties = {\n height: 0,\n margin: 0,\n overflow: 'hidden',\n visibility: 'hidden',\n};\n","import { useEffect } from 'react';\n\nimport type { UseHooks } from 'platejs/react';\n\nimport type { ToggleConfig } from './TogglePlugin';\n\nimport { useToggleIndex } from './toggleIndexAtom';\n\nexport const useHooksToggle: UseHooks<ToggleConfig> = ({\n editor,\n setOption,\n}) => {\n const toggleIndex = useToggleIndex();\n\n useEffect(() => {\n setOption('toggleIndex', toggleIndex);\n }, [editor, setOption, toggleIndex]);\n};\n","import type { TIndentElement } from 'platejs';\n\nimport { buildToggleIndex } from '../toggleIndexAtom';\n\nexport const findElementIdsHiddenInToggle = (\n openToggleIds: Set<string>,\n elements: TIndentElement[]\n): string[] => {\n const toggleIndex = buildToggleIndex(elements);\n\n return elements\n .filter((element) => {\n const enclosingToggleIds = toggleIndex.get(element.id as string) || [];\n\n return enclosingToggleIds.some(\n (toggleId) => !openToggleIds.has(toggleId)\n );\n })\n .map((element) => element.id as string);\n};\n","import type { SlateEditor } from 'platejs';\n\nimport { TogglePlugin } from '../TogglePlugin';\n\nexport function getEnclosingToggleIds(\n editor: SlateEditor,\n elementId: string\n): string[] {\n return editor.getOptions(TogglePlugin).toggleIndex?.get(elementId) || [];\n}\n","import type { NodeEntry, SlateEditor } from 'platejs';\n\nimport last from 'lodash/last.js';\n\nimport { buildToggleIndex } from '../toggleIndexAtom';\n\nexport const getLastEntryEnclosedInToggle = (\n editor: SlateEditor,\n toggleId: string\n): NodeEntry | undefined => {\n const toggleIndex = buildToggleIndex(editor.children);\n const entriesInToggle = editor.children\n .map((node, index) => [node, [index]] as NodeEntry)\n .filter(([node]) =>\n (toggleIndex.get(node.id as string) || []).includes(toggleId)\n );\n\n return last(entriesInToggle);\n};\n","import { type SlateEditor, getEditorPlugin } from 'platejs';\n\nimport { TogglePlugin } from '../TogglePlugin';\nimport { getEnclosingToggleIds } from './getEnclosingToggleIds';\n\nexport const isInClosedToggle = (editor: SlateEditor, elementId: string) => {\n const enclosingToggleIds = getEnclosingToggleIds(editor, elementId);\n\n return getEditorPlugin(editor, TogglePlugin).getOption(\n 'someClosed',\n enclosingToggleIds\n );\n};\n","import { type SlateEditor, ElementApi } from 'platejs';\n\nimport { isInClosedToggle } from '../queries';\n\n// Return false only if the all previous blocks are not selectable\nexport const moveCurrentBlockAfterPreviousSelectable = (\n editor: SlateEditor\n): boolean | undefined => {\n const { selection } = editor;\n\n if (!selection) return;\n\n const aboveBlock = editor.api.block();\n\n if (!aboveBlock) return;\n if (!editor.api.isAt({ start: true })) return;\n\n const beforePoint = editor.api.before(selection);\n\n if (!beforePoint) return;\n\n const blockBefore = editor.api.block({ at: beforePoint });\n\n if (!blockBefore) return;\n if (!isInClosedToggle(editor, blockBefore[0].id as string)) return; // We're already after a selectable then\n\n const previousSelectableBlock = editor.api.previous({\n match: (node) =>\n ElementApi.isElement(node) &&\n !isInClosedToggle(editor, node.id as string),\n });\n\n if (!previousSelectableBlock) return false;\n\n const afterSelectableBlock = [previousSelectableBlock[1][0] + 1];\n editor.tf.moveNodes({\n at: aboveBlock[1],\n to: afterSelectableBlock,\n });\n};\n","import { type SlateEditor, ElementApi } from 'platejs';\n\nimport { isInClosedToggle } from '../queries';\n\n// Return false only if all next blocks are not selectable\nexport const moveNextSelectableAfterCurrentBlock = (editor: SlateEditor) => {\n const { selection } = editor;\n\n if (!selection) return;\n\n const aboveBlock = editor.api.block();\n\n if (!aboveBlock) return;\n if (!editor.api.isAt({ end: true })) return;\n\n const afterPoint = editor.api.after(selection);\n\n if (!afterPoint) return;\n\n const blockAfter = editor.api.block({ at: afterPoint });\n\n if (!blockAfter) return;\n if (!isInClosedToggle(editor, blockAfter[0].id as string)) return; // We're already before a selectable then\n\n const nextSelectableBlock = editor.api.next({\n match: (node) =>\n ElementApi.isElement(node) &&\n !isInClosedToggle(editor, node.id as string),\n });\n\n if (!nextSelectableBlock) return false;\n\n const afterCurrentBlock = [aboveBlock[1][0] + 1];\n editor.tf.moveNodes({\n at: nextSelectableBlock[1],\n to: afterCurrentBlock,\n });\n};\n","import type { SlateEditor } from 'platejs';\n\nimport { TogglePlugin } from '../TogglePlugin';\n\n// When creating a toggle, we open it by default.\n// So before inserting the toggle, we update the store to mark the id of the blocks about to be turned into toggles as open.\nexport const openNextToggles = (editor: SlateEditor) => {\n const nodeEntries = Array.from(\n editor.api.nodes({\n block: true,\n mode: 'lowest',\n })\n );\n\n editor.getApi(TogglePlugin).toggle.toggleIds(\n nodeEntries.map(([node]) => node.id as string),\n true\n );\n};\n","import type { OverrideEditor } from 'platejs/react';\n\nimport { indent } from '@platejs/indent';\nimport { type SlateEditor, type TIndentElement, KEYS, NodeApi } from 'platejs';\n\nimport type { ToggleConfig } from './TogglePlugin';\n\nimport { getLastEntryEnclosedInToggle, isInClosedToggle } from './queries';\nimport {\n moveCurrentBlockAfterPreviousSelectable,\n moveNextSelectableAfterCurrentBlock,\n} from './transforms';\n\nexport const withToggle: OverrideEditor<ToggleConfig> = ({\n api: { isSelectable },\n editor,\n getOption,\n tf: { deleteBackward, deleteForward, insertBreak },\n}) => ({\n api: {\n isSelectable(element) {\n if (\n NodeApi.isNode(element) &&\n isInClosedToggle(editor, element.id as string)\n )\n return false;\n\n return isSelectable(element);\n },\n },\n transforms: {\n deleteBackward(unit) {\n if (\n moveCurrentBlockAfterPreviousSelectable(editor as SlateEditor) === false\n )\n return;\n\n deleteBackward(unit);\n },\n\n deleteForward(unit) {\n if (moveNextSelectableAfterCurrentBlock(editor as SlateEditor) === false)\n return;\n\n deleteForward(unit);\n },\n\n insertBreak() {\n const currentBlockEntry = editor.api.block<TIndentElement>();\n\n if (!currentBlockEntry || currentBlockEntry[0].type !== KEYS.toggle) {\n return insertBreak();\n }\n\n const toggleId = currentBlockEntry[0].id as string;\n const isOpen = getOption('isOpen', toggleId);\n\n editor.tf.withoutNormalizing(() => {\n if (isOpen) {\n insertBreak();\n editor.tf.toggleBlock(KEYS.toggle);\n indent(editor);\n } else {\n const lastEntryEnclosedInToggle = getLastEntryEnclosedInToggle(\n editor,\n toggleId\n );\n\n insertBreak();\n\n if (lastEntryEnclosedInToggle) {\n const newlyInsertedTogglePath = [currentBlockEntry[1][0] + 1];\n const afterLastEntryEncloseInToggle = [\n lastEntryEnclosedInToggle[1][0] + 1,\n ];\n editor.tf.moveNodes({\n at: newlyInsertedTogglePath,\n to: afterLastEntryEncloseInToggle,\n });\n }\n }\n });\n },\n },\n});\n","import type { ExtendConfig } from 'platejs';\n\nimport { toTPlatePlugin } from 'platejs/react';\n\nimport type { buildToggleIndex } from './toggleIndexAtom';\n\nimport {\n type BaseToggleConfig,\n BaseTogglePlugin,\n} from '../lib/BaseTogglePlugin';\nimport { renderToggleAboveNodes } from './renderToggleAboveNodes';\nimport { useHooksToggle } from './useHooksToggle';\nimport { withToggle } from './withToggle';\n\nexport type ToggleConfig = ExtendConfig<\n BaseToggleConfig,\n {\n toggleIndex?: ReturnType<typeof buildToggleIndex>;\n }\n>;\n\n/** Enables support for toggleable elements in the editor. */\nexport const TogglePlugin = toTPlatePlugin<ToggleConfig>(BaseTogglePlugin, {\n options: {\n toggleIndex: new Map(),\n },\n render: {\n aboveNodes: renderToggleAboveNodes,\n },\n useHooks: useHooksToggle as any,\n}).overrideEditor(withToggle);\n","import { useEditorPlugin, usePluginOption } from 'platejs/react';\n\nimport { BaseTogglePlugin } from '../../lib';\n\nexport const useToggleButtonState = (toggleId: string) => {\n const openIds = usePluginOption(BaseTogglePlugin, 'openIds')!;\n\n return {\n open: openIds.has(toggleId),\n toggleId,\n };\n};\n\nexport const useToggleButton = (\n state: ReturnType<typeof useToggleButtonState>\n) => {\n const { api } = useEditorPlugin(BaseTogglePlugin);\n\n return {\n ...state,\n buttonProps: {\n onClick: (e: React.MouseEvent) => {\n e.preventDefault();\n api.toggle.toggleIds([state.toggleId]);\n },\n onMouseDown: (e: React.MouseEvent) => {\n e.preventDefault();\n },\n },\n };\n};\n","import { KEYS } from 'platejs';\nimport { useEditorRef, useEditorSelector } from 'platejs/react';\n\nimport { someToggle } from '../../lib';\nimport { openNextToggles } from '../transforms';\n\nexport const useToggleToolbarButtonState = () => {\n const pressed = useEditorSelector((editor) => someToggle(editor), []);\n\n return {\n pressed,\n };\n};\n\nexport const useToggleToolbarButton = ({\n pressed,\n}: ReturnType<typeof useToggleToolbarButtonState>) => {\n const editor = useEditorRef();\n\n return {\n props: {\n pressed,\n onClick: () => {\n openNextToggles(editor);\n editor.tf.toggleBlock(KEYS.toggle);\n editor.tf.collapse();\n editor.tf.focus();\n },\n onMouseDown: (e: React.MouseEvent<HTMLButtonElement>) => {\n e.preventDefault();\n },\n },\n };\n};\n"],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { KEYS, createTSlatePlugin } from "platejs";
2
+
3
+ //#region src/lib/BaseTogglePlugin.ts
4
+ const BaseTogglePlugin = createTSlatePlugin({
5
+ key: KEYS.toggle,
6
+ node: { isElement: true },
7
+ options: { openIds: /* @__PURE__ */ new Set() }
8
+ }).extendSelectors(({ getOptions }) => ({
9
+ isOpen: (toggleId) => getOptions().openIds.has(toggleId),
10
+ someClosed: (toggleIds) => {
11
+ const { openIds } = getOptions();
12
+ return toggleIds.some((id) => !openIds.has(id));
13
+ }
14
+ })).extendApi(({ setOptions }) => ({ toggleIds: (ids, force = null) => {
15
+ setOptions((draft) => {
16
+ ids.forEach((id) => {
17
+ const isCurrentlyOpen = draft.openIds.has(id);
18
+ if (force === null ? !isCurrentlyOpen : force) draft.openIds.add(id);
19
+ else draft.openIds.delete(id);
20
+ });
21
+ });
22
+ } }));
23
+
24
+ //#endregion
25
+ //#region src/lib/queries/someToggle.ts
26
+ const someToggle = (editor) => !!editor.selection && editor.api.some({ match: (n) => n.type === KEYS.toggle });
27
+
28
+ //#endregion
29
+ export { BaseTogglePlugin as n, someToggle as t };
30
+ //# sourceMappingURL=someToggle-BUWI6X7B.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"someToggle-BUWI6X7B.js","names":["PluginConfig","createTSlatePlugin","KEYS","BaseToggleConfig","openIds","Set","toggle","toggleIds","ids","force","isOpen","toggleId","someClosed","BaseTogglePlugin","key","node","isElement","options","extendSelectors","getOptions","has","some","id","extendApi","setOptions","draft","forEach","isCurrentlyOpen","newIsOpen","add","delete","SlateEditor","KEYS","someToggle","editor","selection","api","some","match","n","type","toggle"],"sources":["../src/lib/BaseTogglePlugin.ts","../src/lib/queries/someToggle.ts"],"sourcesContent":["import { type PluginConfig, createTSlatePlugin, KEYS } from 'platejs';\n\nexport type BaseToggleConfig = PluginConfig<\n 'toggle',\n {\n openIds?: Set<string>;\n },\n {\n toggle: {\n toggleIds: (ids: string[], force?: boolean | null) => void;\n };\n },\n {},\n {\n isOpen?: (toggleId: string) => boolean;\n someClosed?: (toggleIds: string[]) => boolean;\n }\n>;\n\nexport const BaseTogglePlugin = createTSlatePlugin<BaseToggleConfig>({\n key: KEYS.toggle,\n node: { isElement: true },\n options: {\n openIds: new Set(),\n },\n})\n .extendSelectors<BaseToggleConfig['selectors']>(({ getOptions }) => ({\n isOpen: (toggleId) => getOptions().openIds!.has(toggleId),\n someClosed: (toggleIds) => {\n const { openIds } = getOptions();\n\n return toggleIds.some((id) => !openIds!.has(id));\n },\n }))\n .extendApi<BaseToggleConfig['api']['toggle']>(({ setOptions }) => ({\n toggleIds: (ids, force = null) => {\n setOptions((draft) => {\n ids.forEach((id) => {\n const isCurrentlyOpen = draft.openIds!.has(id);\n const newIsOpen = force === null ? !isCurrentlyOpen : force;\n\n if (newIsOpen) {\n draft.openIds!.add(id);\n } else {\n draft.openIds!.delete(id);\n }\n });\n });\n },\n }));\n","import { type SlateEditor, KEYS } from 'platejs';\n\nexport const someToggle = (editor: SlateEditor) =>\n !!editor.selection &&\n editor.api.some({\n match: (n) => n.type === KEYS.toggle,\n });\n"],"mappings":";;;AAmBA,MAAaa,mBAAmBZ,mBAAqC;CACnEa,KAAKZ,KAAKI;CACVS,MAAM,EAAEC,WAAW,MAAM;CACzBC,SAAS,EACPb,yBAAS,IAAIC,KAAI,EACnB;CACD,CAAC,CACCa,iBAAgD,EAAEC,kBAAkB;CACnET,SAASC,aAAaQ,YAAY,CAACf,QAASgB,IAAIT,SAAS;CACzDC,aAAaL,cAAc;EACzB,MAAM,EAAEH,YAAYe,YAAY;AAEhC,SAAOZ,UAAUc,MAAMC,OAAO,CAAClB,QAASgB,IAAIE,GAAG,CAAC;;CAEnD,EAAE,CACFC,WAA8C,EAAEC,kBAAkB,EACjEjB,YAAYC,KAAKC,QAAQ,SAAS;AAChCe,aAAYC,UAAU;AACpBjB,MAAIkB,SAASJ,OAAO;GAClB,MAAMK,kBAAkBF,MAAMrB,QAASgB,IAAIE,GAAG;AAG9C,OAFkBb,UAAU,OAAO,CAACkB,kBAAkBlB,MAGpDgB,OAAMrB,QAASyB,IAAIP,GAAG;OAEtBG,OAAMrB,QAAS0B,OAAOR,GAAG;IAE3B;GACF;GAEL,EAAE;;;;AC/CL,MAAaW,cAAcC,WACzB,CAAC,CAACA,OAAOC,aACTD,OAAOE,IAAIC,KAAK,EACdC,QAAQC,MAAMA,EAAEC,SAASR,KAAKS,QAC/B,CAAC"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@lofcz/platejs-toggle",
3
+ "version": "52.0.11",
4
+ "description": "Toggle plugin for Plate",
5
+ "keywords": [
6
+ "plate",
7
+ "plugin",
8
+ "slate"
9
+ ],
10
+ "homepage": "https://platejs.org",
11
+ "bugs": {
12
+ "url": "https://github.com/udecode/plate/issues"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/lofcz/plate.git",
17
+ "directory": "packages/toggle"
18
+ },
19
+ "license": "MIT",
20
+ "sideEffects": false,
21
+ "exports": {
22
+ ".": "./dist/index.js",
23
+ "./react": "./dist/react/index.js",
24
+ "./package.json": "./package.json"
25
+ },
26
+ "main": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "files": [
29
+ "dist/**/*"
30
+ ],
31
+ "dependencies": {
32
+ "jotai": "^2.18.0",
33
+ "lodash": "^4.17.21",
34
+ "react-compiler-runtime": "^1.0.0",
35
+ "@platejs/indent": "npm:@lofcz/platejs-indent@52.0.11"
36
+ },
37
+ "devDependencies": {
38
+ "@plate/scripts": "1.0.0"
39
+ },
40
+ "peerDependencies": {
41
+ "platejs": ">=52.0.11",
42
+ "react": ">=18.0.0",
43
+ "react-dom": ">=18.0.0"
44
+ },
45
+ "publishConfig": {
46
+ "access": "public"
47
+ },
48
+ "type": "module",
49
+ "module": "./dist/index.js",
50
+ "scripts": {
51
+ "brl": "plate-pkg p:brl",
52
+ "build": "plate-pkg p:build",
53
+ "build:watch": "plate-pkg p:build:watch",
54
+ "clean": "plate-pkg p:clean",
55
+ "lint": "plate-pkg p:lint",
56
+ "lint:fix": "plate-pkg p:lint:fix",
57
+ "test": "plate-pkg p:test",
58
+ "test:watch": "plate-pkg p:test:watch",
59
+ "typecheck": "plate-pkg p:typecheck"
60
+ }
61
+ }