@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gm-pc/react",
3
- "version": "1.28.0-beta.0",
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.0",
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": "107461a0dd5c644e10482ed5f3ed8638fee436cc"
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, Switch } from '@gm-pc/react'
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: false,
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 / 80)
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 / 80)
93
+ const newDisplayCount = Math.floor(availableWidth / tagItemWidth)
96
94
 
97
95
  if (this.state.displayCount !== newDisplayCount) {
98
- this.setState({ displayCount: newDisplayCount > 0 ? newDisplayCount : 0 })
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
- this.setState({ loading: false })
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
- this._handleSelect(valuesToSelect)
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._handleSelect([])
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
- style={{ width: 48 }}
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
- 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
- }
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'>过滤已删除商品</span>
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>()
@@ -70,3 +70,7 @@
70
70
  }
71
71
  }
72
72
  }
73
+
74
+ .gm-more-select-default-bottom {
75
+ border-top: 1px solid var(--gm-color-border);
76
+ }
@@ -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<void> | void
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> | void
131
+ onSearch?(searchWord: string, data: MoreSelectData<V>): Promise<void | any> | any
121
132
  /** 点击回调 */
122
133
  onClick?(selected: MoreSelectSelected<V>[]): void
123
134
 
@@ -6,6 +6,10 @@
6
6
  border-radius: calc(var(--gm-switch-size-height) / 2);
7
7
  background-color: var(--gm-color-bg-switch);
8
8
 
9
+ &.gm-switch-small {
10
+ --gm-switch-size-height: 16px;
11
+ }
12
+
9
13
  &::before {
10
14
  position: absolute;
11
15
  content: '';
@@ -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'