From c124443935ffcd05dfd350595d0f5994e9de31ba Mon Sep 17 00:00:00 2001 From: Seeridia Date: Thu, 2 Jul 2026 21:11:22 +0800 Subject: [PATCH 1/2] style(Switch): support round and line shapes --- docs/web/api/switch.en-US.md | 6 + docs/web/api/switch.md | 6 + style/web/components/switch/_index.less | 189 ++++++++++++++++++++++++ style/web/components/switch/_var.less | 17 +++ 4 files changed, 218 insertions(+) diff --git a/docs/web/api/switch.en-US.md b/docs/web/api/switch.en-US.md index 91e704b4b2..2216c20740 100644 --- a/docs/web/api/switch.en-US.md +++ b/docs/web/api/switch.en-US.md @@ -29,3 +29,9 @@ Switches for normal, loading and disabled are provided. Set the corresponding st Large, medium (default) and small switches are provided. {{ size }} + +### Switches of Different Shapes + +Three shapes are provided: circle, round and line. `label` is not rendered when shape is `line`. + +{{ shape }} diff --git a/docs/web/api/switch.md b/docs/web/api/switch.md index 57b9e773d2..ea15c2e975 100644 --- a/docs/web/api/switch.md +++ b/docs/web/api/switch.md @@ -29,3 +29,9 @@ spline: form 提供 大、中(默认)、小 3种开关。 {{ size }} + +### 不同形状的开关 + +提供胶囊形、圆角形和线性 3 种形状。`line` 形态不展示开关内容。 + +{{ shape }} diff --git a/style/web/components/switch/_index.less b/style/web/components/switch/_index.less index 94cf883d18..54c8c7a8b1 100644 --- a/style/web/components/switch/_index.less +++ b/style/web/components/switch/_index.less @@ -271,3 +271,192 @@ } } } + +.@{prefix}-switch.@{prefix}-switch--shape-round { + border-radius: @switch-round-track-border-radius; + + .@{prefix}-switch__handle, + .@{prefix}-switch__handle::before { + border-radius: @switch-round-handle-border-radius; + } +} + +.@{prefix}-switch.@{prefix}-switch--shape-line { + width: @switch-line-width-default; + min-width: @switch-line-width-default; + height: @switch-height-default; + line-height: @switch-height-default; + background-color: transparent; + overflow: visible; + + &:hover { + background-color: transparent; + } + + &::before { + content: ''; + position: absolute; + left: @switch-line-track-inset; + right: @switch-line-track-inset; + top: 50%; + height: @switch-line-track-height; + transform: translateY(-50%); + border-radius: @switch-line-track-border-radius; + background-color: @switch-unchecked-bg-color; + transition: @switch-transition; + } + + &:hover::before { + background-color: @switch-unchecked-bg-color-hover; + } + + .@{prefix}-switch__handle { + top: 50%; + left: 0; + right: auto; + width: @switch-line-handle-size-default; + height: @switch-line-handle-size-default; + transform: translateY(-50%); + box-shadow: @shadow-1; + z-index: 1; + + .t-icon { + font-size: @switch-line-handle-size-default; + } + } + + &:active:not(.@{prefix}-is-disabled):not(.@{prefix}-is-loading) { + .@{prefix}-switch__handle::before, + &.@{prefix}-is-checked .@{prefix}-switch__handle::before { + left: 0; + right: 0; + } + } + + &.@{prefix}-is-checked { + background-color: transparent; + + &::before { + background-color: @switch-checked-bg-color; + } + + &:hover::before { + background-color: @switch-checked-bg-color-hover; + } + + .@{prefix}-switch__handle { + top: 50%; + left: calc(100% - @switch-line-handle-size-checked-default); + right: auto; + width: @switch-line-handle-size-checked-default; + height: @switch-line-handle-size-checked-default; + transform: translateY(-50%); + + .t-icon { + font-size: @switch-line-handle-size-checked-default; + } + } + } + + &.@{prefix}-is-loading { + background-color: transparent; + + &::before { + background-color: @switch-unchecked-bg-color-loading; + } + + &.@{prefix}-is-checked::before { + background-color: @switch-checked-bg-color-loading; + } + } + + &.@{prefix}-is-disabled { + background-color: transparent; + + .@{prefix}-switch__handle { + box-shadow: @shadow-1; + } + + &::before { + background-color: @switch-unchecked-bg-color-disabled; + } + + &.@{prefix}-is-checked { + background-color: transparent; + + &::before { + background-color: @switch-checked-bg-color-disabled; + } + + .@{prefix}-switch__handle { + box-shadow: @shadow-1; + } + } + } +} + +.@{prefix}-switch.@{prefix}-size-l.@{prefix}-switch--shape-line { + width: @switch-line-width-l; + min-width: @switch-line-width-l; + height: @switch-height-l; + line-height: @switch-height-l; + + .@{prefix}-switch__handle { + top: 50%; + left: 0; + right: auto; + width: @switch-line-handle-size-l; + height: @switch-line-handle-size-l; + transform: translateY(-50%); + + .t-icon { + font-size: @switch-line-handle-size-l; + } + } + + &.@{prefix}-is-checked .@{prefix}-switch__handle { + top: 50%; + left: calc(100% - @switch-line-handle-size-checked-l); + right: auto; + width: @switch-line-handle-size-checked-l; + height: @switch-line-handle-size-checked-l; + transform: translateY(-50%); + + .t-icon { + font-size: @switch-line-handle-size-checked-l; + } + } +} + +.@{prefix}-switch.@{prefix}-size-s.@{prefix}-switch--shape-line { + width: @switch-line-width-s; + min-width: @switch-line-width-s; + height: @switch-height-s; + line-height: @switch-height-s; + + .@{prefix}-switch__handle { + top: 50%; + left: 0; + right: auto; + width: @switch-line-handle-size-s; + height: @switch-line-handle-size-s; + transform: translateY(-50%); + + .t-icon { + font-size: @switch-line-handle-size-s; + } + } + + &.@{prefix}-is-checked .@{prefix}-switch__handle { + top: 50%; + left: calc(100% - @switch-line-handle-size-checked-s); + right: auto; + width: @switch-line-handle-size-checked-s; + height: @switch-line-handle-size-checked-s; + transform: translateY(-50%); + + .t-icon { + font-size: @switch-line-handle-size-checked-s; + } + } +} diff --git a/style/web/components/switch/_var.less b/style/web/components/switch/_var.less index 34a038da8b..3baeb10d9c 100644 --- a/style/web/components/switch/_var.less +++ b/style/web/components/switch/_var.less @@ -51,6 +51,23 @@ @switch-width-border-check-default: (@switch-width-border-check-base - @switch-width-border-check-value * 1); @switch-width-border-check-s: (@switch-width-border-check-base - @switch-width-border-check-value * 2); +// shape +@switch-round-track-border-radius: @border-radius-default; +@switch-round-handle-border-radius: @border-radius-small; + +@switch-line-width-l: 39px; +@switch-line-width-default: 32px; +@switch-line-width-s: 26px; +@switch-line-track-inset: 2px; +@switch-line-track-height: 6px; +@switch-line-track-border-radius: @border-radius-round; +@switch-line-handle-size-l: calc(@switch-height-l - 2 * @switch-width-border-l); +@switch-line-handle-size-default: calc(@switch-height-default - 2 * @switch-width-border-default); +@switch-line-handle-size-s: calc(@switch-height-s - 2 * @switch-width-border-s); +@switch-line-handle-size-checked-l: calc(@switch-height-l - 2 * @switch-width-border-check-l); +@switch-line-handle-size-checked-default: calc(@switch-height-default - 2 * @switch-width-border-check-default); +@switch-line-handle-size-checked-s: calc(@switch-height-s - 2 * @switch-width-border-check-s); + // 字体 @switch-content-font-size-l: @font-size-l; @switch-content-font-size-default: @font-size-s; From 9d5ab177c4fa927d1c9be79c33cbcb2be85c245c Mon Sep 17 00:00:00 2001 From: Seeridia Date: Thu, 2 Jul 2026 21:54:55 +0800 Subject: [PATCH 2/2] fix(Switch): improve line shape styles --- docs/web/api/switch.en-US.md | 2 +- style/web/components/switch/_index.less | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/web/api/switch.en-US.md b/docs/web/api/switch.en-US.md index 2216c20740..25295fdc25 100644 --- a/docs/web/api/switch.en-US.md +++ b/docs/web/api/switch.en-US.md @@ -32,6 +32,6 @@ Large, medium (default) and small switches are provided. ### Switches of Different Shapes -Three shapes are provided: circle, round and line. `label` is not rendered when shape is `line`. +Three shapes are provided: circle, round and line. Switch content is not rendered when shape is `line`. {{ shape }} diff --git a/style/web/components/switch/_index.less b/style/web/components/switch/_index.less index 54c8c7a8b1..947c744166 100644 --- a/style/web/components/switch/_index.less +++ b/style/web/components/switch/_index.less @@ -316,7 +316,7 @@ right: auto; width: @switch-line-handle-size-default; height: @switch-line-handle-size-default; - transform: translateY(-50%); + transform: translate(0, -50%); box-shadow: @shadow-1; z-index: 1; @@ -325,6 +325,10 @@ } } + .@{prefix}-switch__content { + display: none; + } + &:active:not(.@{prefix}-is-disabled):not(.@{prefix}-is-loading) { .@{prefix}-switch__handle::before, &.@{prefix}-is-checked .@{prefix}-switch__handle::before { @@ -346,11 +350,11 @@ .@{prefix}-switch__handle { top: 50%; - left: calc(100% - @switch-line-handle-size-checked-default); + left: 100%; right: auto; width: @switch-line-handle-size-checked-default; height: @switch-line-handle-size-checked-default; - transform: translateY(-50%); + transform: translate(-100%, -50%); .t-icon { font-size: @switch-line-handle-size-checked-default; @@ -407,7 +411,7 @@ right: auto; width: @switch-line-handle-size-l; height: @switch-line-handle-size-l; - transform: translateY(-50%); + transform: translate(0, -50%); .t-icon { font-size: @switch-line-handle-size-l; @@ -416,11 +420,11 @@ &.@{prefix}-is-checked .@{prefix}-switch__handle { top: 50%; - left: calc(100% - @switch-line-handle-size-checked-l); + left: 100%; right: auto; width: @switch-line-handle-size-checked-l; height: @switch-line-handle-size-checked-l; - transform: translateY(-50%); + transform: translate(-100%, -50%); .t-icon { font-size: @switch-line-handle-size-checked-l; @@ -440,7 +444,7 @@ right: auto; width: @switch-line-handle-size-s; height: @switch-line-handle-size-s; - transform: translateY(-50%); + transform: translate(0, -50%); .t-icon { font-size: @switch-line-handle-size-s; @@ -449,11 +453,11 @@ &.@{prefix}-is-checked .@{prefix}-switch__handle { top: 50%; - left: calc(100% - @switch-line-handle-size-checked-s); + left: 100%; right: auto; width: @switch-line-handle-size-checked-s; height: @switch-line-handle-size-checked-s; - transform: translateY(-50%); + transform: translate(-100%, -50%); .t-icon { font-size: @switch-line-handle-size-checked-s;