@t3q-ui/design-system 1.56.1 → 1.58.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/CHANGELOG.md +16 -0
- package/dist/{chunk-MHAO45AL.cjs → chunk-IYDQLTRF.cjs} +6 -5
- package/dist/chunk-IYDQLTRF.cjs.map +1 -0
- package/dist/{chunk-IPF3K4BS.js → chunk-UNNNNYKG.js} +6 -5
- package/dist/chunk-UNNNNYKG.js.map +1 -0
- package/dist/{index-Ci1Wh5sA.d.cts → index-3laRfJM7.d.cts} +3 -2
- package/dist/{index-Ci1Wh5sA.d.ts → index-3laRfJM7.d.ts} +3 -2
- package/dist/index.cjs +462 -474
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -14
- package/dist/index.d.ts +11 -14
- package/dist/index.js +8 -20
- package/dist/index.js.map +1 -1
- package/dist/patterns/index.cjs +69 -69
- package/dist/patterns/index.cjs.map +1 -1
- package/dist/patterns/index.d.cts +2 -2
- package/dist/patterns/index.d.ts +2 -2
- package/dist/patterns/index.js +1 -1
- package/dist/patterns/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/tds/SKILL.md +10 -9
- package/skills/tds/examples/detail-page.tsx +15 -15
- package/skills/tds/examples/list-page.tsx +3 -2
- package/skills/tds/reference/components.md +6 -5
- package/dist/chunk-IPF3K4BS.js.map +0 -1
- package/dist/chunk-MHAO45AL.cjs.map +0 -1
package/dist/patterns/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkIYDQLTRF_cjs = require('../chunk-IYDQLTRF.cjs');
|
|
4
4
|
var react = require('react');
|
|
5
5
|
var lucideReact = require('lucide-react');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -21,7 +21,7 @@ function withSecondaryLine(columns, primaryField, secondaryField) {
|
|
|
21
21
|
return columns.map(
|
|
22
22
|
(c) => c.field === primaryField && c.cellRenderer == null ? {
|
|
23
23
|
...c,
|
|
24
|
-
cellRenderer:
|
|
24
|
+
cellRenderer: chunkIYDQLTRF_cjs.TwoLineCellRenderer,
|
|
25
25
|
cellRendererParams: { ...c.cellRendererParams, secondaryField }
|
|
26
26
|
} : c
|
|
27
27
|
);
|
|
@@ -47,10 +47,10 @@ function LoadingState({ className, lines = 3 }) {
|
|
|
47
47
|
{
|
|
48
48
|
role: "status",
|
|
49
49
|
"aria-label": "\uBD88\uB7EC\uC624\uB294 \uC911",
|
|
50
|
-
className:
|
|
50
|
+
className: chunkIYDQLTRF_cjs.cn("flex flex-col gap-[12px]", className),
|
|
51
51
|
children: [
|
|
52
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
53
|
-
Array.from({ length: lines }, (_, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
52
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.Skeleton, { className: "h-[24px] w-[240px]" }),
|
|
53
|
+
Array.from({ length: lines }, (_, i) => /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.Skeleton, { className: chunkIYDQLTRF_cjs.cn("h-[16px]", i % 2 ? "w-3/5" : "w-full") }, i))
|
|
54
54
|
]
|
|
55
55
|
}
|
|
56
56
|
);
|
|
@@ -68,12 +68,12 @@ function StateBox({
|
|
|
68
68
|
"div",
|
|
69
69
|
{
|
|
70
70
|
role,
|
|
71
|
-
className:
|
|
71
|
+
className: chunkIYDQLTRF_cjs.cn(
|
|
72
72
|
"flex flex-col items-center justify-center gap-[4px] text-center text-sys-text-subtler",
|
|
73
73
|
className
|
|
74
74
|
),
|
|
75
75
|
children: [
|
|
76
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className:
|
|
76
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: chunkIYDQLTRF_cjs.cn("mb-[4px] flex text-sys-text-subtler", iconClassName), children: icon }),
|
|
77
77
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-h5 text-sys-text-main", children: title }),
|
|
78
78
|
description ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "break-keep text-base-regular text-sys-text-subtle wrap-break-word", children: description }) : null,
|
|
79
79
|
action ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-auto mt-[12px] flex gap-[8px]", children: action }) : null
|
|
@@ -94,7 +94,7 @@ function EmptyState({
|
|
|
94
94
|
{
|
|
95
95
|
role: "status",
|
|
96
96
|
className,
|
|
97
|
-
icon: icon ?? /* @__PURE__ */ jsxRuntime.jsx(
|
|
97
|
+
icon: icon ?? /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.EmptyBoxIllustration, {}),
|
|
98
98
|
title: title ?? children,
|
|
99
99
|
description,
|
|
100
100
|
action
|
|
@@ -113,11 +113,11 @@ function ErrorState({
|
|
|
113
113
|
{
|
|
114
114
|
role: "alert",
|
|
115
115
|
className,
|
|
116
|
-
icon: /* @__PURE__ */ jsxRuntime.jsx(
|
|
116
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.LucideIcon, { iconComponentName: "CircleAlert", size: 36 }),
|
|
117
117
|
iconClassName: "text-danger30",
|
|
118
118
|
title,
|
|
119
119
|
description,
|
|
120
|
-
action: onRetry ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
120
|
+
action: onRetry ? /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.Button, { type: "button", variant: "primary", onClick: onRetry, children: retryLabel }) : null
|
|
121
121
|
}
|
|
122
122
|
);
|
|
123
123
|
}
|
|
@@ -174,12 +174,12 @@ function ListPage({
|
|
|
174
174
|
return () => document.removeEventListener("keydown", onKey);
|
|
175
175
|
}, [detailOpen]);
|
|
176
176
|
const resetButton = onResetFilters ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
177
|
-
|
|
177
|
+
chunkIYDQLTRF_cjs.Button,
|
|
178
178
|
{
|
|
179
179
|
type: "button",
|
|
180
180
|
variant: "secondaryOutline",
|
|
181
181
|
onClick: onResetFilters,
|
|
182
|
-
className:
|
|
182
|
+
className: chunkIYDQLTRF_cjs.cn(filtersActive === false && "invisible"),
|
|
183
183
|
"aria-hidden": filtersActive === false || void 0,
|
|
184
184
|
children: [
|
|
185
185
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { size: 16, "aria-hidden": true }),
|
|
@@ -205,7 +205,7 @@ function ListPage({
|
|
|
205
205
|
const quick = quickFilter ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-[8px]", children: [
|
|
206
206
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-small-regular font-medium text-sys-text-subtle", children: quickFilter.label }),
|
|
207
207
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
208
|
-
|
|
208
|
+
chunkIYDQLTRF_cjs.ToggleGroup,
|
|
209
209
|
{
|
|
210
210
|
type: "multiple",
|
|
211
211
|
variant: "outline",
|
|
@@ -217,9 +217,9 @@ function ListPage({
|
|
|
217
217
|
quickFilter.onChange(pressedAll ? [] : next.filter((v) => v !== QUICK_ALL));
|
|
218
218
|
},
|
|
219
219
|
children: [
|
|
220
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
220
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.ToggleGroupItem, { value: QUICK_ALL, count: quickAllCount, countVariant: "primary", children: "\uC804\uCCB4" }),
|
|
221
221
|
quickFilter.options.map((o) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
222
|
-
|
|
222
|
+
chunkIYDQLTRF_cjs.ToggleGroupItem,
|
|
223
223
|
{
|
|
224
224
|
value: o.value,
|
|
225
225
|
count: o.count,
|
|
@@ -260,7 +260,7 @@ function ListPage({
|
|
|
260
260
|
className: "pt-[32px] pb-[16px]",
|
|
261
261
|
title: content.title,
|
|
262
262
|
description: content.description ?? content.children,
|
|
263
|
-
action: withReset && content.children == null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
263
|
+
action: withReset && content.children == null ? /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.Button, { type: "button", variant: "secondaryLink", onClick: () => resetRef.current?.(), children: "\uD544\uD130 \uCD08\uAE30\uD654" }) : null
|
|
264
264
|
}
|
|
265
265
|
);
|
|
266
266
|
},
|
|
@@ -272,7 +272,7 @@ function ListPage({
|
|
|
272
272
|
);
|
|
273
273
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
|
|
274
274
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
275
|
-
|
|
275
|
+
chunkIYDQLTRF_cjs.PageHeader,
|
|
276
276
|
{
|
|
277
277
|
title,
|
|
278
278
|
description,
|
|
@@ -281,19 +281,19 @@ function ListPage({
|
|
|
281
281
|
bottomRight: filterRow
|
|
282
282
|
}
|
|
283
283
|
),
|
|
284
|
-
/* @__PURE__ */ jsxRuntime.jsx("section", { "aria-label": title, className: "px-[24px] py-[32px]", children: error ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
284
|
+
/* @__PURE__ */ jsxRuntime.jsx("section", { "aria-label": title, className: "px-[24px] py-[32px]", children: error ? /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.Alert, { variant: "danger", children: /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.AlertDescription, { children: error }) }) : (
|
|
285
285
|
// 상세 패널(detail)이 있으면 표 쪽이 줄고 패널이 오른쪽에 나란히 선다 — 목록 맥락을 유지한 채 상세를 본다
|
|
286
286
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-[24px]", children: [
|
|
287
287
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
288
288
|
caption,
|
|
289
289
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
290
|
-
|
|
290
|
+
chunkIYDQLTRF_cjs.AgGridTable,
|
|
291
291
|
{
|
|
292
292
|
rowData: rows,
|
|
293
293
|
columnDefs,
|
|
294
294
|
loading,
|
|
295
295
|
noRowsOverlayComponent: EmptyOverlay,
|
|
296
|
-
onSortChanged: onSortChange ? (e) => onSortChange(
|
|
296
|
+
onSortChanged: onSortChange ? (e) => onSortChange(chunkIYDQLTRF_cjs.getSortedColumnState(e).value) : void 0,
|
|
297
297
|
onRowClicked: onRowClick ? (e) => {
|
|
298
298
|
if (e.data) onRowClick(e.data);
|
|
299
299
|
} : void 0,
|
|
@@ -303,8 +303,8 @@ function ListPage({
|
|
|
303
303
|
rowClassRules
|
|
304
304
|
}
|
|
305
305
|
),
|
|
306
|
-
pagination ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
307
|
-
|
|
306
|
+
pagination ? /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.TablePagination, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
307
|
+
chunkIYDQLTRF_cjs.Pagination,
|
|
308
308
|
{
|
|
309
309
|
total: pagination.total,
|
|
310
310
|
rowsPerPage: pagination.pageSize,
|
|
@@ -318,13 +318,13 @@ function ListPage({
|
|
|
318
318
|
// 나란한 상세 패널: 제목·설명·닫기 → 본문 → (안내) → 버튼 줄. 스크롤해도 따라오게 sticky. Card 와 같은 테두리·라운드(그림자 없음).
|
|
319
319
|
// <aside>(complementary) 는 다른 landmark 안에 둘 수 없으므로(axe landmark-complementary-is-top-level) 이름 있는 section — DetailPage 의 aside 와 같다
|
|
320
320
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
321
|
-
|
|
321
|
+
chunkIYDQLTRF_cjs.Panel,
|
|
322
322
|
{
|
|
323
323
|
title: detail.title,
|
|
324
324
|
description: detail.description,
|
|
325
325
|
padding: "large",
|
|
326
326
|
titleRight: /* @__PURE__ */ jsxRuntime.jsx(
|
|
327
|
-
|
|
327
|
+
chunkIYDQLTRF_cjs.IconButton,
|
|
328
328
|
{
|
|
329
329
|
type: "button",
|
|
330
330
|
variant: "secondary",
|
|
@@ -335,7 +335,7 @@ function ListPage({
|
|
|
335
335
|
),
|
|
336
336
|
note: detail.note,
|
|
337
337
|
footer: detail.footer,
|
|
338
|
-
className:
|
|
338
|
+
className: chunkIYDQLTRF_cjs.cn("sticky top-[24px] shrink-0", DETAIL_WIDTH[detail.width ?? "medium"]),
|
|
339
339
|
children: detail.children
|
|
340
340
|
}
|
|
341
341
|
)
|
|
@@ -353,10 +353,10 @@ function MoreMenu({
|
|
|
353
353
|
const select = (fn) => () => {
|
|
354
354
|
pendingRef.current = fn;
|
|
355
355
|
};
|
|
356
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
357
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
356
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(chunkIYDQLTRF_cjs.DropdownMenu, { children: [
|
|
357
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.IconButton, { ref: triggerRef, variant: "secondary", "aria-label": "\uB354\uBCF4\uAE30", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Ellipsis, { size: 24 }) }) }),
|
|
358
358
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
359
|
-
|
|
359
|
+
chunkIYDQLTRF_cjs.DropdownMenuContent,
|
|
360
360
|
{
|
|
361
361
|
align: "end",
|
|
362
362
|
onCloseAutoFocus: (e) => {
|
|
@@ -367,10 +367,10 @@ function MoreMenu({
|
|
|
367
367
|
fn?.();
|
|
368
368
|
},
|
|
369
369
|
children: [
|
|
370
|
-
items.map(({ children, onClick, disabled }, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
371
|
-
deleteAction && items.length ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
370
|
+
items.map(({ children, onClick, disabled }, i) => /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.DropdownMenuItem, { disabled, onSelect: select(onClick), children }, i)),
|
|
371
|
+
deleteAction && items.length ? /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.DropdownMenuSeparator, {}) : null,
|
|
372
372
|
deleteAction ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
373
|
-
|
|
373
|
+
chunkIYDQLTRF_cjs.DropdownMenuItem,
|
|
374
374
|
{
|
|
375
375
|
variant: "danger",
|
|
376
376
|
disabled: deleteAction.disabled,
|
|
@@ -418,7 +418,7 @@ function DetailPage({
|
|
|
418
418
|
body = // 넓은 화면: 본문 2 : 패널 1 + 세로선. 좁은 화면: 세로로 쌓이고 패널은 제목 + 가로선으로 시작한다
|
|
419
419
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-[24px] xl:grid-cols-[2fr_1fr] xl:items-start", children: [
|
|
420
420
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0", children }),
|
|
421
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
421
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.Panel, { title: asideTitle, children: aside })
|
|
422
422
|
] });
|
|
423
423
|
} else {
|
|
424
424
|
body = children;
|
|
@@ -426,11 +426,11 @@ function DetailPage({
|
|
|
426
426
|
const VISIBLE_SECONDARY = 2;
|
|
427
427
|
const visibleSecondary = secondaryActions?.slice(0, VISIBLE_SECONDARY) ?? [];
|
|
428
428
|
const overflowSecondary = secondaryActions?.slice(VISIBLE_SECONDARY) ?? [];
|
|
429
|
-
const primaryButton = primaryAction ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
429
|
+
const primaryButton = primaryAction ? /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.Button, { type: "button", variant: "primaryBold", ...primaryAction }) : null;
|
|
430
430
|
const moreMenu = (items) => items.length || deleteAction ? /* @__PURE__ */ jsxRuntime.jsx(MoreMenu, { items, deleteAction }) : null;
|
|
431
431
|
const fullRow = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
432
432
|
moreMenu(overflowSecondary),
|
|
433
|
-
visibleSecondary.map((action, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
433
|
+
visibleSecondary.map((action, i) => /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.Button, { type: "button", variant: "secondary", ...action }, i)),
|
|
434
434
|
primaryButton
|
|
435
435
|
] });
|
|
436
436
|
const collapsedRow = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -451,7 +451,7 @@ function DetailPage({
|
|
|
451
451
|
/* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "detail-actions-collapsed", className: "flex items-center gap-[8px] @3xl:hidden", children: collapsedRow })
|
|
452
452
|
] }) : primaryButton ? primaryButton : void 0;
|
|
453
453
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
|
|
454
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
454
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.PageHeader, { ...header, actions: actionRow }),
|
|
455
455
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
456
456
|
"section",
|
|
457
457
|
{
|
|
@@ -459,7 +459,7 @@ function DetailPage({
|
|
|
459
459
|
className: "flex flex-col gap-[24px] px-[24px] py-[24px]",
|
|
460
460
|
children: [
|
|
461
461
|
banner,
|
|
462
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className:
|
|
462
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkIYDQLTRF_cjs.cn("w-full", width === "panel" && "mx-auto max-w-[900px]"), children: [
|
|
463
463
|
note,
|
|
464
464
|
body
|
|
465
465
|
] })
|
|
@@ -481,7 +481,7 @@ function useFormShell({
|
|
|
481
481
|
}
|
|
482
482
|
function FormError({ error, className }) {
|
|
483
483
|
if (!error) return null;
|
|
484
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
484
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.Alert, { variant: "danger", className, children: /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.AlertDescription, { children: error }) });
|
|
485
485
|
}
|
|
486
486
|
function FormActions({
|
|
487
487
|
busy,
|
|
@@ -493,7 +493,7 @@ function FormActions({
|
|
|
493
493
|
}) {
|
|
494
494
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
495
495
|
onCancel ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
496
|
-
|
|
496
|
+
chunkIYDQLTRF_cjs.Button,
|
|
497
497
|
{
|
|
498
498
|
type: "button",
|
|
499
499
|
variant: "secondaryOutline",
|
|
@@ -504,7 +504,7 @@ function FormActions({
|
|
|
504
504
|
}
|
|
505
505
|
) : null,
|
|
506
506
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
507
|
-
|
|
507
|
+
chunkIYDQLTRF_cjs.Button,
|
|
508
508
|
{
|
|
509
509
|
type: "submit",
|
|
510
510
|
variant: "primaryBold",
|
|
@@ -556,11 +556,11 @@ function FormPage({
|
|
|
556
556
|
" ",
|
|
557
557
|
"\uD45C\uC2DC\uB294 \uD544\uC218 \uC785\uB825 \uD56D\uBAA9\uC785\uB2C8\uB2E4"
|
|
558
558
|
] }) : null,
|
|
559
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
560
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
559
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.Form, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { id: formId, noValidate: true, onSubmit: handleSubmit, children: [
|
|
560
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.FormSectionLevelContext.Provider, { value: 2, children }),
|
|
561
561
|
/* @__PURE__ */ jsxRuntime.jsx(FormError, { error, className: "mt-[24px]" }),
|
|
562
562
|
aside ? null : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
563
|
-
|
|
563
|
+
chunkIYDQLTRF_cjs.FormFooter,
|
|
564
564
|
{
|
|
565
565
|
align: "end",
|
|
566
566
|
className: "mt-[24px] border-t border-sys-divider-subtle pt-[16px]",
|
|
@@ -572,9 +572,9 @@ function FormPage({
|
|
|
572
572
|
const column = canvas === "subtle" ? (
|
|
573
573
|
// 폼 전체를 흰 Card 하나로(섹션 사이 구분선은 그대로). 위 8px 는 첫 FormSection 의 pt-[16px] 과 더해 24
|
|
574
574
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
575
|
-
|
|
575
|
+
chunkIYDQLTRF_cjs.Card,
|
|
576
576
|
{
|
|
577
|
-
className:
|
|
577
|
+
className: chunkIYDQLTRF_cjs.cn(
|
|
578
578
|
"w-full max-w-[var(--max-w-form-control)] px-[24px] pb-[24px] pt-[8px]",
|
|
579
579
|
align === "center" && !aside && "mx-auto"
|
|
580
580
|
),
|
|
@@ -584,7 +584,7 @@ function FormPage({
|
|
|
584
584
|
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
585
585
|
"div",
|
|
586
586
|
{
|
|
587
|
-
className:
|
|
587
|
+
className: chunkIYDQLTRF_cjs.cn(
|
|
588
588
|
"w-full max-w-[var(--max-w-form-control)]",
|
|
589
589
|
align === "center" && !aside && "mx-auto"
|
|
590
590
|
),
|
|
@@ -593,9 +593,9 @@ function FormPage({
|
|
|
593
593
|
);
|
|
594
594
|
return (
|
|
595
595
|
// subtle 의 캔버스 회색은 기존 토큰(grayscale20, 진단 18-A 의 f7 변형)을 쓴다 — 채택되면 전용 sys 토큰으로 올린다
|
|
596
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className:
|
|
596
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkIYDQLTRF_cjs.cn("w-full", canvas === "subtle" && "bg-sys-background-hover"), children: [
|
|
597
597
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
598
|
-
|
|
598
|
+
chunkIYDQLTRF_cjs.PageHeader,
|
|
599
599
|
{
|
|
600
600
|
title,
|
|
601
601
|
description,
|
|
@@ -609,7 +609,7 @@ function FormPage({
|
|
|
609
609
|
// <aside>(complementary) 는 다른 landmark 안에 둘 수 없으므로(axe) 이름 있는 section (DetailPage aside 와 같은 꼴)
|
|
610
610
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-[24px] xl:grid-cols-[minmax(0,var(--max-w-form-control))_minmax(280px,1fr)] xl:items-start", children: [
|
|
611
611
|
column,
|
|
612
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
612
|
+
/* @__PURE__ */ jsxRuntime.jsxs(chunkIYDQLTRF_cjs.Panel, { title: asideTitle, className: "xl:sticky xl:top-[24px]", children: [
|
|
613
613
|
aside,
|
|
614
614
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
615
615
|
"div",
|
|
@@ -646,23 +646,23 @@ function FormDrawer({
|
|
|
646
646
|
if (!next && busy) return;
|
|
647
647
|
onOpenChange(next);
|
|
648
648
|
};
|
|
649
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
650
|
-
|
|
649
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.Drawer, { open, onOpenChange: guardedOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
650
|
+
chunkIYDQLTRF_cjs.DrawerContent,
|
|
651
651
|
{
|
|
652
652
|
side,
|
|
653
653
|
size,
|
|
654
654
|
...description ? {} : { "aria-describedby": void 0 },
|
|
655
655
|
children: [
|
|
656
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
657
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
658
|
-
description ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
656
|
+
/* @__PURE__ */ jsxRuntime.jsxs(chunkIYDQLTRF_cjs.DrawerHeader, { children: [
|
|
657
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.DrawerTitle, { children: title }),
|
|
658
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.DrawerDescription, { children: description }) : null
|
|
659
659
|
] }),
|
|
660
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
661
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
660
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.Form, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { noValidate: true, onSubmit: handleSubmit, className: "flex min-h-0 flex-1 flex-col", children: [
|
|
661
|
+
/* @__PURE__ */ jsxRuntime.jsxs(chunkIYDQLTRF_cjs.DrawerBody, { className: "px-[24px]", children: [
|
|
662
662
|
children,
|
|
663
663
|
/* @__PURE__ */ jsxRuntime.jsx(FormError, { error, className: "mt-[24px]" })
|
|
664
664
|
] }),
|
|
665
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
665
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.DrawerFooter, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
666
666
|
FormActions,
|
|
667
667
|
{
|
|
668
668
|
busy,
|
|
@@ -697,21 +697,21 @@ function FormDialog({
|
|
|
697
697
|
if (!next && busy) return;
|
|
698
698
|
onOpenChange(next);
|
|
699
699
|
};
|
|
700
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
701
|
-
|
|
700
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.Dialog, { open, onOpenChange: guardedOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
701
|
+
chunkIYDQLTRF_cjs.DialogContent,
|
|
702
702
|
{
|
|
703
703
|
width,
|
|
704
704
|
hideCloseButton: busy,
|
|
705
705
|
...description ? {} : { "aria-describedby": void 0 },
|
|
706
706
|
children: [
|
|
707
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
708
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
709
|
-
description ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
707
|
+
/* @__PURE__ */ jsxRuntime.jsxs(chunkIYDQLTRF_cjs.DialogHeader, { children: [
|
|
708
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.DialogTitle, { children: title }),
|
|
709
|
+
description ? /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.DialogDescription, { children: description }) : null
|
|
710
710
|
] }),
|
|
711
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
711
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.Form, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { noValidate: true, onSubmit: handleSubmit, className: "flex flex-col gap-[16px]", children: [
|
|
712
712
|
children,
|
|
713
713
|
/* @__PURE__ */ jsxRuntime.jsx(FormError, { error }),
|
|
714
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
714
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.DialogFooter, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
715
715
|
FormActions,
|
|
716
716
|
{
|
|
717
717
|
busy,
|
|
@@ -743,7 +743,7 @@ function StatTile({
|
|
|
743
743
|
}) {
|
|
744
744
|
const labelId = react.useId();
|
|
745
745
|
const percent = ratio == null ? null : Math.round(Math.min(Math.max(ratio, 0), 1) * 100);
|
|
746
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
746
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(chunkIYDQLTRF_cjs.Card, { className: "relative gap-[4px] p-[16px]", children: [
|
|
747
747
|
/* @__PURE__ */ jsxRuntime.jsx("span", { id: labelId, className: "text-h6 text-sys-text-subtle", children: href ? (
|
|
748
748
|
// 타일 전체를 클릭 영역으로: 링크의 ::after 를 Card 크기로 늘린다
|
|
749
749
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -755,7 +755,7 @@ function StatTile({
|
|
|
755
755
|
}
|
|
756
756
|
)
|
|
757
757
|
) : label }),
|
|
758
|
-
loading ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
758
|
+
loading ? /* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.Skeleton, { role: "status", "aria-label": "\uBD88\uB7EC\uC624\uB294 \uC911", className: "h-[32px] w-[80px]" }) : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: chunkIYDQLTRF_cjs.cn("flex items-center gap-[6px] text-h2", TONE_TEXT[tone]), children: [
|
|
759
759
|
tone !== "default" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TriangleAlert, { "aria-hidden": true, size: 20, className: "shrink-0" }) : null,
|
|
760
760
|
value
|
|
761
761
|
] }),
|
|
@@ -771,7 +771,7 @@ function StatTile({
|
|
|
771
771
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
772
772
|
"div",
|
|
773
773
|
{
|
|
774
|
-
className:
|
|
774
|
+
className: chunkIYDQLTRF_cjs.cn("h-full rounded-full", TONE_BAR[tone]),
|
|
775
775
|
style: { width: `${percent}%` }
|
|
776
776
|
}
|
|
777
777
|
)
|
|
@@ -800,7 +800,7 @@ function DashboardLayout({
|
|
|
800
800
|
children
|
|
801
801
|
] });
|
|
802
802
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
|
|
803
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
803
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunkIYDQLTRF_cjs.PageHeader, { ...header, actions }),
|
|
804
804
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
805
805
|
"section",
|
|
806
806
|
{
|
|
@@ -822,9 +822,9 @@ function DashboardSection({ title, action, columns, children }) {
|
|
|
822
822
|
// 1px 간격 + 구분선 색 배경 = 칸 사이 가로·세로 구분선. 칸(DashboardPanel)은 자기 배경을 가진다
|
|
823
823
|
// 2열에서 칸 수가 홀수면 마지막 칸이 두 열을 차지해 빈 칸이 생기지 않게 한다
|
|
824
824
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
825
|
-
|
|
825
|
+
chunkIYDQLTRF_cjs.Card,
|
|
826
826
|
{
|
|
827
|
-
className:
|
|
827
|
+
className: chunkIYDQLTRF_cjs.cn(
|
|
828
828
|
"grid grid-cols-1 gap-px overflow-hidden bg-sys-divider-subtler",
|
|
829
829
|
columns === 2 && "xl:grid-cols-2 xl:[&>:last-child:nth-child(odd)]:col-span-2"
|
|
830
830
|
),
|