diff --git a/.dumirc.ts b/.dumirc.ts index f9137735..83cdabe3 100644 --- a/.dumirc.ts +++ b/.dumirc.ts @@ -1,14 +1,19 @@ import { defineConfig } from 'dumi'; +const basePath = process.env.GH_PAGES ? '/input-number/' : '/'; +const publicPath = basePath; + export default defineConfig({ - favicons: [ - 'https://avatars0.githubusercontent.com/u/9441414?s=200&v=4', - ], + favicons: ['https://avatars0.githubusercontent.com/u/9441414?s=200&v=4'], themeConfig: { name: 'InputNumber', - logo: 'https://avatars0.githubusercontent.com/u/9441414?s=200&v=4' + logo: 'https://avatars0.githubusercontent.com/u/9441414?s=200&v=4', }, outputPath: 'docs-dist', + base: basePath, + publicPath, exportStatic: {}, - styles: [`body .dumi-default-header-left { width: 230px; } body .dumi-default-hero-title { font-size: 100px; }`], + styles: [ + `body .dumi-default-header-left { width: 230px; } body .dumi-default-hero-title { font-size: 100px; }`, + ], }); diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 33b1999c..758659af 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,15 +1,2 @@ -# These are supported funding model platforms - -github: ant-design # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] -patreon: # Replace with a single Patreon username -open_collective: ant-design # Replace with a single Open Collective username -ko_fi: # Replace with a single Ko-fi username -tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: # Replace with a single Liberapay username -issuehunt: # Replace with a single IssueHunt username -lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry -polar: # Replace with a single Polar username -buy_me_a_coffee: # Replace with a single Buy Me a Coffee username -thanks_dev: # Replace with a single thanks.dev username -custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] +github: ant-design +open_collective: ant-design diff --git a/.github/dependabot.yml b/.github/dependabot.yml index add01c3d..3b730ef9 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,23 +1,19 @@ version: 2 updates: -- package-ecosystem: npm - directory: "/" - schedule: - interval: daily - time: "21:00" - open-pull-requests-limit: 10 - ignore: - - dependency-name: "@types/react-dom" - versions: - - 17.0.0 - - 17.0.1 - - 17.0.2 - - dependency-name: "@types/react" - versions: - - 17.0.0 - - 17.0.1 - - 17.0.2 - - 17.0.3 - - dependency-name: less - versions: - - 4.1.0 + - package-ecosystem: npm + directory: '/' + schedule: + interval: weekly + day: monday + time: '21:00' + timezone: Asia/Shanghai + open-pull-requests-limit: 10 + + - package-ecosystem: github-actions + directory: '/' + schedule: + interval: weekly + day: monday + time: '21:00' + timezone: Asia/Shanghai + open-pull-requests-limit: 10 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 7c5e0671..b399f316 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,12 +1,12 @@ -name: "CodeQL" +name: 'CodeQL' on: push: - branches: [ "master" ] + branches: ['master'] pull_request: - branches: [ "master" ] + branches: ['master'] schedule: - - cron: "19 0 * * 4" + - cron: '19 0 * * 4' jobs: analyze: @@ -20,22 +20,24 @@ jobs: strategy: fail-fast: false matrix: - language: [ javascript ] + language: [javascript] steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v7 + with: + persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e with: languages: ${{ matrix.language }} queries: +security-and-quality - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@8aad20d150bbac5944a9f9d289da16a4b0d87c1e - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e with: - category: "/language:${{ matrix.language }}" + category: '/language:${{ matrix.language }}' diff --git a/.github/workflows/react-component-ci.yml b/.github/workflows/react-component-ci.yml index 7b1f97cb..36dacae4 100644 --- a/.github/workflows/react-component-ci.yml +++ b/.github/workflows/react-component-ci.yml @@ -1,6 +1,9 @@ name: ✅ test on: [push, pull_request] +permissions: + contents: read jobs: test: uses: react-component/rc-test/.github/workflows/test-utoo.yml@main - secrets: inherit \ No newline at end of file + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/react-doctor.yml b/.github/workflows/react-doctor.yml new file mode 100644 index 00000000..097eb883 --- /dev/null +++ b/.github/workflows/react-doctor.yml @@ -0,0 +1,27 @@ +name: React Doctor + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + push: + branches: [master] + +permissions: + contents: read + pull-requests: write + issues: write + statuses: write + +concurrency: + group: react-doctor-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + react-doctor: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + fetch-depth: 0 + persist-credentials: false + - uses: millionco/react-doctor@0b4f4f4bd248a154e64eb508a48347f71154b3f3 diff --git a/.github/workflows/surge-preview.yml b/.github/workflows/surge-preview.yml new file mode 100644 index 00000000..4c2f17ed --- /dev/null +++ b/.github/workflows/surge-preview.yml @@ -0,0 +1,54 @@ +name: Surge Preview + +on: + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} + cancel-in-progress: true + +permissions: + contents: read + pull-requests: write + checks: write + +jobs: + preview: + runs-on: ubuntu-latest + concurrency: + group: surge-preview-${{ github.event.pull_request.number }} + cancel-in-progress: true + env: + PREVIEW: true + steps: + - uses: actions/checkout@v7 + with: + persist-credentials: false + - name: Check Surge token + id: surge-token + env: + SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }} + run: | + if [ -n "$SURGE_TOKEN" ]; then + echo "enabled=true" >> "$GITHUB_OUTPUT" + else + echo "enabled=false" >> "$GITHUB_OUTPUT" + fi + - name: Build preview + if: ${{ steps.surge-token.outputs.enabled == 'true' }} + run: | + npm install + npm run build + - uses: afc163/surge-preview@bf90a5a86111f6311ca42f0a5a0f80fb0fb03cec + if: ${{ steps.surge-token.outputs.enabled == 'true' }} + env: + SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }} + with: + surge_token: ${{ env.SURGE_TOKEN }} + github_token: ${{ secrets.GITHUB_TOKEN }} + dist: docs-dist + failOnError: false + setCommitStatus: false + - name: Skip Surge preview + if: ${{ steps.surge-token.outputs.enabled != 'true' }} + run: echo "SURGE_TOKEN is not configured; skip Surge preview." diff --git a/.gitignore b/.gitignore index e44962a4..f774ac03 100755 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,5 @@ docs-dist/ .dumi/tmp .dumi/tmp-production -bun.lockb \ No newline at end of file +bun.lockb +.vercel diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 00000000..2312dc58 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx lint-staged diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..c466d872 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,14 @@ +node_modules +coverage +docs-dist +dist +es +lib +.dumi/tmp +.dumi/tmp-production +.vercel +package-lock.json +pnpm-lock.yaml +yarn.lock +bun.lockb +*.log diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..bd0a1f72 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019-present react-component + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 64aee149..1c6b2511 100644 --- a/README.md +++ b/README.md @@ -1,277 +1,151 @@ -# @rc-component/input-number - -Input number control. - -[![NPM version][npm-image]][npm-url] -[![npm download][download-image]][download-url] -[![build status][github-actions-image]][github-actions-url] -[![Codecov][codecov-image]][codecov-url] -[![bundle size][bundlephobia-image]][bundlephobia-url] -[![dumi][dumi-image]][dumi-url] - -[npm-image]: http://img.shields.io/npm/v/@rc-component/input-number.svg?style=flat-square -[npm-url]: http://npmjs.org/package/@rc-component/input-number -[travis-image]: https://img.shields.io/travis/react-component/input-number/master?style=flat-square -[travis-url]: https://travis-ci.com/react-component/input-number -[github-actions-image]: https://github.com/react-component/input-number/actions/workflows/react-component-ci.yml/badge.svg -[github-actions-url]: https://github.com/react-component/input-number/actions/workflows/react-component-ci.yml -[codecov-image]: https://img.shields.io/codecov/c/github/react-component/input-number/master.svg?style=flat-square -[codecov-url]: https://app.codecov.io/gh/react-component/input-number -[david-url]: https://david-dm.org/react-component/input-number -[david-image]: https://david-dm.org/react-component/input-number/status.svg?style=flat-square -[david-dev-url]: https://david-dm.org/react-component/input-number?type=dev -[david-dev-image]: https://david-dm.org/react-component/input-number/dev-status.svg?style=flat-square -[download-image]: https://img.shields.io/npm/dm/@rc-component/input-number.svg?style=flat-square -[download-url]: https://npmjs.org/package/@rc-component/input-number -[bundlephobia-url]: https://bundlephobia.com/package/@rc-component/input-number -[bundlephobia-image]: https://badgen.net/bundlephobia/minzip/@rc-component/input-number -[dumi-url]: https://github.com/umijs/dumi -[dumi-image]: https://img.shields.io/badge/docs%20by-dumi-blue?style=flat-square - -## Screenshots - - +
+

