@douyinfe/semi-foundation 2.67.2 → 2.68.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/datePicker/foundation.ts +1 -1
- package/lib/cjs/datePicker/foundation.d.ts +1 -1
- package/lib/cjs/resizable/constants.d.ts +5 -0
- package/lib/cjs/resizable/constants.js +11 -0
- package/lib/cjs/resizable/foundation.d.ts +4 -0
- package/lib/cjs/resizable/foundation.js +37 -0
- package/lib/cjs/resizable/group/index.d.ts +50 -0
- package/lib/cjs/resizable/group/index.js +271 -0
- package/lib/cjs/resizable/groupConstants.d.ts +16 -0
- package/lib/cjs/resizable/groupConstants.js +25 -0
- package/lib/cjs/resizable/resizable.css +34 -0
- package/lib/cjs/resizable/resizable.scss +39 -0
- package/lib/cjs/resizable/single/index.d.ts +70 -0
- package/lib/cjs/resizable/single/index.js +574 -0
- package/lib/cjs/resizable/singleConstants.d.ts +105 -0
- package/lib/cjs/resizable/singleConstants.js +67 -0
- package/lib/cjs/resizable/utils.d.ts +20 -0
- package/lib/cjs/resizable/utils.js +142 -0
- package/lib/es/datePicker/foundation.d.ts +1 -1
- package/lib/es/resizable/constants.d.ts +5 -0
- package/lib/es/resizable/constants.js +6 -0
- package/lib/es/resizable/foundation.d.ts +4 -0
- package/lib/es/resizable/foundation.js +4 -0
- package/lib/es/resizable/group/index.d.ts +50 -0
- package/lib/es/resizable/group/index.js +262 -0
- package/lib/es/resizable/groupConstants.d.ts +16 -0
- package/lib/es/resizable/groupConstants.js +19 -0
- package/lib/es/resizable/resizable.css +34 -0
- package/lib/es/resizable/resizable.scss +39 -0
- package/lib/es/resizable/single/index.d.ts +70 -0
- package/lib/es/resizable/single/index.js +565 -0
- package/lib/es/resizable/singleConstants.d.ts +105 -0
- package/lib/es/resizable/singleConstants.js +61 -0
- package/lib/es/resizable/utils.d.ts +20 -0
- package/lib/es/resizable/utils.js +124 -0
- package/package.json +3 -3
- package/resizable/constants.ts +13 -0
- package/resizable/foundation.ts +31 -0
- package/resizable/group/index.ts +293 -0
- package/resizable/groupConstants.ts +25 -0
- package/resizable/resizable.scss +39 -0
- package/resizable/single/index.ts +629 -0
- package/resizable/singleConstants.ts +127 -0
- package/resizable/utils.ts +145 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
$module: #{$prefix}-resizable;
|
|
2
|
+
|
|
3
|
+
.#{$module} {
|
|
4
|
+
&-resizable {
|
|
5
|
+
position: relative;
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
flex-shrink: 0;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
&-resizableHandler {
|
|
11
|
+
position: absolute;
|
|
12
|
+
user-select: none;
|
|
13
|
+
z-index: $z-resizable_handler;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
&-group {
|
|
17
|
+
display: flex;
|
|
18
|
+
position: relative;
|
|
19
|
+
box-sizing: border-box;
|
|
20
|
+
height: 100%;
|
|
21
|
+
width: 100%;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&-item {
|
|
25
|
+
position: relative;
|
|
26
|
+
box-sizing: border-box;
|
|
27
|
+
flex-shrink: 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&-handler {
|
|
31
|
+
user-select: none;
|
|
32
|
+
z-index: $z-resizable_handler;
|
|
33
|
+
display: flex;
|
|
34
|
+
align-items: center;
|
|
35
|
+
justify-content: center;
|
|
36
|
+
background-color: var(--semi-color-fill-0);
|
|
37
|
+
opacity: 1;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import BaseFoundation, { DefaultAdapter } from '../../base/foundation';
|
|
2
|
+
import { Size, NumberSize, Direction } from "../singleConstants";
|
|
3
|
+
export interface ResizableHandlerAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
|
|
4
|
+
registerEvent: () => void;
|
|
5
|
+
unregisterEvent: () => void;
|
|
6
|
+
}
|
|
7
|
+
export declare class ResizableHandlerFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<ResizableHandlerAdapter<P, S>, P, S> {
|
|
8
|
+
constructor(adapter: ResizableHandlerAdapter<P, S>);
|
|
9
|
+
init(): void;
|
|
10
|
+
onMouseDown: (e: MouseEvent) => void;
|
|
11
|
+
destroy(): void;
|
|
12
|
+
}
|
|
13
|
+
export interface ResizableAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
|
|
14
|
+
getResizable: () => HTMLDivElement | null;
|
|
15
|
+
registerEvent: () => void;
|
|
16
|
+
unregisterEvent: () => void;
|
|
17
|
+
}
|
|
18
|
+
export declare class ResizableFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<ResizableAdapter<P, S>, P, S> {
|
|
19
|
+
constructor(adapter: ResizableAdapter<P, S>);
|
|
20
|
+
init(): void;
|
|
21
|
+
flexDirection?: 'row' | 'column';
|
|
22
|
+
lockAspectRatio: number;
|
|
23
|
+
resizable: HTMLElement | null;
|
|
24
|
+
parentLeft: number;
|
|
25
|
+
parentTop: number;
|
|
26
|
+
boundaryLeft: number;
|
|
27
|
+
boundaryRight: number;
|
|
28
|
+
boundaryTop: number;
|
|
29
|
+
boundaryBottom: number;
|
|
30
|
+
targetLeft: number;
|
|
31
|
+
targetTop: number;
|
|
32
|
+
get parent(): HTMLElement | null;
|
|
33
|
+
get window(): Window | null;
|
|
34
|
+
get propSize(): Size;
|
|
35
|
+
get size(): NumberSize;
|
|
36
|
+
get sizeStyle(): {
|
|
37
|
+
width: string;
|
|
38
|
+
height: string;
|
|
39
|
+
};
|
|
40
|
+
getParentSize(): {
|
|
41
|
+
width: number;
|
|
42
|
+
height: number;
|
|
43
|
+
};
|
|
44
|
+
registerEvents(): void;
|
|
45
|
+
unregisterEvents(): void;
|
|
46
|
+
getCssPropertySize(newSize: number | string, property: 'width' | 'height'): number | string;
|
|
47
|
+
calBoundaryMax(maxWidth?: number, maxHeight?: number): {
|
|
48
|
+
maxWidth: number;
|
|
49
|
+
maxHeight: number;
|
|
50
|
+
};
|
|
51
|
+
calDirectionSize(clientX: number, clientY: number): {
|
|
52
|
+
newWidth: any;
|
|
53
|
+
newHeight: any;
|
|
54
|
+
};
|
|
55
|
+
calAspectRatioSize(newWidth: number, newHeight: number, max: {
|
|
56
|
+
width?: number;
|
|
57
|
+
height?: number;
|
|
58
|
+
}, min: {
|
|
59
|
+
width?: number;
|
|
60
|
+
height?: number;
|
|
61
|
+
}): {
|
|
62
|
+
newWidth: number;
|
|
63
|
+
newHeight: number;
|
|
64
|
+
};
|
|
65
|
+
setBoundary(): void;
|
|
66
|
+
onResizeStart: (e: MouseEvent, direction: Direction) => void;
|
|
67
|
+
onMouseMove: (event: MouseEvent) => void;
|
|
68
|
+
onMouseUp: (event: MouseEvent) => void;
|
|
69
|
+
destroy(): void;
|
|
70
|
+
}
|
|
@@ -0,0 +1,565 @@
|
|
|
1
|
+
import BaseFoundation from '../../base/foundation';
|
|
2
|
+
import { DEFAULT_SIZE } from "../singleConstants";
|
|
3
|
+
import { getStringSize, getNumberSize, has, calculateNewMax, findNextSnap, snap, clamp } from "../utils";
|
|
4
|
+
export class ResizableHandlerFoundation extends BaseFoundation {
|
|
5
|
+
constructor(adapter) {
|
|
6
|
+
super(Object.assign({}, adapter));
|
|
7
|
+
this.onMouseDown = e => {
|
|
8
|
+
this.getProp('onResizeStart')(e, this.getProp('direction'));
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
init() {
|
|
12
|
+
this._adapter.registerEvent();
|
|
13
|
+
}
|
|
14
|
+
destroy() {
|
|
15
|
+
this._adapter.unregisterEvent();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export class ResizableFoundation extends BaseFoundation {
|
|
19
|
+
constructor(adapter) {
|
|
20
|
+
super(Object.assign({}, adapter));
|
|
21
|
+
this.lockAspectRatio = 1;
|
|
22
|
+
this.resizable = null;
|
|
23
|
+
this.parentLeft = 0;
|
|
24
|
+
this.parentTop = 0;
|
|
25
|
+
this.boundaryLeft = 0;
|
|
26
|
+
this.boundaryRight = 0;
|
|
27
|
+
this.boundaryTop = 0;
|
|
28
|
+
this.boundaryBottom = 0;
|
|
29
|
+
this.targetLeft = 0;
|
|
30
|
+
this.targetTop = 0;
|
|
31
|
+
this.onResizeStart = (e, direction) => {
|
|
32
|
+
this.resizable = this._adapter.getResizable();
|
|
33
|
+
if (!this.resizable || !this.window) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const {
|
|
37
|
+
clientX,
|
|
38
|
+
clientY
|
|
39
|
+
} = e;
|
|
40
|
+
const props = this.getProps();
|
|
41
|
+
const states = this.getStates();
|
|
42
|
+
// Call onResizeStart callback if defined
|
|
43
|
+
if (props.onResizeStart) {
|
|
44
|
+
const shouldContinue = props.onResizeStart(e, direction);
|
|
45
|
+
if (shouldContinue === false) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Update state with new size if defined
|
|
50
|
+
const {
|
|
51
|
+
size
|
|
52
|
+
} = props;
|
|
53
|
+
if (size) {
|
|
54
|
+
const {
|
|
55
|
+
height,
|
|
56
|
+
width
|
|
57
|
+
} = size;
|
|
58
|
+
const {
|
|
59
|
+
height: currentHeight,
|
|
60
|
+
width: currentWidth
|
|
61
|
+
} = states;
|
|
62
|
+
if (height !== undefined && height !== currentHeight) {
|
|
63
|
+
this.setState({
|
|
64
|
+
height
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
if (width !== undefined && width !== currentWidth) {
|
|
68
|
+
this.setState({
|
|
69
|
+
width
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Handle aspect ratio locking
|
|
74
|
+
this.lockAspectRatio = typeof props.lockAspectRatio === 'number' ? props.lockAspectRatio : this.size.width / this.size.height;
|
|
75
|
+
// Determine flexBasis if applicable
|
|
76
|
+
let flexBasis;
|
|
77
|
+
const computedStyle = this.window.getComputedStyle(this.resizable);
|
|
78
|
+
if (computedStyle.flexBasis !== 'auto') {
|
|
79
|
+
const parent = this.parent;
|
|
80
|
+
if (parent) {
|
|
81
|
+
const parentStyle = this.window.getComputedStyle(parent);
|
|
82
|
+
this.flexDirection = parentStyle.flexDirection.startsWith('row') ? 'row' : 'column';
|
|
83
|
+
flexBasis = computedStyle.flexBasis;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Set bounding rectangle and register events
|
|
87
|
+
this.setBoundary();
|
|
88
|
+
this.registerEvents();
|
|
89
|
+
// Update state with initial resize values
|
|
90
|
+
const state = {
|
|
91
|
+
original: {
|
|
92
|
+
x: clientX,
|
|
93
|
+
y: clientY,
|
|
94
|
+
width: this.size.width,
|
|
95
|
+
height: this.size.height
|
|
96
|
+
},
|
|
97
|
+
isResizing: true,
|
|
98
|
+
backgroundStyle: Object.assign(Object.assign({}, states.backgroundStyle), {
|
|
99
|
+
cursor: this.window.getComputedStyle(e.target).cursor || 'auto'
|
|
100
|
+
}),
|
|
101
|
+
direction,
|
|
102
|
+
flexBasis
|
|
103
|
+
};
|
|
104
|
+
this.setState(state);
|
|
105
|
+
};
|
|
106
|
+
this.onMouseMove = event => {
|
|
107
|
+
var _a, _b;
|
|
108
|
+
const states = this.getStates();
|
|
109
|
+
const props = this.getProps();
|
|
110
|
+
if (!states.isResizing || !this.resizable || !this.window) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const {
|
|
114
|
+
clientX,
|
|
115
|
+
clientY
|
|
116
|
+
} = event;
|
|
117
|
+
const {
|
|
118
|
+
direction,
|
|
119
|
+
original,
|
|
120
|
+
width,
|
|
121
|
+
height
|
|
122
|
+
} = states;
|
|
123
|
+
const parentSize = this.getParentSize();
|
|
124
|
+
let {
|
|
125
|
+
maxWidth,
|
|
126
|
+
maxHeight,
|
|
127
|
+
minWidth,
|
|
128
|
+
minHeight
|
|
129
|
+
} = props;
|
|
130
|
+
// Calculate max and min dimensions
|
|
131
|
+
const maxBounds = calculateNewMax(parentSize, this.window.innerWidth, this.window.innerHeight, maxWidth, maxHeight, minWidth, minHeight);
|
|
132
|
+
maxWidth = maxBounds.maxWidth;
|
|
133
|
+
maxHeight = maxBounds.maxHeight;
|
|
134
|
+
minWidth = maxBounds.minWidth;
|
|
135
|
+
minHeight = maxBounds.minHeight;
|
|
136
|
+
// Calculate new size based on direction
|
|
137
|
+
let {
|
|
138
|
+
newWidth,
|
|
139
|
+
newHeight
|
|
140
|
+
} = this.calDirectionSize(clientX, clientY);
|
|
141
|
+
// Apply boundary constraints
|
|
142
|
+
const boundaryMax = this.calBoundaryMax(maxWidth, maxHeight);
|
|
143
|
+
newWidth = getNumberSize(newWidth, parentSize.width, this.window.innerWidth, this.window.innerHeight);
|
|
144
|
+
newHeight = getNumberSize(newHeight, parentSize.height, this.window.innerWidth, this.window.innerHeight);
|
|
145
|
+
// Apply snapping
|
|
146
|
+
if (props.snap) {
|
|
147
|
+
if (props.snap.x) {
|
|
148
|
+
newWidth = findNextSnap(newWidth, props.snap.x, props.snapGap);
|
|
149
|
+
}
|
|
150
|
+
if (props.snap.y) {
|
|
151
|
+
newHeight = findNextSnap(newHeight, props.snap.y, props.snapGap);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Adjust size based on aspect ratio
|
|
155
|
+
const sizeFromAspectRatio = this.calAspectRatioSize(newWidth, newHeight, {
|
|
156
|
+
width: boundaryMax.maxWidth,
|
|
157
|
+
height: boundaryMax.maxHeight
|
|
158
|
+
}, {
|
|
159
|
+
width: minWidth,
|
|
160
|
+
height: minHeight
|
|
161
|
+
});
|
|
162
|
+
newWidth = sizeFromAspectRatio.newWidth;
|
|
163
|
+
newHeight = sizeFromAspectRatio.newHeight;
|
|
164
|
+
// Apply grid snapping if defined
|
|
165
|
+
if (props.grid) {
|
|
166
|
+
const [gridW, gridH] = Array.isArray(props.grid) ? props.grid : [props.grid, props.grid];
|
|
167
|
+
const gap = props.snapGap || 0;
|
|
168
|
+
const newGridWidth = snap(newWidth, gridW);
|
|
169
|
+
const newGridHeight = snap(newHeight, gridH);
|
|
170
|
+
newWidth = gap === 0 || Math.abs(newGridWidth - newWidth) <= gap ? newGridWidth : newWidth;
|
|
171
|
+
newHeight = gap === 0 || Math.abs(newGridHeight - newHeight) <= gap ? newGridHeight : newHeight;
|
|
172
|
+
}
|
|
173
|
+
// Convert width and height to CSS units if needed
|
|
174
|
+
const convertToCssUnit = (size, originalSize, unit) => {
|
|
175
|
+
if (unit.endsWith('%')) {
|
|
176
|
+
return `${size / originalSize * 100}%`;
|
|
177
|
+
} else if (unit.endsWith('vw')) {
|
|
178
|
+
return `${size / this.window.innerWidth * 100}vw`;
|
|
179
|
+
} else if (unit.endsWith('vh')) {
|
|
180
|
+
return `${size / this.window.innerHeight * 100}vh`;
|
|
181
|
+
}
|
|
182
|
+
return size;
|
|
183
|
+
};
|
|
184
|
+
if (typeof width === 'string') {
|
|
185
|
+
newWidth = convertToCssUnit(newWidth, parentSize.width, width || '');
|
|
186
|
+
}
|
|
187
|
+
if (typeof height === 'string') {
|
|
188
|
+
newHeight = convertToCssUnit(newHeight, parentSize.height, height || '');
|
|
189
|
+
}
|
|
190
|
+
// Create new state
|
|
191
|
+
const newState = {
|
|
192
|
+
width: this.getCssPropertySize(newWidth, 'width'),
|
|
193
|
+
height: this.getCssPropertySize(newHeight, 'height')
|
|
194
|
+
};
|
|
195
|
+
if (this.flexDirection === 'row') {
|
|
196
|
+
newState.flexBasis = newState.width;
|
|
197
|
+
} else if (this.flexDirection === 'column') {
|
|
198
|
+
newState.flexBasis = newState.height;
|
|
199
|
+
}
|
|
200
|
+
// Check for changes
|
|
201
|
+
const widthChanged = states.width !== newState.width;
|
|
202
|
+
const heightChanged = states.height !== newState.height;
|
|
203
|
+
const flexBaseChanged = states.flexBasis !== newState.flexBasis;
|
|
204
|
+
const hasChanges = widthChanged || heightChanged || flexBaseChanged;
|
|
205
|
+
if (hasChanges) {
|
|
206
|
+
this.setState(newState);
|
|
207
|
+
// Call onChange callback if defined
|
|
208
|
+
if (props.onChange) {
|
|
209
|
+
let newSize = {
|
|
210
|
+
width: newState.width,
|
|
211
|
+
height: newState.height
|
|
212
|
+
};
|
|
213
|
+
props.onChange(newSize, event, direction);
|
|
214
|
+
}
|
|
215
|
+
const size = props.size;
|
|
216
|
+
if (size) {
|
|
217
|
+
this.setState({
|
|
218
|
+
width: (_a = size.width) !== null && _a !== void 0 ? _a : 'auto',
|
|
219
|
+
height: (_b = size.height) !== null && _b !== void 0 ? _b : 'auto'
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
this.onMouseUp = event => {
|
|
225
|
+
var _a, _b;
|
|
226
|
+
const {
|
|
227
|
+
isResizing,
|
|
228
|
+
direction,
|
|
229
|
+
original
|
|
230
|
+
} = this.getStates();
|
|
231
|
+
if (!isResizing || !this.resizable) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const {
|
|
235
|
+
width: currentWidth,
|
|
236
|
+
height: currentHeight
|
|
237
|
+
} = this.size;
|
|
238
|
+
const delta = {
|
|
239
|
+
width: currentWidth - original.width,
|
|
240
|
+
height: currentHeight - original.height
|
|
241
|
+
};
|
|
242
|
+
const {
|
|
243
|
+
onResizeEnd,
|
|
244
|
+
size
|
|
245
|
+
} = this.getProps();
|
|
246
|
+
// Call onResizeEnd callback if defined
|
|
247
|
+
if (onResizeEnd) {
|
|
248
|
+
onResizeEnd(this.size, event, direction);
|
|
249
|
+
}
|
|
250
|
+
// Update state with new size if provided
|
|
251
|
+
if (size) {
|
|
252
|
+
this.setState({
|
|
253
|
+
width: (_a = size.width) !== null && _a !== void 0 ? _a : 'auto',
|
|
254
|
+
height: (_b = size.height) !== null && _b !== void 0 ? _b : 'auto'
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
// Unregister events and update state
|
|
258
|
+
this.unregisterEvents();
|
|
259
|
+
this.setState({
|
|
260
|
+
isResizing: false,
|
|
261
|
+
backgroundStyle: Object.assign(Object.assign({}, this.getStates().backgroundStyle), {
|
|
262
|
+
cursor: 'auto'
|
|
263
|
+
})
|
|
264
|
+
});
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
init() {
|
|
268
|
+
if (!this.resizable || !this.window) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
const flexBasis = this.window.getComputedStyle(this.resizable).flexBasis;
|
|
272
|
+
this.setState({
|
|
273
|
+
width: this.propSize.width,
|
|
274
|
+
height: this.propSize.height,
|
|
275
|
+
flexBasis: flexBasis !== 'auto' ? flexBasis : undefined
|
|
276
|
+
});
|
|
277
|
+
this.onResizeStart = this.onResizeStart.bind(this);
|
|
278
|
+
this.onMouseMove = this.onMouseMove.bind(this);
|
|
279
|
+
this.onMouseUp = this.onMouseUp.bind(this);
|
|
280
|
+
}
|
|
281
|
+
get parent() {
|
|
282
|
+
if (!this.resizable) {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
return this.resizable.parentNode;
|
|
286
|
+
}
|
|
287
|
+
get window() {
|
|
288
|
+
if (!this.resizable) {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
if (!this.resizable.ownerDocument) {
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
return this.resizable.ownerDocument.defaultView;
|
|
295
|
+
}
|
|
296
|
+
get propSize() {
|
|
297
|
+
const porps = this.getProps();
|
|
298
|
+
return porps.size || porps.defaultSize || DEFAULT_SIZE;
|
|
299
|
+
}
|
|
300
|
+
get size() {
|
|
301
|
+
let width = 0;
|
|
302
|
+
let height = 0;
|
|
303
|
+
if (this.resizable && this.window) {
|
|
304
|
+
width = this.resizable.offsetWidth;
|
|
305
|
+
height = this.resizable.offsetHeight;
|
|
306
|
+
}
|
|
307
|
+
return {
|
|
308
|
+
width,
|
|
309
|
+
height
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
get sizeStyle() {
|
|
313
|
+
const size = this.getProp('size');
|
|
314
|
+
const getSize = property => {
|
|
315
|
+
var _a;
|
|
316
|
+
const value = this.getStates()[property];
|
|
317
|
+
if (typeof value === 'undefined' || value === 'auto') {
|
|
318
|
+
return 'auto';
|
|
319
|
+
}
|
|
320
|
+
const propSizeValue = (_a = this.propSize) === null || _a === void 0 ? void 0 : _a[property];
|
|
321
|
+
if (propSizeValue === null || propSizeValue === void 0 ? void 0 : propSizeValue.toString().endsWith('%')) {
|
|
322
|
+
if (value.toString().endsWith('%')) {
|
|
323
|
+
return value.toString();
|
|
324
|
+
}
|
|
325
|
+
const parentSize = this.getParentSize();
|
|
326
|
+
const numberValue = Number(value.toString().replace('px', ''));
|
|
327
|
+
const percentValue = numberValue / parentSize[property] * 100;
|
|
328
|
+
return `${percentValue}%`;
|
|
329
|
+
}
|
|
330
|
+
return getStringSize(value);
|
|
331
|
+
};
|
|
332
|
+
const isResizing = this.getStates().isResizing;
|
|
333
|
+
const width = size && typeof size.width !== 'undefined' && !isResizing ? getStringSize(size.width) : getSize('width');
|
|
334
|
+
const height = size && typeof size.height !== 'undefined' && !isResizing ? getStringSize(size.height) : getSize('height');
|
|
335
|
+
return {
|
|
336
|
+
width,
|
|
337
|
+
height
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
getParentSize() {
|
|
341
|
+
const appendPseudo = () => {
|
|
342
|
+
if (!this.resizable || !this.window) {
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
const parent = this.parent;
|
|
346
|
+
if (!parent) {
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
const pseudoEle = this.window.document.createElement('div');
|
|
350
|
+
pseudoEle.style.width = '100%';
|
|
351
|
+
pseudoEle.style.height = '100%';
|
|
352
|
+
pseudoEle.style.position = 'absolute';
|
|
353
|
+
pseudoEle.style.transform = 'scale(0, 0)';
|
|
354
|
+
pseudoEle.style.left = '0';
|
|
355
|
+
pseudoEle.style.flex = '0 0 100%';
|
|
356
|
+
parent.appendChild(pseudoEle);
|
|
357
|
+
return pseudoEle;
|
|
358
|
+
};
|
|
359
|
+
const removePseudo = pseudo => {
|
|
360
|
+
const parent = this.parent;
|
|
361
|
+
if (!parent) {
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
parent.removeChild(pseudo);
|
|
365
|
+
};
|
|
366
|
+
if (!this.parent) {
|
|
367
|
+
if (!this.window) {
|
|
368
|
+
return {
|
|
369
|
+
width: 0,
|
|
370
|
+
height: 0
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
return {
|
|
374
|
+
width: this.window.innerWidth,
|
|
375
|
+
height: this.window.innerHeight
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
const pseudoElement = appendPseudo();
|
|
379
|
+
if (!pseudoElement) {
|
|
380
|
+
return {
|
|
381
|
+
width: 0,
|
|
382
|
+
height: 0
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
let flexWrapChanged = false;
|
|
386
|
+
const originalFlexWrap = this.parent.style.flexWrap;
|
|
387
|
+
if (originalFlexWrap !== 'wrap') {
|
|
388
|
+
flexWrapChanged = true;
|
|
389
|
+
this.parent.style.flexWrap = 'wrap';
|
|
390
|
+
}
|
|
391
|
+
pseudoElement.style.position = 'relative';
|
|
392
|
+
pseudoElement.style.minWidth = '100%';
|
|
393
|
+
pseudoElement.style.minHeight = '100%';
|
|
394
|
+
const size = {
|
|
395
|
+
width: pseudoElement.offsetWidth,
|
|
396
|
+
height: pseudoElement.offsetHeight
|
|
397
|
+
};
|
|
398
|
+
if (flexWrapChanged) {
|
|
399
|
+
this.parent.style.flexWrap = originalFlexWrap;
|
|
400
|
+
}
|
|
401
|
+
removePseudo(pseudoElement);
|
|
402
|
+
return size;
|
|
403
|
+
}
|
|
404
|
+
registerEvents() {
|
|
405
|
+
this._adapter.registerEvent();
|
|
406
|
+
}
|
|
407
|
+
unregisterEvents() {
|
|
408
|
+
this._adapter.unregisterEvent();
|
|
409
|
+
}
|
|
410
|
+
getCssPropertySize(newSize, property) {
|
|
411
|
+
var _a;
|
|
412
|
+
const propSizeValue = (_a = this.propSize) === null || _a === void 0 ? void 0 : _a[property];
|
|
413
|
+
const state = this.getStates();
|
|
414
|
+
const isAutoSize = state[property] === 'auto' && state.original[property] === newSize && (typeof propSizeValue === 'undefined' || propSizeValue === 'auto');
|
|
415
|
+
return isAutoSize ? 'auto' : newSize;
|
|
416
|
+
}
|
|
417
|
+
calBoundaryMax(maxWidth, maxHeight) {
|
|
418
|
+
const {
|
|
419
|
+
boundsByDirection
|
|
420
|
+
} = this.getProps();
|
|
421
|
+
const {
|
|
422
|
+
direction
|
|
423
|
+
} = this.getStates();
|
|
424
|
+
const isWidthConstrained = boundsByDirection && has('left', direction);
|
|
425
|
+
const isHeightConstrained = boundsByDirection && has('top', direction);
|
|
426
|
+
let maxWidthConstraint;
|
|
427
|
+
let maxHeightConstraint;
|
|
428
|
+
const props = this.getProps();
|
|
429
|
+
if (props.boundElement === 'parent') {
|
|
430
|
+
const parentElement = this.parent;
|
|
431
|
+
if (parentElement) {
|
|
432
|
+
maxWidthConstraint = isWidthConstrained ? this.boundaryRight - this.parentLeft : parentElement.offsetWidth + (this.parentLeft - this.boundaryLeft);
|
|
433
|
+
maxHeightConstraint = isHeightConstrained ? this.boundaryBottom - this.parentTop : parentElement.offsetHeight + (this.parentTop - this.boundaryTop);
|
|
434
|
+
}
|
|
435
|
+
} else if (props.boundElement === 'window' && this.window) {
|
|
436
|
+
maxWidthConstraint = isWidthConstrained ? this.boundaryRight : this.window.innerWidth - this.boundaryLeft;
|
|
437
|
+
maxHeightConstraint = isHeightConstrained ? this.boundaryBottom : this.window.innerHeight - this.boundaryTop;
|
|
438
|
+
} else if (props.boundElement) {
|
|
439
|
+
const boundary = props.boundElement;
|
|
440
|
+
maxWidthConstraint = isWidthConstrained ? this.boundaryRight - this.targetLeft : boundary.offsetWidth + (this.targetLeft - this.boundaryLeft);
|
|
441
|
+
maxHeightConstraint = isHeightConstrained ? this.boundaryBottom - this.targetTop : boundary.offsetHeight + (this.targetTop - this.boundaryTop);
|
|
442
|
+
}
|
|
443
|
+
if (maxWidthConstraint && Number.isFinite(maxWidthConstraint)) {
|
|
444
|
+
maxWidth = maxWidth && maxWidth < maxWidthConstraint ? maxWidth : maxWidthConstraint;
|
|
445
|
+
}
|
|
446
|
+
if (maxHeightConstraint && Number.isFinite(maxHeightConstraint)) {
|
|
447
|
+
maxHeight = maxHeight && maxHeight < maxHeightConstraint ? maxHeight : maxHeightConstraint;
|
|
448
|
+
}
|
|
449
|
+
return {
|
|
450
|
+
maxWidth,
|
|
451
|
+
maxHeight
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
calDirectionSize(clientX, clientY) {
|
|
455
|
+
const props = this.getProps();
|
|
456
|
+
const scale = props.scale || 1;
|
|
457
|
+
let aspectRatio = props.ratio;
|
|
458
|
+
const [resizeRatioX, resizeRatioY] = Array.isArray(aspectRatio) ? aspectRatio : [aspectRatio, aspectRatio];
|
|
459
|
+
const {
|
|
460
|
+
direction,
|
|
461
|
+
original
|
|
462
|
+
} = this.getStates();
|
|
463
|
+
const {
|
|
464
|
+
lockAspectRatio,
|
|
465
|
+
lockAspectRatioExtraHeight = 0,
|
|
466
|
+
lockAspectRatioExtraWidth = 0
|
|
467
|
+
} = props;
|
|
468
|
+
let newWidth = original.width;
|
|
469
|
+
let newHeight = original.height;
|
|
470
|
+
const calculateNewWidth = deltaX => original.width + deltaX * resizeRatioX / scale;
|
|
471
|
+
const calculateNewHeight = deltaY => original.height + deltaY * resizeRatioY / scale;
|
|
472
|
+
if (has('top', direction)) {
|
|
473
|
+
newHeight = calculateNewHeight(original.y - clientY);
|
|
474
|
+
if (lockAspectRatio) {
|
|
475
|
+
newWidth = (newHeight - lockAspectRatioExtraHeight) * this.lockAspectRatio + lockAspectRatioExtraWidth;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
if (has('bottom', direction)) {
|
|
479
|
+
newHeight = calculateNewHeight(clientY - original.y);
|
|
480
|
+
if (lockAspectRatio) {
|
|
481
|
+
newWidth = (newHeight - lockAspectRatioExtraHeight) * this.lockAspectRatio + lockAspectRatioExtraWidth;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
if (has('right', direction)) {
|
|
485
|
+
newWidth = calculateNewWidth(clientX - original.x);
|
|
486
|
+
if (lockAspectRatio) {
|
|
487
|
+
newHeight = (newWidth - lockAspectRatioExtraWidth) / this.lockAspectRatio + lockAspectRatioExtraHeight;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
if (has('left', direction)) {
|
|
491
|
+
newWidth = calculateNewWidth(original.x - clientX);
|
|
492
|
+
if (lockAspectRatio) {
|
|
493
|
+
newHeight = (newWidth - lockAspectRatioExtraWidth) / this.lockAspectRatio + lockAspectRatioExtraHeight;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
return {
|
|
497
|
+
newWidth,
|
|
498
|
+
newHeight
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
calAspectRatioSize(newWidth, newHeight, max, min) {
|
|
502
|
+
const {
|
|
503
|
+
lockAspectRatio,
|
|
504
|
+
lockAspectRatioExtraHeight = 0,
|
|
505
|
+
lockAspectRatioExtraWidth = 0
|
|
506
|
+
} = this.getProps();
|
|
507
|
+
const minWidth = typeof min.width === 'undefined' ? 10 : min.width;
|
|
508
|
+
const maxWidth = typeof max.width === 'undefined' || max.width < 0 ? newWidth : max.width;
|
|
509
|
+
const minHeight = typeof min.height === 'undefined' ? 10 : min.height;
|
|
510
|
+
const maxHeight = typeof max.height === 'undefined' || max.height < 0 ? newHeight : max.height;
|
|
511
|
+
if (lockAspectRatio) {
|
|
512
|
+
const adjustedMinWidth = (minHeight - lockAspectRatioExtraHeight) * this.lockAspectRatio + lockAspectRatioExtraWidth;
|
|
513
|
+
const adjustedMaxWidth = (maxHeight - lockAspectRatioExtraHeight) * this.lockAspectRatio + lockAspectRatioExtraWidth;
|
|
514
|
+
const adjustedMinHeight = (minWidth - lockAspectRatioExtraWidth) / this.lockAspectRatio + lockAspectRatioExtraHeight;
|
|
515
|
+
const adjustedMaxHeight = (maxWidth - lockAspectRatioExtraWidth) / this.lockAspectRatio + lockAspectRatioExtraHeight;
|
|
516
|
+
const lockedMinWidth = Math.max(minWidth, adjustedMinWidth);
|
|
517
|
+
const lockedMaxWidth = Math.min(maxWidth, adjustedMaxWidth);
|
|
518
|
+
const lockedMinHeight = Math.max(minHeight, adjustedMinHeight);
|
|
519
|
+
const lockedMaxHeight = Math.min(maxHeight, adjustedMaxHeight);
|
|
520
|
+
newWidth = clamp(newWidth, lockedMinWidth, lockedMaxWidth);
|
|
521
|
+
newHeight = clamp(newHeight, lockedMinHeight, lockedMaxHeight);
|
|
522
|
+
} else {
|
|
523
|
+
newWidth = clamp(newWidth, minWidth, maxWidth);
|
|
524
|
+
newHeight = clamp(newHeight, minHeight, maxHeight);
|
|
525
|
+
}
|
|
526
|
+
return {
|
|
527
|
+
newWidth,
|
|
528
|
+
newHeight
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
setBoundary() {
|
|
532
|
+
const props = this.getProps();
|
|
533
|
+
// Set parent boundary
|
|
534
|
+
if (props.boundElement === 'parent') {
|
|
535
|
+
const parentElement = this.parent;
|
|
536
|
+
if (parentElement) {
|
|
537
|
+
const parentRect = parentElement.getBoundingClientRect();
|
|
538
|
+
this.parentLeft = parentRect.left;
|
|
539
|
+
this.parentTop = parentRect.top;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
// Set target (HTML element) boundary
|
|
543
|
+
if (props.boundElement && typeof props.boundElement !== 'string') {
|
|
544
|
+
const targetRect = props.boundElement.getBoundingClientRect();
|
|
545
|
+
this.targetLeft = targetRect.left;
|
|
546
|
+
this.targetTop = targetRect.top;
|
|
547
|
+
}
|
|
548
|
+
// Set resizable boundary
|
|
549
|
+
if (this.resizable) {
|
|
550
|
+
const {
|
|
551
|
+
left,
|
|
552
|
+
top,
|
|
553
|
+
right,
|
|
554
|
+
bottom
|
|
555
|
+
} = this.resizable.getBoundingClientRect();
|
|
556
|
+
this.boundaryLeft = left;
|
|
557
|
+
this.boundaryRight = right;
|
|
558
|
+
this.boundaryTop = top;
|
|
559
|
+
this.boundaryBottom = bottom;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
destroy() {
|
|
563
|
+
this.unregisterEvents();
|
|
564
|
+
}
|
|
565
|
+
}
|