feat: breadcrumb css-var (#8325)

Co-authored-by: undefined <undefined>
feat-4.3
Shuhari 2025-08-26 00:04:28 +08:00 committed by GitHub
parent 171dc9e369
commit e1cfc828ec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 83 additions and 50 deletions

View File

@ -8,6 +8,7 @@ import BreadcrumbItem from './BreadcrumbItem';
import Menu from '../menu'; import Menu from '../menu';
import useConfigInject from '../config-provider/hooks/useConfigInject'; import useConfigInject from '../config-provider/hooks/useConfigInject';
import useStyle from './style'; import useStyle from './style';
import useCSSVarCls from '../config-provider/hooks/useCssVarCls';
import type { CustomSlotsType, VueNode } from '../_util/type'; import type { CustomSlotsType, VueNode } from '../_util/type';
export interface Route { export interface Route {
@ -65,7 +66,8 @@ export default defineComponent({
}>, }>,
setup(props, { slots, attrs }) { setup(props, { slots, attrs }) {
const { prefixCls, direction } = useConfigInject('breadcrumb', props); const { prefixCls, direction } = useConfigInject('breadcrumb', props);
const [wrapSSR, hashId] = useStyle(prefixCls); const rootCls = useCSSVarCls(prefixCls);
const [wrapSSR, hashId, cssVarCls] = useStyle(prefixCls, rootCls);
const getPath = (path: string, params: unknown) => { const getPath = (path: string, params: unknown) => {
path = (path || '').replace(/^\//, ''); path = (path || '').replace(/^\//, '');
Object.keys(params).forEach(key => { Object.keys(params).forEach(key => {
@ -158,6 +160,8 @@ export default defineComponent({
[prefixCls.value]: true, [prefixCls.value]: true,
[`${prefixCls.value}-rtl`]: direction.value === 'rtl', [`${prefixCls.value}-rtl`]: direction.value === 'rtl',
[`${attrs.class}`]: !!attrs.class, [`${attrs.class}`]: !!attrs.class,
[rootCls.value]: true,
[cssVarCls.value]: true,
[hashId.value]: true, [hashId.value]: true,
}; };

View File

@ -1,32 +1,61 @@
import { unit } from '../../_util/cssinjs';
import type { CSSObject } from '../../_util/cssinjs'; import type { CSSObject } from '../../_util/cssinjs';
import type { FullToken, GenerateStyle } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
import { genFocusStyle, resetComponent } from '../../style'; import { genFocusStyle, resetComponent } from '../../style';
import type { FullToken, GenerateStyle, GetDefaultToken } from '../../theme/internal';
import { genStyleHooks, mergeToken } from '../../theme/internal';
export interface ComponentToken {} export interface ComponentToken {
/**
interface BreadcrumbToken extends FullToken<'Breadcrumb'> { * @desc
breadcrumbBaseColor: string; * @descEN Text color of Breadcrumb item
breadcrumbFontSize: number; */
breadcrumbIconFontSize: number; itemColor: string;
breadcrumbLinkColor: string; /**
breadcrumbLinkColorHover: string; * @desc
breadcrumbLastItemColor: string; * @descEN Icon size
breadcrumbSeparatorMargin: number; */
breadcrumbSeparatorColor: string; iconFontSize: number;
/**
* @desc
* @descEN Text color of link
*/
linkColor: string;
/**
* @desc
* @descEN Color of hovered link
*/
linkHoverColor: string;
/**
* @desc
* @descEN Text color of the last item
*/
lastItemColor: string;
/**
* @desc
* @descEN Margin of separator
*/
separatorMargin: number;
/**
* @desc
* @descEN Color of separator
*/
separatorColor: string;
} }
interface BreadcrumbToken extends FullToken<'Breadcrumb'> {}
const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = token => { const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = token => {
const { componentCls, iconCls } = token; const { componentCls, iconCls, calc } = token;
return { return {
[componentCls]: { [componentCls]: {
...resetComponent(token), ...resetComponent(token),
color: token.breadcrumbBaseColor, color: token.itemColor,
fontSize: token.breadcrumbFontSize, fontSize: token.fontSize,
[iconCls]: { [iconCls]: {
fontSize: token.breadcrumbIconFontSize, fontSize: token.iconFontSize,
}, },
ol: { ol: {
@ -38,33 +67,29 @@ const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = token => {
}, },
a: { a: {
color: token.breadcrumbLinkColor, color: token.linkColor,
transition: `color ${token.motionDurationMid}`, transition: `color ${token.motionDurationMid}`,
padding: `0 ${token.paddingXXS}px`, padding: `0 ${unit(token.paddingXXS)}`,
borderRadius: token.borderRadiusSM, borderRadius: token.borderRadiusSM,
height: token.lineHeight * token.fontSize, height: token.fontHeight,
display: 'inline-block', display: 'inline-block',
marginInline: -token.marginXXS, marginInline: calc(token.marginXXS).mul(-1).equal(),
'&:hover': { '&:hover': {
color: token.breadcrumbLinkColorHover, color: token.linkHoverColor,
backgroundColor: token.colorBgTextHover, backgroundColor: token.colorBgTextHover,
}, },
...genFocusStyle(token), ...genFocusStyle(token),
}, },
[`li:last-child`]: { 'li:last-child': {
color: token.breadcrumbLastItemColor, color: token.lastItemColor,
[`& > ${componentCls}-separator`]: {
display: 'none',
},
}, },
[`${componentCls}-separator`]: { [`${componentCls}-separator`]: {
marginInline: token.breadcrumbSeparatorMargin, marginInline: token.separatorMargin,
color: token.breadcrumbSeparatorColor, color: token.separatorColor,
}, },
[`${componentCls}-link`]: { [`${componentCls}-link`]: {
@ -78,10 +103,10 @@ const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = token => {
[`${componentCls}-overlay-link`]: { [`${componentCls}-overlay-link`]: {
borderRadius: token.borderRadiusSM, borderRadius: token.borderRadiusSM,
height: token.lineHeight * token.fontSize, height: token.fontHeight,
display: 'inline-block', display: 'inline-block',
padding: `0 ${token.paddingXXS}px`, padding: `0 ${unit(token.paddingXXS)}`,
marginInline: -token.marginXXS, marginInline: calc(token.marginXXS).mul(-1).equal(),
[`> ${iconCls}`]: { [`> ${iconCls}`]: {
marginInlineStart: token.marginXXS, marginInlineStart: token.marginXXS,
@ -89,11 +114,11 @@ const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = token => {
}, },
'&:hover': { '&:hover': {
color: token.breadcrumbLinkColorHover, color: token.linkHoverColor,
backgroundColor: token.colorBgTextHover, backgroundColor: token.colorBgTextHover,
a: { a: {
color: token.breadcrumbLinkColorHover, color: token.linkHoverColor,
}, },
}, },
@ -112,18 +137,22 @@ const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = token => {
}; };
}; };
// ============================== Export ============================== export const prepareComponentToken: GetDefaultToken<'Breadcrumb'> = token => ({
export default genComponentStyleHook('Breadcrumb', token => { itemColor: token.colorTextDescription,
const BreadcrumbToken = mergeToken<BreadcrumbToken>(token, { lastItemColor: token.colorText,
breadcrumbBaseColor: token.colorTextDescription, iconFontSize: token.fontSize,
breadcrumbFontSize: token.fontSize, linkColor: token.colorTextDescription,
breadcrumbIconFontSize: token.fontSize, linkHoverColor: token.colorText,
breadcrumbLinkColor: token.colorTextDescription, separatorColor: token.colorTextDescription,
breadcrumbLinkColorHover: token.colorText, separatorMargin: token.marginXS,
breadcrumbLastItemColor: token.colorText,
breadcrumbSeparatorMargin: token.marginXS,
breadcrumbSeparatorColor: token.colorTextDescription,
});
return [genBreadcrumbStyle(BreadcrumbToken)];
}); });
// ============================== Export ==============================
export default genStyleHooks(
'Breadcrumb',
token => {
const breadcrumbToken = mergeToken<BreadcrumbToken>(token, {});
return genBreadcrumbStyle(breadcrumbToken);
},
prepareComponentToken,
);