From e3ec61e7e1882fe290cca5af0705e88221b33c26 Mon Sep 17 00:00:00 2001 From: afc163 Date: Fri, 26 Jun 2026 11:11:35 +0800 Subject: [PATCH 01/34] chore: standardize repository tooling --- .github/FUNDING.yml | 17 +- .../workflows/cloudflare-pages-preview.yml | 38 ++ .github/workflows/codeql.yml | 10 +- .github/workflows/main.yml | 4 +- .github/workflows/react-doctor.yml | 26 ++ .github/workflows/surge-preview.yml | 33 ++ README.md | 427 ++++++------------ package.json | 7 +- vercel.json | 6 + 9 files changed, 258 insertions(+), 310 deletions(-) create mode 100644 .github/workflows/cloudflare-pages-preview.yml create mode 100644 .github/workflows/react-doctor.yml create mode 100644 .github/workflows/surge-preview.yml create mode 100644 vercel.json 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/workflows/cloudflare-pages-preview.yml b/.github/workflows/cloudflare-pages-preview.yml new file mode 100644 index 00000000..c1738dfe --- /dev/null +++ b/.github/workflows/cloudflare-pages-preview.yml @@ -0,0 +1,38 @@ +name: Cloudflare Pages Preview + +on: + pull_request: + +permissions: + contents: read + deployments: write + +jobs: + preview: + runs-on: ubuntu-latest + env: + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + CLOUDFLARE_PAGES_PROJECT: ${{ vars.CLOUDFLARE_PAGES_PROJECT }} + PREVIEW: true + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 + with: + persist-credentials: false + - name: Skip Cloudflare Pages preview + if: ${{ env.CLOUDFLARE_API_TOKEN == '' || env.CLOUDFLARE_ACCOUNT_ID == '' || env.CLOUDFLARE_PAGES_PROJECT == '' }} + run: echo "Cloudflare Pages preview is not configured; skip deployment." + - name: Install dependencies + if: ${{ env.CLOUDFLARE_API_TOKEN != '' && env.CLOUDFLARE_ACCOUNT_ID != '' && env.CLOUDFLARE_PAGES_PROJECT != '' }} + run: npm install + - name: Build site + if: ${{ env.CLOUDFLARE_API_TOKEN != '' && env.CLOUDFLARE_ACCOUNT_ID != '' && env.CLOUDFLARE_PAGES_PROJECT != '' }} + run: npm run build + - name: Deploy preview + if: ${{ env.CLOUDFLARE_API_TOKEN != '' && env.CLOUDFLARE_ACCOUNT_ID != '' && env.CLOUDFLARE_PAGES_PROJECT != '' }} + uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 + with: + apiToken: ${{ env.CLOUDFLARE_API_TOKEN }} + accountId: ${{ env.CLOUDFLARE_ACCOUNT_ID }} + command: pages deploy dist --project-name=${{ env.CLOUDFLARE_PAGES_PROJECT }} --branch=${{ github.head_ref }} + gitHubToken: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 9947b182..22e7257d 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -24,18 +24,20 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 + 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 }}" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1fe5da5f..f8482b63 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,5 +2,5 @@ name: ✅ test on: [push, pull_request] jobs: test: - uses: react-component/rc-test/.github/workflows/test-npm.yml@main - secrets: inherit \ No newline at end of file + uses: react-component/rc-test/.github/workflows/test-utoo.yml@main + secrets: inherit diff --git a/.github/workflows/react-doctor.yml b/.github/workflows/react-doctor.yml new file mode 100644 index 00000000..f820dc07 --- /dev/null +++ b/.github/workflows/react-doctor.yml @@ -0,0 +1,26 @@ +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@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 + 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..1f63ec71 --- /dev/null +++ b/.github/workflows/surge-preview.yml @@ -0,0 +1,33 @@ +name: Surge Preview + +on: + pull_request: + +permissions: + contents: read + pull-requests: write + checks: write + +jobs: + preview: + runs-on: ubuntu-latest + env: + SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }} + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 + with: + persist-credentials: false + - uses: afc163/surge-preview@bf90a5a86111f6311ca42f0a5a0f80fb0fb03cec + if: ${{ env.SURGE_TOKEN != '' }} + with: + surge_token: ${{ env.SURGE_TOKEN }} + github_token: ${{ secrets.GITHUB_TOKEN }} + dist: dist + failOnError: true + setCommitStatus: true + build: | + npm install + npm run build + - name: Skip Surge preview + if: ${{ env.SURGE_TOKEN == '' }} + run: echo "SURGE_TOKEN is not configured; skip Surge preview." diff --git a/README.md b/README.md index b4663546..29da06ce 100644 --- a/README.md +++ b/README.md @@ -1,319 +1,172 @@ -# @rc-component/cascader - -React Cascader Component. - -[![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]: https://img.shields.io/npm/v/@rc-component/cascader.svg?style=flat-square -[npm-url]: https://npmjs.org/package/@rc-component/cascader -[travis-image]: https://img.shields.io/travis/react-component/cascader/master?style=flat-square -[travis-url]: https://travis-ci.com/react-component/cascader -[github-actions-image]: https://github.com/react-component/cascader/actions/workflows/main.yml/badge.svg -[github-actions-url]: https://github.com/react-component/cascader/actions/workflows/main.yml -[codecov-image]: https://img.shields.io/codecov/c/github/react-component/cascader/master.svg?style=flat-square -[codecov-url]: https://app.codecov.io/gh/react-component/cascader -[david-url]: https://david-dm.org/react-component/cascader -[david-image]: https://david-dm.org/react-component/cascader/status.svg?style=flat-square -[david-dev-url]: https://david-dm.org/react-component/cascader?type=dev -[david-dev-image]: https://david-dm.org/react-component/cascader/dev-status.svg?style=flat-square -[download-image]: https://img.shields.io/npm/dm/@rc-component/cascader.svg?style=flat-square -[download-url]: https://npmjs.org/package/@rc-component/cascader -[bundlephobia-url]: https://bundlephobia.com/package/@rc-component/cascader -[bundlephobia-image]: https://badgen.net/bundlephobia/minzip/@rc-component/cascader -[dumi-url]: https://github.com/umijs/dumi -[dumi-image]: https://img.shields.io/badge/docs%20by-dumi-blue?style=flat-square - -## Browser Support - -| [IE / Edge](http://godban.github.io/browsers-support-badges/)
IE / Edge | [Firefox](http://godban.github.io/browsers-support-badges/)
Firefox | [Chrome](http://godban.github.io/browsers-support-badges/)
Chrome | [Safari](http://godban.github.io/browsers-support-badges/)
Safari | [Electron](http://godban.github.io/browsers-support-badges/)
Electron | -| --- | --- | --- | --- | --- | -| IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | - -## Screenshots - - - -## Example - -https://cascader-react-component.vercel.app +
+

@rc-component/cascader

+

🧭 React Cascader component for selecting values from hierarchical option trees, with search, multiple selection, async loading, and custom rendering.

+ +

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

+
+ +

+ + + Ant Design + + Part of the Ant Design ecosystem. + +

+ +## Highlights + +| Area | Support | +| --------- | ---------------------------------------------------------------- | +| Data | Nested options, field name mapping, disabled nodes | +| Selection | Single, multiple, checkable, and change-on-select flows | +| Search | Controlled search, custom filter, custom sort, custom render | +| Loading | Async option loading with `loadData` | +| Rendering | Custom option label, dropdown content, icons, and expand trigger | ## Install -[![@rc-component/cascader](https://nodei.co/npm/@rc-component/cascader.png)](https://npmjs.org/package/@rc-component/cascader) - ```bash -$ npm install @rc-component/cascader --save +npm install @rc-component/cascader ``` ## Usage -```js -import React from 'react'; +```tsx | pure import Cascader from '@rc-component/cascader'; - -const options = [{ - 'label': '福建', - 'value': 'fj', - 'children': [{ - 'label': '福州', - 'value': 'fuzhou', - 'children': [{ - 'label': '马尾', - 'value': 'mawei', - }], - }, { - 'label': '泉州', - 'value': 'quanzhou', - }], -}, { - 'label': '浙江', - 'value': 'zj', - 'children': [{ - 'label': '杭州', - 'value': 'hangzhou', - 'children': [{ - 'label': '余杭', - 'value': 'yuhang', - }], - }], -}, { - 'label': '北京', - 'value': 'bj', - 'children': [{ - 'label': '朝阳区', - 'value': 'chaoyang', - }, { - 'label': '海淀区', - 'value': 'haidian', - }], -}]; - -React.render( +import React from 'react'; +import { createRoot } from 'react-dom/client'; + +const options = [ + { + label: 'Zhejiang', + value: 'zhejiang', + children: [ + { + label: 'Hangzhou', + value: 'hangzhou', + children: [{ label: 'Xihu', value: 'xihu' }], + }, + ], + }, + { + label: 'Jiangsu', + value: 'jiangsu', + children: [{ label: 'Nanjing', value: 'nanjing' }], + }, +]; + +const App = () => ( - ... + -, container); +); + +createRoot(document.getElementById('root')!).render(); ``` +## Examples + +Visit the [online examples](https://cascader-react-component.vercel.app/) for search, multiple selection, custom field names, lazy loading, panel mode, and popup customization. + ## API -### props - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
nametypedefaultdescription
optionsObjectThe data options of cascade
valueArrayselected value
defaultValueArrayinitial selected value
onChangeFunction(value, selectedOptions)callback when finishing cascader select
changeOnSelectBooleanfalsechange value on each selection
loadDataFunction(selectedOptions)callback when click any option, use for loading more options
expandTriggerString'click'expand current item when click or hover
openBooleanvisibility of popup overlay
onPopupVisibleChangeFunction(visible)callback when popup overlay's visibility changed
transitionNameStringtransition className like "slide-up"
prefixClsStringrc-cascaderprefix className of popup overlay
popupClassNameStringadditional className of popup overlay
popupPlacementStringbottomLeftuse preset popup align config from builtinPlacements:bottomRight topRight bottomLeft topLeft
getPopupContainerfunction(trigger:Node):Node() => document.bodycontainer which popup select menu rendered into
dropdownMenuColumnStyleObjectstyle object for each cascader pop menu
fieldNamesObject{ label: 'label', value: 'value', children: 'children' }custom field name for label and value and children
expandIconReactNode>specific the default expand icon
loadingIconReactNode>specific the default loading icon
hidePopupOnSelectBoolean>truehide popup on select
showSearchboolean | objectfalseWhether show search input in single mode
- -### showSearch - -| Property | Description | Type | Default | Version | -| --- | --- | --- | --- | --- | -| autoClearSearchValue | Whether the current search will be cleared on selecting an item. Only applies when checkable| boolean | true | -| filter | The function will receive two arguments, inputValue and option, if the function returns true, the option will be included in the filtered set; Otherwise, it will be excluded | function(inputValue, path): boolean | - | | -| limit | Set the count of filtered items | number \| false | 50 | | -| matchInputWidth | Whether the width of list matches input, ([how it looks](https://github.com/ant-design/ant-design/issues/25779)) | boolean | true | | -| render | Used to render filtered options | function(inputValue, path): ReactNode | - | | -| sort | Used to sort filtered options | function(a, b, inputValue) | - | | -| searchValue | The current input "search" text | string | - | - | -| onSearch | called when input changed | function | - | - | - -### option - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
nametypedefaultdescription
labelStringoption text to display
valueStringoption value as react key
disabledBooleandisabled option
childrenArraychildren options
+### Cascader + +| Property | Type | Default | Description | +| -------------------- | ------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | +| autoClearSearchValue | boolean | true | Deprecated. Use `showSearch.autoClearSearchValue` instead. | +| builtinPlacements | BuildInPlacements | - | Custom popup placements. | +| changeOnSelect | boolean | false | Trigger `onChange` when selecting each level. | +| checkable | boolean \| ReactNode | false | Enable multiple selection with checkbox UI. | +| children | ReactElement | - | Trigger element. | +| classNames | Semantic class name map | - | Semantic class names for selector and popup elements. | +| defaultValue | string[] \| number[] \| Array | - | Initial selected value. | +| displayRender | `(label, selectedOptions) => ReactNode` | - | Render selected labels. | +| expandIcon | ReactNode | `>` | Custom expand icon. | +| expandTrigger | `click` \| `hover` | `click` | Trigger action for expanding the next option level. | +| fieldNames | `{ label?: string; value?: string; children?: string }` | `{ label: 'label', value: 'value', children: 'children' }` | Custom option field names. | +| loadData | `(selectedOptions) => void` | - | Load child options asynchronously. | +| loadingIcon | ReactNode | - | Custom loading icon. | +| onChange | `(value, selectedOptions) => void` | - | Called when selection changes. | +| onPopupVisibleChange | `(open: boolean) => void` | - | Called when popup visibility changes. | +| onSearch | `(value: string) => void` | - | Deprecated. Use `showSearch.onSearch` instead. | +| open | boolean | - | Controlled popup visibility. | +| optionRender | `(option) => ReactNode` | - | Custom option renderer. | +| options | Option[] | - | Hierarchical option data. | +| placement | Select placement | - | Popup placement. | +| popupClassName | string | - | Popup class name. | +| popupMenuColumnStyle | CSSProperties | - | Style for each popup menu column. | +| prefixCls | string | `rc-cascader` | Class name prefix. | +| searchValue | string | - | Deprecated. Use `showSearch.searchValue` instead. | +| showCheckedStrategy | `SHOW_PARENT` \| `SHOW_CHILD` | `SHOW_PARENT` | Strategy for rendering checked values in multiple mode. | +| showSearch | boolean \| SearchConfig | false | Enable and configure search. | +| styles | Semantic style map | - | Semantic styles for selector and popup elements. | +| value | string[] \| number[] \| Array | - | Controlled selected value. | + +`Cascader` also accepts public props from `@rc-component/select` `BaseSelect`, except private select-only props such as `mode`, `labelInValue`, `showSearch`, and `tokenSeparators`. + +### SearchConfig + +| Property | Type | Default | Description | +| -------------------- | -------------------------------------------------------- | ------- | ---------------------------------------------------------- | +| autoClearSearchValue | boolean | true | Clear search text after selecting an item. | +| filter | `(inputValue, options, fieldNames) => boolean` | - | Return `true` to include an option path in search results. | +| limit | number \| false | 50 | Limit the number of filtered items. | +| matchInputWidth | boolean | true | Whether the search result width matches the input width. | +| onSearch | `(value: string) => void` | - | Called when search text changes. | +| render | `(inputValue, path, prefixCls, fieldNames) => ReactNode` | - | Render a filtered option path. | +| searchValue | string | - | Controlled search text. | +| sort | `(a, b, inputValue, fieldNames) => number` | - | Sort filtered option paths. | + +### Option + +| Property | Type | Default | Description | +| --------------- | ------------------------ | ------- | ------------------------------------------------ | +| children | Option[] | - | Child options. | +| disabled | boolean | false | Disable this option. | +| disableCheckbox | boolean | false | Disable this option's checkbox in multiple mode. | +| label | ReactNode | - | Display label. | +| value | string \| number \| null | - | Option value. | ## Development ```bash -$ npm install -$ npm start +npm install +npm start ``` -## Test Case +Common commands: ```bash -$ npm test +npm run lint +npm test +npm run tsc +npm run lint:tsc +npm run compile ``` -## Coverage +## Release + +This package uses `prepublishOnly` to run the compile and release checks before publishing: ```bash -$ npm run coverage +npm publish ``` -## License +The publish lifecycle runs: -@rc-component/cascader is released under the MIT license. +```bash +npm run compile && rc-np +``` -## 🤝 Contributing +## License - - Contribution Leaderboard - +`@rc-component/cascader` is released under the MIT license. diff --git a/package.json b/package.json index d1d1fb05..0bb10232 100644 --- a/package.json +++ b/package.json @@ -35,9 +35,10 @@ "coverage": "father test --coverage", "tsc": "bunx tsc --noEmit", "deploy": "UMI_ENV=gh npm run build && gh-pages -d dist", - "lint": "eslint src/ examples/ tests/ --ext .tsx,.ts,.jsx,.jsx", + "lint": "eslint src/ examples/ tests/ --ext .tsx,.ts,.jsx,.js", "now-build": "npm run build", "prepublishOnly": "npm run compile && rc-np", + "prettier": "prettier --write --ignore-unknown .", "lint:tsc": "tsc -p tsconfig.json --noEmit", "start": "dumi dev", "test": "rc-test" @@ -59,6 +60,8 @@ "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", "@types/warning": "^3.0.0", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", "@umijs/fabric": "^4.0.0", "array-tree-filter": "^3.0.2", "cheerio": "1.0.0-rc.12", @@ -66,7 +69,7 @@ "cross-env": "^7.0.0", "dumi": "^2.1.10", "eslint": "^8.54.0", - "eslint-plugin-jest": "^28.8.3", + "eslint-plugin-jest": "^27.9.0", "eslint-plugin-unicorn": "^56.0.1", "father": "^4.0.0", "gh-pages": "^6.1.1", diff --git a/vercel.json b/vercel.json new file mode 100644 index 00000000..e884e1b3 --- /dev/null +++ b/vercel.json @@ -0,0 +1,6 @@ +{ + "framework": "umijs", + "installCommand": "npm install", + "buildCommand": "npm run build", + "outputDirectory": "dist" +} From 2e384d7bbedfd81d7d0a82e434fb44bbeded4301 Mon Sep 17 00:00:00 2001 From: afc163 Date: Fri, 26 Jun 2026 15:03:15 +0800 Subject: [PATCH 02/34] chore: remove cloudflare preview and now-build --- .../workflows/cloudflare-pages-preview.yml | 38 ------------------- package.json | 1 - 2 files changed, 39 deletions(-) delete mode 100644 .github/workflows/cloudflare-pages-preview.yml diff --git a/.github/workflows/cloudflare-pages-preview.yml b/.github/workflows/cloudflare-pages-preview.yml deleted file mode 100644 index c1738dfe..00000000 --- a/.github/workflows/cloudflare-pages-preview.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Cloudflare Pages Preview - -on: - pull_request: - -permissions: - contents: read - deployments: write - -jobs: - preview: - runs-on: ubuntu-latest - env: - CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} - CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - CLOUDFLARE_PAGES_PROJECT: ${{ vars.CLOUDFLARE_PAGES_PROJECT }} - PREVIEW: true - steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 - with: - persist-credentials: false - - name: Skip Cloudflare Pages preview - if: ${{ env.CLOUDFLARE_API_TOKEN == '' || env.CLOUDFLARE_ACCOUNT_ID == '' || env.CLOUDFLARE_PAGES_PROJECT == '' }} - run: echo "Cloudflare Pages preview is not configured; skip deployment." - - name: Install dependencies - if: ${{ env.CLOUDFLARE_API_TOKEN != '' && env.CLOUDFLARE_ACCOUNT_ID != '' && env.CLOUDFLARE_PAGES_PROJECT != '' }} - run: npm install - - name: Build site - if: ${{ env.CLOUDFLARE_API_TOKEN != '' && env.CLOUDFLARE_ACCOUNT_ID != '' && env.CLOUDFLARE_PAGES_PROJECT != '' }} - run: npm run build - - name: Deploy preview - if: ${{ env.CLOUDFLARE_API_TOKEN != '' && env.CLOUDFLARE_ACCOUNT_ID != '' && env.CLOUDFLARE_PAGES_PROJECT != '' }} - uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 - with: - apiToken: ${{ env.CLOUDFLARE_API_TOKEN }} - accountId: ${{ env.CLOUDFLARE_ACCOUNT_ID }} - command: pages deploy dist --project-name=${{ env.CLOUDFLARE_PAGES_PROJECT }} --branch=${{ github.head_ref }} - gitHubToken: ${{ secrets.GITHUB_TOKEN }} diff --git a/package.json b/package.json index 0bb10232..61206614 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ "tsc": "bunx tsc --noEmit", "deploy": "UMI_ENV=gh npm run build && gh-pages -d dist", "lint": "eslint src/ examples/ tests/ --ext .tsx,.ts,.jsx,.js", - "now-build": "npm run build", "prepublishOnly": "npm run compile && rc-np", "prettier": "prettier --write --ignore-unknown .", "lint:tsc": "tsc -p tsconfig.json --noEmit", From 861a38537e53a5c87ae9d1d9788fe28c18c777c2 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sat, 27 Jun 2026 00:29:53 +0800 Subject: [PATCH 03/34] docs: add Ant Design logo to README header --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 29da06ce..43916227 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@

@rc-component/cascader

+ Ant Design

🧭 React Cascader component for selecting values from hierarchical option trees, with search, multiple selection, async loading, and custom rendering.

From 56e34593d3631e0002b256ba2bd93128fb63d046 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sat, 27 Jun 2026 01:56:45 +0800 Subject: [PATCH 04/34] docs: standardize README release details --- README.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 43916227..696b0bf0 100644 --- a/README.md +++ b/README.md @@ -156,18 +156,12 @@ npm run compile ## Release -This package uses `prepublishOnly` to run the compile and release checks before publishing: - ```bash -npm publish +npm run prepublishOnly ``` -The publish lifecycle runs: - -```bash -npm run compile && rc-np -``` +The release flow is handled by `@rc-component/np` through the `rc-np` command after the package build. ## License -`@rc-component/cascader` is released under the MIT license. +@rc-component/cascader is released under the [MIT](./LICENSE.md) license. From e80fda6ede8efa8cff9b42e37daf00e3a2904c97 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sat, 27 Jun 2026 02:13:35 +0800 Subject: [PATCH 05/34] ci: make surge preview non-blocking --- .github/workflows/surge-preview.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/surge-preview.yml b/.github/workflows/surge-preview.yml index 1f63ec71..da133488 100644 --- a/.github/workflows/surge-preview.yml +++ b/.github/workflows/surge-preview.yml @@ -23,7 +23,7 @@ jobs: surge_token: ${{ env.SURGE_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }} dist: dist - failOnError: true + failOnError: false setCommitStatus: true build: | npm install From 24371bb051a8776bd3132cd158bf940af87f4738 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sat, 27 Jun 2026 02:17:43 +0800 Subject: [PATCH 06/34] docs: clarify Ant Design ecosystem note --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 696b0bf0..97f0ff9f 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Ant Design - Part of the Ant Design ecosystem. + Part of the Ant Design ecosystem.

From 0d117cab38a4196ddf4cae1c1cdc14ba038dc229 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sat, 27 Jun 2026 02:25:40 +0800 Subject: [PATCH 07/34] ci: keep surge preview as fallback --- .github/workflows/surge-preview.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/surge-preview.yml b/.github/workflows/surge-preview.yml index da133488..777206d3 100644 --- a/.github/workflows/surge-preview.yml +++ b/.github/workflows/surge-preview.yml @@ -24,7 +24,7 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} dist: dist failOnError: false - setCommitStatus: true + setCommitStatus: false build: | npm install npm run build From 696933640b423952d4c04decc3974baf73e667f6 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sat, 27 Jun 2026 13:03:57 +0800 Subject: [PATCH 08/34] docs: refine README usage and ecosystem note --- README.md | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 97f0ff9f..29359ab3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@

@rc-component/cascader

+

Part of the Ant Design ecosystem.

Ant Design

🧭 React Cascader component for selecting values from hierarchical option trees, with search, multiple selection, async loading, and custom rendering.

@@ -13,14 +14,6 @@

-

- - - Ant Design - - Part of the Ant Design ecosystem. - -

## Highlights @@ -42,8 +35,6 @@ npm install @rc-component/cascader ```tsx | pure import Cascader from '@rc-component/cascader'; -import React from 'react'; -import { createRoot } from 'react-dom/client'; const options = [ { @@ -64,13 +55,11 @@ const options = [ }, ]; -const App = () => ( +export default () => ( ); - -createRoot(document.getElementById('root')!).render(); ``` ## Examples From 079b20b52b24542208f22a6f4b3096901c849674 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sat, 27 Jun 2026 13:22:12 +0800 Subject: [PATCH 09/34] ci: isolate surge preview token --- .github/workflows/surge-preview.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/surge-preview.yml b/.github/workflows/surge-preview.yml index 777206d3..30f70a85 100644 --- a/.github/workflows/surge-preview.yml +++ b/.github/workflows/surge-preview.yml @@ -11,23 +11,25 @@ permissions: jobs: preview: runs-on: ubuntu-latest - env: - SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }} steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 with: persist-credentials: false + - name: Build preview + if: ${{ secrets.SURGE_TOKEN != '' }} + run: | + npm install + npm run build - uses: afc163/surge-preview@bf90a5a86111f6311ca42f0a5a0f80fb0fb03cec - if: ${{ env.SURGE_TOKEN != '' }} + if: ${{ secrets.SURGE_TOKEN != '' }} + env: + SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }} with: surge_token: ${{ env.SURGE_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }} dist: dist failOnError: false setCommitStatus: false - build: | - npm install - npm run build - name: Skip Surge preview - if: ${{ env.SURGE_TOKEN == '' }} + if: ${{ secrets.SURGE_TOKEN == '' }} run: echo "SURGE_TOKEN is not configured; skip Surge preview." From c4193774f0dda8e7fd1e0a4f2157836e5bf12805 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sat, 27 Jun 2026 22:00:28 +0800 Subject: [PATCH 10/34] docs: update Ant Design logo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 29359ab3..daaa5562 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@

@rc-component/cascader

Part of the Ant Design ecosystem.

- Ant Design + Ant Design

🧭 React Cascader component for selecting values from hierarchical option trees, with search, multiple selection, async loading, and custom rendering.

From 77d7bb21b0ff34a78bb1296a77a4147b6ff776e3 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sat, 27 Jun 2026 22:19:03 +0800 Subject: [PATCH 11/34] docs: add Chinese README --- README.md | 2 + README.zh-CN.md | 158 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 README.zh-CN.md diff --git a/README.md b/README.md index daaa5562..09e0e6bd 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@

+

English | 简体中文

+ ## Highlights diff --git a/README.zh-CN.md b/README.zh-CN.md new file mode 100644 index 00000000..cb3bb5d2 --- /dev/null +++ b/README.zh-CN.md @@ -0,0 +1,158 @@ +
+

@rc-component/cascader

+

Ant Design 生态的一部分。

+ Ant Design +

🧭 React 级联选择组件,支持层级选项、搜索、多选、异步加载和自定义渲染。

+ +

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

+
+ +

English | 简体中文

+ + +## 特性 + +| 范围 | 支持 | +| --------- | ---------------------------------------------------------------- | +| Data | Nested options, field name mapping, disabled nodes | +| Selection | Single, multiple, checkable, and change-on-select flows | +| Search | Controlled search, custom filter, custom sort, custom render | +| Loading | Async option loading with `loadData` | +| Rendering | Custom option label, dropdown content, icons, and expand trigger | + +## 安装 + +```bash +npm install @rc-component/cascader +``` + +## 使用 + +```tsx | pure +import Cascader from '@rc-component/cascader'; + +const options = [ + { + label: 'Zhejiang', + value: 'zhejiang', + children: [ + { + label: 'Hangzhou', + value: 'hangzhou', + children: [{ label: 'Xihu', value: 'xihu' }], + }, + ], + }, + { + label: 'Jiangsu', + value: 'jiangsu', + children: [{ label: 'Nanjing', value: 'nanjing' }], + }, +]; + +export default () => ( + + + +); +``` + +## 示例 + +查看[在线示例](https://cascader-react-component.vercel.app/),了解 search, multiple selection, custom field names, lazy loading, panel mode, and popup customization。 + +## API + +### Cascader + +| 参数 | 类型 | 默认值 | 说明 | +| -------------------- | ------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | +| autoClearSearchValue | boolean | true | Deprecated. Use `showSearch.autoClearSearchValue` instead. | +| builtinPlacements | BuildInPlacements | - | Custom popup placements. | +| changeOnSelect | boolean | false | Trigger `onChange` when selecting each level. | +| checkable | boolean \| ReactNode | false | Enable multiple selection with checkbox UI. | +| children | ReactElement | - | Trigger element. | +| classNames | Semantic class name map | - | Semantic class names for selector and popup elements. | +| defaultValue | string[] \| number[] \| Array | - | Initial selected value. | +| displayRender | `(label, selectedOptions) => ReactNode` | - | Render selected labels. | +| expandIcon | ReactNode | `>` | Custom expand icon. | +| expandTrigger | `click` \| `hover` | `click` | Trigger action for expanding the next option level. | +| fieldNames | `{ label?: string; value?: string; children?: string }` | `{ label: 'label', value: 'value', children: 'children' }` | Custom option field names. | +| loadData | `(selectedOptions) => void` | - | Load child options asynchronously. | +| loadingIcon | ReactNode | - | Custom loading icon. | +| onChange | `(value, selectedOptions) => void` | - | Called when selection changes. | +| onPopupVisibleChange | `(open: boolean) => void` | - | Called when popup visibility changes. | +| onSearch | `(value: string) => void` | - | Deprecated. Use `showSearch.onSearch` instead. | +| open | boolean | - | Controlled popup visibility. | +| optionRender | `(option) => ReactNode` | - | Custom option renderer. | +| options | Option[] | - | Hierarchical option data. | +| placement | Select placement | - | Popup placement. | +| popupClassName | string | - | Popup class name. | +| popupMenuColumnStyle | CSSProperties | - | Style for each popup menu column. | +| prefixCls | string | `rc-cascader` | Class name prefix. | +| searchValue | string | - | Deprecated. Use `showSearch.searchValue` instead. | +| showCheckedStrategy | `SHOW_PARENT` \| `SHOW_CHILD` | `SHOW_PARENT` | Strategy for rendering checked values in multiple mode. | +| showSearch | boolean \| SearchConfig | false | Enable and configure search. | +| styles | Semantic style map | - | Semantic styles for selector and popup elements. | +| value | string[] \| number[] \| Array | - | Controlled selected value. | + +`Cascader` also accepts public props from `@rc-component/select` `BaseSelect`, except private select-only props such as `mode`, `labelInValue`, `showSearch`, and `tokenSeparators`. + +### SearchConfig + +| 参数 | 类型 | 默认值 | 说明 | +| -------------------- | -------------------------------------------------------- | ------- | ---------------------------------------------------------- | +| autoClearSearchValue | boolean | true | Clear search text after selecting an item. | +| filter | `(inputValue, options, fieldNames) => boolean` | - | Return `true` to include an option path in search results. | +| limit | number \| false | 50 | Limit the number of filtered items. | +| matchInputWidth | boolean | true | Whether the search result width matches the input width. | +| onSearch | `(value: string) => void` | - | Called when search text changes. | +| render | `(inputValue, path, prefixCls, fieldNames) => ReactNode` | - | Render a filtered option path. | +| searchValue | string | - | Controlled search text. | +| sort | `(a, b, inputValue, fieldNames) => number` | - | Sort filtered option paths. | + +### Option + +| 参数 | 类型 | 默认值 | 说明 | +| --------------- | ------------------------ | ------- | ------------------------------------------------ | +| children | Option[] | - | Child options. | +| disabled | boolean | false | Disable this option. | +| disableCheckbox | boolean | false | Disable this option's checkbox in multiple mode. | +| label | ReactNode | - | Display label. | +| value | string \| number \| null | - | Option value. | + +## 本地开发 + +```bash +npm install +npm start +``` + +Common commands: + +```bash +npm run lint +npm test +npm run tsc +npm run lint:tsc +npm run compile +``` + +## 发布 + +```bash +npm run prepublishOnly +``` + +The release flow is handled by `@rc-component/np` through the `rc-np` command after the package build. + +## 许可证 + +@rc-component/cascader is released under the [MIT](./LICENSE.md) license. From 0a7a7cb313bc4546a83cdad4b2657d532b974a5f Mon Sep 17 00:00:00 2001 From: afc163 Date: Sat, 27 Jun 2026 23:02:22 +0800 Subject: [PATCH 12/34] docs: refine bilingual README branding --- README.md | 3 +- README.zh-CN.md | 105 ++++++++++++++++++++++++------------------------ 2 files changed, 53 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 09e0e6bd..e52b266e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@

@rc-component/cascader

-

Part of the Ant Design ecosystem.

- Ant Design +

Ant Design Part of the Ant Design ecosystem.

🧭 React Cascader component for selecting values from hierarchical option trees, with search, multiple selection, async loading, and custom rendering.

diff --git a/README.zh-CN.md b/README.zh-CN.md index cb3bb5d2..e1d554ca 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,7 +1,6 @@

@rc-component/cascader

-

Ant Design 生态的一部分。

- Ant Design +

Ant Design Ant Design 生态的一部分。

🧭 React 级联选择组件,支持层级选项、搜索、多选、异步加载和自定义渲染。

@@ -21,11 +20,11 @@ | 范围 | 支持 | | --------- | ---------------------------------------------------------------- | -| Data | Nested options, field name mapping, disabled nodes | -| Selection | Single, multiple, checkable, and change-on-select flows | -| Search | Controlled search, custom filter, custom sort, custom render | -| Loading | Async option loading with `loadData` | -| Rendering | Custom option label, dropdown content, icons, and expand trigger | +| 数据 | 嵌套选项、字段名映射和禁用节点 | +| Selection | 单选、多选、勾选和逐级选择流程 | +| 搜索 | 受控搜索、自定义过滤、自定义排序和自定义渲染 | +| Loading | 通过 `loadData` 异步加载选项 | +| Rendering | 自定义选项标签、下拉内容、图标和展开触发方式 | ## 安装 @@ -66,7 +65,7 @@ export default () => ( ## 示例 -查看[在线示例](https://cascader-react-component.vercel.app/),了解 search, multiple selection, custom field names, lazy loading, panel mode, and popup customization。 +查看[在线示例](https://cascader-react-component.vercel.app/),了解搜索、多选、自定义字段名称、延迟加载、面板模式和弹层窗口自定义。 ## API @@ -74,59 +73,59 @@ export default () => ( | 参数 | 类型 | 默认值 | 说明 | | -------------------- | ------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | -| autoClearSearchValue | boolean | true | Deprecated. Use `showSearch.autoClearSearchValue` instead. | -| builtinPlacements | BuildInPlacements | - | Custom popup placements. | -| changeOnSelect | boolean | false | Trigger `onChange` when selecting each level. | -| checkable | boolean \| ReactNode | false | Enable multiple selection with checkbox UI. | -| children | ReactElement | - | Trigger element. | -| classNames | Semantic class name map | - | Semantic class names for selector and popup elements. | -| defaultValue | string[] \| number[] \| Array | - | Initial selected value. | -| displayRender | `(label, selectedOptions) => ReactNode` | - | Render selected labels. | -| expandIcon | ReactNode | `>` | Custom expand icon. | -| expandTrigger | `click` \| `hover` | `click` | Trigger action for expanding the next option level. | -| fieldNames | `{ label?: string; value?: string; children?: string }` | `{ label: 'label', value: 'value', children: 'children' }` | Custom option field names. | -| loadData | `(selectedOptions) => void` | - | Load child options asynchronously. | -| loadingIcon | ReactNode | - | Custom loading icon. | -| onChange | `(value, selectedOptions) => void` | - | Called when selection changes. | -| onPopupVisibleChange | `(open: boolean) => void` | - | Called when popup visibility changes. | -| onSearch | `(value: string) => void` | - | Deprecated. Use `showSearch.onSearch` instead. | -| open | boolean | - | Controlled popup visibility. | -| optionRender | `(option) => ReactNode` | - | Custom option renderer. | -| options | Option[] | - | Hierarchical option data. | -| placement | Select placement | - | Popup placement. | -| popupClassName | string | - | Popup class name. | -| popupMenuColumnStyle | CSSProperties | - | Style for each popup menu column. | -| prefixCls | string | `rc-cascader` | Class name prefix. | -| searchValue | string | - | Deprecated. Use `showSearch.searchValue` instead. | -| showCheckedStrategy | `SHOW_PARENT` \| `SHOW_CHILD` | `SHOW_PARENT` | Strategy for rendering checked values in multiple mode. | -| showSearch | boolean \| SearchConfig | false | Enable and configure search. | -| styles | Semantic style map | - | Semantic styles for selector and popup elements. | -| value | string[] \| number[] \| Array | - | Controlled selected value. | - -`Cascader` also accepts public props from `@rc-component/select` `BaseSelect`, except private select-only props such as `mode`, `labelInValue`, `showSearch`, and `tokenSeparators`. +| autoClearSearchValue | boolean | true | 已弃用。请改用 `showSearch.autoClearSearchValue`。 | +| builtinPlacements | BuildInPlacements | - | 自定义弹层位置。 | +| changeOnSelect | boolean | false | 选择每个级别时触发 `onChange`。 | +| checkable | boolean \| ReactNode | false | 启用带复选框 UI 的多选。 | +| 孩子们 | ReactElement | - | 触发元素。 | +| classNames | 语义className映射 | - | 选择器和弹层元素的语义className称。 | +| defaultValue | 字符串[] \|数字[] \|数组<字符串[] \|数字[]> | - | 初始选中值。 | +| displayRender | `(label, selectedOptions) => ReactNode` | - | 渲染选定的标签。 | +| expandIcon | ReactNode | `>` | 自定义展开图标。 | +| expandTrigger | `click` \| `hover` | `click` | 触发扩展下一个选项级别的操作。 | +| fieldNames | `{ label?: string; value?: string; children?: string }` | `{ label: 'label', value: 'value', children: 'children' }` | 自定义选项字段名称。 | +| loadData | `(selectedOptions) => void` | - | 异步加载子选项。 | +| loadingIcon | ReactNode | - | 自定义加载图标。 | +| onChange | `(value, selectedOptions) => void` | - | 选择更改时调用。 | +| onPopupVisibleChange | `(open: boolean) => void` | - | 当弹层窗口可见性发生变化时调用。 | +| onSearch | `(value: string) => void` | - | 已弃用。请改用 `showSearch.onSearch`。 | +| 打开 | boolean | - | 受控的弹层窗口可见性。 | +| optionRender | `(option) => ReactNode` | - | 自定义选项渲染器。 | +| 选项 | 选项[] | - | 分层选项数据。 | +| placement | 选择展示位置 | - | 弹层窗口放置。 | +| popupClassName | string | - | 弹层className。 | +| popupMenuColumnStyle | CSSProperties | - | 每个弹出菜单列的样式。 | +| prefixCls | string | `rc-cascader` | className前缀。 | +| searchValue | string | - | 已弃用。请改用 `showSearch.searchValue`。 | +| showCheckedStrategy | `SHOW_PARENT` \| `SHOW_CHILD` | `SHOW_PARENT` | 在多种模式下渲染检查值的策略。 | +| showSearch | boolean \| SearchConfig | false | 启用并配置搜索。 | +| styles | 语义风格图 | - | 选择器和弹层元素的语义样式。 | +| 价值 | 字符串[] \|数字[] \|数组<字符串[] \|数字[]> | - | 受控选中值。 | + +`Cascader` 还接受来自 `@rc-component/select` `BaseSelect` 的公共属性,但私有仅选择属性除外,例如 `mode` 、 `labelInValue` 、 `showSearch` 和 `tokenSeparators`。 ### SearchConfig | 参数 | 类型 | 默认值 | 说明 | | -------------------- | -------------------------------------------------------- | ------- | ---------------------------------------------------------- | -| autoClearSearchValue | boolean | true | Clear search text after selecting an item. | -| filter | `(inputValue, options, fieldNames) => boolean` | - | Return `true` to include an option path in search results. | -| limit | number \| false | 50 | Limit the number of filtered items. | -| matchInputWidth | boolean | true | Whether the search result width matches the input width. | -| onSearch | `(value: string) => void` | - | Called when search text changes. | -| render | `(inputValue, path, prefixCls, fieldNames) => ReactNode` | - | Render a filtered option path. | -| searchValue | string | - | Controlled search text. | -| sort | `(a, b, inputValue, fieldNames) => number` | - | Sort filtered option paths. | +| autoClearSearchValue | boolean | true | 选择项目后清除搜索文本。 | +| 筛选 | `(inputValue, options, fieldNames) => boolean` | - | 返回 `true` 以在搜索结果中包含选项路径。 | +| limit | number \| false | 50 | 限制过滤项目的数量。 | +| matchInputWidth | boolean | true | 搜索结果宽度是否与输入宽度匹配。 | +| onSearch | `(value: string) => void` | - | 当搜索文本更改时调用。 | +| 使成为 | `(inputValue, path, prefixCls, fieldNames) => ReactNode` | - | 渲染过滤后的选项路径。 | +| searchValue | string | - | 受控搜索文本。 | +| 种类 | `(a, b, inputValue, fieldNames) => number` | - | 对过滤后的选项路径进行排序。 | -### Option +### 选项 | 参数 | 类型 | 默认值 | 说明 | | --------------- | ------------------------ | ------- | ------------------------------------------------ | -| children | Option[] | - | Child options. | -| disabled | boolean | false | Disable this option. | -| disableCheckbox | boolean | false | Disable this option's checkbox in multiple mode. | +| 孩子们 | 选项[] | - | 儿童选项。 | +| disabled | boolean | false | 禁用此选项。 | +| disableCheckbox | boolean | false | 在多种模式下禁用此选项的复选框。 | | label | ReactNode | - | Display label. | -| value | string \| number \| null | - | Option value. | +| 价值 | 字符串\|数字\|无效的 | - | 选项值。 | ## 本地开发 @@ -151,8 +150,8 @@ npm run compile npm run prepublishOnly ``` -The release flow is handled by `@rc-component/np` through the `rc-np` command after the package build. +包构建完成后,发布流程由 `@rc-component/np` 通过 `rc-np` 命令处理。 ## 许可证 -@rc-component/cascader is released under the [MIT](./LICENSE.md) license. +@rc-component/cascader 基于 [MIT](./LICENSE.md) 许可证发布。 From 4b96a5b37d8a99174eb51f7503491c83fb54e20a Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 01:28:36 +0800 Subject: [PATCH 13/34] chore: standardize rc tooling and docs --- .dumirc.ts | 6 +++++ .github/workflows/surge-preview.yml | 2 +- README.md | 9 ++++++- README.zh-CN.md | 9 ++++++- package.json | 42 ++++++++++++++--------------- src/OptionList/List.tsx | 12 ++++----- src/OptionList/index.tsx | 2 +- tsconfig.json | 15 ++++++++--- vercel.json | 2 +- 9 files changed, 62 insertions(+), 37 deletions(-) diff --git a/.dumirc.ts b/.dumirc.ts index 81392343..f0dcfae4 100644 --- a/.dumirc.ts +++ b/.dumirc.ts @@ -1,7 +1,13 @@ import { defineConfig } from 'dumi'; import path from 'path'; +const basePath = process.env.GH_PAGES ? '/cascader/' : '/'; +const publicPath = basePath; + export default defineConfig({ + outputPath: 'docs-dist', + base: basePath, + publicPath, alias: { 'rc-cascader$': path.resolve('src'), 'rc-cascader/es': path.resolve('src'), diff --git a/.github/workflows/surge-preview.yml b/.github/workflows/surge-preview.yml index 30f70a85..633f829c 100644 --- a/.github/workflows/surge-preview.yml +++ b/.github/workflows/surge-preview.yml @@ -27,7 +27,7 @@ jobs: with: surge_token: ${{ env.SURGE_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }} - dist: dist + dist: docs-dist failOnError: false setCommitStatus: false - name: Skip Surge preview diff --git a/README.md b/README.md index e52b266e..fe030160 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,14 @@ export default () => ( ## Examples -Visit the [online examples](https://cascader-react-component.vercel.app/) for search, multiple selection, custom field names, lazy loading, panel mode, and popup customization. +Run the local dumi site: + +```bash +npm install +npm start +``` + +Then open `http://localhost:8000`. ## API diff --git a/README.zh-CN.md b/README.zh-CN.md index e1d554ca..5302a150 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -65,7 +65,14 @@ export default () => ( ## 示例 -查看[在线示例](https://cascader-react-component.vercel.app/),了解搜索、多选、自定义字段名称、延迟加载、面板模式和弹层窗口自定义。 +运行本地 dumi 站点: + +```bash +npm install +npm start +``` + +然后打开 `http://localhost:8000`。 ## API diff --git a/package.json b/package.json index 61206614..a0b99b5b 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "compile": "father build", "coverage": "father test --coverage", "tsc": "bunx tsc --noEmit", - "deploy": "UMI_ENV=gh npm run build && gh-pages -d dist", + "deploy": "UMI_ENV=gh npm run build && gh-pages -d docs-dist", "lint": "eslint src/ examples/ tests/ --ext .tsx,.ts,.jsx,.js", "prepublishOnly": "npm run compile && rc-np", "prettier": "prettier --write --ignore-unknown .", @@ -51,34 +51,34 @@ "devDependencies": { "@rc-component/father-plugin": "^2.2.0", "@rc-component/form": "^1.4.0", - "@rc-component/np": "^1.0.3", + "@rc-component/np": "^1.0.4", "@rc-component/trigger": "^3.0.0", - "@testing-library/react": "^16.3.0", - "@types/jest": "^29.4.0", - "@types/node": "^24.5.2", - "@types/react": "^19.0.0", - "@types/react-dom": "^19.0.0", - "@types/warning": "^3.0.0", + "@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/warning": "^3.0.4", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", - "@umijs/fabric": "^4.0.0", + "@umijs/fabric": "^4.0.1", "array-tree-filter": "^3.0.2", "cheerio": "1.0.0-rc.12", "core-js": "^3.40.0", - "cross-env": "^7.0.0", - "dumi": "^2.1.10", - "eslint": "^8.54.0", + "cross-env": "^10.1.0", + "dumi": "^2.4.35", + "eslint": "^8.57.1", "eslint-plugin-jest": "^27.9.0", "eslint-plugin-unicorn": "^56.0.1", - "father": "^4.0.0", - "gh-pages": "^6.1.1", - "glob": "^7.1.6", - "less": "^4.2.0", - "prettier": "^3.1.0", - "rc-test": "^7.1.2", - "react": "^19.0.0", - "react-dom": "^19.0.0", - "typescript": "^5.3.2" + "father": "^4.6.23", + "gh-pages": "^6.3.0", + "glob": "^13.0.6", + "less": "^4.6.7", + "prettier": "^3.9.0", + "rc-test": "^7.1.3", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "typescript": "^5.9.3" }, "peerDependencies": { "react": ">=18.0.0", diff --git a/src/OptionList/List.tsx b/src/OptionList/List.tsx index e5ed46c3..fef4b20f 100644 --- a/src/OptionList/List.tsx +++ b/src/OptionList/List.tsx @@ -1,6 +1,6 @@ /* eslint-disable default-case */ import { clsx } from 'clsx'; -import type { BaseSelectProps, useBaseProps } from '@rc-component/select'; +import type { useBaseProps } from '@rc-component/select'; import * as React from 'react'; import { useMemo } from '@rc-component/util'; import type { DefaultOptionType, LegacyKey, SingleValueType } from '../Cascader'; @@ -18,12 +18,10 @@ import Column, { FIX_LABEL } from './Column'; import useActive from './useActive'; import useKeyboard from './useKeyboard'; -export type RefOptionListProps = - NonNullable['ref']> extends React.Ref< - infer Ref - > - ? Ref - : never; +export interface RefOptionListProps { + onKeyDown: React.KeyboardEventHandler; + onKeyUp: React.KeyboardEventHandler; +} export type RawOptionListProps = Pick< ReturnType, diff --git a/src/OptionList/index.tsx b/src/OptionList/index.tsx index dcba9929..c97e533e 100644 --- a/src/OptionList/index.tsx +++ b/src/OptionList/index.tsx @@ -2,7 +2,7 @@ import { useBaseProps } from '@rc-component/select'; import * as React from 'react'; import RawOptionList, { type RefOptionListProps } from './List'; -const RefOptionList = React.forwardRef((props, ref) => { +const RefOptionList = React.forwardRef>((props, ref) => { const { lockOptions, ...baseProps } = useBaseProps(); // >>>>> Render diff --git a/tsconfig.json b/tsconfig.json index 299bbc7e..2b912c63 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,9 +9,16 @@ "strict": true, "esModuleInterop": true, "paths": { - "@/*": ["src/*"], - "@@/*": ["src/.umi/*"], - "@rc-component/cascader": ["src/index.ts"] - } + "@/*": [ + "src/*" + ], + "@@/*": [ + "src/.umi/*" + ], + "@rc-component/cascader": [ + "src/index.ts" + ] + }, + "ignoreDeprecations": "5.0" } } diff --git a/vercel.json b/vercel.json index e884e1b3..5f9139ef 100644 --- a/vercel.json +++ b/vercel.json @@ -2,5 +2,5 @@ "framework": "umijs", "installCommand": "npm install", "buildCommand": "npm run build", - "outputDirectory": "dist" + "outputDirectory": "docs-dist" } From 4649dec010a72c40874e05748eb3f99989d08d77 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 02:01:03 +0800 Subject: [PATCH 14/34] chore: address standardization review comments --- .github/workflows/surge-preview.yml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/surge-preview.yml b/.github/workflows/surge-preview.yml index 633f829c..50782cc0 100644 --- a/.github/workflows/surge-preview.yml +++ b/.github/workflows/surge-preview.yml @@ -15,13 +15,23 @@ jobs: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 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: ${{ secrets.SURGE_TOKEN != '' }} + if: ${{ steps.surge-token.outputs.enabled == 'true' }} run: | npm install npm run build - uses: afc163/surge-preview@bf90a5a86111f6311ca42f0a5a0f80fb0fb03cec - if: ${{ secrets.SURGE_TOKEN != '' }} + if: ${{ steps.surge-token.outputs.enabled == 'true' }} env: SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }} with: @@ -31,5 +41,5 @@ jobs: failOnError: false setCommitStatus: false - name: Skip Surge preview - if: ${{ secrets.SURGE_TOKEN == '' }} + if: ${{ steps.surge-token.outputs.enabled != 'true' }} run: echo "SURGE_TOKEN is not configured; skip Surge preview." From c996caf8c779a073be6e066366292a1d606a5b21 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 12:23:32 +0800 Subject: [PATCH 15/34] ci: update GitHub Actions versions --- .github/workflows/codeql.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 22e7257d..3c681949 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -29,15 +29,15 @@ jobs: persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e + uses: github/codeql-action/init@a0853c24544627f65ddf259abe73b1d18a591444 with: languages: ${{ matrix.language }} queries: +security-and-quality - name: Autobuild - uses: github/codeql-action/autobuild@8aad20d150bbac5944a9f9d289da16a4b0d87c1e + uses: github/codeql-action/autobuild@a0853c24544627f65ddf259abe73b1d18a591444 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e + uses: github/codeql-action/analyze@a0853c24544627f65ddf259abe73b1d18a591444 with: category: "/language:${{ matrix.language }}" From a111888f2287da7fddd7a1370f642c4679f1c1bf Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 12:27:17 +0800 Subject: [PATCH 16/34] ci: use resolvable CodeQL action ref --- .github/workflows/codeql.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3c681949..22e7257d 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -29,15 +29,15 @@ jobs: persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@a0853c24544627f65ddf259abe73b1d18a591444 + uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e with: languages: ${{ matrix.language }} queries: +security-and-quality - name: Autobuild - uses: github/codeql-action/autobuild@a0853c24544627f65ddf259abe73b1d18a591444 + uses: github/codeql-action/autobuild@8aad20d150bbac5944a9f9d289da16a4b0d87c1e - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@a0853c24544627f65ddf259abe73b1d18a591444 + uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e with: category: "/language:${{ matrix.language }}" From 391d33e519c0578b4d6d1ce88b45b15d0f81470b Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 13:14:23 +0800 Subject: [PATCH 17/34] chore: ignore dumi build output --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2565182b..cbe08662 100644 --- a/.gitignore +++ b/.gitignore @@ -38,7 +38,8 @@ coverage # dumi .dumi/tmp .dumi/tmp-production +docs-dist dist .vscode -bun.lockb \ No newline at end of file +bun.lockb From d8fc6e9da5847903cc961a6de49a2295f3cce1b8 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 13:26:49 +0800 Subject: [PATCH 18/34] docs: add license file --- LICENSE | 21 +++++++++++++++++++++ README.md | 2 +- README.zh-CN.md | 2 +- 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 LICENSE 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 fe030160..3ba18562 100644 --- a/README.md +++ b/README.md @@ -161,4 +161,4 @@ The release flow is handled by `@rc-component/np` through the `rc-np` command af ## License -@rc-component/cascader is released under the [MIT](./LICENSE.md) license. +@rc-component/cascader is released under the [MIT](./LICENSE) license. diff --git a/README.zh-CN.md b/README.zh-CN.md index 5302a150..a230f245 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -161,4 +161,4 @@ npm run prepublishOnly ## 许可证 -@rc-component/cascader 基于 [MIT](./LICENSE.md) 许可证发布。 +@rc-component/cascader 基于 [MIT](./LICENSE) 许可证发布。 From e5d663ef56889af5586e081ab7aac26ce4eab0bc Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 13:59:19 +0800 Subject: [PATCH 19/34] ci: use actions checkout v7 --- .github/workflows/codeql.yml | 2 +- .github/workflows/react-doctor.yml | 2 +- .github/workflows/surge-preview.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 22e7257d..65d90eac 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -24,7 +24,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 + uses: actions/checkout@v7 with: persist-credentials: false diff --git a/.github/workflows/react-doctor.yml b/.github/workflows/react-doctor.yml index f820dc07..01760580 100644 --- a/.github/workflows/react-doctor.yml +++ b/.github/workflows/react-doctor.yml @@ -19,7 +19,7 @@ jobs: react-doctor: runs-on: ubuntu-latest steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 + - uses: actions/checkout@v7 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/surge-preview.yml b/.github/workflows/surge-preview.yml index 50782cc0..ef5a81d8 100644 --- a/.github/workflows/surge-preview.yml +++ b/.github/workflows/surge-preview.yml @@ -12,7 +12,7 @@ jobs: preview: runs-on: ubuntu-latest steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 + - uses: actions/checkout@v7 with: persist-credentials: false - name: Check Surge token From be57d3673cb91c403ce276fe82f3a6a35ccec988 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 14:29:42 +0800 Subject: [PATCH 20/34] chore: standardize package metadata --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index a0b99b5b..9ba8f2f5 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "cascade", "cascader" ], - "homepage": "https://github.com/react-component/cascader", + "homepage": "https://react-component.github.io/cascader", "bugs": { "url": "https://github.com/react-component/cascader/issues" }, @@ -83,5 +83,8 @@ "peerDependencies": { "react": ">=18.0.0", "react-dom": ">=18.0.0" + }, + "publishConfig": { + "access": "public" } } From c376d0bf82df849d2fcbb0b0824521920964956d Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 14:36:10 +0800 Subject: [PATCH 21/34] ci: standardize dependabot updates --- .github/dependabot.yml | 52 ++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 35 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index a5cb97ff..3b730ef9 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,37 +1,19 @@ version: 2 updates: -- package-ecosystem: npm - directory: "/" - schedule: - interval: daily - time: "21:00" - open-pull-requests-limit: 10 - ignore: - - dependency-name: np - versions: - - 7.2.0 - - 7.3.0 - - 7.4.0 - - dependency-name: "@types/react" - versions: - - 17.0.0 - - 17.0.1 - - 17.0.2 - - 17.0.3 - - dependency-name: "@types/jest" - versions: - - 26.0.20 - - 26.0.21 - - 26.0.22 - - dependency-name: "@types/react-dom" - versions: - - 17.0.0 - - 17.0.1 - - 17.0.2 - - dependency-name: typescript - versions: - - 4.1.3 - - 4.1.4 - - 4.1.5 - - 4.2.2 - - 4.2.3 + - 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 From 0828de0725b9194b3f6d73d6df65e4180ec3be9c Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 16:08:04 +0800 Subject: [PATCH 22/34] docs: localize Chinese README labels --- README.zh-CN.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.zh-CN.md b/README.zh-CN.md index a230f245..65257ec1 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -21,10 +21,10 @@ | 范围 | 支持 | | --------- | ---------------------------------------------------------------- | | 数据 | 嵌套选项、字段名映射和禁用节点 | -| Selection | 单选、多选、勾选和逐级选择流程 | +| 选择 | 单选、多选、勾选和逐级选择流程 | | 搜索 | 受控搜索、自定义过滤、自定义排序和自定义渲染 | -| Loading | 通过 `loadData` 异步加载选项 | -| Rendering | 自定义选项标签、下拉内容、图标和展开触发方式 | +| 加载 | 通过 `loadData` 异步加载选项 | +| 渲染 | 自定义选项标签、下拉内容、图标和展开触发方式 | ## 安装 From 41d98af82ac778c2bcbf7a249300b7d526448108 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 16:23:30 +0800 Subject: [PATCH 23/34] docs: fix Chinese README API names --- README.zh-CN.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README.zh-CN.md b/README.zh-CN.md index 65257ec1..2b868dc1 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -84,9 +84,9 @@ npm start | builtinPlacements | BuildInPlacements | - | 自定义弹层位置。 | | changeOnSelect | boolean | false | 选择每个级别时触发 `onChange`。 | | checkable | boolean \| ReactNode | false | 启用带复选框 UI 的多选。 | -| 孩子们 | ReactElement | - | 触发元素。 | -| classNames | 语义className映射 | - | 选择器和弹层元素的语义className称。 | -| defaultValue | 字符串[] \|数字[] \|数组<字符串[] \|数字[]> | - | 初始选中值。 | +| children | ReactElement | - | 触发元素。 | +| classNames | Semantic class name map | - | 选择器和弹层元素的语义className称。 | +| defaultValue | string[] \| number[] \| Array | - | 初始选中值。 | | displayRender | `(label, selectedOptions) => ReactNode` | - | 渲染选定的标签。 | | expandIcon | ReactNode | `>` | 自定义展开图标。 | | expandTrigger | `click` \| `hover` | `click` | 触发扩展下一个选项级别的操作。 | @@ -96,18 +96,18 @@ npm start | onChange | `(value, selectedOptions) => void` | - | 选择更改时调用。 | | onPopupVisibleChange | `(open: boolean) => void` | - | 当弹层窗口可见性发生变化时调用。 | | onSearch | `(value: string) => void` | - | 已弃用。请改用 `showSearch.onSearch`。 | -| 打开 | boolean | - | 受控的弹层窗口可见性。 | +| open | boolean | - | 受控的弹层窗口可见性。 | | optionRender | `(option) => ReactNode` | - | 自定义选项渲染器。 | -| 选项 | 选项[] | - | 分层选项数据。 | -| placement | 选择展示位置 | - | 弹层窗口放置。 | +| options | Option[] | - | 分层选项数据。 | +| placement | Select placement | - | 弹层窗口放置。 | | popupClassName | string | - | 弹层className。 | | popupMenuColumnStyle | CSSProperties | - | 每个弹出菜单列的样式。 | | prefixCls | string | `rc-cascader` | className前缀。 | | searchValue | string | - | 已弃用。请改用 `showSearch.searchValue`。 | | showCheckedStrategy | `SHOW_PARENT` \| `SHOW_CHILD` | `SHOW_PARENT` | 在多种模式下渲染检查值的策略。 | | showSearch | boolean \| SearchConfig | false | 启用并配置搜索。 | -| styles | 语义风格图 | - | 选择器和弹层元素的语义样式。 | -| 价值 | 字符串[] \|数字[] \|数组<字符串[] \|数字[]> | - | 受控选中值。 | +| styles | Semantic style map | - | 选择器和弹层元素的语义样式。 | +| value | string[] \| number[] \| Array | - | 受控选中值。 | `Cascader` 还接受来自 `@rc-component/select` `BaseSelect` 的公共属性,但私有仅选择属性除外,例如 `mode` 、 `labelInValue` 、 `showSearch` 和 `tokenSeparators`。 @@ -116,23 +116,23 @@ npm start | 参数 | 类型 | 默认值 | 说明 | | -------------------- | -------------------------------------------------------- | ------- | ---------------------------------------------------------- | | autoClearSearchValue | boolean | true | 选择项目后清除搜索文本。 | -| 筛选 | `(inputValue, options, fieldNames) => boolean` | - | 返回 `true` 以在搜索结果中包含选项路径。 | +| filter | `(inputValue, options, fieldNames) => boolean` | - | 返回 `true` 以在搜索结果中包含选项路径。 | | limit | number \| false | 50 | 限制过滤项目的数量。 | | matchInputWidth | boolean | true | 搜索结果宽度是否与输入宽度匹配。 | | onSearch | `(value: string) => void` | - | 当搜索文本更改时调用。 | -| 使成为 | `(inputValue, path, prefixCls, fieldNames) => ReactNode` | - | 渲染过滤后的选项路径。 | +| render | `(inputValue, path, prefixCls, fieldNames) => ReactNode` | - | 渲染过滤后的选项路径。 | | searchValue | string | - | 受控搜索文本。 | -| 种类 | `(a, b, inputValue, fieldNames) => number` | - | 对过滤后的选项路径进行排序。 | +| sort | `(a, b, inputValue, fieldNames) => number` | - | 对过滤后的选项路径进行排序。 | ### 选项 | 参数 | 类型 | 默认值 | 说明 | | --------------- | ------------------------ | ------- | ------------------------------------------------ | -| 孩子们 | 选项[] | - | 儿童选项。 | +| children | Option[] | - | 儿童选项。 | | disabled | boolean | false | 禁用此选项。 | | disableCheckbox | boolean | false | 在多种模式下禁用此选项的复选框。 | | label | ReactNode | - | Display label. | -| 价值 | 字符串\|数字\|无效的 | - | 选项值。 | +| value | string \| number \| null | - | 选项值。 | ## 本地开发 From 9448dcb577ca2266af1cbfd082fa1ed8a5db8f8c Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 17:14:13 +0800 Subject: [PATCH 24/34] chore: refine preview workflow ignores --- .github/workflows/surge-preview.yml | 3 +++ .prettierignore | 14 ++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 .prettierignore diff --git a/.github/workflows/surge-preview.yml b/.github/workflows/surge-preview.yml index ef5a81d8..394f2b02 100644 --- a/.github/workflows/surge-preview.yml +++ b/.github/workflows/surge-preview.yml @@ -11,6 +11,9 @@ permissions: jobs: preview: runs-on: ubuntu-latest + concurrency: + group: surge-preview-${{ github.event.pull_request.number }} + cancel-in-progress: true steps: - uses: actions/checkout@v7 with: 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 From 6d051cee63a9468f25b456371e1fd0d72eb2ef27 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 17:35:25 +0800 Subject: [PATCH 25/34] docs: polish Chinese README wording --- README.zh-CN.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.zh-CN.md b/README.zh-CN.md index 2b868dc1..d325b9a8 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -85,7 +85,7 @@ npm start | changeOnSelect | boolean | false | 选择每个级别时触发 `onChange`。 | | checkable | boolean \| ReactNode | false | 启用带复选框 UI 的多选。 | | children | ReactElement | - | 触发元素。 | -| classNames | Semantic class name map | - | 选择器和弹层元素的语义className称。 | +| classNames | Semantic class name map | - | 选择器和弹层元素的语义 className。 | | defaultValue | string[] \| number[] \| Array | - | 初始选中值。 | | displayRender | `(label, selectedOptions) => ReactNode` | - | 渲染选定的标签。 | | expandIcon | ReactNode | `>` | 自定义展开图标。 | @@ -100,9 +100,9 @@ npm start | optionRender | `(option) => ReactNode` | - | 自定义选项渲染器。 | | options | Option[] | - | 分层选项数据。 | | placement | Select placement | - | 弹层窗口放置。 | -| popupClassName | string | - | 弹层className。 | +| popupClassName | string | - | 弹层 className。 | | popupMenuColumnStyle | CSSProperties | - | 每个弹出菜单列的样式。 | -| prefixCls | string | `rc-cascader` | className前缀。 | +| prefixCls | string | `rc-cascader` | className 前缀。 | | searchValue | string | - | 已弃用。请改用 `showSearch.searchValue`。 | | showCheckedStrategy | `SHOW_PARENT` \| `SHOW_CHILD` | `SHOW_PARENT` | 在多种模式下渲染检查值的策略。 | | showSearch | boolean \| SearchConfig | false | 启用并配置搜索。 | From 5d0c8f9ac1f1cf77a32728188da2809753f07d5e Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 18:26:51 +0800 Subject: [PATCH 26/34] docs: fix Chinese README wording --- README.zh-CN.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.zh-CN.md b/README.zh-CN.md index d325b9a8..49e29e3e 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -124,14 +124,14 @@ npm start | searchValue | string | - | 受控搜索文本。 | | sort | `(a, b, inputValue, fieldNames) => number` | - | 对过滤后的选项路径进行排序。 | -### 选项 +### 选项 | 参数 | 类型 | 默认值 | 说明 | | --------------- | ------------------------ | ------- | ------------------------------------------------ | -| children | Option[] | - | 儿童选项。 | +| children | Option[] | - | 子选项。 | | disabled | boolean | false | 禁用此选项。 | | disableCheckbox | boolean | false | 在多种模式下禁用此选项的复选框。 | -| label | ReactNode | - | Display label. | +| label | ReactNode | - | 显示标签。 | | value | string \| number \| null | - | 选项值。 | ## 本地开发 From b4cd1a097728108a438aaeb6f9e021b4583523f0 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 18:53:21 +0800 Subject: [PATCH 27/34] chore: align package scripts --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9ba8f2f5..f14e2d1a 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "build": "dumi build", "compile": "father build", "coverage": "father test --coverage", - "tsc": "bunx tsc --noEmit", + "tsc": "tsc --noEmit", "deploy": "UMI_ENV=gh npm run build && gh-pages -d docs-dist", "lint": "eslint src/ examples/ tests/ --ext .tsx,.ts,.jsx,.js", "prepublishOnly": "npm run compile && rc-np", From 7572083da1e478efe59694e775ad5720f7de1129 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 19:13:04 +0800 Subject: [PATCH 28/34] chore: add father config --- .fatherrc.ts | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .fatherrc.ts diff --git a/.fatherrc.ts b/.fatherrc.ts new file mode 100644 index 00000000..96268ae1 --- /dev/null +++ b/.fatherrc.ts @@ -0,0 +1,5 @@ +import { defineConfig } from 'father'; + +export default defineConfig({ + plugins: ['@rc-component/father-plugin'], +}); From 7cc296093048085380edaf9c527916fa663cd0f4 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 19:37:36 +0800 Subject: [PATCH 29/34] docs: document dumi dev server port --- README.md | 2 ++ README.zh-CN.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 3ba18562..bd393a23 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,8 @@ npm install npm start ``` +The dumi site runs at `http://localhost:8000` by default. + Common commands: ```bash diff --git a/README.zh-CN.md b/README.zh-CN.md index 49e29e3e..c94208fc 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -141,6 +141,8 @@ npm install npm start ``` +dumi 站点默认运行在 `http://localhost:8000`。 + Common commands: ```bash From 5bf52486bde2c2c91c1d42f49ae9a0be6363fc16 Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 19:56:39 +0800 Subject: [PATCH 30/34] chore: standardize husky configuration --- .husky/pre-commit | 1 + package.json | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100755 .husky/pre-commit 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/package.json b/package.json index f14e2d1a..2c264df5 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,8 @@ "prettier": "prettier --write --ignore-unknown .", "lint:tsc": "tsc -p tsconfig.json --noEmit", "start": "dumi dev", - "test": "rc-test" + "test": "rc-test", + "prepare": "husky" }, "dependencies": { "@rc-component/select": "~1.8.0", @@ -78,7 +79,9 @@ "rc-test": "^7.1.3", "react": "^18.3.1", "react-dom": "^18.3.1", - "typescript": "^5.9.3" + "typescript": "^5.9.3", + "husky": "^9.1.7", + "lint-staged": "^16.4.0" }, "peerDependencies": { "react": ">=18.0.0", @@ -86,5 +89,8 @@ }, "publishConfig": { "access": "public" + }, + "lint-staged": { + "*": "prettier --write --ignore-unknown" } } From be4e46a7c72249a519ab3c6e44d9202bc5e6e1ae Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 20:31:14 +0800 Subject: [PATCH 31/34] chore: standardize package type entry --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 2c264df5..5b6f0ea2 100644 --- a/package.json +++ b/package.json @@ -92,5 +92,6 @@ }, "lint-staged": { "*": "prettier --write --ignore-unknown" - } + }, + "types": "./es/index.d.ts" } From ffc97aaeb417caf658f8873568c840525cdddc5d Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 21:18:52 +0800 Subject: [PATCH 32/34] ci: limit reusable workflow secrets --- .github/workflows/main.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f8482b63..75e70549 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,10 @@ name: ✅ test on: [push, pull_request] +permissions: + contents: read jobs: test: uses: react-component/rc-test/.github/workflows/test-utoo.yml@main - secrets: inherit + secrets: + + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From 2834c635581b5bb0b30ef8fcc4bda6f693833e8f Mon Sep 17 00:00:00 2001 From: afc163 Date: Sun, 28 Jun 2026 21:29:24 +0800 Subject: [PATCH 33/34] ci: restore reusable workflow compatibility --- .github/workflows/main.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 75e70549..9503b960 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,6 +5,4 @@ permissions: jobs: test: uses: react-component/rc-test/.github/workflows/test-utoo.yml@main - secrets: - - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + secrets: inherit From 10bf0d3050261ca3b456f33c92c8288712c589d9 Mon Sep 17 00:00:00 2001 From: afc163 Date: Mon, 29 Jun 2026 14:24:04 +0800 Subject: [PATCH 34/34] chore: limit reusable workflow secrets --- .github/workflows/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9503b960..8d135ed5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,4 +5,5 @@ permissions: jobs: test: uses: react-component/rc-test/.github/workflows/test-utoo.yml@main - secrets: inherit + secrets: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file