@gm-pc/react 1.21.0 → 1.21.1-alpha.5

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.
@@ -19,6 +19,7 @@ import { Loading } from '../loading'
19
19
  import { getLocale } from '@gm-pc/locales'
20
20
  import { ListBase } from '../list'
21
21
  import { findDOMNode } from 'react-dom'
22
+ import { ConfigConsumer, ConfigProvider, ConfigProviderProps } from '../config_provider'
22
23
 
23
24
  interface MoreSelectBaseState {
24
25
  searchValue: string
@@ -231,7 +232,7 @@ class MoreSelectBase<V extends string | number = string> extends Component<
231
232
  )
232
233
  }
233
234
 
234
- private _renderList = (): ReactNode => {
235
+ private _renderList = (config: ConfigProviderProps): ReactNode => {
235
236
  const {
236
237
  selected = [],
237
238
  multiple,
@@ -245,46 +246,48 @@ class MoreSelectBase<V extends string | number = string> extends Component<
245
246
  const { loading, searchValue, willActiveIndex } = this.state
246
247
  const filterData = this._getFilterData()
247
248
  return (
248
- <div
249
- className={classNames('gm-more-select-popup', popupClassName)}
250
- onKeyDown={this._handlePopupKeyDown}
251
- >
252
- <div className='gm-more-select-popup-input'>
253
- <Input
254
- ref={this._inputRef}
255
- autoFocus
256
- value={searchValue}
257
- onChange={this._handleChange}
258
- placeholder={searchPlaceholder}
259
- />
260
- </div>
261
- <div style={{ height: listHeight }}>
262
- {loading && (
263
- <Flex alignCenter justifyCenter className='gm-bg gm-padding-5'>
264
- <Loading size='20px' />
265
- </Flex>
266
- )}
267
- {!loading && !filterData.length && this._renderEmpty()}
268
- {!loading && !!filterData.length && (
269
- <ListBase
270
- selected={selected.map((v) => v.value)}
271
- data={filterData}
272
- multiple={multiple}
273
- isGroupList={isGroupList}
274
- className='gm-border-0'
275
- renderItem={renderListItem}
276
- onSelect={this._handleSelect}
277
- isScrollTo
278
- willActiveIndex={willActiveIndex!}
279
- style={{ height: listHeight }}
249
+ <ConfigProvider {...config}>
250
+ <div
251
+ className={classNames('gm-more-select-popup', popupClassName)}
252
+ onKeyDown={this._handlePopupKeyDown}
253
+ >
254
+ <div className='gm-more-select-popup-input'>
255
+ <Input
256
+ ref={this._inputRef}
257
+ autoFocus
258
+ value={searchValue}
259
+ onChange={this._handleChange}
260
+ placeholder={searchPlaceholder}
280
261
  />
281
- )}
262
+ </div>
263
+ <div style={{ height: listHeight }}>
264
+ {loading && (
265
+ <Flex alignCenter justifyCenter className='gm-bg gm-padding-5'>
266
+ <Loading size='20px' />
267
+ </Flex>
268
+ )}
269
+ {!loading && !filterData.length && this._renderEmpty()}
270
+ {!loading && !!filterData.length && (
271
+ <ListBase
272
+ selected={selected.map((v) => v.value)}
273
+ data={filterData}
274
+ multiple={multiple}
275
+ isGroupList={isGroupList}
276
+ className='gm-border-0'
277
+ renderItem={renderListItem}
278
+ onSelect={this._handleSelect}
279
+ isScrollTo
280
+ willActiveIndex={willActiveIndex!}
281
+ style={{ height: listHeight }}
282
+ />
283
+ )}
284
+ </div>
285
+ {!loading &&
286
+ !!filterData.length &&
287
+ renderCustomizedBottom &&
288
+ renderCustomizedBottom(this._popoverRef)}
282
289
  </div>
283
- {!loading &&
284
- !!filterData.length &&
285
- renderCustomizedBottom &&
286
- renderCustomizedBottom(this._popoverRef)}
287
- </div>
290
+ </ConfigProvider>
288
291
  )
289
292
  }
290
293
 
@@ -324,69 +327,80 @@ class MoreSelectBase<V extends string | number = string> extends Component<
324
327
  children,
325
328
  } = this.props
326
329
  return (
327
- <div
328
- ref={this._baseRef}
329
- onClick={this._handleMoreSelectClick}
330
- className={classNames(
331
- 'gm-more-select',
332
- {
333
- disabled,
334
- 'gm-more-select-multiple': multiple,
335
- },
336
- className
337
- )}
338
- style={style}
339
- >
340
- <Popover
341
- ref={this._popoverRef}
342
- type={popoverType}
343
- popup={this._renderList}
344
- disabled={disabled}
345
- isInPopup={isInPopup}
346
- onVisibleChange={this._handlePopoverVisibleChange}
347
- >
348
- {children ?? (
349
- <Flex
350
- ref={this._selectionRef}
351
- tabIndex={0}
352
- wrap
353
- className='gm-more-select-selected'
330
+ <ConfigConsumer>
331
+ {(config) => (
332
+ <div
333
+ ref={this._baseRef}
334
+ onClick={this._handleMoreSelectClick}
335
+ className={classNames(
336
+ 'gm-more-select',
337
+ {
338
+ disabled,
339
+ 'gm-more-select-multiple': multiple,
340
+ },
341
+ className
342
+ )}
343
+ style={style}
344
+ >
345
+ <Popover
346
+ ref={this._popoverRef}
347
+ type={popoverType}
348
+ popup={() => this._renderList(config)}
349
+ disabled={disabled}
350
+ isInPopup={isInPopup}
351
+ onVisibleChange={this._handlePopoverVisibleChange}
354
352
  >
355
- {selected.length !== 0 ? (
356
- selected.map((item) => (
357
- <Flex key={item.value as any} className='gm-more-select-selected-item'>
358
- <Popover
359
- disabled={!this.props.isKeyboard}
360
- type='hover'
361
- popup={<div className='gm-padding-10'>{item.text}</div>}
362
- >
363
- <Flex flex column>
364
- {renderSelected!(item)}
353
+ {children ?? (
354
+ <Flex
355
+ ref={this._selectionRef}
356
+ tabIndex={0}
357
+ wrap
358
+ className='gm-more-select-selected'
359
+ >
360
+ {selected.length !== 0 ? (
361
+ selected.map((item) => (
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
+ )}
365
392
  </Flex>
366
- </Popover>
367
- {multiple ? (
368
- <SVGRemove
369
- className='gm-cursor gm-more-select-clear-btn'
370
- onClick={disabled ? _.noop : this._handleClear.bind(this, item)}
371
- />
372
- ) : (
373
- !disabledClose && ( // 是否不限时清除按钮,仅单选可用
374
- <SVGCloseCircle
375
- onClick={disabled ? _.noop : this._handleClear.bind(this, item)}
376
- className='gm-cursor gm-more-select-clear-btn'
377
- />
378
- )
379
- )}
380
- </Flex>
381
- ))
382
- ) : (
383
- // 加多个 &nbsp; 避免对齐问题,有文本才有对齐
384
- <div className='gm-text-placeholder'>{placeholder}&nbsp; </div>
393
+ ))
394
+ ) : (
395
+ // 加多个 &nbsp; 避免对齐问题,有文本才有对齐
396
+ <div className='gm-text-placeholder'>{placeholder}&nbsp; </div>
397
+ )}
398
+ </Flex>
385
399
  )}
386
- </Flex>
387
- )}
388
- </Popover>
389
- </div>
400
+ </Popover>
401
+ </div>
402
+ )}
403
+ </ConfigConsumer>
390
404
  )
391
405
  }
