@t3q-ui/design-system 0.0.0-stage → 1.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/fonts.css ADDED
@@ -0,0 +1,12 @@
1
+ @import 'pretendard/dist/web/variable/pretendardvariable.css';
2
+
3
+ body {
4
+ font-family:
5
+ 'Pretendard Variable',
6
+ Pretendard,
7
+ -apple-system,
8
+ BlinkMacSystemFont,
9
+ system-ui,
10
+ 'Segoe UI',
11
+ sans-serif;
12
+ }
@@ -0,0 +1,253 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ declare namespace class_variance_authority_types {
3
+ type ClassValue = import('clsx').ClassValue;
4
+ type ClassProp = { class: ClassValue; className?: never } | { class?: never; className: ClassValue } | { class?: never; className?: never };
5
+ }
6
+ import * as React from 'react';
7
+ import { ReactNode, CSSProperties } from 'react';
8
+ import { VariantProps } from 'class-variance-authority';
9
+ import * as DialogPrimitive from '@radix-ui/react-dialog';
10
+ import { IHeaderParams, ICellRendererParams } from 'ag-grid-community';
11
+ import { AgGridReactProps, AgGridReact } from 'ag-grid-react';
12
+
13
+ type BadgeTone = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'etc';
14
+ /**
15
+ * outline 뱃지의 accent(테두리) 색. 기본은 {hue}30 — 흰 바탕 대비 primary 4.7 · danger 5.9 · success 4.6 · etc 5.8.
16
+ * yellow30(1.75:1)·cyan30(1.59:1)은 흰 바탕에서 선이 안 보여 warning·info 는 40(5.4·5.5), grayscale30 도 연해 secondary 는 50(3.7)
17
+ * — bold 변형이 warning·info 글자만 예외로 두는 것과 같은 "밝은 색 예외" 규칙 (2026-10-17 이슈 47 6차)
18
+ */
19
+ declare const BADGE_OUTLINE_ACCENT: Record<BadgeTone, {
20
+ border: string;
21
+ icon: string;
22
+ }>;
23
+ declare const badgeVariants: (props?: ({
24
+ size?: "small" | "medium" | null | undefined;
25
+ variant?: "primary" | "info" | "success" | "warning" | "danger" | "primaryBold" | "secondary" | "secondaryBold" | "dangerBold" | "warningBold" | "infoBold" | "etc" | "successBold" | "etcBold" | null | undefined;
26
+ rounded?: "full" | "default" | null | undefined;
27
+ appearance?: "tint" | "outline" | null | undefined;
28
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
29
+ interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
30
+ }
31
+ /**
32
+ * 상태·분류를 색으로 보여 주는 읽기 전용 표시. 표의 상태 열, 제목 옆 상태에 쓴다.
33
+ *
34
+ * 언제 쓰나: 실행 중/중지/오류 같은 상태(`success`·`danger`·`warning`·`info`), 개수·등급 표시. 의미 variant 를 쓰고 색을 직접 바꾸지 않는다. `appearance='outline'` 은 흰 바탕 + 1px accent 테두리.
35
+ * 언제 안 쓰나: 사용자가 붙이고 뗄 수 있는 라벨(→ Tag), 클릭해 동작하는 것(→ Button), 지나가는 알림(→ Toast).
36
+ * 대신/함께: **상태 표시는 Badge 에 아이콘 + 글자** — `<Badge variant='success'><LucideIcon iconComponentName='circle-check' />완료</Badge>`(아이콘은 자식으로 바로, 16px·글자색). 별도 상태 컴포넌트는 없다(2026-10-30). 크기는 기본(`size` 를 주지 않는다). 상태값 → variant·아이콘 매핑은 소비 앱의 상수 한 곳에 둔다.
37
+ */
38
+ declare function Badge({ className, variant, rounded, appearance, size, children, ...props }: BadgeProps): react_jsx_runtime.JSX.Element;
39
+
40
+ declare const buttonVariants: (props?: ({
41
+ variant?: "primary" | "warning" | "danger" | "primaryBold" | "secondary" | "secondaryBold" | "dangerBold" | "warningBold" | "primaryLink" | "dangerLink" | "secondaryLink" | "warningLink" | "primaryOutline" | "secondaryOutline" | "dangerOutline" | "warningOutline" | null | undefined;
42
+ spacing?: "normal" | "compact" | null | undefined;
43
+ shape?: "rounded" | "normal" | null | undefined;
44
+ weight?: "medium" | "bold" | "regular" | "semibold" | null | undefined;
45
+ loading?: boolean | null | undefined;
46
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
47
+ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
48
+ asChild?: boolean;
49
+ }
50
+ /**
51
+ * 클릭으로 동작을 실행하는 기본 버튼. 텍스트가 있는 모든 행동(생성·저장·취소·링크형 보조 행동)에 쓴다.
52
+ *
53
+ * 언제 쓰나: 화면의 주요 행동은 `primaryBold` 1개, 보조 행동은 `secondaryOutline`·`secondaryLink`, 파괴적 행동은 `danger*`. 비동기 처리 중에는 `loading` 으로 잠근다.
54
+ * 언제 안 쓰나: 아이콘만 있는 버튼(→ IconButton), 페이지 이동(→ 링크. 버튼 모양이 꼭 필요하면 `asChild` 로 `<a>` 를 감싼다), 표 안의 상태 표시(→ Badge).
55
+ * 대신/함께: 같은 줄에 주요 버튼을 두 개 두지 않는다. 폼 푸터에서는 취소(secondaryOutline) 왼쪽, 저장(primaryBold) 오른쪽.
56
+ */
57
+ declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
58
+
59
+ declare const Dialog: React.FC<DialogPrimitive.DialogProps>;
60
+ declare const DialogTrigger: React.ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
61
+ declare const DialogPortal: React.FC<DialogPrimitive.DialogPortalProps>;
62
+ declare const DialogClose: React.ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
63
+ declare const DialogOverlay: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
64
+ /**
65
+ * 모달 대화상자 본체. 짧은 입력이나 복합 상호작용을 현재 화면 위에서 처리할 때 쓴다.
66
+ *
67
+ * 언제 쓰나: 이름 바꾸기·태그 추가처럼 필드 서너 개의 입력, 미리보기·선택기처럼 맥락을 잠시 가리는 작업. `DialogTitle` 은 항상 넣는다.
68
+ * 언제 안 쓰나: 되돌릴 수 없는 행동의 최종 확인(→ AlertDialog), 섹션이 여럿인 긴 폼·상세 보기(→ Drawer), 지나가는 결과 알림(→ Toast).
69
+ * 대신/함께: 폼이면 `@t3q-ui/design-system/patterns` 의 FormDialog 가 제출 중 닫힘 차단까지 포함한다.
70
+ */
71
+ declare const DialogContent: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & VariantProps<(props?: ({
72
+ width?: "small" | "medium" | "large" | "xlarge" | null | undefined;
73
+ } & class_variance_authority_types.ClassProp) | undefined) => string> & {
74
+ overlayClassName?: string;
75
+ hideCloseButton?: boolean;
76
+ } & React.RefAttributes<HTMLDivElement>>;
77
+ declare const DialogHeader: {
78
+ (props: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
79
+ displayName: string;
80
+ };
81
+ declare const DialogFooter: {
82
+ (props: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
83
+ displayName: string;
84
+ };
85
+ declare const DialogTitle: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & {
86
+ variant?: "success" | "info" | "warning" | "danger";
87
+ } & React.RefAttributes<HTMLHeadingElement>>;
88
+ declare const DialogDescription: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
89
+
90
+ /**
91
+ * Drawer 루트. `modal`(기본 true)이 false 면 옆 패널 — 배경 dim 없음, 포커스 가두지 않음, 바깥 클릭으로 닫히지 않음(ESC·닫기 버튼).
92
+ *
93
+ * 언제 쓰나: 목록 행을 눌러 보는 상세는 `modal={false}`, 목록 위에 띄우는 긴 폼은 기본(modal).
94
+ * 언제 안 쓰나: 되돌릴 수 없는 확인(→ AlertDialog), 전용 URL 이 필요한 화면(→ 페이지).
95
+ * 대신/함께: 본체는 `DrawerContent`, 폼이면 patterns 의 FormDrawer.
96
+ */
97
+ declare const Drawer: {
98
+ ({ modal, ...props }: React.ComponentProps<typeof DialogPrimitive.Root>): react_jsx_runtime.JSX.Element;
99
+ displayName: string;
100
+ };
101
+ declare const DrawerTrigger: React.ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
102
+ declare const DrawerClose: React.ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
103
+ declare const DrawerPortal: React.FC<DialogPrimitive.DialogPortalProps>;
104
+ declare const DrawerOverlay: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
105
+ /**
106
+ * 화면 가장자리에서 미끄러져 나오는 패널 본체. 목록 맥락을 유지한 채 긴 폼·상세를 볼 때 쓴다.
107
+ *
108
+ * 언제 쓰나: 목록에서 "생성" 을 눌러 여는 섹션 여럿의 폼(side right, size large), 행을 눌러 보는 상세(루트 `Drawer` 에 `modal={false}` — 옆 패널). `DrawerTitle` 은 항상 넣는다.
109
+ * 언제 안 쓰나: 필드 서너 개의 짧은 입력(→ Dialog), 되돌릴 수 없는 확인(→ AlertDialog), 전용 URL 이 필요한 화면(→ 페이지).
110
+ * 대신/함께: 폼이면 `@t3q-ui/design-system/patterns` 의 FormDrawer 가 제출 중 닫힘 차단까지 포함한다. 본문은 `DrawerBody` 로 스크롤시킨다.
111
+ */
112
+ declare const DrawerContent: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & VariantProps<(props?: ({
113
+ side?: "bottom" | "left" | "right" | "top" | null | undefined;
114
+ size?: "small" | "medium" | "large" | "xLarge" | null | undefined;
115
+ } & class_variance_authority_types.ClassProp) | undefined) => string> & React.RefAttributes<HTMLDivElement>>;
116
+ declare const DrawerHeader: {
117
+ ({ ...props }: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
118
+ displayName: string;
119
+ };
120
+ declare const DrawerBody: {
121
+ ({ ...props }: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
122
+ displayName: string;
123
+ };
124
+ declare const DrawerFooter: {
125
+ ({ ...props }: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
126
+ displayName: string;
127
+ };
128
+ declare const DrawerTitle: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
129
+ declare const DrawerDescription: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
130
+
131
+ type PageHeaderTabItem = {
132
+ label: string;
133
+ value: string;
134
+ href?: string;
135
+ matchValues?: string[];
136
+ disabled?: boolean;
137
+ badge?: number | string;
138
+ };
139
+ type PageHeaderState = {
140
+ title?: string;
141
+ /**
142
+ * Optional override for the breadcrumb tail (last item).
143
+ * - `undefined` (default): consuming apps may fall back to `title`.
144
+ * - `null`: explicitly suppress the auto-appended breadcrumb tail.
145
+ * - `string`: use the given text as the breadcrumb tail regardless of `title`.
146
+ *
147
+ * design-system itself does not render breadcrumbs (they are passed in as the
148
+ * `breadcrumb` slot) — this field is a contract for the consuming app's
149
+ * breadcrumb wrapper to read.
150
+ */
151
+ breadcrumbTitle?: string | null;
152
+ description?: ReactNode;
153
+ status?: ReactNode;
154
+ /** 제목 아래 메타. 상세 화면의 핵심 정보는 여기 한 곳 — 여러 개면 `MetaGroup columns={3}` + `MetaItem`(2026-10-30 사용자 결정: 메타 자리를 두 개로 나누지 않는다) */
155
+ meta?: ReactNode;
156
+ actions?: ReactNode;
157
+ /** Right-aligned slot next to the title (e.g. a secondary title action). */
158
+ titleRight?: ReactNode;
159
+ bottomLeft?: ReactNode;
160
+ bottomRight?: ReactNode;
161
+ tabs?: PageHeaderTabItem[];
162
+ activeTab?: string;
163
+ };
164
+ type PageHeaderUpdate = PageHeaderState | ((prev: PageHeaderState) => PageHeaderState);
165
+ type PageHeaderContextType = {
166
+ pageHeader: PageHeaderState;
167
+ setPageHeader: (state: PageHeaderUpdate) => void;
168
+ resetPageHeader: () => void;
169
+ };
170
+ declare function PageHeaderProvider({ children }: {
171
+ children: ReactNode;
172
+ }): react_jsx_runtime.JSX.Element;
173
+ declare function usePageHeader(): PageHeaderContextType;
174
+ type PageHeaderProps = PageHeaderState & {
175
+ breadcrumb?: ReactNode;
176
+ onTabChange?: (value: string, tab: PageHeaderTabItem) => void;
177
+ fallbackTitle?: string;
178
+ compact?: boolean;
179
+ /** 내용(빵부스러기·제목·행동·설명·탭)의 최대 폭 — CSS 길이(예: `var(--max-w-page-content)`). 주면 그 폭 안에 가운데 두고 띠(배경·아래 선)는 전폭 그대로. FormPage 가 폼 폭에 맞춰 넘긴다(2026-10-26 22차). 기본 없음 = 전폭 */
180
+ contentMaxWidth?: string;
181
+ };
182
+ /**
183
+ * 페이지 최상단 헤더. 제목·설명·상태·메타·주요 행동·필터 줄·탭을 한 곳에 둔다.
184
+ *
185
+ * 언제 쓰나: 모든 목록·상세 화면의 맨 위에 한 번. 주요 행동은 `actions`(제목 줄 오른쪽 — 탭이 있어도 같고, 제목이 길어 자리가 모자라면 버튼 묶음이 제목 아래 줄 오른쪽으로 내려간다), 검색·필터는 `bottomRight`, 새로고침은 `titleRight` 에 PageHeaderRefreshButton(actions 와 같은 묶음), 페이지 이동 탭은 `tabs`(제목 아래 별도 줄). 버튼이 나란히 놓이는 슬롯(`actions`·`titleRight`·`bottomLeft`)은 버튼 사이 8px 로 그린다 — 직접 Stack 으로 감싸지 않는다.
186
+ * 언제 안 쓰나: 섹션 제목(→ `FormSection`·`CardHeader`), 모달·패널 제목(→ DialogHeader·DrawerHeader), 한 페이지에 두 번.
187
+ * 대신/함께: 레이아웃이 헤더를 소유하는 앱은 `PageHeaderProvider` + `usePageHeader` 로 내용만 밀어 넣는다. 목록 화면 전체는 ListPage 패턴이 이를 포함한다.
188
+ */
189
+ declare function PageHeader({ breadcrumb, title, fallbackTitle, description, status, meta, actions, titleRight, bottomLeft, bottomRight, tabs, activeTab, onTabChange, compact, contentMaxWidth, }: PageHeaderProps): react_jsx_runtime.JSX.Element;
190
+
191
+ type AgGridTableType = AgGridReactProps & {
192
+ containerStyle?: CSSProperties;
193
+ noRowsOverlayComponentContainerStyle?: CSSProperties;
194
+ };
195
+ /**
196
+ * ag-grid 기반 데이터 표. 목록 화면의 본 표에 쓴다.
197
+ *
198
+ * 언제 쓰나: 서버 페이징 목록, 정렬·컬럼 숨김·행 선택·셀 렌더러가 필요한 표. `loading` 이면 TableSkeleton, 0건이면 `noRowsOverlayComponent`. 주 식별자 열(보통 이름)에는 `type: 'primary'` 를 주면 굵게 강조되고 클릭 가능한 행에서 hover 시 밑줄이 생긴다. `sortable: true` 로 명시한 열은 정렬 전에도 정렬 아이콘이 보인다(그 열에 `unSortIcon: false` 를 주면 끔. 2026-10-16 다시 켬 — 원문 심판이 "정렬 가능 표시 없음" 을 반복 감점). 숫자 열(건수·크기·비율·시간)은 `type: 'number'` — 오른쪽 정렬·숫자 폭이고, width·flex 를 안 주면 폭 140(ag-grid 기본 200 은 비어 보인다). 숫자 열에 `flex` 를 주지 않는다.
199
+ * 언제 안 쓰나: 수십 행 이하의 단순 나열(→ Table), 키-값 표(→ MetaItem), 편집 가능한 파라미터 표(→ ParameterTable).
200
+ * 대신/함께: 목록 화면 전체 골격은 `@t3q-ui/design-system/patterns` 의 ListPage 가 이 표를 포함한다. 정렬 값은 `getSortedColumnState` 로 읽는다. `onRowClicked` 를 주면 포커스된 셀에서 Enter 로도 호출된다(키보드 상세 진입). 열 제목이 들어가는 최소 폭은 표가 보정하고(`width: 110` 같은 좁은 폭을 줘도 "크기(M…" 로 잘리지 않음) 넘치는 셀 글자는 말줄임표로 끝난다. 보조 정보(id·이미지·경로·설명)는 열을 늘리지 말고 `TwoLineCellRenderer`(`cellRendererParams.secondaryField`)로 이름 아래 줄에 — ListPage 는 `secondaryField` 한 줄로 된다. 이름 열만 `flex: 1, minWidth: 200`(남는 폭을 가진다 — maxWidth 를 주면 표 오른쪽이 빈다), 숫자·날짜 열은 `width` 로.
201
+ */
202
+ declare const AgGridTable: React.ForwardRefExoticComponent<AgGridReactProps<any> & {
203
+ containerStyle?: CSSProperties;
204
+ noRowsOverlayComponentContainerStyle?: CSSProperties;
205
+ } & React.RefAttributes<AgGridReact<any>>>;
206
+ declare function HeaderCheckboxRenderer(props: IHeaderParams): react_jsx_runtime.JSX.Element;
207
+ declare function RowCheckboxRenderer(params: ICellRendererParams): react_jsx_runtime.JSX.Element;
208
+
209
+ /** `sortable: true` 로 명시한 열(그룹 안의 열 포함)에 `unSortIcon: true` 를 붙인다. 열이 직접 unSortIcon 을 정했으면 그대로 */
210
+ declare function withExplicitSortIcons<T>(defs: T): T;
211
+ /** 정렬 아이콘이 늘 보이는 숫자 열의 값 셀에 붙는 클래스 — style.css 가 오른쪽 여백을 아이콘 폭(16 + 간격 8)만큼 늘린다 */
212
+ declare const SORT_ICON_OFFSET_CLASS = "ag-cell-sort-offset";
213
+ /**
214
+ * 정렬 아이콘이 늘 보이는 숫자 열(`type` 에 number + `sortable: true` + `unSortIcon: true` — `withExplicitSortIcons` 다음에 부른다)의 값 셀에
215
+ * `SORT_ICON_OFFSET_CLASS` 를 합친다(그룹 children 재귀). 숫자 열 제목은 아이콘이 글자 뒤라 글자가 값보다 아이콘 폭만큼 왼쪽에서 끝났다 —
216
+ * 값을 그만큼 안쪽으로 들여 글자 끝과 값 끝을 맞춘다(2026-10-30 홀드아웃 17 세트 2, Gemini "right-aligned numeric values under left-aligned
217
+ * column headers" 2쌍). 아이콘 위치(글자 뒤, 2026-10-16 4차)는 그대로. 정렬 전엔 아이콘이 없는 열(`defaultColDef` 로만 정렬 가능)·함수형 cellClass 는 그대로
218
+ */
219
+ declare function withSortIconOffset<T>(defs: T): T;
220
+ /** 열 제목 글자 폭 추정(px) — 헤더 14px/700 기준: 한글·한자·전각 14, 그 외(영문·숫자·기호) 8. "제목이 잘리지 않을 만큼" 이면 되고 정확할 필요는 없다 */
221
+ declare function estimateHeaderTextWidth(label: string): number;
222
+ /** 보이는 flex 열이 모두 `maxWidth` 를 가지면 그 `maxWidth` 를 뗀다(그룹 children 재귀) — 남는 폭을 받을 열이 없으면 행이 표 오른쪽 끝 전에
223
+ * 끝나 빈 띠가 남는다(2026-10-28 홀드아웃 14: 이름 열 하나만 `flex: 2, maxWidth: 480` 이고 나머지가 고정 폭, "row dividers stop around 1330px",
224
+ * Opus·Gemini). 상한 없는 flex 열이 하나라도 있거나 flex 열이 없으면 그대로(같은 배열). 런타임에 열을 숨겨 생기는 경우는 다루지 않는다 */
225
+ declare function withFlexFill<T>(defs: T): T;
226
+ /** 폭을 안 준 number 열의 기본 폭. ag-grid 기본 200 은 숫자 열을 비어 보이게 한다(2026-10-27 홀드아웃 13 layout 지적 "wide empty area") */
227
+ declare const NUMBER_COLUMN_WIDTH = 140;
228
+ /** `type: 'number'` 열에 width·flex·minWidth·maxWidth 가 모두 없으면 `width: 140`(그룹 children 재귀). 폭을 하나라도 줬으면 그대로 */
229
+ declare function withNumberColumnWidth<T>(defs: T): T;
230
+ /** `type` 이 가리키는 columnTypes 의 cellClass/headerClass 를 열이 직접 준 값과 합친다(그룹 children 재귀). ag-grid 는 열의 값이
231
+ * 타입의 값을 통째로 덮으므로, 열이 `cellClass: 'font-semibold'` 를 더하기만 해도 number 의 `ag-right-aligned-cell` 이 사라진다 — 그걸 막는다 */
232
+ declare function withTypeClasses<T>(defs: T, columnTypes: Record<string, {
233
+ cellClass?: unknown;
234
+ headerClass?: unknown;
235
+ }>): T;
236
+ declare function withHeaderMinWidth<T>(defs: T): T;
237
+ interface TwoLineCellRendererParams<TRow = unknown> extends ICellRendererParams<TRow> {
238
+ /** 보조 줄에 보일 행 필드(점 표기 가능: 'image.tag'). 값이 없거나 빈 문자열이면 한 줄만 그린다 */
239
+ secondaryField?: string;
240
+ /** 보조 줄에 덧붙일 클래스 — id·경로·버전처럼 고정폭이 읽기 좋은 값은 'font-mono' */
241
+ secondaryClassName?: string;
242
+ }
243
+ /**
244
+ * 두 줄 셀 — 첫 줄은 열의 값(이름), 둘째 줄은 `cellRendererParams.secondaryField` 의 값(id·이미지·경로·설명)을 12px 회색으로.
245
+ * dl-ui-v3 목록의 이름 열(이름 / 설명, 행 56px)과 같은 모양.
246
+ *
247
+ * 언제 쓰나: 주 식별자 열 아래에 보조 정보를 둘 때 — 열을 하나 더 늘리는 대신(열이 많아지면 잘린다. 한 줄 판 12차, 2026-10-18 13차 ⑥). `ListPage secondaryField` 가 이 렌더러를 primary 열에 붙인다.
248
+ * 쓰는 법: `{ field: 'name', cellRenderer: TwoLineCellRenderer, cellRendererParams: { secondaryField: 'image' } }` + 표에 `rowHeight={56}`(ListPage 는 자동).
249
+ * 언제 안 쓰나: 보조 값이 정렬·필터 대상이면 제 열로 둔다. 상태는 Badge(아이콘 + 글자) 셀 렌더러.
250
+ */
251
+ declare function TwoLineCellRenderer<TRow = unknown>(params: TwoLineCellRendererParams<TRow>): react_jsx_runtime.JSX.Element;
252
+
253
+ export { DrawerDescription as A, type BadgeProps as B, type PageHeaderState as C, Dialog as D, PageHeaderProvider as E, usePageHeader as F, type PageHeaderProps as G, PageHeader as H, AgGridTable as I, HeaderCheckboxRenderer as J, type AgGridTableType as K, withExplicitSortIcons as L, withSortIconOffset as M, estimateHeaderTextWidth as N, withFlexFill as O, type PageHeaderTabItem as P, NUMBER_COLUMN_WIDTH as Q, RowCheckboxRenderer as R, SORT_ICON_OFFSET_CLASS as S, withNumberColumnWidth as T, withTypeClasses as U, withHeaderMinWidth as V, type TwoLineCellRendererParams as W, TwoLineCellRenderer as X, Badge as a, badgeVariants as b, type BadgeTone as c, BADGE_OUTLINE_ACCENT as d, Button as e, buttonVariants as f, type ButtonProps as g, DialogPortal as h, DialogOverlay as i, DialogTrigger as j, DialogClose as k, DialogContent as l, DialogHeader as m, DialogFooter as n, DialogTitle as o, DialogDescription as p, Drawer as q, DrawerPortal as r, DrawerOverlay as s, DrawerTrigger as t, DrawerClose as u, DrawerContent as v, DrawerHeader as w, DrawerBody as x, DrawerFooter as y, DrawerTitle as z };
@@ -0,0 +1,253 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ declare namespace class_variance_authority_types {
3
+ type ClassValue = import('clsx').ClassValue;
4
+ type ClassProp = { class: ClassValue; className?: never } | { class?: never; className: ClassValue } | { class?: never; className?: never };
5
+ }
6
+ import * as React from 'react';
7
+ import { ReactNode, CSSProperties } from 'react';
8
+ import { VariantProps } from 'class-variance-authority';
9
+ import * as DialogPrimitive from '@radix-ui/react-dialog';
10
+ import { IHeaderParams, ICellRendererParams } from 'ag-grid-community';
11
+ import { AgGridReactProps, AgGridReact } from 'ag-grid-react';
12
+
13
+ type BadgeTone = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'etc';
14
+ /**
15
+ * outline 뱃지의 accent(테두리) 색. 기본은 {hue}30 — 흰 바탕 대비 primary 4.7 · danger 5.9 · success 4.6 · etc 5.8.
16
+ * yellow30(1.75:1)·cyan30(1.59:1)은 흰 바탕에서 선이 안 보여 warning·info 는 40(5.4·5.5), grayscale30 도 연해 secondary 는 50(3.7)
17
+ * — bold 변형이 warning·info 글자만 예외로 두는 것과 같은 "밝은 색 예외" 규칙 (2026-10-17 이슈 47 6차)
18
+ */
19
+ declare const BADGE_OUTLINE_ACCENT: Record<BadgeTone, {
20
+ border: string;
21
+ icon: string;
22
+ }>;
23
+ declare const badgeVariants: (props?: ({
24
+ size?: "small" | "medium" | null | undefined;
25
+ variant?: "primary" | "info" | "success" | "warning" | "danger" | "primaryBold" | "secondary" | "secondaryBold" | "dangerBold" | "warningBold" | "infoBold" | "etc" | "successBold" | "etcBold" | null | undefined;
26
+ rounded?: "full" | "default" | null | undefined;
27
+ appearance?: "tint" | "outline" | null | undefined;
28
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
29
+ interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
30
+ }
31
+ /**
32
+ * 상태·분류를 색으로 보여 주는 읽기 전용 표시. 표의 상태 열, 제목 옆 상태에 쓴다.
33
+ *
34
+ * 언제 쓰나: 실행 중/중지/오류 같은 상태(`success`·`danger`·`warning`·`info`), 개수·등급 표시. 의미 variant 를 쓰고 색을 직접 바꾸지 않는다. `appearance='outline'` 은 흰 바탕 + 1px accent 테두리.
35
+ * 언제 안 쓰나: 사용자가 붙이고 뗄 수 있는 라벨(→ Tag), 클릭해 동작하는 것(→ Button), 지나가는 알림(→ Toast).
36
+ * 대신/함께: **상태 표시는 Badge 에 아이콘 + 글자** — `<Badge variant='success'><LucideIcon iconComponentName='circle-check' />완료</Badge>`(아이콘은 자식으로 바로, 16px·글자색). 별도 상태 컴포넌트는 없다(2026-10-30). 크기는 기본(`size` 를 주지 않는다). 상태값 → variant·아이콘 매핑은 소비 앱의 상수 한 곳에 둔다.
37
+ */
38
+ declare function Badge({ className, variant, rounded, appearance, size, children, ...props }: BadgeProps): react_jsx_runtime.JSX.Element;
39
+
40
+ declare const buttonVariants: (props?: ({
41
+ variant?: "primary" | "warning" | "danger" | "primaryBold" | "secondary" | "secondaryBold" | "dangerBold" | "warningBold" | "primaryLink" | "dangerLink" | "secondaryLink" | "warningLink" | "primaryOutline" | "secondaryOutline" | "dangerOutline" | "warningOutline" | null | undefined;
42
+ spacing?: "normal" | "compact" | null | undefined;
43
+ shape?: "rounded" | "normal" | null | undefined;
44
+ weight?: "medium" | "bold" | "regular" | "semibold" | null | undefined;
45
+ loading?: boolean | null | undefined;
46
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
47
+ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
48
+ asChild?: boolean;
49
+ }
50
+ /**
51
+ * 클릭으로 동작을 실행하는 기본 버튼. 텍스트가 있는 모든 행동(생성·저장·취소·링크형 보조 행동)에 쓴다.
52
+ *
53
+ * 언제 쓰나: 화면의 주요 행동은 `primaryBold` 1개, 보조 행동은 `secondaryOutline`·`secondaryLink`, 파괴적 행동은 `danger*`. 비동기 처리 중에는 `loading` 으로 잠근다.
54
+ * 언제 안 쓰나: 아이콘만 있는 버튼(→ IconButton), 페이지 이동(→ 링크. 버튼 모양이 꼭 필요하면 `asChild` 로 `<a>` 를 감싼다), 표 안의 상태 표시(→ Badge).
55
+ * 대신/함께: 같은 줄에 주요 버튼을 두 개 두지 않는다. 폼 푸터에서는 취소(secondaryOutline) 왼쪽, 저장(primaryBold) 오른쪽.
56
+ */
57
+ declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
58
+
59
+ declare const Dialog: React.FC<DialogPrimitive.DialogProps>;
60
+ declare const DialogTrigger: React.ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
61
+ declare const DialogPortal: React.FC<DialogPrimitive.DialogPortalProps>;
62
+ declare const DialogClose: React.ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
63
+ declare const DialogOverlay: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
64
+ /**
65
+ * 모달 대화상자 본체. 짧은 입력이나 복합 상호작용을 현재 화면 위에서 처리할 때 쓴다.
66
+ *
67
+ * 언제 쓰나: 이름 바꾸기·태그 추가처럼 필드 서너 개의 입력, 미리보기·선택기처럼 맥락을 잠시 가리는 작업. `DialogTitle` 은 항상 넣는다.
68
+ * 언제 안 쓰나: 되돌릴 수 없는 행동의 최종 확인(→ AlertDialog), 섹션이 여럿인 긴 폼·상세 보기(→ Drawer), 지나가는 결과 알림(→ Toast).
69
+ * 대신/함께: 폼이면 `@t3q-ui/design-system/patterns` 의 FormDialog 가 제출 중 닫힘 차단까지 포함한다.
70
+ */
71
+ declare const DialogContent: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & VariantProps<(props?: ({
72
+ width?: "small" | "medium" | "large" | "xlarge" | null | undefined;
73
+ } & class_variance_authority_types.ClassProp) | undefined) => string> & {
74
+ overlayClassName?: string;
75
+ hideCloseButton?: boolean;
76
+ } & React.RefAttributes<HTMLDivElement>>;
77
+ declare const DialogHeader: {
78
+ (props: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
79
+ displayName: string;
80
+ };
81
+ declare const DialogFooter: {
82
+ (props: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
83
+ displayName: string;
84
+ };
85
+ declare const DialogTitle: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & {
86
+ variant?: "success" | "info" | "warning" | "danger";
87
+ } & React.RefAttributes<HTMLHeadingElement>>;
88
+ declare const DialogDescription: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
89
+
90
+ /**
91
+ * Drawer 루트. `modal`(기본 true)이 false 면 옆 패널 — 배경 dim 없음, 포커스 가두지 않음, 바깥 클릭으로 닫히지 않음(ESC·닫기 버튼).
92
+ *
93
+ * 언제 쓰나: 목록 행을 눌러 보는 상세는 `modal={false}`, 목록 위에 띄우는 긴 폼은 기본(modal).
94
+ * 언제 안 쓰나: 되돌릴 수 없는 확인(→ AlertDialog), 전용 URL 이 필요한 화면(→ 페이지).
95
+ * 대신/함께: 본체는 `DrawerContent`, 폼이면 patterns 의 FormDrawer.
96
+ */
97
+ declare const Drawer: {
98
+ ({ modal, ...props }: React.ComponentProps<typeof DialogPrimitive.Root>): react_jsx_runtime.JSX.Element;
99
+ displayName: string;
100
+ };
101
+ declare const DrawerTrigger: React.ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
102
+ declare const DrawerClose: React.ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
103
+ declare const DrawerPortal: React.FC<DialogPrimitive.DialogPortalProps>;
104
+ declare const DrawerOverlay: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
105
+ /**
106
+ * 화면 가장자리에서 미끄러져 나오는 패널 본체. 목록 맥락을 유지한 채 긴 폼·상세를 볼 때 쓴다.
107
+ *
108
+ * 언제 쓰나: 목록에서 "생성" 을 눌러 여는 섹션 여럿의 폼(side right, size large), 행을 눌러 보는 상세(루트 `Drawer` 에 `modal={false}` — 옆 패널). `DrawerTitle` 은 항상 넣는다.
109
+ * 언제 안 쓰나: 필드 서너 개의 짧은 입력(→ Dialog), 되돌릴 수 없는 확인(→ AlertDialog), 전용 URL 이 필요한 화면(→ 페이지).
110
+ * 대신/함께: 폼이면 `@t3q-ui/design-system/patterns` 의 FormDrawer 가 제출 중 닫힘 차단까지 포함한다. 본문은 `DrawerBody` 로 스크롤시킨다.
111
+ */
112
+ declare const DrawerContent: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & VariantProps<(props?: ({
113
+ side?: "bottom" | "left" | "right" | "top" | null | undefined;
114
+ size?: "small" | "medium" | "large" | "xLarge" | null | undefined;
115
+ } & class_variance_authority_types.ClassProp) | undefined) => string> & React.RefAttributes<HTMLDivElement>>;
116
+ declare const DrawerHeader: {
117
+ ({ ...props }: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
118
+ displayName: string;
119
+ };
120
+ declare const DrawerBody: {
121
+ ({ ...props }: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
122
+ displayName: string;
123
+ };
124
+ declare const DrawerFooter: {
125
+ ({ ...props }: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
126
+ displayName: string;
127
+ };
128
+ declare const DrawerTitle: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
129
+ declare const DrawerDescription: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
130
+
131
+ type PageHeaderTabItem = {
132
+ label: string;
133
+ value: string;
134
+ href?: string;
135
+ matchValues?: string[];
136
+ disabled?: boolean;
137
+ badge?: number | string;
138
+ };
139
+ type PageHeaderState = {
140
+ title?: string;
141
+ /**
142
+ * Optional override for the breadcrumb tail (last item).
143
+ * - `undefined` (default): consuming apps may fall back to `title`.
144
+ * - `null`: explicitly suppress the auto-appended breadcrumb tail.
145
+ * - `string`: use the given text as the breadcrumb tail regardless of `title`.
146
+ *
147
+ * design-system itself does not render breadcrumbs (they are passed in as the
148
+ * `breadcrumb` slot) — this field is a contract for the consuming app's
149
+ * breadcrumb wrapper to read.
150
+ */
151
+ breadcrumbTitle?: string | null;
152
+ description?: ReactNode;
153
+ status?: ReactNode;
154
+ /** 제목 아래 메타. 상세 화면의 핵심 정보는 여기 한 곳 — 여러 개면 `MetaGroup columns={3}` + `MetaItem`(2026-10-30 사용자 결정: 메타 자리를 두 개로 나누지 않는다) */
155
+ meta?: ReactNode;
156
+ actions?: ReactNode;
157
+ /** Right-aligned slot next to the title (e.g. a secondary title action). */
158
+ titleRight?: ReactNode;
159
+ bottomLeft?: ReactNode;
160
+ bottomRight?: ReactNode;
161
+ tabs?: PageHeaderTabItem[];
162
+ activeTab?: string;
163
+ };
164
+ type PageHeaderUpdate = PageHeaderState | ((prev: PageHeaderState) => PageHeaderState);
165
+ type PageHeaderContextType = {
166
+ pageHeader: PageHeaderState;
167
+ setPageHeader: (state: PageHeaderUpdate) => void;
168
+ resetPageHeader: () => void;
169
+ };
170
+ declare function PageHeaderProvider({ children }: {
171
+ children: ReactNode;
172
+ }): react_jsx_runtime.JSX.Element;
173
+ declare function usePageHeader(): PageHeaderContextType;
174
+ type PageHeaderProps = PageHeaderState & {
175
+ breadcrumb?: ReactNode;
176
+ onTabChange?: (value: string, tab: PageHeaderTabItem) => void;
177
+ fallbackTitle?: string;
178
+ compact?: boolean;
179
+ /** 내용(빵부스러기·제목·행동·설명·탭)의 최대 폭 — CSS 길이(예: `var(--max-w-page-content)`). 주면 그 폭 안에 가운데 두고 띠(배경·아래 선)는 전폭 그대로. FormPage 가 폼 폭에 맞춰 넘긴다(2026-10-26 22차). 기본 없음 = 전폭 */
180
+ contentMaxWidth?: string;
181
+ };
182
+ /**
183
+ * 페이지 최상단 헤더. 제목·설명·상태·메타·주요 행동·필터 줄·탭을 한 곳에 둔다.
184
+ *
185
+ * 언제 쓰나: 모든 목록·상세 화면의 맨 위에 한 번. 주요 행동은 `actions`(제목 줄 오른쪽 — 탭이 있어도 같고, 제목이 길어 자리가 모자라면 버튼 묶음이 제목 아래 줄 오른쪽으로 내려간다), 검색·필터는 `bottomRight`, 새로고침은 `titleRight` 에 PageHeaderRefreshButton(actions 와 같은 묶음), 페이지 이동 탭은 `tabs`(제목 아래 별도 줄). 버튼이 나란히 놓이는 슬롯(`actions`·`titleRight`·`bottomLeft`)은 버튼 사이 8px 로 그린다 — 직접 Stack 으로 감싸지 않는다.
186
+ * 언제 안 쓰나: 섹션 제목(→ `FormSection`·`CardHeader`), 모달·패널 제목(→ DialogHeader·DrawerHeader), 한 페이지에 두 번.
187
+ * 대신/함께: 레이아웃이 헤더를 소유하는 앱은 `PageHeaderProvider` + `usePageHeader` 로 내용만 밀어 넣는다. 목록 화면 전체는 ListPage 패턴이 이를 포함한다.
188
+ */
189
+ declare function PageHeader({ breadcrumb, title, fallbackTitle, description, status, meta, actions, titleRight, bottomLeft, bottomRight, tabs, activeTab, onTabChange, compact, contentMaxWidth, }: PageHeaderProps): react_jsx_runtime.JSX.Element;
190
+
191
+ type AgGridTableType = AgGridReactProps & {
192
+ containerStyle?: CSSProperties;
193
+ noRowsOverlayComponentContainerStyle?: CSSProperties;
194
+ };
195
+ /**
196
+ * ag-grid 기반 데이터 표. 목록 화면의 본 표에 쓴다.
197
+ *
198
+ * 언제 쓰나: 서버 페이징 목록, 정렬·컬럼 숨김·행 선택·셀 렌더러가 필요한 표. `loading` 이면 TableSkeleton, 0건이면 `noRowsOverlayComponent`. 주 식별자 열(보통 이름)에는 `type: 'primary'` 를 주면 굵게 강조되고 클릭 가능한 행에서 hover 시 밑줄이 생긴다. `sortable: true` 로 명시한 열은 정렬 전에도 정렬 아이콘이 보인다(그 열에 `unSortIcon: false` 를 주면 끔. 2026-10-16 다시 켬 — 원문 심판이 "정렬 가능 표시 없음" 을 반복 감점). 숫자 열(건수·크기·비율·시간)은 `type: 'number'` — 오른쪽 정렬·숫자 폭이고, width·flex 를 안 주면 폭 140(ag-grid 기본 200 은 비어 보인다). 숫자 열에 `flex` 를 주지 않는다.
199
+ * 언제 안 쓰나: 수십 행 이하의 단순 나열(→ Table), 키-값 표(→ MetaItem), 편집 가능한 파라미터 표(→ ParameterTable).
200
+ * 대신/함께: 목록 화면 전체 골격은 `@t3q-ui/design-system/patterns` 의 ListPage 가 이 표를 포함한다. 정렬 값은 `getSortedColumnState` 로 읽는다. `onRowClicked` 를 주면 포커스된 셀에서 Enter 로도 호출된다(키보드 상세 진입). 열 제목이 들어가는 최소 폭은 표가 보정하고(`width: 110` 같은 좁은 폭을 줘도 "크기(M…" 로 잘리지 않음) 넘치는 셀 글자는 말줄임표로 끝난다. 보조 정보(id·이미지·경로·설명)는 열을 늘리지 말고 `TwoLineCellRenderer`(`cellRendererParams.secondaryField`)로 이름 아래 줄에 — ListPage 는 `secondaryField` 한 줄로 된다. 이름 열만 `flex: 1, minWidth: 200`(남는 폭을 가진다 — maxWidth 를 주면 표 오른쪽이 빈다), 숫자·날짜 열은 `width` 로.
201
+ */
202
+ declare const AgGridTable: React.ForwardRefExoticComponent<AgGridReactProps<any> & {
203
+ containerStyle?: CSSProperties;
204
+ noRowsOverlayComponentContainerStyle?: CSSProperties;
205
+ } & React.RefAttributes<AgGridReact<any>>>;
206
+ declare function HeaderCheckboxRenderer(props: IHeaderParams): react_jsx_runtime.JSX.Element;
207
+ declare function RowCheckboxRenderer(params: ICellRendererParams): react_jsx_runtime.JSX.Element;
208
+
209
+ /** `sortable: true` 로 명시한 열(그룹 안의 열 포함)에 `unSortIcon: true` 를 붙인다. 열이 직접 unSortIcon 을 정했으면 그대로 */
210
+ declare function withExplicitSortIcons<T>(defs: T): T;
211
+ /** 정렬 아이콘이 늘 보이는 숫자 열의 값 셀에 붙는 클래스 — style.css 가 오른쪽 여백을 아이콘 폭(16 + 간격 8)만큼 늘린다 */
212
+ declare const SORT_ICON_OFFSET_CLASS = "ag-cell-sort-offset";
213
+ /**
214
+ * 정렬 아이콘이 늘 보이는 숫자 열(`type` 에 number + `sortable: true` + `unSortIcon: true` — `withExplicitSortIcons` 다음에 부른다)의 값 셀에
215
+ * `SORT_ICON_OFFSET_CLASS` 를 합친다(그룹 children 재귀). 숫자 열 제목은 아이콘이 글자 뒤라 글자가 값보다 아이콘 폭만큼 왼쪽에서 끝났다 —
216
+ * 값을 그만큼 안쪽으로 들여 글자 끝과 값 끝을 맞춘다(2026-10-30 홀드아웃 17 세트 2, Gemini "right-aligned numeric values under left-aligned
217
+ * column headers" 2쌍). 아이콘 위치(글자 뒤, 2026-10-16 4차)는 그대로. 정렬 전엔 아이콘이 없는 열(`defaultColDef` 로만 정렬 가능)·함수형 cellClass 는 그대로
218
+ */
219
+ declare function withSortIconOffset<T>(defs: T): T;
220
+ /** 열 제목 글자 폭 추정(px) — 헤더 14px/700 기준: 한글·한자·전각 14, 그 외(영문·숫자·기호) 8. "제목이 잘리지 않을 만큼" 이면 되고 정확할 필요는 없다 */
221
+ declare function estimateHeaderTextWidth(label: string): number;
222
+ /** 보이는 flex 열이 모두 `maxWidth` 를 가지면 그 `maxWidth` 를 뗀다(그룹 children 재귀) — 남는 폭을 받을 열이 없으면 행이 표 오른쪽 끝 전에
223
+ * 끝나 빈 띠가 남는다(2026-10-28 홀드아웃 14: 이름 열 하나만 `flex: 2, maxWidth: 480` 이고 나머지가 고정 폭, "row dividers stop around 1330px",
224
+ * Opus·Gemini). 상한 없는 flex 열이 하나라도 있거나 flex 열이 없으면 그대로(같은 배열). 런타임에 열을 숨겨 생기는 경우는 다루지 않는다 */
225
+ declare function withFlexFill<T>(defs: T): T;
226
+ /** 폭을 안 준 number 열의 기본 폭. ag-grid 기본 200 은 숫자 열을 비어 보이게 한다(2026-10-27 홀드아웃 13 layout 지적 "wide empty area") */
227
+ declare const NUMBER_COLUMN_WIDTH = 140;
228
+ /** `type: 'number'` 열에 width·flex·minWidth·maxWidth 가 모두 없으면 `width: 140`(그룹 children 재귀). 폭을 하나라도 줬으면 그대로 */
229
+ declare function withNumberColumnWidth<T>(defs: T): T;
230
+ /** `type` 이 가리키는 columnTypes 의 cellClass/headerClass 를 열이 직접 준 값과 합친다(그룹 children 재귀). ag-grid 는 열의 값이
231
+ * 타입의 값을 통째로 덮으므로, 열이 `cellClass: 'font-semibold'` 를 더하기만 해도 number 의 `ag-right-aligned-cell` 이 사라진다 — 그걸 막는다 */
232
+ declare function withTypeClasses<T>(defs: T, columnTypes: Record<string, {
233
+ cellClass?: unknown;
234
+ headerClass?: unknown;
235
+ }>): T;
236
+ declare function withHeaderMinWidth<T>(defs: T): T;
237
+ interface TwoLineCellRendererParams<TRow = unknown> extends ICellRendererParams<TRow> {
238
+ /** 보조 줄에 보일 행 필드(점 표기 가능: 'image.tag'). 값이 없거나 빈 문자열이면 한 줄만 그린다 */
239
+ secondaryField?: string;
240
+ /** 보조 줄에 덧붙일 클래스 — id·경로·버전처럼 고정폭이 읽기 좋은 값은 'font-mono' */
241
+ secondaryClassName?: string;
242
+ }
243
+ /**
244
+ * 두 줄 셀 — 첫 줄은 열의 값(이름), 둘째 줄은 `cellRendererParams.secondaryField` 의 값(id·이미지·경로·설명)을 12px 회색으로.
245
+ * dl-ui-v3 목록의 이름 열(이름 / 설명, 행 56px)과 같은 모양.
246
+ *
247
+ * 언제 쓰나: 주 식별자 열 아래에 보조 정보를 둘 때 — 열을 하나 더 늘리는 대신(열이 많아지면 잘린다. 한 줄 판 12차, 2026-10-18 13차 ⑥). `ListPage secondaryField` 가 이 렌더러를 primary 열에 붙인다.
248
+ * 쓰는 법: `{ field: 'name', cellRenderer: TwoLineCellRenderer, cellRendererParams: { secondaryField: 'image' } }` + 표에 `rowHeight={56}`(ListPage 는 자동).
249
+ * 언제 안 쓰나: 보조 값이 정렬·필터 대상이면 제 열로 둔다. 상태는 Badge(아이콘 + 글자) 셀 렌더러.
250
+ */
251
+ declare function TwoLineCellRenderer<TRow = unknown>(params: TwoLineCellRendererParams<TRow>): react_jsx_runtime.JSX.Element;
252
+
253
+ export { DrawerDescription as A, type BadgeProps as B, type PageHeaderState as C, Dialog as D, PageHeaderProvider as E, usePageHeader as F, type PageHeaderProps as G, PageHeader as H, AgGridTable as I, HeaderCheckboxRenderer as J, type AgGridTableType as K, withExplicitSortIcons as L, withSortIconOffset as M, estimateHeaderTextWidth as N, withFlexFill as O, type PageHeaderTabItem as P, NUMBER_COLUMN_WIDTH as Q, RowCheckboxRenderer as R, SORT_ICON_OFFSET_CLASS as S, withNumberColumnWidth as T, withTypeClasses as U, withHeaderMinWidth as V, type TwoLineCellRendererParams as W, TwoLineCellRenderer as X, Badge as a, badgeVariants as b, type BadgeTone as c, BADGE_OUTLINE_ACCENT as d, Button as e, buttonVariants as f, type ButtonProps as g, DialogPortal as h, DialogOverlay as i, DialogTrigger as j, DialogClose as k, DialogContent as l, DialogHeader as m, DialogFooter as n, DialogTitle as o, DialogDescription as p, Drawer as q, DrawerPortal as r, DrawerOverlay as s, DrawerTrigger as t, DrawerClose as u, DrawerContent as v, DrawerHeader as w, DrawerBody as x, DrawerFooter as y, DrawerTitle as z };