Refactor DTStaggerContainer: wrapper-div approach with delay/interval props
Replace CSS nth-child stagger rules with JS-driven wrapper divs that set animationDelay inline. Adds delay (base offset) and interval (ms between children) props. Removes --dt-stagger-interval CSS variable and 24 nth-child rules in favor of unlimited children support. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,18 +2,22 @@
|
||||
* DTStaggerContainer — Staggered scale-in animation for children.
|
||||
*
|
||||
* CSS reference: animations.css .dt-stagger-container
|
||||
* CSS handles all stagger timing via nth-child — no JS animation needed.
|
||||
* Each child is wrapped in a div that carries the animationDelay.
|
||||
* Wrapper divs inherit display:contents would break animation, so
|
||||
* the CSS rule targets .dt-stagger-container > * directly.
|
||||
*/
|
||||
|
||||
import type { ReactNode, CSSProperties } from 'react';
|
||||
import { Children, type ReactNode, type CSSProperties } from 'react';
|
||||
import { cx } from '../utils/cx';
|
||||
|
||||
interface DTStaggerContainerProps {
|
||||
children: ReactNode;
|
||||
/** Duration per child animation @default '0.33s' */
|
||||
duration?: string;
|
||||
/** Delay between each child @default '75ms' */
|
||||
interval?: string;
|
||||
/** Delay between each child in ms @default 150 */
|
||||
interval?: number;
|
||||
/** Base delay before the first child animates in ms @default 0 */
|
||||
delay?: number;
|
||||
className?: string;
|
||||
style?: CSSProperties;
|
||||
}
|
||||
@@ -21,19 +25,23 @@ interface DTStaggerContainerProps {
|
||||
export function DTStaggerContainer({
|
||||
children,
|
||||
duration,
|
||||
interval,
|
||||
interval = 150,
|
||||
delay = 0,
|
||||
className,
|
||||
style,
|
||||
}: DTStaggerContainerProps) {
|
||||
const cssVars: Record<string, string> = {};
|
||||
if (duration) cssVars['--dt-stagger-duration'] = duration;
|
||||
if (interval) cssVars['--dt-stagger-interval'] = interval;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx('dt-stagger-container', className)}
|
||||
style={{ ...cssVars, ...style } as CSSProperties}>
|
||||
{children}
|
||||
{Children.map(children, (child, i) => (
|
||||
<div style={{ animationDelay: `${delay + i * interval}ms` }}>
|
||||
{child}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,6 @@ export { DTSearchInput } from './components/DTSearchInput';
|
||||
export { DTProgressBar } from './components/DTProgressBar';
|
||||
export { DTAccordion } from './components/DTAccordion';
|
||||
export type { DTAccordionSection } from './components/DTAccordion';
|
||||
export { DTStaggerContainer } from './components/DTStaggerContainer';
|
||||
export { DTBadgeOverlay } from './components/DTBadgeOverlay';
|
||||
|
||||
// Components — filter & feature
|
||||
@@ -58,3 +57,6 @@ export { DTMobileFilterOverlay } from './components/DTMobileFilterOverlay';
|
||||
export { DTGallery } from './components/DTGallery';
|
||||
export type { DTGalleryItem } from './components/DTGallery';
|
||||
export { DTHexagon } from './components/DTHexagon';
|
||||
|
||||
// Components — animation
|
||||
export { DTStaggerContainer } from './components/DTStaggerContainer';
|
||||
|
||||
@@ -82,49 +82,16 @@
|
||||
|
||||
/* ============================================================================
|
||||
Stagger Container
|
||||
Source: storefront framer-motion staggered card entrance
|
||||
Usage: <div class="dt-stagger-container">...</div>
|
||||
Customize: --dt-stagger-duration, --dt-stagger-interval
|
||||
============================================================================ */
|
||||
|
||||
.dt-stagger-container {
|
||||
--dt-stagger-duration: 0.33s;
|
||||
--dt-stagger-interval: 75ms;
|
||||
}
|
||||
|
||||
.dt-stagger-container > * {
|
||||
animation: dt-scale-in var(--dt-stagger-duration) ease-in-out both;
|
||||
}
|
||||
|
||||
.dt-stagger-container > :nth-child(1) { animation-delay: calc(0 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(2) { animation-delay: calc(1 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(3) { animation-delay: calc(2 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(4) { animation-delay: calc(3 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(5) { animation-delay: calc(4 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(6) { animation-delay: calc(5 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(7) { animation-delay: calc(6 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(8) { animation-delay: calc(7 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(9) { animation-delay: calc(8 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(10) { animation-delay: calc(9 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(11) { animation-delay: calc(10 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(12) { animation-delay: calc(11 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(13) { animation-delay: calc(12 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(14) { animation-delay: calc(13 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(15) { animation-delay: calc(14 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(16) { animation-delay: calc(15 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(17) { animation-delay: calc(16 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(18) { animation-delay: calc(17 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(19) { animation-delay: calc(18 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(20) { animation-delay: calc(19 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(21) { animation-delay: calc(20 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(22) { animation-delay: calc(21 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(23) { animation-delay: calc(22 * var(--dt-stagger-interval)); }
|
||||
.dt-stagger-container > :nth-child(24) { animation-delay: calc(23 * var(--dt-stagger-interval)); }
|
||||
|
||||
.dt-stagger-container > :nth-child(n+25) {
|
||||
animation-delay: calc(24 * var(--dt-stagger-interval));
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
Transition Utilities
|
||||
============================================================================ */
|
||||
|
||||
Reference in New Issue
Block a user