@lofcz/platejs-caption 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 +24 -0
- package/README.md +5 -0
- package/dist/BaseCaptionPlugin-jZ8QfZJZ.js +70 -0
- package/dist/BaseCaptionPlugin-jZ8QfZJZ.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/react/index.d.ts +87 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +339 -0
- package/dist/react/index.js.map +1 -0
- package/package.json +58 -0
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,70 @@
|
|
|
1
|
+
import { KEYS, NodeApi, RangeApi, createTSlatePlugin, getPluginTypes, isHotkey } from "platejs";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/withCaption.ts
|
|
4
|
+
/** TODO: tests https://github.com/udecode/editor-protocol/issues/79 */
|
|
5
|
+
/**
|
|
6
|
+
* Selection table:
|
|
7
|
+
*
|
|
8
|
+
* - If anchor is in table, focus in a block before: set focus to start of table
|
|
9
|
+
* - If anchor is in table, focus in a block after: set focus to end of table
|
|
10
|
+
* - If focus is in table, anchor in a block before: set focus to end of table
|
|
11
|
+
* - If focus is in table, anchor in a block after: set focus to the point before
|
|
12
|
+
* start of table
|
|
13
|
+
*/
|
|
14
|
+
const withCaption = ({ editor, getOptions, tf: { apply, moveLine } }) => {
|
|
15
|
+
return { transforms: {
|
|
16
|
+
apply(operation) {
|
|
17
|
+
const { query } = getOptions();
|
|
18
|
+
if (operation.type === "set_selection") {
|
|
19
|
+
const newSelection = {
|
|
20
|
+
...editor.selection,
|
|
21
|
+
...operation.newProperties
|
|
22
|
+
};
|
|
23
|
+
if (editor.dom.currentKeyboardEvent && isHotkey("up", editor.dom.currentKeyboardEvent) && newSelection && RangeApi.isCollapsed(newSelection)) {
|
|
24
|
+
const types = getPluginTypes(editor, query.allow);
|
|
25
|
+
const entry = editor.api.above({
|
|
26
|
+
at: newSelection,
|
|
27
|
+
match: { type: types }
|
|
28
|
+
});
|
|
29
|
+
if (entry) {
|
|
30
|
+
const [node] = entry;
|
|
31
|
+
if (node.caption && NodeApi.string({ children: node.caption }).length > 0) setTimeout(() => {
|
|
32
|
+
editor.setOption(BaseCaptionPlugin, "focusEndPath", entry[1]);
|
|
33
|
+
}, 0);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
apply(operation);
|
|
38
|
+
},
|
|
39
|
+
moveLine: (options) => {
|
|
40
|
+
const apply$1 = () => {
|
|
41
|
+
if (!options.reverse) {
|
|
42
|
+
const types = getPluginTypes(editor, getOptions().query.allow);
|
|
43
|
+
const entry = editor.api.block({ match: { type: types } });
|
|
44
|
+
if (!entry) return;
|
|
45
|
+
editor.setOption(BaseCaptionPlugin, "focusEndPath", entry[1]);
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
if (apply$1()) return true;
|
|
50
|
+
return moveLine(options);
|
|
51
|
+
}
|
|
52
|
+
} };
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/lib/BaseCaptionPlugin.ts
|
|
57
|
+
/** Enables support for caption. */
|
|
58
|
+
const BaseCaptionPlugin = createTSlatePlugin({
|
|
59
|
+
key: KEYS.caption,
|
|
60
|
+
options: {
|
|
61
|
+
focusEndPath: null,
|
|
62
|
+
focusStartPath: null,
|
|
63
|
+
query: { allow: [] },
|
|
64
|
+
visibleId: null
|
|
65
|
+
}
|
|
66
|
+
}).extendSelectors(({ getOptions }) => ({ isVisible: (elementId) => getOptions().visibleId === elementId })).overrideEditor(withCaption);
|
|
67
|
+
|
|
68
|
+
//#endregion
|
|
69
|
+
export { withCaption as n, BaseCaptionPlugin as t };
|
|
70
|
+
//# sourceMappingURL=BaseCaptionPlugin-jZ8QfZJZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseCaptionPlugin-jZ8QfZJZ.js","names":["OverrideEditor","TRange","getPluginTypes","isHotkey","NodeApi","RangeApi","CaptionConfig","BaseCaptionPlugin","withCaption","editor","getOptions","tf","apply","moveLine","transforms","operation","query","type","newSelection","selection","newProperties","dom","currentKeyboardEvent","isCollapsed","types","allow","entry","api","above","at","match","node","caption","string","children","length","setTimeout","setOption","options","reverse","block","Path","PluginConfig","createTSlatePlugin","KEYS","withCaption","CaptionConfig","focusEndPath","focusStartPath","query","allow","visibleId","isVisible","elementId","BaseCaptionPlugin","key","caption","options","extendSelectors","getOptions","overrideEditor"],"sources":["../src/lib/withCaption.ts","../src/lib/BaseCaptionPlugin.ts"],"sourcesContent":["import {\n type OverrideEditor,\n type TRange,\n getPluginTypes,\n isHotkey,\n NodeApi,\n RangeApi,\n} from 'platejs';\n\nimport { type CaptionConfig, BaseCaptionPlugin } from './BaseCaptionPlugin';\n\n/** TODO: tests https://github.com/udecode/editor-protocol/issues/79 */\n\n/**\n * Selection table:\n *\n * - If anchor is in table, focus in a block before: set focus to start of table\n * - If anchor is in table, focus in a block after: set focus to end of table\n * - If focus is in table, anchor in a block before: set focus to end of table\n * - If focus is in table, anchor in a block after: set focus to the point before\n * start of table\n */\nexport const withCaption: OverrideEditor<CaptionConfig> = ({\n editor,\n getOptions,\n tf: { apply, moveLine },\n}) => {\n return {\n transforms: {\n apply(operation) {\n const { query } = getOptions();\n\n if (operation.type === 'set_selection') {\n const newSelection = {\n ...editor.selection,\n ...operation.newProperties,\n } as TRange | null;\n\n if (\n editor.dom.currentKeyboardEvent &&\n isHotkey('up', editor.dom.currentKeyboardEvent) &&\n newSelection &&\n RangeApi.isCollapsed(newSelection)\n ) {\n const types = getPluginTypes(editor, query.allow);\n\n const entry = editor.api.above({\n at: newSelection,\n match: { type: types },\n });\n\n if (entry) {\n const [node] = entry;\n\n if (\n node.caption &&\n NodeApi.string({ children: node.caption } as any).length > 0\n ) {\n setTimeout(() => {\n editor.setOption(BaseCaptionPlugin, 'focusEndPath', entry[1]);\n }, 0);\n }\n }\n }\n }\n\n apply(operation);\n },\n moveLine: (options) => {\n const apply = () => {\n // focus caption from image on down arrow\n if (!options.reverse) {\n const types = getPluginTypes(editor, getOptions().query.allow);\n\n const entry = editor.api.block({\n match: { type: types },\n });\n\n if (!entry) return;\n\n editor.setOption(BaseCaptionPlugin, 'focusEndPath', entry[1]);\n\n return true;\n }\n };\n\n if (apply()) return true;\n\n return moveLine(options);\n },\n },\n };\n};\n","import {\n type Path,\n type PluginConfig,\n createTSlatePlugin,\n KEYS,\n} from 'platejs';\n\nimport { withCaption } from './withCaption';\n\nexport type CaptionConfig = PluginConfig<\n 'caption',\n {\n /** When defined, focus end of caption textarea with the same path. */\n focusEndPath: Path | null;\n /** When defined, focus start of caption textarea with the same path. */\n focusStartPath: Path | null;\n // isVisible?: (elementId: string) => boolean;\n query: {\n /** Plugin keys to enable caption. */\n allow: string[];\n };\n visibleId: string | null;\n },\n {},\n {},\n {\n isVisible?: (elementId: string) => boolean;\n }\n>;\n\n/** Enables support for caption. */\nexport const BaseCaptionPlugin = createTSlatePlugin<CaptionConfig>({\n key: KEYS.caption,\n options: {\n focusEndPath: null,\n focusStartPath: null,\n query: { allow: [] },\n visibleId: null,\n },\n})\n .extendSelectors<CaptionConfig['selectors']>(({ getOptions }) => ({\n isVisible: (elementId) => getOptions().visibleId === elementId,\n }))\n .overrideEditor(withCaption);\n"],"mappings":";;;;;;;;;;;;;AAsBA,MAAaQ,eAA8C,EACzDC,QACAC,YACAC,IAAI,EAAEC,OAAOC,iBACT;AACJ,QAAO,EACLC,YAAY;EACVF,MAAMG,WAAW;GACf,MAAM,EAAEC,UAAUN,YAAY;AAE9B,OAAIK,UAAUE,SAAS,iBAAiB;IACtC,MAAMC,eAAe;KACnB,GAAGT,OAAOU;KACV,GAAGJ,UAAUK;KACd;AAED,QACEX,OAAOY,IAAIC,wBACXnB,SAAS,MAAMM,OAAOY,IAAIC,qBAAqB,IAC/CJ,gBACAb,SAASkB,YAAYL,aAAa,EAClC;KACA,MAAMM,QAAQtB,eAAeO,QAAQO,MAAMS,MAAM;KAEjD,MAAMC,QAAQjB,OAAOkB,IAAIC,MAAM;MAC7BC,IAAIX;MACJY,OAAO,EAAEb,MAAMO,OAAM;MACtB,CAAC;AAEF,SAAIE,OAAO;MACT,MAAM,CAACK,QAAQL;AAEf,UACEK,KAAKC,WACL5B,QAAQ6B,OAAO,EAAEC,UAAUH,KAAKC,SAAS,CAAQ,CAACG,SAAS,EAE3DC,kBAAiB;AACf3B,cAAO4B,UAAU9B,mBAAmB,gBAAgBmB,MAAM,GAAG;SAC5D,EAAE;;;;AAMbd,SAAMG,UAAU;;EAElBF,WAAWyB,YAAY;GACrB,MAAM1B,gBAAc;AAElB,QAAI,CAAC0B,QAAQC,SAAS;KACpB,MAAMf,QAAQtB,eAAeO,QAAQC,YAAY,CAACM,MAAMS,MAAM;KAE9D,MAAMC,QAAQjB,OAAOkB,IAAIa,MAAM,EAC7BV,OAAO,EAAEb,MAAMO,OAAM,EACtB,CAAC;AAEF,SAAI,CAACE,MAAO;AAEZjB,YAAO4B,UAAU9B,mBAAmB,gBAAgBmB,MAAM,GAAG;AAE7D,YAAO;;;AAIX,OAAId,SAAO,CAAE,QAAO;AAEpB,UAAOC,SAASyB,QAAQ;;EAE5B,EACD;;;;;;AC5DH,MAAagB,oBAAoBX,mBAAkC;CACjEY,KAAKX,KAAKY;CACVC,SAAS;EACPV,cAAc;EACdC,gBAAgB;EAChBC,OAAO,EAAEC,OAAO,EAAA,EAAI;EACpBC,WAAW;EACb;CACD,CAAC,CACCO,iBAA6C,EAAEC,kBAAkB,EAChEP,YAAYC,cAAcM,YAAY,CAACR,cAAcE,WACtD,EAAE,CACFO,eAAef,YAAY"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { OverrideEditor, Path, PluginConfig } from "platejs";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/BaseCaptionPlugin.d.ts
|
|
4
|
+
type CaptionConfig = PluginConfig<'caption', {
|
|
5
|
+
/** When defined, focus end of caption textarea with the same path. */
|
|
6
|
+
focusEndPath: Path | null;
|
|
7
|
+
/** When defined, focus start of caption textarea with the same path. */
|
|
8
|
+
focusStartPath: Path | null;
|
|
9
|
+
query: {
|
|
10
|
+
/** Plugin keys to enable caption. */
|
|
11
|
+
allow: string[];
|
|
12
|
+
};
|
|
13
|
+
visibleId: string | null;
|
|
14
|
+
}, {}, {}, {
|
|
15
|
+
isVisible?: (elementId: string) => boolean;
|
|
16
|
+
}>;
|
|
17
|
+
/** Enables support for caption. */
|
|
18
|
+
declare const BaseCaptionPlugin: any;
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/lib/withCaption.d.ts
|
|
21
|
+
/** TODO: tests https://github.com/udecode/editor-protocol/issues/79 */
|
|
22
|
+
/**
|
|
23
|
+
* Selection table:
|
|
24
|
+
*
|
|
25
|
+
* - If anchor is in table, focus in a block before: set focus to start of table
|
|
26
|
+
* - If anchor is in table, focus in a block after: set focus to end of table
|
|
27
|
+
* - If focus is in table, anchor in a block before: set focus to end of table
|
|
28
|
+
* - If focus is in table, anchor in a block after: set focus to the point before
|
|
29
|
+
* start of table
|
|
30
|
+
*/
|
|
31
|
+
declare const withCaption: OverrideEditor<CaptionConfig>;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { BaseCaptionPlugin, CaptionConfig, withCaption };
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/lib/BaseCaptionPlugin.ts","../src/lib/withCaption.ts"],"sourcesContent":[],"mappings":";;;KASY,aAAA,GAAgB;;EAAhB,YAAA,EAIM,IAJO,GAAA,IAAA;EAIP;EAEE,cAAA,EAAA,IAAA,GAAA,IAAA;EANQ,KAAA,EAAA;IAAY;IAsB3B,KAAA,EAAA,MAAA,EAAA;;;;ECTA,SAAA,CAAA,EAAA,CAAA,SAsEZ,EAAA,MAtEwC,EAAA,GAAA,OAAf;;;cDSb;;;;AAtBb;;;;;AAsBA;;;;ACTa,cAAA,WAA4B,EAAf,cAAA,CAAe,aAAD,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { SlateEditor, TElement } from "platejs";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { TextareaAutosizeProps } from "react-textarea-autosize";
|
|
4
|
+
|
|
5
|
+
//#region src/react/CaptionPlugin.d.ts
|
|
6
|
+
declare const CaptionPlugin: any;
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/react/components/Caption.d.ts
|
|
9
|
+
type CaptionOptions = {
|
|
10
|
+
readOnly?: boolean;
|
|
11
|
+
};
|
|
12
|
+
interface CaptionProps extends React.ComponentPropsWithoutRef<'figcaption'> {
|
|
13
|
+
options?: CaptionOptions;
|
|
14
|
+
}
|
|
15
|
+
declare const useCaptionState: (options?: CaptionOptions) => {
|
|
16
|
+
captionString: any;
|
|
17
|
+
hidden: boolean;
|
|
18
|
+
readOnly: any;
|
|
19
|
+
selected: any;
|
|
20
|
+
};
|
|
21
|
+
declare const useCaption: (state: ReturnType<typeof useCaptionState>) => {
|
|
22
|
+
hidden: boolean;
|
|
23
|
+
};
|
|
24
|
+
declare const Caption: any;
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/react/components/CaptionButton.d.ts
|
|
27
|
+
declare const useCaptionButtonState: () => any;
|
|
28
|
+
declare const useCaptionButton: ({
|
|
29
|
+
editor,
|
|
30
|
+
element
|
|
31
|
+
}: ReturnType<typeof useCaptionButtonState>) => {
|
|
32
|
+
props: {
|
|
33
|
+
onClick: () => void;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/react/components/CaptionTextarea.d.ts
|
|
38
|
+
/** Focus textareaRef when focusCaptionPath is set to the image path. */
|
|
39
|
+
declare const useCaptionTextareaFocus: (textareaRef: React.RefObject<HTMLTextAreaElement | null>) => void;
|
|
40
|
+
declare const useCaptionTextareaState: () => {
|
|
41
|
+
captionValue: string | number | readonly string[] | undefined;
|
|
42
|
+
element: any;
|
|
43
|
+
readOnly: any;
|
|
44
|
+
textareaRef: React.RefObject<HTMLTextAreaElement | null>;
|
|
45
|
+
handleChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
46
|
+
handleCompositionEnd: (e: React.CompositionEvent<HTMLTextAreaElement>) => void;
|
|
47
|
+
handleCompositionStart: () => void;
|
|
48
|
+
};
|
|
49
|
+
declare const useCaptionTextarea: ({
|
|
50
|
+
captionValue,
|
|
51
|
+
element,
|
|
52
|
+
readOnly,
|
|
53
|
+
textareaRef,
|
|
54
|
+
handleChange,
|
|
55
|
+
handleCompositionEnd,
|
|
56
|
+
handleCompositionStart
|
|
57
|
+
}: ReturnType<typeof useCaptionTextareaState>) => {
|
|
58
|
+
props: {
|
|
59
|
+
readOnly: any;
|
|
60
|
+
value: string | number | readonly string[] | undefined;
|
|
61
|
+
onBlur: React.FocusEventHandler<HTMLTextAreaElement>;
|
|
62
|
+
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
63
|
+
onCompositionEnd: (e: React.CompositionEvent<HTMLTextAreaElement>) => void;
|
|
64
|
+
onCompositionStart: () => void;
|
|
65
|
+
onKeyDown: React.KeyboardEventHandler<HTMLTextAreaElement>;
|
|
66
|
+
};
|
|
67
|
+
ref: React.RefObject<HTMLTextAreaElement | null>;
|
|
68
|
+
};
|
|
69
|
+
declare const CaptionTextarea: any;
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/react/components/TextareaAutosize.d.ts
|
|
72
|
+
/**
|
|
73
|
+
* `<textarea />` component for React which grows with content.
|
|
74
|
+
*
|
|
75
|
+
* @see https://github.com/Andarist/react-textarea-autosize
|
|
76
|
+
* @see https://github.com/Andarist/react-textarea-autosize/issues/337
|
|
77
|
+
*/
|
|
78
|
+
declare const TextareaAutosize: React.ForwardRefExoticComponent<TextareaAutosizeProps & React.RefAttributes<HTMLTextAreaElement>>;
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region src/react/hooks/useCaptionString.d.ts
|
|
81
|
+
declare const useCaptionString: () => any;
|
|
82
|
+
//#endregion
|
|
83
|
+
//#region src/react/utils/showCaption.d.ts
|
|
84
|
+
declare const showCaption: (editor: SlateEditor, element: TElement) => void;
|
|
85
|
+
//#endregion
|
|
86
|
+
export { Caption, CaptionOptions, CaptionPlugin, CaptionProps, CaptionTextarea, TextareaAutosize, showCaption, useCaption, useCaptionButton, useCaptionButtonState, useCaptionState, useCaptionString, useCaptionTextarea, useCaptionTextareaFocus, useCaptionTextareaState };
|
|
87
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/react/CaptionPlugin.tsx","../../src/react/components/Caption.tsx","../../src/react/components/CaptionButton.tsx","../../src/react/components/CaptionTextarea.tsx","../../src/react/components/TextareaAutosize.tsx","../../src/react/hooks/useCaptionString.ts","../../src/react/utils/showCaption.ts"],"sourcesContent":[],"mappings":";;;;;cAIa;;;KCSD,cAAA;;;UAIK,YAAA,SACP,KAAA,CAAM;EDdH,OAAA,CAAA,ECeD,cDfiD;;cCkBhD,4BAA4B;;EAT7B,MAAA,EAAA,OAAA;EAIK,QAAA,EAAA,GAAA;EAKJ,QAAA,EAAA,GAAA;AAwBb,CAAA;AAIa,cAJA,UASX,EAAA,CAAA,KAAA,EATgC,UAShC,CAAA,OATkD,eASlD,CAAA,EAAA,GAAA;;;cALW;;;cC9CA;cAOA;;;GAGV,kBAAkB;;;;AFVrB,CAAA;;;;cGmBa,uCACE,KAAA,CAAM,UAAU;cAmBlB;;EHvCA,OAAA,EAAA,GAAA;;;oBGiEL,KAAA,CAAM,YAAY;EFxDd,oBAAc,EAAA,CAAA,CAAA,EEwElB,KAAA,CAAM,gBFxEY,CEwEK,mBFxEL,CAAA,EAAA,GAAA,IAAA;EAIT,sBACf,EAAA,GACU,GAAA,IAAA;AAGZ,CAAA;AAwBa,cEiEA,kBFjEuC,EAAA,CAAA;EAAA,YAAlB;EAAU,OAAA;EAAA,QAAA;EAAA,WAAA;EAAA,YAAA;EAAA,oBAAA;EAAA;AAAA,CAAA,EEyEzC,UFzEyC,CAAA,OEyEvB,uBFzEuB,CAAA,EAAA,GAAA;EAI/B,KAAA,EAAA;;;;IC9CA,QAAA,EAAA,CAAA,CAAA,ECiEL,KAAA,CAAM,WD5Db,CC4DyB,mBD5DzB,CAAA,EAAA,GAAA,IAAA;IAEY,gBAeX,EAAA,CAAA,CAAA,EC2DM,KAAA,CAAM,gBD3DZ,CC2D6B,mBD3D7B,CAAA,EAAA,GAAA,IAAA;IAf+B,kBAAA,EAAA,GAAA,GAAA,IAAA;IAAA,SAAA,4BAAA,oBAAA,CAAA;EAGZ,CAAA;EAAlB,GAAA,iBAAA,oBAAA,GAAA,IAAA,CAAA;CAAU;cC6JA;;;;;;AHvKb;;;cISM,kBAAgB,KAAA,CAAA,0BAAA,wBAAA,KAAA,CAAA,cAAA;;;cCNT;;;cCHA,sBAAuB,sBAAsB"}
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { t as BaseCaptionPlugin } from "../BaseCaptionPlugin-jZ8QfZJZ.js";
|
|
2
|
+
import { NodeApi, PathApi, isHotkey } from "platejs";
|
|
3
|
+
import { createPrimitiveComponent, toPlatePlugin, useEditorRef, useElement, useIsomorphicLayoutEffect, usePluginOption, useReadOnly, useSelected } from "platejs/react";
|
|
4
|
+
import { c } from "react-compiler-runtime";
|
|
5
|
+
import React, { useState } from "react";
|
|
6
|
+
import ReactTextareaAutosize from "react-textarea-autosize";
|
|
7
|
+
|
|
8
|
+
//#region src/react/CaptionPlugin.tsx
|
|
9
|
+
const CaptionPlugin = toPlatePlugin(BaseCaptionPlugin);
|
|
10
|
+
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/react/hooks/useCaptionString.ts
|
|
13
|
+
const useCaptionString = () => {
|
|
14
|
+
const $ = c(4);
|
|
15
|
+
const { caption: t0 } = useElement();
|
|
16
|
+
let t1;
|
|
17
|
+
if ($[0] !== t0) {
|
|
18
|
+
t1 = t0 === void 0 ? [{ children: [{ text: "" }] }] : t0;
|
|
19
|
+
$[0] = t0;
|
|
20
|
+
$[1] = t1;
|
|
21
|
+
} else t1 = $[1];
|
|
22
|
+
const nodeCaption = t1;
|
|
23
|
+
let t2;
|
|
24
|
+
if ($[2] !== nodeCaption[0]) {
|
|
25
|
+
t2 = NodeApi.string(nodeCaption[0]) || "";
|
|
26
|
+
$[2] = nodeCaption[0];
|
|
27
|
+
$[3] = t2;
|
|
28
|
+
} else t2 = $[3];
|
|
29
|
+
return t2;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/react/components/Caption.tsx
|
|
34
|
+
const useCaptionState = (t0) => {
|
|
35
|
+
const $ = c(7);
|
|
36
|
+
let t1;
|
|
37
|
+
if ($[0] !== t0) {
|
|
38
|
+
t1 = t0 === void 0 ? {} : t0;
|
|
39
|
+
$[0] = t0;
|
|
40
|
+
$[1] = t1;
|
|
41
|
+
} else t1 = $[1];
|
|
42
|
+
const options = t1;
|
|
43
|
+
const element = useElement();
|
|
44
|
+
const captionString = useCaptionString();
|
|
45
|
+
const showCaption$1 = usePluginOption(CaptionPlugin, "isVisible", element.id);
|
|
46
|
+
const selected = useSelected();
|
|
47
|
+
const _readOnly = useReadOnly();
|
|
48
|
+
const readOnly = options.readOnly || _readOnly;
|
|
49
|
+
const hidden = !showCaption$1 && captionString.length === 0;
|
|
50
|
+
let t2;
|
|
51
|
+
if ($[2] !== captionString || $[3] !== hidden || $[4] !== readOnly || $[5] !== selected) {
|
|
52
|
+
t2 = {
|
|
53
|
+
captionString,
|
|
54
|
+
hidden,
|
|
55
|
+
readOnly,
|
|
56
|
+
selected
|
|
57
|
+
};
|
|
58
|
+
$[2] = captionString;
|
|
59
|
+
$[3] = hidden;
|
|
60
|
+
$[4] = readOnly;
|
|
61
|
+
$[5] = selected;
|
|
62
|
+
$[6] = t2;
|
|
63
|
+
} else t2 = $[6];
|
|
64
|
+
return t2;
|
|
65
|
+
};
|
|
66
|
+
const useCaption = (state) => ({ hidden: state.hidden });
|
|
67
|
+
const Caption = createPrimitiveComponent("figcaption")({
|
|
68
|
+
propsHook: useCaption,
|
|
69
|
+
stateHook: useCaptionState
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/react/components/CaptionButton.tsx
|
|
74
|
+
const useCaptionButtonState = () => {
|
|
75
|
+
const $ = c(3);
|
|
76
|
+
const editor = useEditorRef();
|
|
77
|
+
const element = useElement();
|
|
78
|
+
let t0;
|
|
79
|
+
if ($[0] !== editor || $[1] !== element) {
|
|
80
|
+
t0 = {
|
|
81
|
+
editor,
|
|
82
|
+
element
|
|
83
|
+
};
|
|
84
|
+
$[0] = editor;
|
|
85
|
+
$[1] = element;
|
|
86
|
+
$[2] = t0;
|
|
87
|
+
} else t0 = $[2];
|
|
88
|
+
return t0;
|
|
89
|
+
};
|
|
90
|
+
const useCaptionButton = ({ editor, element }) => ({ props: { onClick: () => {
|
|
91
|
+
const path = editor.api.findPath(element);
|
|
92
|
+
editor.setOption(BaseCaptionPlugin, "visibleId", element.id);
|
|
93
|
+
setTimeout(() => {
|
|
94
|
+
if (path) editor.setOption(BaseCaptionPlugin, "focusEndPath", path);
|
|
95
|
+
}, 0);
|
|
96
|
+
} } });
|
|
97
|
+
|
|
98
|
+
//#endregion
|
|
99
|
+
//#region src/react/components/TextareaAutosize.tsx
|
|
100
|
+
/**
|
|
101
|
+
* `<textarea />` component for React which grows with content.
|
|
102
|
+
*
|
|
103
|
+
* @see https://github.com/Andarist/react-textarea-autosize
|
|
104
|
+
* @see https://github.com/Andarist/react-textarea-autosize/issues/337
|
|
105
|
+
*/
|
|
106
|
+
const TextareaAutosize = React.forwardRef((props, ref) => {
|
|
107
|
+
const $ = c(6);
|
|
108
|
+
const [isRerendered, setIsRerendered] = React.useState(false);
|
|
109
|
+
let t0;
|
|
110
|
+
let t1;
|
|
111
|
+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
112
|
+
t0 = () => setIsRerendered(true);
|
|
113
|
+
t1 = [];
|
|
114
|
+
$[0] = t0;
|
|
115
|
+
$[1] = t1;
|
|
116
|
+
} else {
|
|
117
|
+
t0 = $[0];
|
|
118
|
+
t1 = $[1];
|
|
119
|
+
}
|
|
120
|
+
useIsomorphicLayoutEffect(t0, t1);
|
|
121
|
+
let t2;
|
|
122
|
+
if ($[2] !== isRerendered || $[3] !== props || $[4] !== ref) {
|
|
123
|
+
t2 = isRerendered ? /* @__PURE__ */ React.createElement(ReactTextareaAutosize, {
|
|
124
|
+
...props,
|
|
125
|
+
ref
|
|
126
|
+
}) : null;
|
|
127
|
+
$[2] = isRerendered;
|
|
128
|
+
$[3] = props;
|
|
129
|
+
$[4] = ref;
|
|
130
|
+
$[5] = t2;
|
|
131
|
+
} else t2 = $[5];
|
|
132
|
+
return t2;
|
|
133
|
+
});
|
|
134
|
+
TextareaAutosize.displayName = "TextareaAutosize";
|
|
135
|
+
|
|
136
|
+
//#endregion
|
|
137
|
+
//#region src/react/components/CaptionTextarea.tsx
|
|
138
|
+
/** Focus textareaRef when focusCaptionPath is set to the image path. */
|
|
139
|
+
const useCaptionTextareaFocus = (textareaRef) => {
|
|
140
|
+
const $ = c(6);
|
|
141
|
+
const editor = useEditorRef();
|
|
142
|
+
const element = useElement();
|
|
143
|
+
const focusCaptionPath = usePluginOption(CaptionPlugin, "focusEndPath");
|
|
144
|
+
let t0;
|
|
145
|
+
let t1;
|
|
146
|
+
if ($[0] !== editor || $[1] !== element || $[2] !== focusCaptionPath || $[3] !== textareaRef) {
|
|
147
|
+
t0 = () => {
|
|
148
|
+
if (focusCaptionPath && textareaRef.current) {
|
|
149
|
+
const path = editor.api.findPath(element);
|
|
150
|
+
if (path && PathApi.equals(path, focusCaptionPath)) {
|
|
151
|
+
textareaRef.current.focus();
|
|
152
|
+
editor.setOption(CaptionPlugin, "focusEndPath", null);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
t1 = [
|
|
157
|
+
editor,
|
|
158
|
+
element,
|
|
159
|
+
focusCaptionPath,
|
|
160
|
+
textareaRef
|
|
161
|
+
];
|
|
162
|
+
$[0] = editor;
|
|
163
|
+
$[1] = element;
|
|
164
|
+
$[2] = focusCaptionPath;
|
|
165
|
+
$[3] = textareaRef;
|
|
166
|
+
$[4] = t0;
|
|
167
|
+
$[5] = t1;
|
|
168
|
+
} else {
|
|
169
|
+
t0 = $[4];
|
|
170
|
+
t1 = $[5];
|
|
171
|
+
}
|
|
172
|
+
React.useEffect(t0, t1);
|
|
173
|
+
};
|
|
174
|
+
const useCaptionTextareaState = () => {
|
|
175
|
+
const $ = c(17);
|
|
176
|
+
const element = useElement();
|
|
177
|
+
const editor = useEditorRef();
|
|
178
|
+
const [isComposing, setIsComposing] = useState(false);
|
|
179
|
+
let t0;
|
|
180
|
+
if ($[0] !== element.caption) {
|
|
181
|
+
t0 = () => {
|
|
182
|
+
const nodeCaption = element.caption ?? [{ children: [{ text: "" }] }];
|
|
183
|
+
return NodeApi.string(nodeCaption[0]);
|
|
184
|
+
};
|
|
185
|
+
$[0] = element.caption;
|
|
186
|
+
$[1] = t0;
|
|
187
|
+
} else t0 = $[1];
|
|
188
|
+
const [captionValue, setCaptionValue] = useState(t0);
|
|
189
|
+
let t1;
|
|
190
|
+
if ($[2] !== editor || $[3] !== element) {
|
|
191
|
+
t1 = (newValue) => {
|
|
192
|
+
editor.tf.setNodes({ caption: [{ text: newValue }] }, { at: element });
|
|
193
|
+
};
|
|
194
|
+
$[2] = editor;
|
|
195
|
+
$[3] = element;
|
|
196
|
+
$[4] = t1;
|
|
197
|
+
} else t1 = $[4];
|
|
198
|
+
const updateEditorCaptionValue = t1;
|
|
199
|
+
let t2;
|
|
200
|
+
if ($[5] !== isComposing || $[6] !== updateEditorCaptionValue) {
|
|
201
|
+
t2 = (e) => {
|
|
202
|
+
const newValue_0 = e.target.value;
|
|
203
|
+
setCaptionValue(newValue_0);
|
|
204
|
+
if (!isComposing) updateEditorCaptionValue(newValue_0);
|
|
205
|
+
};
|
|
206
|
+
$[5] = isComposing;
|
|
207
|
+
$[6] = updateEditorCaptionValue;
|
|
208
|
+
$[7] = t2;
|
|
209
|
+
} else t2 = $[7];
|
|
210
|
+
const handleChange = t2;
|
|
211
|
+
let t3;
|
|
212
|
+
if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
|
|
213
|
+
t3 = () => {
|
|
214
|
+
setIsComposing(true);
|
|
215
|
+
};
|
|
216
|
+
$[8] = t3;
|
|
217
|
+
} else t3 = $[8];
|
|
218
|
+
const handleCompositionStart = t3;
|
|
219
|
+
let t4;
|
|
220
|
+
if ($[9] !== updateEditorCaptionValue) {
|
|
221
|
+
t4 = (e_0) => {
|
|
222
|
+
setIsComposing(false);
|
|
223
|
+
const newValue_1 = e_0.currentTarget.value;
|
|
224
|
+
setCaptionValue(newValue_1);
|
|
225
|
+
updateEditorCaptionValue(newValue_1);
|
|
226
|
+
};
|
|
227
|
+
$[9] = updateEditorCaptionValue;
|
|
228
|
+
$[10] = t4;
|
|
229
|
+
} else t4 = $[10];
|
|
230
|
+
const handleCompositionEnd = t4;
|
|
231
|
+
const readOnly = useReadOnly();
|
|
232
|
+
const textareaRef = React.useRef(null);
|
|
233
|
+
useCaptionTextareaFocus(textareaRef);
|
|
234
|
+
let t5;
|
|
235
|
+
if ($[11] !== captionValue || $[12] !== element || $[13] !== handleChange || $[14] !== handleCompositionEnd || $[15] !== readOnly) {
|
|
236
|
+
t5 = {
|
|
237
|
+
captionValue,
|
|
238
|
+
element,
|
|
239
|
+
readOnly,
|
|
240
|
+
textareaRef,
|
|
241
|
+
handleChange,
|
|
242
|
+
handleCompositionEnd,
|
|
243
|
+
handleCompositionStart
|
|
244
|
+
};
|
|
245
|
+
$[11] = captionValue;
|
|
246
|
+
$[12] = element;
|
|
247
|
+
$[13] = handleChange;
|
|
248
|
+
$[14] = handleCompositionEnd;
|
|
249
|
+
$[15] = readOnly;
|
|
250
|
+
$[16] = t5;
|
|
251
|
+
} else t5 = $[16];
|
|
252
|
+
return t5;
|
|
253
|
+
};
|
|
254
|
+
const useCaptionTextarea = (t0) => {
|
|
255
|
+
const $ = c(16);
|
|
256
|
+
const { captionValue, element, readOnly, textareaRef, handleChange, handleCompositionEnd, handleCompositionStart } = t0;
|
|
257
|
+
const editor = useEditorRef();
|
|
258
|
+
let t1;
|
|
259
|
+
if ($[0] !== editor || $[1] !== element) {
|
|
260
|
+
t1 = (e) => {
|
|
261
|
+
if (isHotkey("up", e)) {
|
|
262
|
+
const path = editor.api.findPath(element);
|
|
263
|
+
if (!path) return;
|
|
264
|
+
e.preventDefault();
|
|
265
|
+
editor.tf.focus({ at: path });
|
|
266
|
+
}
|
|
267
|
+
if (isHotkey("down", e)) {
|
|
268
|
+
const path_0 = editor.api.findPath(element);
|
|
269
|
+
if (!path_0) return;
|
|
270
|
+
const nextNodePath = editor.api.after(path_0);
|
|
271
|
+
if (!nextNodePath) return;
|
|
272
|
+
e.preventDefault();
|
|
273
|
+
editor.tf.focus({ at: nextNodePath });
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
$[0] = editor;
|
|
277
|
+
$[1] = element;
|
|
278
|
+
$[2] = t1;
|
|
279
|
+
} else t1 = $[2];
|
|
280
|
+
const onKeyDown = t1;
|
|
281
|
+
let t2;
|
|
282
|
+
if ($[3] !== editor) {
|
|
283
|
+
t2 = (e_0) => {
|
|
284
|
+
if (e_0.target.value.length === 0) editor.setOption(CaptionPlugin, "visibleId", null);
|
|
285
|
+
};
|
|
286
|
+
$[3] = editor;
|
|
287
|
+
$[4] = t2;
|
|
288
|
+
} else t2 = $[4];
|
|
289
|
+
const onBlur = t2;
|
|
290
|
+
let t3;
|
|
291
|
+
if ($[5] !== captionValue || $[6] !== handleChange || $[7] !== handleCompositionEnd || $[8] !== handleCompositionStart || $[9] !== onBlur || $[10] !== onKeyDown || $[11] !== readOnly) {
|
|
292
|
+
t3 = {
|
|
293
|
+
readOnly,
|
|
294
|
+
value: captionValue,
|
|
295
|
+
onBlur,
|
|
296
|
+
onChange: handleChange,
|
|
297
|
+
onCompositionEnd: handleCompositionEnd,
|
|
298
|
+
onCompositionStart: handleCompositionStart,
|
|
299
|
+
onKeyDown
|
|
300
|
+
};
|
|
301
|
+
$[5] = captionValue;
|
|
302
|
+
$[6] = handleChange;
|
|
303
|
+
$[7] = handleCompositionEnd;
|
|
304
|
+
$[8] = handleCompositionStart;
|
|
305
|
+
$[9] = onBlur;
|
|
306
|
+
$[10] = onKeyDown;
|
|
307
|
+
$[11] = readOnly;
|
|
308
|
+
$[12] = t3;
|
|
309
|
+
} else t3 = $[12];
|
|
310
|
+
let t4;
|
|
311
|
+
if ($[13] !== t3 || $[14] !== textareaRef) {
|
|
312
|
+
t4 = {
|
|
313
|
+
props: t3,
|
|
314
|
+
ref: textareaRef
|
|
315
|
+
};
|
|
316
|
+
$[13] = t3;
|
|
317
|
+
$[14] = textareaRef;
|
|
318
|
+
$[15] = t4;
|
|
319
|
+
} else t4 = $[15];
|
|
320
|
+
return t4;
|
|
321
|
+
};
|
|
322
|
+
const CaptionTextarea = createPrimitiveComponent(TextareaAutosize)({
|
|
323
|
+
propsHook: useCaptionTextarea,
|
|
324
|
+
stateHook: useCaptionTextareaState
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
//#endregion
|
|
328
|
+
//#region src/react/utils/showCaption.ts
|
|
329
|
+
const showCaption = (editor, element) => {
|
|
330
|
+
const path = editor.api.findPath(element);
|
|
331
|
+
editor.setOption(CaptionPlugin, "visibleId", element.id);
|
|
332
|
+
setTimeout(() => {
|
|
333
|
+
if (path) editor.setOption(CaptionPlugin, "focusEndPath", path);
|
|
334
|
+
}, 0);
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
//#endregion
|
|
338
|
+
export { Caption, CaptionPlugin, CaptionTextarea, TextareaAutosize, showCaption, useCaption, useCaptionButton, useCaptionButtonState, useCaptionState, useCaptionString, useCaptionTextarea, useCaptionTextareaFocus, useCaptionTextareaState };
|
|
339
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["toPlatePlugin","BaseCaptionPlugin","CaptionPlugin","React","TCaptionElement","NodeApi","useElement","useCaptionString","$","_c","caption","t0","t1","undefined","children","text","nodeCaption","t2","string","React","createPrimitiveComponent","useElement","usePluginOption","useReadOnly","useSelected","CaptionPlugin","useCaptionString","CaptionOptions","readOnly","CaptionProps","ComponentPropsWithoutRef","options","useCaptionState","t0","$","_c","t1","undefined","element","captionString","showCaption","id","selected","_readOnly","hidden","length","t2","useCaption","state","ReturnType","Caption","propsHook","stateHook","useEditorRef","useElement","BaseCaptionPlugin","useCaptionButtonState","$","_c","editor","element","t0","useCaptionButton","ReturnType","props","onClick","path","api","findPath","setOption","id","setTimeout","React","ReactTextareaAutosize","TextareaAutosizeProps","useIsomorphicLayoutEffect","TextareaAutosize","forwardRef","HTMLTextAreaElement","props","ref","$","_c","isRerendered","setIsRerendered","useState","t0","t1","Symbol","for","t2","displayName","React","useCallback","useState","TextareaAutosizeProps","TCaptionElement","TElement","isHotkey","NodeApi","PathApi","createPrimitiveComponent","useEditorRef","useElement","usePluginOption","useReadOnly","CaptionPlugin","TextareaAutosize","useCaptionTextareaFocus","textareaRef","$","_c","editor","element","focusCaptionPath","t0","t1","current","path","api","findPath","equals","focus","setOption","useEffect","useCaptionTextareaState","isComposing","setIsComposing","caption","nodeCaption","children","text","string","captionValue","setCaptionValue","newValue","tf","setNodes","at","updateEditorCaptionValue","t2","e","newValue_0","target","value","handleChange","t3","Symbol","for","handleCompositionStart","t4","e_0","newValue_1","currentTarget","handleCompositionEnd","readOnly","useRef","t5","useCaptionTextarea","preventDefault","path_0","nextNodePath","after","onKeyDown","currentValue","length","onBlur","onChange","onCompositionEnd","onCompositionStart","props","ref","CaptionTextarea","propsHook","stateHook","SlateEditor","TElement","CaptionPlugin","showCaption","editor","element","path","api","findPath","setOption","id","setTimeout"],"sources":["../../src/react/CaptionPlugin.tsx","../../src/react/hooks/useCaptionString.ts","../../src/react/components/Caption.tsx","../../src/react/components/CaptionButton.tsx","../../src/react/components/TextareaAutosize.tsx","../../src/react/components/CaptionTextarea.tsx","../../src/react/utils/showCaption.ts"],"sourcesContent":["import { toPlatePlugin } from 'platejs/react';\n\nimport { BaseCaptionPlugin } from '../lib/BaseCaptionPlugin';\n\nexport const CaptionPlugin = toPlatePlugin(BaseCaptionPlugin);\n","import React from 'react';\n\nimport type { TCaptionElement } from 'platejs';\n\nimport { NodeApi } from 'platejs';\nimport { useElement } from 'platejs/react';\n\nexport const useCaptionString = () => {\n const { caption: nodeCaption = [{ children: [{ text: '' }] }] } =\n useElement<TCaptionElement>();\n\n return React.useMemo(\n () => NodeApi.string(nodeCaption[0] as any) || '',\n [nodeCaption]\n );\n};\n","import type React from 'react';\n\nimport {\n createPrimitiveComponent,\n useElement,\n usePluginOption,\n useReadOnly,\n useSelected,\n} from 'platejs/react';\n\nimport { CaptionPlugin } from '../CaptionPlugin';\nimport { useCaptionString } from '../hooks/useCaptionString';\n\nexport type CaptionOptions = {\n readOnly?: boolean;\n};\n\nexport interface CaptionProps\n extends React.ComponentPropsWithoutRef<'figcaption'> {\n options?: CaptionOptions;\n}\n\nexport const useCaptionState = (options: CaptionOptions = {}) => {\n const element = useElement();\n const captionString = useCaptionString();\n\n const showCaption = usePluginOption(\n CaptionPlugin,\n 'isVisible',\n element.id as string\n );\n\n const selected = useSelected();\n const _readOnly = useReadOnly();\n const readOnly = options.readOnly || _readOnly;\n\n const hidden = !showCaption && captionString.length === 0;\n\n return {\n captionString,\n hidden,\n readOnly,\n selected,\n };\n};\n\nexport const useCaption = (state: ReturnType<typeof useCaptionState>) => ({\n hidden: state.hidden,\n});\n\nexport const Caption = createPrimitiveComponent<'figcaption', CaptionProps>(\n 'figcaption'\n)({\n propsHook: useCaption,\n stateHook: useCaptionState,\n});\n","import { useEditorRef, useElement } from 'platejs/react';\n\nimport { BaseCaptionPlugin } from '../../lib';\n\nexport const useCaptionButtonState = (): any => {\n const editor = useEditorRef();\n const element = useElement();\n\n return { editor, element };\n};\n\nexport const useCaptionButton = ({\n editor,\n element,\n}: ReturnType<typeof useCaptionButtonState>) => ({\n props: {\n onClick: () => {\n const path = editor.api.findPath(element);\n editor.setOption(BaseCaptionPlugin, 'visibleId', element.id as string);\n setTimeout(() => {\n if (path) {\n editor.setOption(BaseCaptionPlugin, 'focusEndPath', path);\n }\n }, 0);\n },\n },\n});\n","import React from 'react';\nimport ReactTextareaAutosize, {\n type TextareaAutosizeProps,\n} from 'react-textarea-autosize';\n\nimport { useIsomorphicLayoutEffect } from 'platejs/react';\n\n/**\n * `<textarea />` component for React which grows with content.\n *\n * @see https://github.com/Andarist/react-textarea-autosize\n * @see https://github.com/Andarist/react-textarea-autosize/issues/337\n */\nconst TextareaAutosize = React.forwardRef<\n HTMLTextAreaElement,\n TextareaAutosizeProps\n>((props, ref) => {\n const [isRerendered, setIsRerendered] = React.useState(false);\n\n useIsomorphicLayoutEffect(() => setIsRerendered(true), []);\n\n return isRerendered ? <ReactTextareaAutosize {...props} ref={ref} /> : null;\n});\nTextareaAutosize.displayName = 'TextareaAutosize';\n\nexport { TextareaAutosize };\n","import React, { useCallback, useState } from 'react';\n\nimport type { TextareaAutosizeProps } from 'react-textarea-autosize';\n\nimport {\n type TCaptionElement,\n type TElement,\n isHotkey,\n NodeApi,\n PathApi,\n} from 'platejs';\nimport {\n createPrimitiveComponent,\n useEditorRef,\n useElement,\n usePluginOption,\n useReadOnly,\n} from 'platejs/react';\n\nimport { CaptionPlugin } from '../CaptionPlugin';\nimport { TextareaAutosize } from './TextareaAutosize';\n\n/** Focus textareaRef when focusCaptionPath is set to the image path. */\nexport const useCaptionTextareaFocus = (\n textareaRef: React.RefObject<HTMLTextAreaElement | null>\n) => {\n const editor = useEditorRef();\n const element = useElement<TCaptionElement>();\n\n const focusCaptionPath = usePluginOption(CaptionPlugin, 'focusEndPath');\n\n React.useEffect(() => {\n if (focusCaptionPath && textareaRef.current) {\n const path = editor.api.findPath(element);\n\n if (path && PathApi.equals(path, focusCaptionPath)) {\n textareaRef.current.focus();\n editor.setOption(CaptionPlugin, 'focusEndPath', null);\n }\n }\n }, [editor, element, focusCaptionPath, textareaRef]);\n};\n\nexport const useCaptionTextareaState = () => {\n const element = useElement<TCaptionElement>();\n const editor = useEditorRef();\n\n const [isComposing, setIsComposing] = useState(false);\n\n const [captionValue, setCaptionValue] = useState<\n TextareaAutosizeProps['value']\n >(() => {\n const nodeCaption =\n element.caption ?? ([{ children: [{ text: '' }] }] as [TElement]);\n\n return NodeApi.string(nodeCaption[0]);\n });\n\n const updateEditorCaptionValue = useCallback(\n (newValue: string) => {\n editor.tf.setNodes<TCaptionElement>(\n { caption: [{ text: newValue }] },\n { at: element }\n );\n },\n [editor, element]\n );\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const newValue = e.target.value;\n setCaptionValue(newValue);\n\n if (!isComposing) {\n updateEditorCaptionValue(newValue);\n }\n },\n [isComposing, updateEditorCaptionValue]\n );\n\n const handleCompositionStart = useCallback(() => {\n setIsComposing(true);\n }, []);\n\n const handleCompositionEnd = useCallback(\n (e: React.CompositionEvent<HTMLTextAreaElement>) => {\n setIsComposing(false);\n const newValue = e.currentTarget.value;\n setCaptionValue(newValue);\n updateEditorCaptionValue(newValue);\n },\n [updateEditorCaptionValue]\n );\n\n const readOnly = useReadOnly();\n\n const textareaRef = React.useRef<HTMLTextAreaElement>(null);\n\n useCaptionTextareaFocus(textareaRef);\n\n return {\n captionValue,\n element,\n readOnly,\n textareaRef,\n handleChange,\n handleCompositionEnd,\n handleCompositionStart,\n };\n};\n\nexport const useCaptionTextarea = ({\n captionValue,\n element,\n readOnly,\n textareaRef,\n handleChange,\n handleCompositionEnd,\n handleCompositionStart,\n}: ReturnType<typeof useCaptionTextareaState>) => {\n const editor = useEditorRef();\n\n const onKeyDown: TextareaAutosizeProps['onKeyDown'] = (e) => {\n // select image\n if (isHotkey('up', e)) {\n const path = editor.api.findPath(element);\n\n if (!path) return;\n\n e.preventDefault();\n\n editor.tf.focus({ at: path });\n }\n // select next block\n if (isHotkey('down', e)) {\n const path = editor.api.findPath(element);\n\n if (!path) return;\n\n const nextNodePath = editor.api.after(path);\n\n if (!nextNodePath) return;\n\n e.preventDefault();\n\n editor.tf.focus({ at: nextNodePath });\n }\n };\n\n const onBlur: TextareaAutosizeProps['onBlur'] = (e) => {\n const currentValue = e.target.value;\n\n if (currentValue.length === 0) {\n editor.setOption(CaptionPlugin, 'visibleId', null);\n }\n };\n\n return {\n props: {\n readOnly,\n value: captionValue,\n onBlur,\n onChange: handleChange,\n onCompositionEnd: handleCompositionEnd,\n onCompositionStart: handleCompositionStart,\n onKeyDown,\n },\n ref: textareaRef,\n };\n};\n\nexport const CaptionTextarea = createPrimitiveComponent(TextareaAutosize)({\n propsHook: useCaptionTextarea,\n stateHook: useCaptionTextareaState,\n});\n","import type { SlateEditor, TElement } from 'platejs';\n\nimport { CaptionPlugin } from '../CaptionPlugin';\n\nexport const showCaption = (editor: SlateEditor, element: TElement) => {\n const path = editor.api.findPath(element);\n editor.setOption(CaptionPlugin, 'visibleId', element.id as string);\n\n setTimeout(() => {\n if (path) {\n editor.setOption(CaptionPlugin, 'focusEndPath', path);\n }\n }, 0);\n};\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lofcz/platejs-caption",
|
|
3
|
+
"version": "52.0.11",
|
|
4
|
+
"description": "Primitive components for caption.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"plate",
|
|
7
|
+
"caption"
|
|
8
|
+
],
|
|
9
|
+
"homepage": "https://platejs.org",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/udecode/plate/issues"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/lofcz/plate.git",
|
|
16
|
+
"directory": "packages/caption"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"sideEffects": false,
|
|
20
|
+
"exports": {
|
|
21
|
+
".": "./dist/index.js",
|
|
22
|
+
"./react": "./dist/react/index.js",
|
|
23
|
+
"./package.json": "./package.json"
|
|
24
|
+
},
|
|
25
|
+
"main": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"files": [
|
|
28
|
+
"dist/**/*"
|
|
29
|
+
],
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"react-compiler-runtime": "^1.0.0",
|
|
32
|
+
"react-textarea-autosize": "^8.5.9"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@plate/scripts": "1.0.0"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"platejs": ">=52.0.11",
|
|
39
|
+
"react": ">=18.0.0",
|
|
40
|
+
"react-dom": ">=18.0.0"
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
45
|
+
"type": "module",
|
|
46
|
+
"module": "./dist/index.js",
|
|
47
|
+
"scripts": {
|
|
48
|
+
"brl": "plate-pkg p:brl",
|
|
49
|
+
"build": "plate-pkg p:build",
|
|
50
|
+
"build:watch": "plate-pkg p:build:watch",
|
|
51
|
+
"clean": "plate-pkg p:clean",
|
|
52
|
+
"lint": "plate-pkg p:lint",
|
|
53
|
+
"lint:fix": "plate-pkg p:lint:fix",
|
|
54
|
+
"test": "plate-pkg p:test",
|
|
55
|
+
"test:watch": "plate-pkg p:test:watch",
|
|
56
|
+
"typecheck": "plate-pkg p:typecheck"
|
|
57
|
+
}
|
|
58
|
+
}
|