Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/components/ProfilePicture/ProfilePicture.stories.tsx
Original file line number Diff line number Diff line change
@@ -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<ComponentProps<typeof ProfilePicture>> = (props: any) => (
<ProfilePicture {...props} />
);

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',
};
101 changes: 101 additions & 0 deletions src/components/ProfilePicture/ProfilePicture.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
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<string, string> = {
s: '16px',
m: '26px',
l: '36px',
};

const textSizeMap: Record<string, Record<string, string>> = {
s: {
fontWeight: '500',
fontSize: '14px',
lineHeight: '24px',
},
m: {
fontWeight: '500',
fontSize: '24px',
lineHeight: '32px',
},
l: {
fontWeight: '500',
fontSize: '34px',
lineHeight: '44px',
},
};

const ComponentSizeMap: Record<string, Record<string, string>> = {
s: {
width: '40px',
height: '40px',
},
m: {
width: '88px',
height: '88px',
},
l: {
width: '128px',
height: '128px',
},
};

const Component = styled(Flex)<any>(({ theme, size, variant, image }) => ({
...ComponentSizeMap[size],
...theme.PROFILE_PICTURE,
...(variant === 'image' && { backgroundImage: `url(${image})` }),
}));

const StyledText = styled.p<any>(({ size }) => ({
...textSizeMap[size],
}));

const renderChildren = (
variant: string,
text: string | undefined,
size: string,
) => {
if (variant === 'icon') {
return (
<Icon
size={iconSizeMap[size]}
color="brandDarkest"
icon={polyIcons.Account}
variant="basic"
margin="0"
/>
);
} else if (variant === 'text') {
return <StyledText size={size}>{text}</StyledText>;
} else if (variant === 'image') {
return <StyledText size={size}>{text}</StyledText>;
}
};

export const ProfilePicture: FC<ProfilePictureProps> = (props) => {
const { text, variant = 'icon', size = 'm', image } = props;
return (
<Component
size={size}
image={image}
variant={variant}
align="center"
justify="center"
{...props}
>
{renderChildren(variant, text, size)}
</Component>
);
};
1 change: 1 addition & 0 deletions src/components/ProfilePicture/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ProfilePicture';
36 changes: 36 additions & 0 deletions src/components/SelectCard/SelectCard.stories.tsx
Original file line number Diff line number Diff line change
@@ -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<ComponentProps<typeof SelectCard>> = (props: any) => (
<SelectCard {...props} />
);

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: () => {},
};
62 changes: 62 additions & 0 deletions src/components/SelectCard/SelectCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
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<HTMLInputElement>;
};

const Component = styled(Flex)<any>(({ theme }) => ({
...theme.SELECT_CARD,
}));

export const SelectCard: FC<SelectCardProps> = (props) => {
const { title, description, checked, icon, onChange } = props;
const [isActive, setIsActive] = useState(checked ?? false);
return (
<Component
onClick={() => setIsActive(!isActive)}
align="center"
justify="spaced"
{...props}
>
<Flex width="100%" padding="0" justify="spaced" variant="basic">
<Flex padding="0" variant="basic" dir="column">
<Checkbox
variant="basic"
checked={isActive}
onChange={(e) => {
setIsActive(isActive);
onChange(e);
}}
label={
<Text as="span" variant="h6" margin="0 18px">
{title}
</Text>
}
/>
<Text margin="0 0 0 36px" as="span" variant="b2">
{description}
</Text>
</Flex>
{icon && (
<Icon
size="48px"
color={isActive ? 'brandMain' : 'gray1'}
bg={isActive ? 'brandLightest' : 'gray5'}
icon={icon}
variant="circle"
margin="0"
/>
)}
</Flex>
</Component>
);
};
1 change: 1 addition & 0 deletions src/components/SelectCard/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './SelectCard';
6 changes: 6 additions & 0 deletions src/components/Text/Text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
20 changes: 19 additions & 1 deletion src/theme/definitions/launchpad.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
Expand Down Expand Up @@ -842,6 +842,24 @@ export const INFOBOXTITLE: Record<InfoBoxVariant, CSSPropertiesExtended> = {
},
};

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<ChipsVariant, CSSPropertiesExtended> = {
default: {
...TYPOGRAPHY.b2m,
Expand Down