Refactor/cssinjs in radio (#34740)

* feat: basic convert to cssinjs

* feat: update

* fix: lint issue

* fix: remove important

* chore: update

* chore: update

* refactor: add optionType for Radio instead of using prefixCls

* fix: use colorPrimaryOutline for  primary-1

* chore: add some comments

* fix: conflict code cleanup

* feat: use motionDurationSlow instead of radioDuration

* chore: update

* chore: update

* fix: use isnert-inline for position left/right

* fix: use css logical properties and values

* fix: padding
This commit is contained in:
vagusX 2022-04-14 19:14:54 +08:00 committed by GitHub
parent 9f0397c585
commit 10427f7c3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 872 additions and 375 deletions

View File

@ -13,4 +13,3 @@ MiniSelect.Option = Select.Option;
MiddleSelect.Option = Select.Option;
export { MiniSelect, MiddleSelect };

View File

@ -7,6 +7,7 @@ import { ConfigContext } from '../config-provider';
import SizeContext from '../config-provider/SizeContext';
import { RadioGroupContextProvider } from './context';
import getDataOrAriaProps from '../_util/getDataOrAriaProps';
import useStyle from './style';
const RadioGroup = React.forwardRef<HTMLDivElement, RadioGroupProps>((props, ref) => {
const { getPrefixCls, direction } = React.useContext(ConfigContext);
@ -16,6 +17,13 @@ const RadioGroup = React.forwardRef<HTMLDivElement, RadioGroupProps>((props, ref
value: props.value,
});
const { prefixCls: customizePrefixCls } = props;
const prefixCls = getPrefixCls('radio', customizePrefixCls);
const groupPrefixCls = `${prefixCls}-group`;
// Style
const [wrapSSR, hashId] = useStyle(prefixCls, getPrefixCls());
const onRadioChange = (ev: RadioChangeEvent) => {
const lastValue = value;
const val = ev.target.value;
@ -30,7 +38,6 @@ const RadioGroup = React.forwardRef<HTMLDivElement, RadioGroupProps>((props, ref
const renderGroup = () => {
const {
prefixCls: customizePrefixCls,
className = '',
options,
buttonStyle = 'outline' as RadioGroupButtonStyle,
@ -42,8 +49,6 @@ const RadioGroup = React.forwardRef<HTMLDivElement, RadioGroupProps>((props, ref
onMouseEnter,
onMouseLeave,
} = props;
const prefixCls = getPrefixCls('radio', customizePrefixCls);
const groupPrefixCls = `${prefixCls}-group`;
let childrenToRender = children;
// 如果存在 options, 优先使用
if (options && options.length > 0) {
@ -87,8 +92,9 @@ const RadioGroup = React.forwardRef<HTMLDivElement, RadioGroupProps>((props, ref
[`${groupPrefixCls}-rtl`]: direction === 'rtl',
},
className,
hashId,
);
return (
return wrapSSR(
<div
{...getDataOrAriaProps(props)}
className={classString}
@ -99,7 +105,7 @@ const RadioGroup = React.forwardRef<HTMLDivElement, RadioGroupProps>((props, ref
ref={ref}
>
{childrenToRender}
</div>
</div>,
);
};

View File

@ -34,7 +34,15 @@ export interface RadioGroupContextProps {
optionType?: RadioGroupOptionType;
}
export type RadioProps = AbstractCheckboxProps<RadioChangeEvent>;
export interface RadioProps extends AbstractCheckboxProps<RadioChangeEvent> {
/**
* Control the appearance for Radio to display as button or not
*
* @default 'default'
* @internal
*/
optionType?: RadioGroupOptionType;
}
export interface RadioChangeEventTarget extends RadioProps {
checked: boolean;

View File

@ -9,6 +9,8 @@ import { ConfigContext } from '../config-provider';
import RadioGroupContext, { RadioOptionTypeContext } from './context';
import devWarning from '../_util/devWarning';
import useStyle from './style';
const InternalRadio: React.ForwardRefRenderFunction<HTMLElement, RadioProps> = (props, ref) => {
const groupContext = React.useContext(RadioGroupContext);
const radioOptionTypeContext = React.useContext(RadioOptionTypeContext);
@ -34,6 +36,9 @@ const InternalRadio: React.ForwardRefRenderFunction<HTMLElement, RadioProps> = (
? `${radioPrefixCls}-button`
: radioPrefixCls;
// Style
const [wrapSSR, hashId] = useStyle(radioPrefixCls, getPrefixCls());
const radioProps: RadioProps = { ...restProps };
if (groupContext) {
radioProps.name = groupContext.name;
@ -50,9 +55,10 @@ const InternalRadio: React.ForwardRefRenderFunction<HTMLElement, RadioProps> = (
[`${prefixCls}-wrapper-in-form-item`]: isFormItemInput,
},
className,
hashId,
);
return (
return wrapSSR(
// eslint-disable-next-line jsx-a11y/label-has-associated-control
<label
className={wrapperClassString}
@ -62,7 +68,7 @@ const InternalRadio: React.ForwardRefRenderFunction<HTMLElement, RadioProps> = (
>
<RcCheckbox {...radioProps} type="radio" prefixCls={prefixCls} ref={mergedRef} />
{children !== undefined ? <span>{children}</span> : null}
</label>
</label>,
);
};

View File

@ -1,366 +1,359 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
// @import '../../style/themes/index';
// @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: 0.3s;
@radio-focus-shadow: 0 0 0 3px @primary-1;
@radio-button-focus-shadow: @radio-focus-shadow;
// @radio-prefix-cls: ~'@{ant-prefix}-radio';
// @radio-group-prefix-cls: ~'@{radio-prefix-cls}-group';
// @radio-inner-prefix-cls: ~'@{radio-prefix-cls}-inner';
// @radio-duration: 0.3s;
// @radio-focus-shadow: 0 0 0 3px @primary-1;
// @radio-button-focus-shadow: @radio-focus-shadow;
.@{radio-group-prefix-cls} {
.reset-component();
// .@{radio-group-prefix-cls} {
// .reset-component();
display: inline-block;
font-size: 0;
// display: inline-block;
// font-size: 0;
.@{ant-prefix}-badge-count {
z-index: 1;
}
// .@{ant-prefix}-badge-count {
// z-index: 1;
// }
> .@{ant-prefix}-badge:not(:first-child) > .@{radio-prefix-cls}-button-wrapper {
border-left: none;
}
}
// > .@{ant-prefix}-badge:not(:first-child) > .@{radio-prefix-cls}-button-wrapper {
// border-left: none;
// }
// }
// 一般状态
.@{radio-prefix-cls}-wrapper {
.reset-component();
position: relative;
display: inline-flex;
align-items: baseline;
margin-right: @radio-wrapper-margin-right;
cursor: pointer;
// // 一般状态
// .@{radio-prefix-cls}-wrapper {
// .reset-component();
// position: relative;
// display: inline-flex;
// align-items: baseline;
// margin-right: @radio-wrapper-margin-right;
// cursor: pointer;
&-disabled {
cursor: not-allowed;
}
// &-disabled {
// cursor: not-allowed;
// }
&::after {
display: inline-block;
width: 0;
overflow: hidden;
content: '\a0';
}
// &::after {
// display: inline-block;
// width: 0;
// overflow: hidden;
// content: '\a0';
// }
// }
&&-in-form-item {
input[type='radio'] {
width: 14px;
height: 14px;
}
}
}
// .@{radio-prefix-cls} {
// .reset-component();
.@{radio-prefix-cls} {
.reset-component();
// position: relative;
// top: @radio-top;
// display: inline-block;
// outline: none;
// cursor: pointer;
position: relative;
top: @radio-top;
display: inline-block;
outline: none;
cursor: pointer;
// .@{radio-prefix-cls}-wrapper:hover &,
// &:hover .@{radio-inner-prefix-cls},
// &-input:focus + .@{radio-inner-prefix-cls} {
// border-color: @radio-dot-color;
// }
.@{radio-prefix-cls}-wrapper:hover &,
&:hover .@{radio-inner-prefix-cls},
&-input:focus + .@{radio-inner-prefix-cls} {
border-color: @radio-dot-color;
}
// &-input:focus + .@{radio-inner-prefix-cls} {
// box-shadow: @radio-focus-shadow;
// }
&-input:focus + .@{radio-inner-prefix-cls} {
box-shadow: @radio-focus-shadow;
}
// &-checked::after {
// position: absolute;
// top: 0;
// left: 0;
// width: 100%;
// height: 100%;
// border: 1px solid @radio-dot-color;
// border-radius: 50%;
// visibility: hidden;
// animation: antRadioEffect 0.36s ease-in-out;
// animation-fill-mode: both;
// content: '';
// }
&-checked::after {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 1px solid @radio-dot-color;
border-radius: 50%;
visibility: hidden;
animation: antRadioEffect 0.36s ease-in-out;
animation-fill-mode: both;
content: '';
}
// &:hover::after,
// .@{radio-prefix-cls}-wrapper:hover &::after {
// visibility: visible;
// }
&:hover::after,
.@{radio-prefix-cls}-wrapper:hover &::after {
visibility: visible;
}
// &-inner {
// &::after {
// position: absolute;
// top: 50%;
// left: 50%;
// display: block;
// width: @radio-size;
// height: @radio-size;
// margin-top: -(@radio-size / 2);
// margin-left: -(@radio-size / 2);
// background-color: @radio-dot-color;
// border-top: 0;
// border-left: 0;
// border-radius: @radio-size;
// transform: scale(0);
// opacity: 0;
// transition: all @radio-duration @ease-in-out-circ;
// content: ' ';
// }
&-inner {
&::after {
position: absolute;
top: 50%;
left: 50%;
display: block;
width: @radio-size;
height: @radio-size;
margin-top: -(@radio-size / 2);
margin-left: -(@radio-size / 2);
background-color: @radio-dot-color;
border-top: 0;
border-left: 0;
border-radius: @radio-size;
transform: scale(0);
opacity: 0;
transition: all @radio-duration @ease-in-out-circ;
content: ' ';
}
// position: relative;
// top: 0;
// left: 0;
// display: block;
// width: @radio-size;
// height: @radio-size;
// background-color: @radio-button-bg;
// border-color: @border-color-base;
// border-style: solid;
// border-width: @radio-border-width;
// border-radius: 50%;
// transition: all @radio-duration;
// }
position: relative;
top: 0;
left: 0;
display: block;
width: @radio-size;
height: @radio-size;
background-color: @radio-button-bg;
border-color: @border-color-base;
border-style: solid;
border-width: @radio-border-width;
border-radius: 50%;
transition: all @radio-duration;
}
// &-input {
// position: absolute;
// top: 0;
// right: 0;
// bottom: 0;
// left: 0;
// z-index: 1;
// cursor: pointer;
// opacity: 0;
// }
// }
&-input {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1;
cursor: pointer;
opacity: 0;
}
}
// // 选中状态
// .@{radio-prefix-cls}-checked {
// .@{radio-inner-prefix-cls} {
// border-color: @radio-dot-color;
// 选中状态
.@{radio-prefix-cls}-checked {
.@{radio-inner-prefix-cls} {
border-color: @radio-dot-color;
// &::after {
// transform: scale((unit(@radio-dot-size) / unit(@radio-size)));
// opacity: 1;
// transition: all @radio-duration @ease-in-out-circ;
// }
// }
// }
&::after {
transform: scale((unit(@radio-dot-size) / unit(@radio-size)));
opacity: 1;
transition: all @radio-duration @ease-in-out-circ;
}
}
}
// .@{radio-prefix-cls}-disabled {
// cursor: not-allowed;
.@{radio-prefix-cls}-disabled {
cursor: not-allowed;
// .@{radio-inner-prefix-cls} {
// background-color: @input-disabled-bg;
// border-color: @border-color-base !important;
// cursor: not-allowed;
.@{radio-inner-prefix-cls} {
background-color: @input-disabled-bg;
border-color: @border-color-base !important;
cursor: not-allowed;
// &::after {
// background-color: @radio-dot-disabled-color;
// }
// }
&::after {
background-color: @radio-dot-disabled-color;
}
}
// .@{radio-prefix-cls}-input {
// cursor: not-allowed;
// }
.@{radio-prefix-cls}-input {
cursor: not-allowed;
}
// & + span {
// color: @disabled-color;
// cursor: not-allowed;
// }
// }
& + span {
color: @disabled-color;
cursor: not-allowed;
}
}
// span.@{radio-prefix-cls} + * {
// padding-right: 8px;
// padding-left: 8px;
// }
span.@{radio-prefix-cls} + * {
padding-right: 8px;
padding-left: 8px;
}
// .@{radio-prefix-cls}-button-wrapper {
// position: relative;
// display: inline-block;
// height: @btn-height-base;
// margin: 0;
// padding: 0 @radio-button-padding-horizontal;
// color: @radio-button-color;
// font-size: @font-size-base;
// line-height: @btn-height-base - 2px;
// background: @radio-button-bg;
// border: @border-width-base @border-style-base @border-color-base;
// // strange align fix for chrome but works
// // https://gw.alipayobjects.com/zos/rmsportal/VFTfKXJuogBAXcvfAUWJ.gif
// border-top-width: @border-width-base + 0.02px;
// border-left-width: 0;
// cursor: pointer;
// transition: color 0.3s, background 0.3s, border-color 0.3s, box-shadow 0.3s;
.@{radio-prefix-cls}-button-wrapper {
position: relative;
display: inline-block;
height: @btn-height-base;
margin: 0;
padding: 0 @radio-button-padding-horizontal;
color: @radio-button-color;
font-size: @font-size-base;
line-height: @btn-height-base - 2px;
background: @radio-button-bg;
border: @border-width-base @border-style-base @border-color-base;
// strange align fix for chrome but works
// https://gw.alipayobjects.com/zos/rmsportal/VFTfKXJuogBAXcvfAUWJ.gif
border-top-width: @border-width-base + 0.02px;
border-left-width: 0;
cursor: pointer;
transition: color 0.3s, background 0.3s, border-color 0.3s, box-shadow 0.3s;
// a {
// color: @radio-button-color;
// }
a {
color: @radio-button-color;
}
// > .@{radio-prefix-cls}-button {
// position: absolute;
// top: 0;
// left: 0;
// z-index: -1;
// width: 100%;
// height: 100%;
// }
> .@{radio-prefix-cls}-button {
position: absolute;
top: 0;
left: 0;
z-index: -1;
width: 100%;
height: 100%;
}
// .@{radio-group-prefix-cls}-large & {
// height: @input-height-lg;
// font-size: @font-size-lg;
// line-height: @input-height-lg - 2px;
// }
.@{radio-group-prefix-cls}-large & {
height: @input-height-lg;
font-size: @font-size-lg;
line-height: @input-height-lg - 2px;
}
// .@{radio-group-prefix-cls}-small & {
// height: @input-height-sm;
// padding: 0 @control-padding-horizontal-sm - 1px;
// line-height: @input-height-sm - 2px;
// }
.@{radio-group-prefix-cls}-small & {
height: @input-height-sm;
padding: 0 @control-padding-horizontal-sm - 1px;
line-height: @input-height-sm - 2px;
}
// &:not(:first-child) {
// &::before {
// position: absolute;
// top: @border-width-base * -1;
// left: -1px;
// display: block;
// box-sizing: content-box;
// width: 1px;
// height: 100%;
// padding: @border-width-base 0;
// background-color: @border-color-base;
// transition: background-color 0.3s;
// content: '';
// }
// }
&:not(:first-child) {
&::before {
position: absolute;
top: @border-width-base * -1;
left: -1px;
display: block;
box-sizing: content-box;
width: 1px;
height: 100%;
padding: @border-width-base 0;
background-color: @border-color-base;
transition: background-color 0.3s;
content: '';
}
}
// &:first-child {
// border-left: @border-width-base @border-style-base @border-color-base;
// border-radius: @border-radius-base 0 0 @border-radius-base;
// }
&:first-child {
border-left: @border-width-base @border-style-base @border-color-base;
border-radius: @border-radius-base 0 0 @border-radius-base;
}
// &:last-child {
// border-radius: 0 @border-radius-base @border-radius-base 0;
// }
&:last-child {
border-radius: 0 @border-radius-base @border-radius-base 0;
}
// &:first-child:last-child {
// border-radius: @border-radius-base;
// }
&:first-child:last-child {
border-radius: @border-radius-base;
}
// &:hover {
// position: relative;
// color: @radio-dot-color;
// }
&:hover {
position: relative;
color: @radio-dot-color;
}
// &:focus-within {
// box-shadow: @radio-button-focus-shadow;
// }
&:focus-within {
box-shadow: @radio-button-focus-shadow;
}
// .@{radio-prefix-cls}-inner,
// input[type='checkbox'],
// input[type='radio'] {
// width: 0;
// height: 0;
// opacity: 0;
// pointer-events: none;
// }
.@{radio-prefix-cls}-inner,
input[type='checkbox'],
input[type='radio'] {
width: 0;
height: 0;
opacity: 0;
pointer-events: none;
}
// &-checked:not(&-disabled) {
// z-index: 1;
// color: @radio-dot-color;
// background: @radio-button-checked-bg;
// border-color: @radio-dot-color;
&-checked:not(&-disabled) {
z-index: 1;
color: @radio-dot-color;
background: @radio-button-checked-bg;
border-color: @radio-dot-color;
// &::before {
// background-color: @radio-dot-color;
// }
&::before {
background-color: @radio-dot-color;
}
// &:first-child {
// border-color: @radio-dot-color;
// }
&:first-child {
border-color: @radio-dot-color;
}
// &:hover {
// color: @radio-button-hover-color;
// border-color: @radio-button-hover-color;
&:hover {
color: @radio-button-hover-color;
border-color: @radio-button-hover-color;
// &::before {
// background-color: @radio-button-hover-color;
// }
// }
&::before {
background-color: @radio-button-hover-color;
}
}
// &:active {
// color: @radio-button-active-color;
// border-color: @radio-button-active-color;
&:active {
color: @radio-button-active-color;
border-color: @radio-button-active-color;
// &::before {
// background-color: @radio-button-active-color;
// }
// }
&::before {
background-color: @radio-button-active-color;
}
}
// &:focus-within {
// box-shadow: @radio-button-focus-shadow;
// }
// }
&:focus-within {
box-shadow: @radio-button-focus-shadow;
}
}
// .@{radio-group-prefix-cls}-solid &-checked:not(&-disabled) {
// color: @radio-solid-checked-color;
// background: @radio-dot-color;
// border-color: @radio-dot-color;
.@{radio-group-prefix-cls}-solid &-checked:not(&-disabled) {
color: @radio-solid-checked-color;
background: @radio-dot-color;
border-color: @radio-dot-color;
// &:hover {
// color: @radio-solid-checked-color;
// background: @radio-button-hover-color;
// border-color: @radio-button-hover-color;
// }
&:hover {
color: @radio-solid-checked-color;
background: @radio-button-hover-color;
border-color: @radio-button-hover-color;
}
// &:active {
// color: @radio-solid-checked-color;
// background: @radio-button-active-color;
// border-color: @radio-button-active-color;
// }
&:active {
color: @radio-solid-checked-color;
background: @radio-button-active-color;
border-color: @radio-button-active-color;
}
// &:focus-within {
// box-shadow: @radio-button-focus-shadow;
// }
// }
&:focus-within {
box-shadow: @radio-button-focus-shadow;
}
}
// &-disabled {
// color: @disabled-color;
// background-color: @input-disabled-bg;
// border-color: @border-color-base;
// cursor: not-allowed;
&-disabled {
color: @disabled-color;
background-color: @input-disabled-bg;
border-color: @border-color-base;
cursor: not-allowed;
// &:first-child,
// &:hover {
// color: @disabled-color;
// background-color: @input-disabled-bg;
// border-color: @border-color-base;
// }
&:first-child,
&:hover {
color: @disabled-color;
background-color: @input-disabled-bg;
border-color: @border-color-base;
}
// &:first-child {
// border-left-color: @border-color-base;
// }
// }
&:first-child {
border-left-color: @border-color-base;
}
}
// &-disabled&-checked {
// color: @radio-disabled-button-checked-color;
// background-color: @radio-disabled-button-checked-bg;
// border-color: @border-color-base;
// box-shadow: none;
// }
// }
&-disabled&-checked {
color: @radio-disabled-button-checked-color;
background-color: @radio-disabled-button-checked-bg;
border-color: @border-color-base;
box-shadow: none;
}
}
// @keyframes antRadioEffect {
// 0% {
// transform: scale(1);
// opacity: 0.5;
// }
@keyframes antRadioEffect {
0% {
transform: scale(1);
opacity: 0.5;
}
// 100% {
// transform: scale(1.6);
// opacity: 0;
// }
// }
100% {
transform: scale(1.6);
opacity: 0;
}
}
@import './rtl';
// @import './rtl';

View File

@ -1,3 +1,488 @@
import '../../style/index.less';
import './index.less';
// deps-lint-skip: form
// deps-lint-skip-all
import { CSSInterpolation, Keyframes } from '@ant-design/cssinjs';
import { TinyColor } from '@ctrl/tinycolor';
import {
DerivativeToken,
useStyleRegister,
useToken,
resetComponent,
UseComponentStyleResult,
} from '../../_util/theme';
import { GlobalToken } from '../../_util/theme/interface';
// ============================== Tokens ==============================
interface RadioToken extends DerivativeToken {
radioFocusShadow: string;
radioButtonFocusShadow: string;
radioSize: number;
radioTop: string;
radioDotSize: number;
radioDotColor: string;
radioDotDisabledColor: string;
radioSolidCheckedColor: string;
radioButtonBg: string;
radioButtonCheckedBg: string;
radioButtonColor: string;
radioButtonHoverColor: string;
radioButtonActiveColor: string;
radioButtonPaddingHorizontal: number;
radioDisabledButtonCheckedBg: string;
radioDisabledButtonCheckedColor: string;
radioWrapperMarginRight: number;
}
function getRadioToken(token: GlobalToken) {
// Radio
const radioFocusShadow = `0 0 0 3px ${token.colorPrimaryOutline}`;
const radioButtonFocusShadow = radioFocusShadow;
const radioSize = token.fontSizeLG;
// FIXME: hard code
const radioTop = '0.2em';
// FIXME: hard code
const radioDotSize = radioSize - 8;
const radioDotColor = token.colorPrimary;
// FIXME: hard code
const radioDotDisabledColor = new TinyColor('#000').setAlpha(0.2).toRgbString();
const radioSolidCheckedColor = token.colorBgComponent;
// Radio buttons
const radioButtonBg = token.colorBgComponent;
const radioButtonCheckedBg = token.colorBgComponent;
const radioButtonColor = token.colorText;
const radioButtonHoverColor = token.colorPrimaryHover;
const radioButtonActiveColor = token.colorPrimaryActive;
// FIXME: hard code
const radioButtonPaddingHorizontal = token.padding - 1;
// FIXME: hard code
const radioDisabledButtonCheckedBg = new TinyColor('#000').tint(90).toRgbString();
const radioDisabledButtonCheckedColor = token.colorTextDisabled;
const radioWrapperMarginRight = token.marginXS;
return {
...token,
radioFocusShadow,
radioButtonFocusShadow,
radioSize,
radioTop,
radioDotSize,
radioDotColor,
radioDotDisabledColor,
radioSolidCheckedColor,
radioButtonBg,
radioButtonCheckedBg,
radioButtonColor,
radioButtonHoverColor,
radioButtonActiveColor,
radioButtonPaddingHorizontal,
radioDisabledButtonCheckedBg,
radioDisabledButtonCheckedColor,
radioWrapperMarginRight,
};
}
// ============================== Styles ==============================
const antRadioEffect = new Keyframes('antRadioEffect', {
'0%': { transform: 'scale(1)', opacity: 0.5 },
'100%': { transform: 'scale(1.6)', opacity: 0 },
});
// styles from RadioGroup only
function getGroupRadioStyle(
prefixCls: string,
antPrefix: string,
token: DerivativeToken,
): CSSInterpolation {
const groupPrefixCls = `${prefixCls}-group`;
return {
[`.${groupPrefixCls}`]: {
...resetComponent(token),
display: 'inline-block',
fontSize: 0,
// RTL
'&&-rtl': {
direction: 'rtl',
},
[`.${antPrefix}-badge .${antPrefix}-badge-count`]: {
zIndex: 1,
},
[`> .${antPrefix}-badge:not(:first-child) > .${prefixCls}-button-wrapper`]: {
borderInlineStart: 'none',
},
},
};
}
// Styles from radio-wrapper
function getRadioBasicStyle(
prefixCls: string,
hashId: string,
token: RadioToken,
): CSSInterpolation {
const radioInnerPrefixCls = `${prefixCls}-inner`;
return {
[`.${prefixCls}-wrapper`]: {
...resetComponent(token),
position: 'relative',
display: 'inline-flex',
alignItems: 'baseline',
marginInlineStart: 0,
marginInlineEnd: token.radioWrapperMarginRight,
cursor: 'pointer',
// RTL
'&&-rtl': {
direction: 'rtl',
},
'&-disabled': {
cursor: 'not-allowed',
},
'&::after': {
display: 'inline-block',
width: 0,
overflow: 'hidden',
content: '"\\a0"',
},
// hashId 在 wrapper 上,只能铺平
[`.${prefixCls}-checked::after`]: {
position: 'absolute',
insetBlockStart: 0,
insetInlineStart: 0,
width: '100%',
height: '100%',
border: `1px solid ${token.radioDotColor}`,
borderRadius: '50%',
visibility: 'hidden',
animation: `${antRadioEffect.getName(hashId)} 0.36s ease-in-out`,
animationFillMode: 'both',
content: '""',
},
[`.${prefixCls}`]: {
...resetComponent(token),
position: 'relative',
insetBlockStart: token.radioTop,
display: 'inline-block',
outline: 'none',
cursor: 'pointer',
},
[`.${prefixCls}-wrapper:hover &,
&:hover .${radioInnerPrefixCls},
&-input:focus + .${radioInnerPrefixCls}`]: {
borderColor: token.radioDotColor,
},
[`.${prefixCls}-input:focus + .${radioInnerPrefixCls}`]: {
boxShadow: token.radioFocusShadow,
},
[`.${prefixCls}:hover::after, .${prefixCls}-wrapper:hover &::after`]: {
visibility: 'visible',
},
[`.${prefixCls}-inner`]: {
'&::after': {
position: 'absolute',
insetBlockStart: '50%',
insetInlineStart: '50%',
display: 'block',
width: token.radioSize,
height: token.radioSize,
marginBlockStart: token.radioSize / -2,
marginInlineStart: token.radioSize / -2,
backgroundColor: token.radioDotColor,
borderBlockStart: 0,
borderInlineStart: 0,
borderRadius: token.radioSize,
transform: 'scale(0)',
opacity: 0,
transition: `all ${token.motionDurationSlow} ${token.motionEaseInOutCirc}`,
content: '""',
},
position: 'relative',
insetBlockStart: 0,
insetInlineStart: 0,
display: 'block',
width: token.radioSize,
height: token.radioSize,
backgroundColor: token.radioButtonBg,
borderColor: token.colorBorder,
borderStyle: 'solid',
borderWidth: token.controlLineWidth,
borderRadius: '50%',
transition: `all ${token.motionDurationSlow}`,
},
[`.${prefixCls}-input`]: {
position: 'absolute',
insetBlockStart: 0,
insetInlineEnd: 0,
insetBlockEnd: 0,
insetInlineStart: 0,
zIndex: 1,
cursor: 'pointer',
opacity: 0,
},
// 选中状态
[`.${prefixCls}-checked`]: {
[`.${radioInnerPrefixCls}`]: {
borderColor: token.radioDotColor,
'&::after': {
transform: `scale(${token.radioDotSize / token.radioSize})`,
opacity: 1,
transition: `all ${token.motionDurationSlow} ${token.motionEaseInOutCirc}`,
},
},
},
[`.${prefixCls}-disabled`]: {
cursor: 'not-allowed',
[`.${radioInnerPrefixCls}`]: {
backgroundColor: token.colorBgComponentDisabled,
borderColor: `${token.colorBorder} !important`,
cursor: 'not-allowed',
'&::after': {
backgroundColor: token.radioDotDisabledColor,
},
},
'&-input': {
cursor: 'not-allowed',
},
[`.${prefixCls}-disabled + span`]: {
color: token.colorTextDisabled,
cursor: 'not-allowed',
},
},
[`span.${prefixCls} + *`]: {
paddingInlineStart: token.paddingXS,
paddingInlineEnd: token.paddingXS,
},
antRadioEffect,
},
};
}
// Styles from radio-button
function getRadioButtonStyle(prefixCls: string, token: RadioToken): CSSInterpolation {
return {
[`.${prefixCls}-button-wrapper`]: {
position: 'relative',
display: 'inline-block',
height: token.controlHeight,
margin: 0,
paddingInline: token.radioButtonPaddingHorizontal,
paddingBlock: 0,
color: token.radioButtonColor,
fontSize: token.fontSize,
lineHeight: `${token.controlHeight - token.controlLineWidth * 2}px`,
background: token.radioButtonBg,
border: `${token.controlLineWidth}px ${token.controlLineType} ${token.colorBorder}`,
// strange align fix for chrome but works
// https://gw.alipayobjects.com/zos/rmsportal/VFTfKXJuogBAXcvfAUWJ.gif
borderBlockStartWidth: token.controlLineWidth + 0.02,
borderInlineStartWidth: 0,
borderInlineEndWidth: token.controlLineWidth,
cursor: 'pointer',
transition: `color ${token.motionDurationSlow}, background ${token.motionDurationSlow}, border-color ${token.motionDurationSlow}, box-shadow ${token.motionDurationSlow}`,
a: {
color: token.radioButtonColor,
},
[`> .${prefixCls}-button`]: {
position: 'absolute',
insetBlockStart: 0,
insetInlineStart: 0,
zIndex: -1,
width: '100%',
height: '100%',
},
[`.${prefixCls}-group-large &`]: {
height: token.controlHeightLG,
fontSize: token.fontSizeLG,
lineHeight: `${token.controlHeightLG - token.controlLineWidth * 2}px`,
},
[`.${prefixCls}-group-small &`]: {
height: token.controlHeightSM,
paddingInline: token.paddingXS - token.controlLineWidth,
paddingBlock: 0,
lineHeight: `${token.controlHeightSM - token.controlLineWidth * 2}px`,
},
'&:not(:first-child)': {
'&::before': {
position: 'absolute',
insetBlockStart: -token.controlLineWidth,
insetInlineStart: -token.controlLineWidth,
display: 'block',
boxSizing: 'content-box',
width: 1,
height: '100%',
paddingBlock: token.controlLineWidth,
paddingInline: 0,
backgroundColor: token.colorBorder,
transition: `background-color ${token.motionDurationSlow}`,
content: '""',
},
},
'&:first-child': {
borderInlineStart: `${token.controlLineWidth}px ${token.controlLineType} ${token.colorBorder}`,
borderStartStartRadius: token.controlRadius,
borderEndStartRadius: token.controlRadius,
},
'&:last-child': {
borderStartEndRadius: token.controlRadius,
borderEndEndRadius: token.controlRadius,
},
'&:first-child:last-child': {
borderRadius: token.controlRadius,
},
'&:hover': {
position: 'relative',
color: token.radioDotColor,
},
'&:focus-within': {
boxShadow: token.radioButtonFocusShadow,
},
[`.${prefixCls}-inner, input[type='checkbox'], input[type='radio']`]: {
width: 0,
height: 0,
opacity: 0,
pointerEvents: 'none',
},
'&-checked:not(&-disabled)': {
zIndex: 1,
color: token.radioDotColor,
background: token.radioButtonCheckedBg,
borderColor: token.radioDotColor,
'&::before': {
backgroundColor: token.radioDotColor,
},
'&:first-child': {
borderColor: token.radioDotColor,
},
'&:hover': {
color: token.radioButtonHoverColor,
borderColor: token.radioButtonHoverColor,
'&::before': {
backgroundColor: token.radioButtonHoverColor,
},
},
'&:active': {
color: token.radioButtonActiveColor,
borderColor: token.radioButtonActiveColor,
'&::before': {
backgroundColor: token.radioButtonActiveColor,
},
},
'&:focus-within': {
boxShadow: token.radioButtonFocusShadow,
},
},
[`.${prefixCls}-group-solid &-checked:not(&-disabled)`]: {
color: token.radioSolidCheckedColor,
background: token.radioDotColor,
borderColor: token.radioDotColor,
'&:hover': {
color: token.radioSolidCheckedColor,
background: token.radioButtonHoverColor,
borderColor: token.radioButtonHoverColor,
},
'&:active': {
color: token.radioSolidCheckedColor,
background: token.radioButtonActiveColor,
borderColor: token.radioButtonActiveColor,
},
'&:focus-within': {
boxShadow: token.radioButtonFocusShadow,
},
},
'&-disabled': {
color: token.colorTextDisabled,
backgroundColor: token.colorBgComponentDisabled,
borderColor: token.colorBorder,
cursor: 'not-allowed',
'&:first-child, &:hover': {
color: token.colorTextDisabled,
backgroundColor: token.colorBgComponentDisabled,
borderColor: token.colorBorder,
},
},
'&-disabled&-checked': {
color: token.radioDisabledButtonCheckedColor,
backgroundColor: token.radioDisabledButtonCheckedBg,
borderColor: token.colorBorder,
boxShadow: 'none',
},
},
};
}
// ============================== Export ==============================
export function getStyle(
prefixCls: string,
hashId: string,
antPrefix: string,
token: RadioToken,
): CSSInterpolation {
return [
getGroupRadioStyle(prefixCls, antPrefix, token),
getRadioBasicStyle(prefixCls, hashId, token),
getRadioButtonStyle(prefixCls, token),
];
}
export default function useStyle(prefixCls: string, antPrefix: string): UseComponentStyleResult {
const [theme, token, hashId] = useToken();
return [
useStyleRegister({ theme, token, hashId, path: [prefixCls] }, () => {
const radioToken = getRadioToken(token);
return getStyle(prefixCls, hashId, antPrefix, radioToken);
}),
hashId,
];
}

View File

@ -1,61 +1,61 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
// @import '../../style/themes/index';
// @import '../../style/mixins/index';
@radio-prefix-cls: ~'@{ant-prefix}-radio';
@radio-group-prefix-cls: ~'@{radio-prefix-cls}-group';
@radio-prefix-cls-button-wrapper: ~'@{radio-prefix-cls}-button-wrapper';
// @radio-prefix-cls: ~'@{ant-prefix}-radio';
// @radio-group-prefix-cls: ~'@{radio-prefix-cls}-group';
// @radio-prefix-cls-button-wrapper: ~'@{radio-prefix-cls}-button-wrapper';
.@{radio-group-prefix-cls} {
&&-rtl {
direction: rtl;
}
}
// .@{radio-group-prefix-cls} {
// &&-rtl {
// direction: rtl;
// }
// }
// 一般状态
.@{radio-prefix-cls}-wrapper {
&&-rtl {
margin-right: 0;
margin-left: @radio-wrapper-margin-right;
direction: rtl;
}
}
// // 一般状态
// .@{radio-prefix-cls}-wrapper {
// &&-rtl {
// margin-right: 0;
// margin-left: @radio-wrapper-margin-right;
// direction: rtl;
// }
// }
.@{radio-prefix-cls-button-wrapper} {
&&-rtl {
border-right-width: 0;
border-left-width: @border-width-base;
}
// .@{radio-prefix-cls-button-wrapper} {
// &&-rtl {
// border-right-width: 0;
// border-left-width: @border-width-base;
// }
&:not(:first-child) {
&::before {
.@{radio-prefix-cls-button-wrapper}.@{radio-prefix-cls-button-wrapper}-rtl& {
right: -1px;
left: 0;
}
}
}
// &:not(:first-child) {
// &::before {
// .@{radio-prefix-cls-button-wrapper}.@{radio-prefix-cls-button-wrapper}-rtl& {
// right: -1px;
// left: 0;
// }
// }
// }
&:first-child {
.@{radio-prefix-cls-button-wrapper}.@{radio-prefix-cls-button-wrapper}-rtl& {
border-right: @border-width-base @border-style-base @border-color-base;
border-radius: 0 @border-radius-base @border-radius-base 0;
}
.@{radio-prefix-cls-button-wrapper}-checked:not([class*=~"' @{radio-prefix-cls}-button-wrapper-disabled'"])& {
border-right-color: @radio-button-hover-color;
}
}
// &:first-child {
// .@{radio-prefix-cls-button-wrapper}.@{radio-prefix-cls-button-wrapper}-rtl& {
// border-right: @border-width-base @border-style-base @border-color-base;
// border-radius: 0 @border-radius-base @border-radius-base 0;
// }
// .@{radio-prefix-cls-button-wrapper}-checked:not([class*=~"' @{radio-prefix-cls}-button-wrapper-disabled'"])& {
// border-right-color: @radio-button-hover-color;
// }
// }
&:last-child {
.@{radio-prefix-cls-button-wrapper}.@{radio-prefix-cls-button-wrapper}-rtl& {
border-radius: @border-radius-base 0 0 @border-radius-base;
}
}
// &:last-child {
// .@{radio-prefix-cls-button-wrapper}.@{radio-prefix-cls-button-wrapper}-rtl& {
// border-radius: @border-radius-base 0 0 @border-radius-base;
// }
// }
&-disabled {
&:first-child {
.@{radio-prefix-cls-button-wrapper}.@{radio-prefix-cls-button-wrapper}-rtl& {
border-right-color: @border-color-base;
}
}
}
}
// &-disabled {
// &:first-child {
// .@{radio-prefix-cls-button-wrapper}.@{radio-prefix-cls-button-wrapper}-rtl& {
// border-right-color: @border-color-base;
// }
// }
// }
// }