feffery_utils_components 0.2.0-rc8 → 0.2.0-rc9
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/DESCRIPTION +1 -1
- package/Project.toml +1 -1
- package/README.md +1 -1
- package/build/lib/feffery_utils_components/FefferyExecuteJs.py +21 -5
- package/build/lib/feffery_utils_components/FefferyRND.py +12 -3
- package/build/lib/feffery_utils_components/async-feffery_rnd.js +1 -1
- package/build/lib/feffery_utils_components/feffery_utils_components.min.js +2 -2
- package/build/lib/feffery_utils_components/metadata.json +83 -1
- package/build/lib/feffery_utils_components/package-info.json +1 -1
- package/feffery_utils_components/FefferyExecuteJs.py +21 -5
- package/feffery_utils_components/FefferyRND.py +12 -3
- package/feffery_utils_components/async-feffery_rnd.js +1 -1
- package/feffery_utils_components/async-feffery_rnd.js.LICENSE.txt +8 -0
- package/feffery_utils_components/feffery_utils_components.min.js +2 -2
- package/feffery_utils_components/metadata.json +83 -1
- package/feffery_utils_components/package-info.json +1 -1
- package/package.json +1 -1
- package/src/lib/components/FefferyExecuteJs.react.js +111 -10
- package/src/lib/components/draggable/FefferyRND.react.js +18 -1
- package/src/lib/fragments/draggable/FefferyRND.react.js +24 -4
- package/usage.py +46 -16
|
@@ -5262,6 +5262,31 @@
|
|
|
5262
5262
|
"required": false,
|
|
5263
5263
|
"description": "\u8bbe\u7f6e\u5f53\u524d\u7ec4\u4ef6\u5c3a\u5bf8\u8c03\u6574\u53ca\u62d6\u62fd\u7684\u5916\u8fb9\u754c\u7c7b\u578b\uff0c\u53ef\u9009\u7684\u6709'window'\u3001'parent'\r\n\u9ed8\u8ba4\u4e3a'window'"
|
|
5264
5264
|
},
|
|
5265
|
+
"selected": {
|
|
5266
|
+
"type": {
|
|
5267
|
+
"name": "bool"
|
|
5268
|
+
},
|
|
5269
|
+
"required": false,
|
|
5270
|
+
"description": "\u8bbe\u7f6e\u6216\u76d1\u542c\u5f53\u524d\u7ec4\u4ef6\u662f\u5426\u5904\u4e8e\u9009\u62e9\u72b6\u6001\r\n\u9ed8\u8ba4\uff1afalse",
|
|
5271
|
+
"defaultValue": {
|
|
5272
|
+
"value": "false",
|
|
5273
|
+
"computed": false
|
|
5274
|
+
}
|
|
5275
|
+
},
|
|
5276
|
+
"selectedStyle": {
|
|
5277
|
+
"type": {
|
|
5278
|
+
"name": "object"
|
|
5279
|
+
},
|
|
5280
|
+
"required": false,
|
|
5281
|
+
"description": "\u8bbe\u7f6e\u5f53\u524d\u7ec4\u4ef6\u5728\u9009\u4e2d\u72b6\u6001\u4e0b\u7684css\u6837\u5f0f"
|
|
5282
|
+
},
|
|
5283
|
+
"selectedClassName": {
|
|
5284
|
+
"type": {
|
|
5285
|
+
"name": "string"
|
|
5286
|
+
},
|
|
5287
|
+
"required": false,
|
|
5288
|
+
"description": "\u914d\u7f6e\u5f53\u524d\u7ec4\u4ef6\u5728\u9009\u4e2d\u72b6\u6001\u4e0b\u7684css\u7c7b\u540d"
|
|
5289
|
+
},
|
|
5265
5290
|
"setProps": {
|
|
5266
5291
|
"type": {
|
|
5267
5292
|
"name": "func"
|
|
@@ -7123,7 +7148,7 @@
|
|
|
7123
7148
|
}
|
|
7124
7149
|
},
|
|
7125
7150
|
"src/lib/components/FefferyExecuteJs.react.js": {
|
|
7126
|
-
"description": "",
|
|
7151
|
+
"description": "js\u76f4\u63a5\u6267\u884c\u7ec4\u4ef6FefferyExecuteJs",
|
|
7127
7152
|
"displayName": "FefferyExecuteJs",
|
|
7128
7153
|
"methods": [],
|
|
7129
7154
|
"props": {
|
|
@@ -7141,6 +7166,63 @@
|
|
|
7141
7166
|
"required": false,
|
|
7142
7167
|
"description": "\u8bbe\u7f6e\u8981\u6267\u884c\u7684js\u4ee3\u7801\u5b57\u7b26\u4e32"
|
|
7143
7168
|
},
|
|
7169
|
+
"mode": {
|
|
7170
|
+
"type": {
|
|
7171
|
+
"name": "enum",
|
|
7172
|
+
"value": [
|
|
7173
|
+
{
|
|
7174
|
+
"value": "'default'",
|
|
7175
|
+
"computed": false
|
|
7176
|
+
},
|
|
7177
|
+
{
|
|
7178
|
+
"value": "'delay'",
|
|
7179
|
+
"computed": false
|
|
7180
|
+
},
|
|
7181
|
+
{
|
|
7182
|
+
"value": "'interval'",
|
|
7183
|
+
"computed": false
|
|
7184
|
+
},
|
|
7185
|
+
{
|
|
7186
|
+
"value": "'wait-until-element-rendered'",
|
|
7187
|
+
"computed": false
|
|
7188
|
+
}
|
|
7189
|
+
]
|
|
7190
|
+
},
|
|
7191
|
+
"required": false,
|
|
7192
|
+
"description": "\u8bbe\u7f6e\u6267\u884c\u6a21\u5f0f\uff0c\u53ef\u9009\u7684\u6709'default'\uff08\u7acb\u5373\u6267\u884c\uff09\u3001'delay'\uff08\u5ef6\u8fdf\u6267\u884c\uff09\u3001'interval'\uff08\u5b9a\u65f6\u8f6e\u8be2\u6267\u884c\uff09\u3001'wait-until-element-rendered'\uff08\u7b49\u5f85\u76ee\u6807\u5143\u7d20\u6e32\u67d3\u540e\u6267\u884c\uff09\r\n\u9ed8\u8ba4\uff1a'default'",
|
|
7193
|
+
"defaultValue": {
|
|
7194
|
+
"value": "'default'",
|
|
7195
|
+
"computed": false
|
|
7196
|
+
}
|
|
7197
|
+
},
|
|
7198
|
+
"delay": {
|
|
7199
|
+
"type": {
|
|
7200
|
+
"name": "number"
|
|
7201
|
+
},
|
|
7202
|
+
"required": false,
|
|
7203
|
+
"description": "delay\u6a21\u5f0f\u4e0b\uff0c\u8bbe\u7f6e\u5ef6\u65f6\u6267\u884c\u65f6\u957f\uff0c\u5355\u4f4d\uff1a\u6beb\u79d2"
|
|
7204
|
+
},
|
|
7205
|
+
"interval": {
|
|
7206
|
+
"type": {
|
|
7207
|
+
"name": "number"
|
|
7208
|
+
},
|
|
7209
|
+
"required": false,
|
|
7210
|
+
"description": "interval\u6a21\u5f0f\u4e0b\uff0c\u8bbe\u7f6e\u8f6e\u8be2\u6267\u884c\u95f4\u9694\u65f6\u957f\uff0c\u5355\u4f4d\uff1a\u6beb\u79d2"
|
|
7211
|
+
},
|
|
7212
|
+
"targetSelector": {
|
|
7213
|
+
"type": {
|
|
7214
|
+
"name": "string"
|
|
7215
|
+
},
|
|
7216
|
+
"required": false,
|
|
7217
|
+
"description": "wait-until-element-rendered\u6a21\u5f0f\u4e0b\uff0c\u8bbe\u7f6e\u9700\u8981\u7b49\u5f85\u6e32\u67d3\u5b8c\u6210\u7684\u76ee\u6807\u5143\u7d20css\u9009\u62e9\u5668"
|
|
7218
|
+
},
|
|
7219
|
+
"targetWaitTimeout": {
|
|
7220
|
+
"type": {
|
|
7221
|
+
"name": "number"
|
|
7222
|
+
},
|
|
7223
|
+
"required": false,
|
|
7224
|
+
"description": "wait-until-element-rendered\u6a21\u5f0f\u4e0b\uff0c\u8bbe\u7f6e\u76ee\u6807\u5143\u7d20\u6e32\u67d3\u68c0\u6d4b\u6700\u5927\u7b49\u5f85\u65f6\u957f\uff0c\u5355\u4f4d\uff1a\u6beb\u79d2\uff0c\u9ed8\u8ba4\u65e0\u9650\u5236"
|
|
7225
|
+
},
|
|
7144
7226
|
"loading_state": {
|
|
7145
7227
|
"type": {
|
|
7146
7228
|
"name": "shape",
|
package/package.json
CHANGED
|
@@ -1,25 +1,99 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* js直接执行组件FefferyExecuteJs
|
|
6
|
+
*/
|
|
5
7
|
const FefferyExecuteJs = (props) => {
|
|
6
8
|
// 取得必要属性或参数
|
|
7
9
|
const {
|
|
8
|
-
id,
|
|
9
10
|
jsString,
|
|
11
|
+
mode,
|
|
12
|
+
delay,
|
|
13
|
+
interval,
|
|
14
|
+
targetSelector,
|
|
15
|
+
targetWaitTimeout,
|
|
10
16
|
setProps,
|
|
11
17
|
loading_state
|
|
12
18
|
} = props;
|
|
13
19
|
|
|
14
20
|
useEffect(() => {
|
|
15
|
-
//
|
|
16
|
-
if (
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
// delay模式
|
|
22
|
+
if (mode === 'delay') {
|
|
23
|
+
// 延时执行原生js程序
|
|
24
|
+
if (jsString) {
|
|
25
|
+
setTimeout(
|
|
26
|
+
() => {
|
|
27
|
+
try { eval(jsString) }
|
|
28
|
+
catch (exception) { console.error(exception) }
|
|
29
|
+
// 重置jsString
|
|
30
|
+
setProps({
|
|
31
|
+
jsString: null
|
|
32
|
+
})
|
|
33
|
+
},
|
|
34
|
+
delay
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
} else if (mode === 'interval') {
|
|
38
|
+
// 定时执行原生js程序
|
|
39
|
+
if (jsString) {
|
|
40
|
+
// 创建轮询器
|
|
41
|
+
const _interval = setInterval(
|
|
42
|
+
() => {
|
|
43
|
+
try { eval(jsString) }
|
|
44
|
+
catch (exception) { console.error(exception) }
|
|
45
|
+
},
|
|
46
|
+
interval
|
|
47
|
+
)
|
|
48
|
+
// jsString更新或组件卸载时,销毁轮询器
|
|
49
|
+
return () => clearInterval(_interval);
|
|
50
|
+
}
|
|
51
|
+
} else if (mode === 'wait-until-element-rendered') {
|
|
52
|
+
// 等待目标元素渲染后执行
|
|
53
|
+
if (jsString) {
|
|
54
|
+
// 记录逻辑开始时间戳
|
|
55
|
+
const startTime = Date.now()
|
|
56
|
+
|
|
57
|
+
// 创建定时器
|
|
58
|
+
let _interval = setInterval(
|
|
59
|
+
() => {
|
|
60
|
+
// 若目标元素出现
|
|
61
|
+
if (document.querySelector(targetSelector)) {
|
|
62
|
+
clearInterval(_interval)
|
|
63
|
+
_interval = false;
|
|
64
|
+
try { eval(jsString) }
|
|
65
|
+
catch (exception) { console.error(exception) }
|
|
66
|
+
// 重置jsString
|
|
67
|
+
setProps({
|
|
68
|
+
jsString: null
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
// 若距离startTime时长超出targetWaitTimeout限制,则强制终止轮询检查过程
|
|
72
|
+
if (targetWaitTimeout && Date.now() - startTime > targetWaitTimeout) {
|
|
73
|
+
clearInterval(_interval)
|
|
74
|
+
_interval = false;
|
|
75
|
+
// 重置jsString
|
|
76
|
+
setProps({
|
|
77
|
+
jsString: null
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
200 // 默认200毫秒检测一次目标元素出现情况
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
// 若jsString更新或组件卸载时,轮询器仍然未被清除,则进行清除
|
|
85
|
+
return () => !_interval && clearInterval(_interval)
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
// 执行原生js程序
|
|
89
|
+
if (jsString) {
|
|
90
|
+
try { eval(jsString) }
|
|
91
|
+
catch (exception) { console.error(exception) }
|
|
92
|
+
// 重置jsString
|
|
93
|
+
setProps({
|
|
94
|
+
jsString: null
|
|
95
|
+
})
|
|
96
|
+
}
|
|
23
97
|
}
|
|
24
98
|
}, [jsString])
|
|
25
99
|
|
|
@@ -39,6 +113,32 @@ FefferyExecuteJs.propTypes = {
|
|
|
39
113
|
*/
|
|
40
114
|
jsString: PropTypes.string,
|
|
41
115
|
|
|
116
|
+
/**
|
|
117
|
+
* 设置执行模式,可选的有'default'(立即执行)、'delay'(延迟执行)、'interval'(定时轮询执行)、'wait-until-element-rendered'(等待目标元素渲染后执行)
|
|
118
|
+
* 默认:'default'
|
|
119
|
+
*/
|
|
120
|
+
mode: PropTypes.oneOf(['default', 'delay', 'interval', 'wait-until-element-rendered']),
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* delay模式下,设置延时执行时长,单位:毫秒
|
|
124
|
+
*/
|
|
125
|
+
delay: PropTypes.number,
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* interval模式下,设置轮询执行间隔时长,单位:毫秒
|
|
129
|
+
*/
|
|
130
|
+
interval: PropTypes.number,
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* wait-until-element-rendered模式下,设置需要等待渲染完成的目标元素css选择器
|
|
134
|
+
*/
|
|
135
|
+
targetSelector: PropTypes.string,
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* wait-until-element-rendered模式下,设置目标元素渲染检测最大等待时长,单位:毫秒,默认无限制
|
|
139
|
+
*/
|
|
140
|
+
targetWaitTimeout: PropTypes.number,
|
|
141
|
+
|
|
42
142
|
loading_state: PropTypes.shape({
|
|
43
143
|
/**
|
|
44
144
|
* Determines if the component is loading or not
|
|
@@ -63,6 +163,7 @@ FefferyExecuteJs.propTypes = {
|
|
|
63
163
|
|
|
64
164
|
// 设置默认参数
|
|
65
165
|
FefferyExecuteJs.defaultProps = {
|
|
166
|
+
mode: 'default'
|
|
66
167
|
}
|
|
67
168
|
|
|
68
169
|
export default FefferyExecuteJs;
|
|
@@ -191,6 +191,22 @@ FefferyRND.propTypes = {
|
|
|
191
191
|
*/
|
|
192
192
|
bounds: PropTypes.oneOf(['window', 'parent']),
|
|
193
193
|
|
|
194
|
+
/**
|
|
195
|
+
* 设置或监听当前组件是否处于选择状态
|
|
196
|
+
* 默认:false
|
|
197
|
+
*/
|
|
198
|
+
selected: PropTypes.bool,
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* 设置当前组件在选中状态下的css样式
|
|
202
|
+
*/
|
|
203
|
+
selectedStyle: PropTypes.object,
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* 配置当前组件在选中状态下的css类名
|
|
207
|
+
*/
|
|
208
|
+
selectedClassName: PropTypes.string,
|
|
209
|
+
|
|
194
210
|
/**
|
|
195
211
|
* Dash-assigned callback that should be called to report property changes
|
|
196
212
|
* to Dash, to make them available for callbacks.
|
|
@@ -215,7 +231,8 @@ FefferyRND.propTypes = {
|
|
|
215
231
|
|
|
216
232
|
// 设置默认参数
|
|
217
233
|
FefferyRND.defaultProps = {
|
|
218
|
-
direction: ['top', 'right', 'bottom', 'left', 'topRight', 'bottomRight', 'bottomLeft', 'topLeft']
|
|
234
|
+
direction: ['top', 'right', 'bottom', 'left', 'topRight', 'bottomRight', 'bottomLeft', 'topLeft'],
|
|
235
|
+
selected: false
|
|
219
236
|
}
|
|
220
237
|
|
|
221
238
|
export default FefferyRND;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
2
|
import { Rnd } from 'react-rnd';
|
|
3
3
|
import { propTypes, defaultProps } from '../../components/draggable/FefferyRND.react';
|
|
4
4
|
import { clone } from 'lodash';
|
|
@@ -28,10 +28,16 @@ const FefferyRND = (props) => {
|
|
|
28
28
|
disableDragging,
|
|
29
29
|
dragAxis,
|
|
30
30
|
bounds,
|
|
31
|
+
selected,
|
|
32
|
+
selectedStyle,
|
|
33
|
+
selectedClassName,
|
|
31
34
|
setProps,
|
|
32
35
|
loading_state
|
|
33
36
|
} = props;
|
|
34
37
|
|
|
38
|
+
// 记录拖拽或尺寸调整结束事件时间戳
|
|
39
|
+
const [dragOrResizeStopTimestamp, setDragOrResizeStopTimestamp] = useState(0);
|
|
40
|
+
|
|
35
41
|
useEffect(() => {
|
|
36
42
|
// size缺省且defaultState.width,defaultState.height有效时,进行赋值
|
|
37
43
|
if (!size && defaultState.width && defaultState.height) {
|
|
@@ -74,8 +80,8 @@ const FefferyRND = (props) => {
|
|
|
74
80
|
|
|
75
81
|
return (
|
|
76
82
|
<Rnd id={id}
|
|
77
|
-
style={style}
|
|
78
|
-
className={className}
|
|
83
|
+
style={{ ...style, ...(selected ? selectedStyle : {}) }}
|
|
84
|
+
className={(selected && selectedClassName) ? className + ' ' + selectedClassName : className}
|
|
79
85
|
default={defaultState}
|
|
80
86
|
size={size}
|
|
81
87
|
position={position}
|
|
@@ -92,8 +98,15 @@ const FefferyRND = (props) => {
|
|
|
92
98
|
disableDragging={disableDragging}
|
|
93
99
|
dragAxis={dragAxis}
|
|
94
100
|
bounds={bounds}
|
|
95
|
-
onDragStop={(e, d) =>
|
|
101
|
+
onDragStop={(e, d) => {
|
|
102
|
+
// 若本次拖拽事件导致了有效偏移,则更新拖拽结束事件时间戳
|
|
103
|
+
if (position && (position.x !== d.x || position.y !== d.y)) {
|
|
104
|
+
setDragOrResizeStopTimestamp(new Date().getTime());
|
|
105
|
+
}
|
|
106
|
+
setProps({ position: { x: d.x, y: d.y } })
|
|
107
|
+
}}
|
|
96
108
|
onResizeStop={(e, direction, ref, delta, p) => {
|
|
109
|
+
setDragOrResizeStopTimestamp(new Date().getTime());
|
|
97
110
|
setProps({
|
|
98
111
|
size: {
|
|
99
112
|
width: ref.style.width,
|
|
@@ -105,6 +118,13 @@ const FefferyRND = (props) => {
|
|
|
105
118
|
}
|
|
106
119
|
})
|
|
107
120
|
}}
|
|
121
|
+
onClick={() => {
|
|
122
|
+
// 若距离最近一次拖拽结束事件时间戳大于200ms,则切换选中状态
|
|
123
|
+
// 从而避免拖拽导致的选中误操作
|
|
124
|
+
if (new Date().getTime() - dragOrResizeStopTimestamp >= 200) {
|
|
125
|
+
setProps({ selected: !selected })
|
|
126
|
+
}
|
|
127
|
+
}}
|
|
108
128
|
data-dash-is-loading={
|
|
109
129
|
(loading_state && loading_state.is_loading) || undefined
|
|
110
130
|
}>
|
package/usage.py
CHANGED
|
@@ -1,33 +1,63 @@
|
|
|
1
1
|
import dash
|
|
2
|
+
import json
|
|
2
3
|
from dash import html
|
|
3
4
|
import feffery_utils_components as fuc
|
|
5
|
+
from dash.dependencies import Input, Output
|
|
4
6
|
|
|
5
|
-
app = dash.Dash(__name__
|
|
7
|
+
app = dash.Dash(__name__)
|
|
6
8
|
|
|
7
9
|
app.layout = html.Div(
|
|
8
10
|
[
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
style={
|
|
14
|
-
'width': 300
|
|
15
|
-
}
|
|
11
|
+
# wait-until-element-rendered模式示例
|
|
12
|
+
html.Button(
|
|
13
|
+
'wait-until-element-rendered模式',
|
|
14
|
+
id='execute-js'
|
|
16
15
|
),
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
16
|
+
# 控制目标元素渲染
|
|
17
|
+
html.Button(
|
|
18
|
+
'渲染目标元素',
|
|
19
|
+
id='render-target-element'
|
|
20
|
+
),
|
|
21
|
+
html.Div(
|
|
22
|
+
id='execute-js-output'
|
|
23
|
+
),
|
|
24
|
+
html.Div(
|
|
25
|
+
id='target-element-container'
|
|
24
26
|
)
|
|
25
27
|
],
|
|
26
28
|
style={
|
|
27
|
-
'padding': '50px
|
|
29
|
+
'padding': '50px 50px 0 50px'
|
|
28
30
|
}
|
|
29
31
|
)
|
|
30
32
|
|
|
31
33
|
|
|
34
|
+
@app.callback(
|
|
35
|
+
Output('target-element-container', 'children'),
|
|
36
|
+
Input('render-target-element', 'n_clicks'),
|
|
37
|
+
prevent_initial_call=True
|
|
38
|
+
)
|
|
39
|
+
def render_target_element(n_clicks):
|
|
40
|
+
|
|
41
|
+
return html.Span(
|
|
42
|
+
'我来也!',
|
|
43
|
+
id='target-element'
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@app.callback(
|
|
48
|
+
Output('execute-js-output', 'children'),
|
|
49
|
+
Input('execute-js', 'n_clicks'),
|
|
50
|
+
prevent_initial_call=True
|
|
51
|
+
)
|
|
52
|
+
def handle_execute_js(n_clicks):
|
|
53
|
+
|
|
54
|
+
return fuc.FefferyExecuteJs(
|
|
55
|
+
jsString="alert('目标元素出现!')",
|
|
56
|
+
mode='wait-until-element-rendered',
|
|
57
|
+
targetSelector='#target-element',
|
|
58
|
+
targetWaitTimeout=5000 # 至多等待5秒
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
32
62
|
if __name__ == '__main__':
|
|
33
63
|
app.run(debug=True)
|