@sproutsocial/racine 11.6.1-input-beta.1 → 11.6.1-input-beta.2
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/__flow__/Input/index.js +16 -28
- package/__flow__/Input/index.test.js +4 -2
- package/commonjs/Input/index.js +17 -24
- package/lib/Input/index.js +17 -24
- package/package.json +1 -1
package/__flow__/Input/index.js
CHANGED
|
@@ -52,9 +52,6 @@ type TypeProps = {
|
|
|
52
52
|
| ((React.ElementRef<any> | HTMLElement) => void),
|
|
53
53
|
onBlur?: (e: SyntheticFocusEvent<HTMLInputElement>) => void,
|
|
54
54
|
onChange?: (e: SyntheticInputEvent<HTMLInputElement>, value: string) => void,
|
|
55
|
-
/** Input.ClearButton onClick callback. Required when using Input.ClearButton.
|
|
56
|
-
The component handles returning focus to Input after onClear is called.
|
|
57
|
-
For controlled Inputs, you must reset "value" yourself.*/
|
|
58
55
|
onClear?: (e: SyntheticEvent<HTMLButtonElement>) => void,
|
|
59
56
|
onFocus?: (e: SyntheticFocusEvent<HTMLInputElement>) => void,
|
|
60
57
|
onKeyDown?: (
|
|
@@ -82,10 +79,8 @@ type TypeState = {
|
|
|
82
79
|
// Using Context so that Input's Input.ClearButton-specific props can be passed to Input.ClearButton,
|
|
83
80
|
// regardless of whether it is manually included as elemAfter or automatically included for type="search" Inputs.
|
|
84
81
|
type TypeInputContext = $Shape<{
|
|
85
|
-
onClear?: (e: SyntheticEvent<HTMLButtonElement>) => void,
|
|
86
82
|
handleClear: (e: SyntheticEvent<HTMLButtonElement>) => void,
|
|
87
83
|
clearButtonLabel: string,
|
|
88
|
-
isControlled: boolean,
|
|
89
84
|
hasValue: boolean,
|
|
90
85
|
size: "large" | "small" | "default",
|
|
91
86
|
}>;
|
|
@@ -102,10 +97,8 @@ const StyledButton: StyledComponent<any, TypeTheme, *> = styled(Button)`
|
|
|
102
97
|
|
|
103
98
|
const ClearButton = () => {
|
|
104
99
|
const {
|
|
105
|
-
onClear,
|
|
106
100
|
handleClear,
|
|
107
101
|
clearButtonLabel,
|
|
108
|
-
isControlled,
|
|
109
102
|
hasValue,
|
|
110
103
|
size: inputSize,
|
|
111
104
|
} = React.useContext(InputContext);
|
|
@@ -115,12 +108,6 @@ const ClearButton = () => {
|
|
|
115
108
|
return null;
|
|
116
109
|
}
|
|
117
110
|
|
|
118
|
-
// Hide the button when no onClear callback is provided to a controlled Input.
|
|
119
|
-
// For a controlled component, all the button would do without an onClear is focus the input.
|
|
120
|
-
if (isControlled && !onClear) {
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
111
|
// Warn if clearButtonLabel is not included, so that the unlocalized fallback will not be mistaken for a proper label.
|
|
125
112
|
if (!clearButtonLabel) {
|
|
126
113
|
console.warn(
|
|
@@ -186,15 +173,18 @@ class Input extends React.Component<TypeProps, TypeState> {
|
|
|
186
173
|
this.props.onBlur?.(e);
|
|
187
174
|
|
|
188
175
|
handleClear = (e: SyntheticEvent<HTMLButtonElement>) => {
|
|
189
|
-
|
|
190
|
-
if (
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
176
|
+
const input = this.inputRef.current;
|
|
177
|
+
if (input) {
|
|
178
|
+
// Clear the value via ref, then dispatch an input event in order to trigger handleChange
|
|
179
|
+
input.value = "";
|
|
180
|
+
const inputEvent = new Event("input", { bubbles: true });
|
|
181
|
+
input.dispatchEvent(inputEvent);
|
|
182
|
+
|
|
183
|
+
// Focus the input, update hasValue, and call any onClear callback
|
|
184
|
+
input.focus();
|
|
185
|
+
this.updateState("");
|
|
186
|
+
this.props.onClear?.(e);
|
|
194
187
|
}
|
|
195
|
-
this.inputRef.current?.focus();
|
|
196
|
-
this.props.onClear?.(e);
|
|
197
|
-
this.updateState("");
|
|
198
188
|
};
|
|
199
189
|
|
|
200
190
|
handleChange = (e: SyntheticInputEvent<HTMLInputElement>) => {
|
|
@@ -214,11 +204,11 @@ class Input extends React.Component<TypeProps, TypeState> {
|
|
|
214
204
|
handlePaste = (e: SyntheticInputEvent<HTMLInputElement>) =>
|
|
215
205
|
this.props.onPaste?.(e, e.currentTarget.value);
|
|
216
206
|
|
|
217
|
-
updateState = (
|
|
218
|
-
const hasValue =
|
|
219
|
-
const
|
|
220
|
-
// Only update state if the value has changed to avoid unnecessary renders.
|
|
221
|
-
if (hasValue !==
|
|
207
|
+
updateState = (inputValue: string) => {
|
|
208
|
+
const hasValue = inputValue !== "";
|
|
209
|
+
const previousHasValue = this.state.hasValue;
|
|
210
|
+
// Only update state if the value of `hasValue` has changed to avoid unnecessary renders.
|
|
211
|
+
if (hasValue !== previousHasValue) {
|
|
222
212
|
this.setState({ hasValue });
|
|
223
213
|
}
|
|
224
214
|
};
|
|
@@ -291,9 +281,7 @@ class Input extends React.Component<TypeProps, TypeState> {
|
|
|
291
281
|
value={{
|
|
292
282
|
handleClear: this.handleClear,
|
|
293
283
|
hasValue: this.state.hasValue,
|
|
294
|
-
isControlled: typeof this.props.value === "string",
|
|
295
284
|
clearButtonLabel,
|
|
296
|
-
onClear,
|
|
297
285
|
size,
|
|
298
286
|
}}
|
|
299
287
|
>
|
|
@@ -85,13 +85,12 @@ describe("Input", () => {
|
|
|
85
85
|
expect(getByRole("button")).toBeTruthy();
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
-
it("should render a clear button for an uncontrolled search Input only
|
|
88
|
+
it("should render a clear button for an uncontrolled search Input only when it has text", () => {
|
|
89
89
|
const { getByRole, queryByRole } = render(
|
|
90
90
|
<Input
|
|
91
91
|
id="name"
|
|
92
92
|
name="name"
|
|
93
93
|
type="search"
|
|
94
|
-
onClear={jest.fn()}
|
|
95
94
|
clearButtonLabel="Clear search"
|
|
96
95
|
/>
|
|
97
96
|
);
|
|
@@ -101,6 +100,9 @@ describe("Input", () => {
|
|
|
101
100
|
expect(input).toHaveFocus();
|
|
102
101
|
userEvent.keyboard("some text");
|
|
103
102
|
expect(getByRole("button")).toBeTruthy();
|
|
103
|
+
userEvent.tab();
|
|
104
|
+
userEvent.keyboard("{enter}");
|
|
105
|
+
expect(queryByRole("button")).toBeFalsy();
|
|
104
106
|
});
|
|
105
107
|
|
|
106
108
|
it("should not render a clear button for search Inputs if there is no text", () => {
|
package/commonjs/Input/index.js
CHANGED
|
@@ -41,22 +41,14 @@ var StyledButton = (0, _styledComponents.default)(_Button.default).withConfig({
|
|
|
41
41
|
|
|
42
42
|
var ClearButton = function ClearButton() {
|
|
43
43
|
var _React$useContext = React.useContext(InputContext),
|
|
44
|
-
onClear = _React$useContext.onClear,
|
|
45
44
|
handleClear = _React$useContext.handleClear,
|
|
46
45
|
clearButtonLabel = _React$useContext.clearButtonLabel,
|
|
47
|
-
isControlled = _React$useContext.isControlled,
|
|
48
46
|
hasValue = _React$useContext.hasValue,
|
|
49
47
|
inputSize = _React$useContext.size; // Hide the button when there is no text to clear.
|
|
50
48
|
|
|
51
49
|
|
|
52
50
|
if (!hasValue) {
|
|
53
51
|
return null;
|
|
54
|
-
} // Hide the button when no onClear callback is provided to a controlled Input.
|
|
55
|
-
// For a controlled component, all the button would do without an onClear is focus the input.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (isControlled && !onClear) {
|
|
59
|
-
return null;
|
|
60
52
|
} // Warn if clearButtonLabel is not included, so that the unlocalized fallback will not be mistaken for a proper label.
|
|
61
53
|
|
|
62
54
|
|
|
@@ -106,19 +98,22 @@ var Input = /*#__PURE__*/function (_React$Component) {
|
|
|
106
98
|
};
|
|
107
99
|
|
|
108
100
|
_this.handleClear = function (e) {
|
|
109
|
-
var _this
|
|
101
|
+
var input = _this.inputRef.current;
|
|
110
102
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
103
|
+
if (input) {
|
|
104
|
+
// Clear the value via ref, then dispatch an input event in order to trigger handleChange
|
|
105
|
+
input.value = "";
|
|
106
|
+
var inputEvent = new Event("input", {
|
|
107
|
+
bubbles: true
|
|
108
|
+
});
|
|
109
|
+
input.dispatchEvent(inputEvent); // Focus the input, update hasValue, and call any onClear callback
|
|
110
|
+
|
|
111
|
+
input.focus();
|
|
117
112
|
|
|
118
|
-
|
|
119
|
-
_this.props.onClear == null ? void 0 : _this.props.onClear(e);
|
|
113
|
+
_this.updateState("");
|
|
120
114
|
|
|
121
|
-
|
|
115
|
+
_this.props.onClear == null ? void 0 : _this.props.onClear(e);
|
|
116
|
+
}
|
|
122
117
|
};
|
|
123
118
|
|
|
124
119
|
_this.handleChange = function (e) {
|
|
@@ -143,11 +138,11 @@ var Input = /*#__PURE__*/function (_React$Component) {
|
|
|
143
138
|
return _this.props.onPaste == null ? void 0 : _this.props.onPaste(e, e.currentTarget.value);
|
|
144
139
|
};
|
|
145
140
|
|
|
146
|
-
_this.updateState = function (
|
|
147
|
-
var hasValue =
|
|
148
|
-
var
|
|
141
|
+
_this.updateState = function (inputValue) {
|
|
142
|
+
var hasValue = inputValue !== "";
|
|
143
|
+
var previousHasValue = _this.state.hasValue; // Only update state if the value of `hasValue` has changed to avoid unnecessary renders.
|
|
149
144
|
|
|
150
|
-
if (hasValue !==
|
|
145
|
+
if (hasValue !== previousHasValue) {
|
|
151
146
|
_this.setState({
|
|
152
147
|
hasValue: hasValue
|
|
153
148
|
});
|
|
@@ -228,9 +223,7 @@ var Input = /*#__PURE__*/function (_React$Component) {
|
|
|
228
223
|
value: {
|
|
229
224
|
handleClear: this.handleClear,
|
|
230
225
|
hasValue: this.state.hasValue,
|
|
231
|
-
isControlled: typeof this.props.value === "string",
|
|
232
226
|
clearButtonLabel: clearButtonLabel,
|
|
233
|
-
onClear: onClear,
|
|
234
227
|
size: size
|
|
235
228
|
}
|
|
236
229
|
}, elementBefore && /*#__PURE__*/React.createElement(_styles.Accessory, {
|
package/lib/Input/index.js
CHANGED
|
@@ -24,22 +24,14 @@ var StyledButton = styled(Button).withConfig({
|
|
|
24
24
|
|
|
25
25
|
var ClearButton = function ClearButton() {
|
|
26
26
|
var _React$useContext = React.useContext(InputContext),
|
|
27
|
-
onClear = _React$useContext.onClear,
|
|
28
27
|
handleClear = _React$useContext.handleClear,
|
|
29
28
|
clearButtonLabel = _React$useContext.clearButtonLabel,
|
|
30
|
-
isControlled = _React$useContext.isControlled,
|
|
31
29
|
hasValue = _React$useContext.hasValue,
|
|
32
30
|
inputSize = _React$useContext.size; // Hide the button when there is no text to clear.
|
|
33
31
|
|
|
34
32
|
|
|
35
33
|
if (!hasValue) {
|
|
36
34
|
return null;
|
|
37
|
-
} // Hide the button when no onClear callback is provided to a controlled Input.
|
|
38
|
-
// For a controlled component, all the button would do without an onClear is focus the input.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (isControlled && !onClear) {
|
|
42
|
-
return null;
|
|
43
35
|
} // Warn if clearButtonLabel is not included, so that the unlocalized fallback will not be mistaken for a proper label.
|
|
44
36
|
|
|
45
37
|
|
|
@@ -89,19 +81,22 @@ var Input = /*#__PURE__*/function (_React$Component) {
|
|
|
89
81
|
};
|
|
90
82
|
|
|
91
83
|
_this.handleClear = function (e) {
|
|
92
|
-
var _this
|
|
84
|
+
var input = _this.inputRef.current;
|
|
93
85
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
86
|
+
if (input) {
|
|
87
|
+
// Clear the value via ref, then dispatch an input event in order to trigger handleChange
|
|
88
|
+
input.value = "";
|
|
89
|
+
var inputEvent = new Event("input", {
|
|
90
|
+
bubbles: true
|
|
91
|
+
});
|
|
92
|
+
input.dispatchEvent(inputEvent); // Focus the input, update hasValue, and call any onClear callback
|
|
93
|
+
|
|
94
|
+
input.focus();
|
|
100
95
|
|
|
101
|
-
|
|
102
|
-
_this.props.onClear == null ? void 0 : _this.props.onClear(e);
|
|
96
|
+
_this.updateState("");
|
|
103
97
|
|
|
104
|
-
|
|
98
|
+
_this.props.onClear == null ? void 0 : _this.props.onClear(e);
|
|
99
|
+
}
|
|
105
100
|
};
|
|
106
101
|
|
|
107
102
|
_this.handleChange = function (e) {
|
|
@@ -126,11 +121,11 @@ var Input = /*#__PURE__*/function (_React$Component) {
|
|
|
126
121
|
return _this.props.onPaste == null ? void 0 : _this.props.onPaste(e, e.currentTarget.value);
|
|
127
122
|
};
|
|
128
123
|
|
|
129
|
-
_this.updateState = function (
|
|
130
|
-
var hasValue =
|
|
131
|
-
var
|
|
124
|
+
_this.updateState = function (inputValue) {
|
|
125
|
+
var hasValue = inputValue !== "";
|
|
126
|
+
var previousHasValue = _this.state.hasValue; // Only update state if the value of `hasValue` has changed to avoid unnecessary renders.
|
|
132
127
|
|
|
133
|
-
if (hasValue !==
|
|
128
|
+
if (hasValue !== previousHasValue) {
|
|
134
129
|
_this.setState({
|
|
135
130
|
hasValue: hasValue
|
|
136
131
|
});
|
|
@@ -211,9 +206,7 @@ var Input = /*#__PURE__*/function (_React$Component) {
|
|
|
211
206
|
value: {
|
|
212
207
|
handleClear: this.handleClear,
|
|
213
208
|
hasValue: this.state.hasValue,
|
|
214
|
-
isControlled: typeof this.props.value === "string",
|
|
215
209
|
clearButtonLabel: clearButtonLabel,
|
|
216
|
-
onClear: onClear,
|
|
217
210
|
size: size
|
|
218
211
|
}
|
|
219
212
|
}, elementBefore && /*#__PURE__*/React.createElement(Accessory, {
|