From 9495c89ebbfcf14c7e46aa22f79d1b3f5f0dfb54 Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Mon, 24 Feb 2025 20:27:52 -0700 Subject: [PATCH] search drop --- .../components/ui/dropdown/DropdownBase.tsx | 1 - .../ui/dropdown/SearchDropdown.stories.tsx | 81 +++++++++++++++++++ .../components/ui/dropdown/SearchDropdown.tsx | 59 ++++++++++++++ 3 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 web/src/components/ui/dropdown/SearchDropdown.stories.tsx create mode 100644 web/src/components/ui/dropdown/SearchDropdown.tsx diff --git a/web/src/components/ui/dropdown/DropdownBase.tsx b/web/src/components/ui/dropdown/DropdownBase.tsx index 45e88ade1..2da6412d1 100644 --- a/web/src/components/ui/dropdown/DropdownBase.tsx +++ b/web/src/components/ui/dropdown/DropdownBase.tsx @@ -4,7 +4,6 @@ import * as React from 'react'; import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'; //import { Check, ChevronRight, Circle } from 'lucide-react'; import { Check, ChevronRight } from '../icons/NucleoIconOutlined'; -import I12px_chevronRight from '../icons/NucleoIconOutlined/I12px_chevron-right'; import { ShapeCircle } from '../icons/NucleoIconOutlined'; import { cn } from '@/lib/classMerge'; diff --git a/web/src/components/ui/dropdown/SearchDropdown.stories.tsx b/web/src/components/ui/dropdown/SearchDropdown.stories.tsx new file mode 100644 index 000000000..9e8741821 --- /dev/null +++ b/web/src/components/ui/dropdown/SearchDropdown.stories.tsx @@ -0,0 +1,81 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { SearchDropdown } from './SearchDropdown'; +import { FiUser, FiSettings, FiMail } from 'react-icons/fi'; +import { useState } from 'react'; + +const meta: Meta = { + title: 'Base/SearchDropdown', + component: SearchDropdown, + parameters: { + layout: 'centered' + }, + argTypes: { + open: { + control: 'boolean', + defaultValue: true + } + }, + tags: ['autodocs'], + render: (args) => ( +
+
} /> + + ) +}; + +export default meta; +type Story = StoryObj; + +const items = [ + { + label: 'Nate Rules', + value: 'profile', + icon: + }, + { + label: 'Settings', + value: 'settings', + icon: + }, + { + label: 'Messages', + value: 'messages', + icon: , + disabled: false + } +]; + +// Basic example +export const Default: Story = { + args: { + items: items, + open: true, + onSelect: (item) => console.log('Selected:', item.value) + } +}; + +// Example with some items disabled +export const WithDisabledItems: Story = { + args: { + items: [ + ...items, + { + label: 'Disabled Option', + value: 'disabled', + disabled: true + } + ], + open: true, + onSelect: (item) => console.log('Selected:', item) + } +}; + +// Example with custom styling +export const CustomStyling: Story = { + args: { + items: items, + open: true, + className: 'bg-slate-100 rounded-lg shadow-lg', + onSelect: (item) => console.log('Selected:', item) + } +}; diff --git a/web/src/components/ui/dropdown/SearchDropdown.tsx b/web/src/components/ui/dropdown/SearchDropdown.tsx new file mode 100644 index 000000000..35c16bf0d --- /dev/null +++ b/web/src/components/ui/dropdown/SearchDropdown.tsx @@ -0,0 +1,59 @@ +import React from 'react'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger +} from './DropdownBase'; +import { cn } from '@/lib/classMerge'; + +export interface SearchDropdownItem { + label: string; + value: string; + icon?: React.ReactNode; + disabled?: boolean; + selected?: boolean; +} + +interface SearchDropdownProps { + items: SearchDropdownItem[]; + onSelect: (item: SearchDropdownItem) => void; + className?: string; + style?: React.CSSProperties; + open: boolean; + children: React.ReactNode; +} + +export const SearchDropdown = React.memo( + ({ items, onSelect, className, children, open }: SearchDropdownProps) => { + return ( + + {children} + + + {items.map((item, index) => ( + onSelect(item)}> + {item.label} + + ))} + + + ); + } +); + +SearchDropdown.displayName = 'SearchDropdown';