feat: affix support cssvar

pull/7940/head
tangjinzhou 2024-11-11 11:32:01 +08:00
parent a0c9369989
commit 3375bd4695
3 changed files with 41 additions and 25 deletions

View File

@ -27,10 +27,11 @@ import useStyle from './style';
function getDefaultTarget() { function getDefaultTarget() {
return typeof window !== 'undefined' ? window : null; return typeof window !== 'undefined' ? window : null;
} }
enum AffixStatus { const AFFIX_STATUS_NONE = 0;
None, const AFFIX_STATUS_PREPARE = 1;
Prepare,
} type AffixStatus = typeof AFFIX_STATUS_NONE | typeof AFFIX_STATUS_PREPARE;
export interface AffixState { export interface AffixState {
affixStyle?: CSSProperties; affixStyle?: CSSProperties;
placeholderStyle?: CSSProperties; placeholderStyle?: CSSProperties;
@ -82,7 +83,7 @@ const Affix = defineComponent({
const state = reactive({ const state = reactive({
affixStyle: undefined, affixStyle: undefined,
placeholderStyle: undefined, placeholderStyle: undefined,
status: AffixStatus.None, status: AFFIX_STATUS_NONE,
lastAffix: false, lastAffix: false,
prevTarget: null, prevTarget: null,
timeout: null, timeout: null,
@ -98,7 +99,12 @@ const Affix = defineComponent({
const measure = () => { const measure = () => {
const { status, lastAffix } = state; const { status, lastAffix } = state;
const { target } = props; const { target } = props;
if (status !== AffixStatus.Prepare || !fixedNode.value || !placeholderNode.value || !target) { if (
status !== AFFIX_STATUS_PREPARE ||
!fixedNode.value ||
!placeholderNode.value ||
!target
) {
return; return;
} }
@ -108,7 +114,7 @@ const Affix = defineComponent({
} }
const newState = { const newState = {
status: AffixStatus.None, status: AFFIX_STATUS_NONE,
} as AffixState; } as AffixState;
const placeholderRect = getTargetRect(placeholderNode.value as HTMLElement); const placeholderRect = getTargetRect(placeholderNode.value as HTMLElement);
@ -172,7 +178,7 @@ const Affix = defineComponent({
}; };
const prepareMeasure = () => { const prepareMeasure = () => {
Object.assign(state, { Object.assign(state, {
status: AffixStatus.Prepare, status: AFFIX_STATUS_PREPARE,
affixStyle: undefined, affixStyle: undefined,
placeholderStyle: undefined, placeholderStyle: undefined,
}); });
@ -253,12 +259,13 @@ const Affix = defineComponent({
}); });
const { prefixCls } = useConfigInject('affix', props); const { prefixCls } = useConfigInject('affix', props);
const [wrapSSR, hashId] = useStyle(prefixCls); const [wrapSSR, hashId, cssVarCls] = useStyle(prefixCls);
return () => { return () => {
const { affixStyle, placeholderStyle, status } = state; const { affixStyle, placeholderStyle, status } = state;
const className = classNames({ const className = classNames({
[prefixCls.value]: affixStyle, [prefixCls.value]: affixStyle,
[hashId.value]: true, [hashId.value]: true,
[cssVarCls.value]: true,
}); });
const restProps = omit(props, [ const restProps = omit(props, [
'prefixCls', 'prefixCls',

View File

@ -1,17 +1,21 @@
import type { CSSObject } from '../../_util/cssinjs'; import type { CSSObject } from '../../_util/cssinjs';
import type { FullToken, GenerateStyle } from '../../theme/internal'; import { FullToken, GenerateStyle, genStyleHooks, GetDefaultToken } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
export interface ComponentToken {} export interface ComponentToken {
/**
* @desc z-index
* @descEN z-index of popup
*/
zIndexPopup: number;
}
interface AffixToken extends FullToken<'Affix'> { interface AffixToken extends FullToken<'Affix'> {
zIndexPopup: number; //
} }
// ============================== Shared ============================== // ============================== Shared ==============================
const genSharedAffixStyle: GenerateStyle<AffixToken> = (token): CSSObject => { const genSharedAffixStyle: GenerateStyle<AffixToken> = (token): CSSObject => {
const { componentCls } = token; const { componentCls } = token;
return { return {
[componentCls]: { [componentCls]: {
position: 'fixed', position: 'fixed',
@ -20,10 +24,9 @@ const genSharedAffixStyle: GenerateStyle<AffixToken> = (token): CSSObject => {
}; };
}; };
// ============================== Export ============================== export const prepareComponentToken: GetDefaultToken<'Affix'> = token => ({
export default genComponentStyleHook('Affix', token => {
const affixToken = mergeToken<AffixToken>(token, {
zIndexPopup: token.zIndexBase + 10, zIndexPopup: token.zIndexBase + 10,
});
return [genSharedAffixStyle(affixToken)];
}); });
// ============================== Export ==============================
export default genStyleHooks('Affix', genSharedAffixStyle, prepareComponentToken);

View File

@ -9,8 +9,11 @@ export function getTargetRect(target: BindElement): DOMRect {
: ({ top: 0, bottom: window.innerHeight } as DOMRect); : ({ top: 0, bottom: window.innerHeight } as DOMRect);
} }
export function getFixedTop(placeholderRect: DOMRect, targetRect: DOMRect, offsetTop: number) { export function getFixedTop(placeholderRect: DOMRect, targetRect: DOMRect, offsetTop?: number) {
if (offsetTop !== undefined && targetRect.top > placeholderRect.top - offsetTop) { if (
offsetTop !== undefined &&
Math.round(targetRect.top) > Math.round(placeholderRect.top) - offsetTop
) {
return `${offsetTop + targetRect.top}px`; return `${offsetTop + targetRect.top}px`;
} }
return undefined; return undefined;
@ -19,9 +22,12 @@ export function getFixedTop(placeholderRect: DOMRect, targetRect: DOMRect, offse
export function getFixedBottom( export function getFixedBottom(
placeholderRect: DOMRect, placeholderRect: DOMRect,
targetRect: DOMRect, targetRect: DOMRect,
offsetBottom: number, offsetBottom?: number,
) { ) {
if (offsetBottom !== undefined && targetRect.bottom < placeholderRect.bottom + offsetBottom) { if (
offsetBottom !== undefined &&
Math.round(targetRect.bottom) < Math.round(placeholderRect.bottom) + offsetBottom
) {
const targetBottomOffset = window.innerHeight - targetRect.bottom; const targetBottomOffset = window.innerHeight - targetRect.bottom;
return `${offsetBottom + targetBottomOffset}px`; return `${offsetBottom + targetBottomOffset}px`;
} }
@ -29,7 +35,7 @@ export function getFixedBottom(
} }
// ======================== Observer ======================== // ======================== Observer ========================
const TRIGGER_EVENTS = [ const TRIGGER_EVENTS: (keyof WindowEventMap)[] = [
'resize', 'resize',
'scroll', 'scroll',
'touchstart', 'touchstart',