Skip to content

Commit 7be2226

Browse files
szalonnamatyasf
authored andcommitted
feat(ui-number-input): add customizable icons for increment and decrement buttons
Closes: CLX-261
1 parent c6cae87 commit 7be2226

File tree

4 files changed

+76
-8
lines changed

4 files changed

+76
-8
lines changed

packages/ui-number-input/src/NumberInput/__examples__/NumberInput.examples.ts renamed to packages/ui-number-input/src/NumberInput/__examples__/NumberInput.examples.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,24 @@
2222
* SOFTWARE.
2323
*/
2424

25+
import React from 'react'
2526
import type { StoryConfig } from '@instructure/ui-test-utils'
27+
import { IconZoomInLine, IconZoomOutLine } from '@instructure/ui-icons'
2628
import type { NumberInputProps } from '../props'
2729

2830
export default {
2931
sectionProp: 'size',
3032
maxExamplesPerPage: 50,
3133
propValues: {
3234
placeholder: [null, 'type something'],
33-
layout: [null, 'inline']
35+
layout: [null, 'inline'],
36+
renderIcons: [
37+
null,
38+
{
39+
increase: <IconZoomInLine />,
40+
decrease: <IconZoomOutLine />
41+
}
42+
]
3443
},
3544
getComponentProps: () => {
3645
return {

packages/ui-number-input/src/NumberInput/__new-tests__/NumberInput.test.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { NumberInput } from '../index'
3333
import NumberInputExamples from '../__examples__/NumberInput.examples'
3434
// eslint-disable-next-line no-restricted-imports
3535
import { generateA11yTests } from '@instructure/ui-scripts/lib/test/generateA11yTests'
36+
import { IconZoomInLine, IconZoomOutLine } from '@instructure/ui-icons'
3637

3738
describe('<NumberInput />', () => {
3839
let consoleWarningMock: ReturnType<typeof vi.spyOn>
@@ -282,4 +283,39 @@ describe('<NumberInput />', () => {
282283
})
283284
}
284285
})
286+
287+
it('renders custom interactive icons', async () => {
288+
const onDecrement = vi.fn()
289+
const onIncrement = vi.fn()
290+
const { container } = render(
291+
<NumberInput
292+
renderLabel="Label"
293+
onIncrement={onIncrement}
294+
onDecrement={onDecrement}
295+
renderIcons={{
296+
increase: <IconZoomInLine />,
297+
decrease: <IconZoomOutLine />
298+
}}
299+
/>
300+
)
301+
302+
const zoomInIcon = container.querySelector('svg[name="IconZoomIn"]')
303+
const zoomOutIcon = container.querySelector('svg[name="IconZoomOut"]')
304+
expect(zoomInIcon).toBeInTheDocument()
305+
expect(zoomOutIcon).toBeInTheDocument()
306+
307+
const buttons = container.querySelectorAll(
308+
'button[class$="-numberInput_arrow'
309+
)
310+
311+
userEvent.click(buttons[0])
312+
await waitFor(() => {
313+
expect(onIncrement).toHaveBeenCalledTimes(1)
314+
})
315+
316+
userEvent.click(buttons[1])
317+
await waitFor(() => {
318+
expect(onDecrement).toHaveBeenCalledTimes(1)
319+
})
320+
})
285321
})

packages/ui-number-input/src/NumberInput/index.tsx

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import type {
5252
NumberInputState,
5353
NumberInputStyleProps
5454
} from './props'
55+
import { Renderable } from '@instructure/shared-types'
5556

5657
/**
5758
---
@@ -203,7 +204,7 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
203204
}
204205
}
205206

206-
renderArrows() {
207+
renderArrows(customIcons?: { increase: Renderable; decrease: Renderable }) {
207208
return (
208209
<span css={this.props.styles?.arrowContainer}>
209210
<button
@@ -213,7 +214,11 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
213214
tabIndex={-1}
214215
type="button"
215216
>
216-
<IconArrowOpenUpLine />
217+
{customIcons?.increase ? (
218+
callRenderProp(customIcons.increase)
219+
) : (
220+
<IconArrowOpenUpLine />
221+
)}
217222
</button>
218223
<button
219224
aria-hidden
@@ -222,7 +227,11 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
222227
tabIndex={-1}
223228
type="button"
224229
>
225-
<IconArrowOpenDownLine />
230+
{customIcons?.decrease ? (
231+
callRenderProp(customIcons.decrease)
232+
) : (
233+
<IconArrowOpenDownLine />
234+
)}
226235
</button>
227236
</span>
228237
)
@@ -238,7 +247,8 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
238247
value,
239248
width,
240249
styles,
241-
allowStringValue
250+
allowStringValue,
251+
renderIcons
242252
} = this.props
243253

244254
const { interaction } = this
@@ -295,7 +305,7 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
295305
onChange={this.handleChange}
296306
onKeyDown={this.handleKeyDown}
297307
/>
298-
{showArrows ? this.renderArrows() : null}
308+
{showArrows ? this.renderArrows(renderIcons) : null}
299309
</span>
300310
</span>
301311
</FormField>

packages/ui-number-input/src/NumberInput/props.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,14 @@ type NumberInputOwnProps = {
166166
* sets the input type to string and allows string as value
167167
*/
168168
allowStringValue?: boolean
169+
170+
/**
171+
* Sets the icons to be rendered for increase and decrease buttons
172+
*/
173+
renderIcons?: {
174+
increase: Renderable
175+
decrease: Renderable
176+
}
169177
}
170178

171179
type NumberInputState = {
@@ -226,7 +234,11 @@ const propTypes: PropValidators<PropKeys> = {
226234
onKeyDown: PropTypes.func,
227235
inputMode: PropTypes.oneOf(['numeric', 'decimal', 'tel']),
228236
textAlign: PropTypes.oneOf(['start', 'center']),
229-
allowStringValue: PropTypes.bool
237+
allowStringValue: PropTypes.bool,
238+
renderIcons: PropTypes.shape({
239+
increase: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
240+
decrease: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired
241+
})
230242
}
231243

232244
const allowedProps: AllowedPropKeys = [
@@ -250,7 +262,8 @@ const allowedProps: AllowedPropKeys = [
250262
'onKeyDown',
251263
'inputMode',
252264
'textAlign',
253-
'allowStringValue'
265+
'allowStringValue',
266+
'renderIcons'
254267
]
255268

256269
export type {

0 commit comments

Comments
 (0)