fixed elements positioning
This commit is contained in:
parent
c88f5d2a37
commit
69ddc59317
@ -274,16 +274,14 @@
|
|||||||
============================================================= */
|
============================================================= */
|
||||||
|
|
||||||
/* Element appear animation keyframes - Safari optimized */
|
/* Element appear animation keyframes - Safari optimized */
|
||||||
|
/* Note: element-fade-in must NOT include transform as it conflicts with
|
||||||
|
element positioning (translate(-50%, -50%)) causing position shift */
|
||||||
@-webkit-keyframes element-fade-in {
|
@-webkit-keyframes element-fade-in {
|
||||||
from {
|
from {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
-webkit-transform: translate3d(0, 0, 0);
|
|
||||||
transform: translate3d(0, 0, 0);
|
|
||||||
}
|
}
|
||||||
to {
|
to {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
-webkit-transform: translate3d(0, 0, 0);
|
|
||||||
transform: translate3d(0, 0, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
* handles state-based style application via JavaScript events.
|
* handles state-based style application via JavaScript events.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useCallback, useState, useEffect } from 'react';
|
import { useCallback, useState, useEffect, useRef } from 'react';
|
||||||
import type { CSSProperties } from 'react';
|
import type { CSSProperties } from 'react';
|
||||||
import {
|
import {
|
||||||
buildHoverStyle,
|
buildHoverStyle,
|
||||||
@ -83,13 +83,20 @@ export function useElementEffects(
|
|||||||
isClickPersisted: false,
|
isClickPersisted: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Track previous resetKey to avoid running on initial mount
|
||||||
|
const prevResetKeyRef = useRef(resetKey);
|
||||||
|
|
||||||
// Reset reveal state and click-persisted state when resetKey changes (e.g., page navigation)
|
// Reset reveal state and click-persisted state when resetKey changes (e.g., page navigation)
|
||||||
|
// Only run when resetKey actually CHANGES, not on initial mount (to avoid re-render during animation)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setState((prev) => ({
|
if (prevResetKeyRef.current !== resetKey) {
|
||||||
...prev,
|
setState((prev) => ({
|
||||||
isRevealed: false,
|
...prev,
|
||||||
isClickPersisted: false,
|
isRevealed: false,
|
||||||
}));
|
isClickPersisted: false,
|
||||||
|
}));
|
||||||
|
prevResetKeyRef.current = resetKey;
|
||||||
|
}
|
||||||
}, [resetKey]);
|
}, [resetKey]);
|
||||||
|
|
||||||
const onMouseEnter = useCallback(() => {
|
const onMouseEnter = useCallback(() => {
|
||||||
|
|||||||
@ -113,13 +113,58 @@ export type EffectPropName = (typeof EFFECT_PROPS)[number];
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Build base transition style for smooth state changes.
|
* Build base transition style for smooth state changes.
|
||||||
|
* Uses specific properties instead of 'all' to avoid affecting positioning transforms.
|
||||||
*/
|
*/
|
||||||
export function buildTransitionStyle(
|
export function buildTransitionStyle(
|
||||||
effects: Partial<ElementEffectProperties>,
|
effects: Partial<ElementEffectProperties>,
|
||||||
): CSSProperties {
|
): CSSProperties {
|
||||||
const duration = normalizeDuration(effects.hoverTransitionDuration) || '0.2s';
|
const duration = normalizeDuration(effects.hoverTransitionDuration) || '0.2s';
|
||||||
|
|
||||||
|
// Build list of properties to transition based on what's configured
|
||||||
|
const transitionProps: string[] = [];
|
||||||
|
|
||||||
|
// Always include opacity if any effect might change it
|
||||||
|
if (
|
||||||
|
effects.hoverOpacity ||
|
||||||
|
effects.focusOpacity ||
|
||||||
|
effects.activeOpacity ||
|
||||||
|
effects.hoverReveal
|
||||||
|
) {
|
||||||
|
transitionProps.push('opacity');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Include transform only for scale effects (not positioning)
|
||||||
|
if (effects.hoverScale || effects.focusScale || effects.activeScale) {
|
||||||
|
transitionProps.push('transform');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Background color
|
||||||
|
if (effects.hoverBackgroundColor || effects.activeBackgroundColor) {
|
||||||
|
transitionProps.push('background-color');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text color
|
||||||
|
if (effects.hoverColor) {
|
||||||
|
transitionProps.push('color');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Box shadow
|
||||||
|
if (effects.hoverBoxShadow || effects.focusBoxShadow) {
|
||||||
|
transitionProps.push('box-shadow');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Outline
|
||||||
|
if (effects.focusOutline) {
|
||||||
|
transitionProps.push('outline');
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no specific properties, return empty (no transition needed)
|
||||||
|
if (transitionProps.length === 0) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
transition: `all ${duration} ease`,
|
transition: transitionProps.map((p) => `${p} ${duration} ease`).join(', '),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user