From cc387b9bbde614b7825d5342c4d7b698bac3c983 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Sun, 6 Mar 2022 21:50:58 +0800 Subject: [PATCH] style: update switch --- components/style/themes/default.less | 8 +- .../__tests__/__snapshots__/demo.test.js.snap | 36 ++- .../__snapshots__/index.test.js.snap | 4 +- components/switch/index.tsx | 9 +- components/switch/style/index.less | 248 ++++++++---------- .../switch/style/{index.ts => index.tsx} | 0 components/switch/style/rtl.less | 52 ++++ 7 files changed, 208 insertions(+), 149 deletions(-) rename components/switch/style/{index.ts => index.tsx} (100%) create mode 100644 components/switch/style/rtl.less diff --git a/components/style/themes/default.less b/components/style/themes/default.less index 0561e9d52..1dfe4c221 100644 --- a/components/style/themes/default.less +++ b/components/style/themes/default.less @@ -795,11 +795,17 @@ // --- @switch-height: 22px; @switch-sm-height: 16px; -@switch-sm-checked-margin-left: -(@switch-sm-height - 3px); +@switch-min-width: 44px; +@switch-sm-min-width: 28px; @switch-disabled-opacity: 0.4; @switch-color: @primary-color; @switch-bg: @component-background; @switch-shadow-color: fade(#00230b, 20%); +@switch-padding: 2px; +@switch-inner-margin-min: ceil(@switch-height * 0.3); +@switch-inner-margin-max: ceil(@switch-height * 1.1); +@switch-sm-inner-margin-min: ceil(@switch-sm-height * 0.3); +@switch-sm-inner-margin-max: ceil(@switch-sm-height * 1.1); // Pagination // --- diff --git a/components/switch/__tests__/__snapshots__/demo.test.js.snap b/components/switch/__tests__/__snapshots__/demo.test.js.snap index ded627567..1fb69cc38 100644 --- a/components/switch/__tests__/__snapshots__/demo.test.js.snap +++ b/components/switch/__tests__/__snapshots__/demo.test.js.snap @@ -2,34 +2,54 @@ exports[`renders ./components/switch/demo/basic.vue correctly 1`] = ` `; exports[`renders ./components/switch/demo/disabled.vue correctly 1`] = `

`; -exports[`renders ./components/switch/demo/loading.vue correctly 1`] = `

`; +exports[`renders ./components/switch/demo/loading.vue correctly 1`] = ` +

+`; exports[`renders ./components/switch/demo/size.vue correctly 1`] = `

`; exports[`renders ./components/switch/demo/text.vue correctly 1`] = `


