fix: focustrap activates on mount to prevent throw
parent
85c247eaf0
commit
53aeb63894
@ -1,27 +1,21 @@
|
|||||||
import FocusTrap from 'focus-trap-react';
|
import FocusTrap from 'focus-trap-react';
|
||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import styled from 'styled-components';
|
import { useMount } from 'react-use';
|
||||||
|
|
||||||
const DefaultFocusButton = styled.button`
|
|
||||||
opacity: 0;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
`;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The FocusTrap always require at least one element to be tabbable.
|
* Focus trap which activates on mount.
|
||||||
* On some dialogs, we don't have any until the content is loaded, and depending on what is loaded, we might not have any tabbable elements in it.
|
|
||||||
* This component renders the children inside a FocusTrap and always adds an invisible button to make FocusTrap happy.
|
|
||||||
*/
|
*/
|
||||||
export function SessionDialogFocusTrap(props: { children: React.ReactNode }) {
|
export function SessionFocusTrap(props: { children: React.ReactNode }) {
|
||||||
// FocusTrap needs a single child so props.children and the default button needs to be wrapped in a container.
|
const [active, setActive] = useState(false);
|
||||||
// This might cause some styling issues, but I didn't find any with our current dialogs
|
|
||||||
|
// Activate the trap on mount so we **should** have a button to tab through. focus-trap-react will throw if we don't have a button when the trap becomes active.
|
||||||
|
// We might still have an issue for dialogs which have buttons added with a useEffect, or asynchronously but have no buttons on mount.
|
||||||
|
// If that happens we will need to force those dialogs to have at least one button so focus-trap-react does not throw.
|
||||||
|
useMount(() => setActive(true));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FocusTrap focusTrapOptions={{ initialFocus: false, allowOutsideClick: true }}>
|
<FocusTrap active={active} focusTrapOptions={{ initialFocus: false, allowOutsideClick: true }}>
|
||||||
<div style={{ position: 'absolute' }}>
|
{props.children}
|
||||||
<DefaultFocusButton />
|
|
||||||
{props.children}
|
|
||||||
</div>
|
|
||||||
</FocusTrap>
|
</FocusTrap>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue