TagsInput
Data Input
여러 태그를 입력하고 관리하는 입력 필드.
Usage
import
API Reference
같은 패밀리
예제
Usage
사용자가 여러 키워드를 입력·확정·삭제해 태그 배열을 만들 때 사용한다.
import
import
import { TagsInput } from '@mildang/design-system/Combobox';API Reference
TagsInput Props
Prop
Type
Default
allowedValues
string[]
지정 안 함
inputValue
string
지정 안 함
isComboboxOpen
boolean
false
onInputChange
(details: InputValueChangeDetails) => void
지정 안 함
onKeyDown
(e: KeyboardEvent<HTMLInputElement>) => void
지정 안 함
placeholder
string
지정 안 함
renderTag
TagsInputRenderTag
지정 안 함
showChip
boolean
true
showSearchIcon
boolean
true
size
"xs" | "sm" | "md" | "lg" | "xl"
md
type
"search" | "free"
search
같은 패밀리
@mildang/design-system/Combobox 에서 같이 내보내는 컴포넌트다.
예제
기본 사용
입력한 값이 칩으로 쌓이는 형태 — 태그처럼 개수가 정해지지 않은 값을 여러 개 받을 때 씁니다.
import type { ComponentProps } from 'react';
import { TagsInput } from '@mildang/design-system/Combobox';
import { useState } from 'react';
const STORY_DEFAULT_ARGS = { ...({}), ...({}) } as ComponentProps<typeof TagsInput>;
const TagsInputDefaultExampleRender = (args: ComponentProps<typeof TagsInput>) => {
const [values, setValues] = useState<string[]>();
return (
<TagsInput
value={values}
onValueChange={(details) => setValues(details.value)}
placeholder="프레임워크를 입력하세요..."
{...args}
/>
);
};
export default function TagsInputDefaultExample(props: Partial<ComponentProps<typeof TagsInput>>) {
const mergedProps = { ...STORY_DEFAULT_ARGS, ...props } as ComponentProps<typeof TagsInput>;
return TagsInputDefaultExampleRender(mergedProps);
}
크기
xs부터 xl까지 칩과 입력 높이가 함께 커지는 5단계를 비교합니다.
import { TagsInput } from '@mildang/design-system/Combobox';
const TagsInputSizesExample = () => (
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', width: '400px' }}>
{(['sm', 'md', 'lg', 'xl'] as const).map((size) => (
<div key={size} style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
<span style={{ width: '24px', fontSize: '12px', color: '#666', flexShrink: 0 }}>{size}</span>
<TagsInput size={size} defaultValue={['React', 'Vue']} placeholder={`size=${size}`} />
</div>
))}
</div>
);
export default TagsInputSizesExample;
상태
import { useState } from 'react';
import { TagsInput } from '@mildang/design-system/Combobox';
const TagsInputDisabledExample = () => {
const [values] = useState<string[]>(['React', 'Vue']);
return <TagsInput value={values} disabled placeholder="비활성화된 상태입니다" />;
};
export default TagsInputDisabledExample;
WithMaxTags
import { useState } from 'react';
import { TagsInput } from '@mildang/design-system/Combobox';
const TagsInputWithMaxTagsExample = () => {
const [values, setValues] = useState<string[]>(['React', 'Vue']);
return (
<TagsInput
value={values}
onValueChange={(details) => setValues(details.value)}
max={3}
placeholder="최대 3개까지 입력 가능"
/>
);
};
export default TagsInputWithMaxTagsExample;
CustomDelimiter
import { useState } from 'react';
import { TagsInput } from '@mildang/design-system/Combobox';
const TagsInputCustomDelimiterExample = () => {
const [values, setValues] = useState<string[]>([]);
return (
<TagsInput
value={values}
onValueChange={(details) => setValues(details.value)}
delimiter={/;|\|/}
placeholder="세미콜론(;) 또는 파이프(|)로 구분"
/>
);
};
export default TagsInputCustomDelimiterExample;
WithAllowedValues
import { useState } from 'react';
import { TagsInput } from '@mildang/design-system/Combobox';
const TagsInputWithAllowedValuesExample = () => {
const [values, setValues] = useState<string[]>([]);
const allowedFrameworks = ['React', 'Vue', 'Angular', 'Svelte', 'Next.js', 'Nuxt.js'];
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', width: '400px' }}>
<TagsInput
value={values}
onValueChange={(details) => setValues(details.value)}
allowedValues={allowedFrameworks}
placeholder="허용된 프레임워크만 입력 가능"
/>
<div style={{ fontSize: '14px', color: '#666' }}>
<p>현재 태그: {values.join(', ') || '(없음)'}</p>
<p style={{ marginTop: '8px', padding: '8px', backgroundColor: '#f5f5f5', borderRadius: '4px' }}>
💡 허용된 값: {allowedFrameworks.join(', ')}
<br />
<br />
allowedValues에 포함된 값만 태그로 추가할 수 있습니다. 다른 값을 입력하면 Enter 키를 눌러도
추가되지 않습니다.
</p>
</div>
</div>
);
};
export default TagsInputWithAllowedValuesExample;
WithValidation
import { useState } from 'react';
import { TagsInput } from '@mildang/design-system/Combobox';
const TagsInputWithValidationExample = () => {
const [values, setValues] = useState<string[]>([]);
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', width: '400px' }}>
<TagsInput
value={values}
onValueChange={(details) => setValues(details.value)}
validate={(details: { value: unknown[]; inputValue: string }) => {
const { value, inputValue } = details;
const stringValues = value as string[];
// 입력값이 비어있으면 false
if (!inputValue || inputValue.trim() === '') {
return false;
}
// 이미 존재하는 태그면 false
if (stringValues.includes(inputValue)) {
return false;
}
// 2-10글자 검증
if (inputValue.length < 2 || inputValue.length > 10) {
return false;
}
return true;
}}
placeholder="2-10글자 태그 입력"
/>
<div style={{ fontSize: '14px', color: '#666' }}>
<p>현재 태그: {values.join(', ') || '(없음)'}</p>
<p style={{ marginTop: '8px', padding: '8px', backgroundColor: '#f5f5f5', borderRadius: '4px' }}>
💡 검증 규칙:
<br />- 2-10글자만 허용
<br />- 중복 불가
<br />- 빈 값 불가
</p>
</div>
</div>
);
};
export default TagsInputWithValidationExample;
WithoutChip
import { useState } from 'react';
import { TagsInput } from '@mildang/design-system/Combobox';
const TagsInputWithoutChipExample = () => {
const [values, setValues] = useState<string[]>(['React', 'Vue', 'Angular']);
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', width: '400px' }}>
<TagsInput
value={values}
onValueChange={(details) => setValues(details.value)}
showChip={false}
placeholder="텍스트로 이어서 표시됩니다"
/>
<div style={{ fontSize: '14px', color: '#666' }}>
<p>태그 개수: {values.length}</p>
<p>표시 형식: {values.join(', ')}</p>
<p style={{ marginTop: '8px', padding: '8px', backgroundColor: '#f5f5f5', borderRadius: '4px' }}>
💡 팁: showChip={false}이면 선택된 값들이 텍스트로 이어서 표시됩니다.
<br />
예: "React, Vue, Angular"와 같이 쉼표로 구분되어 표시됩니다.
<br />칩 삭제 기능은 사용할 수 없지만, Clear 버튼으로 모든 값을 한 번에 지울 수 있습니다.
</p>
</div>
</div>
);
};
export default TagsInputWithoutChipExample;
WithoutSearchIcon
import { useState } from 'react';
import { TagsInput } from '@mildang/design-system/Combobox';
const TagsInputWithoutSearchIconExample = () => {
const [values, setValues] = useState<string[]>(['React', 'Vue', 'Angular']);
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', width: '400px' }}>
<TagsInput
value={values}
onValueChange={(details) => setValues(details.value)}
showSearchIcon={false}
placeholder="검색 아이콘 없이 표시됩니다"
/>
<div style={{ fontSize: '14px', color: '#666' }}>
<p>태그 개수: {values.length}</p>
<p style={{ marginTop: '8px', padding: '8px', backgroundColor: '#f5f5f5', borderRadius: '4px' }}>
💡 팁: showSearchIcon={false}로 설정하면 검색 아이콘이 표시되지 않습니다.
<br />
기본값은 showSearchIcon={true}로, 검색 아이콘이 표시됩니다.
<br />
<br />
입력 검증(allowedValues)은 별도로 제어됩니다.
</p>
</div>
</div>
);
};
export default TagsInputWithoutSearchIconExample;