frontend-patterns/research/experiments/boundary-recovery/routing-fixture.jsx
tegwick 29ccad7002 Test lifecycle-aware Escape ownership routing without settling delays
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0cffe-206f-7323-89d3-b20ca4cf4bf9
2026-09-26 22:58:07 +02:00

35 lines
2.1 KiB
JavaScript

import React, {useState, useRef} from 'react';
import {createRoot} from 'react-dom/client';
import * as Dialog from '@radix-ui/react-dialog';
window.routingObserved = {changes: [], escapes: [], trace: []};
const options = new URLSearchParams(location.search);
function App() {
const [outer, setOuter] = useState(false);
const [inner, setInner] = useState(false);
const [mounted, setMounted] = useState(true);
const [trigger, setTrigger] = useState(true);
const next = useRef(null);
const change = (name, setter) => value => {window.routingObserved.changes.push({name, value});setter(value);};
window.removeInner = () => setInner(false);
window.removeTask = () => setMounted(false);
return <main><button id="next" ref={next}>Next record</button>
{mounted && <Dialog.Root open={outer} onOpenChange={change('outer',setOuter)}>
<Dialog.Trigger id="outer-trigger">Open outer</Dialog.Trigger>
<Dialog.Portal><Dialog.Content aria-describedby={undefined} onEscapeKeyDown={() => window.routingObserved.escapes.push('outer')}>
<Dialog.Title>Outer task</Dialog.Title>
<Dialog.Root open={inner} onOpenChange={change('inner',setInner)}>
{trigger && <Dialog.Trigger id="inner-trigger">Open inner</Dialog.Trigger>}
<Dialog.Portal><Dialog.Content aria-describedby={undefined}
onEscapeKeyDown={event => {window.routingObserved.escapes.push('inner');if(options.has('cancel')) event.preventDefault();}}
onCloseAutoFocus={event => {if(!trigger){event.preventDefault();document.getElementById('outer-close')?.focus();}}}>
<Dialog.Title>Inner task</Dialog.Title>
<Dialog.Close id="inner-close">Close inner</Dialog.Close>
<button id="remove-trigger" onClick={() => {setTrigger(false);setInner(false);}}>Remove trigger and finish</button>
</Dialog.Content></Dialog.Portal>
</Dialog.Root>
<Dialog.Close id="outer-close">Close outer</Dialog.Close>
</Dialog.Content></Dialog.Portal>
</Dialog.Root>}
</main>;
}
createRoot(document.getElementById('root')).render(<App />);