-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathresize-observer.ts
More file actions
90 lines (77 loc) · 2.44 KB
/
resize-observer.ts
File metadata and controls
90 lines (77 loc) · 2.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import {
type ReactiveController,
type ReactiveControllerHost,
isServer,
} from 'lit';
type ResizeObserverControllerCallback = (
...args: Parameters<ResizeObserverCallback>
) => unknown;
/** Configuration for initializing a resize controller. */
export interface ResizeObserverControllerConfig {
/** The callback function to run when a resize mutation is triggered. */
callback: ResizeObserverControllerCallback;
/** Configuration options passed to the underlying ResizeObserver. */
options?: ResizeObserverOptions;
/**
* The initial target element to observe for resize mutations.
*
* If not provided, the host element will be set as initial target.
* Pass in `null` to skip setting an initial target.
*/
target?: Element | null;
}
class ResizeObserverController implements ReactiveController {
private readonly _host: ReactiveControllerHost & Element;
private readonly _targets = new Set<Element>();
private readonly _observer!: ResizeObserver;
private readonly _config: ResizeObserverControllerConfig;
constructor(
host: ReactiveControllerHost & Element,
config: ResizeObserverControllerConfig
) {
this._host = host;
this._config = config;
if (this._config.target !== null) {
this._targets.add(this._config.target ?? host);
}
/* c8 ignore next 3 */
if (isServer) {
return;
}
this._observer = new ResizeObserver((entries) =>
this._config.callback.call(this._host, entries, this._observer)
);
host.addController(this);
}
/** Starts observing the `targe` element. */
public observe(target: Element): void {
this._targets.add(target);
this._observer.observe(target, this._config.options);
this._host.requestUpdate();
}
/** Stops observing the `target` element. */
public unobserve(target: Element): void {
this._targets.delete(target);
this._observer.unobserve(target);
}
/** @internal */
public hostConnected(): void {
for (const target of this._targets) {
this.observe(target);
}
}
/** @internal */
public hostDisconnected(): void {
this._observer.disconnect();
}
}
/**
* Creates a new resize controller bound to the given `host`
* with {@link ResizeObserverControllerConfig | `config`}.
*/
export function createResizeObserverController(
host: ReactiveControllerHost & Element,
config: ResizeObserverControllerConfig
): ResizeObserverController {
return new ResizeObserverController(host, config);
}