mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
TextFieldSearch house keeping updates (#16669)
This commit is contained in:
parent
d096560d85
commit
3deb8734ac
@ -1,10 +1,12 @@
|
||||
import { Story, Canvas, ArgsTable } from '@storybook/addon-docs';
|
||||
|
||||
import { TextFieldBase, TextField } from '..';
|
||||
|
||||
import { TextFieldSearch } from './text-field-search';
|
||||
|
||||
# TextFieldSearch
|
||||
|
||||
The `TextFieldSearch` allows users to enter text to search. It wraps the `TextField` component that adds a search icon to the left of the input.
|
||||
The `TextFieldSearch` allows users to enter text to search
|
||||
|
||||
<Canvas>
|
||||
<Story id="ui-components-component-library-text-field-search-text-field-search-stories-js--default-story" />
|
||||
@ -12,26 +14,34 @@ The `TextFieldSearch` allows users to enter text to search. It wraps the `TextFi
|
||||
|
||||
## Props
|
||||
|
||||
The `TextFieldSearch` accepts all props below as well as all [Box](/docs/ui-components-ui-box-box-stories-js--default-story#props), [TextField](/docs/ui-components-component-library-text-field-text-field-stories-js--default-story#props) component props
|
||||
The `TextFieldSearch` accepts all props below as well as all [Box](/docs/ui-components-ui-box-box-stories-js--default-story#props) component props
|
||||
|
||||
<ArgsTable of={TextFieldSearch} />
|
||||
|
||||
### Show Clear Button
|
||||
`TextFieldSearch` accepts all [TextField](/docs/ui-components-component-library-text-field-text-field-stories-js--default-story#props)
|
||||
component props
|
||||
|
||||
Use the `showClearButton` prop to display a clear button when `TextFieldSearch` has a value. Use the `clearButtonOnClick` prop to pass an `onClick` event handler to clear the value of the input.
|
||||
<ArgsTable of={TextField} />
|
||||
|
||||
Defaults to `true`
|
||||
`TextFieldSearch` accepts all [TextFieldBase](/docs/ui-components-component-library-text-field-base-text-field-base-stories-js--default-story#props)
|
||||
component props
|
||||
|
||||
<ArgsTable of={TextFieldBase} />
|
||||
|
||||
### Clear Button On Click
|
||||
|
||||
`TextFieldSearch` displays a clear button when text is entered into the input. Use the `clearButtonOnClick` prop to pass an `onClick` event handler to clear the value of the input. To hide the clear button, pass `false` to the `showClearButton` prop.
|
||||
|
||||
The clear button uses [ButtonIcon](/docs/ui-components-component-library-button-icon-button-icon-stories-js--default-story) and accepts all props from that component.
|
||||
|
||||
**NOTE: The `showClearButton` only works with a controlled input.**
|
||||
|
||||
<Canvas>
|
||||
<Story id="ui-components-component-library-text-field-search-text-field-search-stories-js--show-clear-button" />
|
||||
<Story id="ui-components-component-library-text-field-search-text-field-search-stories-js--clear-button-on-click" />
|
||||
</Canvas>
|
||||
|
||||
```jsx
|
||||
import { TextFieldSearch } from '../../ui/component-library/text-field';
|
||||
import { TextFieldSearch } from '../../component-library';
|
||||
|
||||
const [value, setValue] = useState('show clear');
|
||||
|
||||
@ -67,7 +77,7 @@ import {
|
||||
BORDER_RADIUS,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
|
||||
import { TextFieldSearch } from '../../ui/component-library/text-field';
|
||||
import { TextFieldSearch } from '../../component-library';
|
||||
|
||||
const [value, setValue] = useState('show clear');
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`TextFieldSearch should render correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="box mm-text-field-base mm-text-field-base--size-md mm-text-field-base--truncate mm-text-field mm-text-field-search box--padding-left-4 box--display-inline-flex box--flex-direction-row box--align-items-center box--background-color-background-default box--rounded-sm box--border-width-1 box--border-style-solid"
|
||||
>
|
||||
<div
|
||||
class="box mm-icon mm-icon--size-sm box--flex-direction-row box--color-inherit"
|
||||
style="mask-image: url('./images/icons/icon-search-filled.svg');"
|
||||
/>
|
||||
<input
|
||||
autocomplete="off"
|
||||
class="box text mm-text-field-base__input text--body-md text--color-text-default box--margin-right-6 box--padding-right-4 box--padding-left-2 box--flex-direction-row box--background-color-transparent"
|
||||
focused="false"
|
||||
type="search"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
@ -12,7 +12,6 @@ import { TextField } from '../text-field';
|
||||
export const TextFieldSearch = ({
|
||||
value,
|
||||
onChange,
|
||||
showClearButton = true,
|
||||
clearButtonOnClick,
|
||||
clearButtonProps,
|
||||
className,
|
||||
@ -24,7 +23,7 @@ export const TextFieldSearch = ({
|
||||
onChange={onChange}
|
||||
type={TEXT_FIELD_BASE_TYPES.SEARCH}
|
||||
leftAccessory={<Icon name={ICON_NAMES.SEARCH_FILLED} size={SIZES.SM} />}
|
||||
showClearButton={showClearButton}
|
||||
showClearButton
|
||||
clearButtonOnClick={clearButtonOnClick}
|
||||
clearButtonProps={clearButtonProps}
|
||||
{...props}
|
||||
@ -40,15 +39,25 @@ TextFieldSearch.propTypes = {
|
||||
* The onChange handler of the TextFieldSearch
|
||||
*/
|
||||
onChange: TextFieldBase.propTypes.onChange,
|
||||
/**
|
||||
* Show a clear button to clear the input
|
||||
* Defaults to true
|
||||
*/
|
||||
showClearButton: PropTypes.bool,
|
||||
/**
|
||||
* The onClick handler for the clear button
|
||||
* Required unless showClearButton is false
|
||||
*
|
||||
* @param {object} props - The props passed to the component.
|
||||
* @param {string} propName - The prop name in this case 'id'.
|
||||
* @param {string} componentName - The name of the component.
|
||||
*/
|
||||
clearButtonOnClick: PropTypes.func,
|
||||
clearButtonOnClick: (props, propName, componentName) => {
|
||||
if (
|
||||
props.showClearButton &&
|
||||
(!props[propName] || !props.clearButtonProps?.onClick)
|
||||
) {
|
||||
return new Error(
|
||||
`${propName} is required unless showClearButton is false. Warning coming from ${componentName} ui/components/component-library/text-field-search/text-field-search.js`,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
/**
|
||||
* The props to pass to the clear button
|
||||
*/
|
||||
|
@ -46,9 +46,6 @@ export default {
|
||||
onChange: {
|
||||
action: 'onChange',
|
||||
},
|
||||
showClearButton: {
|
||||
control: 'boolean',
|
||||
},
|
||||
clearButtonOnClick: {
|
||||
action: 'clearButtonOnClick',
|
||||
},
|
||||
@ -167,8 +164,8 @@ export default {
|
||||
},
|
||||
},
|
||||
args: {
|
||||
showClearButton: true,
|
||||
placeholder: 'Search',
|
||||
value: '',
|
||||
},
|
||||
};
|
||||
|
||||
@ -193,18 +190,16 @@ const Template = (args) => {
|
||||
export const DefaultStory = Template.bind({});
|
||||
DefaultStory.storyName = 'Default';
|
||||
|
||||
export const ShowClearButton = Template.bind({});
|
||||
export const ClearButtonOnClick = Template.bind({});
|
||||
|
||||
ShowClearButton.args = {
|
||||
placeholder: 'Enter text to show clear',
|
||||
showClearButton: true,
|
||||
ClearButtonOnClick.args = {
|
||||
value: 'Text to clear',
|
||||
};
|
||||
|
||||
export const ClearButtonProps = Template.bind({});
|
||||
ClearButtonProps.args = {
|
||||
value: 'clear button props',
|
||||
size: SIZES.LG,
|
||||
showClearButton: true,
|
||||
clearButtonProps: {
|
||||
backgroundColor: COLORS.BACKGROUND_ALTERNATIVE,
|
||||
borderRadius: BORDER_RADIUS.XS,
|
||||
|
@ -6,24 +6,38 @@ import { TextFieldSearch } from './text-field-search';
|
||||
|
||||
describe('TextFieldSearch', () => {
|
||||
it('should render correctly', () => {
|
||||
const { getByRole } = render(<TextFieldSearch />);
|
||||
const { getByRole, container } = render(<TextFieldSearch />);
|
||||
expect(getByRole('searchbox')).toBeDefined();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
it('should render showClearButton button when showClearButton is true and value exists', async () => {
|
||||
it('should render with a custom className', () => {
|
||||
const fn = jest.fn();
|
||||
const { getByTestId } = render(
|
||||
<TextFieldSearch
|
||||
data-testid="test-search"
|
||||
className="test-search"
|
||||
clearButtonOnClick={fn}
|
||||
/>,
|
||||
);
|
||||
expect(getByTestId('test-search')).toHaveClass('test-search');
|
||||
});
|
||||
it('should render showClearButton button when value exists', async () => {
|
||||
const fn = jest.fn();
|
||||
// As showClearButton is intended to be used with a controlled input we need to use renderControlledInput
|
||||
const { user, getByRole } = renderControlledInput(TextFieldSearch, {
|
||||
showClearButton: true,
|
||||
clearButtonOnClick: fn,
|
||||
});
|
||||
await user.type(getByRole('searchbox'), 'test value');
|
||||
expect(getByRole('searchbox')).toHaveValue('test value');
|
||||
expect(getByRole('button', { name: /Clear/u })).toBeDefined();
|
||||
});
|
||||
it('should still render with the rightAccessory when showClearButton is true', async () => {
|
||||
it('should still render with the rightAccessory if it exists', async () => {
|
||||
const fn = jest.fn();
|
||||
// As showClearButton is intended to be used with a controlled input we need to use renderControlledInput
|
||||
const { user, getByRole, getByText } = renderControlledInput(
|
||||
TextFieldSearch,
|
||||
{
|
||||
showClearButton: true,
|
||||
clearButtonOnClick: fn,
|
||||
rightAccessory: <div>right-accessory</div>,
|
||||
},
|
||||
);
|
||||
@ -36,7 +50,6 @@ describe('TextFieldSearch', () => {
|
||||
// As showClearButton is intended to be used with a controlled input we need to use renderControlledInput
|
||||
const fn = jest.fn();
|
||||
const { user, getByRole } = renderControlledInput(TextFieldSearch, {
|
||||
showClearButton: true,
|
||||
clearButtonOnClick: fn,
|
||||
});
|
||||
await user.type(getByRole('searchbox'), 'test value');
|
||||
@ -47,8 +60,8 @@ describe('TextFieldSearch', () => {
|
||||
// As showClearButton is intended to be used with a controlled input we need to use renderControlledInput
|
||||
const fn = jest.fn();
|
||||
const { user, getByRole } = renderControlledInput(TextFieldSearch, {
|
||||
showClearButton: true,
|
||||
clearButtonProps: { onClick: fn },
|
||||
clearButtonOnClick: fn,
|
||||
});
|
||||
await user.type(getByRole('searchbox'), 'test value');
|
||||
await user.click(getByRole('button', { name: /Clear/u }));
|
||||
|
Loading…
x
Reference in New Issue
Block a user