From db76b412474c13d960495b61cfea836edf791f18 Mon Sep 17 00:00:00 2001 From: Veado Date: Thu, 21 Oct 2021 14:46:30 +0200 Subject: [PATCH] CheckButton Custom toggle button - similar to `antd`s Checkbox (https://ant.design/components/checkbox/), but antd Checkbox is just hard to customize --- .../uielements/button/CheckButton.stories.tsx | 69 +++++++++++++++++++ .../uielements/button/CheckButton.styles.tsx | 34 +++++++++ .../uielements/button/CheckButton.tsx | 31 +++++++++ .../button/RefreshButton.stories.tsx | 57 +++++++++++++++ 4 files changed, 191 insertions(+) create mode 100644 src/renderer/components/uielements/button/CheckButton.stories.tsx create mode 100644 src/renderer/components/uielements/button/CheckButton.styles.tsx create mode 100644 src/renderer/components/uielements/button/CheckButton.tsx create mode 100644 src/renderer/components/uielements/button/RefreshButton.stories.tsx diff --git a/src/renderer/components/uielements/button/CheckButton.stories.tsx b/src/renderer/components/uielements/button/CheckButton.stories.tsx new file mode 100644 index 000000000..ae15b65d6 --- /dev/null +++ b/src/renderer/components/uielements/button/CheckButton.stories.tsx @@ -0,0 +1,69 @@ +import React from 'react' + +import { Story, Meta } from '@storybook/react' +import * as FP from 'fp-ts/lib/function' + +import { CheckButton } from './CheckButton' + +type Args = { + label: string + disabled: boolean + isChecked: boolean + onClicked: FP.Lazy +} + +const Template: Story = ({ label, disabled, isChecked, onClicked }) => { + return ( + + {label} + + ) +} + +export const Default = Template.bind({}) + +Default.storyName = 'default' + +const meta: Meta = { + component: CheckButton, + title: 'Components/button/CheckButton', + argTypes: { + label: { + name: 'Label', + control: { + type: 'text' + }, + defaultValue: 'Label' + }, + disabled: { + name: 'disabled', + control: { + type: 'boolean' + }, + defaultValue: false + }, + isChecked: { + name: 'isChecked', + control: { + type: 'boolean' + }, + defaultValue: false + }, + onClicked: { + action: 'onClicked' + } + }, + decorators: [ + (S: Story) => ( +
+ +
+ ) + ] +} + +export default meta diff --git a/src/renderer/components/uielements/button/CheckButton.styles.tsx b/src/renderer/components/uielements/button/CheckButton.styles.tsx new file mode 100644 index 000000000..0e92fd8e0 --- /dev/null +++ b/src/renderer/components/uielements/button/CheckButton.styles.tsx @@ -0,0 +1,34 @@ +import * as AIcon from '@ant-design/icons' +import * as A from 'antd' +import styled from 'styled-components' + +import { Button as ButtonUI } from './Button' + +export const ContentWrapper = styled.div` + display: flex; + align-items: center; + justify-content: space-between; +` + +export const CheckCircleOutlined = styled(AIcon.CheckCircleOutlined)<{ checked: boolean }>` + padding-right: 5px; + // Add some transparency if checked + opacity: ${(props) => (props.checked ? '1' : '0.7')}; + + // hide arrow if not checked + svg path:nth-child(1) { + opacity: ${(props) => (props.checked ? '1' : '0')}; + } +` + +type ButtonProps = { checked: boolean } & A.ButtonProps + +export const Button = styled(ButtonUI).attrs({ + typevalue: 'transparent', + type: 'text' +})` + box-shadow: none; + padding: 0px; + min-width: auto !important; + margin-right: 5px; +` diff --git a/src/renderer/components/uielements/button/CheckButton.tsx b/src/renderer/components/uielements/button/CheckButton.tsx new file mode 100644 index 000000000..4b80f0492 --- /dev/null +++ b/src/renderer/components/uielements/button/CheckButton.tsx @@ -0,0 +1,31 @@ +import React, { useState, useCallback } from 'react' + +import * as FP from 'fp-ts/function' + +import * as Styled from './CheckButton.styles' + +export type Props = { + clickHandler?: FP.Lazy + disabled?: boolean + isChecked?: boolean +} + +export const CheckButton: React.FC = (props): JSX.Element => { + const { clickHandler = FP.constVoid, disabled, isChecked, children } = props + + const [checked, setChecked] = useState(!!isChecked) + + const onClickHandler = useCallback(() => { + setChecked(() => !checked) + clickHandler && clickHandler() + }, [checked, clickHandler]) + + return ( + + + + {children} + + + ) +} diff --git a/src/renderer/components/uielements/button/RefreshButton.stories.tsx b/src/renderer/components/uielements/button/RefreshButton.stories.tsx new file mode 100644 index 000000000..fa2d1cd7b --- /dev/null +++ b/src/renderer/components/uielements/button/RefreshButton.stories.tsx @@ -0,0 +1,57 @@ +import React from 'react' + +import { Story, Meta } from '@storybook/react' +import * as FP from 'fp-ts/lib/function' + +import { RefreshButton } from './RefreshButton' + +type Args = { + label: string + disabled: boolean + onClicked: FP.Lazy +} + +const Template: Story = ({ label, disabled, onClicked }) => { + return +} + +export const Default = Template.bind({}) + +Default.storyName = 'default' + +const meta: Meta = { + component: RefreshButton, + title: 'Components/button/RefreshButton', + argTypes: { + label: { + name: 'Label', + control: { + type: 'text' + }, + defaultValue: 'Label' + }, + disabled: { + name: 'disabled', + control: { + type: 'boolean' + }, + defaultValue: false + }, + onClicked: { + action: 'onClicked' + } + }, + decorators: [ + (S: Story) => ( +
+ +
+ ) + ] +} + +export default meta