@pubwave/editor 0.1.3 → 0.2.0
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/dist/index.cjs +137 -24
- package/dist/index.js +137 -24
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4854,6 +4854,89 @@ function calculateVerticalPositionFromRect(triggerRect, dropdownHeight, margin =
|
|
|
4854
4854
|
margin
|
|
4855
4855
|
);
|
|
4856
4856
|
}
|
|
4857
|
+
function calculateHorizontalPosition(triggerLeft, triggerRight, dropdownWidth, preferredAlign = "left", margin = 8) {
|
|
4858
|
+
const viewportWidth = window.innerWidth;
|
|
4859
|
+
const triggerCenter = (triggerLeft + triggerRight) / 2;
|
|
4860
|
+
const spaceLeft = triggerLeft;
|
|
4861
|
+
const spaceRight = viewportWidth - triggerRight;
|
|
4862
|
+
const requiredSpaceForLeft = dropdownWidth + margin;
|
|
4863
|
+
const requiredSpaceForRight = dropdownWidth + margin;
|
|
4864
|
+
const requiredSpaceForCenter = dropdownWidth / 2 + margin;
|
|
4865
|
+
let align = preferredAlign;
|
|
4866
|
+
let left2;
|
|
4867
|
+
if (preferredAlign === "left") {
|
|
4868
|
+
left2 = triggerLeft;
|
|
4869
|
+
if (left2 < margin || left2 + dropdownWidth > viewportWidth - margin) {
|
|
4870
|
+
if (spaceRight >= requiredSpaceForRight && triggerRight + dropdownWidth <= viewportWidth - margin) {
|
|
4871
|
+
align = "right";
|
|
4872
|
+
left2 = triggerRight - dropdownWidth;
|
|
4873
|
+
} else if (spaceLeft >= requiredSpaceForCenter && triggerCenter - dropdownWidth / 2 >= margin) {
|
|
4874
|
+
align = "center";
|
|
4875
|
+
left2 = triggerCenter - dropdownWidth / 2;
|
|
4876
|
+
} else {
|
|
4877
|
+
if (spaceRight >= spaceLeft) {
|
|
4878
|
+
align = "right";
|
|
4879
|
+
left2 = triggerRight - dropdownWidth;
|
|
4880
|
+
} else {
|
|
4881
|
+
align = "left";
|
|
4882
|
+
left2 = triggerLeft;
|
|
4883
|
+
}
|
|
4884
|
+
left2 = Math.max(margin, Math.min(left2, viewportWidth - dropdownWidth - margin));
|
|
4885
|
+
}
|
|
4886
|
+
}
|
|
4887
|
+
} else if (preferredAlign === "center") {
|
|
4888
|
+
left2 = triggerCenter - dropdownWidth / 2;
|
|
4889
|
+
if (left2 < margin || left2 + dropdownWidth > viewportWidth - margin) {
|
|
4890
|
+
if (spaceRight >= requiredSpaceForRight && triggerRight + dropdownWidth <= viewportWidth - margin) {
|
|
4891
|
+
align = "right";
|
|
4892
|
+
left2 = triggerRight - dropdownWidth;
|
|
4893
|
+
} else if (spaceLeft >= requiredSpaceForLeft && triggerLeft + dropdownWidth <= viewportWidth - margin) {
|
|
4894
|
+
align = "left";
|
|
4895
|
+
left2 = triggerLeft;
|
|
4896
|
+
} else {
|
|
4897
|
+
if (spaceRight >= spaceLeft) {
|
|
4898
|
+
align = "right";
|
|
4899
|
+
left2 = triggerRight - dropdownWidth;
|
|
4900
|
+
} else {
|
|
4901
|
+
align = "left";
|
|
4902
|
+
left2 = triggerLeft;
|
|
4903
|
+
}
|
|
4904
|
+
left2 = Math.max(margin, Math.min(left2, viewportWidth - dropdownWidth - margin));
|
|
4905
|
+
}
|
|
4906
|
+
}
|
|
4907
|
+
} else {
|
|
4908
|
+
left2 = triggerRight - dropdownWidth;
|
|
4909
|
+
if (left2 < margin || left2 + dropdownWidth > viewportWidth - margin) {
|
|
4910
|
+
if (spaceLeft >= requiredSpaceForLeft && triggerLeft + dropdownWidth <= viewportWidth - margin) {
|
|
4911
|
+
align = "left";
|
|
4912
|
+
left2 = triggerLeft;
|
|
4913
|
+
} else if (spaceLeft >= requiredSpaceForCenter && triggerCenter - dropdownWidth / 2 >= margin) {
|
|
4914
|
+
align = "center";
|
|
4915
|
+
left2 = triggerCenter - dropdownWidth / 2;
|
|
4916
|
+
} else {
|
|
4917
|
+
if (spaceLeft >= spaceRight) {
|
|
4918
|
+
align = "left";
|
|
4919
|
+
left2 = triggerLeft;
|
|
4920
|
+
} else {
|
|
4921
|
+
align = "right";
|
|
4922
|
+
left2 = triggerRight - dropdownWidth;
|
|
4923
|
+
}
|
|
4924
|
+
left2 = Math.max(margin, Math.min(left2, viewportWidth - dropdownWidth - margin));
|
|
4925
|
+
}
|
|
4926
|
+
}
|
|
4927
|
+
}
|
|
4928
|
+
left2 = Math.max(margin, Math.min(left2, viewportWidth - dropdownWidth - margin));
|
|
4929
|
+
return { align, left: left2 };
|
|
4930
|
+
}
|
|
4931
|
+
function calculateHorizontalPositionFromRect(triggerRect, dropdownWidth, preferredAlign = "left", margin = 8) {
|
|
4932
|
+
return calculateHorizontalPosition(
|
|
4933
|
+
triggerRect.left,
|
|
4934
|
+
triggerRect.right,
|
|
4935
|
+
dropdownWidth,
|
|
4936
|
+
preferredAlign,
|
|
4937
|
+
margin
|
|
4938
|
+
);
|
|
4939
|
+
}
|
|
4857
4940
|
function PositionedDropdown({
|
|
4858
4941
|
isOpen,
|
|
4859
4942
|
buttonRef,
|
|
@@ -4866,7 +4949,8 @@ function PositionedDropdown({
|
|
|
4866
4949
|
onClick,
|
|
4867
4950
|
"data-testid": dataTestId
|
|
4868
4951
|
}) {
|
|
4869
|
-
const [
|
|
4952
|
+
const [verticalPosition, setVerticalPosition] = React.useState("top");
|
|
4953
|
+
const [horizontalPosition, setHorizontalPosition] = React.useState(null);
|
|
4870
4954
|
const dropdownRef = React.useRef(null);
|
|
4871
4955
|
React.useEffect(() => {
|
|
4872
4956
|
if (!isOpen || !buttonRef.current) return;
|
|
@@ -4874,15 +4958,37 @@ function PositionedDropdown({
|
|
|
4874
4958
|
if (!dropdownRef.current || !buttonRef.current) return;
|
|
4875
4959
|
const buttonRect = buttonRef.current.getBoundingClientRect();
|
|
4876
4960
|
const dropdownHeight = dropdownRef.current.offsetHeight || 300;
|
|
4877
|
-
const
|
|
4878
|
-
|
|
4961
|
+
const dropdownWidth = dropdownRef.current.offsetWidth || 240;
|
|
4962
|
+
const newVerticalPosition = calculateVerticalPositionFromRect(buttonRect, dropdownHeight, margin);
|
|
4963
|
+
setVerticalPosition(newVerticalPosition);
|
|
4964
|
+
let parentContainer = buttonRef.current.parentElement;
|
|
4965
|
+
while (parentContainer) {
|
|
4966
|
+
const style2 = window.getComputedStyle(parentContainer);
|
|
4967
|
+
if (style2.position === "relative" || style2.position === "absolute" || style2.position === "fixed") {
|
|
4968
|
+
break;
|
|
4969
|
+
}
|
|
4970
|
+
parentContainer = parentContainer.parentElement;
|
|
4971
|
+
}
|
|
4972
|
+
const horizontalPos = calculateHorizontalPositionFromRect(
|
|
4973
|
+
buttonRect,
|
|
4974
|
+
dropdownWidth,
|
|
4975
|
+
align,
|
|
4976
|
+
margin
|
|
4977
|
+
);
|
|
4978
|
+
if (parentContainer) {
|
|
4979
|
+
const parentRect = parentContainer.getBoundingClientRect();
|
|
4980
|
+
const relativeLeft = horizontalPos.left - parentRect.left;
|
|
4981
|
+
setHorizontalPosition({ align: horizontalPos.align, left: relativeLeft });
|
|
4982
|
+
} else {
|
|
4983
|
+
setHorizontalPosition(horizontalPos);
|
|
4984
|
+
}
|
|
4879
4985
|
};
|
|
4880
4986
|
checkPosition();
|
|
4881
4987
|
const rafId = requestAnimationFrame(() => {
|
|
4882
4988
|
checkPosition();
|
|
4883
4989
|
});
|
|
4884
4990
|
return () => cancelAnimationFrame(rafId);
|
|
4885
|
-
}, [isOpen, buttonRef, margin]);
|
|
4991
|
+
}, [isOpen, buttonRef, margin, align]);
|
|
4886
4992
|
React.useEffect(() => {
|
|
4887
4993
|
if (!isOpen || !onClickOutside2) return;
|
|
4888
4994
|
const handleClickOutside = (event) => {
|
|
@@ -4897,6 +5003,11 @@ function PositionedDropdown({
|
|
|
4897
5003
|
}, [isOpen, onClickOutside2, buttonRef]);
|
|
4898
5004
|
if (!isOpen) return null;
|
|
4899
5005
|
const getHorizontalStyle = () => {
|
|
5006
|
+
if (horizontalPosition) {
|
|
5007
|
+
return {
|
|
5008
|
+
left: `${horizontalPosition.left}px`
|
|
5009
|
+
};
|
|
5010
|
+
}
|
|
4900
5011
|
switch (align) {
|
|
4901
5012
|
case "center":
|
|
4902
5013
|
return {
|
|
@@ -4922,7 +5033,7 @@ function PositionedDropdown({
|
|
|
4922
5033
|
"data-testid": dataTestId,
|
|
4923
5034
|
style: {
|
|
4924
5035
|
position: "absolute",
|
|
4925
|
-
...
|
|
5036
|
+
...verticalPosition === "top" ? {
|
|
4926
5037
|
bottom: "100%",
|
|
4927
5038
|
marginBottom: `${margin}px`
|
|
4928
5039
|
} : {
|
|
@@ -5992,8 +6103,6 @@ function calculatePosition(editor, toolbarEl) {
|
|
|
5992
6103
|
const toolbarRect = toolbarEl.getBoundingClientRect();
|
|
5993
6104
|
const toolbarWidth = toolbarRect.width;
|
|
5994
6105
|
const toolbarHeight = toolbarRect.height;
|
|
5995
|
-
const centerX = (selectionLeft + selectionRight) / 2;
|
|
5996
|
-
let left2 = centerX - toolbarWidth / 2;
|
|
5997
6106
|
const selectionBottom = Math.max(start2.bottom, end2.bottom);
|
|
5998
6107
|
const verticalPosition = calculateVerticalPosition(
|
|
5999
6108
|
selectionTop,
|
|
@@ -6007,20 +6116,21 @@ function calculatePosition(editor, toolbarEl) {
|
|
|
6007
6116
|
} else {
|
|
6008
6117
|
top2 = selectionBottom + TOOLBAR_OFFSET;
|
|
6009
6118
|
}
|
|
6119
|
+
const horizontalPos = calculateHorizontalPosition(
|
|
6120
|
+
selectionLeft,
|
|
6121
|
+
selectionRight,
|
|
6122
|
+
toolbarWidth,
|
|
6123
|
+
"center",
|
|
6124
|
+
// Default to center alignment
|
|
6125
|
+
TOOLBAR_OFFSET
|
|
6126
|
+
);
|
|
6127
|
+
const left2 = horizontalPos.left;
|
|
6010
6128
|
const viewportWidth = window.innerWidth;
|
|
6011
6129
|
const viewportHeight = window.innerHeight;
|
|
6012
|
-
const padding =
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
|
|
6016
|
-
left2 = viewportWidth - toolbarWidth - padding;
|
|
6017
|
-
}
|
|
6018
|
-
if (top2 < padding) {
|
|
6019
|
-
top2 = padding;
|
|
6020
|
-
} else if (top2 + toolbarHeight > viewportHeight - padding) {
|
|
6021
|
-
top2 = viewportHeight - toolbarHeight - padding;
|
|
6022
|
-
}
|
|
6023
|
-
return { top: top2, left: left2, visible: true };
|
|
6130
|
+
const padding = TOOLBAR_OFFSET;
|
|
6131
|
+
const clampedLeft = Math.max(padding, Math.min(left2, viewportWidth - toolbarWidth - padding));
|
|
6132
|
+
const clampedTop = Math.max(padding, Math.min(top2, viewportHeight - toolbarHeight - padding));
|
|
6133
|
+
return { top: clampedTop, left: clampedLeft, visible: true };
|
|
6024
6134
|
}
|
|
6025
6135
|
function BubbleToolbar({
|
|
6026
6136
|
editor,
|
|
@@ -6265,6 +6375,7 @@ function BubbleToolbar({
|
|
|
6265
6375
|
}
|
|
6266
6376
|
);
|
|
6267
6377
|
}
|
|
6378
|
+
const MIN_WINDOW_WIDTH = 768;
|
|
6268
6379
|
function getClosestBlock(target, proseMirror, editor) {
|
|
6269
6380
|
if (!target || !(target instanceof Node)) return null;
|
|
6270
6381
|
try {
|
|
@@ -6310,14 +6421,16 @@ function BlockHandle({ editor }) {
|
|
|
6310
6421
|
const [isDragging, setIsDragging] = React.useState(false);
|
|
6311
6422
|
const [position, setPosition] = React.useState({ top: 0 });
|
|
6312
6423
|
const [isMobile, setIsMobile] = React.useState(false);
|
|
6424
|
+
const [isWindowTooSmall, setIsWindowTooSmall] = React.useState(false);
|
|
6313
6425
|
React.useEffect(() => {
|
|
6314
|
-
const
|
|
6426
|
+
const checkDeviceAndWindow = () => {
|
|
6315
6427
|
setIsMobile(isMobileDevice());
|
|
6428
|
+
setIsWindowTooSmall(window.innerWidth < MIN_WINDOW_WIDTH);
|
|
6316
6429
|
};
|
|
6317
|
-
|
|
6318
|
-
window.addEventListener("resize",
|
|
6430
|
+
checkDeviceAndWindow();
|
|
6431
|
+
window.addEventListener("resize", checkDeviceAndWindow);
|
|
6319
6432
|
return () => {
|
|
6320
|
-
window.removeEventListener("resize",
|
|
6433
|
+
window.removeEventListener("resize", checkDeviceAndWindow);
|
|
6321
6434
|
};
|
|
6322
6435
|
}, []);
|
|
6323
6436
|
const updatePosition = React.useCallback(() => {
|
|
@@ -6552,7 +6665,7 @@ function BlockHandle({ editor }) {
|
|
|
6552
6665
|
}
|
|
6553
6666
|
setVisible(false);
|
|
6554
6667
|
}, []);
|
|
6555
|
-
if (isMobile || !visible) return null;
|
|
6668
|
+
if (isMobile || isWindowTooSmall || !visible) return null;
|
|
6556
6669
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6557
6670
|
"div",
|
|
6558
6671
|
{
|
package/dist/index.js
CHANGED
|
@@ -4852,6 +4852,89 @@ function calculateVerticalPositionFromRect(triggerRect, dropdownHeight, margin =
|
|
|
4852
4852
|
margin
|
|
4853
4853
|
);
|
|
4854
4854
|
}
|
|
4855
|
+
function calculateHorizontalPosition(triggerLeft, triggerRight, dropdownWidth, preferredAlign = "left", margin = 8) {
|
|
4856
|
+
const viewportWidth = window.innerWidth;
|
|
4857
|
+
const triggerCenter = (triggerLeft + triggerRight) / 2;
|
|
4858
|
+
const spaceLeft = triggerLeft;
|
|
4859
|
+
const spaceRight = viewportWidth - triggerRight;
|
|
4860
|
+
const requiredSpaceForLeft = dropdownWidth + margin;
|
|
4861
|
+
const requiredSpaceForRight = dropdownWidth + margin;
|
|
4862
|
+
const requiredSpaceForCenter = dropdownWidth / 2 + margin;
|
|
4863
|
+
let align = preferredAlign;
|
|
4864
|
+
let left2;
|
|
4865
|
+
if (preferredAlign === "left") {
|
|
4866
|
+
left2 = triggerLeft;
|
|
4867
|
+
if (left2 < margin || left2 + dropdownWidth > viewportWidth - margin) {
|
|
4868
|
+
if (spaceRight >= requiredSpaceForRight && triggerRight + dropdownWidth <= viewportWidth - margin) {
|
|
4869
|
+
align = "right";
|
|
4870
|
+
left2 = triggerRight - dropdownWidth;
|
|
4871
|
+
} else if (spaceLeft >= requiredSpaceForCenter && triggerCenter - dropdownWidth / 2 >= margin) {
|
|
4872
|
+
align = "center";
|
|
4873
|
+
left2 = triggerCenter - dropdownWidth / 2;
|
|
4874
|
+
} else {
|
|
4875
|
+
if (spaceRight >= spaceLeft) {
|
|
4876
|
+
align = "right";
|
|
4877
|
+
left2 = triggerRight - dropdownWidth;
|
|
4878
|
+
} else {
|
|
4879
|
+
align = "left";
|
|
4880
|
+
left2 = triggerLeft;
|
|
4881
|
+
}
|
|
4882
|
+
left2 = Math.max(margin, Math.min(left2, viewportWidth - dropdownWidth - margin));
|
|
4883
|
+
}
|
|
4884
|
+
}
|
|
4885
|
+
} else if (preferredAlign === "center") {
|
|
4886
|
+
left2 = triggerCenter - dropdownWidth / 2;
|
|
4887
|
+
if (left2 < margin || left2 + dropdownWidth > viewportWidth - margin) {
|
|
4888
|
+
if (spaceRight >= requiredSpaceForRight && triggerRight + dropdownWidth <= viewportWidth - margin) {
|
|
4889
|
+
align = "right";
|
|
4890
|
+
left2 = triggerRight - dropdownWidth;
|
|
4891
|
+
} else if (spaceLeft >= requiredSpaceForLeft && triggerLeft + dropdownWidth <= viewportWidth - margin) {
|
|
4892
|
+
align = "left";
|
|
4893
|
+
left2 = triggerLeft;
|
|
4894
|
+
} else {
|
|
4895
|
+
if (spaceRight >= spaceLeft) {
|
|
4896
|
+
align = "right";
|
|
4897
|
+
left2 = triggerRight - dropdownWidth;
|
|
4898
|
+
} else {
|
|
4899
|
+
align = "left";
|
|
4900
|
+
left2 = triggerLeft;
|
|
4901
|
+
}
|
|
4902
|
+
left2 = Math.max(margin, Math.min(left2, viewportWidth - dropdownWidth - margin));
|
|
4903
|
+
}
|
|
4904
|
+
}
|
|
4905
|
+
} else {
|
|
4906
|
+
left2 = triggerRight - dropdownWidth;
|
|
4907
|
+
if (left2 < margin || left2 + dropdownWidth > viewportWidth - margin) {
|
|
4908
|
+
if (spaceLeft >= requiredSpaceForLeft && triggerLeft + dropdownWidth <= viewportWidth - margin) {
|
|
4909
|
+
align = "left";
|
|
4910
|
+
left2 = triggerLeft;
|
|
4911
|
+
} else if (spaceLeft >= requiredSpaceForCenter && triggerCenter - dropdownWidth / 2 >= margin) {
|
|
4912
|
+
align = "center";
|
|
4913
|
+
left2 = triggerCenter - dropdownWidth / 2;
|
|
4914
|
+
} else {
|
|
4915
|
+
if (spaceLeft >= spaceRight) {
|
|
4916
|
+
align = "left";
|
|
4917
|
+
left2 = triggerLeft;
|
|
4918
|
+
} else {
|
|
4919
|
+
align = "right";
|
|
4920
|
+
left2 = triggerRight - dropdownWidth;
|
|
4921
|
+
}
|
|
4922
|
+
left2 = Math.max(margin, Math.min(left2, viewportWidth - dropdownWidth - margin));
|
|
4923
|
+
}
|
|
4924
|
+
}
|
|
4925
|
+
}
|
|
4926
|
+
left2 = Math.max(margin, Math.min(left2, viewportWidth - dropdownWidth - margin));
|
|
4927
|
+
return { align, left: left2 };
|
|
4928
|
+
}
|
|
4929
|
+
function calculateHorizontalPositionFromRect(triggerRect, dropdownWidth, preferredAlign = "left", margin = 8) {
|
|
4930
|
+
return calculateHorizontalPosition(
|
|
4931
|
+
triggerRect.left,
|
|
4932
|
+
triggerRect.right,
|
|
4933
|
+
dropdownWidth,
|
|
4934
|
+
preferredAlign,
|
|
4935
|
+
margin
|
|
4936
|
+
);
|
|
4937
|
+
}
|
|
4855
4938
|
function PositionedDropdown({
|
|
4856
4939
|
isOpen,
|
|
4857
4940
|
buttonRef,
|
|
@@ -4864,7 +4947,8 @@ function PositionedDropdown({
|
|
|
4864
4947
|
onClick,
|
|
4865
4948
|
"data-testid": dataTestId
|
|
4866
4949
|
}) {
|
|
4867
|
-
const [
|
|
4950
|
+
const [verticalPosition, setVerticalPosition] = useState("top");
|
|
4951
|
+
const [horizontalPosition, setHorizontalPosition] = useState(null);
|
|
4868
4952
|
const dropdownRef = useRef(null);
|
|
4869
4953
|
useEffect(() => {
|
|
4870
4954
|
if (!isOpen || !buttonRef.current) return;
|
|
@@ -4872,15 +4956,37 @@ function PositionedDropdown({
|
|
|
4872
4956
|
if (!dropdownRef.current || !buttonRef.current) return;
|
|
4873
4957
|
const buttonRect = buttonRef.current.getBoundingClientRect();
|
|
4874
4958
|
const dropdownHeight = dropdownRef.current.offsetHeight || 300;
|
|
4875
|
-
const
|
|
4876
|
-
|
|
4959
|
+
const dropdownWidth = dropdownRef.current.offsetWidth || 240;
|
|
4960
|
+
const newVerticalPosition = calculateVerticalPositionFromRect(buttonRect, dropdownHeight, margin);
|
|
4961
|
+
setVerticalPosition(newVerticalPosition);
|
|
4962
|
+
let parentContainer = buttonRef.current.parentElement;
|
|
4963
|
+
while (parentContainer) {
|
|
4964
|
+
const style2 = window.getComputedStyle(parentContainer);
|
|
4965
|
+
if (style2.position === "relative" || style2.position === "absolute" || style2.position === "fixed") {
|
|
4966
|
+
break;
|
|
4967
|
+
}
|
|
4968
|
+
parentContainer = parentContainer.parentElement;
|
|
4969
|
+
}
|
|
4970
|
+
const horizontalPos = calculateHorizontalPositionFromRect(
|
|
4971
|
+
buttonRect,
|
|
4972
|
+
dropdownWidth,
|
|
4973
|
+
align,
|
|
4974
|
+
margin
|
|
4975
|
+
);
|
|
4976
|
+
if (parentContainer) {
|
|
4977
|
+
const parentRect = parentContainer.getBoundingClientRect();
|
|
4978
|
+
const relativeLeft = horizontalPos.left - parentRect.left;
|
|
4979
|
+
setHorizontalPosition({ align: horizontalPos.align, left: relativeLeft });
|
|
4980
|
+
} else {
|
|
4981
|
+
setHorizontalPosition(horizontalPos);
|
|
4982
|
+
}
|
|
4877
4983
|
};
|
|
4878
4984
|
checkPosition();
|
|
4879
4985
|
const rafId = requestAnimationFrame(() => {
|
|
4880
4986
|
checkPosition();
|
|
4881
4987
|
});
|
|
4882
4988
|
return () => cancelAnimationFrame(rafId);
|
|
4883
|
-
}, [isOpen, buttonRef, margin]);
|
|
4989
|
+
}, [isOpen, buttonRef, margin, align]);
|
|
4884
4990
|
useEffect(() => {
|
|
4885
4991
|
if (!isOpen || !onClickOutside2) return;
|
|
4886
4992
|
const handleClickOutside = (event) => {
|
|
@@ -4895,6 +5001,11 @@ function PositionedDropdown({
|
|
|
4895
5001
|
}, [isOpen, onClickOutside2, buttonRef]);
|
|
4896
5002
|
if (!isOpen) return null;
|
|
4897
5003
|
const getHorizontalStyle = () => {
|
|
5004
|
+
if (horizontalPosition) {
|
|
5005
|
+
return {
|
|
5006
|
+
left: `${horizontalPosition.left}px`
|
|
5007
|
+
};
|
|
5008
|
+
}
|
|
4898
5009
|
switch (align) {
|
|
4899
5010
|
case "center":
|
|
4900
5011
|
return {
|
|
@@ -4920,7 +5031,7 @@ function PositionedDropdown({
|
|
|
4920
5031
|
"data-testid": dataTestId,
|
|
4921
5032
|
style: {
|
|
4922
5033
|
position: "absolute",
|
|
4923
|
-
...
|
|
5034
|
+
...verticalPosition === "top" ? {
|
|
4924
5035
|
bottom: "100%",
|
|
4925
5036
|
marginBottom: `${margin}px`
|
|
4926
5037
|
} : {
|
|
@@ -5990,8 +6101,6 @@ function calculatePosition(editor, toolbarEl) {
|
|
|
5990
6101
|
const toolbarRect = toolbarEl.getBoundingClientRect();
|
|
5991
6102
|
const toolbarWidth = toolbarRect.width;
|
|
5992
6103
|
const toolbarHeight = toolbarRect.height;
|
|
5993
|
-
const centerX = (selectionLeft + selectionRight) / 2;
|
|
5994
|
-
let left2 = centerX - toolbarWidth / 2;
|
|
5995
6104
|
const selectionBottom = Math.max(start2.bottom, end2.bottom);
|
|
5996
6105
|
const verticalPosition = calculateVerticalPosition(
|
|
5997
6106
|
selectionTop,
|
|
@@ -6005,20 +6114,21 @@ function calculatePosition(editor, toolbarEl) {
|
|
|
6005
6114
|
} else {
|
|
6006
6115
|
top2 = selectionBottom + TOOLBAR_OFFSET;
|
|
6007
6116
|
}
|
|
6117
|
+
const horizontalPos = calculateHorizontalPosition(
|
|
6118
|
+
selectionLeft,
|
|
6119
|
+
selectionRight,
|
|
6120
|
+
toolbarWidth,
|
|
6121
|
+
"center",
|
|
6122
|
+
// Default to center alignment
|
|
6123
|
+
TOOLBAR_OFFSET
|
|
6124
|
+
);
|
|
6125
|
+
const left2 = horizontalPos.left;
|
|
6008
6126
|
const viewportWidth = window.innerWidth;
|
|
6009
6127
|
const viewportHeight = window.innerHeight;
|
|
6010
|
-
const padding =
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
left2 = viewportWidth - toolbarWidth - padding;
|
|
6015
|
-
}
|
|
6016
|
-
if (top2 < padding) {
|
|
6017
|
-
top2 = padding;
|
|
6018
|
-
} else if (top2 + toolbarHeight > viewportHeight - padding) {
|
|
6019
|
-
top2 = viewportHeight - toolbarHeight - padding;
|
|
6020
|
-
}
|
|
6021
|
-
return { top: top2, left: left2, visible: true };
|
|
6128
|
+
const padding = TOOLBAR_OFFSET;
|
|
6129
|
+
const clampedLeft = Math.max(padding, Math.min(left2, viewportWidth - toolbarWidth - padding));
|
|
6130
|
+
const clampedTop = Math.max(padding, Math.min(top2, viewportHeight - toolbarHeight - padding));
|
|
6131
|
+
return { top: clampedTop, left: clampedLeft, visible: true };
|
|
6022
6132
|
}
|
|
6023
6133
|
function BubbleToolbar({
|
|
6024
6134
|
editor,
|
|
@@ -6263,6 +6373,7 @@ function BubbleToolbar({
|
|
|
6263
6373
|
}
|
|
6264
6374
|
);
|
|
6265
6375
|
}
|
|
6376
|
+
const MIN_WINDOW_WIDTH = 768;
|
|
6266
6377
|
function getClosestBlock(target, proseMirror, editor) {
|
|
6267
6378
|
if (!target || !(target instanceof Node)) return null;
|
|
6268
6379
|
try {
|
|
@@ -6308,14 +6419,16 @@ function BlockHandle({ editor }) {
|
|
|
6308
6419
|
const [isDragging, setIsDragging] = useState(false);
|
|
6309
6420
|
const [position, setPosition] = useState({ top: 0 });
|
|
6310
6421
|
const [isMobile, setIsMobile] = useState(false);
|
|
6422
|
+
const [isWindowTooSmall, setIsWindowTooSmall] = useState(false);
|
|
6311
6423
|
useEffect(() => {
|
|
6312
|
-
const
|
|
6424
|
+
const checkDeviceAndWindow = () => {
|
|
6313
6425
|
setIsMobile(isMobileDevice());
|
|
6426
|
+
setIsWindowTooSmall(window.innerWidth < MIN_WINDOW_WIDTH);
|
|
6314
6427
|
};
|
|
6315
|
-
|
|
6316
|
-
window.addEventListener("resize",
|
|
6428
|
+
checkDeviceAndWindow();
|
|
6429
|
+
window.addEventListener("resize", checkDeviceAndWindow);
|
|
6317
6430
|
return () => {
|
|
6318
|
-
window.removeEventListener("resize",
|
|
6431
|
+
window.removeEventListener("resize", checkDeviceAndWindow);
|
|
6319
6432
|
};
|
|
6320
6433
|
}, []);
|
|
6321
6434
|
const updatePosition = useCallback(() => {
|
|
@@ -6550,7 +6663,7 @@ function BlockHandle({ editor }) {
|
|
|
6550
6663
|
}
|
|
6551
6664
|
setVisible(false);
|
|
6552
6665
|
}, []);
|
|
6553
|
-
if (isMobile || !visible) return null;
|
|
6666
|
+
if (isMobile || isWindowTooSmall || !visible) return null;
|
|
6554
6667
|
return /* @__PURE__ */ jsxs(
|
|
6555
6668
|
"div",
|
|
6556
6669
|
{
|