From dc2ca9ac88cd793e31bfb638a4e0e04047a80912 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Fri, 26 Jun 2020 07:45:11 -0700 Subject: [PATCH] Add multi-switch component, refactor radio group, and add success icon (#2324) * Add multi-switch component, refactor radio group, and add succeess icon * Fix dark theme for storybook Co-authored-by: Mike Ellan <52717970+sonicyeti@users.noreply.github.com> --- .../.storybook/preview-head.html | 689 ++++++------------ .../assets/icn-success.svg | 5 + .../components/multi-switch.js | 40 + .../components/multi-switch.stories.js | 17 + .../components/radio-button-group.js | 76 +- .../components/radio-button-group.stories.js | 44 +- .../components/svg-icon.js | 5 +- 7 files changed, 356 insertions(+), 520 deletions(-) create mode 100644 packages/insomnia-components/assets/icn-success.svg create mode 100644 packages/insomnia-components/components/multi-switch.js create mode 100644 packages/insomnia-components/components/multi-switch.stories.js diff --git a/packages/insomnia-components/.storybook/preview-head.html b/packages/insomnia-components/.storybook/preview-head.html index 0c3dca1cfd..41afe8ab7f 100644 --- a/packages/insomnia-components/.storybook/preview-head.html +++ b/packages/insomnia-components/.storybook/preview-head.html @@ -255,484 +255,239 @@ } - + + diff --git a/packages/insomnia-components/assets/icn-success.svg b/packages/insomnia-components/assets/icn-success.svg new file mode 100644 index 0000000000..7628e85091 --- /dev/null +++ b/packages/insomnia-components/assets/icn-success.svg @@ -0,0 +1,5 @@ + + + + diff --git a/packages/insomnia-components/components/multi-switch.js b/packages/insomnia-components/components/multi-switch.js new file mode 100644 index 0000000000..a6e2435220 --- /dev/null +++ b/packages/insomnia-components/components/multi-switch.js @@ -0,0 +1,40 @@ +// @flow +import * as React from 'react'; +import styled from 'styled-components'; +import type { Props as RadioButtonGroupProps } from './radio-button-group'; +import RadioButtonGroup from './radio-button-group'; + +const ThemedButtonGroup: React.ComponentType = styled(RadioButtonGroup)` + font-weight: bold; + background: var(--hl-xs); + color: var(--color-font); + border: 0; + border-radius: 100px; + align-content: space-evenly; + + label { + padding: 0; + } + + span { + text-transform: uppercase; + padding: var(--padding-xs) var(--padding-md); + color: var(--hl); + background: transparent; + font-size: var(--font-size-sm); + margin: 0 auto; + min-width: 4rem; + } + + input:checked + span { + color: var(--color-font); + text-shadow: 0 1px rgba(255, 255, 255, 0.25); + background: var(--color-bg); + } +`; + +const MultiSwitch = (props: RadioButtonGroupProps) => { + return ; +}; + +export default MultiSwitch; diff --git a/packages/insomnia-components/components/multi-switch.stories.js b/packages/insomnia-components/components/multi-switch.stories.js new file mode 100644 index 0000000000..75c81f0501 --- /dev/null +++ b/packages/insomnia-components/components/multi-switch.stories.js @@ -0,0 +1,17 @@ +import * as React from 'react'; +import MultiSwitch from './multi-switch'; + +export default { title: '1st Party | Multi Switch' }; + +export const _default = () => ( + console.log(v)} + choices={[ + { label: 'Design', value: 'design' }, + { label: 'Debug', value: 'debug' }, + { label: 'Test', value: 'test' }, + ]} + /> +); diff --git a/packages/insomnia-components/components/radio-button-group.js b/packages/insomnia-components/components/radio-button-group.js index b8778b272d..bd7246042d 100644 --- a/packages/insomnia-components/components/radio-button-group.js +++ b/packages/insomnia-components/components/radio-button-group.js @@ -2,31 +2,44 @@ import * as React from 'react'; import styled from 'styled-components'; +export type Props = { + name: string, + defaultValue: string, + onChange: (value: string) => any, + choices: Array<{ + label: string, + value: string, + }>, + className?: string, +}; + const StyledRadioButtonGroup: React.ComponentType<{}> = styled.div` display: flex; justify-content: space-between; padding: var(--padding-xs); border: 1px solid var(--hl-xs); border-radius: var(--radius--sm); + & > * :not(:last-child) { margin-right: var(--padding-xs); } +`; - label { - cursor: pointer; - color: var(--color-font); - flex-grow: 1; - justify-content: center; +const StyledRadioButtonBtn: React.ComponentType<{}> = styled.label` + cursor: pointer; + color: var(--color-font); + flex-grow: 1; + justify-content: center; - input { - display: none; - } + input { + display: none; + } - span { - text-align: center; - padding: var(--padding-sm) var(--padding-xs); - display: block; - } + span { + text-align: center; + padding: var(--padding-sm) var(--padding-xs); + display: block; + border-radius: var(--line-height-sm); } input:checked + span { @@ -34,10 +47,35 @@ const StyledRadioButtonGroup: React.ComponentType<{}> = styled.div` } `; -class RadioButtonGroup extends React.Component<{}> { - render() { - return ; - } -} +export default function RadioButtonGroup({ + name, + choices, + defaultValue, + onChange, + className, +}: Props) { + const handleChange = e => { + if (typeof onChange !== 'function') { + return; + } -export default RadioButtonGroup; + onChange(e.currentTarget.value); + }; + + return ( + + {choices.map(({ label, value }) => ( + + + {label} + + ))} + + ); +} diff --git a/packages/insomnia-components/components/radio-button-group.stories.js b/packages/insomnia-components/components/radio-button-group.stories.js index ecfce92875..8c2a978dbf 100644 --- a/packages/insomnia-components/components/radio-button-group.stories.js +++ b/packages/insomnia-components/components/radio-button-group.stories.js @@ -6,37 +6,15 @@ import RadioButtonGroup from './radio-button-group'; export default { title: '1st Party | Radio Button Group' }; export const _default = () => ( - - - - - - + console.log(v)} + choices={[ + { label: 'From Scratch', value: 'scratch' }, + { label: 'From Repository', value: 'repo' }, + { label: 'From Clipboard', value: 'clip' }, + { label: 'From Spec', value: 'spec' }, + ]} + /> ); diff --git a/packages/insomnia-components/components/svg-icon.js b/packages/insomnia-components/components/svg-icon.js index 9ccb5dfcc1..ce1fc681c4 100644 --- a/packages/insomnia-components/components/svg-icon.js +++ b/packages/insomnia-components/components/svg-icon.js @@ -35,6 +35,7 @@ import MemoSvgIcnQuestionFill from '../assets/svgr/IcnQuestionFill'; import MemoSvgIcnQuestion from '../assets/svgr/IcnQuestion'; import MemoSvgIcnSearch from '../assets/svgr/IcnSearch'; import MemoSvgIcnSecCert from '../assets/svgr/IcnSecCert'; +import MemoSvgIcnSuccess from '../assets/svgr/IcnSuccess'; import MemoSvgIcnSync from '../assets/svgr/IcnSync'; import MemoSvgIcnTrashcan from '../assets/svgr/IcnTrashcan'; import MemoSvgIcnTriangle from '../assets/svgr/IcnTriangle'; @@ -93,6 +94,7 @@ export const IconEnum = { questionFill: 'question-fill', question: 'question', secCert: 'sec-cert', + success: 'success', sync: 'sync', trashcan: 'trashcan', triangle: 'triangle', @@ -181,6 +183,7 @@ class SvgIcon extends React.Component { [IconEnum.question]: [ThemeEnum.default, MemoSvgIcnQuestion], [IconEnum.questionFill]: [ThemeEnum.default, MemoSvgIcnQuestionFill], [IconEnum.secCert]: [ThemeEnum.default, MemoSvgIcnSecCert], + [IconEnum.success]: [ThemeEnum.success, MemoSvgIcnSuccess], [IconEnum.sync]: [ThemeEnum.default, MemoSvgIcnSync], [IconEnum.trashcan]: [ThemeEnum.default, MemoSvgIcnTrashcan], [IconEnum.triangle]: [ThemeEnum.default, MemoSvgIcnTriangle], @@ -194,7 +197,7 @@ class SvgIcon extends React.Component { if (!SvgIcon.icons[icon]) { throw new Error( - `Invalid icon "${icon}" used. Must be one of ${Object.values(SvgIcon.icons).join('|')}`, + `Invalid icon "${icon}" used. Must be one of ${Object.values(IconEnum).join('|')}`, ); }