UNPKG

soda-material

Version:

A component library that may follow [material design 3](https://m3.material.io/components) (a.k.a. material you)

55 lines (43 loc) 1.57 kB
import { useCallback, useSyncExternalStore, useState, useEffect } from 'react' export function useMediaQuery(query: string) { const subscribe = useCallback( (callback: VoidFunction) => { const matchMedia = window.matchMedia(query) matchMedia.addEventListener('change', callback) return () => matchMedia.removeEventListener('change', callback) }, [query] ) const getSnapshot = () => window.matchMedia(query).matches const getServerSnapshot = () => { throw Error('useMediaQuery is a client-only hook') } return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) } /** * https://m3.material.io/foundations/layout/applying-layout/window-size-classes */ export function useWindowSizeType() { const isCompact = useMediaQuery('only screen and (max-width : 600px)') const isMedium = useMediaQuery('only screen and (max-width : 840px)') return isCompact ? 'compact' : isMedium ? 'medium' : 'expanded' } /** * for pratical, this hook only intend for one element * @returns ResizeObserverEntry */ export function useResizeObserver( elementRef: React.RefObject<HTMLElement>, options?: ResizeObserverOptions ) { const [entry, setEntry] = useState<ResizeObserverEntry>() useEffect(() => { const ro = new ResizeObserver((entries) => { setEntry(entries[0]) }) const element = elementRef.current! ro.observe(element, options) return () => ro.unobserve(element) }) return entry }