diff --git a/frontend/app/block/block.less b/frontend/app/block/block.less index bfcc97519..516ff4480 100644 --- a/frontend/app/block/block.less +++ b/frontend/app/block/block.less @@ -88,6 +88,7 @@ font: var(--fixed-font); color: var(--secondary-text-color); white-space: nowrap; + cursor: grab; } .block-frame-tech-close { @@ -128,6 +129,7 @@ -webkit-user-select: none; cursor: default; border-radius: 0 0 4px 4px; + cursor: grab; .block-header-icon { font-size: 20px; @@ -145,9 +147,9 @@ padding: 5px 5px 5px 5px; margin-right: 5px; border-radius: 4px; + cursor: pointer; &:hover { - cursor: pointer; background-color: var(--highlight-bg-color); } } diff --git a/frontend/app/block/block.tsx b/frontend/app/block/block.tsx index 8909f8c14..54a3f5e2c 100644 --- a/frontend/app/block/block.tsx +++ b/frontend/app/block/block.tsx @@ -22,6 +22,7 @@ const HoverTimeoutMs = 100; interface BlockProps { blockId: string; onClose?: () => void; + dragHandleRef?: React.RefObject; } function getBlockHeaderText(blockData: Block): string { @@ -31,11 +32,17 @@ function getBlockHeaderText(blockData: Block): string { return `${blockData?.view} [${blockData.oid.substring(0, 8)}]`; } -const FramelessBlockHeader = ({ blockId, onClose }: BlockProps) => { +interface FramelessBlockHeaderProps { + blockId: string; + onClose?: () => void; + dragHandleRef?: React.RefObject; +} + +const FramelessBlockHeader = ({ blockId, onClose, dragHandleRef }: FramelessBlockHeaderProps) => { const [blockData] = WOS.useWaveObjectValue(WOS.makeORef("block", blockId)); return ( -
+
{getBlockHeaderText(blockData)}
{onClose && (
@@ -57,9 +64,18 @@ interface BlockFrameProps { preview: boolean; children?: React.ReactNode; blockRef?: React.RefObject; + dragHandleRef?: React.RefObject; } -const BlockFrame_Tech = ({ blockId, onClose, onClick, preview, blockRef, children }: BlockFrameProps) => { +const BlockFrame_Tech = ({ + blockId, + onClose, + onClick, + preview, + blockRef, + dragHandleRef, + children, +}: BlockFrameProps) => { const [blockData] = WOS.useWaveObjectValue(WOS.makeORef("block", blockId)); const isFocusedAtom = useBlockAtom(blockId, "isFocused", () => { return jotai.atom((get) => { @@ -82,7 +98,9 @@ const BlockFrame_Tech = ({ blockId, onClose, onClick, preview, blockRef, childre onClick={onClick} ref={blockRef} > -
{getBlockHeaderText(blockData)}
+
+ {getBlockHeaderText(blockData)} +
@@ -91,7 +109,15 @@ const BlockFrame_Tech = ({ blockId, onClose, onClick, preview, blockRef, childre ); }; -const BlockFrame_Frameless = ({ blockId, onClose, onClick, preview, blockRef, children }: BlockFrameProps) => { +const BlockFrame_Frameless = ({ + blockId, + onClose, + onClick, + preview, + blockRef, + dragHandleRef, + children, +}: BlockFrameProps) => { const localBlockRef = React.useRef(null); const [showHeader, setShowHeader] = React.useState(preview ? true : false); const hoverState = React.useRef(hoverStateOff); @@ -150,7 +176,7 @@ const BlockFrame_Frameless = ({ blockId, onClose, onClick, preview, blockRef, ch className={clsx("block-header-animation-wrap", showHeader ? "is-showing" : null)} onMouseLeave={mouseLeaveHandler} > - +
{preview ?
: children}
@@ -184,7 +210,7 @@ function setBlockFocus(blockId: string) { WOS.setObjectValue(winData, globalStore.set, true); } -const Block = ({ blockId, onClose }: BlockProps) => { +const Block = ({ blockId, onClose, dragHandleRef }: BlockProps) => { let blockElem: JSX.Element = null; const focusElemRef = React.useRef(null); const blockRef = React.useRef(null); @@ -222,6 +248,7 @@ const Block = ({ blockId, onClose }: BlockProps) => { preview={false} onClick={() => setBlockClicked(true)} blockRef={blockRef} + dragHandleRef={dragHandleRef} >
{}} /> diff --git a/frontend/app/tab/tabcontent.tsx b/frontend/app/tab/tabcontent.tsx index 206ebc5bf..d1c3a19de 100644 --- a/frontend/app/tab/tabcontent.tsx +++ b/frontend/app/tab/tabcontent.tsx @@ -20,13 +20,21 @@ const TabContent = ({ tabId }: { tabId: string }) => { const layoutStateAtom = useMemo(() => getLayoutStateAtomForTab(tabId, tabAtom), [tabAtom, tabId]); const tabData = useAtomValue(tabAtom); - const renderBlock = useCallback((tabData: TabLayoutData, ready: boolean, onClose: () => void) => { - // console.log("renderBlock", tabData); - if (!tabData.blockId || !ready) { - return null; - } - return ; - }, []); + const renderBlock = useCallback( + ( + tabData: TabLayoutData, + ready: boolean, + onClose: () => void, + dragHandleRef: React.RefObject + ) => { + // console.log("renderBlock", tabData); + if (!tabData.blockId || !ready) { + return null; + } + return ; + }, + [] + ); const renderPreview = useCallback((tabData: TabLayoutData) => { console.log("renderPreview", tabData); diff --git a/frontend/faraday/lib/TileLayout.tsx b/frontend/faraday/lib/TileLayout.tsx index a6bc8acdc..e9b335a94 100644 --- a/frontend/faraday/lib/TileLayout.tsx +++ b/frontend/faraday/lib/TileLayout.tsx @@ -322,6 +322,7 @@ const DisplayNode = ({ ready, }: DisplayNodeProps) => { const tileNodeRef = useRef(null); + const dragHandleRef = useRef(null); const previewRef = useRef(null); const hasImagePreviewSetRef = useRef(false); @@ -369,8 +370,10 @@ const DisplayNode = ({ // Register the tile item as a draggable component useEffect(() => { - drag(tileNodeRef); - }, [tileNodeRef]); + if (dragHandleRef.current) { + drag(dragHandleRef); + } + }, [ready]); const onClose = useCallback(() => { onLeafClose(layoutNode); @@ -380,7 +383,7 @@ const DisplayNode = ({ return ( layoutNode.data && (
- {renderContent(layoutNode.data, ready, onClose)} + {renderContent(layoutNode.data, ready, onClose, dragHandleRef)}
) ); diff --git a/frontend/faraday/lib/model.ts b/frontend/faraday/lib/model.ts index f41aafc3e..e5cdf63d5 100644 --- a/frontend/faraday/lib/model.ts +++ b/frontend/faraday/lib/model.ts @@ -158,7 +158,12 @@ export type WritableLayoutNodeAtom = WritableAtom, [value: Layo */ export type WritableLayoutTreeStateAtom = WritableAtom, [value: LayoutTreeState], void>; -export type ContentRenderer = (data: T, ready: boolean, onClose?: () => void) => React.ReactNode; +export type ContentRenderer = ( + data: T, + ready: boolean, + onClose: () => void, + dragHandleRef: React.RefObject +) => React.ReactNode; export type PreviewRenderer = (data: T) => React.ReactElement;