diff --git a/frontend/src/features/settings/__tests__/ProductUsageTab.test.tsx b/frontend/src/features/settings/__tests__/ProductUsageTab.test.tsx index 3699e6cb..a6b677c4 100644 --- a/frontend/src/features/settings/__tests__/ProductUsageTab.test.tsx +++ b/frontend/src/features/settings/__tests__/ProductUsageTab.test.tsx @@ -305,6 +305,23 @@ it('returns focus to the control that opened the consent dialog', async () => { ); }); +// WebKit sizing (Safari, desktop and iOS). The consent dialog is a native +// laid out as a flex column with only a max-height, so its height is +// indefinite. `flex-1` is `flex: 1 1 0%`, and WebKit resolves that 0% basis +// against the indefinite height as zero — the disclosure's hypothetical size +// becomes zero and the dialog shrinks to header plus footer, leaving the +// text in a 32px strip. Chromium treats the same basis as `content`. Measured +// in iOS Safari: 302px dialog / 32px region before, 641px / 371px after. An +// `auto` basis with min-height 0 sizes from content and then shrinks to fit. +// The div-based modals elsewhere are unaffected; only collapses. +it('sizes the consent disclosure from its content, so WebKit does not collapse the dialog', async () => { + mount(); + fireEvent.click(await screen.findByText('productUsage.review')); + const region = await screen.findByRole('group', { name: 'productUsage.consentTitle' }); + expect(region.className.split(' ')).toEqual(expect.arrayContaining(['flex-auto', 'min-h-0', 'overflow-y-auto'])); + expect(region.className.split(' ')).not.toContain('flex-1'); +}); + // A security property, not a nicety: the consent dialog is where an operator // decides whether to open a connection at all, so it has to say which way that // connection runs. UsageService makes exactly two outbound POSTs and reads diff --git a/frontend/src/features/settings/tabs/ProductUsageTab.tsx b/frontend/src/features/settings/tabs/ProductUsageTab.tsx index 54647ab3..bf9b1687 100644 --- a/frontend/src/features/settings/tabs/ProductUsageTab.tsx +++ b/frontend/src/features/settings/tabs/ProductUsageTab.tsx @@ -124,7 +124,7 @@ function ConsentDialog({ tabIndex={0} role="group" aria-label={t('productUsage.consentTitle') as string} - className="flex-1 overflow-y-auto border-y border-neutral-200 dark:border-neutral-700 px-6 py-4 space-y-4 focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-primary-400" + className="min-h-0 flex-auto overflow-y-auto border-y border-neutral-200 dark:border-neutral-700 px-6 py-4 space-y-4 focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-primary-400" > {DISCLOSURE.map(({ key, heading, Icon }) => (