diff --git a/.storybook/main.js b/.storybook/main.js new file mode 100644 index 0000000..1240c76 --- /dev/null +++ b/.storybook/main.js @@ -0,0 +1,16 @@ +module.exports = { + "stories": [ + "../src/**/*.stories.mdx", + "../src/**/*.stories.@(js|jsx|ts|tsx)" + ], + "addons": [ + "@storybook/addon-links", + "@storybook/addon-essentials", + "@storybook/addon-interactions", + "@storybook/preset-create-react-app" + ], + "framework": "@storybook/react", + "core": { + "builder": "@storybook/builder-webpack5" + } +} \ No newline at end of file diff --git a/.storybook/preview.js b/.storybook/preview.js new file mode 100644 index 0000000..48afd56 --- /dev/null +++ b/.storybook/preview.js @@ -0,0 +1,9 @@ +export const parameters = { + actions: { argTypesRegex: "^on[A-Z].*" }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/, + }, + }, +} \ No newline at end of file diff --git a/src/.storybook/main.js b/src/.storybook/main.js new file mode 100644 index 0000000..d9d81a8 --- /dev/null +++ b/src/.storybook/main.js @@ -0,0 +1,23 @@ +module.exports = { + stories: ['../**/*.stories.mdx', '../**/*.stories.@(js|jsx|ts|tsx)'], + /** Expose public folder to storybook as static */ + staticDirs: ['../public'], + addons: [ + '@storybook/addon-links', + '@storybook/addon-essentials', + '@storybook/addon-interactions', + 'storybook-css-modules-preset', + { + name: '@storybook/addon-postcss', + options: { + postcssLoaderOptions: { + implementation: require('postcss'), + }, + }, + }, + ], + framework: '@storybook/react', + core: { + builder: '@storybook/builder-webpack5', + }, + }; \ No newline at end of file diff --git a/src/.storybook/preview.js b/src/.storybook/preview.js new file mode 100644 index 0000000..1aada3d --- /dev/null +++ b/src/.storybook/preview.js @@ -0,0 +1,3 @@ +export const parameters = { + actions: { argTypesRegex: "^on[A-Z].*" }, + } \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index 4e529cc..69002fa 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -10,9 +10,7 @@ import React from "react"; * @return {JSX.Element} */ function App() { - return ( -
Hello world!
- ); + return
Hello world!
; } -export default App; \ No newline at end of file +export default App; diff --git a/src/components/Avatar.tsx b/src/components/Avatar.tsx new file mode 100644 index 0000000..32ce50b --- /dev/null +++ b/src/components/Avatar.tsx @@ -0,0 +1,49 @@ +import React from "react"; +import classNames from "classnames"; + +export type Props = { + /** + * The style avatar + */ + className?: string; + /** + * The path of image + */ + src?: string; + /** + * The alternative text in case the image is not valid + */ + alt?: string; + /** + * The text inside avatar as a child + */ + children?: React.ReactNode; +}; + +const Avatar = ({ className, src, alt, children }: Props) => { + return ( +
+ {/* In case the src is valid, it will show the image */} + {src && ( + {alt} + )} + {/* The text will be shown in case it is valid */} + {children && ( +
+ {children} +
+ )} +
+ ); +}; + +export default Avatar; diff --git a/src/components/Checkbox.stories.tsx b/src/components/Checkbox.stories.tsx index 0b90e2c..b5ba94b 100644 --- a/src/components/Checkbox.stories.tsx +++ b/src/components/Checkbox.stories.tsx @@ -1,58 +1,43 @@ -import React from 'react'; +import React, { useState } from "react"; +import { Meta, Story, ComponentStory, ComponentMeta } from "@storybook/react"; -import { ComponentMeta, ComponentStory } from '@storybook/react'; - -import Checkbox from './Checkbox'; +import Checkbox from "./Checkbox"; export default { - // Title inside navigation bar - title: 'Checkbox', - // Component to test + title: "Checkbox", component: Checkbox, - // Clarifying the way how to process specific - // properties of your component and which values - // it can accept. + // More on argTypes: https://storybook.js.org/docs/react/api/argtypes argTypes: { - checked: { - options: [true, false], - control: { type: 'radio' }, + isChecked: { + type: "boolean", + }, + children: { + type: "string", + defaultValue: "Use light theme", + }, + disabled: { + type: "boolean", + defaultValue: "false", }, }, } as ComponentMeta; -/** - * This is a way to define a tempalte for your component. - * - * This template should cover all the states. - * - * In most cases you should just distruct args attribute - * on a returning component. - */ const Template: ComponentStory = (args) => ( ); -/* -------------------------------------------------------------------------- */ -/* States of your component */ -/* -------------------------------------------------------------------------- */ +export const Checked = Template.bind({}); +Checked.args = { + isChecked: true, + children: "This is custom checkbox", +}; export const Unchecked = Template.bind({}); Unchecked.args = { - label: "On/off lights", - checked: false, - children: undefined, -} -export const Checked = Template.bind({}); -Checked.args = { - children: "On/off lights", - checked: true, - label: undefined, -} + isChecked: false, +}; -export const EitherLabelChildren = Template.bind({}); -EitherLabelChildren.args = { - children: "On/off lights", - checked: true, - label: "Label!", -} -// GO Further \ No newline at end of file +export const Disabled = Template.bind({}); +Disabled.args = { + disabled: true, +}; diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx index ae987d3..dbf3fd7 100644 --- a/src/components/Checkbox.tsx +++ b/src/components/Checkbox.tsx @@ -1,38 +1,47 @@ -import classNames from "classnames"; import React from "react"; +import classNames from "classnames"; +import { ReactComponent as Checkmark } from "assets/svg/check.svg"; -type Props = { +export type Props = { /** - * The way to provide `children` inside a component - * via attribute instead of enclosed tag + * Control the state of checkbox */ - label?: React.ReactNode; + isChecked: boolean; /** - * When you will have both `children` and `label` - * defined on a component it will choose `children` - * to display + * An Element next to the checkbox */ children?: React.ReactNode; -} & Omit, "type">; - -/** - * Customized `input[type="checkbox"]` component with label - * - * All common input properties are inherited. - * - * To define a label content either provide `label` attribute - * or use common `children` property - */ -const Checkbox = ({label, children, className, ...props}: Props) => { - - if(label && !children) { - children = label; - } +} & Omit, "type">; +const Checkbox = ({ children, className, isChecked, ...props }: Props) => { return ( -