From 6c728c98f04f963e2c128754af3d6071ffe9f4ee Mon Sep 17 00:00:00 2001 From: Ashish Date: Wed, 26 Oct 2022 19:53:18 +0530 Subject: [PATCH 1/2] feat: new ProfilePicture and SelectCard components --- .../ProfilePicture/ProfilePicture.stories.tsx | 24 +++++ .../ProfilePicture/ProfilePicture.tsx | 90 +++++++++++++++++++ src/components/ProfilePicture/index.ts | 1 + .../SelectCard/SelectCard.stories.tsx | 36 ++++++++ src/components/SelectCard/SelectCard.tsx | 51 +++++++++++ src/components/SelectCard/index.ts | 1 + src/components/Text/Text.tsx | 6 ++ src/index.ts | 2 + src/theme/definitions/launchpad.ts | 20 ++++- 9 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 src/components/ProfilePicture/ProfilePicture.stories.tsx create mode 100644 src/components/ProfilePicture/ProfilePicture.tsx create mode 100644 src/components/ProfilePicture/index.ts create mode 100644 src/components/SelectCard/SelectCard.stories.tsx create mode 100644 src/components/SelectCard/SelectCard.tsx create mode 100644 src/components/SelectCard/index.ts diff --git a/src/components/ProfilePicture/ProfilePicture.stories.tsx b/src/components/ProfilePicture/ProfilePicture.stories.tsx new file mode 100644 index 0000000..c9e4e89 --- /dev/null +++ b/src/components/ProfilePicture/ProfilePicture.stories.tsx @@ -0,0 +1,24 @@ +import { ComponentProps } from 'react'; +import { Story } from '@storybook/react'; + +import { ProfilePicture } from './ProfilePicture'; + +export default { + title: 'Polyblocks/ProfilePicture', + component: ProfilePicture, +}; + +const Template: Story> = (props: any) => ( + +); + +export const WithIcon = Template.bind({}); +WithIcon.args = { + variant: 'icon', +}; + +export const WithImage = Template.bind({}); +WithImage.args = { + variant: 'image', + image: 'https://www.w3schools.com/howto/img_avatar2.png' +}; diff --git a/src/components/ProfilePicture/ProfilePicture.tsx b/src/components/ProfilePicture/ProfilePicture.tsx new file mode 100644 index 0000000..428a301 --- /dev/null +++ b/src/components/ProfilePicture/ProfilePicture.tsx @@ -0,0 +1,90 @@ +import { FC } from 'react'; +import styled from 'styled-components'; +import { Flex } from '../Flex'; +import { polyIcons } from '../../theme/icons'; +import { Icon } from '../Icon'; + +export type ProfilePictureVariant = 'text' | 'icon' | 'image'; + +export type ProfilePictureProps = { + text?: string; + image?: string; + variant?: ProfilePictureVariant; + size?: 's' | 'm' | 'l'; +}; + +const iconSizeMap: Record = { + s: '16px', + m: '26px', + l: '36px', +}; + +const textSizeMap: Record> = { + s: { + fontWeight: '500', + fontSize: '14px', + lineHeight: '24px', + }, + m: { + fontWeight: '500', + fontSize: '24px', + lineHeight: '32px', + }, + l: { + fontWeight: '500', + fontSize: '34px', + lineHeight: '44px', + }, +}; + +const ComponentSizeMap: Record> = { + s: { + width: '40px', + height: '40px', + }, + m: { + width: '88px', + height: '88px', + }, + l: { + width: '128px', + height: '128px', + }, +}; + +const Component = styled(Flex)(({ theme, size, variant, image }) => ({ + ...ComponentSizeMap[size], + ...theme.PROFILE_PICTURE, + ...(variant === 'image' && { backgroundImage: `url(${image})` }) +})); + +const StyledText = styled.p(({ size }) => ({ + ...textSizeMap[size] +})); + +const renderChildren = (variant: string, text: string | undefined, size: string) => { + if (variant === 'icon') { + return ( + + ) + } else if (variant === 'text') { + return {text}; + } else if (variant === 'image') { + return {text}; + } +} + +export const ProfilePicture: FC = (props) => { + const { text, variant = 'icon', size = 'm', image } = props; + return ( + + {renderChildren(variant, text, size)} + + ); +}; diff --git a/src/components/ProfilePicture/index.ts b/src/components/ProfilePicture/index.ts new file mode 100644 index 0000000..7399757 --- /dev/null +++ b/src/components/ProfilePicture/index.ts @@ -0,0 +1 @@ +export * from './ProfilePicture'; diff --git a/src/components/SelectCard/SelectCard.stories.tsx b/src/components/SelectCard/SelectCard.stories.tsx new file mode 100644 index 0000000..c7d0bc3 --- /dev/null +++ b/src/components/SelectCard/SelectCard.stories.tsx @@ -0,0 +1,36 @@ +import { ComponentProps } from 'react'; +import { Story } from '@storybook/react'; +import { polyIcons } from '../../theme'; +import { SelectCard } from './SelectCard'; + +export default { + title: 'Polyblocks/SelectCard', + component: SelectCard, +}; + +const Template: Story> = (props: any) => ( + +); + +export const Basic = Template.bind({}); +Basic.args = { + title: 'Card title', + description: 'Some description text here.', + onChange: () => {} +}; + +export const Checked = Template.bind({}); +Checked.args = { + title: 'Card title', + description: 'Some description text here.', + checked: true, + onChange: () => {} +}; + +export const WithIcon = Template.bind({}); +WithIcon.args = { + title: 'Card title', + description: 'Some description text here.', + icon: polyIcons.Image, + onChange: () => {} +}; \ No newline at end of file diff --git a/src/components/SelectCard/SelectCard.tsx b/src/components/SelectCard/SelectCard.tsx new file mode 100644 index 0000000..424d4aa --- /dev/null +++ b/src/components/SelectCard/SelectCard.tsx @@ -0,0 +1,51 @@ +import { ComponentType, FC, ChangeEventHandler, useState } from 'react'; +import styled from 'styled-components'; +import { Flex } from '../Flex'; +import { Text } from '../Text'; +import { Checkbox } from '../Checkbox'; +import { Icon } from '../Icon'; + +export type SelectCardProps = { + title?: string; + description?: string; + icon?: ComponentType; + checked?: boolean, + onChange: ChangeEventHandler; +}; + +const Component = styled(Flex)(({ theme }) => ({ + ...theme.SELECT_CARD, +})); + +export const SelectCard: FC = (props) => { + const { title, description, checked, icon, onChange } = props; + const [isActive, setIsActive] = useState(checked ?? false); + return ( + setIsActive(!isActive)} align="center" justify="spaced" {...props}> + + + { + setIsActive(isActive); + onChange(e) + }} + label={{title}} + /> + {description} + + {icon && ( + + )} + + + ); +}; diff --git a/src/components/SelectCard/index.ts b/src/components/SelectCard/index.ts new file mode 100644 index 0000000..cdc4167 --- /dev/null +++ b/src/components/SelectCard/index.ts @@ -0,0 +1 @@ +export * from './SelectCard'; diff --git a/src/components/Text/Text.tsx b/src/components/Text/Text.tsx index f41893d..9773c53 100644 --- a/src/components/Text/Text.tsx +++ b/src/components/Text/Text.tsx @@ -6,6 +6,12 @@ import { getMargin } from '../../theme/utils'; export type TextAs = 'p' | 'span' | 'label'; export type TextVariant = + | 'h1' + | 'h2' + | 'h3' + | 'h4' + | 'h5' + | 'h6' | 'b1m' | 'b1' | 'b2m' diff --git a/src/index.ts b/src/index.ts index 620542e..296d0ee 100644 --- a/src/index.ts +++ b/src/index.ts @@ -56,3 +56,5 @@ export * from './components/Loader'; export * from './components/ProgressBar'; export * from './components/TabBar'; export * from './components/Table'; +export * from './components/ProfilePicture'; +export * from './components/SelectCard'; diff --git a/src/theme/definitions/launchpad.ts b/src/theme/definitions/launchpad.ts index 1f933bf..db30a61 100644 --- a/src/theme/definitions/launchpad.ts +++ b/src/theme/definitions/launchpad.ts @@ -150,7 +150,7 @@ export const TYPOGRAPHY: any = { h6: { margin: `0 0 ${GAP.s} 0`, lineHeight: '27px', - fontWeight: 400, + fontWeight: 500, fontSize: '18px', color: COLOR.gray1, }, @@ -842,6 +842,24 @@ export const INFOBOXTITLE: Record = { }, }; +export const PROFILE_PICTURE: CSSPropertiesExtended = { + borderRadius: '100px', + background: COLOR.brandLightest, + backgroundSize: 'contain' +}; +export const SELECT_CARD: CSSPropertiesExtended = { + padding: '16px', + border: `1px solid ${COLOR.gray4}`, + borderRadius: RADIUS.xl, + cursor: 'pointer', + '&:hover': { + border: `1px solid ${COLOR.gray1}`, + }, + '&:active': { + border: `1px solid ${COLOR.brandMain}`, + }, +} + export const CHIPS: Record = { default: { ...TYPOGRAPHY.b2m, From 6cd88d94d5f96a170e2fb8cdde98b208531a5ef2 Mon Sep 17 00:00:00 2001 From: Ashish Date: Wed, 26 Oct 2022 19:55:07 +0530 Subject: [PATCH 2/2] feat: linting fixes --- .../ProfilePicture/ProfilePicture.stories.tsx | 2 +- .../ProfilePicture/ProfilePicture.tsx | 23 +++++++++++---- .../SelectCard/SelectCard.stories.tsx | 8 ++--- src/components/SelectCard/SelectCard.tsx | 29 +++++++++++++------ src/theme/definitions/launchpad.ts | 4 +-- 5 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/components/ProfilePicture/ProfilePicture.stories.tsx b/src/components/ProfilePicture/ProfilePicture.stories.tsx index c9e4e89..e5488b4 100644 --- a/src/components/ProfilePicture/ProfilePicture.stories.tsx +++ b/src/components/ProfilePicture/ProfilePicture.stories.tsx @@ -20,5 +20,5 @@ WithIcon.args = { export const WithImage = Template.bind({}); WithImage.args = { variant: 'image', - image: 'https://www.w3schools.com/howto/img_avatar2.png' + image: 'https://www.w3schools.com/howto/img_avatar2.png', }; diff --git a/src/components/ProfilePicture/ProfilePicture.tsx b/src/components/ProfilePicture/ProfilePicture.tsx index 428a301..1f67de1 100644 --- a/src/components/ProfilePicture/ProfilePicture.tsx +++ b/src/components/ProfilePicture/ProfilePicture.tsx @@ -55,14 +55,18 @@ const ComponentSizeMap: Record> = { const Component = styled(Flex)(({ theme, size, variant, image }) => ({ ...ComponentSizeMap[size], ...theme.PROFILE_PICTURE, - ...(variant === 'image' && { backgroundImage: `url(${image})` }) + ...(variant === 'image' && { backgroundImage: `url(${image})` }), })); const StyledText = styled.p(({ size }) => ({ - ...textSizeMap[size] + ...textSizeMap[size], })); -const renderChildren = (variant: string, text: string | undefined, size: string) => { +const renderChildren = ( + variant: string, + text: string | undefined, + size: string, +) => { if (variant === 'icon') { return ( - ) + ); } else if (variant === 'text') { return {text}; } else if (variant === 'image') { return {text}; } -} +}; export const ProfilePicture: FC = (props) => { const { text, variant = 'icon', size = 'm', image } = props; return ( - + {renderChildren(variant, text, size)} ); diff --git a/src/components/SelectCard/SelectCard.stories.tsx b/src/components/SelectCard/SelectCard.stories.tsx index c7d0bc3..d4099c0 100644 --- a/src/components/SelectCard/SelectCard.stories.tsx +++ b/src/components/SelectCard/SelectCard.stories.tsx @@ -16,7 +16,7 @@ export const Basic = Template.bind({}); Basic.args = { title: 'Card title', description: 'Some description text here.', - onChange: () => {} + onChange: () => {}, }; export const Checked = Template.bind({}); @@ -24,7 +24,7 @@ Checked.args = { title: 'Card title', description: 'Some description text here.', checked: true, - onChange: () => {} + onChange: () => {}, }; export const WithIcon = Template.bind({}); @@ -32,5 +32,5 @@ WithIcon.args = { title: 'Card title', description: 'Some description text here.', icon: polyIcons.Image, - onChange: () => {} -}; \ No newline at end of file + onChange: () => {}, +}; diff --git a/src/components/SelectCard/SelectCard.tsx b/src/components/SelectCard/SelectCard.tsx index 424d4aa..ad00509 100644 --- a/src/components/SelectCard/SelectCard.tsx +++ b/src/components/SelectCard/SelectCard.tsx @@ -9,7 +9,7 @@ export type SelectCardProps = { title?: string; description?: string; icon?: ComponentType; - checked?: boolean, + checked?: boolean; onChange: ChangeEventHandler; }; @@ -21,25 +21,36 @@ export const SelectCard: FC = (props) => { const { title, description, checked, icon, onChange } = props; const [isActive, setIsActive] = useState(checked ?? false); return ( - setIsActive(!isActive)} align="center" justify="spaced" {...props}> - - + setIsActive(!isActive)} + align="center" + justify="spaced" + {...props} + > + + { setIsActive(isActive); - onChange(e) + onChange(e); }} - label={{title}} + label={ + + {title} + + } /> - {description} + + {description} + {icon && ( = { export const PROFILE_PICTURE: CSSPropertiesExtended = { borderRadius: '100px', background: COLOR.brandLightest, - backgroundSize: 'contain' + backgroundSize: 'contain', }; export const SELECT_CARD: CSSPropertiesExtended = { padding: '16px', @@ -858,7 +858,7 @@ export const SELECT_CARD: CSSPropertiesExtended = { '&:active': { border: `1px solid ${COLOR.brandMain}`, }, -} +}; export const CHIPS: Record = { default: {