@gm-pc/react 1.11.1-beta.0 → 1.11.2-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/package.json +3 -3
- package/src/component/more_select/base.tsx +8 -0
- package/src/component/more_select/more_select.tsx +2 -0
- package/src/component/more_select/stories.tsx +20 -0
- package/src/component/more_select/types.ts +4 -0
- package/src/component/select/select.tsx +9 -21
- package/src/component/select/types.ts +0 -7
- package/src/component/v_browser/types.ts +6 -1
- package/src/component/v_browser/ui/style.less +1 -1
- package/src/component/v_browser/v_browser.stories.mdx +126 -0
- package/src/component/v_browser/v_browser.tsx +3 -3
- package/src/component/v_browser/stories.tsx +0 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gm-pc/react",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.2-beta.0",
|
|
4
4
|
"description": "观麦前端基础组件库",
|
|
5
5
|
"author": "liyatang <liyatang@qq.com>",
|
|
6
6
|
"homepage": "https://github.com/gmfe/gm-pc#readme",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@gm-common/hooks": "^2.10.0",
|
|
26
26
|
"@gm-common/tool": "^2.10.0",
|
|
27
|
-
"@gm-pc/locales": "^1.11.
|
|
27
|
+
"@gm-pc/locales": "^1.11.2-beta.0",
|
|
28
28
|
"big.js": "^6.0.1",
|
|
29
29
|
"classnames": "^2.2.5",
|
|
30
30
|
"lodash": "^4.17.19",
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
"react-router-dom": "^5.2.0",
|
|
49
49
|
"react-window": "^1.8.5"
|
|
50
50
|
},
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "7c8a96ed9ebd309ee37b5b29f69911541b0f788f"
|
|
52
52
|
}
|
|
@@ -275,6 +275,13 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
275
275
|
)
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
private _handleMoreSelectClick = () => {
|
|
279
|
+
const { onClick, selected } = this.props
|
|
280
|
+
if (typeof onClick === 'function') {
|
|
281
|
+
return onClick(selected)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
278
285
|
render() {
|
|
279
286
|
const {
|
|
280
287
|
isInPopup,
|
|
@@ -292,6 +299,7 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
292
299
|
return (
|
|
293
300
|
<div
|
|
294
301
|
ref={this._baseRef}
|
|
302
|
+
onClick={this._handleMoreSelectClick}
|
|
295
303
|
className={classNames(
|
|
296
304
|
'gm-more-select',
|
|
297
305
|
{
|
|
@@ -73,6 +73,7 @@ class MoreSelect<V = any> extends Component<MoreSelectProps<V>> {
|
|
|
73
73
|
multiple,
|
|
74
74
|
isGroupList,
|
|
75
75
|
onSearch,
|
|
76
|
+
onClick,
|
|
76
77
|
renderListFilter,
|
|
77
78
|
...rest
|
|
78
79
|
} = this.props
|
|
@@ -109,6 +110,7 @@ class MoreSelect<V = any> extends Component<MoreSelectProps<V>> {
|
|
|
109
110
|
return (
|
|
110
111
|
<MoreSelectBase<V>
|
|
111
112
|
{...rest}
|
|
113
|
+
onClick={onClick}
|
|
112
114
|
ref={this._moreSelectBaseRef}
|
|
113
115
|
data={oData}
|
|
114
116
|
selected={oSelected}
|
|
@@ -95,6 +95,9 @@ const store = observable({
|
|
|
95
95
|
setMulSelected(selected: any) {
|
|
96
96
|
this.mulSelected = selected
|
|
97
97
|
},
|
|
98
|
+
clickFn(selected: any) {
|
|
99
|
+
this.selected = selected
|
|
100
|
+
},
|
|
98
101
|
})
|
|
99
102
|
|
|
100
103
|
export const ComMoreSelect = () => (
|
|
@@ -249,6 +252,23 @@ export const ComMoreSelectWithMultipleByValue = () => (
|
|
|
249
252
|
/>
|
|
250
253
|
</div>
|
|
251
254
|
)
|
|
255
|
+
|
|
256
|
+
export const ComMoreSelectClick = () => (
|
|
257
|
+
<>
|
|
258
|
+
<MoreSelect<number>
|
|
259
|
+
isGroupList
|
|
260
|
+
multiple
|
|
261
|
+
data={store.dataGroup.slice()}
|
|
262
|
+
onClick={store.clickFn}
|
|
263
|
+
selected={store.selected}
|
|
264
|
+
onSelect={(selected) => {
|
|
265
|
+
store.setSelected(selected)
|
|
266
|
+
}}
|
|
267
|
+
/>
|
|
268
|
+
<div>{_.map(store.selected, (item) => item.text).join('')}</div>
|
|
269
|
+
</>
|
|
270
|
+
)
|
|
271
|
+
|
|
252
272
|
export const ComMoreSelectWithMultipleAndOnSearch = () => {
|
|
253
273
|
return (
|
|
254
274
|
<MoreSelect<number>
|
|
@@ -70,6 +70,8 @@ interface MoreSelectBaseProps<V extends string | number = string>
|
|
|
70
70
|
|
|
71
71
|
/** 搜索回调 */
|
|
72
72
|
onSearch?(searchWord: string, data: MoreSelectGroupDataItem<V>[]): Promise<void> | void
|
|
73
|
+
/** 点击回调 */
|
|
74
|
+
onClick?(selected: MoreSelectSelected<V>[]): void
|
|
73
75
|
|
|
74
76
|
/** 自定义搜索过滤展示的数据 */
|
|
75
77
|
renderListFilter?(
|
|
@@ -94,6 +96,8 @@ interface MoreSelectProps<V extends string | number = string>
|
|
|
94
96
|
onChange?(value: V | V[]): void
|
|
95
97
|
/** 搜索回调 */
|
|
96
98
|
onSearch?(searchWord: string, data: MoreSelectData<V>): Promise<void> | void
|
|
99
|
+
/** 点击回调 */
|
|
100
|
+
onClick?(selected: MoreSelectSelected<V>[]): void
|
|
97
101
|
|
|
98
102
|
/** 自定义搜索过滤展示的数据 */
|
|
99
103
|
renderListFilter?(data: MoreSelectData<V>, searchValue: string): MoreSelectData<V>
|
|
@@ -91,7 +91,6 @@ class Select<V = any> extends Component<SelectProps<V>, SelectState> {
|
|
|
91
91
|
className,
|
|
92
92
|
popoverType,
|
|
93
93
|
isInPopup,
|
|
94
|
-
addonLast,
|
|
95
94
|
...rest
|
|
96
95
|
} = this.props
|
|
97
96
|
const { willActiveIndex } = this.state
|
|
@@ -109,26 +108,15 @@ class Select<V = any> extends Component<SelectProps<V>, SelectState> {
|
|
|
109
108
|
const selected = newData.find((v) => v.value === value)
|
|
110
109
|
|
|
111
110
|
const popup = (
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
/>
|
|
122
|
-
{addonLast && (
|
|
123
|
-
<div
|
|
124
|
-
onClick={() => {
|
|
125
|
-
this._popupRef.current!.apiDoSetActive()
|
|
126
|
-
}}
|
|
127
|
-
>
|
|
128
|
-
{addonLast}
|
|
129
|
-
</div>
|
|
130
|
-
)}
|
|
131
|
-
</>
|
|
111
|
+
<List
|
|
112
|
+
data={newData}
|
|
113
|
+
selected={value}
|
|
114
|
+
onSelect={this._handleChange}
|
|
115
|
+
renderItem={renderItem}
|
|
116
|
+
willActiveIndex={willActiveIndex}
|
|
117
|
+
className='gm-border-0'
|
|
118
|
+
style={{ maxHeight: '250px' }}
|
|
119
|
+
/>
|
|
132
120
|
)
|
|
133
121
|
|
|
134
122
|
// disabledClose 了,不会触发
|
|
@@ -17,13 +17,6 @@ interface SelectProps<V> {
|
|
|
17
17
|
className?: string
|
|
18
18
|
style?: CSSProperties
|
|
19
19
|
placeholder?: string
|
|
20
|
-
/**
|
|
21
|
-
* 在下拉选项最后自定义内容
|
|
22
|
-
*
|
|
23
|
-
* 注意:点击自定义内容时,会将浮层关闭。
|
|
24
|
-
* 你可以在自定义内容的事件处理函数中添加 `e.preventDefault()` 来阻止这个行为。
|
|
25
|
-
*/
|
|
26
|
-
addonLast?: ReactNode
|
|
27
20
|
}
|
|
28
21
|
|
|
29
22
|
export type { SelectProps }
|
|
@@ -14,7 +14,7 @@ export interface VBrowserWindow {
|
|
|
14
14
|
export interface VBrowserProps {
|
|
15
15
|
/** 窗口数量限制 */
|
|
16
16
|
maxLength?: number
|
|
17
|
-
/**
|
|
17
|
+
/** 准备就绪 */
|
|
18
18
|
onReady?: Function
|
|
19
19
|
/** 重新打开vBrowser时恢复已打开窗口, 默认为true */
|
|
20
20
|
restore?: boolean
|
|
@@ -26,7 +26,12 @@ export interface VBrowserProps {
|
|
|
26
26
|
) => void
|
|
27
27
|
/** 窗口打开/切换前调用,返回false会阻止窗口打开/切换 */
|
|
28
28
|
auth?: (from?: VBrowserWindow, to?: VBrowserWindow) => Promise<boolean> | boolean
|
|
29
|
+
/**
|
|
30
|
+
* 错误码参考
|
|
31
|
+
* code: 0, message: '超过最大允许的窗口数量'
|
|
32
|
+
*/
|
|
29
33
|
onError?: (error: { code: number; message: string }) => void
|
|
34
|
+
/** 打开窗口如果没有传入标题,则使用此方法取标题 */
|
|
30
35
|
autoTitle?: (path: string) => string
|
|
31
36
|
}
|
|
32
37
|
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Meta, Story, Canvas } from '@storybook/addon-docs/blocks'
|
|
2
|
+
|
|
3
|
+
<Meta title='窗口/VBrowser(页签)' />
|
|
4
|
+
|
|
5
|
+
# Vbrowser
|
|
6
|
+
|
|
7
|
+
VBrowser 即虚拟浏览器,用以实现页签形式的多窗口管理。
|
|
8
|
+
|
|
9
|
+
## 使用方式
|
|
10
|
+
|
|
11
|
+
实例化一个 VBrowser, 接受以下参数:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
import { VBrowser } from '@gm-pc/react'
|
|
15
|
+
const vbrowser = new VBrowser({
|
|
16
|
+
/** 窗口数量限制 */
|
|
17
|
+
maxLength?: number
|
|
18
|
+
/** 准备就绪 */
|
|
19
|
+
onReady?: Function
|
|
20
|
+
/** 重新打开vBrowser时恢复已打开窗口, 默认为true */
|
|
21
|
+
restore?: boolean
|
|
22
|
+
/** 窗口变化事件 */
|
|
23
|
+
onChange?: (
|
|
24
|
+
from: VBrowserWindow | undefined,
|
|
25
|
+
to: VBrowserWindow,
|
|
26
|
+
windows: VBrowserWindow[]
|
|
27
|
+
) => void
|
|
28
|
+
/** 窗口打开/切换前调用,返回false会阻止窗口打开/切换 */
|
|
29
|
+
auth?: (from?: VBrowserWindow, to?: VBrowserWindow) => Promise<boolean> | boolean
|
|
30
|
+
/**
|
|
31
|
+
* 错误码参考
|
|
32
|
+
* code: 0, message: '超过最大允许的窗口数量'
|
|
33
|
+
*/
|
|
34
|
+
onError?: (error: { code: number; message: string }) => void
|
|
35
|
+
/** 打开窗口如果没有传入标题,则使用此方法取标题 */
|
|
36
|
+
autoTitle?: (path: string) => string
|
|
37
|
+
})
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
vbrowser 暴露了以下属性和方法,详细信息见类型声明/代码提示:
|
|
41
|
+
|
|
42
|
+
属性
|
|
43
|
+
|
|
44
|
+
- `props`
|
|
45
|
+
|
|
46
|
+
实例化传入的参数,可以更改;
|
|
47
|
+
|
|
48
|
+
- `windows`
|
|
49
|
+
|
|
50
|
+
已打开的窗口列表;
|
|
51
|
+
|
|
52
|
+
- `activeIndex`
|
|
53
|
+
|
|
54
|
+
活动窗口索引;
|
|
55
|
+
|
|
56
|
+
- `activeWindow`
|
|
57
|
+
|
|
58
|
+
活动窗口;
|
|
59
|
+
|
|
60
|
+
- `ui`
|
|
61
|
+
|
|
62
|
+
UI 组件,放在页面要显示到的位置,只读;
|
|
63
|
+
|
|
64
|
+
- `mounted`
|
|
65
|
+
|
|
66
|
+
`ui`是否已挂载;
|
|
67
|
+
|
|
68
|
+
方法
|
|
69
|
+
|
|
70
|
+
- `open`
|
|
71
|
+
|
|
72
|
+
打开窗口;
|
|
73
|
+
|
|
74
|
+
- `close`
|
|
75
|
+
|
|
76
|
+
关闭窗口;
|
|
77
|
+
|
|
78
|
+
- `switchWindow`
|
|
79
|
+
|
|
80
|
+
切换窗口;
|
|
81
|
+
|
|
82
|
+
- `showTabs`
|
|
83
|
+
|
|
84
|
+
显示窗口管理栏;
|
|
85
|
+
|
|
86
|
+
- `hideTabs`
|
|
87
|
+
|
|
88
|
+
隐藏窗口管理栏,可以用于进入全屏模式的场景;
|
|
89
|
+
|
|
90
|
+
- `on`
|
|
91
|
+
|
|
92
|
+
事件监听, `'error' | 'change' | 'close' | 'show'`,分别对应错误、窗口切换、窗口关闭、窗口激活事件;
|
|
93
|
+
|
|
94
|
+
- `off`
|
|
95
|
+
|
|
96
|
+
取消监听;
|
|
97
|
+
|
|
98
|
+
## Hook 函数
|
|
99
|
+
|
|
100
|
+
当前提供的 Hook 函数有:
|
|
101
|
+
|
|
102
|
+
- `useWindowEffect`
|
|
103
|
+
|
|
104
|
+
使用方式同 `useEffect`,功能: 窗口激活时、deps 更新时,触发 fn 执行; 窗口失活时执行 fn 返回的销毁函数; 如果子窗口为失活状态,不观察 deps 的更新;
|
|
105
|
+
|
|
106
|
+
## 路由跳转
|
|
107
|
+
|
|
108
|
+
erp 中做了向后兼容,可以继续使用原有的`history.push`等方法来跳转页面,其会被表现为打开或切换子窗口,也可以直接使用上述 vbrowser 的方法来跳转页面;
|
|
109
|
+
|
|
110
|
+
需要注意的是如果想在新浏览器窗口中打开某个页面,不建议使用`window.open`方法,`window.open`打开的浏览器窗口会加载缓存恢复 VBrowser 的子窗口,
|
|
111
|
+
如果其行为不符合预期可以考虑传入 target 到 vbrowser.open 来打开新浏览器窗口:
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
vbrowser.open('/order/order_manage/create' , { target: '_blank' })
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## 注意事项
|
|
118
|
+
|
|
119
|
+
VBrowser 中打开的窗口中的组件,其生命周期会和预期略有不同:
|
|
120
|
+
|
|
121
|
+
多窗口中的子页面组件因为被缓存,原来的 `useEffect` 受到影响,即 effect 仅在子窗口创建时触发,销毁函数仅在子窗口关闭时触发;子窗口失活时依然会观察 deps,并触发 effect;
|
|
122
|
+
|
|
123
|
+
基本大多数情况下可以继续使用 `useEffect`,某些场景下则需要改用 `useWindowEffect`,比如
|
|
124
|
+
|
|
125
|
+
- 希望窗口激活、失活时初始化数据;
|
|
126
|
+
- 希望失活组件停止观察 useEffect 的 deps,比如在订单列表和商品列表页面都观察了`query.q`,那么订单列表页面的`query.q`变化后商品列表页面会做响应,这是没有必要的;
|
|
@@ -45,7 +45,7 @@ class VBrowser implements VBrowser {
|
|
|
45
45
|
|
|
46
46
|
props!: VBrowserProps
|
|
47
47
|
|
|
48
|
-
/**
|
|
48
|
+
/** 子窗口列表 */
|
|
49
49
|
windows: VBrowserWindow[] = []
|
|
50
50
|
/** 选中窗口索引 */
|
|
51
51
|
activeIndex = -1
|
|
@@ -73,7 +73,7 @@ class VBrowser implements VBrowser {
|
|
|
73
73
|
this._stash()
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
/**
|
|
76
|
+
/** 打开新子窗口, 子窗口已存在则判断query是否相等,相等则切换,不相等则隐性销毁重新加载;子窗口不存在则新建子窗口;
|
|
77
77
|
*
|
|
78
78
|
* target为'_blank'时,新开浏览器窗口
|
|
79
79
|
*/
|
|
@@ -153,7 +153,7 @@ class VBrowser implements VBrowser {
|
|
|
153
153
|
// #endregion
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
/**
|
|
156
|
+
/** 关闭子窗口 */
|
|
157
157
|
close(i: number | VBrowserWindow) {
|
|
158
158
|
if (typeof i !== 'number') {
|
|
159
159
|
i = this.windows.findIndex((item) => item.path === (i as VBrowserWindow).path)
|