1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-22 17:33:23 +01:00

Adding ModalFocus component (#18979)

This commit is contained in:
George Marshall 2023-05-09 14:33:29 -07:00 committed by GitHub
parent 62ffd8022a
commit 32688c2e3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 874 additions and 2 deletions

View File

@ -3910,6 +3910,64 @@
"setTimeout": true
}
},
"react-focus-lock": {
"globals": {
"addEventListener": true,
"console.error": true,
"console.warn": true,
"document": true,
"removeEventListener": true,
"setTimeout": true
},
"packages": {
"@babel/runtime": true,
"prop-types": true,
"react": true,
"react-focus-lock>focus-lock": true,
"react-focus-lock>react-clientside-effect": true,
"react-focus-lock>use-callback-ref": true,
"react-focus-lock>use-sidecar": true
}
},
"react-focus-lock>focus-lock": {
"globals": {
"HTMLIFrameElement": true,
"Node.DOCUMENT_FRAGMENT_NODE": true,
"Node.DOCUMENT_NODE": true,
"Node.DOCUMENT_POSITION_CONTAINED_BY": true,
"Node.DOCUMENT_POSITION_CONTAINS": true,
"Node.ELEMENT_NODE": true,
"console.error": true,
"console.warn": true,
"document": true,
"getComputedStyle": true,
"setTimeout": true
},
"packages": {
"wait-on>rxjs>tslib": true
}
},
"react-focus-lock>react-clientside-effect": {
"packages": {
"react": true,
"react-focus-lock>react-clientside-effect>@babel/runtime": true
}
},
"react-focus-lock>use-callback-ref": {
"packages": {
"react": true
}
},
"react-focus-lock>use-sidecar": {
"globals": {
"console.error": true
},
"packages": {
"react": true,
"react-focus-lock>use-sidecar>detect-node-es": true,
"wait-on>rxjs>tslib": true
}
},
"react-idle-timer": {
"globals": {
"clearTimeout": true,

View File

@ -4362,6 +4362,64 @@
"setTimeout": true
}
},
"react-focus-lock": {
"globals": {
"addEventListener": true,
"console.error": true,
"console.warn": true,
"document": true,
"removeEventListener": true,
"setTimeout": true
},
"packages": {
"@babel/runtime": true,
"prop-types": true,
"react": true,
"react-focus-lock>focus-lock": true,
"react-focus-lock>react-clientside-effect": true,
"react-focus-lock>use-callback-ref": true,
"react-focus-lock>use-sidecar": true
}
},
"react-focus-lock>focus-lock": {
"globals": {
"HTMLIFrameElement": true,
"Node.DOCUMENT_FRAGMENT_NODE": true,
"Node.DOCUMENT_NODE": true,
"Node.DOCUMENT_POSITION_CONTAINED_BY": true,
"Node.DOCUMENT_POSITION_CONTAINS": true,
"Node.ELEMENT_NODE": true,
"console.error": true,
"console.warn": true,
"document": true,
"getComputedStyle": true,
"setTimeout": true
},
"packages": {
"wait-on>rxjs>tslib": true
}
},
"react-focus-lock>react-clientside-effect": {
"packages": {
"react": true,
"react-focus-lock>react-clientside-effect>@babel/runtime": true
}
},
"react-focus-lock>use-callback-ref": {
"packages": {
"react": true
}
},
"react-focus-lock>use-sidecar": {
"globals": {
"console.error": true
},
"packages": {
"react": true,
"react-focus-lock>use-sidecar>detect-node-es": true,
"wait-on>rxjs>tslib": true
}
},
"react-idle-timer": {
"globals": {
"clearTimeout": true,

View File

@ -4362,6 +4362,64 @@
"setTimeout": true
}
},
"react-focus-lock": {
"globals": {
"addEventListener": true,
"console.error": true,
"console.warn": true,
"document": true,
"removeEventListener": true,
"setTimeout": true
},
"packages": {
"@babel/runtime": true,
"prop-types": true,
"react": true,
"react-focus-lock>focus-lock": true,
"react-focus-lock>react-clientside-effect": true,
"react-focus-lock>use-callback-ref": true,
"react-focus-lock>use-sidecar": true
}
},
"react-focus-lock>focus-lock": {
"globals": {
"HTMLIFrameElement": true,
"Node.DOCUMENT_FRAGMENT_NODE": true,
"Node.DOCUMENT_NODE": true,
"Node.DOCUMENT_POSITION_CONTAINED_BY": true,
"Node.DOCUMENT_POSITION_CONTAINS": true,
"Node.ELEMENT_NODE": true,
"console.error": true,
"console.warn": true,
"document": true,
"getComputedStyle": true,
"setTimeout": true
},
"packages": {
"wait-on>rxjs>tslib": true
}
},
"react-focus-lock>react-clientside-effect": {
"packages": {
"react": true,
"react-focus-lock>react-clientside-effect>@babel/runtime": true
}
},
"react-focus-lock>use-callback-ref": {
"packages": {
"react": true
}
},
"react-focus-lock>use-sidecar": {
"globals": {
"console.error": true
},
"packages": {
"react": true,
"react-focus-lock>use-sidecar>detect-node-es": true,
"wait-on>rxjs>tslib": true
}
},
"react-idle-timer": {
"globals": {
"clearTimeout": true,

View File

@ -3910,6 +3910,64 @@
"setTimeout": true
}
},
"react-focus-lock": {
"globals": {
"addEventListener": true,
"console.error": true,
"console.warn": true,
"document": true,
"removeEventListener": true,
"setTimeout": true
},
"packages": {
"@babel/runtime": true,
"prop-types": true,
"react": true,
"react-focus-lock>focus-lock": true,
"react-focus-lock>react-clientside-effect": true,
"react-focus-lock>use-callback-ref": true,
"react-focus-lock>use-sidecar": true
}
},
"react-focus-lock>focus-lock": {
"globals": {
"HTMLIFrameElement": true,
"Node.DOCUMENT_FRAGMENT_NODE": true,
"Node.DOCUMENT_NODE": true,
"Node.DOCUMENT_POSITION_CONTAINED_BY": true,
"Node.DOCUMENT_POSITION_CONTAINS": true,
"Node.ELEMENT_NODE": true,
"console.error": true,
"console.warn": true,
"document": true,
"getComputedStyle": true,
"setTimeout": true
},
"packages": {
"wait-on>rxjs>tslib": true
}
},
"react-focus-lock>react-clientside-effect": {
"packages": {
"react": true,
"react-focus-lock>react-clientside-effect>@babel/runtime": true
}
},
"react-focus-lock>use-callback-ref": {
"packages": {
"react": true
}
},
"react-focus-lock>use-sidecar": {
"globals": {
"console.error": true
},
"packages": {
"react": true,
"react-focus-lock>use-sidecar>detect-node-es": true,
"wait-on>rxjs>tslib": true
}
},
"react-idle-timer": {
"globals": {
"clearTimeout": true,

View File

@ -7362,7 +7362,7 @@
},
"stylelint>postcss-html>htmlparser2>domutils>dom-serializer": {
"packages": {
"stylelint>postcss-html>htmlparser2>domutils>dom-serializer>domelementtype": true,
"stylelint>postcss-html>htmlparser2>domelementtype": true,
"stylelint>postcss-html>htmlparser2>entities": true
}
},

View File

@ -345,6 +345,7 @@
"qrcode.react": "^1.0.1",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-focus-lock": "^2.9.4",
"react-idle-timer": "^4.2.5",
"react-inspector": "^2.3.0",
"react-markdown": "^6.0.3",

View File

@ -34,6 +34,7 @@ export { TextField, TEXT_FIELD_TYPES, TEXT_FIELD_SIZES } from './text-field';
export { TextFieldSearch } from './text-field-search';
export { ModalContent, ModalContentSize } from './modal-content';
export { ModalOverlay } from './modal-overlay';
export { ModalFocus } from './modal-focus';
// Molecules
export { BannerBase } from './banner-base';

View File

@ -0,0 +1,248 @@
import { Story, Canvas, ArgsTable } from '@storybook/addon-docs';
import { ModalFocus } from './modal-focus';
# ModalFocus
`ModalFocus` traps the focus within the modal. This greatly improves the experience for screen readers and keyboard only users.
<Canvas>
<Story id="components-componentlibrary-modalfocus--default-story" />
</Canvas>
## Props
The `ModalFocus` is built with [react-focus-lock](https://github.com/theKashey/react-focus-lock) and accepts all of the props from that library.
<ArgsTable of={ModalFocus} />
### Children
Use the `children` prop to render the component to lock focus to
<Canvas>
<Story id="components-componentlibrary-modalfocus--children" />
</Canvas>
```jsx
import React from 'react';
import {
BorderColor,
DISPLAY,
FLEX_DIRECTION,
} from '../../../helpers/constants/design-system';
import Box from '../../ui/box';
import { ModalFocus } from '../../component-library';
const [open, setOpen] = React.useState(false);
<button onClick={() => setOpen(true)} marginBottom={4}>
Open
</button>;
{
open && (
<ModalFocus>
<Box
padding={4}
borderColor={BorderColor.borderDefault}
display={DISPLAY.FLEX}
flexDirection={FLEX_DIRECTION.COLUMN}
gap={4}
>
<p>Modal focus children</p>
<input />
<p>
Use the keyboard to try tabbing around you will notice that the focus
is locked to the content within modal focus
</p>
<button onClick={() => setOpen(false)}>Close</button>
</Box>
</ModalFocus>
);
}
```
### Initial Focus Ref
Use the `initialFocusRef` to pass the `ref` of the element to receive focus initially
<Canvas>
<Story id="components-componentlibrary-modalfocus--initial-focus-ref" />
</Canvas>
```jsx
import React from 'react';
import {
BorderColor,
DISPLAY,
FLEX_DIRECTION,
} from '../../../helpers/constants/design-system';
import Box from '../../ui/box';
import { ModalFocus } from '../../component-library';
const [open, setOpen] = React.useState(false);
const ref = React.useRef < HTMLButtonElement > null;
<button onClick={() => setOpen(true)} marginBottom={4}>
Open
</button>;
{
open && (
<ModalFocus initialFocusRef={ref}>
<Box
padding={4}
borderColor={BorderColor.borderDefault}
display={DISPLAY.FLEX}
flexDirection={FLEX_DIRECTION.COLUMN}
gap={4}
>
<input />
<p>Initial focus is on the close button</p>
<button ref={ref} onClick={() => setOpen(false)}>
Close
</button>
</Box>
</ModalFocus>
);
}
```
### Final Focus Ref
Use the `finalFocusRef` to pass the `ref` of the element to return focus to when `ModalFocus` unmounts
<Canvas>
<Story id="components-componentlibrary-modalfocus--final-focus-ref" />
</Canvas>
```jsx
import React from 'react';
import {
BorderColor,
DISPLAY,
FLEX_DIRECTION,
} from '../../../helpers/constants/design-system';
import Box from '../../ui/box';
import { ModalFocus } from '../../component-library';
const [open, setOpen] = React.useState(false);
const ref = React.useRef < HTMLInputElement > null;
<button onClick={() => setOpen(true)} marginBottom={4}>
Open
</button>;
<input placeholder="Focus will return here" ref={ref} />;
{
open && (
<ModalFocus finalFocusRef={ref}>
<Box
padding={4}
borderColor={BorderColor.borderDefault}
display={DISPLAY.FLEX}
flexDirection={FLEX_DIRECTION.COLUMN}
gap={4}
>
<p>Focus will be returned to the input once closed</p>
<button onClick={() => setOpen(false)}>Close</button>
</Box>
</ModalFocus>
);
}
```
### Restore Focus
Use the `restoreFocus` to restore focus to the element that triggered the `ModalFocus` once it unmounts
<Canvas>
<Story id="components-componentlibrary-modalfocus--restore-focus" />
</Canvas>
```jsx
import React from 'react';
import {
BorderColor,
DISPLAY,
FLEX_DIRECTION,
} from '../../../helpers/constants/design-system';
import Box from '../../ui/box';
import { ModalFocus } from '../../component-library';
const [open, setOpen] = React.useState(false);
<button onClick={() => setOpen(true)} marginBottom={4}>
Open
</button>;
{
open && (
<ModalFocus restoreFocus>
<Box
padding={4}
borderColor={BorderColor.borderDefault}
display={DISPLAY.FLEX}
flexDirection={FLEX_DIRECTION.COLUMN}
gap={4}
>
<p>Focus will be restored to the open button once closed</p>
<button onClick={() => setOpen(false)}>Close</button>
</Box>
</ModalFocus>
);
}
```
### Auto Focus
Use the `autoFocus` to auto focus to the first focusable element within the `ModalFocus` once it mounts
Defaults to `true`
<Canvas>
<Story id="components-componentlibrary-modalfocus--auto-focus" />
</Canvas>
```jsx
import React from 'react';
import {
BorderColor,
DISPLAY,
FLEX_DIRECTION,
} from '../../../helpers/constants/design-system';
import Box from '../../ui/box';
import { ModalFocus } from '../../component-library';
const [open, setOpen] = React.useState(false);
<button onClick={() => setOpen(true)} marginBottom={4}>
Open
</button>;
{
open && (
<ModalFocus autoFocus={false}>
<Box
padding={4}
borderColor={BorderColor.borderDefault}
display={DISPLAY.FLEX}
flexDirection={FLEX_DIRECTION.COLUMN}
gap={4}
>
<p>auto focus set to false</p>
<button onClick={() => setOpen(false)}>Close</button>
</Box>
</ModalFocus>
);
}
```

View File

@ -0,0 +1,2 @@
export { ModalFocus } from './modal-focus';
export type { ModalFocusProps } from './modal-focus.types';

View File

@ -0,0 +1,158 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import Box from '../../ui/box';
import {
BorderColor,
DISPLAY,
FLEX_DIRECTION,
} from '../../../helpers/constants/design-system';
import { ModalFocus } from './modal-focus';
import README from './README.mdx';
export default {
title: 'Components/ComponentLibrary/ModalFocus',
component: ModalFocus,
parameters: {
docs: {
page: README,
},
},
args: {
children: (
<>
<p>Modal focus children</p>
<input />
<p>
Use the keyboard to try tabbing around you will notice that the focus
is locked to the content within modal focus
</p>
</>
),
},
} as ComponentMeta<typeof ModalFocus>;
const Template: ComponentStory<typeof ModalFocus> = (args) => {
const [open, setOpen] = React.useState(false);
return (
<>
<button onClick={() => setOpen(true)}>Open</button>
{open && (
<ModalFocus {...args}>
<Box
padding={4}
borderColor={BorderColor.borderDefault}
display={DISPLAY.FLEX}
flexDirection={FLEX_DIRECTION.COLUMN}
gap={4}
>
{args.children}
<button onClick={() => setOpen(false)}>Close</button>
</Box>
</ModalFocus>
)}
</>
);
};
export const DefaultStory = Template.bind({});
DefaultStory.storyName = 'Default';
export const Children = Template.bind({});
Children.args = {
children: (
<>
<p>Modal focus children</p>
</>
),
};
export const InitialFocusRef = (args) => {
const ref = React.useRef<HTMLButtonElement>(null);
const [open, setOpen] = React.useState(false);
return (
<>
<button onClick={() => setOpen(true)}>Open</button>
{open && (
<ModalFocus {...args} initialFocusRef={ref}>
<Box
padding={4}
borderColor={BorderColor.borderDefault}
display={DISPLAY.FLEX}
flexDirection={FLEX_DIRECTION.COLUMN}
gap={4}
>
<input />
{args.children}
<button ref={ref} onClick={() => setOpen(false)}>
Close
</button>
</Box>
</ModalFocus>
)}
</>
);
};
InitialFocusRef.args = {
children: <p>Initial focus is on the close button</p>,
};
export const FinalFocusRef = (args) => {
const ref = React.useRef<HTMLInputElement>(null);
const [open, setOpen] = React.useState(false);
return (
<>
<Box display={DISPLAY.FLEX} gap={4}>
<button onClick={() => setOpen(true)}>Open</button>
<input placeholder="Focus will return here" ref={ref} />
</Box>
{open && (
<ModalFocus {...args} finalFocusRef={ref}>
<Box
padding={4}
borderColor={BorderColor.borderDefault}
display={DISPLAY.FLEX}
flexDirection={FLEX_DIRECTION.COLUMN}
gap={4}
>
<p>Focus will be returned to the input once closed</p>
<button onClick={() => setOpen(false)}>Close</button>
</Box>
</ModalFocus>
)}
</>
);
};
export const RestoreFocus = (args) => {
const ref = React.useRef<HTMLButtonElement>(null);
const [open, setOpen] = React.useState(false);
return (
<>
<button ref={ref} onClick={() => setOpen(!open)}>
Open
</button>
{open && (
<ModalFocus {...args} restoreFocus>
<Box
padding={4}
borderColor={BorderColor.borderDefault}
display={DISPLAY.FLEX}
flexDirection={FLEX_DIRECTION.COLUMN}
gap={4}
>
<p>Focus will be restored to the open button once closed</p>
<button onClick={() => setOpen(false)}>Close</button>
</Box>
</ModalFocus>
)}
</>
);
};
export const AutoFocus = Template.bind({});
AutoFocus.args = {
autoFocus: false,
children: <p>auto focus set to false</p>,
};

View File

@ -0,0 +1,61 @@
/* eslint-disable jest/require-top-level-describe */
import { render } from '@testing-library/react';
import React from 'react';
import { ModalFocus } from './modal-focus';
describe('ModalFocus', () => {
it('should render with children inside the ModalFocus', () => {
const { getByText } = render(
<ModalFocus>
<div>modal focus</div>
</ModalFocus>,
);
expect(getByText('modal focus')).toBeDefined();
});
it('should render with the initial element focused', () => {
const { getByTestId } = render(
<ModalFocus>
<input data-testid="input" />
</ModalFocus>,
);
expect(getByTestId('input')).toHaveFocus();
});
it('should render with focused with autoFocus is set to false', () => {
const { getByTestId } = render(
<ModalFocus autoFocus={false}>
<input data-testid="input" />
</ModalFocus>,
);
expect(getByTestId('input')).not.toHaveFocus();
});
it('should focus initialFocusRef on render', () => {
const ref: React.RefObject<HTMLInputElement> = React.createRef();
const { getByTestId } = render(
<ModalFocus initialFocusRef={ref}>
<input />
<input />
<input data-testid="input" ref={ref} />
</ModalFocus>,
);
expect(getByTestId('input')).toHaveFocus();
});
it('should focus final focus ref when closed', () => {
const finalRef: React.RefObject<HTMLButtonElement> = React.createRef();
const { rerender, getByRole } = render(
<>
<button ref={finalRef}>button</button>
<ModalFocus finalFocusRef={finalRef}>
<div>modal focus</div>
</ModalFocus>
</>,
);
expect(finalRef.current).not.toHaveFocus();
rerender(<button ref={finalRef}>button</button>);
expect(getByRole('button')).toHaveFocus();
});
});

View File

@ -0,0 +1,46 @@
import React, { useCallback } from 'react';
import ReactFocusLock from 'react-focus-lock';
import type { ModalFocusProps } from './modal-focus.types';
/**
* Based on the ModalFocusScope component from chakra-ui
* https://github.com/chakra-ui/chakra-ui/blob/main/packages/components/modal/src/modal-focus.tsx
*/
const FocusTrap: typeof ReactFocusLock =
(ReactFocusLock as any).default ?? ReactFocusLock;
export const ModalFocus: React.FC<ModalFocusProps> = ({
initialFocusRef,
finalFocusRef,
restoreFocus,
children,
autoFocus,
...props
}) => {
const onActivation = useCallback(() => {
if (initialFocusRef?.current) {
initialFocusRef.current.focus();
}
}, [initialFocusRef]);
const onDeactivation = useCallback(() => {
finalFocusRef?.current?.focus();
}, [finalFocusRef]);
const returnFocus = restoreFocus && !finalFocusRef;
return (
<FocusTrap
autoFocus={autoFocus}
onActivation={onActivation}
onDeactivation={onDeactivation}
returnFocus={returnFocus}
{...props}
>
{children}
</FocusTrap>
);
};
ModalFocus.displayName = 'ModalFocus';

View File

@ -0,0 +1,35 @@
import React from 'react';
export interface FocusableElement {
focus(options?: FocusOptions): void;
}
export interface ModalFocusProps {
/**
* The `ref` of the element to receive focus initially
*/
initialFocusRef?: React.RefObject<FocusableElement>;
/**
* The `ref` of the element to return focus to when `ModalFocus`
* unmounts
*/
finalFocusRef?: React.RefObject<FocusableElement>;
/**
* If `true`, focus will be restored to the element that
* triggered the `ModalFocus` once it unmounts
*
* @default false
*/
restoreFocus?: boolean;
/**
* The node to lock focus to
*/
children: React.ReactNode;
/**
* If `true`, the first focusable element within the `children`
* will auto-focused once `ModalFocus` mounts
*
* @default false
*/
autoFocus?: boolean;
}

View File

@ -1627,6 +1627,15 @@ __metadata:
languageName: node
linkType: hard
"@babel/runtime@npm:^7.12.13":
version: 7.21.0
resolution: "@babel/runtime@npm:7.21.0"
dependencies:
regenerator-runtime: ^0.13.11
checksum: 7b33e25bfa9e0e1b9e8828bb61b2d32bdd46b41b07ba7cb43319ad08efc6fda8eb89445193e67d6541814627df0ca59122c0ea795e412b99c5183a0540d338ab
languageName: node
linkType: hard
"@babel/runtime@patch:@babel/runtime@npm%3A7.18.9#./.yarn/patches/@babel-runtime-npm-7.18.9-28ca6b5f61.patch::locator=metamask-crx%40workspace%3A.":
version: 7.18.9
resolution: "@babel/runtime@patch:@babel/runtime@npm%3A7.18.9#./.yarn/patches/@babel-runtime-npm-7.18.9-28ca6b5f61.patch::version=7.18.9&hash=918bda&locator=metamask-crx%40workspace%3A."
@ -13947,6 +13956,13 @@ __metadata:
languageName: node
linkType: hard
"detect-node-es@npm:^1.1.0":
version: 1.1.0
resolution: "detect-node-es@npm:1.1.0"
checksum: e46307d7264644975b71c104b9f028ed1d3d34b83a15b8a22373640ce5ea630e5640b1078b8ea15f202b54641da71e4aa7597093bd4b91f113db520a26a37449
languageName: node
linkType: hard
"detect-node@npm:^2.0.4":
version: 2.0.4
resolution: "detect-node@npm:2.0.4"
@ -17201,6 +17217,15 @@ __metadata:
languageName: node
linkType: hard
"focus-lock@npm:^0.11.6":
version: 0.11.6
resolution: "focus-lock@npm:0.11.6"
dependencies:
tslib: ^2.0.3
checksum: 6a407c4c45f05f8258f92565541fc5f8043f576643a7603eb999e1a790173e08712056766ed034ccd31c6d6deed259dea558002712fa5ef2432fc6930b9c7a05
languageName: node
linkType: hard
"follow-redirects@npm:^1.14.0, follow-redirects@npm:^1.14.9, follow-redirects@npm:^1.15.0":
version: 1.15.2
resolution: "follow-redirects@npm:1.15.2"
@ -24282,6 +24307,7 @@ __metadata:
react: ^16.12.0
react-devtools: ^4.11.0
react-dom: ^16.12.0
react-focus-lock: ^2.9.4
react-idle-timer: ^4.2.5
react-inspector: ^2.3.0
react-markdown: ^6.0.3
@ -28298,6 +28324,17 @@ __metadata:
languageName: node
linkType: hard
"react-clientside-effect@npm:^1.2.6":
version: 1.2.6
resolution: "react-clientside-effect@npm:1.2.6"
dependencies:
"@babel/runtime": ^7.12.13
peerDependencies:
react: ^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
checksum: 7db6110027a51458b1a46109d2b63dd822825f483c71afef7c0c0a671f3b1aa155049dbd8651c9d536ffac83601f8823b7c3f8916b4f4ee5c3cb7647a85cce4e
languageName: node
linkType: hard
"react-colorful@npm:^5.1.2":
version: 5.3.0
resolution: "react-colorful@npm:5.3.0"
@ -28416,6 +28453,26 @@ __metadata:
languageName: node
linkType: hard
"react-focus-lock@npm:^2.9.4":
version: 2.9.4
resolution: "react-focus-lock@npm:2.9.4"
dependencies:
"@babel/runtime": ^7.0.0
focus-lock: ^0.11.6
prop-types: ^15.6.2
react-clientside-effect: ^1.2.6
use-callback-ref: ^1.3.0
use-sidecar: ^1.1.2
peerDependencies:
"@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0
react: ^16.8.0 || ^17.0.0 || ^18.0.0
peerDependenciesMeta:
"@types/react":
optional: true
checksum: f4c696bdbde5008560388622b994c00502d1faeeabff32b02964770c8c020208872f5f6b914b249a8bf3e97cc12e58bb0d227cd33460093654156b7b7f4c8d76
languageName: node
linkType: hard
"react-idle-timer@npm:^4.2.5":
version: 4.2.5
resolution: "react-idle-timer@npm:4.2.5"
@ -29058,7 +29115,7 @@ __metadata:
languageName: node
linkType: hard
"regenerator-runtime@npm:^0.13.9":
"regenerator-runtime@npm:^0.13.11, regenerator-runtime@npm:^0.13.9":
version: 0.13.11
resolution: "regenerator-runtime@npm:0.13.11"
checksum: 27481628d22a1c4e3ff551096a683b424242a216fee44685467307f14d58020af1e19660bf2e26064de946bad7eff28950eae9f8209d55723e2d9351e632bbb4
@ -33779,6 +33836,37 @@ __metadata:
languageName: node
linkType: hard
"use-callback-ref@npm:^1.3.0":
version: 1.3.0
resolution: "use-callback-ref@npm:1.3.0"
dependencies:
tslib: ^2.0.0
peerDependencies:
"@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0
react: ^16.8.0 || ^17.0.0 || ^18.0.0
peerDependenciesMeta:
"@types/react":
optional: true
checksum: 7913df383a5a6fcb399212eedefaac2e0c6f843555202d4e3010bac3848afe38ecaa3d0d6500ad1d936fbeffd637e6c517e68edb024af5e6beca7f27f3ce7b21
languageName: node
linkType: hard
"use-sidecar@npm:^1.1.2":
version: 1.1.2
resolution: "use-sidecar@npm:1.1.2"
dependencies:
detect-node-es: ^1.1.0
tslib: ^2.0.0
peerDependencies:
"@types/react": ^16.9.0 || ^17.0.0 || ^18.0.0
react: ^16.8.0 || ^17.0.0 || ^18.0.0
peerDependenciesMeta:
"@types/react":
optional: true
checksum: 925d1922f9853e516eaad526b6fed1be38008073067274f0ecc3f56b17bb8ab63480140dd7c271f94150027c996cea4efe83d3e3525e8f3eda22055f6a39220b
languageName: node
linkType: hard
"use@npm:^3.1.0":
version: 3.1.0
resolution: "use@npm:3.1.0"