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:
Peach 2022-03-16 15:04:47 +08:00 committed by GitHub
parent 0eb5cb1e8a
commit 4f669b67af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 397 additions and 133 deletions

View File

@ -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;

View File

@ -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';

View File

@ -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,
];
}