Files
test1/components/image-editor/components/canvas/use-domino-scroll-into-view.ts
2026-03-20 07:33:46 +00:00

58 lines
1.8 KiB
TypeScript

import { useCallback } from 'react'
import { useDominoStore, useDominoStoreInstance } from './domino-hooks'
import type { Padding, ScrollIntoViewOptions } from './domino'
import { useDominoContainer } from './use-domino-container'
import { calculateScrollIntoViewTransform } from './math'
/**
* Hook to scroll an element into view within the Domino canvas.
* (Internal hook, prefer using useDominoInstance)
*/
export function useDominoScrollIntoView(
explicitContainerRef?: React.RefObject<HTMLElement | null>,
) {
const store = useDominoStoreInstance()
const setViewport = useDominoStore(state => state.setViewport)
const containerRef = useDominoContainer(explicitContainerRef)
const scrollIntoView = useCallback(
(elementId: string, options?: ScrollIntoViewOptions) => {
const container = containerRef?.current
if (!container) return false
const { elements, viewport, padding: globalPadding } = store.getState()
const element = elements[elementId]
if (!element) return false
const finalPadding = {
top: options?.padding?.top ?? globalPadding.top ?? 0,
right: options?.padding?.right ?? globalPadding.right ?? 0,
bottom: options?.padding?.bottom ?? globalPadding.bottom ?? 0,
left: options?.padding?.left ?? globalPadding.left ?? 0,
} as Required<Padding>
const nextViewport = calculateScrollIntoViewTransform(
element,
viewport,
container.getBoundingClientRect(),
finalPadding,
{
force: options?.force,
block: options?.block,
inline: options?.inline,
targetScale: options?.scale,
},
)
if (nextViewport) {
setViewport(nextViewport)
return true
}
return false
},
[setViewport, containerRef, store],
)
return scrollIntoView
}