diff --git a/app/client/src/assets/icons/ads/bag.svg b/app/client/src/assets/icons/ads/bag.svg new file mode 100644 index 0000000000..04096a467d --- /dev/null +++ b/app/client/src/assets/icons/ads/bag.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/client/src/assets/icons/ads/book.svg b/app/client/src/assets/icons/ads/book.svg new file mode 100644 index 0000000000..f016135fcd --- /dev/null +++ b/app/client/src/assets/icons/ads/book.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/app/client/src/assets/icons/ads/calender.svg b/app/client/src/assets/icons/ads/calender.svg new file mode 100644 index 0000000000..8be12ddf06 --- /dev/null +++ b/app/client/src/assets/icons/ads/calender.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/client/src/assets/icons/ads/camera.svg b/app/client/src/assets/icons/ads/camera.svg new file mode 100644 index 0000000000..d1b23590c0 --- /dev/null +++ b/app/client/src/assets/icons/ads/camera.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/app/client/src/assets/icons/ads/chat.svg b/app/client/src/assets/icons/ads/chat.svg new file mode 100644 index 0000000000..6fbbcfc754 --- /dev/null +++ b/app/client/src/assets/icons/ads/chat.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/client/src/assets/icons/ads/file.svg b/app/client/src/assets/icons/ads/file.svg new file mode 100644 index 0000000000..4e83e5a8ae --- /dev/null +++ b/app/client/src/assets/icons/ads/file.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/client/src/assets/icons/ads/flight.svg b/app/client/src/assets/icons/ads/flight.svg new file mode 100644 index 0000000000..0a6daa90ab --- /dev/null +++ b/app/client/src/assets/icons/ads/flight.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/client/src/assets/icons/ads/frame.svg b/app/client/src/assets/icons/ads/frame.svg new file mode 100644 index 0000000000..3bd9d4a502 --- /dev/null +++ b/app/client/src/assets/icons/ads/frame.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/app/client/src/assets/icons/ads/globe.svg b/app/client/src/assets/icons/ads/globe.svg new file mode 100644 index 0000000000..228290a5d6 --- /dev/null +++ b/app/client/src/assets/icons/ads/globe.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/client/src/assets/icons/ads/heart.svg b/app/client/src/assets/icons/ads/heart.svg new file mode 100644 index 0000000000..372367768d --- /dev/null +++ b/app/client/src/assets/icons/ads/heart.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/client/src/assets/icons/ads/product.svg b/app/client/src/assets/icons/ads/product.svg new file mode 100644 index 0000000000..9237160df7 --- /dev/null +++ b/app/client/src/assets/icons/ads/product.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/client/src/assets/icons/ads/shopper.svg b/app/client/src/assets/icons/ads/shopper.svg new file mode 100644 index 0000000000..e8deb2e930 --- /dev/null +++ b/app/client/src/assets/icons/ads/shopper.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/client/src/components/ads/AppIcon.tsx b/app/client/src/components/ads/AppIcon.tsx new file mode 100644 index 0000000000..fe8fd23ce5 --- /dev/null +++ b/app/client/src/components/ads/AppIcon.tsx @@ -0,0 +1,115 @@ +import React from "react"; +import { ReactComponent as BagIcon } from "assets/icons/ads/bag.svg"; +import { ReactComponent as ProductIcon } from "assets/icons/ads/product.svg"; +import { ReactComponent as BookIcon } from "assets/icons/ads/book.svg"; +import { ReactComponent as CameraIcon } from "assets/icons/ads/camera.svg"; +import { ReactComponent as FileIcon } from "assets/icons/ads/file.svg"; +import { ReactComponent as ChatIcon } from "assets/icons/ads/chat.svg"; +import { ReactComponent as CalenderIcon } from "assets/icons/ads/calender.svg"; +import { ReactComponent as FrameIcon } from "assets/icons/ads/frame.svg"; +import { ReactComponent as GlobeIcon } from "assets/icons/ads/globe.svg"; +import { ReactComponent as ShopperIcon } from "assets/icons/ads/shopper.svg"; +import { ReactComponent as HeartIcon } from "assets/icons/ads/heart.svg"; +import { ReactComponent as FlightIcon } from "assets/icons/ads/flight.svg"; + +import styled from "styled-components"; +import { Size } from "./Button"; + +export enum AppIconName { + BAG = "bag", + PRODUCT = "product", + BOOK = "book", + CAMERA = "camera", + FILE = "file", + CHAT = "chat", + CALENDER = "calender", + FLIGHT = "flight", + FRAME = "frame", + GLOBE = "globe", + SHOPPER = "shopper", + HEART = "heart", +} + +export const sizeHandler = (size: Size) => { + let iconSize = 0; + switch (size) { + case Size.small: + iconSize = 20; + break; + case Size.medium: + iconSize = 30; + break; + case Size.large: + iconSize = 54; + break; + } + return iconSize; +}; + +const IconWrapper = styled.div` + cursor: pointer; + &:focus { + outline: none; + } + display: flex; + svg { + width: ${props => sizeHandler(props.size)}px; + height: ${props => sizeHandler(props.size)}px; + path { + fill: ${props => props.theme.colors.blackShades[9]}; + } + } +`; + +export type AppIconProps = { + size: Size; + name: AppIconName; +}; + +const AppIcon = (props: AppIconProps) => { + let returnIcon; + switch (props.name) { + case AppIconName.BAG: + returnIcon = ; + break; + case AppIconName.PRODUCT: + returnIcon = ; + break; + case AppIconName.BOOK: + returnIcon = ; + break; + case AppIconName.CAMERA: + returnIcon = ; + break; + case AppIconName.FILE: + returnIcon = ; + break; + case AppIconName.CHAT: + returnIcon = ; + break; + case AppIconName.CALENDER: + returnIcon = ; + break; + case AppIconName.FRAME: + returnIcon = ; + break; + case AppIconName.GLOBE: + returnIcon = ; + break; + case AppIconName.SHOPPER: + returnIcon = ; + break; + case AppIconName.HEART: + returnIcon = ; + break; + case AppIconName.FLIGHT: + returnIcon = ; + break; + default: + returnIcon = null; + break; + } + return returnIcon ? {returnIcon} : null; +}; + +export default AppIcon; diff --git a/app/client/src/components/ads/Button.tsx b/app/client/src/components/ads/Button.tsx index 21a969a2cc..38329daf44 100644 --- a/app/client/src/components/ads/Button.tsx +++ b/app/client/src/components/ads/Button.tsx @@ -1,7 +1,7 @@ import React from "react"; import { CommonComponentProps, hexToRgba, ThemeProp } from "./common"; import styled from "styled-components"; -import { IconName, Icon } from "./Icon"; +import Icon, { IconName } from "./Icon"; import Spinner from "./Spinner"; import { mediumButton, @@ -233,7 +233,7 @@ const btnFontStyles = (props: ThemeProp & ButtonProps): BtnFontType => { buttonFont = largeButton; padding = !props.text && props.icon - ? `${props.theme.spaces[5] - 1}px ${props.theme.spaces[5] - 1}px` + ? `${props.theme.spaces[3]}px` : `${props.theme.spaces[5] - 1}px ${props.theme.spaces[12] - 4}px`; break; } diff --git a/app/client/src/components/ads/Icon.tsx b/app/client/src/components/ads/Icon.tsx index 8cb876cb1a..c662dcda7c 100644 --- a/app/client/src/components/ads/Icon.tsx +++ b/app/client/src/components/ads/Icon.tsx @@ -3,6 +3,7 @@ import { ReactComponent as DeleteIcon } from "assets/icons/ads/delete.svg"; import { ReactComponent as UserIcon } from "assets/icons/ads/user.svg"; import { ReactComponent as GeneralIcon } from "assets/icons/ads/general.svg"; import { ReactComponent as BillingIcon } from "assets/icons/ads/billing.svg"; + import styled from "styled-components"; import { Size } from "./Button"; import { sizeHandler } from "./Spinner"; @@ -48,42 +49,36 @@ export type IconProps = { size?: Size; name?: IconName; invisible?: boolean; + className?: string; }; -export const Icon = (props: IconProps) => { +const Icon = (props: IconProps) => { let returnIcon; switch (props.name) { case "delete": - returnIcon = ( - - - - ); + returnIcon = ; break; case "user": - returnIcon = ( - - - - ); + returnIcon = ; break; case "general": - returnIcon = ( - - - - ); + returnIcon = ; break; case "billing": - returnIcon = ( - - - - ); + returnIcon = ; break; default: returnIcon = null; break; } - return returnIcon; + return returnIcon ? ( + + {returnIcon} + + ) : null; }; + +export default Icon; diff --git a/app/client/src/components/ads/IconSelector.tsx b/app/client/src/components/ads/IconSelector.tsx index 49d7b8304c..c0f354960f 100644 --- a/app/client/src/components/ads/IconSelector.tsx +++ b/app/client/src/components/ads/IconSelector.tsx @@ -1,10 +1,95 @@ +import React, { useState, useEffect } from "react"; +import styled from "styled-components"; +import AppIcon, { AppIconName } from "./AppIcon"; +import { Size } from "./Button"; import { CommonComponentProps } from "./common"; -import { IconName } from "./Icon"; + +export const appIconPalette = [ + AppIconName.BAG, + AppIconName.PRODUCT, + AppIconName.BOOK, + AppIconName.CAMERA, + AppIconName.FILE, + AppIconName.CHAT, + AppIconName.CALENDER, + AppIconName.FLIGHT, + AppIconName.FRAME, + AppIconName.GLOBE, + AppIconName.SHOPPER, + AppIconName.HEART, +]; type IconSelectorProps = CommonComponentProps & { - onSelect: (icon: IconName) => void; + onSelect?: (icon: AppIconName) => void; + selectedColor: string; + selectedIcon?: AppIconName; + iconPalette?: AppIconName[]; + fill?: boolean; }; -export default function IconSelector(props: IconSelectorProps) { - return null; -} +const IconPalette = styled.div<{ fill?: boolean }>` + display: flex; + align-items: center; + flex-wrap: wrap; + width: ${props => (props.fill ? "100%" : "234px")}; +`; + +const IconBox = styled.div<{ + iconName: AppIconName; + selected: AppIconName; + bgColor: string; +}>` + padding: ${props => props.theme.spaces[2]}px + ${props => props.theme.spaces[2] - 1}px; + margin: 0 ${props => props.theme.spaces[2]}px + ${props => props.theme.spaces[2]}px 0; + background-color: ${props => + props.selected === props.iconName + ? props.bgColor + : props.theme.colors.blackShades[2]}; + cursor: pointer; + position: relative; + + &:last-child { + margin-right: ${props => props.theme.spaces[0]}px; + } +`; + +const IconSelector = (props: IconSelectorProps) => { + const [selected, setSelected] = useState(appIconPalette[0]); + + useEffect(() => { + if (props.selectedIcon) { + setSelected(props.selectedIcon); + } + }, [props.selectedIcon]); + + return ( + + {props.iconPalette && + props.iconPalette.map((iconName: AppIconName, index: number) => { + return ( + { + setSelected(iconName); + props.onSelect && props.onSelect(iconName); + }} + > + + + ); + })} + + ); +}; + +IconSelector.defaultProps = { + fill: false, + iconPalette: appIconPalette, +}; + +export default IconSelector; diff --git a/app/client/src/components/ads/Tabs.tsx b/app/client/src/components/ads/Tabs.tsx index c5ade3092e..68f5303705 100644 --- a/app/client/src/components/ads/Tabs.tsx +++ b/app/client/src/components/ads/Tabs.tsx @@ -2,7 +2,7 @@ import React from "react"; import { Tab, Tabs, TabList, TabPanel } from "react-tabs"; import "react-tabs/style/react-tabs.css"; import styled from "styled-components"; -import { Icon, IconName } from "./Icon"; +import Icon, { IconName } from "./Icon"; import { Size } from "./Button"; const TabsWrapper = styled.div<{ shouldOverflow?: boolean }>` diff --git a/app/client/src/components/stories/Icon.stories.tsx b/app/client/src/components/stories/Icon.stories.tsx index abe8509877..7e267cad2d 100644 --- a/app/client/src/components/stories/Icon.stories.tsx +++ b/app/client/src/components/stories/Icon.stories.tsx @@ -1,8 +1,9 @@ import React from "react"; -import { Icon } from "../ads/Icon"; import Button, { Size, Category, Variant } from "components/ads/Button"; import { withKnobs, select, boolean } from "@storybook/addon-knobs"; import { withDesign } from "storybook-addon-designs"; +import Icon from "../ads/Icon"; +import AppIcon, { AppIconName } from "../ads/AppIcon"; export default { title: "Icon", @@ -11,29 +12,57 @@ export default { }; export const ButtonIcon = () => ( - +
+ +
); export const BordelessIcon = () => ( -
+
); + +export const BorderlessAppIcon = () => ( +
+ +
+); diff --git a/app/client/src/components/stories/IconSelector.stories.tsx b/app/client/src/components/stories/IconSelector.stories.tsx new file mode 100644 index 0000000000..9058aad848 --- /dev/null +++ b/app/client/src/components/stories/IconSelector.stories.tsx @@ -0,0 +1,54 @@ +import React from "react"; +import { withKnobs, select, boolean, text } from "@storybook/addon-knobs"; +import { withDesign } from "storybook-addon-designs"; +import IconSelector from "../ads/IconSelector"; +import { action } from "@storybook/addon-actions"; +import { AppIconName } from "../ads/AppIcon"; + +export default { + title: "IconSelector", + component: IconSelector, + decorators: [withKnobs, withDesign], +}; + +export const IconPicker = () => ( +
+ +
+); diff --git a/app/client/src/components/stories/Table.stories.tsx b/app/client/src/components/stories/Table.stories.tsx index 5144f8ae7f..1e40156835 100644 --- a/app/client/src/components/stories/Table.stories.tsx +++ b/app/client/src/components/stories/Table.stories.tsx @@ -1,7 +1,7 @@ import React from "react"; import Table from "../ads/Table"; import Button, { Category, Variant, Size } from "../ads/Button"; -import { Icon } from "../ads/Icon"; +import Icon from "../ads/Icon"; export default { title: "Table",