From a1ae2357db8d63f3086d89c3f6c1d369e0bafe62 Mon Sep 17 00:00:00 2001 From: Henrik Larsson Date: Wed, 3 May 2023 10:20:25 +0200 Subject: [PATCH] Iterated with translations --- app/[locale]/[[...slug]]/page.tsx | 13 +- components/ui/dropdown/dropdown.tsx | 191 ++++++++++++ components/ui/locale-switcher.tsx | 30 -- components/ui/locale-switcher/I18nWidget.tsx | 142 +++++++++ components/ui/locale-switcher/index.ts | 1 + .../ui/locale-switcher/locale-switcher.tsx | 63 ++++ package.json | 2 + pnpm-lock.yaml | 286 ++++++++++++++++++ 8 files changed, 695 insertions(+), 33 deletions(-) create mode 100644 components/ui/dropdown/dropdown.tsx delete mode 100644 components/ui/locale-switcher.tsx create mode 100644 components/ui/locale-switcher/I18nWidget.tsx create mode 100644 components/ui/locale-switcher/index.ts create mode 100644 components/ui/locale-switcher/locale-switcher.tsx diff --git a/app/[locale]/[[...slug]]/page.tsx b/app/[locale]/[[...slug]]/page.tsx index 733fbffc4..0eb490984 100644 --- a/app/[locale]/[[...slug]]/page.tsx +++ b/app/[locale]/[[...slug]]/page.tsx @@ -1,15 +1,22 @@ 'use client'; -import LocaleSwitcher from 'components/ui/locale-switcher'; +import LocaleSwitcher from 'components/ui/locale-switcher/locale-switcher'; import { useTranslations } from 'next-intl'; + +interface PageProps { + params: { + locale: string + } +} -export default function Index() { +export default function Index({params: {locale}} : PageProps) { + const t = useTranslations('Index'); return (

{t('title')}

- +
) } \ No newline at end of file diff --git a/components/ui/dropdown/dropdown.tsx b/components/ui/dropdown/dropdown.tsx new file mode 100644 index 000000000..76032d320 --- /dev/null +++ b/components/ui/dropdown/dropdown.tsx @@ -0,0 +1,191 @@ +import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu' +import { CheckIcon, ChevronRightIcon, CircleIcon } from '@radix-ui/react-icons' +import * as React from 'react' + +import { cn } from 'lib/utils' + +const DropdownMenu = DropdownMenuPrimitive.Root + +const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger + +const DropdownMenuGroup = DropdownMenuPrimitive.Group + +const DropdownMenuPortal = DropdownMenuPrimitive.Portal + +const DropdownMenuSub = DropdownMenuPrimitive.Sub + +const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup + +const DropdownMenuSubTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, children, ...props }, ref) => ( + + {children} + + +)) +DropdownMenuSubTrigger.displayName = + DropdownMenuPrimitive.SubTrigger.displayName + +const DropdownMenuSubContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSubContent.displayName = + DropdownMenuPrimitive.SubContent.displayName + +const DropdownMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, sideOffset = 4, ...props }, ref) => ( + + + +)) +DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName + +const DropdownMenuItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName + +const DropdownMenuCheckboxItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, checked, ...props }, ref) => ( + + + + + + + {children} + +)) +DropdownMenuCheckboxItem.displayName = + DropdownMenuPrimitive.CheckboxItem.displayName + +const DropdownMenuRadioItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {children} + +)) +DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName + +const DropdownMenuLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName + +const DropdownMenuSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName + +const DropdownMenuShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ) +} +DropdownMenuShortcut.displayName = 'DropdownMenuShortcut' + +export { + DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, + DropdownMenuShortcut, DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, DropdownMenuTrigger +} + diff --git a/components/ui/locale-switcher.tsx b/components/ui/locale-switcher.tsx deleted file mode 100644 index 830a01289..000000000 --- a/components/ui/locale-switcher.tsx +++ /dev/null @@ -1,30 +0,0 @@ -'use client' - -import Link from 'next/link' -import { usePathname } from 'next/navigation' -import { i18n } from '../../i18n-config' - -export default function LocaleSwitcher() { - const pathName = usePathname() - const redirectedPathName = (locale: string) => { - if (!pathName) return '/' - const segments = pathName.split('/') - segments[1] = locale - return segments.join('/') - } - - return ( -
-

Locale switcher:

-
    - {i18n.locales.map((locale) => { - return ( -
  • - {locale} -
  • - ) - })} -
-
- ) -} \ No newline at end of file diff --git a/components/ui/locale-switcher/I18nWidget.tsx b/components/ui/locale-switcher/I18nWidget.tsx new file mode 100644 index 000000000..beae0ecac --- /dev/null +++ b/components/ui/locale-switcher/I18nWidget.tsx @@ -0,0 +1,142 @@ +import { useState } from 'react' +import { useRouter } from 'next/router' +import Link from 'next/link' +import Image from 'next/image' +import { cn } from '@lib/utils' + +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from '@components/ui/Dropdown/Dropdown' + +interface LOCALE_DATA { + name: string + img: { + filename: string + alt: string + } +} + +const LOCALES_MAP: Record = { + sv: { + name: 'Swedish', + img: { + filename: 'flag-sv.svg', + alt: 'Swedish flag', + }, + }, + nn: { + name: 'Norwegian', + img: { + filename: 'flag-no.svg', + alt: 'Norwegian flag', + }, + }, + en: { + name: 'English', + img: { + filename: 'flag-en.svg', + alt: 'British flag', + }, + }, +} + +interface I18nWidgetProps { + translations: [] | any +} + +const I18nWidget = ({ translations }: I18nWidgetProps) => { + const [isOpen, setIsOpen] = useState(false) + const { locale, locales, defaultLocale = 'sv' } = useRouter() + const router = useRouter() + + const options: any = locales?.filter((val) => val !== locale) + const currentLocale = locale || defaultLocale + + const handleClick = (e: any, locale: string) => { + e.preventDefault() + + const parent = e.target + + if (parent.nodeName !== 'LI') { + return + } + + let href = '/' + + const hasChildLink = parent.querySelector('a').href !== null + + if (hasChildLink) { + href = parent.querySelector('a').href + } + + router.push({ pathname: href }, { pathname: href }, { locale: locale }) + + setIsOpen(false) + } + + return ( + setIsOpen(!isOpen)}> + + + + +
    + {options.map((locale: any) => { + const translationLink = translations?.find( + (item: object | any) => item.locale === locale + ) + + return ( + handleClick(e, locale)} + > +
  • + setIsOpen(false)} + > + + {LOCALES_MAP[locale].img.alt} + + {LOCALES_MAP[locale].name} + +
  • +
    + ) + })} +
