-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathContainerManager.ts
119 lines (110 loc) · 3.42 KB
/
ContainerManager.ts
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/**
* egjs-grid
* Copyright (c) 2021-present NAVER Corp.
* MIT license
*/
import Component from "@egjs/component";
import { DestroyOptions, SizeRect } from "./types";
import { ResizeWatcherResizeEvent, ResizeWatcher } from "./ResizeWatcher";
import { DEFAULT_GRID_OPTIONS, RECT_NAMES } from "./consts";
export interface ContainerManagerOptions {
horizontal?: boolean;
autoResize?: boolean;
resizeDebounce?: number;
maxResizeDebounce?: number;
useResizeObserver?: boolean;
}
export interface ContainerManagerStatus {
rect: SizeRect;
}
export interface ContainerManagerEvents {
resize: ResizeWatcherResizeEvent;
}
export class ContainerManager extends Component<ContainerManagerEvents> {
protected options: Required<ContainerManagerOptions>;
protected orgCSSText: string;
protected _watcher: ResizeWatcher;
constructor(protected container: HTMLElement, options: ContainerManagerOptions) {
super();
this.options = {
horizontal: DEFAULT_GRID_OPTIONS.horizontal,
autoResize: DEFAULT_GRID_OPTIONS.autoResize,
resizeDebounce: DEFAULT_GRID_OPTIONS.resizeDebounce,
maxResizeDebounce: DEFAULT_GRID_OPTIONS.maxResizeDebounce,
useResizeObserver: DEFAULT_GRID_OPTIONS.useResizeObserver,
...options,
};
this._init();
}
public resize() {
const container = this.container;
this.setRect({
width: container.clientWidth,
height: container.clientHeight,
});
}
public isObserverEnabled() {
return this._watcher.isObserverEnabled();
}
public getRect() {
return this._watcher.getRect();
}
public observeChildren(children: Element[]) {
this._watcher.observeChildren(children);
}
public unobserveChildren(children: Element[]) {
this._watcher.unobserveChildren(children);
}
public setRect(rect: SizeRect) {
this._watcher.setRect(rect);
}
public getInlineSize() {
return this.getRect()[this._names.inlineSize];
}
public getContentSize() {
return this.getRect()[this._names.contentSize];
}
public getStatus() {
return { rect: this._watcher.getRect() };
}
public setStatus(status: ContainerManagerStatus) {
this.setRect(status.rect);
this.setContentSize(this.getContentSize());
}
public setContentSize(size: number) {
const sizeName = this.options.horizontal ? "width" : "height";
this.setRect({
...this.getRect(),
[sizeName]: size,
});
this.container.style[sizeName] = `${size}px`;
}
public destroy(options: DestroyOptions = {}) {
this._watcher.destroy();
if (!options.preserveUI) {
this.container.style.cssText = this.orgCSSText;
}
}
private _init() {
const container = this.container;
const style = window.getComputedStyle(container);
this.orgCSSText = container.style.cssText;
if (style.position === "static") {
container.style.position = "relative";
}
const options = this.options;
this._watcher = new ResizeWatcher(container, {
useWindowResize: options.autoResize,
useResizeObserver: options.useResizeObserver,
resizeDebounce: options.resizeDebounce,
maxResizeDebounce: options.maxResizeDebounce,
watchDirection: options.useResizeObserver ? this._names.inlineSize : false,
}).listen(this._onResize);
}
private _onResize = (e: ResizeWatcherResizeEvent) => {
this.trigger("resize", e);
}
private get _names() {
return RECT_NAMES[this.options.horizontal ? "horizontal" : "vertical"];
}
}