mirror of
https://github.com/EnixCoda/Gitako.git
synced 2026-03-11 08:54:44 +00:00
feat: size observer
This commit is contained in:
parent
781c706137
commit
60c16da490
2 changed files with 113 additions and 0 deletions
45
src/components/SizeObserver.tsx
Normal file
45
src/components/SizeObserver.tsx
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import * as React from 'react'
|
||||
|
||||
type Size = {
|
||||
width: number
|
||||
height: number
|
||||
}
|
||||
|
||||
type Props = {
|
||||
type?: string | React.ComponentType
|
||||
children(size: Partial<Size>): React.ReactNode
|
||||
} & React.HTMLAttributes<HTMLElement>
|
||||
|
||||
export default function SizeObserver({
|
||||
type = 'div',
|
||||
children,
|
||||
...rest
|
||||
}: React.PropsWithChildren<Props>) {
|
||||
const ref = React.useRef<any>()
|
||||
|
||||
const [size, setSize] = React.useState<Partial<Size>>({
|
||||
width: undefined,
|
||||
height: undefined,
|
||||
})
|
||||
|
||||
React.useEffect(() => {
|
||||
const observer = new window.ResizeObserver(entries => {
|
||||
for (let entry of entries) {
|
||||
const rect = entry.contentRect
|
||||
console.log('Element:', entry.target)
|
||||
console.log(`Element size: ${rect.width}px x ${rect.height}px`)
|
||||
console.log(`Element padding: ${rect.top}px ; ${rect.left}px`)
|
||||
setSize({
|
||||
width: rect.width,
|
||||
height: rect.height,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (ref.current) observer.observe(ref.current)
|
||||
}, [])
|
||||
|
||||
const props: any = { ...rest, ref } // :)
|
||||
|
||||
return React.createElement(type, props, children(size))
|
||||
}
|
||||
68
src/resize-observer.d.ts
vendored
Normal file
68
src/resize-observer.d.ts
vendored
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
interface Window {
|
||||
ResizeObserver: ResizeObserver
|
||||
}
|
||||
|
||||
/**
|
||||
* The ResizeObserver interface is used to observe changes to Element's content
|
||||
* rect.
|
||||
*
|
||||
* It is modeled after MutationObserver and IntersectionObserver.
|
||||
*/
|
||||
interface ResizeObserver {
|
||||
new (callback: ResizeObserverCallback): ResizeObserver
|
||||
|
||||
/**
|
||||
* Adds target to the list of observed elements.
|
||||
*/
|
||||
observe: (target: Element) => void
|
||||
|
||||
/**
|
||||
* Removes target from the list of observed elements.
|
||||
*/
|
||||
unobserve: (target: Element) => void
|
||||
|
||||
/**
|
||||
* Clears both the observationTargets and activeTargets lists.
|
||||
*/
|
||||
disconnect: () => void
|
||||
}
|
||||
|
||||
/**
|
||||
* This callback delivers ResizeObserver's notifications. It is invoked by a
|
||||
* broadcast active observations algorithm.
|
||||
*/
|
||||
interface ResizeObserverCallback {
|
||||
(entries: ResizeObserverEntry[], observer: ResizeObserver): void
|
||||
}
|
||||
|
||||
interface ResizeObserverEntry {
|
||||
/**
|
||||
* @param target The Element whose size has changed.
|
||||
*/
|
||||
new (target: Element): void
|
||||
|
||||
/**
|
||||
* The Element whose size has changed.
|
||||
*/
|
||||
readonly target: Element
|
||||
|
||||
/**
|
||||
* Element's content rect when ResizeObserverCallback is invoked.
|
||||
*/
|
||||
readonly contentRect: DOMRectReadOnly
|
||||
}
|
||||
|
||||
interface DOMRectReadOnly {
|
||||
// static fromRect(other: DOMRectInit | undefined): DOMRectReadOnly;
|
||||
|
||||
readonly x: number
|
||||
readonly y: number
|
||||
readonly width: number
|
||||
readonly height: number
|
||||
readonly top: number
|
||||
readonly right: number
|
||||
readonly bottom: number
|
||||
readonly left: number
|
||||
|
||||
toJSON: () => any
|
||||
}
|
||||
Loading…
Reference in a new issue