Skip to content

Commit

Permalink
feat(ui-number-input): add customizable icons for increment and decre…
Browse files Browse the repository at this point in the history
…ment buttons

Closes: CLX-261
  • Loading branch information
szalonna authored and matyasf committed Dec 11, 2024
1 parent c6cae87 commit 7be2226
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,24 @@
* SOFTWARE.
*/

import React from 'react'
import type { StoryConfig } from '@instructure/ui-test-utils'
import { IconZoomInLine, IconZoomOutLine } from '@instructure/ui-icons'
import type { NumberInputProps } from '../props'

export default {
sectionProp: 'size',
maxExamplesPerPage: 50,
propValues: {
placeholder: [null, 'type something'],
layout: [null, 'inline']
layout: [null, 'inline'],
renderIcons: [
null,
{
increase: <IconZoomInLine />,
decrease: <IconZoomOutLine />
}
]
},
getComponentProps: () => {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { NumberInput } from '../index'
import NumberInputExamples from '../__examples__/NumberInput.examples'
// eslint-disable-next-line no-restricted-imports
import { generateA11yTests } from '@instructure/ui-scripts/lib/test/generateA11yTests'
import { IconZoomInLine, IconZoomOutLine } from '@instructure/ui-icons'

describe('<NumberInput />', () => {
let consoleWarningMock: ReturnType<typeof vi.spyOn>
Expand Down Expand Up @@ -282,4 +283,39 @@ describe('<NumberInput />', () => {
})
}
})

it('renders custom interactive icons', async () => {
const onDecrement = vi.fn()
const onIncrement = vi.fn()
const { container } = render(
<NumberInput
renderLabel="Label"
onIncrement={onIncrement}
onDecrement={onDecrement}
renderIcons={{
increase: <IconZoomInLine />,
decrease: <IconZoomOutLine />
}}
/>
)

const zoomInIcon = container.querySelector('svg[name="IconZoomIn"]')
const zoomOutIcon = container.querySelector('svg[name="IconZoomOut"]')
expect(zoomInIcon).toBeInTheDocument()
expect(zoomOutIcon).toBeInTheDocument()

const buttons = container.querySelectorAll(
'button[class$="-numberInput_arrow'
)

userEvent.click(buttons[0])
await waitFor(() => {
expect(onIncrement).toHaveBeenCalledTimes(1)
})

userEvent.click(buttons[1])
await waitFor(() => {
expect(onDecrement).toHaveBeenCalledTimes(1)
})
})
})
20 changes: 15 additions & 5 deletions packages/ui-number-input/src/NumberInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import type {
NumberInputState,
NumberInputStyleProps
} from './props'
import { Renderable } from '@instructure/shared-types'

/**
---
Expand Down Expand Up @@ -203,7 +204,7 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
}
}

renderArrows() {
renderArrows(customIcons?: { increase: Renderable; decrease: Renderable }) {
return (
<span css={this.props.styles?.arrowContainer}>
<button
Expand All @@ -213,7 +214,11 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
tabIndex={-1}
type="button"
>
<IconArrowOpenUpLine />
{customIcons?.increase ? (
callRenderProp(customIcons.increase)
) : (
<IconArrowOpenUpLine />
)}
</button>
<button
aria-hidden
Expand All @@ -222,7 +227,11 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
tabIndex={-1}
type="button"
>
<IconArrowOpenDownLine />
{customIcons?.decrease ? (
callRenderProp(customIcons.decrease)
) : (
<IconArrowOpenDownLine />
)}
</button>
</span>
)
Expand All @@ -238,7 +247,8 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
value,
width,
styles,
allowStringValue
allowStringValue,
renderIcons
} = this.props

const { interaction } = this
Expand Down Expand Up @@ -295,7 +305,7 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
onChange={this.handleChange}
onKeyDown={this.handleKeyDown}
/>
{showArrows ? this.renderArrows() : null}
{showArrows ? this.renderArrows(renderIcons) : null}
</span>
</span>
</FormField>
Expand Down
17 changes: 15 additions & 2 deletions packages/ui-number-input/src/NumberInput/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,14 @@ type NumberInputOwnProps = {
* sets the input type to string and allows string as value
*/
allowStringValue?: boolean

/**
* Sets the icons to be rendered for increase and decrease buttons
*/
renderIcons?: {
increase: Renderable
decrease: Renderable
}
}

type NumberInputState = {
Expand Down Expand Up @@ -226,7 +234,11 @@ const propTypes: PropValidators<PropKeys> = {
onKeyDown: PropTypes.func,
inputMode: PropTypes.oneOf(['numeric', 'decimal', 'tel']),
textAlign: PropTypes.oneOf(['start', 'center']),
allowStringValue: PropTypes.bool
allowStringValue: PropTypes.bool,
renderIcons: PropTypes.shape({
increase: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
decrease: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired
})
}

const allowedProps: AllowedPropKeys = [
Expand All @@ -250,7 +262,8 @@ const allowedProps: AllowedPropKeys = [
'onKeyDown',
'inputMode',
'textAlign',
'allowStringValue'
'allowStringValue',
'renderIcons'
]

export type {
Expand Down

0 comments on commit 7be2226

Please sign in to comment.