From e4da6ba7358a88d98434be1524c6cfad1fc782be Mon Sep 17 00:00:00 2001 From: Teczer Date: Wed, 26 Nov 2025 11:37:43 +0100 Subject: [PATCH 1/4] :sparkles: :lipstick: feat(ui): integrate Radix UI components for drawer and select functionality; add loading spinner and mobile user list drawer --- apps/web/components/ui/drawer.tsx | 118 +++++++++ apps/web/components/ui/select.tsx | 161 +++++++++++++ .../connection-status.component.tsx | 9 +- .../components/flash-button.component.tsx | 2 +- .../components/game-controls.component.tsx | 4 +- .../game/components/item-toggle.component.tsx | 2 +- .../components/loading-spinner.component.tsx | 37 +++ .../mobile-user-list-drawer.component.tsx | 56 +++++ .../components/mobile-user-list.component.tsx | 34 +++ .../components/summoner-input.component.tsx | 64 +++-- .../timer-control-button.component.tsx | 2 +- .../game/components/user-list.component.tsx | 2 +- .../game/screens/game-multiplayer.screen.tsx | 15 +- apps/web/package.json | 2 + pnpm-lock.yaml | 227 +++++++++++++++++- 15 files changed, 683 insertions(+), 52 deletions(-) create mode 100644 apps/web/components/ui/drawer.tsx create mode 100644 apps/web/components/ui/select.tsx create mode 100644 apps/web/features/game/components/loading-spinner.component.tsx create mode 100644 apps/web/features/game/components/mobile-user-list-drawer.component.tsx create mode 100644 apps/web/features/game/components/mobile-user-list.component.tsx diff --git a/apps/web/components/ui/drawer.tsx b/apps/web/components/ui/drawer.tsx new file mode 100644 index 0000000..6a0ef53 --- /dev/null +++ b/apps/web/components/ui/drawer.tsx @@ -0,0 +1,118 @@ +"use client" + +import * as React from "react" +import { Drawer as DrawerPrimitive } from "vaul" + +import { cn } from "@/lib/utils" + +const Drawer = ({ + shouldScaleBackground = true, + ...props +}: React.ComponentProps) => ( + +) +Drawer.displayName = "Drawer" + +const DrawerTrigger = DrawerPrimitive.Trigger + +const DrawerPortal = DrawerPrimitive.Portal + +const DrawerClose = DrawerPrimitive.Close + +const DrawerOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName + +const DrawerContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + +
+ {children} + + +)) +DrawerContent.displayName = "DrawerContent" + +const DrawerHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DrawerHeader.displayName = "DrawerHeader" + +const DrawerFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DrawerFooter.displayName = "DrawerFooter" + +const DrawerTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DrawerTitle.displayName = DrawerPrimitive.Title.displayName + +const DrawerDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DrawerDescription.displayName = DrawerPrimitive.Description.displayName + +export { + Drawer, + DrawerPortal, + DrawerOverlay, + DrawerTrigger, + DrawerClose, + DrawerContent, + DrawerHeader, + DrawerFooter, + DrawerTitle, + DrawerDescription, +} diff --git a/apps/web/components/ui/select.tsx b/apps/web/components/ui/select.tsx new file mode 100644 index 0000000..6014d78 --- /dev/null +++ b/apps/web/components/ui/select.tsx @@ -0,0 +1,161 @@ +"use client" + +import * as React from "react" +import * as SelectPrimitive from "@radix-ui/react-select" +import { FaCheck } from "react-icons/fa" +import { HiChevronDown, HiChevronUp } from "react-icons/hi" + +import { cn } from "@/lib/utils" + +const Select = SelectPrimitive.Root + +const SelectGroup = SelectPrimitive.Group + +const SelectValue = SelectPrimitive.Value + +const SelectTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + span]:line-clamp-1", + className + )} + {...props} + > + {children} + + + + +)) +SelectTrigger.displayName = SelectPrimitive.Trigger.displayName + +const SelectScrollUpButton = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName + +const SelectScrollDownButton = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +SelectScrollDownButton.displayName = + SelectPrimitive.ScrollDownButton.displayName + +const SelectContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, position = "popper", ...props }, ref) => ( + + + + + {children} + + + + +)) +SelectContent.displayName = SelectPrimitive.Content.displayName + +const SelectLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SelectLabel.displayName = SelectPrimitive.Label.displayName + +const SelectItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {children} + +)) +SelectItem.displayName = SelectPrimitive.Item.displayName + +const SelectSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +SelectSeparator.displayName = SelectPrimitive.Separator.displayName + +export { + Select, + SelectGroup, + SelectValue, + SelectTrigger, + SelectContent, + SelectLabel, + SelectItem, + SelectSeparator, + SelectScrollUpButton, + SelectScrollDownButton, +} + diff --git a/apps/web/features/game/components/connection-status.component.tsx b/apps/web/features/game/components/connection-status.component.tsx index 3a642e5..031b6c5 100644 --- a/apps/web/features/game/components/connection-status.component.tsx +++ b/apps/web/features/game/components/connection-status.component.tsx @@ -1,7 +1,7 @@ 'use client' -import { memo } from 'react' import { cn } from '@/lib/utils' +import { memo } from 'react' import { ImSpinner2 } from 'react-icons/im' interface IConnectionStatusProps { @@ -14,7 +14,7 @@ const ConnectionStatusComponent = (props: IConnectionStatusProps) => { if (isConnected) { return ( -
+
Connected
@@ -24,9 +24,9 @@ const ConnectionStatusComponent = (props: IConnectionStatusProps) => { return (