Skip to content

feat: add input masking support - #206

Open
nikzanda wants to merge 3 commits into
react-component:masterfrom
nikzanda:feat/input-mask
Open

nikzanda wants to merge 3 commits into
react-component:masterfrom
nikzanda:feat/input-mask

Conversation

@nikzanda

@nikzanda nikzanda commented Oct 6, 2026 •

Copy link
Copy Markdown

Add native masks to Input so applications can format card numbers, phone numbers and mixed character codes while users type, with caret and selection handling built into the component. For example, mask="0000 0000 0000 0000" displays 1234567890123456 as 1234 5678 9012 3456 without an additional runtime dependency.

Related to ant-design/ant-design#54442. This provides the native foundation; exposing it through Ant Design requires a separate integration after release.

API

  • mask?: InputMask: a string pattern, a readonly array of literal strings and single-character regular expressions, or a pure function receiving { value, selection } and returning a pattern. Dynamic masks receive the proposed input text and its selection offsets; selection is null for initial or externally updated values.
  • maskDefinitions?: Readonly<Record<string, RegExp | null>>: extends or overrides the default string tokens. 0 accepts ASCII digits, X accepts Latin letters, and * accepts alphanumeric characters. A null definition makes a token literal; backslash escapes tokens. Array strings remain literals. Stateful g and y regex flags are ignored without mutating caller-provided expressions.
  • maskPlaceholder?: string | null: unfilled positions are hidden when omitted, undefined, null or ''. An explicit character repeats across empty positions; a longer string supplies placeholders at the corresponding pattern positions, with _ used beyond its length. Placeholder characters are reserved for empty positions, and conflicting rules produce a development warning.

Exports InputMaskState, InputMaskPattern, InputMask, and InputMaskDefinitions.

import Input from '@rc-component/input';

<Input mask="XX-00-**" maskPlaceholder="_" />;

<Input mask="HH-00" maskDefinitions={{ H: /[A-Z]/ }} />;

<Input
  mask={({ value }) =>
    value.replace(/\D/g, '').startsWith('3')
      ? '0000 000000 00000'
      : '0000 0000 0000 0000'
  }
/>;

Behavior and coverage

  • Supports raw or formatted controlled and uncontrolled values, inline dynamic masks and definition updates.
  • Handles insertion, deletion around separators, range replacement, paste, autofill and caret restoration, including shadow roots. Copied partial values retain their characters when pasted into the same mask without placeholders. Typed characters are validated against the next position; edits that cannot be displayed unambiguously without placeholders are ignored.
  • Defers formatting during IME composition and avoids duplicate change events when composition ends.
  • Preserves the React event contract: target.value and currentTarget.value contain formatted text, including separators and visible placeholders. Clearing emits ''. No generic formatter/parser or automatic unmasked-value API is added.
  • Integrates with allowClear, refs, focus, disabled/read-only state, maxLength and character counting. Placeholder-only values hide the clear button through a new hiddenClear prop on BaseInput: since feat: unify allowClear configuration #208, allowClear.disabled removes the affix wrapper, which would remount the input and lose focus. Explicitly disabled clearing keeps the upstream behavior. maxLength limits displayed pattern length; count.exceedFormatter receives formatted text and its result is formatted again.
  • Applies to text, search, tel, url and password inputs. Mask props are excluded from DOM attributes.
  • Adds 99 mask tests, a demo covering static and dynamic patterns, and English and Chinese API documentation.

Summary by CodeRabbit

  • 新功能
    • 输入框支持固定或动态输入掩码、自定义字符规则及占位符。
    • 掩码输入支持格式化、编辑、粘贴和清除,并兼容长度限制、计数和输入法组合。
    • 提供银行卡号掩码示例,展示多种配置方式。
  • 文档
    • 补充中英文输入掩码说明、参数介绍及使用示例。

@vercel

vercel Bot commented Oct 6, 2026

Copy link
Copy Markdown

@nikzanda is attempting to deploy a commit to the afc163's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: d54b832b-332c-4b6e-b22e-82e23bc6a3a5
📥 Commits

Reviewing files that changed from the base of the PR and between b37230b and e5cb0b2.

📒 Files selected for processing (5)
  • README.md
  • src/BaseInput.tsx
  • src/Input.tsx
  • src/interface.ts
  • tests/mask.test.tsx

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

Input 新增掩码配置和公开类型。掩码支持静态及动态模式、自定义规则、占位符和选区编辑,并接入计数、IME 组合及清除流程。此次变更还新增文档、演示示例和测试。

Changes

Input 掩码

Layer / File(s) Summary
掩码类型、解析与编辑
src/interface.ts, src/index.tsx, src/utils/maskUtil.ts
新增掩码类型和 Input 属性。新增 token 解析、格式化及编辑逻辑,处理字面量、占位符、正则规则、插入、删除和光标位置。
掩码输入处理与组件集成
src/hooks/useMask.ts, src/Input.tsx, src/BaseInput.tsx, src/hooks/useCountExceed.ts, tests/mask.test.tsx
新增 useMask,并将掩码值、选区和输入事件接入 Input。掩码显示值用于计数和渲染;BaseInput 支持隐藏清除按钮。测试覆盖格式化、编辑、粘贴、清除、maxLength、计数及 IME 行为。
文档与演示示例
README.md, README.zh-CN.md, docs/demo/mask.md, docs/examples/mask.tsx
新增中英文掩码说明、演示页面和示例组件,展示动态银行卡号掩码、自定义规则和占位符配置。

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~60 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Input
  participant useMask
  participant editMask
  participant BaseInput
  Input->>useMask: 传入掩码配置和输入状态
  useMask->>editMask: 处理编辑值、选区和 token
  useMask-->>Input: 返回格式化值与编辑结果
  Input->>BaseInput: 传入掩码显示值
Loading

Suggested reviewers: qdyanbing

Merge Risk: ⚪ Minimal · up to e5cb0

No identified masking issue remains that needs resolution before merge; normal checks can proceed.

Pre-merge checks · Passed 4 · Failed 1

Failed Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 21 functions across 9 files. (1 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks (4 passed)
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed 标题“feat: add input masking support”准确概括了本次变更的主要内容。标题简洁、明确,并与输入掩码 API、实现、测试和文档变更一致。
Full details: Docstring Coverage

Explanation

Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 21 functions across 9 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

兔子敲下数字行,
掩码将字符排成章。
光标轻移过分隔,
占位符静候输入忙。
新例文档添一页,
兔耳摇摇庆功能。

Comment @coderabbitai help to get the list of available commands.

Preserve masked input focus with the unified allowClear configuration.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant