@gm-pc/react 1.28.0-beta.0 → 1.28.0-beta.10
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 +98 -60
- package/src/component/more_select/more_select.tsx +6 -0
- package/src/component/more_select/style.less +4 -0
- package/src/component/more_select/types.ts +13 -2
- package/src/component/switch/style.less +4 -0
- package/src/component/switch/switch.tsx +7 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gm-pc/react",
|
|
3
|
-
"version": "1.28.0-beta.
|
|
3
|
+
"version": "1.28.0-beta.10",
|
|
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.28.0-beta.
|
|
27
|
+
"@gm-pc/locales": "^1.28.0-beta.10",
|
|
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": "4312bf2ebd2891c4d1ca2e37da666535bc11cf21"
|
|
52
52
|
}
|
|
@@ -20,8 +20,8 @@ import { getLocale } from '@gm-pc/locales'
|
|
|
20
20
|
import { ListBase } from '../list'
|
|
21
21
|
import { findDOMNode } from 'react-dom'
|
|
22
22
|
import { ConfigConsumer, ConfigProvider, ConfigProviderProps } from '../config_provider'
|
|
23
|
-
import { Checkbox
|
|
24
|
-
|
|
23
|
+
import { Checkbox } from '../checkbox'
|
|
24
|
+
import { Switch } from '../switch'
|
|
25
25
|
interface MoreSelectBaseState {
|
|
26
26
|
searchValue: string
|
|
27
27
|
loading: boolean
|
|
@@ -46,7 +46,7 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
46
46
|
loading: false,
|
|
47
47
|
willActiveIndex: this.props.isKeyboard ? 0 : null,
|
|
48
48
|
isCheckedAll: false,
|
|
49
|
-
isFilterDelete:
|
|
49
|
+
isFilterDelete: true,
|
|
50
50
|
displayCount: 0,
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -71,15 +71,14 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
componentDidMount() {
|
|
74
|
-
const { maxTagCount } = this.props
|
|
74
|
+
const { maxTagCount, tagItemWidth = 80, omittedTagWidth = 45 } = this.props
|
|
75
75
|
if (maxTagCount === 'responsive' && this._selectionRef.current) {
|
|
76
76
|
// HACK: 首次计算
|
|
77
77
|
setTimeout(() => {
|
|
78
78
|
if (this._selectionRef.current) {
|
|
79
79
|
const { width } = this._selectionRef.current.getBoundingClientRect()
|
|
80
|
-
const omittedTagWidth = 50 // for "+N..."
|
|
81
80
|
const availableWidth = width - omittedTagWidth
|
|
82
|
-
const newDisplayCount = Math.floor(availableWidth /
|
|
81
|
+
const newDisplayCount = Math.floor(availableWidth / tagItemWidth)
|
|
83
82
|
if (this.state.displayCount !== newDisplayCount) {
|
|
84
83
|
this.setState({ displayCount: newDisplayCount > 0 ? newDisplayCount : 0 })
|
|
85
84
|
}
|
|
@@ -90,12 +89,11 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
90
89
|
for (const entry of entries) {
|
|
91
90
|
const { width } = entry.contentRect
|
|
92
91
|
// Estimate item width, let's say 80px.
|
|
93
|
-
const omittedTagWidth = 50 // for "+N..."
|
|
94
92
|
const availableWidth = width - omittedTagWidth
|
|
95
|
-
const newDisplayCount = Math.floor(availableWidth /
|
|
93
|
+
const newDisplayCount = Math.floor(availableWidth / tagItemWidth)
|
|
96
94
|
|
|
97
95
|
if (this.state.displayCount !== newDisplayCount) {
|
|
98
|
-
this.setState({ displayCount: newDisplayCount
|
|
96
|
+
this.setState({ displayCount: newDisplayCount })
|
|
99
97
|
}
|
|
100
98
|
}
|
|
101
99
|
})
|
|
@@ -174,8 +172,14 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
174
172
|
event: ChangeEvent<HTMLInputElement>,
|
|
175
173
|
isInitSearch?: boolean
|
|
176
174
|
): void => {
|
|
175
|
+
const { onSearch } = this.props
|
|
177
176
|
const searchValue = event.target.value
|
|
178
177
|
this.setState({ searchValue })
|
|
178
|
+
if (onSearch && !this._isUnmounted) {
|
|
179
|
+
this.setState({
|
|
180
|
+
loading: true,
|
|
181
|
+
})
|
|
182
|
+
}
|
|
179
183
|
this._debounceDoSearch(searchValue)
|
|
180
184
|
setTimeout(() => {
|
|
181
185
|
// eslint-disable-next-line no-unused-expressions
|
|
@@ -189,14 +193,12 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
189
193
|
private _doSearch = (query: string): void => {
|
|
190
194
|
const { onSearch, data = [] } = this.props
|
|
191
195
|
if (!this._isUnmounted && onSearch) {
|
|
192
|
-
const result = onSearch(query, data)
|
|
193
|
-
if (!result) {
|
|
194
|
-
return
|
|
195
|
-
}
|
|
196
196
|
this.setState({ loading: true })
|
|
197
|
-
|
|
197
|
+
const result = onSearch(query, data)
|
|
198
198
|
Promise.resolve(result).finally(() => {
|
|
199
|
-
|
|
199
|
+
setTimeout(() => {
|
|
200
|
+
this.setState({ loading: false })
|
|
201
|
+
}, 50)
|
|
200
202
|
})
|
|
201
203
|
}
|
|
202
204
|
}
|
|
@@ -245,9 +247,9 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
245
247
|
}
|
|
246
248
|
|
|
247
249
|
private _getFilterData = () => {
|
|
248
|
-
const { data = [], renderListFilter, renderListFilterType } = this.props
|
|
250
|
+
const { data = [], renderListFilter, renderListFilterType, onSearch } = this.props
|
|
249
251
|
const { searchValue } = this.state
|
|
250
|
-
let filterData: MoreSelectGroupDataItem<V>[]
|
|
252
|
+
let filterData: MoreSelectGroupDataItem<V>[] = []
|
|
251
253
|
if (renderListFilter) {
|
|
252
254
|
filterData = renderListFilter(data, searchValue)
|
|
253
255
|
} else if (renderListFilterType === 'pinyin') {
|
|
@@ -300,9 +302,8 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
300
302
|
return (
|
|
301
303
|
<Flex
|
|
302
304
|
justifyBetween
|
|
303
|
-
className='tw-p-[8px]'
|
|
305
|
+
className='tw-p-[8px] gm-more-select-default-bottom'
|
|
304
306
|
alignCenter
|
|
305
|
-
style={{ borderTop: '1px solid #aeaeae' }}
|
|
306
307
|
>
|
|
307
308
|
{isShowCheckedAll && (
|
|
308
309
|
<Checkbox
|
|
@@ -316,50 +317,109 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
316
317
|
if (isChecked) {
|
|
317
318
|
// 全选当前过滤后的可用数据
|
|
318
319
|
const valuesToSelect = availableData.map((item) => item.value)
|
|
319
|
-
|
|
320
|
+
const prevSelectedValue = selected.map((item) => item.value)
|
|
321
|
+
// console.log(valuesToSelect, selected)
|
|
322
|
+
const newSelected = Array.from(
|
|
323
|
+
new Set([...prevSelectedValue, ...valuesToSelect])
|
|
324
|
+
)
|
|
325
|
+
this._handleSelect(newSelected)
|
|
320
326
|
} else {
|
|
321
|
-
// 取消全选
|
|
322
|
-
this.
|
|
327
|
+
// 取消全选 - 只反勾选availableData的数据
|
|
328
|
+
const { selected = [] } = this.props
|
|
329
|
+
const availableValues = availableData.map((item) => item.value)
|
|
330
|
+
const newSelected = selected.filter(
|
|
331
|
+
(item) => !availableValues.includes(item.value)
|
|
332
|
+
)
|
|
333
|
+
this._handleSelect(newSelected.map((item) => item.value))
|
|
323
334
|
}
|
|
324
335
|
}}
|
|
325
336
|
>
|
|
326
|
-
全选
|
|
337
|
+
全选({availableData.length})
|
|
327
338
|
</Checkbox>
|
|
328
339
|
)}
|
|
329
340
|
{isShowDeletedSwitch && (
|
|
330
341
|
<Flex alignCenter>
|
|
331
342
|
<Flex row>
|
|
332
343
|
<Switch
|
|
333
|
-
|
|
344
|
+
size='small'
|
|
345
|
+
style={{ width: 32 }}
|
|
334
346
|
checked={isFilterDelete}
|
|
335
347
|
onChange={(open) => {
|
|
336
348
|
this.setState({
|
|
337
349
|
isFilterDelete: open,
|
|
338
350
|
})
|
|
339
|
-
if (isCheckedAll) {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
}
|
|
351
|
+
// if (isCheckedAll) {
|
|
352
|
+
// const newAvailableData = open
|
|
353
|
+
// ? flatFilterData.filter((item) => !item.deleted)
|
|
354
|
+
// : flatFilterData
|
|
355
|
+
|
|
356
|
+
// const valuesToSelect = newAvailableData.map((item) => item.value)
|
|
357
|
+
// this._handleSelect(valuesToSelect)
|
|
358
|
+
// }
|
|
347
359
|
}}
|
|
348
360
|
/>
|
|
349
361
|
</Flex>
|
|
350
|
-
<span className='gm-margin-left-5'
|
|
362
|
+
<span className='gm-margin-left-5'>过滤已删除数据</span>
|
|
351
363
|
</Flex>
|
|
352
364
|
)}
|
|
353
365
|
</Flex>
|
|
354
366
|
)
|
|
355
367
|
}
|
|
356
368
|
|
|
369
|
+
renderContent = () => {
|
|
370
|
+
const { loading, willActiveIndex, isFilterDelete } = this.state
|
|
371
|
+
|
|
372
|
+
if (loading) {
|
|
373
|
+
return (
|
|
374
|
+
<Flex alignCenter justifyCenter className='gm-bg gm-padding-5'>
|
|
375
|
+
<Loading size='20px' />
|
|
376
|
+
</Flex>
|
|
377
|
+
)
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
let filterData = this._getFilterData()
|
|
381
|
+
|
|
382
|
+
// 如果开启了过滤已删除商品功能,需要过滤掉已删除的商品
|
|
383
|
+
if (isFilterDelete) {
|
|
384
|
+
filterData = filterData
|
|
385
|
+
.map((group) => ({
|
|
386
|
+
...group,
|
|
387
|
+
children: group.children.filter((item) => !item.deleted),
|
|
388
|
+
}))
|
|
389
|
+
.filter((group) => group.children.length > 0)
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if (!loading && filterData.length === 0) {
|
|
393
|
+
return this._renderEmpty()
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
if (!loading && filterData.length > 0) {
|
|
397
|
+
const {
|
|
398
|
+
selected = [],
|
|
399
|
+
multiple,
|
|
400
|
+
isGroupList,
|
|
401
|
+
renderListItem,
|
|
402
|
+
listHeight,
|
|
403
|
+
} = this.props
|
|
404
|
+
return (
|
|
405
|
+
<ListBase
|
|
406
|
+
selected={selected.map((v) => v.value)}
|
|
407
|
+
data={filterData}
|
|
408
|
+
multiple={multiple}
|
|
409
|
+
isGroupList={isGroupList}
|
|
410
|
+
className='gm-border-0'
|
|
411
|
+
renderItem={renderListItem}
|
|
412
|
+
onSelect={this._handleSelect}
|
|
413
|
+
isScrollTo
|
|
414
|
+
willActiveIndex={willActiveIndex!}
|
|
415
|
+
style={{ height: listHeight }}
|
|
416
|
+
/>
|
|
417
|
+
)
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
357
421
|
private _renderList = (config: ConfigProviderProps): ReactNode => {
|
|
358
422
|
const {
|
|
359
|
-
selected = [],
|
|
360
|
-
multiple,
|
|
361
|
-
isGroupList,
|
|
362
|
-
renderListItem,
|
|
363
423
|
searchPlaceholder,
|
|
364
424
|
listHeight,
|
|
365
425
|
popupClassName,
|
|
@@ -394,28 +454,7 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
394
454
|
placeholder={searchPlaceholder}
|
|
395
455
|
/>
|
|
396
456
|
</div>
|
|
397
|
-
<div style={{ height: listHeight }}>
|
|
398
|
-
{loading && (
|
|
399
|
-
<Flex alignCenter justifyCenter className='gm-bg gm-padding-5'>
|
|
400
|
-
<Loading size='20px' />
|
|
401
|
-
</Flex>
|
|
402
|
-
)}
|
|
403
|
-
{!loading && !filterData.length && this._renderEmpty()}
|
|
404
|
-
{!loading && !!filterData.length && (
|
|
405
|
-
<ListBase
|
|
406
|
-
selected={selected.map((v) => v.value)}
|
|
407
|
-
data={filterData}
|
|
408
|
-
multiple={multiple}
|
|
409
|
-
isGroupList={isGroupList}
|
|
410
|
-
className='gm-border-0'
|
|
411
|
-
renderItem={renderListItem}
|
|
412
|
-
onSelect={this._handleSelect}
|
|
413
|
-
isScrollTo
|
|
414
|
-
willActiveIndex={willActiveIndex!}
|
|
415
|
-
style={{ height: listHeight }}
|
|
416
|
-
/>
|
|
417
|
-
)}
|
|
418
|
-
</div>
|
|
457
|
+
<div style={{ height: listHeight }}>{this.renderContent()}</div>
|
|
419
458
|
{!loading &&
|
|
420
459
|
!!filterData.length &&
|
|
421
460
|
(renderCustomizedBottom
|
|
@@ -464,7 +503,6 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
464
503
|
children,
|
|
465
504
|
maxTagCount,
|
|
466
505
|
maxTagPlaceholder,
|
|
467
|
-
isRenderDefaultBottom = false,
|
|
468
506
|
} = this.props
|
|
469
507
|
|
|
470
508
|
// 处理 maxTagCount 逻辑
|
|
@@ -12,6 +12,12 @@ class MoreSelect<V = any> extends Component<MoreSelectProps<V>> {
|
|
|
12
12
|
renderListFilterType: 'default',
|
|
13
13
|
popoverType: 'focus',
|
|
14
14
|
onKeyDown: _.noop,
|
|
15
|
+
/** 是否展示全选以及过滤已删除商品 */
|
|
16
|
+
isRenderDefaultBottom: false,
|
|
17
|
+
/** 是否展示已删除商品 */
|
|
18
|
+
isShowDeletedSwitch: true,
|
|
19
|
+
/** 是否展示全选 */
|
|
20
|
+
isShowCheckedAll: true,
|
|
15
21
|
}
|
|
16
22
|
|
|
17
23
|
private _moreSelectBaseRef = createRef<MoreSelectBase>()
|
|
@@ -73,6 +73,17 @@ interface MoreSelectCommonProps<V extends string | number = string> {
|
|
|
73
73
|
omittedValues: MoreSelectDataItem<V>[],
|
|
74
74
|
omittedCount: number
|
|
75
75
|
) => ReactNode
|
|
76
|
+
|
|
77
|
+
/** 是否展示全选以及过滤已删除商品 */
|
|
78
|
+
isRenderDefaultBottom?: boolean
|
|
79
|
+
/** 是否展示已删除商品 */
|
|
80
|
+
isShowDeletedSwitch?: boolean
|
|
81
|
+
/** 是否展示全选 */
|
|
82
|
+
isShowCheckedAll?: boolean
|
|
83
|
+
/** 当设置 maxTagCount 的时候的宽度, 根据这个去计算显示内容 */
|
|
84
|
+
tagItemWidth?: number
|
|
85
|
+
/** +N 显示的宽度 */
|
|
86
|
+
omittedTagWidth?: number
|
|
76
87
|
}
|
|
77
88
|
|
|
78
89
|
interface MoreSelectBaseProps<V extends string | number = string>
|
|
@@ -82,7 +93,7 @@ interface MoreSelectBaseProps<V extends string | number = string>
|
|
|
82
93
|
onSelect(selected: MoreSelectDataItem<V>[]): void
|
|
83
94
|
|
|
84
95
|
/** 搜索回调 */
|
|
85
|
-
onSearch?(searchWord: string, data: MoreSelectGroupDataItem<V>[]): Promise<
|
|
96
|
+
onSearch?(searchWord: string, data: MoreSelectGroupDataItem<V>[]): Promise<any> | any
|
|
86
97
|
/** 点击回调 */
|
|
87
98
|
onClick?(selected: MoreSelectSelected<V>[]): void
|
|
88
99
|
|
|
@@ -117,7 +128,7 @@ interface MoreSelectProps<V extends string | number = string>
|
|
|
117
128
|
onSelect?(selected?: MoreSelectSelected<V>): void
|
|
118
129
|
onChange?(value: V | V[]): void
|
|
119
130
|
/** 搜索回调 */
|
|
120
|
-
onSearch?(searchWord: string, data: MoreSelectData<V>): Promise<void> |
|
|
131
|
+
onSearch?(searchWord: string, data: MoreSelectData<V>): Promise<void | any> | any
|
|
121
132
|
/** 点击回调 */
|
|
122
133
|
onClick?(selected: MoreSelectSelected<V>[]): void
|
|
123
134
|
|
|
@@ -11,6 +11,7 @@ interface SwitchProps {
|
|
|
11
11
|
onChange?(checked: boolean): void
|
|
12
12
|
className?: string
|
|
13
13
|
style?: CSSProperties
|
|
14
|
+
size?: 'small' | 'middle'
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
interface SwitchState {
|
|
@@ -26,10 +27,11 @@ class Switch extends Component<SwitchProps, SwitchState> {
|
|
|
26
27
|
on: '',
|
|
27
28
|
off: '',
|
|
28
29
|
onChange: _.noop,
|
|
30
|
+
size: 'middle',
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
readonly state: SwitchState = {
|
|
32
|
-
checked: this.props.checked,
|
|
34
|
+
checked: !!this.props.checked,
|
|
33
35
|
labelWidth: null,
|
|
34
36
|
isReady: false,
|
|
35
37
|
}
|
|
@@ -53,7 +55,7 @@ class Switch extends Component<SwitchProps, SwitchState> {
|
|
|
53
55
|
UNSAFE_componentWillReceiveProps(nextProps: Readonly<SwitchProps>) {
|
|
54
56
|
if ('checked' in nextProps) {
|
|
55
57
|
this.setState({
|
|
56
|
-
checked: nextProps.checked,
|
|
58
|
+
checked: !!nextProps.checked,
|
|
57
59
|
})
|
|
58
60
|
}
|
|
59
61
|
}
|
|
@@ -82,6 +84,7 @@ class Switch extends Component<SwitchProps, SwitchState> {
|
|
|
82
84
|
disabled,
|
|
83
85
|
on,
|
|
84
86
|
off,
|
|
87
|
+
size,
|
|
85
88
|
...rest
|
|
86
89
|
} = this.props
|
|
87
90
|
|
|
@@ -101,8 +104,9 @@ class Switch extends Component<SwitchProps, SwitchState> {
|
|
|
101
104
|
ref={this._inputOffRef}
|
|
102
105
|
className={classNames('gm-switch gm-switch-' + type, className, {
|
|
103
106
|
disabled,
|
|
107
|
+
[`gm-switch-${size}`]: size,
|
|
104
108
|
})}
|
|
105
|
-
style={style}
|
|
109
|
+
style={style as any}
|
|
106
110
|
data-attr={this.state.labelWidth}
|
|
107
111
|
disabled={disabled}
|
|
108
112
|
type='checkbox'
|