섹션 삭제 후 텍스트 블록 추가 버그 수정 및 버튼/구분선 스타일-속성 패널 동기화
CI / test (push) Successful in 11m2s
CI / pr_and_merge (push) Successful in 1m19s
CI / test (pull_request) Successful in 51m33s
CI / pr_and_merge (pull_request) Has been skipped

This commit is contained in:
2025-11-22 15:18:32 +09:00
parent d423aedcbe
commit 4e4c9cd37a
17 changed files with 2658 additions and 152 deletions
@@ -150,6 +150,155 @@ export function FormSelectPropertiesPanel({ block, selectedBlockId, updateBlock
</label>
<div className="mt-3 space-y-2 border-t border-slate-800 pt-3">
<h4 className="text-[11px] font-semibold text-slate-200"> </h4>
<NumericPropertyControl
label="셀렉트 텍스트 크기 (px)"
unitLabel="(px)"
value={(() => {
const raw = selectProps.fontSizeCustom ?? "";
const match = raw.match(/([0-9]+(?:\.[0-9]+)?)/);
if (match) return Number(match[1]);
return 14;
})()}
min={8}
max={40}
step={1}
presets={[
{ id: "xs", label: "XS", value: 12 },
{ id: "sm", label: "S", value: 14 },
{ id: "md", label: "M", value: 16 },
{ id: "lg", label: "L", value: 18 },
{ id: "xl", label: "XL", value: 20 },
]}
onChangeValue={(v) => {
updateBlock(selectedBlockId, {
fontSizeCustom: `${v}px`,
} as any);
}}
/>
{/* 줄간격 px 입력을 받아 preview 렌더러의 em 변환 근거로 사용한다 */}
<NumericPropertyControl
label="셀렉트 줄간격 (px)"
unitLabel="(px)"
value={(() => {
const raw = selectProps.lineHeightCustom ?? "";
const match = raw.match(/([0-9]+(?:\.[0-9]+)?)/);
if (match) return Number(match[1]);
return 20;
})()}
min={8}
max={60}
step={1}
presets={[
{ id: "tight", label: "타이트", value: 18 },
{ id: "normal", label: "보통", value: 24 },
{ id: "loose", label: "루즈", value: 32 },
]}
onChangeValue={(v) => {
updateBlock(selectedBlockId, {
lineHeightCustom: `${v}px`,
} as any);
}}
/>
{/* 자간 px 입력을 제공하여 TDD 시나리오와 동기화한다 */}
<NumericPropertyControl
label="셀렉트 자간 (px)"
unitLabel="(px)"
value={(() => {
const raw = selectProps.letterSpacingCustom ?? "";
const match = raw.match(/(-?[0-9]+(?:\.[0-9]+)?)/);
if (match) return Number(match[1]);
return 0;
})()}
min={-10}
max={20}
step={0.5}
presets={[
{ id: "tight", label: "좁게", value: -1 },
{ id: "normal", label: "보통", value: 0 },
{ id: "wide", label: "넓게", value: 2 },
]}
onChangeValue={(v) => {
updateBlock(selectedBlockId, {
letterSpacingCustom: `${v}px`,
} as any);
}}
/>
<label className="flex flex-col gap-1 text-[11px] text-slate-400">
<span> </span>
<select
className="w-full rounded border border-slate-700 bg-slate-950 px-2 py-1 text-[11px] outline-none focus:border-sky-500"
value={selectProps.widthMode ?? "full"}
onChange={(e) =>
updateBlock(selectedBlockId, {
widthMode: e.target.value,
} as any)
}
>
<option value="auto"></option>
<option value="full"> </option>
<option value="fixed"> </option>
</select>
</label>
{(selectProps.widthMode ?? "full") === "fixed" && (
<NumericPropertyControl
label="필드 고정 너비"
unitLabel="(px)"
value={selectProps.widthPx ?? 240}
min={80}
max={800}
step={10}
presets={[
{ id: "sm", label: "작게", value: 200 },
{ id: "md", label: "보통", value: 280 },
{ id: "lg", label: "넓게", value: 360 },
]}
onChangeValue={(v) => {
updateBlock(selectedBlockId, {
widthPx: v,
} as any);
}}
/>
)}
<NumericPropertyControl
label="셀렉트 가로 패딩 (px)"
unitLabel="(px)"
value={typeof selectProps.paddingX === "number" ? selectProps.paddingX : 12}
min={0}
max={60}
step={2}
presets={[
{ id: "xs", label: "아주 얇게", value: 6 },
{ id: "sm", label: "얇게", value: 10 },
{ id: "md", label: "보통", value: 12 },
{ id: "lg", label: "넓게", value: 16 },
{ id: "xl", label: "아주 넓게", value: 20 },
]}
onChangeValue={(v) =>
updateBlock(selectedBlockId, {
paddingX: v,
} as any)
}
/>
<NumericPropertyControl
label="셀렉트 세로 패딩 (px)"
unitLabel="(px)"
value={typeof selectProps.paddingY === "number" ? selectProps.paddingY : 10}
min={0}
max={40}
step={1}
presets={[
{ id: "xs", label: "아주 얇게", value: 6 },
{ id: "sm", label: "얇게", value: 8 },
{ id: "md", label: "보통", value: 10 },
{ id: "lg", label: "넓게", value: 12 },
{ id: "xl", label: "아주 넓게", value: 16 },
]}
onChangeValue={(v) =>
updateBlock(selectedBlockId, {
paddingY: v,
} as any)
}
/>
<ColorPickerField
label="필드 텍스트 색상"
ariaLabelColorInput="셀렉트 텍스트 색상 피커"