`; diff --git a/components/switch/__tests__/__snapshots__/index.test.js.snap b/components/switch/__tests__/__snapshots__/index.test.js.snap index 1ae01c1ad..bfe4e1a7c 100644 --- a/components/switch/__tests__/__snapshots__/index.test.js.snap +++ b/components/switch/__tests__/__snapshots__/index.test.js.snap @@ -2,6 +2,8 @@ exports[`Switch should has click wave effect 1`] = ` `; diff --git a/components/switch/index.tsx b/components/switch/index.tsx index cfdea4973..260a77674 100644 --- a/components/switch/index.tsx +++ b/components/switch/index.tsx @@ -84,7 +84,7 @@ const Switch = defineComponent({ }, ); - const { prefixCls } = useConfigInject('switch', props); + const { prefixCls, direction, size } = useConfigInject('switch', props); const refSwitchNode = ref(); const focus = () => { refSwitchNode.value?.focus(); @@ -138,11 +138,12 @@ const Switch = defineComponent({ }; const classNames = computed(() => ({ - [`${prefixCls.value}-small`]: props.size === 'small', + [`${prefixCls.value}-small`]: size.value === 'small', [`${prefixCls.value}-loading`]: props.loading, [`${prefixCls.value}-checked`]: checkedStatus.value, [`${prefixCls.value}-disabled`]: props.disabled, [prefixCls.value]: true, + [`${prefixCls.value}-rtl`]: direction.value === 'rtl', })); return () => ( @@ -171,7 +172,9 @@ const Switch = defineComponent({ class={[attrs.class, classNames.value]} ref={refSwitchNode} > - {props.loading ? : null} +
+ {props.loading ? : null} +
{checkedStatus.value ? getPropsSlot(slots, props, 'checkedChildren') diff --git a/components/switch/style/index.less b/components/switch/style/index.less index f6093eaa0..5ead4105d 100644 --- a/components/switch/style/index.less +++ b/components/switch/style/index.less @@ -2,7 +2,10 @@ @import '../../style/mixins/index'; @switch-prefix-cls: ~'@{ant-prefix}-switch'; -@switch-duration: 0.36s; +@switch-duration: 0.2s; + +@switch-pin-size: @switch-height - 4px; +@switch-sm-pin-size: @switch-sm-height - 4px; .@{switch-prefix-cls} { .reset-component(); @@ -10,169 +13,142 @@ position: relative; display: inline-block; box-sizing: border-box; - min-width: 44px; + min-width: @switch-min-width; height: @switch-height; - line-height: @switch-height - 2px; + line-height: @switch-height; vertical-align: middle; background-color: @disabled-color; - border: 1px solid transparent; + border: 0; border-radius: 100px; cursor: pointer; transition: all @switch-duration; user-select: none; - &-inner { - display: block; - margin-right: 6px; - margin-left: 24px; - color: @text-color-inverse; - font-size: @font-size-sm; - } - - &-loading-icon, - &::after { - position: absolute; - top: 1px; - left: 1px; - width: @switch-height - 4px; - height: @switch-height - 4px; - background-color: @switch-bg; - border-radius: 18px; - cursor: pointer; - transition: all @switch-duration @ease-in-out-circ; - content: ' '; - } - - &::after { - box-shadow: 0 2px 4px 0 @switch-shadow-color; - } - - &:not(&-disabled):active::before, - &:not(&-disabled):active::after { - width: 24px; - } - - &-loading-icon { - z-index: 1; - display: none; - font-size: 12px; - // loading default use animation - // animation: loadingCircle 1s infinite linear; - background: transparent; - svg { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - margin: auto; - } - } - - &-loading &-loading-icon { - display: inline-block; - color: @text-color; - } - - &-checked&-loading &-loading-icon { - color: @switch-color; - } - &:focus { outline: 0; - box-shadow: 0 0 0 2px fade(@switch-color, 20%); + box-shadow: 0 0 0 2px fade(@disabled-color, 10%); + } + + &-checked:focus { + box-shadow: 0 0 0 2px @primary-1; } &:focus:hover { box-shadow: none; } - &-small { - min-width: 28px; - height: @switch-sm-height; - line-height: @switch-sm-height - 2px; - - .@{switch-prefix-cls}-inner { - margin-right: 3px; - margin-left: 18px; - font-size: @font-size-sm; - } - - &::after { - width: @switch-sm-height - 4px; - height: @switch-sm-height - 4px; - } - - &:active::before, - &:active::after { - width: 16px; - } - } - - &-small &-loading-icon { - width: @switch-sm-height - 4px; - height: @switch-sm-height - 4px; - } - - &-small&-checked { - .@{switch-prefix-cls}-inner { - margin-right: 18px; - margin-left: 3px; - } - } - - &-small&-checked &-loading-icon { - left: 100%; - margin-left: @switch-sm-checked-margin-left; - } - - &-small&-loading &-loading-icon { - font-weight: bold; - // animation: AntSwitchSmallLoadingCircle 1s infinite linear; - transform: scale(0.66667); - } - &-checked { background-color: @switch-color; - - .@{switch-prefix-cls}-inner { - margin-right: 24px; - margin-left: 6px; - } - - &::after { - left: 100%; - margin-left: -1px; - transform: translateX(-100%); - } - } - - &-checked &-loading-icon { - left: 100%; - margin-left: -19px; } &-loading, &-disabled { cursor: not-allowed; opacity: @switch-disabled-opacity; + * { + box-shadow: none; cursor: not-allowed; } - &::before, - &::after { - cursor: not-allowed; + } + + // ========================= Inner ========================== + &-inner { + display: block; + margin: 0 @switch-inner-margin-min 0 @switch-inner-margin-max; + color: @text-color-inverse; + font-size: @font-size-sm; + transition: margin @switch-duration; + } + + &-checked &-inner { + margin: 0 @switch-inner-margin-max 0 @switch-inner-margin-min; + } + + // ========================= Handle ========================= + &-handle { + position: absolute; + top: @switch-padding; + left: @switch-padding; + width: @switch-pin-size; + height: @switch-pin-size; + transition: all @switch-duration ease-in-out; + + &::before { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: @switch-bg; + border-radius: (@switch-pin-size / 2); + box-shadow: 0 2px 4px 0 @switch-shadow-color; + transition: all @switch-duration ease-in-out; + content: ''; + } + } + + &-checked &-handle { + left: calc(100% - @switch-pin-size - @switch-padding); + } + + &:not(&-disabled):active { + .@{switch-prefix-cls}-handle::before { + right: -30%; + left: 0; + } + + &.@{switch-prefix-cls}-checked { + .@{switch-prefix-cls}-handle::before { + right: 0; + left: -30%; + } + } + } + + // ======================== Loading ========================= + &-loading-icon.@{iconfont-css-prefix} { + position: relative; + top: ((@switch-pin-size - @font-size-base) / 2); + color: rgba(0, 0, 0, 0.65); + vertical-align: top; + } + + &-checked &-loading-icon { + color: @switch-color; + } + + // ========================== Size ========================== + &-small { + min-width: @switch-sm-min-width; + height: @switch-sm-height; + line-height: @switch-sm-height; + + .@{switch-prefix-cls}-inner { + margin: 0 @switch-sm-inner-margin-min 0 @switch-sm-inner-margin-max; + font-size: @font-size-sm; + } + + .@{switch-prefix-cls}-handle { + width: @switch-sm-pin-size; + height: @switch-sm-pin-size; + } + + .@{switch-prefix-cls}-loading-icon { + top: ((@switch-sm-pin-size - 9px) / 2); + font-size: 9px; + } + + &.@{switch-prefix-cls}-checked { + .@{switch-prefix-cls}-inner { + margin: 0 @switch-sm-inner-margin-max 0 @switch-sm-inner-margin-min; + } + + .@{switch-prefix-cls}-handle { + left: calc(100% - @switch-sm-pin-size - @switch-padding); + } } } } -@keyframes AntSwitchSmallLoadingCircle { - 0% { - transform: rotate(0deg) scale(0.66667); - transform-origin: 50% 50%; - } - 100% { - transform: rotate(360deg) scale(0.66667); - transform-origin: 50% 50%; - } -} +@import './rtl'; diff --git a/components/switch/style/index.ts b/components/switch/style/index.tsx similarity index 100% rename from components/switch/style/index.ts rename to components/switch/style/index.tsx diff --git a/components/switch/style/rtl.less b/components/switch/style/rtl.less new file mode 100644 index 000000000..7a7de94bb --- /dev/null +++ b/components/switch/style/rtl.less @@ -0,0 +1,52 @@ +@import '../../style/themes/index'; +@import '../../style/mixins/index'; + +@switch-prefix-cls: ~'@{ant-prefix}-switch'; + +@switch-pin-size: @switch-height - 4px; +@switch-sm-pin-size: @switch-sm-height - 4px; + +.@{switch-prefix-cls}-rtl { + direction: rtl; + + .@{switch-prefix-cls}-inner { + margin: 0 @switch-inner-margin-max 0 @switch-inner-margin-min; + } + + .@{switch-prefix-cls}-handle { + right: @switch-padding; + left: auto; + } + + &:not(&-disabled):active { + .@{switch-prefix-cls}-handle::before { + right: 0; + left: -30%; + } + + &.@{switch-prefix-cls}-checked { + .@{switch-prefix-cls}-handle::before { + right: -30%; + left: 0; + } + } + } + + &.@{switch-prefix-cls}-checked { + .@{switch-prefix-cls}-inner { + margin: 0 @switch-inner-margin-min 0 @switch-inner-margin-max; + } + + .@{switch-prefix-cls}-handle { + right: calc(100% - @switch-pin-size - @switch-padding); + } + } + + &.@{switch-prefix-cls}-small { + &.@{switch-prefix-cls}-checked { + .@{switch-prefix-cls}-handle { + right: calc(100% - @switch-sm-pin-size - @switch-padding); + } + } + } +}