Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(PasswordInput): add typescript types to PasswordInput #13311

Merged
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,15 @@
"code",
"a11y"
]
},
{
"login": "shryoo-ibm",
"name": "Seong-Hyun Ryoo",
"avatar_url": "https://avatars.githubusercontent.com/u/106095943?s=96&v=4",
"profile": "https://seongryoo.github.io",
"contributions": [
"code"
]
}
],
"commitConvention": "none"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ check out our [Contributing Guide](/.github/CONTRIBUTING.md) and our
<td align="center"><a href="https://galvingao.com/"><img src="https://avatars.githubusercontent.com/u/12567059?v=4?s=100" width="100px;" alt=""/><br /><sub><b>GalvinGao</b></sub></a><br /><a href="https://github.com/carbon-design-system/carbon/commits?author=GalvinGao" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/bianca-sparxs"><img src="https://avatars.githubusercontent.com/u/33003148?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Bianca Sparxs</b></sub></a><br /><a href="https://github.com/carbon-design-system/carbon/commits?author=bianca-sparxs" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/davesteinberg"><img src="https://avatars.githubusercontent.com/u/3935584?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dave Steinberg</b></sub></a><br /><a href="https://github.com/carbon-design-system/carbon/commits?author=davesteinberg" title="Code">💻</a></td>
<td align="center"><a href="https://seongryoo.github.io"><img src="https://avatars.githubusercontent.com/u/106095943?s=96&v=4" width="100px;" alt=""/><br /><sub><b>Seong-Hyun Ryoo</b></sub></a><br /><a href="https://github.com/carbon-design-system/carbon/commits?author=shryoo-ibm" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/pratikkarad"><img src="https://avatars.githubusercontent.com/u/32093370?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Pratik Karad</b></sub></a><br /><a href="https://github.com/carbon-design-system/carbon/commits?author=pratikkarad" title="Code">💻</a> <a href="#a11y-pratikkarad" title="Accessibility">️️️️♿️</a></td>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,170 @@
import React, { useContext, useEffect, useState } from 'react';
import React, {
InputHTMLAttributes,
useContext,
useEffect,
useState,
} from 'react';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import PropTypes, { ReactNodeLike } from 'prop-types';
import { View, ViewOff } from '@carbon/icons-react';
import { useNormalizedInputProps } from '../../internal/useNormalizedInputProps';
import { textInputProps } from './util';
import { FormContext } from '../FluidForm';
import * as FeatureFlags from '@carbon/feature-flags';
import deprecate from '../../prop-types/deprecate';
import { usePrefix } from '../../internal/usePrefix';

type ExcludedAttributes = 'size';

