Basic Dropdown
smoothui-registry/basic-dropdownFreeComponent
A BasicDropdown component for SmoothUI.
Install it
npx shadcn@latest add https://www.smoothui.dev/r/basic-dropdown.jsonSource
1"use client";23import { ChevronDown } from "lucide-react";4import { AnimatePresence, motion, useReducedMotion } from "motion/react";5import { useEffect, useRef, useState } from "react";6import { createPortal } from "react-dom";78const ROTATION_ANGLE_OPEN = 180;9const DROPDOWN_OFFSET = 4;1011export interface DropdownItem {12 icon?: React.ReactNode;13 id: string | number;14 label: string;15}1617export interface BasicDropdownProps {18 className?: string;19 items: DropdownItem[];20 label: string;21 onChange?: (item: DropdownItem) => void;22}2324export default function BasicDropdown({25 label,26 items,27 onChange,28 className = "",29}: BasicDropdownProps) {30 const [isOpen, setIsOpen] = useState(false);31 const [selectedItem, setSelectedItem] = useState<DropdownItem | null>(null);32 const [focusedIndex, setFocusedIndex] = useState(-1);33 const dropdownRef = useRef<HTMLDivElement>(null);34 const buttonRef = useRef<HTMLButtonElement>(null);35 const portalRef = useRef<HTMLDivElement>(null);36 const [position, setPosition] = useState({ left: 0, top: 0, width: 0 });37 const shouldReduceMotion = useReducedMotion();3839 const handleItemSelect = (item: DropdownItem) => {40 setSelectedItem(item);41 setIsOpen(false);42 onChange?.(item);43 };4445 const handleToggle = () => {46 if (!isOpen && buttonRef.current) {47 const rect = buttonRef.current.getBoundingClientRect();48 setPosition({49 left: rect.left,50 top: rect.bottom + DROPDOWN_OFFSET,51 width: rect.width,52 });53 }54 setIsOpen(!isOpen);55 };5657 // Update position on scroll/resize when open58 useEffect(() => {59 if (!(isOpen && buttonRef.current)) {60 return;61 }6263 const updatePosition = () => {64 if (buttonRef.current) {65 const rect = buttonRef.current.getBoundingClientRect();66 setPosition({67 left: rect.left,68 top: rect.bottom + DROPDOWN_OFFSET,69 width: rect.width,70 });71 }72 };7374 window.addEventListener("scroll", updatePosition, true);75 window.addEventListener("resize", updatePosition);7677 return () => {78 window.removeEventListener("scroll", updatePosition, true);79 window.removeEventListener("resize", updatePosition);80 };81 }, [isOpen]);8283 // Close dropdown when clicking outside84 useEffect(() => {85 const handleClickOutside = (event: MouseEvent) => {86 const target = event.target as Node;87 if (88 isOpen &&89 dropdownRef.current &&90// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from SmoothUI Registry
All 177 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Agent Avataragent-avatar | SmoothUI Registry | Components | Free | no deps | |
| Ai Approvalai-approval | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Artifactai-artifact | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Branchai-branch | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Citationai-citation | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Context Meterai-context-meter | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Conversationai-conversation | SmoothUI Registry | Components | Free | 2 deps | |
| Ai Coreai-core | SmoothUI Registry | Components | Free | 1 dep |
