From d98fa495ac82c504157738f1be6dd14c77cce44c Mon Sep 17 00:00:00 2001 From: jhdaws Date: Thu, 30 Oct 2025 21:28:04 -0500 Subject: [PATCH 1/9] dropdown done --- app/(root)/dropdown-demo/page.tsx | 36 + app/components/Dropdown.tsx | 209 +- app/styles/components/Dropdown.module.css | 197 + next.config.ts | 20 + package-lock.json | 7717 +++++++++++++++++++++ package.json | 6 +- public/assets/icons/DropDownArrow.svg | 3 + public/assets/icons/FullStar.svg | 4 + svgr.d.ts | 5 + tsconfig.json | 9 +- 10 files changed, 8155 insertions(+), 51 deletions(-) create mode 100644 app/(root)/dropdown-demo/page.tsx create mode 100644 app/styles/components/Dropdown.module.css create mode 100644 package-lock.json create mode 100644 public/assets/icons/DropDownArrow.svg create mode 100644 public/assets/icons/FullStar.svg create mode 100644 svgr.d.ts diff --git a/app/(root)/dropdown-demo/page.tsx b/app/(root)/dropdown-demo/page.tsx new file mode 100644 index 0000000..4a0b355 --- /dev/null +++ b/app/(root)/dropdown-demo/page.tsx @@ -0,0 +1,36 @@ +"use client"; + +// app/(root)/dropdown-demo/page.tsx +import { useMemo, useState } from "react"; +import Dropdown from "../../components/Dropdown"; + +const OPTIONS = ["First action", "Second action", "Sign out"] as const; + +export default function DropdownDemoPage() { + // Showcase the new `selected` capability of the Dropdown + const [selectedIndex, setSelectedIndex] = useState(0); + + // Build menu items with selection + click handlers + const menuItems = useMemo( + () => + OPTIONS.map((label, index) => ({ + label, + selected: index === selectedIndex, + onClick: () => setSelectedIndex(index), + })), + [selectedIndex], + ); + + return ( +
+

Dropdown demo

+
+ Selected: {OPTIONS[selectedIndex]} +
+ +
+ ); +} diff --git a/app/components/Dropdown.tsx b/app/components/Dropdown.tsx index 6722abb..cee821c 100644 --- a/app/components/Dropdown.tsx +++ b/app/components/Dropdown.tsx @@ -1,8 +1,14 @@ -import { useState } from "react"; +"use client"; + +import styles from "@/app/styles/components/Dropdown.module.css"; +import DropDownArrow from "@/public/assets/icons/DropDownArrow.svg"; +import FullStar from "@/public/assets/icons/FullStar.svg"; +import { useEffect, useRef, useState } from "react"; type MenuItem = { label: string; onClick?: () => void; + selected?: boolean; }; type DropdownProps = { @@ -10,73 +16,178 @@ type DropdownProps = { menuItems: MenuItem[]; }; +const isAssetModule = (value: unknown): value is { src: string } => { + if (typeof value !== "object" || value === null) return false; + if (!("src" in value)) return false; + const maybe = (value as { src: unknown }).src; + return typeof maybe === "string"; +}; + +const renderIcon = (Icon: unknown, className?: string) => { + if (!Icon) return null; + + if (typeof Icon === "string") { + return ; + } + + if (isAssetModule(Icon)) { + const src = Icon.src; + return ; + } + + const Comp = Icon as React.ComponentType>; + return