Standalone example · v1
Cookie choices and keyboard focus.
Open the real shop cookie settings. Compare where focus goes, whether it stays in the dialog and where it returns.
Prepare resets only this consent fixture to undecided and closes its transient dialog. No login is needed.
View the shared source
These are the actual source files used by this fixture. A generated snapshot is checked against the implementation before each build validation. Imports and reusable helpers remain visible; this is not a separate teaching copy.
src/components/features/consent/cookie-controls.tsx
'use client';
import {useEffect, useRef, useState} from 'react';
import {useTranslations} from 'next-intl';
import {Button} from '@/components/ui/button';
import {Dialog, DialogPortal, DialogOverlay, DialogContent, DialogTitle, DialogDescription} from '@/components/ui/dialog';
import {useDemoState} from '@/lib/state/use-demo-state';
import {consentChoice} from '@/lib/state/consent';
import type {Variant} from '@/lib/routes';
export function CookieControls({variant}: {variant: Variant}) {
const t = useTranslations('Cookies');
const [consent, setConsent] = useDemoState('consent');
const [open, setOpen] = useState(false);
const [analytics, setAnalytics] = useState(false);
const [marketing, setMarketing] = useState(false);
const title = useRef<HTMLHeadingElement>(null);
const returnTarget = useRef<HTMLElement | null>(null);
const footerTrigger = useRef<HTMLButtonElement>(null);
useEffect(() => {const close = () => setOpen(false); window.addEventListener('demo-reset', close); return () => window.removeEventListener('demo-reset', close);}, []);
useEffect(() => {
if (!open || variant !== 'barriers') return;
const escape = (event: KeyboardEvent) => {if (event.key === 'Escape') setOpen(false);};
window.addEventListener('keydown', escape);
return () => window.removeEventListener('keydown', escape);
}, [open, variant]);
function showSettings() {
returnTarget.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
setAnalytics(consent.analytics); setMarketing(consent.marketing); setOpen(true);
}
function choose(analyticsValue: boolean, marketingValue: boolean) {
if (setConsent(consentChoice(analyticsValue, marketingValue))) {
setOpen(false);
if (!open) footerTrigger.current?.focus();
}
}
function restoreFocus() {
const target = returnTarget.current?.isConnected ? returnTarget.current : footerTrigger.current;
target?.focus();
}
const fields = <>
<div className="consent-options">
<label><input type="checkbox" checked disabled/><span><strong>{t('necessary')}</strong><span>{t('necessaryHelp')}</span></span></label>
<label><input type="checkbox" checked={analytics} onChange={event => setAnalytics(event.target.checked)}/><span><strong>{t('analytics')}</strong><span>{t('analyticsHelp')}</span></span></label>
<label><input type="checkbox" checked={marketing} onChange={event => setMarketing(event.target.checked)}/><span><strong>{t('marketing')}</strong><span>{t('marketingHelp')}</span></span></label>
</div>
<div className="cookie-actions"><Button onClick={() => choose(analytics, marketing)}>{t('save')}</Button><Button variant="outline" onClick={() => choose(false, false)}>{t('reject')}</Button><Button variant="outline" onClick={() => setOpen(false)}>{t('close')}</Button></div>
</>;
return <>
<div className="cookie-footer-control"><Button ref={footerTrigger} id="cookie-settings-trigger" variant="outline" size="sm" onClick={showSettings}>{t('settings')}</Button><span role="status">{t('status', {choice: t(consent.choice)})}</span></div>
{consent.choice === 'unset' && !open && <section className="cookie-banner" aria-labelledby="cookie-banner-heading" data-testid="cookie-banner"><div><h2 id="cookie-banner-heading">{t('bannerTitle')}</h2><p>{t('bannerText')}</p></div><div className="cookie-actions"><Button size="sm" onClick={() => choose(false, false)} variant="outline">{t('reject')}</Button><Button size="sm" onClick={() => choose(true, true)}>{t('accept')}</Button><Button size="sm" variant="outline" onClick={showSettings}>{t('manage')}</Button></div></section>}
{variant === 'improved' ? <Dialog open={open} onOpenChange={setOpen}><DialogPortal><DialogOverlay className="dialog-overlay"/><DialogContent className="cookie-dialog" id="cookie-dialog" data-testid="cookie-dialog" onOpenAutoFocus={event => {event.preventDefault(); title.current?.focus();}} onCloseAutoFocus={event => {event.preventDefault(); restoreFocus();}}><DialogTitle ref={title} tabIndex={-1} className="dialog-heading">{t('dialogTitle')}</DialogTitle><DialogDescription>{t('dialogText')}</DialogDescription>{fields}</DialogContent></DialogPortal></Dialog> : open &&
// Intentional cookie-modal-focus failure: this modal-looking fixture does not move or contain focus.
<div className="cookie-dialog scenario-cookie-modal-barriers" id="cookie-dialog" data-testid="cookie-dialog" role="dialog" aria-modal="true" aria-labelledby="broken-cookie-title" aria-describedby="broken-cookie-description"><h2 id="broken-cookie-title">{t('dialogTitle')}</h2><p id="broken-cookie-description">{t('dialogText')}</p>{fields}</div>}
</>;
}
src/components/ui/dialog.tsx
'use client';
import * as Primitive from '@radix-ui/react-dialog';
export const Dialog = Primitive.Root;
export const DialogPortal = Primitive.Portal;
export const DialogOverlay = Primitive.Overlay;
export const DialogContent = Primitive.Content;
export const DialogTitle = Primitive.Title;
export const DialogDescription = Primitive.Description;
export const DialogClose = Primitive.Close;
src/app/[locale]/globals.css
.cookie-dialog {position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:min(calc(100% - 2rem),36rem);max-height:calc(100dvh - 2rem);overflow:auto;z-index:51;background:var(--card);color:var(--foreground);border:1px solid var(--border);border-radius:.75rem;padding:2rem;}
.scenario-cookie-modal-barriers {inset:auto 1rem 1rem auto;transform:none;}