@gm-pc/react 1.27.5-beta.0 → 1.28.0-beta.1

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.1",
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.1",
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": "994ee00d0f8515ba21e8522f0e66f717bc0859d9"
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: true,
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,42 @@ class MoreSelectBase<V extends string | number = string> extends Component<
64
70
  }
65
71
  }
66
72
 
73
+ componentDidMount() {
74
+ const { maxTagCount, tagItemWidth = 80, omittedTagWidth = 45 } = 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 availableWidth = width - omittedTagWidth
81
+ const newDisplayCount = Math.floor(availableWidth / tagItemWidth)
82
+ if (this.state.displayCount !== newDisplayCount) {
83
+ this.setState({ displayCount: newDisplayCount > 0 ? newDisplayCount : 0 })
84
+ }
85
+ }
86
+ }, 0)
87
+
88
+ this._resizeObserver = new ResizeObserver((entries) => {
89
+ for (const entry of entries) {
90
+ const { width } = entry.contentRect
91
+ // Estimate item width, let's say 80px.
92
+ const availableWidth = width - omittedTagWidth
93
+ const newDisplayCount = Math.floor(availableWidth / tagItemWidth)
94
+
95
+ if (this.state.displayCount !== newDisplayCount) {
96
+ this.setState({ displayCount: newDisplayCount })
97
+ }
98
+ }
99
+ })
100
+ this._resizeObserver.observe(this._selectionRef.current)
101
+ }
102
+ }
103
+
67
104
  componentWillUnmount() {
68
- this._isUnmounted = false
105
+ this._isUnmounted = true
106
+ if (this._resizeObserver) {
107
+ this._resizeObserver.disconnect()
108
+ }
69
109
  }
70
110
 
