@gm-pc/react 1.27.4-beta.6 → 1.28.0-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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gm-pc/react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.28.0-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.
|
|
27
|
+
"@gm-pc/locales": "^1.28.0-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": "107461a0dd5c644e10482ed5f3ed8638fee436cc"
|
|
52
52
|
}
|
|
@@ -20,12 +20,16 @@ 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, Switch } from '@gm-pc/react'
|
|
23
24
|
|
|
24
25
|
interface MoreSelectBaseState {
|
|
25
26
|
searchValue: string
|
|
26
27
|
loading: boolean
|
|
27
28
|
/* keyboard 默认第一个位置 */
|
|
28
29
|
willActiveIndex: number | null
|
|
30
|
+
isCheckedAll: boolean
|
|
31
|
+
isFilterDelete: boolean
|
|
32
|
+
displayCount: number
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
// @todo keydown item disabled
|
|
@@ -41,6 +45,9 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
41
45
|
searchValue: '',
|
|
42
46
|
loading: false,
|
|
43
47
|
willActiveIndex: this.props.isKeyboard ? 0 : null,
|
|
48
|
+
isCheckedAll: false,
|
|
49
|
+
isFilterDelete: false,
|
|
50
|
+
displayCount: 0,
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
private _isUnmounted = false
|
|
@@ -48,6 +55,7 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
48
55
|
private _selectionRef = createRef<HTMLDivElement>()
|
|
49
56
|
private _popoverRef = createRef<Popover>()
|
|
50
57
|
private _inputRef = createRef<HTMLInputElement>()
|
|
58
|
+
private _resizeObserver: ResizeObserver | null = null
|
|
51
59
|
|
|
52
60
|
private _filterData: MoreSelectGroupDataItem<V>[] | undefined
|
|
53
61
|
|
|
@@ -62,8 +70,44 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
62
70
|
}
|
|
63
71
|
}
|
|
64
72
|
|
|
73
|
+
componentDidMount() {
|
|
74
|
+
const { maxTagCount } = this.props
|
|
75
|
+
if (maxTagCount === 'responsive' && this._selectionRef.current) {
|
|
76
|
+
// HACK: 首次计算
|
|
77
|
+
setTimeout(() => {
|
|
78
|
+
if (this._selectionRef.current) {
|
|
79
|
+
const { width } = this._selectionRef.current.getBoundingClientRect()
|
|
80
|
+
const omittedTagWidth = 50 // for "+N..."
|
|
81
|
+
const availableWidth = width - omittedTagWidth
|
|
82
|
+
const newDisplayCount = Math.floor(availableWidth / 80)
|
|
83
|
+
if (this.state.displayCount !== newDisplayCount) {
|
|
84
|
+
this.setState({ displayCount: newDisplayCount > 0 ? newDisplayCount : 0 })
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}, 0)
|
|
88
|
+
|
|
89
|
+
this._resizeObserver = new ResizeObserver((entries) => {
|
|
90
|
+
for (const entry of entries) {
|
|
91
|
+
const { width } = entry.contentRect
|
|
92
|
+
// Estimate item width, let's say 80px.
|
|
93
|
+
const omittedTagWidth = 50 // for "+N..."
|
|
94
|
+
const availableWidth = width - omittedTagWidth
|
|
95
|
+
const newDisplayCount = Math.floor(availableWidth / 80)
|
|
96
|
+
|
|
97
|
+
if (this.state.displayCount !== newDisplayCount) {
|
|
98
|
+
this.setState({ displayCount: newDisplayCount > 0 ? newDisplayCount : 0 })
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
this._resizeObserver.observe(this._selectionRef.current)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
65
106
|
componentWillUnmount() {
|
|
66
|
-
this._isUnmounted =
|
|
107
|
+
this._isUnmounted = true
|
|
108
|
+
if (this._resizeObserver) {
|
|
109
|
+
this._resizeObserver.disconnect()
|
|
110
|
+
}
|
|
67
111
|
}
|
|
68
112
|
|
|
69
113
|
public apiDoFocus = (): void => {
|
|
@@ -166,7 +210,7 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
166
210
|
onSelect(willSelected)
|
|
167
211
|
}
|
|
168
212
|
|
|
169
|
-
private _handlePopupKeyDown = (event: KeyboardEvent): void => {
|
|
213
|
+
private _handlePopupKeyDown = (event: KeyboardEvent<HTMLDivElement>): void => {
|
|
170
214
|
const { onKeyDown } = this.props
|
|
171
215
|
let willActiveIndex = this.state.willActiveIndex as number
|
|
172
216
|
if (!onKeyDown) {
|
|
@@ -232,6 +276,84 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
232
276
|
)
|
|
233
277
|
}
|
|
234
278
|
|
|
279
|
+
renderBottom = () => {
|
|
280
|
+
const {
|
|
281
|
+
selected = [],
|
|
282
|
+
isShowDeletedSwitch = true,
|
|
283
|
+
isShowCheckedAll = true,
|
|
284
|
+
} = this.props
|
|
285
|
+
const { isCheckedAll, isFilterDelete } = this.state
|
|
286
|
+
const flatFilterData = this._getFlatFilterData()
|
|
287
|
+
|
|
288
|
+
// 根据过滤状态决定是否过滤已删除商品
|
|
289
|
+
const availableData = isFilterDelete
|
|
290
|
+
? flatFilterData.filter((item) => !item.deleted)
|
|
291
|
+
: flatFilterData
|
|
292
|
+
|
|
293
|
+
// 检查是否所有可用数据都被选中
|
|
294
|
+
const allSelected =
|
|
295
|
+
availableData.length > 0 &&
|
|
296
|
+
availableData.every((item) =>
|
|
297
|
+
selected.some((selectedItem) => selectedItem.value === item.value)
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
return (
|
|
301
|
+
<Flex
|
|
302
|
+
justifyBetween
|
|
303
|
+
className='tw-p-[8px]'
|
|
304
|
+
alignCenter
|
|
305
|
+
style={{ borderTop: '1px solid #aeaeae' }}
|
|
306
|
+
>
|
|
307
|
+
{isShowCheckedAll && (
|
|
308
|
+
<Checkbox
|
|
309
|
+
checked={allSelected}
|
|
310
|
+
onChange={(e) => {
|
|
311
|
+
const isChecked = e.target.checked
|
|
312
|
+
this.setState({
|
|
313
|
+
isCheckedAll: isChecked,
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
if (isChecked) {
|
|
317
|
+
// 全选当前过滤后的可用数据
|
|
318
|
+
const valuesToSelect = availableData.map((item) => item.value)
|
|
319
|
+
this._handleSelect(valuesToSelect)
|
|
320
|
+
} else {
|
|
321
|
+
// 取消全选
|
|
322
|
+
this._handleSelect([])
|
|
323
|
+
}
|
|
324
|
+
}}
|
|
325
|
+
>
|
|
326
|
+
全选
|
|
327
|
+
</Checkbox>
|
|
328
|
+
)}
|
|
329
|
+
{isShowDeletedSwitch && (
|
|
330
|
+
<Flex alignCenter>
|
|
331
|
+
<Flex row>
|
|
332
|
+
<Switch
|
|
333
|
+
style={{ width: 48 }}
|
|
334
|
+
checked={isFilterDelete}
|
|
335
|
+
onChange={(open) => {
|
|
336
|
+
this.setState({
|
|
337
|
+
isFilterDelete: open,
|
|
338
|
+
})
|
|
339
|
+
if (isCheckedAll) {
|
|
340
|
+
const newAvailableData = open
|
|
341
|
+
? flatFilterData.filter((item) => !item.deleted)
|
|
342
|
+
: flatFilterData
|
|
343
|
+
|
|
344
|
+
const valuesToSelect = newAvailableData.map((item) => item.value)
|
|
345
|
+
this._handleSelect(valuesToSelect)
|
|
346
|
+
}
|
|
347
|
+
}}
|
|
348
|
+
/>
|
|
349
|
+
</Flex>
|
|
350
|
+
<span className='gm-margin-left-5'>过滤已删除商品</span>
|
|
351
|
+
</Flex>
|
|
352
|
+
)}
|
|
353
|
+
</Flex>
|
|
354
|
+
)
|
|
355
|
+
}
|
|
356
|
+
|
|
235
357
|
private _renderList = (config: ConfigProviderProps): ReactNode => {
|
|
236
358
|
const {
|
|
237
359
|
selected = [],
|
|
@@ -242,9 +364,21 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
242
364
|
listHeight,
|
|
243
365
|
popupClassName,
|
|
244
366
|
renderCustomizedBottom,
|
|
367
|
+
isRenderDefaultBottom = false,
|
|
245
368
|
} = this.props
|
|
246
|
-
const { loading, searchValue, willActiveIndex } = this.state
|
|
247
|
-
|
|
369
|
+
const { loading, searchValue, willActiveIndex, isFilterDelete } = this.state
|
|
370
|
+
let filterData = this._getFilterData()
|
|
371
|
+
|
|
372
|
+
// 如果开启了过滤已删除商品功能,需要过滤掉已删除的商品
|
|
373
|
+
if (isFilterDelete) {
|
|
374
|
+
filterData = filterData
|
|
375
|
+
.map((group) => ({
|
|
376
|
+
...group,
|
|
377
|
+
children: group.children.filter((item) => !item.deleted),
|
|
378
|
+
}))
|
|
379
|
+
.filter((group) => group.children.length > 0)
|
|
380
|
+
}
|
|
381
|
+
|
|
248
382
|
return (
|
|
249
383
|
<ConfigProvider {...config}>
|
|
250
384
|
<div
|
|
@@ -284,8 +418,11 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
284
418
|
</div>
|
|
285
419
|
{!loading &&
|
|
286
420
|
!!filterData.length &&
|
|
287
|
-
renderCustomizedBottom
|
|
288
|
-
|
|
421
|
+
(renderCustomizedBottom
|
|
422
|
+
? renderCustomizedBottom(this._popoverRef, this.renderBottom)
|
|
423
|
+
: isRenderDefaultBottom
|
|
424
|
+
? this.renderBottom()
|
|
425
|
+
: null)}
|
|
289
426
|
</div>
|
|
290
427
|
</ConfigProvider>
|
|
291
428
|
)
|
|
@@ -325,7 +462,91 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
325
462
|
style,
|
|
326
463
|
popoverType,
|
|
327
464
|
children,
|
|
465
|
+
maxTagCount,
|
|
466
|
+
maxTagPlaceholder,
|
|
467
|
+
isRenderDefaultBottom = false,
|
|
328
468
|
} = this.props
|
|
469
|
+
|
|
470
|
+
// 处理 maxTagCount 逻辑
|
|
471
|
+
const renderSelectedItems = () => {
|
|
472
|
+
if (!multiple || !maxTagCount || selected.length === 0) {
|
|
473
|
+
return selected.map((item) => (
|
|
474
|
+
<Flex key={item.value as any} className='gm-more-select-selected-item'>
|
|
475
|
+
<Popover
|
|
476
|
+
disabled={!this.props.isKeyboard}
|
|
477
|
+
type='hover'
|
|
478
|
+
popup={<div className='gm-padding-10'>{item.text}</div>}
|
|
479
|
+
>
|
|
480
|
+
<Flex flex column>
|
|
481
|
+
{renderSelected!(item)}
|
|
482
|
+
</Flex>
|
|
483
|
+
</Popover>
|
|
484
|
+
{multiple ? (
|
|
485
|
+
<SVGRemove
|
|
486
|
+
className='gm-cursor gm-more-select-clear-btn'
|
|
487
|
+
onClick={disabled ? _.noop : this._handleClear.bind(this, item)}
|
|
488
|
+
/>
|
|
489
|
+
) : (
|
|
490
|
+
!disabledClose && ( // 是否不限时清除按钮,仅单选可用
|
|
491
|
+
<SVGCloseCircle
|
|
492
|
+
onClick={disabled ? _.noop : this._handleClear.bind(this, item)}
|
|
493
|
+
className='gm-cursor gm-more-select-clear-btn'
|
|
494
|
+
/>
|
|
495
|
+
)
|
|
496
|
+
)}
|
|
497
|
+
</Flex>
|
|
498
|
+
))
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// 处理 maxTagCount 逻辑
|
|
502
|
+
const isResponsive = maxTagCount === 'responsive'
|
|
503
|
+
let displayCount: number
|
|
504
|
+
|
|
505
|
+
if (isResponsive) {
|
|
506
|
+
displayCount = this.state.displayCount
|
|
507
|
+
} else {
|
|
508
|
+
displayCount = maxTagCount as number
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
const itemsToShow = selected.slice(0, displayCount)
|
|
512
|
+
const omittedItems = selected.slice(displayCount)
|
|
513
|
+
const omittedCount = selected.length - displayCount
|
|
514
|
+
|
|
515
|
+
return (
|
|
516
|
+
<>
|
|
517
|
+
{itemsToShow.map((item) => (
|
|
518
|
+
<Flex key={item.value as any} className='gm-more-select-selected-item'>
|
|
519
|
+
<Popover
|
|
520
|
+
disabled={!this.props.isKeyboard}
|
|
521
|
+
type='hover'
|
|
522
|
+
popup={<div className='gm-padding-10'>{item.text}</div>}
|
|
523
|
+
>
|
|
524
|
+
<Flex flex column>
|
|
525
|
+
{renderSelected!(item)}
|
|
526
|
+
</Flex>
|
|
527
|
+
</Popover>
|
|
528
|
+
<SVGRemove
|
|
529
|
+
className='gm-cursor gm-more-select-clear-btn'
|
|
530
|
+
onClick={disabled ? _.noop : this._handleClear.bind(this, item)}
|
|
531
|
+
/>
|
|
532
|
+
</Flex>
|
|
533
|
+
))}
|
|
534
|
+
{omittedCount > 0 && (
|
|
535
|
+
<Flex
|
|
536
|
+
key='omitted'
|
|
537
|
+
className='gm-more-select-selected-item gm-more-select-omitted-item'
|
|
538
|
+
>
|
|
539
|
+
{maxTagPlaceholder ? (
|
|
540
|
+
maxTagPlaceholder(omittedItems, omittedCount)
|
|
541
|
+
) : (
|
|
542
|
+
<span className='gm-more-select-omitted-count'>+{omittedCount}...</span>
|
|
543
|
+
)}
|
|
544
|
+
</Flex>
|
|
545
|
+
)}
|
|
546
|
+
</>
|
|
547
|
+
)
|
|
548
|
+
}
|
|
549
|
+
|
|
329
550
|
return (
|
|
330
551
|
<ConfigConsumer>
|
|
331
552
|
{(config) => (
|
|
@@ -340,7 +561,7 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
340
561
|
},
|
|
341
562
|
className
|
|
342
563
|
)}
|
|
343
|
-
style={style}
|
|
564
|
+
style={style as any}
|
|
344
565
|
>
|
|
345
566
|
<Popover
|
|
346
567
|
ref={this._popoverRef}
|
|
@@ -358,39 +579,7 @@ class MoreSelectBase<V extends string | number = string> extends Component<
|
|
|
358
579
|
className='gm-more-select-selected'
|
|
359
580
|
>
|
|
360
581
|
{selected.length !== 0 ? (
|
|
361
|
-
|
|
362
|
-
<Flex
|
|
363
|
-
key={item.value as any}
|
|
364
|
-
className='gm-more-select-selected-item'
|
|
365
|
-
>
|
|
366
|
-
<Popover
|
|
367
|
-
disabled={!this.props.isKeyboard}
|
|
368
|
-
type='hover'
|
|
369
|
-
popup={<div className='gm-padding-10'>{item.text}</div>}
|
|
370
|
-
>
|
|
371
|
-
<Flex flex column>
|
|
372
|
-
{renderSelected!(item)}
|
|
373
|
-
</Flex>
|
|
374
|
-
</Popover>
|
|
375
|
-
{multiple ? (
|
|
376
|
-
<SVGRemove
|
|
377
|
-
className='gm-cursor gm-more-select-clear-btn'
|
|
378
|
-
onClick={
|
|
379
|
-
disabled ? _.noop : this._handleClear.bind(this, item)
|
|
380
|
-
}
|
|
381
|
-
/>
|
|
382
|
-
) : (
|
|
383
|
-
!disabledClose && ( // 是否不限时清除按钮,仅单选可用
|
|
384
|
-
<SVGCloseCircle
|
|
385
|
-
onClick={
|
|
386
|
-
disabled ? _.noop : this._handleClear.bind(this, item)
|
|
387
|
-
}
|
|
388
|
-
className='gm-cursor gm-more-select-clear-btn'
|
|
389
|
-
/>
|
|
390
|
-
)
|
|
391
|
-
)}
|
|
392
|
-
</Flex>
|
|
393
|
-
))
|
|
582
|
+
renderSelectedItems()
|
|
394
583
|
) : (
|
|
395
584
|
// 加多个 避免对齐问题,有文本才有对齐
|
|
396
585
|
<div className='gm-text-placeholder'>{placeholder} </div>
|
|
@@ -85,6 +85,8 @@ class MoreSelect<V = any> extends Component<MoreSelectProps<V>> {
|
|
|
85
85
|
onSearch,
|
|
86
86
|
onClick,
|
|
87
87
|
renderListFilter,
|
|
88
|
+
maxTagCount,
|
|
89
|
+
maxTagPlaceholder,
|
|
88
90
|
...rest
|
|
89
91
|
} = this.props
|
|
90
92
|
let tempSelect = selected as MoreSelectDataItem<V>[]
|
|
@@ -129,6 +131,8 @@ class MoreSelect<V = any> extends Component<MoreSelectProps<V>> {
|
|
|
129
131
|
isGroupList={isGroupList}
|
|
130
132
|
onSearch={onSearch && this._handleSearch}
|
|
131
133
|
renderListFilter={renderListFilter && this._renderListFilter}
|
|
134
|
+
maxTagCount={maxTagCount}
|
|
135
|
+
maxTagPlaceholder={maxTagPlaceholder}
|
|
132
136
|
/>
|
|
133
137
|
)
|
|
134
138
|
}
|
|
@@ -318,6 +318,98 @@ export const ComMoreSelectWithIsGroupListMultiple = () => (
|
|
|
318
318
|
/>
|
|
319
319
|
)
|
|
320
320
|
|
|
321
|
+
export const ComMoreSelectWithMaxTagCount = () => {
|
|
322
|
+
// 创建一个包含多个选项的数据集
|
|
323
|
+
const manyOptions = [
|
|
324
|
+
{ value: 1, text: '选项1' },
|
|
325
|
+
{ value: 2, text: '选项2' },
|
|
326
|
+
{ value: 3, text: '选项3' },
|
|
327
|
+
{ value: 4, text: '选项4' },
|
|
328
|
+
{ value: 5, text: '选项5' },
|
|
329
|
+
{ value: 6, text: '选项6' },
|
|
330
|
+
{ value: 7, text: '选项7' },
|
|
331
|
+
{ value: 8, text: '选项8' },
|
|
332
|
+
]
|
|
333
|
+
|
|
334
|
+
// 预选多个选项
|
|
335
|
+
const preSelected = manyOptions.slice(0, 6)
|
|
336
|
+
|
|
337
|
+
return (
|
|
338
|
+
<div style={{ width: '300px' }}>
|
|
339
|
+
<h3>maxTagCount 示例</h3>
|
|
340
|
+
|
|
341
|
+
<div style={{ marginBottom: '20px' }}>
|
|
342
|
+
<h4>不使用 maxTagCount(显示所有选项)</h4>
|
|
343
|
+
<MoreSelect<number>
|
|
344
|
+
multiple
|
|
345
|
+
data={manyOptions}
|
|
346
|
+
selected={preSelected}
|
|
347
|
+
onSelect={(selected) => {
|
|
348
|
+
console.log('不限制显示数量:', selected)
|
|
349
|
+
}}
|
|
350
|
+
/>
|
|
351
|
+
</div>
|
|
352
|
+
|
|
353
|
+
<div style={{ marginBottom: '20px' }}>
|
|
354
|
+
<h4>maxTagCount={2}(最多显示2个选项)</h4>
|
|
355
|
+
<MoreSelect<number>
|
|
356
|
+
multiple
|
|
357
|
+
maxTagCount={2}
|
|
358
|
+
data={manyOptions}
|
|
359
|
+
selected={preSelected}
|
|
360
|
+
onSelect={(selected) => {
|
|
361
|
+
console.log('最多显示2个:', selected)
|
|
362
|
+
}}
|
|
363
|
+
/>
|
|
364
|
+
</div>
|
|
365
|
+
|
|
366
|
+
<div style={{ marginBottom: '20px' }}>
|
|
367
|
+
<h4>maxTagCount={3}(最多显示3个选项)</h4>
|
|
368
|
+
<MoreSelect<number>
|
|
369
|
+
multiple
|
|
370
|
+
maxTagCount={3}
|
|
371
|
+
data={manyOptions}
|
|
372
|
+
selected={preSelected}
|
|
373
|
+
onSelect={(selected) => {
|
|
374
|
+
console.log('最多显示3个:', selected)
|
|
375
|
+
}}
|
|
376
|
+
/>
|
|
377
|
+
</div>
|
|
378
|
+
|
|
379
|
+
<div style={{ marginBottom: '20px' }}>
|
|
380
|
+
<h4>maxTagCount=responsive(响应式模式)</h4>
|
|
381
|
+
<MoreSelect<number>
|
|
382
|
+
multiple
|
|
383
|
+
maxTagCount='responsive'
|
|
384
|
+
data={manyOptions}
|
|
385
|
+
selected={preSelected}
|
|
386
|
+
onSelect={(selected) => {
|
|
387
|
+
console.log('响应式模式:', selected)
|
|
388
|
+
}}
|
|
389
|
+
/>
|
|
390
|
+
</div>
|
|
391
|
+
|
|
392
|
+
<div style={{ marginBottom: '20px' }}>
|
|
393
|
+
<h4>自定义 maxTagPlaceholder</h4>
|
|
394
|
+
<MoreSelect<number>
|
|
395
|
+
multiple
|
|
396
|
+
maxTagCount={2}
|
|
397
|
+
maxTagPlaceholder={(omittedValues, omittedCount) => (
|
|
398
|
+
<span style={{ color: '#1890ff', fontWeight: 'bold' }}>
|
|
399
|
+
还有{omittedCount}项未显示
|
|
400
|
+
</span>
|
|
401
|
+
)}
|
|
402
|
+
data={manyOptions}
|
|
403
|
+
selected={preSelected}
|
|
404
|
+
onSelect={(selected) => {
|
|
405
|
+
console.log('自定义占位符:', selected)
|
|
406
|
+
}}
|
|
407
|
+
/>
|
|
408
|
+
</div>
|
|
409
|
+
</div>
|
|
410
|
+
)
|
|
411
|
+
}
|
|
412
|
+
|
|
321
413
|
export default {
|
|
322
414
|
title: '表单/MoreSelect',
|
|
323
415
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { Popover } from '@gm-pc/react'
|
|
2
1
|
import { CSSProperties, ReactNode, KeyboardEvent } from 'react'
|
|
2
|
+
import { Popover } from '../popover'
|
|
3
3
|
|
|
4
4
|
/** 普通的数据格式 */
|
|
5
5
|
interface MoreSelectDataItem<V extends string | number = string> {
|
|
6
6
|
value: V
|
|
7
7
|
text: string
|
|
8
8
|
disabled?: boolean
|
|
9
|
+
/** 是否已删除 */
|
|
10
|
+
deleted?: boolean
|
|
9
11
|
[key: string]: any
|
|
10
12
|
}
|
|
11
13
|
|
|
@@ -36,10 +38,13 @@ interface MoreSelectCommonProps<V extends string | number = string> {
|
|
|
36
38
|
renderListItem?(value: MoreSelectDataItem<V>, index: number): ReactNode
|
|
37
39
|
|
|
38
40
|
/** 自定义popup底部渲染 */
|
|
39
|
-
renderCustomizedBottom?(
|
|
41
|
+
renderCustomizedBottom?(
|
|
42
|
+
ref: React.RefObject<Popover>,
|
|
43
|
+
defaultBottom: () => ReactNode
|
|
44
|
+
): ReactNode
|
|
40
45
|
|
|
41
46
|
/**
|
|
42
|
-
*
|
|
47
|
+
* 自定义"空状态"渲染
|
|
43
48
|
*
|
|
44
49
|
* 若函数返回 undefined 则使用默认的空状态
|
|
45
50
|
*/
|
|
@@ -60,6 +65,14 @@ interface MoreSelectCommonProps<V extends string | number = string> {
|
|
|
60
65
|
/** 目前为了 keyboard */
|
|
61
66
|
isKeyboard?: boolean
|
|
62
67
|
onKeyDown?(event: KeyboardEvent): void
|
|
68
|
+
|
|
69
|
+
/** 最多显示的选中项数量,超出部分会折叠 */
|
|
70
|
+
maxTagCount?: number | 'responsive'
|
|
71
|
+
/** 自定义超出 maxTagCount 时显示的内容 */
|
|
72
|
+
maxTagPlaceholder?: (
|
|
73
|
+
omittedValues: MoreSelectDataItem<V>[],
|
|
74
|
+
omittedCount: number
|
|
75
|
+
) => ReactNode
|
|
63
76
|
}
|
|
64
77
|
|
|
65
78
|
interface MoreSelectBaseProps<V extends string | number = string>
|
|
@@ -80,6 +93,12 @@ interface MoreSelectBaseProps<V extends string | number = string>
|
|
|
80
93
|
): MoreSelectGroupDataItem<V>[]
|
|
81
94
|
/** 是否在active的时候搜索,订单业务相关,searchValue放在localstorage */
|
|
82
95
|
searchOnActive?: boolean
|
|
96
|
+
/** 是否展示全选以及过滤已删除商品 */
|
|
97
|
+
isRenderDefaultBottom?: boolean
|
|
98
|
+
/** 是否展示已删除商品 */
|
|
99
|
+
isShowDeletedSwitch?: boolean
|
|
100
|
+
/** 是否展示全选 */
|
|
101
|
+
isShowCheckedAll?: boolean
|
|
83
102
|
}
|
|
84
103
|
|
|
85
104
|
type MoreSelectData<V extends string | number = string> =
|