Files
invyone/frontend/components/builder/props/ButtonProps.tsx
T
2026-04-10 13:33:37 +09:00

120 lines
5.0 KiB
TypeScript

"use client";
import React from "react";
import { useBuilderState } from "../hooks/useBuilderState";
import type { Component, ButtonConfig, ButtonBarConfig } from "@/types/invyone-component";
const ACTION_OPTIONS: { value: string; label: string }[] = [
{ value: "save", label: "저장" },
{ value: "edit", label: "수정" },
{ value: "delete", label: "삭제" },
{ value: "add", label: "신규" },
{ value: "cancel", label: "취소" },
{ value: "close", label: "닫기" },
{ value: "navigate", label: "화면 이동" },
{ value: "popup", label: "팝업 열기" },
{ value: "search", label: "검색" },
{ value: "reset", label: "초기화" },
{ value: "submit", label: "제출" },
{ value: "approval", label: "승인" },
];
const VARIANT_OPTIONS: { value: string; label: string }[] = [
{ value: "primary", label: "강조 (파란색)" },
{ value: "default", label: "기본 (테두리)" },
{ value: "destructive", label: "위험 (빨간색)" },
{ value: "outline", label: "아웃라인" },
{ value: "ghost", label: "투명" },
];
export function SingleButtonProps({ block }: { block: Component }) {
const updateBlockConfig = useBuilderState((s) => s.updateBlockConfig);
const config = block.config as ButtonConfig;
const update = (key: string, val: any) => updateBlockConfig(block.id, { [key]: val });
return (
<>
<div className="dev-prop-sec"> </div>
<div className="dev-prop-row">
<span className="dev-prop-label"></span>
<input className="dev-input" value={config.text}
onChange={(e) => update("text", e.target.value)} />
</div>
<div className="dev-prop-row inline">
<span className="dev-prop-label"></span>
<select className="dev-select" value={config.actionType}
onChange={(e) => update("actionType", e.target.value)}>
{ACTION_OPTIONS.map((o) => <option key={o.value} value={o.value}>{o.label}</option>)}
</select>
</div>
<div className="dev-prop-row inline">
<span className="dev-prop-label"></span>
<select className="dev-select" value={config.variant}
onChange={(e) => update("variant", e.target.value)}>
{VARIANT_OPTIONS.map((o) => <option key={o.value} value={o.value}>{o.label}</option>)}
</select>
</div>
<div className="dev-prop-row">
<span className="dev-prop-label"> </span>
<input className="dev-input" value={config.confirm || ""}
placeholder="비워두면 확인 없이 실행"
onChange={(e) => update("confirm", e.target.value || undefined)} />
</div>
</>
);
}
export function ButtonBarProps({ block }: { block: Component }) {
const updateBlockConfig = useBuilderState((s) => s.updateBlockConfig);
const config = block.config as ButtonBarConfig;
const updateButton = (idx: number, key: string, val: any) => {
const buttons = [...config.buttons];
buttons[idx] = { ...buttons[idx], [key]: val };
updateBlockConfig(block.id, { buttons } as any);
};
const addButton = () => {
const buttons = [...config.buttons, { text: "버튼", actionType: "save" as const, variant: "default" as const }];
updateBlockConfig(block.id, { buttons } as any);
};
const removeButton = (idx: number) => {
const buttons = config.buttons.filter((_, i) => i !== idx);
updateBlockConfig(block.id, { buttons } as any);
};
return (
<>
<div className="dev-prop-sec"> </div>
{config.buttons.map((btn, i) => (
<div key={i} style={{ padding: "0.15rem 0.6rem", borderBottom: "1px dashed var(--d-border)" }}>
<div style={{ display: "flex", alignItems: "center", gap: "0.2rem", marginBottom: "0.1rem" }}>
<input className="dev-input" style={{ flex: 1 }} value={btn.text}
onChange={(e) => updateButton(i, "text", e.target.value)} />
<button className="dev-delete-btn" style={{ width: "auto", padding: "0.15rem 0.3rem", fontSize: "0.4rem" }}
onClick={() => removeButton(i)}></button>
</div>
<div style={{ display: "flex", gap: "0.2rem" }}>
<select className="dev-select" style={{ flex: 1, fontSize: "0.42rem" }} value={btn.actionType}
onChange={(e) => updateButton(i, "actionType", e.target.value)}>
{ACTION_OPTIONS.map((o) => <option key={o.value} value={o.value}>{o.label}</option>)}
</select>
<select className="dev-select" style={{ flex: 1, fontSize: "0.42rem" }} value={btn.variant}
onChange={(e) => updateButton(i, "variant", e.target.value)}>
{VARIANT_OPTIONS.map((o) => <option key={o.value} value={o.value}>{o.label}</option>)}
</select>
</div>
</div>
))}
<div style={{ padding: "0.2rem 0.6rem" }}>
<button className="dev-btn" style={{ width: "100%", justifyContent: "center" }}
onClick={addButton}>
+
</button>
</div>
</>
);
}