From 4a4495e75c001c2357892348f00ba94cfb4beee1 Mon Sep 17 00:00:00 2001 From: Chlenix Date: Thu, 4 Jul 2024 12:27:40 +0200 Subject: [PATCH] feat(Drawer): new Drawer component --- packages/react/package.json | 1 + .../react/src/components/Drawer/Drawer.mdx | 32 ++ .../src/components/Drawer/Drawer.module.css | 118 +++++++ .../src/components/Drawer/Drawer.stories.tsx | 143 +++++++++ .../src/components/Drawer/Drawer.test.tsx | 74 +++++ .../react/src/components/Drawer/Drawer.tsx | 74 +++++ packages/react/src/components/Drawer/index.ts | 2 + yarn.lock | 289 +++++++++++++++++- 8 files changed, 732 insertions(+), 1 deletion(-) create mode 100644 packages/react/src/components/Drawer/Drawer.mdx create mode 100644 packages/react/src/components/Drawer/Drawer.module.css create mode 100644 packages/react/src/components/Drawer/Drawer.stories.tsx create mode 100644 packages/react/src/components/Drawer/Drawer.test.tsx create mode 100644 packages/react/src/components/Drawer/Drawer.tsx create mode 100644 packages/react/src/components/Drawer/index.ts diff --git a/packages/react/package.json b/packages/react/package.json index 5045ad59fc..77fe454ee9 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -29,6 +29,7 @@ "dependencies": { "@floating-ui/react": "0.26.12", "@navikt/aksel-icons": "^5.12.2", + "@radix-ui/react-dialog": "^1.1.1", "@radix-ui/react-slot": "^1.0.2", "@tanstack/react-virtual": "^3.2.0" }, diff --git a/packages/react/src/components/Drawer/Drawer.mdx b/packages/react/src/components/Drawer/Drawer.mdx new file mode 100644 index 0000000000..cf978983aa --- /dev/null +++ b/packages/react/src/components/Drawer/Drawer.mdx @@ -0,0 +1,32 @@ +import { Meta, Canvas, Controls, Primary } from '@storybook/blocks'; + +import * as DrawerStories from './Drawer.stories'; + + + +# Drawer + +Med `Drawer` kan du vise tilleggsinformasjon eller kontroller uten å forlate den nåværende siden. Den er ideell for å presentere sekundært innhold som ikke trenger å være synlig hele tiden. + +**Vær oppmerksom på:** + +- Drawer bør ikke inneholde kritisk informasjon som brukeren må se umiddelbart. +- Innholdet i Drawer bør være fokusert og relevant for den aktuelle konteksten. + +
+ + + + +## Bruk + +```tsx +import { Drawer } from '@digdir/designsystemet-react'; + +Åpne Drawer} + title='Drawer Tittel' +> +

Drawer innhold

