diff --git a/.hintrc b/.hintrc new file mode 100644 index 0000000..2fa1a2e --- /dev/null +++ b/.hintrc @@ -0,0 +1,13 @@ +{ + "extends": [ + "development" + ], + "hints": { + "axe/forms": [ + "default", + { + "select-name": "off" + } + ] + } +} \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/apps/team-styled/next-env.d.ts b/apps/team-styled/next-env.d.ts index 4f11a03..574313a 100644 --- a/apps/team-styled/next-env.d.ts +++ b/apps/team-styled/next-env.d.ts @@ -3,3 +3,11 @@ // NOTE: This file should not be edited // see https://nextjs.org/docs/basic-features/typescript for more information. + +declare module '*.svg' { + import React = require('react'); + + export const ReactComponent: REact.FC>; + const src: string; + export default src; +} diff --git a/apps/team-styled/public/mg.png b/apps/team-styled/public/mg.png new file mode 100644 index 0000000..4206275 Binary files /dev/null and b/apps/team-styled/public/mg.png differ diff --git a/packages/chakra-ui-styled/src/components/Tag/Tag.stories.tsx b/packages/chakra-ui-styled/src/components/Tag/Tag.stories.tsx new file mode 100644 index 0000000..01db43f --- /dev/null +++ b/packages/chakra-ui-styled/src/components/Tag/Tag.stories.tsx @@ -0,0 +1,95 @@ +import styled from 'styled-components'; +import Tag, { TagProps, colorSchemeType } from './Tag'; + +export default { + title: 'chakra-ui-styled/components/Tag', + component: Tag, + parameters: { controls: { expanded: true } }, + + argTypes: { + children: { control: { type: 'text' } }, + size: { control: { type: 'select' } }, + colorScheme: { control: { type: 'select' } }, + variant: { control: { type: 'radio' } } + }, + args: { + children: '태그 테스트', + size: 'md', + colorScheme: 'blue', + variant: 'solid', + removeButton: true + } +}; +const Wrapper = styled.div` + display: flex; + flex-direction: column; + gap: 20px; +`; +const TagWrap = styled.div` + display: flex; + gap: 45px; + align-items: center; + + & > div { + display: flex; + flex-direction: column; + gap: 12px; + align-items: center; + justify-content: flex-start; + } +`; + +export const TagIndex = (args: TagProps) => { + const tagText: string = 'Tag'; + const colorArr: colorSchemeType[] = ['gray', 'blue', 'teal', 'green', 'red', 'purple', 'pink', 'orange']; + return ( + +

Tag

+ +

Tag Demo

+
+ +
+ +

Tag Index

+ {colorArr.map((color) => ( + +
+ + {tagText} + + + {tagText} + + + {tagText} + +
+
+ + {tagText} + + + {tagText} + + + {tagText} + +
+
+ + {tagText} + + + {tagText} + + + {tagText} + +
+
+ ))} +
+ ); +}; +TagIndex.storyName = 'Tag'; diff --git a/packages/chakra-ui-styled/src/components/Tag/Tag.styled.tsx b/packages/chakra-ui-styled/src/components/Tag/Tag.styled.tsx new file mode 100644 index 0000000..53f7784 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/Tag/Tag.styled.tsx @@ -0,0 +1,83 @@ +import styled, { css } from 'styled-components'; +import { TagProps } from './Tag'; +import { StyleText } from '../../foundation/typography/Text.styled'; + +const tagSize = { + lg: css` + gap: 8px; + height: 32px; + padding: 0 ${({ theme }) => theme.spacing[3]}; + `, + md: css` + gap: 6px; + height: 24px; + padding: 0 ${({ theme }) => theme.spacing[2]}; + `, + sm: css` + gap: 6px; + height: 20px; + padding: 0 ${({ theme }) => theme.spacing[2]}; + ` +}; +const tagText = { + lg: css` + ${({ theme }) => theme.typo.text.md}; + font-weight: ${({ theme }) => theme.typo.fontWeight.medium}; + line-height: 1.5; + `, + md: css` + ${({ theme }) => theme.typo.text.sm}; + font-weight: ${({ theme }) => theme.typo.fontWeight.medium}; + line-height: 1.3; + `, + sm: css` + ${({ theme }) => theme.typo.text.xs}; + font-weight: ${({ theme }) => theme.typo.fontWeight.medium}; + ` +}; + +export const TagStyle = styled.div` + ${({ theme, variant, colorScheme }) => css` + display: inline-flex; + align-items: center; + align-self: flex-start; + justify-content: center; + justify-self: flex-start; + width: auto; + border-radius: ${theme.radii.md}rem; + ${variant === 'solid' + ? css` + color: ${theme.color.white.white}; + background-color: ${theme.color[colorScheme][500]}; + border: 1px solid ${theme.color[colorScheme][500]}; + ` + : variant === 'subtle' + ? css` + color: ${theme.color[colorScheme][800]}; + background-color: ${theme.color[colorScheme][200]}; + border: 1px solid ${theme.color[colorScheme][200]}; + ` + : variant === 'outline' + ? css` + color: ${theme.color[colorScheme][600]}; + background-color: transparent; + border: 1px solid ${theme.color[colorScheme][500]}; + ` + : null} + `} + & .tag-remove-btn { + display: flex; + align-items: center; + justify-content: center; + color: inherit; + background: transparent; + border: 0 none; + outline: none; + } + + & ${StyleText} { + ${({ size }) => tagText[size]} + } + + ${({ size }) => tagSize[size]} +`; diff --git a/packages/chakra-ui-styled/src/components/Tag/Tag.tsx b/packages/chakra-ui-styled/src/components/Tag/Tag.tsx new file mode 100644 index 0000000..42af231 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/Tag/Tag.tsx @@ -0,0 +1,37 @@ +import { StyleText } from '../../foundation/typography/Text.styled'; +import { TagStyle } from './Tag.styled'; + +export type colorSchemeType = 'blue' | 'gray' | 'teal' | 'red' | 'orange' | 'yellow' | 'pink' | 'purple' | 'green'; + +export interface TagProps { + variant: 'solid' | 'subtle' | 'outline'; + size: 'lg' | 'md' | 'sm'; + colorScheme: colorSchemeType; + children: React.ReactNode; + removeButton?: boolean; +} +const RemoveIcon = () => { + return ( + + + + ); +}; +const Tag = ({ children, colorScheme, variant, removeButton, size }: TagProps) => { + return ( + + {children && {children}} + {removeButton && ( + + )} + + ); +}; + +export default Tag; diff --git a/packages/chakra-ui-styled/src/components/badge/Badge.stories.tsx b/packages/chakra-ui-styled/src/components/badge/Badge.stories.tsx new file mode 100644 index 0000000..be98cd5 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/badge/Badge.stories.tsx @@ -0,0 +1,61 @@ +import styled from 'styled-components'; +import Badge, { BadgeProps, colorSchemeType } from './Badge'; + +export default { + title: 'chakra-ui-styled/components/Badge', + component: Badge, + parameters: { controls: { expanded: true } }, + + argTypes: { + variant: { control: { type: 'radio' } }, + colorScheme: { control: { type: 'select' } }, + children: { control: { type: 'text' } }, + }, + args: { + variant: 'solid', + colorScheme: 'blue', + children: '뱃지 테스트', + } +}; +const Wrapper = styled.div` + display: flex; + flex-direction: column; + gap: 20px; +`; +const BtnBox = styled.div` + display: flex; + gap: 16px; + align-items: center; +`; + +export const BadgeIndex = (args: BadgeProps) => { + const BadgeText: string = 'BADGE'; + const colorArr: colorSchemeType[] = ['gray', 'blue', 'teal', 'green', 'red', 'purple', 'pink', 'orange']; + return ( + +

Badge

+ +

Badge Demo

+
+ +
+ +

Badge Index

+ + {colorArr.map((color) => ( + + + {BadgeText} + + + {BadgeText} + + + {BadgeText} + + + ))} +
+ ); +}; +BadgeIndex.storyName = 'Badge'; diff --git a/packages/chakra-ui-styled/src/components/badge/Badge.styled.tsx b/packages/chakra-ui-styled/src/components/badge/Badge.styled.tsx new file mode 100644 index 0000000..728438a --- /dev/null +++ b/packages/chakra-ui-styled/src/components/badge/Badge.styled.tsx @@ -0,0 +1,35 @@ +import styled, { css } from 'styled-components'; +import { BadgeProps } from './Badge'; + +export const StyleBadge = styled.div` + ${({ theme, variant, colorScheme }) => css` + display: inline-flex; + align-items: center; + align-self: flex-start; + justify-content: center; + justify-self: flex-start; + width: auto; + height: 16px; + padding: 0 ${theme.spacing[1]}; + border-radius: ${theme.radii.sm}rem; + ${variant === 'solid' + ? css` + color: ${theme.color.white.white}; + background-color: ${theme.color[colorScheme][500]}; + border: 1px solid ${theme.color[colorScheme][500]}; + ` + : variant === 'subtle' + ? css` + color: ${theme.color[colorScheme][800]}; + background-color: ${theme.color[colorScheme][100]}; + border: 1px solid ${theme.color[colorScheme][100]}; + ` + : variant === 'outline' + ? css` + color: ${theme.color[colorScheme][600]}; + background-color: transparent; + border: 1px solid ${theme.color[colorScheme][500]}; + ` + : null} + `} +`; diff --git a/packages/chakra-ui-styled/src/components/badge/Badge.tsx b/packages/chakra-ui-styled/src/components/badge/Badge.tsx new file mode 100644 index 0000000..f22579a --- /dev/null +++ b/packages/chakra-ui-styled/src/components/badge/Badge.tsx @@ -0,0 +1,21 @@ +import { StyleText } from '../../foundation/typography/Text.styled'; +import { StyleBadge } from './Badge.styled'; + +export type colorSchemeType = 'blue' | 'gray' | 'teal' | 'red' | 'orange' | 'yellow' | 'pink' | 'purple' | 'green'; + +export interface BadgeProps { + colorScheme: colorSchemeType; + variant: 'solid' | 'subtle' | 'outline'; + children: React.ReactNode; +} + +const Badge = ({ variant = 'solid', colorScheme, children }: BadgeProps) => { + return ( + + + {children} + + + ); +}; +export default Badge; diff --git a/packages/chakra-ui-styled/src/components/date-display/card/Card.stories.tsx b/packages/chakra-ui-styled/src/components/date-display/card/Card.stories.tsx new file mode 100644 index 0000000..b1dff30 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/date-display/card/Card.stories.tsx @@ -0,0 +1,32 @@ +import Card from './Card'; +import { ReactNode } from 'react'; + +export type CardType = { + variant: 'elevated' | 'filled' | 'outline'; + children?: ReactNode; +}; +export default { + title: 'chakra-ui-styled/components/date-display/card', + component: Card, + parameter: { controls: { expanded: true } }, + argTypes: {}, + arg: { + variant: 'outline' + } +}; + +export const TableIndex = (args: CardType) => { + return ( + <> +

Demo

+ Demo test +
+ + + +
+ + ); +}; + +TableIndex.storyName = 'Table'; diff --git a/packages/chakra-ui-styled/src/components/date-display/card/Card.tsx b/packages/chakra-ui-styled/src/components/date-display/card/Card.tsx new file mode 100644 index 0000000..a734f7d --- /dev/null +++ b/packages/chakra-ui-styled/src/components/date-display/card/Card.tsx @@ -0,0 +1,34 @@ +import styled, { css } from 'styled-components'; +import { CardType } from './Card.stories'; + +const Card = ({ children, variant }: CardType) => { + return ( + <> + {children} + + ); +}; + +const Container = styled.article` + min-width: 350px; + padding: 20px; + border-radius: 8px; + ${({ variant }) => { + return variant === 'elevated' + ? css` + background-color: white; + box-shadow: + 0 1px 3px #0001, + 0 1px 2px #00000006; + ` + : variant === 'filled' + ? css` + background-color: #e2e8f0; + ` + : css` + border: 1px solid #e2e8f0; + `; + }}; +`; + +export default Card; diff --git a/packages/chakra-ui-styled/src/components/date-display/stats/Stats.stories.tsx b/packages/chakra-ui-styled/src/components/date-display/stats/Stats.stories.tsx new file mode 100644 index 0000000..87c6950 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/date-display/stats/Stats.stories.tsx @@ -0,0 +1,30 @@ +import Stats from './Stats'; + +export type StatsType = { + label: string; + number: string; + text: string; + type: 'increase' | 'decrease' | 'none'; +}; +export default { + title: 'chakra-ui-styled/components/date-display/stat', + component: Stats, + parameter: { controls: { expanded: true } }, + argTypes: {}, + arg: {} +}; + +export const StatsIndex = (args: StatsType) => { + return ( + <> +

