From 3983e6d5b8c1c313d97e9163bf6ef0f3245e9922 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Fri, 27 Oct 2017 14:04:48 +0800 Subject: [PATCH] radio --- .../{checkbox-group.vue => Group.vue} | 6 +- components/checkbox/checkbox.vue | 3 - components/checkbox/index.js | 4 +- components/index.js | 3 + components/radio/Group.vue | 81 +++++ components/radio/Radio.vue | 79 +++++ components/radio/RadioButton.vue | 0 components/radio/index.js | 6 + components/radio/style/index.js | 2 + components/radio/style/index.less | 279 ++++++++++++++++++ examples/checkbox.vue | 2 +- examples/index.js | 3 + examples/radio.vue | 52 ++++ 13 files changed, 509 insertions(+), 11 deletions(-) rename components/checkbox/{checkbox-group.vue => Group.vue} (96%) create mode 100644 components/radio/Group.vue create mode 100644 components/radio/Radio.vue create mode 100644 components/radio/RadioButton.vue create mode 100644 components/radio/index.js create mode 100644 components/radio/style/index.js create mode 100644 components/radio/style/index.less create mode 100644 examples/radio.vue diff --git a/components/checkbox/checkbox-group.vue b/components/checkbox/Group.vue similarity index 96% rename from components/checkbox/checkbox-group.vue rename to components/checkbox/Group.vue index 684d939a9..8d1ddf51c 100644 --- a/components/checkbox/checkbox-group.vue +++ b/components/checkbox/Group.vue @@ -6,7 +6,7 @@ diff --git a/components/radio/Radio.vue b/components/radio/Radio.vue new file mode 100644 index 000000000..cfc568780 --- /dev/null +++ b/components/radio/Radio.vue @@ -0,0 +1,79 @@ + + diff --git a/components/radio/RadioButton.vue b/components/radio/RadioButton.vue new file mode 100644 index 000000000..e69de29bb diff --git a/components/radio/index.js b/components/radio/index.js new file mode 100644 index 000000000..56c40cc32 --- /dev/null +++ b/components/radio/index.js @@ -0,0 +1,6 @@ +import Radio from './Radio.vue' +import RadioGroup from './Group.vue' + +Radio.Group = RadioGroup +export default Radio + diff --git a/components/radio/style/index.js b/components/radio/style/index.js new file mode 100644 index 000000000..cf31ed80f --- /dev/null +++ b/components/radio/style/index.js @@ -0,0 +1,2 @@ +import '../../style/index.less' +import './index.less' diff --git a/components/radio/style/index.less b/components/radio/style/index.less new file mode 100644 index 000000000..7d9c4b06e --- /dev/null +++ b/components/radio/style/index.less @@ -0,0 +1,279 @@ +@import "../../style/themes/default"; +@import "../../style/mixins/index"; + +@radio-prefix-cls: ~"@{ant-prefix}-radio"; +@radio-group-prefix-cls: ~"@{radio-prefix-cls}-group"; +@radio-inner-prefix-cls: ~"@{radio-prefix-cls}-inner"; +@radio-duration: .3s; + +.@{radio-group-prefix-cls} { + display: inline-block; + font-size: @font-size-base; +} + +// 一般状态 +.@{radio-prefix-cls}-wrapper { + font-size: @font-size-base; + display: inline-block; + position: relative; + white-space: nowrap; + margin-right: 8px; + cursor: pointer; +} + +.@{radio-prefix-cls} { + white-space: nowrap; + outline: none; + display: inline-block; + position: relative; + line-height: 1; + vertical-align: text-bottom; + cursor: pointer; + .@{radio-prefix-cls}-wrapper:hover &, + &:hover, + &-focused { + .@{radio-inner-prefix-cls} { + border-color: @primary-color; + } + } + &-checked:after { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + border-radius: 50%; + border: 1px solid @primary-color; + content: ''; + animation: antRadioEffect 0.36s ease-in-out; + animation-fill-mode: both; + visibility: hidden; + } + &:hover:after, + .@{radio-prefix-cls}-wrapper:hover &:after { + visibility: visible; + } + &-inner { + &:after { + position: absolute; + width: 6px; + height: 6px; + left: 3px; + top: 3px; + border-radius: @border-radius-base; + display: table; + border-top: 0; + border-left: 0; + content: ' '; + background-color: @primary-color; + opacity: 0; + transform: scale(0); + transition: all @radio-duration @ease-in-out-circ; + } + + position: relative; + top: 0; + left: 0; + display: block; + width: 14px; + height: 14px; + border-width: 1px; + border-style: solid; + border-radius: 14px; + border-color: @border-color-base; + background-color: @radio-button-bg; + transition: all @radio-duration; + } + + &-input { + position: absolute; + left: 0; + z-index: 1; + cursor: pointer; + opacity: 0; + top: 0; + bottom: 0; + right: 0; + } +} + +// 选中状态 +.@{radio-prefix-cls}-checked { + .@{radio-inner-prefix-cls} { + border-color: @primary-color; + &:after { + transform: scale(1); + opacity: 1; + transition: all @radio-duration @ease-in-out-circ; + } + } +} + +.@{radio-prefix-cls}-disabled { + .@{radio-inner-prefix-cls} { + border-color: @border-color-base !important; + background-color: @input-disabled-bg; + &:after { + background-color: #ccc; + } + } + + .@{radio-prefix-cls}-input { + cursor: not-allowed; + } + + & + span { + color: @disabled-color; + cursor: not-allowed; + } +} + +span.@{radio-prefix-cls} + * { + padding-left: 8px; + padding-right: 8px; +} + +.@{radio-prefix-cls}-button-wrapper { + margin: 0; + height: @input-height-base; + line-height: @input-height-base - 2px; + color: @radio-button-color; + display: inline-block; + transition: all 0.3s ease; + cursor: pointer; + border: @border-width-base @border-style-base @border-color-base; + border-left: 0; + background: @radio-button-bg; + padding: 0 16px; + position: relative; + + a { + color: @radio-button-color; + } + + > .@{radio-prefix-cls}-button { + margin-left: 0; + display: block; + width: 0; + height: 0; + } + + .@{radio-group-prefix-cls}-large & { + height: @input-height-lg; + line-height: @input-height-lg - 2px; + } + + .@{radio-group-prefix-cls}-small & { + height: @input-height-sm; + line-height: @input-height-sm - 2px; + padding: 0 12px; + &:first-child { + border-radius: @border-radius-sm 0 0 @border-radius-sm; + } + &:last-child { + border-radius: 0 @border-radius-sm @border-radius-sm 0; + } + } + + &:not(:first-child) { + &::before { + content: ""; + display: block; + top: 0; + left: -1px; + width: 1px; + height: 100%; + position: absolute; + background-color: @border-color-base; + } + } + &:first-child { + border-radius: @border-radius-base 0 0 @border-radius-base; + border-left: @border-width-base @border-style-base @border-color-base; + } + + &:last-child { + border-radius: 0 @border-radius-base @border-radius-base 0; + } + + &:first-child:last-child { + border-radius: @border-radius-base; + } + + &:hover, + &-focused { + color: @primary-color; + position: relative; + } + + .@{radio-prefix-cls}-inner, + input[type="checkbox"], + input[type="radio"] { + .opacity(0); + width: 0; + height: 0; + } + + &-checked { + background: @radio-button-bg; + border-color: @primary-color; + color: @primary-color; + box-shadow: -1px 0 0 0 @primary-color; + z-index: 1; + &::before { + background-color: @primary-color !important; + opacity: 0.1; + } + &:first-child { + border-color: @primary-color; + box-shadow: none !important; + } + + &:hover { + border-color: @primary-5; + box-shadow: -1px 0 0 0 @primary-5; + color: @primary-5; + } + + &:active { + border-color: @primary-7; + box-shadow: -1px 0 0 0 @primary-7; + color: @primary-7; + } + } + + &-disabled { + border-color: @border-color-base; + background-color: @input-disabled-bg; + cursor: not-allowed; + color: @disabled-color; + + &:first-child, + &:hover { + border-color: @border-color-base; + background-color: @input-disabled-bg; + color: @disabled-color; + } + &:first-child { + border-left-color: @border-color-base; + } + } + + &-disabled&-checked { + color: #fff; + background-color: #e6e6e6; + border-color: @border-color-base; + box-shadow: none; + } +} + +@keyframes antRadioEffect { + 0% { + transform: scale(1); + opacity: 0.5; + } + 100% { + transform: scale(1.6); + opacity: 0; + } +} diff --git a/examples/checkbox.vue b/examples/checkbox.vue index 42da048a0..0c0e3865a 100644 --- a/examples/checkbox.vue +++ b/examples/checkbox.vue @@ -1,6 +1,6 @@