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('|')}`,
);
}