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:
michael
2026-03-09 21:18:12 -07:00
parent 34be1d0b9e
commit c8afd90527
3 changed files with 18 additions and 41 deletions

View File

@@ -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>
);
}

View File

@@ -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';