mirror of https://github.com/sveltejs/svelte
feat: add support for resize observer bindings (#8022)
Implements ResizeObserver bindings: #5524 (comment) Continuation of: #5963 Related to #7583 --------- Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>pull/8022/merge
parent
3a7685fef5
commit
0adc09da97
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Resize observer singleton.
|
||||
* One listener per element only!
|
||||
* https://groups.google.com/a/chromium.org/g/blink-dev/c/z6ienONUb5A/m/F5-VcUZtBAAJ
|
||||
*/
|
||||
export class ResizeObserverSingleton {
|
||||
constructor(readonly options?: ResizeObserverOptions) {}
|
||||
|
||||
observe(element: Element, listener: Listener) {
|
||||
this._listeners.set(element, listener);
|
||||
this._getObserver().observe(element, this.options);
|
||||
return () => {
|
||||
this._listeners.delete(element);
|
||||
this._observer.unobserve(element); // this line can probably be removed
|
||||
};
|
||||
}
|
||||
|
||||
static readonly entries: WeakMap<Element, ResizeObserverEntry> = 'WeakMap' in globalThis ? new WeakMap() : undefined;
|
||||
|
||||
private readonly _listeners: WeakMap<Element, Listener> = 'WeakMap' in globalThis ? new WeakMap() : undefined;
|
||||
private _observer?: ResizeObserver;
|
||||
private _getObserver() {
|
||||
return this._observer ?? (this._observer = new ResizeObserver((entries) => {
|
||||
for (const entry of entries) {
|
||||
ResizeObserverSingleton.entries.set(entry.target, entry);
|
||||
this._listeners.get(entry.target)?.(entry);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
type Listener = (entry: ResizeObserverEntry)=>any;
|
||||
|
||||
// TODO: Remove this
|
||||
interface ResizeObserverSize {
|
||||
readonly blockSize: number;
|
||||
readonly inlineSize: number;
|
||||
}
|
||||
|
||||
interface ResizeObserverEntry {
|
||||
readonly borderBoxSize: readonly ResizeObserverSize[];
|
||||
readonly contentBoxSize: readonly ResizeObserverSize[];
|
||||
readonly contentRect: DOMRectReadOnly;
|
||||
readonly devicePixelContentBoxSize: readonly ResizeObserverSize[];
|
||||
readonly target: Element;
|
||||
}
|
||||
|
||||
type ResizeObserverBoxOptions = 'border-box' | 'content-box' | 'device-pixel-content-box';
|
||||
|
||||
interface ResizeObserverOptions {
|
||||
box?: ResizeObserverBoxOptions;
|
||||
}
|
||||
|
||||
interface ResizeObserver {
|
||||
disconnect(): void;
|
||||
observe(target: Element, options?: ResizeObserverOptions): void;
|
||||
unobserve(target: Element): void;
|
||||
}
|
||||
|
||||
interface ResizeObserverCallback {
|
||||
(entries: ResizeObserverEntry[], observer: ResizeObserver): void;
|
||||
}
|
||||
|
||||
declare let ResizeObserver: {
|
||||
prototype: ResizeObserver;
|
||||
new(callback: ResizeObserverCallback): ResizeObserver;
|
||||
};
|
Loading…
Reference in new issue