mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-24 02:59:58 +08:00
refactor: cssinjs for tag (#34422)
* feat: basic implements * feat: add rtl * feat: reorganize types * test: add test cases for capitalize * test: improve coverage * chore: improve types * chore: update * chore: update
This commit is contained in:
parent
8ac77e00e3
commit
11ffb1ba6f
17
components/_util/__tests__/capitalize.test.ts
Normal file
17
components/_util/__tests__/capitalize.test.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import capitalize from '../capitalize';
|
||||
|
||||
describe('capitalize', () => {
|
||||
it('should capitalize the first character of a string', () => {
|
||||
expect(capitalize('antd')).toBe('Antd');
|
||||
expect(capitalize('Antd')).toBe('Antd');
|
||||
expect(capitalize(' antd')).toBe(' antd');
|
||||
expect(capitalize('')).toBe('');
|
||||
});
|
||||
|
||||
it('should return the original value when is not a string', () => {
|
||||
expect(capitalize(1 as any)).toBe(1);
|
||||
expect(capitalize(true as any)).toBe(true);
|
||||
expect(capitalize(undefined as any)).toBe(undefined);
|
||||
expect(capitalize(null as any)).toBe(null);
|
||||
});
|
||||
});
|
8
components/_util/capitalize.ts
Normal file
8
components/_util/capitalize.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export default function capitalize<T extends string>(str: T): Capitalize<T> {
|
||||
if (typeof str !== 'string') {
|
||||
return str;
|
||||
}
|
||||
|
||||
const ret = str.charAt(0).toUpperCase() + str.slice(1);
|
||||
return ret as Capitalize<T>;
|
||||
}
|
@ -1,5 +1,22 @@
|
||||
import { TinyColor } from '@ctrl/tinycolor';
|
||||
import type { DesignToken } from '.';
|
||||
|
||||
import type { DesignToken, PresetColorType } from '.';
|
||||
|
||||
const presetColors: PresetColorType = {
|
||||
blue: '#1890FF',
|
||||
purple: '#722ED1',
|
||||
cyan: '#13C2C2',
|
||||
green: '#52C41A',
|
||||
magenta: '#EB2F96',
|
||||
pink: '#eb2f96',
|
||||
red: '#F5222D',
|
||||
orange: '#FA8C16',
|
||||
yellow: '#FADB14',
|
||||
volcano: '#FA541C',
|
||||
geekblue: '#2F54EB',
|
||||
gold: '#FAAD14',
|
||||
lime: '#A0D911',
|
||||
};
|
||||
|
||||
const defaultDesignToken: DesignToken = {
|
||||
primaryColor: '#1890ff',
|
||||
@ -59,6 +76,9 @@ const defaultDesignToken: DesignToken = {
|
||||
duration: 0.3,
|
||||
|
||||
zIndexDropdown: 1050,
|
||||
|
||||
// preset color palettes
|
||||
...presetColors,
|
||||
};
|
||||
|
||||
export default defaultDesignToken;
|
||||
|
@ -38,7 +38,39 @@ export {
|
||||
slideRightOut,
|
||||
};
|
||||
|
||||
export interface DesignToken {
|
||||
export interface PresetColorType {
|
||||
blue: string;
|
||||
purple: string;
|
||||
cyan: string;
|
||||
green: string;
|
||||
magenta: string;
|
||||
pink: string;
|
||||
red: string;
|
||||
orange: string;
|
||||
yellow: string;
|
||||
volcano: string;
|
||||
geekblue: string;
|
||||
lime: string;
|
||||
gold: string;
|
||||
}
|
||||
|
||||
export const PresetColorKeys: ReadonlyArray<keyof PresetColorType> = [
|
||||
'blue',
|
||||
'purple',
|
||||
'cyan',
|
||||
'green',
|
||||
'magenta',
|
||||
'pink',
|
||||
'red',
|
||||
'orange',
|
||||
'yellow',
|
||||
'volcano',
|
||||
'geekblue',
|
||||
'lime',
|
||||
'gold',
|
||||
];
|
||||
|
||||
export interface DesignToken extends PresetColorType {
|
||||
primaryColor: string;
|
||||
successColor: string;
|
||||
warningColor: string;
|
||||
@ -93,8 +125,14 @@ export interface DesignToken {
|
||||
boxShadow?: string;
|
||||
}
|
||||
|
||||
type ColorPaletteKeyIndexes = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
|
||||
type ColorPalettes = {
|
||||
[key in `${keyof PresetColorType}-${ColorPaletteKeyIndexes[number]}`]: string;
|
||||
};
|
||||
|
||||
/** This is temporary token definition since final token definition is not ready yet. */
|
||||
export interface DerivativeToken extends Omit<DesignToken, 'duration'> {
|
||||
export interface DerivativeToken extends ColorPalettes, Omit<DesignToken, 'duration'> {
|
||||
primaryHoverColor: string;
|
||||
primaryActiveColor: string;
|
||||
primaryOutlineColor: string;
|
||||
@ -131,21 +169,53 @@ export interface DerivativeToken extends Omit<DesignToken, 'duration'> {
|
||||
// TMP
|
||||
tmpPrimaryColorWeak: string;
|
||||
tmpPrimaryHoverColorWeak: string;
|
||||
// Checked background for Checkable Tag
|
||||
tmpPrimaryColor6: string;
|
||||
// Active background for Checkable Tag
|
||||
tmpPrimaryColor7: string;
|
||||
|
||||
tmpSuccessColorDeprecatedBg: string;
|
||||
tmpWarningColorDeprecatedBg: string;
|
||||
tmpErrorColorDeprecatedBg: string;
|
||||
tmpInfoColorDeprecatedBg: string;
|
||||
|
||||
tmpSuccessColorDeprecatedBorder: string;
|
||||
tmpWarningColorDeprecatedBorder: string;
|
||||
tmpErrorColorDeprecatedBorder: string;
|
||||
tmpInfoColorDeprecatedBorder: string;
|
||||
}
|
||||
|
||||
export { useStyleRegister };
|
||||
|
||||
// =============================== Derivative ===============================
|
||||
function derivative(designToken: DesignToken): DerivativeToken {
|
||||
const { primaryColor, errorColor, warningColor } = designToken;
|
||||
const { primaryColor, errorColor, warningColor, infoColor, successColor } = designToken;
|
||||
|
||||
const primaryColors = generate(primaryColor);
|
||||
const errorColors = generate(errorColor);
|
||||
const warningColors = generate(warningColor);
|
||||
const infoColors = generate(infoColor);
|
||||
const successColors = generate(successColor);
|
||||
|
||||
const paddingSM = (designToken.padding / 4) * 3;
|
||||
const paddingXS = designToken.padding * 0.5;
|
||||
|
||||
const colorPalettes = PresetColorKeys.map((colorKey: keyof PresetColorType) => {
|
||||
const colors = generate(designToken[colorKey]);
|
||||
|
||||
const ret = new Array(10).fill(1).reduce((prev, _, i) => {
|
||||
prev[`${colorKey}-${i + 1}`] = colors[i];
|
||||
return prev;
|
||||
}, {}) as ColorPalettes;
|
||||
return ret;
|
||||
}).reduce((prev, cur) => {
|
||||
prev = {
|
||||
...prev,
|
||||
...cur,
|
||||
};
|
||||
return prev;
|
||||
}, {} as ColorPalettes);
|
||||
|
||||
return {
|
||||
// FIXME: Need design token
|
||||
boxShadow: `
|
||||
@ -155,8 +225,6 @@ function derivative(designToken: DesignToken): DerivativeToken {
|
||||
|
||||
...designToken,
|
||||
|
||||
tmpPrimaryColorWeak: primaryColors[2],
|
||||
tmpPrimaryHoverColorWeak: primaryColors[0],
|
||||
primaryHoverColor: primaryColors[4],
|
||||
primaryActiveColor: primaryColors[6],
|
||||
primaryOutlineColor: new TinyColor(primaryColor).setAlpha(0.2).toRgbString(),
|
||||
@ -191,6 +259,24 @@ function derivative(designToken: DesignToken): DerivativeToken {
|
||||
duration: `${designToken.duration}s`,
|
||||
durationMid: `${(designToken.duration / 3) * 2}s`,
|
||||
durationFast: `${designToken.duration / 3}s`,
|
||||
|
||||
...colorPalettes,
|
||||
|
||||
// TMP
|
||||
tmpPrimaryColorWeak: primaryColors[2],
|
||||
tmpPrimaryHoverColorWeak: primaryColors[0],
|
||||
tmpPrimaryColor6: primaryColors[5],
|
||||
tmpPrimaryColor7: primaryColors[6],
|
||||
|
||||
tmpSuccessColorDeprecatedBg: successColors[0],
|
||||
tmpWarningColorDeprecatedBg: warningColors[0],
|
||||
tmpErrorColorDeprecatedBg: errorColors[0],
|
||||
tmpInfoColorDeprecatedBg: infoColors[0],
|
||||
|
||||
tmpSuccessColorDeprecatedBorder: successColors[2],
|
||||
tmpWarningColorDeprecatedBorder: warningColors[2],
|
||||
tmpErrorColorDeprecatedBorder: errorColors[2],
|
||||
tmpInfoColorDeprecatedBorder: infoColors[2],
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import useStyle from './style';
|
||||
|
||||
export interface CheckableTagProps {
|
||||
prefixCls?: string;
|
||||
@ -24,7 +25,7 @@ const CheckableTag: React.FC<CheckableTagProps> = ({
|
||||
onClick,
|
||||
...restProps
|
||||
}) => {
|
||||
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||
const { getPrefixCls, iconPrefixCls } = React.useContext(ConfigContext);
|
||||
|
||||
const handleClick = (e: React.MouseEvent<HTMLSpanElement, MouseEvent>) => {
|
||||
onChange?.(!checked);
|
||||
@ -32,6 +33,9 @@ const CheckableTag: React.FC<CheckableTagProps> = ({
|
||||
};
|
||||
|
||||
const prefixCls = getPrefixCls('tag', customizePrefixCls);
|
||||
// Style
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls, iconPrefixCls);
|
||||
|
||||
const cls = classNames(
|
||||
prefixCls,
|
||||
{
|
||||
@ -39,9 +43,10 @@ const CheckableTag: React.FC<CheckableTagProps> = ({
|
||||
[`${prefixCls}-checkable-checked`]: checked,
|
||||
},
|
||||
className,
|
||||
hashId,
|
||||
);
|
||||
|
||||
return <span {...restProps} className={cls} onClick={handleClick} />;
|
||||
return wrapSSR(<span {...restProps} className={cls} onClick={handleClick} />);
|
||||
};
|
||||
|
||||
export default CheckableTag;
|
||||
|
@ -14,6 +14,8 @@ import {
|
||||
import Wave from '../_util/wave';
|
||||
import { LiteralUnion } from '../_util/type';
|
||||
|
||||
import useStyle from './style';
|
||||
|
||||
export { CheckableTagProps } from './CheckableTag';
|
||||
|
||||
export interface TagProps extends React.HTMLAttributes<HTMLSpanElement> {
|
||||
@ -51,7 +53,7 @@ const InternalTag: React.ForwardRefRenderFunction<HTMLSpanElement, TagProps> = (
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||
const { getPrefixCls, direction, iconPrefixCls } = React.useContext(ConfigContext);
|
||||
const [visible, setVisible] = React.useState(true);
|
||||
|
||||
React.useEffect(() => {
|
||||
@ -74,6 +76,9 @@ const InternalTag: React.ForwardRefRenderFunction<HTMLSpanElement, TagProps> = (
|
||||
|
||||
const presetColor = isPresetColor();
|
||||
const prefixCls = getPrefixCls('tag', customizePrefixCls);
|
||||
// Style
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls, iconPrefixCls);
|
||||
|
||||
const tagClassName = classNames(
|
||||
prefixCls,
|
||||
{
|
||||
@ -83,6 +88,7 @@ const InternalTag: React.ForwardRefRenderFunction<HTMLSpanElement, TagProps> = (
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
},
|
||||
className,
|
||||
hashId,
|
||||
);
|
||||
|
||||
const handleCloseClick = (e: React.MouseEvent<HTMLElement>) => {
|
||||
@ -130,7 +136,7 @@ const InternalTag: React.ForwardRefRenderFunction<HTMLSpanElement, TagProps> = (
|
||||
</span>
|
||||
);
|
||||
|
||||
return isNeedWave ? <Wave>{tagNode}</Wave> : tagNode;
|
||||
return wrapSSR(isNeedWave ? <Wave>{tagNode}</Wave> : tagNode);
|
||||
};
|
||||
|
||||
const Tag = React.forwardRef<unknown, TagProps>(InternalTag) as TagType;
|
||||
|
@ -1,129 +1,129 @@
|
||||
@import '../../style/themes/index';
|
||||
@import '../../style/mixins/index';
|
||||
// @import '../../style/themes/index';
|
||||
// @import '../../style/mixins/index';
|
||||
|
||||
@tag-prefix-cls: ~'@{ant-prefix}-tag';
|
||||
// @tag-prefix-cls: ~'@{ant-prefix}-tag';
|
||||
|
||||
.@{tag-prefix-cls} {
|
||||
.reset-component();
|
||||
// .@{tag-prefix-cls} {
|
||||
// .reset-component();
|
||||
|
||||
display: inline-block;
|
||||
height: auto;
|
||||
margin-right: 8px;
|
||||
padding: 0 7px;
|
||||
font-size: @tag-font-size;
|
||||
line-height: @tag-line-height;
|
||||
white-space: nowrap;
|
||||
background: @tag-default-bg;
|
||||
border: @border-width-base @border-style-base @border-color-base;
|
||||
border-radius: @border-radius-base;
|
||||
opacity: 1;
|
||||
transition: all 0.3s;
|
||||
// display: inline-block;
|
||||
// height: auto;
|
||||
// margin-right: 8px;
|
||||
// padding: 0 7px;
|
||||
// font-size: @tag-font-size;
|
||||
// line-height: @tag-line-height;
|
||||
// white-space: nowrap;
|
||||
// background: @tag-default-bg;
|
||||
// border: @border-width-base @border-style-base @border-color-base;
|
||||
// border-radius: @border-radius-base;
|
||||
// opacity: 1;
|
||||
// transition: all 0.3s;
|
||||
|
||||
&,
|
||||
a,
|
||||
a:hover {
|
||||
color: @tag-default-color;
|
||||
}
|
||||
// &,
|
||||
// a,
|
||||
// a:hover {
|
||||
// color: @tag-default-color;
|
||||
// }
|
||||
|
||||
> a:first-child:last-child {
|
||||
display: inline-block;
|
||||
margin: 0 -8px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
// > a:first-child:last-child {
|
||||
// display: inline-block;
|
||||
// margin: 0 -8px;
|
||||
// padding: 0 8px;
|
||||
// }
|
||||
|
||||
&-close-icon {
|
||||
margin-left: 3px;
|
||||
color: @text-color-secondary;
|
||||
font-size: 10px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
// &-close-icon {
|
||||
// margin-left: 3px;
|
||||
// color: @text-color-secondary;
|
||||
// font-size: 10px;
|
||||
// cursor: pointer;
|
||||
// transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: @heading-color;
|
||||
}
|
||||
}
|
||||
// &:hover {
|
||||
// color: @heading-color;
|
||||
// }
|
||||
// }
|
||||
|
||||
&-has-color {
|
||||
border-color: transparent;
|
||||
&,
|
||||
a,
|
||||
a:hover,
|
||||
.@{iconfont-css-prefix}-close,
|
||||
.@{iconfont-css-prefix}-close:hover {
|
||||
color: @text-color-inverse;
|
||||
}
|
||||
}
|
||||
// &-has-color {
|
||||
// border-color: transparent;
|
||||
// &,
|
||||
// a,
|
||||
// a:hover,
|
||||
// .@{iconfont-css-prefix}-close,
|
||||
// .@{iconfont-css-prefix}-close:hover {
|
||||
// color: @text-color-inverse;
|
||||
// }
|
||||
// }
|
||||
|
||||
&-checkable {
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
cursor: pointer;
|
||||
// &-checkable {
|
||||
// background-color: transparent;
|
||||
// border-color: transparent;
|
||||
// cursor: pointer;
|
||||
|
||||
&:not(&-checked):hover {
|
||||
color: @primary-color;
|
||||
}
|
||||
// &:not(&-checked):hover {
|
||||
// color: @primary-color;
|
||||
// }
|
||||
|
||||
&:active,
|
||||
&-checked {
|
||||
color: @text-color-inverse;
|
||||
}
|
||||
// &:active,
|
||||
// &-checked {
|
||||
// color: @text-color-inverse;
|
||||
// }
|
||||
|
||||
&-checked {
|
||||
background-color: @primary-6;
|
||||
}
|
||||
// &-checked {
|
||||
// background-color: @primary-6;
|
||||
// }
|
||||
|
||||
&:active {
|
||||
background-color: @primary-7;
|
||||
}
|
||||
}
|
||||
// &:active {
|
||||
// background-color: @primary-7;
|
||||
// }
|
||||
// }
|
||||
|
||||
&-hidden {
|
||||
display: none;
|
||||
}
|
||||
// &-hidden {
|
||||
// display: none;
|
||||
// }
|
||||
|
||||
// mixin to iterate over colors and create CSS class for each one
|
||||
.make-color-classes(@i: length(@preset-colors)) when (@i > 0) {
|
||||
.make-color-classes(@i - 1);
|
||||
@color: extract(@preset-colors, @i);
|
||||
@lightColor: '@{color}-1';
|
||||
@lightBorderColor: '@{color}-3';
|
||||
@darkColor: '@{color}-6';
|
||||
@textColor: '@{color}-7';
|
||||
&-@{color} {
|
||||
color: @@textColor;
|
||||
background: @@lightColor;
|
||||
border-color: @@lightBorderColor;
|
||||
}
|
||||
&-@{color}-inverse {
|
||||
color: @text-color-inverse;
|
||||
background: @@darkColor;
|
||||
border-color: @@darkColor;
|
||||
}
|
||||
}
|
||||
// // mixin to iterate over colors and create CSS class for each one
|
||||
// .make-color-classes(@i: length(@preset-colors)) when (@i > 0) {
|
||||
// .make-color-classes(@i - 1);
|
||||
// @color: extract(@preset-colors, @i);
|
||||
// @lightColor: '@{color}-1';
|
||||
// @lightBorderColor: '@{color}-3';
|
||||
// @darkColor: '@{color}-6';
|
||||
// @textColor: '@{color}-7';
|
||||
// &-@{color} {
|
||||
// color: @@textColor;
|
||||
// background: @@lightColor;
|
||||
// border-color: @@lightBorderColor;
|
||||
// }
|
||||
// &-@{color}-inverse {
|
||||
// color: @text-color-inverse;
|
||||
// background: @@darkColor;
|
||||
// border-color: @@darkColor;
|
||||
// }
|
||||
// }
|
||||
|
||||
.make-status-color-classes(@status, @cssVariableType) {
|
||||
@bgColor: '@{cssVariableType}-color-deprecated-bg';
|
||||
@borderColor: '@{cssVariableType}-color-deprecated-border';
|
||||
@textColor: '@{cssVariableType}-color';
|
||||
&-@{status} {
|
||||
color: @@textColor;
|
||||
background: @@bgColor;
|
||||
border-color: @@borderColor;
|
||||
}
|
||||
}
|
||||
// .make-status-color-classes(@status, @cssVariableType) {
|
||||
// @bgColor: '@{cssVariableType}-color-deprecated-bg';
|
||||
// @borderColor: '@{cssVariableType}-color-deprecated-border';
|
||||
// @textColor: '@{cssVariableType}-color';
|
||||
// &-@{status} {
|
||||
// color: @@textColor;
|
||||
// background: @@bgColor;
|
||||
// border-color: @@borderColor;
|
||||
// }
|
||||
// }
|
||||
|
||||
.make-color-classes();
|
||||
// .make-color-classes();
|
||||
|
||||
.make-status-color-classes(success, success);
|
||||
.make-status-color-classes(processing, info);
|
||||
.make-status-color-classes(error, error);
|
||||
.make-status-color-classes(warning, warning);
|
||||
// .make-status-color-classes(success, success);
|
||||
// .make-status-color-classes(processing, info);
|
||||
// .make-status-color-classes(error, error);
|
||||
// .make-status-color-classes(warning, warning);
|
||||
|
||||
// To ensure that a space will be placed between character and `Icon`.
|
||||
> .@{iconfont-css-prefix} + span,
|
||||
> span + .@{iconfont-css-prefix} {
|
||||
margin-left: 7px;
|
||||
}
|
||||
}
|
||||
// // To ensure that a space will be placed between character and `Icon`.
|
||||
// > .@{iconfont-css-prefix} + span,
|
||||
// > span + .@{iconfont-css-prefix} {
|
||||
// margin-left: 7px;
|
||||
// }
|
||||
// }
|
||||
|
||||
@import './rtl';
|
||||
// @import './rtl';
|
||||
|
@ -1,2 +1,198 @@
|
||||
import '../../style/index.less';
|
||||
import './index.less';
|
||||
// deps-lint-skip-all
|
||||
import { CSSInterpolation, CSSObject } from '@ant-design/cssinjs';
|
||||
import capitalize from '../../_util/capitalize';
|
||||
import {
|
||||
PresetColorType,
|
||||
DerivativeToken,
|
||||
useStyleRegister,
|
||||
useToken,
|
||||
resetComponent,
|
||||
UseComponentStyleResult,
|
||||
PresetColorKeys,
|
||||
} from '../../_util/theme';
|
||||
|
||||
interface TagToken extends DerivativeToken {
|
||||
tagFontSize: number;
|
||||
tagLineHeight: React.CSSProperties['lineHeight'];
|
||||
tagDefaultBg: string;
|
||||
tagDefaultColor: string;
|
||||
}
|
||||
|
||||
// ============================== Styles ==============================
|
||||
|
||||
type CssVariableType = 'success' | 'info' | 'error' | 'warning';
|
||||
|
||||
const genTagStatusStyle = (
|
||||
prefixCls: string,
|
||||
token: TagToken,
|
||||
status: 'success' | 'processing' | 'error' | 'warning',
|
||||
cssVariableType: CssVariableType,
|
||||
): CSSInterpolation => {
|
||||
const capitalizedCssVariableType = capitalize<CssVariableType>(cssVariableType);
|
||||
return {
|
||||
[`.${prefixCls}-${status}`]: {
|
||||
color: token[`${cssVariableType}Color`],
|
||||
background: token[`tmp${capitalizedCssVariableType}ColorDeprecatedBg`],
|
||||
borderColor: token[`tmp${capitalizedCssVariableType}ColorDeprecatedBorder`],
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
// FIXME: special preset colors
|
||||
const genTagColorStyle = (prefixCls: string, token: TagToken): CSSInterpolation =>
|
||||
PresetColorKeys.reduce((prev: CSSObject, colorKey: keyof PresetColorType) => {
|
||||
const lightColor = token[`${colorKey}-1`];
|
||||
const lightBorderColor = token[`${colorKey}-3`];
|
||||
const darkColor = token[`${colorKey}-6`];
|
||||
const textColor = token[`${colorKey}-7`];
|
||||
return {
|
||||
...prev,
|
||||
[`.${prefixCls}-${colorKey}`]: {
|
||||
color: textColor,
|
||||
background: lightColor,
|
||||
borderColor: lightBorderColor,
|
||||
},
|
||||
[`.${prefixCls}-${colorKey}-inverse`]: {
|
||||
color: token.textColorInverse,
|
||||
background: darkColor,
|
||||
borderColor: darkColor,
|
||||
},
|
||||
};
|
||||
}, {} as CSSObject);
|
||||
|
||||
const genBaseStyle = (
|
||||
prefixCls: string,
|
||||
iconPrefixCls: string,
|
||||
token: TagToken,
|
||||
): CSSInterpolation => ({
|
||||
// Result
|
||||
[`.${prefixCls}`]: {
|
||||
...resetComponent(token),
|
||||
display: 'inline-block',
|
||||
height: 'auto',
|
||||
marginInlineStart: token.marginXS,
|
||||
// FIXME: hard code
|
||||
padding: '0 7px',
|
||||
fontSize: token.tagFontSize,
|
||||
lineHeight: token.tagLineHeight,
|
||||
whiteSpace: 'nowrap',
|
||||
background: token.tagDefaultBg,
|
||||
border: `${token.borderWidth}px ${token.borderStyle} ${token.borderColor}`,
|
||||
borderRadius: token.borderRadius,
|
||||
// FIXME: hard code
|
||||
opacity: 1,
|
||||
transition: `all ${token.duration}`,
|
||||
|
||||
// RTL
|
||||
'&&-rtl': {
|
||||
direction: 'rtl',
|
||||
textAlign: 'right',
|
||||
},
|
||||
|
||||
'&, a, a:hover': {
|
||||
color: token.tagDefaultColor,
|
||||
},
|
||||
|
||||
[`.${prefixCls}-close-icon`]: {
|
||||
// FIXME: hard code
|
||||
marginInlineStart: 3,
|
||||
color: token.textColorSecondary,
|
||||
// FIXME: hard code
|
||||
fontSize: 10,
|
||||
cursor: 'pointer',
|
||||
transition: `all ${token.duration}`,
|
||||
|
||||
'&:hover': {
|
||||
color: token.headingColor,
|
||||
},
|
||||
},
|
||||
|
||||
[`&&-has-color`]: {
|
||||
borderColor: 'transparent',
|
||||
|
||||
[`&, a, a:hover, .${iconPrefixCls}-close, .${iconPrefixCls}-close:hover`]: {
|
||||
color: token.textColorInverse,
|
||||
},
|
||||
},
|
||||
|
||||
[`.${prefixCls}-checkable`]: {
|
||||
backgroundColor: 'transparent',
|
||||
borderColor: 'transparent',
|
||||
cursor: 'pointer',
|
||||
|
||||
'&:not(&-checked):hover': {
|
||||
color: token.primaryColor,
|
||||
},
|
||||
|
||||
'&:active, &-checked': {
|
||||
color: token.textColorInverse,
|
||||
},
|
||||
|
||||
'&-checked': {
|
||||
backgroundColor: token.tmpPrimaryColor6,
|
||||
},
|
||||
|
||||
'&:active': {
|
||||
backgroundColor: token.tmpPrimaryColor7,
|
||||
},
|
||||
},
|
||||
|
||||
[`.${prefixCls}-hidden`]: {
|
||||
display: 'none',
|
||||
},
|
||||
|
||||
// To ensure that a space will be placed between character and `Icon`.
|
||||
[`> .${iconPrefixCls} + span, > span + .${iconPrefixCls}`]: {
|
||||
// FIXME: hard code
|
||||
marginInlineStart: 7,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const genTagStyle = (
|
||||
prefixCls: string,
|
||||
iconPrefixCls: string,
|
||||
token: DerivativeToken,
|
||||
): CSSInterpolation => {
|
||||
const tagFontSize = token.fontSizeSM;
|
||||
// FIXME: hard code
|
||||
const tagLineHeight = '18px';
|
||||
const tagDefaultBg = token.backgroundLight;
|
||||
const tagDefaultColor = token.textColor;
|
||||
|
||||
const tagToken = {
|
||||
...token,
|
||||
tagFontSize,
|
||||
tagLineHeight,
|
||||
tagDefaultBg,
|
||||
tagDefaultColor,
|
||||
};
|
||||
|
||||
return [
|
||||
genBaseStyle(prefixCls, iconPrefixCls, tagToken),
|
||||
genTagColorStyle(prefixCls, tagToken),
|
||||
genTagStatusStyle(prefixCls, tagToken, 'success', 'success'),
|
||||
genTagStatusStyle(prefixCls, tagToken, 'processing', 'info'),
|
||||
genTagStatusStyle(prefixCls, tagToken, 'error', 'error'),
|
||||
genTagStatusStyle(prefixCls, tagToken, 'warning', 'warning'),
|
||||
];
|
||||
};
|
||||
|
||||
// ============================== Export ==============================
|
||||
export function getStyle(prefixCls: string, iconPrefixCls: string, token: DerivativeToken) {
|
||||
return [genTagStyle(prefixCls, iconPrefixCls, token)];
|
||||
}
|
||||
|
||||
export default function useStyle(
|
||||
prefixCls: string,
|
||||
iconPrefixCls: string,
|
||||
): UseComponentStyleResult {
|
||||
const [theme, token, hashId] = useToken();
|
||||
|
||||
return [
|
||||
useStyleRegister({ theme, token, hashId, path: [prefixCls] }, () =>
|
||||
getStyle(prefixCls, iconPrefixCls, token),
|
||||
),
|
||||
hashId,
|
||||
];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user