@gm-pc/react 1.27.5-beta.0 → 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.27.5-beta.0",
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.5-beta.0",
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": "62f3bf16794e2d1778f97dc45c342746b9ea53f9"
51
+ "gitHead": "107461a0dd5c644e10482ed5f3ed8638fee436cc"
52
52
  }
@@ -2,7 +2,7 @@ import { HTMLAttributes, ReactNode } from 'react'
2
2
 
3
3
  interface LoadingProps {
4
4
  size?: string
5
- type: any
5
+ type?: any
6
6
  }
7
7
 
8
8
  interface LoadingChunkProps extends HTMLAttributes<HTMLDivElement> {
@@ -20,13 +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
- searchValue: string | undefined
26
+ searchValue: string
26
27
  loading: boolean
27
28
  /* keyboard 默认第一个位置 */
28
29
  willActiveIndex: number | null
29
- isOpen: boolean
30
+ isCheckedAll: boolean
31
+ isFilterDelete: boolean
32
+ displayCount: number
30
33
  }
31
34
 
32
35
  // @todo keydown item disabled
@@ -39,10 +42,12 @@ class MoreSelectBase<V extends string | number = string> extends Component<
39
42
  static renderListFilterPinYin = renderListFilterPinYin
40
43
 
41
44
  readonly state: MoreSelectBaseState = {
42
- searchValue: (undefined as unknown) as string,
45
+ searchValue: '',
43
46
  loading: false,
44
47
  willActiveIndex: this.props.isKeyboard ? 0 : null,
45
- isOpen: false,
48
+ isCheckedAll: false,
49
+ isFilterDelete: false,
50
+ displayCount: 0,
46
51
  }
47
52
 
48
53
  private _isUnmounted = false
@@ -50,6 +55,7 @@ class MoreSelectBase<V extends string | number = string> extends Component<
50
55
  private _selectionRef = createRef<HTMLDivElement>()
51
56
  private _popoverRef = createRef<Popover>()
52
57
  private _inputRef = createRef<HTMLInputElement>()
58
+ private _resizeObserver: ResizeObserver | null = null
53
59
 
54
60
  private _filterData: MoreSelectGroupDataItem<V>[] | undefined
55
61
 
@@ -64,8 +70,44 @@ class MoreSelectBase<V extends string | number = string> extends Component<
64
70
  }
65
71
  }
66
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
+
67
106
  componentWillUnmount() {
68
- this._isUnmounted = false
107
+ this._isUnmounted = true
108
+ if (this._resizeObserver) {
109
+ this._resizeObserver.disconnect()
110
+ }
69
111
  }
70
112
 
