Reusa CampaignListPendingBoundary no layout autenticado para compartilhar useTransition entre o header mobile e o conteúdo do passo. Voltar, X, Pular, seleção de município e tiles de passo passam por CampaignWizardNavLink; o corpo dima com aria-busy e o header mostra skeleton nos slots de título. CampaignTransitionAnchor agora retorna a promise do router para manter o pending honesto até a navegação terminar. Closes #14
33 lines
841 B
TypeScript
33 lines
841 B
TypeScript
'use client'
|
|
|
|
import type { ComponentPropsWithoutRef } from 'react'
|
|
|
|
import {
|
|
CampaignTransitionAnchor,
|
|
useCampaignListTransition,
|
|
} from '@/components/campaign/shared/CampaignListPending'
|
|
import { cn } from '@/lib/utils'
|
|
|
|
/**
|
|
* Wizard route navigation with shared list pending: drives the layout boundary
|
|
* and locks sibling triggers while the RSC payload loads.
|
|
*/
|
|
export const CampaignWizardNavLink = ({
|
|
href,
|
|
className,
|
|
children,
|
|
...anchorProps
|
|
}: Omit<ComponentPropsWithoutRef<'a'>, 'href'> & { href: string }) => {
|
|
const { isPending } = useCampaignListTransition()
|
|
|
|
return (
|
|
<CampaignTransitionAnchor
|
|
href={href}
|
|
className={cn(isPending && 'pointer-events-none', className)}
|
|
aria-busy={isPending || undefined}
|
|
{...anchorProps}
|
|
>
|
|
{children}
|
|
</CampaignTransitionAnchor>
|
|
)
|
|
}
|