Skip to content

Commit d76b928

Browse files
feat(PasswordInput): support warn and inline props (#8366)
* feat(PasswordInput): support `warn` prop * feat(PasswordInput): support `inline` prop * fix(text-input): realign inline text input elements * docs(TextInput): format proptypes * chore: update snapshots * fix(text-input): remove center alignment Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
1 parent be8844d commit d76b928

File tree

4 files changed

+117
-19
lines changed

4 files changed

+117
-19
lines changed

packages/components/src/components/text-input/_text-input.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,11 @@
160160
}
161161
}
162162

163+
.#{$prefix}--text-input__field-wrapper.#{$prefix}--password-input__field-wrapper
164+
.#{$prefix}--text-input__invalid-icon {
165+
right: $carbon--spacing-07;
166+
}
167+
163168
.#{$prefix}--password-input-wrapper .#{$prefix}--text-input__invalid-icon {
164169
right: $carbon--spacing-08;
165170
}

packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5571,6 +5571,9 @@ Map {
55715571
"isRequired": true,
55725572
"type": "string",
55735573
},
5574+
"inline": Object {
5575+
"type": "bool",
5576+
},
55745577
"invalid": Object {
55755578
"type": "bool",
55765579
},
@@ -5633,6 +5636,12 @@ Map {
56335636
],
56345637
"type": "oneOfType",
56355638
},
5639+
"warn": Object {
5640+
"type": "bool",
5641+
},
5642+
"warnText": Object {
5643+
"type": "node",
5644+
},
56365645
},
56375646
"render": [Function],
56385647
},

packages/react/src/components/TextInput/PasswordInput.js

Lines changed: 102 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
import React, { useState } from 'react';
1+
import React, { useContext, useState } from 'react';
22
import classNames from 'classnames';
33
import PropTypes from 'prop-types';
44
import { settings } from 'carbon-components';
5-
import { View16, ViewOff16, WarningFilled16 } from '@carbon/icons-react';
5+
import {
6+
View16,
7+
ViewOff16,
8+
WarningAltFilled16,
9+
WarningFilled16,
10+
} from '@carbon/icons-react';
611
import { textInputProps } from './util';
12+
import { FormContext } from '../FluidForm';
713

814
const { prefix } = settings;
915

