refactor: cssinjs for Rate (#34373)

* refactor: cssinjs for Rate

* refactor: better cssinjs practice for Rate
This commit is contained in:
Peach 2022-03-10 10:47:33 +08:00 committed by GitHub
parent f31f315faa
commit 253b43fed3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 157 additions and 119 deletions

View File

@ -1,9 +1,11 @@
import * as React from 'react';
import classNames from 'classnames';
import RcRate from 'rc-rate';
import StarFilled from '@ant-design/icons/StarFilled';
import Tooltip from '../tooltip';
import { ConfigContext } from '../config-provider';
import useStyle from './style';
export interface RateProps {
prefixCls?: string;
@ -31,17 +33,21 @@ const Rate = React.forwardRef<unknown, RateProps>(({ prefixCls, tooltips, ...pro
return <Tooltip title={tooltips[index]}>{node}</Tooltip>;
};
const { getPrefixCls, direction } = React.useContext(ConfigContext);
const { getPrefixCls, iconPrefixCls, direction } = React.useContext(ConfigContext);
const ratePrefixCls = getPrefixCls('rate', prefixCls);
return (
// Style
const [wrapSSR, hashId] = useStyle(ratePrefixCls, iconPrefixCls);
return wrapSSR(
<RcRate
ref={ref}
characterRender={characterRender}
{...props}
className={classNames(props.className, hashId)}
prefixCls={ratePrefixCls}
direction={direction}
/>
/>,
);
});

View File

@ -1,91 +0,0 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
@rate-prefix-cls: ~'@{ant-prefix}-rate';
.@{rate-prefix-cls} {
.reset-component();
display: inline-block;
margin: 0;
padding: 0;
color: @rate-star-color;
font-size: @rate-star-size;
line-height: unset;
list-style: none;
outline: none;
&-disabled &-star {
cursor: default;
&:hover {
transform: scale(1);
}
}
&-star {
position: relative;
display: inline-block;
color: inherit;
cursor: pointer;
&:not(:last-child) {
margin-right: 8px;
}
> div {
transition: all 0.3s, outline 0s;
&:hover {
transform: @rate-star-hover-scale;
}
&:focus {
outline: 0;
}
&:focus-visible {
outline: 1px dashed @rate-star-color;
transform: @rate-star-hover-scale;
}
}
&-first,
&-second {
color: @rate-star-bg;
transition: all 0.3s;
user-select: none;
.@{iconfont-css-prefix} {
vertical-align: middle;
}
}
&-first {
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
overflow: hidden;
opacity: 0;
}
&-half &-first,
&-half &-second {
opacity: 1;
}
&-half &-first,
&-full &-second {
color: inherit;
}
}
&-text {
display: inline-block;
margin: 0 8px;
font-size: @font-size-base;
}
}
@import './rtl';

View File

@ -1,5 +1,149 @@
import '../../style/index.less';
import './index.less';
// deps-lint-skip-all
import { CSSInterpolation, CSSObject } from '@ant-design/cssinjs';
import {
DerivativeToken,
resetComponent,
UseComponentStyleResult,
useStyleRegister,
useToken,
} from '../../_util/theme';
// style dependencies
import '../../tooltip/style';
interface RateToken extends DerivativeToken {
rateStarColor: string;
rateStarSize: number;
rateStarHoverScale: CSSObject['transform'];
rateCls: string;
iconPrefixCls: string;
}
const genRateStarStyle = (token: RateToken): CSSObject => {
const { rateCls } = token;
return {
[`${rateCls}-star`]: {
position: 'relative',
display: 'inline-block',
color: 'inherit',
cursor: 'pointer',
'&:not(:last-child)': {
marginInlineEnd: token.marginXS,
},
'> div': {
transition: `all ${token.duration}, outline 0s`,
'&:hover': {
transform: token.rateStarHoverScale,
},
'&:focus': {
outline: 0,
},
'&:focus-visible': {
outline: `1px dashed ${token.borderColorSplit}`,
transform: token.rateStarHoverScale,
},
},
'&-first, &-second': {
color: token.borderColorSplit,
transition: `all ${token.duration}`,
userSelect: 'none',
[token.iconPrefixCls]: {
verticalAlign: 'middle',
},
},
'&-first': {
position: 'absolute',
top: 0,
insetInlineStart: 0,
width: '50%',
height: '100%',
overflow: 'hidden',
opacity: 0,
},
[`&-half ${rateCls}-star-first, &-half ${rateCls}-star-second`]: {
opacity: 1,
},
[`&-half ${rateCls}-star-first, &-full ${rateCls}-star-second`]: {
color: 'inherit',
},
},
};
};
const genRateRtlStyle = (token: RateToken): CSSObject => ({
[`&-rtl${token.rateCls}`]: {
direction: 'rtl',
},
});
const genRateStyle = (token: RateToken): CSSInterpolation => {
const { rateCls } = token;
return {
[rateCls]: {
...resetComponent(token),
display: 'inline-block',
margin: 0,
padding: 0,
color: token.rateStarColor,
fontSize: token.rateStarSize,
lineHeight: 'unset',
listStyle: 'none',
outline: 'none',
// disable styles
[`&-disabled${rateCls} ${rateCls}-star`]: {
cursor: 'default',
'&:hover': {
transform: 'scale(1)',
},
},
// star styles
...genRateStarStyle(token),
// text styles
[`+ ${rateCls}-text`]: {
display: 'inline-block',
marginInlineStart: token.marginXS,
fontSize: token.fontSize,
},
// rtl styles
...genRateRtlStyle(token),
},
};
};
// ============================== Export ==============================
export default function useStyle(
prefixCls: string,
iconPrefixCls: string,
): UseComponentStyleResult {
const [theme, token, hashId] = useToken();
const rateToken: RateToken = {
...token,
// FIXME: missing token
rateStarColor: '#fadb14', // @yellow-6
rateStarSize: 20, // fixed-value
rateStarHoverScale: 'scale(1.1)', // fixed-value
rateCls: `.${prefixCls}`,
iconPrefixCls: `.${iconPrefixCls}`,
};
return [
useStyleRegister({ theme, token, hashId, path: [prefixCls] }, () => [genRateStyle(rateToken)]),
hashId,
];
}

View File

@ -1,21 +0,0 @@
.@{rate-prefix-cls} {
&-rtl {
direction: rtl;
}
&-star {
&:not(:last-child) {
.@{rate-prefix-cls}-rtl & {
margin-right: 0;
margin-left: 8px;
}
}
&-first {
.@{rate-prefix-cls}-rtl & {
right: 0;
left: auto;
}
}
}
}