feffery_utils_components 0.1.21 → 0.1.23
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/NAMESPACE +4 -1
- package/Project.toml +1 -1
- package/build/lib/feffery_utils_components/FefferyCountUp.py +68 -0
- package/build/lib/feffery_utils_components/FefferyDiv.py +13 -25
- package/build/lib/feffery_utils_components/FefferyListenUnload.py +43 -0
- package/build/lib/feffery_utils_components/FefferyMotion.py +5 -3
- package/build/lib/feffery_utils_components/FefferyUnmount.py +45 -0
- package/build/lib/feffery_utils_components/_imports_.py +4 -0
- package/build/lib/feffery_utils_components/feffery_utils_components.min.js +4 -4
- package/build/lib/feffery_utils_components/metadata.json +216 -39
- package/build/lib/feffery_utils_components/package-info.json +3 -2
- package/feffery_utils_components/FefferyCountUp.py +68 -0
- package/feffery_utils_components/FefferyDiv.py +13 -25
- package/feffery_utils_components/FefferyListenUnload.py +43 -0
- package/feffery_utils_components/FefferyMotion.py +5 -3
- package/feffery_utils_components/FefferyUnmount.py +45 -0
- package/feffery_utils_components/_imports_.py +4 -0
- package/feffery_utils_components/feffery_utils_components.min.js +4 -4
- package/feffery_utils_components/metadata.json +216 -39
- package/feffery_utils_components/package-info.json +3 -2
- package/package.json +3 -2
- package/src/FefferyUtilsComponents.jl +5 -3
- package/src/jl/''_fefferycountup.jl +34 -0
- package/src/jl/''_fefferydiv.jl +6 -12
- package/src/jl/''_fefferylistenunload.jl +24 -0
- package/src/jl/''_fefferymotion.jl +2 -1
- package/src/jl/''_fefferyunmount.jl +31 -0
- package/src/lib/components/FefferyCountUp.react.js +116 -0
- package/src/lib/components/FefferyDiv.react.js +10 -69
- package/src/lib/components/animations/FefferyMotion.react.js +4 -0
- package/src/lib/components/listeners/FefferyListenUnload.react.js +68 -0
- package/src/lib/index.js +5 -1
- package/usage.py +16 -98
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
import CountUp from 'react-countup';
|
|
3
|
+
|
|
4
|
+
// 定义数字递增组件FefferyCountUp
|
|
5
|
+
const FefferyCountUp = (props) => {
|
|
6
|
+
// 取得必要属性或参数
|
|
7
|
+
const {
|
|
8
|
+
id,
|
|
9
|
+
className,
|
|
10
|
+
style,
|
|
11
|
+
key,
|
|
12
|
+
end,
|
|
13
|
+
start,
|
|
14
|
+
duration,
|
|
15
|
+
decimals,
|
|
16
|
+
enableScrollSpy,
|
|
17
|
+
scrollSpyDelay,
|
|
18
|
+
scrollSpyOnce,
|
|
19
|
+
separator,
|
|
20
|
+
setProps,
|
|
21
|
+
loading_state
|
|
22
|
+
} = props;
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<CountUp
|
|
26
|
+
id={id}
|
|
27
|
+
className={className}
|
|
28
|
+
style={style}
|
|
29
|
+
key={key}
|
|
30
|
+
end={end}
|
|
31
|
+
start={start}
|
|
32
|
+
duration={duration}
|
|
33
|
+
decimals={decimals}
|
|
34
|
+
enableScrollSpy={enableScrollSpy}
|
|
35
|
+
scrollSpyDelay={scrollSpyDelay}
|
|
36
|
+
scrollSpyOnce={scrollSpyOnce}
|
|
37
|
+
separator={separator}
|
|
38
|
+
data-dash-is-loading={
|
|
39
|
+
(loading_state && loading_state.is_loading) || undefined
|
|
40
|
+
} />
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
// 定义参数或属性
|
|
46
|
+
FefferyCountUp.propTypes = {
|
|
47
|
+
// 部件id
|
|
48
|
+
id: PropTypes.string,
|
|
49
|
+
|
|
50
|
+
className: PropTypes.string,
|
|
51
|
+
|
|
52
|
+
style: PropTypes.object,
|
|
53
|
+
|
|
54
|
+
key: PropTypes.string,
|
|
55
|
+
|
|
56
|
+
// 设置数字递增目标,必填
|
|
57
|
+
// 对此参数的更新会重新触发递增动画
|
|
58
|
+
end: PropTypes.number.isRequired,
|
|
59
|
+
|
|
60
|
+
// 设置数字递增起点,默认为0
|
|
61
|
+
// 对此参数的更新会重新触发递增动画
|
|
62
|
+
start: PropTypes.number,
|
|
63
|
+
|
|
64
|
+
// 设置数字递增动画耗时,单位:秒,默认为2
|
|
65
|
+
// 对此参数的更新会重新触发递增动画
|
|
66
|
+
duration: PropTypes.number,
|
|
67
|
+
|
|
68
|
+
// 设置小数精度,默认为0
|
|
69
|
+
decimals: PropTypes.number,
|
|
70
|
+
|
|
71
|
+
// 设置是否在当前元素进入视口后才开始执行递增动画,默认为true
|
|
72
|
+
enableScrollSpy: PropTypes.bool,
|
|
73
|
+
|
|
74
|
+
// 当enableScrollSpy为true时,设置当前元素进入视口后延时多久开始执行递增动画,单位:毫秒,默认为0
|
|
75
|
+
scrollSpyDelay: PropTypes.number,
|
|
76
|
+
|
|
77
|
+
// 设置是否仅进行一次视口出现后启用动画行为,默认为true
|
|
78
|
+
scrollSpyOnce: PropTypes.bool,
|
|
79
|
+
|
|
80
|
+
// 设置自定义千分符,默认为','
|
|
81
|
+
separator: PropTypes.string,
|
|
82
|
+
|
|
83
|
+
loading_state: PropTypes.shape({
|
|
84
|
+
/**
|
|
85
|
+
* Determines if the component is loading or not
|
|
86
|
+
*/
|
|
87
|
+
is_loading: PropTypes.bool,
|
|
88
|
+
/**
|
|
89
|
+
* Holds which property is loading
|
|
90
|
+
*/
|
|
91
|
+
prop_name: PropTypes.string,
|
|
92
|
+
/**
|
|
93
|
+
* Holds the name of the component that is loading
|
|
94
|
+
*/
|
|
95
|
+
component_name: PropTypes.string
|
|
96
|
+
}),
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Dash-assigned callback that should be called to report property changes
|
|
100
|
+
* to Dash, to make them available for callbacks.
|
|
101
|
+
*/
|
|
102
|
+
setProps: PropTypes.func,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// 设置默认参数
|
|
106
|
+
FefferyCountUp.defaultProps = {
|
|
107
|
+
start: 0,
|
|
108
|
+
duration: 2,
|
|
109
|
+
decimals: 0,
|
|
110
|
+
enableScrollSpy: true,
|
|
111
|
+
scrollSpyDelay: 0,
|
|
112
|
+
scrollSpyOnce: true,
|
|
113
|
+
separator: ','
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export default FefferyCountUp;
|
|
@@ -74,10 +74,6 @@ const FefferyDiv = (props) => {
|
|
|
74
74
|
enableListenContextMenu,
|
|
75
75
|
debounceWait,
|
|
76
76
|
clickAwayCount,
|
|
77
|
-
appendChild,
|
|
78
|
-
insertChild,
|
|
79
|
-
replaceChild,
|
|
80
|
-
deleteChildIndex,
|
|
81
77
|
shadow,
|
|
82
78
|
scrollbar,
|
|
83
79
|
enableClickAway,
|
|
@@ -89,46 +85,6 @@ const FefferyDiv = (props) => {
|
|
|
89
85
|
const size = useSize(ref);
|
|
90
86
|
const _isHovering = useHover(ref);
|
|
91
87
|
|
|
92
|
-
// 快捷children数组增删操作
|
|
93
|
-
useEffect(() => {
|
|
94
|
-
if (children && appendChild) {
|
|
95
|
-
setProps({
|
|
96
|
-
children: children.concat(appendChild),
|
|
97
|
-
appendChild: null // 重置
|
|
98
|
-
})
|
|
99
|
-
}
|
|
100
|
-
}, [appendChild])
|
|
101
|
-
|
|
102
|
-
useEffect(() => {
|
|
103
|
-
if (children && insertChild && insertChild.index && insertChild.element) {
|
|
104
|
-
setProps({
|
|
105
|
-
children: children.slice(0, insertChild.index)
|
|
106
|
-
.concat([insertChild.element])
|
|
107
|
-
.concat(children.slice(insertChild.index)),
|
|
108
|
-
insertChild: null // 重置
|
|
109
|
-
})
|
|
110
|
-
}
|
|
111
|
-
}, [insertChild])
|
|
112
|
-
|
|
113
|
-
useEffect(() => {
|
|
114
|
-
if (children && replaceChild && replaceChild.index && replaceChild.element) {
|
|
115
|
-
children[replaceChild.index] = replaceChild.element
|
|
116
|
-
setProps({
|
|
117
|
-
children: children,
|
|
118
|
-
replaceChild: null // 重置
|
|
119
|
-
})
|
|
120
|
-
}
|
|
121
|
-
}, [replaceChild])
|
|
122
|
-
|
|
123
|
-
useEffect(() => {
|
|
124
|
-
if (children && (deleteChildIndex || deleteChildIndex === 0)) {
|
|
125
|
-
setProps({
|
|
126
|
-
children: children.filter((_, i) => i !== deleteChildIndex),
|
|
127
|
-
deleteChildIndex: null // 重置
|
|
128
|
-
})
|
|
129
|
-
}
|
|
130
|
-
}, [deleteChildIndex])
|
|
131
|
-
|
|
132
88
|
// 防抖更新容器尺寸
|
|
133
89
|
const { run: updateWidthHeight } = useRequest(
|
|
134
90
|
(e) => {
|
|
@@ -259,29 +215,6 @@ FefferyDiv.propTypes = {
|
|
|
259
215
|
|
|
260
216
|
children: PropTypes.node,
|
|
261
217
|
|
|
262
|
-
// 快捷children数组增删参数,在有效值传入促使组件更新后会自动重置为undefined
|
|
263
|
-
// 用于快捷向children数组末尾追加新元素
|
|
264
|
-
appendChild: PropTypes.node,
|
|
265
|
-
|
|
266
|
-
// 用于快捷在原children数组第index个位置插入新元素
|
|
267
|
-
insertChild: PropTypes.exact({
|
|
268
|
-
// 要插入的位序
|
|
269
|
-
index: PropTypes.number,
|
|
270
|
-
// 要插入的元素
|
|
271
|
-
element: PropTypes.node
|
|
272
|
-
}),
|
|
273
|
-
|
|
274
|
-
// 用于快捷对children数组第index个位置的元素进行替换
|
|
275
|
-
replaceChild: PropTypes.exact({
|
|
276
|
-
// 要替换元素的位序
|
|
277
|
-
index: PropTypes.number,
|
|
278
|
-
// 要替换的新元素
|
|
279
|
-
element: PropTypes.node
|
|
280
|
-
}),
|
|
281
|
-
|
|
282
|
-
// 用于快捷删除原children第index个位置的元素
|
|
283
|
-
deleteChildIndex: PropTypes.number,
|
|
284
|
-
|
|
285
218
|
style: PropTypes.object,
|
|
286
219
|
|
|
287
220
|
className: PropTypes.oneOfType([
|
|
@@ -316,10 +249,18 @@ FefferyDiv.propTypes = {
|
|
|
316
249
|
|
|
317
250
|
// 监听右键事件
|
|
318
251
|
contextMenuEvent: PropTypes.exact({
|
|
319
|
-
//
|
|
252
|
+
// 以页面整体左上角为原点,记录x坐标
|
|
320
253
|
pageX: PropTypes.number,
|
|
321
|
-
//
|
|
254
|
+
// 以页面整体左上角为原点,记录y坐标
|
|
322
255
|
pageY: PropTypes.number,
|
|
256
|
+
// 以浏览器窗口左上角为原点,记录x坐标
|
|
257
|
+
clientX: PropTypes.number,
|
|
258
|
+
// 以浏览器窗口左上角为原点,记录y坐标
|
|
259
|
+
clientY: PropTypes.number,
|
|
260
|
+
// 以屏幕左上角为原点,记录x坐标
|
|
261
|
+
screenX: PropTypes.number,
|
|
262
|
+
// 以屏幕左上角为原点,记录y坐标
|
|
263
|
+
screenY: PropTypes.number,
|
|
323
264
|
// 点击事件对应的时间戳
|
|
324
265
|
timestamp: PropTypes.number
|
|
325
266
|
}),
|
|
@@ -20,6 +20,7 @@ const FefferyMotion = (props) => {
|
|
|
20
20
|
children,
|
|
21
21
|
style,
|
|
22
22
|
className,
|
|
23
|
+
key,
|
|
23
24
|
initial,
|
|
24
25
|
animate,
|
|
25
26
|
exit,
|
|
@@ -47,6 +48,7 @@ const FefferyMotion = (props) => {
|
|
|
47
48
|
(className ? useCss(className) : undefined)
|
|
48
49
|
}
|
|
49
50
|
style={style}
|
|
51
|
+
key={key}
|
|
50
52
|
initial={initial}
|
|
51
53
|
animate={animate}
|
|
52
54
|
exit={exit}
|
|
@@ -78,6 +80,8 @@ FefferyMotion.propTypes = {
|
|
|
78
80
|
// css类名
|
|
79
81
|
className: PropTypes.string,
|
|
80
82
|
|
|
83
|
+
key: PropTypes.string,
|
|
84
|
+
|
|
81
85
|
// 设置当前组件初始化时的样式
|
|
82
86
|
initial: PropTypes.oneOfType([
|
|
83
87
|
PropTypes.object,
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
|
|
4
|
+
// 定义页面关闭监听组件FefferyListenUnload
|
|
5
|
+
const FefferyListenUnload = (props) => {
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
id,
|
|
9
|
+
setProps,
|
|
10
|
+
loading_state
|
|
11
|
+
} = props;
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
const handleTabClose = (e) => {
|
|
15
|
+
setProps({
|
|
16
|
+
unloaded: true
|
|
17
|
+
})
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
window.addEventListener('beforeunload', handleTabClose);
|
|
21
|
+
|
|
22
|
+
return () => {
|
|
23
|
+
window.removeEventListener('beforeunload', handleTabClose);
|
|
24
|
+
};
|
|
25
|
+
}, []);
|
|
26
|
+
|
|
27
|
+
return (<div
|
|
28
|
+
id={id}
|
|
29
|
+
data-dash-is-loading={
|
|
30
|
+
(loading_state && loading_state.is_loading) || undefined
|
|
31
|
+
} />);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 定义参数或属性
|
|
35
|
+
FefferyListenUnload.propTypes = {
|
|
36
|
+
// 部件id
|
|
37
|
+
id: PropTypes.string,
|
|
38
|
+
|
|
39
|
+
// 每次页面关闭时会触发更新为true
|
|
40
|
+
unloaded: PropTypes.bool,
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Dash-assigned callback that should be called to report property changes
|
|
44
|
+
* to Dash, to make them available for callbacks.
|
|
45
|
+
*/
|
|
46
|
+
setProps: PropTypes.func,
|
|
47
|
+
|
|
48
|
+
loading_state: PropTypes.shape({
|
|
49
|
+
/**
|
|
50
|
+
* Determines if the component is loading or not
|
|
51
|
+
*/
|
|
52
|
+
is_loading: PropTypes.bool,
|
|
53
|
+
/**
|
|
54
|
+
* Holds which property is loading
|
|
55
|
+
*/
|
|
56
|
+
prop_name: PropTypes.string,
|
|
57
|
+
/**
|
|
58
|
+
* Holds the name of the component that is loading
|
|
59
|
+
*/
|
|
60
|
+
component_name: PropTypes.string
|
|
61
|
+
})
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// 设置默认参数
|
|
65
|
+
FefferyListenUnload.defaultProps = {
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export default FefferyListenUnload;
|
package/src/lib/index.js
CHANGED
|
@@ -55,6 +55,8 @@ import FefferyFullscreen from "./components/FefferyFullscreen.react";
|
|
|
55
55
|
import FefferyDeviceDetect from "./components/listeners/FefferyDeviceDetect.react";
|
|
56
56
|
import FefferyMotion from "./components/animations/FefferyMotion.react";
|
|
57
57
|
import FefferyAutoAnimate from "./components/animations/FefferyAutoAnimate.react";
|
|
58
|
+
import FefferyCountUp from "./components/FefferyCountUp.react";
|
|
59
|
+
import FefferyListenUnload from "./components/listeners/FefferyListenUnload.react";
|
|
58
60
|
|
|
59
61
|
/*
|
|
60
62
|
忽略部分设计React中规范的console警告信息
|
|
@@ -144,5 +146,7 @@ export {
|
|
|
144
146
|
FefferyFullscreen,
|
|
145
147
|
FefferyDeviceDetect,
|
|
146
148
|
FefferyMotion,
|
|
147
|
-
FefferyAutoAnimate
|
|
149
|
+
FefferyAutoAnimate,
|
|
150
|
+
FefferyCountUp,
|
|
151
|
+
FefferyListenUnload
|
|
148
152
|
};
|
package/usage.py
CHANGED
|
@@ -1,119 +1,37 @@
|
|
|
1
1
|
import dash
|
|
2
|
-
import
|
|
3
|
-
from datetime import datetime
|
|
4
|
-
from dash import html, dcc
|
|
2
|
+
from dash import html
|
|
5
3
|
import feffery_utils_components as fuc
|
|
6
4
|
from dash.dependencies import Input, Output, State
|
|
7
5
|
|
|
8
|
-
app = dash.Dash(
|
|
6
|
+
app = dash.Dash(
|
|
7
|
+
__name__,
|
|
8
|
+
suppress_callback_exceptions=True
|
|
9
|
+
)
|
|
9
10
|
|
|
10
11
|
app.layout = html.Div(
|
|
11
12
|
[
|
|
12
|
-
fuc.
|
|
13
|
-
id='
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
'id': '指令1',
|
|
18
|
-
'title': '指令1',
|
|
19
|
-
'handler': '() => alert("指令1触发")',
|
|
20
|
-
'section': '模拟js指令'
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
'id': '指令2',
|
|
24
|
-
'title': '指令2',
|
|
25
|
-
'handler': '() => alert("指令2触发")',
|
|
26
|
-
'section': '模拟js指令'
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
'id': '跳转到首页',
|
|
30
|
-
'title': '跳转到首页',
|
|
31
|
-
'handler': '''() => {
|
|
32
|
-
window.location = "/"
|
|
33
|
-
}''',
|
|
34
|
-
'section': '模拟js指令'
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
'id': '指令3',
|
|
38
|
-
'title': '指令3',
|
|
39
|
-
'children': ['指令3-1', '指令3-2'],
|
|
40
|
-
'section': '多层指令菜单项'
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
'id': '指令3-1',
|
|
44
|
-
'title': '指令3-1',
|
|
45
|
-
'parent': '指令3'
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
'id': '指令3-2',
|
|
49
|
-
'title': '指令3-2',
|
|
50
|
-
'parent': '指令3'
|
|
51
|
-
}
|
|
52
|
-
]
|
|
13
|
+
fuc.FefferyListenUnload(
|
|
14
|
+
id='listen-unload'
|
|
15
|
+
),
|
|
16
|
+
html.Div(
|
|
17
|
+
id='output-demo'
|
|
53
18
|
)
|
|
54
19
|
],
|
|
55
20
|
style={
|
|
56
|
-
'padding': '50px'
|
|
21
|
+
'padding': '50px 100px'
|
|
57
22
|
}
|
|
58
23
|
)
|
|
59
24
|
|
|
60
25
|
|
|
61
26
|
@app.callback(
|
|
62
|
-
Output('
|
|
63
|
-
Input('
|
|
64
|
-
prevent_initial_call=True
|
|
27
|
+
Output('output-demo', 'children'),
|
|
28
|
+
Input('listen-unload', 'unloaded')
|
|
65
29
|
)
|
|
66
|
-
def demo(
|
|
30
|
+
def demo(unloaded):
|
|
67
31
|
|
|
68
|
-
if
|
|
69
|
-
return [
|
|
70
|
-
{
|
|
71
|
-
'id': f'指令{searchValue}{i}',
|
|
72
|
-
'title': f'指令{searchValue}{i}',
|
|
73
|
-
'handler': f'() => alert("指令{searchValue}{i}触发")',
|
|
74
|
-
'section': '搜索结果'
|
|
75
|
-
}
|
|
76
|
-
for i in range(100)
|
|
77
|
-
]
|
|
32
|
+
if unloaded:
|
|
78
33
|
|
|
79
|
-
|
|
80
|
-
{
|
|
81
|
-
'id': '指令1',
|
|
82
|
-
'title': '指令1',
|
|
83
|
-
'handler': '() => alert("指令1触发")',
|
|
84
|
-
'section': '模拟js指令'
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
'id': '指令2',
|
|
88
|
-
'title': '指令2',
|
|
89
|
-
'handler': '() => alert("指令2触发")',
|
|
90
|
-
'section': '模拟js指令'
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
'id': '跳转到首页',
|
|
94
|
-
'title': '跳转到首页',
|
|
95
|
-
'handler': '''() => {
|
|
96
|
-
window.location = "/"
|
|
97
|
-
}''',
|
|
98
|
-
'section': '模拟js指令'
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
'id': '指令3',
|
|
102
|
-
'title': '指令3',
|
|
103
|
-
'children': ['指令3-1', '指令3-2'],
|
|
104
|
-
'section': '多层指令菜单项'
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
'id': '指令3-1',
|
|
108
|
-
'title': '指令3-1',
|
|
109
|
-
'parent': '指令3'
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
'id': '指令3-2',
|
|
113
|
-
'title': '指令3-2',
|
|
114
|
-
'parent': '指令3'
|
|
115
|
-
}
|
|
116
|
-
]
|
|
34
|
+
print('页面被关闭')
|
|
117
35
|
|
|
118
36
|
|
|
119
37
|
if __name__ == '__main__':
|