Skip to content

Commit

Permalink
feat(TextInput): add typescript types (#13142)
Browse files Browse the repository at this point in the history
* feat(TextInput): add typescript types

* fix(Text Input): submcompnent workaround + add helperID prop
  • Loading branch information
bianca-sparxs committed Mar 2, 2023
1 parent b32cee5 commit e1d4884
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 9 deletions.
9 changes: 9 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,15 @@
"contributions": [
"code"
]
},
{
"login": "bianca-sparxs",
"name": "Bianca Sparxs",
"avatar_url": "https://avatars.githubusercontent.com/u/33003148?v=4",
"profile": "https://github.com/bianca-sparxs",
"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 @@ -227,6 +227,7 @@ check out our [Contributing Guide](/.github/CONTRIBUTING.md) and our
<td align="center"><a href="https://jsehull.com/"><img src="https://avatars.githubusercontent.com/u/9935383?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jesse Hull</b></sub></a><br /><a href="https://github.com/carbon-design-system/carbon/commits?author=jsehull" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/awarrier99"><img src="https://avatars.githubusercontent.com/u/17476235?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ashvin Warrier</b></sub></a><br /><a href="https://github.com/carbon-design-system/carbon/commits?author=awarrier99" title="Code">💻</a></td>
<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>
</tr>
</table>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import PropTypes from 'prop-types';
import React, { useContext, useState } from 'react';
import React, { ReactNode, useContext, useState } from 'react';
import classNames from 'classnames';
import { useNormalizedInputProps } from '../../internal/useNormalizedInputProps';
import PasswordInput from './PasswordInput';
Expand All @@ -19,6 +19,132 @@ import * as FeatureFlags from '@carbon/feature-flags';
import { usePrefix } from '../../internal/usePrefix';
import { useAnnouncer } from '../../internal/useAnnouncer';

type ExcludedAttributes = 'defaultValue' | 'id' | 'size' | 'value';

export interface TextInputProps
extends Omit<
React.InputHTMLAttributes<HTMLInputElement>,
ExcludedAttributes
> {
/**
* Specify an optional className to be applied to the `<input>` node
*/
className?: string;

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

/**
* Specify whether the `<input>` should be 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?: ReactNode;

/**
* Specify whether you want the underlying label to be visually hidden
*/
hideLabel?: boolean;

/**
* Specify a custom `id` for the `<input>`
*/
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?: ReactNode;

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

/**
* `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.
* 'The `light` prop for `TextInput` has ' +
'been deprecated in favor of the new `Layer` component. It will be removed in the next major release.'
*/
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
*/
onChange?: (
event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => void;

/**
* Optionally provide an `onClick` handler that is called whenever the
* `<input>` is clicked
*/
onClick?: (event: React.MouseEvent<HTMLElement>) => void;

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

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

/**
* Specify the size of the Text Input. Currently supports the following:
*/
size?: 'sm' | 'md' | 'lg' | 'xl';

/**
* Specify the type of the `<input>`
*/
type?: string;

/**
* Specify the value of the `<input>`
*/
value?: string | number | undefined;

/**
* 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?: ReactNode;
}

const TextInput = React.forwardRef(function TextInput(
{
className,
Expand All @@ -42,7 +168,7 @@ const TextInput = React.forwardRef(function TextInput(
enableCounter = false,
maxCount,
...rest
},
}: TextInputProps,
ref
) {
const prefix = usePrefix();
Expand All @@ -51,7 +177,7 @@ const TextInput = React.forwardRef(function TextInput(

const { defaultValue, value } = rest;
const [textCount, setTextCount] = useState(
defaultValue?.length || value?.length || 0
defaultValue?.toString().length || value?.toString().length || 0
);

const normalizedProps = useNormalizedInputProps({
Expand Down Expand Up @@ -187,7 +313,8 @@ const TextInput = React.forwardRef(function TextInput(
);

const { isFluid } = useContext(FormContext);
let ariaAnnouncement = useAnnouncer(textCount, maxCount);
const ariaAnnouncement = useAnnouncer(textCount, maxCount);
const Icon = normalizedProps.icon as any;

return (
<div className={inputWrapperClasses}>
Expand All @@ -203,9 +330,7 @@ const TextInput = React.forwardRef(function TextInput(
<div
className={fieldWrapperClasses}
data-invalid={normalizedProps.invalid || null}>
{normalizedProps.icon && (
<normalizedProps.icon className={iconClasses} />
)}
{Icon && <Icon className={iconClasses} />}
{input}
<span className={`${prefix}--text-input__counter-alert`} role="alert">
{ariaAnnouncement}
Expand All @@ -220,8 +345,8 @@ const TextInput = React.forwardRef(function TextInput(
});

TextInput.displayName = 'TextInput';
TextInput.PasswordInput = PasswordInput;
TextInput.ControlledPasswordInput = ControlledPasswordInput;
(TextInput as any).PasswordInput = PasswordInput;
(TextInput as any).ControlledPasswordInput = ControlledPasswordInput;
TextInput.propTypes = {
/**
* Specify an optional className to be applied to the `<input>` node
Expand Down
1 change: 1 addition & 0 deletions packages/react/src/internal/useNormalizedInputProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { usePrefix } from './usePrefix';
* @property {boolean} disabled - Whether the input is disabled
* @property {boolean} invalid - Whether the input is invalid (takes precedence over warn)
* @property {string} invalidId - The invalid message's id
* @property {string} helperId - id used for helper text
* @property {boolean} warn - Whether the input is in warning state
* @property {string} warnId - The warning message's id
* @property {React.ReactNode | null} validation – React node rendering the appropriate validation message (if any)
Expand Down

0 comments on commit e1d4884

Please sign in to comment.