diff --git a/components/collapse/demo/index.vue b/components/collapse/demo/index.vue index 37ca57d19..7c6230c6e 100644 --- a/components/collapse/demo/index.vue +++ b/components/collapse/demo/index.vue @@ -17,6 +17,7 @@ const md = { - 对复杂区域进行分组和隐藏,保持页面的整洁。 - '手风琴' 是一种特殊的折叠面板,只允许单个内容区域展开。 + ## 代码演示`, us: `# When To Use diff --git a/components/divider/demo/index.vue b/components/divider/demo/index.vue index b3a4a9197..1ea00c62d 100644 --- a/components/divider/demo/index.vue +++ b/components/divider/demo/index.vue @@ -9,6 +9,7 @@ const md = { ## 何时使用 - 对不同章节的文本段落进行分割。 - 对行内文字/链接进行分割,例如表格的操作列。 + ## 代码演示`, us: `# Divider A divider line separates different content. diff --git a/components/index.js b/components/index.js index 252fd8e88..61d21988d 100644 --- a/components/index.js +++ b/components/index.js @@ -76,3 +76,5 @@ const SelectOption = Select.Option const SelectOptGroup = Select.OptGroup export { Select, SelectOption, SelectOptGroup } +export { default as Switch } from './switch' + diff --git a/components/message/demo/index.vue b/components/message/demo/index.vue index d76dc0d5f..c9fe688aa 100644 --- a/components/message/demo/index.vue +++ b/components/message/demo/index.vue @@ -11,6 +11,7 @@ const md = { ## 何时使用 - 可提供成功、警告和错误等反馈信息。 - 顶部居中显示并自动消失,是一种不打断用户操作的轻量级提示方式。 + ## 代码演示`, us: `# Message Display global messages as feedback in response to user operations. diff --git a/components/notification/demo/index.vue b/components/notification/demo/index.vue index c67499a4a..73e548064 100644 --- a/components/notification/demo/index.vue +++ b/components/notification/demo/index.vue @@ -16,6 +16,7 @@ const md = { - 较为复杂的通知内容。 - 带有交互的通知,给出用户下一步的行动点。 - 系统主动推送。 + ## 代码演示`, us: `# Notification Display a notification message globally. diff --git a/components/select/demo/index.vue b/components/select/demo/index.vue index 52cbffa7a..0cf341cb1 100644 --- a/components/select/demo/index.vue +++ b/components/select/demo/index.vue @@ -20,6 +20,7 @@ const md = { ## 何时使用 - 弹出一个下拉菜单给用户选择操作,用于代替原生的选择器,或者需要一个更优雅的多选器时。 - 当选项少时(少于 5 项),建议直接将选项平铺,使用 [Radio](#/cn/components/radio/) 是更好的选择。 + ## 代码演示`, us: `# Select Select component to select value from options. diff --git a/components/spin/Spin.vue b/components/spin/Spin.vue index d3f70c676..d01090963 100644 --- a/components/spin/Spin.vue +++ b/components/spin/Spin.vue @@ -50,13 +50,13 @@ export default { } }, watch: { - spinning (val) { - const { delay, stateSpinning, spinning } = this + spinning () { + const { delay, spinning } = this if (this.debounceTimeout) { clearTimeout(this.debounceTimeout) } - if (stateSpinning && !spinning) { + if (!spinning) { this.debounceTimeout = window.setTimeout(() => this.setState({ stateSpinning: spinning }), 200) if (this.delayTimeout) { clearTimeout(this.delayTimeout) diff --git a/components/spin/demo/delayAndDebounce.md b/components/spin/demo/delayAndDebounce.md index 35f4f7507..bbd6fb4a3 100644 --- a/components/spin/demo/delayAndDebounce.md +++ b/components/spin/demo/delayAndDebounce.md @@ -23,7 +23,7 @@ Specifies a delay for loading state. If `spinning` ends during delay, loading st 可以点击‘切换’按钮,延迟显示 loading 效果。当 spinning 状态在 `delay` 时间内结束,则不显示 loading 状态。 - 切换 + Loading state: +``` diff --git a/components/switch/demo/disabled.md b/components/switch/demo/disabled.md new file mode 100644 index 000000000..36dc4d6fa --- /dev/null +++ b/components/switch/demo/disabled.md @@ -0,0 +1,33 @@ + +#### 不可用 +Switch 失效状态。 + + + +#### Disabled +Disabled state of `Switch`. + + +```html + + +``` diff --git a/components/switch/demo/index.vue b/components/switch/demo/index.vue new file mode 100644 index 000000000..ba2b6be80 --- /dev/null +++ b/components/switch/demo/index.vue @@ -0,0 +1,55 @@ + diff --git a/components/switch/demo/loading.md b/components/switch/demo/loading.md new file mode 100644 index 000000000..22a68318b --- /dev/null +++ b/components/switch/demo/loading.md @@ -0,0 +1,19 @@ + +#### 加载中 +标识开关操作仍在执行中。 + + + +#### Loading +Mark a pending state of switch. + + +```html + +``` diff --git a/components/switch/demo/size.md b/components/switch/demo/size.md new file mode 100644 index 000000000..20ca2aa5a --- /dev/null +++ b/components/switch/demo/size.md @@ -0,0 +1,19 @@ + +#### 两种大小 +`size="small"` 表示小号开关。 + + + +#### Two sizes +`size="small"` represents a small sized switch. + + +```html + +``` diff --git a/components/switch/demo/text.md b/components/switch/demo/text.md new file mode 100644 index 000000000..1c7996d9f --- /dev/null +++ b/components/switch/demo/text.md @@ -0,0 +1,24 @@ + +#### 文字和图标 +带有文字和图标。 + + + +#### Text & icon +With text and icon. + + +```html + +``` diff --git a/components/switch/index.en-US.md b/components/switch/index.en-US.md new file mode 100644 index 000000000..e94c5223e --- /dev/null +++ b/components/switch/index.en-US.md @@ -0,0 +1,20 @@ +## API + +| Property | Description | Type | Default | +| -------- | ----------- | ---- | ------- | +| autoFocus | get focus when component mounted | boolean | false | +| checked | determine whether the `Switch` is checked | boolean | false | +| checkedChildren | content to be shown when the state is checked | string\|slot | | +| defaultChecked | to set the initial state | boolean | false | +| disabled | Disable switch | boolean | false | +| loading | loading state of switch | boolean | false | +| size | the size of the `Switch`, options: `default` `small` | string | default | +| unCheckedChildren | content to be shown when the state is unchecked | string\|slot | | +| onChange | a callback function, can be executed when the checked state is changing | Function(checked:Boolean) | | + +## Methods + +| Name | Description | +| ---- | ----------- | +| blur() | remove focus | +| focus() | get focus | diff --git a/components/switch/index.vue b/components/switch/index.vue new file mode 100644 index 000000000..916dca3ae --- /dev/null +++ b/components/switch/index.vue @@ -0,0 +1,75 @@ + diff --git a/components/switch/index.zh-CN.md b/components/switch/index.zh-CN.md new file mode 100644 index 000000000..89cf59bd5 --- /dev/null +++ b/components/switch/index.zh-CN.md @@ -0,0 +1,20 @@ +## API + +| 参数 | 说明 | 类型 | 默认值 | +| --- | --- | --- | --- | +| autoFocus | 组件自动获取焦点 | boolean | false | +| checked | 指定当前是否选中 | boolean | false | +| checkedChildren | 选中时的内容 | string\|slot | | +| defaultChecked | 初始是否选中 | boolean | false | +| disabled | 是否禁用 | boolean | false | +| loading | 加载中的开关 | boolean | false | +| size | 开关大小,可选值:`default` `small` | string | default | +| unCheckedChildren | 非选中时的内容 | string\|slot | | +| onChange | 变化时回调函数 | Function(checked:Boolean) | | + +## 方法 + +| 名称 | 描述 | +| --- | --- | +| blur() | 移除焦点 | +| focus() | 获取焦点 | diff --git a/components/switch/style/index.js b/components/switch/style/index.js new file mode 100644 index 000000000..cf31ed80f --- /dev/null +++ b/components/switch/style/index.js @@ -0,0 +1,2 @@ +import '../../style/index.less' +import './index.less' diff --git a/components/switch/style/index.less b/components/switch/style/index.less new file mode 100644 index 000000000..987f1a601 --- /dev/null +++ b/components/switch/style/index.less @@ -0,0 +1,165 @@ +@import "../../style/themes/default"; +@import "../../style/mixins/index"; + +@switch-prefix-cls: ~"@{ant-prefix}-switch"; +@switch-duration: .36s; + +.@{switch-prefix-cls} { + .reset-component; + position: relative; + display: inline-block; + box-sizing: border-box; + height: @switch-height; + min-width: 44px; + line-height: @switch-height - 2px; + vertical-align: middle; + border-radius: 100px; + border: 1px solid transparent; + background-color: @disabled-color; + cursor: pointer; + transition: all @switch-duration; + user-select: none; + + &-inner { + color: #fff; + font-size: @font-size-sm; + margin-left: 24px; + margin-right: 6px; + display: block; + } + + &:before, + &:after { + position: absolute; + width: @switch-height - 4px; + height: @switch-height - 4px; + left: 1px; + top: 1px; + border-radius: 18px; + background-color: @component-background; + content: " "; + cursor: pointer; + transition: all @switch-duration @ease-in-out-circ; + } + + &:after { + box-shadow: 0 2px 4px 0 rgba(0, 35, 11, .2); + } + + &:active:before, + &:active:after { + width: 24px; + } + + &:before { + content: "\e64d"; + font-family: anticon; + animation: loadingCircle 1s infinite linear; + text-align: center; + background: transprent; + z-index: 1; + display: none; + font-size: 12px; + } + + &-loading:before { + display: inline-block; + color: @text-color; + } + + &-checked&-loading:before { + color: @switch-color; + } + + &:focus { + box-shadow: 0 0 0 2px fade(@switch-color, 20%); + outline: 0; + } + + &:focus:hover { + box-shadow: none; + } + + &-small { + height: @switch-sm-height; + min-width: 28px; + line-height: @switch-sm-height - 2px; + + .@{switch-prefix-cls}-inner { + margin-left: 18px; + margin-right: 3px; + font-size: @font-size-sm; + } + + &:before, + &:after { + width: @switch-sm-height - 4px; + height: @switch-sm-height - 4px; + } + + &:active:before, + &:active:after { + width: 16px; + } + } + + &-small&-checked { + &:before, + &:after { + left: 100%; + margin-left: -12.5px; + } + + .@{switch-prefix-cls}-inner { + margin-left: 3px; + margin-right: 18px; + } + } + + &-small:active&-checked:before, + &-small:active&-checked:after { + margin-left: -16.5px; + } + + &-small&-loading:before { + animation: AntSwitchSmallLoadingCircle 1s infinite linear; + font-weight: bold; + } + + &-checked { + background-color: @switch-color; + + .@{switch-prefix-cls}-inner { + margin-left: 6px; + margin-right: 24px; + } + + &:before, + &:after { + left: 100%; + margin-left: -19px; + } + + &:active:before, + &:active:after { + margin-left: -25px; + } + } + + &-loading, + &-disabled { + pointer-events: none; + opacity: @switch-disabled-opacity; + } +} + +@keyframes AntSwitchSmallLoadingCircle { + 0% { + transform-origin: 50% 50%; + transform: rotate(0deg) scale(0.66667); + } + 100% { + transform-origin: 50% 50%; + transform: rotate(360deg) scale(0.66667); + } +} diff --git a/components/vc-switch/PropTypes.js b/components/vc-switch/PropTypes.js new file mode 100644 index 000000000..7c2a8938f --- /dev/null +++ b/components/vc-switch/PropTypes.js @@ -0,0 +1,15 @@ +import PropTypes from '../_util/vue-types' + +export const switchPropTypes = { + prefixCls: PropTypes.string, + disabled: PropTypes.bool.def(false), + checkedChildren: PropTypes.any, + unCheckedChildren: PropTypes.any, + // onChange: PropTypes.func, + // onMouseUp: PropTypes.func, + // onClick: PropTypes.func, + tabIndex: PropTypes.number, + checked: PropTypes.bool.def(false), + defaultChecked: PropTypes.bool.def(false), + autoFocus: PropTypes.bool.def(false), +} diff --git a/components/vc-switch/Switch.vue b/components/vc-switch/Switch.vue new file mode 100644 index 000000000..3100edbfe --- /dev/null +++ b/components/vc-switch/Switch.vue @@ -0,0 +1,122 @@ + diff --git a/components/vc-switch/assets/index.less b/components/vc-switch/assets/index.less new file mode 100644 index 000000000..0f7eb65e1 --- /dev/null +++ b/components/vc-switch/assets/index.less @@ -0,0 +1,115 @@ +@switchPrefixCls: rc-switch; + +@duration: .3s; + +.@{switchPrefixCls} { + position: relative; + display: inline-block; + box-sizing: border-box; + width: 44px; + height: 22px; + line-height: 20px; + vertical-align: middle; + border-radius: 20px 20px; + border: 1px solid #ccc; + background-color: #ccc; + cursor: pointer; + transition: all @duration cubic-bezier(0.35, 0, 0.25, 1); + + &-inner { + color: #fff; + font-size: 12px; + position: absolute; + left: 24px; + } + + &: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 @duration cubic-bezier(0.35, 0, 0.25, 1); + animation-timing-function: cubic-bezier(0.35, 0, 0.25, 1); + animation-duration: @duration; + animation-name: rcSwitchOff; + } + + &:hover:after { + transform: scale(1.1); + animation-name: rcSwitchOn; + } + + &:focus { + box-shadow: 0 0 0 2px tint(#2db7f5, 80%); + outline: none; + } + + &-checked { + border: 1px solid #87d068; + background-color: #87d068; + + .@{switchPrefixCls}-inner { + left: 6px; + } + + &:after { + left: 22px; + } + } + + &-disabled { + cursor: no-drop; + background: #ccc; + border-color: #ccc; + + &:after { + background: #9e9e9e; + animation-name: none; + cursor: no-drop; + } + + &:hover:after { + transform: scale(1); + animation-name: none; + } + } + + &-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); + } +} diff --git a/components/vc-switch/demo/simple.vue b/components/vc-switch/demo/simple.vue new file mode 100644 index 000000000..58bbb6bc1 --- /dev/null +++ b/components/vc-switch/demo/simple.vue @@ -0,0 +1,35 @@ + diff --git a/components/vc-switch/index.js b/components/vc-switch/index.js new file mode 100644 index 000000000..6c35cdcd3 --- /dev/null +++ b/components/vc-switch/index.js @@ -0,0 +1,3 @@ +import Switch from './Switch' + +export default Switch diff --git a/contributors.md b/contributors.md index 465c0b00d..8be397727 100644 --- a/contributors.md +++ b/contributors.md @@ -47,12 +47,11 @@ Badge | done Breadcrumb | done Card | done Collapse | done -LocaleProvider Progress Slider -Spin +Spin | done Steps -Switch +Switch | done Table Timeline Transfer diff --git a/examples/demo.js b/examples/demo.js index dab5ace8d..2e3df11cd 100644 --- a/examples/demo.js +++ b/examples/demo.js @@ -23,4 +23,5 @@ export { default as collapse } from 'antd/collapse/demo/index.vue' export { default as notification } from 'antd/notification/demo/index.vue' export { default as message } from 'antd/message/demo/index.vue' export { default as spin } from 'antd/spin/demo/index.vue' +export { default as switch } from 'antd/switch/demo/index.vue'