From a5e6cccd73756bbadfa45b3735b4fb9a43a7f017 Mon Sep 17 00:00:00 2001 From: Muhammad Khubaib Qaiser Date: Wed, 3 Aug 2022 00:33:49 +0500 Subject: [PATCH] Add Filter Button (#51) --- package.json | 2 +- src/assets/icons/FilterIcon.tsx | 28 ++++++++ src/assets/icons/index.ts | 1 + .../FilterButton/FilterButton.stories.tsx | 41 +++++++++++ .../core/FilterButton/FilterButton.tsx | 70 +++++++++++++++++++ src/components/core/FilterButton/index.ts | 1 + src/components/core/FilterButton/styles.ts | 17 +++++ src/components/core/FilterButton/types.ts | 8 +++ src/components/core/index.ts | 1 + src/components/navigation/Menu/Menu.tsx | 2 +- 10 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 src/assets/icons/FilterIcon.tsx create mode 100644 src/components/core/FilterButton/FilterButton.stories.tsx create mode 100644 src/components/core/FilterButton/FilterButton.tsx create mode 100644 src/components/core/FilterButton/index.ts create mode 100644 src/components/core/FilterButton/styles.ts create mode 100644 src/components/core/FilterButton/types.ts diff --git a/package.json b/package.json index 9dd43c7..4c40a8a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gudangada/design-system", - "version": "0.1.30", + "version": "0.1.31", "description": "Gada Design System", "main": "lib/index.js", "module": "lib/index.esm.js", diff --git a/src/assets/icons/FilterIcon.tsx b/src/assets/icons/FilterIcon.tsx new file mode 100644 index 0000000..7f02eea --- /dev/null +++ b/src/assets/icons/FilterIcon.tsx @@ -0,0 +1,28 @@ +import * as React from "react"; +import { iIconProps } from "./types"; +import useIconStyles from "./useIconStyles"; + +const FilterIcon: React.VFC = ({ + width = "24", + height = "24", + color, +}) => { + const { iconColor } = useIconStyles({ color }); + + return ( + + + + ); +}; + +export default FilterIcon; diff --git a/src/assets/icons/index.ts b/src/assets/icons/index.ts index 35c510e..2bd7ec7 100644 --- a/src/assets/icons/index.ts +++ b/src/assets/icons/index.ts @@ -18,5 +18,6 @@ export { default as LogoutIcon } from "./LogoutIcon"; export { default as CampaignIcon } from "./CampaignIcon"; export { default as RedemptionIcon } from "./RedemptionIcon"; export { default as SettingsIcon } from "./SettingsIcon"; +export { default as FilterIcon } from "./FilterIcon"; export * from "./ExpandIcon"; export * from "./types"; diff --git a/src/components/core/FilterButton/FilterButton.stories.tsx b/src/components/core/FilterButton/FilterButton.stories.tsx new file mode 100644 index 0000000..2cde639 --- /dev/null +++ b/src/components/core/FilterButton/FilterButton.stories.tsx @@ -0,0 +1,41 @@ +import * as React from "react"; +import { Meta, Story } from "@storybook/react"; +import FilterButtonUI from "./FilterButton"; +import { iFilterButtonProps } from "./types"; +import { Col } from "../../core"; +import { iMenuItemProps } from "../../navigation"; + +export default { + title: "Components/Core", + component: FilterButtonUI, + args: { + activeFilters: 2, + }, +} as Meta; + +const navItems: iMenuItemProps[] = [ + { + label: "Menu Item 1", + onClick: () => alert("Menu Item 1"), + }, + { + label: "Menu Item 2", + onClick: () => alert("Menu Item 2"), + }, +]; + +//👇 We create a “template” of how args map to rendering +const Template: Story = (props) => { + return ( + + + + ); +}; + +//👇 Each story then reuses that template +export const FilterButton = Template.bind({}); diff --git a/src/components/core/FilterButton/FilterButton.tsx b/src/components/core/FilterButton/FilterButton.tsx new file mode 100644 index 0000000..c63cb78 --- /dev/null +++ b/src/components/core/FilterButton/FilterButton.tsx @@ -0,0 +1,70 @@ +import * as React from "react"; +import { FilterIcon } from "../../../assets"; +import { Menu } from "../../navigation"; +import { StyledFilterButton } from "./styles"; +import { iFilterButtonProps } from "./types"; + +const FilterButton: React.FC = ({ + activeFilters, + menuProps, + buttonProps, + children, +}) => { + const [anchorEl, setAnchorEl] = React.useState(null); + const open = Boolean(anchorEl); + + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const menuItems = React.useMemo(() => { + return menuProps?.menuItems?.map((menuItem) => ({ + ...menuItem, + onClick: (e: React.MouseEvent) => { + menuItem.onClick?.(e); + handleClose(); + }, + })); + }, [menuProps?.menuItems]); + + const isFilterActive = activeFilters > 0; + + return ( + <> + } + isActive={isFilterActive} + {...buttonProps} + > + Filter {activeFilters ? `(${activeFilters})` : ""} + + + + {children} + + + ); +}; + +export default FilterButton; diff --git a/src/components/core/FilterButton/index.ts b/src/components/core/FilterButton/index.ts new file mode 100644 index 0000000..1d5d291 --- /dev/null +++ b/src/components/core/FilterButton/index.ts @@ -0,0 +1 @@ +export { default as FilterButton } from "./FilterButton"; diff --git a/src/components/core/FilterButton/styles.ts b/src/components/core/FilterButton/styles.ts new file mode 100644 index 0000000..f58ad2f --- /dev/null +++ b/src/components/core/FilterButton/styles.ts @@ -0,0 +1,17 @@ +import styled from "@emotion/styled"; +import { buttonClasses } from "@mui/material"; +import { Button } from "../Button"; + +export const StyledFilterButton = styled(Button)<{ isActive: boolean }>( + ({ isActive, theme: { palette } }) => ({ + [`&.${buttonClasses.root}>*`]: { + color: `${palette.interface.teal[700]} !important`, + }, + [`&.${buttonClasses.root}`]: { + backgroundColor: isActive + ? palette.interface.teal[100] + : palette.interface.white, + border: `1px solid ${palette.interface.teal[700]}`, + }, + }) +); diff --git a/src/components/core/FilterButton/types.ts b/src/components/core/FilterButton/types.ts new file mode 100644 index 0000000..9cd0bd6 --- /dev/null +++ b/src/components/core/FilterButton/types.ts @@ -0,0 +1,8 @@ +import { iMenuProps } from "../../navigation/Menu"; +import { iButtonProps } from "../Button"; + +export interface iFilterButtonProps { + activeFilters: number; + buttonProps?: Partial; + menuProps?: Partial; +} diff --git a/src/components/core/index.ts b/src/components/core/index.ts index 0ff0ef4..844b4dc 100644 --- a/src/components/core/index.ts +++ b/src/components/core/index.ts @@ -8,3 +8,4 @@ export * from "./Col"; export * from "./Row"; export * from "./Divider"; export * from "./Chip"; +export * from "./FilterButton"; diff --git a/src/components/navigation/Menu/Menu.tsx b/src/components/navigation/Menu/Menu.tsx index 51f1d28..2194766 100644 --- a/src/components/navigation/Menu/Menu.tsx +++ b/src/components/navigation/Menu/Menu.tsx @@ -19,7 +19,7 @@ const Menu: React.FC = ({ vertical: "top", horizontal: "center", }} - BackdropProps={{ style: { backgroundColor: "rgba(0,0,0,0.001)" } }} + BackdropProps={{ style: { opacity: 0.01 } }} PaperProps={{ elevation: 1 }} {...menuProps} onClose={handleClose}