Add staggered expand animation

Implement sequential delays for detailed view expansions:
- Add staggerIndex prop support to DetailedViewCollapsible and apply per-item animation delays.
- Pass item index in SubmissionItemsList when rendering detailed sections.
- Ensure each detailed view expands with a 50ms incremental delay (up to a max) for a staggered effect.

X-Lovable-Edit-ID: edt-6eb47d5c-853d-43ab-96a7-16a5cc006c30
This commit is contained in:
gpt-engineer-app[bot]
2025-11-12 14:56:11 +00:00
3 changed files with 24 additions and 7 deletions

View File

@@ -10,6 +10,7 @@ interface DetailedViewCollapsibleProps {
children: React.ReactNode; children: React.ReactNode;
fieldCount?: number; fieldCount?: number;
className?: string; className?: string;
staggerIndex?: number;
} }
/** /**
@@ -21,8 +22,11 @@ export function DetailedViewCollapsible({
onToggle, onToggle,
children, children,
fieldCount, fieldCount,
className className,
staggerIndex = 0
}: DetailedViewCollapsibleProps) { }: DetailedViewCollapsibleProps) {
// Calculate stagger delay: 50ms per item, max 300ms
const staggerDelay = Math.min(staggerIndex * 50, 300);
return ( return (
<Collapsible open={!isCollapsed} onOpenChange={() => onToggle()}> <Collapsible open={!isCollapsed} onOpenChange={() => onToggle()}>
<div className={cn("mt-6 pt-6 border-t", className)}> <div className={cn("mt-6 pt-6 border-t", className)}>
@@ -59,7 +63,13 @@ export function DetailedViewCollapsible({
</Button> </Button>
</CollapsibleTrigger> </CollapsibleTrigger>
<CollapsibleContent className="mt-3"> <CollapsibleContent
className="mt-3"
style={{
animationDelay: `${staggerDelay}ms`,
transitionDelay: `${staggerDelay}ms`
}}
>
{children} {children}
</CollapsibleContent> </CollapsibleContent>
</div> </div>

View File

@@ -135,7 +135,7 @@ export const SubmissionItemsList = memo(function SubmissionItemsList({
} }
// Render item with appropriate display component // Render item with appropriate display component
const renderItem = (item: SubmissionItemData) => { const renderItem = (item: SubmissionItemData, index: number = 0) => {
// SubmissionItemData from submissions.ts has item_data property // SubmissionItemData from submissions.ts has item_data property
const entityData = item.item_data; const entityData = item.item_data;
const actionType = item.action_type || 'create'; const actionType = item.action_type || 'create';
@@ -201,6 +201,7 @@ export const SubmissionItemsList = memo(function SubmissionItemsList({
isCollapsed={isCollapsed} isCollapsed={isCollapsed}
onToggle={toggle} onToggle={toggle}
fieldCount={countFields(entityData)} fieldCount={countFields(entityData)}
staggerIndex={index}
> >
<SubmissionChangesDisplay <SubmissionChangesDisplay
item={item} item={item}
@@ -225,6 +226,7 @@ export const SubmissionItemsList = memo(function SubmissionItemsList({
isCollapsed={isCollapsed} isCollapsed={isCollapsed}
onToggle={toggle} onToggle={toggle}
fieldCount={countFields(entityData)} fieldCount={countFields(entityData)}
staggerIndex={index}
> >
<SubmissionChangesDisplay <SubmissionChangesDisplay
item={item} item={item}
@@ -249,6 +251,7 @@ export const SubmissionItemsList = memo(function SubmissionItemsList({
isCollapsed={isCollapsed} isCollapsed={isCollapsed}
onToggle={toggle} onToggle={toggle}
fieldCount={countFields(entityData)} fieldCount={countFields(entityData)}
staggerIndex={index}
> >
<SubmissionChangesDisplay <SubmissionChangesDisplay
item={item} item={item}
@@ -273,6 +276,7 @@ export const SubmissionItemsList = memo(function SubmissionItemsList({
isCollapsed={isCollapsed} isCollapsed={isCollapsed}
onToggle={toggle} onToggle={toggle}
fieldCount={countFields(entityData)} fieldCount={countFields(entityData)}
staggerIndex={index}
> >
<SubmissionChangesDisplay <SubmissionChangesDisplay
item={item} item={item}
@@ -297,6 +301,7 @@ export const SubmissionItemsList = memo(function SubmissionItemsList({
isCollapsed={isCollapsed} isCollapsed={isCollapsed}
onToggle={toggle} onToggle={toggle}
fieldCount={countFields(entityData)} fieldCount={countFields(entityData)}
staggerIndex={index}
> >
<SubmissionChangesDisplay <SubmissionChangesDisplay
item={item} item={item}
@@ -334,9 +339,9 @@ export const SubmissionItemsList = memo(function SubmissionItemsList({
)} )}
{/* Show regular submission items */} {/* Show regular submission items */}
{items.map((item) => ( {items.map((item, index) => (
<div key={item.id} className={view === 'summary' ? 'border-l-2 border-primary/20 pl-3' : ''}> <div key={item.id} className={view === 'summary' ? 'border-l-2 border-primary/20 pl-3' : ''}>
{renderItem(item)} {renderItem(item, index)}
</div> </div>
))} ))}

View File

@@ -50,8 +50,10 @@ export function useDetailedViewState(): UseDetailedViewStateReturn {
}); });
} }
if (data?.moderation_preferences) { // Type assertion needed until Supabase regenerates types after migration
const prefs = data.moderation_preferences as ModerationPreferences; const preferences = (data as any)?.moderation_preferences;
if (preferences) {
const prefs = preferences as ModerationPreferences;
setIsCollapsed(prefs.detailed_view_collapsed ?? true); setIsCollapsed(prefs.detailed_view_collapsed ?? true);
} }
} else { } else {