diff --git a/src/components/campaign/dashboard/CampaignHomeLayout.tsx b/src/components/campaign/dashboard/CampaignHomeLayout.tsx index edb30893..40f45bdc 100644 --- a/src/components/campaign/dashboard/CampaignHomeLayout.tsx +++ b/src/components/campaign/dashboard/CampaignHomeLayout.tsx @@ -15,11 +15,14 @@ const HomeChromeRetractionShell = ({ slot, className, children, + allowHorizontalBleed = false, }: { retracted: boolean slot?: string className?: string children: ReactNode + /** B111 — keep Y clip for grid-rows retraction without clipping -mx bleed on X. */ + allowHorizontalBleed?: boolean }) => (
-
{children}
+
+ {children} +
) @@ -63,6 +71,7 @@ export const CampaignHomeLayout = ({ retracted={focused} slot="home-actions-chrome" className="order-1 md:order-2" + allowHorizontalBleed >
{ + if (!shouldShowHomeSummaryDelta(delta)) return null + const direction = resolveHomeSummaryDeltaDirection(delta) const magnitude = formatHomeSummaryDeltaMagnitude(delta) @@ -26,13 +29,11 @@ const HomeSummaryDelta = ({ delta }: { delta: number | null }) => { 'inline-flex items-center gap-0.5 text-sm font-medium tabular-nums', direction === 'up' && 'text-emerald-700 dark:text-emerald-400', direction === 'down' && 'text-rose-700 dark:text-rose-400', - (direction === 'flat' || direction === 'unavailable') && 'text-muted-foreground', )} > {direction === 'up' ? : null} {direction === 'down' ? : null} - {direction === 'flat' ? : null} - {magnitude ?? '—'} + {magnitude} ) } @@ -47,7 +48,7 @@ export const CampaignHomeSummary = ({ view }: { view: CampaignHomeSummaryView })

- {view.homeSummaryDelta !== null ? ( + {shouldShowHomeSummaryDelta(view.homeSummaryDelta) ? (

{homeSummaryDeltaPeriodLabel}

) : null} diff --git a/src/lib/campaignHomeSummaryDelta.ts b/src/lib/campaignHomeSummaryDelta.ts index c83adbba..bcc20168 100644 --- a/src/lib/campaignHomeSummaryDelta.ts +++ b/src/lib/campaignHomeSummaryDelta.ts @@ -15,6 +15,10 @@ export const resolveHomeSummaryDeltaDirection = ( return delta > 0 ? 'up' : 'down' } +/** B111 — render the Δ chip only when there was movement in the window. */ +export const shouldShowHomeSummaryDelta = (delta: number | null): boolean => + delta !== null && delta !== 0 + /** Absolute magnitude for display; null when unavailable; "0" when flat. */ export const formatHomeSummaryDeltaMagnitude = (delta: number | null): string | null => { if (delta === null) return null diff --git a/tests/unit/campaignHomeLayout.unit.spec.tsx b/tests/unit/campaignHomeLayout.unit.spec.tsx index 9eee5a38..aee45f74 100644 --- a/tests/unit/campaignHomeLayout.unit.spec.tsx +++ b/tests/unit/campaignHomeLayout.unit.spec.tsx @@ -30,6 +30,16 @@ describe('CampaignHomeLayout', () => { expect(actions?.className).toContain('md:w-auto') }) + it('does not clip horizontal bleed on the actions retraction shell', () => { + const { container } = render(Actions block

} />) + + const actionsChrome = container.querySelector('[data-slot="home-actions-chrome"]') + const bleedWrapper = actionsChrome?.querySelector('[data-allow-horizontal-bleed="true"]') + expect(bleedWrapper).not.toBeNull() + expect(bleedWrapper?.className).toContain('overflow-y-hidden') + expect(bleedWrapper?.className).not.toContain('overflow-hidden') + }) + it('renders search slot inside home-dock when provided', () => { render( { />, ) - expect(screen.getByLabelText('Variação nos últimos 7 dias indisponível')).toBeTruthy() + expect(screen.queryByLabelText(/nos últimos 7 dias/)).toBeNull() expect(screen.queryByRole('progressbar')).toBeNull() }) + + it('omits the delta chip and period caption when delta is flat', () => { + render( + , + ) + + expect(screen.getByText('12.345')).toBeTruthy() + expect(screen.queryByLabelText(/nos últimos 7 dias/)).toBeNull() + expect(screen.queryByText('nos últimos 7 dias')).toBeNull() + expect(screen.queryByText('0')).toBeNull() + }) }) diff --git a/tests/unit/campaignHomeSummaryDelta.unit.spec.ts b/tests/unit/campaignHomeSummaryDelta.unit.spec.ts index d0b53d10..18888a5f 100644 --- a/tests/unit/campaignHomeSummaryDelta.unit.spec.ts +++ b/tests/unit/campaignHomeSummaryDelta.unit.spec.ts @@ -4,6 +4,7 @@ import { formatHomeSummaryDeltaMagnitude, homeSummaryDeltaAriaLabel, resolveHomeSummaryDeltaDirection, + shouldShowHomeSummaryDelta, } from '@/lib/campaignHomeSummaryDelta' describe('campaignHomeSummaryDelta', () => { @@ -30,4 +31,11 @@ describe('campaignHomeSummaryDelta', () => { expect(homeSummaryDeltaAriaLabel(0)).toBe('Sem variação nos últimos 7 dias') expect(homeSummaryDeltaAriaLabel(null)).toBe('Variação nos últimos 7 dias indisponível') }) + + it('shows the delta chip only when movement occurred', () => { + expect(shouldShowHomeSummaryDelta(500)).toBe(true) + expect(shouldShowHomeSummaryDelta(-200)).toBe(true) + expect(shouldShowHomeSummaryDelta(0)).toBe(false) + expect(shouldShowHomeSummaryDelta(null)).toBe(false) + }) })