From 415257ca0341a91be6832efb2b2c6f8ad8de8bb5 Mon Sep 17 00:00:00 2001 From: hachiojidev <72719739+hachiojidev@users.noreply.github.com> Date: Thu, 10 Dec 2020 11:19:28 +0900 Subject: [PATCH] feat: Input (#86) --- src/components/Input/index.stories.tsx | 41 +++++++++++++++ src/components/Input/index.tsx | 70 ++++++++++++++++++++++++++ src/components/Input/types.ts | 15 ++++++ src/index.ts | 1 + 4 files changed, 127 insertions(+) create mode 100644 src/components/Input/index.stories.tsx create mode 100644 src/components/Input/index.tsx create mode 100644 src/components/Input/types.ts diff --git a/src/components/Input/index.stories.tsx b/src/components/Input/index.stories.tsx new file mode 100644 index 000000000..615fd2274 --- /dev/null +++ b/src/components/Input/index.stories.tsx @@ -0,0 +1,41 @@ +import React from "react"; +import styled from "styled-components"; +/* eslint-disable import/no-unresolved */ +import { Meta } from "@storybook/react/types-6-0"; +import Heading from "../Heading"; +import Input from "./index"; +import { scales } from "./types"; + +const Row = styled.div` + display: flex; + margin-bottom: 32px; + + & > input + input { + margin-left: 16px; + } +`; + +export default { + title: "Input", + component: Input, + argTypes: {}, +} as Meta; + +export const Default: React.FC = () => { + return ( +
+ {Object.keys(scales).map((key) => ( + <> + {key} + + + + + + + + + ))} +
+ ); +}; diff --git a/src/components/Input/index.tsx b/src/components/Input/index.tsx new file mode 100644 index 000000000..d3a1b2b0e --- /dev/null +++ b/src/components/Input/index.tsx @@ -0,0 +1,70 @@ +import styled, { DefaultTheme } from "styled-components"; +import { InputProps, scales } from "./types"; + +interface StyledInputProps extends InputProps { + theme: DefaultTheme; +} + +/** + * Priority: Warning --> Success + */ +const getBoxShadow = ({ isSuccess = false, isWarning = false, theme }: StyledInputProps) => { + if (isWarning) { + return theme.shadows.warning; + } + + if (isSuccess) { + return theme.shadows.success; + } + + return theme.shadows.inset; +}; + +const getHeight = ({ scale = scales.MD }: StyledInputProps) => { + switch (scale) { + case scales.SM: + return "32px"; + case scales.LG: + return "48px"; + case scales.MD: + default: + return "40px"; + } +}; + +const Input = styled.input` + background-color: ${({ theme }) => theme.colors.input}; + border: 0; + border-radius: 16px; + box-shadow: ${getBoxShadow}; + color: ${({ theme }) => theme.colors.text}; + display: block; + font-size: 16px; + height: ${getHeight}; + outline: 0; + padding: 0 16px; + width: 100%; + + &::placeholder { + color: ${({ theme }) => theme.colors.textSubtle}; + } + + &:disabled { + background-color: ${({ theme }) => theme.colors.backgroundDisabled}; + box-shadow: none; + color: ${({ theme }) => theme.colors.textDisabled}; + cursor: not-allowed; + } + + &:focus:not(:disabled) { + box-shadow: ${({ theme }) => theme.shadows.focus}; + } +`; + +Input.defaultProps = { + scale: scales.MD, + isSuccess: false, + isWarning: false, +}; + +export default Input; diff --git a/src/components/Input/types.ts b/src/components/Input/types.ts new file mode 100644 index 000000000..84d7f91be --- /dev/null +++ b/src/components/Input/types.ts @@ -0,0 +1,15 @@ +import { SpaceProps } from "styled-system"; + +export const scales = { + SM: "sm", + MD: "md", + LG: "lg", +} as const; + +export type Scales = typeof scales[keyof typeof scales]; + +export interface InputProps extends SpaceProps { + scale?: Scales; + isSuccess?: boolean; + isWarning?: boolean; +} diff --git a/src/index.ts b/src/index.ts index 1ee29247f..d61173a86 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,7 @@ export { default as ColorBox } from "./components/ColorBox"; export { default as Flex } from "./components/Flex"; export { default as Dropdown } from "./components/Dropdown"; export { default as Heading } from "./components/Heading"; +export { default as Input } from "./components/Input"; export * from "./components/Card"; export * from "./components/Layouts"; export * from "./components/Svg";