Skip to content

Commit

Permalink
Add storybook catalog
Browse files Browse the repository at this point in the history
  • Loading branch information
vbifonixor committed Feb 21, 2022
1 parent c497350 commit d594af9
Show file tree
Hide file tree
Showing 4 changed files with 291 additions and 0 deletions.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -59,6 +59,7 @@
"terser-webpack-plugin": "^5.2.5",
"typescript": "^4.4.2",
"url-loader": "^4.1.1",
"use-clipboard-copy": "^0.2.0",
"web-vitals": "^2.1.0",
"webpack": "^5.64.4",
"webpack-dev-server": "^4.6.0",
Expand Down
48 changes: 48 additions & 0 deletions src/components/Icon/stories/IconStand.tsx
@@ -0,0 +1,48 @@
import React, {useCallback, useState} from 'react';
import {Icon} from '../';
import {useClipboard} from 'use-clipboard-copy';
import './styles.css';

type Props = {
children: JSX.Element;
name: string;
type: string;
color?: string;
};

const getIconCode = (type: string, name: string) =>
`<Icon type="${type}" name="${name}" />`;

export const IconStand = ({children, name, type, color}: Props) => {
const clipboard = useClipboard();

const [copySuccess, setCopySuccess] = useState(false);

const handleCopyName = useCallback(() => {
clipboard.copy(getIconCode(type, name));
setCopySuccess(true);
setTimeout(() => setCopySuccess(false), 1000);
}, [type, name, clipboard]);

return (
<div className={`iconStand ${type}`}>
<div className="iconStand-icon" style={{color}}>
{children}
</div>
<div className="iconStand-name" onClick={handleCopyName}>
<span className="iconStand-nameText">{name}</span>
<span
className={`iconStand-nameCopyIcon ${
copySuccess ? 'success' : 'neutral'
}`}
>
{copySuccess ? (
<Icon type="mono" name="check" />
) : (
<Icon type="mono" name="clipboard" />
)}
</span>
</div>
</div>
);
};
137 changes: 137 additions & 0 deletions src/components/Icon/stories/icon.stories.tsx
@@ -0,0 +1,137 @@
import React from 'react';

import {ComponentStory, ComponentMeta} from '@storybook/react';

import {Icon} from '../';
import catalog from '../catalog.json';
import {IconStand} from './IconStand';
import {
IllustrationsNames,
MonochromeIconNames,
MulticolorIconNames,
} from '../iconNames';
import './styles.css';

export default {
title: 'Icon',
controls: {
hideNoControlsWarning: true,
},
argTypes: {},
} as ComponentMeta<typeof Icon>;

const MonochromeCupboard = ({color}: {color: string}) => (
<div className="wrapper">
<h1 className="heading">Monochrome Icons</h1>
<div className="container">
{catalog.mono.map((iconName) => {
return (
<div className="item">
<IconStand
name={iconName}
key={`mono-${iconName}`}
type="mono"
color={color}
>
<Icon
name={iconName as MonochromeIconNames}
type="mono"
/>
</IconStand>
</div>
);
})}
</div>
</div>
);

export const Monochrome: ComponentStory<typeof MonochromeCupboard> =
({color}) => {
return <MonochromeCupboard color={color} />;
};

Monochrome.argTypes = {
color: {
control: {
type: 'color',
presetColors: [
{color: '#f368e0', title: 'Lian Hong Lotus Pink'},
{color: '#feca57', title: 'Casandora Yellow'},
{color: '#ff6b6b', title: 'Pastel Red'},
{color: '#48dbfb', title: 'Megaman'},
{color: '#1dd1a1', title: 'Wild Carribean Green'},
{color: '#00d2d3', title: 'Jade Dust'},
{color: '#54a0ff', title: 'Joust Blue'},
{color: '#5f27cd', title: 'Nasu Purple'},
{color: '#222f3e', title: 'Imperial Primer'},
],
},
},
};

Monochrome.args = {
color: '#222f3e',
};

const MulticolorCupboard = () => (
<div className="wrapper">
<h1 className="heading">Multicolor Icons</h1>
<div className="container">
{catalog.multi.map((iconName) => {
return (
<div className="item">
<IconStand
name={iconName}
key={`multi-${iconName}`}
type="multi"
>
<Icon
name={iconName as MulticolorIconNames}
type="multi"
/>
</IconStand>
</div>
);
})}
</div>
</div>
);

export const Multicolor: ComponentStory<typeof MulticolorCupboard> =
() => {
return <MulticolorCupboard />;
};

const IllustrationCupboard = ({name}: {name: IllustrationsNames}) => (
<div className="wrapper">
<h1 className="heading">Illustration</h1>
<div className="container illustration">
<IconStand
name={name}
key={`illustration-${name}`}
type="illustration"
>
<Icon name={name} type="illustration" />
</IconStand>
</div>
</div>
);

export const Illustration: ComponentStory<
typeof IllustrationCupboard
> = ({name}: {name: IllustrationsNames}) => (
<IllustrationCupboard name={name} />
);

Illustration.argTypes = {
name: {
control: {
type: 'select',
options: catalog.illustration as IllustrationsNames[],
},
},
};

Illustration.args = {
name: catalog.illustration[0] as IllustrationsNames,
};
105 changes: 105 additions & 0 deletions src/components/Icon/stories/styles.css
@@ -0,0 +1,105 @@
.wrapper {
display: flex;
flex-direction: column;
align-items: center;
}

.heading {
font-family: sans-serif;
font-size: 36px;
margin-bottom: 40px;
}

.container {
display: flex;
flex-wrap: wrap;
max-width: 95vw;
margin: 0 auto;
align-items: stretch;
justify-content: center;
}

.container.illustration {
width: 50vw;
}

.item {
display: flex;
width: 15%;
justify-content: center;
margin-bottom: 35px;
}

.iconStand {
width: 70%;
padding: 10px;
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1),
0 8px 10px -6px rgb(0 0 0 / 0.1);
border-radius: 0.5rem;
border: 1px solid rgba(0, 0, 0, 0.05);
}

.iconStand.illustration {
width: 100%;
box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
}

.iconStand-icon {
width: 50%;
margin-bottom: 16px;
}

.iconStand.illustration .iconStand-icon {
width: 85%;
min-width: 350px;
min-height: 260px;
padding: 40px;
box-sizing: border-box;
}

.iconStand-name {
font-family: monospace;
font-size: 12px;
font-weight: 300;
text-align: center;
background-color: #fafafa;
border: 1px solid #f0f0f0;
box-sizing: border-box;
width: 100%;
padding: 2px 4px;
border-radius: 0.25rem;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1),
0 1px 2px -1px rgb(0 0 0 / 0.1);
}

.iconStand.illustration .iconStand-name {
font-size: 16px;
padding: 4px 8px;
height: auto;
}

.iconStand-nameText {
width: calc(100% - 16px);
}

.iconStand-nameCopyIcon {
width: 12px;
height: 12px;
}

.iconStand-nameCopyIcon.success {
color: #1dd1a1;
}

.iconStand-nameCopyIcon.neutral {
color: #576574;
}

0 comments on commit d594af9

Please sign in to comment.