Skip to content

Commit

Permalink
fix(ui): TextField value optional로 수정, generic parameter 삭제, forwardR…
Browse files Browse the repository at this point in the history
…ef 전달. (#210)

* fix: TextField value optional로 수정

* cs

* forwardRef 추가

* change cs

* fix: remove generic parameter.

* remove

* fix: remove generic type in stories

* remove number type
  • Loading branch information
Brokyeom authored Nov 20, 2024
1 parent a323944 commit 0f5ad34
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 36 deletions.
5 changes: 5 additions & 0 deletions .changeset/fluffy-countries-flash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sopt-makers/ui': patch
---

TextField value prop optinal 로 변경, forwardRef 추가.
2 changes: 1 addition & 1 deletion apps/docs/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ function App() {
return (
<>
<Test text='Test Component' size='big' color='blue' />
<TextField<string>
<TextField
placeholder='Placeholder...'
required
labelText='Label'
Expand Down
69 changes: 42 additions & 27 deletions apps/docs/src/stories/Fonts.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { ChangeEvent, useState } from 'react';
import { TextField } from '@sopt-makers/ui';

export default {
title: 'fonts/Fonts'
}
title: 'fonts/Fonts',
};

type FontName = keyof typeof fontsObject;

Expand All @@ -13,10 +13,10 @@ const useInput = (defaultValue: string) => {

const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
setInput(e.target.value);
}
};

return [input, handleInputChange] as const;
}
};

export const Default = () => {
const [text, handleTextChange] = useInput('SOPT에 없던 새로운 가치를 프로덕트를 통해 만들어 갑니다.');
Expand All @@ -32,26 +32,41 @@ export const Default = () => {
case 'LABEL':
return '#346FFA';
}
}

return <div className="fonts-wrap">
<p style={{ fontSize: '20px' }}>* 공통 스타일 - fontFamily : SUIT / fontStyle : normal *</p>
<TextField<string> value={text} onChange={handleTextChange} placeholder="예시 문장을 입력해주세요" />

{Object.keys(fontsObject).map((fontName) => {
const fontObject = fontsObject[fontName as FontName];

return <div key={fontName} className="fonts-group">
<p style={{ color: getFontColor(fontName.split('_')[0]) }}>{fontName}</p>
<div>
<p><span>fontWeight : </span>{fontObject.fontWeight}</p>
<p><span>fontSize : </span>{fontObject.fontSize}</p>
<p><span>lineHeight : </span>{fontObject.lineHeight}</p>
<p><span>letterSpacing : </span>{fontObject.letterSpacing}</p>
</div>
<p style={fontObject}>{text}</p>
</div>
}
)}
</div>
}
};

return (
<div className='fonts-wrap'>
<p style={{ fontSize: '20px' }}>* 공통 스타일 - fontFamily : SUIT / fontStyle : normal *</p>
<TextField value={text} onChange={handleTextChange} placeholder='예시 문장을 입력해주세요' />

{Object.keys(fontsObject).map((fontName) => {
const fontObject = fontsObject[fontName as FontName];

return (
<div key={fontName} className='fonts-group'>
<p style={{ color: getFontColor(fontName.split('_')[0]) }}>{fontName}</p>
<div>
<p>
<span>fontWeight : </span>
{fontObject.fontWeight}
</p>
<p>
<span>fontSize : </span>
{fontObject.fontSize}
</p>
<p>
<span>lineHeight : </span>
{fontObject.lineHeight}
</p>
<p>
<span>letterSpacing : </span>
{fontObject.letterSpacing}
</p>
</div>
<p style={fontObject}>{text}</p>
</div>
);
})}
</div>
);
};
2 changes: 1 addition & 1 deletion apps/docs/src/stories/TextField.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const useTextField = (props: TextFieldProps) => {
setText(e.target.value);
};

return <TextField<string> {...props} value={text} onChange={handleTextChange} />;
return <TextField {...props} value={text} onChange={handleTextChange} />;
};

export default {
Expand Down
17 changes: 10 additions & 7 deletions packages/ui/Input/TextField.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import type { ReactNode, InputHTMLAttributes } from 'react';
import { type ReactNode, type InputHTMLAttributes, forwardRef } from 'react';
import { FieldBox } from 'FieldBox';
import * as S from './style.css';

interface TextFieldProps<T> extends Omit<InputHTMLAttributes<HTMLInputElement>, 'value'> {
interface TextFieldProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'value'> {
className?: string;
topAddon?: ReactNode;
bottomAddon?: ReactNode;
labelText?: string;
descriptionText?: string;
required?: boolean;
errorMessage?: string;
value: T;
value?: string;
// isError -> validationFn 순서로 적용
isError?: boolean;
validationFn?: (input: T) => boolean;
validationFn?: (input: string) => boolean;
}

function TextField<T extends string | number>(props: TextFieldProps<T>) {
const TextField = forwardRef<HTMLInputElement, TextFieldProps>((props, ref) => {
const {
className,
topAddon,
Expand All @@ -34,7 +34,7 @@ function TextField<T extends string | number>(props: TextFieldProps<T>) {
const hasError = () => {
if (inputProps.disabled || inputProps.readOnly) return false;
if (isError !== undefined) return isError;
if (validationFn && !validationFn(value)) return true;
if (validationFn && value && !validationFn(value)) return true;
return false;
};

Expand All @@ -47,6 +47,7 @@ function TextField<T extends string | number>(props: TextFieldProps<T>) {
/>
}
className={className}
ref={ref}
topAddon={
labelText || descriptionText ? (
<FieldBox.Label description={descriptionText} label={labelText} required={required} />
Expand All @@ -58,6 +59,8 @@ function TextField<T extends string | number>(props: TextFieldProps<T>) {
<input {...inputProps} className={`${S.input} ${hasError() ? S.inputError : ''}`} value={value} />
</FieldBox>
);
}
});

TextField.displayName = 'TextField';

export default TextField;

0 comments on commit 0f5ad34

Please sign in to comment.