@gm-pc/react 1.20.1 → 1.21.1-alpha.4
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 +3 -3
- package/src/component/button/button.tsx +5 -2
- package/src/component/button/style.less +5 -0
- package/src/component/config_provider/config_provider.tsx +16 -0
- package/src/component/config_provider/context.ts +10 -0
- package/src/component/config_provider/index.ts +3 -0
- package/src/component/form/form.tsx +17 -8
- package/src/component/form/style.less +13 -0
- package/src/component/input/input.tsx +6 -2
- package/src/component/input/style.less +5 -0
- package/src/component/level_select/level_select.tsx +30 -23
- package/src/component/list/base.tsx +39 -27
- package/src/component/list/style.less +7 -0
- package/src/component/more_select/base.tsx +113 -99
- package/src/component/nav/style.less +2 -2
- package/src/component/recommend_input/recommend_input.tsx +10 -6
- package/src/component/select/select.tsx +48 -40
- package/src/component/selection/selection.tsx +70 -57
- package/src/component/selection/style.less +5 -0
- package/src/component/tabs/style.less +9 -9
- package/src/component/textarea/style.less +4 -0
- package/src/component/textarea/textarea.tsx +12 -2
- package/src/css/other.less +4 -0
- package/src/css/var/variables.less +7 -0
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gm-pc/react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.21.1-alpha.4",
|
|
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.21.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": "0ca36eb94f309b229dd8f7e29756e86802fe3de2"
|
|
52
52
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import React, { FC, useState, MouseEvent, AnchorHTMLAttributes } from 'react'
|
|
1
|
+
import React, { FC, useState, MouseEvent, AnchorHTMLAttributes, useContext } from 'react'
|
|
2
2
|
import _ from 'lodash'
|
|
3
3
|
import classNames from 'classnames'
|
|
4
4
|
import { is } from '@gm-common/tool'
|
|
5
5
|
import { Loading } from '../loading'
|
|
6
|
+
import { ConfigContext } from '../config_provider'
|
|
6
7
|
|
|
7
8
|
type ButtonType = 'default' | 'primary' | 'success' | 'danger' | 'link'
|
|
8
9
|
type ButtonSize = 'small' | 'middle' | 'large'
|
|
@@ -36,6 +37,7 @@ const Button: FC<ButtonProps> = ({
|
|
|
36
37
|
...rest
|
|
37
38
|
}) => {
|
|
38
39
|
const [isLoading, setIsLoading] = useState(false)
|
|
40
|
+
const { fontSize } = useContext(ConfigContext)
|
|
39
41
|
|
|
40
42
|
const loadFlag = loading || isLoading
|
|
41
43
|
|
|
@@ -69,8 +71,9 @@ const Button: FC<ButtonProps> = ({
|
|
|
69
71
|
`gm-btn gm-btn-${type}`,
|
|
70
72
|
{
|
|
71
73
|
'gm-btn-block': block,
|
|
72
|
-
[`gm-btn-${size}`]: size,
|
|
73
74
|
'gm-btn-plain': type !== 'link' && plain,
|
|
75
|
+
[`gm-btn-${size}`]: size,
|
|
76
|
+
[`gm-btn-text-${fontSize}`]: !!fontSize,
|
|
74
77
|
},
|
|
75
78
|
className
|
|
76
79
|
)}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React, { FC } from 'react'
|
|
2
|
+
import { ConfigContext } from './context'
|
|
3
|
+
|
|
4
|
+
/** xs: 12px sm: 14px */
|
|
5
|
+
export type FontSizeType = 'xs' | 'sm'
|
|
6
|
+
|
|
7
|
+
export interface ConfigProviderProps {
|
|
8
|
+
fontSize?: FontSizeType
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// 加一个div加上css var
|
|
12
|
+
const ConfigProvider: FC<ConfigProviderProps> = ({ children, ...config }) => {
|
|
13
|
+
return <ConfigContext.Provider value={config}>{children}</ConfigContext.Provider>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default ConfigProvider
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createContext } from 'react'
|
|
2
|
+
import { FontSizeType } from './config_provider'
|
|
3
|
+
|
|
4
|
+
export interface ConfigConsumerProps {
|
|
5
|
+
fontSize?: FontSizeType
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const ConfigContext = createContext<ConfigConsumerProps>({})
|
|
9
|
+
|
|
10
|
+
export const ConfigConsumer = ConfigContext.Consumer
|
|
@@ -11,6 +11,7 @@ import classNames from 'classnames'
|
|
|
11
11
|
import FormContext from './context'
|
|
12
12
|
import Validator from '../../validator'
|
|
13
13
|
import { FormProps, FormItemProps } from './types'
|
|
14
|
+
import { ConfigConsumer } from '../config_provider'
|
|
14
15
|
const { Provider } = FormContext
|
|
15
16
|
|
|
16
17
|
interface FormState {
|
|
@@ -117,14 +118,22 @@ class Form extends Component<FormProps, FormState> {
|
|
|
117
118
|
<Provider
|
|
118
119
|
value={{ labelWidth, disabledCol, inline, btnPosition, colWidth, canValidate }}
|
|
119
120
|
>
|
|
120
|
-
<
|
|
121
|
-
{
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
121
|
+
<ConfigConsumer>
|
|
122
|
+
{({ fontSize }) => (
|
|
123
|
+
<form
|
|
124
|
+
{...rest}
|
|
125
|
+
className={classNames(
|
|
126
|
+
'gm-form',
|
|
127
|
+
{ 'form-inline': inline, [`gm-form-text-${fontSize}`]: fontSize },
|
|
128
|
+
className
|
|
129
|
+
)}
|
|
130
|
+
onSubmit={this._handleSubmit}
|
|
131
|
+
>
|
|
132
|
+
{children}
|
|
133
|
+
{hasButtonInGroup && <button type='submit' style={{ display: 'none' }} />}
|
|
134
|
+
</form>
|
|
135
|
+
)}
|
|
136
|
+
</ConfigConsumer>
|
|
128
137
|
</Provider>
|
|
129
138
|
)
|
|
130
139
|
}
|
|
@@ -58,6 +58,19 @@
|
|
|
58
58
|
right: -28px;
|
|
59
59
|
top: 7px;
|
|
60
60
|
}
|
|
61
|
+
|
|
62
|
+
/** 字体大小 */
|
|
63
|
+
&.gm-form-text-sm {
|
|
64
|
+
font-size: var(--gm-size-text-sm);
|
|
65
|
+
|
|
66
|
+
.gm-form-label {
|
|
67
|
+
font-size: var(--gm-size-text-sm);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.gm-form-control {
|
|
71
|
+
font-size: var(--gm-size-text-sm);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
61
74
|
}
|
|
62
75
|
|
|
63
76
|
@media (max-width: 768px) {
|
|
@@ -1,17 +1,21 @@
|
|
|
1
|
-
import React, { forwardRef, InputHTMLAttributes } from 'react'
|
|
1
|
+
import React, { forwardRef, InputHTMLAttributes, useContext } from 'react'
|
|
2
2
|
import classNames from 'classnames'
|
|
3
|
+
import { ConfigContext } from '../config_provider'
|
|
3
4
|
|
|
4
5
|
type InputProps = InputHTMLAttributes<HTMLInputElement>
|
|
5
6
|
|
|
6
7
|
/** 没什么,就一个input,多了个类名 gm-input 用来和库配合做UI */
|
|
7
8
|
const Input = forwardRef<HTMLInputElement, InputProps>((props, ref) => {
|
|
8
9
|
const { className, value = '', ...rest } = props
|
|
10
|
+
const { fontSize } = useContext(ConfigContext)
|
|
9
11
|
return (
|
|
10
12
|
<input
|
|
11
13
|
ref={ref}
|
|
12
14
|
{...rest}
|
|
13
15
|
value={value}
|
|
14
|
-
className={classNames('gm-input', className
|
|
16
|
+
className={classNames('gm-input', className, {
|
|
17
|
+
[`gm-input-${fontSize}`]: fontSize,
|
|
18
|
+
})}
|
|
15
19
|
/>
|
|
16
20
|
)
|
|
17
21
|
})
|
|
@@ -7,6 +7,7 @@ import { LevelList } from '../level_list'
|
|
|
7
7
|
import { getLevel } from '../level_list/utils'
|
|
8
8
|
import _ from 'lodash'
|
|
9
9
|
import { judgeFunction } from '../../common/utils'
|
|
10
|
+
import { ConfigConsumer, ConfigProvider, ConfigProviderProps } from '../config_provider'
|
|
10
11
|
|
|
11
12
|
interface LevelSelectState<V> {
|
|
12
13
|
willActiveSelected: V[]
|
|
@@ -48,22 +49,24 @@ class LevelSelect<V = any> extends Component<LevelSelectProps<V>, LevelSelectSta
|
|
|
48
49
|
this.setState({ willActiveSelected })
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
private _renderPopup = (): ReactNode => {
|
|
52
|
+
private _renderPopup = (config: ConfigProviderProps): ReactNode => {
|
|
52
53
|
const { titles, data, selected, right, onlySelectLeaf } = this.props
|
|
53
54
|
const { willActiveSelected } = this.state
|
|
54
55
|
return (
|
|
55
|
-
<
|
|
56
|
-
<
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
56
|
+
<ConfigProvider {...config}>
|
|
57
|
+
<Flex justifyEnd={right}>
|
|
58
|
+
<LevelList<V>
|
|
59
|
+
isReverse={right}
|
|
60
|
+
data={data}
|
|
61
|
+
onWillActiveSelect={this._handleWillActiveSelect}
|
|
62
|
+
willActiveSelected={willActiveSelected}
|
|
63
|
+
selected={selected}
|
|
64
|
+
onSelect={this._handleSelect}
|
|
65
|
+
titles={titles}
|
|
66
|
+
onlySelectLeaf={onlySelectLeaf}
|
|
67
|
+
/>
|
|
68
|
+
</Flex>
|
|
69
|
+
</ConfigProvider>
|
|
67
70
|
)
|
|
68
71
|
}
|
|
69
72
|
|
|
@@ -192,16 +195,20 @@ class LevelSelect<V = any> extends Component<LevelSelectProps<V>, LevelSelectSta
|
|
|
192
195
|
render() {
|
|
193
196
|
const { disabled, children, popoverType, right } = this.props
|
|
194
197
|
return (
|
|
195
|
-
<
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
198
|
+
<ConfigConsumer>
|
|
199
|
+
{(config) => (
|
|
200
|
+
<Popover
|
|
201
|
+
ref={this._popoverRef}
|
|
202
|
+
right={right}
|
|
203
|
+
disabled={disabled}
|
|
204
|
+
popup={this._renderPopup(config)}
|
|
205
|
+
type={popoverType}
|
|
206
|
+
pureContainer
|
|
207
|
+
>
|
|
208
|
+
{children ?? this._renderTarget()}
|
|
209
|
+
</Popover>
|
|
210
|
+
)}
|
|
211
|
+
</ConfigConsumer>
|
|
205
212
|
)
|
|
206
213
|
}
|
|
207
214
|
}
|
|
@@ -3,6 +3,7 @@ import classNames from 'classnames'
|
|
|
3
3
|
import { xor, flatMap, isNil, noop } from 'lodash'
|
|
4
4
|
import { ListBaseProps } from './types'
|
|
5
5
|
import { ListDataItem } from '../../types'
|
|
6
|
+
import { ConfigConsumer } from '../config_provider'
|
|
6
7
|
|
|
7
8
|
class Base<V = any> extends Component<ListBaseProps<V>> {
|
|
8
9
|
static defaultProps = {
|
|
@@ -83,34 +84,45 @@ class Base<V = any> extends Component<ListBaseProps<V>> {
|
|
|
83
84
|
|
|
84
85
|
let sequenceDataIndex = -1
|
|
85
86
|
return (
|
|
86
|
-
<
|
|
87
|
-
{
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
87
|
+
<ConfigConsumer>
|
|
88
|
+
{({ fontSize }) => (
|
|
89
|
+
<div
|
|
90
|
+
{...rest}
|
|
91
|
+
ref={this._listRef}
|
|
92
|
+
className={classNames(
|
|
93
|
+
'gm-list',
|
|
94
|
+
{
|
|
95
|
+
'gm-list-group': isGroupList,
|
|
96
|
+
[`gm-list-text-${fontSize}`]: fontSize,
|
|
97
|
+
},
|
|
98
|
+
className
|
|
99
|
+
)}
|
|
100
|
+
>
|
|
101
|
+
{data.map((group, gIndex) => (
|
|
102
|
+
<div key={gIndex} className='gm-list-group-item'>
|
|
103
|
+
<div className='gm-list-label'>{group.label}</div>
|
|
104
|
+
{group.children.map((item, index) => {
|
|
105
|
+
sequenceDataIndex++
|
|
106
|
+
return (
|
|
107
|
+
<div
|
|
108
|
+
key={`${index}_${item.value}`}
|
|
109
|
+
{...getItemProps!(item)}
|
|
110
|
+
className={classNames('gm-list-item', {
|
|
111
|
+
active: selected.includes(item.value),
|
|
112
|
+
'will-active': willActiveIndex === sequenceDataIndex,
|
|
113
|
+
disabled: item.disabled,
|
|
114
|
+
})}
|
|
115
|
+
onClick={() => this._handleSelect(item)}
|
|
116
|
+
>
|
|
117
|
+
{renderItem!(item, index)}
|
|
118
|
+
</div>
|
|
119
|
+
)
|
|
120
|
+
})}
|
|
121
|
+
</div>
|
|
122
|
+
))}
|
|
111
123
|
</div>
|
|
112
|
-
)
|
|
113
|
-
</
|
|
124
|
+
)}
|
|
125
|
+
</ConfigConsumer>
|
|
114
126
|
)
|
|
115
127
|
}
|
|
116
128
|
}
|
|
@@ -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
|
-
<
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
<
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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
|
-
|
|
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
|
-
<
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
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
|
-
{
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
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
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
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
|
-
// 加多个 避免对齐问题,有文本才有对齐
|
|
384
|
-
<div className='gm-text-placeholder'>{placeholder} </div>
|
|
393
|
+
))
|
|
394
|
+
) : (
|
|
395
|
+
// 加多个 避免对齐问题,有文本才有对齐
|
|
396
|
+
<div className='gm-text-placeholder'>{placeholder} </div>
|
|
397
|
+
)}
|
|
398
|
+
</Flex>
|
|
385
399
|
)}
|
|
386
|
-
</
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
</
|
|
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
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
<
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
-
<
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
<
|
|
84
|
-
{
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
-
|
|
91
|
+
disabled,
|
|
92
|
+
'gm-selection-disabled-clean': clean,
|
|
93
|
+
'gm-selection-disabled-close': disabledClose,
|
|
94
|
+
[`gm-selection-text-${fontSize}`]: fontSize,
|
|
130
95
|
},
|
|
131
|
-
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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
|
-
</
|
|
156
|
+
</ConfigConsumer>
|
|
144
157
|
)
|
|
145
158
|
}
|
|
146
159
|
}
|
|
@@ -61,27 +61,27 @@
|
|
|
61
61
|
overflow-y: hidden;
|
|
62
62
|
|
|
63
63
|
&::-webkit-scrollbar {
|
|
64
|
-
height: 3px;
|
|
65
|
-
width: 100px;
|
|
66
|
-
border-radius: 2px;
|
|
64
|
+
height: 3px !important;
|
|
65
|
+
width: 100px !important;
|
|
66
|
+
border-radius: 2px !important;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
&::-webkit-scrollbar-track {
|
|
70
|
-
background: rgb(239, 239, 239);
|
|
71
|
-
border-radius: 2px;
|
|
70
|
+
background: rgb(239, 239, 239) !important;
|
|
71
|
+
border-radius: 2px !important;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
&::-webkit-scrollbar-thumb {
|
|
75
|
-
background: #bfbfbf;
|
|
76
|
-
border-radius: 10px;
|
|
75
|
+
background: #bfbfbf !important;
|
|
76
|
+
border-radius: 10px !important;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
&::-webkit-scrollbar-thumb:hover {
|
|
80
|
-
background: #bfbfbf;
|
|
80
|
+
background: #bfbfbf !important;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
&::-webkit-scrollbar-corner {
|
|
84
|
-
background: #179a16;
|
|
84
|
+
background: #179a16 !important;
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
@@ -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
|
|
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
|
package/src/css/other.less
CHANGED
|
@@ -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