o2o-site-AEO/solution/frontend/src/features/builder/canvas/thumbs.tsx
Mina Choi c85c577349 이름: solution/front → solution/frontend
`backend` 옆에 `front` 가 있을 이유가 없었다. negosium 의 negodata/front 를 그대로
베꼈고 그게 왜 front 인지는 따져보지 않았다 — 근거 없이 들여온 이름이라 바로잡는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019uYhHQdssRubirPirrdJJC
2026-08-31 15:27:16 +09:00

176 lines
5.7 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 배리에이션 와이어프레임 썸네일.
*
* 사장님은 "InfoTable" 이라는 이름으로 고르지 않는다 — 모양을 보고 고른다.
* 그래서 배리에이션 카드에는 반드시 그림이 붙고, 그 그림은 여기 한 곳에서만 그린다.
*/
import type {ThumbKey} from './types';
const BOX = 'fill-stone-300';
const LINE = 'fill-stone-200';
const ACCENT = 'fill-stone-500';
/** 40×28 좌표계 위에 회색 블록으로 레이아웃 얼개만 그린다. */
const SHAPES: Record<ThumbKey, React.ReactNode> = {
fullbleed: (
<>
<rect x="0" y="0" width="40" height="28" className={BOX} />
<rect x="3" y="18" width="20" height="3" className={ACCENT} />
<rect x="3" y="23" width="12" height="2" className={LINE} />
</>
),
split: (
<>
<rect x="2" y="6" width="16" height="3" className={ACCENT} />
<rect x="2" y="12" width="14" height="2" className={LINE} />
<rect x="2" y="16" width="10" height="2" className={LINE} />
<rect x="22" y="5" width="16" height="18" className={BOX} />
</>
),
stack: (
<>
<rect x="2" y="3" width="36" height="12" className={BOX} />
<rect x="2" y="18" width="24" height="2.5" className={ACCENT} />
<rect x="2" y="22" width="34" height="2" className={LINE} />
</>
),
centered: (
<>
<rect x="14" y="5" width="12" height="2" className={LINE} />
<rect x="9" y="10" width="22" height="3" className={ACCENT} />
<rect x="6" y="17" width="28" height="2" className={LINE} />
<rect x="10" y="21" width="20" height="2" className={LINE} />
</>
),
grid: (
<>
{[2, 11, 20, 29].map((x) =>
[4, 15].map((y) => (
<rect key={`${x}-${y}`} x={x} y={y} width="8" height="8" className={BOX} />
)),
)}
</>
),
masonry: (
<>
<rect x="2" y="3" width="11" height="13" className={BOX} />
<rect x="2" y="18" width="11" height="7" className={BOX} />
<rect x="15" y="3" width="11" height="8" className={BOX} />
<rect x="15" y="13" width="11" height="12" className={BOX} />
<rect x="28" y="3" width="10" height="14" className={BOX} />
<rect x="28" y="19" width="10" height="6" className={BOX} />
</>
),
carousel: (
<>
<rect x="1" y="6" width="6" height="14" className={LINE} />
<rect x="9" y="4" width="22" height="18" className={BOX} />
<rect x="33" y="6" width="6" height="14" className={LINE} />
<rect x="17" y="24" width="6" height="1.5" className={ACCENT} />
</>
),
list: (
<>
{[3, 11, 19].map((y) => (
<g key={y}>
<rect x="2" y={y} width="9" height="6" className={BOX} />
<rect x="13" y={y + 1} width="16" height="2" className={ACCENT} />
<rect x="13" y={y + 4} width="22" height="1.5" className={LINE} />
</g>
))}
</>
),
table: (
<>
<rect x="2" y="3" width="36" height="4" className={ACCENT} />
{[9, 14, 19, 24].map((y) => (
<g key={y}>
<rect x="2" y={y} width="14" height="2" className={LINE} />
<rect x="20" y={y} width="18" height="2" className={LINE} />
</g>
))}
</>
),
cards: (
<>
{[2, 21].map((x) =>
[3, 15].map((y) => (
<g key={`${x}-${y}`}>
<rect x={x} y={y} width="17" height="9" className={LINE} />
<rect x={x + 2} y={y + 2} width="9" height="2" className={ACCENT} />
<rect x={x + 2} y={y + 5.5} width="13" height="1.5" className={BOX} />
</g>
)),
)}
</>
),
accordion: (
<>
<rect x="2" y="3" width="36" height="4" className={ACCENT} />
<rect x="2" y="9" width="36" height="7" className={LINE} />
<rect x="2" y="18" width="36" height="4" className={ACCENT} />
<rect x="2" y="24" width="36" height="2" className={LINE} />
</>
),
'two-column': (
<>
{[2, 21].map((x) => (
<g key={x}>
<rect x={x} y="4" width="17" height="2.5" className={ACCENT} />
<rect x={x} y="8.5" width="15" height="1.5" className={LINE} />
<rect x={x} y="15" width="17" height="2.5" className={ACCENT} />
<rect x={x} y="19.5" width="15" height="1.5" className={LINE} />
</g>
))}
</>
),
banner: (
<>
<rect x="0" y="8" width="40" height="12" className={ACCENT} />
<rect x="4" y="11" width="16" height="2.5" className="fill-white/80" />
<rect x="26" y="11" width="10" height="5" className="fill-white/90" />
</>
),
form: (
<>
<rect x="2" y="3" width="20" height="2.5" className={ACCENT} />
<rect x="2" y="8" width="17" height="4" className={LINE} />
<rect x="21" y="8" width="17" height="4" className={LINE} />
<rect x="2" y="14" width="36" height="6" className={LINE} />
<rect x="2" y="22" width="36" height="4" className={ACCENT} />
</>
),
timeline: (
<>
<rect x="5" y="3" width="1.5" height="22" className={LINE} />
{[4, 12, 20].map((y) => (
<g key={y}>
<circle cx="5.75" cy={y + 1.5} r="2" className={ACCENT} />
<rect x="11" y={y} width="14" height="2" className={ACCENT} />
<rect x="11" y={y + 3.5} width="24" height="1.5" className={LINE} />
</g>
))}
</>
),
compact: (
<>
<rect x="2" y="8" width="12" height="2.5" className={ACCENT} />
<rect x="2" y="13" width="36" height="6" className={LINE} />
</>
),
};
export function VariantThumb({thumb, className}: {thumb: ThumbKey; className?: string}) {
return (
<svg
viewBox="0 0 40 28"
role="presentation"
className={className}
preserveAspectRatio="xMidYMid meet"
>
<rect x="0" y="0" width="40" height="28" className="fill-white" />
{SHAPES[thumb]}
</svg>
);
}