@webiny/lexical-editor 6.4.0-beta.2 → 6.4.0-beta.4
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/components/Toolbar/StaticToolbar.css +0 -14
- package/components/ToolbarActions/FontSizeAction.d.ts +2 -0
- package/components/ToolbarActions/FontSizeAction.js +71 -0
- package/components/ToolbarActions/FontSizeAction.js.map +1 -0
- package/context/RichTextEditorContext.js +8 -1
- package/context/RichTextEditorContext.js.map +1 -1
- package/exports/admin/ui/lexical.d.ts +15 -0
- package/exports/admin/ui/lexical.js +5 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +11 -10
- package/plugins/FloatingLinkEditorPlugin/FloatingLinkEditor.js +1 -1
- package/plugins/FloatingLinkEditorPlugin/FloatingLinkEditor.js.map +1 -1
- package/ui/DropDown.d.ts +4 -9
- package/ui/DropDown.js +18 -129
- package/ui/DropDown.js.map +1 -1
- package/utils/setFloatingElemPosition.js +23 -18
- package/utils/setFloatingElemPosition.js.map +1 -1
- package/exports/admin/lexical.d.ts +0 -15
- package/exports/admin/lexical.js +0 -5
|
@@ -241,12 +241,6 @@
|
|
|
241
241
|
margin: 0 4px;
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
-
.lexical-dropdown-container {
|
|
245
|
-
position: absolute;
|
|
246
|
-
bottom: -5px;
|
|
247
|
-
left: 0;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
244
|
.static-toolbar button.item i {
|
|
251
245
|
opacity: 0.6;
|
|
252
246
|
}
|
|
@@ -357,16 +351,8 @@ i.font-color,
|
|
|
357
351
|
margin: 0 4px;
|
|
358
352
|
}
|
|
359
353
|
|
|
360
|
-
.lexical-dropdown-container {
|
|
361
|
-
position: absolute;
|
|
362
|
-
bottom: -5px;
|
|
363
|
-
left: 0;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
354
|
.lexical-dropdown {
|
|
367
|
-
z-index: 10;
|
|
368
355
|
display: block;
|
|
369
|
-
position: fixed;
|
|
370
356
|
box-shadow:
|
|
371
357
|
0 12px 28px 0 rgba(0, 0, 0, 0.2),
|
|
372
358
|
0 2px 4px 0 rgba(0, 0, 0, 0.1),
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import react, { useCallback, useMemo } from "react";
|
|
2
|
+
import { $getSelection, $isRangeSelection } from "lexical";
|
|
3
|
+
import { $getSelectionStyleValueForProperty, $patchStyleText } from "@lexical/selection";
|
|
4
|
+
import { useDeriveValueFromSelection } from "../../hooks/useCurrentSelection.js";
|
|
5
|
+
import { useRichTextEditor } from "../../hooks/index.js";
|
|
6
|
+
import { DropDown, DropDownItem } from "../../ui/DropDown.js";
|
|
7
|
+
const FontSizeDropdown = ({ sizes })=>{
|
|
8
|
+
const { editor } = useRichTextEditor();
|
|
9
|
+
const fontSizeOptions = useMemo(()=>[
|
|
10
|
+
{
|
|
11
|
+
value: "inherit",
|
|
12
|
+
label: "Auto"
|
|
13
|
+
},
|
|
14
|
+
...sizes.map((size)=>({
|
|
15
|
+
value: size,
|
|
16
|
+
label: `${size}`
|
|
17
|
+
}))
|
|
18
|
+
], [
|
|
19
|
+
sizes
|
|
20
|
+
]);
|
|
21
|
+
const selectedFontSize = useDeriveValueFromSelection(({ rangeSelection })=>{
|
|
22
|
+
if (!rangeSelection) return "inherit";
|
|
23
|
+
return $getSelectionStyleValueForProperty(rangeSelection, "font-size", "inherit");
|
|
24
|
+
});
|
|
25
|
+
const onFontSizeSelect = useCallback((size)=>{
|
|
26
|
+
editor.update(()=>{
|
|
27
|
+
if (editor.isEditable()) {
|
|
28
|
+
const selection = $getSelection();
|
|
29
|
+
if (null === selection) return;
|
|
30
|
+
if ($isRangeSelection(selection) && selection.isCollapsed()) {
|
|
31
|
+
const anchor = selection.anchor.getNode();
|
|
32
|
+
const topElement = anchor.getTopLevelElementOrThrow();
|
|
33
|
+
topElement.select(0, topElement.getChildrenSize());
|
|
34
|
+
const expanded = $getSelection();
|
|
35
|
+
if (null !== expanded) $patchStyleText(expanded, {
|
|
36
|
+
"font-size": size
|
|
37
|
+
});
|
|
38
|
+
} else $patchStyleText(selection, {
|
|
39
|
+
"font-size": size
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}, [
|
|
44
|
+
editor
|
|
45
|
+
]);
|
|
46
|
+
const selectedOption = fontSizeOptions.find((option)=>option.value === selectedFontSize);
|
|
47
|
+
return /*#__PURE__*/ react.createElement(DropDown, {
|
|
48
|
+
buttonClassName: "toolbar-item typography-dropdown",
|
|
49
|
+
buttonAriaLabel: "Typography formatting options",
|
|
50
|
+
buttonLabel: selectedOption?.label || "Auto",
|
|
51
|
+
stopCloseOnClickSelf: true,
|
|
52
|
+
disabled: false,
|
|
53
|
+
showScroll: true
|
|
54
|
+
}, fontSizeOptions.map((option)=>/*#__PURE__*/ react.createElement(DropDownItem, {
|
|
55
|
+
className: `item typography-item ${selectedFontSize === option.value ? "active dropdown-item-active" : ""}`,
|
|
56
|
+
onClick: ()=>onFontSizeSelect(option.value),
|
|
57
|
+
key: option.value
|
|
58
|
+
}, /*#__PURE__*/ react.createElement("span", {
|
|
59
|
+
className: "text"
|
|
60
|
+
}, option.label))));
|
|
61
|
+
};
|
|
62
|
+
const FontSizeAction = ()=>{
|
|
63
|
+
const { theme } = useRichTextEditor();
|
|
64
|
+
if (!theme.fontSizes || 0 === theme.fontSizes.length) return null;
|
|
65
|
+
return /*#__PURE__*/ react.createElement(FontSizeDropdown, {
|
|
66
|
+
sizes: theme.fontSizes
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
export { FontSizeAction };
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=FontSizeAction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components/ToolbarActions/FontSizeAction.js","sources":["../../../src/components/ToolbarActions/FontSizeAction.tsx"],"sourcesContent":["import React, { useCallback, useMemo } from \"react\";\nimport { $getSelection, $isRangeSelection } from \"lexical\";\nimport { $patchStyleText } from \"@lexical/selection\";\nimport { $getSelectionStyleValueForProperty } from \"@lexical/selection\";\nimport { useDeriveValueFromSelection } from \"~/hooks/useCurrentSelection.js\";\nimport { useRichTextEditor } from \"~/hooks/index.js\";\nimport { DropDown } from \"~/ui/DropDown.js\";\nimport { DropDownItem } from \"~/ui/DropDown.js\";\n\ninterface FontSizeDropdownProps {\n sizes: string[];\n}\n\nconst FontSizeDropdown = ({ sizes }: FontSizeDropdownProps) => {\n const { editor } = useRichTextEditor();\n\n const fontSizeOptions = useMemo(() => {\n return [\n {\n value: \"inherit\",\n label: \"Auto\"\n },\n ...sizes.map(size => {\n return {\n value: size,\n label: `${size}`\n };\n })\n ];\n }, [sizes]);\n\n const selectedFontSize = useDeriveValueFromSelection(({ rangeSelection }) => {\n if (!rangeSelection) {\n return \"inherit\";\n }\n return $getSelectionStyleValueForProperty(rangeSelection, \"font-size\", \"inherit\");\n });\n\n const onFontSizeSelect = useCallback(\n (size: string) => {\n editor.update(() => {\n if (editor.isEditable()) {\n const selection = $getSelection();\n if (selection === null) {\n return;\n }\n\n if ($isRangeSelection(selection) && selection.isCollapsed()) {\n const anchor = selection.anchor.getNode();\n const topElement = anchor.getTopLevelElementOrThrow();\n topElement.select(0, topElement.getChildrenSize());\n const expanded = $getSelection();\n if (expanded !== null) {\n $patchStyleText(expanded, { \"font-size\": size });\n }\n } else {\n $patchStyleText(selection, { \"font-size\": size });\n }\n }\n });\n },\n [editor]\n );\n\n const selectedOption = fontSizeOptions.find(option => option.value === selectedFontSize);\n\n return (\n <DropDown\n buttonClassName=\"toolbar-item typography-dropdown\"\n buttonAriaLabel={\"Typography formatting options\"}\n buttonLabel={selectedOption?.label || \"Auto\"}\n stopCloseOnClickSelf={true}\n disabled={false}\n showScroll={true}\n >\n {fontSizeOptions.map(option => (\n <DropDownItem\n className={`item typography-item ${\n selectedFontSize === option.value ? \"active dropdown-item-active\" : \"\"\n }`}\n onClick={() => onFontSizeSelect(option.value)}\n key={option.value}\n >\n <span className=\"text\">{option.label}</span>\n </DropDownItem>\n ))}\n </DropDown>\n );\n};\n\nexport const FontSizeAction = () => {\n const { theme } = useRichTextEditor();\n\n if (!theme.fontSizes || theme.fontSizes.length === 0) {\n return null;\n }\n\n return <FontSizeDropdown sizes={theme.fontSizes} />;\n};\n"],"names":["FontSizeDropdown","sizes","editor","useRichTextEditor","fontSizeOptions","useMemo","size","selectedFontSize","useDeriveValueFromSelection","rangeSelection","$getSelectionStyleValueForProperty","onFontSizeSelect","useCallback","selection","$getSelection","$isRangeSelection","anchor","topElement","expanded","$patchStyleText","selectedOption","option","DropDown","DropDownItem","FontSizeAction","theme"],"mappings":";;;;;;AAaA,MAAMA,mBAAmB,CAAC,EAAEC,KAAK,EAAyB;IACtD,MAAM,EAAEC,MAAM,EAAE,GAAGC;IAEnB,MAAMC,kBAAkBC,QAAQ,IACrB;YACH;gBACI,OAAO;gBACP,OAAO;YACX;eACGJ,MAAM,GAAG,CAACK,CAAAA,OACF;oBACH,OAAOA;oBACP,OAAO,GAAGA,MAAM;gBACpB;SAEP,EACF;QAACL;KAAM;IAEV,MAAMM,mBAAmBC,4BAA4B,CAAC,EAAEC,cAAc,EAAE;QACpE,IAAI,CAACA,gBACD,OAAO;QAEX,OAAOC,mCAAmCD,gBAAgB,aAAa;IAC3E;IAEA,MAAME,mBAAmBC,YACrB,CAACN;QACGJ,OAAO,MAAM,CAAC;YACV,IAAIA,OAAO,UAAU,IAAI;gBACrB,MAAMW,YAAYC;gBAClB,IAAID,AAAc,SAAdA,WACA;gBAGJ,IAAIE,kBAAkBF,cAAcA,UAAU,WAAW,IAAI;oBACzD,MAAMG,SAASH,UAAU,MAAM,CAAC,OAAO;oBACvC,MAAMI,aAAaD,OAAO,yBAAyB;oBACnDC,WAAW,MAAM,CAAC,GAAGA,WAAW,eAAe;oBAC/C,MAAMC,WAAWJ;oBACjB,IAAII,AAAa,SAAbA,UACAC,gBAAgBD,UAAU;wBAAE,aAAaZ;oBAAK;gBAEtD,OACIa,gBAAgBN,WAAW;oBAAE,aAAaP;gBAAK;YAEvD;QACJ;IACJ,GACA;QAACJ;KAAO;IAGZ,MAAMkB,iBAAiBhB,gBAAgB,IAAI,CAACiB,CAAAA,SAAUA,OAAO,KAAK,KAAKd;IAEvE,OAAO,WAAP,GACI,oBAACe,UAAQA;QACL,iBAAgB;QAChB,iBAAiB;QACjB,aAAaF,gBAAgB,SAAS;QACtC,sBAAsB;QACtB,UAAU;QACV,YAAY;OAEXhB,gBAAgB,GAAG,CAACiB,CAAAA,SAAAA,WAAAA,GACjB,oBAACE,cAAYA;YACT,WAAW,CAAC,qBAAqB,EAC7BhB,qBAAqBc,OAAO,KAAK,GAAG,gCAAgC,IACtE;YACF,SAAS,IAAMV,iBAAiBU,OAAO,KAAK;YAC5C,KAAKA,OAAO,KAAK;yBAEjB,oBAAC;YAAK,WAAU;WAAQA,OAAO,KAAK;AAKxD;AAEO,MAAMG,iBAAiB;IAC1B,MAAM,EAAEC,KAAK,EAAE,GAAGtB;IAElB,IAAI,CAACsB,MAAM,SAAS,IAAIA,AAA2B,MAA3BA,MAAM,SAAS,CAAC,MAAM,EAC1C,OAAO;IAGX,OAAO,WAAP,GAAO,oBAACzB,kBAAgBA;QAAC,OAAOyB,MAAM,SAAS;;AACnD"}
|
|
@@ -7,6 +7,8 @@ const RichTextEditorProvider = ({ theme, toolbarActionPlugins = [], children })=
|
|
|
7
7
|
const getOverlaysElement = useCallback(()=>{
|
|
8
8
|
const rootElement = editor.getRootElement();
|
|
9
9
|
if (!rootElement) return document.body;
|
|
10
|
+
const dialogContent = rootElement.closest("[role='dialog']");
|
|
11
|
+
if (dialogContent) return dialogContent;
|
|
10
12
|
const shell = rootElement.closest(".editor-shell");
|
|
11
13
|
if (!shell) return document.body;
|
|
12
14
|
const overlays = shell.previousElementSibling;
|
|
@@ -14,7 +16,12 @@ const RichTextEditorProvider = ({ theme, toolbarActionPlugins = [], children })=
|
|
|
14
16
|
}, [
|
|
15
17
|
editor
|
|
16
18
|
]);
|
|
17
|
-
const internalTheme = useMemo(()=>new Theme(
|
|
19
|
+
const internalTheme = useMemo(()=>new Theme({
|
|
20
|
+
colors: theme.colors,
|
|
21
|
+
typography: theme.typography,
|
|
22
|
+
fontSizes: theme.fontSizes,
|
|
23
|
+
tokens: theme.tokens
|
|
24
|
+
}), [
|
|
18
25
|
theme
|
|
19
26
|
]);
|
|
20
27
|
return /*#__PURE__*/ react.createElement(RichTextEditorContext.Provider, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context/RichTextEditorContext.js","sources":["../../src/context/RichTextEditorContext.tsx"],"sourcesContent":["import React, { createContext, useCallback, useMemo } from \"react\";\nimport type { LexicalEditor } from \"lexical\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { type EditorTheme, Theme } from \"@webiny/lexical-theme\";\nimport type { ToolbarActionPlugin } from \"~/types.js\";\n\nexport interface RichTextEditorContext {\n editor: LexicalEditor;\n getOverlaysElement: () => HTMLElement;\n toolbarActionPlugins: ToolbarActionPlugin[];\n theme: Theme;\n}\n\nexport const RichTextEditorContext = createContext<RichTextEditorContext | undefined>(undefined);\n\ninterface RichTextEditorProviderProps {\n theme: EditorTheme;\n toolbarActionPlugins?: ToolbarActionPlugin[];\n children?: React.ReactNode | React.ReactNode[];\n}\n\nexport const RichTextEditorProvider = ({\n theme,\n toolbarActionPlugins = [],\n children\n}: RichTextEditorProviderProps) => {\n const [editor] = useLexicalComposerContext();\n\n const getOverlaysElement = useCallback(() => {\n const rootElement = editor.getRootElement();\n if (!rootElement) {\n return document.body;\n }\n\n const shell = rootElement.closest(\".editor-shell\");\n if (!shell) {\n return document.body;\n }\n const overlays = shell.previousElementSibling;\n\n return (overlays ?? document.body) as HTMLElement;\n }, [editor]);\n\n const internalTheme = useMemo(\n ()
|
|
1
|
+
{"version":3,"file":"context/RichTextEditorContext.js","sources":["../../src/context/RichTextEditorContext.tsx"],"sourcesContent":["import React, { createContext, useCallback, useMemo } from \"react\";\nimport type { LexicalEditor } from \"lexical\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { type EditorTheme, Theme } from \"@webiny/lexical-theme\";\nimport type { ToolbarActionPlugin } from \"~/types.js\";\n\nexport interface RichTextEditorContext {\n editor: LexicalEditor;\n getOverlaysElement: () => HTMLElement;\n toolbarActionPlugins: ToolbarActionPlugin[];\n theme: Theme;\n}\n\nexport const RichTextEditorContext = createContext<RichTextEditorContext | undefined>(undefined);\n\ninterface RichTextEditorProviderProps {\n theme: EditorTheme;\n toolbarActionPlugins?: ToolbarActionPlugin[];\n children?: React.ReactNode | React.ReactNode[];\n}\n\nexport const RichTextEditorProvider = ({\n theme,\n toolbarActionPlugins = [],\n children\n}: RichTextEditorProviderProps) => {\n const [editor] = useLexicalComposerContext();\n\n const getOverlaysElement = useCallback(() => {\n const rootElement = editor.getRootElement();\n if (!rootElement) {\n return document.body;\n }\n\n const dialogContent = rootElement.closest(\"[role='dialog']\");\n if (dialogContent) {\n return dialogContent as HTMLElement;\n }\n\n const shell = rootElement.closest(\".editor-shell\");\n if (!shell) {\n return document.body;\n }\n const overlays = shell.previousElementSibling;\n\n return (overlays ?? document.body) as HTMLElement;\n }, [editor]);\n\n const internalTheme = useMemo(\n () =>\n new Theme({\n colors: theme.colors,\n typography: theme.typography,\n fontSizes: theme.fontSizes,\n tokens: theme.tokens\n }),\n [theme]\n );\n\n return (\n <RichTextEditorContext.Provider\n value={{\n editor,\n getOverlaysElement,\n theme: internalTheme,\n toolbarActionPlugins\n }}\n >\n {children}\n </RichTextEditorContext.Provider>\n );\n};\n"],"names":["RichTextEditorContext","createContext","undefined","RichTextEditorProvider","theme","toolbarActionPlugins","children","editor","useLexicalComposerContext","getOverlaysElement","useCallback","rootElement","document","dialogContent","shell","overlays","internalTheme","useMemo","Theme"],"mappings":";;;AAaO,MAAMA,wBAAwB,WAAHA,GAAGC,cAAiDC;AAQ/E,MAAMC,yBAAyB,CAAC,EACnCC,KAAK,EACLC,uBAAuB,EAAE,EACzBC,QAAQ,EACkB;IAC1B,MAAM,CAACC,OAAO,GAAGC;IAEjB,MAAMC,qBAAqBC,YAAY;QACnC,MAAMC,cAAcJ,OAAO,cAAc;QACzC,IAAI,CAACI,aACD,OAAOC,SAAS,IAAI;QAGxB,MAAMC,gBAAgBF,YAAY,OAAO,CAAC;QAC1C,IAAIE,eACA,OAAOA;QAGX,MAAMC,QAAQH,YAAY,OAAO,CAAC;QAClC,IAAI,CAACG,OACD,OAAOF,SAAS,IAAI;QAExB,MAAMG,WAAWD,MAAM,sBAAsB;QAE7C,OAAQC,YAAYH,SAAS,IAAI;IACrC,GAAG;QAACL;KAAO;IAEX,MAAMS,gBAAgBC,QAClB,IACI,IAAIC,MAAM;YACN,QAAQd,MAAM,MAAM;YACpB,YAAYA,MAAM,UAAU;YAC5B,WAAWA,MAAM,SAAS;YAC1B,QAAQA,MAAM,MAAM;QACxB,IACJ;QAACA;KAAM;IAGX,OAAO,WAAP,GACI,oBAACJ,sBAAsB,QAAQ;QAC3B,OAAO;YACHO;YACAE;YACA,OAAOO;YACPX;QACJ;OAECC;AAGb"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { LexicalHtmlRenderer } from "../../../components/LexicalHtmlRenderer.js";
|
|
2
|
+
export { getNodeFromSelection } from "../../../hooks/index.js";
|
|
3
|
+
export { useCurrentElement } from "../../../hooks/index.js";
|
|
4
|
+
export { useCurrentSelection } from "../../../hooks/index.js";
|
|
5
|
+
export { useDeriveValueFromSelection } from "../../../hooks/index.js";
|
|
6
|
+
export { useRichTextEditor } from "../../../hooks/index.js";
|
|
7
|
+
export { useFontColorPicker } from "../../../hooks/index.js";
|
|
8
|
+
export { useTextAlignmentAction } from "../../../hooks/index.js";
|
|
9
|
+
export { useTypographyAction } from "../../../hooks/index.js";
|
|
10
|
+
export { useIsMounted } from "../../../hooks/index.js";
|
|
11
|
+
export { Divider } from "../../../ui/Divider.js";
|
|
12
|
+
export { DropDownItem } from "../../../ui/DropDown.js";
|
|
13
|
+
export { DropDown } from "../../../ui/DropDown.js";
|
|
14
|
+
export type { Klass, LexicalNode } from "../../../types.js";
|
|
15
|
+
export { LexicalEditorConfig, useLexicalEditorConfig } from "../../../components/LexicalEditorConfig/LexicalEditorConfig.js";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { LexicalHtmlRenderer } from "../../../components/LexicalHtmlRenderer.js";
|
|
2
|
+
export { getNodeFromSelection, useCurrentElement, useCurrentSelection, useDeriveValueFromSelection, useFontColorPicker, useIsMounted, useRichTextEditor, useTextAlignmentAction, useTypographyAction } from "../../../hooks/index.js";
|
|
3
|
+
export { Divider } from "../../../ui/Divider.js";
|
|
4
|
+
export { DropDown, DropDownItem } from "../../../ui/DropDown.js";
|
|
5
|
+
export { LexicalEditorConfig, useLexicalEditorConfig } from "../../../components/LexicalEditorConfig/LexicalEditorConfig.js";
|
package/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { BoldAction } from "./components/ToolbarActions/BoldAction.js";
|
|
|
7
7
|
export { BulletListAction } from "./components/ToolbarActions/BulletListAction.js";
|
|
8
8
|
export { CodeHighlightAction } from "./components/ToolbarActions/CodeHighlightAction.js";
|
|
9
9
|
export { FontColorAction } from "./components/ToolbarActions/FontColorAction.js";
|
|
10
|
+
export { FontSizeAction } from "./components/ToolbarActions/FontSizeAction.js";
|
|
10
11
|
export { ItalicAction } from "./components/ToolbarActions/ItalicAction.js";
|
|
11
12
|
export { LinkAction } from "./components/ToolbarActions/LinkAction.js";
|
|
12
13
|
export { NumberedListAction } from "./components/ToolbarActions/NumberedListAction.js";
|
package/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export { BoldAction } from "./components/ToolbarActions/BoldAction.js";
|
|
|
8
8
|
export { BulletListAction } from "./components/ToolbarActions/BulletListAction.js";
|
|
9
9
|
export { CodeHighlightAction } from "./components/ToolbarActions/CodeHighlightAction.js";
|
|
10
10
|
export { FontColorAction } from "./components/ToolbarActions/FontColorAction.js";
|
|
11
|
+
export { FontSizeAction } from "./components/ToolbarActions/FontSizeAction.js";
|
|
11
12
|
export { ItalicAction } from "./components/ToolbarActions/ItalicAction.js";
|
|
12
13
|
export { LinkAction } from "./components/ToolbarActions/LinkAction.js";
|
|
13
14
|
export { NumberedListAction } from "./components/ToolbarActions/NumberedListAction.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webiny/lexical-editor",
|
|
3
|
-
"version": "6.4.0-beta.
|
|
3
|
+
"version": "6.4.0-beta.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./index.js",
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
},
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@floating-ui/dom": "1.7.6",
|
|
16
15
|
"@lexical/code": "0.44.0",
|
|
17
16
|
"@lexical/history": "0.44.0",
|
|
18
17
|
"@lexical/react": "0.44.0",
|
|
@@ -20,21 +19,23 @@
|
|
|
20
19
|
"@lexical/selection": "0.44.0",
|
|
21
20
|
"@lexical/text": "0.44.0",
|
|
22
21
|
"@lexical/utils": "0.44.0",
|
|
23
|
-
"@webiny/lexical-nodes": "6.4.0-beta.
|
|
24
|
-
"@webiny/lexical-theme": "6.4.0-beta.
|
|
25
|
-
"@webiny/react-composition": "6.4.0-beta.
|
|
26
|
-
"@webiny/react-properties": "6.4.0-beta.
|
|
22
|
+
"@webiny/lexical-nodes": "6.4.0-beta.4",
|
|
23
|
+
"@webiny/lexical-theme": "6.4.0-beta.4",
|
|
24
|
+
"@webiny/react-composition": "6.4.0-beta.4",
|
|
25
|
+
"@webiny/react-properties": "6.4.0-beta.4",
|
|
27
26
|
"lexical": "0.44.0",
|
|
28
27
|
"lodash": "4.18.1",
|
|
28
|
+
"radix-ui": "1.4.3",
|
|
29
29
|
"react": "18.3.1",
|
|
30
30
|
"react-dom": "18.3.1"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@webiny/build-tools": "6.4.0-beta.
|
|
33
|
+
"@webiny/build-tools": "6.4.0-beta.4"
|
|
34
34
|
},
|
|
35
35
|
"publishConfig": {
|
|
36
|
-
"access": "public"
|
|
37
|
-
"directory": "dist"
|
|
36
|
+
"access": "public"
|
|
38
37
|
},
|
|
39
|
-
"
|
|
38
|
+
"webiny": {
|
|
39
|
+
"publishFrom": "dist"
|
|
40
|
+
}
|
|
40
41
|
}
|
|
@@ -7,7 +7,7 @@ function FloatingLinkEditor({ editor, isVisible, LinkForm }) {
|
|
|
7
7
|
className: "z-dialog absolute link-editor",
|
|
8
8
|
style: {
|
|
9
9
|
opacity: isVisible ? 1 : 0,
|
|
10
|
-
pointerEvents: isVisible ? "
|
|
10
|
+
pointerEvents: isVisible ? "all" : "none"
|
|
11
11
|
}
|
|
12
12
|
}, isVisible ? /*#__PURE__*/ react.createElement(LinkForm, {
|
|
13
13
|
linkData: linkData,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins/FloatingLinkEditorPlugin/FloatingLinkEditor.js","sources":["../../../src/plugins/FloatingLinkEditorPlugin/FloatingLinkEditor.tsx"],"sourcesContent":["import React from \"react\";\nimport type { LexicalEditor } from \"lexical\";\nimport { LinkFormProps } from \"./types.js\";\nimport { useFloatingLinkEditor } from \"./useFloatingLinkEditor.js\";\n\ninterface FloatingLinkEditorProps {\n editor: LexicalEditor;\n isVisible: boolean;\n LinkForm: React.FunctionComponent<LinkFormProps>;\n}\n\nexport function FloatingLinkEditor({ editor, isVisible, LinkForm }: FloatingLinkEditorProps) {\n const { editorRef, linkData, applyChanges, removeLink } = useFloatingLinkEditor(editor);\n\n return (\n <div\n ref={editorRef}\n className=\"z-dialog absolute link-editor\"\n style={{ opacity: isVisible ? 1 : 0, pointerEvents: isVisible ? \"
|
|
1
|
+
{"version":3,"file":"plugins/FloatingLinkEditorPlugin/FloatingLinkEditor.js","sources":["../../../src/plugins/FloatingLinkEditorPlugin/FloatingLinkEditor.tsx"],"sourcesContent":["import React from \"react\";\nimport type { LexicalEditor } from \"lexical\";\nimport { LinkFormProps } from \"./types.js\";\nimport { useFloatingLinkEditor } from \"./useFloatingLinkEditor.js\";\n\ninterface FloatingLinkEditorProps {\n editor: LexicalEditor;\n isVisible: boolean;\n LinkForm: React.FunctionComponent<LinkFormProps>;\n}\n\nexport function FloatingLinkEditor({ editor, isVisible, LinkForm }: FloatingLinkEditorProps) {\n const { editorRef, linkData, applyChanges, removeLink } = useFloatingLinkEditor(editor);\n\n return (\n <div\n ref={editorRef}\n className=\"z-dialog absolute link-editor\"\n style={{ opacity: isVisible ? 1 : 0, pointerEvents: isVisible ? \"all\" : \"none\" }}\n >\n {isVisible ? (\n <LinkForm linkData={linkData} onSave={applyChanges} removeLink={removeLink} />\n ) : null}\n </div>\n );\n}\n"],"names":["FloatingLinkEditor","editor","isVisible","LinkForm","editorRef","linkData","applyChanges","removeLink","useFloatingLinkEditor"],"mappings":";;AAWO,SAASA,mBAAmB,EAAEC,MAAM,EAAEC,SAAS,EAAEC,QAAQ,EAA2B;IACvF,MAAM,EAAEC,SAAS,EAAEC,QAAQ,EAAEC,YAAY,EAAEC,UAAU,EAAE,GAAGC,sBAAsBP;IAEhF,OAAO,WAAP,GACI,oBAAC;QACG,KAAKG;QACL,WAAU;QACV,OAAO;YAAE,SAASF,YAAY,IAAI;YAAG,eAAeA,YAAY,QAAQ;QAAO;OAE9EA,YAAY,WAAZA,GACG,oBAACC,UAAAA;QAAS,UAAUE;QAAU,QAAQC;QAAc,YAAYC;SAChE;AAGhB"}
|
package/ui/DropDown.d.ts
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*
|
|
7
|
-
*/
|
|
8
1
|
import type { ReactNode } from "react";
|
|
9
2
|
import * as React from "react";
|
|
10
3
|
export declare function DropDownItem({ children, className, onClick, title }: {
|
|
@@ -13,7 +6,7 @@ export declare function DropDownItem({ children, className, onClick, title }: {
|
|
|
13
6
|
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
14
7
|
title?: string;
|
|
15
8
|
}): React.JSX.Element;
|
|
16
|
-
|
|
9
|
+
interface DropDownProps {
|
|
17
10
|
disabled?: boolean;
|
|
18
11
|
buttonAriaLabel?: string;
|
|
19
12
|
buttonClassName: string;
|
|
@@ -22,4 +15,6 @@ export declare function DropDown({ disabled, buttonLabel, buttonAriaLabel, butto
|
|
|
22
15
|
children: ReactNode;
|
|
23
16
|
stopCloseOnClickSelf?: boolean;
|
|
24
17
|
showScroll?: boolean;
|
|
25
|
-
}
|
|
18
|
+
}
|
|
19
|
+
export declare function DropDown({ disabled, buttonLabel, buttonAriaLabel, buttonClassName, buttonIconClassName, children, showScroll }: DropDownProps): React.JSX.Element;
|
|
20
|
+
export {};
|
package/ui/DropDown.js
CHANGED
|
@@ -1,152 +1,41 @@
|
|
|
1
|
+
import { DropdownMenu } from "radix-ui";
|
|
1
2
|
import * as __rspack_external_react from "react";
|
|
2
|
-
const DropDownContext = /*#__PURE__*/ __rspack_external_react.createContext(null);
|
|
3
3
|
function DropDownItem({ children, className, onClick, title }) {
|
|
4
|
-
const ref = (0, __rspack_external_react.useRef)(null);
|
|
5
|
-
const dropDownContext = __rspack_external_react.useContext(DropDownContext);
|
|
6
|
-
if (null === dropDownContext) throw new Error("DropDownItem must be used within a DropDown");
|
|
7
|
-
const { registerItem } = dropDownContext;
|
|
8
|
-
(0, __rspack_external_react.useEffect)(()=>{
|
|
9
|
-
if (!ref.current) return;
|
|
10
|
-
registerItem(ref);
|
|
11
|
-
}, [
|
|
12
|
-
ref,
|
|
13
|
-
registerItem
|
|
14
|
-
]);
|
|
15
4
|
return /*#__PURE__*/ __rspack_external_react.createElement("button", {
|
|
16
5
|
className: className,
|
|
17
6
|
onClick: onClick,
|
|
18
|
-
ref: ref,
|
|
19
7
|
title: title,
|
|
20
8
|
type: "button"
|
|
21
9
|
}, children);
|
|
22
10
|
}
|
|
23
|
-
function
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
setItems((prev)=>prev ? [
|
|
28
|
-
...prev,
|
|
29
|
-
itemRef
|
|
30
|
-
] : [
|
|
31
|
-
itemRef
|
|
32
|
-
]);
|
|
33
|
-
}, [
|
|
34
|
-
setItems
|
|
35
|
-
]);
|
|
36
|
-
const handleKeyDown = (event)=>{
|
|
37
|
-
if (!items) return;
|
|
38
|
-
const key = event.key;
|
|
39
|
-
if ([
|
|
40
|
-
"Escape",
|
|
41
|
-
"ArrowUp",
|
|
42
|
-
"ArrowDown",
|
|
43
|
-
"Tab"
|
|
44
|
-
].includes(key)) event.preventDefault();
|
|
45
|
-
if ("Escape" === key || "Tab" === key) onClose();
|
|
46
|
-
else if ("ArrowUp" === key) setHighlightedItem((prev)=>{
|
|
47
|
-
if (!prev) return items[0];
|
|
48
|
-
const index = items.indexOf(prev) - 1;
|
|
49
|
-
return items[-1 === index ? items.length - 1 : index];
|
|
50
|
-
});
|
|
51
|
-
else if ("ArrowDown" === key) setHighlightedItem((prev)=>{
|
|
52
|
-
if (!prev) return items[0];
|
|
53
|
-
return items[items.indexOf(prev) + 1];
|
|
54
|
-
});
|
|
55
|
-
};
|
|
56
|
-
const contextValue = (0, __rspack_external_react.useMemo)(()=>({
|
|
57
|
-
registerItem
|
|
58
|
-
}), [
|
|
59
|
-
registerItem
|
|
60
|
-
]);
|
|
61
|
-
(0, __rspack_external_react.useEffect)(()=>{
|
|
62
|
-
if (items && !highlightedItem) setHighlightedItem(items[0]);
|
|
63
|
-
if (highlightedItem && highlightedItem.current) highlightedItem.current.focus();
|
|
64
|
-
}, [
|
|
65
|
-
items,
|
|
66
|
-
highlightedItem
|
|
67
|
-
]);
|
|
68
|
-
return /*#__PURE__*/ __rspack_external_react.createElement(DropDownContext.Provider, {
|
|
69
|
-
value: contextValue
|
|
70
|
-
}, /*#__PURE__*/ __rspack_external_react.createElement("div", {
|
|
71
|
-
className: `lexical-dropdown ${showScroll ? "" : "no-scroll"}`,
|
|
72
|
-
ref: dropDownRef,
|
|
73
|
-
onKeyDown: handleKeyDown
|
|
74
|
-
}, children));
|
|
75
|
-
}
|
|
76
|
-
function DropDown({ disabled = false, buttonLabel, buttonAriaLabel, buttonClassName, buttonIconClassName, children, stopCloseOnClickSelf, showScroll = true }) {
|
|
77
|
-
const dropDownRef = (0, __rspack_external_react.useRef)(null);
|
|
78
|
-
const buttonRef = (0, __rspack_external_react.useRef)(null);
|
|
79
|
-
const [positionIsCalculated, setPositionIsCalculated] = (0, __rspack_external_react.useState)(false);
|
|
80
|
-
const [showDropDown, setShowDropDown] = (0, __rspack_external_react.useState)(false);
|
|
81
|
-
const handleClose = ()=>{
|
|
82
|
-
setPositionIsCalculated(false);
|
|
83
|
-
setShowDropDown(false);
|
|
84
|
-
if (buttonRef && buttonRef.current) buttonRef.current.focus();
|
|
85
|
-
};
|
|
86
|
-
(0, __rspack_external_react.useEffect)(()=>{
|
|
87
|
-
const button = buttonRef.current;
|
|
88
|
-
const dropDown = dropDownRef.current;
|
|
89
|
-
if (showDropDown && button && dropDown) {
|
|
90
|
-
dropDown.style.top = "44px";
|
|
91
|
-
dropDown.style.left = `${button.offsetLeft}px`;
|
|
92
|
-
setPositionIsCalculated(true);
|
|
93
|
-
}
|
|
94
|
-
}, [
|
|
95
|
-
dropDownRef,
|
|
96
|
-
buttonRef,
|
|
97
|
-
showDropDown
|
|
98
|
-
]);
|
|
99
|
-
(0, __rspack_external_react.useEffect)(()=>{
|
|
100
|
-
const button = buttonRef.current;
|
|
101
|
-
if (button && showDropDown) {
|
|
102
|
-
const handle = (event)=>{
|
|
103
|
-
const target = event.target;
|
|
104
|
-
if (stopCloseOnClickSelf) {
|
|
105
|
-
if (dropDownRef.current && dropDownRef.current.contains(target)) return;
|
|
106
|
-
}
|
|
107
|
-
if (!button.contains(target)) setShowDropDown(false);
|
|
108
|
-
};
|
|
109
|
-
document.addEventListener("click", handle);
|
|
110
|
-
return ()=>{
|
|
111
|
-
document.removeEventListener("click", handle);
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
}, [
|
|
115
|
-
dropDownRef,
|
|
116
|
-
buttonRef,
|
|
117
|
-
showDropDown,
|
|
118
|
-
stopCloseOnClickSelf
|
|
119
|
-
]);
|
|
120
|
-
const displayContainer = (0, __rspack_external_react.useMemo)(()=>positionIsCalculated ? {
|
|
121
|
-
display: "block"
|
|
122
|
-
} : {
|
|
123
|
-
display: "none"
|
|
124
|
-
}, [
|
|
125
|
-
positionIsCalculated
|
|
126
|
-
]);
|
|
127
|
-
return /*#__PURE__*/ __rspack_external_react.createElement(__rspack_external_react.Fragment, null, /*#__PURE__*/ __rspack_external_react.createElement("button", {
|
|
11
|
+
function DropDown({ disabled = false, buttonLabel, buttonAriaLabel, buttonClassName, buttonIconClassName, children, showScroll = true }) {
|
|
12
|
+
return /*#__PURE__*/ __rspack_external_react.createElement(DropdownMenu.Root, null, /*#__PURE__*/ __rspack_external_react.createElement(DropdownMenu.Trigger, {
|
|
13
|
+
asChild: true
|
|
14
|
+
}, /*#__PURE__*/ __rspack_external_react.createElement("button", {
|
|
128
15
|
style: {
|
|
129
16
|
position: "relative"
|
|
130
17
|
},
|
|
131
18
|
disabled: disabled,
|
|
132
19
|
"aria-label": buttonAriaLabel || buttonLabel,
|
|
133
|
-
className: buttonClassName
|
|
134
|
-
onClick: ()=>setShowDropDown(!showDropDown),
|
|
135
|
-
ref: buttonRef
|
|
20
|
+
className: buttonClassName
|
|
136
21
|
}, buttonIconClassName && /*#__PURE__*/ __rspack_external_react.createElement("span", {
|
|
137
22
|
className: buttonIconClassName
|
|
138
23
|
}), buttonLabel && /*#__PURE__*/ __rspack_external_react.createElement("span", {
|
|
139
24
|
className: "text dropdown-button-text"
|
|
140
25
|
}, buttonLabel), /*#__PURE__*/ __rspack_external_react.createElement("i", {
|
|
141
26
|
className: "chevron-down"
|
|
142
|
-
})),
|
|
143
|
-
className:
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
27
|
+
}))), /*#__PURE__*/ __rspack_external_react.createElement(DropdownMenu.Portal, null, /*#__PURE__*/ __rspack_external_react.createElement(DropdownMenu.Content, {
|
|
28
|
+
className: `lexical-dropdown z-overlay ${showScroll ? "" : "no-scroll"}`,
|
|
29
|
+
sideOffset: 4,
|
|
30
|
+
collisionPadding: 8,
|
|
31
|
+
onCloseAutoFocus: (e)=>e.preventDefault()
|
|
32
|
+
}, /*#__PURE__*/ __rspack_external_react.createElement("div", {
|
|
33
|
+
className: showScroll ? "lexical-dropdown-scroll" : "",
|
|
34
|
+
style: showScroll ? {
|
|
35
|
+
maxHeight: 250,
|
|
36
|
+
overflowY: "auto"
|
|
37
|
+
} : void 0
|
|
38
|
+
}, children))));
|
|
150
39
|
}
|
|
151
40
|
export { DropDown, DropDownItem };
|
|
152
41
|
|
package/ui/DropDown.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui/DropDown.js","sources":["../../src/ui/DropDown.tsx"],"sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\nimport type { ReactNode, RefObject } from \"react\";\nimport * as React from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\ntype DropDownContextType = {\n registerItem: (ref: React.RefObject<HTMLButtonElement>) => void;\n};\n\nconst DropDownContext = React.createContext<DropDownContextType | null>(null);\n\nexport function DropDownItem({\n children,\n className,\n onClick,\n title\n}: {\n children: React.ReactNode;\n className: string;\n onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;\n title?: string;\n}) {\n const ref = useRef<HTMLButtonElement>(null);\n\n const dropDownContext = React.useContext(DropDownContext);\n\n if (dropDownContext === null) {\n throw new Error(\"DropDownItem must be used within a DropDown\");\n }\n\n const { registerItem } = dropDownContext;\n\n useEffect(() => {\n if (!ref.current) {\n return;\n }\n\n registerItem(ref as RefObject<HTMLButtonElement>);\n }, [ref, registerItem]);\n\n return (\n <button className={className} onClick={onClick} ref={ref} title={title} type=\"button\">\n {children}\n </button>\n );\n}\n\nfunction DropDownItems({\n children,\n dropDownRef,\n showScroll = true,\n onClose\n}: {\n children: React.ReactNode;\n dropDownRef?: React.Ref<HTMLDivElement>;\n showScroll?: boolean;\n onClose: () => void;\n}) {\n const [items, setItems] = useState<React.RefObject<HTMLButtonElement>[]>();\n const [highlightedItem, setHighlightedItem] = useState<React.RefObject<HTMLButtonElement>>();\n\n const registerItem = useCallback(\n (itemRef: React.RefObject<HTMLButtonElement>) => {\n setItems(prev => (prev ? [...prev, itemRef] : [itemRef]));\n },\n [setItems]\n );\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (!items) {\n return;\n }\n\n const key = event.key;\n\n if ([\"Escape\", \"ArrowUp\", \"ArrowDown\", \"Tab\"].includes(key)) {\n event.preventDefault();\n }\n\n if (key === \"Escape\" || key === \"Tab\") {\n onClose();\n } else if (key === \"ArrowUp\") {\n setHighlightedItem(prev => {\n if (!prev) {\n return items[0];\n }\n const index = items.indexOf(prev) - 1;\n return items[index === -1 ? items.length - 1 : index];\n });\n } else if (key === \"ArrowDown\") {\n setHighlightedItem(prev => {\n if (!prev) {\n return items[0];\n }\n return items[items.indexOf(prev) + 1];\n });\n }\n };\n\n const contextValue = useMemo(\n () => ({\n registerItem\n }),\n [registerItem]\n );\n\n useEffect(() => {\n if (items && !highlightedItem) {\n setHighlightedItem(items[0]);\n }\n\n if (highlightedItem && highlightedItem.current) {\n highlightedItem.current.focus();\n }\n }, [items, highlightedItem]);\n\n return (\n <DropDownContext.Provider value={contextValue}>\n <div\n className={`lexical-dropdown ${showScroll ? \"\" : \"no-scroll\"}`}\n ref={dropDownRef}\n onKeyDown={handleKeyDown}\n >\n {children}\n </div>\n </DropDownContext.Provider>\n );\n}\n\nexport function DropDown({\n disabled = false,\n buttonLabel,\n buttonAriaLabel,\n buttonClassName,\n buttonIconClassName,\n children,\n stopCloseOnClickSelf,\n showScroll = true\n}: {\n disabled?: boolean;\n buttonAriaLabel?: string;\n buttonClassName: string;\n buttonIconClassName?: string;\n buttonLabel?: string;\n children: ReactNode;\n stopCloseOnClickSelf?: boolean;\n showScroll?: boolean;\n}): React.JSX.Element {\n const dropDownRef = useRef<HTMLDivElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n // Used to prevent flickering of the dropdown while calculating the dropdown position.\n const [positionIsCalculated, setPositionIsCalculated] = useState(false);\n const [showDropDown, setShowDropDown] = useState(false);\n\n const handleClose = () => {\n setPositionIsCalculated(false);\n setShowDropDown(false);\n if (buttonRef && buttonRef.current) {\n buttonRef.current.focus();\n }\n };\n\n useEffect(() => {\n const button = buttonRef.current;\n const dropDown = dropDownRef.current;\n\n if (showDropDown && button && dropDown) {\n dropDown.style.top = \"44px\";\n dropDown.style.left = `${button.offsetLeft}px`;\n setPositionIsCalculated(true);\n }\n }, [dropDownRef, buttonRef, showDropDown]);\n\n useEffect(() => {\n const button = buttonRef.current;\n if (button && showDropDown) {\n const handle = (event: MouseEvent) => {\n const target = event.target;\n if (stopCloseOnClickSelf) {\n if (dropDownRef.current && dropDownRef.current.contains(target as Node)) {\n return;\n }\n }\n\n if (!button.contains(target as Node)) {\n setShowDropDown(false);\n }\n };\n document.addEventListener(\"click\", handle);\n return () => {\n document.removeEventListener(\"click\", handle);\n };\n }\n return;\n }, [dropDownRef, buttonRef, showDropDown, stopCloseOnClickSelf]);\n\n const displayContainer = useMemo(() => {\n // To prevent blinking, we show the container only when the dropdown position is calculated.\n // Without this, window would be visible first on left (0px), and after a millisecond on the right side.\n return positionIsCalculated ? { display: \"block\" } : { display: \"none\" };\n }, [positionIsCalculated]);\n\n return (\n <>\n <button\n style={{ position: \"relative\" }}\n disabled={disabled}\n aria-label={buttonAriaLabel || buttonLabel}\n className={buttonClassName}\n onClick={() => setShowDropDown(!showDropDown)}\n ref={buttonRef}\n >\n {buttonIconClassName && <span className={buttonIconClassName} />}\n {buttonLabel && <span className=\"text dropdown-button-text\">{buttonLabel}</span>}\n <i className=\"chevron-down\" />\n </button>\n {showDropDown && (\n <div className={\"lexical-dropdown-container\"} style={displayContainer}>\n <DropDownItems\n showScroll={showScroll}\n dropDownRef={dropDownRef}\n onClose={handleClose}\n >\n {children}\n </DropDownItems>\n </div>\n )}\n </>\n );\n}\n"],"names":["DropDownContext","React","DropDownItem","children","className","onClick","title","ref","useRef","dropDownContext","Error","registerItem","useEffect","DropDownItems","dropDownRef","showScroll","onClose","items","setItems","useState","highlightedItem","setHighlightedItem","useCallback","itemRef","prev","handleKeyDown","event","key","index","contextValue","useMemo","DropDown","disabled","buttonLabel","buttonAriaLabel","buttonClassName","buttonIconClassName","stopCloseOnClickSelf","buttonRef","positionIsCalculated","setPositionIsCalculated","showDropDown","setShowDropDown","handleClose","button","dropDown","handle","target","document","displayContainer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ui/DropDown.js","sources":["../../src/ui/DropDown.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport * as React from \"react\";\nimport { DropdownMenu } from \"radix-ui\";\n\nexport function DropDownItem({\n children,\n className,\n onClick,\n title\n}: {\n children: React.ReactNode;\n className: string;\n onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;\n title?: string;\n}) {\n return (\n <button className={className} onClick={onClick} title={title} type=\"button\">\n {children}\n </button>\n );\n}\n\ninterface DropDownProps {\n disabled?: boolean;\n buttonAriaLabel?: string;\n buttonClassName: string;\n buttonIconClassName?: string;\n buttonLabel?: string;\n children: ReactNode;\n stopCloseOnClickSelf?: boolean;\n showScroll?: boolean;\n}\n\nexport function DropDown({\n disabled = false,\n buttonLabel,\n buttonAriaLabel,\n buttonClassName,\n buttonIconClassName,\n children,\n showScroll = true\n}: DropDownProps): React.JSX.Element {\n return (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger asChild>\n <button\n style={{ position: \"relative\" }}\n disabled={disabled}\n aria-label={buttonAriaLabel || buttonLabel}\n className={buttonClassName}\n >\n {buttonIconClassName && <span className={buttonIconClassName} />}\n {buttonLabel && (\n <span className=\"text dropdown-button-text\">{buttonLabel}</span>\n )}\n <i className=\"chevron-down\" />\n </button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Portal>\n <DropdownMenu.Content\n className={`lexical-dropdown z-overlay ${showScroll ? \"\" : \"no-scroll\"}`}\n sideOffset={4}\n collisionPadding={8}\n onCloseAutoFocus={e => e.preventDefault()}\n >\n <div\n className={showScroll ? \"lexical-dropdown-scroll\" : \"\"}\n style={showScroll ? { maxHeight: 250, overflowY: \"auto\" } : undefined}\n >\n {children}\n </div>\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n );\n}\n"],"names":["DropDownItem","children","className","onClick","title","DropDown","disabled","buttonLabel","buttonAriaLabel","buttonClassName","buttonIconClassName","showScroll","DropdownMenu","e","undefined"],"mappings":";;AAIO,SAASA,aAAa,EACzBC,QAAQ,EACRC,SAAS,EACTC,OAAO,EACPC,KAAK,EAMR;IACG,OAAO,WAAP,GACI,sCAAC;QAAO,WAAWF;QAAW,SAASC;QAAS,OAAOC;QAAO,MAAK;OAC9DH;AAGb;AAaO,SAASI,SAAS,EACrBC,WAAW,KAAK,EAChBC,WAAW,EACXC,eAAe,EACfC,eAAe,EACfC,mBAAmB,EACnBT,QAAQ,EACRU,aAAa,IAAI,EACL;IACZ,OAAO,WAAP,GACI,sCAACC,aAAa,IAAI,sBACd,sCAACA,aAAa,OAAO;QAAC;qBAClB,sCAAC;QACG,OAAO;YAAE,UAAU;QAAW;QAC9B,UAAUN;QACV,cAAYE,mBAAmBD;QAC/B,WAAWE;OAEVC,uBAAuB,WAAvBA,GAAuB,sCAAC;QAAK,WAAWA;QACxCH,eAAe,WAAfA,GACG,sCAAC;QAAK,WAAU;OAA6BA,cAAAA,WAAAA,GAEjD,sCAAC;QAAE,WAAU;wBAGrB,sCAACK,aAAa,MAAM,sBAChB,sCAACA,aAAa,OAAO;QACjB,WAAW,CAAC,2BAA2B,EAAED,aAAa,KAAK,aAAa;QACxE,YAAY;QACZ,kBAAkB;QAClB,kBAAkBE,CAAAA,IAAKA,EAAE,cAAc;qBAEvC,sCAAC;QACG,WAAWF,aAAa,4BAA4B;QACpD,OAAOA,aAAa;YAAE,WAAW;YAAK,WAAW;QAAO,IAAIG;OAE3Db;AAMzB"}
|
|
@@ -1,25 +1,30 @@
|
|
|
1
|
-
import { computePosition, flip, offset, shift } from "@floating-ui/dom";
|
|
2
1
|
const GAP = 10;
|
|
3
2
|
function setFloatingElemPosition(basePosition, elementToPosition) {
|
|
4
3
|
setTimeout(()=>{
|
|
5
|
-
if (null === basePosition) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
if (null === basePosition) return void Object.assign(elementToPosition.style, {
|
|
5
|
+
position: "fixed",
|
|
6
|
+
left: "-10000px",
|
|
7
|
+
top: "-10000px",
|
|
8
|
+
transform: "none"
|
|
9
|
+
});
|
|
10
|
+
const rangeRect = basePosition.getBoundingClientRect();
|
|
11
|
+
const containerRect = elementToPosition.offsetParent?.getBoundingClientRect() ?? {
|
|
12
|
+
left: 0,
|
|
13
|
+
top: 0
|
|
11
14
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
const elWidth = elementToPosition.offsetWidth;
|
|
16
|
+
const elHeight = elementToPosition.offsetHeight;
|
|
17
|
+
const viewportWidth = window.innerWidth;
|
|
18
|
+
const viewportHeight = window.innerHeight;
|
|
19
|
+
let left = rangeRect.left - containerRect.left;
|
|
20
|
+
let top = rangeRect.bottom + GAP - containerRect.top;
|
|
21
|
+
if (rangeRect.left + elWidth > viewportWidth - GAP) left = viewportWidth - elWidth - GAP - containerRect.left;
|
|
22
|
+
if (rangeRect.bottom + GAP + elHeight > viewportHeight - GAP) top = rangeRect.top - elHeight - GAP - containerRect.top;
|
|
23
|
+
Object.assign(elementToPosition.style, {
|
|
24
|
+
position: "absolute",
|
|
25
|
+
left: `${left}px`,
|
|
26
|
+
top: `${top}px`,
|
|
27
|
+
transform: "none"
|
|
23
28
|
});
|
|
24
29
|
}, 10);
|
|
25
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils/setFloatingElemPosition.js","sources":["../../src/utils/setFloatingElemPosition.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"utils/setFloatingElemPosition.js","sources":["../../src/utils/setFloatingElemPosition.ts"],"sourcesContent":["const GAP = 10;\n\nexport function setFloatingElemPosition(\n basePosition: Range | null,\n elementToPosition: HTMLElement\n): void {\n setTimeout(() => {\n if (basePosition === null) {\n Object.assign(elementToPosition.style, {\n position: \"fixed\",\n left: \"-10000px\",\n top: \"-10000px\",\n transform: \"none\"\n });\n return;\n }\n\n const rangeRect = basePosition.getBoundingClientRect();\n const containerRect = elementToPosition.offsetParent?.getBoundingClientRect() ?? {\n left: 0,\n top: 0\n };\n\n const elWidth = elementToPosition.offsetWidth;\n const elHeight = elementToPosition.offsetHeight;\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n let left = rangeRect.left - containerRect.left;\n let top = rangeRect.bottom + GAP - containerRect.top;\n\n if (rangeRect.left + elWidth > viewportWidth - GAP) {\n left = viewportWidth - elWidth - GAP - containerRect.left;\n }\n\n if (rangeRect.bottom + GAP + elHeight > viewportHeight - GAP) {\n top = rangeRect.top - elHeight - GAP - containerRect.top;\n }\n\n Object.assign(elementToPosition.style, {\n position: \"absolute\",\n left: `${left}px`,\n top: `${top}px`,\n transform: \"none\"\n });\n }, 10);\n}\n"],"names":["GAP","setFloatingElemPosition","basePosition","elementToPosition","setTimeout","Object","rangeRect","containerRect","elWidth","elHeight","viewportWidth","window","viewportHeight","left","top"],"mappings":"AAAA,MAAMA,MAAM;AAEL,SAASC,wBACZC,YAA0B,EAC1BC,iBAA8B;IAE9BC,WAAW;QACP,IAAIF,AAAiB,SAAjBA,cAAuB,YACvBG,OAAO,MAAM,CAACF,kBAAkB,KAAK,EAAE;YACnC,UAAU;YACV,MAAM;YACN,KAAK;YACL,WAAW;QACf;QAIJ,MAAMG,YAAYJ,aAAa,qBAAqB;QACpD,MAAMK,gBAAgBJ,kBAAkB,YAAY,EAAE,2BAA2B;YAC7E,MAAM;YACN,KAAK;QACT;QAEA,MAAMK,UAAUL,kBAAkB,WAAW;QAC7C,MAAMM,WAAWN,kBAAkB,YAAY;QAC/C,MAAMO,gBAAgBC,OAAO,UAAU;QACvC,MAAMC,iBAAiBD,OAAO,WAAW;QAEzC,IAAIE,OAAOP,UAAU,IAAI,GAAGC,cAAc,IAAI;QAC9C,IAAIO,MAAMR,UAAU,MAAM,GAAGN,MAAMO,cAAc,GAAG;QAEpD,IAAID,UAAU,IAAI,GAAGE,UAAUE,gBAAgBV,KAC3Ca,OAAOH,gBAAgBF,UAAUR,MAAMO,cAAc,IAAI;QAG7D,IAAID,UAAU,MAAM,GAAGN,MAAMS,WAAWG,iBAAiBZ,KACrDc,MAAMR,UAAU,GAAG,GAAGG,WAAWT,MAAMO,cAAc,GAAG;QAG5DF,OAAO,MAAM,CAACF,kBAAkB,KAAK,EAAE;YACnC,UAAU;YACV,MAAM,GAAGU,KAAK,EAAE,CAAC;YACjB,KAAK,GAAGC,IAAI,EAAE,CAAC;YACf,WAAW;QACf;IACJ,GAAG;AACP"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export { LexicalHtmlRenderer } from "../../components/LexicalHtmlRenderer.js";
|
|
2
|
-
export { getNodeFromSelection } from "../../hooks/index.js";
|
|
3
|
-
export { useCurrentElement } from "../../hooks/index.js";
|
|
4
|
-
export { useCurrentSelection } from "../../hooks/index.js";
|
|
5
|
-
export { useDeriveValueFromSelection } from "../../hooks/index.js";
|
|
6
|
-
export { useRichTextEditor } from "../../hooks/index.js";
|
|
7
|
-
export { useFontColorPicker } from "../../hooks/index.js";
|
|
8
|
-
export { useTextAlignmentAction } from "../../hooks/index.js";
|
|
9
|
-
export { useTypographyAction } from "../../hooks/index.js";
|
|
10
|
-
export { useIsMounted } from "../../hooks/index.js";
|
|
11
|
-
export { Divider } from "../../ui/Divider.js";
|
|
12
|
-
export { DropDownItem } from "../../ui/DropDown.js";
|
|
13
|
-
export { DropDown } from "../../ui/DropDown.js";
|
|
14
|
-
export type { Klass, LexicalNode } from "../../types.js";
|
|
15
|
-
export { LexicalEditorConfig, useLexicalEditorConfig } from "../../components/LexicalEditorConfig/LexicalEditorConfig.js";
|
package/exports/admin/lexical.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export { LexicalHtmlRenderer } from "../../components/LexicalHtmlRenderer.js";
|
|
2
|
-
export { getNodeFromSelection, useCurrentElement, useCurrentSelection, useDeriveValueFromSelection, useFontColorPicker, useIsMounted, useRichTextEditor, useTextAlignmentAction, useTypographyAction } from "../../hooks/index.js";
|
|
3
|
-
export { Divider } from "../../ui/Divider.js";
|
|
4
|
-
export { DropDown, DropDownItem } from "../../ui/DropDown.js";
|
|
5
|
-
export { LexicalEditorConfig, useLexicalEditorConfig } from "../../components/LexicalEditorConfig/LexicalEditorConfig.js";
|