mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-07 09:26:06 +08:00
refactor: cssinjs for Switch (#34517)
* refactor: cssinjs for Switch * chore: restore less file for Switch * style: add fixme for origin numeric style
This commit is contained in:
parent
0eb5cb1e8a
commit
4f669b67af
@ -7,6 +7,7 @@ import Wave from '../_util/wave';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import SizeContext from '../config-provider/SizeContext';
|
||||
import devWarning from '../_util/devWarning';
|
||||
import useStyle from './style';
|
||||
|
||||
export type SwitchSize = 'small' | 'default';
|
||||
export type SwitchChangeEventHandler = (checked: boolean, event: MouseEvent) => void;
|
||||
@ -54,7 +55,7 @@ const Switch = React.forwardRef<unknown, SwitchProps>(
|
||||
'`value` is not a valid prop, do you mean `checked`?',
|
||||
);
|
||||
|
||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||
const { getPrefixCls, iconPrefixCls, direction } = React.useContext(ConfigContext);
|
||||
const size = React.useContext(SizeContext);
|
||||
const prefixCls = getPrefixCls('switch', customizePrefixCls);
|
||||
const loadingIcon = (
|
||||
@ -63,6 +64,9 @@ const Switch = React.forwardRef<unknown, SwitchProps>(
|
||||
</div>
|
||||
);
|
||||
|
||||
// Style
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls, iconPrefixCls);
|
||||
|
||||
const classes = classNames(
|
||||
{
|
||||
[`${prefixCls}-small`]: (customizeSize || size) === 'small',
|
||||
@ -70,9 +74,10 @@ const Switch = React.forwardRef<unknown, SwitchProps>(
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
},
|
||||
className,
|
||||
hashId,
|
||||
);
|
||||
|
||||
return (
|
||||
return wrapSSR(
|
||||
<Wave insertExtraNode>
|
||||
<RcSwitch
|
||||
{...props}
|
||||
@ -82,7 +87,7 @@ const Switch = React.forwardRef<unknown, SwitchProps>(
|
||||
ref={ref}
|
||||
loadingIcon={loadingIcon}
|
||||
/>
|
||||
</Wave>
|
||||
</Wave>,
|
||||
);
|
||||
},
|
||||
) as CompoundedComponent;
|
||||
|
@ -1,154 +1,154 @@
|
||||
@import '../../style/themes/index';
|
||||
@import '../../style/mixins/index';
|
||||
// @import '../../style/themes/index';
|
||||
// @import '../../style/mixins/index';
|
||||
|
||||
@switch-prefix-cls: ~'@{ant-prefix}-switch';
|
||||
@switch-duration: 0.2s;
|
||||
// @switch-prefix-cls: ~'@{ant-prefix}-switch';
|
||||
// @switch-duration: 0.2s;
|
||||
|
||||
@switch-pin-size: @switch-height - 4px;
|
||||
@switch-sm-pin-size: @switch-sm-height - 4px;
|
||||
// @switch-pin-size: @switch-height - 4px;
|
||||
// @switch-sm-pin-size: @switch-sm-height - 4px;
|
||||
|
||||
.@{switch-prefix-cls} {
|
||||
.reset-component();
|
||||
// .@{switch-prefix-cls} {
|
||||
// .reset-component();
|
||||
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
min-width: @switch-min-width;
|
||||
height: @switch-height;
|
||||
line-height: @switch-height;
|
||||
vertical-align: middle;
|
||||
background-color: @disabled-color;
|
||||
border: 0;
|
||||
border-radius: 100px;
|
||||
cursor: pointer;
|
||||
transition: all @switch-duration;
|
||||
user-select: none;
|
||||
// position: relative;
|
||||
// display: inline-block;
|
||||
// box-sizing: border-box;
|
||||
// min-width: @switch-min-width;
|
||||
// height: @switch-height;
|
||||
// line-height: @switch-height;
|
||||
// vertical-align: middle;
|
||||
// background-color: @disabled-color;
|
||||
// border: 0;
|
||||
// border-radius: 100px;
|
||||
// cursor: pointer;
|
||||
// transition: all @switch-duration;
|
||||
// user-select: none;
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 2px fade(@disabled-color, 10%);
|
||||
}
|
||||
// &:focus {
|
||||
// outline: 0;
|
||||
// box-shadow: 0 0 0 2px fade(@disabled-color, 10%);
|
||||
// }
|
||||
|
||||
&-checked:focus {
|
||||
box-shadow: 0 0 0 2px @primary-1;
|
||||
}
|
||||
// &-checked:focus {
|
||||
// box-shadow: 0 0 0 2px @primary-1;
|
||||
// }
|
||||
|
||||
&:focus:hover {
|
||||
box-shadow: none;
|
||||
}
|
||||
// &:focus:hover {
|
||||
// box-shadow: none;
|
||||
// }
|
||||
|
||||
&-checked {
|
||||
background-color: @switch-color;
|
||||
}
|
||||
// &-checked {
|
||||
// background-color: @switch-color;
|
||||
// }
|
||||
|
||||
&-loading,
|
||||
&-disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: @switch-disabled-opacity;
|
||||
// &-loading,
|
||||
// &-disabled {
|
||||
// cursor: not-allowed;
|
||||
// opacity: @switch-disabled-opacity;
|
||||
|
||||
* {
|
||||
box-shadow: none;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
// * {
|
||||
// box-shadow: none;
|
||||
// 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;
|
||||
}
|
||||
// // ========================= 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;
|
||||
}
|
||||
// &-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;
|
||||
// // ========================= 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: '';
|
||||
}
|
||||
}
|
||||
// &::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);
|
||||
}
|
||||
// &-checked &-handle {
|
||||
// left: calc(100% - @switch-pin-size - @switch-padding);
|
||||
// }
|
||||
|
||||
&:not(&-disabled):active {
|
||||
.@{switch-prefix-cls}-handle::before {
|
||||
right: -30%;
|
||||
left: 0;
|
||||
}
|
||||
// &: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%;
|
||||
}
|
||||
}
|
||||
}
|
||||
// &.@{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;
|
||||
}
|
||||
// // ======================== 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;
|
||||
}
|
||||
// &-checked &-loading-icon {
|
||||
// color: @switch-color;
|
||||
// }
|
||||
|
||||
// ========================== Size ==========================
|
||||
&-small {
|
||||
min-width: @switch-sm-min-width;
|
||||
height: @switch-sm-height;
|
||||
line-height: @switch-sm-height;
|
||||
// // ========================== 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}-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}-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}-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}-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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// .@{switch-prefix-cls}-handle {
|
||||
// left: calc(100% - @switch-sm-pin-size - @switch-padding);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@import './rtl';
|
||||
// @import './rtl';
|
||||
|
@ -1,2 +1,261 @@
|
||||
import '../../style/index.less';
|
||||
import './index.less';
|
||||
// deps-lint-skip-all
|
||||
import { TinyColor } from '@ctrl/tinycolor';
|
||||
import { CSSObject } from '@ant-design/cssinjs';
|
||||
import {
|
||||
DerivativeToken,
|
||||
resetComponent,
|
||||
UseComponentStyleResult,
|
||||
useStyleRegister,
|
||||
useToken,
|
||||
GenerateStyle,
|
||||
} from '../../_util/theme';
|
||||
|
||||
interface SwitchToken extends DerivativeToken {
|
||||
switchMinWidth: number;
|
||||
switchHeight: number;
|
||||
switchDuration: string;
|
||||
switchColor: string;
|
||||
switchDisabledOpacity: number;
|
||||
switchInnerMarginMin: number;
|
||||
switchInnerMarginMax: number;
|
||||
switchPadding: number;
|
||||
switchPinSize: number;
|
||||
switchBg: string;
|
||||
switchShadowColor: string;
|
||||
switchMinWidthSM: number;
|
||||
switchHeightSM: number;
|
||||
switchInnerMarginMinSM: number;
|
||||
switchInnerMarginMaxSM: number;
|
||||
switchPinSizeSM: number;
|
||||
switchCls: string;
|
||||
iconPrefixCls: string;
|
||||
}
|
||||
|
||||
const genSwitchSmallStyle: GenerateStyle<SwitchToken, CSSObject> = token => ({
|
||||
[`&${token.switchCls}-small`]: {
|
||||
minWidth: token.switchMinWidthSM,
|
||||
height: token.switchHeightSM,
|
||||
lineHeight: `${token.switchHeightSM}px`,
|
||||
|
||||
[`${token.switchCls}-inner`]: {
|
||||
marginInlineStart: token.switchInnerMarginMaxSM,
|
||||
marginInlineEnd: token.switchInnerMarginMinSM,
|
||||
fontSize: token.fontSizeSM,
|
||||
},
|
||||
|
||||
[`${token.switchCls}-handle`]: {
|
||||
width: token.switchPinSizeSM,
|
||||
height: token.switchPinSizeSM,
|
||||
},
|
||||
|
||||
[`${token.switchCls}-loading-icon`]: {
|
||||
top: (token.switchPinSizeSM - 9) / 2,
|
||||
// FIXME
|
||||
fontSize: 9,
|
||||
},
|
||||
|
||||
[`&${token.switchCls}-checked`]: {
|
||||
[`${token.switchCls}-inner`]: {
|
||||
marginInlineStart: token.switchInnerMarginMinSM,
|
||||
marginInlineEnd: token.switchInnerMarginMaxSM,
|
||||
},
|
||||
|
||||
[`${token.switchCls}-handle`]: {
|
||||
insetInlineStart: `calc(100% - ${token.switchPinSizeSM + token.switchPadding}px)`,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const genSwitchLoadingStyle: GenerateStyle<SwitchToken, CSSObject> = token => ({
|
||||
[`${token.switchCls}-loading-icon${token.iconPrefixCls}`]: {
|
||||
position: 'relative',
|
||||
top: (token.switchPinSize - token.fontSize) / 2,
|
||||
color: 'rgba(0, 0, 0, 0.65)',
|
||||
verticalAlign: 'top',
|
||||
},
|
||||
|
||||
[`&${token.switchCls}-checked ${token.switchCls}-loading-icon`]: {
|
||||
color: token.switchColor,
|
||||
},
|
||||
});
|
||||
|
||||
const genSwitchHandleStyle: GenerateStyle<SwitchToken, CSSObject> = token => {
|
||||
const switchHandleCls = `${token.switchCls}-handle`;
|
||||
|
||||
return {
|
||||
[switchHandleCls]: {
|
||||
position: 'absolute',
|
||||
top: token.switchPadding,
|
||||
insetInlineStart: token.switchPadding,
|
||||
width: token.switchPinSize,
|
||||
height: token.switchPinSize,
|
||||
transition: `all ${token.switchDuration} ease-in-out`,
|
||||
|
||||
'&::before': {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
insetInlineEnd: 0,
|
||||
bottom: 0,
|
||||
insetInlineStart: 0,
|
||||
backgroundColor: token.switchBg,
|
||||
borderRadius: token.switchPinSize / 2,
|
||||
// FIXME
|
||||
boxShadow: `0 2px 4px 0 ${token.switchShadowColor}`,
|
||||
transition: `all ${token.switchDuration} ease-in-out`,
|
||||
content: '""',
|
||||
},
|
||||
},
|
||||
|
||||
[`&${token.switchCls}-checked ${switchHandleCls}`]: {
|
||||
insetInlineStart: `calc(100% - ${token.switchPinSize + token.switchPadding}px)`,
|
||||
},
|
||||
|
||||
[`&:not(${token.switchCls}-disabled):active`]: {
|
||||
[`${switchHandleCls}::before`]: {
|
||||
// FIXME
|
||||
insetInlineEnd: '-30%',
|
||||
insetInlineStart: 0,
|
||||
},
|
||||
|
||||
[`&${token.switchCls}-checked ${switchHandleCls}::before`]: {
|
||||
insetInlineEnd: 0,
|
||||
// FIXME
|
||||
insetInlineStart: '-30%',
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const genSwitchInnerStyle: GenerateStyle<SwitchToken, CSSObject> = token => {
|
||||
const switchInnerCls = `${token.switchCls}-inner`;
|
||||
|
||||
return {
|
||||
[switchInnerCls]: {
|
||||
display: 'block',
|
||||
marginInlineEnd: token.switchInnerMarginMin,
|
||||
marginInlineStart: token.switchInnerMarginMax,
|
||||
color: token.textColorInverse,
|
||||
fontSize: token.fontSizeSM,
|
||||
transition: `margin-inline-end ${token.switchDuration}, margin-inline-start ${token.switchDuration}`,
|
||||
},
|
||||
|
||||
[`&${token.switchCls}-checked ${switchInnerCls}`]: {
|
||||
marginInlineEnd: token.switchInnerMarginMax,
|
||||
marginInlineStart: token.switchInnerMarginMin,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const genSwitchStyle = (token: SwitchToken): CSSObject => {
|
||||
const { switchCls } = token;
|
||||
|
||||
return {
|
||||
[switchCls]: {
|
||||
...resetComponent(token),
|
||||
|
||||
position: 'relative',
|
||||
display: 'inline-block',
|
||||
boxSizing: 'border-box',
|
||||
minWidth: token.switchMinWidth,
|
||||
height: token.switchHeight,
|
||||
lineHeight: `${token.switchHeight}px`,
|
||||
verticalAlign: 'middle',
|
||||
backgroundColor: token.textColorDisabled,
|
||||
border: '0',
|
||||
// FIXME
|
||||
borderRadius: 100,
|
||||
cursor: 'pointer',
|
||||
transition: `all ${token.switchDuration}`,
|
||||
userSelect: 'none',
|
||||
|
||||
'&:focus': {
|
||||
outline: 0,
|
||||
// FIXME
|
||||
boxShadow: `0 0 0 2px ${new TinyColor(token.textColorDisabled)
|
||||
.setAlpha(0.1)
|
||||
.toRgbString()}`,
|
||||
},
|
||||
|
||||
[`&${token.switchCls}-checked:focus`]: {
|
||||
// FIXME
|
||||
boxShadow: `0 0 0 2px ${token.tmpPrimaryHoverColorWeak}`,
|
||||
},
|
||||
|
||||
'&:focus:hover': {
|
||||
boxShadow: 'none',
|
||||
},
|
||||
|
||||
[`&${token.switchCls}-checked`]: {
|
||||
backgroundColor: token.switchColor,
|
||||
},
|
||||
|
||||
[`&${token.switchCls}-loading, &${token.switchCls}-disabled`]: {
|
||||
cursor: 'not-allowed',
|
||||
opacity: token.switchDisabledOpacity,
|
||||
|
||||
'*': {
|
||||
boxShadow: 'none',
|
||||
cursor: 'not-allowed',
|
||||
},
|
||||
},
|
||||
|
||||
// inner style
|
||||
...genSwitchInnerStyle(token),
|
||||
|
||||
// handle style
|
||||
...genSwitchHandleStyle(token),
|
||||
|
||||
// loading style
|
||||
...genSwitchLoadingStyle(token),
|
||||
|
||||
// small style
|
||||
...genSwitchSmallStyle(token),
|
||||
|
||||
// rtl style
|
||||
[`&${token.switchCls}-rtl`]: {
|
||||
direction: 'rtl',
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
// ============================== Export ==============================
|
||||
export default function useStyle(
|
||||
prefixCls: string,
|
||||
iconPrefixCls: string,
|
||||
): UseComponentStyleResult {
|
||||
const [theme, token, hashId] = useToken();
|
||||
const switchHeight = 22;
|
||||
const switchHeightSM = 16;
|
||||
|
||||
const switchToken: SwitchToken = {
|
||||
...token,
|
||||
// FIXME: missing token
|
||||
switchMinWidth: 44,
|
||||
switchHeight,
|
||||
switchDuration: '0.2s',
|
||||
switchColor: token.primaryColor,
|
||||
switchDisabledOpacity: 0.4,
|
||||
switchInnerMarginMin: Math.ceil(switchHeight * 0.3),
|
||||
switchInnerMarginMax: Math.ceil(switchHeight * 1.1),
|
||||
switchPadding: 2,
|
||||
switchPinSize: switchHeight - 4,
|
||||
switchBg: token.componentBackground,
|
||||
switchShadowColor: new TinyColor('#00230b').setAlpha(0.2).toRgbString(),
|
||||
switchMinWidthSM: 28,
|
||||
switchHeightSM,
|
||||
switchInnerMarginMinSM: Math.ceil(switchHeight * 0.3),
|
||||
switchInnerMarginMaxSM: Math.ceil(switchHeight * 1.1),
|
||||
switchPinSizeSM: switchHeightSM - 4,
|
||||
switchCls: `.${prefixCls}`,
|
||||
iconPrefixCls: `.${iconPrefixCls}`,
|
||||
};
|
||||
|
||||
return [
|
||||
useStyleRegister({ theme, token, hashId, path: [prefixCls] }, () => [
|
||||
genSwitchStyle(switchToken),
|
||||
]),
|
||||
hashId,
|
||||
];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user