This commit is contained in:
2026-05-25 17:08:18 +08:00
parent df501f6151
commit f1259b71b5
9178 changed files with 1626125 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
The MIT License (MIT)
Copyright (c) 2014-present yiminghe
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.
+74
View File
@@ -0,0 +1,74 @@
# rc-switch
---
Switch ui component for react.
[![NPM version][npm-image]][npm-url]
[![npm download][download-image]][download-url]
[![build status][github-actions-image]][github-actions-url]
[![Test coverage][codecov-image]][codecov-url]
[![bundle size][bundlephobia-image]][bundlephobia-url]
[npm-image]: http://img.shields.io/npm/v/rc-switch.svg?style=flat-square
[npm-url]: http://npmjs.org/package/rc-switch
[travis-image]: https://img.shields.io/travis/react-component/switch/master?style=flat-square
[travis-url]: https://travis-ci.com/react-component/switch
[github-actions-image]: https://github.com/react-component/switch/workflows/CI/badge.svg
[github-actions-url]: https://github.com/react-component/switch/actions
[codecov-image]: https://img.shields.io/codecov/c/github/react-component/switch/master.svg?style=flat-square
[codecov-url]: https://app.codecov.io/gh/react-component/switch
[david-url]: https://david-dm.org/react-component/switch
[david-image]: https://david-dm.org/react-component/switch/status.svg?style=flat-square
[david-dev-url]: https://david-dm.org/react-component/switch?type=dev
[david-dev-image]: https://david-dm.org/react-component/switch/dev-status.svg?style=flat-square
[download-image]: https://img.shields.io/npm/dm/rc-switch.svg?style=flat-square
[download-url]: https://npmjs.org/package/rc-switch
[bundlephobia-url]: https://bundlephobia.com/package/rc-switch
[bundlephobia-image]: https://badgen.net/bundlephobia/minzip/rc-switch
## Install
[![rc-switch](https://nodei.co/npm/rc-switch.png)](https://npmjs.org/package/rc-switch)
## Usage
```js
import Switch from 'rc-switch';
export default () => <Switch />;
```
## Compatibility
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://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" />](http://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" />](http://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" />](http://godban.github.io/browsers-support-badges/)<br>Electron |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
## API
| Property | Type | Default | Description |
| -------------- | ------------------------ | --------- | -------------------------------------------------------- |
| prefixCls | String | rc-switch | |
| className | String | '' | additional class name of root node |
| checked | boolean | false | whether switch is checked |
| defaultChecked | boolean | false | whether switch is checked on init |
| onChange | Function(checked, event) | | called when switch is checked or unchecked |
| tabIndex | number | | tab-index of switch node |
| onClick | Function(checked, event) | | called when switch is clicked |
| autoFocus | boolean | | get focus when mounts |
| disabled | boolean | false | whether switch is disabled |
| loadingIcon | React.ReactNode | | specific the extra node. generally used in loading icon. |
## Development
```
npm install
npm start
```
Online demo: http://react-component.github.io/switch/
## License
rc-switch is released under the MIT license.
+111
View File
@@ -0,0 +1,111 @@
.rc-switch {
position: relative;
display: inline-block;
box-sizing: border-box;
width: 44px;
height: 22px;
line-height: 20px;
padding: 0;
vertical-align: middle;
border-radius: 20px 20px;
border: 1px solid #ccc;
background-color: #ccc;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.35, 0, 0.25, 1);
overflow: hidden;
}
.rc-switch-inner-checked,
.rc-switch-inner-unchecked {
color: #fff;
font-size: 12px;
position: absolute;
top: 0;
transition: left 0.3s cubic-bezier(0.35, 0, 0.25, 1);
}
.rc-switch-inner-checked {
left: -14px;
}
.rc-switch-inner-unchecked {
left: 24px;
}
.rc-switch:after {
position: absolute;
width: 18px;
height: 18px;
left: 2px;
top: 1px;
border-radius: 50% 50%;
background-color: #fff;
content: " ";
cursor: pointer;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.26);
transform: scale(1);
transition: left 0.3s cubic-bezier(0.35, 0, 0.25, 1);
animation-timing-function: cubic-bezier(0.35, 0, 0.25, 1);
animation-duration: 0.3s;
animation-name: rcSwitchOff;
}
.rc-switch:hover:after {
transform: scale(1.1);
animation-name: rcSwitchOn;
}
.rc-switch:focus {
box-shadow: 0 0 0 2px #d5f1fd;
outline: none;
}
.rc-switch-checked {
border: 1px solid #87d068;
background-color: #87d068;
}
.rc-switch-checked .rc-switch-inner-checked {
left: 6px;
}
.rc-switch-checked .rc-switch-inner-unchecked {
left: 44px;
}
.rc-switch-checked:after {
left: 22px;
}
.rc-switch-disabled {
cursor: no-drop;
background: #ccc;
border-color: #ccc;
}
.rc-switch-disabled:after {
background: #9e9e9e;
animation-name: none;
cursor: no-drop;
}
.rc-switch-disabled:hover:after {
transform: scale(1);
animation-name: none;
}
.rc-switch-label {
display: inline-block;
line-height: 20px;
font-size: 14px;
padding-left: 10px;
vertical-align: middle;
white-space: normal;
pointer-events: none;
user-select: text;
}
@keyframes rcSwitchOn {
0% {
transform: scale(1);
}
50% {
transform: scale(1.25);
}
100% {
transform: scale(1.1);
}
}
@keyframes rcSwitchOff {
0% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
+27
View File
@@ -0,0 +1,27 @@
import * as React from 'react';
export type SwitchChangeEventHandler = (checked: boolean, event: React.MouseEvent<HTMLButtonElement> | React.KeyboardEvent<HTMLButtonElement>) => void;
export type SwitchClickEventHandler = SwitchChangeEventHandler;
interface SwitchProps extends Omit<React.HTMLAttributes<HTMLButtonElement>, 'onChange' | 'onClick'> {
className?: string;
prefixCls?: string;
disabled?: boolean;
checkedChildren?: React.ReactNode;
unCheckedChildren?: React.ReactNode;
onChange?: SwitchChangeEventHandler;
onKeyDown?: React.KeyboardEventHandler<HTMLButtonElement>;
onClick?: SwitchClickEventHandler;
tabIndex?: number;
checked?: boolean;
defaultChecked?: boolean;
loadingIcon?: React.ReactNode;
style?: React.CSSProperties;
title?: string;
styles?: {
content?: React.CSSProperties;
};
classNames?: {
content?: string;
};
}
declare const Switch: React.ForwardRefExoticComponent<SwitchProps & React.RefAttributes<HTMLButtonElement>>;
export default Switch;
+69
View File
@@ -0,0 +1,69 @@
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import * as React from 'react';
import { clsx } from 'clsx';
import useControlledState from "@rc-component/util/es/hooks/useControlledState";
import KeyCode from "@rc-component/util/es/KeyCode";
const Switch = /*#__PURE__*/React.forwardRef(({
prefixCls = 'rc-switch',
className,
checked,
defaultChecked,
disabled,
loadingIcon,
checkedChildren,
unCheckedChildren,
onClick,
onChange,
onKeyDown,
styles,
classNames: switchClassNames,
...restProps
}, ref) => {
const [innerChecked, setInnerChecked] = useControlledState(defaultChecked ?? false, checked);
function triggerChange(newChecked, event) {
let mergedChecked = innerChecked;
if (!disabled) {
mergedChecked = newChecked;
setInnerChecked(mergedChecked);
onChange?.(mergedChecked, event);
}
return mergedChecked;
}
function onInternalKeyDown(e) {
if (e.which === KeyCode.LEFT) {
triggerChange(false, e);
} else if (e.which === KeyCode.RIGHT) {
triggerChange(true, e);
}
onKeyDown?.(e);
}
function onInternalClick(e) {
const ret = triggerChange(!innerChecked, e);
// [Legacy] trigger onClick with value
onClick?.(ret, e);
}
const switchClassName = clsx(prefixCls, className, {
[`${prefixCls}-checked`]: innerChecked,
[`${prefixCls}-disabled`]: disabled
});
return /*#__PURE__*/React.createElement("button", _extends({}, restProps, {
type: "button",
role: "switch",
"aria-checked": innerChecked,
disabled: disabled,
className: switchClassName,
ref: ref,
onKeyDown: onInternalKeyDown,
onClick: onInternalClick
}), loadingIcon, /*#__PURE__*/React.createElement("span", {
className: `${prefixCls}-inner`
}, /*#__PURE__*/React.createElement("span", {
className: clsx(`${prefixCls}-inner-checked`, switchClassNames?.content),
style: styles?.content
}, checkedChildren), /*#__PURE__*/React.createElement("span", {
className: clsx(`${prefixCls}-inner-unchecked`, switchClassNames?.content),
style: styles?.content
}, unCheckedChildren)));
});
Switch.displayName = 'Switch';
export default Switch;
+27
View File
@@ -0,0 +1,27 @@
import * as React from 'react';
export type SwitchChangeEventHandler = (checked: boolean, event: React.MouseEvent<HTMLButtonElement> | React.KeyboardEvent<HTMLButtonElement>) => void;
export type SwitchClickEventHandler = SwitchChangeEventHandler;
interface SwitchProps extends Omit<React.HTMLAttributes<HTMLButtonElement>, 'onChange' | 'onClick'> {
className?: string;
prefixCls?: string;
disabled?: boolean;
checkedChildren?: React.ReactNode;
unCheckedChildren?: React.ReactNode;
onChange?: SwitchChangeEventHandler;
onKeyDown?: React.KeyboardEventHandler<HTMLButtonElement>;
onClick?: SwitchClickEventHandler;
tabIndex?: number;
checked?: boolean;
defaultChecked?: boolean;
loadingIcon?: React.ReactNode;
style?: React.CSSProperties;
title?: string;
styles?: {
content?: React.CSSProperties;
};
classNames?: {
content?: string;
};
}
declare const Switch: React.ForwardRefExoticComponent<SwitchProps & React.RefAttributes<HTMLButtonElement>>;
export default Switch;
+78
View File
@@ -0,0 +1,78 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var React = _interopRequireWildcard(require("react"));
var _clsx = require("clsx");
var _useControlledState = _interopRequireDefault(require("@rc-component/util/lib/hooks/useControlledState"));
var _KeyCode = _interopRequireDefault(require("@rc-component/util/lib/KeyCode"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
const Switch = /*#__PURE__*/React.forwardRef(({
prefixCls = 'rc-switch',
className,
checked,
defaultChecked,
disabled,
loadingIcon,
checkedChildren,
unCheckedChildren,
onClick,
onChange,
onKeyDown,
styles,
classNames: switchClassNames,
...restProps
}, ref) => {
const [innerChecked, setInnerChecked] = (0, _useControlledState.default)(defaultChecked ?? false, checked);
function triggerChange(newChecked, event) {
let mergedChecked = innerChecked;
if (!disabled) {
mergedChecked = newChecked;
setInnerChecked(mergedChecked);
onChange?.(mergedChecked, event);
}
return mergedChecked;
}
function onInternalKeyDown(e) {
if (e.which === _KeyCode.default.LEFT) {
triggerChange(false, e);
} else if (e.which === _KeyCode.default.RIGHT) {
triggerChange(true, e);
}
onKeyDown?.(e);
}
function onInternalClick(e) {
const ret = triggerChange(!innerChecked, e);
// [Legacy] trigger onClick with value
onClick?.(ret, e);
}
const switchClassName = (0, _clsx.clsx)(prefixCls, className, {
[`${prefixCls}-checked`]: innerChecked,
[`${prefixCls}-disabled`]: disabled
});
return /*#__PURE__*/React.createElement("button", _extends({}, restProps, {
type: "button",
role: "switch",
"aria-checked": innerChecked,
disabled: disabled,
className: switchClassName,
ref: ref,
onKeyDown: onInternalKeyDown,
onClick: onInternalClick
}), loadingIcon, /*#__PURE__*/React.createElement("span", {
className: `${prefixCls}-inner`
}, /*#__PURE__*/React.createElement("span", {
className: (0, _clsx.clsx)(`${prefixCls}-inner-checked`, switchClassNames?.content),
style: styles?.content
}, checkedChildren), /*#__PURE__*/React.createElement("span", {
className: (0, _clsx.clsx)(`${prefixCls}-inner-unchecked`, switchClassNames?.content),
style: styles?.content
}, unCheckedChildren)));
});
Switch.displayName = 'Switch';
var _default = exports.default = Switch;
+80
View File
@@ -0,0 +1,80 @@
{
"name": "@rc-component/switch",
"version": "1.0.3",
"description": "switch ui component for react",
"keywords": [
"react",
"react-component",
"react-switch",
"switch"
],
"homepage": "http://github.com/react-component/switch",
"bugs": {
"url": "http://github.com/react-component/switch/issues"
},
"repository": {
"type": "git",
"url": "git@github.com:react-component/switch.git"
},
"license": "MIT",
"main": "lib/index",
"module": "./es/index",
"files": [
"assets/*.css",
"es",
"lib"
],
"scripts": {
"compile": "father build && lessc assets/index.less assets/index.css",
"docs:build": "dumi build",
"docs:deploy": "gh-pages -d .doc",
"gh-pages": "npm run docs:build && npm run docs:deploy",
"lint": "eslint .",
"lint-staged": "lint-staged",
"prepare": "husky install && dumi setup",
"prepublishOnly": "npm run compile && rc-np",
"postpublish": "npm run gh-pages",
"start": "dumi dev",
"test": "umi-test"
},
"lint-staged": {
"**/*.{js,jsx,tsx,ts,md,json}": [
"prettier --write"
]
},
"dependencies": {
"@rc-component/util": "^1.3.0",
"clsx": "^2.1.1"
},
"devDependencies": {
"@rc-component/father-plugin": "^2.0.0",
"@rc-component/np": "^1.0.3",
"@types/jest": "^29.4.0",
"@types/node": "^24.5.2",
"@types/react": "^19.1.14",
"@types/react-dom": "^19.1.9",
"@umijs/fabric": "^3.0.0",
"cheerio": "1.0.0-rc.12",
"dumi": "^2.0.0",
"enzyme": "^3.0.0",
"enzyme-adapter-react-16": "^1.0.1",
"enzyme-to-json": "^3.0.0",
"eslint": "^8.55.0",
"eslint-plugin-jest": "^27.6.0",
"eslint-plugin-unicorn": "^49.0.0",
"father": "^4.0.0",
"gh-pages": "^6.1.0",
"husky": "^8.0.1",
"less": "^4.1.3",
"lint-staged": "^15.1.0",
"prettier": "^3.1.0",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-test-renderer": "^16.0.0",
"umi-test": "^1.9.7"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
}