+
; +``` diff --git a/packages/react/src/components/Drawer/Drawer.module.css b/packages/react/src/components/Drawer/Drawer.module.css new file mode 100644 index 0000000000..014ac96d87 --- /dev/null +++ b/packages/react/src/components/Drawer/Drawer.module.css @@ -0,0 +1,118 @@ +.overlay { + background-color: rgba(0, 0, 0, 0.5); + position: fixed; + inset: 0; + animation: overlayShow 150ms cubic-bezier(0.16, 1, 0.3, 1); +} + +.content { + background-color: white; + box-shadow: + hsl(206 22% 7% / 35%) 0px 10px 38px -10px, + hsl(206 22% 7% / 20%) 0px 10px 20px -15px; + position: fixed; + top: 0; + bottom: 0; + width: 90%; + max-width: 450px; + padding: 25px; + animation-duration: 150ms; + animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1); +} + +.content:focus { + outline: none; +} + +.right { + right: 0; + animation-name: contentShowRight; +} + +.left { + left: 0; + animation-name: contentShowLeft; +} + +.top { + top: 0; + left: 0; + right: 0; + bottom: auto; + width: 100%; + max-width: 100%; + height: 50%; + max-height: 300px; + animation-name: contentShowTop; +} + +.closeButton { + position: fixed; + right: 0; + margin-right: var(--fds-spacing-4); +} + +.bottom { + top: auto; + bottom: 0; + left: 0; + right: 0; + width: 100%; + max-width: 100%; + height: 50%; + max-height: 300px; + animation-name: contentShowBottom; +} + +@keyframes overlayShow { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +@keyframes contentShowRight { + from { + opacity: 0; + transform: translate3d(100%, 0, 0); + } + to { + opacity: 1; + transform: translate3d(0, 0, 0); + } +} + +@keyframes contentShowLeft { + from { + opacity: 0; + transform: translate3d(-100%, 0, 0); + } + to { + opacity: 1; + transform: translate3d(0, 0, 0); + } +} + +@keyframes contentShowTop { + from { + opacity: 0; + transform: translate3d(0, -100%, 0); + } + to { + opacity: 1; + transform: translate3d(0, 0, 0); + } +} + +@keyframes contentShowBottom { + from { + opacity: 0; + transform: translate3d(0, 100%, 0); + } + to { + opacity: 1; + transform: translate3d(0, 0, 0); + } +} diff --git a/packages/react/src/components/Drawer/Drawer.stories.tsx b/packages/react/src/components/Drawer/Drawer.stories.tsx new file mode 100644 index 0000000000..74ddc306a3 --- /dev/null +++ b/packages/react/src/components/Drawer/Drawer.stories.tsx @@ -0,0 +1,143 @@ +import React, { useRef, useState } from 'react'; +import type { Meta, StoryFn } from '@storybook/react'; + +import { Button } from '../Button'; +import { Textfield } from '../form/Textfield'; +import { Paragraph } from '../Typography'; +import { Divider } from '../Divider'; +import { Combobox } from '..'; + +import { Drawer, type DrawerRef } from './Drawer'; + +export default { + title: 'Komponenter/Drawer', + component: Drawer, +} as Meta; + +export const Preview: StoryFn = (args) => { + const drawerRef = useRef(null); + + return ( + <> + + +

Drawer Content

+ + Lorem ipsum dolor sit, amet consectetur adipisicing elit. Blanditiis + doloremque obcaecati assumenda odio ducimus sunt et. + +
+ + ); +}; + +export const WithBuiltInTrigger: StoryFn = (args) => { + return ( + Open Drawer} + {...args} + > +

Drawer with Built-in Trigger

+ This drawer uses the built-in trigger prop. +
+ ); +}; + +export const DifferentPositions: StoryFn = () => { + const drawerRef = useRef(null); + const [position, setPosition] = useState<'left' | 'right' | 'top' | 'bottom'>( + 'right', + ); + + return ( + <> + + + +

Drawer from {position}

+ This drawer opens from the {position}. +
+ + ); +}; + +export const DrawerWithForm: StoryFn = () => { + const drawerRef = useRef(null); + const [input, setInput] = useState(''); + + return ( + <> + + +

Drawer with Form

+ setInput(e.target.value)} + /> + +
+ + ); +}; + +export const DrawerWithDivider: StoryFn = () => ( + Open Drawer with Divider}> +

Drawer with Divider

+ + Content between dividers + +
+); + +export const DrawerWithSelect: StoryFn = () => { + const drawerRef = useRef(null); + + return ( + <> + + +

Drawer with Select

+ + No results found + Oslo + Bergen + Trondheim + Stavanger + +
+ + ); +}; diff --git a/packages/react/src/components/Drawer/Drawer.test.tsx b/packages/react/src/components/Drawer/Drawer.test.tsx new file mode 100644 index 0000000000..6888c30227 --- /dev/null +++ b/packages/react/src/components/Drawer/Drawer.test.tsx @@ -0,0 +1,74 @@ +import { act, render as renderRtl, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { Drawer, DrawerProps } from './Drawer'; + +const TRIGGER_TEXT = 'Open Drawer'; +const DRAWER_CONTENT = 'Drawer Content'; +const DRAWER_TITLE = 'Drawer Title'; + +const TestComponent = (props: Partial) => ( + {TRIGGER_TEXT}} + {...props} + > + {DRAWER_CONTENT} + +); + +const render = async (props: Partial = {}) => { + await act(async () => {}); + const user = userEvent.setup(); + return { + user, + ...renderRtl(), + }; +}; + +describe('Drawer', () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('should render the trigger', async () => { + await render(); + expect(screen.getByText(TRIGGER_TEXT)).toBeInTheDocument(); + }); + + it('should open the drawer', async () => { + const { user } = await render(); + const trigger = screen.getByText(TRIGGER_TEXT); + await user.click(trigger); + expect(screen.getByText(DRAWER_CONTENT)).toBeInTheDocument(); + }); + + it('should close the drawer', async () => { + const { user } = await render(); + const trigger = screen.getByText(TRIGGER_TEXT); + await user.click(trigger); + const closeButton = screen.getByRole('button', { name: /close/i }); + await user.click(closeButton); + expect(screen.queryByText(DRAWER_CONTENT)).not.toBeInTheDocument(); + }); + + it('should use custom aria-label for close button', async () => { + const customLabel = 'Custom Close Label'; + await render({ arialabelCloseDrawer: customLabel }); + const trigger = screen.getByText(TRIGGER_TEXT); + await userEvent.click(trigger); + expect(screen.getByLabelText(customLabel)).toBeInTheDocument(); + }); + + it('should not render trigger when not provided', async () => { + await render({ trigger: undefined }); + expect(screen.queryByText(TRIGGER_TEXT)).not.toBeInTheDocument(); + }); + + it('should autofocus on close button when opened', async () => { + const { user } = await render(); + const trigger = screen.getByText(TRIGGER_TEXT); + await user.click(trigger); + + const closeButton = screen.getByRole('button', { name: /close/i }); + expect(closeButton).toHaveFocus(); + }); +}); diff --git a/packages/react/src/components/Drawer/Drawer.tsx b/packages/react/src/components/Drawer/Drawer.tsx new file mode 100644 index 0000000000..b18a6a6a3a --- /dev/null +++ b/packages/react/src/components/Drawer/Drawer.tsx @@ -0,0 +1,74 @@ +import React, { type HTMLAttributes } from 'react'; +import * as Dialog from '@radix-ui/react-dialog'; +import { XMarkIcon } from '@navikt/aksel-icons'; +import styles from './Drawer.module.css'; +import { Button } from '../Button'; + +export type DrawerProps = { + position?: 'top' | 'bottom' | 'left' | 'right'; + trigger?: React.ReactNode; + arialabelCloseDrawer?: string; +} & HTMLAttributes; + +export type DrawerRef = { + open: () => void; + close: () => void; + contentRef: React.RefObject; +}; + +export const Drawer = React.forwardRef( + ( + { children, position = 'right', trigger, arialabelCloseDrawer, ...rest }, + ref, + ) => { + const [isOpen, setIsOpen] = React.useState(false); + const contentRef = React.useRef(null); + + React.useImperativeHandle(ref, () => ({ + open: () => setIsOpen(true), + close: () => setIsOpen(false), + contentRef, + })); + + return ( + + {trigger && {trigger}} + + + { + event.preventDefault(); + contentRef.current?.focus(); + }} + {...rest} + > + + {children} + + + + ); + }, +); + +Drawer.displayName = 'Drawer'; diff --git a/packages/react/src/components/Drawer/index.ts b/packages/react/src/components/Drawer/index.ts new file mode 100644 index 0000000000..d61d81e8df --- /dev/null +++ b/packages/react/src/components/Drawer/index.ts @@ -0,0 +1,2 @@ +export { Drawer } from './Drawer'; +export type { DrawerProps, DrawerRef } from './Drawer'; diff --git a/yarn.lock b/yarn.lock index 89927772b8..854b4a0f38 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2000,6 +2000,7 @@ __metadata: dependencies: "@floating-ui/react": "npm:0.26.12" "@navikt/aksel-icons": "npm:^5.12.2" + "@radix-ui/react-dialog": "npm:^1.1.1" "@radix-ui/react-slot": "npm:^1.0.2" "@tanstack/react-virtual": "npm:^3.2.0" copyfiles: "npm:^2.4.1" @@ -3747,6 +3748,13 @@ __metadata: languageName: node linkType: hard +"@radix-ui/primitive@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/primitive@npm:1.1.0" + checksum: 10/7cbf70bfd4b2200972dbd52a9366801b5a43dd844743dc97eb673b3ec8e64f5dd547538faaf9939abbfe8bb275773767ecf5a87295d90ba09c15cba2b5528c89 + languageName: node + linkType: hard + "@radix-ui/react-compose-refs@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-compose-refs@npm:1.0.1" @@ -3762,6 +3770,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-compose-refs@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-compose-refs@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/047a4ed5f87cb848be475507cd62836cf5af5761484681f521ea543ea7c9d59d61d42806d6208863d5e2380bf38cdf4cff73c2bbe5f52dbbe50fb04e1a13ac72 + languageName: node + linkType: hard + "@radix-ui/react-context@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-context@npm:1.0.1" @@ -3777,6 +3798,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-context@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-context@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/755aea1966dc9b778890e6d330482e9285e9cd9417425da364706cf1d43a041f0b5b2412e6dfebb81e35f68ce47304dd52bcda01f223685c287ac654e6142d7e + languageName: node + linkType: hard + "@radix-ui/react-dialog@npm:^1.0.5": version: 1.0.5 resolution: "@radix-ui/react-dialog@npm:1.0.5" @@ -3810,6 +3844,38 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-dialog@npm:^1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-dialog@npm:1.1.1" + dependencies: + "@radix-ui/primitive": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-context": "npm:1.1.0" + "@radix-ui/react-dismissable-layer": "npm:1.1.0" + "@radix-ui/react-focus-guards": "npm:1.1.0" + "@radix-ui/react-focus-scope": "npm:1.1.0" + "@radix-ui/react-id": "npm:1.1.0" + "@radix-ui/react-portal": "npm:1.1.1" + "@radix-ui/react-presence": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-slot": "npm:1.1.0" + "@radix-ui/react-use-controllable-state": "npm:1.1.0" + aria-hidden: "npm:^1.1.1" + react-remove-scroll: "npm:2.5.7" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/8c4b4af680e306db4fe113e9e19eb173f633b40b267030906167f6f62adfaa02aa2cb8ee97775ad0c701242a5ef6d0ce3528e1b13e640cbc6ea356eb27836189 + languageName: node + linkType: hard + "@radix-ui/react-dismissable-layer@npm:1.0.5": version: 1.0.5 resolution: "@radix-ui/react-dismissable-layer@npm:1.0.5" @@ -3834,6 +3900,29 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-dismissable-layer@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-dismissable-layer@npm:1.1.0" + dependencies: + "@radix-ui/primitive": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + "@radix-ui/react-use-escape-keydown": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/08baf3441f811ce88649fa90cf8031f496f81a404cda75fa2a7b42020e3368f8f2a96911a4a1f7065cfa3fb2c091156c009d9255f81feeaf2f7ffadcfd12caf1 + languageName: node + linkType: hard + "@radix-ui/react-focus-guards@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-focus-guards@npm:1.0.1" @@ -3849,6 +3938,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-focus-guards@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-focus-guards@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/199717e7da1ba9b3fa74b04f6a245aaebf6bdb8ae7d6f4b5f21f95f4086414a3587beebc77399a99be7d3a4b2499eaa52bf72bef660f8e69856b0fd0593b074f + languageName: node + linkType: hard + "@radix-ui/react-focus-scope@npm:1.0.4": version: 1.0.4 resolution: "@radix-ui/react-focus-scope@npm:1.0.4" @@ -3871,6 +3973,27 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-focus-scope@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-focus-scope@npm:1.1.0" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/a34dc5caecc56483e293de770fde3addcebd975b94625cb7057bee3f0837d82bba9a672bef7c7902d28d68d31ab9b3847c88285664b5b747ac9141dabf11df3c + languageName: node + linkType: hard + "@radix-ui/react-id@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-id@npm:1.0.1" @@ -3887,6 +4010,21 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-id@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-id@npm:1.1.0" + dependencies: + "@radix-ui/react-use-layout-effect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/6fbc9d1739b3b082412da10359e63967b4f3a60383ebda4c9e56b07a722d29bee53b203b3b1418f88854a29315a7715867133bb149e6e22a027a048cdd20d970 + languageName: node + linkType: hard + "@radix-ui/react-portal@npm:1.0.4": version: 1.0.4 resolution: "@radix-ui/react-portal@npm:1.0.4" @@ -3907,6 +4045,26 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-portal@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-portal@npm:1.1.1" + dependencies: + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-layout-effect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/84dab64ce9c9f4ed7d75df6d1d82877dc7976a98cc192287d39ba2ea512415ed7bf34caf02d579a18fe21766403fa9ae41d2482a14dee5514179ee1b09cc333c + languageName: node + linkType: hard + "@radix-ui/react-presence@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-presence@npm:1.0.1" @@ -3928,6 +4086,26 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-presence@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-presence@npm:1.1.0" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-use-layout-effect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/e3ce746560e1551c9c480f0ef1f085763faf7094ac9600ca15d8bacb1bf5c70e59effe889bd2116b56c798f69f8d2bfa32d14defd30b9381fb2dcc555367f11c + languageName: node + linkType: hard + "@radix-ui/react-primitive@npm:1.0.3": version: 1.0.3 resolution: "@radix-ui/react-primitive@npm:1.0.3" @@ -3948,6 +4126,25 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-primitive@npm:2.0.0": + version: 2.0.0 + resolution: "@radix-ui/react-primitive@npm:2.0.0" + dependencies: + "@radix-ui/react-slot": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10/f3dc683f5ba6534739356ac78ba5008d237b2f0e97eb3d578fcb01ecdb869a0729c24adc6dec238bfb1074763629935724381451313c109ca1be2a60fe4c16e3 + languageName: node + linkType: hard + "@radix-ui/react-slot@npm:1.0.2, @radix-ui/react-slot@npm:^1.0.2": version: 1.0.2 resolution: "@radix-ui/react-slot@npm:1.0.2" @@ -3964,6 +4161,21 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-slot@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-slot@npm:1.1.0" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/95e190868418b1c83adf6627256f6b664b0dcbea95d7215de9c64ac2c31102fc09155565d9ca27be6abd20fc63d0b0bacfe1b67d78b2de1d198244c848e1a54e + languageName: node + linkType: hard + "@radix-ui/react-use-callback-ref@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-use-callback-ref@npm:1.0.1" @@ -3979,6 +4191,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-use-callback-ref@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-callback-ref@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/2ec7903c67e3034b646005556f44fd975dc5204db6885fc58403e3584f27d95f0b573bc161de3d14fab9fda25150bf3b91f718d299fdfc701c736bd0bd2281fa + languageName: node + linkType: hard + "@radix-ui/react-use-controllable-state@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-use-controllable-state@npm:1.0.1" @@ -3995,6 +4220,21 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-use-controllable-state@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-controllable-state@npm:1.1.0" + dependencies: + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/9583679150dc521c9de20ee22cb858697dd4f5cefc46ab8ebfc5e7511415a053994e87d4ca3f49de84d27eebc13535b0a6c9892c91ab43e3e553e5d7270f378f + languageName: node + linkType: hard + "@radix-ui/react-use-escape-keydown@npm:1.0.3": version: 1.0.3 resolution: "@radix-ui/react-use-escape-keydown@npm:1.0.3" @@ -4011,6 +4251,21 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-use-escape-keydown@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-escape-keydown@npm:1.1.0" + dependencies: + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/9bf88ea272b32ea0f292afd336780a59c5646f795036b7e6105df2d224d73c54399ee5265f61d571eb545d28382491a8b02dc436e3088de8dae415d58b959b71 + languageName: node + linkType: hard + "@radix-ui/react-use-layout-effect@npm:1.0.1": version: 1.0.1 resolution: "@radix-ui/react-use-layout-effect@npm:1.0.1" @@ -4026,6 +4281,19 @@ __metadata: languageName: node linkType: hard +"@radix-ui/react-use-layout-effect@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-layout-effect@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/271ea0bf1cd74718895a68414a6e95537737f36e02ad08eeb61a82b229d6abda9cff3135a479e134e1f0ce2c3ff97bb85babbdce751985fb755a39b231d7ccf2 + languageName: node + linkType: hard + "@react-aria/ssr@npm:^3.5.0": version: 3.9.3 resolution: "@react-aria/ssr@npm:3.9.3" @@ -18409,7 +18677,7 @@ __metadata: languageName: node linkType: hard -"react-remove-scroll-bar@npm:^2.3.3": +"react-remove-scroll-bar@npm:^2.3.3, react-remove-scroll-bar@npm:^2.3.4": version: 2.3.6 resolution: "react-remove-scroll-bar@npm:2.3.6" dependencies: @@ -18444,6 +18712,25 @@ __metadata: languageName: node linkType: hard +"react-remove-scroll@npm:2.5.7": + version: 2.5.7 + resolution: "react-remove-scroll@npm:2.5.7" + dependencies: + react-remove-scroll-bar: "npm:^2.3.4" + react-style-singleton: "npm:^2.2.1" + tslib: "npm:^2.1.0" + use-callback-ref: "npm:^1.3.0" + use-sidecar: "npm:^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: 10/a1285d118e734855be6a1cf6c83a2ee39d8c5a5c3c336a1e9b80ab571326669bf39a52607f1889337c559c18b9e5fd5a0772fa82f748de3fcfe114ee6f772cc6 + languageName: node + linkType: hard + "react-smooth@npm:^4.0.0": version: 4.0.1 resolution: "react-smooth@npm:4.0.1"