@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,105 @@
|
|
|
1
|
+
export declare const directions: readonly ["top", "right", "bottom", "left", "topRight", "bottomRight", "bottomLeft", "topLeft"];
|
|
2
|
+
export declare const directionStyles: {
|
|
3
|
+
readonly top: {
|
|
4
|
+
readonly top: "-5px";
|
|
5
|
+
readonly width: "100%";
|
|
6
|
+
readonly height: "10px";
|
|
7
|
+
readonly left: "0px";
|
|
8
|
+
readonly cursor: "row-resize";
|
|
9
|
+
};
|
|
10
|
+
readonly right: {
|
|
11
|
+
readonly left: any;
|
|
12
|
+
readonly right: "-5px";
|
|
13
|
+
readonly width: "10px";
|
|
14
|
+
readonly height: "100%";
|
|
15
|
+
readonly top: "0px";
|
|
16
|
+
readonly cursor: "col-resize";
|
|
17
|
+
};
|
|
18
|
+
readonly bottom: {
|
|
19
|
+
readonly top: any;
|
|
20
|
+
readonly bottom: "-5px";
|
|
21
|
+
readonly width: "100%";
|
|
22
|
+
readonly height: "10px";
|
|
23
|
+
readonly left: "0px";
|
|
24
|
+
readonly cursor: "row-resize";
|
|
25
|
+
};
|
|
26
|
+
readonly left: {
|
|
27
|
+
readonly left: "-5px";
|
|
28
|
+
readonly width: "10px";
|
|
29
|
+
readonly height: "100%";
|
|
30
|
+
readonly top: "0px";
|
|
31
|
+
readonly cursor: "col-resize";
|
|
32
|
+
};
|
|
33
|
+
readonly topRight: {
|
|
34
|
+
readonly right: "-10px";
|
|
35
|
+
readonly top: "-10px";
|
|
36
|
+
readonly cursor: "ne-resize";
|
|
37
|
+
readonly width: "20px";
|
|
38
|
+
readonly height: "20px";
|
|
39
|
+
readonly position: "absolute";
|
|
40
|
+
};
|
|
41
|
+
readonly bottomRight: {
|
|
42
|
+
readonly right: "-10px";
|
|
43
|
+
readonly bottom: "-10px";
|
|
44
|
+
readonly cursor: "se-resize";
|
|
45
|
+
readonly width: "20px";
|
|
46
|
+
readonly height: "20px";
|
|
47
|
+
readonly position: "absolute";
|
|
48
|
+
};
|
|
49
|
+
readonly bottomLeft: {
|
|
50
|
+
readonly left: "-10px";
|
|
51
|
+
readonly bottom: "-10px";
|
|
52
|
+
readonly cursor: "sw-resize";
|
|
53
|
+
readonly width: "20px";
|
|
54
|
+
readonly height: "20px";
|
|
55
|
+
readonly position: "absolute";
|
|
56
|
+
};
|
|
57
|
+
readonly topLeft: {
|
|
58
|
+
readonly left: "-10px";
|
|
59
|
+
readonly top: "-10px";
|
|
60
|
+
readonly cursor: "nw-resize";
|
|
61
|
+
readonly width: "20px";
|
|
62
|
+
readonly height: "20px";
|
|
63
|
+
readonly position: "absolute";
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
export type Direction = 'top' | 'right' | 'bottom' | 'left' | 'topRight' | 'bottomRight' | 'bottomLeft' | 'topLeft';
|
|
67
|
+
export interface HandleClassName {
|
|
68
|
+
top?: string;
|
|
69
|
+
right?: string;
|
|
70
|
+
bottom?: string;
|
|
71
|
+
left?: string;
|
|
72
|
+
topRight?: string;
|
|
73
|
+
bottomRight?: string;
|
|
74
|
+
bottomLeft?: string;
|
|
75
|
+
topLeft?: string;
|
|
76
|
+
}
|
|
77
|
+
export type HandlerCallback = (e: MouseEvent, direction: Direction) => void;
|
|
78
|
+
export interface Enable {
|
|
79
|
+
top?: boolean;
|
|
80
|
+
right?: boolean;
|
|
81
|
+
bottom?: boolean;
|
|
82
|
+
left?: boolean;
|
|
83
|
+
topRight?: boolean;
|
|
84
|
+
bottomRight?: boolean;
|
|
85
|
+
bottomLeft?: boolean;
|
|
86
|
+
topLeft?: boolean;
|
|
87
|
+
}
|
|
88
|
+
export interface Size {
|
|
89
|
+
width?: string | number;
|
|
90
|
+
height?: string | number;
|
|
91
|
+
}
|
|
92
|
+
export interface NumberSize {
|
|
93
|
+
width: number;
|
|
94
|
+
height: number;
|
|
95
|
+
}
|
|
96
|
+
export interface NewSize {
|
|
97
|
+
newHeight: number | string;
|
|
98
|
+
newWidth: number | string;
|
|
99
|
+
}
|
|
100
|
+
export declare const DEFAULT_SIZE: {
|
|
101
|
+
width: string;
|
|
102
|
+
height: string;
|
|
103
|
+
};
|
|
104
|
+
export type ResizeCallback = (size: Size, event: MouseEvent, direction: Direction) => void;
|
|
105
|
+
export type ResizeStartCallback = (e: MouseEvent, dir: Direction) => void | boolean;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// single
|
|
2
|
+
const rowStyleBase = {
|
|
3
|
+
width: '100%',
|
|
4
|
+
height: '10px',
|
|
5
|
+
top: '0px',
|
|
6
|
+
left: '0px',
|
|
7
|
+
cursor: 'row-resize'
|
|
8
|
+
};
|
|
9
|
+
const colStyleBase = {
|
|
10
|
+
width: '10px',
|
|
11
|
+
height: '100%',
|
|
12
|
+
top: '0px',
|
|
13
|
+
left: '0px',
|
|
14
|
+
cursor: 'col-resize'
|
|
15
|
+
};
|
|
16
|
+
const edgeStyleBase = {
|
|
17
|
+
width: '20px',
|
|
18
|
+
height: '20px',
|
|
19
|
+
position: 'absolute'
|
|
20
|
+
};
|
|
21
|
+
export const directions = ['top', 'right', 'bottom', 'left', 'topRight', 'bottomRight', 'bottomLeft', 'topLeft'];
|
|
22
|
+
export const directionStyles = {
|
|
23
|
+
top: Object.assign(Object.assign({}, rowStyleBase), {
|
|
24
|
+
top: '-5px'
|
|
25
|
+
}),
|
|
26
|
+
right: Object.assign(Object.assign({}, colStyleBase), {
|
|
27
|
+
left: undefined,
|
|
28
|
+
right: '-5px'
|
|
29
|
+
}),
|
|
30
|
+
bottom: Object.assign(Object.assign({}, rowStyleBase), {
|
|
31
|
+
top: undefined,
|
|
32
|
+
bottom: '-5px'
|
|
33
|
+
}),
|
|
34
|
+
left: Object.assign(Object.assign({}, colStyleBase), {
|
|
35
|
+
left: '-5px'
|
|
36
|
+
}),
|
|
37
|
+
topRight: Object.assign(Object.assign({}, edgeStyleBase), {
|
|
38
|
+
right: '-10px',
|
|
39
|
+
top: '-10px',
|
|
40
|
+
cursor: 'ne-resize'
|
|
41
|
+
}),
|
|
42
|
+
bottomRight: Object.assign(Object.assign({}, edgeStyleBase), {
|
|
43
|
+
right: '-10px',
|
|
44
|
+
bottom: '-10px',
|
|
45
|
+
cursor: 'se-resize'
|
|
46
|
+
}),
|
|
47
|
+
bottomLeft: Object.assign(Object.assign({}, edgeStyleBase), {
|
|
48
|
+
left: '-10px',
|
|
49
|
+
bottom: '-10px',
|
|
50
|
+
cursor: 'sw-resize'
|
|
51
|
+
}),
|
|
52
|
+
topLeft: Object.assign(Object.assign({}, edgeStyleBase), {
|
|
53
|
+
left: '-10px',
|
|
54
|
+
top: '-10px',
|
|
55
|
+
cursor: 'nw-resize'
|
|
56
|
+
})
|
|
57
|
+
};
|
|
58
|
+
export const DEFAULT_SIZE = {
|
|
59
|
+
width: 'auto',
|
|
60
|
+
height: 'auto'
|
|
61
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const clamp: (n: number, min: number, max: number) => number;
|
|
2
|
+
export declare const snap: (n: number, size: number) => number;
|
|
3
|
+
export declare const has: (dir: 'top' | 'right' | 'bottom' | 'left', target: string) => boolean;
|
|
4
|
+
export declare const findNextSnap: (n: number, snapArray: number[], snapGap?: number) => number;
|
|
5
|
+
export declare const getStringSize: (n: number | string) => string;
|
|
6
|
+
export declare const getNumberSize: (size: undefined | string | number, parentSize: number, innerWidth: number, innerHeight: number) => number;
|
|
7
|
+
export declare const calculateNewMax: (parentSize: {
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
}, innerWidth: number, innerHeight: number, maxWidth?: string | number, maxHeight?: string | number, minWidth?: string | number, minHeight?: string | number) => {
|
|
11
|
+
maxWidth: number;
|
|
12
|
+
maxHeight: number;
|
|
13
|
+
minWidth: number;
|
|
14
|
+
minHeight: number;
|
|
15
|
+
};
|
|
16
|
+
export declare const getItemDirection: (dir: 'vertical' | 'horizontal') => string[];
|
|
17
|
+
export declare const getPixelSize: (size: string, parentSize: number) => number;
|
|
18
|
+
export declare const judgeConstraint: (newSize: number, min: string, max: string, parentSize: number, offset?: number) => boolean;
|
|
19
|
+
export declare const adjustNewSize: (newSize: number, min: string, max: string, parentSize: number, offset: number) => number;
|
|
20
|
+
export declare const getOffset: (style: CSSStyleDeclaration, direction: 'horizontal' | 'vertical') => number;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
export const clamp = (n, min, max) => Math.max(Math.min(n, max), min);
|
|
2
|
+
export const snap = (n, size) => Math.round(n / size) * size;
|
|
3
|
+
export const has = (dir, target) => new RegExp(dir, 'i').test(target);
|
|
4
|
+
export const findNextSnap = function (n, snapArray) {
|
|
5
|
+
let snapGap = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
6
|
+
const closestGapIndex = snapArray.reduce((prev, curr, index) => Math.abs(curr - n) < Math.abs(snapArray[prev] - n) ? index : prev, 0);
|
|
7
|
+
const gap = Math.abs(snapArray[closestGapIndex] - n);
|
|
8
|
+
return snapGap === 0 || gap < snapGap ? snapArray[closestGapIndex] : n;
|
|
9
|
+
};
|
|
10
|
+
export const getStringSize = n => {
|
|
11
|
+
n = n.toString();
|
|
12
|
+
if (n === 'auto') {
|
|
13
|
+
return n;
|
|
14
|
+
}
|
|
15
|
+
if (n.endsWith('px')) {
|
|
16
|
+
return n;
|
|
17
|
+
}
|
|
18
|
+
if (n.endsWith('%')) {
|
|
19
|
+
return n;
|
|
20
|
+
}
|
|
21
|
+
if (n.endsWith('vh')) {
|
|
22
|
+
return n;
|
|
23
|
+
}
|
|
24
|
+
if (n.endsWith('vw')) {
|
|
25
|
+
return n;
|
|
26
|
+
}
|
|
27
|
+
if (n.endsWith('vmax')) {
|
|
28
|
+
return n;
|
|
29
|
+
}
|
|
30
|
+
if (n.endsWith('vmin')) {
|
|
31
|
+
return n;
|
|
32
|
+
}
|
|
33
|
+
return `${n}px`;
|
|
34
|
+
};
|
|
35
|
+
export const getNumberSize = (size, parentSize, innerWidth, innerHeight) => {
|
|
36
|
+
if (size && typeof size === 'string') {
|
|
37
|
+
if (size.endsWith('px')) {
|
|
38
|
+
return Number(size.replace('px', ''));
|
|
39
|
+
}
|
|
40
|
+
if (size.endsWith('%')) {
|
|
41
|
+
const ratio = Number(size.replace('%', '')) / 100;
|
|
42
|
+
return parentSize * ratio;
|
|
43
|
+
}
|
|
44
|
+
if (size.endsWith('vw')) {
|
|
45
|
+
const ratio = Number(size.replace('vw', '')) / 100;
|
|
46
|
+
return innerWidth * ratio;
|
|
47
|
+
}
|
|
48
|
+
if (size.endsWith('vh')) {
|
|
49
|
+
const ratio = Number(size.replace('vh', '')) / 100;
|
|
50
|
+
return innerHeight * ratio;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return typeof size === 'undefined' ? size : Number(size);
|
|
54
|
+
};
|
|
55
|
+
export const calculateNewMax = (parentSize, innerWidth, innerHeight, maxWidth, maxHeight, minWidth, minHeight) => {
|
|
56
|
+
maxWidth = getNumberSize(maxWidth, parentSize.width, innerWidth, innerHeight);
|
|
57
|
+
maxHeight = getNumberSize(maxHeight, parentSize.height, innerWidth, innerHeight);
|
|
58
|
+
minWidth = getNumberSize(minWidth, parentSize.width, innerWidth, innerHeight);
|
|
59
|
+
minHeight = getNumberSize(minHeight, parentSize.height, innerWidth, innerHeight);
|
|
60
|
+
return {
|
|
61
|
+
maxWidth,
|
|
62
|
+
maxHeight,
|
|
63
|
+
minWidth,
|
|
64
|
+
minHeight
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
export const getItemDirection = dir => {
|
|
68
|
+
if (dir === 'vertical') {
|
|
69
|
+
return ['bottom', 'top'];
|
|
70
|
+
} else {
|
|
71
|
+
return ['right', 'left'];
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
export const getPixelSize = (size, parentSize) => {
|
|
75
|
+
if (size.endsWith('px')) {
|
|
76
|
+
return Number(size.replace('px', ''));
|
|
77
|
+
}
|
|
78
|
+
if (size.endsWith('%')) {
|
|
79
|
+
return Number(size.replace('%', '')) / 100 * parentSize;
|
|
80
|
+
}
|
|
81
|
+
return typeof size === 'undefined' ? size : Number(size);
|
|
82
|
+
};
|
|
83
|
+
export const judgeConstraint = function (newSize, min, max, parentSize) {
|
|
84
|
+
let offset = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
|
|
85
|
+
min = min !== null && min !== void 0 ? min : "0%";
|
|
86
|
+
max = max !== null && max !== void 0 ? max : "100%";
|
|
87
|
+
const minSize = getPixelSize(min, parentSize);
|
|
88
|
+
const maxSize = getPixelSize(max, parentSize);
|
|
89
|
+
if (newSize <= minSize + offset) {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
if (newSize >= maxSize - offset) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
return false;
|
|
96
|
+
};
|
|
97
|
+
export const adjustNewSize = (newSize, min, max, parentSize, offset) => {
|
|
98
|
+
min = min !== null && min !== void 0 ? min : "0%";
|
|
99
|
+
max = max !== null && max !== void 0 ? max : "100%";
|
|
100
|
+
const minSize = getPixelSize(min, parentSize);
|
|
101
|
+
const maxSize = getPixelSize(max, parentSize);
|
|
102
|
+
if (newSize <= minSize + offset) {
|
|
103
|
+
return minSize + offset;
|
|
104
|
+
}
|
|
105
|
+
if (newSize >= maxSize - offset) {
|
|
106
|
+
return maxSize - offset;
|
|
107
|
+
}
|
|
108
|
+
return newSize;
|
|
109
|
+
};
|
|
110
|
+
export const getOffset = (style, direction) => {
|
|
111
|
+
if (direction === 'horizontal') {
|
|
112
|
+
const paddingLeft = parseFloat(style.paddingLeft);
|
|
113
|
+
const paddingRight = parseFloat(style.paddingRight);
|
|
114
|
+
const borderLeftWidth = parseFloat(style.borderLeftWidth);
|
|
115
|
+
const borderRightWidth = parseFloat(style.borderRightWidth);
|
|
116
|
+
return paddingLeft + paddingRight + borderLeftWidth + borderRightWidth;
|
|
117
|
+
} else {
|
|
118
|
+
const paddingTop = parseFloat(style.paddingTop);
|
|
119
|
+
const paddingBottom = parseFloat(style.paddingBottom);
|
|
120
|
+
const borderTopWidth = parseFloat(style.borderTopWidth);
|
|
121
|
+
const borderBottomWidth = parseFloat(style.borderBottomWidth);
|
|
122
|
+
return paddingTop + paddingBottom + borderTopWidth + borderBottomWidth;
|
|
123
|
+
}
|
|
124
|
+
};
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@douyinfe/semi-foundation",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.68.0-beta.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build:lib": "node ./scripts/compileLib.js",
|
|
7
7
|
"prepublishOnly": "npm run build:lib"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@douyinfe/semi-animation": "2.
|
|
10
|
+
"@douyinfe/semi-animation": "2.68.0-beta.0",
|
|
11
11
|
"@mdx-js/mdx": "^3.0.1",
|
|
12
12
|
"async-validator": "^3.5.0",
|
|
13
13
|
"classnames": "^2.2.6",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"*.scss",
|
|
29
29
|
"*.css"
|
|
30
30
|
],
|
|
31
|
-
"gitHead": "
|
|
31
|
+
"gitHead": "14e3f82adfde5d9ac0de952b74b3e2cee2e5fd33",
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@babel/plugin-transform-runtime": "^7.15.8",
|
|
34
34
|
"@babel/preset-env": "^7.15.8",
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ResizableHandlerAdapter,
|
|
3
|
+
ResizableHandlerFoundation,
|
|
4
|
+
ResizableFoundation,
|
|
5
|
+
ResizableAdapter }
|
|
6
|
+
from './single';
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
ResizableHandlerAdapter,
|
|
10
|
+
ResizableHandlerFoundation,
|
|
11
|
+
ResizableFoundation,
|
|
12
|
+
ResizableAdapter
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
ResizeGroupAdapter,
|
|
17
|
+
ResizeItemAdapter,
|
|
18
|
+
ResizeHandlerAdapter,
|
|
19
|
+
ResizeGroupFoundation,
|
|
20
|
+
ResizeItemFoundation,
|
|
21
|
+
ResizeHandlerFoundation
|
|
22
|
+
} from './group';
|
|
23
|
+
|
|
24
|
+
export {
|
|
25
|
+
ResizeGroupAdapter,
|
|
26
|
+
ResizeItemAdapter,
|
|
27
|
+
ResizeHandlerAdapter,
|
|
28
|
+
ResizeGroupFoundation,
|
|
29
|
+
ResizeItemFoundation,
|
|
30
|
+
ResizeHandlerFoundation
|
|
31
|
+
};
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { getItemDirection, getPixelSize } from "../utils";
|
|
2
|
+
import BaseFoundation, { DefaultAdapter } from '../../base/foundation';
|
|
3
|
+
import { ResizeStartCallback, ResizeCallback } from "../singleConstants";
|
|
4
|
+
import { adjustNewSize, judgeConstraint, getOffset } from "../utils";
|
|
5
|
+
export interface ResizeHandlerAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
|
|
6
|
+
registerEvents: () => void;
|
|
7
|
+
unregisterEvents: () => void
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class ResizeHandlerFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<ResizeHandlerAdapter<P, S>, P, S> {
|
|
11
|
+
constructor(adapter: ResizeHandlerAdapter<P, S>) {
|
|
12
|
+
super({ ...adapter });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
init(): void {
|
|
16
|
+
this._adapter.registerEvents();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
destroy(): void {
|
|
20
|
+
this._adapter.unregisterEvents();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ResizeItemAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class ResizeItemFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<ResizeItemAdapter<P, S>, P, S> {
|
|
28
|
+
constructor(adapter: ResizeItemAdapter<P, S>) {
|
|
29
|
+
super({ ...adapter });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
init(): void {
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
destroy(): void {
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface ResizeGroupAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
|
|
40
|
+
getGroupRef: () => HTMLDivElement | null;
|
|
41
|
+
getItem: (index: number) => HTMLDivElement;
|
|
42
|
+
getItemCount: () => number;
|
|
43
|
+
getHandler: (index: number) => HTMLDivElement;
|
|
44
|
+
getHandlerCount: () => number;
|
|
45
|
+
getItemMin: (index: number) => string;
|
|
46
|
+
getItemMax: (index: number) => string;
|
|
47
|
+
getItemStart: (index: number) => ResizeStartCallback;
|
|
48
|
+
getItemChange: (index: number) => ResizeCallback;
|
|
49
|
+
getItemEnd: (index: number) => ResizeCallback;
|
|
50
|
+
getItemDefaultSize: (index: number) => string | number;
|
|
51
|
+
registerEvents: () => void;
|
|
52
|
+
unregisterEvents: () => void
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export class ResizeGroupFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<ResizeGroupAdapter<P, S>, P, S> {
|
|
56
|
+
constructor(adapter: ResizeGroupAdapter<P, S>) {
|
|
57
|
+
super({ ...adapter });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get groupRef(): HTMLDivElement | null {
|
|
61
|
+
return this._adapter.getGroupRef();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
direction: 'horizontal' | 'vertical'
|
|
65
|
+
itemMinusMap: Map<number, number>;
|
|
66
|
+
totalMinus: number;
|
|
67
|
+
avaliableSize: number;
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
init(): void {
|
|
71
|
+
this.direction = this.getProp('direction');
|
|
72
|
+
this.itemMinusMap = new Map();
|
|
73
|
+
this.calculateSpace();
|
|
74
|
+
}
|
|
75
|
+
get window(): Window | null {
|
|
76
|
+
return this.groupRef.ownerDocument.defaultView as Window ?? null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
registerEvents = () => {
|
|
81
|
+
this._adapter.registerEvents();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
unregisterEvents = () => {
|
|
85
|
+
this._adapter.unregisterEvents();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
onResizeStart = (handlerIndex: number, e: MouseEvent) => { // handler ref
|
|
89
|
+
let { clientX, clientY } = e;
|
|
90
|
+
let lastItem = this._adapter.getItem(handlerIndex), nextItem = this._adapter.getItem(handlerIndex + 1);
|
|
91
|
+
let lastOffset: number, nextOffset: number;
|
|
92
|
+
// offset caused by padding and border
|
|
93
|
+
const lastStyle = this.window.getComputedStyle(lastItem);
|
|
94
|
+
const nextStyle = this.window.getComputedStyle(nextItem);
|
|
95
|
+
|
|
96
|
+
lastOffset = getOffset(lastStyle, this.direction);
|
|
97
|
+
nextOffset = getOffset(nextStyle, this.direction);
|
|
98
|
+
const states = this.getStates();
|
|
99
|
+
this.setState({
|
|
100
|
+
isResizing: true,
|
|
101
|
+
originalPosition: {
|
|
102
|
+
x: clientX,
|
|
103
|
+
y: clientY,
|
|
104
|
+
lastItemSize: (this.direction === 'horizontal' ? lastItem.offsetWidth : lastItem.offsetHeight),
|
|
105
|
+
nextItemSize: (this.direction === 'horizontal' ? nextItem.offsetWidth : nextItem.offsetHeight),
|
|
106
|
+
lastOffset,
|
|
107
|
+
nextOffset,
|
|
108
|
+
},
|
|
109
|
+
backgroundStyle: {
|
|
110
|
+
...states.backgroundStyle,
|
|
111
|
+
cursor: this.window.getComputedStyle(e.target as HTMLElement).cursor || 'auto',
|
|
112
|
+
},
|
|
113
|
+
curHandler: handlerIndex
|
|
114
|
+
} as any);
|
|
115
|
+
this.registerEvents();
|
|
116
|
+
|
|
117
|
+
let lastStart = this._adapter.getItemStart(handlerIndex),
|
|
118
|
+
nextStart = this._adapter.getItemStart(handlerIndex + 1);
|
|
119
|
+
let [lastDir, nextDir] = getItemDirection(this.direction);
|
|
120
|
+
if (lastStart) {
|
|
121
|
+
lastStart(e, lastDir as any);
|
|
122
|
+
}
|
|
123
|
+
if (nextStart) {
|
|
124
|
+
nextStart(e, nextDir as any);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
onResizing = (e: MouseEvent) => {
|
|
130
|
+
const state = this.getStates();
|
|
131
|
+
if (!state.isResizing) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const { curHandler, originalPosition } = state;
|
|
135
|
+
let { x: initX, y: initY, lastItemSize, nextItemSize, lastOffset, nextOffset } = originalPosition;
|
|
136
|
+
let { clientX, clientY } = e;
|
|
137
|
+
|
|
138
|
+
const props = this.getProps();
|
|
139
|
+
const { direction } = props;
|
|
140
|
+
let lastItem = this._adapter.getItem(curHandler), nextItem = this._adapter.getItem(curHandler + 1);
|
|
141
|
+
let parentSize = this.direction === 'horizontal' ? this.groupRef.offsetWidth : this.groupRef.offsetHeight;
|
|
142
|
+
let availableSize = parentSize - this.totalMinus;
|
|
143
|
+
|
|
144
|
+
let delta = direction === 'horizontal' ? (clientX - initX) : (clientY - initY);
|
|
145
|
+
let lastNewSize = lastItemSize + delta;
|
|
146
|
+
let nextNewSize = nextItemSize - delta;
|
|
147
|
+
|
|
148
|
+
// 判断是否超出限制
|
|
149
|
+
let lastFlag = judgeConstraint(lastNewSize, this._adapter.getItemMin(curHandler), this._adapter.getItemMax(curHandler), availableSize, lastOffset),
|
|
150
|
+
nextFlag = judgeConstraint(nextNewSize, this._adapter.getItemMin(curHandler + 1), this._adapter.getItemMax(curHandler + 1), availableSize, nextOffset);
|
|
151
|
+
|
|
152
|
+
if (lastFlag) {
|
|
153
|
+
lastNewSize = adjustNewSize(lastNewSize, this._adapter.getItemMin(curHandler), this._adapter.getItemMax(curHandler), availableSize, lastOffset);
|
|
154
|
+
nextNewSize = lastItemSize + nextItemSize - lastNewSize;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (nextFlag) {
|
|
158
|
+
nextNewSize = adjustNewSize(nextNewSize, this._adapter.getItemMin(curHandler + 1), this._adapter.getItemMax(curHandler + 1), availableSize, nextOffset);
|
|
159
|
+
lastNewSize = lastItemSize + nextItemSize - nextNewSize;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (direction === 'horizontal') {
|
|
163
|
+
lastItem.style.width = (lastNewSize) / parentSize * 100 + '%';
|
|
164
|
+
nextItem.style.width = (nextNewSize) / parentSize * 100 + '%';
|
|
165
|
+
} else if (direction === 'vertical') {
|
|
166
|
+
lastItem.style.height = (lastNewSize) / parentSize * 100 + '%';
|
|
167
|
+
nextItem.style.height = (nextNewSize) / parentSize * 100 + '%';
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
let lastFunc = this._adapter.getItemChange(curHandler),
|
|
171
|
+
nextFunc = this._adapter.getItemChange(curHandler + 1);
|
|
172
|
+
let [lastDir, nextDir] = getItemDirection(this.direction);
|
|
173
|
+
if (lastFunc) {
|
|
174
|
+
lastFunc( { width: lastItem.offsetWidth, height: lastItem.offsetHeight }, e, lastDir as any);
|
|
175
|
+
}
|
|
176
|
+
if (nextFunc) {
|
|
177
|
+
nextFunc( { width: nextItem.offsetWidth, height: nextItem.offsetHeight }, e, nextDir as any);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
onResizeEnd = (e: MouseEvent) => {
|
|
182
|
+
const { curHandler } = this.getStates();
|
|
183
|
+
let lastItem = this._adapter.getItem(curHandler), nextItem = this._adapter.getItem(curHandler + 1);
|
|
184
|
+
let lastFunc = this._adapter.getItemEnd(curHandler),
|
|
185
|
+
nextFunc = this._adapter.getItemEnd(curHandler + 1);
|
|
186
|
+
let [lastDir, nextDir] = getItemDirection(this.direction);
|
|
187
|
+
if (lastFunc) {
|
|
188
|
+
lastFunc( { width: lastItem.offsetWidth, height: lastItem.offsetHeight }, e, lastDir as any);
|
|
189
|
+
}
|
|
190
|
+
if (nextFunc) {
|
|
191
|
+
nextFunc( { width: nextItem.offsetWidth, height: nextItem.offsetHeight }, e, nextDir as any);
|
|
192
|
+
}
|
|
193
|
+
this.setState({
|
|
194
|
+
isResizing: false,
|
|
195
|
+
curHandler: null
|
|
196
|
+
} as any);
|
|
197
|
+
this.unregisterEvents();
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
calculateSpace = () => {
|
|
201
|
+
const props = this.getProps();
|
|
202
|
+
const { direction } = props;
|
|
203
|
+
|
|
204
|
+
// calculate accurate space for group item
|
|
205
|
+
let handlerSizes = new Array(this._adapter.getHandlerCount()).fill(0);
|
|
206
|
+
let groupSize = direction === 'horizontal' ? this.groupRef.offsetWidth : this.groupRef.offsetHeight;
|
|
207
|
+
this.totalMinus = 0;
|
|
208
|
+
for (let i = 0; i < this._adapter.getHandlerCount(); i++) {
|
|
209
|
+
let handlerSize = direction === 'horizontal' ? this._adapter.getHandler(i).offsetWidth : this._adapter.getHandler(i).offsetHeight;
|
|
210
|
+
handlerSizes[i] = handlerSize;
|
|
211
|
+
this.totalMinus += handlerSize;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// allocate size for items which don't have default size
|
|
215
|
+
let totalSizePercent = 0;
|
|
216
|
+
let undefineLoc: Map<number, number> = new Map(), undefinedTotal = 0; // proportion
|
|
217
|
+
|
|
218
|
+
for (let i = 0; i < this._adapter.getItemCount(); i++) {
|
|
219
|
+
if (i === 0) {
|
|
220
|
+
this.itemMinusMap.set(i, handlerSizes[i] / 2);
|
|
221
|
+
} else if (i === this._adapter.getItemCount() - 1) {
|
|
222
|
+
this.itemMinusMap.set(i, handlerSizes[i - 1] / 2);
|
|
223
|
+
} else {
|
|
224
|
+
this.itemMinusMap.set(i, handlerSizes[i - 1] / 2 + handlerSizes[i] / 2);
|
|
225
|
+
}
|
|
226
|
+
const child = this._adapter.getItem(i);
|
|
227
|
+
let minSize = this._adapter.getItemMin(i), maxSize = this._adapter.getItemMax(i);
|
|
228
|
+
let minSizePercent = minSize ? getPixelSize(minSize, groupSize) / groupSize * 100 : 0,
|
|
229
|
+
maxSizePercent = maxSize ? getPixelSize(maxSize, groupSize) / groupSize * 100 : 100;
|
|
230
|
+
if (minSizePercent > maxSizePercent) {
|
|
231
|
+
console.warn('[Semi ResizableItem]: min size bigger than max size');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
let defaultSize = this._adapter.getItemDefaultSize(i);
|
|
235
|
+
if (defaultSize) {
|
|
236
|
+
let itemSizePercent: number;
|
|
237
|
+
if (typeof defaultSize === 'string') {
|
|
238
|
+
if (defaultSize.endsWith('%')) {
|
|
239
|
+
itemSizePercent = parseFloat(defaultSize.slice(0, -1));
|
|
240
|
+
} else if (defaultSize.endsWith('px')) {
|
|
241
|
+
itemSizePercent = parseFloat(defaultSize.slice(0, -2)) / groupSize * 100;
|
|
242
|
+
} else if (/^-?\d+(\.\d+)?$/.test(defaultSize)) {
|
|
243
|
+
// 仅由数字组成,表示按比例分配剩下空间
|
|
244
|
+
undefineLoc.set(i, parseFloat(defaultSize));
|
|
245
|
+
undefinedTotal += parseFloat(defaultSize);
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
} else {
|
|
249
|
+
undefineLoc.set(i, defaultSize);
|
|
250
|
+
undefinedTotal += defaultSize;
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
totalSizePercent += itemSizePercent;
|
|
256
|
+
|
|
257
|
+
if (direction === 'horizontal') {
|
|
258
|
+
child.style.width = `calc(${itemSizePercent}% - ${this.itemMinusMap.get(i)}px)`;
|
|
259
|
+
} else {
|
|
260
|
+
child.style.height = `calc(${itemSizePercent}% - ${this.itemMinusMap.get(i)}px)`;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (itemSizePercent < minSizePercent) {
|
|
264
|
+
console.warn('[Semi ResizableGroup]: item size smaller than min size');
|
|
265
|
+
}
|
|
266
|
+
if (itemSizePercent > maxSizePercent) {
|
|
267
|
+
console.warn('[Semi ResizableGroup]: item size bigger than max size');
|
|
268
|
+
}
|
|
269
|
+
} else {
|
|
270
|
+
undefineLoc.set(i, 1);
|
|
271
|
+
undefinedTotal += 1;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
let undefineSizePercent = 100 - totalSizePercent;
|
|
275
|
+
if (totalSizePercent > 100) {
|
|
276
|
+
console.warn('[Semi ResizableGroup]: total Size bigger than 100%');
|
|
277
|
+
undefineSizePercent = 10; // 如果总和超过100%,则保留10%的空间均分给未定义的item
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
undefineLoc.forEach((value, key) => {
|
|
281
|
+
const child = this._adapter.getItem(key);
|
|
282
|
+
if (direction === 'horizontal') {
|
|
283
|
+
child.style.width = `calc(${undefineSizePercent / undefinedTotal * value}% - ${this.itemMinusMap.get(key)}px)`;
|
|
284
|
+
} else {
|
|
285
|
+
child.style.height = `calc(${undefineSizePercent / undefinedTotal * value}% - ${this.itemMinusMap.get(key)}px)`;
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
destroy(): void {
|
|
291
|
+
|
|
292
|
+
}
|
|
293
|
+
}
|