71
113
  public apiDoFocus = (): void => {
@@ -135,10 +177,6 @@ class MoreSelectBase<V extends string | number = string> extends Component<
135
177
  const searchValue = event.target.value
136
178
  this.setState({ searchValue })
137
179
  this._debounceDoSearch(searchValue)
138
- if (this.props.isSameAntd) {
139
- // eslint-disable-next-line no-unused-expressions
140
- this._popoverRef.current?.apiDoSetActive(true)
141
- }
142
180
  setTimeout(() => {
143
181
  // eslint-disable-next-line no-unused-expressions
144
182
  isInitSearch && this._inputRef.current?.select()
@@ -172,7 +210,7 @@ class MoreSelectBase<V extends string | number = string> extends Component<
172
210
  onSelect(willSelected)
173
211
  }
174
212
 
175
- private _handlePopupKeyDown = (event: KeyboardEvent): void => {
213
+ private _handlePopupKeyDown = (event: KeyboardEvent<HTMLDivElement>): void => {
176
214
  const { onKeyDown } = this.props
177
215
  let willActiveIndex = this.state.willActiveIndex as number
178
216
  if (!onKeyDown) {
@@ -238,19 +276,81 @@ class MoreSelectBase<V extends string | number = string> extends Component<
238
276
  )
239
277
  }
240
278
 
241
- private _renderSearchInput = () => {
242
- const { searchPlaceholder } = this.props
243
- const { searchValue } = this.state
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
+
244
300
  return (
245
- <div className='gm-more-select-popup-input'>
246
- <Input
247
- ref={this._inputRef}
248
- autoFocus
249
- value={searchValue}
250
- onChange={this._handleChange}
251
- placeholder={searchPlaceholder}
252
- />
253
- </div>
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>
254
354
  )
255
355
  }
256
356
 
@@ -260,20 +360,40 @@ class MoreSelectBase<V extends string | number = string> extends Component<
260
360
  multiple,
261
361
  isGroupList,
262
362
  renderListItem,
363
+ searchPlaceholder,
263
364
  listHeight,
264
365
  popupClassName,
265
366
  renderCustomizedBottom,
266
- isSameAntd = false,
367
+ isRenderDefaultBottom = false,
267
368
  } = this.props
268
- const { loading, willActiveIndex } = this.state
269
- const filterData = this._getFilterData()
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
+
270
382
  return (
271
383
  <ConfigProvider {...config}>
272
384
  <div
273
385
  className={classNames('gm-more-select-popup', popupClassName)}
274
386
  onKeyDown={this._handlePopupKeyDown}
275
387
  >
276
- {isSameAntd ? null : this._renderSearchInput()}
388
+ <div className='gm-more-select-popup-input'>
389
+ <Input
390
+ ref={this._inputRef}
391
+ autoFocus
392
+ value={searchValue}
393
+ onChange={this._handleChange}
394
+ placeholder={searchPlaceholder}
395
+ />
396
+ </div>
277
397
  <div style={{ height: listHeight }}>
278
398
  {loading && (
279
399
  <Flex alignCenter justifyCenter className='gm-bg gm-padding-5'>
@@ -298,8 +418,11 @@ class MoreSelectBase<V extends string | number = string> extends Component<
298
418
  </div>
299
419
  {!loading &&
300
420
  !!filterData.length &&
301
- renderCustomizedBottom &&
302
- renderCustomizedBottom(this._popoverRef)}
421
+ (renderCustomizedBottom
422
+ ? renderCustomizedBottom(this._popoverRef, this.renderBottom)
423
+ : isRenderDefaultBottom
424
+ ? this.renderBottom()
425
+ : null)}
303
426
  </div>
304
427
  </ConfigProvider>
305
428
  )
@@ -313,16 +436,7 @@ class MoreSelectBase<V extends string | number = string> extends Component<
313
436
  }
314
437
 
315
438
  private _handlePopoverVisibleChange = (active: boolean) => {
316
- if (this.props.isSameAntd) {
317
- this.setState({
318
- isOpen: active,
319
- })
320
- if (!this.props.multiple && !active) {
321
- this.setState({ searchValue: undefined })
322
- }
323
- }
324
-
325
- if (active && this.props.searchOnActive && !this.props.isSameAntd) {
439
+ if (active && this.props.searchOnActive) {
326
440
  const searchValue = localStorage.getItem('_GM-PC_MORESELECT_SEARCHVALUE')
327
441
  if (searchValue) {
328
442
  this.setState({ searchValue })
@@ -348,10 +462,90 @@ class MoreSelectBase<V extends string | number = string> extends Component<
348
462
  style,
349
463
  popoverType,
350
464
  children,
351
- searchPlaceholder,
352
- isSameAntd = false,
465
+ maxTagCount,
466
+ maxTagPlaceholder,
467
+ isRenderDefaultBottom = false,
353
468
  } = this.props
354
- const { searchValue } = this.state
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
+ }
355
549
 
356
550
  return (
357
551
  <ConfigConsumer>
@@ -367,15 +561,13 @@ class MoreSelectBase<V extends string | number = string> extends Component<
367
561
  },
368
562
  className
369
563
  )}
370
- style={style}
564
+ style={style as any}
371
565
  >
372
566
  <Popover
373
567
  ref={this._popoverRef}
374
568
  type={popoverType}
375
569
  popup={() => this._renderList(config)}
376
- disabled={
377
- disabled || (!isSameAntd ? false : this.state.searchValue === undefined)
378
- }
570
+ disabled={disabled}
379
571
  isInPopup={isInPopup}
380
572
  onVisibleChange={this._handlePopoverVisibleChange}
381
573
  >
@@ -384,78 +576,13 @@ class MoreSelectBase<V extends string | number = string> extends Component<
384
576
  ref={this._selectionRef}
385
577
  tabIndex={0}
386
578
  wrap
387
- className={classNames({
388
- 'gm-more-select-selected': true,
389
- 'gm-more-select-selected-antd': isSameAntd,
390
- })}
579
+ className='gm-more-select-selected'
391
580
  >
392
581
  {selected.length !== 0 ? (
393
- selected.map((item) => (
394
- <Flex
395
- key={item.value as any}
396
- className='gm-more-select-selected-item'
397
- alignCenter
398
- >
399
- <Popover
400
- disabled={!this.props.isKeyboard}
401
- type='hover'
402
- popup={<div className='gm-padding-10'>{item.text}</div>}
403
- >
404
- <Flex flex column>
405
- {isSameAntd ? (
406
- <div className='gm-more-select-popup-input'>
407
- <Input
408
- ref={this._inputRef}
409
- value={
410
- !this.state.isOpen
411
- ? renderSelected!(item)
412
- : searchValue
413
- }
414
- onChange={this._handleChange}
415
- placeholder={searchPlaceholder}
416
- className='gm-more-select-popup-input-no-border'
417
- />
418
- </div>
419
- ) : (
420
- renderSelected!(item)
421
- )}
422
- </Flex>
423
- </Popover>
424
- {multiple ? (
425
- <SVGRemove
426
- className='gm-cursor gm-more-select-clear-btn'
427
- onClick={
428
- disabled ? _.noop : this._handleClear.bind(this, item)
429
- }
430
- />
431
- ) : (
432
- !disabledClose && ( // 是否不限时清除按钮,仅单选可用
433
- <SVGCloseCircle
434
- onClick={
435
- disabled ? _.noop : this._handleClear.bind(this, item)
436
- }
437
- className='gm-cursor gm-more-select-clear-btn'
438
- />
439
- )
440
- )}
441
- </Flex>
442
- ))
582
+ renderSelectedItems()
443
583
  ) : (
444
584
  // 加多个 &nbsp; 避免对齐问题,有文本才有对齐
445
- <>
446
- {isSameAntd ? (
447
- <Input
448
- ref={this._inputRef}
449
- value={searchValue}
450
- onChange={this._handleChange}
451
- placeholder={searchPlaceholder}
452
- className='gm-more-select-popup-input-no-border'
453
- />
454
- ) : (
455
- <div className='gm-text-placeholder'>{placeholder}&nbsp; </div>
456
- )}
457
- </>
458
- //
585
+ <div className='gm-text-placeholder'>{placeholder}&nbsp; </div>
459
586
  )}
460
587
  </Flex>
461
588
  )}