+
+
+ ) +} + +export default I18nWidget diff --git a/components/ui/locale-switcher/index.ts b/components/ui/locale-switcher/index.ts new file mode 100644 index 000000000..46525c3d4 --- /dev/null +++ b/components/ui/locale-switcher/index.ts @@ -0,0 +1 @@ +export { default } from './I18nWidget' diff --git a/components/ui/locale-switcher/locale-switcher.tsx b/components/ui/locale-switcher/locale-switcher.tsx new file mode 100644 index 000000000..3966f1a08 --- /dev/null +++ b/components/ui/locale-switcher/locale-switcher.tsx @@ -0,0 +1,63 @@ +'use client' + +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from 'components/ui/dropdown/dropdown' +import Link from 'next/link' +import { usePathname } from 'next/navigation' +import { useState } from 'react' +import { i18n } from '../../../i18n-config' + +interface LocaleSwitcherProps { + currentLocale: string +} + +export default function LocaleSwitcher({currentLocale}: LocaleSwitcherProps) { + const pathName = usePathname() + + const redirectedPathName = (locale: string) => { + if (!pathName) return '/' + const segments = pathName.split('/') + segments[1] = locale + return segments.join('/') + } + + const [isOpen, setIsOpen] = useState(false) + + return ( +
+ + setIsOpen(!isOpen)}> + + + + +
    + {i18n.locales.map((locale) => { + return ( + +
  • + {locale} +
  • +
    + ) + })} +
+
+
+
+ ) +} \ No newline at end of file diff --git a/package.json b/package.json index 55716b77f..af8ce4341 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,8 @@ "@headlessui/react": "^1.7.10", "@next/bundle-analyzer": "^13.3.4", "@portabletext/react": "^3.0.0", + "@radix-ui/react-dropdown-menu": "^2.0.4", + "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-navigation-menu": "^1.1.2", "@sanity/icons": "2", "@sanity/image-url": "^1.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b3aa504d4..350e5a525 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,6 +5,8 @@ specifiers: '@next/bundle-analyzer': ^13.3.4 '@playwright/test': ^1.31.2 '@portabletext/react': ^3.0.0 + '@radix-ui/react-dropdown-menu': ^2.0.4 + '@radix-ui/react-icons': ^1.3.0 '@radix-ui/react-navigation-menu': ^1.1.2 '@sanity/icons': '2' '@sanity/image-url': ^1.0.2 @@ -49,6 +51,8 @@ dependencies: '@headlessui/react': 1.7.14_biqbaboplfbrettd7655fr4n2y '@next/bundle-analyzer': 13.3.4 '@portabletext/react': 3.0.0_react@18.2.0 + '@radix-ui/react-dropdown-menu': 2.0.4_5ndqzdd6t4rivxsukjv3i3ak2q + '@radix-ui/react-icons': 1.3.0_react@18.2.0 '@radix-ui/react-navigation-menu': 1.1.2_biqbaboplfbrettd7655fr4n2y '@sanity/icons': 2.3.1_react@18.2.0 '@sanity/image-url': 1.0.2 @@ -869,16 +873,40 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@floating-ui/core/0.7.3: + resolution: {integrity: sha512-buc8BXHmG9l82+OQXOFU3Kr2XQx9ys01U/Q9HMIrZ300iLc8HLMgh7dcCqgYzAzf4BkoQvDcXf5Y+CuEZ5JBYg==} + dev: false + /@floating-ui/core/1.2.6: resolution: {integrity: sha512-EvYTiXet5XqweYGClEmpu3BoxmsQ4hkj3QaYA6qEnigCWffTP3vNRwBReTdrwDwo7OoJ3wM8Uoe9Uk4n+d4hfg==} dev: false + /@floating-ui/dom/0.5.4: + resolution: {integrity: sha512-419BMceRLq0RrmTSDxn8hf9R3VCJv2K9PUfugh5JyEFmdjzDo+e8U5EdR8nzKq8Yj1htzLm3b6eQEEam3/rrtg==} + dependencies: + '@floating-ui/core': 0.7.3 + dev: false + /@floating-ui/dom/1.2.7: resolution: {integrity: sha512-DyqylONj1ZaBnzj+uBnVfzdjjCkFCL2aA9ESHLyUOGSqb03RpbLMImP1ekIQXYs4KLk9jAjJfZAU8hXfWSahEg==} dependencies: '@floating-ui/core': 1.2.6 dev: false + /@floating-ui/react-dom/0.7.2_5ndqzdd6t4rivxsukjv3i3ak2q: + resolution: {integrity: sha512-1T0sJcpHgX/u4I1OzIEhlcrvkUN8ln39nz7fMoE/2HDHrPiMFoOGR7++GYyfUmIQHkkrTinaeQsO3XWubjSvGg==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/dom': 0.5.4 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + use-isomorphic-layout-effect: 1.1.2_3stiutgnnbnfnf3uowm5cip22i + transitivePeerDependencies: + - '@types/react' + dev: false + /@floating-ui/react-dom/1.1.1_biqbaboplfbrettd7655fr4n2y: resolution: {integrity: sha512-F27E+7SLB5NZvwF9Egqx/PlvxOhMnA6k/yNMQUqaQ9BPZdr4fQgSW6J6AKNIrBQElBT8IRDtv9j6h7FDkgp3dA==} peerDependencies: @@ -1248,6 +1276,18 @@ packages: '@babel/runtime': 7.21.5 dev: false + /@radix-ui/react-arrow/1.0.2_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-fqYwhhI9IarZ0ll2cUSfKuXHlJK0qE4AfnRrPBbRwEH/4mGQn04/QFGomLi8TXWIdv9WJk//KgGm+aDxVIr1wA==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + dependencies: + '@babel/runtime': 7.21.5 + '@radix-ui/react-primitive': 1.0.2_biqbaboplfbrettd7655fr4n2y + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + /@radix-ui/react-collection/1.0.2_biqbaboplfbrettd7655fr4n2y: resolution: {integrity: sha512-s8WdQQ6wNXpaxdZ308KSr8fEWGrg4un8i4r/w7fhiS4ElRNjk5rRcl0/C6TANG2LvLOGIxtzo/jAg6Qf73TEBw==} peerDependencies: @@ -1306,6 +1346,57 @@ packages: react-dom: 18.2.0_react@18.2.0 dev: false + /@radix-ui/react-dropdown-menu/2.0.4_5ndqzdd6t4rivxsukjv3i3ak2q: + resolution: {integrity: sha512-y6AT9+MydyXcByivdK1+QpjWoKaC7MLjkS/cH1Q3keEyMvDkiY85m8o2Bi6+Z1PPUlCsMULopxagQOSfN0wahg==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + dependencies: + '@babel/runtime': 7.21.5 + '@radix-ui/primitive': 1.0.0 + '@radix-ui/react-compose-refs': 1.0.0_react@18.2.0 + '@radix-ui/react-context': 1.0.0_react@18.2.0 + '@radix-ui/react-id': 1.0.0_react@18.2.0 + '@radix-ui/react-menu': 2.0.4_5ndqzdd6t4rivxsukjv3i3ak2q + '@radix-ui/react-primitive': 1.0.2_biqbaboplfbrettd7655fr4n2y + '@radix-ui/react-use-controllable-state': 1.0.0_react@18.2.0 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + transitivePeerDependencies: + - '@types/react' + dev: false + + /@radix-ui/react-focus-guards/1.0.0_react@18.2.0: + resolution: {integrity: sha512-UagjDk4ijOAnGu4WMUPj9ahi7/zJJqNZ9ZAiGPp7waUWJO0O1aWXi/udPphI0IUjvrhBsZJGSN66dR2dsueLWQ==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 + dependencies: + '@babel/runtime': 7.21.5 + react: 18.2.0 + dev: false + + /@radix-ui/react-focus-scope/1.0.2_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-spwXlNTfeIprt+kaEWE/qYuYT3ZAqJiAGjN/JgdvgVDTu8yc+HuX+WOWXrKliKnLnwck0F6JDkqIERncnih+4A==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + dependencies: + '@babel/runtime': 7.21.5 + '@radix-ui/react-compose-refs': 1.0.0_react@18.2.0 + '@radix-ui/react-primitive': 1.0.2_biqbaboplfbrettd7655fr4n2y + '@radix-ui/react-use-callback-ref': 1.0.0_react@18.2.0 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + + /@radix-ui/react-icons/1.3.0_react@18.2.0: + resolution: {integrity: sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==} + peerDependencies: + react: ^16.x || ^17.x || ^18.x + dependencies: + react: 18.2.0 + dev: false + /@radix-ui/react-id/1.0.0_react@18.2.0: resolution: {integrity: sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==} peerDependencies: @@ -1316,6 +1407,37 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-menu/2.0.4_5ndqzdd6t4rivxsukjv3i3ak2q: + resolution: {integrity: sha512-mzKR47tZ1t193trEqlQoJvzY4u9vYfVH16ryBrVrCAGZzkgyWnMQYEZdUkM7y8ak9mrkKtJiqB47TlEnubeOFQ==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + dependencies: + '@babel/runtime': 7.21.5 + '@radix-ui/primitive': 1.0.0 + '@radix-ui/react-collection': 1.0.2_biqbaboplfbrettd7655fr4n2y + '@radix-ui/react-compose-refs': 1.0.0_react@18.2.0 + '@radix-ui/react-context': 1.0.0_react@18.2.0 + '@radix-ui/react-direction': 1.0.0_react@18.2.0 + '@radix-ui/react-dismissable-layer': 1.0.3_biqbaboplfbrettd7655fr4n2y + '@radix-ui/react-focus-guards': 1.0.0_react@18.2.0 + '@radix-ui/react-focus-scope': 1.0.2_biqbaboplfbrettd7655fr4n2y + '@radix-ui/react-id': 1.0.0_react@18.2.0 + '@radix-ui/react-popper': 1.1.1_5ndqzdd6t4rivxsukjv3i3ak2q + '@radix-ui/react-portal': 1.0.2_biqbaboplfbrettd7655fr4n2y + '@radix-ui/react-presence': 1.0.0_biqbaboplfbrettd7655fr4n2y + '@radix-ui/react-primitive': 1.0.2_biqbaboplfbrettd7655fr4n2y + '@radix-ui/react-roving-focus': 1.0.3_biqbaboplfbrettd7655fr4n2y + '@radix-ui/react-slot': 1.0.1_react@18.2.0 + '@radix-ui/react-use-callback-ref': 1.0.0_react@18.2.0 + aria-hidden: 1.2.3 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + react-remove-scroll: 2.5.5_3stiutgnnbnfnf3uowm5cip22i + transitivePeerDependencies: + - '@types/react' + dev: false + /@radix-ui/react-navigation-menu/1.1.2_biqbaboplfbrettd7655fr4n2y: resolution: {integrity: sha512-1fSjOAGTThYSgJ5pENG2V8we7+6KDbfbiyt66HmLTeo0W3PAmmciclm0o97VlcVZW7q5Vg2hN7Cbj4XKo5u2sw==} peerDependencies: @@ -1341,6 +1463,41 @@ packages: react-dom: 18.2.0_react@18.2.0 dev: false + /@radix-ui/react-popper/1.1.1_5ndqzdd6t4rivxsukjv3i3ak2q: + resolution: {integrity: sha512-keYDcdMPNMjSC8zTsZ8wezUMiWM9Yj14wtF3s0PTIs9srnEPC9Kt2Gny1T3T81mmSeyDjZxsD9N5WCwNNb712w==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + dependencies: + '@babel/runtime': 7.21.5 + '@floating-ui/react-dom': 0.7.2_5ndqzdd6t4rivxsukjv3i3ak2q + '@radix-ui/react-arrow': 1.0.2_biqbaboplfbrettd7655fr4n2y + '@radix-ui/react-compose-refs': 1.0.0_react@18.2.0 + '@radix-ui/react-context': 1.0.0_react@18.2.0 + '@radix-ui/react-primitive': 1.0.2_biqbaboplfbrettd7655fr4n2y + '@radix-ui/react-use-callback-ref': 1.0.0_react@18.2.0 + '@radix-ui/react-use-layout-effect': 1.0.0_react@18.2.0 + '@radix-ui/react-use-rect': 1.0.0_react@18.2.0 + '@radix-ui/react-use-size': 1.0.0_react@18.2.0 + '@radix-ui/rect': 1.0.0 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + transitivePeerDependencies: + - '@types/react' + dev: false + + /@radix-ui/react-portal/1.0.2_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-swu32idoCW7KA2VEiUZGBSu9nB6qwGdV6k6HYhUoOo3M1FFpD+VgLzUqtt3mwL1ssz7r2x8MggpLSQach2Xy/Q==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + dependencies: + '@babel/runtime': 7.21.5 + '@radix-ui/react-primitive': 1.0.2_biqbaboplfbrettd7655fr4n2y + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + /@radix-ui/react-presence/1.0.0_biqbaboplfbrettd7655fr4n2y: resolution: {integrity: sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==} peerDependencies: @@ -1366,6 +1523,26 @@ packages: react-dom: 18.2.0_react@18.2.0 dev: false + /@radix-ui/react-roving-focus/1.0.3_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-stjCkIoMe6h+1fWtXlA6cRfikdBzCLp3SnVk7c48cv/uy3DTGoXhN76YaOYUJuy3aEDvDIKwKR5KSmvrtPvQPQ==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + dependencies: + '@babel/runtime': 7.21.5 + '@radix-ui/primitive': 1.0.0 + '@radix-ui/react-collection': 1.0.2_biqbaboplfbrettd7655fr4n2y + '@radix-ui/react-compose-refs': 1.0.0_react@18.2.0 + '@radix-ui/react-context': 1.0.0_react@18.2.0 + '@radix-ui/react-direction': 1.0.0_react@18.2.0 + '@radix-ui/react-id': 1.0.0_react@18.2.0 + '@radix-ui/react-primitive': 1.0.2_biqbaboplfbrettd7655fr4n2y + '@radix-ui/react-use-callback-ref': 1.0.0_react@18.2.0 + '@radix-ui/react-use-controllable-state': 1.0.0_react@18.2.0 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + /@radix-ui/react-slot/1.0.1_react@18.2.0: resolution: {integrity: sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==} peerDependencies: @@ -1423,6 +1600,26 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-use-rect/1.0.0_react@18.2.0: + resolution: {integrity: sha512-TB7pID8NRMEHxb/qQJpvSt3hQU4sqNPM1VCTjTRjEOa7cEop/QMuq8S6fb/5Tsz64kqSvB9WnwsDHtjnrM9qew==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 + dependencies: + '@babel/runtime': 7.21.5 + '@radix-ui/rect': 1.0.0 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-size/1.0.0_react@18.2.0: + resolution: {integrity: sha512-imZ3aYcoYCKhhgNpkNDh/aTiU05qw9hX+HHI1QDBTyIlcFjgeFlKKySNGMwTp7nYFLQg/j0VA2FmCY4WPDDHMg==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 + dependencies: + '@babel/runtime': 7.21.5 + '@radix-ui/react-use-layout-effect': 1.0.0_react@18.2.0 + react: 18.2.0 + dev: false + /@radix-ui/react-visually-hidden/1.0.2_biqbaboplfbrettd7655fr4n2y: resolution: {integrity: sha512-qirnJxtYn73HEk1rXL12/mXnu2rwsNHDID10th2JGtdK25T9wX+mxRmGt7iPSahw512GbZOc0syZX1nLQGoEOg==} peerDependencies: @@ -1435,6 +1632,12 @@ packages: react-dom: 18.2.0_react@18.2.0 dev: false + /@radix-ui/rect/1.0.0: + resolution: {integrity: sha512-d0O68AYy/9oeEy1DdC07bz1/ZXX+DqCskRd3i4JzLSTXwefzaepQrKjXC7aNM8lTHjFLDO0pDgaEiQ7jEk+HVg==} + dependencies: + '@babel/runtime': 7.21.5 + dev: false + /@resvg/resvg-wasm/2.0.0-alpha.4: resolution: {integrity: sha512-pWIG9a/x1ky8gXKRhPH1OPKpHFoMN1ISLbJ+O+gPXQHIAKhNd5I28RlWf7q576hAOQA9JZTlo3p/M2uyLzJmmw==} engines: {node: '>= 10'} @@ -2198,6 +2401,13 @@ packages: /argparse/2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + /aria-hidden/1.2.3: + resolution: {integrity: sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==} + engines: {node: '>=10'} + dependencies: + tslib: 2.5.0 + dev: false + /aria-query/5.1.3: resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} dependencies: @@ -3830,6 +4040,11 @@ packages: - supports-color dev: false + /get-nonce/1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + dev: false + /get-random-values-esm/1.0.0: resolution: {integrity: sha512-BVgZ1PZwR5NKDpHpUcPmWcAQpoIOPXaFy6Vni3UdPbOlxO7eknhxsfytxwss16f75EABfnAC+XZjzTurNlPY/g==} dependencies: @@ -4236,6 +4451,12 @@ packages: p-is-promise: 3.0.0 dev: false + /invariant/2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + dependencies: + loose-envify: 1.4.0 + dev: false + /is-alphabetical/1.0.4: resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} dev: false @@ -5769,6 +5990,41 @@ packages: engines: {node: '>=0.10.0'} dev: false + /react-remove-scroll-bar/2.3.4_3stiutgnnbnfnf3uowm5cip22i: + resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} + engines: {node: '>=10'} + 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 + dependencies: + '@types/react': 18.0.27 + react: 18.2.0 + react-style-singleton: 2.2.1_3stiutgnnbnfnf3uowm5cip22i + tslib: 2.5.0 + dev: false + + /react-remove-scroll/2.5.5_3stiutgnnbnfnf3uowm5cip22i: + resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==} + engines: {node: '>=10'} + 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 + dependencies: + '@types/react': 18.0.27 + react: 18.2.0 + react-remove-scroll-bar: 2.3.4_3stiutgnnbnfnf3uowm5cip22i + react-style-singleton: 2.2.1_3stiutgnnbnfnf3uowm5cip22i + tslib: 2.5.0 + use-callback-ref: 1.3.0_3stiutgnnbnfnf3uowm5cip22i + use-sidecar: 1.1.2_3stiutgnnbnfnf3uowm5cip22i + dev: false + /react-rx/2.1.3_react@18.2.0+rxjs@7.8.0: resolution: {integrity: sha512-4dppkgEFAldr75IUUz14WyxuI2cJhpXYrrIM+4gvG6slKzaMUCmcgiiykx9Hst0UmtwNt247nRoOFDmN0Q7GJw==} peerDependencies: @@ -5781,6 +6037,23 @@ packages: use-sync-external-store: 1.2.0_react@18.2.0 dev: false + /react-style-singleton/2.2.1_3stiutgnnbnfnf3uowm5cip22i: + resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} + engines: {node: '>=10'} + 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 + dependencies: + '@types/react': 18.0.27 + get-nonce: 1.0.1 + invariant: 2.2.4 + react: 18.2.0 + tslib: 2.5.0 + dev: false + /react/18.2.0: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} engines: {node: '>=0.10.0'} @@ -6938,6 +7211,19 @@ packages: react: 18.2.0 dev: false + /use-isomorphic-layout-effect/1.1.2_3stiutgnnbnfnf3uowm5cip22i: + resolution: {integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.0.27 + react: 18.2.0 + dev: false + /use-sidecar/1.1.2_3stiutgnnbnfnf3uowm5cip22i: resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} engines: {node: '>=10'}