export interface PasswordInputProps
extends Omit<InputHTMLAttributes<HTMLInputElement>, ExcludedAttributes> {
/**
* Provide a custom className that is applied directly to the underlyling `<input>` node
*/
className?: string;

/**
* Optionally provide the default value of the `<input>`
*/
defaultValue?: string | number;

/**
* Specify whether the control is disabled
*/
disabled?: boolean;

/**
* Specify whether to display the character counter
*/
enableCounter?: boolean;

/**
* Provide text that is used alongside the control label for additional help
*/
helperText?: ReactNodeLike;

/**
* Specify whether or not the underlying label is visually hidden
*/
hideLabel?: boolean;

/**
* "Hide password" tooltip text on password visibility toggle
*/
hidePasswordLabel?: string;

/**
* Provide a unique identifier for the input field
*/
id: string;

/**
* `true` to use the inline version
*/
inline?: boolean;

/**
* Specify whether the control is currently invalid
*/
invalid?: boolean;

/**
* Provide the text that is displayed when the control is in an invalid state
*/
invalidText?: ReactNodeLike;

/**
* Provide the text that will be read by a screen reader when visiting this control
*/
labelText: ReactNodeLike;

/**
* @deprecated The `light` prop for `PasswordInput` has been deprecated in favor of the new `Layer` component. It will be removed in the next major release.
* `true` to use the light version. For use on $ui-01 backgrounds only.
* Don't use this to make tile background color same as container background color.
*/
light?: boolean;

/**
* Max character count allowed for the input. This is needed in order for enableCounter to display
*/
maxCount?: number;

/**
* Optionally provide an `onChange` handler that is called whenever `<input>` is updated
* @param evt Change event triggered by `<input>`
* @returns {void}
*/
onChange?: (evt: React.ChangeEvent<HTMLInputElement>) => void;

/**
* Optionally provide an `onClick` handler that is called whenever the `<input>` is returned
* @param evt Mouse event triggered by `<input>`
* @returns {void}
*/
onClick?: (evt: React.MouseEvent<HTMLInputElement>) => void;

/**
* Callback function that is called whenever the toggle password visibility button is clicked
* @param evt Mouse event triggered by the password visibility `<button>`
* @returns {void}
*/
onTogglePasswordVisibility?: (
evt: React.MouseEvent<HTMLButtonElement>
) => void;

/**
* Specify the placeholder attribute for the `<input>`
*/
placeholder?: string;

/**
* Whether the input should be read-only
*/
readOnly?: boolean;

/**
* "Show password" tooltip text on password visibility toggle
*/
showPasswordLabel?: string;

/**
* Specify the size of the Text Input. Supports `sm`, `md`, or `lg`.
*/
size?: 'sm' | 'md' | 'lg';

/**
* Specify the alignment of the tooltip to the icon-only button.
* Can be one of: `start`, `center`, or `end`.
*/
tooltipAlignment?: 'start' | 'center' | 'end';

/**
* Specify the direction of the tooltip for the icon-only button.
* Can be either `top`, `right`, `bottom`, or `left`
*/
tooltipPosition?: 'top' | 'right' | 'bottom' | 'left';

/**
* The input type, either `password` or `text`
*/
type?: 'password' | 'text';

/**
* Provide the current value of the `<input>`
*/
value?: string | number;

/**
* Specify whether the control is currently in warning state
*/
warn?: boolean;

/**
* Provide the text that is displayed when the control is in warning state
*/
warnText?: ReactNodeLike;
}

const PasswordInput = React.forwardRef(function PasswordInput(
{
className,
Expand All @@ -26,15 +182,16 @@ const PasswordInput = React.forwardRef(function PasswordInput(
onClick = () => {},
onTogglePasswordVisibility,
placeholder,
readOnly,
size = 'md',
showPasswordLabel = 'Show password',
tooltipPosition = 'bottom',
tooltipAlignment = 'center',
type = 'password',
warn,
warn = false,
warnText,
...rest
},
}: PasswordInputProps,
ref
) {
const [inputType, setInputType] = useState(type);
Expand All @@ -45,6 +202,8 @@ const PasswordInput = React.forwardRef(function PasswordInput(
invalidText,
warn,
warnText,
readOnly,
disabled,
});

const { isFluid } = useContext(FormContext);
Expand Down Expand Up @@ -180,6 +339,8 @@ const PasswordInput = React.forwardRef(function PasswordInput(
setInputType(type);
}, [type]);

const Icon = normalizedProps.icon as typeof React.Component;

return (
<div className={inputWrapperClasses}>
{!inline ? (
Expand All @@ -194,9 +355,7 @@ const PasswordInput = React.forwardRef(function PasswordInput(
<div
className={fieldWrapperClasses}
data-invalid={normalizedProps.invalid || null}>
{normalizedProps.icon && (
<normalizedProps.icon className={iconClasses} />
)}
{Icon && <Icon className={iconClasses} />}
{input}
{isFluid && !inline && normalizedProps.validation}
</div>
Expand Down Expand Up @@ -306,9 +465,7 @@ PasswordInput.propTypes = {
/**
* Specify the size of the Text Input. Supports `sm`, `md`, or `lg`.
*/
size: FeatureFlags.enabled('enable-v11-release')
? PropTypes.oneOf(['sm', 'md', 'lg'])
: PropTypes.string,
size: PropTypes.oneOf(['sm', 'md', 'lg']),

/**
* Specify the alignment of the tooltip to the icon-only button.
Expand Down