@@ -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
  }
@@ -14,15 +14,10 @@
14
14
  }
15
15
  }
16
16
 
17
- .gm-more-select-selected-antd {
18
- padding: 0 12px;
19
- }
20
-
21
17
  .gm-more-select-clear-btn {
22
18
  position: absolute;
23
- right: 4px;
24
- top: 50%;
25
- transform: translateY(-50%);
19
+ right: 5px;
20
+ top: 7px;
26
21
  cursor: pointer;
27
22
  color: var(--gm-color-desc);
28
23
  }
@@ -75,10 +70,3 @@
75
70
  }
76
71
  }
77
72
  }
78
-
79
- .gm-more-select-popup-input-no-border {
80
- border: none !important;
81
- border-radius: 0 !important;
82
- padding: 0 !important;
83
- box-shadow: none !important;
84
- }
@@ -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?(ref: React.RefObject<Popover>): ReactNode
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,8 +93,12 @@ interface MoreSelectBaseProps<V extends string | number = string>
80
93
  ): MoreSelectGroupDataItem<V>[]
81
94
  /** 是否在active的时候搜索,订单业务相关,searchValue放在localstorage */
82
95
  searchOnActive?: boolean
83
- /** 是否用select */
84
- isSameAntd?: boolean
96
+ /** 是否展示全选以及过滤已删除商品 */
97
+ isRenderDefaultBottom?: boolean
98
+ /** 是否展示已删除商品 */
99
+ isShowDeletedSwitch?: boolean
100
+ /** 是否展示全选 */
101
+ isShowCheckedAll?: boolean
85
102
  }
86
103
 
87
104
  type MoreSelectData<V extends string | number = string> =
@@ -6,13 +6,17 @@ import _ from 'lodash'
6
6
  import { getLocale } from '@gm-pc/locales'
7
7
 
8
8
  function getLimitData(limit: number, pageSizeOptions?: string[]) {
9
- const limitData = [
10
- { value: limit, text: limit + '' },
11
- { value: 10, text: '10' },
12
- { value: 20, text: '20' },
13
- { value: 50, text: '50' },
14
- ...(pageSizeOptions?.map((v) => ({ value: Number(v), text: v })) || []),
15
- ]
9
+ let limitData = []
10
+ if (pageSizeOptions) {
11
+ limitData = pageSizeOptions.map((v) => ({ value: Number(v), text: v }))
12
+ } else {
13
+ limitData = [
14
+ { value: limit, text: limit + '' },
15
+ { value: 10, text: '10' },
16
+ { value: 20, text: '20' },
17
+ { value: 50, text: '50' },
18
+ ]
19
+ }
16
20
 
17
21
  return _.orderBy(
18
22
  _.uniqBy(limitData, (v) => v.value),