From 527387bbfebd40ff1a1ab6e015c172ae6c761cd7 Mon Sep 17 00:00:00 2001 From: George Marshall Date: Tue, 21 Feb 2023 10:35:28 -0800 Subject: [PATCH] Adding Input component and updating TextFieldBase (#17664) * Adding Input component and updating TextField * Exporting from index, removing as prop and updating snapshot --- .../component-library-components.scss | 1 + .../form-text-field.test.js.snap | 2 +- ui/components/component-library/index.js | 1 + .../component-library/input/README.mdx | 270 ++++++++++++++ .../input/__snapshots__/input.test.js.snap | 12 + .../component-library/input/index.js | 2 + .../input/input.constants.js | 6 + .../component-library/input/input.js | 170 +++++++++ .../component-library/input/input.scss | 16 + .../component-library/input/input.stories.js | 287 +++++++++++++++ .../component-library/input/input.test.js | 145 ++++++++ .../text-field-base/README.mdx | 338 ------------------ .../text-field-search.test.js.snap | 2 +- .../__snapshots__/text-field.test.js.snap | 2 +- .../text-field/text-field.js | 9 +- .../text-field/text-field.scss | 10 - ui/components/component-library/text/text.js | 2 +- .../__snapshots__/reveal-seed.test.js.snap | 2 +- 18 files changed, 918 insertions(+), 359 deletions(-) create mode 100644 ui/components/component-library/input/README.mdx create mode 100644 ui/components/component-library/input/__snapshots__/input.test.js.snap create mode 100644 ui/components/component-library/input/index.js create mode 100644 ui/components/component-library/input/input.constants.js create mode 100644 ui/components/component-library/input/input.js create mode 100644 ui/components/component-library/input/input.scss create mode 100644 ui/components/component-library/input/input.stories.js create mode 100644 ui/components/component-library/input/input.test.js delete mode 100644 ui/components/component-library/text-field-base/README.mdx diff --git a/ui/components/component-library/component-library-components.scss b/ui/components/component-library/component-library-components.scss index e3f00439c..faa75d589 100644 --- a/ui/components/component-library/component-library-components.scss +++ b/ui/components/component-library/component-library-components.scss @@ -20,6 +20,7 @@ @import 'button-link/button-link'; @import 'button-primary/button-primary'; @import 'button-secondary/button-secondary'; +@import 'input/input'; // Molecules @import 'picker-network/picker-network'; @import 'tag-url/tag-url'; diff --git a/ui/components/component-library/form-text-field/__snapshots__/form-text-field.test.js.snap b/ui/components/component-library/form-text-field/__snapshots__/form-text-field.test.js.snap index 493f0a94a..0e68bd298 100644 --- a/ui/components/component-library/form-text-field/__snapshots__/form-text-field.test.js.snap +++ b/ui/components/component-library/form-text-field/__snapshots__/form-text-field.test.js.snap @@ -10,7 +10,7 @@ exports[`FormTextField should render correctly 1`] = ` > + + + +## Props + +The `Input` accepts all props below as well as all [Box](/docs/components-ui-box--default-story#props) component props + + + +### Type + +Use the `type` prop to change the type of input. + +Possible types include: + +- `INPUT_TYPES.TEXT` +- `INPUT_TYPES.NUMBER` +- `INPUT_TYPES.PASSWORD` +- `INPUT_TYPES.SEARCH` + +Defaults to `INPUT_TYPES.TEXT`. + + + + + +```jsx +import { Input, INPUT_TYPES } from '../../component-library'; + + + + + +``` + +### Ref + +Use the `ref` prop to access the ref of the `` html element of `Input`. This is useful for focusing the input from a button or other component. + + + + + +```jsx +import { Button, Input } from '../../component-library'; + +const inputRef = useRef(null); +const [value, setValue] = useState(''); +const handleOnClick = () => { + inputRef.current.focus(); +}; +const handleOnChange = (e) => { + setValue(e.target.value); +}; + + + +``` + +### Auto Complete + +Use the `autoComplete` prop to set the autocomplete html attribute. It allows the browser to predict the value based on earlier typed values. + + + + + +```jsx +import { Input } from '../../component-library'; + +; +``` + +### Auto Focus + +Use the `autoFocus` prop to focus the `Input` during the first mount + +To view story see [Canvas tab](/story/components-componentlibrary-input--auto-focus). Removing it from docs because created annoying reading experience 😁 + +```jsx +import { Input } from '../../component-library'; + +; +``` + +### Default Value + +Use the `defaultValue` prop to set the default value of the `Input`. Used for uncontrolled inputs. + + + + + +```jsx +import { Input } from '../../component-library'; + +; +``` + +### Disabled + +Use the `disabled` prop to set the disabled state of the `Input` + + + + + +```jsx +import { Input } from '../../component-library'; + +; +``` + +### Error + +Use the `error` prop to set `aria-invalid="true"`. This helps with screen readers for accessibility. There is no visual indicator for `error` this should be handled in the parent component. + + + + + +```jsx +import { Input } from '../../component-library'; + +; +``` + +### Max Length + +Use the `maxLength` prop to set the maximum allowed input characters for the `Input` + + + + + +```jsx +import { Input } from '../../component-library'; + +; +``` + +### Read Only + +Use the `readOnly` prop to set the `Input` to read only + + + + + +```jsx +import { Input } from '../../component-library'; + +; +``` + +### Required + +Use the `required` prop to set the html `required` attribute used by the browser api. There is no visual indicator for `required` this should be handled in the parent component. + + + + + +```jsx +import { Input } from '../../component-library'; + +// No visual indicator. Used by the browser api +; +``` + +### Disable Style States + +Use the `disableStyleStates` to remove disabled and focus styles + +#### IMPORTANT NOTE + +This sets the CSS to `outline: none` so ensure there is a proper fallback to enable accessibility for keyboard only and vision impaired users. Check `TextField` source code to see how it is done properly. + + + + + +```jsx +import { Input } from '../../component-library'; + +; +``` + +### Text Variant + +Use the `textVariant` and `TextVariant` enum to change the font size and style of the input + +#### IMPORTANT NOTE + +This should RARELY be used but it is available for custom inputs that require larger text + + + + + +```jsx +import { TextVariant } from '../../../helpers/constants/design-system'; +import { Input } from '../../component-library'; + + + + + + + + + + + +``` diff --git a/ui/components/component-library/input/__snapshots__/input.test.js.snap b/ui/components/component-library/input/__snapshots__/input.test.js.snap new file mode 100644 index 000000000..3f314fa85 --- /dev/null +++ b/ui/components/component-library/input/__snapshots__/input.test.js.snap @@ -0,0 +1,12 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Input should render correctly 1`] = ` +
+ +
+`; diff --git a/ui/components/component-library/input/index.js b/ui/components/component-library/input/index.js new file mode 100644 index 000000000..a8a921a47 --- /dev/null +++ b/ui/components/component-library/input/index.js @@ -0,0 +1,2 @@ +export { Input } from './input'; +export { INPUT_TYPES } from './input.constants'; diff --git a/ui/components/component-library/input/input.constants.js b/ui/components/component-library/input/input.constants.js new file mode 100644 index 000000000..3d0ee82f0 --- /dev/null +++ b/ui/components/component-library/input/input.constants.js @@ -0,0 +1,6 @@ +export const INPUT_TYPES = { + TEXT: 'text', + NUMBER: 'number', + PASSWORD: 'password', + SEARCH: 'search', +}; diff --git a/ui/components/component-library/input/input.js b/ui/components/component-library/input/input.js new file mode 100644 index 000000000..28067ba1b --- /dev/null +++ b/ui/components/component-library/input/input.js @@ -0,0 +1,170 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; + +import { + TextVariant, + BackgroundColor, + BorderStyle, +} from '../../../helpers/constants/design-system'; + +import Box from '../../ui/box'; + +import { Text } from '../text'; + +import { INPUT_TYPES } from './input.constants'; + +export const Input = React.forwardRef( + ( + { + autoComplete, + autoFocus, + className, + defaultValue, + disabled, + error, + id, + maxLength, + name, + onBlur, + onChange, + onFocus, + placeholder, + readOnly, + required, + type = 'text', + value, + textVariant = TextVariant.bodyMd, + disableStateStyles, + ...props + }, + ref, + ) => ( + + ), +); + +Input.propTypes = { + /** + * Autocomplete allows the browser to predict the value based on earlier typed values + */ + autoComplete: PropTypes.bool, + /** + * If `true`, the input will be focused during the first mount. + */ + autoFocus: PropTypes.bool, + /** + * An additional className to apply to the input + */ + className: PropTypes.string, + /** + * The default input value, useful when not controlling the component. + */ + defaultValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + /** + * If `true`, the input will be disabled. + */ + disabled: PropTypes.bool, + /** + * Disables focus state by setting CSS outline: none; + * !!IMPORTANT!! + * If this is set to true ensure there is a proper fallback + * to enable accessibility for keyboard only and vision impaired users + */ + disableStateStyles: PropTypes.bool, + /** + * If `true`, aria-invalid will be true + */ + error: PropTypes.bool, + /** + * The id of the `input` element. + */ + id: PropTypes.string, + /** + * Max number of characters to allow + */ + maxLength: PropTypes.number, + /** + * Name attribute of the `input` element. + */ + name: PropTypes.string, + /** + * Callback fired on blur + */ + onBlur: PropTypes.func, + /** + * Callback fired when the value is changed. + */ + onChange: PropTypes.func, + /** + * Callback fired on focus + */ + onFocus: PropTypes.func, + /** + * The short hint displayed in the input before the user enters a value. + */ + placeholder: PropTypes.string, + /** + * It prevents the user from changing the value of the field (not from interacting with the field). + */ + readOnly: PropTypes.bool, + /** + * If `true`, the input will be required. Currently no visual difference is shown. + */ + required: PropTypes.bool, + /** + * Use this to override the text variant of the Text component. + * Should only be used for approved custom input components + * Use the TextVariant enum + */ + textVariant: PropTypes.oneOf(Object.values(TextVariant)), + /** + * Type of the input element. Can be INPUT_TYPES.TEXT, INPUT_TYPES.PASSWORD, INPUT_TYPES.NUMBER + * Defaults to INPUT_TYPES.TEXT ('text') + * If you require another type add it to INPUT_TYPES + */ + type: PropTypes.oneOf(Object.values(INPUT_TYPES)), + /** + * The input value, required for a controlled component. + */ + value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + /** + * Input accepts all the props from Box + */ + ...Box.propTypes, +}; + +Input.displayName = 'Input'; diff --git a/ui/components/component-library/input/input.scss b/ui/components/component-library/input/input.scss new file mode 100644 index 000000000..82bd89038 --- /dev/null +++ b/ui/components/component-library/input/input.scss @@ -0,0 +1,16 @@ +.mm-input { + --input-opacity-disabled: 0.5; + + box-sizing: content-box; + + &--disable-state-styles { + &:focus, + &:focus-visible { + outline: none; + } + } + + &--disabled { + opacity: var(--input-opacity-disabled); + } +} diff --git a/ui/components/component-library/input/input.stories.js b/ui/components/component-library/input/input.stories.js new file mode 100644 index 000000000..6cc5a3cf6 --- /dev/null +++ b/ui/components/component-library/input/input.stories.js @@ -0,0 +1,287 @@ +import React, { useRef } from 'react'; +import { useArgs } from '@storybook/client-api'; + +import { + DISPLAY, + FLEX_DIRECTION, + TextVariant, +} from '../../../helpers/constants/design-system'; +import Box from '../../ui/box/box'; + +import { Button } from '..'; + +import { INPUT_TYPES } from './input.constants'; +import { Input } from './input'; + +import README from './README.mdx'; + +const marginSizeControlOptions = [ + undefined, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 'auto', +]; + +export default { + title: 'Components/ComponentLibrary/Input', + component: Input, + parameters: { + docs: { + page: README, + }, + }, + argTypes: { + autoComplete: { + control: 'boolean', + }, + autoFocus: { + control: 'boolean', + }, + className: { + control: 'text', + }, + defaultValue: { + control: 'text', + }, + disabled: { + control: 'boolean', + }, + disableStateStyles: { + control: 'boolean', + }, + error: { + control: 'boolean', + }, + id: { + control: 'text', + }, + maxLength: { + control: 'number', + }, + name: { + control: 'text', + }, + onBlur: { + action: 'onBlur', + }, + onChange: { + action: 'onChange', + }, + onFocus: { + action: 'onFocus', + }, + placeholder: { + control: 'text', + }, + readOnly: { + control: 'boolean', + }, + required: { + control: 'boolean', + }, + type: { + control: 'select', + options: Object.values(INPUT_TYPES), + }, + value: { + control: 'text', + }, + textVariant: { + control: 'select', + options: Object.values(TextVariant), + }, + marginTop: { + options: marginSizeControlOptions, + control: 'select', + table: { category: 'box props' }, + }, + marginRight: { + options: marginSizeControlOptions, + control: 'select', + table: { category: 'box props' }, + }, + marginBottom: { + options: marginSizeControlOptions, + control: 'select', + table: { category: 'box props' }, + }, + marginLeft: { + options: marginSizeControlOptions, + control: 'select', + table: { category: 'box props' }, + }, + }, + args: { + placeholder: 'Placeholder...', + value: '', + }, +}; + +const Template = (args) => { + const [{ value }, updateArgs] = useArgs(); + const handleOnChange = (e) => { + updateArgs({ value: e.target.value }); + }; + return ; +}; + +export const DefaultStory = Template.bind({}); +DefaultStory.storyName = 'Default'; + +export const Type = (args) => ( + + + + + + +); + +Type.args = { + value: undefined, +}; + +export const Ref = (args) => { + const [{ value }, updateArgs] = useArgs(); + const inputRef = useRef(null); + const handleOnClick = () => { + inputRef.current.focus(); + }; + const handleOnChange = (e) => { + updateArgs({ value: e.target.value }); + }; + return ( + + + + + ); +}; + +export const AutoComplete = Template.bind({}); +AutoComplete.args = { + autoComplete: true, + type: INPUT_TYPES.PASSWORD, + placeholder: 'Enter password', +}; + +export const AutoFocus = Template.bind({}); +AutoFocus.args = { autoFocus: true }; + +export const DefaultValue = () => ( + +); +export const Disabled = Template.bind({}); +Disabled.args = { disabled: true }; + +export const ErrorStory = Template.bind({}); +ErrorStory.args = { error: true }; +ErrorStory.storyName = 'Error'; + +export const MaxLength = Template.bind({}); +MaxLength.args = { maxLength: 10, placeholder: 'Max length 10' }; + +export const ReadOnly = Template.bind({}); +ReadOnly.args = { readOnly: true, value: 'Read only' }; + +export const Required = Template.bind({}); +Required.args = { required: true, placeholder: 'Required' }; + +export const DisableStateStyles = Template.bind({}); +DisableStateStyles.args = { + disableStateStyles: true, +}; + +export const TextVariantStory = (args) => { + const [{ value }, updateArgs] = useArgs(); + const handleOnChange = (e) => { + updateArgs({ value: e.target.value }); + }; + return ( + + + + + + + + + + + + + ); +}; + +TextVariantStory.storyName = 'Text Variant'; diff --git a/ui/components/component-library/input/input.test.js b/ui/components/component-library/input/input.test.js new file mode 100644 index 000000000..0601d479b --- /dev/null +++ b/ui/components/component-library/input/input.test.js @@ -0,0 +1,145 @@ +/* eslint-disable jest/require-top-level-describe */ +import React from 'react'; +import { fireEvent, render, act } from '@testing-library/react'; +import { renderWithUserEvent } from '../../../../test/lib/render-helpers'; + +import { TextVariant } from '../../../helpers/constants/design-system'; +import { Input } from './input'; +import { INPUT_TYPES } from './input.constants'; + +describe('Input', () => { + it('should render correctly', () => { + const { getByRole, container } = render(); + expect(getByRole('textbox')).toBeDefined(); + expect(container).toMatchSnapshot(); + }); + it('should render correctly with custom className', () => { + const { getByRole } = render(); + expect(getByRole('textbox')).toHaveClass('test'); + }); + it('should render and be able to input text', () => { + const { getByTestId } = render(); + const InputComponent = getByTestId('input'); + + expect(InputComponent.value).toBe(''); // initial value is empty string + fireEvent.change(InputComponent, { target: { value: 'text value' } }); + expect(InputComponent.value).toBe('text value'); + fireEvent.change(InputComponent, { target: { value: '' } }); // reset value + expect(InputComponent.value).toBe(''); // value is empty string after reset + }); + it('should render without state styles when disableStateStyles is true', async () => { + const { getByTestId, user } = renderWithUserEvent( + , + ); + const InputComponent = getByTestId('input'); + + await user.click(InputComponent); + expect(getByTestId('input')).toHaveFocus(); + expect(getByTestId('input')).toHaveClass('mm-input--disable-state-styles'); + expect(getByTestId('input')).not.toHaveClass('mm-input--disabled'); + }); + it('should render and fire onFocus and onBlur events', async () => { + const onFocus = jest.fn(); + const onBlur = jest.fn(); + const { getByTestId, user } = renderWithUserEvent( + , + ); + + const InputComponent = getByTestId('input'); + await user.click(InputComponent); + expect(onFocus).toHaveBeenCalledTimes(1); + fireEvent.blur(InputComponent); + expect(onBlur).toHaveBeenCalledTimes(1); + }); + it('should pass ref to allow input to focus through another element', () => { + const ref = React.createRef(); + const { getByRole } = renderWithUserEvent(); + + act(() => ref.current.focus()); + expect(getByRole('textbox')).toHaveFocus(); + }); + it('should render and fire onChange event', async () => { + const onChange = jest.fn(); + const { getByTestId, user } = renderWithUserEvent( + , + ); + const InputComponent = getByTestId('input'); + await user.type(InputComponent, '123'); + expect(InputComponent).toHaveValue('123'); + expect(onChange).toHaveBeenCalledTimes(3); + }); + it('should render with different types', () => { + const { getByTestId } = render( + <> + + + + + , + ); + expect(getByTestId('input-text-default')).toHaveAttribute('type', 'text'); + expect(getByTestId('input-text')).toHaveAttribute('type', 'text'); + expect(getByTestId('input-number')).toHaveAttribute('type', 'number'); + expect(getByTestId('input-password')).toHaveAttribute('type', 'password'); + }); + it('should render with autoComplete', () => { + const { getByTestId } = render( + , + ); + expect(getByTestId('input-auto-complete')).toHaveAttribute( + 'autocomplete', + 'on', + ); + }); + it('should render with autoFocus', () => { + const { getByRole } = render(); + expect(getByRole('textbox')).toHaveFocus(); + }); + it('should render with a defaultValue', () => { + const { getByRole } = render(); + expect(getByRole('textbox').value).toBe('default value'); + }); + it('should render in disabled state and not focus or be clickable', async () => { + const mockOnFocus = jest.fn(); + const { getByRole, getByTestId, user } = renderWithUserEvent( + , + ); + const InputComponent = getByTestId('input'); + await user.click(InputComponent); + expect(getByRole('textbox')).toBeDisabled(); + expect(mockOnFocus).toHaveBeenCalledTimes(0); + }); + it('should render with maxLength and not allow more than the set characters', async () => { + const { getByRole, user } = renderWithUserEvent(); + const InputComponent = getByRole('textbox'); + await user.type(InputComponent, '1234567890'); + expect(getByRole('textbox')).toBeDefined(); + expect(InputComponent.maxLength).toBe(5); + expect(InputComponent.value).toBe('12345'); + expect(InputComponent.value).toHaveLength(5); + }); + it('should render with readOnly attr when readOnly is true', async () => { + const { getByTestId, getByRole, user } = renderWithUserEvent( + , + ); + const InputComponent = getByTestId('read-only'); + await user.type(InputComponent, '1234567890'); + expect(getByRole('textbox').value).toBe(''); + expect(getByRole('textbox')).toHaveAttribute('readonly', ''); + }); + it('should render with required attr when required is true', () => { + const { getByTestId } = render( + , + ); + expect(getByTestId('input-required')).toHaveAttribute('required', ''); + }); + it('should render with a different Text variant', () => { + const { getByTestId } = render( + , + ); + expect(getByTestId('input-required')).toHaveClass('mm-text--heading-sm'); + }); +}); diff --git a/ui/components/component-library/text-field-base/README.mdx b/ui/components/component-library/text-field-base/README.mdx deleted file mode 100644 index 947796709..000000000 --- a/ui/components/component-library/text-field-base/README.mdx +++ /dev/null @@ -1,338 +0,0 @@ -import { Story, Canvas, ArgsTable } from '@storybook/addon-docs'; - -import { TextFieldBase } from './text-field-base'; - -### This is a base component. It should not be used in your feature code directly but as a "base" for other UI components - -# TextFieldBase - -The `TextFieldBase` is the base component for all text fields. It should not be used directly. It functions as both a uncontrolled and controlled input. - - - - - -## Props - -The `TextFieldBase` accepts all props below as well as all [Box](/docs/components-ui-box--default-story#props) component props - - - -### Size - -Use the `size` prop to set the height of the `TextFieldBase`. - -Possible sizes include: - -- `sm` 32px -- `md` 40px -- `lg` 48px - -Defaults to `md` - - - - - -```jsx -import { Size } from '../../../helpers/constants/design-system'; -import { TextFieldBase } from '../../component-library'; - - - - -``` - -### Type - -Use the `type` prop to change the type of input. - -Possible types include: - -- `text` -- `number` -- `password` - -Defaults to `text`. - - - - - -```jsx -import { TextFieldBase } from '../../component-library'; - - // (Default) - - -``` - -### Truncate - -Use the `truncate` prop to truncate the text of the the `TextFieldBase`. Defaults to `true`. - - - - - -```jsx -import { TextFieldBase } from '../../component-library'; - -; // truncate is set to `true` by default -; -``` - -### Left Accessory Right Accessory - -Use the `leftAccessory` and `rightAccessory` props to add components such as icons or buttons to either side of the `TextFieldBase`. - - - - - -```jsx -import { Color, DISPLAY } from '../../../helpers/constants/design-system'; -import { ButtonIcon, Icon, ICON_NAMES, TextFieldBase } from '../../component-library'; - - - } -/> - - - } -/> - -} - rightAccessory={} -/> - -} - rightAccessory={ - isAddressValid && ( - - ) - } -/> -``` - -### Input Ref - -Use the `inputRef` prop to access the ref of the `` html element of `TextFieldBase`. This is useful for focusing the input from a button or other component. - - - - - -```jsx -import { Button, TextFieldBase } from '../../component-library'; - -const inputRef = useRef(null); -const [value, setValue] = useState(''); -const handleOnClick = () => { - inputRef.current.focus(); -}; -const handleOnChange = (e) => { - setValue(e.target.value); -}; - - - -``` - -### Input Component - -Use the `InputComponent` prop change the component used for the input element. This is useful for replacing the base input with a custom input while retaining the functionality of the `TextFieldBase`. - -Defaults to the [Text](/docs/components-componentlibrary-text--default-story) component - -To function fully the custom component should accept the following props: - -- `aria-invalid` -- `as` -- `autoComplete` -- `autoFocus` -- `backgroundColor` -- `defaultValue` -- `disabled` -- `focused` -- `id` -- `margin` -- `maxLength` -- `name` -- `onBlur` -- `onChange` -- `onFocus` -- `padding` -- `paddingLeft` -- `paddingRight` -- `placeholder` -- `readOnly` -- `ref` -- `required` -- `value` -- `variant` -- `type` - - - - - -```jsx -import { TextFieldBase, Icon, ICON_NAMES } from '../../component-library'; -import { Size } from '../../../helpers/constants/design-system'; - -// should map the props to the custom input component -const CustomInputComponent = () =>
{/* Custom input component */}
; - -const TextFieldCustomInput = (args) => ( - - } - /> -); -``` - -### Auto Complete - -Use the `autoComplete` prop to set the autocomplete html attribute. It allows the browser to predict the value based on earlier typed values. - - - - - -```jsx -import { TextFieldBase } from '../../component-library'; - -; -``` - -### Auto Focus - -Use the `autoFocus` prop to focus the `TextFieldBase` during the first mount - - - - - -```jsx -import { TextFieldBase } from '../../component-library'; - -; -``` - -### Default Value - -Use the `defaultValue` prop to set the default value of the `TextFieldBase` - - - - - -```jsx -import { TextFieldBase } from '../../component-library'; - -; -``` - -### Disabled - -Use the `disabled` prop to set the disabled state of the `TextFieldBase` - - - - - -```jsx -import { TextFieldBase } from '../../component-library'; - -; -``` - -### Error - -Use the `error` prop to set the error state of the `TextFieldBase` - - - - - -```jsx -import { TextFieldBase } from '../../component-library'; - -; -``` - -### Max Length - -Use the `maxLength` prop to set the maximum allowed input characters for the `TextFieldBase` - - - - - -```jsx -import { TextFieldBase } from '../../component-library'; - -; -``` - -### Read Only - -Use the `readOnly` prop to set the `TextFieldBase` to read only. When `readOnly` is true `TextFieldBase` will not have a focus state. - - - - - -```jsx -import { TextFieldBase } from '../../component-library'; - -; -``` - -### Required - -Use the `required` prop to set the `TextFieldBase` to required. Currently there is no visual difference to the `TextFieldBase` when required. - - - - - -```jsx -import { TextFieldBase } from '../../component-library'; - -// Currently no visual difference -; -``` diff --git a/ui/components/component-library/text-field-search/__snapshots__/text-field-search.test.js.snap b/ui/components/component-library/text-field-search/__snapshots__/text-field-search.test.js.snap index 102fc15d2..ddb232239 100644 --- a/ui/components/component-library/text-field-search/__snapshots__/text-field-search.test.js.snap +++ b/ui/components/component-library/text-field-search/__snapshots__/text-field-search.test.js.snap @@ -11,7 +11,7 @@ exports[`TextFieldSearch should render correctly 1`] = ` /> { const internalInputRef = useRef(null); @@ -114,8 +113,7 @@ export const TextField = ({ {startAccessory}