1
This commit is contained in:
+83
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"3.9.3": [
|
||||
"https://github.com/ant-design/ant-design/commit/6550df34b639ab0b3bf2c1cbf9b9828735c1fd41"
|
||||
],
|
||||
">= 3.10.0 <=3.10.9": [
|
||||
"https://github.com/ant-design/ant-design/commit/6550df34b639ab0b3bf2c1cbf9b9828735c1fd41"
|
||||
],
|
||||
">= 3.11.0 <=3.11.5": [
|
||||
"https://github.com/ant-design/ant-design/commit/6550df34b639ab0b3bf2c1cbf9b9828735c1fd41"
|
||||
],
|
||||
">= 4.21.6 < 4.22.0": ["https://github.com/ant-design/ant-design/pull/36682"],
|
||||
">= 4.22.2 <= 4.22.5": [
|
||||
"https://github.com/ant-design/ant-design/issues/36932",
|
||||
"https://github.com/ant-design/ant-design/pull/36800",
|
||||
"https://github.com/ant-design/ant-design/issues/37024"
|
||||
],
|
||||
"4.23.0": ["https://github.com/ant-design/ant-design/issues/37461"],
|
||||
"4.23.5": [
|
||||
"https://github.com/ant-design/ant-design/issues/37929",
|
||||
"https://github.com/ant-design/ant-design/issues/37931"
|
||||
],
|
||||
"4.24.0": ["https://github.com/ant-design/ant-design/issues/38371"],
|
||||
"5.0.4": ["https://github.com/ant-design/ant-design/issues/39284"],
|
||||
"5.0.6": ["https://github.com/ant-design/ant-design/issues/39807"],
|
||||
"5.1.0": ["https://github.com/react-component/drawer/pull/370"],
|
||||
"5.1.2": ["https://github.com/ant-design/ant-design/issues/39949"],
|
||||
"5.1.3": ["https://github.com/ant-design/ant-design/issues/40113"],
|
||||
"5.1.4": ["https://github.com/ant-design/ant-design/issues/40186"],
|
||||
">= 5.2.3 <= 5.3.0": [
|
||||
"https://github.com/ant-design/ant-design/pull/40719#issuecomment-1453418135"
|
||||
],
|
||||
"5.4.1": ["https://github.com/ant-design/ant-design/issues/41751"],
|
||||
">= 5.4.3 <= 5.4.5": [
|
||||
"https://github.com/ant-design/cssinjs/pull/108",
|
||||
"https://github.com/ant-design/ant-design/pull/41993"
|
||||
],
|
||||
"5.6.2": ["https://github.com/ant-design/ant-design/issues/43113"],
|
||||
"5.6.3": ["https://github.com/ant-design/ant-design/issues/43190"],
|
||||
"5.7.0": ["https://github.com/ant-design/ant-design/issues/43684"],
|
||||
"5.7.1": [
|
||||
"https://github.com/ant-design/ant-design/issues/43654",
|
||||
"https://github.com/ant-design/ant-design/issues/43684"
|
||||
],
|
||||
"5.8.0": ["https://github.com/ant-design/ant-design/issues/43943"],
|
||||
"5.9.1": ["https://github.com/ant-design/ant-design/issues/44907"],
|
||||
"5.10.0": ["https://github.com/ant-design/ant-design/issues/45289"],
|
||||
"5.11.0": ["https://github.com/ant-design/ant-design/issues/45742"],
|
||||
"5.11.1": ["https://github.com/ant-design/ant-design/issues/45883"],
|
||||
"5.11.2": ["https://github.com/ant-design/ant-design/issues/46005"],
|
||||
"5.11.4": ["https://github.com/ant-design/ant-design/pull/46103"],
|
||||
"5.12.3": ["https://github.com/ant-design/ant-design/issues/46525"],
|
||||
"5.12.6": ["https://github.com/ant-design/ant-design/issues/46719"],
|
||||
"5.13.0": ["https://github.com/ant-design/ant-design/pull/46962"],
|
||||
"5.14.0": ["https://github.com/ant-design/ant-design/issues/47354"],
|
||||
"5.15.0": ["https://github.com/ant-design/ant-design/pull/47504#issuecomment-1980459433"],
|
||||
">= 5.16.0 <= 5.16.1": ["https://github.com/ant-design/ant-design/issues/48200"],
|
||||
"5.16.3": ["https://github.com/ant-design/ant-design/issues/48568"],
|
||||
"5.17.1": ["https://github.com/ant-design/ant-design/issues/48913"],
|
||||
"5.18.2": ["https://github.com/ant-design/ant-design/pull/49487"],
|
||||
"5.20.4": ["https://github.com/ant-design/ant-design/issues/50687"],
|
||||
"5.21.0": [
|
||||
"https://github.com/ant-design/ant-design/issues/50960",
|
||||
"https://github.com/ant-design/ant-design/issues/50969"
|
||||
],
|
||||
"5.21.6": [
|
||||
"https://github.com/ant-design/ant-design/issues/51420",
|
||||
"https://github.com/ant-design/ant-design/issues/51430"
|
||||
],
|
||||
"5.22.0": [
|
||||
"https://github.com/ant-design/ant-design/issues/51601",
|
||||
"https://github.com/ant-design/ant-design/issues/51420",
|
||||
"https://github.com/ant-design/ant-design/issues/51430"
|
||||
],
|
||||
"5.22.1": [
|
||||
"https://github.com/ant-design/ant-design/issues/51420",
|
||||
"https://github.com/ant-design/ant-design/issues/51430"
|
||||
],
|
||||
"5.22.6": ["https://github.com/ant-design/ant-design/issues/52124"],
|
||||
"5.24.8": ["https://github.com/ant-design/ant-design/issues/53652"],
|
||||
"5.25.0": ["https://github.com/ant-design/ant-design/issues/53764"],
|
||||
">= 5.28.1 <= 5.29.0": ["https://github.com/ant-design/ant-design/issues/55755"],
|
||||
"6.3.0": ["https://github.com/ant-design/ant-design/pull/56946"]
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
MIT LICENSE
|
||||
|
||||
Copyright (c) 2015-present Ant UED, https://xtech.antfin.com/
|
||||
|
||||
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.
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
<div align="center"><a name="readme-top"></a>
|
||||
|
||||
<img height="180" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg">
|
||||
|
||||
<h1>Ant Design</h1>
|
||||
|
||||
An enterprise-class UI design language and React UI library.
|
||||
|
||||
[![CI status][github-action-image]][github-action-url] [![codecov][codecov-image]][codecov-url] [![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url] [![][bundlephobia-image]][bundlephobia-url] [![][jsdelivr-image]][jsdelivr-url]
|
||||
|
||||
[![Follow Twitter][twitter-image]][twitter-url] [![dumi][dumi-image]][dumi-url] [![FOSSA Status][fossa-image]][fossa-url] [![Issues need help][help-wanted-image]][help-wanted-url] [![LFX Active Contributors][lfx-image]][lfx-url]
|
||||
|
||||
[Changelog](./CHANGELOG.en-US.md) · [Report Bug][github-issues-url] · [Request Feature][github-issues-url] · English · [中文](./README-zh_CN.md)
|
||||
|
||||
## ❤️ Sponsors [](https://opencollective.com/ant-design/contribute/sponsors-218)
|
||||
|
||||
| <a href="https://youmind.com?utm_source=ant-design"><img src="https://mdn.alipayobjects.com/huamei_vmgq1x/afts/img/A*SXcuQYBZ6oQAAAAAQJAAAAgAeh6VAQ/original" width="80" alt="YouMind"></a> | <a href="https://tractian.com?utm_source=ant-design"><img src="https://mdn.alipayobjects.com/huamei_vmgq1x/afts/img/A*Z4-4Q67SG5UAAAAAQLAAAAgAeh6VAQ/original" width="80" alt="TRACTIAN"></a> | <a href="https://lobehub.com?utm_source=ant-design"><img src="https://unpkg.com/@lobehub/icons-static-svg@1.79.0/icons/lobehub-color.svg" width="80" alt="LobeHub"></a> |
|
||||
| :-: | :-: | :-: |
|
||||
|
||||
[npm-image]: https://img.shields.io/npm/v/antd.svg?style=flat-square
|
||||
[npm-url]: https://npmjs.org/package/antd
|
||||
[github-action-image]: https://github.com/ant-design/ant-design/actions/workflows/test.yml/badge.svg
|
||||
[github-action-url]: https://github.com/ant-design/ant-design/actions/workflows/test.yml
|
||||
[codecov-image]: https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square
|
||||
[codecov-url]: https://codecov.io/gh/ant-design/ant-design/branch/master
|
||||
[download-image]: https://img.shields.io/npm/dm/antd.svg?style=flat-square
|
||||
[download-url]: https://npmjs.org/package/antd
|
||||
[fossa-image]: https://app.fossa.io/api/projects/git%2Bgithub.com%2Fant-design%2Fant-design.svg?type=shield
|
||||
[fossa-url]: https://app.fossa.io/projects/git%2Bgithub.com%2Fant-design%2Fant-design?ref=badge_shield
|
||||
[help-wanted-image]: https://img.shields.io/github/issues/ant-design/ant-design/help%20wanted?color=green&style=flat-square
|
||||
[help-wanted-url]: https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22
|
||||
[twitter-image]: https://img.shields.io/twitter/follow/AntDesignUI.svg?label=Ant%20Design
|
||||
[twitter-url]: https://twitter.com/AntDesignUI
|
||||
[jsdelivr-image]: https://data.jsdelivr.com/v1/package/npm/antd/badge
|
||||
[jsdelivr-url]: https://www.jsdelivr.com/package/npm/antd
|
||||
[bundlephobia-image]: https://img.shields.io/bundlephobia/minzip/antd?style=flat-square
|
||||
[bundlephobia-url]: https://bundlephobia.com/package/antd
|
||||
[dumi-image]: https://img.shields.io/badge/docs%20by-dumi-blue?style=flat-square
|
||||
[dumi-url]: https://github.com/umijs/dumi
|
||||
[github-issues-url]: https://new-issue.ant.design
|
||||
[lfx-image]: https://insights.linuxfoundation.org/api/badge/active-contributors?project=ant-design-ant-design&repos=https://github.com/ant-design/ant-design
|
||||
[lfx-url]: https://insights.linuxfoundation.org/project/ant-design-ant-design/repository/ant-design-ant-design
|
||||
|
||||
</div>
|
||||
|
||||
[](https://ant.design)
|
||||
|
||||
## ✨ Features
|
||||
|
||||
- 🌈 Enterprise-class UI designed for web applications.
|
||||
- 📦 A set of high-quality React components out of the box.
|
||||
- 🛡 Written in TypeScript with predictable static types.
|
||||
- ⚙️ Whole package of design resources and development tools.
|
||||
- 🌍 Internationalization support for dozens of languages.
|
||||
- 🎨 Powerful theme customization based on CSS-in-JS.
|
||||
|
||||
## 🖥 Environment Support
|
||||
|
||||
- Modern browsers
|
||||
- Server-side Rendering
|
||||
- [Electron](https://www.electronjs.org/)
|
||||
|
||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="Edge" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)<br>Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)<br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)<br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)<br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/electron/electron_48x48.png" alt="Electron" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)<br>Electron |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
|
||||
## 📦 Install
|
||||
|
||||
```bash
|
||||
npm install antd
|
||||
```
|
||||
|
||||
```bash
|
||||
yarn add antd
|
||||
```
|
||||
|
||||
```bash
|
||||
pnpm add antd
|
||||
```
|
||||
|
||||
```bash
|
||||
bun add antd
|
||||
```
|
||||
|
||||
## 🔨 Usage
|
||||
|
||||
```tsx
|
||||
import { Button, DatePicker } from 'antd';
|
||||
|
||||
export default () => (
|
||||
<>
|
||||
<Button type="primary">PRESS ME</Button>
|
||||
<DatePicker placeholder="select date" />
|
||||
</>
|
||||
);
|
||||
```
|
||||
|
||||
## 🔗 Links
|
||||
|
||||
- [Home page](https://ant.design/)
|
||||
- [Components Overview](https://ant.design/components/overview)
|
||||
- [Sponsor](https://ant.design/docs/react/sponsor)
|
||||
- [Change Log](CHANGELOG.en-US.md)
|
||||
- [rc-components](https://react-component.github.io/)
|
||||
- [🆕 Ant Design X](https://x.ant.design/index-cn)
|
||||
- [Ant Design Pro](https://pro.ant.design/)
|
||||
- [Pro Components](https://procomponents.ant.design)
|
||||
- [Ant Design Mobile](https://mobile.ant.design)
|
||||
- [Ant Design Mini](https://mini.ant.design)
|
||||
- [Ant Design Charts](https://charts.ant.design)
|
||||
- [Ant Design Web3](https://web3.ant.design)
|
||||
- [Landing Pages](https://landing.ant.design)
|
||||
- [Ant Motion](https://motion.ant.design)
|
||||
- [Scaffold Market](https://scaffold.ant.design)
|
||||
- [Developer Instruction](https://github.com/ant-design/ant-design/wiki/Development)
|
||||
- [Versioning Release Note](https://github.com/ant-design/ant-design/wiki/%E8%BD%AE%E5%80%BC%E8%A7%84%E5%88%99%E5%92%8C%E7%89%88%E6%9C%AC%E5%8F%91%E5%B8%83%E6%B5%81%E7%A8%8B)
|
||||
- [FAQ](https://ant.design/docs/react/faq)
|
||||
- [Online Playground](https://u.ant.design/reproduce) for bug reports
|
||||
- [Customize Theme](https://ant.design/docs/react/customize-theme)
|
||||
- [How to Apply for Being A Collaborator](https://github.com/ant-design/ant-design/wiki/Collaborators#how-to-apply-for-being-a-collaborator)
|
||||
|
||||
## ⌨️ Development
|
||||
|
||||
Use [opensumi.run](https://opensumi.run), a free online pure front-end dev environment.
|
||||
|
||||
[](https://opensumi.run/ide/ant-design/ant-design)
|
||||
|
||||
Or clone locally:
|
||||
|
||||
```bash
|
||||
$ git clone git@github.com:ant-design/ant-design.git
|
||||
$ cd ant-design
|
||||
$ npm install
|
||||
$ npm start
|
||||
```
|
||||
|
||||
Open your browser and visit http://127.0.0.1:8001, see more at [Development](https://github.com/ant-design/ant-design/wiki/Development).
|
||||
|
||||
## 🤝 Contributing [](https://makeapullrequest.com)
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://next.ossinsight.io/widgets/official/compose-recent-top-contributors?repo_id=34526884" target="_blank" style="display: block" align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-recent-top-contributors/thumbnail.png?repo_id=34526884&image_size=auto&color_scheme=dark" width="280">
|
||||
<img alt="Top Contributors of ant-design/ant-design - Last 28 days" src="https://next.ossinsight.io/widgets/official/compose-recent-top-contributors/thumbnail.png?repo_id=34526884&image_size=auto&color_scheme=light" width="280">
|
||||
</picture>
|
||||
</a>
|
||||
</td>
|
||||
<td rowspan="2">
|
||||
<a href="https://next.ossinsight.io/widgets/official/compose-last-28-days-stats?repo_id=34526884" target="_blank" style="display: block" align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-last-28-days-stats/thumbnail.png?repo_id=34526884&image_size=auto&color_scheme=dark" width="655" height="auto">
|
||||
<img alt="Performance Stats of ant-design/ant-design - Last 28 days" src="https://next.ossinsight.io/widgets/official/compose-last-28-days-stats/thumbnail.png?repo_id=34526884&image_size=auto&color_scheme=light" width="655" height="auto">
|
||||
</picture>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://next.ossinsight.io/widgets/official/compose-org-active-contributors?period=past_28_days&activity=new&owner_id=12101536&repo_ids=34526884" target="_blank" style="display: block" align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-org-active-contributors/thumbnail.png?period=past_28_days&activity=new&owner_id=12101536&repo_ids=34526884&image_size=2x3&color_scheme=dark" width="273" height="auto">
|
||||
<img alt="New participants of ant-design - past 28 days" src="https://next.ossinsight.io/widgets/official/compose-org-active-contributors/thumbnail.png?period=past_28_days&activity=new&owner_id=12101536&repo_ids=34526884&image_size=2x3&color_scheme=light" width="273" height="auto">
|
||||
</picture>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<a href="https://openomy.app/github/ant-design/ant-design" target="_blank" style="display: block; width: 100%;" align="center">
|
||||
<img src="https://openomy.app/svg?repo=ant-design/ant-design&chart=bubble&latestMonth=3" target="_blank" alt="Contribution Leaderboard" style="display: block; width: 100%;" />
|
||||
</a>
|
||||
|
||||
Let's build a better antd together.
|
||||
|
||||
We warmly invite contributions from everyone. Before you get started, please take a moment to review our [Contribution Guide](https://ant.design/docs/react/contributing). Feel free to share your ideas through [Pull Requests](https://github.com/ant-design/ant-design/pulls) or [GitHub Issues](https://github.com/ant-design/ant-design/issues). If you're interested in enhancing our codebase, explore the [Development Instructions](https://github.com/ant-design/ant-design/wiki/Development) and enjoy your coding journey! :)
|
||||
|
||||
For collaborators, adhere to our [Pull Request Principle](https://github.com/ant-design/ant-design/wiki/PR-principle) and utilize our [Pull Request Template](https://github.com/ant-design/ant-design/wiki/PR-principle#pull-request-template) when creating a Pull Request.
|
||||
|
||||
## Issue funding
|
||||
|
||||
We use [Issuehunt](https://issuehunt.io/repos/3452688) to up-vote and promote specific features that you would like to see and implement. Check our backlog and help us:
|
||||
|
||||
[](https://issuehunt.io/repos/34526884)
|
||||
|
||||
## ❤️ Backers [](https://opencollective.com/ant-design#support)
|
||||
|
||||
[](https://opencollective.com/ant-design/contribute/backers-217/checkout)
|
||||
+137136
File diff suppressed because it is too large
Load Diff
+1
File diff suppressed because one or more lines are too long
+357
File diff suppressed because one or more lines are too long
+120
@@ -0,0 +1,120 @@
|
||||
/*!
|
||||
*
|
||||
* antd v6.3.7
|
||||
*
|
||||
* Copyright 2015-present, Alipay, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* react-is.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
+1
File diff suppressed because one or more lines are too long
+103
File diff suppressed because one or more lines are too long
+121654
File diff suppressed because it is too large
Load Diff
+1
File diff suppressed because one or more lines are too long
+357
File diff suppressed because one or more lines are too long
+120
@@ -0,0 +1,120 @@
|
||||
/*!
|
||||
*
|
||||
* antd v6.3.7
|
||||
*
|
||||
* Copyright 2015-present, Alipay, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* react-is.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
|
||||
/** */
|
||||
+1
File diff suppressed because one or more lines are too long
+246
@@ -0,0 +1,246 @@
|
||||
/* stylelint-disable */
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
input::-ms-clear,
|
||||
input::-ms-reveal {
|
||||
display: none;
|
||||
}
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
line-height: 1.15;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-ms-overflow-style: scrollbar;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
[tabindex='-1']:focus {
|
||||
outline: none;
|
||||
}
|
||||
hr {
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5em;
|
||||
font-weight: 500;
|
||||
}
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
abbr[title],
|
||||
abbr[data-original-title] {
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
border-bottom: 0;
|
||||
cursor: help;
|
||||
}
|
||||
address {
|
||||
margin-bottom: 1em;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
input[type='text'],
|
||||
input[type='password'],
|
||||
input[type='number'],
|
||||
textarea {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
dt {
|
||||
font-weight: 500;
|
||||
}
|
||||
dd {
|
||||
margin-bottom: 0.5em;
|
||||
margin-left: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 0 0 1em;
|
||||
}
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-size: 1em;
|
||||
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
||||
}
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1em;
|
||||
overflow: auto;
|
||||
}
|
||||
figure {
|
||||
margin: 0 0 1em;
|
||||
}
|
||||
img {
|
||||
vertical-align: middle;
|
||||
border-style: none;
|
||||
}
|
||||
a,
|
||||
area,
|
||||
button,
|
||||
[role='button'],
|
||||
input:not([type='range']),
|
||||
label,
|
||||
select,
|
||||
summary,
|
||||
textarea {
|
||||
touch-action: manipulation;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
caption {
|
||||
padding-top: 0.75em;
|
||||
padding-bottom: 0.3em;
|
||||
text-align: left;
|
||||
caption-side: bottom;
|
||||
}
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
optgroup,
|
||||
textarea {
|
||||
margin: 0;
|
||||
color: inherit;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
button,
|
||||
input {
|
||||
overflow: visible;
|
||||
}
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
button,
|
||||
html [type='button'],
|
||||
[type='reset'],
|
||||
[type='submit'] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
button::-moz-focus-inner,
|
||||
[type='button']::-moz-focus-inner,
|
||||
[type='reset']::-moz-focus-inner,
|
||||
[type='submit']::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border-style: none;
|
||||
}
|
||||
input[type='radio'],
|
||||
input[type='checkbox'] {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
input[type='date'],
|
||||
input[type='time'],
|
||||
input[type='datetime-local'],
|
||||
input[type='month'] {
|
||||
-webkit-appearance: listbox;
|
||||
}
|
||||
textarea {
|
||||
overflow: auto;
|
||||
resize: vertical;
|
||||
}
|
||||
fieldset {
|
||||
min-width: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
legend {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
margin-bottom: 0.5em;
|
||||
padding: 0;
|
||||
color: inherit;
|
||||
font-size: 1.5em;
|
||||
line-height: inherit;
|
||||
white-space: normal;
|
||||
}
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
[type='number']::-webkit-inner-spin-button,
|
||||
[type='number']::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
[type='search'] {
|
||||
outline-offset: -2px;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
[type='search']::-webkit-search-cancel-button,
|
||||
[type='search']::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
::-webkit-file-upload-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
output {
|
||||
display: inline-block;
|
||||
}
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import * as React from 'react';
|
||||
import type { ButtonProps, LegacyButtonType } from '../button/Button';
|
||||
export interface ActionButtonProps {
|
||||
type?: LegacyButtonType;
|
||||
actionFn?: (...args: any[]) => any | PromiseLike<any>;
|
||||
close?: (...args: any[]) => void;
|
||||
autoFocus?: boolean;
|
||||
prefixCls: string;
|
||||
buttonProps?: ButtonProps;
|
||||
emitEvent?: boolean;
|
||||
quitOnNullishReturnValue?: boolean;
|
||||
children?: React.ReactNode;
|
||||
/**
|
||||
* Do not throw if is await mode
|
||||
*/
|
||||
isSilent?: () => boolean;
|
||||
}
|
||||
declare const ActionButton: React.FC<ActionButtonProps>;
|
||||
export default ActionButton;
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
"use client";
|
||||
|
||||
import * as React from 'react';
|
||||
import useState from "@rc-component/util/es/hooks/useState";
|
||||
import Button from '../button/Button';
|
||||
import { convertLegacyProps } from '../button/buttonHelpers';
|
||||
import { isThenable } from './is';
|
||||
const ActionButton = props => {
|
||||
const {
|
||||
type,
|
||||
children,
|
||||
prefixCls,
|
||||
buttonProps,
|
||||
close,
|
||||
autoFocus,
|
||||
emitEvent,
|
||||
isSilent,
|
||||
quitOnNullishReturnValue,
|
||||
actionFn
|
||||
} = props;
|
||||
const clickedRef = React.useRef(false);
|
||||
const buttonRef = React.useRef(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const onInternalClose = (...args) => {
|
||||
close?.(...args);
|
||||
};
|
||||
React.useEffect(() => {
|
||||
let timeoutId = null;
|
||||
if (autoFocus) {
|
||||
timeoutId = setTimeout(() => {
|
||||
buttonRef.current?.focus({
|
||||
preventScroll: true
|
||||
});
|
||||
});
|
||||
}
|
||||
return () => {
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
};
|
||||
}, [autoFocus]);
|
||||
const handlePromiseOnOk = returnValueOfOnOk => {
|
||||
if (!isThenable(returnValueOfOnOk)) {
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
returnValueOfOnOk.then((...args) => {
|
||||
setLoading(false, true);
|
||||
onInternalClose.apply(void 0, args);
|
||||
clickedRef.current = false;
|
||||
}, e => {
|
||||
// See: https://github.com/ant-design/ant-design/issues/6183
|
||||
setLoading(false, true);
|
||||
clickedRef.current = false;
|
||||
// Do not throw if is `await` mode
|
||||
if (isSilent?.()) {
|
||||
return;
|
||||
}
|
||||
return Promise.reject(e);
|
||||
});
|
||||
};
|
||||
const onClick = e => {
|
||||
if (clickedRef.current) {
|
||||
return;
|
||||
}
|
||||
clickedRef.current = true;
|
||||
if (!actionFn) {
|
||||
onInternalClose();
|
||||
return;
|
||||
}
|
||||
let returnValueOfOnOk;
|
||||
if (emitEvent) {
|
||||
returnValueOfOnOk = actionFn(e);
|
||||
if (quitOnNullishReturnValue && !isThenable(returnValueOfOnOk)) {
|
||||
clickedRef.current = false;
|
||||
onInternalClose(e);
|
||||
return;
|
||||
}
|
||||
} else if (actionFn.length) {
|
||||
returnValueOfOnOk = actionFn(close);
|
||||
// https://github.com/ant-design/ant-design/issues/23358
|
||||
clickedRef.current = false;
|
||||
} else {
|
||||
returnValueOfOnOk = actionFn();
|
||||
if (!isThenable(returnValueOfOnOk)) {
|
||||
onInternalClose();
|
||||
return;
|
||||
}
|
||||
}
|
||||
handlePromiseOnOk(returnValueOfOnOk);
|
||||
};
|
||||
return /*#__PURE__*/React.createElement(Button, {
|
||||
...convertLegacyProps(type),
|
||||
onClick: onClick,
|
||||
loading: loading,
|
||||
prefixCls: prefixCls,
|
||||
...buttonProps,
|
||||
ref: buttonRef
|
||||
}, children);
|
||||
};
|
||||
export default ActionButton;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import React from 'react';
|
||||
declare const ContextIsolator: React.FC<Readonly<React.PropsWithChildren<Partial<Record<'space' | 'form', boolean>>>>>;
|
||||
export default ContextIsolator;
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
"use client";
|
||||
|
||||
import React from 'react';
|
||||
import { NoFormStyle } from '../form/context';
|
||||
import { NoCompactStyle } from '../space/Compact';
|
||||
import { isNonNullable } from './is';
|
||||
const ContextIsolator = props => {
|
||||
const {
|
||||
space,
|
||||
form,
|
||||
children
|
||||
} = props;
|
||||
if (!isNonNullable(children)) {
|
||||
return null;
|
||||
}
|
||||
let result = children;
|
||||
if (form) {
|
||||
result = /*#__PURE__*/React.createElement(NoFormStyle, {
|
||||
override: true,
|
||||
status: true
|
||||
}, result);
|
||||
}
|
||||
if (space) {
|
||||
result = /*#__PURE__*/React.createElement(NoCompactStyle, null, result);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
export default ContextIsolator;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import type { AnyObject } from './type';
|
||||
export declare function withPureRenderTheme<T extends AnyObject = AnyObject>(Component: React.FC<T>): (props: T) => React.JSX.Element;
|
||||
export interface BaseProps {
|
||||
prefixCls?: string;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
declare const genPurePanel: <ComponentProps extends BaseProps = BaseProps>(Component: React.ComponentType<Readonly<ComponentProps>>, alignPropName?: "align" | "dropdownAlign" | "popupAlign", postProps?: (props: ComponentProps) => ComponentProps, defaultPrefixCls?: string, getDropdownCls?: (prefixCls: string) => string) => (props: AnyObject) => React.JSX.Element;
|
||||
export default genPurePanel;
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
"use client";
|
||||
|
||||
import * as React from 'react';
|
||||
import { useControlledState } from '@rc-component/util';
|
||||
import ConfigProvider, { ConfigContext } from '../config-provider';
|
||||
export function withPureRenderTheme(Component) {
|
||||
return props => (/*#__PURE__*/React.createElement(ConfigProvider, {
|
||||
theme: {
|
||||
token: {
|
||||
motion: false,
|
||||
zIndexPopupBase: 0
|
||||
}
|
||||
}
|
||||
}, /*#__PURE__*/React.createElement(Component, {
|
||||
...props
|
||||
})));
|
||||
}
|
||||
/* istanbul ignore next */
|
||||
const genPurePanel = (Component, alignPropName, postProps, defaultPrefixCls, getDropdownCls) => {
|
||||
const PurePanel = props => {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
style
|
||||
} = props;
|
||||
const holderRef = React.useRef(null);
|
||||
const [popupHeight, setPopupHeight] = React.useState(0);
|
||||
const [popupWidth, setPopupWidth] = React.useState(0);
|
||||
const [open, setOpen] = useControlledState(false, props.open);
|
||||
const {
|
||||
getPrefixCls
|
||||
} = React.useContext(ConfigContext);
|
||||
const prefixCls = getPrefixCls(defaultPrefixCls || 'select', customizePrefixCls);
|
||||
React.useEffect(() => {
|
||||
// We do not care about ssr
|
||||
setOpen(true);
|
||||
if (typeof ResizeObserver !== 'undefined') {
|
||||
const resizeObserver = new ResizeObserver(entries => {
|
||||
const element = entries[0].target;
|
||||
setPopupHeight(element.offsetHeight + 8);
|
||||
setPopupWidth(element.offsetWidth);
|
||||
});
|
||||
const interval = setInterval(() => {
|
||||
const dropdownCls = getDropdownCls ? `.${getDropdownCls(prefixCls)}` : `.${prefixCls}-dropdown`;
|
||||
const popup = holderRef.current?.querySelector(dropdownCls);
|
||||
if (popup) {
|
||||
clearInterval(interval);
|
||||
resizeObserver.observe(popup);
|
||||
}
|
||||
}, 10);
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
resizeObserver.disconnect();
|
||||
};
|
||||
}
|
||||
}, [prefixCls]);
|
||||
let mergedProps = {
|
||||
...props,
|
||||
style: {
|
||||
...style,
|
||||
margin: 0
|
||||
},
|
||||
open,
|
||||
getPopupContainer: () => holderRef.current
|
||||
};
|
||||
if (postProps) {
|
||||
mergedProps = postProps(mergedProps);
|
||||
}
|
||||
if (alignPropName) {
|
||||
mergedProps = {
|
||||
...mergedProps,
|
||||
[alignPropName]: {
|
||||
overflow: {
|
||||
adjustX: false,
|
||||
adjustY: false
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
const mergedStyle = {
|
||||
paddingBottom: popupHeight,
|
||||
position: 'relative',
|
||||
minWidth: popupWidth
|
||||
};
|
||||
return /*#__PURE__*/React.createElement("div", {
|
||||
ref: holderRef,
|
||||
style: mergedStyle
|
||||
}, /*#__PURE__*/React.createElement(Component, {
|
||||
...mergedProps
|
||||
}));
|
||||
};
|
||||
return withPureRenderTheme(PurePanel);
|
||||
};
|
||||
export default genPurePanel;
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import type * as React from 'react';
|
||||
export type HTMLAriaDataAttributes = React.AriaAttributes & {
|
||||
[key: `data-${string}`]: unknown;
|
||||
} & Pick<React.HTMLAttributes<HTMLDivElement>, 'role'>;
|
||||
+1
@@ -0,0 +1 @@
|
||||
export {};
|
||||
+1
@@ -0,0 +1 @@
|
||||
export default function capitalize<T extends string>(str: T): Capitalize<T>;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
export default function capitalize(str) {
|
||||
if (typeof str !== 'string') {
|
||||
return str;
|
||||
}
|
||||
const ret = str.charAt(0).toUpperCase() + str.slice(1);
|
||||
return ret;
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import type { PresetColorKey } from '../theme/interface';
|
||||
type InverseColor = `${PresetColorKey}-inverse`;
|
||||
export declare const PresetStatusColors: readonly ["success", "processing", "error", "default", "warning"];
|
||||
export type PresetColorType = PresetColorKey | InverseColor;
|
||||
export type PresetStatusColorType = (typeof PresetStatusColors)[number];
|
||||
/**
|
||||
* determine if the color keyword belongs to the `Ant Design` {@link PresetColors}.
|
||||
* @param color color to be judged
|
||||
* @param includeInverse whether to include reversed colors
|
||||
*/
|
||||
export declare function isPresetColor(color?: any, includeInverse?: boolean): boolean;
|
||||
export declare function isPresetStatusColor(color?: any): color is PresetStatusColorType;
|
||||
export {};
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
||||
import { PresetColors } from '../theme/interface';
|
||||
const inverseColors = PresetColors.map(color => `${color}-inverse`);
|
||||
export const PresetStatusColors = ['success', 'processing', 'error', 'default', 'warning'];
|
||||
/**
|
||||
* determine if the color keyword belongs to the `Ant Design` {@link PresetColors}.
|
||||
* @param color color to be judged
|
||||
* @param includeInverse whether to include reversed colors
|
||||
*/
|
||||
export function isPresetColor(color, includeInverse = true) {
|
||||
if (includeInverse) {
|
||||
return [].concat(_toConsumableArray(inverseColors), _toConsumableArray(PresetColors)).includes(color);
|
||||
}
|
||||
return PresetColors.includes(color);
|
||||
}
|
||||
export function isPresetStatusColor(color) {
|
||||
return PresetStatusColors.includes(color);
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import type { TooltipProps } from '../tooltip';
|
||||
declare const convertToTooltipProps: <P extends TooltipProps>(tooltip: P | ReactNode, context?: P) => P | null;
|
||||
export default convertToTooltipProps;
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import { isValidElement } from 'react';
|
||||
import { isNonNullable, isPlainObject } from './is';
|
||||
const convertToTooltipProps = (tooltip, context) => {
|
||||
if (!isNonNullable(tooltip)) {
|
||||
return null;
|
||||
}
|
||||
if (isPlainObject(tooltip) && ! /*#__PURE__*/isValidElement(tooltip)) {
|
||||
return {
|
||||
...context,
|
||||
...tooltip
|
||||
};
|
||||
}
|
||||
return {
|
||||
...context,
|
||||
title: tooltip
|
||||
};
|
||||
};
|
||||
export default convertToTooltipProps;
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
declare function copy(text: string, config?: {
|
||||
format?: 'text/plain' | 'text/html';
|
||||
}): Promise<boolean>;
|
||||
export default copy;
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
import warning from './warning';
|
||||
const execCopy = (text, isHtmlFormat) => {
|
||||
let copySuccess = false;
|
||||
const onCopy = event => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
event.clipboardData?.clearData();
|
||||
event.clipboardData?.setData('text/plain', text);
|
||||
if (isHtmlFormat) {
|
||||
event.clipboardData?.setData('text/html', text);
|
||||
}
|
||||
copySuccess = true;
|
||||
};
|
||||
try {
|
||||
document.addEventListener('copy', onCopy, {
|
||||
capture: true
|
||||
});
|
||||
document.execCommand('copy');
|
||||
return copySuccess;
|
||||
} catch {
|
||||
return false;
|
||||
} finally {
|
||||
document.removeEventListener('copy', onCopy, {
|
||||
capture: true
|
||||
});
|
||||
}
|
||||
};
|
||||
const asyncCopy = async (text, isHtmlFormat) => {
|
||||
try {
|
||||
if (isHtmlFormat) {
|
||||
await navigator.clipboard.write([new ClipboardItem({
|
||||
'text/html': new Blob([text], {
|
||||
type: 'text/html'
|
||||
}),
|
||||
'text/plain': new Blob([text], {
|
||||
type: 'text/plain'
|
||||
})
|
||||
})]);
|
||||
} else {
|
||||
await navigator.clipboard.writeText(text);
|
||||
}
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
async function copy(text, config) {
|
||||
if (typeof text !== 'string') {
|
||||
process.env.NODE_ENV !== "production" ? warning(false, 'The clipboard content must be of string type', '') : void 0;
|
||||
return false;
|
||||
}
|
||||
const isHtmlFormat = config?.format === 'text/html';
|
||||
if (await asyncCopy(text, isHtmlFormat)) {
|
||||
return true;
|
||||
}
|
||||
if (execCopy(text, isHtmlFormat)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
export default copy;
|
||||
+1
@@ -0,0 +1 @@
|
||||
export declare function easeInOutCubic(t: number, b: number, c: number, d: number): number;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
export function easeInOutCubic(t, b, c, d) {
|
||||
const cc = c - b;
|
||||
t /= d / 2;
|
||||
if (t < 1) {
|
||||
return cc / 2 * t * t * t + b;
|
||||
}
|
||||
// biome-ignore lint: it is a common easing function
|
||||
return cc / 2 * ((t -= 2) * t * t + 2) + b;
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
declare function mergeProps<A, B>(a: A, b: B): B & A;
|
||||
declare function mergeProps<A, B, C>(a: A, b: B, c: C): C & B & A;
|
||||
declare function mergeProps<A, B, C, D>(a: A, b: B, c: C, d: D): D & C & B & A;
|
||||
export default mergeProps;
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
function mergeProps(...items) {
|
||||
const ret = {};
|
||||
items.forEach(item => {
|
||||
if (item) {
|
||||
Object.keys(item).forEach(key => {
|
||||
if (item[key] !== undefined) {
|
||||
ret[key] = item[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
export default mergeProps;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import type { SizeType } from '../config-provider/SizeContext';
|
||||
export declare function isPresetSize(size?: SizeType | string | number): size is SizeType;
|
||||
export declare function isValidGapNumber(size?: SizeType | string | number): size is number;
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import { isNumber } from './is';
|
||||
export function isPresetSize(size) {
|
||||
return ['small', 'middle', 'medium', 'large'].includes(size);
|
||||
}
|
||||
export function isValidGapNumber(size) {
|
||||
if (!size) {
|
||||
// The case of size = 0 is deliberately excluded here, because the default value of the gap attribute in CSS is 0, so if the user passes 0 in, we can directly ignore it.
|
||||
return false;
|
||||
}
|
||||
return isNumber(size);
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import type { BaseInputProps } from '@rc-component/input/lib/interface';
|
||||
export type AllowClear = BaseInputProps['allowClear'];
|
||||
declare const getAllowClear: (allowClear: AllowClear) => AllowClear;
|
||||
export default getAllowClear;
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
"use client";
|
||||
|
||||
import React from 'react';
|
||||
import CloseCircleFilled from "@ant-design/icons/es/icons/CloseCircleFilled";
|
||||
import { isPlainObject } from './is';
|
||||
const getAllowClear = allowClear => {
|
||||
let mergedAllowClear;
|
||||
if (isPlainObject(allowClear) && allowClear?.clearIcon) {
|
||||
mergedAllowClear = allowClear;
|
||||
} else if (allowClear) {
|
||||
mergedAllowClear = {
|
||||
clearIcon: /*#__PURE__*/React.createElement(CloseCircleFilled, null)
|
||||
};
|
||||
}
|
||||
return mergedAllowClear;
|
||||
};
|
||||
export default getAllowClear;
|
||||
+1
@@ -0,0 +1 @@
|
||||
export default function getReactMajorVersion(): number;
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// ZombieJ: This is only warn for React 17 not support.
|
||||
// But Jest mock React 17 will cause many issues in testing,
|
||||
// Can be safe to remove in next major version.
|
||||
import { version } from 'react';
|
||||
export default function getReactMajorVersion() {
|
||||
const majorVersion = Number.parseInt(version.split('.')[0], 10);
|
||||
return majorVersion;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import type * as React from 'react';
|
||||
export type RenderFunction = () => React.ReactNode;
|
||||
export declare const getRenderPropValue: (propValue?: React.ReactNode | RenderFunction) => React.ReactNode;
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
export const getRenderPropValue = propValue => {
|
||||
if (!propValue) {
|
||||
return null;
|
||||
}
|
||||
return typeof propValue === 'function' ? propValue() : propValue;
|
||||
};
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
export declare const isWindow: (obj: any) => obj is Window;
|
||||
declare const getScroll: (target: HTMLElement | Window | Document | null) => number;
|
||||
export default getScroll;
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import { isNonNullable } from './is';
|
||||
export const isWindow = obj => {
|
||||
return isNonNullable(obj) && obj === obj.window;
|
||||
};
|
||||
const getScroll = target => {
|
||||
if (typeof window === 'undefined') {
|
||||
/* istanbul ignore next */
|
||||
return 0;
|
||||
}
|
||||
let result = 0;
|
||||
if (isWindow(target)) {
|
||||
result = target.pageYOffset;
|
||||
} else if (target instanceof Document) {
|
||||
result = target.documentElement.scrollTop;
|
||||
} else if (target instanceof HTMLElement) {
|
||||
result = target.scrollTop;
|
||||
} else if (target) {
|
||||
// According to the type inference, the `target` is `never` type.
|
||||
// Since we configured the loose mode type checking, and supports mocking the target with such shape below::
|
||||
// `{ documentElement: { scrollLeft: 200, scrollTop: 400 } }`,
|
||||
// the program may falls into this branch.
|
||||
// Check the corresponding tests for details. Don't sure what is the real scenario this happens.
|
||||
/* biome-ignore lint/complexity/useLiteralKeys: target is a never type */ /* eslint-disable-next-line dot-notation */
|
||||
result = target['scrollTop'];
|
||||
}
|
||||
if (target && !isWindow(target) && typeof result !== 'number') {
|
||||
result = (target.ownerDocument ?? target).documentElement?.scrollTop;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
export default getScroll;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
export * from './useClosable';
|
||||
export * from './useForceUpdate';
|
||||
export * from './useMergedMask';
|
||||
export * from './useMergeSemantic';
|
||||
export * from './useMultipleSelect';
|
||||
export * from './useOrientation';
|
||||
export * from './usePatchElement';
|
||||
export * from './useProxyImperativeHandle';
|
||||
export * from './useSyncState';
|
||||
export * from './useZIndex';
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
export * from './useClosable';
|
||||
export * from './useForceUpdate';
|
||||
export * from './useMergedMask';
|
||||
export * from './useMergeSemantic';
|
||||
export * from './useMultipleSelect';
|
||||
export * from './useOrientation';
|
||||
export * from './usePatchElement';
|
||||
export * from './useProxyImperativeHandle';
|
||||
export * from './useSyncState';
|
||||
export * from './useZIndex';
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import React from 'react';
|
||||
import type { DialogProps } from '@rc-component/dialog';
|
||||
export type ClosableType = DialogProps['closable'];
|
||||
export type BaseContextClosable = {
|
||||
closable?: ClosableType;
|
||||
closeIcon?: ReactNode;
|
||||
};
|
||||
export type ContextClosable<T extends BaseContextClosable = any> = Partial<Pick<T, 'closable' | 'closeIcon'>>;
|
||||
export declare const pickClosable: <T extends BaseContextClosable>(context?: ContextClosable<T>) => ContextClosable<T> | undefined;
|
||||
/** Collection contains the all the props related with closable. e.g. `closable`, `closeIcon` */
|
||||
interface ClosableCollection {
|
||||
closable?: ClosableType;
|
||||
closeIcon?: ReactNode;
|
||||
disabled?: boolean;
|
||||
}
|
||||
interface FallbackCloseCollection extends ClosableCollection {
|
||||
/**
|
||||
* Some components need to wrap CloseIcon twice,
|
||||
* this method will be executed once after the final CloseIcon is calculated
|
||||
*/
|
||||
closeIconRender?: (closeIcon: ReactNode) => ReactNode;
|
||||
}
|
||||
type DataAttributes = {
|
||||
[key: `data-${string}`]: string;
|
||||
};
|
||||
export declare const computeClosable: (propCloseCollection?: ClosableCollection, contextCloseCollection?: ClosableCollection | null, fallbackCloseCollection?: FallbackCloseCollection, closeLabel?: string) => [closable: boolean, closeIcon: React.ReactNode, closeBtnIsDisabled: boolean, ariaOrDataProps: React.AriaAttributes & DataAttributes];
|
||||
export declare const useClosable: (propCloseCollection?: ClosableCollection, contextCloseCollection?: ClosableCollection | null, fallbackCloseCollection?: FallbackCloseCollection) => [closable: boolean, closeIcon: ReactNode, closeBtnIsDisabled: boolean, ariaOrDataProps: React.AriaAttributes & DataAttributes];
|
||||
export {};
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
"use client";
|
||||
|
||||
import React from 'react';
|
||||
import CloseOutlined from "@ant-design/icons/es/icons/CloseOutlined";
|
||||
import pickAttrs from "@rc-component/util/es/pickAttrs";
|
||||
import { useLocale } from '../../locale';
|
||||
import defaultLocale from '../../locale/en_US';
|
||||
import extendsObject from '../extendsObject';
|
||||
import { isNonNullable, isPlainObject } from '../is';
|
||||
export const pickClosable = context => {
|
||||
if (!context) {
|
||||
return undefined;
|
||||
}
|
||||
const {
|
||||
closable,
|
||||
closeIcon
|
||||
} = context;
|
||||
return {
|
||||
closable,
|
||||
closeIcon
|
||||
};
|
||||
};
|
||||
const EmptyFallbackCloseCollection = {};
|
||||
const computeClosableConfig = (closable, closeIcon) => {
|
||||
if (!closable && (closable === false || closeIcon === false || closeIcon === null)) {
|
||||
return false;
|
||||
}
|
||||
if (closable === undefined && closeIcon === undefined) {
|
||||
return null;
|
||||
}
|
||||
let closableConfig = {
|
||||
closeIcon: typeof closeIcon !== 'boolean' && closeIcon !== null ? closeIcon : undefined
|
||||
};
|
||||
if (isPlainObject(closable)) {
|
||||
closableConfig = {
|
||||
...closableConfig,
|
||||
...closable
|
||||
};
|
||||
}
|
||||
return closableConfig;
|
||||
};
|
||||
const mergeClosableConfigs = (propConfig, contextConfig, fallbackConfig) => {
|
||||
if (propConfig === false) {
|
||||
return false;
|
||||
}
|
||||
if (propConfig) {
|
||||
return extendsObject(fallbackConfig, contextConfig, propConfig);
|
||||
}
|
||||
if (contextConfig === false) {
|
||||
return false;
|
||||
}
|
||||
if (contextConfig) {
|
||||
return extendsObject(fallbackConfig, contextConfig);
|
||||
}
|
||||
return fallbackConfig.closable ? fallbackConfig : false;
|
||||
};
|
||||
const computeCloseIcon = (mergedConfig, fallbackCloseCollection, closeLabel) => {
|
||||
const {
|
||||
closeIconRender
|
||||
} = fallbackCloseCollection;
|
||||
const {
|
||||
closeIcon,
|
||||
...restConfig
|
||||
} = mergedConfig;
|
||||
let finalCloseIcon = closeIcon;
|
||||
const ariaOrDataProps = pickAttrs(restConfig, true);
|
||||
if (isNonNullable(finalCloseIcon)) {
|
||||
if (closeIconRender) {
|
||||
finalCloseIcon = closeIconRender(finalCloseIcon);
|
||||
}
|
||||
finalCloseIcon = /*#__PURE__*/React.isValidElement(finalCloseIcon) ? (/*#__PURE__*/React.cloneElement(finalCloseIcon, {
|
||||
'aria-label': closeLabel,
|
||||
...finalCloseIcon.props,
|
||||
...ariaOrDataProps
|
||||
})) : (/*#__PURE__*/React.createElement("span", {
|
||||
"aria-label": closeLabel,
|
||||
...ariaOrDataProps
|
||||
}, finalCloseIcon));
|
||||
}
|
||||
return [finalCloseIcon, ariaOrDataProps];
|
||||
};
|
||||
export const computeClosable = (propCloseCollection, contextCloseCollection, fallbackCloseCollection = EmptyFallbackCloseCollection, closeLabel = 'Close') => {
|
||||
const propConfig = computeClosableConfig(propCloseCollection?.closable, propCloseCollection?.closeIcon);
|
||||
const contextConfig = computeClosableConfig(contextCloseCollection?.closable, contextCloseCollection?.closeIcon);
|
||||
const mergedFallback = {
|
||||
closeIcon: /*#__PURE__*/React.createElement(CloseOutlined, null),
|
||||
...fallbackCloseCollection
|
||||
};
|
||||
const mergedConfig = mergeClosableConfigs(propConfig, contextConfig, mergedFallback);
|
||||
const closeBtnIsDisabled = typeof mergedConfig !== 'boolean' ? !!mergedConfig?.disabled : false;
|
||||
if (mergedConfig === false) {
|
||||
return [false, null, closeBtnIsDisabled, {}];
|
||||
}
|
||||
const [closeIcon, ariaProps] = computeCloseIcon(mergedConfig, mergedFallback, closeLabel);
|
||||
return [true, closeIcon, closeBtnIsDisabled, ariaProps];
|
||||
};
|
||||
export const useClosable = (propCloseCollection, contextCloseCollection, fallbackCloseCollection = EmptyFallbackCloseCollection) => {
|
||||
const [contextLocale] = useLocale('global', defaultLocale.global);
|
||||
return React.useMemo(() => {
|
||||
return computeClosable(propCloseCollection, contextCloseCollection, {
|
||||
closeIcon: /*#__PURE__*/React.createElement(CloseOutlined, null),
|
||||
...fallbackCloseCollection
|
||||
}, contextLocale.close);
|
||||
}, [propCloseCollection, contextCloseCollection, fallbackCloseCollection, contextLocale.close]);
|
||||
};
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import React from 'react';
|
||||
export declare const useForceUpdate: () => [number, React.ActionDispatch<[]>];
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import React from 'react';
|
||||
export const useForceUpdate = () => {
|
||||
return React.useReducer(ori => ori + 1, 0);
|
||||
};
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
import * as React from 'react';
|
||||
import type { AnyObject, EmptyObject, ValidChar } from '../type';
|
||||
export type SemanticSchema = {
|
||||
_default?: string;
|
||||
} & {
|
||||
[key: `${ValidChar}${string}`]: SemanticSchema;
|
||||
};
|
||||
export type Resolvable<T, P extends AnyObject> = T | ((info: {
|
||||
props: P;
|
||||
}) => T);
|
||||
export type SemanticClassNamesType<Props extends AnyObject, SemanticClassNames extends Record<PropertyKey, string>, NestedStructure extends EmptyObject = EmptyObject> = Resolvable<Readonly<SemanticClassNames>, Props> & NestedStructure;
|
||||
export type SemanticStylesType<Props extends AnyObject, SemanticStyles extends Record<PropertyKey, React.CSSProperties>, NestedStructure extends EmptyObject = EmptyObject> = Resolvable<Readonly<SemanticStyles>, Props> & NestedStructure;
|
||||
export type SemanticType<P = any, T = any> = T | ((info: {
|
||||
props: P;
|
||||
}) => T);
|
||||
export declare const mergeClassNames: <Name extends string, SemanticClassNames extends Partial<Record<Name, any>>>(schema?: SemanticSchema, ...classNames: (SemanticClassNames | undefined)[]) => SemanticClassNames;
|
||||
export declare const mergeStyles: <StylesType extends AnyObject>(...styles: (Partial<StylesType> | undefined)[]) => Record<PropertyKey, React.CSSProperties>;
|
||||
export declare const resolveStyleOrClass: <T extends AnyObject>(value: T | ((config: any) => T), info: {
|
||||
props: AnyObject;
|
||||
}) => T;
|
||||
type MaybeFn<T, P> = T | ((info: {
|
||||
props: P;
|
||||
}) => T) | undefined;
|
||||
type ObjectOnly<T> = T extends (...args: any) => any ? never : T;
|
||||
/**
|
||||
* @desc Merge classNames and styles from multiple sources. When `schema` is provided, it **must** provide the nest object structure.
|
||||
* @descZH 合并来自多个来源的 classNames 和 styles,当提供了 `schema` 时,必须提供嵌套的对象结构。
|
||||
*/
|
||||
export declare const useMergeSemantic: <ClassNamesType extends AnyObject, StylesType extends AnyObject, Props extends AnyObject>(classNamesList: MaybeFn<ClassNamesType, Props>[], stylesList: MaybeFn<StylesType, Props>[], info: {
|
||||
props: Props;
|
||||
}, schema?: SemanticSchema) => readonly [ObjectOnly<ClassNamesType>, ObjectOnly<StylesType>];
|
||||
export {};
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
||||
import * as React from 'react';
|
||||
import { clsx } from 'clsx';
|
||||
import { isPlainObject } from '../is';
|
||||
// ========================= ClassNames =========================
|
||||
export const mergeClassNames = (schema, ...classNames) => {
|
||||
const mergedSchema = schema || {};
|
||||
return classNames.filter(Boolean).reduce((acc, cur) => {
|
||||
// Loop keys of the current classNames
|
||||
Object.keys(cur || {}).forEach(key => {
|
||||
const keySchema = mergedSchema[key];
|
||||
const curVal = cur[key];
|
||||
if (isPlainObject(keySchema)) {
|
||||
if (isPlainObject(curVal)) {
|
||||
// Loop fill
|
||||
acc[key] = mergeClassNames(keySchema, acc[key], curVal);
|
||||
} else {
|
||||
// Covert string to object structure
|
||||
const {
|
||||
_default: defaultField
|
||||
} = keySchema;
|
||||
if (defaultField) {
|
||||
acc[key] = acc[key] || {};
|
||||
acc[key][defaultField] = clsx(acc[key][defaultField], curVal);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Flatten fill
|
||||
acc[key] = clsx(acc[key], curVal);
|
||||
}
|
||||
});
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
const useSemanticClassNames = (schema, ...classNames) => {
|
||||
return React.useMemo(() => mergeClassNames.apply(void 0, [schema].concat(classNames)), [schema].concat(classNames));
|
||||
};
|
||||
// =========================== Styles ===========================
|
||||
export const mergeStyles = (...styles) => {
|
||||
return styles.filter(Boolean).reduce((acc, cur = {}) => {
|
||||
Object.keys(cur).forEach(key => {
|
||||
acc[key] = {
|
||||
...acc[key],
|
||||
...cur[key]
|
||||
};
|
||||
});
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
const useSemanticStyles = (...styles) => {
|
||||
return React.useMemo(() => mergeStyles.apply(void 0, styles), [].concat(styles));
|
||||
};
|
||||
// =========================== Export ===========================
|
||||
const fillObjectBySchema = (obj, schema) => {
|
||||
const newObj = {
|
||||
...obj
|
||||
};
|
||||
Object.keys(schema).forEach(key => {
|
||||
if (key !== '_default') {
|
||||
const nestSchema = schema[key];
|
||||
const nextValue = newObj[key] || {};
|
||||
newObj[key] = nestSchema ? fillObjectBySchema(nextValue, nestSchema) : nextValue;
|
||||
}
|
||||
});
|
||||
return newObj;
|
||||
};
|
||||
export const resolveStyleOrClass = (value, info) => {
|
||||
return typeof value === 'function' ? value(info) : value;
|
||||
};
|
||||
/**
|
||||
* @desc Merge classNames and styles from multiple sources. When `schema` is provided, it **must** provide the nest object structure.
|
||||
* @descZH 合并来自多个来源的 classNames 和 styles,当提供了 `schema` 时,必须提供嵌套的对象结构。
|
||||
*/
|
||||
export const useMergeSemantic = (classNamesList, stylesList, info, schema) => {
|
||||
const resolvedClassNamesList = classNamesList.map(classNames => classNames ? resolveStyleOrClass(classNames, info) : undefined);
|
||||
const resolvedStylesList = stylesList.map(styles => styles ? resolveStyleOrClass(styles, info) : undefined);
|
||||
const mergedClassNames = useSemanticClassNames.apply(void 0, [schema].concat(_toConsumableArray(resolvedClassNamesList)));
|
||||
const mergedStyles = useSemanticStyles.apply(void 0, _toConsumableArray(resolvedStylesList));
|
||||
return React.useMemo(() => {
|
||||
if (!schema) {
|
||||
return [mergedClassNames, mergedStyles];
|
||||
}
|
||||
return [fillObjectBySchema(mergedClassNames, schema), fillObjectBySchema(mergedStyles, schema)];
|
||||
}, [mergedClassNames, mergedStyles, schema]);
|
||||
};
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
export interface MaskConfig {
|
||||
enabled?: boolean;
|
||||
blur?: boolean;
|
||||
closable?: boolean;
|
||||
}
|
||||
export type MaskType = MaskConfig | boolean;
|
||||
export declare const normalizeMaskConfig: (mask?: MaskType, maskClosable?: boolean) => MaskConfig;
|
||||
export declare const useMergedMask: (mask?: MaskType, contextMask?: MaskType, prefixCls?: string, maskClosable?: boolean) => [config: boolean, maskBlurClassName: {
|
||||
[key: string]: string | undefined;
|
||||
}, maskClosable: boolean];
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
import { useMemo } from 'react';
|
||||
import { isPlainObject } from '../is';
|
||||
export const normalizeMaskConfig = (mask, maskClosable) => {
|
||||
let maskConfig = {};
|
||||
if (isPlainObject(mask)) {
|
||||
maskConfig = mask;
|
||||
}
|
||||
if (typeof mask === 'boolean') {
|
||||
maskConfig = {
|
||||
enabled: mask
|
||||
};
|
||||
}
|
||||
if (maskConfig.closable === undefined && maskClosable !== undefined) {
|
||||
maskConfig.closable = maskClosable;
|
||||
}
|
||||
return maskConfig;
|
||||
};
|
||||
export const useMergedMask = (mask, contextMask, prefixCls, maskClosable) => {
|
||||
return useMemo(() => {
|
||||
const maskConfig = normalizeMaskConfig(mask, maskClosable);
|
||||
const contextMaskConfig = normalizeMaskConfig(contextMask);
|
||||
const mergedConfig = {
|
||||
blur: false,
|
||||
...contextMaskConfig,
|
||||
...maskConfig,
|
||||
closable: maskConfig.closable ?? maskClosable ?? contextMaskConfig.closable ?? true
|
||||
};
|
||||
const className = mergedConfig.blur ? `${prefixCls}-mask-blur` : undefined;
|
||||
return [mergedConfig.enabled !== false, {
|
||||
mask: className
|
||||
}, !!mergedConfig.closable];
|
||||
}, [mask, contextMask, prefixCls, maskClosable]);
|
||||
};
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
export type PrevSelectedIndex = null | number;
|
||||
/**
|
||||
* @title multipleSelect hooks
|
||||
* @description multipleSelect by hold down shift key
|
||||
*/
|
||||
export declare const useMultipleSelect: <T, K>(getKey: (item: T, index: number, array: T[]) => K) => readonly [(currentSelectedIndex: number, data: T[], selectedKeys: Set<K>) => K[], import("react").Dispatch<import("react").SetStateAction<PrevSelectedIndex>>];
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import { useCallback, useState } from 'react';
|
||||
/**
|
||||
* @title multipleSelect hooks
|
||||
* @description multipleSelect by hold down shift key
|
||||
*/
|
||||
export const useMultipleSelect = getKey => {
|
||||
const [prevSelectedIndex, setPrevSelectedIndex] = useState(null);
|
||||
const multipleSelect = useCallback((currentSelectedIndex, data, selectedKeys) => {
|
||||
const configPrevSelectedIndex = prevSelectedIndex ?? currentSelectedIndex;
|
||||
// add/delete the selected range
|
||||
const startIndex = Math.min(configPrevSelectedIndex || 0, currentSelectedIndex);
|
||||
const endIndex = Math.max(configPrevSelectedIndex || 0, currentSelectedIndex);
|
||||
const rangeKeys = data.slice(startIndex, endIndex + 1).map(getKey);
|
||||
const shouldSelected = rangeKeys.some(rangeKey => !selectedKeys.has(rangeKey));
|
||||
const changedKeys = [];
|
||||
rangeKeys.forEach(item => {
|
||||
if (shouldSelected) {
|
||||
if (!selectedKeys.has(item)) {
|
||||
changedKeys.push(item);
|
||||
}
|
||||
selectedKeys.add(item);
|
||||
} else {
|
||||
selectedKeys.delete(item);
|
||||
changedKeys.push(item);
|
||||
}
|
||||
});
|
||||
setPrevSelectedIndex(shouldSelected ? endIndex : null);
|
||||
return changedKeys;
|
||||
}, [prevSelectedIndex]);
|
||||
return [multipleSelect, setPrevSelectedIndex];
|
||||
};
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export type Orientation = 'horizontal' | 'vertical';
|
||||
export declare const useOrientation: (orientation?: Orientation, vertical?: boolean, legacyDirection?: Orientation) => [Orientation, boolean];
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import { useMemo } from 'react';
|
||||
const isValidOrientation = orientation => {
|
||||
return orientation === 'horizontal' || orientation === 'vertical';
|
||||
};
|
||||
export const useOrientation = (orientation, vertical, legacyDirection) => {
|
||||
return useMemo(() => {
|
||||
const validOrientation = isValidOrientation(orientation);
|
||||
let mergedOrientation;
|
||||
if (validOrientation) {
|
||||
mergedOrientation = orientation;
|
||||
} else if (typeof vertical === 'boolean') {
|
||||
mergedOrientation = vertical ? 'vertical' : 'horizontal';
|
||||
} else {
|
||||
const validLegacyDirection = isValidOrientation(legacyDirection);
|
||||
mergedOrientation = validLegacyDirection ? legacyDirection : 'horizontal';
|
||||
}
|
||||
return [mergedOrientation, mergedOrientation === 'vertical'];
|
||||
}, [legacyDirection, orientation, vertical]);
|
||||
};
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import * as React from 'react';
|
||||
export declare const usePatchElement: () => [React.ReactElement[], (element: React.ReactElement) => () => void];
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
||||
import * as React from 'react';
|
||||
export const usePatchElement = () => {
|
||||
const [elements, setElements] = React.useState([]);
|
||||
const patchElement = React.useCallback(element => {
|
||||
// append a new element to elements (and create a new ref)
|
||||
setElements(originElements => [].concat(_toConsumableArray(originElements), [element]));
|
||||
// return a function that removes the new element out of elements (and create a new ref)
|
||||
// it works a little like useEffect
|
||||
return () => {
|
||||
setElements(originElements => originElements.filter(ele => ele !== element));
|
||||
};
|
||||
}, []);
|
||||
return [elements, patchElement];
|
||||
};
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import type { Ref } from 'react';
|
||||
export declare const useProxyImperativeHandle: <NativeELementType extends HTMLElement, ReturnRefType extends {
|
||||
nativeElement: NativeELementType;
|
||||
}>(ref: Ref<any> | undefined, init: () => ReturnRefType) => void;
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
// Proxy the dom ref with `{ nativeElement, otherFn }` type
|
||||
// ref: https://github.com/ant-design/ant-design/discussions/45242
|
||||
import { useImperativeHandle } from 'react';
|
||||
const fillProxy = (element, handler) => {
|
||||
element._antProxy = element._antProxy || {};
|
||||
Object.keys(handler).forEach(key => {
|
||||
if (!(key in element._antProxy)) {
|
||||
const ori = element[key];
|
||||
element._antProxy[key] = ori;
|
||||
element[key] = handler[key];
|
||||
}
|
||||
});
|
||||
return element;
|
||||
};
|
||||
export const useProxyImperativeHandle = (ref, init) => {
|
||||
return useImperativeHandle(ref, () => {
|
||||
const refObj = init();
|
||||
const {
|
||||
nativeElement
|
||||
} = refObj;
|
||||
if (typeof Proxy !== 'undefined') {
|
||||
return new Proxy(nativeElement, {
|
||||
get(obj, prop) {
|
||||
if (refObj[prop]) {
|
||||
return refObj[prop];
|
||||
}
|
||||
return Reflect.get(obj, prop);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Fallback of IE
|
||||
return fillProxy(nativeElement, refObj);
|
||||
});
|
||||
};
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
type UseSyncStateProps<T> = readonly [() => T, (newValue: T) => void];
|
||||
export declare const useSyncState: <T>(initialValue: T) => UseSyncStateProps<T>;
|
||||
export {};
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import { useForceUpdate } from './useForceUpdate';
|
||||
export const useSyncState = initialValue => {
|
||||
const ref = React.useRef(initialValue);
|
||||
const [, forceUpdate] = useForceUpdate();
|
||||
return [() => ref.current, newValue => {
|
||||
ref.current = newValue;
|
||||
forceUpdate();
|
||||
}];
|
||||
};
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
export type ZIndexContainer = 'Modal' | 'Drawer' | 'Popover' | 'Popconfirm' | 'Tooltip' | 'Tour' | 'FloatButton';
|
||||
export type ZIndexConsumer = 'SelectLike' | 'Dropdown' | 'DatePicker' | 'Menu' | 'ImagePreview';
|
||||
export declare const CONTAINER_MAX_OFFSET: number;
|
||||
export declare const containerBaseZIndexOffset: Record<ZIndexContainer, number>;
|
||||
export declare const consumerBaseZIndexOffset: Record<ZIndexConsumer, number>;
|
||||
type ReturnResult = [zIndex: number | undefined, contextZIndex: number];
|
||||
export declare const useZIndex: (componentType: ZIndexContainer | ZIndexConsumer, customZIndex?: number) => ReturnResult;
|
||||
export {};
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
import React from 'react';
|
||||
import useToken from '../../theme/useToken';
|
||||
import { devUseWarning } from '../warning';
|
||||
import ZIndexContext from '../zindexContext';
|
||||
// Z-Index control range
|
||||
// Container: 1000 + offset 100 (max base + 10 * offset = 2000)
|
||||
// Popover: offset 50
|
||||
// Notification: Container Max zIndex + componentOffset
|
||||
const CONTAINER_OFFSET = 100;
|
||||
const CONTAINER_OFFSET_MAX_COUNT = 10;
|
||||
export const CONTAINER_MAX_OFFSET = CONTAINER_OFFSET * CONTAINER_OFFSET_MAX_COUNT;
|
||||
/**
|
||||
* Static function will default be the `CONTAINER_MAX_OFFSET`.
|
||||
* But it still may have children component like Select, Dropdown.
|
||||
* So the warning zIndex should exceed the `CONTAINER_MAX_OFFSET`.
|
||||
*/
|
||||
const CONTAINER_MAX_OFFSET_WITH_CHILDREN = CONTAINER_MAX_OFFSET + CONTAINER_OFFSET;
|
||||
export const containerBaseZIndexOffset = {
|
||||
Modal: CONTAINER_OFFSET,
|
||||
Drawer: CONTAINER_OFFSET,
|
||||
Popover: CONTAINER_OFFSET,
|
||||
Popconfirm: CONTAINER_OFFSET,
|
||||
Tooltip: CONTAINER_OFFSET,
|
||||
Tour: CONTAINER_OFFSET,
|
||||
FloatButton: CONTAINER_OFFSET
|
||||
};
|
||||
export const consumerBaseZIndexOffset = {
|
||||
SelectLike: 50,
|
||||
Dropdown: 50,
|
||||
DatePicker: 50,
|
||||
Menu: 50,
|
||||
ImagePreview: 1
|
||||
};
|
||||
const isContainerType = type => {
|
||||
return type in containerBaseZIndexOffset;
|
||||
};
|
||||
export const useZIndex = (componentType, customZIndex) => {
|
||||
const [, token] = useToken();
|
||||
const parentZIndex = React.useContext(ZIndexContext);
|
||||
const isContainer = isContainerType(componentType);
|
||||
let result;
|
||||
if (customZIndex !== undefined) {
|
||||
result = [customZIndex, customZIndex];
|
||||
} else {
|
||||
let zIndex = parentZIndex ?? 0;
|
||||
if (isContainer) {
|
||||
zIndex +=
|
||||
// Use preset token zIndex by default but not stack when has parent container
|
||||
(parentZIndex ? 0 : token.zIndexPopupBase) +
|
||||
// Container offset
|
||||
containerBaseZIndexOffset[componentType];
|
||||
} else {
|
||||
zIndex += consumerBaseZIndexOffset[componentType];
|
||||
}
|
||||
result = [parentZIndex === undefined ? customZIndex : zIndex, zIndex];
|
||||
}
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const warning = devUseWarning(componentType);
|
||||
const maxZIndex = token.zIndexPopupBase + CONTAINER_MAX_OFFSET_WITH_CHILDREN;
|
||||
const currentZIndex = result[0] || 0;
|
||||
process.env.NODE_ENV !== "production" ? warning(customZIndex !== undefined || currentZIndex <= maxZIndex, 'usage', '`zIndex` is over design token `zIndexPopupBase` too much. It may cause unexpected override.') : void 0;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
export declare const isNonNullable: <T>(val: T) => val is NonNullable<T>;
|
||||
export declare const isNumber: (val: any) => val is number;
|
||||
export declare const isString: (val: any) => val is string;
|
||||
export declare const isPlainObject: <T extends object = object>(val: any) => val is T;
|
||||
export declare const isFunction: (val: any) => val is (...args: any[]) => any;
|
||||
export declare const isThenable: <T>(val?: PromiseLike<T>) => val is PromiseLike<T>;
|
||||
export declare const isPrimitive: (val: any) => boolean;
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
export const isNonNullable = val => {
|
||||
return val !== undefined && val !== null;
|
||||
};
|
||||
export const isNumber = val => {
|
||||
return typeof val === 'number' && !Number.isNaN(val);
|
||||
};
|
||||
export const isString = val => {
|
||||
return typeof val === 'string';
|
||||
};
|
||||
export const isPlainObject = val => {
|
||||
return val !== null && typeof val === 'object';
|
||||
};
|
||||
export const isFunction = val => {
|
||||
return typeof val === 'function';
|
||||
};
|
||||
export const isThenable = val => {
|
||||
return isNonNullable(val) && isFunction(val.then);
|
||||
};
|
||||
export const isPrimitive = val => {
|
||||
return typeof val !== 'object' && !isFunction(val) || val === null;
|
||||
};
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import type { CSSMotionProps } from '@rc-component/motion';
|
||||
declare const initCollapseMotion: (rootCls?: string) => CSSMotionProps;
|
||||
declare const _SelectPlacements: readonly ["bottomLeft", "bottomRight", "topLeft", "topRight"];
|
||||
export type SelectCommonPlacement = (typeof _SelectPlacements)[number];
|
||||
declare const getTransitionName: (rootPrefixCls: string, motion: string, transitionName?: string) => string;
|
||||
export { getTransitionName };
|
||||
export default initCollapseMotion;
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
import { defaultPrefixCls } from '../config-provider';
|
||||
import { isPlainObject } from './is';
|
||||
// ================== Collapse Motion ==================
|
||||
const getCollapsedHeight = () => ({
|
||||
height: 0,
|
||||
opacity: 0
|
||||
});
|
||||
const getRealHeight = node => ({
|
||||
height: node?.scrollHeight ?? 0,
|
||||
opacity: node ? 1 : 0
|
||||
});
|
||||
const getCurrentHeight = node => ({
|
||||
height: node?.offsetHeight ?? 0
|
||||
});
|
||||
const isTransitionEvent = event => {
|
||||
return isPlainObject(event) && 'propertyName' in event;
|
||||
};
|
||||
const skipOpacityTransition = (_, event) => {
|
||||
return event?.deadline === true || (isTransitionEvent(event) ? event.propertyName === 'height' : false);
|
||||
};
|
||||
const initCollapseMotion = (rootCls = defaultPrefixCls) => ({
|
||||
motionName: `${rootCls}-motion-collapse`,
|
||||
onAppearStart: getCollapsedHeight,
|
||||
onEnterStart: getCollapsedHeight,
|
||||
onAppearActive: getRealHeight,
|
||||
onEnterActive: getRealHeight,
|
||||
onLeaveStart: getCurrentHeight,
|
||||
onLeaveActive: getCollapsedHeight,
|
||||
onAppearEnd: skipOpacityTransition,
|
||||
onEnterEnd: skipOpacityTransition,
|
||||
onLeaveEnd: skipOpacityTransition,
|
||||
motionDeadline: 500
|
||||
});
|
||||
const _SelectPlacements = ['bottomLeft', 'bottomRight', 'topLeft', 'topRight'];
|
||||
const getTransitionName = (rootPrefixCls, motion, transitionName) => {
|
||||
if (transitionName !== undefined) {
|
||||
return transitionName;
|
||||
}
|
||||
return `${rootPrefixCls}-${motion}`;
|
||||
};
|
||||
export { getTransitionName };
|
||||
export default initCollapseMotion;
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import type { BuildInPlacements } from '@rc-component/trigger';
|
||||
import { getArrowOffsetToken } from '../style/placementArrow';
|
||||
export interface AdjustOverflow {
|
||||
adjustX?: 0 | 1;
|
||||
adjustY?: 0 | 1;
|
||||
}
|
||||
export interface PlacementsConfig {
|
||||
arrowWidth: number;
|
||||
arrowPointAtCenter?: boolean;
|
||||
autoAdjustOverflow?: boolean | AdjustOverflow;
|
||||
offset: number;
|
||||
borderRadius: number;
|
||||
visibleFirst?: boolean;
|
||||
}
|
||||
export declare function getOverflowOptions(placement: string, arrowOffset: ReturnType<typeof getArrowOffsetToken>, arrowWidth: number, autoAdjustOverflow?: boolean | AdjustOverflow): {
|
||||
adjustX?: boolean | number;
|
||||
adjustY?: boolean | number;
|
||||
shiftX?: boolean | number;
|
||||
shiftY?: boolean | number;
|
||||
};
|
||||
export default function getPlacements(config: PlacementsConfig): BuildInPlacements;
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
import { getArrowOffsetToken } from '../style/placementArrow';
|
||||
import { isPlainObject } from './is';
|
||||
export function getOverflowOptions(placement, arrowOffset, arrowWidth, autoAdjustOverflow) {
|
||||
if (autoAdjustOverflow === false) {
|
||||
return {
|
||||
adjustX: false,
|
||||
adjustY: false
|
||||
};
|
||||
}
|
||||
const overflow = isPlainObject(autoAdjustOverflow) ? autoAdjustOverflow : {};
|
||||
const baseOverflow = {};
|
||||
switch (placement) {
|
||||
case 'top':
|
||||
case 'bottom':
|
||||
baseOverflow.shiftX = arrowOffset.arrowOffsetHorizontal * 2 + arrowWidth;
|
||||
baseOverflow.shiftY = true;
|
||||
baseOverflow.adjustY = true;
|
||||
break;
|
||||
case 'left':
|
||||
case 'right':
|
||||
baseOverflow.shiftY = arrowOffset.arrowOffsetVertical * 2 + arrowWidth;
|
||||
baseOverflow.shiftX = true;
|
||||
baseOverflow.adjustX = true;
|
||||
break;
|
||||
}
|
||||
const mergedOverflow = {
|
||||
...baseOverflow,
|
||||
...overflow
|
||||
};
|
||||
// Support auto shift
|
||||
if (!mergedOverflow.shiftX) {
|
||||
mergedOverflow.adjustX = true;
|
||||
}
|
||||
if (!mergedOverflow.shiftY) {
|
||||
mergedOverflow.adjustY = true;
|
||||
}
|
||||
return mergedOverflow;
|
||||
}
|
||||
const PlacementAlignMap = {
|
||||
left: {
|
||||
points: ['cr', 'cl']
|
||||
},
|
||||
right: {
|
||||
points: ['cl', 'cr']
|
||||
},
|
||||
top: {
|
||||
points: ['bc', 'tc']
|
||||
},
|
||||
bottom: {
|
||||
points: ['tc', 'bc']
|
||||
},
|
||||
topLeft: {
|
||||
points: ['bl', 'tl']
|
||||
},
|
||||
leftTop: {
|
||||
points: ['tr', 'tl']
|
||||
},
|
||||
topRight: {
|
||||
points: ['br', 'tr']
|
||||
},
|
||||
rightTop: {
|
||||
points: ['tl', 'tr']
|
||||
},
|
||||
bottomRight: {
|
||||
points: ['tr', 'br']
|
||||
},
|
||||
rightBottom: {
|
||||
points: ['bl', 'br']
|
||||
},
|
||||
bottomLeft: {
|
||||
points: ['tl', 'bl']
|
||||
},
|
||||
leftBottom: {
|
||||
points: ['br', 'bl']
|
||||
}
|
||||
};
|
||||
const ArrowCenterPlacementAlignMap = {
|
||||
topLeft: {
|
||||
points: ['bl', 'tc']
|
||||
},
|
||||
leftTop: {
|
||||
points: ['tr', 'cl']
|
||||
},
|
||||
topRight: {
|
||||
points: ['br', 'tc']
|
||||
},
|
||||
rightTop: {
|
||||
points: ['tl', 'cr']
|
||||
},
|
||||
bottomRight: {
|
||||
points: ['tr', 'bc']
|
||||
},
|
||||
rightBottom: {
|
||||
points: ['bl', 'cr']
|
||||
},
|
||||
bottomLeft: {
|
||||
points: ['tl', 'bc']
|
||||
},
|
||||
leftBottom: {
|
||||
points: ['br', 'cl']
|
||||
}
|
||||
};
|
||||
const DisableAutoArrowList = new Set(['topLeft', 'topRight', 'bottomLeft', 'bottomRight', 'leftTop', 'leftBottom', 'rightTop', 'rightBottom']);
|
||||
export default function getPlacements(config) {
|
||||
const {
|
||||
arrowWidth,
|
||||
autoAdjustOverflow,
|
||||
arrowPointAtCenter,
|
||||
offset,
|
||||
borderRadius,
|
||||
visibleFirst
|
||||
} = config;
|
||||
const halfArrowWidth = arrowWidth / 2;
|
||||
const placementMap = {};
|
||||
// Dynamic offset
|
||||
const arrowOffset = getArrowOffsetToken({
|
||||
contentRadius: borderRadius,
|
||||
limitVerticalRadius: true
|
||||
});
|
||||
Object.keys(PlacementAlignMap).forEach(key => {
|
||||
const template = arrowPointAtCenter && ArrowCenterPlacementAlignMap[key] || PlacementAlignMap[key];
|
||||
const placementInfo = {
|
||||
...template,
|
||||
offset: [0, 0],
|
||||
dynamicInset: true
|
||||
};
|
||||
placementMap[key] = placementInfo;
|
||||
// Disable autoArrow since design is fixed position
|
||||
if (DisableAutoArrowList.has(key)) {
|
||||
placementInfo.autoArrow = false;
|
||||
}
|
||||
// Static offset
|
||||
switch (key) {
|
||||
case 'top':
|
||||
case 'topLeft':
|
||||
case 'topRight':
|
||||
placementInfo.offset[1] = -halfArrowWidth - offset;
|
||||
break;
|
||||
case 'bottom':
|
||||
case 'bottomLeft':
|
||||
case 'bottomRight':
|
||||
placementInfo.offset[1] = halfArrowWidth + offset;
|
||||
break;
|
||||
case 'left':
|
||||
case 'leftTop':
|
||||
case 'leftBottom':
|
||||
placementInfo.offset[0] = -halfArrowWidth - offset;
|
||||
break;
|
||||
case 'right':
|
||||
case 'rightTop':
|
||||
case 'rightBottom':
|
||||
placementInfo.offset[0] = halfArrowWidth + offset;
|
||||
break;
|
||||
}
|
||||
if (arrowPointAtCenter) {
|
||||
switch (key) {
|
||||
case 'topLeft':
|
||||
case 'bottomLeft':
|
||||
placementInfo.offset[0] = -arrowOffset.arrowOffsetHorizontal - halfArrowWidth;
|
||||
break;
|
||||
case 'topRight':
|
||||
case 'bottomRight':
|
||||
placementInfo.offset[0] = arrowOffset.arrowOffsetHorizontal + halfArrowWidth;
|
||||
break;
|
||||
case 'leftTop':
|
||||
case 'rightTop':
|
||||
placementInfo.offset[1] = -arrowOffset.arrowOffsetHorizontal * 2 + halfArrowWidth;
|
||||
break;
|
||||
case 'leftBottom':
|
||||
case 'rightBottom':
|
||||
placementInfo.offset[1] = arrowOffset.arrowOffsetHorizontal * 2 - halfArrowWidth;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Overflow
|
||||
placementInfo.overflow = getOverflowOptions(key, arrowOffset, arrowWidth, autoAdjustOverflow);
|
||||
// VisibleFirst
|
||||
if (visibleFirst) {
|
||||
placementInfo.htmlRegion = 'visibleFirst';
|
||||
}
|
||||
});
|
||||
return placementMap;
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import React from 'react';
|
||||
import type { AnyObject } from './type';
|
||||
export declare function isFragment(child: any): boolean;
|
||||
type RenderProps = AnyObject | ((originProps: AnyObject) => AnyObject | undefined);
|
||||
export declare const replaceElement: <P>(element: React.ReactNode, replacement: React.ReactNode, props?: RenderProps) => React.ReactNode;
|
||||
export declare function cloneElement<P>(element: React.ReactNode, props?: RenderProps): React.ReactElement<P>;
|
||||
export {};
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import { isFunction } from './is';
|
||||
export function isFragment(child) {
|
||||
return child && /*#__PURE__*/React.isValidElement(child) && child.type === React.Fragment;
|
||||
}
|
||||
export const replaceElement = (element, replacement, props) => {
|
||||
if (! /*#__PURE__*/React.isValidElement(element)) {
|
||||
return replacement;
|
||||
}
|
||||
return /*#__PURE__*/React.cloneElement(element, isFunction(props) ? props(element.props || {}) : props);
|
||||
};
|
||||
export function cloneElement(element, props) {
|
||||
return replaceElement(element, element, props);
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
export declare const responsiveArray: readonly ["xxxl", "xxl", "xl", "lg", "md", "sm", "xs"];
|
||||
export declare const responsiveArrayReversed: ("xs" | "sm" | "md" | "lg" | "xl" | "xxl" | "xxxl")[];
|
||||
export type Breakpoint = (typeof responsiveArray)[number];
|
||||
export type BreakpointMap = Record<Breakpoint, string>;
|
||||
export type ScreenMap = Partial<Record<Breakpoint, boolean>>;
|
||||
export type ScreenSizeMap = Partial<Record<Breakpoint, number>>;
|
||||
type SubscribeFunc = (screens: ScreenMap) => void;
|
||||
export declare const matchScreen: (screens: ScreenMap, screenSizes?: ScreenSizeMap) => number | undefined;
|
||||
interface ResponsiveObserverType {
|
||||
responsiveMap: BreakpointMap;
|
||||
dispatch: (map: ScreenMap) => boolean;
|
||||
subscribe: (func: SubscribeFunc) => number;
|
||||
unsubscribe: (token: number) => void;
|
||||
register: () => void;
|
||||
unregister: () => void;
|
||||
matchHandlers: Record<PropertyKey, {
|
||||
mql: MediaQueryList;
|
||||
listener: (this: MediaQueryList, ev: MediaQueryListEvent) => void;
|
||||
}>;
|
||||
}
|
||||
declare const useResponsiveObserver: () => ResponsiveObserverType;
|
||||
export default useResponsiveObserver;
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
import React from 'react';
|
||||
import { useToken } from '../theme/internal';
|
||||
export const responsiveArray = ['xxxl', 'xxl', 'xl', 'lg', 'md', 'sm', 'xs'];
|
||||
export const responsiveArrayReversed = [].concat(responsiveArray).reverse();
|
||||
const getResponsiveMap = token => ({
|
||||
xs: `(max-width: ${token.screenXSMax}px)`,
|
||||
sm: `(min-width: ${token.screenSM}px)`,
|
||||
md: `(min-width: ${token.screenMD}px)`,
|
||||
lg: `(min-width: ${token.screenLG}px)`,
|
||||
xl: `(min-width: ${token.screenXL}px)`,
|
||||
xxl: `(min-width: ${token.screenXXL}px)`,
|
||||
xxxl: `(min-width: ${token.screenXXXL}px)`
|
||||
});
|
||||
/**
|
||||
* Ensures that the breakpoints token are valid, in good order
|
||||
* For each breakpoint : screenMin <= screen <= screenMax and screenMax <= nextScreenMin
|
||||
*/
|
||||
const validateBreakpoints = token => {
|
||||
const indexableToken = token;
|
||||
const revBreakpoints = [].concat(responsiveArray).reverse();
|
||||
revBreakpoints.forEach((breakpoint, i) => {
|
||||
const breakpointUpper = breakpoint.toUpperCase();
|
||||
const screenMin = `screen${breakpointUpper}Min`;
|
||||
const screen = `screen${breakpointUpper}`;
|
||||
if (!(indexableToken[screenMin] <= indexableToken[screen])) {
|
||||
throw new Error(`${screenMin}<=${screen} fails : !(${indexableToken[screenMin]}<=${indexableToken[screen]})`);
|
||||
}
|
||||
if (i < revBreakpoints.length - 1) {
|
||||
const screenMax = `screen${breakpointUpper}Max`;
|
||||
if (!(indexableToken[screen] <= indexableToken[screenMax])) {
|
||||
throw new Error(`${screen}<=${screenMax} fails : !(${indexableToken[screen]}<=${indexableToken[screenMax]})`);
|
||||
}
|
||||
const nextBreakpointUpperMin = revBreakpoints[i + 1].toUpperCase();
|
||||
const nextScreenMin = `screen${nextBreakpointUpperMin}Min`;
|
||||
if (!(indexableToken[screenMax] <= indexableToken[nextScreenMin])) {
|
||||
throw new Error(`${screenMax}<=${nextScreenMin} fails : !(${indexableToken[screenMax]}<=${indexableToken[nextScreenMin]})`);
|
||||
}
|
||||
}
|
||||
});
|
||||
return token;
|
||||
};
|
||||
export const matchScreen = (screens, screenSizes) => {
|
||||
if (!screenSizes) {
|
||||
return;
|
||||
}
|
||||
for (const breakpoint of responsiveArray) {
|
||||
if (screens[breakpoint] && screenSizes?.[breakpoint] !== undefined) {
|
||||
return screenSizes[breakpoint];
|
||||
}
|
||||
}
|
||||
};
|
||||
const useResponsiveObserver = () => {
|
||||
const [, token] = useToken();
|
||||
const responsiveMap = getResponsiveMap(validateBreakpoints(token));
|
||||
// To avoid repeat create instance, we add `useMemo` here.
|
||||
return React.useMemo(() => {
|
||||
const subscribers = new Map();
|
||||
let subUid = -1;
|
||||
let screens = {};
|
||||
return {
|
||||
responsiveMap,
|
||||
matchHandlers: {},
|
||||
dispatch(pointMap) {
|
||||
screens = pointMap;
|
||||
subscribers.forEach(func => {
|
||||
func(screens);
|
||||
});
|
||||
return subscribers.size >= 1;
|
||||
},
|
||||
subscribe(func) {
|
||||
if (!subscribers.size) {
|
||||
this.register();
|
||||
}
|
||||
subUid += 1;
|
||||
subscribers.set(subUid, func);
|
||||
func(screens);
|
||||
return subUid;
|
||||
},
|
||||
unsubscribe(paramToken) {
|
||||
subscribers.delete(paramToken);
|
||||
if (!subscribers.size) {
|
||||
this.unregister();
|
||||
}
|
||||
},
|
||||
register() {
|
||||
Object.entries(responsiveMap).forEach(([screen, mediaQuery]) => {
|
||||
const listener = ({
|
||||
matches
|
||||
}) => {
|
||||
this.dispatch({
|
||||
...screens,
|
||||
[screen]: matches
|
||||
});
|
||||
};
|
||||
const mql = window.matchMedia(mediaQuery);
|
||||
if (typeof mql?.addEventListener === 'function') {
|
||||
mql.addEventListener('change', listener);
|
||||
}
|
||||
this.matchHandlers[mediaQuery] = {
|
||||
mql,
|
||||
listener
|
||||
};
|
||||
listener(mql);
|
||||
});
|
||||
},
|
||||
unregister() {
|
||||
Object.values(responsiveMap).forEach(mediaQuery => {
|
||||
const handler = this.matchHandlers[mediaQuery];
|
||||
if (typeof handler?.mql?.removeEventListener === 'function') {
|
||||
handler.mql.removeEventListener('change', handler?.listener);
|
||||
}
|
||||
});
|
||||
subscribers.clear();
|
||||
}
|
||||
};
|
||||
}, [responsiveMap]);
|
||||
};
|
||||
export default useResponsiveObserver;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
interface ScrollToOptions {
|
||||
/** Scroll container, default as window */
|
||||
getContainer?: () => HTMLElement | Window | Document;
|
||||
/** Scroll end callback */
|
||||
callback?: () => void;
|
||||
/** Animation duration, default as 450 */
|
||||
duration?: number;
|
||||
}
|
||||
export default function scrollTo(y: number, options?: ScrollToOptions): () => void;
|
||||
export {};
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
import raf from "@rc-component/util/es/raf";
|
||||
import { easeInOutCubic } from './easings';
|
||||
import getScroll, { isWindow } from './getScroll';
|
||||
export default function scrollTo(y, options = {}) {
|
||||
const {
|
||||
getContainer = () => window,
|
||||
callback,
|
||||
duration = 450
|
||||
} = options;
|
||||
const container = getContainer();
|
||||
const scrollTop = getScroll(container);
|
||||
const startTime = Date.now();
|
||||
let rafId;
|
||||
const frameFunc = () => {
|
||||
const timestamp = Date.now();
|
||||
const time = timestamp - startTime;
|
||||
const nextScrollTop = easeInOutCubic(time > duration ? duration : time, scrollTop, y, duration);
|
||||
if (isWindow(container)) {
|
||||
container.scrollTo(window.pageXOffset, nextScrollTop);
|
||||
} else if (container instanceof Document || container.constructor.name === 'HTMLDocument') {
|
||||
container.documentElement.scrollTop = nextScrollTop;
|
||||
} else {
|
||||
container.scrollTop = nextScrollTop;
|
||||
}
|
||||
if (time < duration) {
|
||||
rafId = raf(frameFunc);
|
||||
} else if (typeof callback === 'function') {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
rafId = raf(frameFunc);
|
||||
return () => {
|
||||
raf.cancel(rafId);
|
||||
};
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import type { ValidateStatus } from '../form/FormItem';
|
||||
declare const _InputStatuses: readonly ["warning", "error", "", "success", "validating"];
|
||||
export type InputStatus = (typeof _InputStatuses)[number];
|
||||
export declare const getStatusClassNames: (prefixCls: string, status?: ValidateStatus, hasFeedback?: boolean) => string;
|
||||
export declare const getMergedStatus: (contextStatus?: ValidateStatus, customStatus?: InputStatus) => "" | "success" | "error" | "warning" | "validating" | undefined;
|
||||
export {};
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import { clsx } from 'clsx';
|
||||
const _InputStatuses = ['warning', 'error', '', 'success', 'validating'];
|
||||
export const getStatusClassNames = (prefixCls, status, hasFeedback) => {
|
||||
return clsx({
|
||||
[`${prefixCls}-status-success`]: status === 'success',
|
||||
[`${prefixCls}-status-warning`]: status === 'warning',
|
||||
[`${prefixCls}-status-error`]: status === 'error',
|
||||
[`${prefixCls}-status-validating`]: status === 'validating',
|
||||
[`${prefixCls}-has-feedback`]: hasFeedback
|
||||
});
|
||||
};
|
||||
export const getMergedStatus = (contextStatus, customStatus) => customStatus || contextStatus;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import { isStyleSupport } from '@rc-component/util/lib/Dom/styleChecker';
|
||||
export declare const canUseDocElement: () => false | HTMLElement;
|
||||
export { isStyleSupport };
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import canUseDom from "@rc-component/util/es/Dom/canUseDom";
|
||||
import { isStyleSupport } from "@rc-component/util/es/Dom/styleChecker";
|
||||
export const canUseDocElement = () => canUseDom() && window.document.documentElement;
|
||||
export { isStyleSupport };
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
declare function throttleByAnimationFrame<T extends any[]>(fn: (...args: T) => void): {
|
||||
(...args: T): void;
|
||||
cancel(): void;
|
||||
};
|
||||
export default throttleByAnimationFrame;
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
||||
import raf from "@rc-component/util/es/raf";
|
||||
function throttleByAnimationFrame(fn) {
|
||||
let requestId = null;
|
||||
const later = args => () => {
|
||||
requestId = null;
|
||||
fn.apply(void 0, _toConsumableArray(args));
|
||||
};
|
||||
const throttled = (...args) => {
|
||||
if (requestId === null) {
|
||||
requestId = raf(later(args));
|
||||
}
|
||||
};
|
||||
throttled.cancel = () => {
|
||||
raf.cancel(requestId);
|
||||
requestId = null;
|
||||
};
|
||||
return throttled;
|
||||
}
|
||||
export default throttleByAnimationFrame;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
interface Config {
|
||||
skipEmpty?: boolean;
|
||||
}
|
||||
declare const toList: <T>(val: T | T[], config?: Config) => T[];
|
||||
export default toList;
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import { isNonNullable } from './is';
|
||||
const toList = (val, config = {}) => {
|
||||
if (!isNonNullable(val) && config?.skipEmpty) {
|
||||
return [];
|
||||
}
|
||||
return Array.isArray(val) ? val : [val];
|
||||
};
|
||||
export default toList;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import type { TransferKey } from '../transfer/interface';
|
||||
export declare const groupKeysMap: (keys: TransferKey[]) => Map<import("react").Key, number>;
|
||||
export declare const groupDisabledKeysMap: <RecordType extends any[]>(dataSource: RecordType) => Map<import("react").Key, number>;
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
export const groupKeysMap = keys => {
|
||||
const map = new Map();
|
||||
keys.forEach((key, index) => {
|
||||
map.set(key, index);
|
||||
});
|
||||
return map;
|
||||
};
|
||||
export const groupDisabledKeysMap = dataSource => {
|
||||
const map = new Map();
|
||||
dataSource.forEach(({
|
||||
disabled,
|
||||
key
|
||||
}, index) => {
|
||||
if (disabled) {
|
||||
map.set(key, index);
|
||||
}
|
||||
});
|
||||
return map;
|
||||
};
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
import type React from 'react';
|
||||
export type Primitive = null | undefined | string | number | boolean | symbol | bigint;
|
||||
/** https://github.com/Microsoft/TypeScript/issues/29729 */
|
||||
export type LiteralUnion<T, U extends Primitive = string> = T | (U & Record<never, never>);
|
||||
export type AnyObject = Record<PropertyKey, any>;
|
||||
export type EmptyObject = Record<never, never>;
|
||||
export type CustomComponent<P = AnyObject> = React.ComponentType<P> | string;
|
||||
/**
|
||||
* Get component props
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Checkbox } from 'antd'
|
||||
* import type { GetProps } from 'antd';
|
||||
*
|
||||
* type CheckboxGroupProps = GetProps<typeof Checkbox.Group>
|
||||
*
|
||||
* const MyContext = React.createContext<{ sample?: boolean }>({});
|
||||
* type MyContextProps = GetProps<typeof MyContext>;
|
||||
*
|
||||
* ```
|
||||
* @since 5.13.0
|
||||
*/
|
||||
export type GetProps<T extends React.ComponentType<any> | object> = T extends React.Context<infer CP> ? CP : T extends React.ComponentType<infer P> ? P : T extends object ? T : never;
|
||||
/**
|
||||
* Get component props by component name
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Select } from 'antd';
|
||||
* import type { GetProp, SelectProps } from 'antd';
|
||||
*
|
||||
* type SelectOption1 = GetProp<SelectProps, 'options'>[number];
|
||||
* // or
|
||||
* type SelectOption2 = GetProp<typeof Select, 'options'>[number];
|
||||
*
|
||||
* const onChange: GetProp<typeof Select, 'onChange'> = (value, option) => {
|
||||
* // Do something
|
||||
* };
|
||||
* ```
|
||||
* @since 5.13.0
|
||||
*/
|
||||
export type GetProp<T extends React.ComponentType<any> | object, PropName extends keyof GetProps<T>> = NonNullable<GetProps<T>[PropName]>;
|
||||
type ReactRefComponent<Props extends {
|
||||
ref?: React.Ref<any> | string;
|
||||
}> = (props: Props) => React.ReactNode;
|
||||
type ExtractRefAttributesRef<T> = T extends React.RefAttributes<infer P> ? P : never;
|
||||
/**
|
||||
* Get component ref
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Input } from 'antd';
|
||||
* import type { GetRef } from 'antd';
|
||||
*
|
||||
* type InputRef = GetRef<typeof Input>;
|
||||
* ```
|
||||
* @since 5.13.0
|
||||
*/
|
||||
export type GetRef<T extends ReactRefComponent<any> | React.Component<any>> = T extends React.Component<any> ? T : T extends React.ComponentType<infer P> ? ExtractRefAttributesRef<P> : never;
|
||||
export type ValidChar = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z';
|
||||
export {};
|
||||
+1
@@ -0,0 +1 @@
|
||||
export {};
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
import * as React from 'react';
|
||||
export declare function noop(): void;
|
||||
export declare function resetWarned(): void;
|
||||
type Warning = (valid: boolean, component: string, message?: string) => void;
|
||||
declare const warning: Warning;
|
||||
type BaseTypeWarning = (valid: boolean,
|
||||
/**
|
||||
* - deprecated: Some API will be removed in future but still support now.
|
||||
* - usage: Some API usage is not correct.
|
||||
* - breaking: Breaking change like API is removed.
|
||||
*/
|
||||
type: 'deprecated' | 'usage' | 'breaking', message?: string) => void;
|
||||
type TypeWarning = BaseTypeWarning & {
|
||||
deprecated: (valid: boolean, oldProp: string, newProp: string, message?: string) => void;
|
||||
};
|
||||
export interface WarningContextProps {
|
||||
/**
|
||||
* @descCN 设置警告等级,设置 `false` 时会将废弃相关信息聚合为单条信息。
|
||||
* @descEN Set the warning level. When set to `false`, discard related information will be aggregated into a single message.
|
||||
* @since 5.10.0
|
||||
*/
|
||||
strict?: boolean;
|
||||
}
|
||||
export declare const WarningContext: React.Context<WarningContextProps>;
|
||||
/**
|
||||
* This is a hook but we not named as `useWarning`
|
||||
* since this is only used in development.
|
||||
* We should always wrap this in `if (process.env.NODE_ENV !== 'production')` condition
|
||||
*/
|
||||
export declare const devUseWarning: (component: string) => TypeWarning;
|
||||
export default warning;
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
import * as React from 'react';
|
||||
import { warning as rcWarning } from '@rc-component/util';
|
||||
export function noop() {}
|
||||
const {
|
||||
resetWarned: rcResetWarned
|
||||
} = rcWarning;
|
||||
let deprecatedWarnList = null;
|
||||
export function resetWarned() {
|
||||
deprecatedWarnList = null;
|
||||
rcResetWarned();
|
||||
}
|
||||
let _warning = noop;
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
_warning = (valid, component, message) => {
|
||||
rcWarning(valid, `[antd: ${component}] ${message}`);
|
||||
// StrictMode will inject console which will not throw warning in React 17.
|
||||
if (process.env.NODE_ENV === 'test') {
|
||||
resetWarned();
|
||||
}
|
||||
};
|
||||
}
|
||||
const warning = _warning;
|
||||
export const WarningContext = /*#__PURE__*/React.createContext({});
|
||||
/**
|
||||
* This is a hook but we not named as `useWarning`
|
||||
* since this is only used in development.
|
||||
* We should always wrap this in `if (process.env.NODE_ENV !== 'production')` condition
|
||||
*/
|
||||
export const devUseWarning = process.env.NODE_ENV !== 'production' ? component => {
|
||||
const {
|
||||
strict
|
||||
} = React.useContext(WarningContext);
|
||||
const typeWarning = (valid, type, message) => {
|
||||
if (!valid) {
|
||||
if (strict === false && type === 'deprecated') {
|
||||
const existWarning = deprecatedWarnList;
|
||||
if (!deprecatedWarnList) {
|
||||
deprecatedWarnList = {};
|
||||
}
|
||||
deprecatedWarnList[component] = deprecatedWarnList[component] || [];
|
||||
if (!deprecatedWarnList[component].includes(message || '')) {
|
||||
deprecatedWarnList[component].push(message || '');
|
||||
}
|
||||
// Warning for the first time
|
||||
if (!existWarning) {
|
||||
console.warn('[antd] There exists deprecated usage in your code:', deprecatedWarnList);
|
||||
}
|
||||
} else {
|
||||
process.env.NODE_ENV !== "production" ? warning(valid, component, message) : void 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
typeWarning.deprecated = (valid, oldProp, newProp, message = '') => {
|
||||
typeWarning(valid, 'deprecated', `\`${oldProp}\` is deprecated. Please use \`${newProp}\` instead.${message ? ` ${message}` : ''}`);
|
||||
};
|
||||
return typeWarning;
|
||||
} : () => {
|
||||
const noopWarning = () => {};
|
||||
noopWarning.deprecated = noop;
|
||||
return noopWarning;
|
||||
};
|
||||
export default warning;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import type { WaveProps } from '.';
|
||||
import type { ShowWaveEffect } from './interface';
|
||||
export interface WaveEffectProps {
|
||||
className: string;
|
||||
target: HTMLElement;
|
||||
component?: string;
|
||||
colorSource?: WaveProps['colorSource'];
|
||||
}
|
||||
declare const showWaveEffect: ShowWaveEffect;
|
||||
export default showWaveEffect;
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
"use client";
|
||||
|
||||
import * as React from 'react';
|
||||
import CSSMotion from '@rc-component/motion';
|
||||
import raf from "@rc-component/util/es/raf";
|
||||
import { render, unmount } from "@rc-component/util/es/React/render";
|
||||
import { composeRef } from "@rc-component/util/es/ref";
|
||||
import { clsx } from 'clsx';
|
||||
import { ConfigContext } from '../../config-provider';
|
||||
import { genCssVar } from '../../theme/util/genStyleUtils';
|
||||
import { TARGET_CLS } from './interface';
|
||||
import { getTargetWaveColor } from './util';
|
||||
function validateNum(value) {
|
||||
return Number.isNaN(value) ? 0 : value;
|
||||
}
|
||||
const WaveEffect = props => {
|
||||
const {
|
||||
className,
|
||||
target,
|
||||
component,
|
||||
colorSource
|
||||
} = props;
|
||||
const divRef = React.useRef(null);
|
||||
const {
|
||||
getPrefixCls
|
||||
} = React.useContext(ConfigContext);
|
||||
const rootPrefixCls = getPrefixCls();
|
||||
const [varName] = genCssVar(rootPrefixCls, 'wave');
|
||||
// ===================== Effect =====================
|
||||
const [waveColor, setWaveColor] = React.useState(null);
|
||||
const [borderRadius, setBorderRadius] = React.useState([]);
|
||||
const [left, setLeft] = React.useState(0);
|
||||
const [top, setTop] = React.useState(0);
|
||||
const [width, setWidth] = React.useState(0);
|
||||
const [height, setHeight] = React.useState(0);
|
||||
const [enabled, setEnabled] = React.useState(false);
|
||||
const waveStyle = {
|
||||
left,
|
||||
top,
|
||||
width,
|
||||
height,
|
||||
borderRadius: borderRadius.map(radius => `${radius}px`).join(' ')
|
||||
};
|
||||
if (waveColor) {
|
||||
waveStyle[varName('color')] = waveColor;
|
||||
}
|
||||
function syncPos() {
|
||||
const nodeStyle = getComputedStyle(target);
|
||||
// Get wave color from target
|
||||
setWaveColor(getTargetWaveColor(target, colorSource));
|
||||
const isStatic = nodeStyle.position === 'static';
|
||||
// Rect
|
||||
const {
|
||||
borderLeftWidth,
|
||||
borderTopWidth
|
||||
} = nodeStyle;
|
||||
setLeft(isStatic ? target.offsetLeft : validateNum(-Number.parseFloat(borderLeftWidth)));
|
||||
setTop(isStatic ? target.offsetTop : validateNum(-Number.parseFloat(borderTopWidth)));
|
||||
setWidth(target.offsetWidth);
|
||||
setHeight(target.offsetHeight);
|
||||
// Get border radius
|
||||
const {
|
||||
borderTopLeftRadius,
|
||||
borderTopRightRadius,
|
||||
borderBottomLeftRadius,
|
||||
borderBottomRightRadius
|
||||
} = nodeStyle;
|
||||
setBorderRadius([borderTopLeftRadius, borderTopRightRadius, borderBottomRightRadius, borderBottomLeftRadius].map(radius => validateNum(Number.parseFloat(radius))));
|
||||
}
|
||||
React.useEffect(() => {
|
||||
if (target) {
|
||||
// We need delay to check position here
|
||||
// since UI may change after click
|
||||
const id = raf(() => {
|
||||
syncPos();
|
||||
setEnabled(true);
|
||||
});
|
||||
// Add resize observer to follow size
|
||||
let resizeObserver;
|
||||
if (typeof ResizeObserver !== 'undefined') {
|
||||
resizeObserver = new ResizeObserver(syncPos);
|
||||
resizeObserver.observe(target);
|
||||
}
|
||||
return () => {
|
||||
raf.cancel(id);
|
||||
resizeObserver?.disconnect();
|
||||
};
|
||||
}
|
||||
}, [target]);
|
||||
if (!enabled) {
|
||||
return null;
|
||||
}
|
||||
const isSmallComponent = (component === 'Checkbox' || component === 'Radio') && target?.classList.contains(TARGET_CLS);
|
||||
return /*#__PURE__*/React.createElement(CSSMotion, {
|
||||
visible: true,
|
||||
motionAppear: true,
|
||||
motionName: "wave-motion",
|
||||
motionDeadline: 5000,
|
||||
onAppearEnd: (_, event) => {
|
||||
if (event.deadline || event.propertyName === 'opacity') {
|
||||
const holder = divRef.current?.parentElement;
|
||||
unmount(holder).then(() => {
|
||||
holder?.remove();
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}, ({
|
||||
className: motionClassName
|
||||
}, ref) => (/*#__PURE__*/React.createElement("div", {
|
||||
ref: composeRef(divRef, ref),
|
||||
className: clsx(className, motionClassName, {
|
||||
'wave-quick': isSmallComponent
|
||||
}),
|
||||
style: waveStyle
|
||||
})));
|
||||
};
|
||||
const showWaveEffect = (target, info) => {
|
||||
const {
|
||||
component
|
||||
} = info;
|
||||
// Skip for unchecked checkbox
|
||||
if (component === 'Checkbox' && !target.querySelector('input')?.checked) {
|
||||
return;
|
||||
}
|
||||
// Create holder
|
||||
const holder = document.createElement('div');
|
||||
holder.style.position = 'absolute';
|
||||
holder.style.left = '0px';
|
||||
holder.style.top = '0px';
|
||||
target?.insertBefore(holder, target?.firstChild);
|
||||
render(/*#__PURE__*/React.createElement(WaveEffect, {
|
||||
...info,
|
||||
target: target
|
||||
}), holder);
|
||||
};
|
||||
export default showWaveEffect;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import type { WaveComponent } from './interface';
|
||||
export interface WaveProps {
|
||||
disabled?: boolean;
|
||||
children?: React.ReactNode;
|
||||
component?: WaveComponent;
|
||||
colorSource?: 'color' | 'backgroundColor' | 'borderColor' | null;
|
||||
}
|
||||
declare const Wave: React.FC<WaveProps>;
|
||||
export default Wave;
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
import React, { useContext, useRef } from 'react';
|
||||
import isVisible from "@rc-component/util/es/Dom/isVisible";
|
||||
import { composeRef, getNodeRef, supportRef } from "@rc-component/util/es/ref";
|
||||
import { clsx } from 'clsx';
|
||||
import { ConfigContext } from '../../config-provider';
|
||||
import { cloneElement } from '../reactNode';
|
||||
import useStyle from './style';
|
||||
import useWave from './useWave';
|
||||
const Wave = props => {
|
||||
const {
|
||||
children,
|
||||
disabled,
|
||||
component,
|
||||
colorSource
|
||||
} = props;
|
||||
const {
|
||||
getPrefixCls
|
||||
} = useContext(ConfigContext);
|
||||
const containerRef = useRef(null);
|
||||
// ============================== Style ===============================
|
||||
const prefixCls = getPrefixCls('wave');
|
||||
const hashId = useStyle(prefixCls);
|
||||
// =============================== Wave ===============================
|
||||
const showWave = useWave(containerRef, clsx(prefixCls, hashId), component, colorSource);
|
||||
// ============================== Effect ==============================
|
||||
React.useEffect(() => {
|
||||
const node = containerRef.current;
|
||||
if (!node || node.nodeType !== window.Node.ELEMENT_NODE || disabled) {
|
||||
return;
|
||||
}
|
||||
// Click handler
|
||||
const onClick = e => {
|
||||
// Fix radio button click twice
|
||||
if (!isVisible(e.target) ||
|
||||
// No need wave
|
||||
!node.getAttribute || node.getAttribute('disabled') || node.disabled || node.className.includes('disabled') && !node.className.includes('disabled:') || node.getAttribute('aria-disabled') === 'true' || node.className.includes('-leave')) {
|
||||
return;
|
||||
}
|
||||
showWave(e);
|
||||
};
|
||||
// Bind events
|
||||
node.addEventListener('click', onClick, true);
|
||||
return () => {
|
||||
node.removeEventListener('click', onClick, true);
|
||||
};
|
||||
}, [disabled]);
|
||||
// ============================== Render ==============================
|
||||
if (! /*#__PURE__*/React.isValidElement(children)) {
|
||||
return children ?? null;
|
||||
}
|
||||
const ref = supportRef(children) ? composeRef(getNodeRef(children), containerRef) : containerRef;
|
||||
return cloneElement(children, {
|
||||
ref
|
||||
});
|
||||
};
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
Wave.displayName = 'Wave';
|
||||
}
|
||||
export default Wave;
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import type { WaveProps } from '.';
|
||||
import type { GlobalToken } from '../../theme/internal';
|
||||
export declare const TARGET_CLS = "ant-wave-target";
|
||||
export type ShowWaveEffect = (element: HTMLElement, info: {
|
||||
className: string;
|
||||
token: GlobalToken;
|
||||
component?: WaveComponent;
|
||||
event: MouseEvent;
|
||||
hashId: string;
|
||||
colorSource?: WaveProps['colorSource'];
|
||||
}) => void;
|
||||
export type ShowWave = (event: MouseEvent) => void;
|
||||
export type WaveComponent = 'Tag' | 'Button' | 'Checkbox' | 'Radio' | 'Switch' | 'Steps';
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import { defaultPrefixCls } from '../../config-provider';
|
||||
export const TARGET_CLS = `${defaultPrefixCls}-wave-target`;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import type { FullToken } from '../../theme/internal';
|
||||
export interface ComponentToken {
|
||||
}
|
||||
export interface WaveToken extends FullToken<'Wave'> {
|
||||
}
|
||||
declare const _default: (prefixCls: string, rootCls?: string) => string;
|
||||
export default _default;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user