71
111
  public apiDoFocus = (): void => {
@@ -135,10 +175,6 @@ class MoreSelectBase<V extends string | number = string> extends Component<
135
175
  const searchValue = event.target.value
136
176
  this.setState({ searchValue })
137
177
  this._debounceDoSearch(searchValue)
138
- if (this.props.isSameAntd) {
139
- // eslint-disable-next-line no-unused-expressions
140
- this._popoverRef.current?.apiDoSetActive(true)
141
- }
142
178
  setTimeout(() => {
143
179
  // eslint-disable-next-line no-unused-expressions
144
180
  isInitSearch && this._inputRef.current?.select()
@@ -172,7 +208,7 @@ class MoreSelectBase<V extends string | number = string> extends Component<
172
208
  onSelect(willSelected)
173
209
  }
174
210
 
175
- private _handlePopupKeyDown = (event: KeyboardEvent): void => {
211
+ private _handlePopupKeyDown = (event: KeyboardEvent<HTMLDivElement>): void => {
176
212
  const { onKeyDown } = this.props
177
213
  let willActiveIndex = this.state.willActiveIndex as number
178
214
  if (!onKeyDown) {
@@ -238,19 +274,80 @@ class MoreSelectBase<V extends string | number = string> extends Component<
238
274
  )
239
275
  }
240
276
 
241
- private _renderSearchInput = () => {
242
- const { searchPlaceholder } = this.props
243
- const { searchValue } = this.state
277
+ renderBottom = () => {
278
+ const {
279
+ selected = [],
280
+ isShowDeletedSwitch = true,
281
+ isShowCheckedAll = true,
282
+ } = this.props
283
+ const { isCheckedAll, isFilterDelete } = this.state
284
+ const flatFilterData = this._getFlatFilterData()
285
+
286
+ // 根据过滤状态决定是否过滤已删除商品
287
+ const availableData = isFilterDelete
288
+ ? flatFilterData.filter((item) => !item.deleted)
289
+ : flatFilterData
290
+
291
+ // 检查是否所有可用数据都被选中
292
+ const allSelected =
293
+ availableData.length > 0 &&
294
+ availableData.every((item) =>
295
+ selected.some((selectedItem) => selectedItem.value === item.value)
296
+ )
297
+
244
298
  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>
299
+ <Flex
300
+ justifyBetween
301
+ className='tw-p-[8px] gm-more-select-default-bottom'
302
+ alignCenter
303
+ >
304
+ {isShowCheckedAll && (
305
+ <Checkbox
306
+ checked={allSelected}
307
+ onChange={(e) => {
308
+ const isChecked = e.target.checked
309
+ this.setState({
310
+ isCheckedAll: isChecked,
311
+ })
312
+
313
+ if (isChecked) {
314
+ // 全选当前过滤后的可用数据
315
+ const valuesToSelect = availableData.map((item) => item.value)
316
+ this._handleSelect(valuesToSelect)
317
+ } else {
318
+ // 取消全选
319
+ this._handleSelect([])
320
+ }
321
+ }}
322
+ >
323
+ 全选({availableData.length})
324
+ </Checkbox>
325
+ )}
326
+ {isShowDeletedSwitch && (
327
+ <Flex alignCenter>
328
+ <Flex row>
329
+ <Switch
330
+ style={{ width: 48 }}
331
+ checked={isFilterDelete}
332
+ onChange={(open) => {
333
+ this.setState({
334
+ isFilterDelete: open,
335
+ })
336
+ if (isCheckedAll) {
337
+ const newAvailableData = open
338
+ ? flatFilterData.filter((item) => !item.deleted)
339
+ : flatFilterData
340
+
341
+ const valuesToSelect = newAvailableData.map((item) => item.value)
342
+ this._handleSelect(valuesToSelect)
343
+ }
344
+ }}
345
+ />
346
+ </Flex>
347
+ <span className='gm-margin-left-5'>过滤已删除商品</span>
348
+ </Flex>
349
+ )}
350
+ </Flex>
254
351
  )
255
352
  }
256
353
 
@@ -260,20 +357,40 @@ class MoreSelectBase<V extends string | number = string> extends Component<
260
357
  multiple,
261
358
  isGroupList,
262
359
  renderListItem,
360
+ searchPlaceholder,
263
361
  listHeight,
264
362
  popupClassName,
265
363
  renderCustomizedBottom,
266
- isSameAntd = false,
364
+ isRenderDefaultBottom = false,
267
365
  } = this.props
268
- const { loading, willActiveIndex } = this.state
269
- const filterData = this._getFilterData()
366
+ const { loading, searchValue, willActiveIndex, isFilterDelete } = this.state
367
+ let filterData = this._getFilterData()
368
+
369
+ // 如果开启了过滤已删除商品功能,需要过滤掉已删除的商品
370
+ if (isFilterDelete) {
371
+ filterData = filterData
372
+ .map((group) => ({
373
+ ...group,
374
+ children: group.children.filter((item) => !item.deleted),
375
+ }))
376
+ .filter((group) => group.children.length > 0)
377
+ }
378
+
270
379
  return (
271
380
  <ConfigProvider {...config}>
272
381
  <div
273
382
  className={classNames('gm-more-select-popup', popupClassName)}
274
383
  onKeyDown={this._handlePopupKeyDown}
275
384
  >
276
- {isSameAntd ? null : this._renderSearchInput()}
385
+ <div className='gm-more-select-popup-input'>
386
+ <Input
387
+ ref={this._inputRef}
388
+ autoFocus
389
+ value={searchValue}
390
+ onChange={this._handleChange}
391
+ placeholder={searchPlaceholder}
392
+ />
393
+ </div>
277
394
  <div style={{ height: listHeight }}>
278
395
  {loading && (
279
396
  <Flex alignCenter justifyCenter className='gm-bg gm-padding-5'>
@@ -298,8 +415,11 @@ class MoreSelectBase<V extends string | number = string> extends Component<
298
415
  </div>
299
416
  {!loading &&
300
417
  !!filterData.length &&
301
- renderCustomizedBottom &&
302
- renderCustomizedBottom(this._popoverRef)}
418
+ (renderCustomizedBottom
419
+ ? renderCustomizedBottom(this._popoverRef, this.renderBottom)
420
+ : isRenderDefaultBottom
421
+ ? this.renderBottom()
422
+ : null)}
303
423
  </div>
304
424
  </ConfigProvider>
305
425
  )
@@ -313,16 +433,7 @@ class MoreSelectBase<V extends string | number = string> extends Component<
313
433
  }
314
434
 
315
435
  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) {
436
+ if (active && this.props.searchOnActive) {
326
437
  const searchValue = localStorage.getItem('_GM-PC_MORESELECT_SEARCHVALUE')
327
438
  if (searchValue) {
328
439
  this.setState({ searchValue })
@@ -348,10 +459,89 @@ class MoreSelectBase<V extends string | number = string> extends Component<
348
459
  style,
349
460
  popoverType,
350
461
  children,
351
- searchPlaceholder,
352
- isSameAntd = false,
462
+ maxTagCount,
463
+ maxTagPlaceholder,
353
464
  } = this.props
354
- const { searchValue } = this.state
465
+
466
+ // 处理 maxTagCount 逻辑
467
+ const renderSelectedItems = () => {
468
+ if (!multiple || !maxTagCount || selected.length === 0) {
469
+ return selected.map((item) => (
470
+ <Flex key={item.value as any} className='gm-more-select-selected-item'>
471
+ <Popover
472
+ disabled={!this.props.isKeyboard}
473
+ type='hover'
474
+ popup={<div className='gm-padding-10'>{item.text}</div>}
475
+ >
476
+ <Flex flex column>
477
+ {renderSelected!(item)}
478
+ </Flex>
479
+ </Popover>
480
+ {multiple ? (
481
+ <SVGRemove
482
+ className='gm-cursor gm-more-select-clear-btn'
483
+ onClick={disabled ? _.noop : this._handleClear.bind(this, item)}
484
+ />
485
+ ) : (
486
+ !disabledClose && ( // 是否不限时清除按钮,仅单选可用
487
+ <SVGCloseCircle
488
+ onClick={disabled ? _.noop : this._handleClear.bind(this, item)}
489
+ className='gm-cursor gm-more-select-clear-btn'
490
+ />
491
+ )
492
+ )}
493
+ </Flex>
494
+ ))
495
+ }
496
+
497
+ // 处理 maxTagCount 逻辑
498
+ const isResponsive = maxTagCount === 'responsive'
499
+ let displayCount: number
500
+
501
+ if (isResponsive) {
502
+ displayCount = this.state.displayCount
503
+ } else {
504
+ displayCount = maxTagCount as number
505
+ }
506
+
507
+ const itemsToShow = selected.slice(0, displayCount)
508
+ const omittedItems = selected.slice(displayCount)
509
+ const omittedCount = selected.length - displayCount
510
+
511
+ return (
512
+ <>
513
+ {itemsToShow.map((item) => (
514
+ <Flex key={item.value as any} className='gm-more-select-selected-item'>
515
+ <Popover
516
+ disabled={!this.props.isKeyboard}
517
+ type='hover'
518
+ popup={<div className='gm-padding-10'>{item.text}</div>}
519
+ >
520
+ <Flex flex column>
521
+ {renderSelected!(item)}
522
+ </Flex>
523
+ </Popover>
524
+ <SVGRemove
525
+ className='gm-cursor gm-more-select-clear-btn'
526
+ onClick={disabled ? _.noop : this._handleClear.bind(this, item)}
527
+ />
528
+ </Flex>
529
+ ))}
530
+ {omittedCount > 0 && (
531
+ <Flex
532
+ key='omitted'
533
+ className='gm-more-select-selected-item gm-more-select-omitted-item'
534
+ >
535
+ {maxTagPlaceholder ? (
536
+ maxTagPlaceholder(omittedItems, omittedCount)
537
+ ) : (
538
+ <span className='gm-more-select-omitted-count'>+{omittedCount}...</span>
539
+ )}
540
+ </Flex>
541
+ )}
542
+ </>
543
+ )
544
+ }
355
545
 
356
546
  return (
357
547
  <ConfigConsumer>
@@ -367,15 +557,13 @@ class MoreSelectBase<V extends string | number = string> extends Component<
367
557
  },
368
558
  className
369
559
  )}
370
- style={style}
560
+ style={style as any}
371
561
  >
372
562
  <Popover
373
563
  ref={this._popoverRef}
374
564
  type={popoverType}
375
565
  popup={() => this._renderList(config)}
376
- disabled={
377
- disabled || (!isSameAntd ? false : this.state.searchValue === undefined)
378
- }
566
+ disabled={disabled}
379
567
  isInPopup={isInPopup}
380
568
  onVisibleChange={this._handlePopoverVisibleChange}
381
569
  >
@@ -384,78 +572,13 @@ class MoreSelectBase<V extends string | number = string> extends Component<
384
572
  ref={this._selectionRef}
385
573
  tabIndex={0}
386
574
  wrap
387
- className={classNames({
388
- 'gm-more-select-selected': true,
389
- 'gm-more-select-selected-antd': isSameAntd,
390
- })}
575
+ className='gm-more-select-selected'
391
576
  >
392
577
  {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
- ))
578
+ renderSelectedItems()
443
579
  ) : (
444
580
  // 加多个 &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
- //
581
+ <div className='gm-text-placeholder'>{placeholder}&nbsp; </div>
459
582
  )}
