From c8ffa35e88d81a69721a1920889a653fef72c1df Mon Sep 17 00:00:00 2001 From: Muhammad Khubaib Qaiser Date: Tue, 2 Aug 2022 18:25:55 +0500 Subject: [PATCH 1/9] Add Label to Searchbar and improve Menu component (#50) --- package.json | 2 +- .../core/Searchbar/Searchbar.stories.tsx | 1 + src/components/core/Searchbar/Searchbar.tsx | 56 ++++++++++--------- src/components/inputs/AutoComplete/styles.ts | 2 +- src/components/navigation/Menu/Menu.tsx | 13 +++-- src/components/navigation/Menu/types.ts | 2 +- 6 files changed, 44 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index d8258e8..9dd43c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gudangada/design-system", - "version": "0.1.29", + "version": "0.1.30", "description": "Gada Design System", "main": "lib/index.js", "module": "lib/index.esm.js", diff --git a/src/components/core/Searchbar/Searchbar.stories.tsx b/src/components/core/Searchbar/Searchbar.stories.tsx index 2926f6e..2d4a7f4 100644 --- a/src/components/core/Searchbar/Searchbar.stories.tsx +++ b/src/components/core/Searchbar/Searchbar.stories.tsx @@ -24,6 +24,7 @@ const Template: Story = (props) => { return ( = (props) => { onClickCancel, onChangeValue, size = "default", + label, ...rest } = props; @@ -24,32 +27,35 @@ const Searchbar: React.VFC = (props) => { }; return ( - - onChangeValue(event.target.value)} - startAdornment={ - - - - } - inputRef={inputRef} - endAdornment={ - withEndAdornment && ( - - {props.value ? ( - - - - ) : ( - - )} + + {label && } + + onChangeValue(event.target.value)} + startAdornment={ + + - ) - } - /> - + } + inputRef={inputRef} + endAdornment={ + withEndAdornment && ( + + {props.value ? ( + + + + ) : ( + + )} + + ) + } + /> + + ); }; diff --git a/src/components/inputs/AutoComplete/styles.ts b/src/components/inputs/AutoComplete/styles.ts index d8f056a..12f9e95 100644 --- a/src/components/inputs/AutoComplete/styles.ts +++ b/src/components/inputs/AutoComplete/styles.ts @@ -1,6 +1,6 @@ import styled from "@emotion/styled"; import { outlinedInputClasses } from "@mui/material"; -import { Col } from "../../core"; +import { Col } from "../../core/Col"; export const StyledAutoCompleteContainer = styled(Col)<{ isError?: boolean }>( ({ theme: { palette }, isError }) => ({ diff --git a/src/components/navigation/Menu/Menu.tsx b/src/components/navigation/Menu/Menu.tsx index 16020b4..51f1d28 100644 --- a/src/components/navigation/Menu/Menu.tsx +++ b/src/components/navigation/Menu/Menu.tsx @@ -3,8 +3,9 @@ import { Menu as MuiMenu } from "@mui/material"; import { iMenuProps } from "./types"; import MenuItem from "./MenuItem"; -const Menu: React.VFC = ({ +const Menu: React.FC = ({ menuItems, + children, handleClose, ...menuProps }) => { @@ -18,12 +19,16 @@ const Menu: React.VFC = ({ vertical: "top", horizontal: "center", }} + BackdropProps={{ style: { backgroundColor: "rgba(0,0,0,0.001)" } }} + PaperProps={{ elevation: 1 }} {...menuProps} onClose={handleClose} > - {menuItems.map((menuItem) => { - return ; - })} + {menuItems + ? menuItems.map((menuItem) => { + return ; + }) + : children} ); }; diff --git a/src/components/navigation/Menu/types.ts b/src/components/navigation/Menu/types.ts index 33a8f8e..9e5d47d 100644 --- a/src/components/navigation/Menu/types.ts +++ b/src/components/navigation/Menu/types.ts @@ -10,6 +10,6 @@ export interface iMenuItemProps { } export interface iMenuProps extends MenuProps { - menuItems: iMenuItemProps[]; + menuItems?: iMenuItemProps[]; handleClose: VoidFunction; } From a5e6cccd73756bbadfa45b3735b4fb9a43a7f017 Mon Sep 17 00:00:00 2001 From: Muhammad Khubaib Qaiser Date: Wed, 3 Aug 2022 00:33:49 +0500 Subject: [PATCH 2/9] 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} From 47bf89336ddccbce946a18d1f6531149a0fce6e6 Mon Sep 17 00:00:00 2001 From: Muhammad Khubaib Qaiser Date: Wed, 3 Aug 2022 09:29:16 +0500 Subject: [PATCH 3/9] Fix FilterButton hover UI (#52) --- package.json | 2 +- src/components/core/FilterButton/styles.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 4c40a8a..da8b7dd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gudangada/design-system", - "version": "0.1.31", + "version": "0.1.32", "description": "Gada Design System", "main": "lib/index.js", "module": "lib/index.esm.js", diff --git a/src/components/core/FilterButton/styles.ts b/src/components/core/FilterButton/styles.ts index f58ad2f..e375235 100644 --- a/src/components/core/FilterButton/styles.ts +++ b/src/components/core/FilterButton/styles.ts @@ -5,7 +5,7 @@ import { Button } from "../Button"; export const StyledFilterButton = styled(Button)<{ isActive: boolean }>( ({ isActive, theme: { palette } }) => ({ [`&.${buttonClasses.root}>*`]: { - color: `${palette.interface.teal[700]} !important`, + color: `${palette.interface.teal[900]} !important`, }, [`&.${buttonClasses.root}`]: { backgroundColor: isActive @@ -13,5 +13,8 @@ export const StyledFilterButton = styled(Button)<{ isActive: boolean }>( : palette.interface.white, border: `1px solid ${palette.interface.teal[700]}`, }, + [`&.${buttonClasses.root}:hover`]: { + backgroundColor: palette.interface.teal[50], + }, }) ); From 927130e9fb9bd6832714b394136087fd61ecf83e Mon Sep 17 00:00:00 2001 From: Muhammad Khubaib Qaiser Date: Tue, 6 Sep 2022 11:45:04 +0500 Subject: [PATCH 4/9] Add header prop to SideNav and fix sub-nav item alignment (#54) --- package.json | 2 +- src/components/core/Divider/styles.ts | 9 ++++--- src/components/core/NavListItem/styles.ts | 6 +++++ .../Dashboard/DashboardLayout.stories.tsx | 7 +++-- .../layout/Dashboard/DashboardLayout.tsx | 2 ++ src/components/layout/Dashboard/types.ts | 1 + src/components/navigation/SideNav/SideNav.tsx | 26 ++++++++++++++++--- src/components/navigation/SideNav/types.ts | 1 + 8 files changed, 44 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index da8b7dd..3ee7b90 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gudangada/design-system", - "version": "0.1.32", + "version": "0.1.33", "description": "Gada Design System", "main": "lib/index.js", "module": "lib/index.esm.js", diff --git a/src/components/core/Divider/styles.ts b/src/components/core/Divider/styles.ts index 89adf9a..1933a56 100644 --- a/src/components/core/Divider/styles.ts +++ b/src/components/core/Divider/styles.ts @@ -3,6 +3,9 @@ import { Divider } from "@mui/material"; import { pxToRem } from "../../../styles"; import { iDividerProps } from "./types"; -export const StyledDivider = styled(Divider)(({ size }) => ({ - height: size === "large" ? pxToRem(8) : pxToRem(1), -})); +export const StyledDivider = styled(Divider)( + ({ size, color }) => ({ + height: size === "large" ? pxToRem(8) : pxToRem(1), + backgroundColor: color, + }) +); diff --git a/src/components/core/NavListItem/styles.ts b/src/components/core/NavListItem/styles.ts index 4e90b8f..c118e55 100644 --- a/src/components/core/NavListItem/styles.ts +++ b/src/components/core/NavListItem/styles.ts @@ -14,6 +14,12 @@ export const StyledListItemButton = styled(ListItemButton)< "&:hover": { backgroundColor: palette.overlay.teal, }, + + ...(isSubNavItem + ? { + paddingLeft: `${pxToRem(28)} !important`, + } + : {}), })); export const StyledActiveIndicatorContainer = styled.div< diff --git a/src/components/layout/Dashboard/DashboardLayout.stories.tsx b/src/components/layout/Dashboard/DashboardLayout.stories.tsx index 95a97ea..e5b0f15 100644 --- a/src/components/layout/Dashboard/DashboardLayout.stories.tsx +++ b/src/components/layout/Dashboard/DashboardLayout.stories.tsx @@ -2,9 +2,10 @@ import * as React from "react"; import { Meta } from "@storybook/react"; import DashboardLayoutUI from "./DashboardLayout"; import { Col } from "../../core/Col"; -import { HomeIcon, CampaignIcon } from "../../../assets"; +import { HomeIcon, CampaignIcon, GadaIcon } from "../../../assets"; import { iDashboardNavItems } from "./types"; import { Link } from "@mui/material"; +import { Text } from "../../core"; export default { title: "Components/Layout", @@ -26,13 +27,15 @@ const DashboardNavigation: iDashboardNavItems[] = [ }, ]; -export const Dashboard: React.VFC = () => { +export const DashboardLayout: React.VFC = () => { return ( } navItems={DashboardNavigation} activePathname="/" dashboardBaseUrl="/" LinkComponent={Link} + header={Some Header} > Page Component diff --git a/src/components/layout/Dashboard/DashboardLayout.tsx b/src/components/layout/Dashboard/DashboardLayout.tsx index bab3f75..93c79f2 100644 --- a/src/components/layout/Dashboard/DashboardLayout.tsx +++ b/src/components/layout/Dashboard/DashboardLayout.tsx @@ -11,6 +11,7 @@ const DashboardLayout: React.FC = ({ activePathname, dashboardBaseUrl, stickyBottomFooter, + header, children, contentContainerClassName, }) => { @@ -45,6 +46,7 @@ const DashboardLayout: React.FC = ({ Logo={Logo} navItemsProps={{ navItems: sideNavItems, LinkComponent }} stickyBottomFooter={stickyBottomFooter} + header={header} />
= ({ Logo, drawerProps, navItemsProps: { navItems, ...restNavProps }, stickyBottomFooter, + header, }) => { + const { palette } = useAppTheme(); + const paperRef = React.useRef(null); const [_, setShowShadow] = React.useState(false); @@ -52,11 +56,25 @@ const SideNav: React.VFC = ({ > {Logo && ( - - {Logo} - + <> + + {Logo} + + + + + )} - + {header} diff --git a/src/components/navigation/SideNav/types.ts b/src/components/navigation/SideNav/types.ts index 2665fca..966fd2b 100644 --- a/src/components/navigation/SideNav/types.ts +++ b/src/components/navigation/SideNav/types.ts @@ -7,6 +7,7 @@ export interface iSideNavProps { drawerProps?: iDrawerProps; navItemsProps: iNavListItemsProps; stickyBottomFooter?: React.ReactNode; + header?: React.ReactNode; } export interface iTopBottomNavItems { From 80ac6dfc9965007c1990f5f0d980048502d72029 Mon Sep 17 00:00:00 2001 From: Muhammad Khubaib Qaiser Date: Wed, 14 Sep 2022 00:09:58 +0500 Subject: [PATCH 5/9] Add horizontal scrolling to Table (#55) * Add horizontal scrolling to Table * Bump up version --- package.json | 2 +- .../data-grid/Table/Table.stories.tsx | 323 ++++++++++-------- src/components/data-grid/Table/Table.tsx | 25 +- 3 files changed, 188 insertions(+), 162 deletions(-) diff --git a/package.json b/package.json index 3ee7b90..596fd86 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gudangada/design-system", - "version": "0.1.33", + "version": "0.1.34", "description": "Gada Design System", "main": "lib/index.js", "module": "lib/index.esm.js", diff --git a/src/components/data-grid/Table/Table.stories.tsx b/src/components/data-grid/Table/Table.stories.tsx index abaf671..54c0250 100644 --- a/src/components/data-grid/Table/Table.stories.tsx +++ b/src/components/data-grid/Table/Table.stories.tsx @@ -1,7 +1,7 @@ import { Meta } from "@storybook/react"; import { orderBy } from "lodash"; import * as React from "react"; -import { Text } from "../../core"; +import { Col, Text } from "../../core"; import Table from "./Table"; import TableRow from "./TableRow"; @@ -31,6 +31,113 @@ interface iFood { protein: number; } +const tableData: iFood[] = [ + { + id: "Cupcake", + name: "Cupcake", + calories: 305, + fat: 3.7, + carbs: 67, + protein: 4.3, + }, + { + id: "Donut", + name: "Donut", + calories: 452, + fat: 25.0, + carbs: 51, + protein: 4.9, + }, + { + id: "Eclair", + name: "Eclair", + calories: 262, + fat: 16.0, + carbs: 24, + protein: 6.0, + }, + { + id: "Frozen yoghurt", + name: "Frozen yoghurt", + calories: 159, + fat: 6.0, + carbs: 24, + protein: 4.0, + }, + { + id: "Gingerbread", + name: "Gingerbread", + calories: 356, + fat: 16.0, + carbs: 49, + protein: 3.9, + }, + { + id: "Honeycomb", + name: "Honeycomb", + calories: 408, + fat: 3.2, + carbs: 87, + protein: 6.5, + }, + { + id: "Ice cream sandwich", + name: "Ice cream sandwich", + calories: 237, + fat: 9.0, + carbs: 37, + protein: 4.3, + }, + { + id: "Jelly Bean", + name: "Jelly Bean", + calories: 375, + fat: 0.0, + carbs: 94, + protein: 0.0, + }, + { + id: "KitKat", + name: "KitKat", + calories: 518, + fat: 26.0, + carbs: 65, + protein: 7.0, + }, + { + id: "Lollipop", + name: "Lollipop", + calories: 392, + fat: 0.2, + carbs: 98, + protein: 0.0, + }, + { + id: "Marshmallow", + name: "Marshmallow", + calories: 318, + fat: 0, + carbs: 81, + protein: 2.0, + }, + { + id: "Nougat", + name: "Nougat", + calories: 360, + fat: 19.0, + carbs: 9, + protein: 37.0, + }, + { + id: "Oreo", + name: "Oreo", + calories: 437, + fat: 18.0, + carbs: 63, + protein: 4.0, + }, +]; + export const SimpleTable: React.VFC> = ({ tableRowProps, }) => { @@ -42,49 +149,6 @@ export const SimpleTable: React.VFC> = ({ { id: "protein", content: "Protein (g)" }, ]; - const tableData: iFood[] = [ - { - id: "Frozen yoghurt", - name: "Frozen yoghurt", - calories: 159, - fat: 6.0, - carbs: 24, - protein: 4.0, - }, - { - id: "Ice cream sandwich", - name: "Ice cream sandwich", - calories: 237, - fat: 9.0, - carbs: 37, - protein: 4.3, - }, - { - id: "Eclair", - name: "Eclair", - calories: 262, - fat: 16.0, - carbs: 24, - protein: 6.0, - }, - { - id: "Cupcake", - name: "Cupcake", - calories: 305, - fat: 3.7, - carbs: 67, - protein: 4.3, - }, - { - id: "Gingerbread", - name: "Gingerbread", - calories: 356, - fat: 16.0, - carbs: 49, - protein: 3.9, - }, - ]; - const renderRow: iRenderTableRowItemHandler = (row) => { return ( @@ -113,112 +177,7 @@ export const SimpleTable: React.VFC> = ({ export const SortableTable: React.VFC> = ({ tableRowProps, }) => { - const [rows, setRows] = React.useState([ - { - id: "Cupcake", - name: "Cupcake", - calories: 305, - fat: 3.7, - carbs: 67, - protein: 4.3, - }, - { - id: "Donut", - name: "Donut", - calories: 452, - fat: 25.0, - carbs: 51, - protein: 4.9, - }, - { - id: "Eclair", - name: "Eclair", - calories: 262, - fat: 16.0, - carbs: 24, - protein: 6.0, - }, - { - id: "Frozen yoghurt", - name: "Frozen yoghurt", - calories: 159, - fat: 6.0, - carbs: 24, - protein: 4.0, - }, - { - id: "Gingerbread", - name: "Gingerbread", - calories: 356, - fat: 16.0, - carbs: 49, - protein: 3.9, - }, - { - id: "Honeycomb", - name: "Honeycomb", - calories: 408, - fat: 3.2, - carbs: 87, - protein: 6.5, - }, - { - id: "Ice cream sandwich", - name: "Ice cream sandwich", - calories: 237, - fat: 9.0, - carbs: 37, - protein: 4.3, - }, - { - id: "Jelly Bean", - name: "Jelly Bean", - calories: 375, - fat: 0.0, - carbs: 94, - protein: 0.0, - }, - { - id: "KitKat", - name: "KitKat", - calories: 518, - fat: 26.0, - carbs: 65, - protein: 7.0, - }, - { - id: "Lollipop", - name: "Lollipop", - calories: 392, - fat: 0.2, - carbs: 98, - protein: 0.0, - }, - { - id: "Marshmallow", - name: "Marshmallow", - calories: 318, - fat: 0, - carbs: 81, - protein: 2.0, - }, - { - id: "Nougat", - name: "Nougat", - calories: 360, - fat: 19.0, - carbs: 9, - protein: 37.0, - }, - { - id: "Oreo", - name: "Oreo", - calories: 437, - fat: 18.0, - carbs: 63, - protein: 4.0, - }, - ]); + const [rows, setRows] = React.useState(tableData); const [order, setOrder] = React.useState>( Array(5).fill(undefined) @@ -285,3 +244,67 @@ export const SortableTable: React.VFC> = ({ /> ); }; + +export const TablePaginated: React.VFC> = () => { + const [page, setPage] = React.useState(1); + const pageSize = 5; + + const tableHeadingCells: iTableHeadingCell[] = [ + { + id: "name", + content: "Dessert (100g serving)", + }, + { + id: "calories", + content: "Calories", + }, + { id: "Fat", content: "Fat (g)" }, + { + id: "carbs", + content: "Carbs (g)", + }, + { + id: "protein", + content: "Protein (g)", + }, + ]; + + const renderRow: iRenderTableRowItemHandler = (row) => { + return ( + + {() => ( + <> + {row.name} + {row.calories} + {row.fat} + {row.carbs} + {row.protein} + + )} + + ); + }; + + const paginatedData = React.useMemo(() => { + const startIndex = (page - 1) * pageSize; + return tableData.slice(startIndex, startIndex + pageSize); + }, [page, pageSize]); + + return ( + + + + ); +}; diff --git a/src/components/data-grid/Table/Table.tsx b/src/components/data-grid/Table/Table.tsx index b285975..892e672 100644 --- a/src/components/data-grid/Table/Table.tsx +++ b/src/components/data-grid/Table/Table.tsx @@ -80,9 +80,12 @@ const Table: React.VFC> = ({ }, [emptyDataMessage, tableHeadingCells]); return ( - + > = ({ : data.map(renderTableItem)} - {withPagination && paginationProps ? ( - - - - ) : null} + {withPagination && paginationProps ? ( + + + + ) : null} ); }; From 7d072feb0d52ea885f98be83d0b108b868bd3026 Mon Sep 17 00:00:00 2001 From: Muhammad Khubaib Qaiser Date: Wed, 14 Sep 2022 10:33:45 +0500 Subject: [PATCH 6/9] Fix Table height due to overflow (#56) --- package.json | 2 +- src/components/data-grid/Table/Table.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 596fd86..59a3bb0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gudangada/design-system", - "version": "0.1.34", + "version": "0.1.35", "description": "Gada Design System", "main": "lib/index.js", "module": "lib/index.esm.js", diff --git a/src/components/data-grid/Table/Table.tsx b/src/components/data-grid/Table/Table.tsx index 892e672..a8c44d7 100644 --- a/src/components/data-grid/Table/Table.tsx +++ b/src/components/data-grid/Table/Table.tsx @@ -80,7 +80,7 @@ const Table: React.VFC> = ({ }, [emptyDataMessage, tableHeadingCells]); return ( - + Date: Tue, 8 Nov 2022 10:14:40 +0500 Subject: [PATCH 7/9] Add upload button component (#57) --- package-lock.json | 4 +- package.json | 2 +- .../Button/{ => Button}/Button.stories.tsx | 0 .../core/Button/{ => Button}/Button.tsx | 2 +- .../core/Button/{ => Button}/constants.ts | 0 src/components/core/Button/Button/index.ts | 2 + .../core/Button/{ => Button}/types.ts | 0 .../FileUploadButton.stories.tsx | 68 ++++++++ .../FileUploadButton/FileUploadButton.tsx | 151 ++++++++++++++++++ .../core/Button/FileUploadButton/index.ts | 2 + .../core/Button/FileUploadButton/styles.ts | 125 +++++++++++++++ .../core/Button/FileUploadButton/types.ts | 19 +++ src/components/core/Button/index.ts | 4 +- 13 files changed, 373 insertions(+), 6 deletions(-) rename src/components/core/Button/{ => Button}/Button.stories.tsx (100%) rename src/components/core/Button/{ => Button}/Button.tsx (97%) rename src/components/core/Button/{ => Button}/constants.ts (100%) create mode 100644 src/components/core/Button/Button/index.ts rename src/components/core/Button/{ => Button}/types.ts (100%) create mode 100644 src/components/core/Button/FileUploadButton/FileUploadButton.stories.tsx create mode 100644 src/components/core/Button/FileUploadButton/FileUploadButton.tsx create mode 100644 src/components/core/Button/FileUploadButton/index.ts create mode 100644 src/components/core/Button/FileUploadButton/styles.ts create mode 100644 src/components/core/Button/FileUploadButton/types.ts diff --git a/package-lock.json b/package-lock.json index 44f2f85..176dff7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@gudangada/design-system", - "version": "0.1.29", + "version": "0.1.35", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@gudangada/design-system", - "version": "0.1.29", + "version": "0.1.35", "license": "MIT", "dependencies": { "clsx": "1.1.1" diff --git a/package.json b/package.json index 59a3bb0..5f8b95a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gudangada/design-system", - "version": "0.1.35", + "version": "0.1.36", "description": "Gada Design System", "main": "lib/index.js", "module": "lib/index.esm.js", diff --git a/src/components/core/Button/Button.stories.tsx b/src/components/core/Button/Button/Button.stories.tsx similarity index 100% rename from src/components/core/Button/Button.stories.tsx rename to src/components/core/Button/Button/Button.stories.tsx diff --git a/src/components/core/Button/Button.tsx b/src/components/core/Button/Button/Button.tsx similarity index 97% rename from src/components/core/Button/Button.tsx rename to src/components/core/Button/Button/Button.tsx index f36d307..e0bfa96 100644 --- a/src/components/core/Button/Button.tsx +++ b/src/components/core/Button/Button/Button.tsx @@ -7,7 +7,7 @@ import { Typography, } from "@mui/material"; import { ButtonPropsMap } from "./constants"; -import { iIconProps } from "../../../assets/icons/types"; +import { iIconProps } from "../../../../assets/icons/types"; const Button: React.FC = ({ children, diff --git a/src/components/core/Button/constants.ts b/src/components/core/Button/Button/constants.ts similarity index 100% rename from src/components/core/Button/constants.ts rename to src/components/core/Button/Button/constants.ts diff --git a/src/components/core/Button/Button/index.ts b/src/components/core/Button/Button/index.ts new file mode 100644 index 0000000..f86a56d --- /dev/null +++ b/src/components/core/Button/Button/index.ts @@ -0,0 +1,2 @@ +export { default as Button } from "./Button"; +export * from "./types"; diff --git a/src/components/core/Button/types.ts b/src/components/core/Button/Button/types.ts similarity index 100% rename from src/components/core/Button/types.ts rename to src/components/core/Button/Button/types.ts diff --git a/src/components/core/Button/FileUploadButton/FileUploadButton.stories.tsx b/src/components/core/Button/FileUploadButton/FileUploadButton.stories.tsx new file mode 100644 index 0000000..8e3580e --- /dev/null +++ b/src/components/core/Button/FileUploadButton/FileUploadButton.stories.tsx @@ -0,0 +1,68 @@ +import * as React from "react"; +import { Meta, Story } from "@storybook/react"; +import { iFileChangeHandler, iFileUploadButtonProps } from "./types"; +import FileUploadButtonUI from "./FileUploadButton"; + +export default { + title: "Components/Core", + component: FileUploadButtonUI, +} as Meta; + +//👇 We create a “template” of how args map to rendering +const Template: Story = ({ + action, + onChange, + url, + ...props +}) => { + const [file, setFile] = React.useState(null); + const [fileUrl, setFileUrl] = React.useState(null); + + const onChangeFile: iFileChangeHandler = (newFile, url) => { + setFile(newFile); + setFileUrl(url); + }; + + return ( + + ); +}; + +//👇 Each story then reuses that template +export const FileUploadButton = Template.bind({}); + +FileUploadButton.parameters = { + controls: { + include: [ + "title", + "description", + "action", + "variant", + "errorText", + "url", + "accept", + ], + }, +}; +FileUploadButton.argTypes = { + variant: { + control: { + type: "select", + options: ["default", "compact"], + }, + }, +}; +FileUploadButton.args = { + title: "Banner", + description: "Campaign Banner", + action: { action: "Upload Image" }, + variant: "default", + errorText: "", + url: "", + accept: ".jpg,.png", +}; diff --git a/src/components/core/Button/FileUploadButton/FileUploadButton.tsx b/src/components/core/Button/FileUploadButton/FileUploadButton.tsx new file mode 100644 index 0000000..49c6f65 --- /dev/null +++ b/src/components/core/Button/FileUploadButton/FileUploadButton.tsx @@ -0,0 +1,151 @@ +import * as React from "react"; +import { CrossOutlinedIcon } from "../../../../assets"; +import { FormHelperText } from "../../../inputs/FormHelperText"; +import { Col } from "../../Col"; +import { Row } from "../../Row"; +import { Text } from "../../Text"; +import { Button } from "../Button"; +import { + ActionContainer, + ActionContainerCompact, + CloseButtonContainer, + CloseButtonContainerCompact, + Container, + ImagePreview, + ImagePreviewContainer, + ImagePreviewContainerCompact, + UploadButtonWrapper, +} from "./styles"; +import { iFileUploadButtonProps } from "./types"; + +const FileUploadButton: React.VFC = ({ + title, + description, + variant = "default", + accept, + url, + action, + errorText, + onChange, +}) => { + const inputRef = React.useRef(null); + const hasFile = Boolean(url); + const hasError = Boolean(errorText); + + const MainLayout = variant === "compact" ? Col : Row; + + const onClickUpload = () => { + inputRef.current?.click(); + }; + + const onFileChange: React.ChangeEventHandler = (e) => { + const file = e.target.files?.item(0); + + onChange(file, file ? URL.createObjectURL(file) : undefined); + }; + + const onResetFile = () => { + if (inputRef.current) inputRef.current.value = ""; + onChange(null, undefined); + }; + + return ( + + + {title || description ? ( + + {title && ( + + {title} + + )} + {description && ( + + {description} + + )} + + ) : null} + + + + {variant === "default" ? ( + <> + + {url && } + + + + + {action.description && ( + + {action.description} + + )} + + {url ? ( + + + + ) : null} + + + ) : ( + <> + {url && ( + + + + )} + {!url ? ( + + <> + + {action.description && ( + + {action.description} + + )} + + + ) : ( + + + + )} + + )} + + + + {errorText && ( + + {errorText} + + )} + + ); +}; + +export default FileUploadButton; diff --git a/src/components/core/Button/FileUploadButton/index.ts b/src/components/core/Button/FileUploadButton/index.ts new file mode 100644 index 0000000..39cae37 --- /dev/null +++ b/src/components/core/Button/FileUploadButton/index.ts @@ -0,0 +1,2 @@ +export { default as FileUploadButton } from "./FileUploadButton"; +export * from "./types"; diff --git a/src/components/core/Button/FileUploadButton/styles.ts b/src/components/core/Button/FileUploadButton/styles.ts new file mode 100644 index 0000000..e357d71 --- /dev/null +++ b/src/components/core/Button/FileUploadButton/styles.ts @@ -0,0 +1,125 @@ +import styled from "@emotion/styled"; +import { pxToRem } from "../../../../styles"; +import { Col, iColProps } from "../../Col"; +import { Row } from "../../Row"; +import { iFileUploadButtonProps } from "./types"; + +interface iContainerProps + extends Omit, + Partial { + hasFile?: boolean; + hasError?: boolean; +} + +export const Container = styled(Col)( + ({ hasError = false, hasFile = false, variant, theme }) => ({ + height: variant === "compact" ? 140 : 100, + minHeight: variant === "compact" ? 140 : 100, + width: variant === "compact" ? 140 : "100%", + minWidth: variant === "compact" ? 140 : "100%", + overflow: "hidden", + borderRadius: pxToRem(8), + border: `1px dashed ${theme.palette.interface.black[200]}`, + borderStyle: !hasFile ? "dashed" : "solid", + borderColor: hasError + ? theme.palette.interface.red[500] + : theme.palette.interface.black[200], + + "&>div": { + height: "100%", + }, + }) +); + +export const UploadButtonWrapper = styled(Row)(({ theme }) => ({ + padding: 16, + cursor: "pointer", + "&:hover": { + backgroundColor: theme.palette.interface.black[50], + }, +})); + +export const ImagePreviewContainer = styled.div(({ theme }) => ({ + display: "flex", + flex: 0.3, + height: "100%", + position: "relative", + backgroundColor: theme.palette.interface.black[100], +})); + +export const ImagePreviewContainerCompact = styled.div( + ({ theme }) => ({ + width: "100%", + minWidth: "100%", + maxWidth: "100%", + height: "100%", + position: "relative", + backgroundColor: theme.palette.interface.black[100], + }) +); + +export const ImagePreview = styled.img({ + width: "100%", + height: "100%", + objectFit: "cover", + position: "absolute", + top: 0, + left: 0, +}); + +export const ActionContainer = styled(Col)(() => ({ + flex: 1, + paddingRight: 16, + height: "100%", + alignItems: "flex-start", + justifyContent: "center", +})); + +export const ActionContainerCompact = styled(Col)(({ theme }) => ({ + padding: 16, + height: "100%", + width: "100%", + cursor: "pointer", + alignItems: "center", + justifyContent: "center", + + "&:hover": { + backgroundColor: theme.palette.interface.black[50], + }, +})); + +export const CloseButtonContainer = styled.div(({ theme }) => ({ + display: "flex", + width: 24, + height: 24, + padding: 4, + borderRadius: 8, + justifyContent: "center", + cursor: "pointer", + + "&:hover": { + backgroundColor: theme.palette.interface.black[50], + }, + + "&>svg": { + margin: 0, + }, +})); + +export const CloseButtonContainerCompact = styled.div(({ theme }) => ({ + display: "flex", + alignItems: "center", + justifyContent: "center", + position: "absolute", + top: 8, + right: 8, + width: 28, + height: 28, + borderRadius: "50%", + backgroundColor: theme.palette.interface.white, + cursor: "pointer", + + "&:hover": { + backgroundColor: theme.palette.interface.black[50], + }, +})); diff --git a/src/components/core/Button/FileUploadButton/types.ts b/src/components/core/Button/FileUploadButton/types.ts new file mode 100644 index 0000000..2b70452 --- /dev/null +++ b/src/components/core/Button/FileUploadButton/types.ts @@ -0,0 +1,19 @@ +export interface iFileUploadAction { + action: string; + description?: string; +} + +export type iFileUploadVariant = "default" | "compact"; + +export type iFileChangeHandler = (file?: File | null, url?: string) => void; + +export interface iFileUploadButtonProps { + title?: string; + description?: string; + variant?: iFileUploadVariant; + action: iFileUploadAction; + url?: string | null; + accept?: HTMLInputElement["accept"]; + errorText?: string; + onChange: iFileChangeHandler; +} diff --git a/src/components/core/Button/index.ts b/src/components/core/Button/index.ts index f86a56d..dc57803 100644 --- a/src/components/core/Button/index.ts +++ b/src/components/core/Button/index.ts @@ -1,2 +1,2 @@ -export { default as Button } from "./Button"; -export * from "./types"; +export * from "./Button"; +export * from "./FileUploadButton"; From 5134631863961edb99a24857dd94cbf27ca8d06f Mon Sep 17 00:00:00 2001 From: William Joseph <84491621+williamjosephgada@users.noreply.github.com> Date: Mon, 13 Feb 2023 15:18:31 +0700 Subject: [PATCH 8/9] refactor: add new children props on theme provider (#62) --- src/components/core/ThemeProvider/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/core/ThemeProvider/types.ts b/src/components/core/ThemeProvider/types.ts index 1c4ba4c..e8513bb 100644 --- a/src/components/core/ThemeProvider/types.ts +++ b/src/components/core/ThemeProvider/types.ts @@ -1,6 +1,7 @@ import { iSnackbarProviderProps } from "../../feedback"; export interface iGadaThemeProviderProps { + children: any; withSnackbarProvider?: boolean; snackbarProps?: iSnackbarProviderProps; } From 48073e6e855fb345df9826a406cb393374a3979a Mon Sep 17 00:00:00 2001 From: William Joseph <84491621+williamjosephgada@users.noreply.github.com> Date: Mon, 13 Feb 2023 15:39:40 +0700 Subject: [PATCH 9/9] refactor: add package version (#63) * refactor: add package version * refactor: update package version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5f8b95a..288240b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gudangada/design-system", - "version": "0.1.36", + "version": "0.1.38", "description": "Gada Design System", "main": "lib/index.js", "module": "lib/index.esm.js",