Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[draft] Primitive vs Wrapper: Label에서 시작된 컴포넌트 설계 고민 #976

hyoseong1994 started this conversation in 초안
Discussion options

아직 수정중입니다. 리뷰는 추후에 요청하겠습니다.

처음에는 Label을 form 컴포넌트들(TextInput 등)에 포함해야하는가에 대해서 논의하게 되었습니다.
label 포함하는 전략을 타사 라이브러리를 비교하여 몇가지 제안을 했습니다.

논의의 시작

Label 포함 전략 비교

구분 Material UI Chakra UI Ant Design
단일 Form Element ⭕ 포함 (TextField) ❌ (FormControl로 분리) ❌ (Form.Item에서 처리)
Group 컴포넌트 ❌ 별도 (FormLabel) ❌ (FormControl) ❌ (Form.Item)

제안

항목 1. Group만 포함 2. 완전 분리 (FormField) 3. 전체 포함 4. 분리 + Wrapper (최종 제안)
구조 Group에만 label 포함 모든 컴포넌트에서 label 제거, FormField로 조합 모든 컴포넌트에 label 포함 FormField 기반 + TextField 등 wrapper 제공
일관성 ❌ 낮음 ⭕ 높음 ⭕ 높음 ⭕ 높음
확장성 ❌ 낮음 ⭕ 매우 높음 ❌ 낮음 ⭕ 매우 높음
자유도 ⚠️ 제한적 ⭕ 매우 높음 ❌ 거의 없음 ⭕ 매우 높음
DX ⚠️ 중간 ❌ 낮음 (초기) ⭕ 높음 ⭕ 높음
접근성 관리 ❌ 분산됨 ⭕ 중앙 관리 ❌ 컴포넌트별 중복 ⭕ 중앙 관리
개발 비용 ⭕ 낮음 ❌ 높음 ❌ 높음 ⚠️ 중간

Group 만 Label 포함

현재 구조이며 RadioGroup, CheckboxGroup에서만 Label이 포함되고 TextInput등은 포함되지 않습니다.

<TextInput
 placeholder="검색어를 입력하세요..."
/>
 
<RadioGroup
 label="세로 방향 (Vertical)"
 defaultValue="apple"
>
 <Radio value="apple">사과</Radio>
 <Radio value="banana">바나나</Radio>
 <Radio value="orange">오렌지</Radio>
</RadioGroup>

모든 컴포넌트에서 label 제거, FormField로 조합

<FormField>
 <FormField.Label>이름</FormField.Label>
 <FormField.Control>
 <Input />
 </FormField.Control>
 <FormField.Description>
 daleui 에서 사용할 이름을 입력해주세요.
 </FormField.Description>
 <FormField.ErrorMessage>
 이름은 50자를 넘길 수 없습니다.
 </FormField.ErrorMessage>
</FormField>

모든 컴포넌트에 label 포함

<TextInputField 
 label="이메일" 
 description="설명을 입력하세요" 
 errorMessage="에러입니다" 
/>

FormField 기반 + TextField 등 wrapper 제공

// primitive
<FormField>
 <FormField.Label>이름</FormField.Label>
 <FormField.Control>
 <Input />
 </FormField.Control>
 <FormField.Description>
 daleui 에서 사용할 이름을 입력해주세요.
 </FormField.Description>
 <FormField.ErrorMessage>
 이름은 50자를 넘길 수 없습니다.
 </FormField.ErrorMessage>
</FormField>
// Wrapper
<TextInputField 
 label="이메일" 
 description="설명을 입력하세요" 
 errorMessage="에러입니다" 
/>

4번을 최종으로 제안했습니다.

FormField를 통해 label / description / error를 일관되게 관리하고,
TextField와 같은 wrapper 컴포넌트에서 접근성을 포함한 기본 동작을 제공합니다.
또한 FormField 조합을 통해 복잡한 케이스에서도 세밀한 제어가 가능합니다.

새로운 의견

윤섭님이 MUI, Mantine, React Spectrum, Carbon 등 다양한 라이브러리 들을 비교해서 Label이 포함된 형태로 제공되고있다고 알려주셨고
"우선순위를 두자면 지금은 label 내장 컴포넌트를 먼저 갖추고, 저수준 컴포넌트는 실제 수요가 생겼을 때 추가하는 게 현실적이라고 생각합니다." 라는 의견을 주셨습니다.

제가 생각하기에는
초기에 TextInput을 label 포함 형태로 정의할 경우, 이후 순수 input이 필요한 시점에 네이밍이 어색해질 가능성이 있다고 생각했습니다.
ex )

  • TextInput (label 포함)
  • PureTextInput 또는 BaseTextInput

처럼 파생 네이밍이 생기게 되고, 이게 오히려 API 복잡도를 높일 수 있다고 생각했습니다. 또한 Label을 포함할 경우 컴포넌트에 책임이 너무 커지지 않을까 우려했습니다.

관점에 전환

처음에는 좋은 컴포넌트, 책임분리 이런 부분만 집중하다보니 놓쳤습니다.
1.0 배포를 앞둔 시점에서 이걸 변경하는게 올바를까? 배포 후에 break change 는 어떻게 해야하지? 라는 관점에서 보니 새로웠습니다.
지금 당장은 wrapper 컴포넌트로 제공하고 primitive 컴포넌트는 추후에 제공하면 break change가 없어진다는 걸 깨닫게 되었습니다.
"나무를 보지말고 숲을 봐라" 처럼 한곳에만 매몰되다보니 전체적인 그림을 보지 못하는 상황이 생겼었네요

You must be logged in to vote

Replies: 0 comments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
초안
Labels
None yet
1 participant

AltStyle によって変換されたページ (->オリジナル) /