@jswork/antd-components 1.0.78 → 1.0.80
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/README.md +1 -56
- package/dist/main.cjs.js +77 -0
- package/dist/main.cjs.js.map +1 -0
- package/dist/main.d.mts +1062 -0
- package/dist/main.d.ts +1062 -34
- package/dist/main.esm.js +77 -0
- package/dist/main.esm.js.map +1 -0
- package/dist/style.css +2 -267
- package/dist/style.css.map +1 -0
- package/package.json +30 -75
- package/src/lib/_abstract-upload.tsx +131 -0
- package/src/lib/alert.tsx +53 -0
- package/src/lib/breadcrumb.tsx +40 -0
- package/src/lib/checkable-dropdown.tsx +170 -0
- package/src/lib/checkable-tag-list.tsx +122 -0
- package/src/lib/checkable-tag.tsx +101 -0
- package/src/lib/checkbox-group.tsx +72 -0
- package/src/lib/checkbox.tsx +59 -0
- package/src/lib/codeflask.tsx +17 -0
- package/src/lib/confirm-button.tsx +87 -0
- package/src/lib/date-picker.tsx +60 -0
- package/src/lib/editable-tag-group.tsx +234 -0
- package/src/lib/input-hidden.tsx +13 -0
- package/src/lib/input-number.tsx +52 -0
- package/src/lib/input-tags.tsx +140 -0
- package/src/lib/input-token.tsx +102 -0
- package/src/lib/input.tsx +58 -0
- package/src/lib/interactive-list.tsx +173 -0
- package/src/lib/pre-select.tsx +128 -0
- package/src/lib/radio-group.tsx +67 -0
- package/src/lib/range-picker.tsx +59 -0
- package/src/lib/rate.tsx +38 -0
- package/src/lib/search.tsx +49 -0
- package/src/lib/select.tsx +86 -0
- package/src/lib/slider-range.tsx +40 -0
- package/src/lib/slider.tsx +37 -0
- package/src/lib/switch.tsx +52 -0
- package/src/lib/textarea.tsx +29 -0
- package/src/lib/time-picker.tsx +66 -0
- package/src/lib/transfer.tsx +70 -0
- package/src/lib/tree-select.tsx +64 -0
- package/src/lib/tree.tsx +60 -0
- package/src/lib/upload-dragger.tsx +60 -0
- package/src/lib/upload-picture-card.tsx +56 -0
- package/src/lib/upload-picture.tsx +47 -0
- package/src/lib/upload.tsx +55 -0
- package/src/main.ts +34 -0
- package/src/style.scss +191 -0
- package/LICENSE.txt +0 -21
- package/dist/index.esm.js +0 -10
- package/dist/index.js +0 -10
- package/dist/lib/_abstract-upload.d.ts +0 -40
- package/dist/lib/alert.d.ts +0 -14
- package/dist/lib/breadcrumb.d.ts +0 -29
- package/dist/lib/checkable-dropdown.d.ts +0 -52
- package/dist/lib/checkable-tag-list.d.ts +0 -51
- package/dist/lib/checkable-tag.d.ts +0 -43
- package/dist/lib/checkbox-group.d.ts +0 -38
- package/dist/lib/checkbox.d.ts +0 -27
- package/dist/lib/codeflask.d.ts +0 -9
- package/dist/lib/confirm-button.d.ts +0 -23
- package/dist/lib/date-picker.d.ts +0 -26
- package/dist/lib/editable-tag-group.d.ts +0 -92
- package/dist/lib/input-hidden.d.ts +0 -7
- package/dist/lib/input-number.d.ts +0 -27
- package/dist/lib/input-tags.d.ts +0 -37
- package/dist/lib/input-token.d.ts +0 -39
- package/dist/lib/input.d.ts +0 -29
- package/dist/lib/interactive-list.d.ts +0 -56
- package/dist/lib/pre-select.d.ts +0 -57
- package/dist/lib/radio-group.d.ts +0 -42
- package/dist/lib/range-picker.d.ts +0 -27
- package/dist/lib/rate.d.ts +0 -23
- package/dist/lib/search.d.ts +0 -29
- package/dist/lib/select.d.ts +0 -43
- package/dist/lib/slider-range.d.ts +0 -23
- package/dist/lib/slider.d.ts +0 -22
- package/dist/lib/switch.d.ts +0 -27
- package/dist/lib/textarea.d.ts +0 -22
- package/dist/lib/time-picker.d.ts +0 -29
- package/dist/lib/transfer.d.ts +0 -37
- package/dist/lib/tree-select.d.ts +0 -32
- package/dist/lib/tree.d.ts +0 -31
- package/dist/lib/upload-dragger.d.ts +0 -28
- package/dist/lib/upload-picture-card.d.ts +0 -14
- package/dist/lib/upload-picture.d.ts +0 -14
- package/dist/lib/upload.d.ts +0 -28
- /package/{dist → src}/styles/input-tags.scss +0 -0
- /package/{dist → src}/styles/override.scss +0 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import cx from 'classnames';
|
|
2
|
+
import React, { createRef } from 'react';
|
|
3
|
+
import noop from '@jswork/noop';
|
|
4
|
+
import AutosizeInput from 'react-input-autosize';
|
|
5
|
+
import { Button, Tag } from 'antd';
|
|
6
|
+
import deepEqual from 'fast-deep-equal';
|
|
7
|
+
import nx from '@jswork/next';
|
|
8
|
+
import _ from 'lodash';
|
|
9
|
+
import '@jswork/next-dom-event';
|
|
10
|
+
import { AcInteractiveList } from './interactive-list';
|
|
11
|
+
|
|
12
|
+
const CLASS_NAME = 'ac-editable-tag-group';
|
|
13
|
+
type StdEventTarget = { target: { value: any } };
|
|
14
|
+
type StdCallback = (inEvent: StdEventTarget) => void;
|
|
15
|
+
|
|
16
|
+
type Props = {
|
|
17
|
+
/**
|
|
18
|
+
* The extended className for component.
|
|
19
|
+
*/
|
|
20
|
+
className?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Default value.
|
|
23
|
+
*/
|
|
24
|
+
value?: any[];
|
|
25
|
+
/**
|
|
26
|
+
* The change handler.
|
|
27
|
+
*/
|
|
28
|
+
onChange?: StdCallback;
|
|
29
|
+
/**
|
|
30
|
+
* The minimum tag number.
|
|
31
|
+
*/
|
|
32
|
+
min?: number;
|
|
33
|
+
/**
|
|
34
|
+
* The maximum tags number.
|
|
35
|
+
*/
|
|
36
|
+
max?: number;
|
|
37
|
+
/**
|
|
38
|
+
* If set readOnly.
|
|
39
|
+
*/
|
|
40
|
+
readOnly?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* If set disabled.
|
|
43
|
+
*/
|
|
44
|
+
disabled?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Trigger key, default is `Space`.
|
|
47
|
+
*/
|
|
48
|
+
triggers?: string[];
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export class AcEditableTagGroup extends React.Component<Props> {
|
|
52
|
+
static displayName = CLASS_NAME;
|
|
53
|
+
static formSchema = CLASS_NAME;
|
|
54
|
+
static defaultProps = {
|
|
55
|
+
value: [],
|
|
56
|
+
min: 0,
|
|
57
|
+
max: 10,
|
|
58
|
+
onChange: noop,
|
|
59
|
+
triggers: [' ', 'Tab']
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
private inputRef = createRef<HTMLInputElement>();
|
|
63
|
+
private btnRef = createRef<HTMLButtonElement>();
|
|
64
|
+
private rootForwardedRef = createRef<HTMLDivElement>();
|
|
65
|
+
private rootRef = createRef<any>();
|
|
66
|
+
private imeStartRes;
|
|
67
|
+
private imeEndRes;
|
|
68
|
+
|
|
69
|
+
get latestInput(): HTMLInputElement {
|
|
70
|
+
const root = this.rootForwardedRef.current!;
|
|
71
|
+
const selector = `.${CLASS_NAME}__input input`;
|
|
72
|
+
const els: NodeListOf<HTMLInputElement> = root.querySelectorAll(selector);
|
|
73
|
+
return els[els.length - 1];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
state = {
|
|
77
|
+
value: this.props.value,
|
|
78
|
+
ime: false
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
template = ({ item, index }, cb) => {
|
|
82
|
+
// TODO: tag.cloable will create ant-tag-hidden?
|
|
83
|
+
const { readOnly } = this.props;
|
|
84
|
+
return (
|
|
85
|
+
<Tag key={index}>
|
|
86
|
+
<AutosizeInput
|
|
87
|
+
ref={this.inputRef}
|
|
88
|
+
type="text"
|
|
89
|
+
size="small"
|
|
90
|
+
value={item}
|
|
91
|
+
disabled={readOnly}
|
|
92
|
+
readOnly={readOnly}
|
|
93
|
+
className={`${CLASS_NAME}__input`}
|
|
94
|
+
onChange={this.handleInputChange.bind(this, index)}
|
|
95
|
+
onBlur={this.handleInputBlur}
|
|
96
|
+
onKeyDown={this.handleInputKeyDown}
|
|
97
|
+
/>
|
|
98
|
+
{!readOnly && <i className={`${CLASS_NAME}__close`} onClick={cb}></i>}
|
|
99
|
+
</Tag>
|
|
100
|
+
);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
templateCreate = () => {
|
|
104
|
+
const { readOnly } = this.props;
|
|
105
|
+
if (readOnly) return null;
|
|
106
|
+
return (
|
|
107
|
+
<Button
|
|
108
|
+
ref={this.btnRef}
|
|
109
|
+
size="small"
|
|
110
|
+
type="dashed"
|
|
111
|
+
onClick={this.actionCreate}
|
|
112
|
+
className={`${CLASS_NAME}__create`}>
|
|
113
|
+
<i className={`${CLASS_NAME}__plus`}></i>
|
|
114
|
+
新增
|
|
115
|
+
</Button>
|
|
116
|
+
);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Default item's value.
|
|
121
|
+
*/
|
|
122
|
+
templateDefault = () => {
|
|
123
|
+
return '';
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Add new default item.
|
|
128
|
+
*/
|
|
129
|
+
actionCreate = () => {
|
|
130
|
+
const { value } = this.state;
|
|
131
|
+
value!.push(this.templateDefault());
|
|
132
|
+
this.handleChange(value);
|
|
133
|
+
this.rootRef.current!.notify(value);
|
|
134
|
+
this.actionFocusLast();
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Focus latest input element if exists.
|
|
139
|
+
* @param inDelay
|
|
140
|
+
*/
|
|
141
|
+
actionFocusLast = (inDelay?: number) => {
|
|
142
|
+
const delay = inDelay || 100;
|
|
143
|
+
setTimeout(() => {
|
|
144
|
+
this.latestInput?.focus();
|
|
145
|
+
}, delay);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
handleInputChange = (inIndex, inEvent) => {
|
|
149
|
+
const { value } = this.state;
|
|
150
|
+
value![inIndex] = inEvent.target.value;
|
|
151
|
+
this.handleChange(value);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
handleInputBlur = () => {
|
|
155
|
+
let { value } = this.state;
|
|
156
|
+
const len = value?.length;
|
|
157
|
+
setTimeout(() => {
|
|
158
|
+
value = _.uniq(value);
|
|
159
|
+
if (document.activeElement !== this.latestInput) {
|
|
160
|
+
value = value?.filter(Boolean);
|
|
161
|
+
}
|
|
162
|
+
this.handleChange(value);
|
|
163
|
+
if (value?.length !== len) {
|
|
164
|
+
this.actionFocusLast(100);
|
|
165
|
+
}
|
|
166
|
+
}, 10);
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
handleInputKeyDown = (inEvent) => {
|
|
170
|
+
const { triggers } = this.props;
|
|
171
|
+
const { ime } = this.state;
|
|
172
|
+
if (triggers?.includes(inEvent.key)) {
|
|
173
|
+
if (inEvent.key === ' ' && ime) return;
|
|
174
|
+
inEvent.preventDefault();
|
|
175
|
+
this.actionCreate();
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
handleInterChange = (inEvent) => {
|
|
180
|
+
const { value } = inEvent.target;
|
|
181
|
+
this.handleChange(value);
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
handleChange = (inValue, inCallback?) => {
|
|
185
|
+
const callback = inCallback || noop;
|
|
186
|
+
const { onChange } = this.props;
|
|
187
|
+
const value = inValue.map((item) => item.trim());
|
|
188
|
+
const target = { value };
|
|
189
|
+
this.setState(target, () => {
|
|
190
|
+
onChange!({ target });
|
|
191
|
+
callback(value);
|
|
192
|
+
});
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
componentDidMount() {
|
|
196
|
+
const doc = document as any;
|
|
197
|
+
this.imeStartRes = nx.DomEvent.on(doc, 'compositionstart', () => this.setState({ ime: true }));
|
|
198
|
+
this.imeEndRes = nx.DomEvent.on(doc, 'compositionend', () => this.setState({ ime: false }));
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
componentWillUnmount() {
|
|
202
|
+
this.imeStartRes.destroy();
|
|
203
|
+
this.imeEndRes.destroy();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
shouldComponentUpdate(nextProps: Readonly<Props>): boolean {
|
|
207
|
+
const { value } = nextProps;
|
|
208
|
+
if (!deepEqual(value, this.props.value)) {
|
|
209
|
+
this.setState({ value: value!.slice() });
|
|
210
|
+
}
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
render() {
|
|
215
|
+
const { className, value, onChange, min, max, triggers, ...props } = this.props;
|
|
216
|
+
const { value: stateValue } = this.state;
|
|
217
|
+
|
|
218
|
+
return (
|
|
219
|
+
<AcInteractiveList
|
|
220
|
+
className={cx(CLASS_NAME, className)}
|
|
221
|
+
forwardedRef={this.rootForwardedRef}
|
|
222
|
+
ref={this.rootRef}
|
|
223
|
+
min={min}
|
|
224
|
+
max={max}
|
|
225
|
+
items={stateValue}
|
|
226
|
+
template={this.template}
|
|
227
|
+
templateCreate={this.templateCreate}
|
|
228
|
+
templateDefault={this.templateDefault}
|
|
229
|
+
onChange={this.handleInterChange}
|
|
230
|
+
{...props}
|
|
231
|
+
/>
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const CLASS_NAME = 'ac-input-hidden';
|
|
4
|
+
|
|
5
|
+
export class AcInputHidden extends React.Component {
|
|
6
|
+
static displayName = CLASS_NAME;
|
|
7
|
+
static formSchema = CLASS_NAME;
|
|
8
|
+
static defaultProps = {};
|
|
9
|
+
|
|
10
|
+
render() {
|
|
11
|
+
return <input type="hidden" {...this.props} />;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import noop from '@jswork/noop';
|
|
3
|
+
import { InputNumber, InputNumberProps } from 'antd';
|
|
4
|
+
import cx from 'classnames';
|
|
5
|
+
|
|
6
|
+
const CLASS_NAME = 'ac-input-number';
|
|
7
|
+
type StdEventTarget = { target: { value: any } };
|
|
8
|
+
type StdCallback = (inEvent: StdEventTarget) => void;
|
|
9
|
+
|
|
10
|
+
type Props = {
|
|
11
|
+
className?: string;
|
|
12
|
+
value?: number;
|
|
13
|
+
onChange?: StdCallback;
|
|
14
|
+
} & InputNumberProps;
|
|
15
|
+
|
|
16
|
+
export class AcInputNumber extends React.Component<Props> {
|
|
17
|
+
static displayName = CLASS_NAME;
|
|
18
|
+
static formSchema = CLASS_NAME;
|
|
19
|
+
static defaultProps = {
|
|
20
|
+
onChange: noop
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
state = {
|
|
24
|
+
value: this.props.value
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
shouldComponentUpdate(inProps: Readonly<Props>): boolean {
|
|
28
|
+
const { value } = inProps;
|
|
29
|
+
if (value !== this.props.value) this.setState({ value });
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
handleChange = (inEvent) => {
|
|
34
|
+
const { onChange } = this.props;
|
|
35
|
+
const target = { value: inEvent };
|
|
36
|
+
this.setState(target);
|
|
37
|
+
onChange!({ target });
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
render() {
|
|
41
|
+
const { className, value, onChange, ...props } = this.props;
|
|
42
|
+
const { value: stateValue } = this.state;
|
|
43
|
+
return (
|
|
44
|
+
<InputNumber
|
|
45
|
+
className={cx(CLASS_NAME, className)}
|
|
46
|
+
value={stateValue}
|
|
47
|
+
onChange={this.handleChange}
|
|
48
|
+
{...props}
|
|
49
|
+
/>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import noop from '@jswork/noop';
|
|
3
|
+
import { Tag } from 'antd';
|
|
4
|
+
import cx from 'classnames';
|
|
5
|
+
import fde from 'fast-deep-equal';
|
|
6
|
+
|
|
7
|
+
const CLASS_NAME = 'ac-input-tags';
|
|
8
|
+
const TRIGGER_KEYS = ['Tab', 'Enter', 'Space'];
|
|
9
|
+
|
|
10
|
+
// @ https://cdpn.io/iamqamarali/fullpage/qyawoR?anon=true&view=
|
|
11
|
+
type StdEventTarget = { target: { value: any } };
|
|
12
|
+
type StdCallback = (inEvent: StdEventTarget) => void;
|
|
13
|
+
|
|
14
|
+
type Props = {
|
|
15
|
+
className?: string;
|
|
16
|
+
items?: string[];
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
onChange?: StdCallback;
|
|
19
|
+
} & React.HTMLAttributes<HTMLDivElement>;
|
|
20
|
+
|
|
21
|
+
type State = {
|
|
22
|
+
items?: string[];
|
|
23
|
+
inputValue: string;
|
|
24
|
+
isComposite: boolean;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export class AcInputTags extends React.Component<Props, State> {
|
|
28
|
+
static displayName = CLASS_NAME;
|
|
29
|
+
static formSchema = CLASS_NAME;
|
|
30
|
+
static defaultProps = {
|
|
31
|
+
items: [],
|
|
32
|
+
disabled: false,
|
|
33
|
+
onChange: noop
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
inputRef = React.createRef<HTMLInputElement>();
|
|
37
|
+
|
|
38
|
+
constructor(inProps) {
|
|
39
|
+
super(inProps);
|
|
40
|
+
const { items } = inProps;
|
|
41
|
+
this.state = {
|
|
42
|
+
items,
|
|
43
|
+
isComposite: false,
|
|
44
|
+
inputValue: ''
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
shouldComponentUpdate(nextProps: Readonly<Props>): boolean {
|
|
49
|
+
const { items } = nextProps;
|
|
50
|
+
if (!fde(items, this.props.items)) {
|
|
51
|
+
this.setState({ items });
|
|
52
|
+
}
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
handleInputChange = (inEvent) => {
|
|
57
|
+
const { value } = inEvent.target;
|
|
58
|
+
this.setState({ inputValue: value });
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
handleInputKeyAction = (inEvent) => {
|
|
62
|
+
const { code } = inEvent;
|
|
63
|
+
const { value } = inEvent.target;
|
|
64
|
+
const { items, isComposite } = this.state;
|
|
65
|
+
const val = value.trim();
|
|
66
|
+
const idx = items!.length - 1;
|
|
67
|
+
inEvent.stopPropagation();
|
|
68
|
+
|
|
69
|
+
if (isComposite) return false;
|
|
70
|
+
if (code === 'Backspace') return this.handleTagRemove(idx);
|
|
71
|
+
if (code === 'Tab') inEvent.preventDefault();
|
|
72
|
+
if (TRIGGER_KEYS.includes(code)) {
|
|
73
|
+
if (val) {
|
|
74
|
+
if (!items!.includes(val)) {
|
|
75
|
+
items!.push(val);
|
|
76
|
+
this.setState({ inputValue: '' });
|
|
77
|
+
this.execChange(items!);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
handleTagRemove = (inIndex, inForce?: boolean) => {
|
|
84
|
+
const { disabled } = this.props;
|
|
85
|
+
const { items, inputValue } = this.state;
|
|
86
|
+
if (disabled) return;
|
|
87
|
+
const newItems = items!.filter((_, idx) => idx !== inIndex);
|
|
88
|
+
if (!inputValue || inForce) this.execChange(newItems);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
handleMouseEnter = () => {
|
|
92
|
+
this.inputRef.current?.focus();
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
execChange = (inItems) => {
|
|
96
|
+
const { onChange } = this.props;
|
|
97
|
+
this.setState({ items: (inItems || []).slice(0) }, () => {
|
|
98
|
+
this.inputRef.current?.focus();
|
|
99
|
+
onChange!({ target: { value: inItems } });
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
render() {
|
|
104
|
+
const { className, onChange, disabled, ...props } = this.props;
|
|
105
|
+
const { items, inputValue } = this.state;
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<div
|
|
109
|
+
data-disabled={disabled}
|
|
110
|
+
className={cx(CLASS_NAME, className)}
|
|
111
|
+
onMouseOver={this.handleMouseEnter}
|
|
112
|
+
onClick={this.handleMouseEnter}
|
|
113
|
+
{...props}>
|
|
114
|
+
{items!.map((item, idx) => {
|
|
115
|
+
return (
|
|
116
|
+
<Tag
|
|
117
|
+
data-disabled={disabled}
|
|
118
|
+
className={`${CLASS_NAME}__tag`}
|
|
119
|
+
closeIcon
|
|
120
|
+
onClose={this.handleTagRemove.bind(this, idx, true)}
|
|
121
|
+
key={idx}>
|
|
122
|
+
{item}
|
|
123
|
+
</Tag>
|
|
124
|
+
);
|
|
125
|
+
})}
|
|
126
|
+
<input
|
|
127
|
+
disabled={disabled}
|
|
128
|
+
autoFocus
|
|
129
|
+
ref={this.inputRef}
|
|
130
|
+
onCompositionStart={() => this.setState({ isComposite: true })}
|
|
131
|
+
onCompositionEnd={() => this.setState({ isComposite: false })}
|
|
132
|
+
onInput={this.handleInputChange}
|
|
133
|
+
onKeyDown={this.handleInputKeyAction}
|
|
134
|
+
value={inputValue}
|
|
135
|
+
className={cx(`${CLASS_NAME}__input`, className)}
|
|
136
|
+
/>
|
|
137
|
+
</div>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import noop from '@jswork/noop';
|
|
3
|
+
import { Button, Input, InputProps } from 'antd';
|
|
4
|
+
import { UnlockOutlined, LockOutlined } from '@ant-design/icons';
|
|
5
|
+
import { nanoid } from 'nanoid';
|
|
6
|
+
import cx from 'classnames';
|
|
7
|
+
|
|
8
|
+
const CLASS_NAME = 'ac-input-token';
|
|
9
|
+
type StdEventTarget = { target: { value: any } };
|
|
10
|
+
type StdCallback = (inEvent: StdEventTarget) => void;
|
|
11
|
+
|
|
12
|
+
type Props = {
|
|
13
|
+
className?: string;
|
|
14
|
+
value?: string;
|
|
15
|
+
onChange?: StdCallback;
|
|
16
|
+
autoComplete?: boolean;
|
|
17
|
+
labelCreate?: string;
|
|
18
|
+
labelRemove?: string;
|
|
19
|
+
} & InputProps;
|
|
20
|
+
|
|
21
|
+
export class AcInputToken extends React.Component<Props> {
|
|
22
|
+
static displayName = CLASS_NAME;
|
|
23
|
+
static formSchema = CLASS_NAME;
|
|
24
|
+
static defaultProps = {
|
|
25
|
+
onChange: noop,
|
|
26
|
+
autoComplete: false,
|
|
27
|
+
labelCreate: '生成Token',
|
|
28
|
+
labelRemove: '去掉Token'
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
private rootRef = React.createRef<any>();
|
|
32
|
+
state = { value: this.props.value };
|
|
33
|
+
|
|
34
|
+
shouldComponentUpdate(nextProps: Readonly<Props>): boolean {
|
|
35
|
+
const { value } = nextProps;
|
|
36
|
+
if (value !== this.props.value) this.setState({ value });
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get complete() {
|
|
41
|
+
return this.props.autoComplete ? 'on' : 'off';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
get tokenView() {
|
|
45
|
+
const { labelCreate, labelRemove } = this.props;
|
|
46
|
+
return (
|
|
47
|
+
<Button.Group>
|
|
48
|
+
<Button
|
|
49
|
+
size="small"
|
|
50
|
+
icon={<LockOutlined />}
|
|
51
|
+
className={`${CLASS_NAME}__action`}
|
|
52
|
+
onClick={this.handleTokenCreate}>
|
|
53
|
+
{labelCreate}
|
|
54
|
+
</Button>
|
|
55
|
+
<Button
|
|
56
|
+
size="small"
|
|
57
|
+
icon={<UnlockOutlined />}
|
|
58
|
+
className={`${CLASS_NAME}__action`}
|
|
59
|
+
onClick={this.handleTokenRemove}>
|
|
60
|
+
{labelRemove}
|
|
61
|
+
</Button>
|
|
62
|
+
</Button.Group>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
handleTokenCreate = () => {
|
|
67
|
+
this.doChange(nanoid());
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
handleTokenRemove = () => {
|
|
71
|
+
this.doChange('');
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
handleChange = (inEvent) => {
|
|
75
|
+
const { value } = inEvent.target;
|
|
76
|
+
this.doChange(value);
|
|
77
|
+
this.rootRef.current.input.focus();
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
doChange = (inValue) => {
|
|
81
|
+
const { onChange } = this.props;
|
|
82
|
+
const target = { value: inValue };
|
|
83
|
+
this.setState(target);
|
|
84
|
+
onChange!({ target });
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
render() {
|
|
88
|
+
const { className, value, autoComplete, onChange, labelCreate, labelRemove, ...props } =
|
|
89
|
+
this.props;
|
|
90
|
+
return (
|
|
91
|
+
<Input
|
|
92
|
+
ref={this.rootRef}
|
|
93
|
+
value={this.state.value}
|
|
94
|
+
onChange={this.handleChange}
|
|
95
|
+
addonAfter={this.tokenView}
|
|
96
|
+
className={cx(CLASS_NAME, className)}
|
|
97
|
+
autoComplete={this.complete}
|
|
98
|
+
{...props}
|
|
99
|
+
/>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import noop from '@jswork/noop';
|
|
3
|
+
import { Input, InputProps } from 'antd';
|
|
4
|
+
import cx from 'classnames';
|
|
5
|
+
|
|
6
|
+
const CLASS_NAME = 'ac-input';
|
|
7
|
+
type StdEventTarget = { target: { value: any } };
|
|
8
|
+
type StdCallback = (inEvent: StdEventTarget) => void;
|
|
9
|
+
|
|
10
|
+
type Props = {
|
|
11
|
+
className?: string;
|
|
12
|
+
onChange?: StdCallback;
|
|
13
|
+
autoComplete?: boolean;
|
|
14
|
+
} & InputProps;
|
|
15
|
+
|
|
16
|
+
export class AcInput extends React.Component<Props> {
|
|
17
|
+
static displayName = CLASS_NAME;
|
|
18
|
+
static formSchema = CLASS_NAME;
|
|
19
|
+
static defaultProps = {
|
|
20
|
+
onChange: noop,
|
|
21
|
+
autoComplete: false
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
state = { value: this.props.value };
|
|
25
|
+
|
|
26
|
+
shouldComponentUpdate(inProps: Readonly<Props>): boolean {
|
|
27
|
+
const { value } = inProps;
|
|
28
|
+
if (value !== this.props.value) this.setState({ value });
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
handleChange = (inEvent) => {
|
|
33
|
+
const { onChange } = this.props;
|
|
34
|
+
const { value } = inEvent.target;
|
|
35
|
+
const target = { value };
|
|
36
|
+
this.setState(target);
|
|
37
|
+
onChange!({ target });
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
get complete() {
|
|
41
|
+
return this.props.autoComplete ? 'on' : 'off';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
render() {
|
|
45
|
+
const { className, value, autoComplete, onChange, ...props } = this.props;
|
|
46
|
+
const { value: stateValue } = this.state;
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<Input
|
|
50
|
+
className={cx(CLASS_NAME, className)}
|
|
51
|
+
autoComplete={this.complete}
|
|
52
|
+
value={stateValue}
|
|
53
|
+
onChange={this.handleChange}
|
|
54
|
+
{...props}
|
|
55
|
+
/>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
}
|