@rc-component/input-number

+

Ant Design Part of the Ant Design ecosystem.

+

🔢 Accessible React number input with precision, formatting, keyboard, and wheel support.

+ +

+ NPM version + npm downloads + build status + Codecov + bundle size + dumi +

+
+ +

English | 简体中文

+ +## Highlights + +- Controlled and uncontrolled numeric input modes. +- Decimal precision, custom parser, formatter, and decimal separator support. +- Keyboard stepping, mouse wheel stepping, and custom step handlers. +- Prefix, suffix, spinner controls, and semantic `classNames` / `styles` slots. +- TypeScript generic value typing for number and string based value flows. ## Install -[![@rc-component/input-number](https://nodei.co/npm/@rc-component/input-number.png)](https://npmjs.org/package/@rc-component/input-number) +```bash +npm install @rc-component/input-number +``` ## Usage -```js +```tsx | pure import InputNumber from '@rc-component/input-number'; -export default () => ; +export default () => ; ``` -## Development +```tsx | pure +import InputNumber from '@rc-component/input-number'; +export default () => ( + `$ ${value}`} + parser={(displayValue) => displayValue?.replace(/\$\s?/g, '') || ''} + /> +); ``` + +## Examples + +Run the local dumi site: + +```bash npm install npm start ``` -## Example +Then open `http://localhost:8000`. -http://127.0.0.1:8000/examples/ +## API -online example: https://input-number.vercel.app/ +### InputNumber + +| Property | Type | Default | Description | +| --- | --- | --- | --- | +| autoFocus | `boolean` | `false` | Focus the input when mounted. | +| changeOnBlur | `boolean` | `true` | Commit value changes on blur. | +| changeOnWheel | `boolean` | `false` | Allow value changes from the mouse wheel. | +| className | `string` | - | Class name for the root element. | +| classNames | `Partial>` | - | Semantic class names for input-number slots. | +| controls | `boolean` | `true` | Show increment and decrement controls. | +| decimalSeparator | `string` | - | Decimal separator used by the display formatter. | +| defaultValue | `T` | - | Initial value. | +| disabled | `boolean` | `false` | Disable the input. | +| downHandler | `ReactNode` | - | Custom decrement control. | +| formatter | `(value: T \| undefined, info: { userTyping: boolean; input: string }) => string` | - | Format the displayed value. | +| inputMode | `string` | - | Native input `inputMode` attribute. | +| keyboard | `boolean` | `true` | Enable keyboard stepping. | +| max | `T` | - | Maximum value. | +| min | `T` | - | Minimum value. | +| mode | `'input' \| 'spinner'` | `input` | Render mode. | +| parser | `(displayValue: string \| undefined) => T` | - | Parse the displayed value back to a value. | +| precision | `number` | - | Display precision. | +| prefix | `ReactNode` | - | Prefix content. | +| prefixCls | `string` | `rc-input-number` | Class name prefix. | +| readOnly | `boolean` | `false` | Mark the input as read only. | +| step | `number \| string` | `1` | Step size. | +| stringMode | `boolean` | `false` | Keep values as strings for high precision decimals. | +| style | `React.CSSProperties` | - | Inline styles for the root element. | +| styles | `Partial>` | - | Semantic styles for input-number slots. | +| suffix | `ReactNode` | - | Suffix content. | +| upHandler | `ReactNode` | - | Custom increment control. | +| value | `T \| null` | - | Controlled value. | +| onChange | `(value: T \| null) => void` | - | Triggered when the committed value changes. | +| onInput | `(text: string) => void` | - | Triggered when the raw input text changes. | +| onPressEnter | `React.KeyboardEventHandler` | - | Triggered when Enter is pressed. | +| onStep | `(value: T, info: { offset: number \| string; type: 'up' \| 'down'; emitter: 'handler' \| 'keyboard' \| 'wheel' }) => void` | - | Triggered when the value changes by step. | + +Native input attributes such as `id`, `name`, `placeholder`, `required`, `readOnly`, and `tabIndex` are also supported unless explicitly overridden above. + +### Ref + +```tsx | pure +import InputNumber, { type InputNumberRef } from '@rc-component/input-number'; + +const ref = React.useRef(null); + +ref.current?.focus(); +ref.current?.blur(); +``` -## API +| Property | Type | Description | +| ------------- | --------------------------------------- | -------------------- | +| focus | `(options?: InputFocusOptions) => void` | Focus the input. | +| blur | `() => void` | Blur the input. | +| nativeElement | `HTMLElement` | Root native element. | -### props - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
nametypedefaultdescription
prefixClsstringrc-input-numberSpecifies the class prefix
minNumberSpecifies the minimum value
onClick
placeholderstring
maxNumberSpecifies the maximum value
stepNumber or String1Specifies the legal number intervals
precisionNumberSpecifies the precision length of value
disabledBooleanfalseSpecifies that an InputNumber should be disabled
requiredBooleanfalseSpecifies that an InputNumber is required
autoFocusBooleanfalseSpecifies that an InputNumber should automatically get focus when the page loads
readOnlyBooleanfalseSpecifies that an InputNumber is read only
controlsBooleantrueWhether to enable the control buttons
nameStringSpecifies the name of an InputNumber
idStringSpecifies the id of an InputNumber
valueNumberSpecifies the value of an InputNumber
defaultValueNumberSpecifies the defaultValue of an InputNumber
onChangeFunctionCalled when value of an InputNumber changed
onBlurFunctionCalled when user leaves an input field
onPressEnterFunctionThe callback function that is triggered when Enter key is pressed.
onFocusFunctionCalled when an element gets focus
styleObjectroot style. such as {width:100}
upHandlerReact.Nodecustom the up step element
downHandlerReact.Nodecustom the down step element
formatter(value: number|string): displayValue: stringSpecifies the format of the value presented
parser(displayValue: string) => value: number`input => input.replace(/[^\w\.-]*/g, '')`Specifies the value extracted from formatter
patternstringSpecifies a regex pattern to be added to the input number element - useful for forcing iOS to open the number pad instead of the normal keyboard (supply a regex of "\d*" to do this) or form validation
decimalSeparatorstringSpecifies the decimal separator
inputModestringSpecifies the inputmode of input
wheelBooleantrueAllows changing value with mouse wheel
- -## Keyboard Navigation -* When you hit the or key, the input value will be increased or decreased by `step` -* With the Shift key (Shift+⬆, Shift+⬇), the input value will be changed by `10 * step` -* With the Ctrl or key (Ctrl+⬆ or ⌘+⬆ or Ctrl+⬇ or ⌘+⬇ ), the input value will be changed by `0.1 * step` - -## Mouse Wheel -* When you scroll up or down, the input value will be increased or decreased by `step` -* Scrolling with the Shift key, the input value will be changed by `10 * step` - -## Test Case +## Keyboard And Wheel -``` +- Arrow up and Arrow down change the value by `step`. +- `Shift + Arrow` changes the value by `10 * step`. +- `Ctrl` / `Command + Arrow` changes the value by `0.1 * step`. +- Mouse wheel changes are opt-in through `changeOnWheel`. + +## Development + +```bash +npm install +npm start npm test -npm run chrome-test +npm run tsc +npm run compile +npm run build ``` -## Coverage +The dumi site runs at `http://localhost:8000` by default. -``` -npm run coverage +## Release + +```bash +npm run prepublishOnly ``` -open coverage/ dir +The release flow is handled by `@rc-component/np` through the `rc-np` command after the package build. ## License -@rc-component/input-number is released under the MIT license. +@rc-component/input-number is released under the [MIT](./LICENSE) license. diff --git a/README.zh-CN.md b/README.zh-CN.md new file mode 100644 index 00000000..86c62412 --- /dev/null +++ b/README.zh-CN.md @@ -0,0 +1,151 @@ +
+

