@pubwave/editor 0.1.2 → 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/README.md +0 -22
- package/dist/index.cjs +180 -22
- package/dist/index.css +1 -1
- package/dist/index.d.ts +13 -0
- package/dist/index.js +180 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -600,32 +600,15 @@ const customCommands: SlashCommand[] = [
|
|
|
600
600
|
|
|
601
601
|
---
|
|
602
602
|
|
|
603
|
-
## ⚡ SSR Integration (Next.js)
|
|
604
603
|
|
|
605
|
-
The library is SSR-safe and can be imported server-side without errors. The editor component itself renders client-side only.
|
|
606
604
|
|
|
607
|
-
```tsx
|
|
608
|
-
'use client';
|
|
609
|
-
|
|
610
|
-
import { PubwaveEditor } from '@pubwave/editor';
|
|
611
|
-
import '@pubwave/editor/style.css';
|
|
612
|
-
|
|
613
|
-
export default function EditorComponent() {
|
|
614
|
-
return <PubwaveEditor />;
|
|
615
|
-
}
|
|
616
|
-
```
|
|
617
605
|
|
|
618
|
-
---
|
|
619
606
|
|
|
620
607
|
|
|
621
608
|
## 🐛 Troubleshooting
|
|
622
609
|
|
|
623
610
|
### Common Issues
|
|
624
611
|
|
|
625
|
-
**Q: The editor doesn't render in Next.js SSR**
|
|
626
|
-
- Make sure you're using `'use client'` directive
|
|
627
|
-
- Ensure the component is marked as a client component
|
|
628
|
-
|
|
629
612
|
**Q: Styles are not applied**
|
|
630
613
|
- Ensure you've imported the CSS: `import '@pubwave/editor/style.css'`
|
|
631
614
|
- Check that CSS custom properties are defined
|
|
@@ -650,11 +633,6 @@ export default function EditorComponent() {
|
|
|
650
633
|
|
|
651
634
|
---
|
|
652
635
|
|
|
653
|
-
## 🤝 Contributing
|
|
654
|
-
|
|
655
|
-
See [CONTRIBUTING.md](./CONTRIBUTING.md) for development setup and guidelines.
|
|
656
|
-
|
|
657
|
-
---
|
|
658
636
|
|
|
659
637
|
## 📄 License
|
|
660
638
|
|
package/dist/index.cjs
CHANGED
|
@@ -463,6 +463,13 @@ function safeRequestAnimationFrame(callback) {
|
|
|
463
463
|
}
|
|
464
464
|
return 0;
|
|
465
465
|
}
|
|
466
|
+
function isMobileDevice() {
|
|
467
|
+
if (!canUseDOM) return false;
|
|
468
|
+
const hasTouchSupport = "ontouchstart" in window || navigator.maxTouchPoints > 0;
|
|
469
|
+
const hasCoarsePointer = window.matchMedia("(pointer: coarse)").matches;
|
|
470
|
+
const hasHover = window.matchMedia("(hover: hover)").matches;
|
|
471
|
+
return hasTouchSupport && hasCoarsePointer || hasTouchSupport && !hasHover;
|
|
472
|
+
}
|
|
466
473
|
function TextIcon() {
|
|
467
474
|
return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 7V4h16v3M9 20h6M12 4v16" }) });
|
|
468
475
|
}
|
|
@@ -4847,6 +4854,89 @@ function calculateVerticalPositionFromRect(triggerRect, dropdownHeight, margin =
|
|
|
4847
4854
|
margin
|
|
4848
4855
|
);
|
|
4849
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
|
+
}
|
|
4850
4940
|
function PositionedDropdown({
|
|
4851
4941
|
isOpen,
|
|
4852
4942
|
buttonRef,
|
|
@@ -4859,7 +4949,8 @@ function PositionedDropdown({
|
|
|
4859
4949
|
onClick,
|
|
4860
4950
|
"data-testid": dataTestId
|
|
4861
4951
|
}) {
|
|
4862
|
-
const [
|
|
4952
|
+
const [verticalPosition, setVerticalPosition] = React.useState("top");
|
|
4953
|
+
const [horizontalPosition, setHorizontalPosition] = React.useState(null);
|
|
4863
4954
|
const dropdownRef = React.useRef(null);
|
|
4864
4955
|
React.useEffect(() => {
|
|
4865
4956
|
if (!isOpen || !buttonRef.current) return;
|
|
@@ -4867,15 +4958,37 @@ function PositionedDropdown({
|
|
|
4867
4958
|
if (!dropdownRef.current || !buttonRef.current) return;
|
|
4868
4959
|
const buttonRect = buttonRef.current.getBoundingClientRect();
|
|
4869
4960
|
const dropdownHeight = dropdownRef.current.offsetHeight || 300;
|
|
4870
|
-
const
|
|
4871
|
-
|
|
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
|
+
}
|
|
4872
4985
|
};
|
|
4873
4986
|
checkPosition();
|
|
4874
4987
|
const rafId = requestAnimationFrame(() => {
|
|
4875
4988
|
checkPosition();
|
|
4876
4989
|
});
|
|
4877
4990
|
return () => cancelAnimationFrame(rafId);
|
|
4878
|
-
}, [isOpen, buttonRef, margin]);
|
|
4991
|
+
}, [isOpen, buttonRef, margin, align]);
|
|
4879
4992
|
React.useEffect(() => {
|
|
4880
4993
|
if (!isOpen || !onClickOutside2) return;
|
|
4881
4994
|
const handleClickOutside = (event) => {
|
|
@@ -4890,6 +5003,11 @@ function PositionedDropdown({
|
|
|
4890
5003
|
}, [isOpen, onClickOutside2, buttonRef]);
|
|
4891
5004
|
if (!isOpen) return null;
|
|
4892
5005
|
const getHorizontalStyle = () => {
|
|
5006
|
+
if (horizontalPosition) {
|
|
5007
|
+
return {
|
|
5008
|
+
left: `${horizontalPosition.left}px`
|
|
5009
|
+
};
|
|
5010
|
+
}
|
|
4893
5011
|
switch (align) {
|
|
4894
5012
|
case "center":
|
|
4895
5013
|
return {
|
|
@@ -4915,7 +5033,7 @@ function PositionedDropdown({
|
|
|
4915
5033
|
"data-testid": dataTestId,
|
|
4916
5034
|
style: {
|
|
4917
5035
|
position: "absolute",
|
|
4918
|
-
...
|
|
5036
|
+
...verticalPosition === "top" ? {
|
|
4919
5037
|
bottom: "100%",
|
|
4920
5038
|
marginBottom: `${margin}px`
|
|
4921
5039
|
} : {
|
|
@@ -5985,8 +6103,6 @@ function calculatePosition(editor, toolbarEl) {
|
|
|
5985
6103
|
const toolbarRect = toolbarEl.getBoundingClientRect();
|
|
5986
6104
|
const toolbarWidth = toolbarRect.width;
|
|
5987
6105
|
const toolbarHeight = toolbarRect.height;
|
|
5988
|
-
const centerX = (selectionLeft + selectionRight) / 2;
|
|
5989
|
-
let left2 = centerX - toolbarWidth / 2;
|
|
5990
6106
|
const selectionBottom = Math.max(start2.bottom, end2.bottom);
|
|
5991
6107
|
const verticalPosition = calculateVerticalPosition(
|
|
5992
6108
|
selectionTop,
|
|
@@ -6000,20 +6116,21 @@ function calculatePosition(editor, toolbarEl) {
|
|
|
6000
6116
|
} else {
|
|
6001
6117
|
top2 = selectionBottom + TOOLBAR_OFFSET;
|
|
6002
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;
|
|
6003
6128
|
const viewportWidth = window.innerWidth;
|
|
6004
6129
|
const viewportHeight = window.innerHeight;
|
|
6005
|
-
const padding =
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
left2 = viewportWidth - toolbarWidth - padding;
|
|
6010
|
-
}
|
|
6011
|
-
if (top2 < padding) {
|
|
6012
|
-
top2 = padding;
|
|
6013
|
-
} else if (top2 + toolbarHeight > viewportHeight - padding) {
|
|
6014
|
-
top2 = viewportHeight - toolbarHeight - padding;
|
|
6015
|
-
}
|
|
6016
|
-
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 };
|
|
6017
6134
|
}
|
|
6018
6135
|
function BubbleToolbar({
|
|
6019
6136
|
editor,
|
|
@@ -6258,6 +6375,7 @@ function BubbleToolbar({
|
|
|
6258
6375
|
}
|
|
6259
6376
|
);
|
|
6260
6377
|
}
|
|
6378
|
+
const MIN_WINDOW_WIDTH = 768;
|
|
6261
6379
|
function getClosestBlock(target, proseMirror, editor) {
|
|
6262
6380
|
if (!target || !(target instanceof Node)) return null;
|
|
6263
6381
|
try {
|
|
@@ -6302,18 +6420,33 @@ function BlockHandle({ editor }) {
|
|
|
6302
6420
|
const [visible, setVisible] = React.useState(false);
|
|
6303
6421
|
const [isDragging, setIsDragging] = React.useState(false);
|
|
6304
6422
|
const [position, setPosition] = React.useState({ top: 0 });
|
|
6423
|
+
const [isMobile, setIsMobile] = React.useState(false);
|
|
6424
|
+
const [isWindowTooSmall, setIsWindowTooSmall] = React.useState(false);
|
|
6425
|
+
React.useEffect(() => {
|
|
6426
|
+
const checkDeviceAndWindow = () => {
|
|
6427
|
+
setIsMobile(isMobileDevice());
|
|
6428
|
+
setIsWindowTooSmall(window.innerWidth < MIN_WINDOW_WIDTH);
|
|
6429
|
+
};
|
|
6430
|
+
checkDeviceAndWindow();
|
|
6431
|
+
window.addEventListener("resize", checkDeviceAndWindow);
|
|
6432
|
+
return () => {
|
|
6433
|
+
window.removeEventListener("resize", checkDeviceAndWindow);
|
|
6434
|
+
};
|
|
6435
|
+
}, []);
|
|
6305
6436
|
const updatePosition = React.useCallback(() => {
|
|
6306
6437
|
const container = containerRef.current;
|
|
6307
6438
|
const block = currentBlockRef.current;
|
|
6308
6439
|
if (!container || !block) return;
|
|
6309
6440
|
const editorContainer = container.closest(".pubwave-editor");
|
|
6310
6441
|
if (!editorContainer) return;
|
|
6442
|
+
void editorContainer.offsetHeight;
|
|
6311
6443
|
const editorRect = editorContainer.getBoundingClientRect();
|
|
6312
6444
|
let offset2 = 14;
|
|
6313
6445
|
let target = block;
|
|
6314
6446
|
if (["UL", "OL", "BLOCKQUOTE"].includes(block.tagName) && block.firstElementChild instanceof HTMLElement) {
|
|
6315
6447
|
target = block.firstElementChild;
|
|
6316
6448
|
}
|
|
6449
|
+
void target.offsetHeight;
|
|
6317
6450
|
const targetRect = target.getBoundingClientRect();
|
|
6318
6451
|
try {
|
|
6319
6452
|
const style = window.getComputedStyle(target);
|
|
@@ -6332,12 +6465,18 @@ function BlockHandle({ editor }) {
|
|
|
6332
6465
|
} catch (e) {
|
|
6333
6466
|
}
|
|
6334
6467
|
const top2 = targetRect.top - editorRect.top + offset2;
|
|
6335
|
-
|
|
6468
|
+
if (!isNaN(top2) && isFinite(top2) && top2 >= 0) {
|
|
6469
|
+
setPosition({ top: top2 });
|
|
6470
|
+
}
|
|
6336
6471
|
}, []);
|
|
6337
6472
|
const showHandle = React.useCallback((block) => {
|
|
6338
6473
|
currentBlockRef.current = block;
|
|
6339
6474
|
setVisible(true);
|
|
6340
|
-
|
|
6475
|
+
requestAnimationFrame(() => {
|
|
6476
|
+
requestAnimationFrame(() => {
|
|
6477
|
+
updatePosition();
|
|
6478
|
+
});
|
|
6479
|
+
});
|
|
6341
6480
|
}, [updatePosition]);
|
|
6342
6481
|
const hideHandle = React.useCallback(() => {
|
|
6343
6482
|
if (!isDraggingRef.current) {
|
|
@@ -6399,8 +6538,16 @@ function BlockHandle({ editor }) {
|
|
|
6399
6538
|
hideHandle();
|
|
6400
6539
|
}, 150);
|
|
6401
6540
|
};
|
|
6541
|
+
const onEditorMouseLeave = () => {
|
|
6542
|
+
if (isDraggingRef.current) return;
|
|
6543
|
+
clearHideTimeout();
|
|
6544
|
+
hideTimeoutRef.current = setTimeout(() => {
|
|
6545
|
+
hideHandle();
|
|
6546
|
+
}, 150);
|
|
6547
|
+
};
|
|
6402
6548
|
proseMirror.addEventListener("mouseover", onMouseOver);
|
|
6403
6549
|
proseMirror.addEventListener("mouseout", onMouseOut);
|
|
6550
|
+
editorContainer.addEventListener("mouseleave", onEditorMouseLeave);
|
|
6404
6551
|
const handleTransaction = ({ transaction }) => {
|
|
6405
6552
|
if (transaction.docChanged && !isDraggingRef.current) {
|
|
6406
6553
|
hideHandle();
|
|
@@ -6410,10 +6557,20 @@ function BlockHandle({ editor }) {
|
|
|
6410
6557
|
return () => {
|
|
6411
6558
|
proseMirror.removeEventListener("mouseover", onMouseOver);
|
|
6412
6559
|
proseMirror.removeEventListener("mouseout", onMouseOut);
|
|
6560
|
+
editorContainer.removeEventListener("mouseleave", onEditorMouseLeave);
|
|
6413
6561
|
editor.off("transaction", handleTransaction);
|
|
6414
6562
|
clearHideTimeout();
|
|
6415
6563
|
};
|
|
6416
6564
|
}, [editor, showHandle, hideHandle, clearHideTimeout]);
|
|
6565
|
+
React.useEffect(() => {
|
|
6566
|
+
if (visible && currentBlockRef.current) {
|
|
6567
|
+
requestAnimationFrame(() => {
|
|
6568
|
+
requestAnimationFrame(() => {
|
|
6569
|
+
updatePosition();
|
|
6570
|
+
});
|
|
6571
|
+
});
|
|
6572
|
+
}
|
|
6573
|
+
}, [visible, updatePosition]);
|
|
6417
6574
|
React.useEffect(() => {
|
|
6418
6575
|
if (!visible) return;
|
|
6419
6576
|
const onScroll = () => {
|
|
@@ -6508,7 +6665,7 @@ function BlockHandle({ editor }) {
|
|
|
6508
6665
|
}
|
|
6509
6666
|
setVisible(false);
|
|
6510
6667
|
}, []);
|
|
6511
|
-
if (!visible) return null;
|
|
6668
|
+
if (isMobile || isWindowTooSmall || !visible) return null;
|
|
6512
6669
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6513
6670
|
"div",
|
|
6514
6671
|
{
|
|
@@ -7515,6 +7672,7 @@ exports.handleSelectionClear = handleSelectionClear;
|
|
|
7515
7672
|
exports.isEditable = isEditable;
|
|
7516
7673
|
exports.isEditorValid = isEditorValid;
|
|
7517
7674
|
exports.isMarkActive = isMarkActive;
|
|
7675
|
+
exports.isMobileDevice = isMobileDevice;
|
|
7518
7676
|
exports.isNodeActive = isNodeActive;
|
|
7519
7677
|
exports.isReadOnly = isReadOnly;
|
|
7520
7678
|
exports.isSSR = isSSR;
|
package/dist/index.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */
|
|
2
|
-
@layer properties{@supports ((-webkit-hyphens:none) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.isolate{isolation:isolate}.container{width:100%}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.resize{resize:both}.border{border-style:var(--tw-border-style);border-width:1px}.uppercase{text-transform:uppercase}.italic{font-style:italic}.underline{text-decoration-line:underline}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}:root{--pubwave-bg:#fff;--pubwave-surface:#fff;--pubwave-text:#37352f;--pubwave-text-muted:#9b9a97;--pubwave-border:#e3e2e0;--pubwave-border-light:#f3f4f6;--pubwave-hover:#f7f6f3;--pubwave-focus:#0000000d;--pubwave-selection:#3b82f6;--pubwave-selection-bg:#2383e226;--pubwave-primary:#2383e2;--pubwave-primary-hover:#2563eb;--pubwave-handle-color:#9b9a97;--pubwave-primary-faded:#3b82f61a;--pubwave-drop-indicator:#3b82f6;--pubwave-drop-target:#3b82f60d;--pubwave-error:#ef4444;--pubwave-success:#10b981;--pubwave-warning:#f59e0b;--pubwave-text-secondary:#374151;--pubwave-text-tertiary:#4b5563;--pubwave-hover-bg:#f3f4f6;--pubwave-hover-task:#e8f2ff;--pubwave-checked-text:#9ca3af;--pubwave-spacing-xs:.25rem;--pubwave-spacing-sm:.5rem;--pubwave-spacing-md:1rem;--pubwave-spacing-lg:1.5rem;--pubwave-spacing-xl:2rem;--pubwave-spacing-1:4px;--pubwave-spacing-2:8px;--pubwave-spacing-3:12px;--pubwave-spacing-4:16px;--pubwave-spacing-7:28px;--pubwave-font-family:inherit;--pubwave-font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--pubwave-font-size-xs:11px;--pubwave-font-size-sm:13px;--pubwave-font-size-base:14px;--pubwave-font-size-md:1rem;--pubwave-font-size-lg:1.125rem;--pubwave-font-size-xl:1.25rem;--pubwave-font-size-2xl:1.5rem;--pubwave-font-size-3xl:2rem;--pubwave-line-height:1.625;--pubwave-line-height-heading:1.25;--pubwave-button-width:28px;--pubwave-button-height:28px;--pubwave-icon-size:20px;--pubwave-checkbox-size:20px;--pubwave-checkbox-input-size:16px;--pubwave-divider-width:1px;--pubwave-divider-height:20px;--pubwave-drop-indicator-width:2px;--pubwave-drop-indicator-height:2px;--pubwave-task-item-height:30px;--pubwave-radius-xs:3px;--pubwave-radius-sm:4px;--pubwave-radius:6px;--pubwave-radius-md:6px;--pubwave-radius-lg:8px;--pubwave-shadow-sm:0 1px 2px 0 #0000000d;--pubwave-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f;--pubwave-shadow-lg:0 10px 15px -3px #0000001a,0 4px 6px -2px #0000000d}@media (prefers-color-scheme:dark){:root{--pubwave-bg:#1a1a1a;--pubwave-surface:#262626;--pubwave-text:#e5e7eb;--pubwave-text-muted:#9ca3af;--pubwave-border:#374151;--pubwave-border-light:#4b5563;--pubwave-hover:#ffffff0d;--pubwave-focus:#ffffff14;--pubwave-selection:#60a5fa;--pubwave-selection-bg:#60a5fa26;--pubwave-primary:#60a5fa;--pubwave-primary-hover:#3b82f6;--pubwave-primary-faded:#60a5fa26;--pubwave-drop-indicator:#60a5fa;--pubwave-drop-target:#60a5fa14;--pubwave-error:#f87171;--pubwave-text-secondary:#d1d5db;--pubwave-text-tertiary:#9ca3af;--pubwave-hover-bg:#374151;--pubwave-hover-task:#3b82f626;--pubwave-checked-text:#6b7280}}.pubwave-editor{width:var(--pubwave-container-width,100%);max-width:var(--pubwave-container-max-width,none);font-family:var(--pubwave-font-family);color:var(--pubwave-text);background:var(--pubwave-bg,#fff);border-radius:var(--pubwave-container-border-radius,16px);min-height:var(--pubwave-container-min-height,700px);padding:var(--pubwave-container-padding-y,96px)var(--pubwave-container-padding-x,120px);padding-left:var(--pubwave-container-padding-left,140px);position:relative;box-shadow:0 0 0 1px #0000000a,0 20px 25px -5px #0000000d,0 10px 10px -5px #00000005}@media (max-width:768px){.pubwave-editor{padding:var(--pubwave-container-padding-y-mobile,20px)var(--pubwave-container-padding-x-mobile,16px);padding-left:var(--pubwave-container-padding-left-mobile,16px);border-radius:var(--pubwave-container-border-radius-mobile,12px);min-height:var(--pubwave-container-min-height-mobile,400px)}}.pubwave-editor,.pubwave-editor *,.pubwave-editor :before,.pubwave-editor :after{box-sizing:border-box}.pubwave-editor__content{outline:none;flex-direction:column;min-height:1em;display:flex}.pubwave-editor__content .ProseMirror{min-height:100%;padding-bottom:30vh;padding-top:var(--pubwave-spacing-md,1rem);outline:none;flex-grow:1}.pubwave-editor__content .ProseMirror p.is-editor-empty:first-child:before,.pubwave-editor__content.ProseMirror-focused p.pubwave-editor__node--empty:before,.ProseMirror.ProseMirror-focused p.pubwave-editor__node--empty:before{content:attr(data-placeholder);float:left;color:var(--pubwave-text-muted);pointer-events:none;height:0}.pubwave-editor__content .ProseMirror>*+*{margin-top:.75em}@media (max-width:768px){.pubwave-editor__content .ProseMirror>*+*{margin-top:.35em}.pubwave-editor__content .ProseMirror h1+*,.pubwave-editor__content .ProseMirror h2+*,.pubwave-editor__content .ProseMirror h3+*{margin-top:.4em}.pubwave-editor__content .ProseMirror h1,.pubwave-editor__content .ProseMirror h2,.pubwave-editor__content .ProseMirror h3{margin-top:.6em}.pubwave-editor__content .ProseMirror{font-size:var(--pubwave-font-size-base-mobile,15px)}.pubwave-editor__content .ProseMirror h1{font-size:var(--pubwave-font-size-3xl-mobile,1.75rem)}.pubwave-editor__content .ProseMirror h2{font-size:var(--pubwave-font-size-2xl-mobile,1.375rem)}.pubwave-editor__content .ProseMirror h3{font-size:var(--pubwave-font-size-xl-mobile,1.125rem)}}.pubwave-editor__content .pubwave-editor__bullet-list,.pubwave-editor__content .pubwave-editor__ordered-list{padding-left:1.3em!important}.pubwave-editor__content .ProseMirror p{line-height:var(--pubwave-line-height);margin:0}.pubwave-editor__content .ProseMirror h1,.pubwave-editor__content .ProseMirror h2,.pubwave-editor__content .ProseMirror h3{line-height:var(--pubwave-line-height-heading);margin:0;font-weight:600}.pubwave-editor__content .ProseMirror h1{font-size:var(--pubwave-font-size-3xl)}.pubwave-editor__content .ProseMirror h2{font-size:var(--pubwave-font-size-2xl)}.pubwave-editor__content .ProseMirror h3{font-size:var(--pubwave-font-size-xl)}.pubwave-editor__content .ProseMirror ul:not([data-type=taskList]),.pubwave-editor__content .ProseMirror ol{margin:0;padding-left:1.5em}.pubwave-editor__content .ProseMirror li:not([data-type=taskItem]):not(.pubwave-editor__task-item){margin:.25em 0}.pubwave-editor__content .ProseMirror li>p{margin:0}.pubwave-editor__content ul[data-type=taskList]{padding:var(--pubwave-spacing-4,16px)0;margin:0!important;padding-left:0!important;list-style:none!important}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li,.pubwave-editor__content .ProseMirror ul[data-type=taskList]>li,.pubwave-editor__content .ProseMirror ul[data-type=taskList] li[data-type=taskItem],.pubwave-editor__content .ProseMirror ul[data-type=taskList] li.pubwave-editor__task-item,.pubwave-editor__content .ProseMirror .pubwave-editor__task-item,.pubwave-editor__content.ProseMirror ul[data-type=taskList] li,.ProseMirror.pubwave-editor__content ul[data-type=taskList] li{border-radius:var(--pubwave-radius-sm,4px)!important;-webkit-appearance:none!important;-moz-appearance:none!important;appearance:none!important;flex-direction:row!important;align-items:center!important;gap:.5em!important;margin:0!important;padding:0!important;list-style:none!important;display:flex!important}.pubwave-editor__task-item{height:var(--pubwave-task-item-height,30px)}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li::marker{content:""!important;width:0!important;font-size:0!important;display:none!important}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li[data-type=taskItem]::marker{content:""!important;width:0!important;font-size:0!important;display:none!important}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li.pubwave-editor__task-item::marker{content:""!important;width:0!important;font-size:0!important;display:none!important}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li:before,.pubwave-editor__content .ProseMirror ul[data-type=taskList] li[data-type=taskItem]:before,.pubwave-editor__content .ProseMirror ul[data-type=taskList] li.pubwave-editor__task-item:before{content:""!important;width:0!important;display:none!important}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li:hover,.pubwave-editor__content .ProseMirror ul[data-type=taskList] li.ProseMirror-selectednode{background-color:var(--pubwave-hover-task,#e8f2ff)}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li>label,.pubwave-editor__content .ProseMirror ul[data-type=taskList] li[data-type=taskItem]>label,.pubwave-editor__content .ProseMirror ul[data-type=taskList] li.pubwave-editor__task-item>label{cursor:pointer!important;width:var(--pubwave-checkbox-size,20px)!important;height:var(--pubwave-checkbox-size,20px)!important;min-height:var(--pubwave-checkbox-size,20px)!important;max-height:var(--pubwave-checkbox-size,20px)!important;flex-shrink:0!important;align-self:center!important;margin:0!important;padding:0!important;line-height:1!important;display:block!important;position:relative!important;overflow:hidden!important}li>label input[type=checkbox]{width:var(--pubwave-checkbox-input-size,16px);height:var(--pubwave-checkbox-input-size,16px);cursor:pointer;margin-top:5px}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li>label:before{content:"";width:var(--pubwave-checkbox-size,20px);height:var(--pubwave-checkbox-size,20px);border:1.5px solid var(--pubwave-text,#1a1a1a);border-radius:var(--pubwave-radius-xs,3px);background-color:var(--pubwave-bg,#fff);box-sizing:border-box;transition:all .15s;display:block;position:absolute;top:0;left:0}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li[data-checked=true]>label:before{background-color:var(--pubwave-primary-hover,#2563eb);border-color:var(--pubwave-primary-hover,#2563eb)}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li[data-checked=true]>label:after{content:"";border:solid var(--pubwave-bg,#fff);box-sizing:border-box;z-index:1;border-width:0 2px 2px 0;width:5px;height:10px;position:absolute;top:3px;left:6px;transform:rotate(45deg)}.pubwave-editor__content ul[data-type=taskList] li>div,.pubwave-editor__content ul[data-type=taskList] li[data-type=taskItem]>div,.pubwave-editor__content ul[data-type=taskList] li.pubwave-editor__task-item>div{min-width:0!important;color:var(--pubwave-text,#1a1a1a)!important;flex:1!important;margin:0!important;padding:.1em 0!important;display:block!important}.pubwave-editor__content ul[data-type=taskList] li>div p,.pubwave-editor__content ul[data-type=taskList] li[data-type=taskItem]>div p,.pubwave-editor__content ul[data-type=taskList] li.pubwave-editor__task-item>div p,.pubwave-editor__content ul[data-type=taskList] li>div>p,.pubwave-editor__content ul[data-type=taskList] li>div p.pubwave-editor__paragraph,.pubwave-editor__content ul[data-type=taskList] li[data-type=taskItem]>div p.pubwave-editor__paragraph{width:100%!important;min-height:1.5em!important;margin:0!important;padding:0!important;line-height:1.5!important;display:block!important}.pubwave-editor__content.ProseMirror ul[data-type=taskList] li[data-checked=true]>div p,.pubwave-editor__content ul[data-type=taskList] li[data-checked=true]>div p{color:var(--pubwave-checked-text,#9ca3af)!important;text-decoration:line-through!important}.pubwave-editor__content blockquote,.pubwave-editor__content.ProseMirror blockquote{margin:.5em 0;padding-left:1em;font-style:italic;border-left:3px solid var(--pubwave-text,#1a1a1a)!important}.pubwave-editor__content .ProseMirror pre,.pubwave-editor__content pre{margin:.5em 0;padding:.5em .75em;line-height:1.5;overflow-x:auto;background:var(--pubwave-border-light,#f3f4f6)!important;border-radius:var(--pubwave-radius-md,6px)!important;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important;font-size:var(--pubwave-font-size-sm,13px)!important;color:#1a1a1a!important}.pubwave-editor__content .ProseMirror pre code,.pubwave-editor__content pre code{font-size:inherit!important;color:inherit!important;background:0 0!important;border-radius:0!important;padding:0!important;font-family:inherit!important}.pubwave-block{padding-left:2.5em;position:relative}.pubwave-block-menu{z-index:2;align-items:center;gap:.5em;display:flex;position:absolute;top:50%;left:.5em;transform:translateY(-50%)}.pubwave-editor__content .ProseMirror hr,.pubwave-editor__content hr,.pubwave-editor__content .pubwave-editor__divider{border:none;border-top:1px solid var(--pubwave-border,#e5e7eb)!important;background:0 0!important;height:0!important;margin:1em 0!important}.pubwave-editor__content .ProseMirror img,.pubwave-editor__content img,.pubwave-editor__content .pubwave-editor__image{border-radius:var(--pubwave-radius-md,6px);cursor:pointer;max-width:100%;height:auto;margin:1em auto;transition:opacity .2s;display:block;box-shadow:0 1px 3px #0000001a}.pubwave-editor__content .ProseMirror img:hover,.pubwave-editor__content img:hover,.pubwave-editor__content .pubwave-editor__image:hover{opacity:.9}.pubwave-editor__content .ProseMirror img.ProseMirror-selectednode,.pubwave-editor__content img.ProseMirror-selectednode,.pubwave-editor__content .pubwave-editor__image.ProseMirror-selectednode{outline:2px solid var(--pubwave-primary,#2383e2);outline-offset:2px}.pubwave-editor__content .ProseMirror strong{font-weight:600}.pubwave-editor__content .ProseMirror em{font-style:italic}.pubwave-editor__content .ProseMirror u{text-decoration:underline}.pubwave-editor__content .ProseMirror s{text-decoration:line-through}.pubwave-editor__content .ProseMirror code{background:var(--pubwave-hover);border-radius:var(--pubwave-radius-sm);font-family:var(--pubwave-font-mono);padding:.15em .35em;font-size:.9em}.pubwave-editor__content .ProseMirror a,.pubwave-editor .ProseMirror a{cursor:pointer;text-decoration:underline;color:var(--pubwave-link-color,#2383e2)!important}.pubwave-editor__content .ProseMirror a:hover,.pubwave-editor .ProseMirror a:hover{opacity:.8;color:var(--pubwave-link-hover-color,var(--pubwave-link-color,#2383e2))!important}.pubwave-editor__content .ProseMirror ::-moz-selection{background-color:var(--pubwave-selection-bg)}.pubwave-editor__content .ProseMirror ::selection{background-color:var(--pubwave-selection-bg)}.pubwave-editor--readonly,.pubwave-editor--readonly .pubwave-editor__content{cursor:default}.pubwave-block--dragging{opacity:.4}.pubwave-block--drag-preview{color:var(--pubwave-text-muted,#9b9a97)!important;opacity:.6!important}.pubwave-block--drag-preview div,.pubwave-block--drag-preview p,.pubwave-block--drag-preview label,.pubwave-block--drag-preview .pubwave-editor__task-item>div{color:var(--pubwave-text-muted,#9b9a97)!important}.pubwave-block--drag-preview label input{display:none!important}.pubwave-block--drag-preview label:before{border-color:var(--pubwave-text-muted,#9b9a97)!important;width:16px!important;height:16px!important}.pubwave-block--drag-preview label:after{border-color:var(--pubwave-bg,#fff)!important;top:2px!important;left:4px!important}.ProseMirror .ProseMirror-gapcursor{pointer-events:none;display:none;position:absolute}.ProseMirror .ProseMirror-gapcursor:after{content:"";border-top:1px solid var(--pubwave-text);width:20px;animation:1.1s steps(2,start) infinite pubwave-cursor-blink;display:block;position:absolute;top:-2px}@keyframes pubwave-cursor-blink{to{visibility:hidden}}.ProseMirror-focused .ProseMirror-gapcursor{display:block}.tippy-box{z-index:var(--pubwave-z-dropdown,60)!important;background:0 0!important;border:none!important}.tippy-box:has(.pubwave-slash-menu){background:0 0!important;border:none!important}.pubwave-slash-menu{border:1px solid var(--pubwave-border,#e3e2e0)!important}.ProseMirror-dropcursor{border-left:2px solid var(--pubwave-primary);pointer-events:none}.pubwave-editor .ProseMirror .suggestion{border:1px solid var(--pubwave-border,#e3e2e0)!important;border-radius:var(--pubwave-radius-md,6px)!important;color:#1f2937!important;background-color:#fffffff2!important;padding:2px 4px!important;display:inline-block!important}.pubwave-editor .ProseMirror .suggestion,.pubwave-editor .ProseMirror .suggestion *,.pubwave-editor .ProseMirror .suggestion span,.pubwave-editor .ProseMirror .suggestion strong,.pubwave-editor .ProseMirror .suggestion em,.pubwave-editor .ProseMirror .suggestion code{color:#1f2937!important}.tippy-box,.tippy-box[data-theme]{z-index:60!important}.tippy-box[data-theme~=pubwave]{box-shadow:none;background:0 0;border:none}.tippy-box[data-theme~=pubwave] .tippy-content{padding:0}.tippy-box[data-theme~=light-border]{border-radius:var(--pubwave-radius,6px);box-shadow:var(--pubwave-shadow-md,0 4px 6px -1px #0000001a);padding:4px 8px;font-size:12px;color:#fff!important;background-color:#000!important;border:none!important}.tippy-box[data-theme~=light-border] .tippy-content{color:#fff!important}.pubwave-block-handle__drag,.pubwave-block-handle__add{color:var(--pubwave-text-muted,#9b9a97)!important}.pubwave-toolbar__button:not(:disabled):hover,.pubwave-toolbar__turn-into-option:not(.pubwave-toolbar__turn-into-option--active):hover{background-color:var(--pubwave-hover)!important}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}
|
|
2
|
+
@layer properties{@supports ((-webkit-hyphens:none) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.isolate{isolation:isolate}.container{width:100%}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.resize{resize:both}.border{border-style:var(--tw-border-style);border-width:1px}.uppercase{text-transform:uppercase}.italic{font-style:italic}.underline{text-decoration-line:underline}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}:root{--pubwave-bg:#fff;--pubwave-surface:#fff;--pubwave-text:#37352f;--pubwave-text-muted:#9b9a97;--pubwave-border:#e3e2e0;--pubwave-border-light:#f3f4f6;--pubwave-hover:#f7f6f3;--pubwave-focus:#0000000d;--pubwave-selection:#3b82f6;--pubwave-selection-bg:#2383e226;--pubwave-primary:#2383e2;--pubwave-primary-hover:#2563eb;--pubwave-handle-color:#9b9a97;--pubwave-primary-faded:#3b82f61a;--pubwave-drop-indicator:#3b82f6;--pubwave-drop-target:#3b82f60d;--pubwave-error:#ef4444;--pubwave-success:#10b981;--pubwave-warning:#f59e0b;--pubwave-text-secondary:#374151;--pubwave-text-tertiary:#4b5563;--pubwave-hover-bg:#f3f4f6;--pubwave-hover-task:#e8f2ff;--pubwave-checked-text:#9ca3af;--pubwave-spacing-xs:.25rem;--pubwave-spacing-sm:.5rem;--pubwave-spacing-md:1rem;--pubwave-spacing-lg:1.5rem;--pubwave-spacing-xl:2rem;--pubwave-spacing-1:4px;--pubwave-spacing-2:8px;--pubwave-spacing-3:12px;--pubwave-spacing-4:16px;--pubwave-spacing-7:28px;--pubwave-font-family:inherit;--pubwave-font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--pubwave-font-size-xs:11px;--pubwave-font-size-sm:13px;--pubwave-font-size-base:14px;--pubwave-font-size-md:1rem;--pubwave-font-size-lg:1.125rem;--pubwave-font-size-xl:1.25rem;--pubwave-font-size-2xl:1.5rem;--pubwave-font-size-3xl:2rem;--pubwave-line-height:1.625;--pubwave-line-height-heading:1.25;--pubwave-button-width:28px;--pubwave-button-height:28px;--pubwave-icon-size:20px;--pubwave-checkbox-size:20px;--pubwave-checkbox-input-size:16px;--pubwave-divider-width:1px;--pubwave-divider-height:20px;--pubwave-drop-indicator-width:2px;--pubwave-drop-indicator-height:2px;--pubwave-task-item-height:30px;--pubwave-radius-xs:3px;--pubwave-radius-sm:4px;--pubwave-radius:6px;--pubwave-radius-md:6px;--pubwave-radius-lg:8px;--pubwave-shadow-sm:0 1px 2px 0 #0000000d;--pubwave-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f;--pubwave-shadow-lg:0 10px 15px -3px #0000001a,0 4px 6px -2px #0000000d}@media (prefers-color-scheme:dark){:root{--pubwave-bg:#1a1a1a;--pubwave-surface:#262626;--pubwave-text:#e5e7eb;--pubwave-text-muted:#9ca3af;--pubwave-border:#374151;--pubwave-border-light:#4b5563;--pubwave-hover:#ffffff0d;--pubwave-focus:#ffffff14;--pubwave-selection:#60a5fa;--pubwave-selection-bg:#60a5fa26;--pubwave-primary:#60a5fa;--pubwave-primary-hover:#3b82f6;--pubwave-primary-faded:#60a5fa26;--pubwave-drop-indicator:#60a5fa;--pubwave-drop-target:#60a5fa14;--pubwave-error:#f87171;--pubwave-text-secondary:#d1d5db;--pubwave-text-tertiary:#9ca3af;--pubwave-hover-bg:#374151;--pubwave-hover-task:#3b82f626;--pubwave-checked-text:#6b7280}}.pubwave-editor{width:var(--pubwave-container-width,100%);max-width:var(--pubwave-container-max-width,none);font-family:var(--pubwave-font-family);color:var(--pubwave-text);background:var(--pubwave-bg,#fff);border-radius:var(--pubwave-container-border-radius,16px);min-height:var(--pubwave-container-min-height,700px);padding:var(--pubwave-container-padding-y,96px)var(--pubwave-container-padding-x,120px);padding-left:var(--pubwave-container-padding-left,140px);position:relative;box-shadow:0 0 0 1px #0000000a,0 20px 25px -5px #0000000d,0 10px 10px -5px #00000005}@media (max-width:768px){.pubwave-editor{padding:var(--pubwave-container-padding-y-mobile,20px)var(--pubwave-container-padding-x-mobile,16px);padding-left:var(--pubwave-container-padding-left-mobile,16px);border-radius:var(--pubwave-container-border-radius-mobile,12px);min-height:var(--pubwave-container-min-height-mobile,400px)}}.pubwave-editor,.pubwave-editor *,.pubwave-editor :before,.pubwave-editor :after{box-sizing:border-box}.pubwave-editor__content{outline:none;flex-direction:column;min-height:1em;display:flex}.pubwave-editor__content .ProseMirror{min-height:100%;padding-bottom:30vh;padding-top:var(--pubwave-spacing-md,1rem);outline:none;flex-grow:1}.pubwave-editor__content .ProseMirror p.is-editor-empty:first-child:before,.pubwave-editor__content.ProseMirror-focused p.pubwave-editor__node--empty:before,.ProseMirror.ProseMirror-focused p.pubwave-editor__node--empty:before{content:attr(data-placeholder);float:left;color:var(--pubwave-text-muted);pointer-events:none;height:0}.pubwave-editor__content .ProseMirror>*+*{margin-top:.75em}@media (max-width:768px){.pubwave-editor__content .ProseMirror>*+*{margin-top:.35em}.pubwave-editor__content .ProseMirror h1+*,.pubwave-editor__content .ProseMirror h2+*,.pubwave-editor__content .ProseMirror h3+*{margin-top:.4em}.pubwave-editor__content .ProseMirror h1,.pubwave-editor__content .ProseMirror h2,.pubwave-editor__content .ProseMirror h3{margin-top:.6em}.pubwave-editor__content .ProseMirror{font-size:var(--pubwave-font-size-base-mobile,15px)}.pubwave-editor__content .ProseMirror h1{font-size:var(--pubwave-font-size-3xl-mobile,1.75rem)}.pubwave-editor__content .ProseMirror h2{font-size:var(--pubwave-font-size-2xl-mobile,1.375rem)}.pubwave-editor__content .ProseMirror h3{font-size:var(--pubwave-font-size-xl-mobile,1.125rem)}}.pubwave-editor__content .pubwave-editor__bullet-list,.pubwave-editor__content .pubwave-editor__ordered-list{padding-left:1.3em!important}.pubwave-editor__content .ProseMirror p{line-height:var(--pubwave-line-height);margin:0}.pubwave-editor__content .ProseMirror h1,.pubwave-editor__content .ProseMirror h2,.pubwave-editor__content .ProseMirror h3{line-height:var(--pubwave-line-height-heading);margin:0;font-weight:600}.pubwave-editor__content .ProseMirror h1{font-size:var(--pubwave-font-size-3xl)}.pubwave-editor__content .ProseMirror h2{font-size:var(--pubwave-font-size-2xl)}.pubwave-editor__content .ProseMirror h3{font-size:var(--pubwave-font-size-xl)}.pubwave-editor__content .ProseMirror ul:not([data-type=taskList]),.pubwave-editor__content .ProseMirror ol{margin:0;padding-left:1.5em}.pubwave-editor__content .ProseMirror li:not([data-type=taskItem]):not(.pubwave-editor__task-item){margin:.25em 0}.pubwave-editor__content .ProseMirror li>p{margin:0}.pubwave-editor__content ul[data-type=taskList]{padding:var(--pubwave-spacing-4,16px)0;margin:0!important;padding-left:0!important;list-style:none!important}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li,.pubwave-editor__content .ProseMirror ul[data-type=taskList]>li,.pubwave-editor__content .ProseMirror ul[data-type=taskList] li[data-type=taskItem],.pubwave-editor__content .ProseMirror ul[data-type=taskList] li.pubwave-editor__task-item,.pubwave-editor__content .ProseMirror .pubwave-editor__task-item,.pubwave-editor__content.ProseMirror ul[data-type=taskList] li,.ProseMirror.pubwave-editor__content ul[data-type=taskList] li{border-radius:var(--pubwave-radius-sm,4px)!important;-webkit-appearance:none!important;-moz-appearance:none!important;appearance:none!important;flex-direction:row!important;align-items:center!important;gap:.5em!important;margin:0!important;padding:0!important;list-style:none!important;display:flex!important}.pubwave-editor__task-item{height:var(--pubwave-task-item-height,30px)}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li::marker{content:""!important;width:0!important;font-size:0!important;display:none!important}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li[data-type=taskItem]::marker{content:""!important;width:0!important;font-size:0!important;display:none!important}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li.pubwave-editor__task-item::marker{content:""!important;width:0!important;font-size:0!important;display:none!important}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li:before,.pubwave-editor__content .ProseMirror ul[data-type=taskList] li[data-type=taskItem]:before,.pubwave-editor__content .ProseMirror ul[data-type=taskList] li.pubwave-editor__task-item:before{content:""!important;width:0!important;display:none!important}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li:hover,.pubwave-editor__content .ProseMirror ul[data-type=taskList] li.ProseMirror-selectednode{background-color:var(--pubwave-hover-task,#e8f2ff)}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li>label,.pubwave-editor__content .ProseMirror ul[data-type=taskList] li[data-type=taskItem]>label,.pubwave-editor__content .ProseMirror ul[data-type=taskList] li.pubwave-editor__task-item>label{cursor:pointer!important;width:var(--pubwave-checkbox-size,20px)!important;height:var(--pubwave-checkbox-size,20px)!important;min-height:var(--pubwave-checkbox-size,20px)!important;max-height:var(--pubwave-checkbox-size,20px)!important;flex-shrink:0!important;align-self:center!important;margin:0!important;padding:0!important;line-height:1!important;display:block!important;position:relative!important;overflow:hidden!important}li>label input[type=checkbox]{width:var(--pubwave-checkbox-input-size,16px);height:var(--pubwave-checkbox-input-size,16px);cursor:pointer;margin-top:5px}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li>label:before{content:"";width:var(--pubwave-checkbox-size,20px);height:var(--pubwave-checkbox-size,20px);border:1.5px solid var(--pubwave-text,#1a1a1a);border-radius:var(--pubwave-radius-xs,3px);background-color:var(--pubwave-bg,#fff);box-sizing:border-box;transition:all .15s;display:block;position:absolute;top:0;left:0}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li[data-checked=true]>label:before{background-color:var(--pubwave-primary-hover,#2563eb);border-color:var(--pubwave-primary-hover,#2563eb)}.pubwave-editor__content .ProseMirror ul[data-type=taskList] li[data-checked=true]>label:after{content:"";border:solid var(--pubwave-bg,#fff);box-sizing:border-box;z-index:1;border-width:0 2px 2px 0;width:5px;height:10px;position:absolute;top:3px;left:6px;transform:rotate(45deg)}.pubwave-editor__content ul[data-type=taskList] li>div,.pubwave-editor__content ul[data-type=taskList] li[data-type=taskItem]>div,.pubwave-editor__content ul[data-type=taskList] li.pubwave-editor__task-item>div{min-width:0!important;color:var(--pubwave-text,#1a1a1a)!important;flex:1!important;margin:0!important;padding:.1em 0!important;display:block!important}.pubwave-editor__content ul[data-type=taskList] li>div p,.pubwave-editor__content ul[data-type=taskList] li[data-type=taskItem]>div p,.pubwave-editor__content ul[data-type=taskList] li.pubwave-editor__task-item>div p,.pubwave-editor__content ul[data-type=taskList] li>div>p,.pubwave-editor__content ul[data-type=taskList] li>div p.pubwave-editor__paragraph,.pubwave-editor__content ul[data-type=taskList] li[data-type=taskItem]>div p.pubwave-editor__paragraph{width:100%!important;min-height:1.5em!important;margin:0!important;padding:0!important;line-height:1.5!important;display:block!important}.pubwave-editor__content.ProseMirror ul[data-type=taskList] li[data-checked=true]>div p,.pubwave-editor__content ul[data-type=taskList] li[data-checked=true]>div p{color:var(--pubwave-checked-text,#9ca3af)!important;text-decoration:line-through!important}.pubwave-editor__content blockquote,.pubwave-editor__content.ProseMirror blockquote{margin:.5em 0;padding-left:1em;font-style:italic;border-left:3px solid var(--pubwave-text,#1a1a1a)!important}.pubwave-editor__content .ProseMirror pre,.pubwave-editor__content pre{margin:.5em 0;padding:.5em .75em;line-height:1.5;overflow-x:auto;background:var(--pubwave-border-light,#f3f4f6)!important;border-radius:var(--pubwave-radius-md,6px)!important;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important;font-size:var(--pubwave-font-size-sm,13px)!important;color:#1a1a1a!important}.pubwave-editor__content .ProseMirror pre code,.pubwave-editor__content pre code{font-size:inherit!important;color:inherit!important;background:0 0!important;border-radius:0!important;padding:0!important;font-family:inherit!important}.pubwave-block{padding-left:2.5em;position:relative}.pubwave-block-menu{z-index:2;align-items:center;gap:.5em;display:flex;position:absolute;top:50%;left:.5em;transform:translateY(-50%)}.pubwave-editor__content .ProseMirror hr,.pubwave-editor__content hr,.pubwave-editor__content .pubwave-editor__divider{border:none;border-top:1px solid var(--pubwave-border,#e5e7eb)!important;background:0 0!important;height:0!important;margin:1em 0!important}.pubwave-editor__content .ProseMirror img,.pubwave-editor__content img,.pubwave-editor__content .pubwave-editor__image{border-radius:var(--pubwave-radius-md,6px);cursor:pointer;max-width:100%;height:auto;margin:1em auto;transition:opacity .2s;display:block;box-shadow:0 1px 3px #0000001a}.pubwave-editor__content .ProseMirror img:hover,.pubwave-editor__content img:hover,.pubwave-editor__content .pubwave-editor__image:hover{opacity:.9}.pubwave-editor__content .ProseMirror img.ProseMirror-selectednode,.pubwave-editor__content img.ProseMirror-selectednode,.pubwave-editor__content .pubwave-editor__image.ProseMirror-selectednode{outline:2px solid var(--pubwave-primary,#2383e2);outline-offset:2px}.pubwave-editor__content .ProseMirror strong{font-weight:600}.pubwave-editor__content .ProseMirror em{font-style:italic}.pubwave-editor__content .ProseMirror u{text-decoration:underline}.pubwave-editor__content .ProseMirror s{text-decoration:line-through}.pubwave-editor__content .ProseMirror code{background:var(--pubwave-hover);border-radius:var(--pubwave-radius-sm);font-family:var(--pubwave-font-mono);padding:.15em .35em;font-size:.9em}.pubwave-editor__content .ProseMirror a,.pubwave-editor .ProseMirror a{cursor:pointer;text-decoration:underline;color:var(--pubwave-link-color,#2383e2)!important}.pubwave-editor__content .ProseMirror a:hover,.pubwave-editor .ProseMirror a:hover{opacity:.8;color:var(--pubwave-link-hover-color,var(--pubwave-link-color,#2383e2))!important}.pubwave-editor__content .ProseMirror ::-moz-selection{background-color:var(--pubwave-selection-bg)}.pubwave-editor__content .ProseMirror ::selection{background-color:var(--pubwave-selection-bg)}.pubwave-editor--readonly,.pubwave-editor--readonly .pubwave-editor__content{cursor:default}.pubwave-block--dragging{opacity:.4}.pubwave-block--drag-preview{color:var(--pubwave-text-muted,#9b9a97)!important;opacity:.6!important}.pubwave-block--drag-preview div,.pubwave-block--drag-preview p,.pubwave-block--drag-preview label,.pubwave-block--drag-preview .pubwave-editor__task-item>div{color:var(--pubwave-text-muted,#9b9a97)!important}.pubwave-block--drag-preview label input{display:none!important}.pubwave-block--drag-preview label:before{border-color:var(--pubwave-text-muted,#9b9a97)!important;width:16px!important;height:16px!important}.pubwave-block--drag-preview label:after{border-color:var(--pubwave-bg,#fff)!important;top:2px!important;left:4px!important}.ProseMirror .ProseMirror-gapcursor{pointer-events:none;display:none;position:absolute}.ProseMirror .ProseMirror-gapcursor:after{content:"";border-top:1px solid var(--pubwave-text);width:20px;animation:1.1s steps(2,start) infinite pubwave-cursor-blink;display:block;position:absolute;top:-2px}@keyframes pubwave-cursor-blink{to{visibility:hidden}}.ProseMirror-focused .ProseMirror-gapcursor{display:block}.tippy-box{z-index:var(--pubwave-z-dropdown,60)!important;background:0 0!important;border:none!important}.tippy-box:has(.pubwave-slash-menu){background:0 0!important;border:none!important}.pubwave-slash-menu{border:1px solid var(--pubwave-border,#e3e2e0)!important}.ProseMirror-dropcursor{border-left:2px solid var(--pubwave-primary);pointer-events:none}.pubwave-editor .ProseMirror .suggestion{border:1px solid var(--pubwave-border,#e3e2e0)!important;border-radius:var(--pubwave-radius-md,6px)!important;color:#1f2937!important;background-color:#fffffff2!important;padding:2px 4px!important;display:inline-block!important}.pubwave-editor .ProseMirror .suggestion,.pubwave-editor .ProseMirror .suggestion *,.pubwave-editor .ProseMirror .suggestion span,.pubwave-editor .ProseMirror .suggestion strong,.pubwave-editor .ProseMirror .suggestion em,.pubwave-editor .ProseMirror .suggestion code{color:#1f2937!important}.tippy-box,.tippy-box[data-theme]{z-index:60!important}.tippy-box[data-theme~=pubwave]{box-shadow:none;background:0 0;border:none}.tippy-box[data-theme~=pubwave] .tippy-content{padding:0}.tippy-box[data-theme~=light-border]{border-radius:var(--pubwave-radius,6px);box-shadow:var(--pubwave-shadow-md,0 4px 6px -1px #0000001a);padding:4px 8px;font-size:12px;color:#fff!important;background-color:#000!important;border:none!important}.tippy-box[data-theme~=light-border] .tippy-content{color:#fff!important}.pubwave-block-handle__drag,.pubwave-block-handle__add{color:var(--pubwave-text-muted,#9b9a97)!important}.pubwave-toolbar__button:not(:disabled):hover,.pubwave-toolbar__turn-into-option:not(.pubwave-toolbar__turn-into-option--active):hover{background-color:var(--pubwave-hover)!important}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}
|
package/dist/index.d.ts
CHANGED
|
@@ -759,6 +759,19 @@ export declare function isEditorValid(editor: Editor_2 | null): editor is Editor
|
|
|
759
759
|
*/
|
|
760
760
|
export declare function isMarkActive(editor: Editor_2, markType: string): boolean;
|
|
761
761
|
|
|
762
|
+
/**
|
|
763
|
+
* Check if the device is a mobile/touch device
|
|
764
|
+
* Returns true for mobile devices, false for desktop
|
|
765
|
+
*
|
|
766
|
+
* This function safely checks for mobile device characteristics:
|
|
767
|
+
* - Touch support
|
|
768
|
+
* - Coarse pointer type (touch screen)
|
|
769
|
+
* - Hover capability (mobile devices typically don't support hover)
|
|
770
|
+
*
|
|
771
|
+
* @returns true if the device appears to be a mobile/touch device, false otherwise
|
|
772
|
+
*/
|
|
773
|
+
export declare function isMobileDevice(): boolean;
|
|
774
|
+
|
|
762
775
|
/**
|
|
763
776
|
* Check if a node type is currently active
|
|
764
777
|
*/
|
package/dist/index.js
CHANGED
|
@@ -461,6 +461,13 @@ function safeRequestAnimationFrame(callback) {
|
|
|
461
461
|
}
|
|
462
462
|
return 0;
|
|
463
463
|
}
|
|
464
|
+
function isMobileDevice() {
|
|
465
|
+
if (!canUseDOM) return false;
|
|
466
|
+
const hasTouchSupport = "ontouchstart" in window || navigator.maxTouchPoints > 0;
|
|
467
|
+
const hasCoarsePointer = window.matchMedia("(pointer: coarse)").matches;
|
|
468
|
+
const hasHover = window.matchMedia("(hover: hover)").matches;
|
|
469
|
+
return hasTouchSupport && hasCoarsePointer || hasTouchSupport && !hasHover;
|
|
470
|
+
}
|
|
464
471
|
function TextIcon() {
|
|
465
472
|
return /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "M4 7V4h16v3M9 20h6M12 4v16" }) });
|
|
466
473
|
}
|
|
@@ -4845,6 +4852,89 @@ function calculateVerticalPositionFromRect(triggerRect, dropdownHeight, margin =
|
|
|
4845
4852
|
margin
|
|
4846
4853
|
);
|
|
4847
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
|
+
}
|
|
4848
4938
|
function PositionedDropdown({
|
|
4849
4939
|
isOpen,
|
|
4850
4940
|
buttonRef,
|
|
@@ -4857,7 +4947,8 @@ function PositionedDropdown({
|
|
|
4857
4947
|
onClick,
|
|
4858
4948
|
"data-testid": dataTestId
|
|
4859
4949
|
}) {
|
|
4860
|
-
const [
|
|
4950
|
+
const [verticalPosition, setVerticalPosition] = useState("top");
|
|
4951
|
+
const [horizontalPosition, setHorizontalPosition] = useState(null);
|
|
4861
4952
|
const dropdownRef = useRef(null);
|
|
4862
4953
|
useEffect(() => {
|
|
4863
4954
|
if (!isOpen || !buttonRef.current) return;
|
|
@@ -4865,15 +4956,37 @@ function PositionedDropdown({
|
|
|
4865
4956
|
if (!dropdownRef.current || !buttonRef.current) return;
|
|
4866
4957
|
const buttonRect = buttonRef.current.getBoundingClientRect();
|
|
4867
4958
|
const dropdownHeight = dropdownRef.current.offsetHeight || 300;
|
|
4868
|
-
const
|
|
4869
|
-
|
|
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
|
+
}
|
|
4870
4983
|
};
|
|
4871
4984
|
checkPosition();
|
|
4872
4985
|
const rafId = requestAnimationFrame(() => {
|
|
4873
4986
|
checkPosition();
|
|
4874
4987
|
});
|
|
4875
4988
|
return () => cancelAnimationFrame(rafId);
|
|
4876
|
-
}, [isOpen, buttonRef, margin]);
|
|
4989
|
+
}, [isOpen, buttonRef, margin, align]);
|
|
4877
4990
|
useEffect(() => {
|
|
4878
4991
|
if (!isOpen || !onClickOutside2) return;
|
|
4879
4992
|
const handleClickOutside = (event) => {
|
|
@@ -4888,6 +5001,11 @@ function PositionedDropdown({
|
|
|
4888
5001
|
}, [isOpen, onClickOutside2, buttonRef]);
|
|
4889
5002
|
if (!isOpen) return null;
|
|
4890
5003
|
const getHorizontalStyle = () => {
|
|
5004
|
+
if (horizontalPosition) {
|
|
5005
|
+
return {
|
|
5006
|
+
left: `${horizontalPosition.left}px`
|
|
5007
|
+
};
|
|
5008
|
+
}
|
|
4891
5009
|
switch (align) {
|
|
4892
5010
|
case "center":
|
|
4893
5011
|
return {
|
|
@@ -4913,7 +5031,7 @@ function PositionedDropdown({
|
|
|
4913
5031
|
"data-testid": dataTestId,
|
|
4914
5032
|
style: {
|
|
4915
5033
|
position: "absolute",
|
|
4916
|
-
...
|
|
5034
|
+
...verticalPosition === "top" ? {
|
|
4917
5035
|
bottom: "100%",
|
|
4918
5036
|
marginBottom: `${margin}px`
|
|
4919
5037
|
} : {
|
|
@@ -5983,8 +6101,6 @@ function calculatePosition(editor, toolbarEl) {
|
|
|
5983
6101
|
const toolbarRect = toolbarEl.getBoundingClientRect();
|
|
5984
6102
|
const toolbarWidth = toolbarRect.width;
|
|
5985
6103
|
const toolbarHeight = toolbarRect.height;
|
|
5986
|
-
const centerX = (selectionLeft + selectionRight) / 2;
|
|
5987
|
-
let left2 = centerX - toolbarWidth / 2;
|
|
5988
6104
|
const selectionBottom = Math.max(start2.bottom, end2.bottom);
|
|
5989
6105
|
const verticalPosition = calculateVerticalPosition(
|
|
5990
6106
|
selectionTop,
|
|
@@ -5998,20 +6114,21 @@ function calculatePosition(editor, toolbarEl) {
|
|
|
5998
6114
|
} else {
|
|
5999
6115
|
top2 = selectionBottom + TOOLBAR_OFFSET;
|
|
6000
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;
|
|
6001
6126
|
const viewportWidth = window.innerWidth;
|
|
6002
6127
|
const viewportHeight = window.innerHeight;
|
|
6003
|
-
const padding =
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
left2 = viewportWidth - toolbarWidth - padding;
|
|
6008
|
-
}
|
|
6009
|
-
if (top2 < padding) {
|
|
6010
|
-
top2 = padding;
|
|
6011
|
-
} else if (top2 + toolbarHeight > viewportHeight - padding) {
|
|
6012
|
-
top2 = viewportHeight - toolbarHeight - padding;
|
|
6013
|
-
}
|
|
6014
|
-
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 };
|
|
6015
6132
|
}
|
|
6016
6133
|
function BubbleToolbar({
|
|
6017
6134
|
editor,
|
|
@@ -6256,6 +6373,7 @@ function BubbleToolbar({
|
|
|
6256
6373
|
}
|
|
6257
6374
|
);
|
|
6258
6375
|
}
|
|
6376
|
+
const MIN_WINDOW_WIDTH = 768;
|
|
6259
6377
|
function getClosestBlock(target, proseMirror, editor) {
|
|
6260
6378
|
if (!target || !(target instanceof Node)) return null;
|
|
6261
6379
|
try {
|
|
@@ -6300,18 +6418,33 @@ function BlockHandle({ editor }) {
|
|
|
6300
6418
|
const [visible, setVisible] = useState(false);
|
|
6301
6419
|
const [isDragging, setIsDragging] = useState(false);
|
|
6302
6420
|
const [position, setPosition] = useState({ top: 0 });
|
|
6421
|
+
const [isMobile, setIsMobile] = useState(false);
|
|
6422
|
+
const [isWindowTooSmall, setIsWindowTooSmall] = useState(false);
|
|
6423
|
+
useEffect(() => {
|
|
6424
|
+
const checkDeviceAndWindow = () => {
|
|
6425
|
+
setIsMobile(isMobileDevice());
|
|
6426
|
+
setIsWindowTooSmall(window.innerWidth < MIN_WINDOW_WIDTH);
|
|
6427
|
+
};
|
|
6428
|
+
checkDeviceAndWindow();
|
|
6429
|
+
window.addEventListener("resize", checkDeviceAndWindow);
|
|
6430
|
+
return () => {
|
|
6431
|
+
window.removeEventListener("resize", checkDeviceAndWindow);
|
|
6432
|
+
};
|
|
6433
|
+
}, []);
|
|
6303
6434
|
const updatePosition = useCallback(() => {
|
|
6304
6435
|
const container = containerRef.current;
|
|
6305
6436
|
const block = currentBlockRef.current;
|
|
6306
6437
|
if (!container || !block) return;
|
|
6307
6438
|
const editorContainer = container.closest(".pubwave-editor");
|
|
6308
6439
|
if (!editorContainer) return;
|
|
6440
|
+
void editorContainer.offsetHeight;
|
|
6309
6441
|
const editorRect = editorContainer.getBoundingClientRect();
|
|
6310
6442
|
let offset2 = 14;
|
|
6311
6443
|
let target = block;
|
|
6312
6444
|
if (["UL", "OL", "BLOCKQUOTE"].includes(block.tagName) && block.firstElementChild instanceof HTMLElement) {
|
|
6313
6445
|
target = block.firstElementChild;
|
|
6314
6446
|
}
|
|
6447
|
+
void target.offsetHeight;
|
|
6315
6448
|
const targetRect = target.getBoundingClientRect();
|
|
6316
6449
|
try {
|
|
6317
6450
|
const style = window.getComputedStyle(target);
|
|
@@ -6330,12 +6463,18 @@ function BlockHandle({ editor }) {
|
|
|
6330
6463
|
} catch (e) {
|
|
6331
6464
|
}
|
|
6332
6465
|
const top2 = targetRect.top - editorRect.top + offset2;
|
|
6333
|
-
|
|
6466
|
+
if (!isNaN(top2) && isFinite(top2) && top2 >= 0) {
|
|
6467
|
+
setPosition({ top: top2 });
|
|
6468
|
+
}
|
|
6334
6469
|
}, []);
|
|
6335
6470
|
const showHandle = useCallback((block) => {
|
|
6336
6471
|
currentBlockRef.current = block;
|
|
6337
6472
|
setVisible(true);
|
|
6338
|
-
|
|
6473
|
+
requestAnimationFrame(() => {
|
|
6474
|
+
requestAnimationFrame(() => {
|
|
6475
|
+
updatePosition();
|
|
6476
|
+
});
|
|
6477
|
+
});
|
|
6339
6478
|
}, [updatePosition]);
|
|
6340
6479
|
const hideHandle = useCallback(() => {
|
|
6341
6480
|
if (!isDraggingRef.current) {
|
|
@@ -6397,8 +6536,16 @@ function BlockHandle({ editor }) {
|
|
|
6397
6536
|
hideHandle();
|
|
6398
6537
|
}, 150);
|
|
6399
6538
|
};
|
|
6539
|
+
const onEditorMouseLeave = () => {
|
|
6540
|
+
if (isDraggingRef.current) return;
|
|
6541
|
+
clearHideTimeout();
|
|
6542
|
+
hideTimeoutRef.current = setTimeout(() => {
|
|
6543
|
+
hideHandle();
|
|
6544
|
+
}, 150);
|
|
6545
|
+
};
|
|
6400
6546
|
proseMirror.addEventListener("mouseover", onMouseOver);
|
|
6401
6547
|
proseMirror.addEventListener("mouseout", onMouseOut);
|
|
6548
|
+
editorContainer.addEventListener("mouseleave", onEditorMouseLeave);
|
|
6402
6549
|
const handleTransaction = ({ transaction }) => {
|
|
6403
6550
|
if (transaction.docChanged && !isDraggingRef.current) {
|
|
6404
6551
|
hideHandle();
|
|
@@ -6408,10 +6555,20 @@ function BlockHandle({ editor }) {
|
|
|
6408
6555
|
return () => {
|
|
6409
6556
|
proseMirror.removeEventListener("mouseover", onMouseOver);
|
|
6410
6557
|
proseMirror.removeEventListener("mouseout", onMouseOut);
|
|
6558
|
+
editorContainer.removeEventListener("mouseleave", onEditorMouseLeave);
|
|
6411
6559
|
editor.off("transaction", handleTransaction);
|
|
6412
6560
|
clearHideTimeout();
|
|
6413
6561
|
};
|
|
6414
6562
|
}, [editor, showHandle, hideHandle, clearHideTimeout]);
|
|
6563
|
+
useEffect(() => {
|
|
6564
|
+
if (visible && currentBlockRef.current) {
|
|
6565
|
+
requestAnimationFrame(() => {
|
|
6566
|
+
requestAnimationFrame(() => {
|
|
6567
|
+
updatePosition();
|
|
6568
|
+
});
|
|
6569
|
+
});
|
|
6570
|
+
}
|
|
6571
|
+
}, [visible, updatePosition]);
|
|
6415
6572
|
useEffect(() => {
|
|
6416
6573
|
if (!visible) return;
|
|
6417
6574
|
const onScroll = () => {
|
|
@@ -6506,7 +6663,7 @@ function BlockHandle({ editor }) {
|
|
|
6506
6663
|
}
|
|
6507
6664
|
setVisible(false);
|
|
6508
6665
|
}, []);
|
|
6509
|
-
if (!visible) return null;
|
|
6666
|
+
if (isMobile || isWindowTooSmall || !visible) return null;
|
|
6510
6667
|
return /* @__PURE__ */ jsxs(
|
|
6511
6668
|
"div",
|
|
6512
6669
|
{
|
|
@@ -7514,6 +7671,7 @@ export {
|
|
|
7514
7671
|
isEditable,
|
|
7515
7672
|
isEditorValid,
|
|
7516
7673
|
isMarkActive,
|
|
7674
|
+
isMobileDevice,
|
|
7517
7675
|
isNodeActive,
|
|
7518
7676
|
isReadOnly,
|
|
7519
7677
|
isSSR,
|