diff --git a/apps/client/package.json b/apps/client/package.json index c2a3999a6..1db8353e7 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -4,6 +4,7 @@ "private": true, "type": "module", "dependencies": { + "@base-ui-components/react": "1.0.0-beta.0", "@chakra-ui/react": "^2.7.0", "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", diff --git a/apps/client/src/common/components/buttons/Button.module.scss b/apps/client/src/common/components/buttons/Button.module.scss index d8f2d8cf3..f3547a105 100644 --- a/apps/client/src/common/components/buttons/Button.module.scss +++ b/apps/client/src/common/components/buttons/Button.module.scss @@ -57,5 +57,9 @@ } .large { - height: 3.5rem; + height: 2.5rem; +} + +.xlarge { + height: 3rem; } diff --git a/apps/client/src/common/components/buttons/Button.tsx b/apps/client/src/common/components/buttons/Button.tsx index 9a09a1889..5858ea9a2 100644 --- a/apps/client/src/common/components/buttons/Button.tsx +++ b/apps/client/src/common/components/buttons/Button.tsx @@ -6,7 +6,7 @@ import style from './Button.module.scss'; interface ButtonProps extends ButtonHTMLAttributes { variant?: 'subtle' | 'primary'; - size?: 'medium' | 'large'; + size?: 'medium' | 'large' | 'xlarge'; } export default function Button(props: ButtonProps) { diff --git a/apps/client/src/common/components/buttons/IconButton.module.scss b/apps/client/src/common/components/buttons/IconButton.module.scss index 5b86bb8dc..dcfb8031a 100644 --- a/apps/client/src/common/components/buttons/IconButton.module.scss +++ b/apps/client/src/common/components/buttons/IconButton.module.scss @@ -2,8 +2,6 @@ .baseIconButton { aspect-ratio: 1; - height: 2rem; - width: 2rem; display: grid; place-content: center; @@ -65,3 +63,18 @@ border-color: $red-900; } } + +.medium { + height: 2rem; + width: 2rem; +} + +.large { + height: 2.5rem; + width: 2.5rem; +} + +.xlarge { + height: 3rem; + height: 3rem; +} diff --git a/apps/client/src/common/components/buttons/IconButton.tsx b/apps/client/src/common/components/buttons/IconButton.tsx index 57f9f3ad1..f02534d02 100644 --- a/apps/client/src/common/components/buttons/IconButton.tsx +++ b/apps/client/src/common/components/buttons/IconButton.tsx @@ -6,13 +6,18 @@ import style from './IconButton.module.scss'; interface IconButtonProps extends ButtonHTMLAttributes { variant?: 'subtle' | 'subtle-white' | 'destructive'; + size?: 'medium' | 'large' | 'xlarge'; } export default function IconButton(props: IconButtonProps) { - const { className, children, variant = 'subtle', ...buttonProps } = props; + const { className, children, variant = 'subtle', size = 'medium', ...buttonProps } = props; return ( - ); diff --git a/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx b/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx index a10fed16f..4490c5a81 100644 --- a/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx +++ b/apps/client/src/common/components/navigation-menu/ViewNavigationMenu.tsx @@ -11,15 +11,31 @@ interface ViewNavigationMenuProps { isLockable?: boolean; } -function ViewNavigationMenu(props: ViewNavigationMenuProps) { - const { isLockable } = props; - +export default memo(ViewNavigationMenu); +function ViewNavigationMenu({ isLockable }: ViewNavigationMenuProps) { const { isOpen: isMenuOpen, onOpen: onMenuOpen, onClose: onMenuClose } = useDisclosure(); const { showEditFormDrawer, isViewLocked } = useViewEditor({ isLockable }); const toggleMenu = () => (isMenuOpen ? onMenuClose() : onMenuOpen()); - useHotkeys([['mod + ,', () => toggleMenu()]]); + useHotkeys([ + [ + 'Space', + () => { + if (isViewLocked) return; + toggleMenu(); + }, + { preventDefault: true }, + ], + [ + 'mod + ,', + () => { + if (isViewLocked) return; + showEditFormDrawer(); + }, + { preventDefault: true }, + ], + ]); if (isViewLocked) { return ; @@ -32,5 +48,3 @@ function ViewNavigationMenu(props: ViewNavigationMenuProps) { ); } - -export default memo(ViewNavigationMenu); diff --git a/apps/client/src/common/components/view-params-editor/ViewParamsEditor.module.scss b/apps/client/src/common/components/view-params-editor/ViewParamsEditor.module.scss index 1f6ff63a9..614e0c71b 100644 --- a/apps/client/src/common/components/view-params-editor/ViewParamsEditor.module.scss +++ b/apps/client/src/common/components/view-params-editor/ViewParamsEditor.module.scss @@ -8,12 +8,81 @@ } } +.backdrop { + position: fixed; + inset: 0; + z-index: 10; + background-color: rgba(0, 0, 0, 0.7); + transition: opacity 300ms cubic-bezier(0.45, 1.005, 0, 1.005); + + &[data-starting-style], + &[data-ending-style] { + opacity: 0; + } +} + +.drawer { + box-sizing: border-box; + position: fixed; + top: 0; + right: 0; + bottom: 0; + z-index: 11; + + width: 40rem; + height: 100vh; + + display: flex; + flex-direction: column; + padding: 1rem 1.5rem; + + background-color: $gray-1250; + color: $ui-white; + + &[data-open] { + transform: translateX(0%); + transition: transform 300ms cubic-bezier(0.45, 1.005, 0, 1.005); + } + + &[data-starting-style], + &[data-ending-style] { + transform: translateX(100%); + transition: transform 500ms cubic-bezier(0.45, 1.005, 0, 1.005); + } + + // take the whole screen in mobile devices + @media (max-width: $min-tablet) { + width: 100vw; + } +} + +.header { + display: flex; + align-items: center; + justify-content: space-between; + height: 3.5rem; + + font-weight: 600; + font-size: 1.25rem; +} + +.body { + flex: 1; + padding-bottom: 10vh; + overflow-y: scroll; +} + +.footer { + display: flex; + gap: 1rem; + align-items: center; + justify-content: flex-end; +} + .sectionList { display: flex; flex-direction: column; - min-height: 100%; gap: 2rem; - overflow-y: scroll; padding-right: 0.5rem; } diff --git a/apps/client/src/common/components/view-params-editor/ViewParamsEditor.tsx b/apps/client/src/common/components/view-params-editor/ViewParamsEditor.tsx index d30da2fef..4a37c9ad0 100644 --- a/apps/client/src/common/components/view-params-editor/ViewParamsEditor.tsx +++ b/apps/client/src/common/components/view-params-editor/ViewParamsEditor.tsx @@ -1,18 +1,12 @@ import { FormEvent, memo, useEffect } from 'react'; +import { IoClose } from 'react-icons/io5'; import { useSearchParams } from 'react-router-dom'; -import { - Button, - Drawer, - DrawerBody, - DrawerCloseButton, - DrawerContent, - DrawerFooter, - DrawerHeader, - DrawerOverlay, - useDisclosure, -} from '@chakra-ui/react'; +import { Dialog } from '@base-ui-components/react/dialog'; +import { useDisclosure } from '@mantine/hooks'; import useViewSettings from '../../hooks-query/useViewSettings'; +import Button from '../buttons/Button'; +import IconButton from '../buttons/IconButton'; import Info from '../info/Info'; import { ViewOption } from './viewParams.types'; @@ -31,27 +25,27 @@ function ViewParamsEditor({ viewOptions }: EditFormDrawerProps) { const [searchParams, setSearchParams] = useSearchParams(); const { data: viewSettings } = useViewSettings(); - const { isOpen, onClose, onOpen } = useDisclosure(); + const [isOpen, handlers] = useDisclosure(false); // handle opening the drawer useEffect(() => { const isEditing = searchParams.get('edit'); if (isEditing === 'true') { - return onOpen(); + return handlers.open(); } - }, [searchParams, onOpen]); + }, [searchParams, handlers]); const handleClose = () => { searchParams.delete('edit'); setSearchParams(searchParams); - onClose(); + handlers.close(); }; const resetParams = () => { setSearchParams(); - onClose(); + handlers.close(); }; const onParamsFormSubmit = (formEvent: FormEvent) => { @@ -63,39 +57,48 @@ function ViewParamsEditor({ viewOptions }: EditFormDrawerProps) { }; return ( - - - - - - Customise - - - - {viewSettings.overrideStyles && ( - This view style is being modified by a custom CSS file. - )} -
- {viewOptions.map((section) => ( - - ))} - -
- - - - - -
-
+ { + if (!open) { + handleClose(); + } + }} + > + + + +
+ Customise + + + +
+
+ {viewSettings.overrideStyles && ( + This view style is being modified by a custom CSS file. + )} +
+ {viewOptions.map((section) => ( + + ))} + +
+
+ + +
+
+
+
); } diff --git a/apps/client/src/views/countdown/Countdown.tsx b/apps/client/src/views/countdown/Countdown.tsx index 4e7db1170..10af1ea61 100644 --- a/apps/client/src/views/countdown/Countdown.tsx +++ b/apps/client/src/views/countdown/Countdown.tsx @@ -114,7 +114,7 @@ function CountdownContents({ playableEvents, selectedId, subscriptions, time, go return (
-
@@ -127,7 +127,7 @@ function CountdownContents({ playableEvents, selectedId, subscriptions, time, go return (
-
diff --git a/apps/client/src/views/countdown/CountdownSelect.tsx b/apps/client/src/views/countdown/CountdownSelect.tsx index 192d80fb9..194fcd4e9 100644 --- a/apps/client/src/views/countdown/CountdownSelect.tsx +++ b/apps/client/src/views/countdown/CountdownSelect.tsx @@ -83,13 +83,13 @@ export default function CountdownSelect({ events, subscriptions, disableEdit }: })}
- - -
diff --git a/apps/client/src/views/countdown/CountdownSubscriptions.tsx b/apps/client/src/views/countdown/CountdownSubscriptions.tsx index 4b4fe74cf..5d411eb14 100644 --- a/apps/client/src/views/countdown/CountdownSubscriptions.tsx +++ b/apps/client/src/views/countdown/CountdownSubscriptions.tsx @@ -113,7 +113,7 @@ export default function CountdownSubscriptions({ ); })}
-
diff --git a/e2e/tests/002-view-navigation.spec.ts b/e2e/tests/002-view-navigation.spec.ts index b93f83330..20e918d84 100644 --- a/e2e/tests/002-view-navigation.spec.ts +++ b/e2e/tests/002-view-navigation.spec.ts @@ -3,34 +3,34 @@ import { expect, type Page, test } from '@playwright/test'; test.describe('test view navigation feature', () => { test.beforeEach(async ({ page }) => { await page.goto('http://localhost:4001/'); - page.locator('data-test-id=timer-view'); + await expect(page.locator('data-testid=timer-view')).toBeVisible(); }); test('Minimal', async ({ page }) => { await openNavigationMenu(page); await page.getByRole('link', { name: 'Minimal Timer' }).click(); - page.locator('data-test-id=minimal-timer'); + await expect(page.locator('data-testid=minimal-timer')).toBeVisible(); await expect(page).toHaveURL('http://localhost:4001/minimal'); }); test('Wall Clock', async ({ page }) => { await openNavigationMenu(page); await page.getByRole('link', { name: 'Wall Clock', exact: true }).click(); - page.locator('data-test-id=clock-view'); + await expect(page.locator('data-testid=clock-view')).toBeVisible(); await expect(page).toHaveURL('http://localhost:4001/clock'); }); test('Timeline', async ({ page }) => { await openNavigationMenu(page); await page.getByRole('link', { name: 'Timeline' }).click(); - page.locator('data-test-id=timeline-view'); + page.locator('data-testid=timeline-view'); await expect(page).toHaveURL('http://localhost:4001/timeline'); }); test('Backstage', async ({ page }) => { await openNavigationMenu(page); await page.getByRole('link', { name: 'Backstage' }).click(); - page.locator('data-test-id=backstage-view'); + page.locator('data-testid=backstage-view'); await expect(page).toHaveURL('http://localhost:4001/backstage'); }); @@ -38,39 +38,39 @@ test.describe('test view navigation feature', () => { await openNavigationMenu(page); await page.getByRole('link', { name: 'Lower Thirds' }).click(); await expect(page).toHaveURL('http://localhost:4001/lower'); - const errorBoundary = page.locator('data-test-id=error-container'); + const errorBoundary = page.locator('data-testid=error-container'); await expect(errorBoundary).toHaveCount(0); }); test('Studio Clock', async ({ page }) => { await openNavigationMenu(page); await page.getByRole('link', { name: 'Studio Clock' }).click(); - page.locator('data-test-id=studio-view'); + page.locator('data-testid=studio-view'); await expect(page).toHaveURL('http://localhost:4001/studio'); }); test('Countdown', async ({ page }) => { await openNavigationMenu(page); await page.getByRole('link', { name: 'Countdown' }).click(); - page.locator('data-test-id=countdown-view'); + page.locator('data-testid=countdown-view'); await expect(page).toHaveURL('http://localhost:4001/countdown'); }); test('Project Info', async ({ page }) => { await openNavigationMenu(page); await page.getByRole('link', { name: 'Project Info' }).click(); - page.locator('data-test-id=project-view'); + page.locator('data-testid=project-view'); await expect(page).toHaveURL('http://localhost:4001/info'); }); test('Timer', async ({ page }) => { await openNavigationMenu(page); await page.getByRole('link', { name: 'Timer', exact: true }).click(); - page.locator('data-test-id=timer-view'); + page.locator('data-testid=timer-view'); await expect(page).toHaveURL('http://localhost:4001/timer'); }); }); async function openNavigationMenu(page: Page) { - await page.keyboard.press('ControlOrMeta + ,'); + await page.keyboard.press('Space'); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 634b1c35f..2a217c56e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -86,6 +86,9 @@ importers: apps/client: dependencies: + '@base-ui-components/react': + specifier: 1.0.0-beta.0 + version: 1.0.0-beta.0(@types/react@18.0.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@chakra-ui/react': specifier: ^2.7.0 version: 2.7.0(@emotion/react@11.10.6(@types/react@18.0.26)(react@18.3.1))(@emotion/styled@11.10.6(@emotion/react@11.10.6(@types/react@18.0.26)(react@18.3.1))(@types/react@18.0.26)(react@18.3.1))(@types/react@18.0.26)(framer-motion@10.11.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -178,7 +181,7 @@ importers: version: 3.1.1 zustand: specifier: ^5.0.3 - version: 5.0.3(@types/react@18.0.26)(react@18.3.1)(use-sync-external-store@1.2.0(react@18.3.1)) + version: 5.0.3(@types/react@18.0.26)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)) devDependencies: '@sentry/vite-plugin': specifier: ^2.16.1 @@ -299,7 +302,7 @@ importers: version: 2.8.5 dotenv: specifier: ^16.0.1 - version: 16.3.1 + version: 16.5.0 express: specifier: 5.1.0 version: 5.1.0 @@ -618,6 +621,10 @@ packages: resolution: {integrity: sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==} engines: {node: '>=6.9.0'} + '@babel/runtime@7.27.6': + resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} + engines: {node: '>=6.9.0'} + '@babel/template@7.22.15': resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} engines: {node: '>=6.9.0'} @@ -642,6 +649,17 @@ packages: resolution: {integrity: sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw==} engines: {node: '>=6.9.0'} + '@base-ui-components/react@1.0.0-beta.0': + resolution: {integrity: sha512-lPw5/40g/TbpSG1e1g4drl10kaSY2VBOFFQ9axmGhwPGqrQmTuW42jcUq/7OPdXQAyMakfWMWLSXyk3NXbRk+Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@types/react': ^17 || ^18 || ^19 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + peerDependenciesMeta: + '@types/react': + optional: true + '@chakra-ui/accordion@2.2.0': resolution: {integrity: sha512-2IK1iLzTZ22u8GKPPPn65mqJdZidn4AvkgAbv17ISdKA07VHJ8jSd4QF1T5iCXjKfZ0XaXozmhP4kDhjwF2IbQ==} peerDependencies: @@ -1704,6 +1722,27 @@ packages: resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@floating-ui/core@1.7.1': + resolution: {integrity: sha512-azI0DrjMMfIug/ExbBaeDVJXcY0a7EPvPjb2xAJPa4HeimBX+Z18HK8QQR3jb6356SnDDdxx+hinMLcJEDdOjw==} + + '@floating-ui/dom@1.7.1': + resolution: {integrity: sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ==} + + '@floating-ui/react-dom@2.1.3': + resolution: {integrity: sha512-huMBfiU9UnQ2oBwIhgzyIiSpVgvlDstU8CX0AF+wS+KzmYMs0J2a3GwuFHV1Lz+jlrQGeC1fF+Nv0QoumyV0bA==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/react@0.27.12': + resolution: {integrity: sha512-kKlWNrpIQxF1B/a2MZvE0/uyKby4960yjO91W7nVyNKmmfNi62xU9HCjL1M1eWzx/LFj/VPSwJVbwQk9Pq/68A==} + peerDependencies: + react: '>=17.0.0' + react-dom: '>=17.0.0' + + '@floating-ui/utils@0.2.9': + resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + '@fontsource/open-sans@5.0.28': resolution: {integrity: sha512-hBvJHY76pJT/JynGUB5EXWhnzjYfLdcMn655J5p1v9lTT9HdQSy+keq2KPVXO2Htlg998BBa3p6u/jlrZ6w0kg==} @@ -3108,10 +3147,6 @@ packages: dotenv-expand@5.1.0: resolution: {integrity: sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==} - dotenv@16.3.1: - resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} - engines: {node: '>=12'} - dotenv@16.5.0: resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} engines: {node: '>=12'} @@ -5114,6 +5149,9 @@ packages: resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} engines: {node: ^14.18.0 || >=16.0.0} + tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + tar-mini@0.2.0: resolution: {integrity: sha512-+qfUHz700DWnRutdUsxRRVZ38G1Qr27OetwaMYTdg8hcPxf46U0S1Zf76dQMWRBmusOt2ZCK5kbIaiLkoGO7WQ==} @@ -5391,10 +5429,10 @@ packages: '@types/react': optional: true - use-sync-external-store@1.2.0: - resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + use-sync-external-store@1.5.0: + resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 utf8-byte-length@1.0.4: resolution: {integrity: sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==} @@ -5873,6 +5911,8 @@ snapshots: dependencies: regenerator-runtime: 0.14.1 + '@babel/runtime@7.27.6': {} + '@babel/template@7.22.15': dependencies: '@babel/code-frame': 7.24.2 @@ -5923,6 +5963,17 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@base-ui-components/react@1.0.0-beta.0(@types/react@18.0.26)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.27.6 + '@floating-ui/react': 0.27.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@floating-ui/utils': 0.2.9 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + use-sync-external-store: 1.5.0(react@18.3.1) + optionalDependencies: + '@types/react': 18.0.26 + '@chakra-ui/accordion@2.2.0(@chakra-ui/system@2.5.8(@emotion/react@11.10.6(@types/react@18.0.26)(react@18.3.1))(@emotion/styled@11.10.6(@emotion/react@11.10.6(@types/react@18.0.26)(react@18.3.1))(@types/react@18.0.26)(react@18.3.1))(react@18.3.1))(framer-motion@10.11.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: '@chakra-ui/descendant': 3.0.14(react@18.3.1) @@ -7101,6 +7152,31 @@ snapshots: '@eslint/js@8.56.0': {} + '@floating-ui/core@1.7.1': + dependencies: + '@floating-ui/utils': 0.2.9 + + '@floating-ui/dom@1.7.1': + dependencies: + '@floating-ui/core': 1.7.1 + '@floating-ui/utils': 0.2.9 + + '@floating-ui/react-dom@2.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/dom': 1.7.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@floating-ui/react@0.27.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/react-dom': 2.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@floating-ui/utils': 0.2.9 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tabbable: 6.2.0 + + '@floating-ui/utils@0.2.9': {} + '@fontsource/open-sans@5.0.28': {} '@gar/promisify@1.1.3': {} @@ -7338,7 +7414,7 @@ snapshots: '@babel/core': 7.23.6 '@sentry/babel-plugin-component-annotate': 2.16.1 '@sentry/cli': 2.23.0(encoding@0.1.13) - dotenv: 16.3.1 + dotenv: 16.5.0 find-up: 5.0.0 glob: 9.3.2 magic-string: 0.30.8 @@ -8721,8 +8797,6 @@ snapshots: dotenv-expand@5.1.0: {} - dotenv@16.3.1: {} - dotenv@16.5.0: {} dotenv@9.0.2: {} @@ -11014,6 +11088,8 @@ snapshots: '@pkgr/core': 0.1.1 tslib: 2.6.2 + tabbable@6.2.0: {} + tar-mini@0.2.0: {} tar-stream@2.2.0: @@ -11270,10 +11346,9 @@ snapshots: optionalDependencies: '@types/react': 18.0.26 - use-sync-external-store@1.2.0(react@18.3.1): + use-sync-external-store@1.5.0(react@18.3.1): dependencies: react: 18.3.1 - optional: true utf8-byte-length@1.0.4: {} @@ -11547,8 +11622,8 @@ snapshots: compress-commons: 4.1.2 readable-stream: 3.6.2 - zustand@5.0.3(@types/react@18.0.26)(react@18.3.1)(use-sync-external-store@1.2.0(react@18.3.1)): + zustand@5.0.3(@types/react@18.0.26)(react@18.3.1)(use-sync-external-store@1.5.0(react@18.3.1)): optionalDependencies: '@types/react': 18.0.26 react: 18.3.1 - use-sync-external-store: 1.2.0(react@18.3.1) + use-sync-external-store: 1.5.0(react@18.3.1)