460
583
  </Flex>
461
584
  )}
@@ -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>()
@@ -85,6 +91,8 @@ class MoreSelect<V = any> extends Component<MoreSelectProps<V>> {
85
91
  onSearch,
86
92
  onClick,
87
93
  renderListFilter,
94
+ maxTagCount,
95
+ maxTagPlaceholder,
88
96
  ...rest
89
97
  } = this.props
90
98
  let tempSelect = selected as MoreSelectDataItem<V>[]
@@ -129,6 +137,8 @@ class MoreSelect<V = any> extends Component<MoreSelectProps<V>> {
129
137
  isGroupList={isGroupList}
130
138
  onSearch={onSearch && this._handleSearch}
131
139
  renderListFilter={renderListFilter && this._renderListFilter}
140
+ maxTagCount={maxTagCount}
141
+ maxTagPlaceholder={maxTagPlaceholder}
132
142
  />
133
143
  )
134
144
  }
@@ -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
  }
@@ -76,9 +71,6 @@
76
71
  }
77
72
  }
78
73
 
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;
74
+ .gm-more-select-default-bottom {
75
+ border-top: 1px solid var(--gm-color-border);
84
76
  }
@@ -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,25 @@ 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
76
+
77
+ /** 是否展示全选以及过滤已删除商品 */
78
+ isRenderDefaultBottom?: boolean
79
+ /** 是否展示已删除商品 */
80
+ isShowDeletedSwitch?: boolean
81
+ /** 是否展示全选 */
82
+ isShowCheckedAll?: boolean
83
+ /** 当设置 maxTagCount 的时候的宽度, 根据这个去计算显示内容 */
84
+ tagItemWidth?: number
85
+ /** +N 显示的宽度 */
86
+ omittedTagWidth?: number
63
87
  }
64
88
 
65
89
  interface MoreSelectBaseProps<V extends string | number = string>
@@ -80,8 +104,12 @@ interface MoreSelectBaseProps<V extends string | number = string>
80
104
  ): MoreSelectGroupDataItem<V>[]
81
105
  /** 是否在active的时候搜索,订单业务相关,searchValue放在localstorage */
82
106
  searchOnActive?: boolean
83
- /** 是否用select */
84
- isSameAntd?: boolean
107
+ /** 是否展示全选以及过滤已删除商品 */
108
+ isRenderDefaultBottom?: boolean
109
+ /** 是否展示已删除商品 */
110
+ isShowDeletedSwitch?: boolean
111
+ /** 是否展示全选 */
112
+ isShowCheckedAll?: boolean
85
113
  }
86
114
 
87
115
  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),