Probe rendering and modal focus boundaries in pinned browser fixture
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0cffe-206f-7323-89d3-b20ca4cf4bf9
This commit is contained in:
parent
50c68575f1
commit
3eecd74b0d
18 changed files with 2067 additions and 0 deletions
81
research/experiments/boundary-recovery/fixture.jsx
Normal file
81
research/experiments/boundary-recovery/fixture.jsx
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import React, {useState, useRef} from 'react';
|
||||
import {createRoot} from 'react-dom/client';
|
||||
import * as Dialog from '@radix-ui/react-dialog';
|
||||
|
||||
window.observed = {caught: [], globalErrors: [], requests: [], dialogTransitions: []};
|
||||
window.addEventListener('error', e => window.observed.globalErrors.push(e.message));
|
||||
class Boundary extends React.Component {
|
||||
state = {failed: false};
|
||||
static getDerivedStateFromError() { return {failed: true}; }
|
||||
componentDidCatch(error) { window.observed.caught.push({boundary: this.props.name, message: error.message}); }
|
||||
render() {
|
||||
if (this.state.failed) return this.props.brokenFallback
|
||||
? <BrokenFallback /> : <p role="alert" data-testid={this.props.name}>Region unavailable</p>;
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
function BrokenFallback() { throw new Error('fallback fault'); }
|
||||
function Panel() {
|
||||
const [broken, setBroken] = useState(false);
|
||||
const [request, setRequest] = useState('idle');
|
||||
if (broken) throw new Error('render fault');
|
||||
return <section data-testid="panel">
|
||||
<button onClick={() => setBroken(true)}>Break render</button>
|
||||
<button onClick={() => {throw new Error('event fault');}}>Break event</button>
|
||||
<button onClick={async () => {
|
||||
setRequest('pending');
|
||||
try {
|
||||
const r = await fetch('/failure');
|
||||
window.observed.requests.push(r.status);
|
||||
if (!r.ok) throw new Error('request rejected');
|
||||
setRequest('accepted');
|
||||
} catch {setRequest('request failed');}
|
||||
}}>Fail request</button>
|
||||
<p role="status">{request}</p>
|
||||
</section>;
|
||||
}
|
||||
function FailureFixture() {
|
||||
const [clicks, setClicks] = useState(0);
|
||||
const brokenFallback = new URLSearchParams(location.search).has('brokenFallback');
|
||||
return <main>
|
||||
<button onClick={() => setClicks(clicks + 1)}>Sibling {clicks}</button>
|
||||
<Boundary name="outer"><Boundary name="inner" brokenFallback={brokenFallback}>
|
||||
<Panel />
|
||||
</Boundary></Boundary>
|
||||
</main>;
|
||||
}
|
||||
function Modal({children, title}) {
|
||||
return <Dialog.Portal><Dialog.Overlay />
|
||||
<Dialog.Content aria-describedby={undefined}>
|
||||
<Dialog.Title>{title}</Dialog.Title>{children}
|
||||
</Dialog.Content>
|
||||
</Dialog.Portal>;
|
||||
}
|
||||
function FocusFixture() {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [present, setPresent] = useState(true);
|
||||
const next = useRef(null);
|
||||
const explicit = new URLSearchParams(location.search).has('explicit');
|
||||
return <main>
|
||||
<button id="next" ref={next}>Next record</button>
|
||||
<Dialog.Root open={open} onOpenChange={value => {window.observed.dialogTransitions.push({dialog: "outer", open: value}); setOpen(value);}}>
|
||||
{present && <Dialog.Trigger id="invoker">Open task</Dialog.Trigger>}
|
||||
<Dialog.Portal><Dialog.Overlay />
|
||||
<Dialog.Content aria-describedby={undefined} onCloseAutoFocus={event => {
|
||||
if (explicit && !present) {event.preventDefault(); next.current?.focus();}
|
||||
}}>
|
||||
<Dialog.Title>Record task</Dialog.Title>
|
||||
<button id="remove" onClick={() => {setPresent(false); setOpen(false);}}>Remove invoking record</button>
|
||||
<Dialog.Root onOpenChange={value => window.observed.dialogTransitions.push({dialog: "inner", open: value})}>
|
||||
<Dialog.Trigger id="nested-invoker">Nested task</Dialog.Trigger>
|
||||
<Modal title="Nested task"><Dialog.Close id="nested-close">Close nested</Dialog.Close></Modal>
|
||||
</Dialog.Root>
|
||||
<Dialog.Close id="close">Close task</Dialog.Close>
|
||||
</Dialog.Content>
|
||||
</Dialog.Portal>
|
||||
</Dialog.Root>
|
||||
</main>;
|
||||
}
|
||||
createRoot(document.getElementById('root')).render(
|
||||
new URLSearchParams(location.search).get('mode') === 'focus' ? <FocusFixture /> : <FailureFixture />
|
||||
);
|
||||
Loading…
Add table
Add a link
Reference in a new issue