392
406
  }
@@ -1,4 +1,4 @@
1
- import React, { useMemo, useRef, FC, FocusEvent } from 'react'
1
+ import React, { useMemo, useRef, FC, FocusEvent, useContext } from 'react'
2
2
  import { Popover } from '../popover'
3
3
  import { Input } from '../input'
4
4
  import { List } from '../list'
@@ -6,6 +6,7 @@ import _ from 'lodash'
6
6
  import { pinYinFilter } from '@gm-common/tool'
7
7
  import SVGCloseCircle from '../../svg/close-circle.svg'
8
8
  import classNames from 'classnames'
9
+ import { ConfigContext, ConfigProvider } from '../config_provider'
9
10
 
10
11
  interface DataItem {
11
12
  text: string
@@ -31,6 +32,7 @@ const RecommendInput: FC<RecommendInputProps> = ({
31
32
  ...rest
32
33
  }) => {
33
34
  const popoverRef = useRef<Popover>(null)
35
+ const config = useContext(ConfigContext)
34
36
 
35
37
  // 构造list需要的数据结构
36
38
  const _data = useMemo(() => {
@@ -68,11 +70,13 @@ const RecommendInput: FC<RecommendInputProps> = ({
68
70
  type='realFocus'
69
71
  popup={
70
72
  searchData.length > 0 ? (
71
- <List
72
- data={searchData}
73
- onSelect={handleSelect}
74
- style={{ height: listHeight }}
75
- />
73
+ <ConfigProvider {...config}>
74
+ <List
75
+ data={searchData}
76
+ onSelect={handleSelect}
77
+ style={{ height: listHeight }}
78
+ />
79
+ </ConfigProvider>
76
80
  ) : (
77
81
  <></> // 需要element
78
82
  )
@@ -7,6 +7,8 @@ import { Selection } from '../selection'
7
7
  import { List } from '../list'
8
8
  import { ListDataItem } from '../../types'
9
9
  import { judgeFunction } from '../../common/utils'
10
+ import { ConfigConsumer, ConfigProvider } from '../config_provider'
11
+ import { ConfigProviderProps, FontSizeType } from '../config_provider/config_provider'
10
12
 
11
13
  interface SelectState {
12
14
  willActiveIndex: number
@@ -108,26 +110,28 @@ class Select<V = any> extends Component<SelectProps<V>, SelectState> {
108
110
 
109
111
  const selected = newData.find((v) => v.value === value)
110
112
 
111
- const popup = (
113
+ const popup = (config?: ConfigProviderProps) => (
112
114
  <>
113
- <List
114
- data={newData}
115
- selected={value}
116
- onSelect={this._handleChange}
117
- renderItem={renderItem}
118
- willActiveIndex={willActiveIndex}
119
- className='gm-border-0'
120
- style={{ maxHeight: '250px' }}
121
- />
122
- {addonLast && (
123
- <div
124
- onClick={() => {
125
- this._popupRef.current!.apiDoSetActive()
126
- }}
127
- >
128
- {addonLast}
129
- </div>
130
- )}
115
+ <ConfigProvider {...config}>
116
+ <List
117
+ data={newData}
118
+ selected={value}
119
+ onSelect={this._handleChange}
120
+ renderItem={renderItem}
121
+ willActiveIndex={willActiveIndex}
122
+ className='gm-border-0'
123
+ style={{ maxHeight: '250px' }}
124
+ />
125
+ {addonLast && (
126
+ <div
127
+ onClick={() => {
128
+ this._popupRef.current!.apiDoSetActive()
129
+ }}
130
+ >
131
+ {addonLast}
132
+ </div>
133
+ )}
134
+ </ConfigProvider>
131
135
  </>
132
136
  )
133
137
 
@@ -135,27 +139,31 @@ class Select<V = any> extends Component<SelectProps<V>, SelectState> {
135
139
  const handleChange = _.noop
136
140
 
137
141
  return (
138
- <Popover
139
- ref={this._popupRef}
140
- type={popoverType}
141
- disabled={disabled}
142
- popup={popup}
143
- isInPopup={isInPopup}
144
- >
145
- <Selection
146
- {...rest}
147
- ref={this._selectionRef}
148
- selected={selected}
149
- onSelect={handleChange}
150
- disabled={disabled}
151
- disabledClose
152
- clean={clean}
153
- renderSelected={renderSelected}
154
- className={classNames('gm-select', className)}
155
- noInput
156
- onKeyDown={this._handleKeyDown}
157
- />
158
- </Popover>
142
+ <ConfigConsumer>
143
+ {(config) => (
144
+ <Popover
145
+ ref={this._popupRef}
146
+ type={popoverType}
147
+ disabled={disabled}
148
+ popup={popup(config)}
149
+ isInPopup={isInPopup}
150
+ >
151
+ <Selection
152
+ {...rest}
153
+ ref={this._selectionRef}
154
+ selected={selected}
155
+ onSelect={handleChange}
156
+ disabled={disabled}
157
+ disabledClose
158
+ clean={clean}
159
+ renderSelected={renderSelected}
160
+ className={classNames('gm-select', className)}
161
+ noInput
162
+ onKeyDown={this._handleKeyDown}
163
+ />
164
+ </Popover>
165
+ )}
166
+ </ConfigConsumer>
159
167
  )
160
168
  }
161
169
  }
@@ -12,6 +12,7 @@ import _ from 'lodash'
12
12
  import classNames from 'classnames'
13
13
  import SVGCloseCircle from '../../svg/close-circle.svg'
14
14
  import { IconDownUp } from '../icon_down_up'
15
+ import { ConfigConsumer } from '../config_provider'
15
16
 
16
17
  type Selected = any
17
18
 
@@ -80,67 +81,79 @@ class Selection extends Component<SelectionProps> {
80
81
  }
81
82
 
82
83
  return (
83
- <div
84
- {...rest}
85
- className={classNames(
86
- 'gm-selection',
87
- {
88
- disabled,
89
- 'gm-selection-disabled-clean': clean,
90
- 'gm-selection-disabled-close': disabledClose,
91
- },
92
- className
93
- )}
94
- >
95
- {noInput ? (
84
+ <ConfigConsumer>
85
+ {({ fontSize }) => (
96
86
  <div
97
- ref={this._inputRef}
98
- // @ts-ignore
99
- disabled={disabled}
100
- className='gm-form-control gm-selection-selected gm-text-ellipsis'
101
- tabIndex={0}
102
- onKeyDown={onKeyDown}
103
- >
104
- {text || <span className='gm-text-desc'>{placeholder}</span>}
105
- </div>
106
- ) : (
107
- <input
108
- type='text'
109
- ref={this._inputRef as RefObject<HTMLInputElement>}
110
- disabled={disabled}
111
- value={(text as string) || ''}
112
- onChange={_.noop}
113
- onKeyDown={onKeyDown}
114
- placeholder={placeholder}
115
- className='gm-form-control gm-selection-selected'
116
- />
117
- )}
118
- {selected && !disabledClose && !clean && (
119
- <SVGCloseCircle
120
- onClick={this._handleClear}
121
- className='gm-selection-icon gm-selection-close-icon'
122
- />
123
- )}
124
- {funIcon ? (
125
- cloneElement(funIcon as ReactElement, {
126
- className: classNames(
127
- 'gm-selection-icon',
87
+ {...rest}
88
+ className={classNames(
89
+ 'gm-selection',
128
90
  {
129
- 'gm-selection-fun-icon': selected && !disabledClose && !clean,
91
+ disabled,
92
+ 'gm-selection-disabled-clean': clean,
93
+ 'gm-selection-disabled-close': disabledClose,
94
+ [`gm-selection-text-${fontSize}`]: fontSize,
130
95
  },
131
- (funIcon as ReactElement).props?.className
132
- ),
133
- })
134
- ) : (
135
- <IconDownUp
136
- disabled={disabled}
137
- active={(className ?? '').includes('gm-popover-active')}
138
- className={classNames('gm-selection-icon', 'gm-selection-down-up', {
139
- 'gm-selection-fun-icon': selected && !disabledClose && !clean,
140
- })}
141
- />
96
+ className
97
+ )}
98
+ >
99
+ {noInput ? (
100
+ <div
101
+ ref={this._inputRef}
102
+ // @ts-ignore
103
+ disabled={disabled}
104
+ className={classNames(
105
+ 'gm-form-control gm-selection-selected gm-text-ellipsis',
106
+ {
107
+ [`gm-form-control-text-${fontSize}`]: fontSize,
108
+ }
109
+ )}
110
+ tabIndex={0}
111
+ onKeyDown={onKeyDown}
112
+ >
113
+ {text || <span className='gm-text-desc'>{placeholder}</span>}
114
+ </div>
115
+ ) : (
116
+ <input
117
+ type='text'
118
+ ref={this._inputRef as RefObject<HTMLInputElement>}
119
+ disabled={disabled}
120
+ value={(text as string) || ''}
121
+ onChange={_.noop}
122
+ onKeyDown={onKeyDown}
123
+ placeholder={placeholder}
124
+ className={classNames('gm-form-control gm-selection-selected', {
125
+ [`gm-form-control-text-${fontSize}`]: fontSize,
126
+ })}
127
+ />
128
+ )}
129
+ {selected && !disabledClose && !clean && (
130
+ <SVGCloseCircle
131
+ onClick={this._handleClear}
132
+ className='gm-selection-icon gm-selection-close-icon'
133
+ />
134
+ )}
135
+ {funIcon ? (
136
+ cloneElement(funIcon as ReactElement, {
137
+ className: classNames(
138
+ 'gm-selection-icon',
139
+ {
140
+ 'gm-selection-fun-icon': selected && !disabledClose && !clean,
141
+ },
142
+ (funIcon as ReactElement).props?.className
143
+ ),
144
+ })
145
+ ) : (
146
+ <IconDownUp
147
+ disabled={disabled}
148
+ active={(className ?? '').includes('gm-popover-active')}
149
+ className={classNames('gm-selection-icon', 'gm-selection-down-up', {
150
+ 'gm-selection-fun-icon': selected && !disabledClose && !clean,
151
+ })}
152
+ />
153
+ )}
154
+ </div>
142
155
  )}
143
- </div>
156
+ </ConfigConsumer>
144
157
  )
145
158
  }
146
159
  }
@@ -57,4 +57,9 @@
57
57
  border: 1px solid transparent;
58
58
  }
59
59
  }
60
+
61
+ /** 字体大小 */
62
+ &.gm-selection-text-sm {
63
+ font-size: var(--gm-size-text-sm);
64
+ }
60
65
  }
@@ -5,4 +5,8 @@
5
5
  line-height: normal;
6
6
 
7
7
  .gmDisabledBgWith();
8
+
9
+ &.gm-textarea-text-sm {
10
+ font-size: var(--gm-size-text-sm);
11
+ }
8
12
  }
@@ -1,11 +1,21 @@
1
- import React, { forwardRef, TextareaHTMLAttributes } from 'react'
1
+ import React, { forwardRef, TextareaHTMLAttributes, useContext } from 'react'
2
2
  import classNames from 'classnames'
3
+ import { ConfigContext } from '../config_provider'
3
4
 
4
5
  type TextAreaProps = TextareaHTMLAttributes<HTMLTextAreaElement>
5
6
 
6
7
  const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>((props, ref) => {
8
+ const { fontSize } = useContext(ConfigContext)
7
9
  const { className, ...rest } = props
8
- return <textarea ref={ref} {...rest} className={classNames('gm-textarea', className)} />
10
+ return (
11
+ <textarea
12
+ ref={ref}
13
+ {...rest}
14
+ className={classNames('gm-textarea', className, {
15
+ [`gm-textarea-text-${fontSize}`]: fontSize,
16
+ })}
17
+ />
18
+ )
9
19
  })
10
20
 
11
21
  export default TextArea
@@ -8,4 +8,8 @@
8
8
  .gmFormControl();
9
9
 
10
10
  .gmDisabledBgWith();
11
+
12
+ &.gm-form-control-text-sm {
13
+ font-size: var(--gm-size-text-sm);
14
+ }
11
15
  }
@@ -17,6 +17,10 @@
17
17
  // grid
18
18
  @gm-grid-columns: 24;
19
19
 
20
+ // 字体大小
21
+ @gm-font-size-xs: 12px;
22
+ @gm-font-size-sm: 14px;
23
+
20
24
  // 颜色会变
21
25
  :root {
22
26
  // color
@@ -81,6 +85,9 @@
81
85
  --gm-size-text-18: 18px;
82
86
  --gm-size-text-20: 20px;
83
87
 
88
+ --gm-size-text-xs: @gm-font-size-xs;
89
+ --gm-size-text-sm: @gm-font-size-sm;
90
+
84
91
  // 大小
85
92
  --gm-size-form-height: 30px;
86
93
  --gm-size-border-radius: 2px;
package/src/index.ts CHANGED
@@ -58,3 +58,4 @@ export * from './component/recommend_input'
58
58
  export * from './component/card'
59
59
  export * from './component/controlled_form'
60
60
  export * from './component/v_browser'
61
+ export * from './component/config_provider'