Demo

+ +
+ + + + + ); +}; + +StatsIndex.storyName = 'Stat'; diff --git a/packages/chakra-ui-styled/src/components/date-display/stats/Stats.tsx b/packages/chakra-ui-styled/src/components/date-display/stats/Stats.tsx new file mode 100644 index 0000000..8f10c0d --- /dev/null +++ b/packages/chakra-ui-styled/src/components/date-display/stats/Stats.tsx @@ -0,0 +1,63 @@ +import { createContext } from 'react'; +import styled, { css } from 'styled-components'; +import { StatsType } from './Stats.stories'; + +const Stats = ({ label, number, text, type = 'none' }: StatsType) => { + return ( + + {label} + {number} + {type === 'increase' && ( + + + + + {text} + + )} + {type === 'decrease' && ( + + + + + {text} + + )} + {type === 'none' && {text}} + + ); +}; + +const Container = styled.div` + display: flex; + flex-direction: column; + gap: 4px; +`; +const StatLabel = styled.p` + ${({ theme }) => css` + color: ${theme.color.gray['700']}; + + font-size: ${theme.typo.text['sm'].fontSize}; + font-weight: ${theme.typo.text['sm'].fontWeight}; + `} +`; +const StatNumber = styled.p` + ${({ theme }) => css` + color: ${theme.color.gray['700']}; + + font-size: ${theme.typo.text['2xl'].fontSize}; + font-weight: ${theme.typo.fontWeight.semibold}; + `} +`; +const StatText = styled.p` + ${({ theme }) => css` + display: flex; + align-items: center; + font-size: ${theme.typo.text['sm'].fontSize}; + font-weight: ${theme.typo.text['sm'].fontWeight}; + color: ${theme.color.gray['700']}; + opacity: 0.8; + `} +`; + +export default Stats; diff --git a/packages/chakra-ui-styled/src/components/date-display/stats/assets/icon-dec.svg b/packages/chakra-ui-styled/src/components/date-display/stats/assets/icon-dec.svg new file mode 100644 index 0000000..808fddc --- /dev/null +++ b/packages/chakra-ui-styled/src/components/date-display/stats/assets/icon-dec.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/chakra-ui-styled/src/components/date-display/stats/assets/icon-inc.svg b/packages/chakra-ui-styled/src/components/date-display/stats/assets/icon-inc.svg new file mode 100644 index 0000000..3f36884 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/date-display/stats/assets/icon-inc.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/chakra-ui-styled/src/components/date-display/table/Table.stories.tsx b/packages/chakra-ui-styled/src/components/date-display/table/Table.stories.tsx new file mode 100644 index 0000000..f8c6689 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/date-display/table/Table.stories.tsx @@ -0,0 +1,76 @@ +import Table from './Table'; +import { progressType } from '../../feedback/progress/Progress.stories'; +import styled from 'styled-components'; + +export type ColumnType = { field: string }; +export type RowType = { [key: string]: string }; +const columnDefs: ColumnType[] = [ + { + field: 'one' + }, + { + field: 'kName' + }, + { + field: 'name' + } +]; +const rowDatas: RowType[] = [ + { + one: 'one', + name: 'one', + kName: '하나' + }, + { + one: 'two', + name: 'two', + kName: '두' + }, + { + one: 'three', + name: 'three', + kName: '셋' + } +]; +export type TableType = { + rD?: RowType[]; + cD?: ColumnType[]; + variant: 'unstyled' | 'striped' | 'simple'; +}; +export default { + title: 'chakra-ui-styled/components/date-display/table', + component: Table, + parameter: { controls: { expanded: true } }, + argTypes: {}, + arg: { + columnDefs, + rowDatas, + variant: 'unstyled' + } +}; + +export const TableIndex = (args: TableType) => { + return ( + <> + +

Demo

+ +
+
+
+
+ + + ); +}; + +const Container = styled.div` + width: 100%; + height: 100%; + background-color: #eee; + padding: 24px; + display: flex; + flex-direction: column; + gap: 24px; +`; +TableIndex.storyName = 'Table'; diff --git a/packages/chakra-ui-styled/src/components/date-display/table/Table.tsx b/packages/chakra-ui-styled/src/components/date-display/table/Table.tsx new file mode 100644 index 0000000..1a59e27 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/date-display/table/Table.tsx @@ -0,0 +1,92 @@ +import styled, { css } from 'styled-components'; +import { useState } from 'react'; +import { ColumnType, RowType, TableType } from './Table.stories'; +import { theme } from '../../../styles/ChakraThemeProvider'; + +const Table = ({ rD, cD, variant }: TableType) => { + const [columnDefs, setColumnDefs] = useState(cD || []); + const [rowDatas, setRowData] = useState(rD || []); + + const titles: string[] = columnDefs.map((columnDef) => columnDef.field); + return ( + <> + + + {titles.map((title, index) => ( + {title} + ))} + + {rowDatas.map((rowData, rIndex) => ( + + {titles.map((title, cIndex) => ( + {rowData[title]} + ))} + + ))} + + + ); +}; + +const Container = styled.article` + padding: 12px; + border-radius: 12px; + background-color: white; + border: 1px solid #e2e8f0; + font-size: ${({ theme }) => theme.typo.text.xs.fontSize}; + color: ${theme.color.gray[700]}; + + ${({ variant, theme }) => { + switch (variant) { + case 'unstyled': + return css` + border: none; + ${TableRow} { + border: none; + } + `; + case 'simple': + return css` + ${TableRow} { + border-bottom: 1px solid ${theme.color.gray['200']}; + &:last-child { + border: none; + } + } + `; + case 'striped': + return css` + ${TableRow}:nth-child(even) { + background-color: ${theme.color.gray['100']}; + } + `; + default: + return css``; + } + }} +`; +const HeadingRow = styled.section` + &:first-child { + font-weight: ${({ theme }) => theme.typo.fontWeight.bold}; + } + display: flex; +`; +const TableRow = styled.section` + display: flex; + padding: 16px 24px; +`; +const TitleColumn = styled.div` + flex: 1; + padding: 16px 24px; +`; + +const RowData = styled.div` + flex: 1; + font-size: ${({ theme }) => theme.typo.text.sm.fontSize}; + + &:first-child { + font-weight: ${({ theme }) => theme.typo.fontWeight.medium}; + } +`; +// accent : font medium : regular +export default Table; diff --git a/packages/chakra-ui-styled/src/components/disclosure/accordion/Accordion.stories.tsx b/packages/chakra-ui-styled/src/components/disclosure/accordion/Accordion.stories.tsx new file mode 100644 index 0000000..e8f4535 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/disclosure/accordion/Accordion.stories.tsx @@ -0,0 +1,65 @@ +import Accordion from './Accordion'; +import styled from 'styled-components'; +import { ReactNode } from 'react'; + +export type accordionType = { + state: boolean; + title?: string; + text?: string; + children?: ReactNode; +}; + +export default { + title: 'chakra-ui-styled/components/disclosure/accordion', + component: Accordion, + parameter: { controls: { expanded: true } }, + argTypes: { + state: { + control: { + type: 'boolean', + title: 'Accordion Button', + text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.' + } + } + } +}; + +const Container = styled.div``; +export const AccordionComponent = (args: accordionType) => { + return ( + <> + +

Accordion Demo

+ + + + + +
+
+
+ + + + + + + + + + + +
+ + ); +}; +AccordionComponent.storyName = 'Accordion'; diff --git a/packages/chakra-ui-styled/src/components/disclosure/accordion/Accordion.tsx b/packages/chakra-ui-styled/src/components/disclosure/accordion/Accordion.tsx new file mode 100644 index 0000000..6853063 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/disclosure/accordion/Accordion.tsx @@ -0,0 +1,88 @@ +import { accordionType } from './Accordion.stories'; +import { createContext, ReactNode, useContext, useState } from 'react'; +import styled, { css } from 'styled-components'; + +const AccordionContext = createContext({ + isOpen: false, + setIsOpen: (value: boolean) => {} +}); + +const Accordion = ({ state, children }: accordionType) => { + const [isOpen, setIsOpen] = useState(state); + const providerValue = { + isOpen, + setIsOpen + }; + return ( + + {children} + + ); +}; + +const Toggle = ({ title, children }: { title: string; children?: ReactNode }) => { + const { isOpen, setIsOpen } = useContext(AccordionContext); + + return ( +
setIsOpen(!isOpen)}> + +
{title}
+
+ + + +
+
+

{children}

+
+ ); +}; + +const Panel = ({ text }: { text: string }) => { + const { isOpen } = useContext(AccordionContext); + + return isOpen && {text}; +}; + +Accordion.Toggle = Toggle; +Accordion.Panel = Panel; + +export default Accordion; + +const TitleBox = styled.div<{ isOpen: boolean }>` + display: flex; + justify-content: space-between; + flex: 1; + width: inherit; + max-width: 345px; + user-select: none; + ${({ isOpen }) => + isOpen && + css` + div { + transform: rotate(180deg); + } + `} +`; +const TextBox = styled.div` + font-size: 16px; + font-weight: 400; +`; + +const Container = styled.article` + display: flex; + justify-content: space-between; + align-items: center; + width: 403px; + border-block: 1px solid #d0d0d0; + padding: 10px 12px; + h5 { + font-size: 16px; + font-weight: 400; + } + > div { + display: flex; + width: 100%; + flex-direction: column; + } +`; diff --git a/packages/chakra-ui-styled/src/components/disclosure/accordion/asset/AccordionIcon.svg b/packages/chakra-ui-styled/src/components/disclosure/accordion/asset/AccordionIcon.svg new file mode 100644 index 0000000..2b23fec --- /dev/null +++ b/packages/chakra-ui-styled/src/components/disclosure/accordion/asset/AccordionIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/chakra-ui-styled/src/components/disclosure/tabs/Tabs.stories.tsx b/packages/chakra-ui-styled/src/components/disclosure/tabs/Tabs.stories.tsx new file mode 100644 index 0000000..3915295 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/disclosure/tabs/Tabs.stories.tsx @@ -0,0 +1,77 @@ +import Tabs from './Tabs'; +import { tabType } from './tab/tab.types'; +import styled from 'styled-components'; + +export default { + title: 'chakra-ui-styled/components/disclosure/tabs', + component: Tabs, + parameter: { controls: { expanded: true } }, + argTypes: { + size: { + control: { + type: 'select' + } + }, + styleType: { + control: { + type: 'select' + } + }, + active: { + control: { + type: 'boolean' + } + }, + arg: { + size: 'lg', + styleType: 'unstyled', + active: 'true', + text: 'Tabs' + } + } +}; + +const Container = styled.div` + background-color: #eee; +`; + +export const TabsComponent = (args: tabType) => { + return ( + +

Tabs Demo

+ +
+

unstyled

+ + + +
+
+

line Tabs

+ + + +
+
+

enclosed Tabs

+ + + +
+
+

soft-rounded Tabs

+ + + +
+
+

solid-rounded Tabs

+ + + +
+
+ ); +}; + +TabsComponent.storyName = 'Tabs'; diff --git a/packages/chakra-ui-styled/src/components/tabs/Tabs.styles.tsx b/packages/chakra-ui-styled/src/components/disclosure/tabs/Tabs.styles.tsx similarity index 100% rename from packages/chakra-ui-styled/src/components/tabs/Tabs.styles.tsx rename to packages/chakra-ui-styled/src/components/disclosure/tabs/Tabs.styles.tsx diff --git a/packages/chakra-ui-styled/src/components/disclosure/tabs/Tabs.tsx b/packages/chakra-ui-styled/src/components/disclosure/tabs/Tabs.tsx new file mode 100644 index 0000000..b92a3eb --- /dev/null +++ b/packages/chakra-ui-styled/src/components/disclosure/tabs/Tabs.tsx @@ -0,0 +1,44 @@ +import styled, { css } from 'styled-components'; +import Tab from './tab/Tab'; +import { tabType } from './tab/tab.types'; + +const Container = styled.div` + ${({ theme }) => css` + display: flex; + > div { + border-bottom: 2px solid ${theme.color.gray[200]}; + } + h2 { + span { + font-weight: 400; + } + } + `} +`; +// active 를 기본값 null false, true 면 true; +const Tabs = ({ size, styleType, active, text }: tabType) => { + return ( + + + + + + ); +}; + +// tab atoms 종류 +// +// unstyled +// soft-rounded +// solid-rounded +// enclosed +// line +// +// tab 사이즈 +// +// lg +// md +// sm +// tabs 종류별 1묶음으로 크기 분류 + +export default Tabs; diff --git a/packages/chakra-ui-styled/src/components/disclosure/tabs/tab/Tab.stories.tsx b/packages/chakra-ui-styled/src/components/disclosure/tabs/tab/Tab.stories.tsx new file mode 100644 index 0000000..f1d0ed2 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/disclosure/tabs/tab/Tab.stories.tsx @@ -0,0 +1,84 @@ +import Tab from './Tab'; +import { tabType } from './tab.types'; +import styled from 'styled-components'; +// import { TextComponent } from '../../../../foundation/typography/Text.styled'; + +export default { + title: 'chakra-ui-styled/components/tabs', + component: Tab, + parameter: { controls: { expanded: true } }, + argTypes: { + size: { + control: { + type: 'select' + } + }, + styleType: { + control: { + type: 'select' + } + }, + active: { + control: { + type: 'boolean' + } + }, + arg: { + size: 'lg', + styleType: 'unstyled', + active: 'true', + text: 'Tabs' + } + } +}; +const DemoContainer = styled.div` + padding: 2rem; + background-color: #ddd; +`; +const Container = styled.div` + display: flex; + flex-direction: column; + gap: 16px; + div { + display: flex; + gap: 16px; + } + background-color: #eee; + padding: 2rem; +`; +export const TabComponent = (args: tabType) => { + return ( +
+

