UNPKG

@explita/editor

Version:

`@explita/editor` is a versatile, modern rich-text editor built on TipTap for seamless integration into React applications. It provides extensive customization options and advanced features to cater to diverse content creation needs.

92 lines (91 loc) 5.33 kB
"use client"; import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; import { useEffect, useRef, useState } from "react"; import { DEFAULT_MARGIN, INCH_TO_PX, MIN_SPACE } from "../lib/constants"; import { useEditorStore } from "../store/useEditorState"; import { PagePadding } from "./PagePadding"; const markers = Array.from({ length: 83 }, (_, i) => i); export function Ruler() { const { editorOpts, setEditorOpts } = useEditorStore(); const [isDraggingLeft, setIsDraggingLeft] = useState(false); const [isDraggingRight, setIsDraggingRight] = useState(false); const [isDialogOpen, setIsDialogOpen] = useState(false); const [rulerWidth, setRulerWidth] = useState(0); const rulerRef = useRef(null); useEffect(() => { const editorContent = document.querySelector(".editor-content"); setRulerWidth(editorContent?.clientWidth || 0); }, []); function handlePagePadding(section, value) { setEditorOpts((prev) => ({ ...prev, padding: { ...prev.padding, [section]: value, }, })); } function handleLeftMouseDown() { setIsDraggingLeft(true); } function handleRightMouseDown() { setIsDraggingRight(true); } function handleMouseMove(e) { if ((isDraggingLeft || isDraggingRight) && rulerRef.current) { const container = rulerRef.current.querySelector(".ruler-container"); if (container) { const containerRect = container.getBoundingClientRect(); const relativeX = e.clientX - containerRect.left; const rawPosition = Math.max(0, Math.min(rulerWidth, relativeX)); if (isDraggingLeft) { const maxLeftPosition = rulerWidth - (editorOpts.padding.right || 0) - MIN_SPACE; const newLeftPosition = Math.min(maxLeftPosition, rawPosition); handlePagePadding("left", newLeftPosition / INCH_TO_PX); } else if (isDraggingRight) { const maxRightPosition = rulerWidth - ((editorOpts.padding.left || 0) + MIN_SPACE); const newRightPosition = Math.max(rulerWidth - rawPosition, 0); const contraintRightPosition = Math.min(maxRightPosition, newRightPosition); handlePagePadding("right", contraintRightPosition / INCH_TO_PX); } } } } function handleMouseUp() { setIsDraggingLeft(false); setIsDraggingRight(false); } function handleLeftDoubleClick() { handlePagePadding("left", DEFAULT_MARGIN * INCH_TO_PX); } function handleRightDoubleClick() { handlePagePadding("right", DEFAULT_MARGIN * INCH_TO_PX); } return (_jsxs(_Fragment, { children: [_jsx(PagePadding, { opened: isDialogOpen, setOpened: setIsDialogOpen }), _jsx("div", { ref: rulerRef, onMouseMove: handleMouseMove, onMouseUp: handleMouseUp, onMouseLeave: handleMouseUp, onDoubleClick: () => setIsDialogOpen(true), className: "ruler-container-wrapper", style: { transform: `scale(${editorOpts.zoomLevel})`, width: `${rulerWidth}px`, }, children: _jsxs("div", { className: "ruler-container", children: [_jsx(Marker, { position: (editorOpts.padding.left || 0) * INCH_TO_PX || 0, isLeft: true, isDragging: isDraggingLeft, onMouseDown: handleLeftMouseDown, onDoudleClick: handleLeftDoubleClick }), _jsx(Marker, { position: (editorOpts.padding.right || 0) * INCH_TO_PX || 0, isLeft: false, isDragging: isDraggingRight, onMouseDown: handleRightMouseDown, onDoudleClick: handleRightDoubleClick }), _jsx("div", { className: "absolute inset-x-0 bottom-0 h-full", children: _jsx("div", { className: "relative h-full", style: { width: `${rulerWidth}px` }, children: markers.map((marker) => { const position = (marker * rulerWidth) / 82; return (_jsxs("div", { className: "absolute bottom-0", style: { left: `${position}px` }, children: [marker % 10 === 0 && (_jsxs(_Fragment, { children: [_jsx("span", { className: "mark-10" }), _jsx("span", { className: "digit", children: marker / 10 + 1 })] })), marker % 5 === 0 && marker % 10 !== 0 && (_jsx("span", { className: "mark-5-10" })), marker % 5 !== 0 && _jsx("span", { className: "mark-5" })] }, marker)); }) }) })] }) })] })); } function Marker({ position, isLeft, isDragging, onMouseDown, onDoudleClick, }) { return _jsx(_Fragment, {}); // return ( // <div // className="absolute top-0 w-4 h-full cursor-ew-resize z-[5] group -ml-2" // style={{ [isLeft ? "left" : "right"]: `${position}px` }} // onMouseDown={onMouseDown} // onDoubleClick={onDoudleClick} // > // <FaCaretDown className="absolute left-1/2 top-0 h-full fill-blue-500 transform -translate-x-1/2" /> // <div // className="absolute left-1/2 top-4 transform -translate-x-1/2 transition-opacity duration-150 !h-screen w-[1px] bg-blue-500 scale-x-50" // style={{ // display: isDragging ? "block" : "none", // }} // /> // </div> // ); }