diff --git a/.babelrc b/.babelrc index 8b838d2..7336e76 100644 --- a/.babelrc +++ b/.babelrc @@ -1,11 +1,8 @@ -{ - "presets": [ - "@babel/preset-env", - "@babel/preset-react", - "@babel/preset-flow" - ], - "plugins": [ - "@babel/plugin-proposal-class-properties", - "@babel/plugin-proposal-object-rest-spread" - ] -} \ No newline at end of file +{ + "presets": ["@babel/preset-env", "@babel/preset-react", "@babel/preset-flow"], + "plugins": [ + "@babel/plugin-transform-regenerator", + "@babel/plugin-proposal-class-properties", + "@babel/plugin-proposal-object-rest-spread" + ] +} diff --git a/.eslintrc b/.eslintrc index 7268b93..390923c 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,47 +1,49 @@ -{ - "parser": "babel-eslint", - "extends": ["airbnb", "plugin:flowtype/recommended"], - "env": { - "browser": true, - "node": true, - "mocha": true, - "jest/globals": true - }, - "plugins": ["flowtype", "jest"], - "settings": { - "flowtype": { - "onlyFilesWithFlowAnnotation": true - } - }, - "rules": { - "jsx-quotes": ["error", "prefer-single"], - "import/prefer-default-export": ["off"], - "react/jsx-filename-extension": [1, { "extensions": [".js"] }], - "jsx-a11y/anchor-is-valid": [ - "error", - { - "components": ["Link"], - "specialLink": ["to", "hrefLeft", "hrefRight"], - "aspects": ["noHref", "invalidHref", "preferButton"] - } - ], - "jsx-a11y/no-autofocus": [ - 0, - { - "ignoreNonDOM": true - } - ], - "max-len": [ - "error", - { - "code": 120, - "tabWidth": 2, - "ignoreUrls": true, - "ignoreComments": true, - "ignoreStrings": true, - "ignorePattern": "]*>.*?

", - "ignoreTrailingComments": true - } - ] - } -} +{ + "parser": "babel-eslint", + "extends": ["airbnb", "plugin:flowtype/recommended"], + "env": { + "browser": true, + "node": true, + "mocha": true, + "jest/globals": true + }, + "plugins": ["flowtype", "jest"], + "settings": { + "flowtype": { + "onlyFilesWithFlowAnnotation": true + } + }, + "rules": { + "jsx-quotes": ["error", "prefer-single"], + "import/prefer-default-export": ["off"], + "react/jsx-filename-extension": [1, { "extensions": [".js"] }], + "jsx-a11y/anchor-is-valid": [ + "error", + { + "components": ["Link"], + "specialLink": ["to", "hrefLeft", "hrefRight"], + "aspects": ["noHref", "invalidHref", "preferButton"] + } + ], + "jsx-a11y/no-autofocus": [ + 0, + { + "ignoreNonDOM": true + } + ], + "max-len": [ + "error", + { + "code": 120, + "tabWidth": 2, + "ignoreUrls": true, + "ignoreComments": true, + "ignoreStrings": true, + "ignorePattern": "]*>.*?

", + "ignoreTrailingComments": true + } + ], + "consistent-return": 0, + "react/destructuring-assignment": 0 + } +} diff --git a/__tests__/components/Sidebar.test.js b/__tests__/components/Sidebar.test.js index c42f932..d8636ae 100644 --- a/__tests__/components/Sidebar.test.js +++ b/__tests__/components/Sidebar.test.js @@ -10,6 +10,7 @@ import { SidebarComponent } from '../../app/components/sidebar'; describe('', () => { describe('render()', () => { test('should render correctly', () => { + // $FlowFixMe const { asFragment } = render( diff --git a/app/components/Button.mdx b/app/components/Button.mdx new file mode 100644 index 0000000..c26bb96 --- /dev/null +++ b/app/components/Button.mdx @@ -0,0 +1,54 @@ +--- +name: Button +--- + +import { Playground, PropsTable } from 'docz' + +import { Button } from './button.js' +import { DoczWrapper } from '../theme.js' + +# Button + + + +## Primary + + +
+ {() =>
+
+ +## Secondary + + +
+ {() =>
+
+ +## Primary Disabled + + +
+ {() =>
+
+ +## Secondary Disabled + + +
+ + {() =>
+
+ +## Link Button + + +
+ {() =>
+
diff --git a/app/components/Input.mdx b/app/components/Input.mdx new file mode 100644 index 0000000..5111f62 --- /dev/null +++ b/app/components/Input.mdx @@ -0,0 +1,26 @@ +--- +name: Input +--- + +import { Playground, PropsTable } from 'docz' + +import { InputComponent } from './input.js' +import { DoczWrapper } from '../theme.js' + +# Input + + + +## Text Input + + + {() => } + + +## Textarea + + + + {() => } + + diff --git a/app/components/QRCode.mdx b/app/components/QRCode.mdx new file mode 100644 index 0000000..d424423 --- /dev/null +++ b/app/components/QRCode.mdx @@ -0,0 +1,23 @@ +--- +name: QRCode +--- + +import { Playground, PropsTable } from 'docz' + +import { QRCode } from './qrcode.js' + +# QRCode + + + +## Basic usage + + + + + +## Custom size + + + + diff --git a/app/components/button.js b/app/components/button.js new file mode 100644 index 0000000..650bc7b --- /dev/null +++ b/app/components/button.js @@ -0,0 +1,94 @@ +// @flow + +import React from 'react'; +import styled from 'styled-components'; +import { Link } from 'react-router-dom'; +/* eslint-disable import/no-extraneous-dependencies */ +// $FlowFixMe +import { darken } from 'polished'; + +const defaultStyles = ` + padding: 10px 30px; + font-family: ${ + // $FlowFixMe + props => props.theme.fontFamily +}; + font-weight: bold; + font-size: 0.9em; + cursor: pointer; + outline: none; + min-width: 100px; + border-radius: 100px; + transition: background-color 0.1s ease-in-out; +`; + +const Primary = styled.button` + ${defaultStyles}; + background-color: ${props => props.theme.colors.primary}; + color: ${props => props.theme.colors.secondary}; + border: none; + + &:hover { + background-color: ${props => darken(0.1, props.theme.colors.primary(props))}; + } + + &:disabled { + background-color: #3e3c42; + cursor: not-allowed; + opacity: 0.8; + } +`; + +const Secondary = styled.button` + ${defaultStyles}; + background-color: Transparent; + color: ${props => props.theme.colors.secondary}; + border: 2px solid #3e3c42; + + &:hover { + border-color: ${props => props.theme.colors.primary}; + } + + &:disabled { + background-color: Transparent; + cursor: not-allowed; + color: #3e3c42; + + &:hover { + border-color: #3e3c42; + } + } +`; + +type Props = { + label: string, + onClick?: () => void, + to?: string, + variant?: 'primary' | 'secondary', + disabled?: boolean, +}; + +export const Button = ({ + onClick, label, to, variant, disabled, +}: Props) => { + if (to && onClick) throw new Error('Should define either "to" or "onClick"'); + + const component = variant === 'primary' ? ( + + {label} + + ) : ( + + {label} + + ); + + return to ? {component} : component; +}; + +Button.defaultProps = { + to: null, + variant: 'primary', + onClick: null, + disabled: false, +}; diff --git a/app/components/input.js b/app/components/input.js new file mode 100644 index 0000000..459ae30 --- /dev/null +++ b/app/components/input.js @@ -0,0 +1,53 @@ +// @flow +import React from 'react'; + +import styled from 'styled-components'; + +// TODO: Missing styles + +const defaultStyles = ` + padding: 10px; + width: 100%; + outline: none; + font-family: ${props => props.theme.fontFamily} +`; + +const Input = styled.input.attrs({ + type: 'text', +})` + ${defaultStyles}; +`; + +const Textarea = styled.textarea` + ${defaultStyles}; +`; + +type Props = { + inputType?: 'input' | 'textarea' | 'dropdown', + value: string, + onChange: string => void, + rows?: number, + disabled?: boolean, + type?: string, +}; + +export const InputComponent = ({ inputType, onChange, ...props }: Props) => { + const inputTypes = { + input: () => onChange(evt.target.value)} {...props} />, + textarea: () =>