diff --git a/package-lock.json b/package-lock.json index af84d731fe..8609a240a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -96,7 +96,7 @@ "jest-junit": "^13.0.0", "lint-staged": "^13.2.2", "msw": "^1.2.1", - "postcss": "^8.4.12", + "postcss": "^8.4.31", "prettier": "^2.8.8", "react-scripts": "^5.0.1", "react-test-renderer": "^18.2.0", @@ -25706,9 +25706,9 @@ } }, "node_modules/postcss": { - "version": "8.4.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", - "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "dev": true, "funding": [ { @@ -52698,9 +52698,9 @@ } }, "postcss": { - "version": "8.4.23", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", - "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "dev": true, "requires": { "nanoid": "^3.3.6", diff --git a/package.json b/package.json index 042c7d506a..11030d033a 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,7 @@ "jest-junit": "^13.0.0", "lint-staged": "^13.2.2", "msw": "^1.2.1", - "postcss": "^8.4.12", + "postcss": "^8.4.31", "prettier": "^2.8.8", "react-scripts": "^5.0.1", "react-test-renderer": "^18.2.0", diff --git a/src/ui/Icon/Icon.tsx b/src/ui/Icon/Icon.tsx index 63d5054801..55977b1d1f 100644 --- a/src/ui/Icon/Icon.tsx +++ b/src/ui/Icon/Icon.tsx @@ -13,7 +13,7 @@ const iconComponentCollection = { type IconCollection = typeof iconComponentCollection type Variant = keyof IconCollection -type OutlineIconCollection = typeof svgOutline +export type OutlineIconCollection = typeof svgOutline type SolidIconCollection = typeof svgSolid type DeveloperIconCollection = typeof svgDeveloper diff --git a/src/ui/TextInput/TextInput.spec.jsx b/src/ui/TextInput/TextInput.spec.tsx similarity index 57% rename from src/ui/TextInput/TextInput.spec.jsx rename to src/ui/TextInput/TextInput.spec.tsx index 0a007b3a0f..81e9b15387 100644 --- a/src/ui/TextInput/TextInput.spec.jsx +++ b/src/ui/TextInput/TextInput.spec.tsx @@ -1,12 +1,18 @@ import { render, screen } from '@testing-library/react' +import { OutlineIconCollection } from 'ui/Icon/Icon' + import TextInput from './TextInput' -describe('TextInput', () => { - let wrapper +interface TextInputSetupArgs { + label?: string + icon?: keyof OutlineIconCollection + placeholder?: string +} - function setup(props) { - wrapper = render() +describe('TextInput', () => { + function setup(props: TextInputSetupArgs) { + render() } describe('when rendered', () => { @@ -17,9 +23,9 @@ describe('TextInput', () => { }) it('renders the textbox with the name of the label', () => { - screen.getByRole('textbox', { - name: /label/i, - }) + expect( + screen.getByRole('textbox', { name: /label/i }) + ).toBeInTheDocument() }) }) @@ -31,9 +37,9 @@ describe('TextInput', () => { }) it('renders the textbox with the placeholder as the label', () => { - screen.getByRole('textbox', { - name: /search orgs/i, - }) + expect( + screen.getByRole('textbox', { name: /search orgs/i }) + ).toBeInTheDocument() }) }) @@ -45,7 +51,8 @@ describe('TextInput', () => { }) it('renders an icon', () => { - expect(wrapper.container.querySelector('svg')).not.toBeNull() + const icon = screen.getByText(/search.svg/) + expect(icon).toBeInTheDocument() }) }) }) diff --git a/src/ui/TextInput/TextInput.stories.jsx b/src/ui/TextInput/TextInput.stories.jsx deleted file mode 100644 index 40eff7f14c..0000000000 --- a/src/ui/TextInput/TextInput.stories.jsx +++ /dev/null @@ -1,34 +0,0 @@ -import TextInput from './TextInput' - -const Template = (args) => - -export const NormalInput = Template.bind({}) -NormalInput.args = { - label: 'Name', - placeholder: 'Write your name', -} - -export const NumberInput = Template.bind({}) -NumberInput.args = { - label: 'Age', - placeholder: 'Type your age', - type: 'number', -} - -export const InputWithNoLabel = Template.bind({}) -InputWithNoLabel.args = { - placeholder: - 'If no labels, the placeholder will also be used as a label for a11y', - type: 'number', -} - -export const InputWithIcon = Template.bind({}) -InputWithIcon.args = { - icon: 'search', - placeholder: 'Search', -} - -export default { - component: TextInput, - title: 'Components/TextInput', -} diff --git a/src/ui/TextInput/TextInput.stories.tsx b/src/ui/TextInput/TextInput.stories.tsx new file mode 100644 index 0000000000..1236859074 --- /dev/null +++ b/src/ui/TextInput/TextInput.stories.tsx @@ -0,0 +1,40 @@ +import { Meta, StoryObj } from '@storybook/react' + +import TextInput from './TextInput' + +export default { + title: 'Components/TextInput', + component: TextInput, +} as Meta + +type Story = StoryObj + +export const TextInputWithLabel: Story = { + args: { + label: 'Name', + placeholder: 'Write your name', + }, + render: (args) => { + return + }, +} + +export const TextInputWithPlaceholder: Story = { + args: { + placeholder: 'Type your age', + type: 'number', + }, + render: (args) => { + return + }, +} + +export const TextInputWithIcon: Story = { + args: { + icon: 'search', + placeholder: 'Search', + }, + render: (args) => { + return + }, +} diff --git a/src/ui/TextInput/TextInput.jsx b/src/ui/TextInput/TextInput.tsx similarity index 73% rename from src/ui/TextInput/TextInput.jsx rename to src/ui/TextInput/TextInput.tsx index 5c9745eff3..eb0b0f8066 100644 --- a/src/ui/TextInput/TextInput.jsx +++ b/src/ui/TextInput/TextInput.tsx @@ -1,11 +1,18 @@ import cs from 'classnames' -import defaultTo from 'lodash/defaultTo' -import uniqueId from 'lodash/uniqueId' -import PropTypes from 'prop-types' -import { forwardRef } from 'react' +import { defaultTo, uniqueId } from 'lodash' +import { forwardRef, HTMLProps, Ref } from 'react' -import { dataMarketingType } from 'shared/propTypes' import Icon from 'ui/Icon' +import { OutlineIconCollection } from 'ui/Icon/Icon' + + +interface TextInputProps extends HTMLProps { + label?: string + icon?: keyof OutlineIconCollection + placeholder?: string + variant?: 'default' | 'topRounded' + dataMarketing?: string +} const VariantClasses = { default: 'rounded border', @@ -22,8 +29,15 @@ const styles = { const TextInput = forwardRef( ( - { type = 'text', icon, label, placeholder, variant = 'default', ...props }, - ref + { + type = 'text', + icon, + label, + placeholder, + variant = 'default', + ...props + }: TextInputProps, + ref: Ref ) => { const id = uniqueId('text-input') const { className, dataMarketing, ...newProps } = props @@ -66,15 +80,4 @@ const TextInput = forwardRef( TextInput.displayName = 'TextInput' -TextInput.propTypes = { - label: PropTypes.string, - type: PropTypes.string, - icon: PropTypes.string, - placeholder: PropTypes.string, - onChange: PropTypes.func, - value: PropTypes.string, - variant: PropTypes.oneOf(['default', 'topRounded']), - dataMarketing: dataMarketingType, -} - export default TextInput