start making filter user button

This commit is contained in:
Nate Kelley 2025-04-03 16:21:11 -06:00
parent 285f14c24d
commit 55bdd865c1
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
3 changed files with 103 additions and 1 deletions

View File

@ -0,0 +1,18 @@
import type { Meta, StoryObj } from '@storybook/react';
import { FilterDashboardButton } from './FilterDashboardButton';
const meta = {
title: 'Features/Buttons/FilterDashboardButton',
component: FilterDashboardButton,
parameters: {
layout: 'centered'
},
tags: ['autodocs']
} satisfies Meta<typeof FilterDashboardButton>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {}
};

View File

@ -0,0 +1,80 @@
import React, { useMemo, useState } from 'react';
import { Button } from '@/components/ui/buttons';
import { BarsFilter } from '@/components/ui/icons';
import { Dropdown, DropdownItems } from '@/components/ui/dropdown';
import { Input } from '@/components/ui/inputs';
import { MagnifierSparkle } from '@/components/ui/icons';
import { Text } from '@/components/ui/typography';
import { faker } from '@faker-js/faker';
import { cn } from '@/lib/classMerge';
const filterItems = Array.from({ length: 100 }, (_, index) => {
const randomWord = faker.commerce.productAdjective() + ' ' + faker.commerce.productMaterial();
return {
label: randomWord,
value: randomWord + index
};
});
export const FilterDashboardButton: React.FC = React.memo(() => {
const [filterText, setFilterText] = useState('');
const allDropdownItems: DropdownItems = useMemo(() => {
return [
...filterItems.filter((item) => item.label.toLowerCase().includes(filterText.toLowerCase()))
];
}, [filterText]);
const menuHeader = useMemo(() => {
return (
<div className="flex flex-col">
<div className="flex items-center gap-x-2 p-1">
<Input
placeholder="Filters..."
autoFocus
variant={'ghost'}
value={filterText}
onKeyDown={(e) => {
// e.preventDefault();
e.stopPropagation();
}}
onChange={(e) => {
e.preventDefault();
e.stopPropagation();
setFilterText(e.target.value);
}}
/>
</div>
<div className="flex border-t p-1">
<div
className={cn(
'hover:bg-item-select flex w-full cursor-pointer items-center gap-x-1.5 rounded p-1',
filterText && 'bg-item-select'
)}>
<span className="text-icon-color">
<MagnifierSparkle />
</span>
<Text className="whitespace-nowrap" variant="default">
AI Filter
</Text>
{filterText && (
<Text truncate variant="tertiary">
"{filterText}"
</Text>
)}
</div>
</div>
</div>
);
}, [filterText]);
return (
<Dropdown items={allDropdownItems} menuHeader={menuHeader} menuHeaderClassName="p-0!">
<Button variant="ghost" prefix={<BarsFilter />}>
Filter
</Button>
</Dropdown>
);
});
FilterDashboardButton.displayName = 'FilterDashboardButton';

View File

@ -66,6 +66,7 @@ export interface DropdownProps<T = string> extends DropdownMenuProps {
footerClassName?: string; footerClassName?: string;
sideOffset?: number; sideOffset?: number;
disabled?: boolean; disabled?: boolean;
menuHeaderClassName?: string;
} }
export interface DropdownContentProps<T = string> export interface DropdownContentProps<T = string>
@ -94,6 +95,7 @@ export const DropdownBase = <T,>({
footerContent, footerContent,
dir, dir,
modal, modal,
menuHeaderClassName,
sideOffset, sideOffset,
footerClassName = '', footerClassName = '',
showIndex = false, showIndex = false,
@ -125,6 +127,7 @@ export const DropdownBase = <T,>({
footerContent={footerContent} footerContent={footerContent}
className={contentClassName} className={contentClassName}
footerClassName={footerClassName} footerClassName={footerClassName}
menuHeaderClassName={menuHeaderClassName}
/> />
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
@ -142,6 +145,7 @@ export const DropdownContent = <T,>({
emptyStateText = 'No items found', emptyStateText = 'No items found',
footerContent, footerContent,
className, className,
menuHeaderClassName,
footerClassName, footerClassName,
onSelect onSelect
}: DropdownContentProps<T>) => { }: DropdownContentProps<T>) => {
@ -213,7 +217,7 @@ export const DropdownContent = <T,>({
<> <>
{menuHeader && ( {menuHeader && (
<div className="flex flex-col"> <div className="flex flex-col">
<div className="p-1"> <div className={cn('p-1', menuHeaderClassName)}>
<DropdownMenuHeaderSelector <DropdownMenuHeaderSelector
menuHeader={menuHeader} menuHeader={menuHeader}
onChange={handleSearchChange} onChange={handleSearchChange}