@instructure/ui-number-input 10.8.1-snapshot-0 → 10.8.1-snapshot-3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -2
- package/es/NumberInput/__new-tests__/NumberInput.test.js +29 -1
- package/es/NumberInput/index.js +6 -5
- package/es/NumberInput/props.js +6 -2
- package/lib/NumberInput/__new-tests__/NumberInput.test.js +30 -1
- package/lib/NumberInput/index.js +6 -5
- package/lib/NumberInput/props.js +6 -2
- package/package.json +17 -17
- package/src/NumberInput/__new-tests__/NumberInput.test.tsx +36 -0
- package/src/NumberInput/index.tsx +15 -5
- package/src/NumberInput/props.ts +15 -2
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/NumberInput/index.d.ts +15 -3
- package/types/NumberInput/index.d.ts.map +1 -1
- package/types/NumberInput/props.d.ts +7 -0
- package/types/NumberInput/props.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
-
## [10.8.1-snapshot-
|
|
6
|
+
## [10.8.1-snapshot-3](https://github.com/instructure/instructure-ui/compare/v10.8.0...v10.8.1-snapshot-3) (2024-12-11)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **ui-number-input:** add customizable icons for increment and decrement buttons ([7be2226](https://github.com/instructure/instructure-ui/commit/7be222651902524f6c166e39f09878542a646d7c))
|
|
9
12
|
|
|
10
13
|
|
|
11
14
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var _NumberInput, _NumberInput2, _NumberInput3, _NumberInput4;
|
|
1
|
+
var _NumberInput, _NumberInput2, _NumberInput3, _NumberInput4, _IconZoomInLine, _IconZoomOutLine;
|
|
2
2
|
/*
|
|
3
3
|
* The MIT License (MIT)
|
|
4
4
|
*
|
|
@@ -33,6 +33,7 @@ import { NumberInput } from '../index';
|
|
|
33
33
|
import NumberInputExamples from '../__examples__/NumberInput.examples';
|
|
34
34
|
// eslint-disable-next-line no-restricted-imports
|
|
35
35
|
import { generateA11yTests } from '@instructure/ui-scripts/lib/test/generateA11yTests';
|
|
36
|
+
import { IconZoomInLine, IconZoomOutLine } from '@instructure/ui-icons';
|
|
36
37
|
describe('<NumberInput />', () => {
|
|
37
38
|
let consoleWarningMock;
|
|
38
39
|
let consoleErrorMock;
|
|
@@ -253,4 +254,31 @@ describe('<NumberInput />', () => {
|
|
|
253
254
|
});
|
|
254
255
|
}
|
|
255
256
|
});
|
|
257
|
+
it('renders custom interactive icons', async () => {
|
|
258
|
+
const onDecrement = vi.fn();
|
|
259
|
+
const onIncrement = vi.fn();
|
|
260
|
+
const _render11 = render(/*#__PURE__*/React.createElement(NumberInput, {
|
|
261
|
+
renderLabel: "Label",
|
|
262
|
+
onIncrement: onIncrement,
|
|
263
|
+
onDecrement: onDecrement,
|
|
264
|
+
renderIcons: {
|
|
265
|
+
increase: _IconZoomInLine || (_IconZoomInLine = /*#__PURE__*/React.createElement(IconZoomInLine, null)),
|
|
266
|
+
decrease: _IconZoomOutLine || (_IconZoomOutLine = /*#__PURE__*/React.createElement(IconZoomOutLine, null))
|
|
267
|
+
}
|
|
268
|
+
})),
|
|
269
|
+
container = _render11.container;
|
|
270
|
+
const zoomInIcon = container.querySelector('svg[name="IconZoomIn"]');
|
|
271
|
+
const zoomOutIcon = container.querySelector('svg[name="IconZoomOut"]');
|
|
272
|
+
expect(zoomInIcon).toBeInTheDocument();
|
|
273
|
+
expect(zoomOutIcon).toBeInTheDocument();
|
|
274
|
+
const buttons = container.querySelectorAll('button[class$="-numberInput_arrow');
|
|
275
|
+
userEvent.click(buttons[0]);
|
|
276
|
+
await waitFor(() => {
|
|
277
|
+
expect(onIncrement).toHaveBeenCalledTimes(1);
|
|
278
|
+
});
|
|
279
|
+
userEvent.click(buttons[1]);
|
|
280
|
+
await waitFor(() => {
|
|
281
|
+
expect(onDecrement).toHaveBeenCalledTimes(1);
|
|
282
|
+
});
|
|
283
|
+
});
|
|
256
284
|
});
|
package/es/NumberInput/index.js
CHANGED
|
@@ -150,7 +150,7 @@ let NumberInput = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle
|
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
-
renderArrows() {
|
|
153
|
+
renderArrows(customIcons) {
|
|
154
154
|
var _this$props$styles, _this$props$styles2, _this$props$styles3;
|
|
155
155
|
return jsx("span", {
|
|
156
156
|
css: (_this$props$styles = this.props.styles) === null || _this$props$styles === void 0 ? void 0 : _this$props$styles.arrowContainer
|
|
@@ -160,13 +160,13 @@ let NumberInput = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle
|
|
|
160
160
|
onMouseDown: this.handleClickUpArrow,
|
|
161
161
|
tabIndex: -1,
|
|
162
162
|
type: "button"
|
|
163
|
-
}, _IconArrowOpenUpLine || (_IconArrowOpenUpLine = jsx(IconArrowOpenUpLine, null))), jsx("button", {
|
|
163
|
+
}, customIcons !== null && customIcons !== void 0 && customIcons.increase ? callRenderProp(customIcons.increase) : _IconArrowOpenUpLine || (_IconArrowOpenUpLine = jsx(IconArrowOpenUpLine, null))), jsx("button", {
|
|
164
164
|
"aria-hidden": true,
|
|
165
165
|
css: (_this$props$styles3 = this.props.styles) === null || _this$props$styles3 === void 0 ? void 0 : _this$props$styles3.arrow,
|
|
166
166
|
onMouseDown: this.handleClickDownArrow,
|
|
167
167
|
tabIndex: -1,
|
|
168
168
|
type: "button"
|
|
169
|
-
}, _IconArrowOpenDownLin || (_IconArrowOpenDownLin = jsx(IconArrowOpenDownLine, null))));
|
|
169
|
+
}, customIcons !== null && customIcons !== void 0 && customIcons.decrease ? callRenderProp(customIcons.decrease) : _IconArrowOpenDownLin || (_IconArrowOpenDownLin = jsx(IconArrowOpenDownLine, null))));
|
|
170
170
|
}
|
|
171
171
|
render() {
|
|
172
172
|
var _this$props$styles4, _this$props$styles5, _this$props$styles6;
|
|
@@ -179,7 +179,8 @@ let NumberInput = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle
|
|
|
179
179
|
value = _this$props4.value,
|
|
180
180
|
width = _this$props4.width,
|
|
181
181
|
styles = _this$props4.styles,
|
|
182
|
-
allowStringValue = _this$props4.allowStringValue
|
|
182
|
+
allowStringValue = _this$props4.allowStringValue,
|
|
183
|
+
renderIcons = _this$props4.renderIcons;
|
|
183
184
|
const interaction = this.interaction;
|
|
184
185
|
const rawLabel = callRenderProp(renderLabel);
|
|
185
186
|
const label = hasVisibleChildren(rawLabel) ? jsx(React.Fragment, null, rawLabel, isRequired && jsx("span", {
|
|
@@ -214,7 +215,7 @@ let NumberInput = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle
|
|
|
214
215
|
onBlur: this.handleBlur,
|
|
215
216
|
onChange: this.handleChange,
|
|
216
217
|
onKeyDown: this.handleKeyDown
|
|
217
|
-
})), showArrows ? this.renderArrows() : null)));
|
|
218
|
+
})), showArrows ? this.renderArrows(renderIcons) : null)));
|
|
218
219
|
}
|
|
219
220
|
}, _NumberInput.displayName = "NumberInput", _NumberInput.componentId = 'NumberInput', _NumberInput.allowedProps = allowedProps, _NumberInput.propTypes = propTypes, _NumberInput.defaultProps = {
|
|
220
221
|
// Leave interaction default undefined so that `disabled` and `readOnly` can also be supplied
|
package/es/NumberInput/props.js
CHANGED
|
@@ -45,7 +45,11 @@ const propTypes = {
|
|
|
45
45
|
onKeyDown: PropTypes.func,
|
|
46
46
|
inputMode: PropTypes.oneOf(['numeric', 'decimal', 'tel']),
|
|
47
47
|
textAlign: PropTypes.oneOf(['start', 'center']),
|
|
48
|
-
allowStringValue: PropTypes.bool
|
|
48
|
+
allowStringValue: PropTypes.bool,
|
|
49
|
+
renderIcons: PropTypes.shape({
|
|
50
|
+
increase: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
|
|
51
|
+
decrease: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired
|
|
52
|
+
})
|
|
49
53
|
};
|
|
50
|
-
const allowedProps = ['renderLabel', 'id', 'interaction', 'messages', 'placeholder', 'isRequired', 'showArrows', 'size', 'value', 'width', 'display', 'inputRef', 'onFocus', 'onBlur', 'onChange', 'onDecrement', 'onIncrement', 'onKeyDown', 'inputMode', 'textAlign', 'allowStringValue'];
|
|
54
|
+
const allowedProps = ['renderLabel', 'id', 'interaction', 'messages', 'placeholder', 'isRequired', 'showArrows', 'size', 'value', 'width', 'display', 'inputRef', 'onFocus', 'onBlur', 'onChange', 'onDecrement', 'onIncrement', 'onKeyDown', 'inputMode', 'textAlign', 'allowStringValue', 'renderIcons'];
|
|
51
55
|
export { propTypes, allowedProps };
|
|
@@ -10,7 +10,9 @@ require("@testing-library/jest-dom");
|
|
|
10
10
|
var _index = require("../index");
|
|
11
11
|
var _NumberInput5 = _interopRequireDefault(require("../__examples__/NumberInput.examples"));
|
|
12
12
|
var _generateA11yTests = require("@instructure/ui-scripts/lib/test/generateA11yTests");
|
|
13
|
-
var
|
|
13
|
+
var _IconZoomInLine2 = require("@instructure/ui-icons/lib/IconZoomInLine.js");
|
|
14
|
+
var _IconZoomOutLine2 = require("@instructure/ui-icons/lib/IconZoomOutLine.js");
|
|
15
|
+
var _NumberInput, _NumberInput2, _NumberInput3, _NumberInput4, _IconZoomInLine, _IconZoomOutLine;
|
|
14
16
|
/*
|
|
15
17
|
* The MIT License (MIT)
|
|
16
18
|
*
|
|
@@ -255,4 +257,31 @@ describe('<NumberInput />', () => {
|
|
|
255
257
|
});
|
|
256
258
|
}
|
|
257
259
|
});
|
|
260
|
+
it('renders custom interactive icons', async () => {
|
|
261
|
+
const onDecrement = _vitest.vi.fn();
|
|
262
|
+
const onIncrement = _vitest.vi.fn();
|
|
263
|
+
const _render11 = (0, _react2.render)(/*#__PURE__*/_react.default.createElement(_index.NumberInput, {
|
|
264
|
+
renderLabel: "Label",
|
|
265
|
+
onIncrement: onIncrement,
|
|
266
|
+
onDecrement: onDecrement,
|
|
267
|
+
renderIcons: {
|
|
268
|
+
increase: _IconZoomInLine || (_IconZoomInLine = /*#__PURE__*/_react.default.createElement(_IconZoomInLine2.IconZoomInLine, null)),
|
|
269
|
+
decrease: _IconZoomOutLine || (_IconZoomOutLine = /*#__PURE__*/_react.default.createElement(_IconZoomOutLine2.IconZoomOutLine, null))
|
|
270
|
+
}
|
|
271
|
+
})),
|
|
272
|
+
container = _render11.container;
|
|
273
|
+
const zoomInIcon = container.querySelector('svg[name="IconZoomIn"]');
|
|
274
|
+
const zoomOutIcon = container.querySelector('svg[name="IconZoomOut"]');
|
|
275
|
+
expect(zoomInIcon).toBeInTheDocument();
|
|
276
|
+
expect(zoomOutIcon).toBeInTheDocument();
|
|
277
|
+
const buttons = container.querySelectorAll('button[class$="-numberInput_arrow');
|
|
278
|
+
_userEvent.default.click(buttons[0]);
|
|
279
|
+
await (0, _react2.waitFor)(() => {
|
|
280
|
+
expect(onIncrement).toHaveBeenCalledTimes(1);
|
|
281
|
+
});
|
|
282
|
+
_userEvent.default.click(buttons[1]);
|
|
283
|
+
await (0, _react2.waitFor)(() => {
|
|
284
|
+
expect(onDecrement).toHaveBeenCalledTimes(1);
|
|
285
|
+
});
|
|
286
|
+
});
|
|
258
287
|
});
|
package/lib/NumberInput/index.js
CHANGED
|
@@ -162,7 +162,7 @@ let NumberInput = exports.NumberInput = (_dec = (0, _withDeterministicId.withDet
|
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
|
-
renderArrows() {
|
|
165
|
+
renderArrows(customIcons) {
|
|
166
166
|
var _this$props$styles, _this$props$styles2, _this$props$styles3;
|
|
167
167
|
return (0, _emotion.jsx)("span", {
|
|
168
168
|
css: (_this$props$styles = this.props.styles) === null || _this$props$styles === void 0 ? void 0 : _this$props$styles.arrowContainer
|
|
@@ -172,13 +172,13 @@ let NumberInput = exports.NumberInput = (_dec = (0, _withDeterministicId.withDet
|
|
|
172
172
|
onMouseDown: this.handleClickUpArrow,
|
|
173
173
|
tabIndex: -1,
|
|
174
174
|
type: "button"
|
|
175
|
-
}, _IconArrowOpenUpLine || (_IconArrowOpenUpLine = (0, _emotion.jsx)(_IconArrowOpenUpLine2.IconArrowOpenUpLine, null))), (0, _emotion.jsx)("button", {
|
|
175
|
+
}, customIcons !== null && customIcons !== void 0 && customIcons.increase ? (0, _callRenderProp.callRenderProp)(customIcons.increase) : _IconArrowOpenUpLine || (_IconArrowOpenUpLine = (0, _emotion.jsx)(_IconArrowOpenUpLine2.IconArrowOpenUpLine, null))), (0, _emotion.jsx)("button", {
|
|
176
176
|
"aria-hidden": true,
|
|
177
177
|
css: (_this$props$styles3 = this.props.styles) === null || _this$props$styles3 === void 0 ? void 0 : _this$props$styles3.arrow,
|
|
178
178
|
onMouseDown: this.handleClickDownArrow,
|
|
179
179
|
tabIndex: -1,
|
|
180
180
|
type: "button"
|
|
181
|
-
}, _IconArrowOpenDownLin || (_IconArrowOpenDownLin = (0, _emotion.jsx)(_IconArrowOpenDownLine.IconArrowOpenDownLine, null))));
|
|
181
|
+
}, customIcons !== null && customIcons !== void 0 && customIcons.decrease ? (0, _callRenderProp.callRenderProp)(customIcons.decrease) : _IconArrowOpenDownLin || (_IconArrowOpenDownLin = (0, _emotion.jsx)(_IconArrowOpenDownLine.IconArrowOpenDownLine, null))));
|
|
182
182
|
}
|
|
183
183
|
render() {
|
|
184
184
|
var _this$props$styles4, _this$props$styles5, _this$props$styles6;
|
|
@@ -191,7 +191,8 @@ let NumberInput = exports.NumberInput = (_dec = (0, _withDeterministicId.withDet
|
|
|
191
191
|
value = _this$props4.value,
|
|
192
192
|
width = _this$props4.width,
|
|
193
193
|
styles = _this$props4.styles,
|
|
194
|
-
allowStringValue = _this$props4.allowStringValue
|
|
194
|
+
allowStringValue = _this$props4.allowStringValue,
|
|
195
|
+
renderIcons = _this$props4.renderIcons;
|
|
195
196
|
const interaction = this.interaction;
|
|
196
197
|
const rawLabel = (0, _callRenderProp.callRenderProp)(renderLabel);
|
|
197
198
|
const label = (0, _hasVisibleChildren.hasVisibleChildren)(rawLabel) ? (0, _emotion.jsx)(_react.default.Fragment, null, rawLabel, isRequired && (0, _emotion.jsx)("span", {
|
|
@@ -226,7 +227,7 @@ let NumberInput = exports.NumberInput = (_dec = (0, _withDeterministicId.withDet
|
|
|
226
227
|
onBlur: this.handleBlur,
|
|
227
228
|
onChange: this.handleChange,
|
|
228
229
|
onKeyDown: this.handleKeyDown
|
|
229
|
-
})), showArrows ? this.renderArrows() : null)));
|
|
230
|
+
})), showArrows ? this.renderArrows(renderIcons) : null)));
|
|
230
231
|
}
|
|
231
232
|
}, _NumberInput.displayName = "NumberInput", _NumberInput.componentId = 'NumberInput', _NumberInput.allowedProps = _props.allowedProps, _NumberInput.propTypes = _props.propTypes, _NumberInput.defaultProps = {
|
|
232
233
|
// Leave interaction default undefined so that `disabled` and `readOnly` can also be supplied
|
package/lib/NumberInput/props.js
CHANGED
|
@@ -52,6 +52,10 @@ const propTypes = exports.propTypes = {
|
|
|
52
52
|
onKeyDown: _propTypes.default.func,
|
|
53
53
|
inputMode: _propTypes.default.oneOf(['numeric', 'decimal', 'tel']),
|
|
54
54
|
textAlign: _propTypes.default.oneOf(['start', 'center']),
|
|
55
|
-
allowStringValue: _propTypes.default.bool
|
|
55
|
+
allowStringValue: _propTypes.default.bool,
|
|
56
|
+
renderIcons: _propTypes.default.shape({
|
|
57
|
+
increase: _propTypes.default.oneOfType([_propTypes.default.node, _propTypes.default.func]).isRequired,
|
|
58
|
+
decrease: _propTypes.default.oneOfType([_propTypes.default.node, _propTypes.default.func]).isRequired
|
|
59
|
+
})
|
|
56
60
|
};
|
|
57
|
-
const allowedProps = exports.allowedProps = ['renderLabel', 'id', 'interaction', 'messages', 'placeholder', 'isRequired', 'showArrows', 'size', 'value', 'width', 'display', 'inputRef', 'onFocus', 'onBlur', 'onChange', 'onDecrement', 'onIncrement', 'onKeyDown', 'inputMode', 'textAlign', 'allowStringValue'];
|
|
61
|
+
const allowedProps = exports.allowedProps = ['renderLabel', 'id', 'interaction', 'messages', 'placeholder', 'isRequired', 'showArrows', 'size', 'value', 'width', 'display', 'inputRef', 'onFocus', 'onBlur', 'onChange', 'onDecrement', 'onIncrement', 'onKeyDown', 'inputMode', 'textAlign', 'allowStringValue', 'renderIcons'];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/ui-number-input",
|
|
3
|
-
"version": "10.8.1-snapshot-
|
|
3
|
+
"version": "10.8.1-snapshot-3",
|
|
4
4
|
"description": "A UI component library made by Instructure Inc.",
|
|
5
5
|
"author": "Instructure, Inc. Engineering and Product Design",
|
|
6
6
|
"homepage": "https://instructure.github.io/instructure-ui/",
|
|
@@ -23,26 +23,26 @@
|
|
|
23
23
|
"ts:check": "tsc -p tsconfig.build.json --noEmit --emitDeclarationOnly false"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@instructure/ui-axe-check": "10.8.1-snapshot-
|
|
27
|
-
"@instructure/ui-babel-preset": "10.8.1-snapshot-
|
|
28
|
-
"@instructure/ui-scripts": "10.8.1-snapshot-
|
|
29
|
-
"@instructure/ui-test-utils": "10.8.1-snapshot-
|
|
30
|
-
"@instructure/ui-themes": "10.8.1-snapshot-
|
|
31
|
-
"@testing-library/jest-dom": "^6.
|
|
26
|
+
"@instructure/ui-axe-check": "10.8.1-snapshot-3",
|
|
27
|
+
"@instructure/ui-babel-preset": "10.8.1-snapshot-3",
|
|
28
|
+
"@instructure/ui-scripts": "10.8.1-snapshot-3",
|
|
29
|
+
"@instructure/ui-test-utils": "10.8.1-snapshot-3",
|
|
30
|
+
"@instructure/ui-themes": "10.8.1-snapshot-3",
|
|
31
|
+
"@testing-library/jest-dom": "^6.6.3",
|
|
32
32
|
"@testing-library/react": "^16.0.1",
|
|
33
33
|
"@testing-library/user-event": "^14.5.2",
|
|
34
|
-
"vitest": "^2.1.
|
|
34
|
+
"vitest": "^2.1.8"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@babel/runtime": "^7.
|
|
38
|
-
"@instructure/emotion": "10.8.1-snapshot-
|
|
39
|
-
"@instructure/shared-types": "10.8.1-snapshot-
|
|
40
|
-
"@instructure/ui-form-field": "10.8.1-snapshot-
|
|
41
|
-
"@instructure/ui-icons": "10.8.1-snapshot-
|
|
42
|
-
"@instructure/ui-react-utils": "10.8.1-snapshot-
|
|
43
|
-
"@instructure/ui-testable": "10.8.1-snapshot-
|
|
44
|
-
"@instructure/ui-utils": "10.8.1-snapshot-
|
|
45
|
-
"@instructure/uid": "10.8.1-snapshot-
|
|
37
|
+
"@babel/runtime": "^7.26.0",
|
|
38
|
+
"@instructure/emotion": "10.8.1-snapshot-3",
|
|
39
|
+
"@instructure/shared-types": "10.8.1-snapshot-3",
|
|
40
|
+
"@instructure/ui-form-field": "10.8.1-snapshot-3",
|
|
41
|
+
"@instructure/ui-icons": "10.8.1-snapshot-3",
|
|
42
|
+
"@instructure/ui-react-utils": "10.8.1-snapshot-3",
|
|
43
|
+
"@instructure/ui-testable": "10.8.1-snapshot-3",
|
|
44
|
+
"@instructure/ui-utils": "10.8.1-snapshot-3",
|
|
45
|
+
"@instructure/uid": "10.8.1-snapshot-3",
|
|
46
46
|
"keycode": "^2",
|
|
47
47
|
"prop-types": "^15.8.1"
|
|
48
48
|
},
|
|
@@ -33,6 +33,7 @@ import { NumberInput } from '../index'
|
|
|
33
33
|
import NumberInputExamples from '../__examples__/NumberInput.examples'
|
|
34
34
|
// eslint-disable-next-line no-restricted-imports
|
|
35
35
|
import { generateA11yTests } from '@instructure/ui-scripts/lib/test/generateA11yTests'
|
|
36
|
+
import { IconZoomInLine, IconZoomOutLine } from '@instructure/ui-icons'
|
|
36
37
|
|
|
37
38
|
describe('<NumberInput />', () => {
|
|
38
39
|
let consoleWarningMock: ReturnType<typeof vi.spyOn>
|
|
@@ -282,4 +283,39 @@ describe('<NumberInput />', () => {
|
|
|
282
283
|
})
|
|
283
284
|
}
|
|
284
285
|
})
|
|
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
|
+
})
|
|
285
321
|
})
|
|
@@ -52,6 +52,7 @@ import type {
|
|
|
52
52
|
NumberInputState,
|
|
53
53
|
NumberInputStyleProps
|
|
54
54
|
} from './props'
|
|
55
|
+
import { Renderable } from '@instructure/shared-types'
|
|
55
56
|
|
|
56
57
|
/**
|
|
57
58
|
---
|
|
@@ -203,7 +204,7 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
|
|
|
203
204
|
}
|
|
204
205
|
}
|
|
205
206
|
|
|
206
|
-
renderArrows() {
|
|
207
|
+
renderArrows(customIcons?: { increase: Renderable; decrease: Renderable }) {
|
|
207
208
|
return (
|
|
208
209
|
<span css={this.props.styles?.arrowContainer}>
|
|
209
210
|
<button
|
|
@@ -213,7 +214,11 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
|
|
|
213
214
|
tabIndex={-1}
|
|
214
215
|
type="button"
|
|
215
216
|
>
|
|
216
|
-
|
|
217
|
+
{customIcons?.increase ? (
|
|
218
|
+
callRenderProp(customIcons.increase)
|
|
219
|
+
) : (
|
|
220
|
+
<IconArrowOpenUpLine />
|
|
221
|
+
)}
|
|
217
222
|
</button>
|
|
218
223
|
<button
|
|
219
224
|
aria-hidden
|
|
@@ -222,7 +227,11 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
|
|
|
222
227
|
tabIndex={-1}
|
|
223
228
|
type="button"
|
|
224
229
|
>
|
|
225
|
-
|
|
230
|
+
{customIcons?.decrease ? (
|
|
231
|
+
callRenderProp(customIcons.decrease)
|
|
232
|
+
) : (
|
|
233
|
+
<IconArrowOpenDownLine />
|
|
234
|
+
)}
|
|
226
235
|
</button>
|
|
227
236
|
</span>
|
|
228
237
|
)
|
|
@@ -238,7 +247,8 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
|
|
|
238
247
|
value,
|
|
239
248
|
width,
|
|
240
249
|
styles,
|
|
241
|
-
allowStringValue
|
|
250
|
+
allowStringValue,
|
|
251
|
+
renderIcons
|
|
242
252
|
} = this.props
|
|
243
253
|
|
|
244
254
|
const { interaction } = this
|
|
@@ -295,7 +305,7 @@ class NumberInput extends Component<NumberInputProps, NumberInputState> {
|
|
|
295
305
|
onChange={this.handleChange}
|
|
296
306
|
onKeyDown={this.handleKeyDown}
|
|
297
307
|
/>
|
|
298
|
-
{showArrows ? this.renderArrows() : null}
|
|
308
|
+
{showArrows ? this.renderArrows(renderIcons) : null}
|
|
299
309
|
</span>
|
|
300
310
|
</span>
|
|
301
311
|
</FormField>
|
package/src/NumberInput/props.ts
CHANGED
|
@@ -166,6 +166,14 @@ type NumberInputOwnProps = {
|
|
|
166
166
|
* sets the input type to string and allows string as value
|
|
167
167
|
*/
|
|
168
168
|
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
|
+
}
|
|
169
177
|
}
|
|
170
178
|
|
|
171
179
|
type NumberInputState = {
|
|
@@ -226,7 +234,11 @@ const propTypes: PropValidators<PropKeys> = {
|
|
|
226
234
|
onKeyDown: PropTypes.func,
|
|
227
235
|
inputMode: PropTypes.oneOf(['numeric', 'decimal', 'tel']),
|
|
228
236
|
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
|
+
})
|
|
230
242
|
}
|
|
231
243
|
|
|
232
244
|
const allowedProps: AllowedPropKeys = [
|
|
@@ -250,7 +262,8 @@ const allowedProps: AllowedPropKeys = [
|
|
|
250
262
|
'onKeyDown',
|
|
251
263
|
'inputMode',
|
|
252
264
|
'textAlign',
|
|
253
|
-
'allowStringValue'
|
|
265
|
+
'allowStringValue',
|
|
266
|
+
'renderIcons'
|
|
254
267
|
]
|
|
255
268
|
|
|
256
269
|
export type {
|