@rc-component/input-number

+

Ant Design Ant Design 生态的一部分。

+

🔢 React 数字输入组件,支持格式化、精度、步进和键盘交互。

+ +

+ NPM version + npm downloads + build status + Codecov + bundle size + dumi +

+
+ +

English | 简体中文

+ +## 特性 + +- 受控和非受控数字输入模式。 +- 小数精度、自定义解析器、格式化程序和小数分隔符支持。 +- 支持键盘步进、鼠标滚轮步进和自定义步进处理。 +- 支持前缀、后缀、步进控制器和语义化 `classNames` / `styles` 插槽。 +- TypeScript 通用值类型用于基于数字和字符串的值流。 + +## 安装 + +```bash +npm install @rc-component/input-number +``` + +## 使用 + +```tsx | pure +import InputNumber from '@rc-component/input-number'; + +export default () => ; +``` + +```tsx | pure +import InputNumber from '@rc-component/input-number'; + +export default () => ( + `$ ${value}`} + parser={(displayValue) => displayValue?.replace(/\$\s?/g, '') || ''} + /> +); +``` + +## 示例 + +运行本地 dumi 站点: + +```bash +npm install +npm start +``` + +然后打开 `http://localhost:8000`。 + +## API + +### InputNumber + +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| autoFocus | `boolean` | `false` | 安装后聚焦输入。 | +| changeOnBlur | `boolean` | `true` | 提交模糊值的变化。 | +| changeOnWheel | `boolean` | `false` | 允许通过鼠标滚轮更改值。 | +| className | `string` | - | 根元素的 className。 | +| classNames | `Partial>` | - | 输入数字槽的语义 className。 | +| controls | `boolean` | `true` | 显示增量和减量控件。 | +| decimalSeparator | `string` | - | 显示格式化程序使用的小数分隔符。 | +| defaultValue | `T` | - | 初始值。 | +| disabled | `boolean` | `false` | 禁用输入。 | +| downHandler | `ReactNode` | - | 自定义减量控制。 | +| formatter | `(value: T \| undefined, info: { userTyping: boolean; input: string }) => string` | - | 设置显示值的格式。 | +| inputMode | `string` | - | 原生 input `inputMode` 属性。 | +| keyboard | `boolean` | `true` | 启用键盘步进。 | +| max | `T` | - | 最大值。 | +| min | `T` | - | 最小值。 | +| mode | `'input' \| 'spinner'` | `input` | 渲染模式。 | +| parser | `(displayValue: string \| undefined) => T` | - | 将显示的值解析回一个值。 | +| precision | `number` | - | 显示精度。 | +| prefix | `ReactNode` | - | 前缀内容。 | +| prefixCls | `string` | `rc-input-number` | className 前缀。 | +| readOnly | `boolean` | `false` | 将输入标记为只读。 | +| step | `number \| string` | `1` | 步长。 | +| stringMode | `boolean` | `false` | 将值保留为字符串以获得高精度小数。 | +| style | `React.CSSProperties` | - | 根元素的内联样式。 | +| styles | `Partial>` | - | 输入数字槽的语义样式。 | +| suffix | `ReactNode` | - | 后缀内容。 | +| upHandler | `ReactNode` | - | 自定义增量控制。 | +| value | `T \| null` | - | 受控值。 | +| onChange | `(value: T \| null) => void` | - | 当提交的值改变时触发。 | +| onInput | `(text: string) => void` | - | 当原始输入文本更改时触发。 | +| onPressEnter | `React.KeyboardEventHandler` | - | 当按下 Enter 时触发。 | +| onStep | `(value: T, info: { offset: number \| string; type: 'up' \| 'down'; emitter: 'handler' \| 'keyboard' \| 'wheel' }) => void` | - | 当值逐步变化时触发。 | + +除非上方明确覆盖,也支持 `id`, `name`, `placeholder`, `required`, `readOnly`, and `tabIndex` 等原生 input 属性。 + +### Ref + +```tsx | pure +import InputNumber, { type InputNumberRef } from '@rc-component/input-number'; + +const ref = React.useRef(null); + +ref.current?.focus(); +ref.current?.blur(); +``` + +| 参数 | 类型 | 说明 | +| ------------- | --------------------------------------- | ------------ | +| focus | `(options?: InputFocusOptions) => void` | 集中输入。 | +| blur | `() => void` | 模糊输入。 | +| nativeElement | `HTMLElement` | 根原生元素。 | + +## 键盘与滚轮 + +- 上箭头和下箭头会按 `step` 改变数值。 +- `Shift + Arrow` 将值更改为 `10 * step`。 +- `Ctrl` / `Command + Arrow` 将值更改为`0.1 * step`。 +- 鼠标滚轮改值需要通过 `changeOnWheel` 显式开启。 + +## 本地开发 + +```bash +npm install +npm start +npm test +npm run tsc +npm run compile +npm run build +``` + +dumi 站点默认运行在 `http://localhost:8000`。 + +## 发布 + +```bash +npm run prepublishOnly +``` + +包构建完成后,发布流程由 `@rc-component/np` 通过 `rc-np` 命令处理。 + +## 许可证 + +@rc-component/input-number 基于 [MIT](./LICENSE) 许可证发布。 diff --git a/package.json b/package.json index 37963cab..d7fb3495 100644 --- a/package.json +++ b/package.json @@ -8,13 +8,13 @@ "react-input-number", "input-number" ], - "homepage": "https://github.com/react-component/input-number", + "homepage": "https://react-component.github.io/input-number", "bugs": { "url": "https://github.com/react-component/input-number/issues" }, "repository": { "type": "git", - "url": "git@github.com:react-component/input-number.git" + "url": "https://github.com/react-component/input-number.git" }, "license": "MIT", "author": "tsjxyz@gmail.com", @@ -27,22 +27,22 @@ "assets/*.css" ], "scripts": { + "build": "npm run docs:build", "compile": "father build && lessc assets/index.less assets/index.css", "coverage": "rc-test --coverage", "docs:build": "dumi build", + "docs:build:gh-pages": "GH_PAGES=1 npm run docs:build", "docs:deploy": "gh-pages -d docs-dist", "lint": "eslint src/ --ext .ts,.tsx,.jsx,.js,.md", - "prepare": "husky install", + "prepare": "husky", "prepublishOnly": "npm run compile && rc-np", - "prettier": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"", + "prettier": "prettier --write --ignore-unknown .", "start": "dumi dev", - "test": "rc-test" + "test": "rc-test", + "tsc": "tsc --noEmit" }, "lint-staged": { - "**/*.{js,jsx,tsx,ts,md,json}": [ - "prettier --write", - "git add" - ] + "*": "prettier --write --ignore-unknown" }, "dependencies": { "@rc-component/mini-decimal": "^1.1.1", @@ -51,34 +51,39 @@ }, "devDependencies": { "@rc-component/father-plugin": "^2.2.0", - "@rc-component/np": "^1.0.3", + "@rc-component/np": "^1.0.4", "@swc-node/jest": "^1.5.5", - "@testing-library/jest-dom": "^6.1.5", - "@testing-library/react": "^16.0.0", - "@types/jest": "^29.2.4", - "@types/node": "^24.5.2", - "@types/react": "^18.0.26", - "@types/react-dom": "^18.0.9", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^15.0.7", + "@types/jest": "^29.5.14", + "@types/node": "^26.0.1", + "@types/react": "^18.3.31", + "@types/react-dom": "^18.3.7", "@types/responselike": "^1.0.0", "@umijs/fabric": "^4.0.1", - "@umijs/test": "^4.0.36", - "dumi": "^2.0.13", - "eslint": "^8.54.0", - "father": "^4.5.5", - "glob": "^11.0.0", + "@umijs/test": "^4.6.68", + "dumi": "^2.4.35", + "eslint": "^8.57.1", + "father": "^4.6.23", + "gh-pages": "^6.3.0", + "glob": "^13.0.6", "husky": "^9.1.7", - "jest-environment-jsdom": "^29.3.1", - "less": "^4.1.3", - "lint-staged": "^15.1.0", - "rc-test": "^7.0.14", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "jest-environment-jsdom": "^29.7.0", + "less": "^4.6.7", + "lint-staged": "^16.4.0", + "prettier": "^3.9.0", + "rc-test": "^7.1.3", + "react": "^18.3.1", + "react-dom": "^18.3.1", "regenerator-runtime": "^0.14.1", "ts-node": "^10.9.1", - "typescript": "^5.1.6" + "typescript": "^5.9.3" }, "peerDependencies": { "react": ">=16.9.0", "react-dom": ">=16.9.0" + }, + "publishConfig": { + "access": "public" } } diff --git a/tests/util/wrapper.ts b/tests/util/wrapper.ts index dd31921f..dafc2518 100644 --- a/tests/util/wrapper.ts +++ b/tests/util/wrapper.ts @@ -1,4 +1,4 @@ -import type { RenderOptions } from '@testing-library/react'; +import type { RenderOptions, RenderResult } from '@testing-library/react'; import { act, render } from '@testing-library/react'; import type { ReactElement } from 'react'; @@ -12,8 +12,10 @@ export const sleep = async (timeout = 0) => { }); }; -const customRender = (ui: ReactElement, options?: Omit) => - render(ui, { ...options }); +const customRender = ( + ui: ReactElement, + options?: Omit, +): RenderResult => render(ui, { ...options }); export * from '@testing-library/react'; export { customRender as render }; diff --git a/tsconfig.json b/tsconfig.json index 172aabc3..c9cba3fe 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,9 +8,30 @@ "skipLibCheck": true, "esModuleInterop": true, "paths": { - "@/*": ["src/*"], - "@@/*": ["src/.umi/*"], - "@rc-component/input-number": ["src/index.ts"] - } - } + "@/*": [ + "src/*" + ], + "@@/*": [ + "src/.umi/*" + ], + "@rc-component/input-number": [ + "src/index.ts" + ] + }, + "ignoreDeprecations": "5.0" + }, + "include": [ + ".fatherrc.ts", + ".dumirc.ts", + "**/*.ts", + "**/*.tsx" + ], + "exclude": [ + "node_modules", + "lib", + "es", + "dist", + "docs-dist", + ".dumi/tmp" + ] } diff --git a/vercel.json b/vercel.json new file mode 100644 index 00000000..5f9139ef --- /dev/null +++ b/vercel.json @@ -0,0 +1,6 @@ +{ + "framework": "umijs", + "installCommand": "npm install", + "buildCommand": "npm run build", + "outputDirectory": "docs-dist" +}