diff --git a/packages/ui-number-input/src/NumberInput/__examples__/NumberInput.examples.ts b/packages/ui-number-input/src/NumberInput/__examples__/NumberInput.examples.tsx
similarity index 87%
rename from packages/ui-number-input/src/NumberInput/__examples__/NumberInput.examples.ts
rename to packages/ui-number-input/src/NumberInput/__examples__/NumberInput.examples.tsx
index 27a197af75..9f0ae7916a 100644
--- a/packages/ui-number-input/src/NumberInput/__examples__/NumberInput.examples.ts
+++ b/packages/ui-number-input/src/NumberInput/__examples__/NumberInput.examples.tsx
@@ -22,7 +22,9 @@
* 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 {
@@ -30,7 +32,14 @@ export default {
maxExamplesPerPage: 50,
propValues: {
placeholder: [null, 'type something'],
- layout: [null, 'inline']
+ layout: [null, 'inline'],
+ renderIcons: [
+ null,
+ {
+ increase: ,
+ decrease:
+ }
+ ]
},
getComponentProps: () => {
return {
diff --git a/packages/ui-number-input/src/NumberInput/__new-tests__/NumberInput.test.tsx b/packages/ui-number-input/src/NumberInput/__new-tests__/NumberInput.test.tsx
index 16540b1205..a76c5ba862 100644
--- a/packages/ui-number-input/src/NumberInput/__new-tests__/NumberInput.test.tsx
+++ b/packages/ui-number-input/src/NumberInput/__new-tests__/NumberInput.test.tsx
@@ -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('', () => {
let consoleWarningMock: ReturnType
@@ -282,4 +283,39 @@ describe('', () => {
})
}
})
+
+ it('renders custom interactive icons', async () => {
+ const onDecrement = vi.fn()
+ const onIncrement = vi.fn()
+ const { container } = render(
+ ,
+ decrease:
+ }}
+ />
+ )
+
+ 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)
+ })
+ })
})
diff --git a/packages/ui-number-input/src/NumberInput/index.tsx b/packages/ui-number-input/src/NumberInput/index.tsx
index 4c40a1e2f6..703cecd52d 100644
--- a/packages/ui-number-input/src/NumberInput/index.tsx
+++ b/packages/ui-number-input/src/NumberInput/index.tsx
@@ -52,6 +52,7 @@ import type {
NumberInputState,
NumberInputStyleProps
} from './props'
+import { Renderable } from '@instructure/shared-types'
/**
---
@@ -203,7 +204,7 @@ class NumberInput extends Component {
}
}
- renderArrows() {
+ renderArrows(customIcons?: { increase: Renderable; decrease: Renderable }) {
return (
)
@@ -238,7 +247,8 @@ class NumberInput extends Component {
value,
width,
styles,
- allowStringValue
+ allowStringValue,
+ renderIcons
} = this.props
const { interaction } = this
@@ -295,7 +305,7 @@ class NumberInput extends Component {
onChange={this.handleChange}
onKeyDown={this.handleKeyDown}
/>
- {showArrows ? this.renderArrows() : null}
+ {showArrows ? this.renderArrows(renderIcons) : null}
diff --git a/packages/ui-number-input/src/NumberInput/props.ts b/packages/ui-number-input/src/NumberInput/props.ts
index d41f03fa75..38b190d2eb 100644
--- a/packages/ui-number-input/src/NumberInput/props.ts
+++ b/packages/ui-number-input/src/NumberInput/props.ts
@@ -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 = {
@@ -226,7 +234,11 @@ const propTypes: PropValidators = {
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 = [
@@ -250,7 +262,8 @@ const allowedProps: AllowedPropKeys = [
'onKeyDown',
'inputMode',
'textAlign',
- 'allowStringValue'
+ 'allowStringValue',
+ 'renderIcons'
]
export type {