search drop

This commit is contained in:
Nate Kelley 2025-02-24 20:27:52 -07:00
parent 0789055602
commit 9495c89ebb
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
3 changed files with 140 additions and 1 deletions

View File

@ -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';

View File

@ -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<typeof SearchDropdown> = {
title: 'Base/SearchDropdown',
component: SearchDropdown,
parameters: {
layout: 'centered'
},
argTypes: {
open: {
control: 'boolean',
defaultValue: true
}
},
tags: ['autodocs'],
render: (args) => (
<div className="flex min-w-[500px] flex-col gap-0">
<SearchDropdown {...args} children={<div className="h-6 w-full bg-gray-300"></div>} />
</div>
)
};
export default meta;
type Story = StoryObj<typeof SearchDropdown>;
const items = [
{
label: 'Nate Rules',
value: 'profile',
icon: <FiUser />
},
{
label: 'Settings',
value: 'settings',
icon: <FiSettings />
},
{
label: 'Messages',
value: 'messages',
icon: <FiMail />,
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)
}
};

View File

@ -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 (
<DropdownMenu open={open} defaultOpen={open} modal={false}>
<DropdownMenuTrigger asChild>{children}</DropdownMenuTrigger>
<DropdownMenuContent
className={cn(
'w-full min-w-[var(--radix-popper-anchor-width)]',
'data-[state=closed]:zoom-out-100 data-[state=open]:zoom-in-100',
'rounded-t-none',
className
)}
sideOffset={0}
align={'center'}
side={'bottom'}
loop>
{items.map((item, index) => (
<DropdownMenuItem
disabled={item.disabled}
key={index}
className="min-h-10"
onClick={() => onSelect(item)}>
{item.label}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
);
}
);
SearchDropdown.displayName = 'SearchDropdown';