Tab

+ +

demo

+ +
+ +
+ + + + + +
+
+ + + + + +
+
+ + + + + +
+
+
+ ); +}; + +TabComponent.storyName = 'Tab'; diff --git a/packages/chakra-ui-styled/src/components/disclosure/tabs/tab/Tab.tsx b/packages/chakra-ui-styled/src/components/disclosure/tabs/tab/Tab.tsx new file mode 100644 index 0000000..599a27d --- /dev/null +++ b/packages/chakra-ui-styled/src/components/disclosure/tabs/tab/Tab.tsx @@ -0,0 +1,117 @@ +import styled, { css } from 'styled-components'; +import { tabType } from './tab.types'; +import { TextComponent } from '../../../../foundation/typography/Text'; +// +// export const sizeStyles = { +// sm: css` +// padding: ${({ theme }) => theme.spacing[4]} ${({ theme }) => theme.spacing[1]}; +// background-color: transparent; +// `, +// md: css` +// padding: ${({ theme }) => theme.spacing[4]} ${({ theme }) => theme.spacing[2]}; +// background-color: transparent; +// `, +// lg: css` +// padding: ${({ theme }) => theme.spacing[4]} ${({ theme }) => theme.spacing[3]}; +// background-color: transparent; +// ` +// }; +// +// export const tabStyle = { +// unstyled: css` +// background-color: transparent; +// border: none; +// `, +// line: css` +// color: ${({ theme }) => theme.color.blue[600]}; +// border-bottom: 2px solid ${({ theme }) => theme.color.blue[600]}; +// `, +// enclosed: css` +// color: ${({ theme }) => theme.color.blue[600]}; +// background-color: ${({ theme }) => theme.color.white.white}; +// border-top: ${({ theme }) => theme.spacing.px} solid ${({ theme }) => theme.color.gray[200]}; +// border-right: ${({ theme }) => theme.spacing.px} solid ${({ theme }) => theme.color.gray[200]}; +// border-left: ${({ theme }) => theme.spacing.px} solid ${({ theme }) => theme.color.gray[200]}; +// border-radius: ${({ theme }) => theme.radii.md} ${({ theme }) => theme.radii.md} 0 0; +// `, +// softRounded: css` +// color: ${({ theme }) => theme.color.blue[700]}; +// background-color: ${({ theme }) => theme.color.blue[100]}; +// border-radius: 999px; +// `, +// solidRounded: css` +// color: ${({ theme }) => theme.color.white.white}; +// background-color: ${({ theme }) => theme.color.blue[600]}; +// border-radius: 999px; +// ` +// }; + +const TabBtn = styled.div` + ${({ theme, size, active, styleType }) => { + const sizeStyles = { + sm: css` + padding: ${theme.spacing[1]} ${theme.spacing[4]}; + `, + md: css` + padding: ${theme.spacing[2]} ${theme.spacing[4]}; + `, + lg: css` + padding: ${theme.spacing[3]} ${theme.spacing[4]}; + ` + }; + const tabStyle = { + unstyled: css` + background-color: transparent !important; + border: none; + `, + line: css` + color: ${theme.color.blue[600]}; + background-color: transparent; + border-bottom: 2px solid ${theme.color.blue[600]}; + `, + enclosed: css` + color: ${theme.color.blue[600]}; + background-color: ${theme.color.white.white} !important; + border-top: ${theme.spacing.px} solid ${theme.color.gray[200]}; + border-right: ${theme.spacing.px} solid ${theme.color.gray[200]}; + border-left: ${theme.spacing.px} solid ${theme.color.gray[200]}; + border-radius: ${theme.radii.md} ${theme.radii.md} 0 0; + `, + softRounded: css` + color: ${theme.color.blue[700]}; + background-color: ${theme.color.blue[100]} !important; + border-radius: 999px; + `, + solidRounded: css` + color: ${theme.color.white.white}; + background-color: ${theme.color.blue[600]} !important; + border-radius: 999px; + ` + }; + return css` + ${active && tabStyle[styleType]} + ${sizeStyles[size]} + `; + }} +`; + +// TODO +// size = sm md lg 프롭스로 전달 후 +// {({size))=> size === 'sm' && } 식으로 작업하여 동적 작업하기. +const Tab = ({ size, styleType, active, text = 'Tabs' }: tabType) => { + //rounded = fsz semibold 그외 medium + + return ( + <> +
+ {/**/} + + {text} + +
+
+ + ); +}; + +export default Tab; diff --git a/packages/chakra-ui-styled/src/components/disclosure/tabs/tab/tab.types.ts b/packages/chakra-ui-styled/src/components/disclosure/tabs/tab/tab.types.ts new file mode 100644 index 0000000..adc2a0c --- /dev/null +++ b/packages/chakra-ui-styled/src/components/disclosure/tabs/tab/tab.types.ts @@ -0,0 +1,6 @@ +export interface tabType { + text?: string; + size: 'sm' | 'md' | 'lg'; + styleType: 'unstyled' | 'line' | 'enclosed' | 'softRounded' | 'solidRounded'; + active: boolean; +} diff --git a/packages/chakra-ui-styled/src/components/feedback/alert/Alert.stories.tsx b/packages/chakra-ui-styled/src/components/feedback/alert/Alert.stories.tsx new file mode 100644 index 0000000..007bc14 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/feedback/alert/Alert.stories.tsx @@ -0,0 +1,89 @@ +import Alert from './Alert'; + +export type alertType = { + alertStyle: 'vanilla' | 'solid' | 'top-border' | 'left-border'; + variant: 'info' | 'warning' | 'error' | 'success'; + title?: string; + text?: string; +}; +export default { + title: 'chakra-ui-styled/components/feedback/alert', + component: Alert, + parameter: { controls: { expanded: true } }, + argTypes: { + alertStyle: { control: { type: 'select' } }, + variant: { control: { type: 'select' } }, + title: { control: { type: 'text' } }, + text: { control: { type: 'text' } } + }, + arg: { + variant: 'info', + alertStyle: 'vanilla', + title: 'Title', + text: 'This is a description.' + } +}; + +export const AlertIndex = (args: alertType) => { + return ( + <> +
+

Alert Demo

+ +
+
+

Info

+ +
+ + + +
+ + +
+ + +
+
+

warning

+ +
+ +
+ + +
+ + +
+
+

error

+ +
+ + +
+ + +
+ + +
+
+

success

+ +
+ + +
+ + +
+ + +
+ + ); +}; +AlertIndex.storyName = 'Alert'; diff --git a/packages/chakra-ui-styled/src/components/feedback/alert/Alert.tsx b/packages/chakra-ui-styled/src/components/feedback/alert/Alert.tsx new file mode 100644 index 0000000..2797c36 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/feedback/alert/Alert.tsx @@ -0,0 +1,97 @@ +import styled, { css } from 'styled-components'; +import Icon from './Icon'; +import { alertType } from './Alert.stories'; + +const demoTitle: alertType['title'] = 'Title'; +const demoText: alertType['text'] = 'This is a description.'; + +const Alert = ({ alertStyle, variant, title = demoTitle, text = demoText }: alertType) => { + return ( + + + +
{title}
+

{text}

+
+
+ ); +}; + +const Container = styled.article` + display: flex; + align-items: center; + gap: 12px; + width: 400px; + height: 72px; + padding: 12px; + ${({ theme, variant }) => css` + background-color: ${variant === 'info' + ? theme.color.blue['100'] + : variant === 'warning' + ? theme.color.orange['100'] + : variant === 'error' + ? theme.color.red['100'] + : variant === 'success' + ? theme.color.green['100'] + : null}; + `}; + + ${({ variant, alertStyle, theme }) => css` + ${alertStyle === 'left-border' + ? css` + border-left-style: solid; + border-left-width: 4px; + border-left-color: ${variant === 'info' + ? theme.color.blue['500'] + : variant === 'warning' + ? theme.color.orange['500'] + : variant === 'error' + ? theme.color.red['500'] + : variant === 'success' + ? theme.color.green['500'] + : null}; + ` + : alertStyle === 'top-border' + ? css` + border-top-style: solid; + border-top-width: 4px; + border-top-color: ${variant === 'info' + ? theme.color.blue['500'] + : variant === 'warning' + ? theme.color.orange['500'] + : variant === 'error' + ? theme.color.red['500'] + : variant === 'success' + ? theme.color.green['500'] + : null}; + ` + : alertStyle === 'solid' + ? css` + color: ${theme.color.white.white}; + background-color: ${variant === 'info' + ? theme.color.blue['500'] + : variant === 'warning' + ? theme.color.orange['500'] + : variant === 'error' + ? theme.color.red['500'] + : variant === 'success' + ? theme.color.green['500'] + : null}; + ` + : null} + `} +`; +const TextBox = styled.div` + display: flex; + flex-direction: column; + h5 { + font-size: 17px; + font-weight: 700; + } + p { + font-size: 16px; + font-weight: 400; + } +`; + +export default Alert; diff --git a/packages/chakra-ui-styled/src/components/feedback/alert/Icon.tsx b/packages/chakra-ui-styled/src/components/feedback/alert/Icon.tsx new file mode 100644 index 0000000..36b5c89 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/feedback/alert/Icon.tsx @@ -0,0 +1,60 @@ +import { alertType } from './Alert.stories'; + +type IconProps = { + alertStyle: alertType['alertStyle']; + variant: alertType['variant']; +}; +const Icon = ({ alertStyle, variant }: IconProps) => { + let color; + if (variant === 'info') { + color = alertStyle === 'solid' ? '#fff' : '#3182ce'; + return ( + <> + + + + + ); + } else if (variant === 'error') { + color = alertStyle === 'solid' ? '#fff' : '#e53e3e'; + return ( + <> + + + + + ); + } else if (variant === 'success') { + color = alertStyle === 'solid' ? '#fff' : '#38a169'; + return ( + <> + + + + + ); + } else if (variant === 'warning') { + color = alertStyle === 'solid' ? '#fff' : '#dd6b20'; + return ( + <> + + + + + ); + } +}; + +export default Icon; diff --git a/packages/chakra-ui-styled/src/components/feedback/alert/assets/errorIcon.svg b/packages/chakra-ui-styled/src/components/feedback/alert/assets/errorIcon.svg new file mode 100644 index 0000000..af22bd6 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/feedback/alert/assets/errorIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/chakra-ui-styled/src/components/feedback/alert/assets/infoIcon.svg b/packages/chakra-ui-styled/src/components/feedback/alert/assets/infoIcon.svg new file mode 100644 index 0000000..6f28670 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/feedback/alert/assets/infoIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/chakra-ui-styled/src/components/feedback/alert/assets/successIcon.svg b/packages/chakra-ui-styled/src/components/feedback/alert/assets/successIcon.svg new file mode 100644 index 0000000..2b54d8c --- /dev/null +++ b/packages/chakra-ui-styled/src/components/feedback/alert/assets/successIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/chakra-ui-styled/src/components/feedback/alert/assets/warningIcon.svg b/packages/chakra-ui-styled/src/components/feedback/alert/assets/warningIcon.svg new file mode 100644 index 0000000..41da3e1 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/feedback/alert/assets/warningIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/chakra-ui-styled/src/components/feedback/progress/Progress.stories.tsx b/packages/chakra-ui-styled/src/components/feedback/progress/Progress.stories.tsx new file mode 100644 index 0000000..b5e9f21 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/feedback/progress/Progress.stories.tsx @@ -0,0 +1,82 @@ +import Progress from './Progress'; + +export type progressType = { + progress: number; + size: 'xs' | 'sm' | 'md' | 'lg'; + color: string; +}; +export default { + title: 'chakra-ui-styled/components/feedback/progress', + component: Progress, + parameter: { controls: { expanded: true } }, + argTypes: { + progress: { + control: { + type: 'number' + } + }, + size: { + options: ['xs', 'sm', 'md', 'lg'], + control: { + type: 'select' + } + }, + color: { + options: ['green', 'blue', 'red', 'orange', 'pink', 'purple', 'teal'], + control: { + type: 'select' + } + } + }, + arg: { + progress: 10, + size: 'lg', + color: 'red' + } +}; + +export const ProgressIndex = (args: progressType) => { + console.log(args); + return ( + <> +
+

Progress Demo

+
+ + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+
+ + + + +
+
+
+ + + + +
+ + ); +}; + +ProgressIndex.storyName = 'Progress'; diff --git a/packages/chakra-ui-styled/src/components/feedback/progress/Progress.tsx b/packages/chakra-ui-styled/src/components/feedback/progress/Progress.tsx new file mode 100644 index 0000000..63a0f8e --- /dev/null +++ b/packages/chakra-ui-styled/src/components/feedback/progress/Progress.tsx @@ -0,0 +1,302 @@ +import styled, { css } from 'styled-components'; +import { createContext, ReactNode, useContext, useEffect, useState } from 'react'; +import { progressType } from './Progress.stories'; + +export type contextType = progressType & { + children?: ReactNode; +}; + +const ProgressContext = createContext({ + color: 'green', + size: 'lg', + percent: 0, + setPercent: (value: number) => {} +}); + +const Progress = ({ color, size, progress, children }: contextType) => { + const [percent, setPercent] = useState(0); + const providerValue = { + color, + size, + percent, + setPercent + }; + + useEffect(() => { + setPercent(progress); + }, [progress]); + return ( + + {children} + + ); +}; + +const Inner = () => { + const { percent, size, color } = useContext(ProgressContext); + console.log('Inner context:', { percent, size, color }); + const height = size === 'xs' ? 4 : size === 'sm' ? 8 : size === 'md' ? 16 : 20; + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; + +const Track = () => { + return ; +}; +// height 4 8 12 16 color blue,orange,pink,purple,red,green,teal +const Container = styled.div<{ size: string }>` + width: 400px; + ${({ theme, size }) => { + if (size === 'xs') { + return css` + height: 4px; + `; + } else if (size === 'sm') { + return css` + height: 8px; + `; + } else if (size === 'md') { + return css` + height: 12px; + `; + } else if (size === 'lg') { + return css` + height: 16px; + `; + } + }} + display: flex; + overflow: hidden; +`; + +const Bar = styled.div<{ percent: number; color: string }>` + flex-shrink: 0; + position: relative; + ${({ percent, color }) => css` + width: ${percent}%; + background-color: ${color}; + `} + svg { + position: absolute; + top: 0; + left: 0; + } +`; +const Background = styled.div` + background-color: #edf2f7; + flex: 1; +`; +export default Progress; +Progress.Inner = Inner; +Progress.Track = Track; diff --git a/packages/chakra-ui-styled/src/components/feedback/progress/assets/progress-stripe.svg b/packages/chakra-ui-styled/src/components/feedback/progress/assets/progress-stripe.svg new file mode 100644 index 0000000..d5e86c9 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/feedback/progress/assets/progress-stripe.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/chakra-ui-styled/src/components/feedback/skeleton/Skeleton.stories.tsx b/packages/chakra-ui-styled/src/components/feedback/skeleton/Skeleton.stories.tsx new file mode 100644 index 0000000..7c73b7f --- /dev/null +++ b/packages/chakra-ui-styled/src/components/feedback/skeleton/Skeleton.stories.tsx @@ -0,0 +1,51 @@ +import Skeleton from './Skeleton'; +import { ReactNode } from 'react'; + +export type skeletonType = { + isLoading: boolean; + children?: ReactNode; +}; +export default { + title: 'chakra-ui-styled/components/feedback/skeleton', + component: Skeleton, + parameter: { controls: { expanded: true } }, + argTypes: { + isLoading: { + control: { + type: 'boolean' + } + } + }, + arg: { + isLoading: true + } +}; + +export const SkeletonIndex = (args: skeletonType) => { + return ( + <> +

Demo

+ +
+
+

+

+

+ +
+ +

.skeleton-text

+
+
+
+

.skeleton-image

+
+ +

.skeleton-circle

+
+ + + ); +}; + +SkeletonIndex.storyName = 'Skeleton'; diff --git a/packages/chakra-ui-styled/src/components/feedback/skeleton/Skeleton.tsx b/packages/chakra-ui-styled/src/components/feedback/skeleton/Skeleton.tsx new file mode 100644 index 0000000..356b2b5 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/feedback/skeleton/Skeleton.tsx @@ -0,0 +1,50 @@ +import styled from 'styled-components'; +import { skeletonType } from './Skeleton.stories'; + +const Skeleton = ({ isLoading, children }: skeletonType) => { + return isLoading && {children}; +}; + +const SkeletonTheme = styled.div` + @keyframes gradientShift { + 0% { + background-position: 0 51%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0 51%; + } + } + + & .skeleton-circle { + background: linear-gradient(270deg, #e2e8f0, #ffffff); + background-size: 400% 400%; + animation: gradientShift 4s ease infinite; + border-radius: 9999px; + width: 51px; + height: 51px; + margin: 16px 0; + } + & .skeleton-text { + background: linear-gradient(270deg, #e2e8f0, #ffffff); + background-size: 400% 400%; + animation: gradientShift 4s ease infinite; + width: 447px; + border-radius: 2px; + height: 8px; + align-self: stretch; + margin: 16px 0; + } + & .skeleton-image { + background: linear-gradient(270deg, #e2e8f0, #ffffff); + background-size: 400% 400%; + animation: gradientShift 4s ease infinite; + border-radius: 4px; + width: 447px; + height: 113px; + margin: 16px 0; + } +`; +export default Skeleton; diff --git a/packages/chakra-ui-styled/src/components/form/button/Button.stories.tsx b/packages/chakra-ui-styled/src/components/form/button/Button.stories.tsx index a855d04..3e11a13 100644 --- a/packages/chakra-ui-styled/src/components/form/button/Button.stories.tsx +++ b/packages/chakra-ui-styled/src/components/form/button/Button.stories.tsx @@ -1,13 +1,25 @@ import styled from 'styled-components'; import Button, { ButtonProps } from './Button'; +const IconDummy = () => { + return ( + + + + ); +}; + export default { title: 'chakra-ui-styled/components/form/button', component: Button, parameters: { controls: { expanded: true } }, argTypes: { - text: { control: { type: 'text' } }, + as: { control: { type: 'text' } }, + children: { control: { type: 'text' } }, size: { control: { type: 'select' } }, colorScheme: { control: { type: 'select' } }, variant: { control: { type: 'radio' } }, @@ -15,12 +27,12 @@ export default { rightIcon: { control: { type: 'text' } } }, args: { - text: '안녕', + children: '안녕', size: 'lg', - leftIcon: 'react', - rightIcon: 'react', colorScheme: 'blue', - variant: 'solid' + variant: 'solid', + leftIcon: , + rightIcon: } }; const Wrapper = styled.div` @@ -33,6 +45,7 @@ const BtnBox = styled.div` gap: 16px; align-items: center; `; + export const ButtonIndex = (args: ButtonProps) => { const btnText: string = 'Button'; return ( @@ -46,129 +59,273 @@ export const ButtonIndex = (args: ButtonProps) => {

Button Index

- + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + ); diff --git a/packages/chakra-ui-styled/src/components/form/button/Button.styled.tsx b/packages/chakra-ui-styled/src/components/form/button/Button.styled.tsx new file mode 100644 index 0000000..9f7f8b8 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/button/Button.styled.tsx @@ -0,0 +1,180 @@ +import styled, { css } from 'styled-components'; +import { ButtonProps } from './Button'; + +const iconSize = { + lg: '16px', + md: '16px', + sm: '14px', + xs: '12px' +}; + +const buttonSize = { + lg: css` + height: 48px; + padding: 0 ${({ theme }) => theme.spacing[6]}; + `, + md: css` + height: 40px; + padding: 0 ${({ theme }) => theme.spacing[4]}; + `, + sm: css` + height: 32px; + padding: 0 ${({ theme }) => theme.spacing[3]}; + `, + xs: css` + height: 24px; + padding: 0 ${({ theme }) => theme.spacing[2]}; + ` +}; + +const buttonColor = { + blue: { + enabled: css` + ${({ theme }) => theme.color.blue[500]} + `, + hover: css` + ${({ theme }) => theme.color.blue[400]} + `, + active: css` + ${({ theme }) => theme.color.blue[600]} + ` + }, + gray: { + enabled: css` + ${({ theme }) => theme.color.gray[100]} + `, + hover: css` + ${({ theme }) => theme.color.gray[50]} + `, + active: css` + ${({ theme }) => theme.color.gray[200]} + ` + }, + teal: { + enabled: css` + ${({ theme }) => theme.color.teal[500]} + `, + hover: css` + ${({ theme }) => theme.color.teal[400]} + `, + active: css` + ${({ theme }) => theme.color.teal[600]} + ` + }, + red: { + enabled: css` + ${({ theme }) => theme.color.red[500]} + `, + hover: css` + ${({ theme }) => theme.color.red[400]} + `, + active: css` + ${({ theme }) => theme.color.red[600]} + ` + }, + orange: { + enabled: css` + ${({ theme }) => theme.color.orange[500]} + `, + hover: css` + ${({ theme }) => theme.color.orange[400]} + `, + active: css` + ${({ theme }) => theme.color.orange[600]} + ` + }, + yellow: { + enabled: css` + ${({ theme }) => theme.color.yellow[400]} + `, + hover: css` + ${({ theme }) => theme.color.yellow[300]} + `, + active: css` + ${({ theme }) => theme.color.yellow[500]} + ` + }, + pink: { + enabled: css` + ${({ theme }) => theme.color.pink[500]} + `, + hover: css` + ${({ theme }) => theme.color.pink[400]} + `, + active: css` + ${({ theme }) => theme.color.pink[600]} + ` + }, + purple: { + enabled: css` + ${({ theme }) => theme.color.purple[500]} + `, + hover: css` + ${({ theme }) => theme.color.purple[400]} + `, + active: css` + ${({ theme }) => theme.color.purple[600]} + ` + }, + green: { + enabled: css` + ${({ theme }) => theme.color.green[500]} + `, + hover: css` + ${({ theme }) => theme.color.green[400]} + `, + active: css` + ${({ theme }) => theme.color.green[600]} + ` + } +}; + +export const StyleButton = styled.button` + ${({ theme, variant, colorScheme }) => css` + display: flex; + column-gap: ${theme.spacing[2]}; + align-items: center; + justify-content: center; + border: 1px solid ${buttonColor[colorScheme].enabled}; + border-radius: ${theme.radii.md}rem; + + ${variant === 'outline' + ? css` + color: ${colorScheme === 'gray' ? theme.color.gray[800] : buttonColor[colorScheme].enabled}; + background-color: ${theme.color.white.white}; + + &:hover { + color: ${colorScheme === 'gray' ? theme.color.gray[800] : buttonColor[colorScheme].hover}; + border-color: ${buttonColor[colorScheme].hover}; + } + + &:active { + color: ${colorScheme === 'gray' ? theme.color.gray[800] : buttonColor[colorScheme].hover}; + border-color: ${buttonColor[colorScheme].active}; + } + ` + : variant === 'solid' + ? css` + color: ${colorScheme === 'gray' || colorScheme === 'yellow' + ? theme.color.gray[800] + : theme.color.white.white}; + background-color: ${buttonColor[colorScheme].enabled}; + + &:hover { + background-color: ${buttonColor[colorScheme].hover}; + border-color: ${buttonColor[colorScheme].hover}; + } + + &:active { + background-color: ${buttonColor[colorScheme].active}; + border-color: ${buttonColor[colorScheme].active}; + } + ` + : null} + `} + & .icon, & .icon svg { + width: ${({ size }) => iconSize[size]}; + height: ${({ size }) => iconSize[size]}; + } + ${({ size }) => buttonSize[size]} +`; diff --git a/packages/chakra-ui-styled/src/components/form/button/Button.tsx b/packages/chakra-ui-styled/src/components/form/button/Button.tsx index 57b12b9..565a242 100644 --- a/packages/chakra-ui-styled/src/components/form/button/Button.tsx +++ b/packages/chakra-ui-styled/src/components/form/button/Button.tsx @@ -1,242 +1,39 @@ -import styled, { css } from 'styled-components'; -import { TextComponent } from '../../../foundation/typography/Text.styled'; +import { StyleText } from '../../../foundation/typography/Text.styled'; +import { StyleButton } from './Button.styled'; export interface ButtonProps { + as?: React.ElementType; size: 'lg' | 'md' | 'sm' | 'xs'; colorScheme: 'blue' | 'gray' | 'teal' | 'red' | 'orange' | 'yellow' | 'pink' | 'purple' | 'green'; variant?: 'solid' | 'outline'; - leftIcon?: string; - rightIcon?: string; - text: string; + children?: string; + leftIcon?: React.ReactNode; + rightIcon?: React.ReactNode; + onClick?: () => void; } - -// @todo icon dummy 추후 수정 -interface IconBaseProps { - size: string; -} -const IconDummy = ({ size }: IconBaseProps) => { - return ( - - - - ); +const setIcon = (icon: React.ReactNode) => { + return
{icon}
; }; -const getColor = (colorScheme: string) => { - // css`${({ theme }) => { - switch (colorScheme) { - case 'blue': - return { - enabled: css` - ${({ theme }) => theme.color.blue[500]} - `, - hover: css` - ${({ theme }) => theme.color.blue[400]} - `, - active: css` - ${({ theme }) => theme.color.blue[600]} - ` - }; - case 'gray': - return { - enabled: css` - ${({ theme }) => theme.color.gray[100]} - `, - hover: css` - ${({ theme }) => theme.color.gray[50]} - `, - active: css` - ${({ theme }) => theme.color.gray[200]} - ` - }; - case 'teal': - return { - enabled: css` - ${({ theme }) => theme.color.teal[500]} - `, - hover: css` - ${({ theme }) => theme.color.teal[400]} - `, - active: css` - ${({ theme }) => theme.color.teal[600]} - ` - }; - case 'red': - return { - enabled: css` - ${({ theme }) => theme.color.red[500]} - `, - hover: css` - ${({ theme }) => theme.color.red[400]} - `, - active: css` - ${({ theme }) => theme.color.red[600]} - ` - }; - case 'orange': - return { - enabled: css` - ${({ theme }) => theme.color.orange[500]} - `, - hover: css` - ${({ theme }) => theme.color.orange[400]} - `, - active: css` - ${({ theme }) => theme.color.orange[600]} - ` - }; - case 'yellow': - return { - enabled: css` - ${({ theme }) => theme.color.yellow[400]} - `, - hover: css` - ${({ theme }) => theme.color.yellow[300]} - `, - active: css` - ${({ theme }) => theme.color.yellow[500]} - ` - }; - case 'pink': - return { - enabled: css` - ${({ theme }) => theme.color.pink[500]} - `, - hover: css` - ${({ theme }) => theme.color.pink[400]} - `, - active: css` - ${({ theme }) => theme.color.pink[600]} - ` - }; - case 'purple': - return { - enabled: css` - ${({ theme }) => theme.color.purple[500]} - `, - hover: css` - ${({ theme }) => theme.color.purple[400]} - `, - active: css` - ${({ theme }) => theme.color.purple[600]} - ` - }; - case 'green': - return { - enabled: css` - ${({ theme }) => theme.color.green[500]} - `, - hover: css` - ${({ theme }) => theme.color.green[400]} - `, - active: css` - ${({ theme }) => theme.color.green[600]} - ` - }; - default: - return { - enabled: css` - ${({ theme }) => theme.color.blue[500]} - `, - hover: css` - ${({ theme }) => theme.color.blue[400]} - `, - active: css` - ${({ theme }) => theme.color.blue[600]} - ` - }; - } -}; - -const getButtonSize = (size: string) => css` - ${({ theme }) => { - switch (size) { - case 'lg': - return css` - height: 48px; - padding: 0 ${theme.spacing[6]}; - `; - case 'md': - return css` - height: 40px; - padding: 0 ${theme.spacing[4]}; - `; - case 'sm': - return css` - height: 32px; - padding: 0 ${theme.spacing[3]}; - `; - case 'xs': - return css` - height: 24px; - padding: 0 ${theme.spacing[2]}; - `; - } - }} -`; - -const iconSize = { - lg: '16px', - md: '16px', - sm: '14px', - xs: '12px' -}; - -const StyleButton = styled.button` - ${({ theme, variant, colorScheme }) => css` - display: flex; - column-gap: ${theme.spacing[2]}; - align-items: center; - justify-content: center; - border: 1px solid ${getColor(colorScheme).enabled}; - border-radius: ${theme.radii.md}rem; - - ${variant === 'outline' - ? css` - color: ${colorScheme === 'gray' ? theme.color.gray[800] : getColor(colorScheme).enabled}; - background-color: ${theme.color.white.white}; - - &:hover { - color: ${colorScheme === 'gray' ? theme.color.gray[800] : getColor(colorScheme).hover}; - border-color: ${getColor(colorScheme).hover}; - } - - &:active { - color: ${colorScheme === 'gray' ? theme.color.gray[800] : getColor(colorScheme).hover}; - border-color: ${getColor(colorScheme).active}; - } - ` - : variant === 'solid' - ? css` - color: ${colorScheme === 'gray' || colorScheme === 'yellow' - ? theme.color.gray[800] - : theme.color.white.white}; - background-color: ${getColor(colorScheme).enabled}; - - &:hover { - background-color: ${getColor(colorScheme).hover}; - border-color: ${getColor(colorScheme).hover}; - } - - &:active { - background-color: ${getColor(colorScheme).active}; - border-color: ${getColor(colorScheme).active}; - } - ` - : null} - `} - ${({ size }) => getButtonSize(size)} -`; - -const Button = ({ size = 'md', variant = 'solid', colorScheme, leftIcon, rightIcon, text }: ButtonProps) => { +const Button = ({ + as = 'button', + size = 'md', + variant = 'solid', + colorScheme, + leftIcon, + rightIcon, + children, + onClick +}: ButtonProps) => { return ( - - {leftIcon && } - {text} - {rightIcon && } + + {leftIcon && setIcon(leftIcon)} + {children && ( + + {children} + + )} + {rightIcon && setIcon(rightIcon)} ); }; diff --git a/packages/chakra-ui-styled/src/components/form/checkbox/Checbok.stories.tsx b/packages/chakra-ui-styled/src/components/form/checkbox/Checbok.stories.tsx index 526f931..315bace 100644 --- a/packages/chakra-ui-styled/src/components/form/checkbox/Checbok.stories.tsx +++ b/packages/chakra-ui-styled/src/components/form/checkbox/Checbok.stories.tsx @@ -1,6 +1,5 @@ import styled from 'styled-components'; -import Checkbox, { CheckboxProps } from './Checkbox'; - +import Checkbox, { CheckboxProps, colorSchemeType } from './Checkbox'; export default { title: 'chakra-ui-styled/components/form/checkbox', @@ -15,7 +14,7 @@ export default { isDisabled: { control: { type: 'boolean' } }, }, args: { - text: '체크대상텍스트', + text: '선택대상', size: 'md', colorScheme: 'blue', isChecked: true, @@ -35,10 +34,9 @@ const CheckboxGroup = styled.div` flex: 1 1 30%; gap: 5px 0px; `; -const colorSchemeIndex = ['blue', 'teal', 'green', 'cyan', 'purple', 'pink'] - export const CheckboxIndex = (args: CheckboxProps) => { const chkText: string = 'Checkbox Label'; + const colorArr: colorSchemeType[] = ['blue', 'teal', 'green', 'cyan', 'purple', 'pink']; return (

Checkbox

@@ -49,132 +47,29 @@ export const CheckboxIndex = (args: CheckboxProps) => {

Checkbox Index

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + {colorArr.map((color) => ( + + + + + + + + + + + + + + + + + + + + + + ))} ); }; diff --git a/packages/chakra-ui-styled/src/components/form/checkbox/Checkbox.styled.tsx b/packages/chakra-ui-styled/src/components/form/checkbox/Checkbox.styled.tsx new file mode 100644 index 0000000..4e26016 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/checkbox/Checkbox.styled.tsx @@ -0,0 +1,64 @@ +import styled, { css } from 'styled-components'; +import { CheckboxProps } from './Checkbox'; + +const checkboxSize = { sm: 12, md: 16, lg: 20, }; +const iconSize = { sm: 8, md: 12, lg: 16, }; +export const CheckboxForm = styled.input.attrs({ type: "checkbox" })` + position: absolute; + opacity: 0; + cursor: pointer; + width: 0; + height: 0; +`; +export const Label = styled.label` + flex: 1 1 30%; + display: flex; + align-items: center; + gap: 8px; + + & span { + width: ${({ size }) => checkboxSize[size]}px; + height: ${({ size }) => checkboxSize[size]}px; + border-radius: 2px; + display: flex; + justify-content: center; + align-items: center; + + &::after { + font-size: ${({ size }) => iconSize[size]}px; + line-height: 1; + } + ${({ isChecked, isDisabled, isIndeterminate, colorScheme, theme }) => css` + ${isDisabled // 비활성화 기준으로 잡아 잉여코드 제거 + ? css` // only 비활성o + background-color: ${theme.color.gray[200]}; + border: none; + ${isChecked && css` // 동시 체크o + &::after { + content: '✔'; + color: ${theme.color.gray[500]}; + } + `} + ` + : isChecked + ? css` // 비활성x, 동시 체크o + background-color: ${theme.color[colorScheme][500]}; + border: 1px solid ${theme.color[colorScheme][500]}; + &::after { + ${isIndeterminate + ? css` // 불확실o + content: '-'; + transform: translateY(-10%); + ` + : css` // 불확실x + content: '✔'; + `} + color: ${theme.color.white.white}; + }` + : css` // 비활성x, 동시 체크x + border: 2px solid ${theme.color.gray[200]}; + background: none; + `} + `} + } +`; \ No newline at end of file diff --git a/packages/chakra-ui-styled/src/components/form/checkbox/Checkbox.tsx b/packages/chakra-ui-styled/src/components/form/checkbox/Checkbox.tsx index 277fa00..ea1b0a3 100644 --- a/packages/chakra-ui-styled/src/components/form/checkbox/Checkbox.tsx +++ b/packages/chakra-ui-styled/src/components/form/checkbox/Checkbox.tsx @@ -1,137 +1,25 @@ -import styled, { css } from 'styled-components'; +import { StyleText } from '../../../foundation/typography/Text.styled'; +import { CheckboxForm, Label } from './Checkbox.styled'; + +export type colorSchemeType = 'blue' | 'teal' | 'green' | 'cyan' | 'purple' | 'pink'; export interface CheckboxProps { size: 'sm' | 'md' | 'lg'; - colorScheme: 'blue' | 'teal' | 'green' | 'cyan' | 'purple' | 'pink'; + colorScheme: colorSchemeType; isChecked?: boolean; isDisabled?: boolean; isIndeterminate?: boolean; - // Indeterminate는 체크를 했다는 전제조건에서만 나올 수 있음, isDisabled가 true이면 Indeterminate는 자동으로 해제, 우선 배제하고 작업진행 text: string; } -const checkboxSize = { sm: 12, md: 16, lg: 20, }; -const iconSize = { sm: 8, md: 12, lg: 16, }; -// 기본색상 -const getColor = (colorScheme: string) => css` - ${({ theme }) => { - switch (colorScheme) { - case 'blue': - return theme.color.blue[500]; - case 'teal': - return theme.color.teal[500]; - case 'green': - return theme.color.green[500]; - case 'cyan': - return theme.color.cyan[500]; - case 'purple': - return theme.color.purple[500]; - case 'pink': - return theme.color.pink[500]; - case 'gray': - return theme.color.gray[500]; - default: - return theme.color.blue[500]; - } - }} -`; -// label 사이즈 설정 했을 때 label의 왼쪽여백 조정 -const getLabelPadding = (size: string) => css` - ${({ theme }) => { - switch (size) { - case 'sm': - return theme.spacing[5]; - case 'md': - return theme.spacing[6]; - case 'lg': - return theme.spacing[7]; - default: - return theme.spacing[6]; - } - }} -`; -const CheckboxForm = styled.input.attrs({ type: "checkbox" })` - position: absolute; - opacity: 0; - cursor: pointer; - height: 0; - width: 0; - - &:checked:indeterminate ~ span::after { - display: flex; - } -`; -const Label = styled.label` - flex: 1 0 30%; - display: flex; - align-items: center; - position: relative; - padding: 0 0 0 ${({ size }) => getLabelPadding(size)}; - - & span { - box-sizing: border-box; - position: absolute; - top: 50%; - left: 0; - transform: translate(0, -50%); - width: ${({ size }) => checkboxSize[size]}px; - height: ${({ size }) => checkboxSize[size]}px; - border-radius: 2px; - text-align: center; - &::after { - position: absolute; - font-size: ${({ size }) => iconSize[size]}px; - width: inherit; - height: inherit; - top: inherit; - left: 50%; - transform: translate(-50%, -50%); - display: flex; - justify-content: center; - align-items: center; - } - // label에서 CheckboxProps적용시 - ${({ isChecked, isDisabled, isIndeterminate, colorScheme, theme }) => css` - ${isDisabled // 비활성화 기준으로 잡아 잉여코드 제거 - ? css` // only 비활성o - background-color: ${theme.color.gray[200]}; - border: none; - ${isChecked && css` // 동시 체크o - &::after { - content: '✔'; - color: ${theme.color.gray[500]}; - } - `} - ` - : isChecked - ? css` // 비활성x, 동시 체크o - background-color: ${getColor(colorScheme)}; - border: 1px solid ${getColor(colorScheme)}; - &::after { - ${isIndeterminate - ? css` // 불확실o - content: '-'; - transform: translate(-50%, -60%); - ` - : css` // 불확실x - content: '✔'; - `} - color: ${theme.color.white.white}; - transform: translate(-50%, -60%); - }` - : css` // 비활성x, 동시 체크x - border: 2px solid ${theme.color.gray[200]}; - background: none; - `} - `} - } -`; const Checkbox = ({ size = 'md', isChecked = true, isDisabled = false, isIndeterminate = true, colorScheme, text }: CheckboxProps) => { return ( ); }; diff --git a/packages/chakra-ui-styled/src/components/form/closebutton/CloseButton.stories.tsx b/packages/chakra-ui-styled/src/components/form/closebutton/CloseButton.stories.tsx new file mode 100644 index 0000000..2abece2 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/closebutton/CloseButton.stories.tsx @@ -0,0 +1,41 @@ +import styled from 'styled-components'; +import CloseButton, { CloseButtonProps } from './CloseButton'; +import { CloseIconStyle } from './CloseButton.styled'; + +export default { + title: 'chakra-ui-styled/components/form/closebutton', + component: CloseButton, + parameters: { controls: { expanded: true } }, + + argTypes: { + size: { control: { type: 'select' } } + }, + args: { + size: 'sm', + icon: + } +}; +const Wrapper = styled.div` + display: flex; + flex-direction: column; + gap: 20px; +`; + +export const CloseButtonIndex = (args: CloseButtonProps) => { + return ( + +

CloseButton

+ +

CloseButton Demo

+
+ +
+ +

CloseButton Index

+ } /> + } /> + } /> +
+ ); +}; +CloseButtonIndex.storyName = 'CloseButton'; diff --git a/packages/chakra-ui-styled/src/components/form/closebutton/CloseButton.styled.tsx b/packages/chakra-ui-styled/src/components/form/closebutton/CloseButton.styled.tsx new file mode 100644 index 0000000..fab7117 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/closebutton/CloseButton.styled.tsx @@ -0,0 +1,7 @@ +export const CloseIconStyle = () => { + return ( + + + + ); +}; diff --git a/packages/chakra-ui-styled/src/components/form/closebutton/CloseButton.tsx b/packages/chakra-ui-styled/src/components/form/closebutton/CloseButton.tsx new file mode 100644 index 0000000..c98a725 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/closebutton/CloseButton.tsx @@ -0,0 +1,27 @@ +import styled from 'styled-components'; + +export interface CloseButtonProps { + size: 'sm' | 'md' | 'lg'; + icon?: React.ReactNode; + onClick?: () => void; + className?: string; +} +const ViewBoxSize = { sm: 24, md: 32, lg: 40 }; +const setIcon = (icon: React.ReactNode) => { + return
{icon}
; +}; +const CloseButtonStyle = styled.div` + width: ${({ size }) => ViewBoxSize[size]}px; + height: ${({ size }) => ViewBoxSize[size]}px; + aspect-ratio: 1; + cursor: pointer; +`; +const CloseButton = ({ size = 'sm', icon, className, onClick }: CloseButtonProps) => { + return ( + + {icon && setIcon(icon)} + + ) +}; + +export default CloseButton; diff --git a/packages/chakra-ui-styled/src/components/form/input/Input.stories.tsx b/packages/chakra-ui-styled/src/components/form/input/Input.stories.tsx new file mode 100644 index 0000000..5f08efe --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/input/Input.stories.tsx @@ -0,0 +1,144 @@ +import styled from 'styled-components'; +import { InputSize } from './InputGroup'; +import Input, { InputType } from './Input'; + +export default { + title: 'chakra-ui-styled/components/form/Input/Input', + component: Input, + parameters: { controls: { expanded: true } }, + + argTypes: { + $size: { control: { type: 'select' } }, + $variant: { control: { type: 'select' } }, + $isInvalid: { control: { type: 'boolean' } }, + disabled: { control: { type: 'boolean' } }, + readOnly: { control: { type: 'boolean' } } + }, + args: { + $size: 'xs', + $variant: 'outline', + $isInvalid: false, + disabled: false, + readOnly: false + } +}; +const Wrapper = styled.div` + display: flex; + flex-direction: column; + gap: 20px; +`; +const BtnBox = styled.div` + display: flex; + gap: 16px; + align-items: center; +`; + +export const InputIndex = (args: InputType) => { + const inputArr: InputSize[] = ['xs', 'sm', 'md', 'lg']; + return ( + +

InputIndex

+

InputIndex Demo

+
+ +
+

Input Index

+ {inputArr.map((size, idx) => ( + + + + + + ))} +


+ {inputArr.map((size, idx) => ( + + + + + + ))} +


+ {inputArr.map((size) => ( + + + + + + ))} +
+ ); +}; +InputIndex.storyName = 'Input'; diff --git a/packages/chakra-ui-styled/src/components/form/input/Input.styled.tsx b/packages/chakra-ui-styled/src/components/form/input/Input.styled.tsx new file mode 100644 index 0000000..7c4d810 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/input/Input.styled.tsx @@ -0,0 +1,73 @@ +import styled, { css } from 'styled-components'; +import { InputStyleSize } from './InputGroup.styled'; +import { CommonInputType } from './InputGroup'; + +const getInputVariant = ($props: CommonInputType) => { + if ($props.$variant === 'outline' || $props.$variant === 'flushed') { + return css` + padding: 0 ${InputStyleSize[$props.$size]?.padding}; + ${$props.$isInvalid && !$props.disabled && !$props.readOnly + ? css` + border: 1px solid ${({ theme }) => theme.color.red[500]}; + box-shadow: ${({ theme }) => theme.color.red[500]} 0 0 0 1px; + ` + : css` + border: 1px solid ${$props.$variant === 'outline' ? ({ theme }) => theme.color.gray[200] : 'transparent'}; + `}; + + &:focus-visible { + ${!$props.$isInvalid && + !$props.disabled && + !$props.readOnly && + css` + border-color: ${({ theme }) => theme.color.blue[500]}; + box-shadow: ${({ theme }) => theme.color.blue[500]} 0 0 0 1px; + `}; + } + `; + } + if ($props.$variant === 'filled') { + return css` + border: 0 none; + border-radius: 0; + + ${$props.$isInvalid && !$props.disabled && !$props.readOnly + ? css` + border-bottom: 1px solid ${({ theme }) => theme.color.red[500]}; + box-shadow: ${({ theme }) => theme.color.red[500]} 0 1px 0 0; + ` + : css` + border-bottom: 1px solid ${({ theme }) => theme.color.gray[200]}; + `}; + &:focus-visible { + ${!$props.$isInvalid && + !$props.disabled && + !$props.readOnly && + css` + border-bottom: 1px solid ${({ theme }) => theme.color.blue[500]}; + box-shadow: ${({ theme }) => theme.color.blue[500]} 0 1px 0 0; + `}; + } + `; + } + return null; +}; + +export const InputStyle = styled.input<{ $props: CommonInputType }>` + ${({ theme, $props }) => css` + position: relative; + z-index: 1; + box-sizing: border-box; + display: flex; + flex: 1; + height: ${InputStyleSize[$props.$size]?.height}; + border-radius: ${InputStyleSize[$props.$size].radii}; + ${theme.typo.text[$props.$size]}; + ${($props.disabled || $props.readOnly) && { opacity: '0.4', backgroundColor: `${theme.color.gray[100]}` }}; + ${getInputVariant($props)} + + &:focus-visible { + outline: none; + } + `} +`; diff --git a/packages/chakra-ui-styled/src/components/form/input/Input.tsx b/packages/chakra-ui-styled/src/components/form/input/Input.tsx new file mode 100644 index 0000000..4e3d974 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/input/Input.tsx @@ -0,0 +1,32 @@ +import { CommonInputType } from './InputGroup'; +import { InputStyle } from './Input.styled'; + +export type InputType = CommonInputType & { + type?: 'text' | 'email' | 'tel' | 'password'; + name: string; + id: string; + placeholder?: string; +}; + +// input +const Input = ({ + $size = 'xs', + $isInvalid = false, + $variant = 'filled', + readOnly = false, + disabled = false, + placeholder = 'placeholder', + ...rest +}: InputType) => { + return ( + + ); +}; + +export default Input; diff --git a/packages/chakra-ui-styled/src/components/form/input/InputAddon.tsx b/packages/chakra-ui-styled/src/components/form/input/InputAddon.tsx new file mode 100644 index 0000000..27b9667 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/input/InputAddon.tsx @@ -0,0 +1,15 @@ +import styled, { css } from 'styled-components'; +import { colorType } from './InputGroup'; + +export type InputAddonType = { + $color?: colorType; + $bg?: colorType; + dataPosition?: 'left' | 'right'; + $element: React.ReactNode; +}; +export const AddonStyle = styled.figure` + ${({ $color, $bg, theme }) => css` + color: ${$color ? theme.color[$color][500] : theme.color.black.black}; + background-color: ${$bg ? theme.color[$bg][100] : 'transparent'}; + `} +`; diff --git a/packages/chakra-ui-styled/src/components/form/input/InputGroup.styled.tsx b/packages/chakra-ui-styled/src/components/form/input/InputGroup.styled.tsx new file mode 100644 index 0000000..c99316b --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/input/InputGroup.styled.tsx @@ -0,0 +1,155 @@ +import styled, { css } from 'styled-components'; + +import { InputGroupType } from './InputGroup'; + +import { AddonStyle } from './InputAddon'; +import { InputStyle } from './Input.styled'; + +export const InputStyleSize = { + xs: { + height: '24px', + padding: '8px', + iconSize: '12px', + radii: css` + ${({ theme }) => theme.radii.sm + 'rem'} + ` + }, + sm: { + height: '32px', + padding: '12px', + iconSize: '14px', + radii: css` + ${({ theme }) => theme.radii.base + 'rem'} + ` + }, + md: { + height: '40px', + padding: '12px', + iconSize: '16px', + radii: css` + ${({ theme }) => theme.radii.md + 'rem'} + ` + }, + lg: { + height: '48px', + padding: '16px', + iconSize: '18px', + radii: css` + ${({ theme }) => theme.radii.lg + 'rem'} + ` + } +}; + +const getInputRadii = ($props: InputGroupType) => { + //leftAddon만있을경우 + if (!$props.rightAddon && $props.leftAddon) { + return css` + border-top-right-radius: ${InputStyleSize[$props.$size].radii}; + border-bottom-right-radius: ${InputStyleSize[$props.$size].radii}; + `; + } + //rightAddon만있을경우 + if ($props.rightAddon && !$props.leftAddon) { + return css` + border-top-left-radius: ${InputStyleSize[$props.$size].radii}; + border-bottom-left-radius: ${InputStyleSize[$props.$size].radii}; + `; + } + //다 없을경우 + if (!$props.rightAddon && !$props.leftAddon) { + return css` + border-radius: ${InputStyleSize[$props.$size].radii}; + `; + } + if ($props.rightAddon && $props.leftAddon) { + return css` + border-radius: 0; + `; + } + return null; +}; + +const getAddonBorder = ($position: string) => { + let AddonPosition; + let borderPosition; + switch ($position) { + case 'left': + break; + case 'right': + css` + border-left: 0 none; + border-top-right-radius: ${InputStyleSize[$props.$size].radii}; + border-bottom-right-radius: ${InputStyleSize[$props.$size].radii}; + `; + break; + } +}; + +export const InputGroupStyle = styled.div<{ + $props: InputGroupType; +}>` + ${({ theme, $props }) => css` + box-sizing: border-box; + display: flex; + align-items: flex-start; + justify-content: space-between; + width: 100%; + + & ${InputStyle} { + flex-grow: 1; + padding-right: ${$props.rightAddon ? InputStyleSize[$props.$size].padding : 0}; + padding-left: ${$props.leftAddon ? InputStyleSize[$props.$size].padding : InputStyleSize[$props.$size].padding}; + border-radius: 0; + ${getInputRadii($props)}; + + // 왼쪽 요소만있고, 왼쪽요소의 백그라운드가 투명일때 + ${$props.leftAddon && + !$props.leftAddon.props.$bg && + css` + &:not(:focus-visible) { + border-left-color: transparent; + } + padding-left: 0; + `} + // 오른쪽 요소만있고, 오른쪽요소의 백그라운드가 투명일때 + ${$props.rightAddon && + !$props.rightAddon.props.$bg && + css` + &:not(:focus-visible) { + border-right-color: transparent; + } + `} + } + & ${AddonStyle} { + display: flex; + flex: none; + align-items: center; + justify-content: center; + min-width: ${InputStyleSize[$props.$size].height}; + height: ${InputStyleSize[$props.$size].height}; + ${theme.typo.text[$props.$size]}; + padding: 0 ${InputStyleSize[$props.$size].padding}; + border: 1px solid ${theme.color.gray[200]}; + ${InputStyleSize[$props.$size].padding}; + ${($props.readOnly || $props.disabled) && + css` + background-color: ${theme.color.gray[100]}; + opacity: 0.4; + `} + &[dataPosition='left'] { + border-right: 0 none; + border-top-left-radius: ${InputStyleSize[$props.$size].radii}; + border-bottom-left-radius: ${InputStyleSize[$props.$size].radii}; + } + + &[dataPosition='right'] { + border-left: 0 none; + border-top-right-radius: ${InputStyleSize[$props.$size].radii}; + border-bottom-right-radius: ${InputStyleSize[$props.$size].radii}; + } + } + & ${AddonStyle} svg { + width: ${InputStyleSize[$props.$size].iconSize}; + } + `} +`; diff --git a/packages/chakra-ui-styled/src/components/form/input/InputGroup.tsx b/packages/chakra-ui-styled/src/components/form/input/InputGroup.tsx new file mode 100644 index 0000000..2353889 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/input/InputGroup.tsx @@ -0,0 +1,59 @@ +import React from 'react'; + +import Input, { InputType } from './Input'; +import { AddonStyle, InputAddonType } from './InputAddon'; +import { InputGroupStyle } from './InputGroup.styled'; + +export type InputSize = 'xs' | 'sm' | 'md' | 'lg'; +export type VariantType = 'outline' | 'filled' | 'flushed'; +export type colorType = 'blue' | 'gray' | 'teal' | 'red' | 'orange' | 'yellow' | 'pink' | 'purple' | 'green'; + +export type CommonInputType = { + $size: InputSize; + $variant?: VariantType; + $isInvalid: boolean; + disabled: boolean; + readOnly: boolean; +}; + +export type InputGroupType = CommonInputType & + InputType & { + leftAddon?: React.ReactElement; + rightAddon?: React.ReactElement; + }; + +export const InputAddon = ({ $color, $bg, $element, dataPosition }: InputAddonType) => { + return ( + + {$element} + + ); +}; + +// Root Provider +export const InputGroup = ({ + $size, + $isInvalid, + disabled, + readOnly, + leftAddon, + rightAddon, + ...rest +}: InputGroupType) => { + return ( + + {leftAddon && leftAddon} + + {rightAddon && rightAddon} + + ); +}; + +export default InputGroup; diff --git a/packages/chakra-ui-styled/src/components/form/input/InputGruop.stories.tsx b/packages/chakra-ui-styled/src/components/form/input/InputGruop.stories.tsx new file mode 100644 index 0000000..2b43e3c --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/input/InputGruop.stories.tsx @@ -0,0 +1,153 @@ +import styled from 'styled-components'; +import InputGroup, { InputAddon, InputGroupType, InputSize } from './InputGroup'; + +const IconDummy = () => { + return ( + + + + ); +}; + +export default { + title: 'chakra-ui-styled/components/form/Input/InputGroup', + component: InputGroup, + parameters: { controls: { expanded: true } }, + + argTypes: { + $size: { control: { type: 'select' } }, + $isInvalid: { control: { type: 'boolean' } }, + disabled: { control: { type: 'boolean' } }, + readOnly: { control: { type: 'boolean' } } + }, + args: { + $size: 'xs', + $isInvalid: false, + disabled: false, + readOnly: false, + leftAddon: } />, + rightAddon: } /> + } +}; +const Wrapper = styled.div` + display: flex; + flex-direction: column; + gap: 20px; +`; +const InputBox = styled.div` + display: flex; + flex-direction: column; + gap: 16px; + align-items: flex-start; + + & > div { + flex: 1; + } +`; +const BtnBox = styled.div` + display: flex; + gap: 16px; + align-items: flex-start; +`; + +export const InputGroupIndex = (args: InputGroupType) => { + const inputArr: InputSize[] = ['xs', 'sm', 'md', 'lg']; + return ( + +

InputGroup

+

InputGroup Demo

+
+ +
+

InputGroup Index

+ + {inputArr.map((size) => ( + + + } />} + rightAddon={} />} + /> + } />} + /> + } />} + /> + } />} + rightAddon={} />} + /> + } />} + /> + } />} + /> + + ))} + +
+ ); +}; +InputGroupIndex.storyName = 'InputGroup'; diff --git a/packages/chakra-ui-styled/src/components/form/numberinput/NumberInput.stories.tsx b/packages/chakra-ui-styled/src/components/form/numberinput/NumberInput.stories.tsx new file mode 100644 index 0000000..ab830c2 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/numberinput/NumberInput.stories.tsx @@ -0,0 +1,98 @@ +import styled from 'styled-components'; +import NumberInput, { NumberInputProps, colorSchemeType } from './NumberInput'; +import { IncrementStepperIconStyle, DecrementStepperIconStyle } from './NumberInput.styled'; + +export default { + title: 'chakra-ui-styled/components/form/numberinput', + component: NumberInput, + parameters: { controls: { expanded: true } }, + + argTypes: { + size: { control: { type: 'select' } }, + colorScheme: { control: { type: 'select' } }, + value: { control: { type: 'number' } }, + disabled: { control: { type: 'boolean' } }, + readonly: { control: { type: 'boolean' } }, + isInvalid: { control: { type: 'boolean' } } + }, + args: { + size: 'sm', + colorScheme: 'blue', + incrementIcon: , + decrementIcon: , + value: 1, + disabled: false, + readonly: false, + isInvalid: false + } +}; +const Wrapper = styled.div` + display: flex; + flex-direction: column; + gap: 20px; +`; +const Stack = styled.div` + display: flex; + flex-flow: row wrap; + flex: 1 1 0; + gap: 10px; +`; +export const NumberInputIndex = (args: NumberInputProps) => { + const colorArr: colorSchemeType[] = ['whiteAlpha', 'blackAlpha', 'gray', 'red', 'orange', 'yellow', 'green', 'teal', 'blue', 'cyan', 'purple', 'pink']; + return ( + +

NumberInput

+ +

NumberInput Demo

+
+ +
+ +

NumberInput Index

+ {colorArr.map((color) => ( + + } decrementIcon={} + /> + } decrementIcon={} + /> + } decrementIcon={} + /> + + } decrementIcon={} + /> + } decrementIcon={} + /> + } decrementIcon={} + /> + + } decrementIcon={} + /> + } decrementIcon={} + /> + } decrementIcon={} + /> + + } decrementIcon={} + /> + } decrementIcon={} + /> + } decrementIcon={} + /> + + ))} +
+ ); +}; +NumberInputIndex.storyName = 'NumberInput'; diff --git a/packages/chakra-ui-styled/src/components/form/numberinput/NumberInput.styled.tsx b/packages/chakra-ui-styled/src/components/form/numberinput/NumberInput.styled.tsx new file mode 100644 index 0000000..e240fc5 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/numberinput/NumberInput.styled.tsx @@ -0,0 +1,122 @@ +import styled, { css } from 'styled-components'; +import { NumberInputProps } from './NumberInput'; + +const numberInputSize = { + xs: css` + height: 24px; + border-radius: 2px; + padding: 0px 0px 0px 12px; + `, + sm: css` + height: 32px; + border-radius: 2px; + padding: 0px 0px 0px 12px; + `, + md: css` + height: 40px; + border-radius: 6px; + padding: 0px 0px 0px 16px; + `, + lg: css` + height: 48px; + border-radius: 6px; + padding: 0px 0px 0px 16px; + `, +}; +const fontSize = { + xs: css` + ${({ theme }) => theme.typo.text.xs} + `, + sm: css` + ${({ theme }) => theme.typo.text.sm} + `, + md: css` + ${({ theme }) => theme.typo.text.md} + `, + lg: css` + ${({ theme }) => theme.typo.text.lg} + `, +}; +export const StyleNumberInput = styled.div` + display: flex; + align-items: center; + flex: 1 1 30%; + ${({ size }) => numberInputSize[size]} + & input{ + ${({ size }) => fontSize[size]} + } + &:focus { + outline: 0; + } + ${({ disabled, readOnly, isInvalid, colorScheme, theme }) => css` + ${disabled || readOnly + ? css` + // 비활성o + opacity: 0.5; + border: 1px solid ${theme.color.gray[200]}; + pointer-events: none; + ` + : css` + // 기본 + border: 1px solid ${theme.color.gray[200]}; + &:focus-within { + outline: 1px solid ${theme.color[colorScheme][500]}; + } + // 기본 + min, max값이 넘었을경우 조건 충족 : 굵은아웃라인 들어와야함 + ${isInvalid && + css` + outline: 3px solid ${theme.color.red[500]}; + `} + `} + `} +`; +export const NumberInputField = styled.input.attrs({ type: "text" })` + flex: 1; + border: none; + &:focus{ + outline: 0; + } +`; +export const NumberInputStepper = styled.div` + width: 24px; + height: 100%; + display: flex; + flex-direction: column; +`; +export const IncrementStepperIconStyle = () => { + return ( + + + + ); +}; +export const DecrementStepperIconStyle = () => { + return ( + + + + ); +}; +export const NumberIncrementStepper = styled.div` + display: flex; + justify-content: center; + align-items: center; + flex: 1; + height: 50%; + cursor: pointer; + ${({ theme }) => css` + border-left: 1px solid ${theme.color.gray[200]}; + `} +`; +export const NumberDecrementStepper = styled.div` + display: flex; + justify-content: center; + align-items: center; + flex: 1; + height: 50%; + cursor: pointer; + ${({ theme }) => css` + border-left: 1px solid ${theme.color.gray[200]}; + border-top: 1px solid ${theme.color.gray[200]}; + `} +`; \ No newline at end of file diff --git a/packages/chakra-ui-styled/src/components/form/numberinput/NumberInput.tsx b/packages/chakra-ui-styled/src/components/form/numberinput/NumberInput.tsx new file mode 100644 index 0000000..dabe61e --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/numberinput/NumberInput.tsx @@ -0,0 +1,35 @@ +import { StyleNumberInput, NumberInputField, NumberInputStepper, NumberIncrementStepper, NumberDecrementStepper } from './NumberInput.styled'; +import { useState } from 'react' + +export type colorSchemeType = 'whiteAlpha' | 'blackAlpha' | 'gray' | 'red' | 'orange' | 'yellow' | 'green' | 'teal' | 'blue' | 'cyan' | 'purple' | 'pink' ; +export interface NumberInputProps { + size: "xs" | 'sm' | 'md' | 'lg'; + colorScheme: colorSchemeType; + isInvalid?: boolean; + disabled?: boolean; + readOnly?: boolean; + value: number; + incrementIcon?: React.ReactNode; + decrementIcon?: React.ReactNode; +} + +const setIcon = (incrementIcon: React.ReactNode) => { + return
{incrementIcon}
; +}; +const NumberInput = ({ size = 'md', colorScheme, value, incrementIcon, decrementIcon, disabled = false, readOnly = false, isInvalid = false }: NumberInputProps) => { + const [count, setCount] = useState(0) + return ( + + + + setCount((count) => count + 1)}> + {incrementIcon && setIcon(incrementIcon)} + + setCount((count) => count - 1)}> + {decrementIcon && setIcon(decrementIcon)} + + + + ); +}; +export default NumberInput; \ No newline at end of file diff --git a/packages/chakra-ui-styled/src/components/form/pininput/PinInput.stories.tsx b/packages/chakra-ui-styled/src/components/form/pininput/PinInput.stories.tsx new file mode 100644 index 0000000..55aaa96 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/pininput/PinInput.stories.tsx @@ -0,0 +1,38 @@ +import styled from 'styled-components'; +import PinInput, { PinInputProps } from './PinInput'; + +export default { + title: 'chakra-ui-styled/components/form/pininput', + component: PinInput, + parameters: { controls: { expanded: true } }, + + argTypes: { + size: { control: { type: 'select' } }, + colorScheme: { control: { type: 'select' } }, + numOfInputs: { control: { type: 'number' } }, + }, + args: { + size: 'sm', + colorScheme: 'blue', + numOfInputs: 4, + } +}; +const Wrapper = styled.div` + display: flex; + flex-direction: column; + gap: 20px; +`; + +export const PinInputIndex = (args: PinInputProps) => { + return ( + +

PinInput

+ +

PinInput Demo

+
+ +
+
+ ); +}; +PinInputIndex.storyName = 'PinInput'; diff --git a/packages/chakra-ui-styled/src/components/form/pininput/PinInput.style.tsx b/packages/chakra-ui-styled/src/components/form/pininput/PinInput.style.tsx new file mode 100644 index 0000000..4060329 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/pininput/PinInput.style.tsx @@ -0,0 +1,53 @@ +import styled, { css } from 'styled-components'; +import { PinInputProps } from './PinInput'; + +const PinInputSize = { + xs: css` + width: ${({ theme }) => theme.spacing[6]}; + border-radius: 2px; + ${({ theme }) => theme.typo.text.xs}; + `, + sm: css` + width: ${({ theme }) => theme.spacing[8]}; + border-radius: 4px; + ${({ theme }) => theme.typo.text.sm} + `, + md: css` + width: ${({ theme }) => theme.spacing[10]}; + border-radius: 4px; + ${({ theme }) => theme.typo.text.md} + `, + lg: css` + width: ${({ theme }) => theme.spacing[12]}; + border-radius: 6px; + ${({ theme }) => theme.typo.text.lg} + ` +}; +export const StylePinInput = styled.div.attrs({ autoFocus: true })` + display: flex; + gap: 6px; + + & input { + ${({ size }) => PinInputSize[size]} + ${({ colorScheme, theme }) => css` + border: 1px solid ${theme.color.gray[200]}; + + &:focus { + outline: 2px solid ${theme.color[colorScheme][500]}; + } + + &:placeholder-shown { + color: ${theme.color.gray[400]}; + } + `} + } +`; + +export const PinInputField = styled.input.attrs({ type: 'text', maxlength: 1, placeholder: '○' })` + aspect-ratio: 1; + text-align: center; + + &:focus { + outline: 0; + } +`; diff --git a/packages/chakra-ui-styled/src/components/form/pininput/PinInput.tsx b/packages/chakra-ui-styled/src/components/form/pininput/PinInput.tsx new file mode 100644 index 0000000..ffac48c --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/pininput/PinInput.tsx @@ -0,0 +1,47 @@ +import { StylePinInput, PinInputField } from './PinInput.style'; + +export type colorSchemeType = + | 'whiteAlpha' + | 'blackAlpha' + | 'gray' + | 'red' + | 'orange' + | 'yellow' + | 'green' + | 'teal' + | 'blue' + | 'cyan' + | 'purple' + | 'pink'; +export interface PinInputProps { + size: 'xs' | 'sm' | 'md' | 'lg'; + colorScheme: colorSchemeType; + numOfInputs: number; +} + +const PinInput = ({ size = 'md', colorScheme, numOfInputs = 4 }: PinInputProps) => { + const inputArray = Array.from({ length: numOfInputs }); + const onFocusInput = (e: React.KeyboardEvent) => { + const pinInput = e.target as HTMLInputElement; + const value = pinInput.value; + const maxLength = Number(pinInput.getAttribute('maxlength')); + + if (e.code === 'Backspace') { + if (!pinInput.previousSibling) return; + !value ? (pinInput.previousSibling as HTMLInputElement).focus() : pinInput.focus(); + } + if (value.length === maxLength && e.code !== 'Backspace') { + if (!pinInput.nextSibling) return; + (pinInput.nextSibling as HTMLInputElement).focus(); + } + }; + + return ( + + {inputArray.map((_, index) => { + return ; + })} + + ); +}; +export default PinInput; diff --git a/packages/chakra-ui-styled/src/components/form/radio/Radio.stories.tsx b/packages/chakra-ui-styled/src/components/form/radio/Radio.stories.tsx new file mode 100644 index 0000000..7c48bf3 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/radio/Radio.stories.tsx @@ -0,0 +1,71 @@ +import styled from 'styled-components'; +import Radio, { RadioProps, colorSchemeType } from './Radio'; + +export default { + title: 'chakra-ui-styled/components/form/radio', + component: Radio, + parameters: { controls: { expanded: true } }, + + argTypes: { + text: { control: { type: 'text' } }, + size: { control: { type: 'select' } }, + colorScheme: { control: { type: 'select' } }, + defaultChecked: { control: { type: 'boolean' } }, + isDisabled: { control: { type: 'boolean' } }, + }, + args: { + text: '선택대상', + size: 'md', + colorScheme: 'blue', + defaultChecked: true, + isDisabled: false, + } +}; + +const Wrapper = styled.div` + display: flex; + flex-direction: column; + gap: 20px; +`; +const RadioGroup = styled.div` + display: flex; + flex-flow: row wrap; + flex: 1 1 30%; + gap: 5px 0px; +`; +export const RadioIndex = (args: RadioProps) => { + const radioText: string = 'Radio Label'; + const colorArr: colorSchemeType[] = ['blue', 'teal', 'green', 'cyan', 'purple', 'pink']; + return ( + +

Radio

+ +

Radio Demo

+
+ +
+ +

Radio Index

+ {colorArr.map((color) => ( + + + + + + + + + + + + + + + + + + ))} +
+ ); +}; +RadioIndex.storyName = 'Radio'; \ No newline at end of file diff --git a/packages/chakra-ui-styled/src/components/form/radio/Radio.styled.tsx b/packages/chakra-ui-styled/src/components/form/radio/Radio.styled.tsx new file mode 100644 index 0000000..5b3d432 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/radio/Radio.styled.tsx @@ -0,0 +1,46 @@ +import styled, { css } from 'styled-components'; +import { RadioProps } from './Radio'; + + +const RadioSize = { sm: 12, md: 16, lg: 20, }; +const borderSize = { sm: 4, md: 5, lg: 6 }; +export const RadioForm = styled.input.attrs({ type: "Radio" })` + position: absolute; + opacity: 0; + cursor: pointer; + width: 0; + height: 0; +`; +export const Label = styled.label` + flex: 1 1 30%; + display: flex; + align-items: center; + gap: 8px; + + & span { + width: ${({ size }) => RadioSize[size]}px; + height: ${({ size }) => RadioSize[size]}px; + border-radius: 50%; + + ${({ size, defaultChecked, isDisabled, colorScheme, theme }) => css` + ${isDisabled + ? css`// 비활성o + background-color: ${theme.color.gray[200]}; + border: 2px solid ${theme.color.gray[200]}; + ${defaultChecked && css` // 동시 체크o + border: ${borderSize[size]}px solid ${theme.color.gray[200]}; + background-color: ${theme.color.gray[500]}; + `} + ` + : defaultChecked + ? css` // 비활성x, 동시 체크o + border: ${borderSize[size]}px solid ${theme.color[colorScheme][500]}; + background-color: ${theme.color.white.white}; + ` + : css` // 비활성x, 동시 체크x + border: 2px solid ${theme.color.gray[200]}; + background: none; + `} + `} + } +`; \ No newline at end of file diff --git a/packages/chakra-ui-styled/src/components/form/radio/Radio.tsx b/packages/chakra-ui-styled/src/components/form/radio/Radio.tsx new file mode 100644 index 0000000..44fb31a --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/radio/Radio.tsx @@ -0,0 +1,24 @@ +import { StyleText } from '../../../foundation/typography/Text.styled'; +import { RadioForm, Label } from './Radio.styled'; + +export type colorSchemeType = 'blue' | 'teal' | 'green' | 'cyan' | 'purple' | 'pink'; +export interface RadioProps { + size: 'sm' | 'md' | 'lg'; + colorScheme: colorSchemeType; + defaultChecked?: boolean; + isDisabled?: boolean; + text: string; +} + +const Radio = ({ size = 'md', defaultChecked = true, isDisabled = false, colorScheme, text }: RadioProps) => { + return ( + + ); +}; +export default Radio; \ No newline at end of file diff --git a/packages/chakra-ui-styled/src/components/form/select/Select.stories.tsx b/packages/chakra-ui-styled/src/components/form/select/Select.stories.tsx new file mode 100644 index 0000000..5e98bc5 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/form/select/Select.stories.tsx @@ -0,0 +1,68 @@ +import styled from 'styled-components'; +import Select, { SelectProps, colorSchemeType } from './Select'; + +export default { + title: 'chakra-ui-styled/components/form/select', + component: Select, + parameters: { controls: { expanded: true } }, + + argTypes: { + placeholder: { control: { type: 'text' } }, + size: { control: { type: 'select' } }, + colorScheme: { control: { type: 'select' } }, + disabled: { control: { type: 'boolean' } }, + readonly: { control: { type: 'boolean' } }, + isInvalid: { control: { type: 'boolean' } } + }, + args: { + placeholder: 'Hello', + size: 'md', + colorScheme: 'blue', + disabled: false, + readonly: false, + isInvalid: false + } +}; +const Wrapper = styled.div` + display: flex; + flex-direction: column; + gap: 20px; +`; +const Stack = styled.div` + display: flex; + flex-flow: row wrap; + flex: 1 1 0; + gap: 10px; +`; +export const SelectIndex = (args: SelectProps) => { + const colorArr: colorSchemeType[] = ['whiteAlpha', 'blackAlpha', 'gray', 'red', 'orange', 'yellow', 'green', 'teal', 'blue', 'cyan', 'purple', 'pink']; + return ( + +

Select

+ +

Select Demo

+
+ + + + + + +