@gm-pc/react 1.28.1-beta.1 → 1.28.1-beta.3
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/list/base.tsx +8 -2
- package/src/component/list/style.less +2 -0
- package/src/component/list/types.ts +3 -1
- package/src/component/more_select/base.tsx +80 -26
- package/src/component/more_select/more_select.tsx +1 -0
- package/src/component/more_select/types.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gm-pc/react",
|
|
3
|
-
"version": "1.28.1-beta.
|
|
3
|
+
"version": "1.28.1-beta.3",
|
|
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.1-beta.
|
|
27
|
+
"@gm-pc/locales": "^1.28.1-beta.3",
|
|
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": "d17ee3618dda2c5d2a632c1dda13a8a0f497a70d"
|
|
52
52
|
}
|
|
@@ -4,12 +4,14 @@ import { xor, flatMap, isNil, noop } from 'lodash'
|
|
|
4
4
|
import { ListBaseProps } from './types'
|
|
5
5
|
import { ListDataItem } from '../../types'
|
|
6
6
|
import { ConfigConsumer } from '../config_provider'
|
|
7
|
+
import SVGOk from '../../svg/ok.svg'
|
|
7
8
|
|
|
8
9
|
class Base<V = any> extends Component<ListBaseProps<V>> {
|
|
9
10
|
static defaultProps = {
|
|
10
11
|
onSelect: noop,
|
|
11
12
|
renderItem: (value: any) => value.text,
|
|
12
13
|
getItemProps: () => ({}),
|
|
14
|
+
showSelectedIcon: true,
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
private _listRef = createRef<HTMLDivElement>()
|
|
@@ -61,9 +63,9 @@ class Base<V = any> extends Component<ListBaseProps<V>> {
|
|
|
61
63
|
}
|
|
62
64
|
const { multiple, selected, onSelect } = this.props
|
|
63
65
|
if (multiple) {
|
|
64
|
-
onSelect && onSelect(xor(selected, [item.value]))
|
|
66
|
+
onSelect && onSelect(xor(selected, [item.value]), item)
|
|
65
67
|
} else {
|
|
66
|
-
onSelect && onSelect([item.value])
|
|
68
|
+
onSelect && onSelect([item.value], item)
|
|
67
69
|
}
|
|
68
70
|
}
|
|
69
71
|
|
|
@@ -79,6 +81,7 @@ class Base<V = any> extends Component<ListBaseProps<V>> {
|
|
|
79
81
|
className,
|
|
80
82
|
willActiveIndex,
|
|
81
83
|
getItemProps,
|
|
84
|
+
showSelectedIcon,
|
|
82
85
|
...rest
|
|
83
86
|
} = this.props
|
|
84
87
|
|
|
@@ -115,6 +118,9 @@ class Base<V = any> extends Component<ListBaseProps<V>> {
|
|
|
115
118
|
onClick={() => this._handleSelect(item)}
|
|
116
119
|
>
|
|
117
120
|
{renderItem!(item, index)}
|
|
121
|
+
{multiple && showSelectedIcon && selected.includes(item.value) && (
|
|
122
|
+
<SVGOk />
|
|
123
|
+
)}
|
|
118
124
|
</div>
|
|
119
125
|
)
|
|
120
126
|
})}
|
|
@@ -12,12 +12,14 @@ interface CommonListProps<V> {
|
|
|
12
12
|
getItemProps?(item: ListDataItem<V>): HTMLAttributes<HTMLDivElement>
|
|
13
13
|
className?: string
|
|
14
14
|
style?: CSSProperties
|
|
15
|
+
/** 是否显示选中状态的图标,默认为 true */
|
|
16
|
+
showSelectedIcon?: boolean
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
interface ListBaseProps<V> extends CommonListProps<V> {
|
|
18
20
|
data: ListGroupDataItem<V>[]
|
|
19
21
|
selected: V[]
|
|
20
|
-
onSelect?(selected: V[]): void
|
|
22
|
+
onSelect?(selected: V[], item: ListDataItem<V>): void
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
interface ListProps<V> extends CommonListProps<V> {
|
|
@@ -31,6 +31,9 @@ interface MoreSelectBaseState {
|
|
|
31
31
|
isCheckedAll: boolean
|
|
32
32
|
isFilterDelete: boolean
|
|
33
33
|
displayCount: number
|
|
34
|
+
// isPopupJustOpened: boolean
|
|
35
|
+
previousSelected?: MoreSelectDataItem<V>[]
|
|
36
|
+
previousCurrentSelected: MoreSelectDataItem<V>[]
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
// @todo keydown item disabled
|
|
@@ -49,6 +52,8 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
49
52
|
isCheckedAll: false,
|
|
50
53
|
isFilterDelete: true,
|
|
51
54
|
displayCount: 0,
|
|
55
|
+
previousSelected: [],
|
|
56
|
+
previousCurrentSelected: [],
|
|
52
57
|
}
|
|
53
58
|
|
|
54
59
|
private _isUnmounted = false
|
|
@@ -176,6 +181,10 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
176
181
|
const { onSearch } = this.props
|
|
177
182
|
const searchValue = event.target.value
|
|
178
183
|
this.setState({ searchValue })
|
|
184
|
+
this.setState({
|
|
185
|
+
previousSelected: this.props.selected,
|
|
186
|
+
previousCurrentSelected: this.props.selected,
|
|
187
|
+
})
|
|
179
188
|
if (onSearch && !this._isUnmounted) {
|
|
180
189
|
this.setState({
|
|
181
190
|
loading: true,
|
|
@@ -206,8 +215,10 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
206
215
|
|
|
207
216
|
private _debounceDoSearch = _.debounce(this._doSearch, this.props.delay)
|
|
208
217
|
|
|
209
|
-
private _handleClear = (clearItem: MoreSelectDataItem<V>, event
|
|
210
|
-
event
|
|
218
|
+
private _handleClear = (clearItem: MoreSelectDataItem<V>, event?: MouseEvent): void => {
|
|
219
|
+
if (event) {
|
|
220
|
+
event.stopPropagation()
|
|
221
|
+
}
|
|
211
222
|
const { onSelect = _.noop, selected = [] } = this.props
|
|
212
223
|
const willSelected = selected.filter((item) => item.value !== clearItem.value)
|
|
213
224
|
onSelect(willSelected)
|
|
@@ -217,6 +228,9 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
217
228
|
event.stopPropagation()
|
|
218
229
|
const { onSelect = _.noop } = this.props
|
|
219
230
|
onSelect([])
|
|
231
|
+
this.setState({
|
|
232
|
+
previousCurrentSelected: [],
|
|
233
|
+
})
|
|
220
234
|
}
|
|
221
235
|
|
|
222
236
|
private _handlePopupKeyDown = (event: KeyboardEvent<HTMLDivElement>): void => {
|
|
@@ -299,9 +313,6 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
299
313
|
? flatFilterData.filter((item) => !item.deleted)
|
|
300
314
|
: flatFilterData
|
|
301
315
|
|
|
302
|
-
// 计算总数:availableData + selected,过滤重复值
|
|
303
|
-
const totalCount = _.uniqBy([...availableData, ...selected], 'value').length
|
|
304
|
-
|
|
305
316
|
// 检查是否所有可用数据都被选中
|
|
306
317
|
const allSelected =
|
|
307
318
|
availableData.length > 0 &&
|
|
@@ -333,6 +344,12 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
333
344
|
new Set([...prevSelectedValue, ...valuesToSelect])
|
|
334
345
|
)
|
|
335
346
|
this._handleSelect(newSelected)
|
|
347
|
+
// 更新 previousCurrentSelected
|
|
348
|
+
this.setState({
|
|
349
|
+
previousCurrentSelected: Array.from(
|
|
350
|
+
new Set([...this.state.previousCurrentSelected, ...availableData])
|
|
351
|
+
),
|
|
352
|
+
})
|
|
336
353
|
} else {
|
|
337
354
|
// 取消全选 - 只反勾选availableData的数据
|
|
338
355
|
const { selected = [] } = this.props
|
|
@@ -341,10 +358,16 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
341
358
|
(item) => !availableValues.includes(item.value)
|
|
342
359
|
)
|
|
343
360
|
this._handleSelect(newSelected.map((item) => item.value))
|
|
361
|
+
// 更新 previousCurrentSelected
|
|
362
|
+
this.setState({
|
|
363
|
+
previousCurrentSelected: this.state.previousCurrentSelected.filter(
|
|
364
|
+
(item) => !availableValues.includes(item.value)
|
|
365
|
+
),
|
|
366
|
+
})
|
|
344
367
|
}
|
|
345
368
|
}}
|
|
346
369
|
>
|
|
347
|
-
全选({
|
|
370
|
+
全选({availableData.length})
|
|
348
371
|
</Checkbox>
|
|
349
372
|
)}
|
|
350
373
|
{isShowDeletedSwitch && (
|
|
@@ -410,9 +433,11 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
410
433
|
isGroupList,
|
|
411
434
|
renderListItem,
|
|
412
435
|
listHeight,
|
|
436
|
+
showSelectedIcon,
|
|
413
437
|
} = this.props
|
|
438
|
+
const { previousSelected = [], previousCurrentSelected = [] } = this.state
|
|
414
439
|
|
|
415
|
-
const selectedValues = new Set(
|
|
440
|
+
const selectedValues = new Set(previousSelected?.map((v) => v.value))
|
|
416
441
|
|
|
417
442
|
// 分离已勾选和未勾选的数据
|
|
418
443
|
const availableGroups: MoreSelectGroupDataItem<V>[] = []
|
|
@@ -421,9 +446,10 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
421
446
|
|
|
422
447
|
if (multiple) {
|
|
423
448
|
filterData.forEach((group) => {
|
|
424
|
-
const availableChildren = group.children.filter(
|
|
425
|
-
|
|
426
|
-
|
|
449
|
+
const availableChildren = group.children.filter((item) => {
|
|
450
|
+
// return true
|
|
451
|
+
return !selectedValues.has(item.value)
|
|
452
|
+
})
|
|
427
453
|
|
|
428
454
|
if (availableChildren.length > 0) {
|
|
429
455
|
availableGroups.push({
|
|
@@ -433,43 +459,65 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
433
459
|
}
|
|
434
460
|
})
|
|
435
461
|
|
|
436
|
-
if (
|
|
462
|
+
if (previousSelected.length > 0) {
|
|
437
463
|
selectedGroups.push({
|
|
438
464
|
label: '',
|
|
439
|
-
children:
|
|
465
|
+
children: previousSelected,
|
|
440
466
|
})
|
|
441
467
|
}
|
|
442
468
|
}
|
|
443
469
|
|
|
444
470
|
return (
|
|
445
471
|
<div style={{ height: listHeight, overflow: 'auto' }}>
|
|
446
|
-
{
|
|
472
|
+
{previousSelected.length > 0 && multiple && !this.state.searchValue && (
|
|
447
473
|
<>
|
|
448
474
|
<div className='gm-more-select-section-title gm-padding-5 gm-text-desc gm-text-12'>
|
|
449
475
|
已选中
|
|
450
476
|
</div>
|
|
451
477
|
<ListBase
|
|
452
|
-
|
|
478
|
+
showSelectedIcon={showSelectedIcon}
|
|
479
|
+
selected={previousCurrentSelected.map((v) => v.value)}
|
|
453
480
|
data={selectedGroups}
|
|
454
481
|
multiple={multiple}
|
|
455
482
|
isGroupList={false}
|
|
456
483
|
className='gm-border-0'
|
|
457
484
|
renderItem={renderListItem}
|
|
458
|
-
onSelect={
|
|
485
|
+
onSelect={(v, target) => {
|
|
486
|
+
this._handleSelect(v)
|
|
487
|
+
// 判断是勾选还是反选:如果 v 中包含 target.value,说明是勾选操作;否则是反选操作
|
|
488
|
+
const isChecked = v.includes(target.value)
|
|
489
|
+
if (isChecked) {
|
|
490
|
+
// 勾选:添加到 previousCurrentSelected
|
|
491
|
+
this.setState({
|
|
492
|
+
previousCurrentSelected: [
|
|
493
|
+
...this.state.previousCurrentSelected,
|
|
494
|
+
target,
|
|
495
|
+
],
|
|
496
|
+
})
|
|
497
|
+
} else {
|
|
498
|
+
// 反选:从 previousCurrentSelected 中移除
|
|
499
|
+
this.setState({
|
|
500
|
+
previousCurrentSelected: this.state.previousCurrentSelected?.filter(
|
|
501
|
+
(item) => item.value !== target.value
|
|
502
|
+
),
|
|
503
|
+
})
|
|
504
|
+
}
|
|
505
|
+
}}
|
|
459
506
|
isScrollTo={false}
|
|
460
507
|
/>
|
|
461
508
|
</>
|
|
462
509
|
)}
|
|
463
510
|
<>
|
|
464
|
-
{multiple && (
|
|
511
|
+
{multiple && !this.state.searchValue && (
|
|
465
512
|
<div className='gm-more-select-section-title gm-padding-5 gm-text-desc gm-text-12'>
|
|
466
513
|
未选中
|
|
467
514
|
</div>
|
|
468
515
|
)}
|
|
469
516
|
|
|
470
517
|
<ListBase
|
|
518
|
+
showSelectedIcon={showSelectedIcon}
|
|
471
519
|
selected={selected?.map((v) => v.value)}
|
|
472
|
-
data={multiple ? availableGroups : filterData}
|
|
520
|
+
data={multiple && !this.state.searchValue ? availableGroups : filterData}
|
|
473
521
|
multiple={multiple}
|
|
474
522
|
isGroupList={isGroupList}
|
|
475
523
|
className='gm-border-0'
|
|
@@ -541,15 +589,21 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
541
589
|
}
|
|
542
590
|
|
|
543
591
|
private _handlePopoverVisibleChange = (active: boolean) => {
|
|
544
|
-
if (active
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
this.
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
592
|
+
if (active) {
|
|
593
|
+
this.setState({
|
|
594
|
+
previousSelected: this.props.selected,
|
|
595
|
+
previousCurrentSelected: this.props.selected,
|
|
596
|
+
})
|
|
597
|
+
if (this.props.searchOnActive) {
|
|
598
|
+
const searchValue = localStorage.getItem('_GM-PC_MORESELECT_SEARCHVALUE')
|
|
599
|
+
if (searchValue) {
|
|
600
|
+
this.setState({ searchValue })
|
|
601
|
+
setTimeout(() => {
|
|
602
|
+
// eslint-disable-next-line no-unused-expressions
|
|
603
|
+
this._inputRef.current?.select()
|
|
604
|
+
this._debounceDoSearch(searchValue)
|
|
605
|
+
}, 0)
|
|
606
|
+
}
|
|
553
607
|
}
|
|
554
608
|
}
|
|
555
609
|
}
|