From d6cec40f83bc637113ceb51175603a9d8412bb65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=B9=A4=E4=BB=99?= Date: Tue, 21 Oct 2025 10:00:19 +0800 Subject: [PATCH 1/3] feat(spinner): support spinner type --- assets/index.less | 25 ++++++++++++++ docs/demo/spinner.tsx | 78 +++++++++++++++++++++++++++++++++++++++++++ docs/example.md | 4 +++ src/InputNumber.tsx | 30 +++++++++++++++-- src/StepHandler.tsx | 53 +++++++++++++++++------------ 5 files changed, 166 insertions(+), 24 deletions(-) create mode 100644 docs/demo/spinner.tsx diff --git a/assets/index.less b/assets/index.less index a5e1abe5..d6714d55 100644 --- a/assets/index.less +++ b/assets/index.less @@ -133,4 +133,29 @@ .handler-disabled(); } } + + &-type-spinner { + display: inline-flex; + align-items: center; + } + + &-type-spinner &-handler-wrap { + flex: 0 0 20px; + border-left: 0; + } + + &-type-spinner &-handler { + line-height: 26px; + } + + &-type-spinner &-handler-up { + border-bottom: 0; + border-left: 1px solid #d9d9d9; + height: 100%; + } + &-type-spinner &-handler-down { + border-top: 0; + border-right: 1px solid #d9d9d9; + height: 100%; + } } diff --git a/docs/demo/spinner.tsx b/docs/demo/spinner.tsx new file mode 100644 index 00000000..085bc0b3 --- /dev/null +++ b/docs/demo/spinner.tsx @@ -0,0 +1,78 @@ +/* eslint no-console:0 */ +import InputNumber from '@rc-component/input-number'; +import React from 'react'; +import '../../assets/index.less'; + +export default () => { + const [disabled, setDisabled] = React.useState(false); + const [readOnly, setReadOnly] = React.useState(false); + const [keyboard, setKeyboard] = React.useState(true); + const [wheel, setWheel] = React.useState(true); + const [stringMode, setStringMode] = React.useState(false); + const [value, setValue] = React.useState(93); + + const onChange = (val: number) => { + console.warn('onChange:', val, typeof val); + setValue(val); + }; + + return ( +
+

Controlled

+ +

+ + + + + +

+ +
+

Uncontrolled

+ + +
+

!changeOnBlur

+ +
+ ); +}; diff --git a/docs/example.md b/docs/example.md index 7743a757..b88e7135 100644 --- a/docs/example.md +++ b/docs/example.md @@ -52,3 +52,7 @@ nav: ## focus + +## spinner + + diff --git a/src/InputNumber.tsx b/src/InputNumber.tsx index 8cb3d822..509503df 100644 --- a/src/InputNumber.tsx +++ b/src/InputNumber.tsx @@ -63,6 +63,8 @@ export interface InputNumberProps /** value will show as string */ stringMode?: boolean; + type?: 'input' | 'spinner'; + defaultValue?: T; value?: T | null; @@ -119,6 +121,7 @@ type InternalInputNumberProps = Omit & { const InternalInputNumber = React.forwardRef( (props: InternalInputNumberProps, ref: React.Ref) => { const { + type, prefixCls, className, style, @@ -607,7 +610,7 @@ const InternalInputNumber = React.forwardRef( onCompositionEnd={onCompositionEnd} onBeforeInput={onBeforeInput} > - {controls && ( + {type === 'input' && controls && ( )} + + {type === 'spinner' && controls && ( + + )} +
+ + {type === 'spinner' && controls && ( + + )} ); }, @@ -641,6 +665,7 @@ const InternalInputNumber = React.forwardRef( const InputNumber = React.forwardRef((props, ref) => { const { + type = 'input', disabled, style, prefixCls = 'rc-input-number', @@ -675,7 +700,7 @@ const InputNumber = React.forwardRef((props, r return ( ((props, r ref={holderRef} > void; } @@ -29,6 +31,8 @@ export default function StepHandler({ downNode, upDisabled, downDisabled, + upHidden, + downHidden, onStep, }: StepHandlerProps) { // ======================== Step ======================== @@ -98,28 +102,33 @@ export default function StepHandler({ return (
- { - onStepMouseDown(e, true); - }} - aria-label="Increase Value" - aria-disabled={upDisabled} - className={upClassName} - > - {upNode || } - - { - onStepMouseDown(e, false); - }} - aria-label="Decrease Value" - aria-disabled={downDisabled} - className={downClassName} - > - {downNode || } - + {!upHidden && ( + { + onStepMouseDown(e, true); + }} + aria-label="Increase Value" + aria-disabled={upDisabled} + className={upClassName} + > + {upNode || } + + )} + + {!downHidden && ( + { + onStepMouseDown(e, false); + }} + aria-label="Decrease Value" + aria-disabled={downDisabled} + className={downClassName} + > + {downNode || } + + )}
); } From 71c4bc6dbcb91127c415922fa82e2fcba67fb70d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=B9=A4=E4=BB=99?= Date: Tue, 28 Oct 2025 11:30:18 +0800 Subject: [PATCH 2/3] test: update snapshot --- tests/__snapshots__/baseInput.test.tsx.snap | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/__snapshots__/baseInput.test.tsx.snap b/tests/__snapshots__/baseInput.test.tsx.snap index a8e10153..dfc613ff 100644 --- a/tests/__snapshots__/baseInput.test.tsx.snap +++ b/tests/__snapshots__/baseInput.test.tsx.snap @@ -4,7 +4,7 @@ exports[`baseInput addon should render properly 1`] = `

Date: Tue, 28 Oct 2025 11:56:10 +0800 Subject: [PATCH 3/3] fix: dom --- assets/index.less | 9 ++---- src/StepHandler.tsx | 66 ++++++++++++++++++++++++++------------------ tests/props.test.tsx | 48 ++++++++++++++++++-------------- 3 files changed, 68 insertions(+), 55 deletions(-) diff --git a/assets/index.less b/assets/index.less index d6714d55..e3e559e5 100644 --- a/assets/index.less +++ b/assets/index.less @@ -139,23 +139,18 @@ align-items: center; } - &-type-spinner &-handler-wrap { - flex: 0 0 20px; - border-left: 0; - } - &-type-spinner &-handler { + flex: 0 0 20px; line-height: 26px; + height: 100%; } &-type-spinner &-handler-up { border-bottom: 0; border-left: 1px solid #d9d9d9; - height: 100%; } &-type-spinner &-handler-down { border-top: 0; border-right: 1px solid #d9d9d9; - height: 100%; } } diff --git a/src/StepHandler.tsx b/src/StepHandler.tsx index b6bd6fdf..cc53e1a0 100644 --- a/src/StepHandler.tsx +++ b/src/StepHandler.tsx @@ -100,35 +100,47 @@ export default function StepHandler({ onMouseLeave: safeOnStopStep, }; + const upHandle = ( + { + onStepMouseDown(e, true); + }} + aria-label="Increase Value" + aria-disabled={upDisabled} + className={upClassName} + > + {upNode || } + + ); + + const downHandle = ( + { + onStepMouseDown(e, false); + }} + aria-label="Decrease Value" + aria-disabled={downDisabled} + className={downClassName} + > + {downNode || } + + ); + + if (upHidden) { + return downHandle; + } + + if (downHidden) { + return upHandle; + } + return (
- {!upHidden && ( - { - onStepMouseDown(e, true); - }} - aria-label="Increase Value" - aria-disabled={upDisabled} - className={upClassName} - > - {upNode || } - - )} - - {!downHidden && ( - { - onStepMouseDown(e, false); - }} - aria-label="Decrease Value" - aria-disabled={downDisabled} - className={downClassName} - > - {downNode || } - - )} + {upHandle} + + {downHandle}
); } diff --git a/tests/props.test.tsx b/tests/props.test.tsx index 0b50c102..0bd4b4f1 100644 --- a/tests/props.test.tsx +++ b/tests/props.test.tsx @@ -2,11 +2,10 @@ import React from 'react'; import '@testing-library/jest-dom'; import { render, fireEvent } from '@testing-library/react'; import KeyCode from '@rc-component/util/lib/KeyCode'; -import type { ValueType } from '../src' +import type { ValueType } from '../src'; import InputNumber from '../src'; describe('InputNumber.Props', () => { - it('max', () => { const onChange = jest.fn(); const { container } = render(); @@ -61,7 +60,6 @@ describe('InputNumber.Props', () => { expect(input).toHaveFocus(); done(); }, 500); - }); describe('step', () => { @@ -96,8 +94,8 @@ describe('InputNumber.Props', () => { , ); @@ -114,8 +112,8 @@ describe('InputNumber.Props', () => { , ); @@ -186,7 +184,7 @@ describe('InputNumber.Props', () => { return (