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

fix(input, input-box): allow passing type="url" #3425

Merged
merged 4 commits into from
Aug 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/lazy-chicken-search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@twilio-paste/input': patch
'@twilio-paste/input-box': patch
'@twilio-paste/core': patch
---

[Input, Input Box] allow passing `type="url"` to the Input component for convenient browser validation.
2 changes: 1 addition & 1 deletion .codesandbox/ci.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,4 @@
"/packages/paste-nextjs-template",
"/packages/paste-token-contrast-checker"
]
}
}
12 changes: 11 additions & 1 deletion packages/paste-core/components/input-box/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import PropTypes from 'prop-types';
import type {BoxProps} from '@twilio-paste/box';

export type InputBoxTypes = 'text' | 'email' | 'hidden' | 'number' | 'password' | 'search' | 'tel' | 'date' | 'time';
export type InputBoxTypes =
| 'text'
| 'email'
| 'hidden'
| 'number'
| 'password'
| 'search'
| 'tel'
| 'date'
| 'time'
| 'url';
export type Variants = 'default' | 'inverse';

export interface FauxInputProps {
Expand Down
19 changes: 0 additions & 19 deletions packages/paste-core/components/input/src/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import {useMergeRefs} from '@twilio-paste/utils';
import {Box} from '@twilio-paste/box';
import type {BoxProps, BoxStyleProps} from '@twilio-paste/box';
Expand Down Expand Up @@ -257,23 +256,5 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(

Input.displayName = 'Input';

Input.propTypes = {
disabled: PropTypes.bool,
element: PropTypes.string,
hasError: PropTypes.bool,
id: PropTypes.string,
name: PropTypes.string,
onBlur: PropTypes.func,
onChange: PropTypes.func,
onFocus: PropTypes.func,
placeholder: PropTypes.string,
readOnly: PropTypes.bool,
required: PropTypes.bool,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type: PropTypes.oneOf(['text', 'email', 'hidden', 'number', 'password', 'search', 'tel', 'date', 'time'])
.isRequired as any,
value: PropTypes.string,
};

export {Input};
export type {InputBoxTypes as InputTypes};
43 changes: 25 additions & 18 deletions packages/paste-core/components/input/stories/input.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type {StoryFn} from '@storybook/react';
import {useUID} from '@twilio-paste/uid-library';
import {action} from '@storybook/addon-actions';
import {Anchor} from '@twilio-paste/anchor';
import {Form, FormControl} from '@twilio-paste/form';
import {useTheme} from '@twilio-paste/theme';
import {Box} from '@twilio-paste/box';
import {Text} from '@twilio-paste/text';
Expand All @@ -23,25 +24,31 @@ export default {
export const DefaultInput = (): React.ReactNode => {
const uid = useUID();
const helpTextUid = useUID();
const [value, setValue] = React.useState('Input');
const [value, setValue] = React.useState('');
return (
<>
<Label htmlFor={uid}>Label</Label>
<Input
id={uid}
aria-describedby={helpTextUid}
type="text"
placeholder="Placeholder"
value={value}
onChange={(event) => {
setValue(event.target.value);
action('handleChange');
}}
onFocus={action('handleFocus')}
onBlur={action('handleBlur')}
/>
<HelpText id={helpTextUid}>Info that helps a user with this field.</HelpText>
</>
<Form>
<FormControl>
<Label required htmlFor={uid}>
Website
</Label>
<Input
id={uid}
aria-describedby={helpTextUid}
type="url"
pattern="https://.*"
required
placeholder="https://twilio.com"
value={value}
onChange={(event) => {
setValue(event.target.value);
action('handleChange');
}}
onFocus={action('handleFocus')}
onBlur={action('handleBlur')}
/>
<HelpText id={helpTextUid}>The URL to your personal homepage.</HelpText>
</FormControl>
</Form>
);
};

Expand Down
40 changes: 22 additions & 18 deletions packages/paste-website/src/pages/components/input/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ An input for entering search strings. It may include an icon in supporting brows

An input for entering a telephone number. It displays a telephone keypad in some devices with dynamic keypads.

#### url

An input for entering a URL. The input value is [automatically validated](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/url#value) to ensure that it's either empty or a properly-formatted URL before the form can be submitted.

### Input with number functionality

Use an Input with number functionality by setting `type="number"`. Users can change the numeric value by entering a number,
Expand Down Expand Up @@ -547,24 +551,24 @@ const Component = () => (

All the valid HTML attributes for `input` are supported including the following props:

| Prop | Type | Description | Default |
| ------------------ | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ----------------- |
| id? | string | Sets the id of the input. Should match the htmlFor of `Label`. | null |
| type | 'text', 'email', 'hidden', 'number', 'password', 'search', 'tel' | Sets the type of the input. Required. | null |
| name? | string | Sets the name of the input. | null |
| value? | string | Sets the value of the input. | null |
| placeholder? | string | Sets the placeholder of the input. | null |
| disabled? | boolean | Disables the input. | false |
| readOnly? | boolean | Sets the input to readonly. | false |
| required? | boolean | Sets the input as required. | false |
| hasError? | boolean | Sets the input to an error state. | false |
| onChange? | `(event: React.MouseEvent<HTMLElement>)` | | null |
| onFocus? | `(event: React.MouseEvent<HTMLElement>)` | | null |
| onBlur? | `(event: React.MouseEvent<HTMLElement>)` | | null |
| variant? | 'default', 'inverse' | | 'default' |
| element? | `string` | Overrides the default element name to apply unique styles with the Customization Provider | 'INPUT' |
| i18nStepUpLabel? | `string` | Provides an accessible label for the increment button on inputs of type "number" when using non-English languages | 'step value up' |
| i18nStepDownLabel? | `string` | Provides an accessible label for the decrement button on inputs of type "number" when using non-English languages | 'step value down' |
| Prop | Type | Description | Default |
| ------------------ | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ----------------- |
| id? | string | Sets the id of the input. Should match the htmlFor of `Label`. | null |
| type | 'text', 'email', 'hidden', 'number', 'password', 'search', 'tel', 'url' | Sets the type of the input. Required. | null |
| name? | string | Sets the name of the input. | null |
| value? | string | Sets the value of the input. | null |
| placeholder? | string | Sets the placeholder of the input. | null |
| disabled? | boolean | Disables the input. | false |
| readOnly? | boolean | Sets the input to readonly. | false |
| required? | boolean | Sets the input as required. | false |
| hasError? | boolean | Sets the input to an error state. | false |
| onChange? | `(event: React.MouseEvent<HTMLElement>)` | | null |
| onFocus? | `(event: React.MouseEvent<HTMLElement>)` | | null |
| onBlur? | `(event: React.MouseEvent<HTMLElement>)` | | null |
| variant? | 'default', 'inverse' | | 'default' |
| element? | `string` | Overrides the default element name to apply unique styles with the Customization Provider | 'INPUT' |
| i18nStepUpLabel? | `string` | Provides an accessible label for the increment button on inputs of type "number" when using non-English languages | 'step value up' |
| i18nStepDownLabel? | `string` | Provides an accessible label for the decrement button on inputs of type "number" when using non-English languages | 'step value down' |

<ChangelogRevealer>
<Changelog />
Expand Down