diff --git a/.changeset/perfect-dolls-march.md b/.changeset/perfect-dolls-march.md new file mode 100644 index 0000000000..e7adda7853 --- /dev/null +++ b/.changeset/perfect-dolls-march.md @@ -0,0 +1,5 @@ +--- +'@toptal/picasso-number-input': minor +--- + +- support custom `endAdornment` in NumberInput diff --git a/packages/base/NumberInput/src/NumberInput/NumberInput.tsx b/packages/base/NumberInput/src/NumberInput/NumberInput.tsx index 58531a81de..50011b22bf 100644 --- a/packages/base/NumberInput/src/NumberInput/NumberInput.tsx +++ b/packages/base/NumberInput/src/NumberInput/NumberInput.tsx @@ -50,6 +50,7 @@ export const NumberInput = forwardRef( status, onResetClick, enableReset, + endAdornment: customEndAdornment = null, width, icon, size, @@ -63,7 +64,7 @@ export const NumberInput = forwardRef( useRef(null) ) - const endAdornment = hideControls ? null : ( + const defaultEndAdornment = ( ( /> ) + const endAdornment = hideControls ? ( + customEndAdornment + ) : ( + <> + {customEndAdornment} + {defaultEndAdornment} + + ) + const startAdornment = icon ? ( {icon} diff --git a/packages/base/NumberInput/src/NumberInput/story/WithEndAdornment.example.tsx b/packages/base/NumberInput/src/NumberInput/story/WithEndAdornment.example.tsx new file mode 100644 index 0000000000..c422f7a7a8 --- /dev/null +++ b/packages/base/NumberInput/src/NumberInput/story/WithEndAdornment.example.tsx @@ -0,0 +1,26 @@ +import type { ChangeEventHandler } from 'react' +import React, { useState } from 'react' +import { NumberInput, Container, Typography } from '@toptal/picasso' + +const WithEndAdornmentExample = () => { + const [value, setValue] = useState('1') + + const handleChange: ChangeEventHandler = event => { + setValue(event.target.value) + } + + return ( + + $/hr} + /> + + ) +} + +export default WithEndAdornmentExample diff --git a/packages/base/NumberInput/src/NumberInput/story/index.jsx b/packages/base/NumberInput/src/NumberInput/story/index.jsx index 55c85f1bde..9be41aaa96 100644 --- a/packages/base/NumberInput/src/NumberInput/story/index.jsx +++ b/packages/base/NumberInput/src/NumberInput/story/index.jsx @@ -4,7 +4,7 @@ import PicassoBook from '~/.storybook/components/PicassoBook' const page = PicassoBook.section('Forms').createPage( 'NumberInput', `Input component for numbers - + ${PicassoBook.createSourceLink(__filename)} ` ) @@ -35,6 +35,11 @@ page 'With Icon', 'base/NumberInput' ) + .addExample( + 'NumberInput/story/WithEndAdornment.example.tsx', + 'With End Adornment', + 'base/NumberInput' + ) .addExample( 'NumberInput/story/Sizes.example.tsx', 'Sizes', diff --git a/packages/base/NumberInput/src/NumberInput/test.tsx b/packages/base/NumberInput/src/NumberInput/test.tsx index 356d34020c..9eccb92c26 100644 --- a/packages/base/NumberInput/src/NumberInput/test.tsx +++ b/packages/base/NumberInput/src/NumberInput/test.tsx @@ -22,6 +22,8 @@ const NumberInputRenderer = ( value={value} onChange={handleChange} status={props.status} + endAdornment={props.endAdornment} + hideControls={props.hideControls} testIds={props.testIds} /> ) @@ -150,4 +152,35 @@ describe('NumberInput', () => { expect(validIcon).not.toBeVisible() }) }) + + describe('end adornment', () => { + describe('when endAdornment is passed', () => { + it('renders endAdornment with control buttons', () => { + const testProps: NumberInputProps = { + value: '10', + endAdornment:
, + } + + const { getByTestId, getAllByRole } = renderNumberInput(testProps) + + expect(getByTestId('custom-end-adornment')).toBeVisible() + expect(getAllByRole('button')).toHaveLength(2) + }) + }) + + describe('when endAdornment is passed and controls are hidden', () => { + it('renders endAdornment without control buttons', () => { + const testProps: NumberInputProps = { + value: '10', + endAdornment:
, + hideControls: true, + } + + const { getByTestId, queryAllByRole } = renderNumberInput(testProps) + + expect(getByTestId('custom-end-adornment')).toBeVisible() + expect(queryAllByRole('button')).toHaveLength(0) + }) + }) + }) })