-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'fe-dev' into feature/#371
- Loading branch information
Showing
36 changed files
with
513 additions
and
111 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
75 changes: 75 additions & 0 deletions
75
HDesign/src/components/EditableItem/EditableItem.Input.style.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import {css} from '@emotion/react'; | ||
|
||
import {TextSize} from '@components/Text/Text.type'; | ||
|
||
import {Theme} from '@theme/theme.type'; | ||
|
||
import TYPOGRAPHY from '@token/typography'; | ||
|
||
interface InputWrapperStyleProps { | ||
theme: Theme; | ||
hasFocus: boolean; | ||
hasError: boolean; | ||
} | ||
|
||
interface InputStyleProps { | ||
theme: Theme; | ||
textSize: TextSize; | ||
} | ||
|
||
interface InputSizeStyleProps { | ||
textSize: TextSize; | ||
} | ||
|
||
interface InputBaseStyleProps { | ||
theme: Theme; | ||
} | ||
|
||
export const inputWrapperStyle = ({theme, hasFocus, hasError}: InputWrapperStyleProps) => | ||
css({ | ||
position: 'relative', | ||
display: 'inline-block', | ||
|
||
'&::after': { | ||
content: '""', | ||
position: 'absolute', | ||
left: 0, | ||
right: 0, | ||
bottom: 0, | ||
height: '0.125rem', | ||
backgroundColor: hasFocus ? theme.colors.primary : hasError ? theme.colors.error : 'transparent', | ||
transition: 'background-color 0.2s', | ||
transitionTimingFunction: 'cubic-bezier(0.7, 0.62, 0.62, 1.16)', | ||
}, | ||
}); | ||
|
||
export const inputStyle = ({theme, textSize}: InputStyleProps) => [inputSizeStyle({textSize}), inputBaseStyle({theme})]; | ||
|
||
const inputSizeStyle = ({textSize}: InputSizeStyleProps) => { | ||
const style = { | ||
head: css(TYPOGRAPHY.head), | ||
title: css(TYPOGRAPHY.title), | ||
subTitle: css(TYPOGRAPHY.subTitle), | ||
bodyBold: css(TYPOGRAPHY.bodyBold), | ||
body: css(TYPOGRAPHY.body), | ||
smallBodyBold: css(TYPOGRAPHY.smallBodyBold), | ||
smallBody: css(TYPOGRAPHY.smallBody), | ||
captionBold: css(TYPOGRAPHY.captionBold), | ||
caption: css(TYPOGRAPHY.caption), | ||
tiny: css(TYPOGRAPHY.tiny), | ||
}; | ||
|
||
return [style[textSize]]; | ||
}; | ||
|
||
const inputBaseStyle = ({theme}: InputBaseStyleProps) => | ||
css({ | ||
border: 'none', | ||
outline: 'none', | ||
paddingBottom: '0.125rem', | ||
|
||
color: theme.colors.black, | ||
'&:placeholder': { | ||
color: theme.colors.gray, | ||
}, | ||
}); |
27 changes: 27 additions & 0 deletions
27
HDesign/src/components/EditableItem/EditableItem.Input.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/** @jsxImportSource @emotion/react */ | ||
import React, {forwardRef, useEffect, useImperativeHandle, useRef, useState} from 'react'; | ||
|
||
import {InputProps} from '@components/EditableItem/EditableItem.Input.type'; | ||
|
||
import {useTheme} from '@theme/HDesignProvider'; | ||
|
||
import {inputStyle, inputWrapperStyle} from './EditableItem.Input.style'; | ||
import useEditableItemInput from './useEditableItemInput'; | ||
|
||
export const EditableItemInput: React.FC<InputProps> = forwardRef<HTMLInputElement, InputProps>(function Input( | ||
{textSize = 'body', hasError = false, ...htmlProps}, | ||
ref, | ||
) { | ||
const {theme} = useTheme(); | ||
const inputRef = useRef<HTMLInputElement>(null); | ||
const {hasFocus} = useEditableItemInput({inputRef}); | ||
useImperativeHandle(ref, () => inputRef.current!); | ||
|
||
return ( | ||
<div css={inputWrapperStyle({theme, hasFocus, hasError})}> | ||
<input css={inputStyle({theme, textSize})} ref={inputRef} {...htmlProps} /> | ||
</div> | ||
); | ||
}); | ||
|
||
export default EditableItemInput; |
18 changes: 18 additions & 0 deletions
18
HDesign/src/components/EditableItem/EditableItem.Input.type.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import {TextSize} from '@components/Text/Text.type'; | ||
|
||
import {Theme} from '@theme/theme.type'; | ||
|
||
export interface InputStyleProps { | ||
hasError?: boolean; | ||
textSize?: TextSize; | ||
} | ||
|
||
export interface InputCustomProps {} | ||
|
||
export interface InputStylePropsWithTheme extends InputStyleProps { | ||
theme: Theme; | ||
} | ||
|
||
export type InputOptionProps = InputStyleProps & InputCustomProps; | ||
|
||
export type InputProps = React.ComponentProps<'input'> & InputOptionProps; |
23 changes: 23 additions & 0 deletions
23
HDesign/src/components/EditableItem/EditableItem.context.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** @jsxImportSource @emotion/react */ | ||
import {createContext, PropsWithChildren, useContext, useState} from 'react'; | ||
|
||
interface EditableItemContextProps { | ||
hasAnyFocus: boolean; | ||
setHasAnyFocus: React.Dispatch<React.SetStateAction<boolean>>; | ||
} | ||
|
||
const EditableItemContext = createContext<EditableItemContextProps | null>(null); | ||
|
||
export const useEditableItemContext = () => { | ||
const context = useContext(EditableItemContext); | ||
if (!context) { | ||
throw new Error('useEditableItemContext must be used within an EditableItemProvider'); | ||
} | ||
return context; | ||
}; | ||
|
||
export const EditableItemProvider: React.FC<PropsWithChildren> = ({children}: React.PropsWithChildren) => { | ||
const [hasAnyFocus, setHasAnyFocus] = useState(false); | ||
|
||
return <EditableItemContext.Provider value={{hasAnyFocus, setHasAnyFocus}}>{children}</EditableItemContext.Provider>; | ||
}; |
44 changes: 44 additions & 0 deletions
44
HDesign/src/components/EditableItem/EditableItem.input.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/** @jsxImportSource @emotion/react */ | ||
import type {Meta, StoryObj} from '@storybook/react'; | ||
|
||
import EditableItemInput from '@components/EditableItem/EditableItem.Input'; | ||
|
||
import EditableItem from './EditableItem'; | ||
import {EditableItemProvider} from './EditableItem.context'; | ||
|
||
const meta = { | ||
title: 'Components/EditableItemInput', | ||
component: EditableItemInput, | ||
tags: ['autodocs'], | ||
parameters: {}, | ||
argTypes: { | ||
textSize: { | ||
description: '', | ||
control: {type: 'select'}, | ||
}, | ||
hasError: { | ||
description: '', | ||
control: {type: 'boolean'}, | ||
}, | ||
}, | ||
args: { | ||
placeholder: 'μ§μΆ λ΄μ', | ||
textSize: 'body', | ||
hasError: false, | ||
autoFocus: true, | ||
}, | ||
} satisfies Meta<typeof EditableItemInput>; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof meta>; | ||
|
||
export const Playground: Story = { | ||
render: ({...args}) => { | ||
return ( | ||
<EditableItemProvider> | ||
<EditableItem.Input {...args} /> | ||
</EditableItemProvider> | ||
); | ||
}, | ||
}; |
44 changes: 44 additions & 0 deletions
44
HDesign/src/components/EditableItem/EditableItem.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/** @jsxImportSource @emotion/react */ | ||
import type {Meta, StoryObj} from '@storybook/react'; | ||
|
||
import EditableItem from '@components/EditableItem/EditableItem'; | ||
import Flex from '@components/Flex/Flex'; | ||
import Text from '@components/Text/Text'; | ||
|
||
const meta = { | ||
title: 'Components/EditableItem', | ||
component: EditableItem, | ||
tags: ['autodocs'], | ||
parameters: {}, | ||
argTypes: { | ||
backgroundColor: { | ||
description: '', | ||
control: {type: 'select'}, | ||
}, | ||
}, | ||
args: { | ||
backgroundColor: 'lightGrayContainer', | ||
}, | ||
} satisfies Meta<typeof EditableItem>; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof meta>; | ||
|
||
export const Playground: Story = { | ||
render: ({...args}) => { | ||
return ( | ||
<EditableItem | ||
backgroundColor={args.backgroundColor} | ||
onFocus={() => console.log('focus')} | ||
onBlur={() => console.log('blur')} | ||
> | ||
<EditableItem.Input placeholder="μ§μΆ λ΄μ" textSize="bodyBold"></EditableItem.Input> | ||
<Flex gap="0.25rem" alignItems="center"> | ||
<EditableItem.Input placeholder="0" type="number" style={{textAlign: 'right'}}></EditableItem.Input> | ||
<Text size="caption">μ</Text> | ||
</Flex> | ||
</EditableItem> | ||
); | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import {css} from '@emotion/react'; | ||
|
||
import {Theme} from '@theme/theme.type'; | ||
|
||
import {ColorKeys} from '@token/colors'; | ||
|
||
export const editableItemStyle = (theme: Theme, backgroundColor: ColorKeys) => | ||
css({ | ||
display: 'flex', | ||
justifyContent: 'space-between', | ||
padding: '0.5rem', | ||
borderRadius: '0.5rem', | ||
backgroundColor: theme.colors[backgroundColor], | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/** @jsxImportSource @emotion/react */ | ||
import React, {useEffect} from 'react'; | ||
|
||
import {useTheme} from '@theme/HDesignProvider'; | ||
|
||
import {editableItemStyle} from './EditableItem.style'; | ||
import EditableItemInput from './EditableItem.Input'; | ||
import {EditableItemProps} from './EditableItem.type'; | ||
import {EditableItemProvider} from './EditableItem.context'; | ||
import useEditableItem from './useEditableItem'; | ||
|
||
const EditableItemBase = ({ | ||
onInputFocus, | ||
onInputBlur, | ||
backgroundColor = 'white', | ||
children, | ||
...htmlProps | ||
}: EditableItemProps) => { | ||
const {theme} = useTheme(); | ||
|
||
useEditableItem({onInputFocus, onInputBlur}); | ||
|
||
return ( | ||
<div css={editableItemStyle(theme, backgroundColor)} {...htmlProps}> | ||
{children} | ||
</div> | ||
); | ||
}; | ||
|
||
export const EditableItem = (props: EditableItemProps) => { | ||
return ( | ||
<EditableItemProvider> | ||
<EditableItemBase {...props} /> | ||
</EditableItemProvider> | ||
); | ||
}; | ||
|
||
EditableItem.Input = EditableItemInput; | ||
|
||
export default EditableItem; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import {Theme} from '@theme/theme.type'; | ||
|
||
import {ColorKeys} from '@token/colors'; | ||
|
||
export interface EditableItemStyleProps { | ||
backgroundColor: ColorKeys; | ||
} | ||
|
||
export interface EditableItemCustomProps { | ||
onInputFocus?: () => void; | ||
onInputBlur?: () => void; | ||
} | ||
|
||
export interface EditableItemStylePropsWithTheme extends EditableItemStyleProps { | ||
theme: Theme; | ||
} | ||
|
||
export type EditableItemOptionProps = EditableItemStyleProps & EditableItemCustomProps; | ||
|
||
export type EditableItemProps = React.ComponentProps<'div'> & EditableItemOptionProps; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import {useEffect} from 'react'; | ||
|
||
import {useEditableItemContext} from './EditableItem.context'; | ||
|
||
interface UseEditableItemProps { | ||
onInputFocus?: () => void; | ||
onInputBlur?: () => void; | ||
} | ||
|
||
const useEditableItem = ({onInputFocus, onInputBlur}: UseEditableItemProps) => { | ||
const {hasAnyFocus} = useEditableItemContext(); | ||
|
||
useEffect(() => { | ||
if (hasAnyFocus && onInputFocus) { | ||
onInputFocus(); | ||
} | ||
if (!hasAnyFocus && onInputBlur) { | ||
onInputBlur(); | ||
} | ||
}, [hasAnyFocus, onInputFocus, onInputBlur]); | ||
}; | ||
|
||
export default useEditableItem; |
Oops, something went wrong.