Skip to content
This repository has been archived by the owner on Apr 15, 2022. It is now read-only.

Switch Component #31

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
56 changes: 56 additions & 0 deletions src/components/Switch/Switch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React, { ReactElement } from "react";
import { Switch as SwitchHeadlessUI } from "@headlessui/react";
import styled, { css } from "styled-components";

export type SwitchProps = {
onCheck: (enabled: boolean) => void;
checked: boolean;
};

type SwitchButtonProps = {
checked: boolean;
};

const width = 40;
const height = 24;
const borderRadius = 9999;
const borderWidth = 4;

const StyledSwitch = styled(SwitchHeadlessUI)<SwitchProps>`
border-radius: ${borderRadius}px;
background-color: ${({ checked, theme }) =>
checked ? theme.colors.background : theme.colors.secondary};
border-color: transparent;
border-width: ${borderWidth + "px"};
width: ${width + "px"};
height: ${height + "px"};
outline: solid;
outline-color: ${({ theme }) => theme.colors.primary};
outline-width: 1px;
position: relative;
display: inline-flex;
flex-shrink: 0;
padding: 0;
cursor: pointer;
`;

const StyledSpan = styled.span`
${({ checked }: SwitchButtonProps) => css`
background-color: ${({ theme }) => theme.colors.primary};
border-radius: ${borderRadius}px;
pointer-events: none;
display: inline-block;
height: ${height - borderWidth * 2}px;
width: ${height - borderWidth * 2}px;
transition-duration: 200ms;
transform: ${checked ? "translateX(0px)" : "translateX(1rem)"};
`}
`;

export const Switch = ({ checked, onCheck }: SwitchProps): ReactElement => {
return (
<StyledSwitch checked={checked} onChange={onCheck}>
<StyledSpan checked={checked} aria-hidden={"true"} />
</StyledSwitch>
);
};
1 change: 1 addition & 0 deletions src/components/Switch/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./Switch";
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export { default as Icon } from "./Icon";
export * from "./Banner";
export * from "./Button";
export * from "./Card";
export * from "./Switch";
export * from "./BoxVaultAPY";
export * from "./Dropdown";
export * from "./Spinner";
Expand Down
19 changes: 19 additions & 0 deletions stories/components/Switch.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React, { useState } from "react";
import { ComponentStory, ComponentMeta } from "@storybook/react";
import { Switch as SwitchComponent } from "../../src/components/Switch";

export default {
title: "Components/Switch",
component: SwitchComponent,
} as ComponentMeta<typeof SwitchComponent>;

const Template: ComponentStory<typeof SwitchComponent> = (props) => {
const [isChecked, _setChecked] = useState<boolean>(false)
return (
<SwitchComponent
checked={isChecked}
onCheck={_setChecked} />
)
};

export const Switch = Template.bind({});