Files
invyone/frontend/lib/registry/components/common/row-helpers.tsx
T
DDD1542 e347a75953
Build & Deploy to K8s / build-and-deploy (push) Successful in 5m32s
refactor: ConfigPanel hook/helper 추출 + IconPicker cp+Portal
- useDbTables: search/table/stats 의 DB 테이블 로드 hook (3 패널 중복 제거)
- TableConnectSection + AutoLoadButton: search/table 의 테이블 연결 섹션 + 자동 로드 버튼
- row-helpers: RowNumberBadge / RowExpandChevron / RowDeleteBtn (4 패널 dense list helper)
- IconPicker: shadcn 톤 -> cp 톤 (28px 트리거, focus glow, cp 변수)
- IconPicker popover: React Portal + position:fixed (부모 overflow:hidden 우회)
- input X버튼은 hoverBg={false} 로 silent visual change 원복

Codex (GPT-5.5) 와 매 단계 교차검증 후 진행
미완 후속 사항 (auto-flip / 외부 클릭 닫기 / z-index 표준화 등) 노트에 기록

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 11:25:06 +09:00

138 lines
3.5 KiB
TypeScript
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.
"use client";
/**
* Row helpers — 4 패널 (search/table/stats/input) 의 dense list row 에서 반복되는
* 작은 visual elements 만 추출. row 뼈대 자체는 호출처에 그대로 둠.
*
* Codex 검토 (2026-04-29) 가이드:
* - helper-only 추출 (작은 cp 컴포넌트 후보)
* - DenseListRow / ExpandableRow 같은 wrapper 는 ★ silent breakage 위험으로 보류
* - 호출처별 row prop 폭증 + expanded state 위치 / hover 표시 / row padding 회귀 위험
*
* 적용 패턴:
* - RowNumberBadge: search/table/stats 의 #번호 (4 패널 중 3)
* - RowExpandChevron: table/stats 의 ▸/▾ 펼침 버튼 (2 패널)
* - RowDeleteBtn: 4 패널 모두 사용 — visible/size/아이콘 prop 으로 미세 차이 흡수
*
* silent visual change 알림:
* - input 의 옵션 ×버튼은 원래 hover bg 없었음 → helper 적용 시 hover 시 옅은 red bg 추가됨
* - 통일 차원에서 의도적
*/
import React from "react";
export interface RowNumberBadgeProps {
n: number;
}
export const RowNumberBadge: React.FC<RowNumberBadgeProps> = ({ n }) => (
<span
style={{
fontSize: 9,
color: "var(--cp-text-muted)",
fontFamily: "var(--v5-font-mono)",
textAlign: "right",
}}
>
{n}
</span>
);
export interface RowExpandChevronProps {
expanded: boolean;
onToggle: () => void;
size?: number;
}
export const RowExpandChevron: React.FC<RowExpandChevronProps> = ({
expanded,
onToggle,
size = 18,
}) => (
<button
type="button"
onClick={onToggle}
title={expanded ? "접기" : "펼침"}
style={{
width: size,
height: size,
padding: 0,
background: "transparent",
border: "none",
cursor: "pointer",
color: "var(--cp-text-muted)",
display: "flex",
alignItems: "center",
justifyContent: "center",
fontSize: 10,
}}
>
{expanded ? "▾" : "▸"}
</button>
);
export interface RowDeleteBtnProps {
onClick: () => void;
/**
* 부모 hover state — false 면 transparent (자리 차지). 기본 true (항상 visible).
*
* ★ search/table/stats 같은 dense list row 에서는 반드시 `visible={hover}` 명시할 것.
* 생략하면 hover 와 무관하게 항상 빨간 ×버튼 노출 → UX 어긋남.
*/
visible?: boolean;
size?: number;
/** 아이콘 (기본 "×" 텍스트) */
children?: React.ReactNode;
title?: string;
/** hover 시 옅은 red bg 표시 (기본 true). false 면 hover bg 없이 색만 강조. */
hoverBg?: boolean;
}
export const RowDeleteBtn: React.FC<RowDeleteBtnProps> = ({
onClick,
visible = true,
size = 22,
children = "×",
title = "제거",
hoverBg = true,
}) => (
<button
type="button"
onClick={onClick}
title={title}
style={{
width: size,
height: size,
padding: 0,
background: "transparent",
border: "none",
cursor: "pointer",
color: visible ? "var(--v5-red, #ef4444)" : "transparent",
display: "flex",
alignItems: "center",
justifyContent: "center",
borderRadius: 4,
...(hoverBg && {
transition: "color .12s ease, background .12s ease",
}),
}}
onMouseEnter={
hoverBg
? (e) => {
(e.currentTarget as HTMLButtonElement).style.background =
"rgba(239, 68, 68, 0.10)";
}
: undefined
}
onMouseLeave={
hoverBg
? (e) => {
(e.currentTarget as HTMLButtonElement).style.background = "transparent";
}
: undefined
}
>
{children}
</button>
);