UNPKG

@lifi/widget

Version:

LI.FI Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.

109 lines (87 loc) 3.21 kB
import { debounce, useTheme } from '@mui/material' import type { RefObject } from 'react' import { useLayoutEffect, useState } from 'react' import { ElementId, getAppContainer, getHeaderElement, getScrollableContainer, } from '../utils/elements.js' import { useDefaultElementId } from './useDefaultElementId.js' const getContentHeight = ( elementId: string, listParentRef: RefObject<HTMLUListElement | HTMLDivElement | null> ) => { const containerElement = getScrollableContainer(elementId) const headerElement = getHeaderElement(elementId) const listParentElement = listParentRef?.current let oldHeight: string | undefined // This covers the case where in full height flex mode when the browser height is reduced // - this allows a virtualised list to be made smaller if (listParentElement) { oldHeight = listParentElement.style.height listParentElement.style.height = '0' } if (!containerElement || !headerElement) { console.warn( `Can't find ${ElementId.ScrollableContainer} or ${ElementId.Header} id.` ) return 0 } const { height: containerHeight } = containerElement.getBoundingClientRect() const { height: headerHeight } = headerElement.getBoundingClientRect() // This covers the case where in full height flex mode when the browser height is reduced the // - this allows a virtualised list to be set to minimum size if (listParentElement && oldHeight) { listParentElement.style.height = oldHeight } return containerHeight - headerHeight } interface UseContentHeightProps { listParentRef: RefObject<HTMLUListElement | HTMLDivElement | null> headerRef?: RefObject<HTMLElement | null> } export const defaultMinListHeight = 360 export const minMobileListHeight = 160 // NOTE: this hook is implicitly tied to the widget height functionality in the // AppExpandedContainer, RelativeContainer and CssBaselineContainer components as defined in AppContainer.ts // CSS changes in those components can have implications for the functionality in this hook export const useListHeight = ({ listParentRef, headerRef, }: UseContentHeightProps) => { const elementId = useDefaultElementId() const [contentHeight, setContentHeight] = useState<number>(0) const theme = useTheme() useLayoutEffect(() => { const handleResize = () => { setContentHeight(getContentHeight(elementId, listParentRef)) } const processResize = debounce(() => handleResize(), 40) // calling this on initial mount prevents the lists resizing appearing glitchy handleResize() const appContainer = getAppContainer(elementId) let resizeObserver: ResizeObserver if (appContainer) { resizeObserver = new ResizeObserver(processResize) resizeObserver.observe(appContainer) } return () => { if (resizeObserver) { resizeObserver.disconnect() } } }, [elementId, listParentRef]) const minListHeight = theme.container?.height === '100%' ? minMobileListHeight : defaultMinListHeight const listHeight = Math.max( contentHeight - (headerRef?.current?.offsetHeight ?? 0), minListHeight ) return { minListHeight, listHeight, } }