@liberfi.io/ui-scaffold 0.1.112 → 0.1.113

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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/draggable/states.ts","../src/components/draggable/useDraggableModalDisclosure.ts","../src/components/draggable/useDraggablePanelDisclosure.ts","../src/components/draggable/DraggableModal.tsx","../src/components/draggable/DraggablePanel.tsx","../src/components/draggable/DraggablePanelProvider.tsx","../src/components/draggable/useDraggableDisclosure.ts","../src/components/layout/types.ts","../src/components/layout/ScaffoldContext.ts","../src/components/layout/Scaffold.tsx","../src/components/layout/NavLink.tsx","../src/components/layout/ScaffoldHeader.tsx","../src/components/layout/ScaffoldFooter.tsx","../src/components/layout/ScaffoldToolbar.tsx","../src/components/layout/Logo.tsx","../src/components/modal/AsyncModal.tsx","../src/components/modal/useAsyncModal.ts","../src/components/split/SplitHandle.tsx","../src/components/split/SplitView.tsx","../src/version.ts"],"names":["_storagePrefix","setDraggableStoragePrefix","prefix","storageKey","name","id","base","panelStateFamily","atomFamily","atomWithStorage","panelWidthFamily","panelMinWidthFamily","panelMaxWidthFamily","modalOpenFamily","modalShouldStartDraggingFamily","modalSizeFamily","modalRestoreSizeFamily","modalPositionFamily","modalRestorePositionFamily","modalMinimizedFamily","modalMinWidthFamily","modalMaxWidthFamily","lastDraggableTypeFamily","panelOrdersFamily","_","useDraggableModalDisclosure","isOpen","setIsOpen","useAtom","isMinimized","setIsMinimized","restoreSize","useAtomValue","restorePosition","setSize","useSetAtom","setPosition","setShouldStartDragging","setLastDraggableType","onOpen","useCallback","options","shouldStartDragging","position","size","prev","onClose","useMemo","useDraggablePanelDisclosure","panelState","setPanelState","setPanelWidth","setPanelOrders","left","right","MINIMIZED_SIZE","MAXIMIZED_SIZE","MAXIMIZED_POSITION","DraggableModal","memo","title","minWidth","maxWidth","minHeight","maxHeight","leftSidebar","leftSidebarWidth","rightSidebar","rightSidebarWidth","aspectRatio","showHeader","header","headerHeight","children","t","useTranslation","onOpenPanel","setRestoreSize","setRestorePosition","isDragging","setIsDragging","useState","isResizing","setIsResizing","resizeDirection","setResizeDirection","currentEdge","setCurrentEdge","dockAnimationEdge","setDockAnimationEdge","dockToEdge","setDockToEdge","dockToEdgeTimeoutRef","useRef","panelMinWidth","panelMaxWidth","positionRef","useValueRef","setPositionRef","useCallbackRef","sizeRef","setSizeRef","leftSidebarWidthRef","hasLeftSidebarRef","rightSidebarWidthRef","hasRightSidebarRef","aspectRatioRef","headerHeightRef","minWidthRef","maxWidthRef","minHeightRef","maxHeightRef","isDraggingRef","currentEdgeRef","dockToEdgeRef","onCloseRef","onOpenPanelRef","panelMinWidthRef","panelMaxWidthRef","isMaximized","useEffect","clampedWidth","clampedHeight","newX","newY","handleMouseMove","e","handleMouseUp","startInteraction","interactionType","direction","startX","startY","startWidth","startHeight","startPosition","cleanup","deltaX","deltaY","leftOffset","minX","rightOffset","maxX","maxY","edge","calculateNewSize","width","height","constraint","newWidth","newHeight","widthBasedHeight","heightBasedWidth","absDeltaX","absDeltaY","avgHeight","newSize","handleMinimize","handleMaximize","handleResize","throttle","bottom","jsxs","Fragment","createPortal","jsx","cn","StyledTooltip","DraggableIcon","Button","RestoreWindowIcon","MinimizeIcon","UnMaximizeIcon","MaximizeIcon","XCloseIcon","DraggablePanel","setWidth","openModal","closePanel","modalMinWidth","modalMaxWidth","widthRef","isResizingRef","setWidthRef","openModalRef","closePanelRef","modalMinWidthRef","modalMaxWidthRef","handleResizeStart","onResize","distance","onResizeEnd","handleDragStart","onDragMove","onDragEnd","handleClose","ResizeHandle","DraggablePanelProvider","contents","storagePrefix","className","classNames","prefixApplied","panelOrders","store","getDefaultStore","content","leftOpenPanels","a","b","rightOpenPanels","props","useDraggableDisclosure","isModalOpen","onOpenModal","onCloseModal","isPanelOpen","onClosePanel","lastDraggableType","ALL_BREAKPOINTS","isNavItemActive","item","pathname","getVisibilityClass","breakpoints","has","ScaffoldContext","createContext","useScaffold","ctx","useContext","useScaffoldLayout","config","DEFAULT_HEADER_HEIGHT","DEFAULT_MOBILE_HEADER_HEIGHT","DEFAULT_FOOTER_HEIGHT","DEFAULT_TOOLBAR_HEIGHT","noop","Scaffold","onNavigate","footer","toolbar","mobileHeaderHeight","footerHeight","toolbarHeight","defaultHeaderVisible","defaultFooterVisible","defaultToolbarVisible","headerVisible","setHeaderVisible","footerVisible","setFooterVisible","toolbarVisible","setToolbarVisible","scaffoldId","useId","ctxValue","headerClass","footerClass","toolbarClass","headerStyleRule","NavLink","variant","active","handlePress","ScaffoldHeader","navItems","style","HorizontalScrollContainer","ScaffoldFooter","ScaffoldToolbar","Logo","href","icon","miniIcon","ariaLabel","Link","AsyncModal","events","useEventEmitter","onOpenChange","useDisclosure","params","setParams","onResultRef","wrappedOnClose","wrappedOnResult","result","wrappedOnOpenChange","open","handler","useAsyncModal","resolve","SplitHandle","onResizeStart","isHorizontal","HANDLE_SIZE","getPersistedSize","raw","persistSize","SplitView","primary","secondary","defaultSize","minSize","maxSize","secondaryMinSize","onSizeChange","persistId","containerRef","minSizeRef","maxSizeRef","secondaryMinSizeRef","handleSizeChange","cursor","startPos","startSize","containerEl","containerTotal","onMouseMove","ev","delta","effectiveMax","onMouseUp","version_default"],"mappings":"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","file":"index.js","sourcesContent":["\"use client\";\n\nimport { atomFamily } from \"jotai-family\";\nimport { atomWithStorage } from \"jotai/utils\";\n\nlet _storagePrefix = \"\";\n\n/**\n * Set a prefix for all draggable localStorage keys.\n * Must be called before any draggable component renders.\n *\n * @example\n * setDraggableStoragePrefix(\"myapp\");\n * // keys become: \"myapp:panelState.chart\", \"myapp:modalOpen.chart\", etc.\n */\nexport function setDraggableStoragePrefix(prefix: string) {\n _storagePrefix = prefix;\n}\n\nfunction storageKey(name: string, id: string | null): string {\n const base = `${name}.${id ?? \"default\"}`;\n return _storagePrefix ? `${_storagePrefix}:${base}` : base;\n}\n\n/** whether the panel is docked or not */\nexport const panelStateFamily = atomFamily((id: string | null) =>\n atomWithStorage<\"none\" | \"left\" | \"right\">(\n storageKey(\"panelState\", id),\n \"none\",\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n\n/** width of the panel */\nexport const panelWidthFamily = atomFamily((id: string | null) =>\n atomWithStorage(storageKey(\"panelWidth\", id), 350, undefined, {\n getOnInit: true,\n }),\n);\n\nexport const panelMinWidthFamily = atomFamily((id: string | null) =>\n atomWithStorage(storageKey(\"panelMinWidth\", id), 320, undefined, {\n getOnInit: true,\n }),\n);\n\nexport const panelMaxWidthFamily = atomFamily((id: string | null) =>\n atomWithStorage(storageKey(\"panelMaxWidth\", id), 440, undefined, {\n getOnInit: true,\n }),\n);\n\n/** whether the modal is open */\nexport const modalOpenFamily = atomFamily((id: string | null) =>\n atomWithStorage(storageKey(\"modalOpen\", id), false, undefined, {\n getOnInit: true,\n }),\n);\n\n/** whether the modal should start dragging automatically when opened */\nexport const modalShouldStartDraggingFamily = atomFamily((id: string | null) =>\n atomWithStorage(\n storageKey(\"modalShouldStartDragging\", id),\n false,\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n\n/** size of the modal */\nexport const modalSizeFamily = atomFamily((id: string | null) =>\n atomWithStorage<{ width: number; height: number }>(\n storageKey(\"modalSize\", id),\n { width: 350, height: 580 },\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n\n/** restore size of the modal when maximized or minimized */\nexport const modalRestoreSizeFamily = atomFamily((id: string | null) =>\n atomWithStorage<{ width: number; height: number }>(\n storageKey(\"modalRestoreSize\", id),\n { width: 350, height: 580 },\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n\n/** position of the modal */\nexport const modalPositionFamily = atomFamily((id: string | null) =>\n atomWithStorage<{ x: number; y: number }>(\n storageKey(\"modalPosition\", id),\n {\n x:\n typeof window !== \"undefined\"\n ? Math.max(0, (window.innerWidth - 350) / 2)\n : 0,\n y:\n typeof window !== \"undefined\"\n ? Math.max(0, (window.innerHeight - 580) / 2)\n : 0,\n },\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n\n/** restore position of the modal when maximized or minimized */\nexport const modalRestorePositionFamily = atomFamily((id: string | null) =>\n atomWithStorage<{ x: number; y: number }>(\n storageKey(\"modalRestorePosition\", id),\n {\n x:\n typeof window !== \"undefined\"\n ? Math.max(0, (window.innerWidth - 350) / 2)\n : 0,\n y:\n typeof window !== \"undefined\"\n ? Math.max(0, (window.innerHeight - 580) / 2)\n : 0,\n },\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n\nexport const modalMinimizedFamily = atomFamily((id: string | null) =>\n atomWithStorage<boolean>(storageKey(\"modalMinimized\", id), false, undefined, {\n getOnInit: true,\n }),\n);\n\nexport const modalMinWidthFamily = atomFamily((id: string | null) =>\n atomWithStorage<number>(storageKey(\"modalMinWidth\", id), 200, undefined, {\n getOnInit: true,\n }),\n);\n\nexport const modalMaxWidthFamily = atomFamily((id: string | null) =>\n atomWithStorage<number>(\n storageKey(\"modalMaxWidth\", id),\n typeof window !== \"undefined\" ? window.innerWidth - 40 : 0,\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n\nexport const lastDraggableTypeFamily = atomFamily((id: string | null) =>\n atomWithStorage<\"left\" | \"right\" | \"modal\">(\n storageKey(\"lastPanelType\", id),\n \"modal\",\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n\n/** Wrapped in atomFamily for lazy creation so it picks up the storage prefix */\nexport const panelOrdersFamily = atomFamily((_: null) =>\n atomWithStorage<{\n left: { [id: string]: number };\n right: { [id: string]: number };\n }>(\n storageKey(\"panelOrders\", null),\n {\n left: {},\n right: {},\n },\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n","\"use client\";\n\nimport { useCallback, useMemo } from \"react\";\nimport { useAtom, useAtomValue, useSetAtom } from \"jotai\";\nimport {\n lastDraggableTypeFamily,\n modalMinimizedFamily,\n modalOpenFamily,\n modalPositionFamily,\n modalRestorePositionFamily,\n modalRestoreSizeFamily,\n modalShouldStartDraggingFamily,\n modalSizeFamily,\n} from \"./states\";\n\nexport type OpenDraggableModalOptions = {\n /** should start dragging automatically when the modal is opened */\n shouldStartDragging?: boolean;\n /** adjust position of the modal when it is opened */\n position?: { x?: number; y?: number };\n /** adjust size of the modal when it is opened */\n size?: { width?: number; height?: number };\n};\n\nexport type UseDraggableModalDisclosureReturnType = {\n isOpen: boolean;\n onOpen: (options?: OpenDraggableModalOptions) => void;\n onClose: () => void;\n};\n\nexport function useDraggableModalDisclosure(\n id: string,\n): UseDraggableModalDisclosureReturnType {\n const [isOpen, setIsOpen] = useAtom(modalOpenFamily(id));\n const [isMinimized, setIsMinimized] = useAtom(modalMinimizedFamily(id));\n const restoreSize = useAtomValue(modalRestoreSizeFamily(id));\n const restorePosition = useAtomValue(modalRestorePositionFamily(id));\n const setSize = useSetAtom(modalSizeFamily(id));\n const setPosition = useSetAtom(modalPositionFamily(id));\n const setShouldStartDragging = useSetAtom(modalShouldStartDraggingFamily(id));\n const setLastDraggableType = useSetAtom(lastDraggableTypeFamily(id));\n\n const onOpen = useCallback(\n (options: OpenDraggableModalOptions = {}) => {\n const { shouldStartDragging, position, size } = options;\n if (position) setPosition((prev) => ({ ...prev, ...position }));\n if (size) setSize((prev) => ({ ...prev, ...size }));\n setShouldStartDragging(shouldStartDragging ?? false);\n setIsOpen(true);\n setLastDraggableType(\"modal\");\n },\n [setIsOpen, setPosition, setSize, setShouldStartDragging],\n );\n\n const onClose = useCallback(() => {\n setIsOpen(false);\n // restore the modal if it is minimized when closing\n if (isMinimized) {\n setSize({ ...restoreSize });\n setPosition({ ...restorePosition });\n setIsMinimized(false);\n }\n }, [\n isMinimized,\n restoreSize,\n restorePosition,\n setIsMinimized,\n setIsOpen,\n setSize,\n setPosition,\n ]);\n\n return useMemo(\n () => ({\n isOpen,\n onOpen,\n onClose,\n }),\n [isOpen, onOpen, onClose],\n );\n}\n","\"use client\";\n\nimport { useCallback, useMemo } from \"react\";\nimport { useAtom, useSetAtom } from \"jotai\";\nimport {\n lastDraggableTypeFamily,\n panelOrdersFamily,\n panelStateFamily,\n panelWidthFamily,\n} from \"./states\";\n\nexport type OpenDraggablePanelOptions = {\n /** which side the panel is docked on */\n position?: \"left\" | \"right\";\n /** adjust size of the modal when it is opened */\n width?: number;\n};\n\nexport type UseDraggablePanelDisclosureReturnType = {\n isOpen: boolean;\n position?: \"left\" | \"right\";\n onOpen: (options?: OpenDraggablePanelOptions) => void;\n onClose: () => void;\n};\n\nexport function useDraggablePanelDisclosure(\n id: string,\n): UseDraggablePanelDisclosureReturnType {\n const [panelState, setPanelState] = useAtom(panelStateFamily(id));\n const setPanelWidth = useSetAtom(panelWidthFamily(id));\n const setLastDraggableType = useSetAtom(lastDraggableTypeFamily(id));\n const setPanelOrders = useSetAtom(panelOrdersFamily(null));\n\n const onOpen = useCallback(\n (options: OpenDraggablePanelOptions = {}) => {\n const position = options.position ?? \"left\";\n setPanelWidth(options.width ?? 320);\n setPanelState(position);\n setLastDraggableType(position);\n setPanelOrders(({ left, right }) => {\n if (position === \"left\") {\n return { left: { ...left, [id]: Date.now() }, right };\n } else {\n return { left, right: { ...right, [id]: Date.now() } };\n }\n });\n },\n [id, setPanelState, setPanelWidth],\n );\n\n const onClose = useCallback(() => {\n setPanelState(\"none\");\n }, [setPanelState]);\n\n const isOpen = useMemo(() => panelState !== \"none\", [panelState]);\n\n const position = useMemo(\n () => (panelState !== \"none\" ? panelState : undefined),\n [panelState],\n );\n\n return useMemo(\n () => ({\n isOpen,\n position,\n onOpen,\n onClose,\n }),\n [isOpen, onOpen, onClose],\n );\n}\n","\"use client\";\n\nimport {\n memo,\n useState,\n useEffect,\n useRef,\n PropsWithChildren,\n useMemo,\n useCallback,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useAtom, useAtomValue } from \"jotai\";\nimport { useCallbackRef, useValueRef } from \"@liberfi.io/hooks\";\nimport { useTranslation } from \"@liberfi.io/i18n\";\nimport {\n Button,\n cn,\n DraggableIcon,\n MaximizeIcon,\n MinimizeIcon,\n RestoreWindowIcon,\n StyledTooltip,\n UnMaximizeIcon,\n XCloseIcon,\n} from \"@liberfi.io/ui\";\nimport { throttle } from \"@liberfi.io/utils\";\nimport {\n modalMinimizedFamily,\n modalPositionFamily,\n modalRestorePositionFamily,\n modalRestoreSizeFamily,\n modalShouldStartDraggingFamily,\n modalSizeFamily,\n panelMaxWidthFamily,\n panelMinWidthFamily,\n} from \"./states\";\nimport { useDraggableModalDisclosure } from \"./useDraggableModalDisclosure\";\nimport { useDraggablePanelDisclosure } from \"./useDraggablePanelDisclosure\";\n\nconst MINIMIZED_SIZE = {\n width: 200,\n height: 48,\n};\n\nconst MAXIMIZED_SIZE = {\n width: typeof window !== \"undefined\" ? window.innerWidth - 40 : 0,\n height: typeof window !== \"undefined\" ? window.innerHeight - 40 : 0,\n};\n\nconst MAXIMIZED_POSITION = {\n x: 20,\n y: 20,\n};\n\ntype ResizeDirection =\n | \"topLeft\"\n | \"topRight\"\n | \"bottomLeft\"\n | \"bottomRight\"\n | \"top\"\n | \"bottom\"\n | \"left\"\n | \"right\";\n\nexport type DraggableModalProps = PropsWithChildren<{\n /** unique identifier for the modal, must be the same with the panel */\n id: string;\n /** title of the modal */\n title?: React.ReactNode;\n /** constraints for the minimum width */\n minWidth?: number;\n /** constraints for the maximum width */\n maxWidth?: number;\n /** constraints for the minimum height */\n minHeight?: number;\n /** constraints for the maximum height */\n maxHeight?: number;\n /** left sidebar of the modal */\n leftSidebar?: React.ReactNode;\n /** width of the left sidebar */\n leftSidebarWidth?: number;\n /** right sidebar of the modal */\n rightSidebar?: React.ReactNode;\n /** width of the right sidebar */\n rightSidebarWidth?: number;\n /** constraints for the aspect ratio when resizing */\n aspectRatio?: number;\n /** whether to show the header */\n showHeader?: boolean;\n /** custom header content */\n header?: React.ReactNode;\n /** height of the modal header */\n headerHeight?: number;\n}>;\n\nexport const DraggableModal = memo(function DraggablePopup({\n id,\n title,\n minWidth = 504,\n maxWidth = MAXIMIZED_SIZE.width,\n minHeight = 200,\n maxHeight = MAXIMIZED_SIZE.height,\n leftSidebar,\n leftSidebarWidth = 200,\n rightSidebar,\n rightSidebarWidth = 200,\n aspectRatio,\n showHeader = true,\n header,\n headerHeight = 44,\n children,\n}: DraggableModalProps) {\n const { t } = useTranslation();\n\n // control the open state of the modal\n const { isOpen, onClose } = useDraggableModalDisclosure(id);\n\n // control the open state of the panel\n const { onOpen: onOpenPanel } = useDraggablePanelDisclosure(id);\n\n // whether the modal is minimized\n const [isMinimized, setIsMinimized] = useAtom(modalMinimizedFamily(id));\n\n // latest position\n const [position, setPosition] = useAtom(modalPositionFamily(id));\n\n // latest modal size\n const [size, setSize] = useAtom(modalSizeFamily(id));\n\n // restore size when maximized or minimized\n const [restoreSize, setRestoreSize] = useAtom(modalRestoreSizeFamily(id));\n\n // restore position when maximized or minimized\n const [restorePosition, setRestorePosition] = useAtom(\n modalRestorePositionFamily(id),\n );\n\n // start dragging automatically when the component is mounted\n const [shouldStartDragging, setShouldStartDragging] = useAtom(\n modalShouldStartDraggingFamily(id),\n );\n\n // whether the modal is being dragged\n const [isDragging, setIsDragging] = useState(shouldStartDragging);\n\n // whether the modal is being resized\n const [isResizing, setIsResizing] = useState(false);\n\n // direction of the resize\n const [resizeDirection, setResizeDirection] =\n useState<ResizeDirection | null>(null);\n\n // which edge is the modal near\n const [currentEdge, setCurrentEdge] = useState<\"left\" | \"right\" | null>(null);\n\n // which edge to display docking animation\n const [dockAnimationEdge, setDockAnimationEdge] = useState<\n \"left\" | \"right\" | null\n >(null);\n\n // which edge is waiting for the timeout to dock on\n const [dockToEdge, setDockToEdge] = useState<\"left\" | \"right\" | null>(null);\n\n // timeout for docking to the edge\n const dockToEdgeTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n const panelMinWidth = useAtomValue(panelMinWidthFamily(id));\n\n const panelMaxWidth = useAtomValue(panelMaxWidthFamily(id));\n\n // refs for props & states to avoid re-rendering\n const positionRef = useValueRef(position);\n const setPositionRef = useCallbackRef(setPosition);\n const sizeRef = useValueRef(size);\n const setSizeRef = useCallbackRef(setSize);\n const leftSidebarWidthRef = useValueRef(leftSidebarWidth);\n const hasLeftSidebarRef = useValueRef(!!leftSidebar);\n const rightSidebarWidthRef = useValueRef(rightSidebarWidth);\n const hasRightSidebarRef = useValueRef(!!rightSidebar);\n const aspectRatioRef = useValueRef(aspectRatio);\n const headerHeightRef = useValueRef(headerHeight);\n const minWidthRef = useValueRef(minWidth);\n const maxWidthRef = useValueRef(maxWidth);\n const minHeightRef = useValueRef(minHeight);\n const maxHeightRef = useValueRef(maxHeight);\n const isDraggingRef = useValueRef(isDragging);\n const currentEdgeRef = useValueRef(currentEdge);\n const dockToEdgeRef = useValueRef(dockToEdge);\n const onCloseRef = useCallbackRef(onClose);\n const onOpenPanelRef = useCallbackRef(onOpenPanel);\n const panelMinWidthRef = useValueRef(panelMinWidth);\n const panelMaxWidthRef = useValueRef(panelMaxWidth);\n\n // whether the modal is maximized\n const isMaximized = useMemo(\n () =>\n size.width === MAXIMIZED_SIZE.width &&\n size.height === MAXIMIZED_SIZE.height,\n [size.width, size.height],\n );\n\n // clamp size to min/max constraints and adjust position when the component is mounted\n useEffect(() => {\n const clampedWidth = Math.min(Math.max(size.width, minWidth), maxWidth);\n const clampedHeight = Math.min(Math.max(size.height, minHeight), maxHeight);\n if (clampedWidth !== size.width || clampedHeight !== size.height) {\n setSizeRef({ width: clampedWidth, height: clampedHeight });\n }\n\n let newX = Math.max(0, position.x);\n let newY = Math.max(0, position.y);\n if (newX + clampedWidth > window.innerWidth) {\n newX = Math.max(0, window.innerWidth - clampedWidth);\n }\n if (newY + clampedHeight > window.innerHeight) {\n newY = Math.max(0, window.innerHeight - clampedHeight);\n }\n if (newX !== position.x || newY !== position.y) {\n setPositionRef({ x: newX, y: newY });\n }\n }, [id]);\n\n // start dragging automatically when the component is mounted, just follow the mouse movement\n useEffect(() => {\n if (isOpen && shouldStartDragging) {\n setIsDragging(true);\n\n const handleMouseMove = (e: MouseEvent) => {\n setPositionRef({\n x: e.clientX - size.width / 2,\n y: e.clientY - 20,\n });\n };\n\n const handleMouseUp = () => {\n setIsDragging(false);\n // finish start dragging\n setShouldStartDragging(false);\n document.removeEventListener(\"mousemove\", handleMouseMove);\n document.removeEventListener(\"mouseup\", handleMouseUp);\n };\n\n document.addEventListener(\"mousemove\", handleMouseMove);\n document.addEventListener(\"mouseup\", handleMouseUp);\n document.body.style.cursor = \"grabbing\";\n\n return () => {\n document.removeEventListener(\"mousemove\", handleMouseMove);\n document.removeEventListener(\"mouseup\", handleMouseUp);\n document.body.style.cursor = \"\";\n };\n }\n }, [isOpen, shouldStartDragging, setShouldStartDragging, size.width]);\n\n const startInteraction = (\n e: React.MouseEvent,\n interactionType: \"drag\" | \"resize\",\n direction?: ResizeDirection,\n ) => {\n // user interaction starts, stop auto-dragging which is triggered when the component is mounted\n setShouldStartDragging(false);\n\n // reset states\n setIsDragging(false);\n setIsResizing(false);\n setResizeDirection(null);\n\n // set states according to interaction type\n if (interactionType === \"drag\") {\n setIsDragging(true);\n } else if (interactionType === \"resize\") {\n setResizeDirection(direction || null);\n setIsResizing(true);\n }\n\n // save start position and size in closure\n const startX = e.clientX;\n const startY = e.clientY;\n const startWidth = sizeRef.current.width;\n const startHeight = sizeRef.current.height;\n const startPosition = { ...positionRef.current };\n\n const cleanup = () => {\n document.removeEventListener(\"mousemove\", handleMouseMove);\n document.removeEventListener(\"mouseup\", handleMouseUp);\n document.body.style.cursor = \"\";\n\n setIsDragging(false);\n setIsResizing(false);\n setResizeDirection(null);\n setCurrentEdge(null);\n\n if (dockToEdgeTimeoutRef.current) {\n clearTimeout(dockToEdgeTimeoutRef.current);\n dockToEdgeTimeoutRef.current = null;\n }\n setDockToEdge(null);\n setDockAnimationEdge(null);\n };\n\n const handleMouseMove = (e: MouseEvent) => {\n if (interactionType === \"drag\") {\n const deltaX = e.clientX - startX;\n const deltaY = e.clientY - startY;\n let newX = startPosition.x + deltaX;\n let newY = startPosition.y + deltaY;\n\n // calculate boundaries\n const leftOffset = hasLeftSidebarRef.current\n ? leftSidebarWidthRef.current\n : 0;\n const minX = 12 + leftOffset;\n\n const rightOffset = hasRightSidebarRef.current\n ? rightSidebarWidthRef.current\n : 0;\n const maxX = window.innerWidth - 12 - startWidth - rightOffset;\n\n // display 44px for header\n const maxY = window.innerHeight - 12 - 44;\n\n // check if near the edge\n const edge = newX <= minX ? \"left\" : newX >= maxX ? \"right\" : null;\n if (edge !== currentEdgeRef.current) {\n setCurrentEdge(edge);\n }\n\n // if is waiting for the timeout to dock on the edge, display the animation\n if (dockToEdgeTimeoutRef.current && edge) {\n setDockAnimationEdge(edge);\n }\n\n // interrupt the timeout if the modal is moved away from the edge\n if (dockToEdgeTimeoutRef.current) {\n if (\n (dockToEdgeRef.current === \"left\" &&\n (newX > minX || edge !== \"left\")) ||\n (dockToEdgeRef.current === \"right\" &&\n (newX < maxX || edge !== \"right\"))\n ) {\n clearTimeout(dockToEdgeTimeoutRef.current);\n dockToEdgeTimeoutRef.current = null;\n setDockToEdge(null);\n setDockAnimationEdge(null);\n }\n }\n\n // wait for the timeout to dock on the edge\n if (!dockToEdgeTimeoutRef.current && edge) {\n if (dockToEdgeRef.current !== edge) {\n setDockToEdge(edge);\n setDockAnimationEdge(edge);\n dockToEdgeTimeoutRef.current = setTimeout(() => {\n if (isDraggingRef.current && currentEdgeRef.current === edge) {\n // still dragging & near the edge, convert to panel\n cleanup();\n // close modal\n onCloseRef();\n // open panel\n onOpenPanelRef({\n position: edge,\n width: Math.min(\n Math.max(sizeRef.current.width, panelMinWidthRef.current),\n panelMaxWidthRef.current,\n ),\n });\n } else {\n setDockToEdge(null);\n }\n }, 350);\n }\n }\n\n // limit within the boundaries\n newX = Math.min(Math.max(newX, 12 + leftOffset), maxX);\n newY = Math.min(Math.max(newY, 12), maxY);\n setPositionRef({ x: newX, y: newY });\n } else if (interactionType === \"resize\" && direction) {\n const deltaX = e.clientX - startX;\n const deltaY = e.clientY - startY;\n\n // calculate new size (considering aspect ratio)\n const calculateNewSize = (\n width: number,\n height: number,\n constraint: \"width\" | \"height\" | \"both\",\n ) => {\n let newWidth = Math.min(\n Math.max(width, minWidthRef.current),\n maxWidthRef.current,\n );\n let newHeight = Math.min(\n Math.max(height, minHeightRef.current),\n maxHeightRef.current,\n );\n\n if (aspectRatioRef.current) {\n if (constraint === \"width\") {\n newHeight = Math.min(\n Math.max(\n width / aspectRatioRef.current + headerHeightRef.current,\n minHeightRef.current,\n ),\n maxHeightRef.current,\n );\n newWidth =\n (newHeight - headerHeightRef.current) * aspectRatioRef.current;\n } else if (constraint === \"height\") {\n newWidth = Math.min(\n Math.max(\n (height - headerHeightRef.current) * aspectRatioRef.current,\n minWidthRef.current,\n ),\n maxWidthRef.current,\n );\n newHeight =\n newWidth / aspectRatioRef.current + headerHeightRef.current;\n } else {\n const widthBasedHeight =\n width / aspectRatioRef.current + headerHeightRef.current;\n const heightBasedWidth =\n (height - headerHeightRef.current) * aspectRatioRef.current;\n const absDeltaX = Math.abs(deltaX);\n const absDeltaY = Math.abs(deltaY);\n\n if (absDeltaX > 1.1 * absDeltaY) {\n newHeight = Math.min(\n Math.max(widthBasedHeight, minHeightRef.current),\n maxHeightRef.current,\n );\n newWidth =\n (newHeight - headerHeightRef.current) *\n aspectRatioRef.current;\n } else if (absDeltaY > 1.1 * absDeltaX) {\n newWidth = Math.min(\n Math.max(heightBasedWidth, minWidthRef.current),\n maxWidthRef.current,\n );\n newHeight =\n newWidth / aspectRatioRef.current + headerHeightRef.current;\n } else {\n const avgHeight = (newHeight + widthBasedHeight) / 2;\n newWidth = Math.min(\n Math.max(\n (newWidth + heightBasedWidth) / 2,\n minWidthRef.current,\n ),\n maxWidthRef.current,\n );\n newHeight = Math.min(\n Math.max(avgHeight, minHeightRef.current),\n maxHeightRef.current,\n );\n newWidth =\n (newHeight - headerHeightRef.current) *\n aspectRatioRef.current;\n }\n }\n\n newWidth = Math.min(\n Math.max(newWidth, minWidthRef.current),\n maxWidthRef.current,\n );\n newHeight = Math.min(\n Math.max(newHeight, minHeightRef.current),\n maxHeightRef.current,\n );\n }\n\n return { width: newWidth, height: newHeight };\n };\n\n // handle the resize direction\n switch (direction) {\n case \"topLeft\": {\n const newSize = calculateNewSize(\n startWidth - deltaX,\n startHeight - deltaY,\n \"both\",\n );\n setSizeRef(newSize);\n setPositionRef({\n x: startPosition.x + (startWidth - newSize.width),\n y: startPosition.y + (startHeight - newSize.height),\n });\n break;\n }\n case \"topRight\": {\n const newSize = calculateNewSize(\n startWidth + deltaX,\n startHeight - deltaY,\n \"both\",\n );\n setSizeRef(newSize);\n setPositionRef({\n x: startPosition.x,\n y: startPosition.y + (startHeight - newSize.height),\n });\n break;\n }\n case \"bottomLeft\": {\n const newSize = calculateNewSize(\n startWidth - deltaX,\n startHeight + deltaY,\n \"both\",\n );\n setSizeRef(newSize);\n setPositionRef({\n x: startPosition.x + (startWidth - newSize.width),\n y: startPosition.y,\n });\n break;\n }\n case \"bottomRight\": {\n setSizeRef(\n calculateNewSize(\n startWidth + deltaX,\n startHeight + deltaY,\n \"both\",\n ),\n );\n break;\n }\n case \"top\": {\n const newSize = calculateNewSize(\n startWidth,\n startHeight - deltaY,\n \"height\",\n );\n setSizeRef(newSize);\n setPositionRef({\n x: startPosition.x,\n y: startPosition.y + (startHeight - newSize.height),\n });\n break;\n }\n case \"bottom\": {\n setSizeRef(\n calculateNewSize(startWidth, startHeight + deltaY, \"height\"),\n );\n break;\n }\n case \"left\": {\n const newSize = calculateNewSize(\n startWidth - deltaX,\n startHeight,\n \"width\",\n );\n setSizeRef(newSize);\n setPositionRef({\n x: startPosition.x + (startWidth - newSize.width),\n y: startPosition.y,\n });\n break;\n }\n case \"right\": {\n setSizeRef(\n calculateNewSize(startWidth + deltaX, startHeight, \"width\"),\n );\n break;\n }\n }\n }\n };\n\n const handleMouseUp = () => {\n // limit the position within the boundaries\n if (position.x < 0 || position.y < 0) {\n setPositionRef({\n x: Math.max(0, position.x),\n y: Math.max(0, position.y),\n });\n }\n cleanup();\n };\n\n document.addEventListener(\"mousemove\", handleMouseMove);\n document.addEventListener(\"mouseup\", handleMouseUp);\n };\n\n const handleMinimize = useCallback(() => {\n if (isMinimized) {\n // already minimized, restore to the previous size and position\n setSizeRef({ ...restoreSize });\n setPositionRef({ ...restorePosition });\n setIsMinimized(false);\n } else {\n // minimize\n if (isMaximized) {\n // if minimized from maximized directly, use the size and position which is stored before maximized\n setPositionRef({ ...restorePosition });\n } else {\n // otherwise store the current size and position\n setRestoreSize({ ...size });\n setRestorePosition({ ...position });\n }\n setSizeRef({ ...MINIMIZED_SIZE });\n setIsMinimized(true);\n }\n }, [\n isMinimized,\n isMaximized,\n size,\n position,\n restoreSize,\n restorePosition,\n setIsMinimized,\n setRestoreSize,\n setRestorePosition,\n ]);\n\n const handleMaximize = useCallback(() => {\n if (isMaximized) {\n // already maximized, restore to the previous size and position\n setSizeRef({ ...restoreSize });\n setPositionRef({ ...restorePosition });\n } else {\n // maximize\n if (isMinimized) {\n // if maximized from minimized directly, use the stored size and position before minimized\n setIsMinimized(false);\n } else {\n // otherwise store the current size and position\n setRestoreSize({ ...size });\n setRestorePosition({ ...position });\n }\n setSizeRef({ ...MAXIMIZED_SIZE });\n setPositionRef({ ...MAXIMIZED_POSITION });\n }\n }, [\n isMaximized,\n isMinimized,\n size,\n position,\n restoreSize,\n restorePosition,\n setIsMinimized,\n setRestoreSize,\n setRestorePosition,\n ]);\n\n // adjust position to the boundary when the window is resized\n useEffect(() => {\n const handleResize = throttle(() => {\n if (positionRef.current.x < 0 || positionRef.current.y < 0) {\n setPositionRef({\n x: Math.max(0, positionRef.current.x),\n y: Math.max(0, positionRef.current.y),\n });\n }\n const right = positionRef.current.x + sizeRef.current.width;\n const bottom = positionRef.current.y + sizeRef.current.height;\n if (right > window.innerWidth || bottom > window.innerHeight) {\n setPositionRef({\n x: Math.min(\n positionRef.current.x,\n Math.max(0, window.innerWidth - sizeRef.current.width),\n ),\n y: Math.min(\n positionRef.current.y,\n Math.max(0, window.innerHeight - sizeRef.current.height),\n ),\n });\n }\n }, 100);\n\n window.addEventListener(\"resize\", handleResize);\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n };\n }, []);\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <>\n {/* Overlay when dragging or resizing */}\n {(isDragging || isResizing) &&\n createPortal(\n <div\n className={cn(\n \"max-sm:hidden fixed inset-0 z-9999 bg-transparent w-full h-full select-none\",\n isDragging && (dockToEdge ? \"cursor-grabbing\" : \"cursor-move\"),\n !isDragging && {\n \"cursor-ns-resize\":\n resizeDirection === \"top\" || resizeDirection === \"bottom\",\n \"cursor-ew-resize\":\n resizeDirection === \"left\" || resizeDirection === \"right\",\n \"cursor-nwse-resize\":\n resizeDirection === \"topLeft\" ||\n resizeDirection === \"bottomRight\",\n \"cursor-nesw-resize\":\n resizeDirection === \"topRight\" ||\n resizeDirection === \"bottomLeft\",\n \"cursor-auto\": resizeDirection === null,\n },\n )}\n />,\n document.body,\n )}\n\n {/* Modal container */}\n <div\n className={cn(\n \"max-sm:hidden fixed z-50 left-0 top-0\",\n isDragging ? \"will-change-transform\" : \"will-change-auto\",\n isResizing || isDragging\n ? \"transition-none\"\n : \"transition-transform duration-250 ease-[cubic-bezier(0.16,1,0.3,1)]\",\n )}\n style={{\n transform: `translate(${Math.round(position.x - (leftSidebar ? leftSidebarWidth : 0))}px, ${Math.round(position.y)}px)`,\n }}\n >\n <div className=\"flex relative z-50\">\n {leftSidebar && (\n <div\n className={cn(\n \"relative mt-1 z-10 transition-all duration-250 ease-[cubic-bezier(0.16,1,0.3,1)]\",\n isDragging\n ? \"opacity-40 translate-x-4\"\n : \"opacity-100 translate-x-0\",\n )}\n style={{\n width: leftSidebarWidth,\n height: isMinimized ? 40 : size.height - 8,\n }}\n >\n {leftSidebar}\n </div>\n )}\n\n {/* modal content */}\n <div\n className={cn(\n \"z-50 relative bg-content1 border border-border rounded-lg overflow-hidden\",\n isDragging\n ? \"opacity-80 shadow-md scale-102 blur-[0.5px]\"\n : \"opacity-100 shadow-lg scale-100 blur-none\",\n )}\n style={{\n width: size.width,\n height: size.height,\n transition:\n isResizing || isDragging\n ? \"none\"\n : \"transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.2s cubic-bezier(0.33, 1, 0.68, 1), height 0.25s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.2s cubic-bezier(0.33, 1, 0.68, 1)\",\n contain: \"content\",\n }}\n >\n <div\n className={cn(\n \"w-full h-full\",\n dockAnimationEdge && \"animate-modal-shrink\",\n dockAnimationEdge === \"left\" ? \"origin-left\" : \"origin-right\",\n )}\n style={{ contain: \"paint\" }}\n >\n {/* resize handles */}\n {!isMinimized && (\n <>\n <div\n className=\"absolute top-0 left-0 w-3 h-3 cursor-nw-resize z-20\"\n onMouseDown={(e) =>\n startInteraction(e, \"resize\", \"topLeft\")\n }\n />\n <div\n className=\"absolute top-0 right-0 w-3 h-3 cursor-ne-resize z-20\"\n onMouseDown={(e) =>\n startInteraction(e, \"resize\", \"topRight\")\n }\n />\n <div\n className=\"absolute bottom-0 left-0 w-3 h-3 cursor-sw-resize z-20\"\n onMouseDown={(e) =>\n startInteraction(e, \"resize\", \"bottomLeft\")\n }\n />\n <div\n className=\"absolute bottom-0 right-0 w-3 h-3 cursor-se-resize z-20\"\n onMouseDown={(e) =>\n startInteraction(e, \"resize\", \"bottomRight\")\n }\n />\n <div\n className=\"absolute top-0 left-3 right-3 h-1.5 cursor-n-resize z-20\"\n onMouseDown={(e) => startInteraction(e, \"resize\", \"top\")}\n />\n <div\n className=\"absolute bottom-0 left-3 right-3 h-1.5 cursor-s-resize z-20\"\n onMouseDown={(e) => startInteraction(e, \"resize\", \"bottom\")}\n />\n <div\n className=\"absolute left-0 top-3 bottom-3 w-1.5 cursor-w-resize z-20\"\n onMouseDown={(e) => startInteraction(e, \"resize\", \"left\")}\n />\n <div\n className=\"absolute right-0 top-3 bottom-3 w-1.5 cursor-e-resize z-20\"\n onMouseDown={(e) => startInteraction(e, \"resize\", \"right\")}\n />\n </>\n )}\n\n {/* header */}\n {showHeader && (\n <div\n className=\"relative border-b border-border/80 px-3 gap-4 flex items-center justify-between cursor-move select-none\"\n onMouseDown={(e) => startInteraction(e, \"drag\")}\n style={{ height: headerHeight }}\n >\n {/* drag tooltip */}\n <StyledTooltip\n placement=\"top\"\n content={t(\"scaffold.draggableModal.snapToEdge\")}\n >\n <DraggableIcon className=\"text-neutral absolute left-1/2 -translate-x-1/2 top-0\" />\n </StyledTooltip>\n\n {header || (\n <>\n <div\n className=\"min-w-0 flex-initial text-sm font-medium truncate cursor-auto\"\n onMouseDown={(e) => e.stopPropagation()}\n >\n {title}\n </div>\n <div\n className=\"flex-none flex items-center justify-end gap-1\"\n onMouseDown={(e) => e.stopPropagation()}\n >\n {/* minimize button */}\n <Button\n size=\"sm\"\n variant=\"light\"\n radius=\"lg\"\n isIconOnly\n onPress={handleMinimize}\n >\n {isMinimized ? (\n <RestoreWindowIcon\n width={18}\n height={18}\n className=\"text-neutral\"\n />\n ) : (\n <MinimizeIcon\n width={18}\n height={18}\n className=\"text-neutral\"\n />\n )}\n </Button>\n {/* maximize button */}\n <Button\n size=\"sm\"\n variant=\"light\"\n radius=\"lg\"\n isIconOnly\n onPress={handleMaximize}\n >\n {isMaximized ? (\n <UnMaximizeIcon\n width={18}\n height={18}\n className=\"text-neutral\"\n />\n ) : (\n <MaximizeIcon\n width={18}\n height={18}\n className=\"text-neutral\"\n />\n )}\n </Button>\n {/* close button */}\n <Button\n size=\"sm\"\n variant=\"light\"\n radius=\"lg\"\n isIconOnly\n onPress={onClose}\n >\n <XCloseIcon\n width={18}\n height={18}\n className=\"text-neutral\"\n />\n </Button>\n </div>\n </>\n )}\n </div>\n )}\n\n {/* content */}\n {!isMinimized && (\n <div\n className={\n showHeader\n ? \"h-[calc(100%-44px)] overflow-x-hidden overflow-y-auto\"\n : \"h-full overflow-x-hidden overflow-y-auto cursor-move\"\n }\n onMouseDown={\n showHeader ? undefined : (e) => startInteraction(e, \"drag\")\n }\n >\n {children}\n </div>\n )}\n </div>\n </div>\n\n {rightSidebar && (\n <div\n className={cn(\n \"relative mt-1 z-10 transition-all duration-250 ease-[cubic-bezier(0.16,1,0.3,1)]\",\n isDragging\n ? \"opacity-40 -translate-x-4\"\n : \"opacity-100 translate-x-0\",\n )}\n style={{\n width: rightSidebarWidth,\n height: isMinimized ? 40 : size.height - 8,\n }}\n >\n {rightSidebar}\n </div>\n )}\n </div>\n </div>\n </>\n );\n});\n","\"use client\";\n\nimport { useState, PropsWithChildren } from \"react\";\nimport { useAtom, useAtomValue } from \"jotai\";\nimport { useCallbackRef, useValueRef } from \"@liberfi.io/hooks\";\nimport { useTranslation } from \"@liberfi.io/i18n\";\nimport {\n Button,\n cn,\n DraggableIcon,\n StyledTooltip,\n XCloseIcon,\n} from \"@liberfi.io/ui\";\nimport {\n modalMaxWidthFamily,\n modalMinWidthFamily,\n panelStateFamily,\n panelWidthFamily,\n} from \"./states\";\nimport { useDraggableModalDisclosure } from \"./useDraggableModalDisclosure\";\nimport { useDraggablePanelDisclosure } from \"./useDraggablePanelDisclosure\";\n\nexport type DraggablePanelProps = PropsWithChildren<{\n /** unique id for the panel, must be the same with the modal */\n id: string;\n /** title of the modal */\n title?: React.ReactNode;\n /** maximum width of the panel */\n maxWidth?: number;\n /** minimum width of the panel */\n minWidth?: number;\n /** which side the panel is docked on */\n position: \"left\" | \"right\";\n /** whether to show the header */\n showHeader?: boolean;\n /** custom header content */\n header?: React.ReactNode;\n /** height of the modal header */\n headerHeight?: number;\n}>;\n\nexport function DraggablePanel({\n id,\n title,\n maxWidth = 440,\n minWidth = 320,\n position,\n showHeader = true,\n header,\n headerHeight = 44,\n children,\n}: DraggablePanelProps) {\n const { t } = useTranslation();\n\n // whether the panel is docked or not\n const panelState = useAtomValue(panelStateFamily(id));\n\n // whether the panel is being resized or not\n const [isResizing, setIsResizing] = useState(false);\n\n // whether the panel is being dragged or not\n const [isDragging, setIsDragging] = useState(false);\n\n // panel width\n const [width, setWidth] = useAtom(panelWidthFamily(id));\n\n // converting to modal\n const { onOpen: openModal } = useDraggableModalDisclosure(id);\n\n // control the close state of the panel\n const { onClose: closePanel } = useDraggablePanelDisclosure(id);\n\n const modalMinWidth = useAtomValue(modalMinWidthFamily(id));\n\n const modalMaxWidth = useAtomValue(modalMaxWidthFamily(id));\n\n // refs for props & states to avoid re-rendering\n const widthRef = useValueRef(width);\n const maxWidthRef = useValueRef(maxWidth);\n const minWidthRef = useValueRef(minWidth);\n const positionRef = useValueRef(position);\n const isResizingRef = useValueRef(isResizing);\n const isDraggingRef = useValueRef(isDragging);\n const setWidthRef = useCallbackRef(setWidth);\n const openModalRef = useCallbackRef(openModal);\n const closePanelRef = useCallbackRef(closePanel);\n const modalMinWidthRef = useValueRef(modalMinWidth);\n const modalMaxWidthRef = useValueRef(modalMaxWidth);\n\n const handleResizeStart = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsResizing(true);\n document.body.style.cursor = \"ew-resize\";\n document.body.style.userSelect = \"none\";\n document.body.style.overflow = \"hidden\";\n document.body.style.position = \"fixed\";\n document.body.style.width = \"100%\";\n document.body.style.height = \"100%\";\n\n // save start size & position in closure\n const startX = e.clientX;\n const startWidth = widthRef.current;\n\n const onResize = (e: MouseEvent) => {\n if (!isResizingRef.current) return;\n\n const deltaX = e.clientX - startX;\n\n const distance =\n positionRef.current === \"right\"\n ? startWidth - deltaX\n : startWidth + deltaX;\n\n const width = Math.min(\n Math.max(distance, minWidthRef.current),\n maxWidthRef.current,\n );\n setWidthRef(width);\n };\n\n const onResizeEnd = () => {\n setIsResizing(false);\n document.body.style.cursor = \"\";\n document.body.style.userSelect = \"\";\n document.body.style.overflow = \"\";\n document.body.style.position = \"\";\n document.body.style.width = \"\";\n document.body.style.height = \"\";\n document.removeEventListener(\"mousemove\", onResize);\n document.removeEventListener(\"mouseup\", onResizeEnd);\n };\n\n document.addEventListener(\"mousemove\", onResize);\n document.addEventListener(\"mouseup\", onResizeEnd);\n };\n\n const handleDragStart = (e: React.MouseEvent) => {\n // if the target is a button, don't trigger drag\n if (e.target instanceof HTMLElement && e.target.closest(\"button\")) {\n return;\n }\n e.preventDefault();\n\n setIsDragging(true);\n\n // save start position in closure\n const startX = e.clientX;\n const startY = e.clientY;\n\n const cleanup = () => {\n document.removeEventListener(\"mousemove\", onDragMove);\n document.removeEventListener(\"mouseup\", onDragEnd);\n setIsDragging(false);\n };\n\n const onDragMove = (e: MouseEvent) => {\n if (!isDraggingRef.current) return;\n\n const deltaX = Math.abs(e.clientX - startX);\n const deltaY = Math.abs(e.clientY - startY);\n\n // if the drag distance is greater than 10px, convert to modal\n if (deltaX > 10 || deltaY > 10) {\n cleanup();\n // close the panel\n closePanelRef();\n // open the modal\n openModalRef({\n // modal should follow the cursor\n shouldStartDragging: true,\n position: {\n x: e.clientX - widthRef.current / 2 + 20,\n y: e.clientY - 20,\n },\n // adjust modal's width to the panel's width\n size: {\n width: Math.min(\n Math.max(widthRef.current, modalMinWidthRef.current),\n modalMaxWidthRef.current,\n ),\n },\n });\n }\n };\n\n const onDragEnd = () => {\n cleanup();\n };\n\n document.addEventListener(\"mousemove\", onDragMove);\n document.addEventListener(\"mouseup\", onDragEnd);\n };\n\n const handleClose = () => {\n closePanelRef();\n };\n\n if (panelState !== position) {\n return null;\n }\n\n return (\n <div className=\"max-sm:hidden flex-none flex flex-row overflow-hidden\">\n {/* when the panel is on the right, show the resize handle on the left */}\n {position === \"right\" && (\n <ResizeHandle\n isResizing={isResizing}\n handleResizeStart={handleResizeStart}\n />\n )}\n\n {/* panel content container */}\n <div\n className={cn(\n \"flex flex-col min-h-0 overflow-hidden bg-content1\",\n isDragging\n ? \"opacity-80 scale-98 blur-[1px]\"\n : \"opacity-100 scale-100 blur-none\",\n )}\n style={{\n width: `${width}px`,\n transition:\n isResizing || isDragging\n ? \"none\"\n : \"transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.2s cubic-bezier(0.33, 1, 0.68, 1), height 0.4s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.2s cubic-bezier(0.33, 1, 0.68, 1)\",\n contain: \"content\",\n }}\n >\n {/* header */}\n {showHeader && (\n <div\n className=\"flex-none relative border-b border-border/80 px-3 gap-4 flex items-center justify-between cursor-move select-none\"\n onMouseDown={handleDragStart}\n style={{ height: headerHeight }}\n >\n {/* drag tooltip */}\n <StyledTooltip\n placement=\"top\"\n content={t(\"scaffold.draggablePanel.snapToModal\")}\n >\n <DraggableIcon className=\"text-neutral absolute left-1/2 -translate-x-1/2 top-0\" />\n </StyledTooltip>\n\n {header || (\n <>\n <div\n className=\"min-w-0 flex-initial text-sm font-medium truncate cursor-auto\"\n onMouseDown={(e) => e.stopPropagation()}\n >\n {title}\n </div>\n <div\n className=\"flex-none flex items-center justify-end gap-1\"\n onMouseDown={(e) => e.stopPropagation()}\n >\n {/* close button */}\n <Button\n size=\"sm\"\n variant=\"light\"\n radius=\"lg\"\n isIconOnly\n onPress={handleClose}\n >\n <XCloseIcon\n width={18}\n height={18}\n className=\"text-neutral\"\n />\n </Button>\n </div>\n </>\n )}\n </div>\n )}\n\n <div className=\"flex-auto min-h-0 overflow-y-auto\">{children}</div>\n </div>\n\n {/* when the panel is on the left, show the resize handle on the right */}\n {position === \"left\" && (\n <ResizeHandle\n isResizing={isResizing}\n handleResizeStart={handleResizeStart}\n />\n )}\n </div>\n );\n}\n\ntype ResizeHandleProps = {\n isResizing: boolean;\n handleResizeStart: (e: React.MouseEvent) => void;\n};\n\nfunction ResizeHandle({ isResizing, handleResizeStart }: ResizeHandleProps) {\n return (\n <div className=\"relative\">\n <div className=\"relative w-1 h-full cursor-ew-resize bg-border/80 hover:bg-border transition-colors duration-150 ease-in-out group flex flex-col items-center justify-center gap-1\">\n <i className=\"rounded-full w-0.5 h-0.5 bg-neutral\" />\n <i className=\"rounded-full w-0.5 h-0.5 bg-neutral\" />\n <i className=\"rounded-full w-0.5 h-0.5 bg-neutral\" />\n\n {/* expend click area */}\n <div\n className=\"absolute inset-0 -left-1.5 -right-1.5 cursor-ew-resize\"\n onMouseDown={handleResizeStart}\n />\n </div>\n\n {isResizing && <div className=\"fixed inset-0 z-50 cursor-ew-resize\" />}\n </div>\n );\n}\n","\"use client\";\n\nimport { PropsWithChildren, useEffect, useMemo, useRef } from \"react\";\nimport { getDefaultStore, useAtomValue } from \"jotai\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { DraggableModal } from \"./DraggableModal\";\nimport { DraggablePanel } from \"./DraggablePanel\";\nimport {\n modalMaxWidthFamily,\n modalMinWidthFamily,\n panelMaxWidthFamily,\n panelMinWidthFamily,\n panelOrdersFamily,\n panelStateFamily,\n setDraggableStoragePrefix,\n} from \"./states\";\n\nexport type DraggableContentProps = PropsWithChildren<{\n /** unique identifier for both the modal & panel */\n id: string;\n /** title of both the modal & panel */\n title?: React.ReactNode;\n /** whether to show the header for both the modal & panel */\n showHeader?: boolean;\n /** custom header content for both the modal & panel */\n header?: React.ReactNode;\n /** height of the modal header for both the modal & panel */\n headerHeight?: number;\n /** constraints for the minimum width of the modal */\n modalMinWidth?: number;\n /** constraints for the maximum width of the modal */\n modalMaxWidth?: number;\n /** constraints for the minimum width of the panel */\n panelMinWidth?: number;\n /** constraints for the maximum width of the panel */\n panelMaxWidth?: number;\n /** constraints for the minimum height of the modal */\n minHeight?: number;\n /** constraints for the maximum height of the modal */\n maxHeight?: number;\n /** left sidebar of the modal */\n leftSidebar?: React.ReactNode;\n /** width of the left sidebar */\n leftSidebarWidth?: number;\n /** right sidebar of the modal */\n rightSidebar?: React.ReactNode;\n /** width of the right sidebar */\n rightSidebarWidth?: number;\n /** constraints for the aspect ratio when resizing modal */\n aspectRatio?: number;\n}>;\n\nexport type DraggablePanelProviderProps = PropsWithChildren<{\n /** draggable contents */\n contents?: Array<DraggableContentProps>;\n /** Prefix for all draggable localStorage keys (e.g. \"myapp\" → \"myapp:panelState.chart\") */\n storagePrefix?: string;\n /** root container class name */\n className?: string;\n /** class names slots*/\n classNames?: {\n root?: string;\n left?: string;\n right?: string;\n content?: string;\n };\n}>;\n\nexport function DraggablePanelProvider({\n contents = [],\n storagePrefix,\n className,\n classNames,\n children,\n}: DraggablePanelProviderProps) {\n const prefixApplied = useRef(false);\n if (!prefixApplied.current && storagePrefix !== undefined) {\n setDraggableStoragePrefix(storagePrefix);\n prefixApplied.current = true;\n }\n const panelOrders = useAtomValue(panelOrdersFamily(null));\n\n // sync panel & order widths\n useEffect(() => {\n const store = getDefaultStore();\n contents.forEach((content) => {\n store.set(panelMinWidthFamily(content.id), content.panelMinWidth ?? 320);\n store.set(panelMaxWidthFamily(content.id), content.panelMaxWidth ?? 440);\n store.set(modalMinWidthFamily(content.id), content.modalMinWidth ?? 504);\n store.set(\n modalMaxWidthFamily(content.id),\n content.modalMaxWidth ?? window.innerWidth - 40,\n );\n });\n }, [contents]);\n\n // latest opened on the left\n const leftOpenPanels = useMemo(\n () =>\n contents\n .filter((content) => {\n const store = getDefaultStore();\n // hasn't been opened on the left\n if (!panelOrders.left[content.id]) return false;\n // whether the panel is opened on the left\n return store.get(panelStateFamily(content.id)) === \"left\";\n })\n .sort((a, b) => panelOrders.left[b.id] - panelOrders.left[a.id]),\n [contents, panelOrders.left],\n );\n\n // latest opened on the right\n const rightOpenPanels = useMemo(\n () =>\n contents\n .filter((content) => {\n const store = getDefaultStore();\n // hasn't been opened on the right\n if (!panelOrders.right[content.id]) return false;\n // whether the panel is opened on the right\n return store.get(panelStateFamily(content.id)) === \"right\";\n })\n .sort(\n (a, b) =>\n (panelOrders.right[a.id] ?? 0) - (panelOrders.right[b.id] ?? 0),\n ),\n [contents, panelOrders.right],\n );\n\n return (\n <>\n <div\n className={cn(\n \"w-full h-full flex flex-row overflow-hidden\",\n className,\n classNames?.root,\n )}\n >\n {/* left panels */}\n <div className={cn(\"flex-none h-full flex flex-row\", classNames?.left)}>\n {leftOpenPanels.map((props) => (\n <DraggablePanel\n key={`left-${props.id}`}\n {...props}\n position=\"left\"\n minWidth={props.panelMinWidth ?? 320}\n maxWidth={props.panelMaxWidth ?? 440}\n />\n ))}\n </div>\n {/* main content */}\n <div className={cn(\"flex-auto min-w-0 h-full\", classNames?.content)}>\n {children}\n </div>\n {/* right panels */}\n <div\n className={cn(\"flex-none h-full flex flex-row\", classNames?.right)}\n >\n {rightOpenPanels.map((props) => (\n <DraggablePanel\n key={`right-${props.id}`}\n {...props}\n position=\"right\"\n minWidth={props.panelMinWidth ?? 320}\n maxWidth={props.panelMaxWidth ?? 440}\n />\n ))}\n </div>\n </div>\n {/* modals */}\n {contents.map((props) => (\n <DraggableModal\n key={`modal-${props.id}`}\n {...props}\n minWidth={props.modalMinWidth ?? 504}\n maxWidth={props.modalMaxWidth ?? window.innerWidth - 40}\n />\n ))}\n </>\n );\n}\n","\"use client\";\n\nimport { useCallback, useMemo } from \"react\";\nimport { useAtomValue } from \"jotai\";\nimport { lastDraggableTypeFamily } from \"./states\";\nimport { useDraggableModalDisclosure } from \"./useDraggableModalDisclosure\";\nimport { useDraggablePanelDisclosure } from \"./useDraggablePanelDisclosure\";\n\nexport type UseDraggableDisclosureReturnType = {\n isOpen: boolean;\n onOpen: () => void;\n onClose: () => void;\n};\n\nexport function useDraggableDisclosure(\n id: string,\n): UseDraggableDisclosureReturnType {\n const {\n isOpen: isModalOpen,\n onOpen: onOpenModal,\n onClose: onCloseModal,\n } = useDraggableModalDisclosure(id);\n\n const {\n isOpen: isPanelOpen,\n onOpen: onOpenPanel,\n onClose: onClosePanel,\n } = useDraggablePanelDisclosure(id);\n\n const lastDraggableType = useAtomValue(lastDraggableTypeFamily(id));\n\n const onOpen = useCallback(() => {\n if (isModalOpen || isPanelOpen) return;\n if (lastDraggableType === \"modal\") {\n onOpenModal();\n } else {\n onOpenPanel({ position: lastDraggableType });\n }\n }, [isModalOpen, isPanelOpen, lastDraggableType, onOpenModal, onOpenPanel]);\n\n const onClose = useCallback(() => {\n if (isModalOpen) {\n onCloseModal();\n } else if (isPanelOpen) {\n onClosePanel();\n }\n }, [isModalOpen, isPanelOpen, onCloseModal, onClosePanel]);\n\n const isOpen = useMemo(\n () => isModalOpen || isPanelOpen,\n [isModalOpen, isPanelOpen],\n );\n\n return useMemo(\n () => ({\n isOpen,\n onOpen,\n onClose,\n }),\n [isOpen, onOpen, onClose],\n );\n}\n","import type { ReactNode } from \"react\";\n\n/** Responsive breakpoints: desktop (>=1024px), tablet (640–1023px), mobile (<640px) */\nexport type LayoutBreakpoint = \"desktop\" | \"tablet\" | \"mobile\";\n\nexport const ALL_BREAKPOINTS: LayoutBreakpoint[] = [\n \"desktop\",\n \"tablet\",\n \"mobile\",\n];\n\n/** Navigation item for header links and footer tabs */\nexport type NavItem = {\n key: string;\n label: string;\n href: string;\n icon?: ReactNode;\n /**\n * Custom active-matching rule.\n * - function: called with pathname, return true if active\n * - RegExp: tested against pathname\n * - string: pathname.startsWith(match)\n * - undefined: exact match for \"/\", startsWith for others\n */\n match?: string | RegExp | ((pathname: string) => boolean);\n};\n\n/** Check whether a NavItem is active for the given pathname */\nexport function isNavItemActive(item: NavItem, pathname: string): boolean {\n if (item.match !== undefined) {\n if (typeof item.match === \"function\") return item.match(pathname);\n if (item.match instanceof RegExp) return item.match.test(pathname);\n return pathname.startsWith(item.match);\n }\n if (item.href === \"/\") return pathname === \"/\";\n return pathname.startsWith(item.href);\n}\n\n/**\n * Map a LayoutBreakpoint[] to Tailwind visibility class names.\n *\n * desktop = lg+ (>=1024), tablet = sm..lg (640–1023), mobile = <sm (<640)\n *\n * Returns a class string that hides the element on breakpoints NOT in the array.\n */\nexport function getVisibilityClass(breakpoints: LayoutBreakpoint[]): string {\n const has = {\n desktop: breakpoints.includes(\"desktop\"),\n tablet: breakpoints.includes(\"tablet\"),\n mobile: breakpoints.includes(\"mobile\"),\n };\n\n if (has.desktop && has.tablet && has.mobile) return \"\";\n if (!has.desktop && !has.tablet && !has.mobile) return \"hidden\";\n if (has.desktop && has.tablet && !has.mobile) return \"max-sm:hidden\";\n if (has.desktop && !has.tablet && !has.mobile) return \"max-lg:hidden\";\n if (!has.desktop && has.tablet && has.mobile) return \"lg:hidden\";\n if (!has.desktop && !has.tablet && has.mobile) return \"sm:hidden\";\n if (!has.desktop && has.tablet && !has.mobile)\n return \"max-sm:hidden lg:hidden\";\n\n // [\"desktop\", \"mobile\"] — non-contiguous breakpoints cannot be expressed\n // with pure Tailwind hidden/show classes without forcing a display type.\n throw new Error(\n `getVisibilityClass: non-contiguous breakpoints [${breakpoints.join(\", \")}] are not supported. ` +\n \"Use a contiguous range (e.g. [desktop, tablet], [tablet, mobile]).\",\n );\n}\n","import { createContext, useContext, useEffect } from \"react\";\nimport type { LayoutBreakpoint } from \"./types\";\n\nexport type ScaffoldContextValue = {\n /** Current route pathname for nav active detection (IoC) */\n pathname: string;\n /** Navigation callback (IoC — no router dependency) */\n onNavigate: (href: string) => void;\n /** Header height in px */\n headerHeight: number;\n /** Header height in px on mobile (max-width 639px) */\n mobileHeaderHeight: number;\n /** Footer height in px */\n footerHeight: number;\n /** Toolbar height in px */\n toolbarHeight: number;\n\n /** Breakpoints where the header is visible */\n headerVisible: LayoutBreakpoint[];\n /** Breakpoints where the footer is visible */\n footerVisible: LayoutBreakpoint[];\n /** Breakpoints where the toolbar is visible */\n toolbarVisible: LayoutBreakpoint[];\n\n /** Override header visibility (used by useScaffoldLayout) */\n setHeaderVisible: (breakpoints: LayoutBreakpoint[]) => void;\n /** Override footer visibility (used by useScaffoldLayout) */\n setFooterVisible: (breakpoints: LayoutBreakpoint[]) => void;\n /** Override toolbar visibility (used by useScaffoldLayout) */\n setToolbarVisible: (breakpoints: LayoutBreakpoint[]) => void;\n\n /** Default headerVisible from Scaffold props (for reset on unmount) */\n defaultHeaderVisible: LayoutBreakpoint[];\n /** Default footerVisible from Scaffold props (for reset on unmount) */\n defaultFooterVisible: LayoutBreakpoint[];\n /** Default toolbarVisible from Scaffold props (for reset on unmount) */\n defaultToolbarVisible: LayoutBreakpoint[];\n};\n\nexport const ScaffoldContext = createContext<ScaffoldContextValue | null>(null);\n\n/** Read the Scaffold context. Throws if used outside a Scaffold. */\nexport function useScaffold(): ScaffoldContextValue {\n const ctx = useContext(ScaffoldContext);\n if (!ctx) {\n throw new Error(\"useScaffold must be used within a <Scaffold> component.\");\n }\n return ctx;\n}\n\n/**\n * Declaratively set the layout for the current page.\n * Overrides on mount, resets to Scaffold defaults on unmount.\n *\n * @example\n * useScaffoldLayout({\n * headerVisible: [\"desktop\", \"tablet\"],\n * footerVisible: [\"tablet\", \"mobile\"],\n * toolbarVisible: [\"desktop\"],\n * });\n */\nexport function useScaffoldLayout(config: {\n headerVisible?: LayoutBreakpoint[];\n footerVisible?: LayoutBreakpoint[];\n toolbarVisible?: LayoutBreakpoint[];\n}): void {\n const ctx = useScaffold();\n\n useEffect(() => {\n if (config.headerVisible !== undefined) {\n ctx.setHeaderVisible(config.headerVisible);\n }\n if (config.footerVisible !== undefined) {\n ctx.setFooterVisible(config.footerVisible);\n }\n if (config.toolbarVisible !== undefined) {\n ctx.setToolbarVisible(config.toolbarVisible);\n }\n\n return () => {\n if (config.headerVisible !== undefined) {\n ctx.setHeaderVisible(ctx.defaultHeaderVisible);\n }\n if (config.footerVisible !== undefined) {\n ctx.setFooterVisible(ctx.defaultFooterVisible);\n }\n if (config.toolbarVisible !== undefined) {\n ctx.setToolbarVisible(ctx.defaultToolbarVisible);\n }\n };\n }, [config.headerVisible, config.footerVisible, config.toolbarVisible]);\n}\n","import {\n type PropsWithChildren,\n type ReactNode,\n useId,\n useMemo,\n useState,\n} from \"react\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { ScaffoldContext, type ScaffoldContextValue } from \"./ScaffoldContext\";\nimport {\n type LayoutBreakpoint,\n ALL_BREAKPOINTS,\n getVisibilityClass,\n} from \"./types\";\n\nconst DEFAULT_HEADER_HEIGHT = 60;\nconst DEFAULT_MOBILE_HEADER_HEIGHT = 48;\nconst DEFAULT_FOOTER_HEIGHT = 56;\nconst DEFAULT_TOOLBAR_HEIGHT = 36;\nconst noop = () => {};\n\nexport type ScaffoldProps = PropsWithChildren<{\n /** Current route pathname for nav active detection */\n pathname?: string;\n /** Navigation callback (IoC — decoupled from router) */\n onNavigate?: (href: string) => void;\n /** Header slot */\n header?: ReactNode;\n /** Footer slot (typically mobile tab navigation) */\n footer?: ReactNode;\n /** Toolbar slot (typically desktop bottom status bar) */\n toolbar?: ReactNode;\n /** Header height in px (default 60) */\n headerHeight?: number;\n /** Header height in px on mobile — max-width 639px (default 48) */\n mobileHeaderHeight?: number;\n /** Footer height in px (default 56) */\n footerHeight?: number;\n /** Toolbar height in px (default 36) */\n toolbarHeight?: number;\n /** Breakpoints where the header is visible (default all) */\n headerVisible?: LayoutBreakpoint[];\n /** Breakpoints where the footer is visible (default none) */\n footerVisible?: LayoutBreakpoint[];\n /** Breakpoints where the toolbar is visible (default none) */\n toolbarVisible?: LayoutBreakpoint[];\n className?: string;\n classNames?: {\n wrapper?: string;\n header?: string;\n content?: string;\n footer?: string;\n toolbar?: string;\n };\n}>;\n\nexport function Scaffold({\n children,\n pathname = \"\",\n onNavigate = noop,\n header,\n footer,\n toolbar,\n headerHeight = DEFAULT_HEADER_HEIGHT,\n mobileHeaderHeight = DEFAULT_MOBILE_HEADER_HEIGHT,\n footerHeight = DEFAULT_FOOTER_HEIGHT,\n toolbarHeight = DEFAULT_TOOLBAR_HEIGHT,\n headerVisible: defaultHeaderVisible = ALL_BREAKPOINTS,\n footerVisible: defaultFooterVisible = [],\n toolbarVisible: defaultToolbarVisible = [],\n className,\n classNames,\n}: ScaffoldProps) {\n const [headerVisible, setHeaderVisible] =\n useState<LayoutBreakpoint[]>(defaultHeaderVisible);\n const [footerVisible, setFooterVisible] =\n useState<LayoutBreakpoint[]>(defaultFooterVisible);\n const [toolbarVisible, setToolbarVisible] = useState<LayoutBreakpoint[]>(\n defaultToolbarVisible,\n );\n\n const scaffoldId = useId();\n\n const ctxValue = useMemo<ScaffoldContextValue>(\n () => ({\n pathname,\n onNavigate,\n headerHeight,\n mobileHeaderHeight,\n footerHeight,\n toolbarHeight,\n headerVisible,\n footerVisible,\n toolbarVisible,\n setHeaderVisible,\n setFooterVisible,\n setToolbarVisible,\n defaultHeaderVisible,\n defaultFooterVisible,\n defaultToolbarVisible,\n }),\n [\n pathname,\n onNavigate,\n headerHeight,\n mobileHeaderHeight,\n footerHeight,\n toolbarHeight,\n headerVisible,\n footerVisible,\n toolbarVisible,\n defaultHeaderVisible,\n defaultFooterVisible,\n defaultToolbarVisible,\n ],\n );\n\n const headerClass = getVisibilityClass(headerVisible);\n const footerClass = getVisibilityClass(footerVisible);\n const toolbarClass = getVisibilityClass(toolbarVisible);\n\n const headerStyleRule =\n mobileHeaderHeight !== headerHeight\n ? `[data-scaffold-id=\"${scaffoldId}\"]{--scaffold-header-height:${headerHeight}px}` +\n `@media(max-width:639px){[data-scaffold-id=\"${scaffoldId}\"]{--scaffold-header-height:${mobileHeaderHeight}px}}`\n : `[data-scaffold-id=\"${scaffoldId}\"]{--scaffold-header-height:${headerHeight}px}`;\n\n return (\n <ScaffoldContext.Provider value={ctxValue}>\n <style>{headerStyleRule}</style>\n <div\n data-scaffold-id={scaffoldId}\n className={cn(\n \"w-full h-screen max-sm:h-dvh flex flex-col overflow-hidden bg-background\",\n classNames?.wrapper,\n className,\n )}\n style={\n {\n \"--scaffold-footer-height\": `calc(${footerHeight}px + env(safe-area-inset-bottom))`,\n \"--scaffold-toolbar-height\": `${toolbarHeight}px`,\n } as React.CSSProperties\n }\n >\n {/* Header */}\n {header && (\n <nav\n className={cn(\n \"w-full flex-none relative z-50\",\n headerClass,\n classNames?.header,\n )}\n style={{ height: \"var(--scaffold-header-height)\" }}\n >\n {header}\n </nav>\n )}\n\n {/* Content */}\n <div\n className={cn(\n \"w-full flex-auto min-h-0 relative overflow-y-auto\",\n classNames?.content,\n )}\n >\n {children}\n </div>\n\n {/* Toolbar (desktop bottom bar) */}\n {toolbar && (\n <div\n className={cn(\n \"w-full flex-none\",\n toolbarClass,\n classNames?.toolbar,\n )}\n style={{ height: `${toolbarHeight}px` }}\n >\n {toolbar}\n </div>\n )}\n\n {/* Footer (mobile tab navigation) */}\n {footer && (\n <div\n className={cn(\n \"w-full flex-none pb-[env(safe-area-inset-bottom)]\",\n footerClass,\n classNames?.footer,\n )}\n style={{\n height: `calc(${footerHeight}px + env(safe-area-inset-bottom))`,\n }}\n >\n {footer}\n </div>\n )}\n </div>\n </ScaffoldContext.Provider>\n );\n}\n","import { useCallback } from \"react\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { useScaffold } from \"./ScaffoldContext\";\nimport { isNavItemActive, type NavItem } from \"./types\";\n\nexport type NavLinkProps = {\n item: NavItem;\n /** \"header\" = horizontal text link, \"footer\" = vertical icon+text tab */\n variant?: \"header\" | \"footer\";\n className?: string;\n};\n\nexport function NavLink({ item, variant = \"header\", className }: NavLinkProps) {\n const { pathname, onNavigate } = useScaffold();\n const active = isNavItemActive(item, pathname);\n\n const handlePress = useCallback(() => {\n onNavigate(item.href);\n }, [onNavigate, item.href]);\n\n if (variant === \"footer\") {\n return (\n <button\n type=\"button\"\n data-active={active}\n className={cn(\n \"flex flex-col items-center justify-center gap-0.5 px-2 py-1 min-w-0\",\n \"text-xs font-medium text-foreground/60\",\n \"data-[active=true]:text-primary\",\n className,\n )}\n onClick={handlePress}\n aria-label={item.label}\n aria-current={active ? \"page\" : undefined}\n >\n {item.icon && (\n <span className=\"flex items-center justify-center\">{item.icon}</span>\n )}\n <span className=\"truncate\">{item.label}</span>\n </button>\n );\n }\n\n return (\n <button\n type=\"button\"\n data-active={active}\n className={cn(\n \"h-8 text-sm font-medium px-2 xl:px-3 rounded-sm cursor-pointer\",\n \"text-foreground hover:text-primary hover:bg-primary-50\",\n \"data-[active=true]:text-primary\",\n className,\n )}\n onClick={handlePress}\n aria-label={item.label}\n aria-current={active ? \"page\" : undefined}\n >\n {item.label}\n </button>\n );\n}\n","import type { CSSProperties, PropsWithChildren, ReactNode } from \"react\";\nimport { cn, HorizontalScrollContainer } from \"@liberfi.io/ui\";\nimport { NavLink } from \"./NavLink\";\nimport type { NavItem } from \"./types\";\n\nexport type ScaffoldHeaderProps = PropsWithChildren<{\n /** Left slot (e.g. Logo) */\n left?: ReactNode;\n /** Right slot (e.g. account menu, settings) */\n right?: ReactNode;\n /** Navigation items rendered as horizontal links with auto-active detection */\n navItems?: NavItem[];\n className?: string;\n style?: CSSProperties;\n}>;\n\n/**\n * Pre-built header layout with left / nav / right slots.\n * Pass `children` for full custom control (left/right/navItems will be ignored).\n */\nexport function ScaffoldHeader({\n children,\n left,\n right,\n navItems,\n className,\n style,\n}: ScaffoldHeaderProps) {\n if (children) {\n return (\n <header\n className={cn(\n \"w-full h-full flex items-center bg-background border-b border-border\",\n className,\n )}\n style={style}\n >\n {children}\n </header>\n );\n }\n\n return (\n <header\n className={cn(\n \"w-full h-full px-6 max-lg:px-4 max-sm:px-3 flex items-center justify-between gap-6 max-lg:gap-4 max-sm:gap-3 bg-background border-b border-border\",\n className,\n )}\n >\n {/* Left: logo (fixed) */}\n {left && <div className=\"shrink-0 flex items-center\">{left}</div>}\n\n {/* Center: nav items (scrollable when space is tight, hidden on mobile) */}\n {navItems && navItems.length > 0 && (\n <HorizontalScrollContainer\n className=\"flex-auto min-w-0 max-sm:hidden\"\n classNames={{ content: \"gap-1\" }}\n >\n {navItems.map((item) => (\n <NavLink key={item.key} item={item} variant=\"header\" />\n ))}\n </HorizontalScrollContainer>\n )}\n\n {/* Right: always fully visible */}\n {right && <div className=\"shrink-0 flex items-center gap-4\">{right}</div>}\n </header>\n );\n}\n","import type { PropsWithChildren } from \"react\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { NavLink } from \"./NavLink\";\nimport type { NavItem } from \"./types\";\n\nexport type ScaffoldFooterProps = PropsWithChildren<{\n /** Navigation items rendered as vertical icon+text tabs */\n navItems?: NavItem[];\n className?: string;\n}>;\n\n/**\n * Pre-built footer layout with tab-style navigation.\n * Pass `children` for full custom control (navItems will be ignored).\n */\nexport function ScaffoldFooter({\n children,\n navItems,\n className,\n}: ScaffoldFooterProps) {\n if (children) {\n return (\n <footer\n className={cn(\n \"w-full h-full flex items-center bg-background border-t border-border\",\n className,\n )}\n >\n {children}\n </footer>\n );\n }\n\n return (\n <footer\n className={cn(\n \"w-full h-full flex justify-evenly items-center bg-background border-t border-border\",\n className,\n )}\n >\n {navItems?.map((item) => (\n <NavLink key={item.key} item={item} variant=\"footer\" />\n ))}\n </footer>\n );\n}\n","import type { PropsWithChildren, ReactNode } from \"react\";\nimport { cn } from \"@liberfi.io/ui\";\n\nexport type ScaffoldToolbarProps = PropsWithChildren<{\n /** Left-aligned content */\n left?: ReactNode;\n /** Right-aligned content */\n right?: ReactNode;\n className?: string;\n}>;\n\n/**\n * Pre-built bottom toolbar layout with left / right slots.\n * Typically shown on desktop while ScaffoldFooter is shown on mobile.\n * Pass `children` for full custom control (left/right will be ignored).\n */\nexport function ScaffoldToolbar({\n children,\n left,\n right,\n className,\n}: ScaffoldToolbarProps) {\n if (children) {\n return (\n <div\n className={cn(\n \"w-full h-full flex items-center bg-background border-t border-border\",\n className,\n )}\n >\n {children}\n </div>\n );\n }\n\n return (\n <div\n className={cn(\n \"w-full h-full px-6 flex items-center justify-between gap-4 bg-background border-t border-border\",\n className,\n )}\n >\n {left && <div className=\"flex items-center gap-4\">{left}</div>}\n {right && <div className=\"flex items-center gap-4\">{right}</div>}\n </div>\n );\n}\n","import { cn, Link } from \"@liberfi.io/ui\";\n\nexport type LogoProps = {\n /** icon for desktop */\n icon: React.ReactNode;\n /** icon for mobile & desktop */\n miniIcon?: React.ReactNode;\n /** url when clicking the logo image */\n href?: string;\n /** Accessible label for the logo link (sets aria-label) */\n ariaLabel?: string;\n /** custom styles */\n className?: string;\n};\n\nexport function Logo({\n href = \"/\",\n icon,\n miniIcon,\n ariaLabel = \"Home\",\n className,\n}: LogoProps) {\n return (\n <Link\n href={href}\n className={cn(\"flex-none flex justify-center items-center\", className)}\n aria-label={ariaLabel}\n >\n <div\n className={cn(\n \"flex justify-center items-center\",\n !!miniIcon && \"max-xl:hidden\",\n )}\n >\n {icon}\n </div>\n {miniIcon && (\n <div className=\"flex justify-center items-center xl:hidden\">\n {miniIcon}\n </div>\n )}\n </Link>\n );\n}\n","import { ReactNode, useCallback, useEffect, useRef, useState } from \"react\";\nimport { useEventEmitter } from \"@liberfi.io/hooks\";\nimport { useDisclosure } from \"@liberfi.io/ui\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type RenderAsyncModalProps<P = any, R = any> = {\n /** custom parameters for the modal */\n params?: P;\n /** whether the modal is open */\n isOpen: boolean;\n /** close the modal without a result (resolves Promise with undefined) */\n onClose: () => void;\n /** change the open state of the modal */\n onOpenChange: (isOpen: boolean) => void;\n /** submit a result and auto-close the modal */\n onResult: (result: R) => void;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AsyncModalProps<P = any, R = any> = {\n /** unique identifier for the modal */\n id: string;\n /** render the modal content */\n children: (props: RenderAsyncModalProps<P, R>) => ReactNode;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type OpenAsyncModalOptions<P = any, R = any> = {\n /** custom parameters for the modal */\n params?: P;\n /** callback when the modal resolves (result value, or undefined on dismiss) */\n onResult?: (result: R | undefined) => void;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function AsyncModal<P = any, R = any>({\n id,\n children,\n}: AsyncModalProps<P, R>) {\n const events = useEventEmitter();\n const { isOpen, onOpen, onClose, onOpenChange } = useDisclosure();\n\n const [params, setParams] = useState<P | undefined>(undefined);\n const onResultRef = useRef<((result: R | undefined) => void) | undefined>(\n undefined,\n );\n\n const cleanup = useCallback(() => {\n onResultRef.current = undefined;\n setParams(undefined);\n }, []);\n\n const wrappedOnClose = useCallback(() => {\n onResultRef.current?.(undefined);\n cleanup();\n onClose();\n }, [onClose, cleanup]);\n\n const wrappedOnResult = useCallback(\n (result: R) => {\n onResultRef.current?.(result);\n cleanup();\n onClose();\n },\n [onClose, cleanup],\n );\n\n const wrappedOnOpenChange = useCallback(\n (open: boolean) => {\n if (!open) {\n wrappedOnClose();\n }\n },\n [wrappedOnClose],\n );\n\n useEffect(() => {\n const handler = (options?: OpenAsyncModalOptions<P, R>) => {\n setParams(options?.params);\n onResultRef.current = options?.onResult;\n onOpen();\n };\n events.on(`open_modal:${id}`, handler);\n return () => {\n events.off(`open_modal:${id}`, handler);\n };\n }, [id, onOpen, events]);\n\n useEffect(() => {\n const handler = () => {\n wrappedOnClose();\n };\n events.on(`close_modal:${id}`, handler);\n return () => {\n events.off(`close_modal:${id}`, handler);\n };\n }, [id, wrappedOnClose, events]);\n\n return children({\n params,\n isOpen,\n onClose: wrappedOnClose,\n onOpenChange: wrappedOnOpenChange,\n onResult: wrappedOnResult,\n });\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { useCallback } from \"react\";\nimport { useEventEmitter } from \"@liberfi.io/hooks\";\nimport { OpenAsyncModalOptions } from \"./AsyncModal\";\n\nexport type UseAsyncModalReturnType<P = any, R = any> = {\n /** Open the modal. Returns a Promise that resolves with the result, or undefined on dismiss. */\n onOpen: (options?: OpenAsyncModalOptions<P, R>) => Promise<R | undefined>;\n /** Close the modal from outside (triggers dismiss). */\n onClose: () => void;\n};\n\nexport function useAsyncModal<P = any, R = any>(\n id: string,\n): UseAsyncModalReturnType<P, R> {\n const events = useEventEmitter();\n\n const onOpen = useCallback(\n (options?: OpenAsyncModalOptions<P, R>): Promise<R | undefined> => {\n return new Promise<R | undefined>((resolve) => {\n const wrappedOnResult = (result: R | undefined) => {\n options?.onResult?.(result);\n resolve(result);\n };\n events.emit(`open_modal:${id}`, {\n ...options,\n onResult: wrappedOnResult,\n } satisfies OpenAsyncModalOptions<P, R>);\n });\n },\n [id, events],\n );\n\n const onClose = useCallback(() => {\n events.emit(`close_modal:${id}`);\n }, [id, events]);\n\n return { onOpen, onClose };\n}\n","import { cn } from \"@liberfi.io/ui\";\n\nexport type SplitHandleProps = {\n direction: \"horizontal\" | \"vertical\";\n isResizing: boolean;\n onResizeStart: (e: React.MouseEvent) => void;\n className?: string;\n};\n\nexport function SplitHandle({\n direction,\n isResizing,\n onResizeStart,\n className,\n}: SplitHandleProps) {\n const isHorizontal = direction === \"horizontal\";\n\n return (\n <div className={cn(\"relative flex-none\", className)}>\n <div\n className={cn(\n \"flex items-center justify-center bg-border/80 hover:bg-border transition-colors duration-150 ease-in-out\",\n isHorizontal\n ? \"w-1 h-full cursor-ew-resize flex-col gap-1\"\n : \"w-full h-1 cursor-ns-resize flex-row gap-1\",\n )}\n >\n <i className=\"rounded-full w-0.5 h-0.5 bg-neutral\" />\n <i className=\"rounded-full w-0.5 h-0.5 bg-neutral\" />\n <i className=\"rounded-full w-0.5 h-0.5 bg-neutral\" />\n\n <div\n className={cn(\n \"absolute inset-0\",\n isHorizontal\n ? \"-left-1.5 -right-1.5 cursor-ew-resize\"\n : \"-top-1.5 -bottom-1.5 cursor-ns-resize\",\n )}\n onMouseDown={onResizeStart}\n />\n </div>\n\n {isResizing && (\n <div\n className={cn(\n \"fixed inset-0 z-50\",\n isHorizontal ? \"cursor-ew-resize\" : \"cursor-ns-resize\",\n )}\n />\n )}\n </div>\n );\n}\n","import { type ReactNode, useCallback, useRef, useState } from \"react\";\nimport { useCallbackRef, useValueRef } from \"@liberfi.io/hooks\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { SplitHandle } from \"./SplitHandle\";\n\nconst HANDLE_SIZE = 4;\n\nexport type SplitViewProps = {\n /** Split direction */\n direction?: \"horizontal\" | \"vertical\";\n /** Content for the primary (first) pane */\n primary: ReactNode;\n /** Content for the secondary (second) pane */\n secondary: ReactNode;\n /** Initial size of the primary pane in px */\n defaultSize?: number;\n /** Minimum size of the primary pane in px */\n minSize?: number;\n /** Maximum size of the primary pane in px */\n maxSize?: number;\n /** Minimum size of the secondary pane in px */\n secondaryMinSize?: number;\n /** Callback when size changes */\n onSizeChange?: (size: number) => void;\n /** Unique id for localStorage persistence (omit to disable) */\n persistId?: string;\n className?: string;\n classNames?: {\n primary?: string;\n secondary?: string;\n handle?: string;\n };\n};\n\nfunction getPersistedSize(id: string | undefined): number | null {\n if (!id) return null;\n try {\n const raw = localStorage.getItem(`splitView.${id}`);\n return raw ? Number(raw) : null;\n } catch {\n return null;\n }\n}\n\nfunction persistSize(id: string | undefined, size: number) {\n if (!id) return;\n try {\n localStorage.setItem(`splitView.${id}`, String(size));\n } catch {\n // noop\n }\n}\n\n/**\n * Resizable split-view container with a draggable handle between two panes.\n * Supports horizontal (left | right) and vertical (top | bottom) splitting.\n * Composable: nest SplitViews for complex layouts (e.g. trading dashboards).\n */\nexport function SplitView({\n direction = \"horizontal\",\n primary,\n secondary,\n defaultSize = 400,\n minSize = 100,\n maxSize = Infinity,\n secondaryMinSize = 100,\n onSizeChange,\n persistId,\n className,\n classNames,\n}: SplitViewProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const [size, setSize] = useState<number>(\n () => getPersistedSize(persistId) ?? defaultSize,\n );\n const [isResizing, setIsResizing] = useState(false);\n\n const isHorizontal = direction === \"horizontal\";\n\n const sizeRef = useValueRef(size);\n const minSizeRef = useValueRef(minSize);\n const maxSizeRef = useValueRef(maxSize);\n const secondaryMinSizeRef = useValueRef(secondaryMinSize);\n const isResizingRef = useValueRef(isResizing);\n\n const handleSizeChange = useCallbackRef((newSize: number) => {\n setSize(newSize);\n persistSize(persistId, newSize);\n onSizeChange?.(newSize);\n });\n\n const handleResizeStart = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsResizing(true);\n\n const cursor = isHorizontal ? \"ew-resize\" : \"ns-resize\";\n document.body.style.cursor = cursor;\n document.body.style.userSelect = \"none\";\n\n const startPos = isHorizontal ? e.clientX : e.clientY;\n const startSize = sizeRef.current;\n const containerEl = containerRef.current;\n const containerTotal = containerEl\n ? isHorizontal\n ? containerEl.offsetWidth\n : containerEl.offsetHeight\n : Infinity;\n\n const onMouseMove = (ev: MouseEvent) => {\n if (!isResizingRef.current) return;\n\n const currentPos = isHorizontal ? ev.clientX : ev.clientY;\n const delta = currentPos - startPos;\n\n const effectiveMax = Math.min(\n maxSizeRef.current,\n containerTotal - secondaryMinSizeRef.current - HANDLE_SIZE,\n );\n\n const newSize = Math.min(\n Math.max(startSize + delta, minSizeRef.current),\n effectiveMax,\n );\n handleSizeChange(newSize);\n };\n\n const onMouseUp = () => {\n setIsResizing(false);\n document.body.style.cursor = \"\";\n document.body.style.userSelect = \"\";\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"mouseup\", onMouseUp);\n };\n\n document.addEventListener(\"mousemove\", onMouseMove);\n document.addEventListener(\"mouseup\", onMouseUp);\n },\n [\n isHorizontal,\n sizeRef,\n minSizeRef,\n maxSizeRef,\n secondaryMinSizeRef,\n isResizingRef,\n handleSizeChange,\n ],\n );\n\n return (\n <div\n ref={containerRef}\n className={cn(\n \"w-full h-full flex overflow-hidden\",\n isHorizontal ? \"flex-row\" : \"flex-col\",\n className,\n )}\n >\n <div\n className={cn(\"flex-none overflow-hidden\", classNames?.primary)}\n style={\n isHorizontal\n ? { width: `${size}px`, minWidth: `${minSize}px` }\n : { height: `${size}px`, minHeight: `${minSize}px` }\n }\n >\n {primary}\n </div>\n\n <SplitHandle\n direction={direction}\n isResizing={isResizing}\n onResizeStart={handleResizeStart}\n className={classNames?.handle}\n />\n\n <div\n className={cn(\n \"flex-auto min-w-0 min-h-0 overflow-hidden\",\n classNames?.secondary,\n )}\n style={\n isHorizontal\n ? { minWidth: `${secondaryMinSize}px` }\n : { minHeight: `${secondaryMinSize}px` }\n }\n >\n {secondary}\n </div>\n </div>\n );\n}\n","declare global {\n interface Window {\n __LIBERFI_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};\n window.__LIBERFI_VERSION__[\"@liberfi.io/ui-scaffold\"] = \"0.1.112\";\n}\n\nexport default \"0.1.112\";\n"]}
1
+ {"version":3,"sources":["../src/components/draggable/states.ts","../src/components/draggable/useDraggableModalDisclosure.ts","../src/components/draggable/useDraggablePanelDisclosure.ts","../src/components/draggable/DraggableModal.tsx","../src/components/draggable/DraggablePanel.tsx","../src/components/draggable/DraggablePanelProvider.tsx","../src/components/draggable/useDraggableDisclosure.ts","../src/components/layout/types.ts","../src/components/layout/ScaffoldContext.ts","../src/components/layout/Scaffold.tsx","../src/components/layout/NavLink.tsx","../src/components/layout/ScaffoldHeader.tsx","../src/components/layout/ScaffoldFooter.tsx","../src/components/layout/ScaffoldToolbar.tsx","../src/components/layout/Logo.tsx","../src/components/modal/AsyncModal.tsx","../src/components/modal/useAsyncModal.ts","../src/components/split/SplitHandle.tsx","../src/components/split/SplitView.tsx","../src/version.ts"],"names":["_storagePrefix","setDraggableStoragePrefix","prefix","storageKey","name","id","base","panelStateFamily","atomFamily","atomWithStorage","panelWidthFamily","panelMinWidthFamily","panelMaxWidthFamily","modalOpenFamily","modalShouldStartDraggingFamily","modalSizeFamily","modalRestoreSizeFamily","modalPositionFamily","modalRestorePositionFamily","modalMinimizedFamily","modalMinWidthFamily","modalMaxWidthFamily","lastDraggableTypeFamily","panelOrdersFamily","_","useDraggableModalDisclosure","isOpen","setIsOpen","useAtom","isMinimized","setIsMinimized","restoreSize","useAtomValue","restorePosition","setSize","useSetAtom","setPosition","setShouldStartDragging","setLastDraggableType","onOpen","useCallback","options","shouldStartDragging","position","size","prev","onClose","useMemo","useDraggablePanelDisclosure","panelState","setPanelState","setPanelWidth","setPanelOrders","left","right","MINIMIZED_SIZE","MAXIMIZED_SIZE","MAXIMIZED_POSITION","DraggableModal","memo","title","minWidth","maxWidth","minHeight","maxHeight","leftSidebar","leftSidebarWidth","rightSidebar","rightSidebarWidth","aspectRatio","showHeader","header","headerHeight","children","t","useTranslation","onOpenPanel","setRestoreSize","setRestorePosition","isDragging","setIsDragging","useState","isResizing","setIsResizing","resizeDirection","setResizeDirection","currentEdge","setCurrentEdge","dockAnimationEdge","setDockAnimationEdge","dockToEdge","setDockToEdge","dockToEdgeTimeoutRef","useRef","panelMinWidth","panelMaxWidth","positionRef","useValueRef","setPositionRef","useCallbackRef","sizeRef","setSizeRef","leftSidebarWidthRef","hasLeftSidebarRef","rightSidebarWidthRef","hasRightSidebarRef","aspectRatioRef","headerHeightRef","minWidthRef","maxWidthRef","minHeightRef","maxHeightRef","isDraggingRef","currentEdgeRef","dockToEdgeRef","onCloseRef","onOpenPanelRef","panelMinWidthRef","panelMaxWidthRef","isMaximized","useEffect","clampedWidth","clampedHeight","newX","newY","handleMouseMove","e","handleMouseUp","startInteraction","interactionType","direction","startX","startY","startWidth","startHeight","startPosition","cleanup","deltaX","deltaY","leftOffset","minX","rightOffset","maxX","maxY","edge","calculateNewSize","width","height","constraint","newWidth","newHeight","widthBasedHeight","heightBasedWidth","absDeltaX","absDeltaY","avgHeight","newSize","handleMinimize","handleMaximize","handleResize","throttle","bottom","jsxs","Fragment","createPortal","jsx","cn","StyledTooltip","DraggableIcon","Button","RestoreWindowIcon","MinimizeIcon","UnMaximizeIcon","MaximizeIcon","XCloseIcon","DraggablePanel","setWidth","openModal","closePanel","modalMinWidth","modalMaxWidth","widthRef","isResizingRef","setWidthRef","openModalRef","closePanelRef","modalMinWidthRef","modalMaxWidthRef","handleResizeStart","onResize","distance","onResizeEnd","handleDragStart","onDragMove","onDragEnd","handleClose","ResizeHandle","DraggablePanelProvider","contents","storagePrefix","className","classNames","prefixApplied","panelOrders","store","getDefaultStore","content","leftOpenPanels","a","b","rightOpenPanels","props","useDraggableDisclosure","isModalOpen","onOpenModal","onCloseModal","isPanelOpen","onClosePanel","lastDraggableType","ALL_BREAKPOINTS","isNavItemActive","item","pathname","getVisibilityClass","breakpoints","has","ScaffoldContext","createContext","useScaffold","ctx","useContext","useScaffoldLayout","config","DEFAULT_HEADER_HEIGHT","DEFAULT_MOBILE_HEADER_HEIGHT","DEFAULT_FOOTER_HEIGHT","DEFAULT_TOOLBAR_HEIGHT","noop","Scaffold","onNavigate","footer","toolbar","mobileHeaderHeight","footerHeight","toolbarHeight","defaultHeaderVisible","defaultFooterVisible","defaultToolbarVisible","headerVisible","setHeaderVisible","footerVisible","setFooterVisible","toolbarVisible","setToolbarVisible","scaffoldId","useId","ctxValue","headerClass","footerClass","toolbarClass","headerStyleRule","NavLink","variant","active","handlePress","ScaffoldHeader","navItems","style","HorizontalScrollContainer","ScaffoldFooter","ScaffoldToolbar","Logo","href","icon","miniIcon","ariaLabel","Link","AsyncModal","events","useEventEmitter","onOpenChange","useDisclosure","params","setParams","onResultRef","wrappedOnClose","wrappedOnResult","result","wrappedOnOpenChange","open","handler","useAsyncModal","resolve","SplitHandle","onResizeStart","isHorizontal","HANDLE_SIZE","getPersistedSize","raw","persistSize","SplitView","primary","secondary","defaultSize","minSize","maxSize","secondaryMinSize","onSizeChange","persistId","containerRef","minSizeRef","maxSizeRef","secondaryMinSizeRef","handleSizeChange","cursor","startPos","startSize","containerEl","containerTotal","onMouseMove","ev","delta","effectiveMax","onMouseUp","version_default"],"mappings":"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","file":"index.js","sourcesContent":["\"use client\";\n\nimport { atomFamily } from \"jotai-family\";\nimport { atomWithStorage } from \"jotai/utils\";\n\nlet _storagePrefix = \"\";\n\n/**\n * Set a prefix for all draggable localStorage keys.\n * Must be called before any draggable component renders.\n *\n * @example\n * setDraggableStoragePrefix(\"myapp\");\n * // keys become: \"myapp:panelState.chart\", \"myapp:modalOpen.chart\", etc.\n */\nexport function setDraggableStoragePrefix(prefix: string) {\n _storagePrefix = prefix;\n}\n\nfunction storageKey(name: string, id: string | null): string {\n const base = `${name}.${id ?? \"default\"}`;\n return _storagePrefix ? `${_storagePrefix}:${base}` : base;\n}\n\n/** whether the panel is docked or not */\nexport const panelStateFamily = atomFamily((id: string | null) =>\n atomWithStorage<\"none\" | \"left\" | \"right\">(\n storageKey(\"panelState\", id),\n \"none\",\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n\n/** width of the panel */\nexport const panelWidthFamily = atomFamily((id: string | null) =>\n atomWithStorage(storageKey(\"panelWidth\", id), 350, undefined, {\n getOnInit: true,\n }),\n);\n\nexport const panelMinWidthFamily = atomFamily((id: string | null) =>\n atomWithStorage(storageKey(\"panelMinWidth\", id), 320, undefined, {\n getOnInit: true,\n }),\n);\n\nexport const panelMaxWidthFamily = atomFamily((id: string | null) =>\n atomWithStorage(storageKey(\"panelMaxWidth\", id), 440, undefined, {\n getOnInit: true,\n }),\n);\n\n/** whether the modal is open */\nexport const modalOpenFamily = atomFamily((id: string | null) =>\n atomWithStorage(storageKey(\"modalOpen\", id), false, undefined, {\n getOnInit: true,\n }),\n);\n\n/** whether the modal should start dragging automatically when opened */\nexport const modalShouldStartDraggingFamily = atomFamily((id: string | null) =>\n atomWithStorage(\n storageKey(\"modalShouldStartDragging\", id),\n false,\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n\n/** size of the modal */\nexport const modalSizeFamily = atomFamily((id: string | null) =>\n atomWithStorage<{ width: number; height: number }>(\n storageKey(\"modalSize\", id),\n { width: 350, height: 580 },\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n\n/** restore size of the modal when maximized or minimized */\nexport const modalRestoreSizeFamily = atomFamily((id: string | null) =>\n atomWithStorage<{ width: number; height: number }>(\n storageKey(\"modalRestoreSize\", id),\n { width: 350, height: 580 },\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n\n/** position of the modal */\nexport const modalPositionFamily = atomFamily((id: string | null) =>\n atomWithStorage<{ x: number; y: number }>(\n storageKey(\"modalPosition\", id),\n {\n x:\n typeof window !== \"undefined\"\n ? Math.max(0, (window.innerWidth - 350) / 2)\n : 0,\n y:\n typeof window !== \"undefined\"\n ? Math.max(0, (window.innerHeight - 580) / 2)\n : 0,\n },\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n\n/** restore position of the modal when maximized or minimized */\nexport const modalRestorePositionFamily = atomFamily((id: string | null) =>\n atomWithStorage<{ x: number; y: number }>(\n storageKey(\"modalRestorePosition\", id),\n {\n x:\n typeof window !== \"undefined\"\n ? Math.max(0, (window.innerWidth - 350) / 2)\n : 0,\n y:\n typeof window !== \"undefined\"\n ? Math.max(0, (window.innerHeight - 580) / 2)\n : 0,\n },\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n\nexport const modalMinimizedFamily = atomFamily((id: string | null) =>\n atomWithStorage<boolean>(storageKey(\"modalMinimized\", id), false, undefined, {\n getOnInit: true,\n }),\n);\n\nexport const modalMinWidthFamily = atomFamily((id: string | null) =>\n atomWithStorage<number>(storageKey(\"modalMinWidth\", id), 200, undefined, {\n getOnInit: true,\n }),\n);\n\nexport const modalMaxWidthFamily = atomFamily((id: string | null) =>\n atomWithStorage<number>(\n storageKey(\"modalMaxWidth\", id),\n typeof window !== \"undefined\" ? window.innerWidth - 40 : 0,\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n\nexport const lastDraggableTypeFamily = atomFamily((id: string | null) =>\n atomWithStorage<\"left\" | \"right\" | \"modal\">(\n storageKey(\"lastPanelType\", id),\n \"modal\",\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n\n/** Wrapped in atomFamily for lazy creation so it picks up the storage prefix */\nexport const panelOrdersFamily = atomFamily((_: null) =>\n atomWithStorage<{\n left: { [id: string]: number };\n right: { [id: string]: number };\n }>(\n storageKey(\"panelOrders\", null),\n {\n left: {},\n right: {},\n },\n undefined,\n {\n getOnInit: true,\n },\n ),\n);\n","\"use client\";\n\nimport { useCallback, useMemo } from \"react\";\nimport { useAtom, useAtomValue, useSetAtom } from \"jotai\";\nimport {\n lastDraggableTypeFamily,\n modalMinimizedFamily,\n modalOpenFamily,\n modalPositionFamily,\n modalRestorePositionFamily,\n modalRestoreSizeFamily,\n modalShouldStartDraggingFamily,\n modalSizeFamily,\n} from \"./states\";\n\nexport type OpenDraggableModalOptions = {\n /** should start dragging automatically when the modal is opened */\n shouldStartDragging?: boolean;\n /** adjust position of the modal when it is opened */\n position?: { x?: number; y?: number };\n /** adjust size of the modal when it is opened */\n size?: { width?: number; height?: number };\n};\n\nexport type UseDraggableModalDisclosureReturnType = {\n isOpen: boolean;\n onOpen: (options?: OpenDraggableModalOptions) => void;\n onClose: () => void;\n};\n\nexport function useDraggableModalDisclosure(\n id: string,\n): UseDraggableModalDisclosureReturnType {\n const [isOpen, setIsOpen] = useAtom(modalOpenFamily(id));\n const [isMinimized, setIsMinimized] = useAtom(modalMinimizedFamily(id));\n const restoreSize = useAtomValue(modalRestoreSizeFamily(id));\n const restorePosition = useAtomValue(modalRestorePositionFamily(id));\n const setSize = useSetAtom(modalSizeFamily(id));\n const setPosition = useSetAtom(modalPositionFamily(id));\n const setShouldStartDragging = useSetAtom(modalShouldStartDraggingFamily(id));\n const setLastDraggableType = useSetAtom(lastDraggableTypeFamily(id));\n\n const onOpen = useCallback(\n (options: OpenDraggableModalOptions = {}) => {\n const { shouldStartDragging, position, size } = options;\n if (position) setPosition((prev) => ({ ...prev, ...position }));\n if (size) setSize((prev) => ({ ...prev, ...size }));\n setShouldStartDragging(shouldStartDragging ?? false);\n setIsOpen(true);\n setLastDraggableType(\"modal\");\n },\n [setIsOpen, setPosition, setSize, setShouldStartDragging],\n );\n\n const onClose = useCallback(() => {\n setIsOpen(false);\n // restore the modal if it is minimized when closing\n if (isMinimized) {\n setSize({ ...restoreSize });\n setPosition({ ...restorePosition });\n setIsMinimized(false);\n }\n }, [\n isMinimized,\n restoreSize,\n restorePosition,\n setIsMinimized,\n setIsOpen,\n setSize,\n setPosition,\n ]);\n\n return useMemo(\n () => ({\n isOpen,\n onOpen,\n onClose,\n }),\n [isOpen, onOpen, onClose],\n );\n}\n","\"use client\";\n\nimport { useCallback, useMemo } from \"react\";\nimport { useAtom, useSetAtom } from \"jotai\";\nimport {\n lastDraggableTypeFamily,\n panelOrdersFamily,\n panelStateFamily,\n panelWidthFamily,\n} from \"./states\";\n\nexport type OpenDraggablePanelOptions = {\n /** which side the panel is docked on */\n position?: \"left\" | \"right\";\n /** adjust size of the modal when it is opened */\n width?: number;\n};\n\nexport type UseDraggablePanelDisclosureReturnType = {\n isOpen: boolean;\n position?: \"left\" | \"right\";\n onOpen: (options?: OpenDraggablePanelOptions) => void;\n onClose: () => void;\n};\n\nexport function useDraggablePanelDisclosure(\n id: string,\n): UseDraggablePanelDisclosureReturnType {\n const [panelState, setPanelState] = useAtom(panelStateFamily(id));\n const setPanelWidth = useSetAtom(panelWidthFamily(id));\n const setLastDraggableType = useSetAtom(lastDraggableTypeFamily(id));\n const setPanelOrders = useSetAtom(panelOrdersFamily(null));\n\n const onOpen = useCallback(\n (options: OpenDraggablePanelOptions = {}) => {\n const position = options.position ?? \"left\";\n setPanelWidth(options.width ?? 320);\n setPanelState(position);\n setLastDraggableType(position);\n setPanelOrders(({ left, right }) => {\n if (position === \"left\") {\n return { left: { ...left, [id]: Date.now() }, right };\n } else {\n return { left, right: { ...right, [id]: Date.now() } };\n }\n });\n },\n [id, setPanelState, setPanelWidth],\n );\n\n const onClose = useCallback(() => {\n setPanelState(\"none\");\n }, [setPanelState]);\n\n const isOpen = useMemo(() => panelState !== \"none\", [panelState]);\n\n const position = useMemo(\n () => (panelState !== \"none\" ? panelState : undefined),\n [panelState],\n );\n\n return useMemo(\n () => ({\n isOpen,\n position,\n onOpen,\n onClose,\n }),\n [isOpen, onOpen, onClose],\n );\n}\n","\"use client\";\n\nimport {\n memo,\n useState,\n useEffect,\n useRef,\n PropsWithChildren,\n useMemo,\n useCallback,\n} from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useAtom, useAtomValue } from \"jotai\";\nimport { useCallbackRef, useValueRef } from \"@liberfi.io/hooks\";\nimport { useTranslation } from \"@liberfi.io/i18n\";\nimport {\n Button,\n cn,\n DraggableIcon,\n MaximizeIcon,\n MinimizeIcon,\n RestoreWindowIcon,\n StyledTooltip,\n UnMaximizeIcon,\n XCloseIcon,\n} from \"@liberfi.io/ui\";\nimport { throttle } from \"@liberfi.io/utils\";\nimport {\n modalMinimizedFamily,\n modalPositionFamily,\n modalRestorePositionFamily,\n modalRestoreSizeFamily,\n modalShouldStartDraggingFamily,\n modalSizeFamily,\n panelMaxWidthFamily,\n panelMinWidthFamily,\n} from \"./states\";\nimport { useDraggableModalDisclosure } from \"./useDraggableModalDisclosure\";\nimport { useDraggablePanelDisclosure } from \"./useDraggablePanelDisclosure\";\n\nconst MINIMIZED_SIZE = {\n width: 200,\n height: 48,\n};\n\nconst MAXIMIZED_SIZE = {\n width: typeof window !== \"undefined\" ? window.innerWidth - 40 : 0,\n height: typeof window !== \"undefined\" ? window.innerHeight - 40 : 0,\n};\n\nconst MAXIMIZED_POSITION = {\n x: 20,\n y: 20,\n};\n\ntype ResizeDirection =\n | \"topLeft\"\n | \"topRight\"\n | \"bottomLeft\"\n | \"bottomRight\"\n | \"top\"\n | \"bottom\"\n | \"left\"\n | \"right\";\n\nexport type DraggableModalProps = PropsWithChildren<{\n /** unique identifier for the modal, must be the same with the panel */\n id: string;\n /** title of the modal */\n title?: React.ReactNode;\n /** constraints for the minimum width */\n minWidth?: number;\n /** constraints for the maximum width */\n maxWidth?: number;\n /** constraints for the minimum height */\n minHeight?: number;\n /** constraints for the maximum height */\n maxHeight?: number;\n /** left sidebar of the modal */\n leftSidebar?: React.ReactNode;\n /** width of the left sidebar */\n leftSidebarWidth?: number;\n /** right sidebar of the modal */\n rightSidebar?: React.ReactNode;\n /** width of the right sidebar */\n rightSidebarWidth?: number;\n /** constraints for the aspect ratio when resizing */\n aspectRatio?: number;\n /** whether to show the header */\n showHeader?: boolean;\n /** custom header content */\n header?: React.ReactNode;\n /** height of the modal header */\n headerHeight?: number;\n}>;\n\nexport const DraggableModal = memo(function DraggablePopup({\n id,\n title,\n minWidth = 504,\n maxWidth = MAXIMIZED_SIZE.width,\n minHeight = 200,\n maxHeight = MAXIMIZED_SIZE.height,\n leftSidebar,\n leftSidebarWidth = 200,\n rightSidebar,\n rightSidebarWidth = 200,\n aspectRatio,\n showHeader = true,\n header,\n headerHeight = 44,\n children,\n}: DraggableModalProps) {\n const { t } = useTranslation();\n\n // control the open state of the modal\n const { isOpen, onClose } = useDraggableModalDisclosure(id);\n\n // control the open state of the panel\n const { onOpen: onOpenPanel } = useDraggablePanelDisclosure(id);\n\n // whether the modal is minimized\n const [isMinimized, setIsMinimized] = useAtom(modalMinimizedFamily(id));\n\n // latest position\n const [position, setPosition] = useAtom(modalPositionFamily(id));\n\n // latest modal size\n const [size, setSize] = useAtom(modalSizeFamily(id));\n\n // restore size when maximized or minimized\n const [restoreSize, setRestoreSize] = useAtom(modalRestoreSizeFamily(id));\n\n // restore position when maximized or minimized\n const [restorePosition, setRestorePosition] = useAtom(\n modalRestorePositionFamily(id),\n );\n\n // start dragging automatically when the component is mounted\n const [shouldStartDragging, setShouldStartDragging] = useAtom(\n modalShouldStartDraggingFamily(id),\n );\n\n // whether the modal is being dragged\n const [isDragging, setIsDragging] = useState(shouldStartDragging);\n\n // whether the modal is being resized\n const [isResizing, setIsResizing] = useState(false);\n\n // direction of the resize\n const [resizeDirection, setResizeDirection] =\n useState<ResizeDirection | null>(null);\n\n // which edge is the modal near\n const [currentEdge, setCurrentEdge] = useState<\"left\" | \"right\" | null>(null);\n\n // which edge to display docking animation\n const [dockAnimationEdge, setDockAnimationEdge] = useState<\n \"left\" | \"right\" | null\n >(null);\n\n // which edge is waiting for the timeout to dock on\n const [dockToEdge, setDockToEdge] = useState<\"left\" | \"right\" | null>(null);\n\n // timeout for docking to the edge\n const dockToEdgeTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n const panelMinWidth = useAtomValue(panelMinWidthFamily(id));\n\n const panelMaxWidth = useAtomValue(panelMaxWidthFamily(id));\n\n // refs for props & states to avoid re-rendering\n const positionRef = useValueRef(position);\n const setPositionRef = useCallbackRef(setPosition);\n const sizeRef = useValueRef(size);\n const setSizeRef = useCallbackRef(setSize);\n const leftSidebarWidthRef = useValueRef(leftSidebarWidth);\n const hasLeftSidebarRef = useValueRef(!!leftSidebar);\n const rightSidebarWidthRef = useValueRef(rightSidebarWidth);\n const hasRightSidebarRef = useValueRef(!!rightSidebar);\n const aspectRatioRef = useValueRef(aspectRatio);\n const headerHeightRef = useValueRef(headerHeight);\n const minWidthRef = useValueRef(minWidth);\n const maxWidthRef = useValueRef(maxWidth);\n const minHeightRef = useValueRef(minHeight);\n const maxHeightRef = useValueRef(maxHeight);\n const isDraggingRef = useValueRef(isDragging);\n const currentEdgeRef = useValueRef(currentEdge);\n const dockToEdgeRef = useValueRef(dockToEdge);\n const onCloseRef = useCallbackRef(onClose);\n const onOpenPanelRef = useCallbackRef(onOpenPanel);\n const panelMinWidthRef = useValueRef(panelMinWidth);\n const panelMaxWidthRef = useValueRef(panelMaxWidth);\n\n // whether the modal is maximized\n const isMaximized = useMemo(\n () =>\n size.width === MAXIMIZED_SIZE.width &&\n size.height === MAXIMIZED_SIZE.height,\n [size.width, size.height],\n );\n\n // clamp size to min/max constraints and adjust position when the component is mounted\n useEffect(() => {\n const clampedWidth = Math.min(Math.max(size.width, minWidth), maxWidth);\n const clampedHeight = Math.min(Math.max(size.height, minHeight), maxHeight);\n if (clampedWidth !== size.width || clampedHeight !== size.height) {\n setSizeRef({ width: clampedWidth, height: clampedHeight });\n }\n\n let newX = Math.max(0, position.x);\n let newY = Math.max(0, position.y);\n if (newX + clampedWidth > window.innerWidth) {\n newX = Math.max(0, window.innerWidth - clampedWidth);\n }\n if (newY + clampedHeight > window.innerHeight) {\n newY = Math.max(0, window.innerHeight - clampedHeight);\n }\n if (newX !== position.x || newY !== position.y) {\n setPositionRef({ x: newX, y: newY });\n }\n }, [id]);\n\n // start dragging automatically when the component is mounted, just follow the mouse movement\n useEffect(() => {\n if (isOpen && shouldStartDragging) {\n setIsDragging(true);\n\n const handleMouseMove = (e: MouseEvent) => {\n setPositionRef({\n x: e.clientX - size.width / 2,\n y: e.clientY - 20,\n });\n };\n\n const handleMouseUp = () => {\n setIsDragging(false);\n // finish start dragging\n setShouldStartDragging(false);\n document.removeEventListener(\"mousemove\", handleMouseMove);\n document.removeEventListener(\"mouseup\", handleMouseUp);\n };\n\n document.addEventListener(\"mousemove\", handleMouseMove);\n document.addEventListener(\"mouseup\", handleMouseUp);\n document.body.style.cursor = \"grabbing\";\n\n return () => {\n document.removeEventListener(\"mousemove\", handleMouseMove);\n document.removeEventListener(\"mouseup\", handleMouseUp);\n document.body.style.cursor = \"\";\n };\n }\n }, [isOpen, shouldStartDragging, setShouldStartDragging, size.width]);\n\n const startInteraction = (\n e: React.MouseEvent,\n interactionType: \"drag\" | \"resize\",\n direction?: ResizeDirection,\n ) => {\n // user interaction starts, stop auto-dragging which is triggered when the component is mounted\n setShouldStartDragging(false);\n\n // reset states\n setIsDragging(false);\n setIsResizing(false);\n setResizeDirection(null);\n\n // set states according to interaction type\n if (interactionType === \"drag\") {\n setIsDragging(true);\n } else if (interactionType === \"resize\") {\n setResizeDirection(direction || null);\n setIsResizing(true);\n }\n\n // save start position and size in closure\n const startX = e.clientX;\n const startY = e.clientY;\n const startWidth = sizeRef.current.width;\n const startHeight = sizeRef.current.height;\n const startPosition = { ...positionRef.current };\n\n const cleanup = () => {\n document.removeEventListener(\"mousemove\", handleMouseMove);\n document.removeEventListener(\"mouseup\", handleMouseUp);\n document.body.style.cursor = \"\";\n\n setIsDragging(false);\n setIsResizing(false);\n setResizeDirection(null);\n setCurrentEdge(null);\n\n if (dockToEdgeTimeoutRef.current) {\n clearTimeout(dockToEdgeTimeoutRef.current);\n dockToEdgeTimeoutRef.current = null;\n }\n setDockToEdge(null);\n setDockAnimationEdge(null);\n };\n\n const handleMouseMove = (e: MouseEvent) => {\n if (interactionType === \"drag\") {\n const deltaX = e.clientX - startX;\n const deltaY = e.clientY - startY;\n let newX = startPosition.x + deltaX;\n let newY = startPosition.y + deltaY;\n\n // calculate boundaries\n const leftOffset = hasLeftSidebarRef.current\n ? leftSidebarWidthRef.current\n : 0;\n const minX = 12 + leftOffset;\n\n const rightOffset = hasRightSidebarRef.current\n ? rightSidebarWidthRef.current\n : 0;\n const maxX = window.innerWidth - 12 - startWidth - rightOffset;\n\n // display 44px for header\n const maxY = window.innerHeight - 12 - 44;\n\n // check if near the edge\n const edge = newX <= minX ? \"left\" : newX >= maxX ? \"right\" : null;\n if (edge !== currentEdgeRef.current) {\n setCurrentEdge(edge);\n }\n\n // if is waiting for the timeout to dock on the edge, display the animation\n if (dockToEdgeTimeoutRef.current && edge) {\n setDockAnimationEdge(edge);\n }\n\n // interrupt the timeout if the modal is moved away from the edge\n if (dockToEdgeTimeoutRef.current) {\n if (\n (dockToEdgeRef.current === \"left\" &&\n (newX > minX || edge !== \"left\")) ||\n (dockToEdgeRef.current === \"right\" &&\n (newX < maxX || edge !== \"right\"))\n ) {\n clearTimeout(dockToEdgeTimeoutRef.current);\n dockToEdgeTimeoutRef.current = null;\n setDockToEdge(null);\n setDockAnimationEdge(null);\n }\n }\n\n // wait for the timeout to dock on the edge\n if (!dockToEdgeTimeoutRef.current && edge) {\n if (dockToEdgeRef.current !== edge) {\n setDockToEdge(edge);\n setDockAnimationEdge(edge);\n dockToEdgeTimeoutRef.current = setTimeout(() => {\n if (isDraggingRef.current && currentEdgeRef.current === edge) {\n // still dragging & near the edge, convert to panel\n cleanup();\n // close modal\n onCloseRef();\n // open panel\n onOpenPanelRef({\n position: edge,\n width: Math.min(\n Math.max(sizeRef.current.width, panelMinWidthRef.current),\n panelMaxWidthRef.current,\n ),\n });\n } else {\n setDockToEdge(null);\n }\n }, 350);\n }\n }\n\n // limit within the boundaries\n newX = Math.min(Math.max(newX, 12 + leftOffset), maxX);\n newY = Math.min(Math.max(newY, 12), maxY);\n setPositionRef({ x: newX, y: newY });\n } else if (interactionType === \"resize\" && direction) {\n const deltaX = e.clientX - startX;\n const deltaY = e.clientY - startY;\n\n // calculate new size (considering aspect ratio)\n const calculateNewSize = (\n width: number,\n height: number,\n constraint: \"width\" | \"height\" | \"both\",\n ) => {\n let newWidth = Math.min(\n Math.max(width, minWidthRef.current),\n maxWidthRef.current,\n );\n let newHeight = Math.min(\n Math.max(height, minHeightRef.current),\n maxHeightRef.current,\n );\n\n if (aspectRatioRef.current) {\n if (constraint === \"width\") {\n newHeight = Math.min(\n Math.max(\n width / aspectRatioRef.current + headerHeightRef.current,\n minHeightRef.current,\n ),\n maxHeightRef.current,\n );\n newWidth =\n (newHeight - headerHeightRef.current) * aspectRatioRef.current;\n } else if (constraint === \"height\") {\n newWidth = Math.min(\n Math.max(\n (height - headerHeightRef.current) * aspectRatioRef.current,\n minWidthRef.current,\n ),\n maxWidthRef.current,\n );\n newHeight =\n newWidth / aspectRatioRef.current + headerHeightRef.current;\n } else {\n const widthBasedHeight =\n width / aspectRatioRef.current + headerHeightRef.current;\n const heightBasedWidth =\n (height - headerHeightRef.current) * aspectRatioRef.current;\n const absDeltaX = Math.abs(deltaX);\n const absDeltaY = Math.abs(deltaY);\n\n if (absDeltaX > 1.1 * absDeltaY) {\n newHeight = Math.min(\n Math.max(widthBasedHeight, minHeightRef.current),\n maxHeightRef.current,\n );\n newWidth =\n (newHeight - headerHeightRef.current) *\n aspectRatioRef.current;\n } else if (absDeltaY > 1.1 * absDeltaX) {\n newWidth = Math.min(\n Math.max(heightBasedWidth, minWidthRef.current),\n maxWidthRef.current,\n );\n newHeight =\n newWidth / aspectRatioRef.current + headerHeightRef.current;\n } else {\n const avgHeight = (newHeight + widthBasedHeight) / 2;\n newWidth = Math.min(\n Math.max(\n (newWidth + heightBasedWidth) / 2,\n minWidthRef.current,\n ),\n maxWidthRef.current,\n );\n newHeight = Math.min(\n Math.max(avgHeight, minHeightRef.current),\n maxHeightRef.current,\n );\n newWidth =\n (newHeight - headerHeightRef.current) *\n aspectRatioRef.current;\n }\n }\n\n newWidth = Math.min(\n Math.max(newWidth, minWidthRef.current),\n maxWidthRef.current,\n );\n newHeight = Math.min(\n Math.max(newHeight, minHeightRef.current),\n maxHeightRef.current,\n );\n }\n\n return { width: newWidth, height: newHeight };\n };\n\n // handle the resize direction\n switch (direction) {\n case \"topLeft\": {\n const newSize = calculateNewSize(\n startWidth - deltaX,\n startHeight - deltaY,\n \"both\",\n );\n setSizeRef(newSize);\n setPositionRef({\n x: startPosition.x + (startWidth - newSize.width),\n y: startPosition.y + (startHeight - newSize.height),\n });\n break;\n }\n case \"topRight\": {\n const newSize = calculateNewSize(\n startWidth + deltaX,\n startHeight - deltaY,\n \"both\",\n );\n setSizeRef(newSize);\n setPositionRef({\n x: startPosition.x,\n y: startPosition.y + (startHeight - newSize.height),\n });\n break;\n }\n case \"bottomLeft\": {\n const newSize = calculateNewSize(\n startWidth - deltaX,\n startHeight + deltaY,\n \"both\",\n );\n setSizeRef(newSize);\n setPositionRef({\n x: startPosition.x + (startWidth - newSize.width),\n y: startPosition.y,\n });\n break;\n }\n case \"bottomRight\": {\n setSizeRef(\n calculateNewSize(\n startWidth + deltaX,\n startHeight + deltaY,\n \"both\",\n ),\n );\n break;\n }\n case \"top\": {\n const newSize = calculateNewSize(\n startWidth,\n startHeight - deltaY,\n \"height\",\n );\n setSizeRef(newSize);\n setPositionRef({\n x: startPosition.x,\n y: startPosition.y + (startHeight - newSize.height),\n });\n break;\n }\n case \"bottom\": {\n setSizeRef(\n calculateNewSize(startWidth, startHeight + deltaY, \"height\"),\n );\n break;\n }\n case \"left\": {\n const newSize = calculateNewSize(\n startWidth - deltaX,\n startHeight,\n \"width\",\n );\n setSizeRef(newSize);\n setPositionRef({\n x: startPosition.x + (startWidth - newSize.width),\n y: startPosition.y,\n });\n break;\n }\n case \"right\": {\n setSizeRef(\n calculateNewSize(startWidth + deltaX, startHeight, \"width\"),\n );\n break;\n }\n }\n }\n };\n\n const handleMouseUp = () => {\n // limit the position within the boundaries\n if (position.x < 0 || position.y < 0) {\n setPositionRef({\n x: Math.max(0, position.x),\n y: Math.max(0, position.y),\n });\n }\n cleanup();\n };\n\n document.addEventListener(\"mousemove\", handleMouseMove);\n document.addEventListener(\"mouseup\", handleMouseUp);\n };\n\n const handleMinimize = useCallback(() => {\n if (isMinimized) {\n // already minimized, restore to the previous size and position\n setSizeRef({ ...restoreSize });\n setPositionRef({ ...restorePosition });\n setIsMinimized(false);\n } else {\n // minimize\n if (isMaximized) {\n // if minimized from maximized directly, use the size and position which is stored before maximized\n setPositionRef({ ...restorePosition });\n } else {\n // otherwise store the current size and position\n setRestoreSize({ ...size });\n setRestorePosition({ ...position });\n }\n setSizeRef({ ...MINIMIZED_SIZE });\n setIsMinimized(true);\n }\n }, [\n isMinimized,\n isMaximized,\n size,\n position,\n restoreSize,\n restorePosition,\n setIsMinimized,\n setRestoreSize,\n setRestorePosition,\n ]);\n\n const handleMaximize = useCallback(() => {\n if (isMaximized) {\n // already maximized, restore to the previous size and position\n setSizeRef({ ...restoreSize });\n setPositionRef({ ...restorePosition });\n } else {\n // maximize\n if (isMinimized) {\n // if maximized from minimized directly, use the stored size and position before minimized\n setIsMinimized(false);\n } else {\n // otherwise store the current size and position\n setRestoreSize({ ...size });\n setRestorePosition({ ...position });\n }\n setSizeRef({ ...MAXIMIZED_SIZE });\n setPositionRef({ ...MAXIMIZED_POSITION });\n }\n }, [\n isMaximized,\n isMinimized,\n size,\n position,\n restoreSize,\n restorePosition,\n setIsMinimized,\n setRestoreSize,\n setRestorePosition,\n ]);\n\n // adjust position to the boundary when the window is resized\n useEffect(() => {\n const handleResize = throttle(() => {\n if (positionRef.current.x < 0 || positionRef.current.y < 0) {\n setPositionRef({\n x: Math.max(0, positionRef.current.x),\n y: Math.max(0, positionRef.current.y),\n });\n }\n const right = positionRef.current.x + sizeRef.current.width;\n const bottom = positionRef.current.y + sizeRef.current.height;\n if (right > window.innerWidth || bottom > window.innerHeight) {\n setPositionRef({\n x: Math.min(\n positionRef.current.x,\n Math.max(0, window.innerWidth - sizeRef.current.width),\n ),\n y: Math.min(\n positionRef.current.y,\n Math.max(0, window.innerHeight - sizeRef.current.height),\n ),\n });\n }\n }, 100);\n\n window.addEventListener(\"resize\", handleResize);\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n };\n }, []);\n\n if (!isOpen) {\n return null;\n }\n\n return (\n <>\n {/* Overlay when dragging or resizing */}\n {(isDragging || isResizing) &&\n createPortal(\n <div\n className={cn(\n \"max-sm:hidden fixed inset-0 z-9999 bg-transparent w-full h-full select-none\",\n isDragging && (dockToEdge ? \"cursor-grabbing\" : \"cursor-move\"),\n !isDragging && {\n \"cursor-ns-resize\":\n resizeDirection === \"top\" || resizeDirection === \"bottom\",\n \"cursor-ew-resize\":\n resizeDirection === \"left\" || resizeDirection === \"right\",\n \"cursor-nwse-resize\":\n resizeDirection === \"topLeft\" ||\n resizeDirection === \"bottomRight\",\n \"cursor-nesw-resize\":\n resizeDirection === \"topRight\" ||\n resizeDirection === \"bottomLeft\",\n \"cursor-auto\": resizeDirection === null,\n },\n )}\n />,\n document.body,\n )}\n\n {/* Modal container */}\n <div\n className={cn(\n \"max-sm:hidden fixed z-50 left-0 top-0\",\n isDragging ? \"will-change-transform\" : \"will-change-auto\",\n isResizing || isDragging\n ? \"transition-none\"\n : \"transition-transform duration-250 ease-[cubic-bezier(0.16,1,0.3,1)]\",\n )}\n style={{\n transform: `translate(${Math.round(position.x - (leftSidebar ? leftSidebarWidth : 0))}px, ${Math.round(position.y)}px)`,\n }}\n >\n <div className=\"flex relative z-50\">\n {leftSidebar && (\n <div\n className={cn(\n \"relative mt-1 z-10 transition-all duration-250 ease-[cubic-bezier(0.16,1,0.3,1)]\",\n isDragging\n ? \"opacity-40 translate-x-4\"\n : \"opacity-100 translate-x-0\",\n )}\n style={{\n width: leftSidebarWidth,\n height: isMinimized ? 40 : size.height - 8,\n }}\n >\n {leftSidebar}\n </div>\n )}\n\n {/* modal content */}\n <div\n className={cn(\n \"z-50 relative bg-content1 border border-border rounded-lg overflow-hidden\",\n isDragging\n ? \"opacity-80 shadow-md scale-102 blur-[0.5px]\"\n : \"opacity-100 shadow-lg scale-100 blur-none\",\n )}\n style={{\n width: size.width,\n height: size.height,\n transition:\n isResizing || isDragging\n ? \"none\"\n : \"transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.2s cubic-bezier(0.33, 1, 0.68, 1), height 0.25s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.2s cubic-bezier(0.33, 1, 0.68, 1)\",\n contain: \"content\",\n }}\n >\n <div\n className={cn(\n \"w-full h-full\",\n dockAnimationEdge && \"animate-modal-shrink\",\n dockAnimationEdge === \"left\" ? \"origin-left\" : \"origin-right\",\n )}\n style={{ contain: \"paint\" }}\n >\n {/* resize handles */}\n {!isMinimized && (\n <>\n <div\n className=\"absolute top-0 left-0 w-3 h-3 cursor-nw-resize z-20\"\n onMouseDown={(e) =>\n startInteraction(e, \"resize\", \"topLeft\")\n }\n />\n <div\n className=\"absolute top-0 right-0 w-3 h-3 cursor-ne-resize z-20\"\n onMouseDown={(e) =>\n startInteraction(e, \"resize\", \"topRight\")\n }\n />\n <div\n className=\"absolute bottom-0 left-0 w-3 h-3 cursor-sw-resize z-20\"\n onMouseDown={(e) =>\n startInteraction(e, \"resize\", \"bottomLeft\")\n }\n />\n <div\n className=\"absolute bottom-0 right-0 w-3 h-3 cursor-se-resize z-20\"\n onMouseDown={(e) =>\n startInteraction(e, \"resize\", \"bottomRight\")\n }\n />\n <div\n className=\"absolute top-0 left-3 right-3 h-1.5 cursor-n-resize z-20\"\n onMouseDown={(e) => startInteraction(e, \"resize\", \"top\")}\n />\n <div\n className=\"absolute bottom-0 left-3 right-3 h-1.5 cursor-s-resize z-20\"\n onMouseDown={(e) => startInteraction(e, \"resize\", \"bottom\")}\n />\n <div\n className=\"absolute left-0 top-3 bottom-3 w-1.5 cursor-w-resize z-20\"\n onMouseDown={(e) => startInteraction(e, \"resize\", \"left\")}\n />\n <div\n className=\"absolute right-0 top-3 bottom-3 w-1.5 cursor-e-resize z-20\"\n onMouseDown={(e) => startInteraction(e, \"resize\", \"right\")}\n />\n </>\n )}\n\n {/* header */}\n {showHeader && (\n <div\n className=\"relative border-b border-border/80 px-3 gap-4 flex items-center justify-between cursor-move select-none\"\n onMouseDown={(e) => startInteraction(e, \"drag\")}\n style={{ height: headerHeight }}\n >\n {/* drag tooltip */}\n <StyledTooltip\n placement=\"top\"\n content={t(\"scaffold.draggableModal.snapToEdge\")}\n >\n <DraggableIcon className=\"text-neutral absolute left-1/2 -translate-x-1/2 top-0\" />\n </StyledTooltip>\n\n {header || (\n <>\n <div\n className=\"min-w-0 flex-initial text-sm font-medium truncate cursor-auto\"\n onMouseDown={(e) => e.stopPropagation()}\n >\n {title}\n </div>\n <div\n className=\"flex-none flex items-center justify-end gap-1\"\n onMouseDown={(e) => e.stopPropagation()}\n >\n {/* minimize button */}\n <Button\n size=\"sm\"\n variant=\"light\"\n radius=\"lg\"\n isIconOnly\n onPress={handleMinimize}\n >\n {isMinimized ? (\n <RestoreWindowIcon\n width={18}\n height={18}\n className=\"text-neutral\"\n />\n ) : (\n <MinimizeIcon\n width={18}\n height={18}\n className=\"text-neutral\"\n />\n )}\n </Button>\n {/* maximize button */}\n <Button\n size=\"sm\"\n variant=\"light\"\n radius=\"lg\"\n isIconOnly\n onPress={handleMaximize}\n >\n {isMaximized ? (\n <UnMaximizeIcon\n width={18}\n height={18}\n className=\"text-neutral\"\n />\n ) : (\n <MaximizeIcon\n width={18}\n height={18}\n className=\"text-neutral\"\n />\n )}\n </Button>\n {/* close button */}\n <Button\n size=\"sm\"\n variant=\"light\"\n radius=\"lg\"\n isIconOnly\n onPress={onClose}\n >\n <XCloseIcon\n width={18}\n height={18}\n className=\"text-neutral\"\n />\n </Button>\n </div>\n </>\n )}\n </div>\n )}\n\n {/* content */}\n {!isMinimized && (\n <div\n className={\n showHeader\n ? \"h-[calc(100%-44px)] overflow-x-hidden overflow-y-auto\"\n : \"h-full overflow-x-hidden overflow-y-auto cursor-move\"\n }\n onMouseDown={\n showHeader ? undefined : (e) => startInteraction(e, \"drag\")\n }\n >\n {children}\n </div>\n )}\n </div>\n </div>\n\n {rightSidebar && (\n <div\n className={cn(\n \"relative mt-1 z-10 transition-all duration-250 ease-[cubic-bezier(0.16,1,0.3,1)]\",\n isDragging\n ? \"opacity-40 -translate-x-4\"\n : \"opacity-100 translate-x-0\",\n )}\n style={{\n width: rightSidebarWidth,\n height: isMinimized ? 40 : size.height - 8,\n }}\n >\n {rightSidebar}\n </div>\n )}\n </div>\n </div>\n </>\n );\n});\n","\"use client\";\n\nimport { useState, PropsWithChildren } from \"react\";\nimport { useAtom, useAtomValue } from \"jotai\";\nimport { useCallbackRef, useValueRef } from \"@liberfi.io/hooks\";\nimport { useTranslation } from \"@liberfi.io/i18n\";\nimport {\n Button,\n cn,\n DraggableIcon,\n StyledTooltip,\n XCloseIcon,\n} from \"@liberfi.io/ui\";\nimport {\n modalMaxWidthFamily,\n modalMinWidthFamily,\n panelStateFamily,\n panelWidthFamily,\n} from \"./states\";\nimport { useDraggableModalDisclosure } from \"./useDraggableModalDisclosure\";\nimport { useDraggablePanelDisclosure } from \"./useDraggablePanelDisclosure\";\n\nexport type DraggablePanelProps = PropsWithChildren<{\n /** unique id for the panel, must be the same with the modal */\n id: string;\n /** title of the modal */\n title?: React.ReactNode;\n /** maximum width of the panel */\n maxWidth?: number;\n /** minimum width of the panel */\n minWidth?: number;\n /** which side the panel is docked on */\n position: \"left\" | \"right\";\n /** whether to show the header */\n showHeader?: boolean;\n /** custom header content */\n header?: React.ReactNode;\n /** height of the modal header */\n headerHeight?: number;\n}>;\n\nexport function DraggablePanel({\n id,\n title,\n maxWidth = 440,\n minWidth = 320,\n position,\n showHeader = true,\n header,\n headerHeight = 44,\n children,\n}: DraggablePanelProps) {\n const { t } = useTranslation();\n\n // whether the panel is docked or not\n const panelState = useAtomValue(panelStateFamily(id));\n\n // whether the panel is being resized or not\n const [isResizing, setIsResizing] = useState(false);\n\n // whether the panel is being dragged or not\n const [isDragging, setIsDragging] = useState(false);\n\n // panel width\n const [width, setWidth] = useAtom(panelWidthFamily(id));\n\n // converting to modal\n const { onOpen: openModal } = useDraggableModalDisclosure(id);\n\n // control the close state of the panel\n const { onClose: closePanel } = useDraggablePanelDisclosure(id);\n\n const modalMinWidth = useAtomValue(modalMinWidthFamily(id));\n\n const modalMaxWidth = useAtomValue(modalMaxWidthFamily(id));\n\n // refs for props & states to avoid re-rendering\n const widthRef = useValueRef(width);\n const maxWidthRef = useValueRef(maxWidth);\n const minWidthRef = useValueRef(minWidth);\n const positionRef = useValueRef(position);\n const isResizingRef = useValueRef(isResizing);\n const isDraggingRef = useValueRef(isDragging);\n const setWidthRef = useCallbackRef(setWidth);\n const openModalRef = useCallbackRef(openModal);\n const closePanelRef = useCallbackRef(closePanel);\n const modalMinWidthRef = useValueRef(modalMinWidth);\n const modalMaxWidthRef = useValueRef(modalMaxWidth);\n\n const handleResizeStart = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsResizing(true);\n document.body.style.cursor = \"ew-resize\";\n document.body.style.userSelect = \"none\";\n document.body.style.overflow = \"hidden\";\n document.body.style.position = \"fixed\";\n document.body.style.width = \"100%\";\n document.body.style.height = \"100%\";\n\n // save start size & position in closure\n const startX = e.clientX;\n const startWidth = widthRef.current;\n\n const onResize = (e: MouseEvent) => {\n if (!isResizingRef.current) return;\n\n const deltaX = e.clientX - startX;\n\n const distance =\n positionRef.current === \"right\"\n ? startWidth - deltaX\n : startWidth + deltaX;\n\n const width = Math.min(\n Math.max(distance, minWidthRef.current),\n maxWidthRef.current,\n );\n setWidthRef(width);\n };\n\n const onResizeEnd = () => {\n setIsResizing(false);\n document.body.style.cursor = \"\";\n document.body.style.userSelect = \"\";\n document.body.style.overflow = \"\";\n document.body.style.position = \"\";\n document.body.style.width = \"\";\n document.body.style.height = \"\";\n document.removeEventListener(\"mousemove\", onResize);\n document.removeEventListener(\"mouseup\", onResizeEnd);\n };\n\n document.addEventListener(\"mousemove\", onResize);\n document.addEventListener(\"mouseup\", onResizeEnd);\n };\n\n const handleDragStart = (e: React.MouseEvent) => {\n // if the target is a button, don't trigger drag\n if (e.target instanceof HTMLElement && e.target.closest(\"button\")) {\n return;\n }\n e.preventDefault();\n\n setIsDragging(true);\n\n // save start position in closure\n const startX = e.clientX;\n const startY = e.clientY;\n\n const cleanup = () => {\n document.removeEventListener(\"mousemove\", onDragMove);\n document.removeEventListener(\"mouseup\", onDragEnd);\n setIsDragging(false);\n };\n\n const onDragMove = (e: MouseEvent) => {\n if (!isDraggingRef.current) return;\n\n const deltaX = Math.abs(e.clientX - startX);\n const deltaY = Math.abs(e.clientY - startY);\n\n // if the drag distance is greater than 10px, convert to modal\n if (deltaX > 10 || deltaY > 10) {\n cleanup();\n // close the panel\n closePanelRef();\n // open the modal\n openModalRef({\n // modal should follow the cursor\n shouldStartDragging: true,\n position: {\n x: e.clientX - widthRef.current / 2 + 20,\n y: e.clientY - 20,\n },\n // adjust modal's width to the panel's width\n size: {\n width: Math.min(\n Math.max(widthRef.current, modalMinWidthRef.current),\n modalMaxWidthRef.current,\n ),\n },\n });\n }\n };\n\n const onDragEnd = () => {\n cleanup();\n };\n\n document.addEventListener(\"mousemove\", onDragMove);\n document.addEventListener(\"mouseup\", onDragEnd);\n };\n\n const handleClose = () => {\n closePanelRef();\n };\n\n if (panelState !== position) {\n return null;\n }\n\n return (\n <div className=\"max-sm:hidden flex-none flex flex-row overflow-hidden\">\n {/* when the panel is on the right, show the resize handle on the left */}\n {position === \"right\" && (\n <ResizeHandle\n isResizing={isResizing}\n handleResizeStart={handleResizeStart}\n />\n )}\n\n {/* panel content container */}\n <div\n className={cn(\n \"flex flex-col min-h-0 overflow-hidden bg-content1\",\n isDragging\n ? \"opacity-80 scale-98 blur-[1px]\"\n : \"opacity-100 scale-100 blur-none\",\n )}\n style={{\n width: `${width}px`,\n transition:\n isResizing || isDragging\n ? \"none\"\n : \"transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.2s cubic-bezier(0.33, 1, 0.68, 1), height 0.4s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.2s cubic-bezier(0.33, 1, 0.68, 1)\",\n contain: \"content\",\n }}\n >\n {/* header */}\n {showHeader && (\n <div\n className=\"flex-none relative border-b border-border/80 px-3 gap-4 flex items-center justify-between cursor-move select-none\"\n onMouseDown={handleDragStart}\n style={{ height: headerHeight }}\n >\n {/* drag tooltip */}\n <StyledTooltip\n placement=\"top\"\n content={t(\"scaffold.draggablePanel.snapToModal\")}\n >\n <DraggableIcon className=\"text-neutral absolute left-1/2 -translate-x-1/2 top-0\" />\n </StyledTooltip>\n\n {header || (\n <>\n <div\n className=\"min-w-0 flex-initial text-sm font-medium truncate cursor-auto\"\n onMouseDown={(e) => e.stopPropagation()}\n >\n {title}\n </div>\n <div\n className=\"flex-none flex items-center justify-end gap-1\"\n onMouseDown={(e) => e.stopPropagation()}\n >\n {/* close button */}\n <Button\n size=\"sm\"\n variant=\"light\"\n radius=\"lg\"\n isIconOnly\n onPress={handleClose}\n >\n <XCloseIcon\n width={18}\n height={18}\n className=\"text-neutral\"\n />\n </Button>\n </div>\n </>\n )}\n </div>\n )}\n\n <div className=\"flex-auto min-h-0 overflow-y-auto\">{children}</div>\n </div>\n\n {/* when the panel is on the left, show the resize handle on the right */}\n {position === \"left\" && (\n <ResizeHandle\n isResizing={isResizing}\n handleResizeStart={handleResizeStart}\n />\n )}\n </div>\n );\n}\n\ntype ResizeHandleProps = {\n isResizing: boolean;\n handleResizeStart: (e: React.MouseEvent) => void;\n};\n\nfunction ResizeHandle({ isResizing, handleResizeStart }: ResizeHandleProps) {\n return (\n <div className=\"relative\">\n <div className=\"relative w-1 h-full cursor-ew-resize bg-border/80 hover:bg-border transition-colors duration-150 ease-in-out group flex flex-col items-center justify-center gap-1\">\n <i className=\"rounded-full w-0.5 h-0.5 bg-neutral\" />\n <i className=\"rounded-full w-0.5 h-0.5 bg-neutral\" />\n <i className=\"rounded-full w-0.5 h-0.5 bg-neutral\" />\n\n {/* expend click area */}\n <div\n className=\"absolute inset-0 -left-1.5 -right-1.5 cursor-ew-resize\"\n onMouseDown={handleResizeStart}\n />\n </div>\n\n {isResizing && <div className=\"fixed inset-0 z-50 cursor-ew-resize\" />}\n </div>\n );\n}\n","\"use client\";\n\nimport { PropsWithChildren, useEffect, useMemo, useRef } from \"react\";\nimport { getDefaultStore, useAtomValue } from \"jotai\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { DraggableModal } from \"./DraggableModal\";\nimport { DraggablePanel } from \"./DraggablePanel\";\nimport {\n modalMaxWidthFamily,\n modalMinWidthFamily,\n panelMaxWidthFamily,\n panelMinWidthFamily,\n panelOrdersFamily,\n panelStateFamily,\n setDraggableStoragePrefix,\n} from \"./states\";\n\nexport type DraggableContentProps = PropsWithChildren<{\n /** unique identifier for both the modal & panel */\n id: string;\n /** title of both the modal & panel */\n title?: React.ReactNode;\n /** whether to show the header for both the modal & panel */\n showHeader?: boolean;\n /** custom header content for both the modal & panel */\n header?: React.ReactNode;\n /** height of the modal header for both the modal & panel */\n headerHeight?: number;\n /** constraints for the minimum width of the modal */\n modalMinWidth?: number;\n /** constraints for the maximum width of the modal */\n modalMaxWidth?: number;\n /** constraints for the minimum width of the panel */\n panelMinWidth?: number;\n /** constraints for the maximum width of the panel */\n panelMaxWidth?: number;\n /** constraints for the minimum height of the modal */\n minHeight?: number;\n /** constraints for the maximum height of the modal */\n maxHeight?: number;\n /** left sidebar of the modal */\n leftSidebar?: React.ReactNode;\n /** width of the left sidebar */\n leftSidebarWidth?: number;\n /** right sidebar of the modal */\n rightSidebar?: React.ReactNode;\n /** width of the right sidebar */\n rightSidebarWidth?: number;\n /** constraints for the aspect ratio when resizing modal */\n aspectRatio?: number;\n}>;\n\nexport type DraggablePanelProviderProps = PropsWithChildren<{\n /** draggable contents */\n contents?: Array<DraggableContentProps>;\n /** Prefix for all draggable localStorage keys (e.g. \"myapp\" → \"myapp:panelState.chart\") */\n storagePrefix?: string;\n /** root container class name */\n className?: string;\n /** class names slots*/\n classNames?: {\n root?: string;\n left?: string;\n right?: string;\n content?: string;\n };\n}>;\n\nexport function DraggablePanelProvider({\n contents = [],\n storagePrefix,\n className,\n classNames,\n children,\n}: DraggablePanelProviderProps) {\n const prefixApplied = useRef(false);\n if (!prefixApplied.current && storagePrefix !== undefined) {\n setDraggableStoragePrefix(storagePrefix);\n prefixApplied.current = true;\n }\n const panelOrders = useAtomValue(panelOrdersFamily(null));\n\n // sync panel & order widths\n useEffect(() => {\n const store = getDefaultStore();\n contents.forEach((content) => {\n store.set(panelMinWidthFamily(content.id), content.panelMinWidth ?? 320);\n store.set(panelMaxWidthFamily(content.id), content.panelMaxWidth ?? 440);\n store.set(modalMinWidthFamily(content.id), content.modalMinWidth ?? 504);\n store.set(\n modalMaxWidthFamily(content.id),\n content.modalMaxWidth ?? window.innerWidth - 40,\n );\n });\n }, [contents]);\n\n // latest opened on the left\n const leftOpenPanels = useMemo(\n () =>\n contents\n .filter((content) => {\n const store = getDefaultStore();\n // hasn't been opened on the left\n if (!panelOrders.left[content.id]) return false;\n // whether the panel is opened on the left\n return store.get(panelStateFamily(content.id)) === \"left\";\n })\n .sort((a, b) => panelOrders.left[b.id] - panelOrders.left[a.id]),\n [contents, panelOrders.left],\n );\n\n // latest opened on the right\n const rightOpenPanels = useMemo(\n () =>\n contents\n .filter((content) => {\n const store = getDefaultStore();\n // hasn't been opened on the right\n if (!panelOrders.right[content.id]) return false;\n // whether the panel is opened on the right\n return store.get(panelStateFamily(content.id)) === \"right\";\n })\n .sort(\n (a, b) =>\n (panelOrders.right[a.id] ?? 0) - (panelOrders.right[b.id] ?? 0),\n ),\n [contents, panelOrders.right],\n );\n\n return (\n <>\n <div\n className={cn(\n \"w-full h-full flex flex-row overflow-hidden\",\n className,\n classNames?.root,\n )}\n >\n {/* left panels */}\n <div className={cn(\"flex-none h-full flex flex-row\", classNames?.left)}>\n {leftOpenPanels.map((props) => (\n <DraggablePanel\n key={`left-${props.id}`}\n {...props}\n position=\"left\"\n minWidth={props.panelMinWidth ?? 320}\n maxWidth={props.panelMaxWidth ?? 440}\n />\n ))}\n </div>\n {/* main content */}\n <div className={cn(\"flex-auto min-w-0 h-full\", classNames?.content)}>\n {children}\n </div>\n {/* right panels */}\n <div\n className={cn(\"flex-none h-full flex flex-row\", classNames?.right)}\n >\n {rightOpenPanels.map((props) => (\n <DraggablePanel\n key={`right-${props.id}`}\n {...props}\n position=\"right\"\n minWidth={props.panelMinWidth ?? 320}\n maxWidth={props.panelMaxWidth ?? 440}\n />\n ))}\n </div>\n </div>\n {/* modals */}\n {contents.map((props) => (\n <DraggableModal\n key={`modal-${props.id}`}\n {...props}\n minWidth={props.modalMinWidth ?? 504}\n maxWidth={props.modalMaxWidth ?? window.innerWidth - 40}\n />\n ))}\n </>\n );\n}\n","\"use client\";\n\nimport { useCallback, useMemo } from \"react\";\nimport { useAtomValue } from \"jotai\";\nimport { lastDraggableTypeFamily } from \"./states\";\nimport { useDraggableModalDisclosure } from \"./useDraggableModalDisclosure\";\nimport { useDraggablePanelDisclosure } from \"./useDraggablePanelDisclosure\";\n\nexport type UseDraggableDisclosureReturnType = {\n isOpen: boolean;\n onOpen: () => void;\n onClose: () => void;\n};\n\nexport function useDraggableDisclosure(\n id: string,\n): UseDraggableDisclosureReturnType {\n const {\n isOpen: isModalOpen,\n onOpen: onOpenModal,\n onClose: onCloseModal,\n } = useDraggableModalDisclosure(id);\n\n const {\n isOpen: isPanelOpen,\n onOpen: onOpenPanel,\n onClose: onClosePanel,\n } = useDraggablePanelDisclosure(id);\n\n const lastDraggableType = useAtomValue(lastDraggableTypeFamily(id));\n\n const onOpen = useCallback(() => {\n if (isModalOpen || isPanelOpen) return;\n if (lastDraggableType === \"modal\") {\n onOpenModal();\n } else {\n onOpenPanel({ position: lastDraggableType });\n }\n }, [isModalOpen, isPanelOpen, lastDraggableType, onOpenModal, onOpenPanel]);\n\n const onClose = useCallback(() => {\n if (isModalOpen) {\n onCloseModal();\n } else if (isPanelOpen) {\n onClosePanel();\n }\n }, [isModalOpen, isPanelOpen, onCloseModal, onClosePanel]);\n\n const isOpen = useMemo(\n () => isModalOpen || isPanelOpen,\n [isModalOpen, isPanelOpen],\n );\n\n return useMemo(\n () => ({\n isOpen,\n onOpen,\n onClose,\n }),\n [isOpen, onOpen, onClose],\n );\n}\n","import type { ReactNode } from \"react\";\n\n/** Responsive breakpoints: desktop (>=1024px), tablet (640–1023px), mobile (<640px) */\nexport type LayoutBreakpoint = \"desktop\" | \"tablet\" | \"mobile\";\n\nexport const ALL_BREAKPOINTS: LayoutBreakpoint[] = [\n \"desktop\",\n \"tablet\",\n \"mobile\",\n];\n\n/** Navigation item for header links and footer tabs */\nexport type NavItem = {\n key: string;\n label: string;\n href: string;\n icon?: ReactNode;\n /**\n * Custom active-matching rule.\n * - function: called with pathname, return true if active\n * - RegExp: tested against pathname\n * - string: pathname.startsWith(match)\n * - undefined: exact match for \"/\", startsWith for others\n */\n match?: string | RegExp | ((pathname: string) => boolean);\n};\n\n/** Check whether a NavItem is active for the given pathname */\nexport function isNavItemActive(item: NavItem, pathname: string): boolean {\n if (item.match !== undefined) {\n if (typeof item.match === \"function\") return item.match(pathname);\n if (item.match instanceof RegExp) return item.match.test(pathname);\n return pathname.startsWith(item.match);\n }\n if (item.href === \"/\") return pathname === \"/\";\n return pathname.startsWith(item.href);\n}\n\n/**\n * Map a LayoutBreakpoint[] to Tailwind visibility class names.\n *\n * desktop = lg+ (>=1024), tablet = sm..lg (640–1023), mobile = <sm (<640)\n *\n * Returns a class string that hides the element on breakpoints NOT in the array.\n */\nexport function getVisibilityClass(breakpoints: LayoutBreakpoint[]): string {\n const has = {\n desktop: breakpoints.includes(\"desktop\"),\n tablet: breakpoints.includes(\"tablet\"),\n mobile: breakpoints.includes(\"mobile\"),\n };\n\n if (has.desktop && has.tablet && has.mobile) return \"\";\n if (!has.desktop && !has.tablet && !has.mobile) return \"hidden\";\n if (has.desktop && has.tablet && !has.mobile) return \"max-sm:hidden\";\n if (has.desktop && !has.tablet && !has.mobile) return \"max-lg:hidden\";\n if (!has.desktop && has.tablet && has.mobile) return \"lg:hidden\";\n if (!has.desktop && !has.tablet && has.mobile) return \"sm:hidden\";\n if (!has.desktop && has.tablet && !has.mobile)\n return \"max-sm:hidden lg:hidden\";\n\n // [\"desktop\", \"mobile\"] — non-contiguous breakpoints cannot be expressed\n // with pure Tailwind hidden/show classes without forcing a display type.\n throw new Error(\n `getVisibilityClass: non-contiguous breakpoints [${breakpoints.join(\", \")}] are not supported. ` +\n \"Use a contiguous range (e.g. [desktop, tablet], [tablet, mobile]).\",\n );\n}\n","import { createContext, useContext, useEffect } from \"react\";\nimport type { LayoutBreakpoint } from \"./types\";\n\nexport type ScaffoldContextValue = {\n /** Current route pathname for nav active detection (IoC) */\n pathname: string;\n /** Navigation callback (IoC — no router dependency) */\n onNavigate: (href: string) => void;\n /** Header height in px */\n headerHeight: number;\n /** Header height in px on mobile (max-width 639px) */\n mobileHeaderHeight: number;\n /** Footer height in px */\n footerHeight: number;\n /** Toolbar height in px */\n toolbarHeight: number;\n\n /** Breakpoints where the header is visible */\n headerVisible: LayoutBreakpoint[];\n /** Breakpoints where the footer is visible */\n footerVisible: LayoutBreakpoint[];\n /** Breakpoints where the toolbar is visible */\n toolbarVisible: LayoutBreakpoint[];\n\n /** Override header visibility (used by useScaffoldLayout) */\n setHeaderVisible: (breakpoints: LayoutBreakpoint[]) => void;\n /** Override footer visibility (used by useScaffoldLayout) */\n setFooterVisible: (breakpoints: LayoutBreakpoint[]) => void;\n /** Override toolbar visibility (used by useScaffoldLayout) */\n setToolbarVisible: (breakpoints: LayoutBreakpoint[]) => void;\n\n /** Default headerVisible from Scaffold props (for reset on unmount) */\n defaultHeaderVisible: LayoutBreakpoint[];\n /** Default footerVisible from Scaffold props (for reset on unmount) */\n defaultFooterVisible: LayoutBreakpoint[];\n /** Default toolbarVisible from Scaffold props (for reset on unmount) */\n defaultToolbarVisible: LayoutBreakpoint[];\n};\n\nexport const ScaffoldContext = createContext<ScaffoldContextValue | null>(null);\n\n/** Read the Scaffold context. Throws if used outside a Scaffold. */\nexport function useScaffold(): ScaffoldContextValue {\n const ctx = useContext(ScaffoldContext);\n if (!ctx) {\n throw new Error(\"useScaffold must be used within a <Scaffold> component.\");\n }\n return ctx;\n}\n\n/**\n * Declaratively set the layout for the current page.\n * Overrides on mount, resets to Scaffold defaults on unmount.\n *\n * @example\n * useScaffoldLayout({\n * headerVisible: [\"desktop\", \"tablet\"],\n * footerVisible: [\"tablet\", \"mobile\"],\n * toolbarVisible: [\"desktop\"],\n * });\n */\nexport function useScaffoldLayout(config: {\n headerVisible?: LayoutBreakpoint[];\n footerVisible?: LayoutBreakpoint[];\n toolbarVisible?: LayoutBreakpoint[];\n}): void {\n const ctx = useScaffold();\n\n useEffect(() => {\n if (config.headerVisible !== undefined) {\n ctx.setHeaderVisible(config.headerVisible);\n }\n if (config.footerVisible !== undefined) {\n ctx.setFooterVisible(config.footerVisible);\n }\n if (config.toolbarVisible !== undefined) {\n ctx.setToolbarVisible(config.toolbarVisible);\n }\n\n return () => {\n if (config.headerVisible !== undefined) {\n ctx.setHeaderVisible(ctx.defaultHeaderVisible);\n }\n if (config.footerVisible !== undefined) {\n ctx.setFooterVisible(ctx.defaultFooterVisible);\n }\n if (config.toolbarVisible !== undefined) {\n ctx.setToolbarVisible(ctx.defaultToolbarVisible);\n }\n };\n }, [config.headerVisible, config.footerVisible, config.toolbarVisible]);\n}\n","import {\n type PropsWithChildren,\n type ReactNode,\n useId,\n useMemo,\n useState,\n} from \"react\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { ScaffoldContext, type ScaffoldContextValue } from \"./ScaffoldContext\";\nimport {\n type LayoutBreakpoint,\n ALL_BREAKPOINTS,\n getVisibilityClass,\n} from \"./types\";\n\nconst DEFAULT_HEADER_HEIGHT = 60;\nconst DEFAULT_MOBILE_HEADER_HEIGHT = 48;\nconst DEFAULT_FOOTER_HEIGHT = 56;\nconst DEFAULT_TOOLBAR_HEIGHT = 36;\nconst noop = () => {};\n\nexport type ScaffoldProps = PropsWithChildren<{\n /** Current route pathname for nav active detection */\n pathname?: string;\n /** Navigation callback (IoC — decoupled from router) */\n onNavigate?: (href: string) => void;\n /** Header slot */\n header?: ReactNode;\n /** Footer slot (typically mobile tab navigation) */\n footer?: ReactNode;\n /** Toolbar slot (typically desktop bottom status bar) */\n toolbar?: ReactNode;\n /** Header height in px (default 60) */\n headerHeight?: number;\n /** Header height in px on mobile — max-width 639px (default 48) */\n mobileHeaderHeight?: number;\n /** Footer height in px (default 56) */\n footerHeight?: number;\n /** Toolbar height in px (default 36) */\n toolbarHeight?: number;\n /** Breakpoints where the header is visible (default all) */\n headerVisible?: LayoutBreakpoint[];\n /** Breakpoints where the footer is visible (default none) */\n footerVisible?: LayoutBreakpoint[];\n /** Breakpoints where the toolbar is visible (default none) */\n toolbarVisible?: LayoutBreakpoint[];\n className?: string;\n classNames?: {\n wrapper?: string;\n header?: string;\n content?: string;\n footer?: string;\n toolbar?: string;\n };\n}>;\n\nexport function Scaffold({\n children,\n pathname = \"\",\n onNavigate = noop,\n header,\n footer,\n toolbar,\n headerHeight = DEFAULT_HEADER_HEIGHT,\n mobileHeaderHeight = DEFAULT_MOBILE_HEADER_HEIGHT,\n footerHeight = DEFAULT_FOOTER_HEIGHT,\n toolbarHeight = DEFAULT_TOOLBAR_HEIGHT,\n headerVisible: defaultHeaderVisible = ALL_BREAKPOINTS,\n footerVisible: defaultFooterVisible = [],\n toolbarVisible: defaultToolbarVisible = [],\n className,\n classNames,\n}: ScaffoldProps) {\n const [headerVisible, setHeaderVisible] =\n useState<LayoutBreakpoint[]>(defaultHeaderVisible);\n const [footerVisible, setFooterVisible] =\n useState<LayoutBreakpoint[]>(defaultFooterVisible);\n const [toolbarVisible, setToolbarVisible] = useState<LayoutBreakpoint[]>(\n defaultToolbarVisible,\n );\n\n const scaffoldId = useId();\n\n const ctxValue = useMemo<ScaffoldContextValue>(\n () => ({\n pathname,\n onNavigate,\n headerHeight,\n mobileHeaderHeight,\n footerHeight,\n toolbarHeight,\n headerVisible,\n footerVisible,\n toolbarVisible,\n setHeaderVisible,\n setFooterVisible,\n setToolbarVisible,\n defaultHeaderVisible,\n defaultFooterVisible,\n defaultToolbarVisible,\n }),\n [\n pathname,\n onNavigate,\n headerHeight,\n mobileHeaderHeight,\n footerHeight,\n toolbarHeight,\n headerVisible,\n footerVisible,\n toolbarVisible,\n defaultHeaderVisible,\n defaultFooterVisible,\n defaultToolbarVisible,\n ],\n );\n\n const headerClass = getVisibilityClass(headerVisible);\n const footerClass = getVisibilityClass(footerVisible);\n const toolbarClass = getVisibilityClass(toolbarVisible);\n\n const headerStyleRule =\n mobileHeaderHeight !== headerHeight\n ? `[data-scaffold-id=\"${scaffoldId}\"]{--scaffold-header-height:${headerHeight}px}` +\n `@media(max-width:639px){[data-scaffold-id=\"${scaffoldId}\"]{--scaffold-header-height:${mobileHeaderHeight}px}}`\n : `[data-scaffold-id=\"${scaffoldId}\"]{--scaffold-header-height:${headerHeight}px}`;\n\n return (\n <ScaffoldContext.Provider value={ctxValue}>\n <style>{headerStyleRule}</style>\n <div\n data-scaffold-id={scaffoldId}\n className={cn(\n \"w-full h-screen max-sm:h-dvh flex flex-col overflow-hidden bg-background\",\n classNames?.wrapper,\n className,\n )}\n style={\n {\n \"--scaffold-footer-height\": `calc(${footerHeight}px + env(safe-area-inset-bottom))`,\n \"--scaffold-toolbar-height\": `${toolbarHeight}px`,\n } as React.CSSProperties\n }\n >\n {/* Header */}\n {header && (\n <nav\n className={cn(\n \"w-full flex-none relative z-50\",\n headerClass,\n classNames?.header,\n )}\n style={{ height: \"var(--scaffold-header-height)\" }}\n >\n {header}\n </nav>\n )}\n\n {/* Content */}\n <div\n className={cn(\n \"w-full flex-auto min-h-0 relative overflow-y-auto\",\n classNames?.content,\n )}\n >\n {children}\n </div>\n\n {/* Toolbar (desktop bottom bar) */}\n {toolbar && (\n <div\n className={cn(\n \"w-full flex-none\",\n toolbarClass,\n classNames?.toolbar,\n )}\n style={{ height: `${toolbarHeight}px` }}\n >\n {toolbar}\n </div>\n )}\n\n {/* Footer (mobile tab navigation) */}\n {footer && (\n <div\n className={cn(\n \"w-full flex-none pb-[env(safe-area-inset-bottom)]\",\n footerClass,\n classNames?.footer,\n )}\n style={{\n height: `calc(${footerHeight}px + env(safe-area-inset-bottom))`,\n }}\n >\n {footer}\n </div>\n )}\n </div>\n </ScaffoldContext.Provider>\n );\n}\n","import { useCallback } from \"react\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { useScaffold } from \"./ScaffoldContext\";\nimport { isNavItemActive, type NavItem } from \"./types\";\n\nexport type NavLinkProps = {\n item: NavItem;\n /** \"header\" = horizontal text link, \"footer\" = vertical icon+text tab */\n variant?: \"header\" | \"footer\";\n className?: string;\n};\n\nexport function NavLink({ item, variant = \"header\", className }: NavLinkProps) {\n const { pathname, onNavigate } = useScaffold();\n const active = isNavItemActive(item, pathname);\n\n const handlePress = useCallback(() => {\n onNavigate(item.href);\n }, [onNavigate, item.href]);\n\n if (variant === \"footer\") {\n return (\n <button\n type=\"button\"\n data-active={active}\n className={cn(\n \"flex flex-col items-center justify-center gap-0.5 px-2 py-1 min-w-0\",\n \"text-xs font-medium text-foreground/60\",\n \"data-[active=true]:text-primary\",\n className,\n )}\n onClick={handlePress}\n aria-label={item.label}\n aria-current={active ? \"page\" : undefined}\n >\n {item.icon && (\n <span className=\"flex items-center justify-center\">{item.icon}</span>\n )}\n <span className=\"truncate\">{item.label}</span>\n </button>\n );\n }\n\n return (\n <button\n type=\"button\"\n data-active={active}\n className={cn(\n \"h-8 text-sm font-medium px-2 xl:px-3 rounded-sm cursor-pointer\",\n \"text-foreground hover:text-primary hover:bg-primary-50\",\n \"data-[active=true]:text-primary\",\n className,\n )}\n onClick={handlePress}\n aria-label={item.label}\n aria-current={active ? \"page\" : undefined}\n >\n {item.label}\n </button>\n );\n}\n","import type { CSSProperties, PropsWithChildren, ReactNode } from \"react\";\nimport { cn, HorizontalScrollContainer } from \"@liberfi.io/ui\";\nimport { NavLink } from \"./NavLink\";\nimport type { NavItem } from \"./types\";\n\nexport type ScaffoldHeaderProps = PropsWithChildren<{\n /** Left slot (e.g. Logo) */\n left?: ReactNode;\n /** Right slot (e.g. account menu, settings) */\n right?: ReactNode;\n /** Navigation items rendered as horizontal links with auto-active detection */\n navItems?: NavItem[];\n className?: string;\n style?: CSSProperties;\n}>;\n\n/**\n * Pre-built header layout with left / nav / right slots.\n * Pass `children` for full custom control (left/right/navItems will be ignored).\n */\nexport function ScaffoldHeader({\n children,\n left,\n right,\n navItems,\n className,\n style,\n}: ScaffoldHeaderProps) {\n if (children) {\n return (\n <header\n className={cn(\n \"w-full h-full flex items-center bg-background border-b border-border\",\n className,\n )}\n style={style}\n >\n {children}\n </header>\n );\n }\n\n return (\n <header\n className={cn(\n \"w-full h-full px-6 max-lg:px-4 max-sm:px-3 flex items-center justify-between gap-6 max-lg:gap-4 max-sm:gap-3 bg-background border-b border-border\",\n className,\n )}\n >\n {/* Left: logo (fixed) */}\n {left && <div className=\"shrink-0 flex items-center\">{left}</div>}\n\n {/* Center: nav items (scrollable when space is tight, hidden on mobile) */}\n {navItems && navItems.length > 0 && (\n <HorizontalScrollContainer\n className=\"flex-auto min-w-0 max-sm:hidden\"\n classNames={{ content: \"gap-1\" }}\n >\n {navItems.map((item) => (\n <NavLink key={item.key} item={item} variant=\"header\" />\n ))}\n </HorizontalScrollContainer>\n )}\n\n {/* Right: always fully visible */}\n {right && <div className=\"shrink-0 flex items-center gap-4\">{right}</div>}\n </header>\n );\n}\n","import type { PropsWithChildren } from \"react\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { NavLink } from \"./NavLink\";\nimport type { NavItem } from \"./types\";\n\nexport type ScaffoldFooterProps = PropsWithChildren<{\n /** Navigation items rendered as vertical icon+text tabs */\n navItems?: NavItem[];\n className?: string;\n}>;\n\n/**\n * Pre-built footer layout with tab-style navigation.\n * Pass `children` for full custom control (navItems will be ignored).\n */\nexport function ScaffoldFooter({\n children,\n navItems,\n className,\n}: ScaffoldFooterProps) {\n if (children) {\n return (\n <footer\n className={cn(\n \"w-full h-full flex items-center bg-background border-t border-border\",\n className,\n )}\n >\n {children}\n </footer>\n );\n }\n\n return (\n <footer\n className={cn(\n \"w-full h-full flex justify-evenly items-center bg-background border-t border-border\",\n className,\n )}\n >\n {navItems?.map((item) => (\n <NavLink key={item.key} item={item} variant=\"footer\" />\n ))}\n </footer>\n );\n}\n","import type { PropsWithChildren, ReactNode } from \"react\";\nimport { cn } from \"@liberfi.io/ui\";\n\nexport type ScaffoldToolbarProps = PropsWithChildren<{\n /** Left-aligned content */\n left?: ReactNode;\n /** Right-aligned content */\n right?: ReactNode;\n className?: string;\n}>;\n\n/**\n * Pre-built bottom toolbar layout with left / right slots.\n * Typically shown on desktop while ScaffoldFooter is shown on mobile.\n * Pass `children` for full custom control (left/right will be ignored).\n */\nexport function ScaffoldToolbar({\n children,\n left,\n right,\n className,\n}: ScaffoldToolbarProps) {\n if (children) {\n return (\n <div\n className={cn(\n \"w-full h-full flex items-center bg-background border-t border-border\",\n className,\n )}\n >\n {children}\n </div>\n );\n }\n\n return (\n <div\n className={cn(\n \"w-full h-full px-6 flex items-center justify-between gap-4 bg-background border-t border-border\",\n className,\n )}\n >\n {left && <div className=\"flex items-center gap-4\">{left}</div>}\n {right && <div className=\"flex items-center gap-4\">{right}</div>}\n </div>\n );\n}\n","import { cn, Link } from \"@liberfi.io/ui\";\n\nexport type LogoProps = {\n /** icon for desktop */\n icon: React.ReactNode;\n /** icon for mobile & desktop */\n miniIcon?: React.ReactNode;\n /** url when clicking the logo image */\n href?: string;\n /** Accessible label for the logo link (sets aria-label) */\n ariaLabel?: string;\n /** custom styles */\n className?: string;\n};\n\nexport function Logo({\n href = \"/\",\n icon,\n miniIcon,\n ariaLabel = \"Home\",\n className,\n}: LogoProps) {\n return (\n <Link\n href={href}\n className={cn(\"flex-none flex justify-center items-center\", className)}\n aria-label={ariaLabel}\n >\n <div\n className={cn(\n \"flex justify-center items-center\",\n !!miniIcon && \"max-xl:hidden\",\n )}\n >\n {icon}\n </div>\n {miniIcon && (\n <div className=\"flex justify-center items-center xl:hidden\">\n {miniIcon}\n </div>\n )}\n </Link>\n );\n}\n","import { ReactNode, useCallback, useEffect, useRef, useState } from \"react\";\nimport { useEventEmitter } from \"@liberfi.io/hooks\";\nimport { useDisclosure } from \"@liberfi.io/ui\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type RenderAsyncModalProps<P = any, R = any> = {\n /** custom parameters for the modal */\n params?: P;\n /** whether the modal is open */\n isOpen: boolean;\n /** close the modal without a result (resolves Promise with undefined) */\n onClose: () => void;\n /** change the open state of the modal */\n onOpenChange: (isOpen: boolean) => void;\n /** submit a result and auto-close the modal */\n onResult: (result: R) => void;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AsyncModalProps<P = any, R = any> = {\n /** unique identifier for the modal */\n id: string;\n /** render the modal content */\n children: (props: RenderAsyncModalProps<P, R>) => ReactNode;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type OpenAsyncModalOptions<P = any, R = any> = {\n /** custom parameters for the modal */\n params?: P;\n /** callback when the modal resolves (result value, or undefined on dismiss) */\n onResult?: (result: R | undefined) => void;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function AsyncModal<P = any, R = any>({\n id,\n children,\n}: AsyncModalProps<P, R>) {\n const events = useEventEmitter();\n const { isOpen, onOpen, onClose, onOpenChange } = useDisclosure();\n\n const [params, setParams] = useState<P | undefined>(undefined);\n const onResultRef = useRef<((result: R | undefined) => void) | undefined>(\n undefined,\n );\n\n const cleanup = useCallback(() => {\n onResultRef.current = undefined;\n setParams(undefined);\n }, []);\n\n const wrappedOnClose = useCallback(() => {\n onResultRef.current?.(undefined);\n cleanup();\n onClose();\n }, [onClose, cleanup]);\n\n const wrappedOnResult = useCallback(\n (result: R) => {\n onResultRef.current?.(result);\n cleanup();\n onClose();\n },\n [onClose, cleanup],\n );\n\n const wrappedOnOpenChange = useCallback(\n (open: boolean) => {\n if (!open) {\n wrappedOnClose();\n }\n },\n [wrappedOnClose],\n );\n\n useEffect(() => {\n const handler = (options?: OpenAsyncModalOptions<P, R>) => {\n setParams(options?.params);\n onResultRef.current = options?.onResult;\n onOpen();\n };\n events.on(`open_modal:${id}`, handler);\n return () => {\n events.off(`open_modal:${id}`, handler);\n };\n }, [id, onOpen, events]);\n\n useEffect(() => {\n const handler = () => {\n wrappedOnClose();\n };\n events.on(`close_modal:${id}`, handler);\n return () => {\n events.off(`close_modal:${id}`, handler);\n };\n }, [id, wrappedOnClose, events]);\n\n return children({\n params,\n isOpen,\n onClose: wrappedOnClose,\n onOpenChange: wrappedOnOpenChange,\n onResult: wrappedOnResult,\n });\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { useCallback } from \"react\";\nimport { useEventEmitter } from \"@liberfi.io/hooks\";\nimport { OpenAsyncModalOptions } from \"./AsyncModal\";\n\nexport type UseAsyncModalReturnType<P = any, R = any> = {\n /** Open the modal. Returns a Promise that resolves with the result, or undefined on dismiss. */\n onOpen: (options?: OpenAsyncModalOptions<P, R>) => Promise<R | undefined>;\n /** Close the modal from outside (triggers dismiss). */\n onClose: () => void;\n};\n\nexport function useAsyncModal<P = any, R = any>(\n id: string,\n): UseAsyncModalReturnType<P, R> {\n const events = useEventEmitter();\n\n const onOpen = useCallback(\n (options?: OpenAsyncModalOptions<P, R>): Promise<R | undefined> => {\n return new Promise<R | undefined>((resolve) => {\n const wrappedOnResult = (result: R | undefined) => {\n options?.onResult?.(result);\n resolve(result);\n };\n events.emit(`open_modal:${id}`, {\n ...options,\n onResult: wrappedOnResult,\n } satisfies OpenAsyncModalOptions<P, R>);\n });\n },\n [id, events],\n );\n\n const onClose = useCallback(() => {\n events.emit(`close_modal:${id}`);\n }, [id, events]);\n\n return { onOpen, onClose };\n}\n","import { cn } from \"@liberfi.io/ui\";\n\nexport type SplitHandleProps = {\n direction: \"horizontal\" | \"vertical\";\n isResizing: boolean;\n onResizeStart: (e: React.MouseEvent) => void;\n className?: string;\n};\n\nexport function SplitHandle({\n direction,\n isResizing,\n onResizeStart,\n className,\n}: SplitHandleProps) {\n const isHorizontal = direction === \"horizontal\";\n\n return (\n <div className={cn(\"relative flex-none\", className)}>\n <div\n className={cn(\n \"flex items-center justify-center bg-border/80 hover:bg-border transition-colors duration-150 ease-in-out\",\n isHorizontal\n ? \"w-1 h-full cursor-ew-resize flex-col gap-1\"\n : \"w-full h-1 cursor-ns-resize flex-row gap-1\",\n )}\n >\n <i className=\"rounded-full w-0.5 h-0.5 bg-neutral\" />\n <i className=\"rounded-full w-0.5 h-0.5 bg-neutral\" />\n <i className=\"rounded-full w-0.5 h-0.5 bg-neutral\" />\n\n <div\n className={cn(\n \"absolute inset-0\",\n isHorizontal\n ? \"-left-1.5 -right-1.5 cursor-ew-resize\"\n : \"-top-1.5 -bottom-1.5 cursor-ns-resize\",\n )}\n onMouseDown={onResizeStart}\n />\n </div>\n\n {isResizing && (\n <div\n className={cn(\n \"fixed inset-0 z-50\",\n isHorizontal ? \"cursor-ew-resize\" : \"cursor-ns-resize\",\n )}\n />\n )}\n </div>\n );\n}\n","import { type ReactNode, useCallback, useRef, useState } from \"react\";\nimport { useCallbackRef, useValueRef } from \"@liberfi.io/hooks\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { SplitHandle } from \"./SplitHandle\";\n\nconst HANDLE_SIZE = 4;\n\nexport type SplitViewProps = {\n /** Split direction */\n direction?: \"horizontal\" | \"vertical\";\n /** Content for the primary (first) pane */\n primary: ReactNode;\n /** Content for the secondary (second) pane */\n secondary: ReactNode;\n /** Initial size of the primary pane in px */\n defaultSize?: number;\n /** Minimum size of the primary pane in px */\n minSize?: number;\n /** Maximum size of the primary pane in px */\n maxSize?: number;\n /** Minimum size of the secondary pane in px */\n secondaryMinSize?: number;\n /** Callback when size changes */\n onSizeChange?: (size: number) => void;\n /** Unique id for localStorage persistence (omit to disable) */\n persistId?: string;\n className?: string;\n classNames?: {\n primary?: string;\n secondary?: string;\n handle?: string;\n };\n};\n\nfunction getPersistedSize(id: string | undefined): number | null {\n if (!id) return null;\n try {\n const raw = localStorage.getItem(`splitView.${id}`);\n return raw ? Number(raw) : null;\n } catch {\n return null;\n }\n}\n\nfunction persistSize(id: string | undefined, size: number) {\n if (!id) return;\n try {\n localStorage.setItem(`splitView.${id}`, String(size));\n } catch {\n // noop\n }\n}\n\n/**\n * Resizable split-view container with a draggable handle between two panes.\n * Supports horizontal (left | right) and vertical (top | bottom) splitting.\n * Composable: nest SplitViews for complex layouts (e.g. trading dashboards).\n */\nexport function SplitView({\n direction = \"horizontal\",\n primary,\n secondary,\n defaultSize = 400,\n minSize = 100,\n maxSize = Infinity,\n secondaryMinSize = 100,\n onSizeChange,\n persistId,\n className,\n classNames,\n}: SplitViewProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const [size, setSize] = useState<number>(\n () => getPersistedSize(persistId) ?? defaultSize,\n );\n const [isResizing, setIsResizing] = useState(false);\n\n const isHorizontal = direction === \"horizontal\";\n\n const sizeRef = useValueRef(size);\n const minSizeRef = useValueRef(minSize);\n const maxSizeRef = useValueRef(maxSize);\n const secondaryMinSizeRef = useValueRef(secondaryMinSize);\n const isResizingRef = useValueRef(isResizing);\n\n const handleSizeChange = useCallbackRef((newSize: number) => {\n setSize(newSize);\n persistSize(persistId, newSize);\n onSizeChange?.(newSize);\n });\n\n const handleResizeStart = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsResizing(true);\n\n const cursor = isHorizontal ? \"ew-resize\" : \"ns-resize\";\n document.body.style.cursor = cursor;\n document.body.style.userSelect = \"none\";\n\n const startPos = isHorizontal ? e.clientX : e.clientY;\n const startSize = sizeRef.current;\n const containerEl = containerRef.current;\n const containerTotal = containerEl\n ? isHorizontal\n ? containerEl.offsetWidth\n : containerEl.offsetHeight\n : Infinity;\n\n const onMouseMove = (ev: MouseEvent) => {\n if (!isResizingRef.current) return;\n\n const currentPos = isHorizontal ? ev.clientX : ev.clientY;\n const delta = currentPos - startPos;\n\n const effectiveMax = Math.min(\n maxSizeRef.current,\n containerTotal - secondaryMinSizeRef.current - HANDLE_SIZE,\n );\n\n const newSize = Math.min(\n Math.max(startSize + delta, minSizeRef.current),\n effectiveMax,\n );\n handleSizeChange(newSize);\n };\n\n const onMouseUp = () => {\n setIsResizing(false);\n document.body.style.cursor = \"\";\n document.body.style.userSelect = \"\";\n document.removeEventListener(\"mousemove\", onMouseMove);\n document.removeEventListener(\"mouseup\", onMouseUp);\n };\n\n document.addEventListener(\"mousemove\", onMouseMove);\n document.addEventListener(\"mouseup\", onMouseUp);\n },\n [\n isHorizontal,\n sizeRef,\n minSizeRef,\n maxSizeRef,\n secondaryMinSizeRef,\n isResizingRef,\n handleSizeChange,\n ],\n );\n\n return (\n <div\n ref={containerRef}\n className={cn(\n \"w-full h-full flex overflow-hidden\",\n isHorizontal ? \"flex-row\" : \"flex-col\",\n className,\n )}\n >\n <div\n className={cn(\"flex-none overflow-hidden\", classNames?.primary)}\n style={\n isHorizontal\n ? { width: `${size}px`, minWidth: `${minSize}px` }\n : { height: `${size}px`, minHeight: `${minSize}px` }\n }\n >\n {primary}\n </div>\n\n <SplitHandle\n direction={direction}\n isResizing={isResizing}\n onResizeStart={handleResizeStart}\n className={classNames?.handle}\n />\n\n <div\n className={cn(\n \"flex-auto min-w-0 min-h-0 overflow-hidden\",\n classNames?.secondary,\n )}\n style={\n isHorizontal\n ? { minWidth: `${secondaryMinSize}px` }\n : { minHeight: `${secondaryMinSize}px` }\n }\n >\n {secondary}\n </div>\n </div>\n );\n}\n","declare global {\n interface Window {\n __LIBERFI_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};\n window.__LIBERFI_VERSION__[\"@liberfi.io/ui-scaffold\"] = \"0.1.113\";\n}\n\nexport default \"0.1.113\";\n"]}