File name
Commit message
Commit date
File name
Commit message
Commit date
09-03
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
'use client';
import { useState } from 'react';
import { FoxHelperText } from '@fox/core/components/fox-helper-text';
import { FoxIconButton } from '@fox/core/components/fox-icon-button';
import { FoxInput } from '@fox/core/components/fox-input';
import { FoxTextButton } from '@fox/core/components/fox-text-button';
import {
DEFAULT_KEYWORD_ROWS,
type ContentKeyword,
} from '@/lib/domain/content';
import {
KEYWORD_DESCRIPTION_MAX_LENGTH,
KEYWORD_MAX_LENGTH,
} from '@/lib/domain/content-form';
import styles from './content-form.module.scss';
interface ContentKeywordFieldProps {
defaultKeywords?: readonly ContentKeyword[];
error?: string;
}
const EMPTY_ROW: ContentKeyword = { keyword: '', description: '' };
function initialRows(
defaults: readonly ContentKeyword[]
): Array<ContentKeyword & { key: number }> {
const rows = defaults.length > 0 ? defaults : Array.from({ length: DEFAULT_KEYWORD_ROWS }, () => EMPTY_ROW);
return rows.map((row, index) => ({ ...row, key: index }));
}
/** 키워드 — 키워드와 설명을 쌍으로 입력한다. 기본 2줄이고 줄을 더 늘릴 수 있다. */
export function ContentKeywordField({
defaultKeywords = [],
error,
}: ContentKeywordFieldProps) {
const [rows, setRows] = useState(() => initialRows(defaultKeywords));
const [nextKey, setNextKey] = useState(rows.length);
function addRow() {
setRows((current) => [...current, { ...EMPTY_ROW, key: nextKey }]);
setNextKey((current) => current + 1);
}
function removeRow(key: number) {
setRows((current) =>
current.length === 1 ? current : current.filter((row) => row.key !== key)
);
}
return (
<>
{rows.map((row) => (
<div key={row.key} className={styles.keywordRow}>
<div className={styles.keywordName}>
<FoxInput
size="md"
name="keyword"
aria-label="키워드"
defaultValue={row.keyword}
placeholder="키워드"
maxLength={KEYWORD_MAX_LENGTH}
/>
</div>
<div className={styles.keywordDescription}>
<FoxInput
size="md"
name="keywordDescription"
aria-label="키워드 설명"
defaultValue={row.description}
placeholder="키워드에 대한 간단한 설명"
maxLength={KEYWORD_DESCRIPTION_MAX_LENGTH}
/>
</div>
<FoxIconButton
type="default"
size="md"
icon={<i className="fox-ico fox-ico-Trash" aria-hidden="true" />}
label="키워드 삭제"
disabled={rows.length === 1}
onAction={() => removeRow(row.key)}
/>
</div>
))}
<div>
<FoxTextButton
size="md"
leadingIcon={<i className="fox-ico fox-ico-Plus" aria-hidden="true" />}
label="키워드 추가"
onAction={addRow}
/>
</div>
{error && <FoxHelperText type="danger" message={error} />}
</>
);
}