@@ -17,6 +23,7 @@ const PasswordInput = React.forwardRef(function PasswordInput(
1723
onChange,
1824
onClick,
1925
hideLabel,
26+
inline,
2027
invalid,
2128
invalidText,
2229
helperText,
@@ -26,6 +33,8 @@ const PasswordInput = React.forwardRef(function PasswordInput(
2633
hidePasswordLabel = 'Hide password',
2734
showPasswordLabel = 'Show password',
2835
size,
36+
warn,
37+
warnText,
2938
...other
3039
},
3140
ref
@@ -34,6 +43,7 @@ const PasswordInput = React.forwardRef(function PasswordInput(
3443
const togglePasswordVisibility = () =>
3544
setInputType(inputType === 'password' ? 'text' : 'password');
3645
const errorId = id + '-error-msg';
46+
const warnId = id + '-warn-msg';
3747
const textInputClasses = classNames(
3848
`${prefix}--text-input`,
3949
`${prefix}--password-input`,
@@ -62,23 +72,58 @@ const PasswordInput = React.forwardRef(function PasswordInput(
6272
ref,
6373
...other,
6474
};
75+
const inputWrapperClasses = classNames(
76+
`${prefix}--form-item`,
77+
`${prefix}--text-input-wrapper`,
78+
`${prefix}--password-input-wrapper`,
79+
{
80+
[`${prefix}--text-input-wrapper--light`]: light,
81+
[`${prefix}--text-input-wrapper--inline`]: inline,
82+
}
83+
);
6584
const labelClasses = classNames(`${prefix}--label`, {
6685
[`${prefix}--visually-hidden`]: hideLabel,
6786
[`${prefix}--label--disabled`]: disabled,
87+
[`${prefix}--label--inline`]: inline,
88+
[`${prefix}--label--inline--${size}`]: inline && !!size,
6889
});
6990
const helperTextClasses = classNames(`${prefix}--form__helper-text`, {
7091
[`${prefix}--form__helper-text--disabled`]: disabled,
92+
[`${prefix}--form__helper-text--inline`]: inline,
7193
});
94+
const fieldOuterWrapperClasses = classNames(
95+
`${prefix}--text-input__field-outer-wrapper`,
96+
{
97+
[`${prefix}--text-input__field-outer-wrapper--inline`]: inline,
98+
}
99+
);
100+
const fieldWrapperClasses = classNames(
101+
`${prefix}--text-input__field-wrapper`,
102+
{
103+
[`${prefix}--text-input__field-wrapper--warning`]: !invalid && warn,
104+
}
105+
);
72106
const label = labelText ? (
73107
<label htmlFor={id} className={labelClasses}>
74108
{labelText}
75109
</label>
76110
) : null;
77-
const error = invalid ? (
78-
<div className={`${prefix}--form-requirement`} id={errorId}>
79-
{invalidText}
80-
</div>
81-
) : null;
111+
112+
let error = null;
113+
if (invalid) {
114+
error = (
115+
<div className={`${prefix}--form-requirement`} id={errorId}>
116+
{invalidText}
117+
</div>
118+
);
119+
} else if (warn) {
120+
error = (
121+
<div className={`${prefix}--form-requirement`} id={warnId}>
122+
{warnText}
123+
</div>
124+
);
125+
}
126+
82127
const passwordIsVisible = inputType === 'text';
83128
const passwordVisibilityIcon = passwordIsVisible ? (
84129
<ViewOff16 className={`${prefix}--icon-visibility-off`} />
@@ -100,7 +145,13 @@ const PasswordInput = React.forwardRef(function PasswordInput(
100145
const input = (
101146
<>
102147
<input
103-
{...textInputProps({ invalid, sharedTextInputProps, errorId })}
148+
{...textInputProps({
149+
invalid,
150+
sharedTextInputProps,
151+
errorId,
152+
warn,
153+
warnId,
154+
})}
104155
disabled={disabled}
105156
data-toggle-password-visibility={inputType === 'password'}
106157
/>
@@ -122,19 +173,36 @@ const PasswordInput = React.forwardRef(function PasswordInput(
122173
<div className={helperTextClasses}>{helperText}</div>
123174
) : null;
124175

176+
const { isFluid } = useContext(FormContext);
177+
125178
return (
126-
<div
127-
className={`${prefix}--form-item ${prefix}--text-input-wrapper ${prefix}--password-input-wrapper`}>
128-
{label}
129-
<div
130-
className={`${prefix}--text-input__field-wrapper`}
131-
data-invalid={invalid || null}>
132-
{invalid && (
133-
<WarningFilled16 className={`${prefix}--text-input__invalid-icon`} />
134-
)}
135-
{input}
179+
<div className={inputWrapperClasses}>
180+
{!inline ? (
181+
label
182+
) : (
183+
<div className={`${prefix}--text-input__label-helper-wrapper`}>
184+
{label}
185+
{!isFluid && helper}
186+
</div>
187+
)}
188+
<div className={fieldOuterWrapperClasses}>
189+
<div className={fieldWrapperClasses} data-invalid={invalid || null}>
190+
{invalid && (
191+
<WarningFilled16
192+
className={`${prefix}--text-input__invalid-icon`}
193+
/>
194+
)}
195+
{!invalid && warn && (
196+
<WarningAltFilled16
197+
className={`${prefix}--text-input__invalid-icon ${prefix}--text-input__invalid-icon--warning`}
198+
/>
199+
)}
200+
{input}
201+
{isFluid && !inline && error}
202+
</div>
203+
{!isFluid && error}
204+
{!invalid && !warn && !isFluid && !inline && helper}
136205
</div>
137-
{error ? error : helper}
138206
</div>
139207
);
140208
});
@@ -176,6 +244,11 @@ PasswordInput.propTypes = {
176244
*/
177245
id: PropTypes.string.isRequired,
178246

247+
/**
248+
* `true` to use the inline version.
249+
*/
250+
inline: PropTypes.bool,
251+
179252
/**
180253
* Specify whether the control is currently invalid
181254
*/
@@ -240,6 +313,16 @@ PasswordInput.propTypes = {
240313
* Provide the current value of the `<input>`
241314
*/
242315
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
316+
317+
/**
318+
* Specify whether the control is currently in warning state
319+
*/
320+
warn: PropTypes.bool,
321+
322+
/**
323+
* Provide the text that is displayed when the control is in warning state
324+
*/
325+
warnText: PropTypes.node,
243326
};
244327

245328
PasswordInput.defaultProps = {

packages/react/src/components/TextInput/TextInput.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ TextInput.propTypes = {
261261
* Specify whether the control is currently in warning state
262262
*/
263263
warn: PropTypes.bool,
264+
264265
/**
265266
* Provide the text that is displayed when the control is in warning state
266267
*/

0 commit comments

Comments
 (0)