From 5e8a658d21deefb1f5575db58ff55ea7ab54650a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mati=CC=81as?= Date: Tue, 26 Apr 2022 13:12:59 +0200 Subject: [PATCH 1/2] feat(checkbox): add checkbox component --- .storybook/main.js | 7 ++- .storybook/preview-body.html | 4 ++ .storybook/preview.js | 29 ++++++--- package.json | 1 + src/components/Button.tsx | 5 +- src/components/Checkbox.tsx | 107 ++++++++++++++++++++++++++++++++++ src/components/IconButton.tsx | 3 +- src/components/TextInput.tsx | 1 + src/index.ts | 1 + src/styles/colors.ts | 14 ++--- stories/Checkbox.stories.tsx | 38 ++++++++++++ yarn.lock | 2 +- 12 files changed, 192 insertions(+), 20 deletions(-) create mode 100644 src/components/Checkbox.tsx create mode 100644 stories/Checkbox.stories.tsx diff --git a/.storybook/main.js b/.storybook/main.js index 8a9720c..61728fd 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -1,4 +1,9 @@ module.exports = { stories: ['../stories/**/**/*.stories.mdx', '../stories/**/**/*.stories.@(js|jsx|ts|tsx)'], - addons: ['@storybook/addon-links', '@storybook/addon-essentials', 'storybook-addon-designs'], + addons: [ + '@storybook/addon-backgrounds', + '@storybook/addon-links', + '@storybook/addon-essentials', + 'storybook-addon-designs', + ], }; diff --git a/.storybook/preview-body.html b/.storybook/preview-body.html index 442c604..1b6936c 100644 --- a/.storybook/preview-body.html +++ b/.storybook/preview-body.html @@ -12,6 +12,10 @@ font-size: 12px; } + body { + min-height: 100vh; + } + * { box-sizing: border-box; } diff --git a/.storybook/preview.js b/.storybook/preview.js index 48afd56..58496ce 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,9 +1,22 @@ +import colors from '../src/styles/colors'; + export const parameters = { - actions: { argTypesRegex: "^on[A-Z].*" }, - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/, - }, - }, -} \ No newline at end of file + actions: { argTypesRegex: '^on[A-Z].*' }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/, + }, + }, + backgrounds: { + default: 'dark', + values: [ + { name: 'dark', value: '#111' }, + { name: 'light', value: '#F8F8F8' }, + { name: 'black', value: '#000000' }, + { name: 'white', value: '#FFFFFF' }, + { name: 'purple', value: colors.gradients.purple }, + { name: 'darkBlue', value: colors.gradients.darkBlue }, + ], + }, +}; diff --git a/package.json b/package.json index 02af023..7fc5404 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "@commitlint/cli": "16.2.3", "@commitlint/config-conventional": "16.2.1", "@storybook/addon-actions": "6.4.22", + "@storybook/addon-backgrounds": "^6.4.22", "@storybook/addon-essentials": "6.4.22", "@storybook/addon-links": "6.4.22", "@storybook/react": "6.4.22", diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 02a370d..4a76de7 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -1,8 +1,9 @@ import React, { ButtonHTMLAttributes, MouseEvent, PropsWithChildren } from 'react'; import styled from 'styled-components'; -import theme from '../styles/theme'; + import colors from '../styles/colors'; import fonts from '../styles/fonts'; +import theme from '../styles/theme'; interface ButtonProps { text?: string; @@ -135,5 +136,5 @@ const StyledButtonText = styled.span<{ ${({ variant, disabled }) => variant === 'secondary' && !disabled && - `background-image: ${colors.gradients.lightBlue} background-size: 100%; -webkit-background-clip: text; -webkit-text-fill-color: transparent; -moz-background-clip: text; -moz-text-fill-color: transparent;`} + `background-image: ${colors.gradients.lightBlue}; background-size: 100%; -webkit-background-clip: text; -webkit-text-fill-color: transparent; -moz-background-clip: text; -moz-text-fill-color: transparent;`} `; diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx new file mode 100644 index 0000000..89faab2 --- /dev/null +++ b/src/components/Checkbox.tsx @@ -0,0 +1,107 @@ +import React from 'react'; +import styled from 'styled-components'; + +import colors from '../styles/colors'; + +interface CheckboxProps { + id: string; + disabled?: boolean; + label?: string; + name?: string; + checked?: boolean; + onChange: (checked: boolean) => unknown; +} + +export default function Checkbox({ + id, + disabled = false, + label, + name, + checked, + onChange, +}: CheckboxProps) { + return ( + + onChange(!checked)} + /> + + + {label && {label}} + + + ); +} + +const StyledContainer = styled.div` + display: inline-block; +`; + +const HiddenCheckbox = styled.input.attrs({ type: 'checkbox' })` + border: 0; + clip: rect(0 0 0 0); + clip-path: inset(50%); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + white-space: nowrap; + width: 1px; +`; + +const StyledLabel = styled.label` + display: flex; +`; + +const StyledLabelText = styled.span<{ disabled?: boolean }>` + display: inline-block; + cursor: pointer; + font-family: 'Inter Bold'; + font-size: 1.2rem; + line-height: 2.2rem; + ${colors.white}; + color: ${(attrs) => (attrs.disabled ? colors.disabled : colors.white)}; +`; + +const StyledCheckbox = styled.div<{ checked?: boolean; disabled?: boolean }>` + position: relative; + display: inline-block; + cursor: pointer; + overflow: hidden; + margin-right: 0.75rem; + width: 2.2rem; + height: 2.2rem; + border-radius: 50%; + background-image: ${colors.gradients.pink}; + + ${(attrs) => attrs.disabled && `filter: grayscale(100%);`} + + ::before { + content: ''; + position: absolute; + left: 8%; + top: 8%; + border-radius: 50%; + width: 84%; + height: 84%; + background-color: ${colors.backgroundColor}; + } + + ::after { + content: ''; + position: absolute; + left: 27%; + top: 27%; + border-radius: 50%; + width: 46%; + height: 46%; + background-image: ${colors.gradients.pink}; + opacity: ${(attrs) => (attrs.checked ? '1' : '0')}; + transition: opacity 80ms ease-in-out; + } +`; diff --git a/src/components/IconButton.tsx b/src/components/IconButton.tsx index 3edf20a..3bb1ca1 100644 --- a/src/components/IconButton.tsx +++ b/src/components/IconButton.tsx @@ -1,5 +1,6 @@ import React, { PropsWithChildren } from 'react'; import styled from 'styled-components'; + import colors from '../styles/colors'; import spacings from '../styles/spacings'; @@ -53,5 +54,5 @@ const StyledGradient = styled.div<{ border: 1px solid ${colors.black}; border-radius: ${({ rounded }) => (rounded ? '30px' : '4px')}; cursor: pointer; - ${({ active }) => active && `background: ${colors.gradients.grey}`} + ${({ active }) => active && `background: ${colors.gradients.grey};`} `; diff --git a/src/components/TextInput.tsx b/src/components/TextInput.tsx index ac7d685..91ab89c 100644 --- a/src/components/TextInput.tsx +++ b/src/components/TextInput.tsx @@ -1,5 +1,6 @@ import React, { FormEventHandler } from 'react'; import styled from 'styled-components'; + import colors from '../styles/colors'; interface TextInputProps { diff --git a/src/index.ts b/src/index.ts index 0af60f4..613f77b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -51,6 +51,7 @@ export { default as IconButton } from './components/IconButton'; export { default as Tabs } from './components/Tabs'; export { default as LinkButton } from './components/LinkButton'; export { default as Selector } from './components/Selector'; +export { default as Checkbox } from './components/Checkbox'; export { default as Dropdown } from './components/Dropdown'; export { default as Card } from './components/Card'; export { default as Carousel } from './components/Carousel'; diff --git a/src/styles/colors.ts b/src/styles/colors.ts index 8fc4b01..f77ea01 100644 --- a/src/styles/colors.ts +++ b/src/styles/colors.ts @@ -10,13 +10,13 @@ export default { pink: '#ED1EFF', green: '#31D8A4', gradients: { - darkBlue: 'linear-gradient(180deg, #08021E 0%, #1F0777 146.21%);', - lightBlue: 'linear-gradient(73.6deg, #85FFC4 2.11%, #5CC6FF 90.45%);', - purple: 'linear-gradient(73.6deg, #8E2DE2 2.11%, #4B01E0 90.45%);', - orange: 'linear-gradient(73.6deg, #FF8060 2.11%, #FEB27A 90.45%);', - pink: 'linear-gradient(73.6deg, #8E2DE2 2.11%, #ED1EFF 90.45%);', - rainbow: 'linear-gradient(90deg, #ED1EFF 0%, #00D1FF 100%);', - grey: 'linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)), linear-gradient(311.52deg, #3D464C -36.37%, #131619 62.81%);', + darkBlue: 'linear-gradient(180deg, #08021E 0%, #1F0777 146.21%)', + lightBlue: 'linear-gradient(73.6deg, #85FFC4 2.11%, #5CC6FF 90.45%)', + purple: 'linear-gradient(73.6deg, #8E2DE2 2.11%, #4B01E0 90.45%)', + orange: 'linear-gradient(73.6deg, #FF8060 2.11%, #FEB27A 90.45%)', + pink: 'linear-gradient(73.6deg, #8E2DE2 2.11%, #ED1EFF 90.45%)', + rainbow: 'linear-gradient(90deg, #ED1EFF 0%, #00D1FF 100%)', + grey: 'linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)), linear-gradient(311.52deg, #3D464C -36.37%, #131619 62.81%)', }, hoverOpacity: '9f', } as const; diff --git a/stories/Checkbox.stories.tsx b/stories/Checkbox.stories.tsx new file mode 100644 index 0000000..9d9ce11 --- /dev/null +++ b/stories/Checkbox.stories.tsx @@ -0,0 +1,38 @@ +import React, { useState } from 'react'; +import { withDesign } from 'storybook-addon-designs'; + +import { ComponentMeta, ComponentStory } from '@storybook/react'; + +import Checkbox from '../src/components/Checkbox'; + +export default { + title: 'Checkbox', + component: Checkbox, + decorators: [withDesign], + args: { + id: 'checkbox', + name: 'example-checkbox', + }, + parameters: { + backgrounds: { + default: 'darkBlue', + }, + design: { + type: 'figma', + url: 'https://www.figma.com/file/zeCepPb3Bo6Fd92FdcolUT/v1.0?node-id=894%3A23624', + }, + }, +} as ComponentMeta; + +export const Example: ComponentStory = (args) => { + const [checked, setChecked] = useState(false); + return ; +}; + +export const Enabled: ComponentStory = (args) => ( + +); + +export const Disabled: ComponentStory = (args) => ( + +); diff --git a/yarn.lock b/yarn.lock index 10fed4f..c8e6ccb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1940,7 +1940,7 @@ util-deprecate "^1.0.2" uuid-browser "^3.1.0" -"@storybook/addon-backgrounds@6.4.22": +"@storybook/addon-backgrounds@6.4.22", "@storybook/addon-backgrounds@^6.4.22": version "6.4.22" resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-6.4.22.tgz#5d9dbff051eefc1ca6e6c7973c01d17fbef4c2f5" integrity sha512-xQIV1SsjjRXP7P5tUoGKv+pul1EY8lsV7iBXQb5eGbp4AffBj3qoYBSZbX4uiazl21o0MQiQoeIhhaPVaFIIGg== From e972decf5c7979e0df2dfd5518964149ef72ff52 Mon Sep 17 00:00:00 2001 From: fritzschoff Date: Thu, 28 Apr 2022 09:39:23 +0100 Subject: [PATCH 2/2] fix(checkbox): removed unused css --- src/components/Checkbox.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx index 89faab2..3e8b969 100644 --- a/src/components/Checkbox.tsx +++ b/src/components/Checkbox.tsx @@ -19,9 +19,10 @@ export default function Checkbox({ name, checked, onChange, + ...rest }: CheckboxProps) { return ( - + ` font-family: 'Inter Bold'; font-size: 1.2rem; line-height: 2.2rem; - ${colors.white}; color: ${(attrs) => (attrs.disabled ? colors.disabled : colors.white)}; `;