mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-27 20:49:53 +08:00
feat: Anchor support cssVar (#45808)
* feat: Anchor support cssVar * fix: fix * fix: fix * Update components/anchor/style/index.ts Co-authored-by: MadCcc <madccc@foxmail.com> Signed-off-by: lijianan <574980606@qq.com> * fix: fix * fix: fix * fix: fix * fix: fix * fix: fix * fix: fix --------- Signed-off-by: lijianan <574980606@qq.com> Co-authored-by: MadCcc <madccc@foxmail.com>
This commit is contained in:
parent
411ca7ab5e
commit
194dbcedfa
@ -9,10 +9,12 @@ import { devUseWarning } from '../_util/warning';
|
||||
import Affix from '../affix';
|
||||
import type { ConfigConsumerProps } from '../config-provider';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
|
||||
import type { AnchorLinkBaseProps } from './AnchorLink';
|
||||
import AnchorLink from './AnchorLink';
|
||||
import AnchorContext from './context';
|
||||
import useStyle from './style';
|
||||
import useCSSVar from './style/cssVar';
|
||||
|
||||
export interface AnchorLinkItemProps extends AnchorLinkBaseProps {
|
||||
key: React.Key;
|
||||
@ -79,11 +81,6 @@ export interface AnchorProps {
|
||||
replace?: boolean;
|
||||
}
|
||||
|
||||
interface InternalAnchorProps extends AnchorProps {
|
||||
anchorPrefixCls: string;
|
||||
rootClassName: string;
|
||||
}
|
||||
|
||||
export interface AnchorState {
|
||||
activeLink: null | string;
|
||||
}
|
||||
@ -109,10 +106,10 @@ export interface AntAnchor {
|
||||
direction: AnchorDirection;
|
||||
}
|
||||
|
||||
const AnchorContent: React.FC<InternalAnchorProps> = (props) => {
|
||||
const Anchor: React.FC<AnchorProps> = (props) => {
|
||||
const {
|
||||
rootClassName,
|
||||
anchorPrefixCls: prefixCls,
|
||||
prefixCls: customPrefixCls,
|
||||
className,
|
||||
style,
|
||||
offsetTop,
|
||||
@ -151,9 +148,15 @@ const AnchorContent: React.FC<InternalAnchorProps> = (props) => {
|
||||
const spanLinkNode = React.useRef<HTMLSpanElement>(null);
|
||||
const animating = React.useRef<boolean>(false);
|
||||
|
||||
const { direction, getTargetContainer, anchor } =
|
||||
const { direction, anchor, getTargetContainer, getPrefixCls } =
|
||||
React.useContext<ConfigConsumerProps>(ConfigContext);
|
||||
|
||||
const prefixCls = getPrefixCls('anchor', customPrefixCls);
|
||||
|
||||
const [, hashId] = useStyle(prefixCls);
|
||||
const rootCls = useCSSVarCls(prefixCls);
|
||||
const wrapCSSVar = useCSSVar(rootCls);
|
||||
|
||||
const getCurrentContainer = getContainer ?? getTargetContainer ?? getDefaultContainer;
|
||||
|
||||
const dependencyListItem: React.DependencyList[number] = JSON.stringify(links);
|
||||
@ -182,10 +185,7 @@ const AnchorContent: React.FC<InternalAnchorProps> = (props) => {
|
||||
inkStyle.left = horizontalAnchor ? `${linkNode.offsetLeft}px` : '';
|
||||
inkStyle.width = horizontalAnchor ? `${linkNode.clientWidth}px` : '';
|
||||
if (horizontalAnchor) {
|
||||
scrollIntoView(linkNode, {
|
||||
scrollMode: 'if-needed',
|
||||
block: 'nearest',
|
||||
});
|
||||
scrollIntoView(linkNode, { scrollMode: 'if-needed', block: 'nearest' });
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -274,6 +274,8 @@ const AnchorContent: React.FC<InternalAnchorProps> = (props) => {
|
||||
);
|
||||
|
||||
const wrapperClass = classNames(
|
||||
hashId,
|
||||
rootCls,
|
||||
rootClassName,
|
||||
`${prefixCls}-wrapper`,
|
||||
{
|
||||
@ -347,7 +349,7 @@ const AnchorContent: React.FC<InternalAnchorProps> = (props) => {
|
||||
[activeLink, onClick, handleScrollTo, anchorDirection],
|
||||
);
|
||||
|
||||
return (
|
||||
return wrapCSSVar(
|
||||
<AnchorContext.Provider value={memoizedContextValue}>
|
||||
{affix ? (
|
||||
<Affix offsetTop={offsetTop} target={getCurrentContainer}>
|
||||
@ -356,23 +358,7 @@ const AnchorContent: React.FC<InternalAnchorProps> = (props) => {
|
||||
) : (
|
||||
anchorContent
|
||||
)}
|
||||
</AnchorContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
const Anchor: React.FC<AnchorProps> = (props) => {
|
||||
const { prefixCls: customizePrefixCls, rootClassName } = props;
|
||||
const { getPrefixCls } = React.useContext<ConfigConsumerProps>(ConfigContext);
|
||||
const anchorPrefixCls = getPrefixCls('anchor', customizePrefixCls);
|
||||
|
||||
const [wrapSSR, hashId] = useStyle(anchorPrefixCls);
|
||||
|
||||
return wrapSSR(
|
||||
<AnchorContent
|
||||
{...props}
|
||||
rootClassName={classNames(hashId, rootClassName)}
|
||||
anchorPrefixCls={anchorPrefixCls}
|
||||
/>,
|
||||
</AnchorContext.Provider>,
|
||||
);
|
||||
};
|
||||
|
||||
|
4
components/anchor/style/cssVar.ts
Normal file
4
components/anchor/style/cssVar.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import { prepareComponentToken } from '.';
|
||||
import { genCSSVarRegister } from '../../theme/internal';
|
||||
|
||||
export default genCSSVarRegister<'Anchor'>('Anchor', prepareComponentToken);
|
@ -1,6 +1,7 @@
|
||||
import type { CSSObject } from '@ant-design/cssinjs';
|
||||
import { unit } from '@ant-design/cssinjs';
|
||||
|
||||
import { resetComponent, textEllipsis } from '../../style';
|
||||
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||
import type { FullToken, GenerateStyle, GetDefaultToken } from '../../theme/internal';
|
||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||
|
||||
export interface ComponentToken {
|
||||
@ -18,13 +19,13 @@ export interface ComponentToken {
|
||||
|
||||
interface AnchorToken extends FullToken<'Anchor'> {
|
||||
holderOffsetBlock: number;
|
||||
anchorPaddingBlockSecondary: number;
|
||||
anchorBallSize: number;
|
||||
anchorTitleBlock: number;
|
||||
anchorPaddingBlockSecondary: number | string;
|
||||
anchorBallSize: number | string;
|
||||
anchorTitleBlock: number | string;
|
||||
}
|
||||
|
||||
// ============================== Shared ==============================
|
||||
const genSharedAnchorStyle: GenerateStyle<AnchorToken> = (token): CSSObject => {
|
||||
const genSharedAnchorStyle: GenerateStyle<AnchorToken> = (token) => {
|
||||
const {
|
||||
componentCls,
|
||||
holderOffsetBlock,
|
||||
@ -33,11 +34,12 @@ const genSharedAnchorStyle: GenerateStyle<AnchorToken> = (token): CSSObject => {
|
||||
colorPrimary,
|
||||
lineType,
|
||||
colorSplit,
|
||||
calc,
|
||||
} = token;
|
||||
|
||||
return {
|
||||
[`${componentCls}-wrapper`]: {
|
||||
marginBlockStart: -holderOffsetBlock,
|
||||
marginBlockStart: calc(holderOffsetBlock).mul(-1).equal(),
|
||||
paddingBlockStart: holderOffsetBlock,
|
||||
|
||||
// delete overflow: auto
|
||||
@ -50,7 +52,7 @@ const genSharedAnchorStyle: GenerateStyle<AnchorToken> = (token): CSSObject => {
|
||||
|
||||
[`${componentCls}-link`]: {
|
||||
paddingBlock: token.linkPaddingBlock,
|
||||
paddingInline: `${token.linkPaddingInlineStart}px 0`,
|
||||
paddingInline: `${unit(token.linkPaddingInlineStart)} 0`,
|
||||
|
||||
'&-title': {
|
||||
...textEllipsis,
|
||||
@ -83,7 +85,7 @@ const genSharedAnchorStyle: GenerateStyle<AnchorToken> = (token): CSSObject => {
|
||||
insetInlineStart: 0,
|
||||
top: 0,
|
||||
height: '100%',
|
||||
borderInlineStart: `${lineWidthBold}px ${lineType} ${colorSplit}`,
|
||||
borderInlineStart: `${unit(lineWidthBold)} ${lineType} ${colorSplit}`,
|
||||
content: '" "',
|
||||
},
|
||||
|
||||
@ -95,7 +97,6 @@ const genSharedAnchorStyle: GenerateStyle<AnchorToken> = (token): CSSObject => {
|
||||
transition: `top ${motionDurationSlow} ease-in-out`,
|
||||
width: lineWidthBold,
|
||||
backgroundColor: colorPrimary,
|
||||
|
||||
[`&${componentCls}-ink-visible`]: {
|
||||
display: 'inline-block',
|
||||
},
|
||||
@ -110,7 +111,7 @@ const genSharedAnchorStyle: GenerateStyle<AnchorToken> = (token): CSSObject => {
|
||||
};
|
||||
};
|
||||
|
||||
const genSharedAnchorHorizontalStyle: GenerateStyle<AnchorToken> = (token): CSSObject => {
|
||||
const genSharedAnchorHorizontalStyle: GenerateStyle<AnchorToken> = (token) => {
|
||||
const { componentCls, motionDurationSlow, lineWidthBold, colorPrimary } = token;
|
||||
|
||||
return {
|
||||
@ -128,7 +129,7 @@ const genSharedAnchorHorizontalStyle: GenerateStyle<AnchorToken> = (token): CSSO
|
||||
value: 0,
|
||||
},
|
||||
bottom: 0,
|
||||
borderBottom: `1px ${token.lineType} ${token.colorSplit}`,
|
||||
borderBottom: `${unit(token.lineWidth)} ${token.lineType} ${token.colorSplit}`,
|
||||
content: '" "',
|
||||
},
|
||||
|
||||
@ -158,22 +159,23 @@ const genSharedAnchorHorizontalStyle: GenerateStyle<AnchorToken> = (token): CSSO
|
||||
};
|
||||
};
|
||||
|
||||
export const prepareComponentToken: GetDefaultToken<'Anchor'> = (token) => ({
|
||||
linkPaddingBlock: token.paddingXXS,
|
||||
linkPaddingInlineStart: token.padding,
|
||||
});
|
||||
|
||||
// ============================== Export ==============================
|
||||
export default genComponentStyleHook(
|
||||
'Anchor',
|
||||
(token) => {
|
||||
const { fontSize, fontSizeLG, paddingXXS } = token;
|
||||
|
||||
const { fontSize, fontSizeLG, paddingXXS, calc } = token;
|
||||
const anchorToken = mergeToken<AnchorToken>(token, {
|
||||
holderOffsetBlock: paddingXXS,
|
||||
anchorPaddingBlockSecondary: paddingXXS / 2,
|
||||
anchorTitleBlock: (fontSize / 14) * 3,
|
||||
anchorBallSize: fontSizeLG / 2,
|
||||
anchorPaddingBlockSecondary: calc(paddingXXS).div(2).equal(),
|
||||
anchorTitleBlock: calc(fontSize).div(14).mul(3).equal(),
|
||||
anchorBallSize: calc(fontSizeLG).div(2).equal(),
|
||||
});
|
||||
return [genSharedAnchorStyle(anchorToken), genSharedAnchorHorizontalStyle(anchorToken)];
|
||||
},
|
||||
(token) => ({
|
||||
linkPaddingBlock: token.paddingXXS,
|
||||
linkPaddingInlineStart: token.padding,
|
||||
}),
|
||||
prepareComponentToken,
|
||||
);
|
||||
|
@ -28,7 +28,6 @@ console.error = (msg: any) => {
|
||||
|
||||
async function checkCSSVar() {
|
||||
const ignore = [
|
||||
'anchor',
|
||||
'badge',
|
||||
'breadcrumb',
|
||||
'calendar',
|
||||
|
Loading…
Reference in New Issue
Block a user