diff --git a/web/src/components/features/buttons/FilterDashboardButton.stories.tsx b/web/src/components/features/buttons/FilterDashboardButton.stories.tsx new file mode 100644 index 000000000..285676d4e --- /dev/null +++ b/web/src/components/features/buttons/FilterDashboardButton.stories.tsx @@ -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; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: {} +}; diff --git a/web/src/components/features/buttons/FilterDashboardButton.tsx b/web/src/components/features/buttons/FilterDashboardButton.tsx new file mode 100644 index 000000000..f0e88eb0c --- /dev/null +++ b/web/src/components/features/buttons/FilterDashboardButton.tsx @@ -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 ( +
+
+ { + // e.preventDefault(); + e.stopPropagation(); + }} + onChange={(e) => { + e.preventDefault(); + e.stopPropagation(); + setFilterText(e.target.value); + }} + /> +
+
+
+ + + + + AI Filter + + {filterText && ( + + "{filterText}" + + )} +
+
+
+ ); + }, [filterText]); + + return ( + + + + ); +}); + +FilterDashboardButton.displayName = 'FilterDashboardButton'; diff --git a/web/src/components/ui/dropdown/Dropdown.tsx b/web/src/components/ui/dropdown/Dropdown.tsx index 050731b59..20ca81829 100644 --- a/web/src/components/ui/dropdown/Dropdown.tsx +++ b/web/src/components/ui/dropdown/Dropdown.tsx @@ -66,6 +66,7 @@ export interface DropdownProps extends DropdownMenuProps { footerClassName?: string; sideOffset?: number; disabled?: boolean; + menuHeaderClassName?: string; } export interface DropdownContentProps @@ -94,6 +95,7 @@ export const DropdownBase = ({ footerContent, dir, modal, + menuHeaderClassName, sideOffset, footerClassName = '', showIndex = false, @@ -125,6 +127,7 @@ export const DropdownBase = ({ footerContent={footerContent} className={contentClassName} footerClassName={footerClassName} + menuHeaderClassName={menuHeaderClassName} /> @@ -142,6 +145,7 @@ export const DropdownContent = ({ emptyStateText = 'No items found', footerContent, className, + menuHeaderClassName, footerClassName, onSelect }: DropdownContentProps) => { @@ -213,7 +217,7 @@ export const DropdownContent = ({ <> {menuHeader && (
-
+