diff --git a/package-lock.json b/package-lock.json
index f8f2659f85..d2b932e3bd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "antd-mobile",
- "version": "5.39.0",
+ "version": "5.40.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "antd-mobile",
- "version": "5.39.0",
+ "version": "5.40.0",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
diff --git a/src/components/virtual-input/demos/demo1.tsx b/src/components/virtual-input/demos/demo1.tsx
index c3e14ec2e9..b154a761e9 100644
--- a/src/components/virtual-input/demos/demo1.tsx
+++ b/src/components/virtual-input/demos/demo1.tsx
@@ -6,13 +6,15 @@ const TWO_DIGIT_NUMBER_REGEX = /^(([1-9]\d{0,11})|0)(\.\d{0,2}?)?$/
export default () => {
const [value, setValue] = useState('')
+ const ref = React.useRef(null)
return (
<>
}
+ ref={ref}
+ keyboard={}
/>
@@ -24,6 +26,13 @@ export default () => {
/>
+
+ }
+ />
+
+
{
}
}}
placeholder='请输入内容'
- keyboard={}
+ keyboard={}
+ style={{
+ '--font-size': '40px',
+ }}
/>
-
+
>
)
}
diff --git a/src/components/virtual-input/tests/virtual-input.test.tsx b/src/components/virtual-input/tests/virtual-input.test.tsx
index 8197deba26..3fecd5bed1 100644
--- a/src/components/virtual-input/tests/virtual-input.test.tsx
+++ b/src/components/virtual-input/tests/virtual-input.test.tsx
@@ -280,16 +280,16 @@ describe('VirtualInput', () => {
if (caretContainer != null) {
expect(getCaretPosition(caretContainer)).toBe(3)
- // click '1' left side in inputbox, caret position should be 0
+ // click '1' left side in inputbox, caret position should move to end
clickSiblingElements(caretContainer, 0, true)
await waitFor(() => {
expect(
document.querySelector(`.${KeyBoardClassPrefix}-popup`)
).toBeVisible()
})
- expect(getCaretPosition(caretContainer)).toBe(0)
+ expect(getCaretPosition(caretContainer)).toBe(3)
- // click '9' by keyboard, content should be '9123', caret position should be 1
+ // click '9' by keyboard, content should be '1239', caret position should be ended
fireEvent.touchEnd(screen.getByText('9'))
await waitFor(() => {
expect(
@@ -298,8 +298,8 @@ describe('VirtualInput', () => {
})
expect(
document.querySelector(`.${classPrefix}-content`)
- ).toHaveTextContent('9123')
- expect(getCaretPosition(caretContainer)).toBe(1)
+ ).toHaveTextContent('1239')
+ expect(getCaretPosition(caretContainer)).toBe(4)
// click delete by keyboard, content should be '123', caret position should be 1
fireEvent.touchEnd(screen.getByTitle('清除'))
@@ -311,7 +311,7 @@ describe('VirtualInput', () => {
expect(
document.querySelector(`.${classPrefix}-content`)
).toHaveTextContent('123')
- expect(getCaretPosition(caretContainer)).toBe(0)
+ expect(getCaretPosition(caretContainer)).toBe(3)
// click input box, caret position should be 3
fireEvent.click(document.querySelector(`.${classPrefix}-content`) as any)
@@ -324,7 +324,7 @@ describe('VirtualInput', () => {
}
})
- test('只支持两位金额的受控组件,光标处理正常', async () => {
+ test('controlled component with 2-digit decimal amount should handle cursor correctly', async () => {
const KeyBoardClassPrefix = 'adm-number-keyboard'
const Wrapper = () => {
const [value, setValue] = React.useState('0')
@@ -371,7 +371,7 @@ describe('VirtualInput', () => {
if (caretContainer != null) {
expect(getCaretPosition(caretContainer)).toBe(3)
- // 输入小数部分
+ // Input decimal part
fireEvent.touchEnd(screen.getByTitle('.'))
fireEvent.touchEnd(screen.getByTitle('4'))
fireEvent.touchEnd(screen.getByTitle('5'))
@@ -381,7 +381,7 @@ describe('VirtualInput', () => {
).toHaveTextContent('103.45')
expect(getCaretPosition(caretContainer)).toBe(6)
- // 光标移动到 10x3.45, 输入小数点无效
+ // Move cursor to between 10 and 3.45, decimal input should be invalid
clickSiblingElements(caretContainer, 2, true)
await waitFor(() => {
expect(
@@ -395,22 +395,8 @@ describe('VirtualInput', () => {
).toHaveTextContent('103.45')
expect(getCaretPosition(caretContainer)).toBe(2)
- // 光标移动到 x103.45,输入 0 无效
- clickSiblingElements(caretContainer, 0, true)
- await waitFor(() => {
- expect(
- document.querySelector(`.${KeyBoardClassPrefix}-popup`)
- ).toBeVisible()
- })
- expect(getCaretPosition(caretContainer)).toBe(0)
- fireEvent.touchEnd(screen.getByTitle('.'))
- expect(
- document.querySelector(`.${classPrefix}-content`)
- ).toHaveTextContent('103.45')
- expect(getCaretPosition(caretContainer)).toBe(0)
-
- // 光标移动到 1x03.45,并删除 1
- clickSiblingElements(caretContainer, 0, false)
+ // Move cursor between 1 and 03.45, then delete 1
+ clickSiblingElements(caretContainer, 1, true)
await waitFor(() => {
expect(
document.querySelector(`.${KeyBoardClassPrefix}-popup`)
@@ -418,7 +404,7 @@ describe('VirtualInput', () => {
})
expect(getCaretPosition(caretContainer)).toBe(1)
- fireEvent.touchEnd(screen.getByTitle('清除')) // 点删除
+ fireEvent.touchEnd(screen.getByTitle('清除')) // Click delete
await waitFor(() => {
expect(
document.querySelector(`.${KeyBoardClassPrefix}-popup`)
@@ -427,10 +413,10 @@ describe('VirtualInput', () => {
expect(
document.querySelector(`.${classPrefix}-content`)
).toHaveTextContent('3.45')
- expect(getCaretPosition(caretContainer)).toBe(4) // 变为 3.45 光标到最末尾
+ expect(getCaretPosition(caretContainer)).toBe(4) // Value becomes 3.45 with cursor at end
- // 光标移动到 3x.45,并删除 3
- clickSiblingElements(caretContainer, 0, false)
+ // Move cursor between 3 and .45, then delete 3
+ clickSiblingElements(caretContainer, 1, true)
await waitFor(() => {
expect(
document.querySelector(`.${KeyBoardClassPrefix}-popup`)
@@ -438,7 +424,7 @@ describe('VirtualInput', () => {
})
expect(getCaretPosition(caretContainer)).toBe(1)
- fireEvent.touchEnd(screen.getByTitle('清除')) // 点删除
+ fireEvent.touchEnd(screen.getByTitle('清除')) // Click delete
await waitFor(() => {
expect(
document.querySelector(`.${KeyBoardClassPrefix}-popup`)
@@ -447,15 +433,15 @@ describe('VirtualInput', () => {
expect(
document.querySelector(`.${classPrefix}-content`)
).toHaveTextContent('0.45')
- expect(getCaretPosition(caretContainer)).toBe(4) // 变为 0.45 光标到最末尾
+ expect(getCaretPosition(caretContainer)).toBe(4) // Value becomes 0.45 with cursor at end
- // 全部删除,最后为 0
+ // Delete all, value becomes 0
fireEvent.click(document.querySelector(`.${classPrefix}-clear`) as any)
expect(
document.querySelector(`.${classPrefix}-content`)
).toHaveTextContent('0')
- fireEvent.touchEnd(screen.getByTitle('9')) // 在 0 时输入 9,则为 9
+ fireEvent.touchEnd(screen.getByTitle('9')) // When value is 0, input 9 becomes 9
expect(
document.querySelector(`.${classPrefix}-content`)
).toHaveTextContent('9')
diff --git a/src/components/virtual-input/virtual-input.tsx b/src/components/virtual-input/virtual-input.tsx
index 23b587066f..24a328d64b 100644
--- a/src/components/virtual-input/virtual-input.tsx
+++ b/src/components/virtual-input/virtual-input.tsx
@@ -128,7 +128,7 @@ export const VirtualInput = forwardRef(
value.substring(0, caretPosition) +
v +
value.substring(caretPosition)
- // 临时记录,用于后续光标位置
+ // Temporarily store for subsequent cursor positioning
keyboardDataRef.current = { newValue, mode: 'input' }
setValue(newValue)
keyboard.props.onInput?.(v)
@@ -138,7 +138,7 @@ export const VirtualInput = forwardRef(
const newValue =
value.substring(0, caretPosition - 1) +
value.substring(caretPosition)
- // 临时记录,用于后续光标位置
+ // Temporarily store for subsequent cursor positioning
keyboardDataRef.current = { newValue, mode: 'delete' }
setValue(newValue)
keyboard.props.onDelete?.()
@@ -160,19 +160,22 @@ export const VirtualInput = forwardRef(
getContainer: null,
} as NumberKeyboardProps)
- // 点击输入框时,将光标置于最后
+ // When clicking input box, place cursor at end
const setCaretPositionToEnd = () => {
setCaretPosition(value.length)
}
- // 点击单个字符时,根据点击位置置于字符前或后
+ // When clicking character, position cursor before or after based on click position
const changeCaretPosition = (index: number) => (e: React.MouseEvent) => {
e.stopPropagation()
-
+ if (index === 0) {
+ setCaretPosition(value.length)
+ return
+ }
const rect = (e.target as HTMLElement).getBoundingClientRect()
const midX = rect.left + rect.width / 2
const clickX = e.clientX
- // 点击区域是否偏右
+ // Check if click area is right-biased
const isRight = clickX > midX
setCaretPosition(isRight ? index + 1 : index)
@@ -187,8 +190,8 @@ export const VirtualInput = forwardRef(
className={classNames(classPrefix, {
[`${classPrefix}-disabled`]: mergedProps.disabled,
})}
- tabIndex={mergedProps.disabled ? undefined : 0}
role='textbox'
+ tabIndex={mergedProps.disabled ? undefined : 0}
onFocus={onFocus}
onBlur={onBlur}
onClick={mergedProps.onClick}
@@ -196,6 +199,7 @@ export const VirtualInput = forwardRef(
(
{i}
))}
-
+ {hasFocus && (
+
+ )}
{chars.slice(caretPosition).map((i: string, index: number) => (