@wipco/sdui 0.20.0 → 0.21.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.
@@ -0,0 +1,133 @@
1
+ import { boxed } from './chunk-SAN4IX6N.js';
2
+ import { useState } from 'react';
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
+
5
+ var RECORD_SHEET_CSS = `
6
+ .erp-recsheet__scroll{overflow-x:auto;min-width:0}
7
+ .erp-recsheet{width:100%;min-width:44rem;border-collapse:collapse;table-layout:fixed;font-size:var(--wp-size-sm)}
8
+ .erp-recsheet td{height:var(--wp-row-h-dense);border:var(--wp-border-w) solid var(--wp-border-default);padding:var(--wp-space-1) var(--wp-space-2);color:var(--wp-text-default);vertical-align:middle;line-height:var(--wp-leading-snug);overflow-wrap:anywhere}
9
+ .erp-recsheet td.erp-recsheet__title{background:var(--wp-surface-inverse);color:var(--wp-text-inverse);text-align:center;font-size:var(--wp-size-lg);font-weight:var(--wp-weight-semibold);letter-spacing:var(--wp-tracking-heading);padding:var(--wp-space-3) var(--wp-space-2)}
10
+ .erp-recsheet td.erp-recsheet__label{background:var(--wp-surface-sunken);color:var(--wp-text-subtle);font-size:var(--wp-size-xs);font-weight:var(--wp-weight-semibold);text-align:center;white-space:nowrap}
11
+ .erp-recsheet td.erp-recsheet__section{background:var(--wp-surface-brand-tint);border-top:var(--wp-border-w-strong) solid var(--wp-border-brand);color:var(--wp-text-brand);font-size:var(--wp-size-xs);font-weight:var(--wp-weight-semibold);letter-spacing:var(--wp-tracking-heading)}
12
+ .erp-recsheet tr.erp-recsheet__gap td{border:0;padding:0;height:var(--wp-space-3)}
13
+ .erp-recsheet td.erp-recsheet__mono{font-family:var(--wp-font-mono);font-size:var(--wp-size-xs)}
14
+ .erp-recsheet td.erp-recsheet__photo{background:var(--wp-surface-sunken);padding:var(--wp-space-2);text-align:center}
15
+ .erp-recsheet__img{display:block;width:100%;height:11rem;object-fit:cover;border-radius:var(--wp-radius-sm)}
16
+ .erp-recsheet__noimg{display:flex;align-items:center;justify-content:center;width:100%;height:11rem;border:var(--wp-border-w) dashed var(--wp-border-default);border-radius:var(--wp-radius-sm);color:var(--wp-text-disabled);font-size:var(--wp-size-xs)}
17
+ .erp-recsheet__note{margin:var(--wp-space-2) 0 0;text-align:right;color:var(--wp-text-subtle);font-size:var(--wp-size-xs)}
18
+ @media print{
19
+ .erp-recsheet__scroll{overflow-x:visible}
20
+ .erp-recsheet{min-width:0}
21
+ .erp-recsheet tr{break-inside:avoid}
22
+ }
23
+ `;
24
+ function RecordSheetStyles() {
25
+ return /* @__PURE__ */ jsx("style", { href: "erp-recsheet", precedence: "medium", children: RECORD_SHEET_CSS });
26
+ }
27
+ function gridColumns(columns) {
28
+ if (typeof columns !== "number" || !Number.isFinite(columns)) return 24;
29
+ return Math.min(60, Math.max(1, Math.floor(columns)));
30
+ }
31
+ function cellClass(cell) {
32
+ const classes = [];
33
+ if (cell.kind === "label") classes.push("erp-recsheet__label");
34
+ else if (cell.kind === "section") classes.push("erp-recsheet__section");
35
+ else if (cell.kind === "photo") classes.push("erp-recsheet__photo");
36
+ if (cell.mono) classes.push("erp-recsheet__mono");
37
+ return classes.length > 0 ? classes.join(" ") : void 0;
38
+ }
39
+ function isBlank(value) {
40
+ return value === null || value === void 0 || value === "";
41
+ }
42
+ function pickValue(cell, item) {
43
+ if (!item || typeof item !== "object") return void 0;
44
+ const row = item;
45
+ if (cell.fields && cell.fields.length > 0) {
46
+ const parts = cell.fields.map((name) => isBlank(row[name]) ? "" : String(row[name]));
47
+ if (parts.every((part) => part === "")) return void 0;
48
+ return parts.join(cell.separator ?? " ~ ");
49
+ }
50
+ if (cell.field) return row[cell.field];
51
+ return void 0;
52
+ }
53
+ function PhotoCell({ src, alt }) {
54
+ const [failed, setFailed] = useState(false);
55
+ const label = alt ?? "\uC0AC\uC9C4";
56
+ if (!src || failed) return /* @__PURE__ */ jsx("span", { className: "erp-recsheet__noimg", children: label });
57
+ return /* @__PURE__ */ jsx("img", { className: "erp-recsheet__img", src, alt: label, onError: () => setFailed(true) });
58
+ }
59
+ function cellContent(cell, item, repeated) {
60
+ if (cell.kind === "photo") return /* @__PURE__ */ jsx(PhotoCell, { src: cell.src, alt: cell.alt });
61
+ if (!repeated) {
62
+ if (!isBlank(cell.text)) return cell.text;
63
+ if (cell.kind === "label" || cell.kind === "section") return null;
64
+ return cell.placeholder ?? "-";
65
+ }
66
+ const value = pickValue(cell, item);
67
+ if (!isBlank(value)) return value;
68
+ return item ? cell.placeholder ?? "-" : null;
69
+ }
70
+ function renderCells(cells, items, keyPrefix) {
71
+ return cells.map((cell, index) => {
72
+ const item = items ? items[cell.source ?? 0] ?? null : null;
73
+ return /* @__PURE__ */ jsx(
74
+ "td",
75
+ {
76
+ className: cellClass(cell),
77
+ colSpan: cell.span && cell.span > 1 ? cell.span : void 0,
78
+ rowSpan: cell.rowSpan && cell.rowSpan > 1 ? cell.rowSpan : void 0,
79
+ style: cell.align && cell.align !== "left" ? { textAlign: cell.align } : void 0,
80
+ children: cellContent(cell, item, items !== null)
81
+ },
82
+ `${keyPrefix}-${index}`
83
+ );
84
+ });
85
+ }
86
+ function repeatLength(sources, minRows) {
87
+ const longest = sources.reduce((max, source) => Math.max(max, source.length), 0);
88
+ return Math.max(longest, Math.max(0, Math.floor(minRows ?? 0)));
89
+ }
90
+ function RecordSheetImpl({ columns, title, rows, note }) {
91
+ const width = gridColumns(columns);
92
+ const list = Array.isArray(rows) ? rows : [];
93
+ const body = [];
94
+ list.forEach((row, rowIndex) => {
95
+ if (row?.gap) {
96
+ body.push(
97
+ /* @__PURE__ */ jsx("tr", { className: "erp-recsheet__gap", children: /* @__PURE__ */ jsx("td", { colSpan: width }) }, `gap-${rowIndex}`)
98
+ );
99
+ return;
100
+ }
101
+ const cells = Array.isArray(row?.cells) ? row.cells : [];
102
+ if (cells.length === 0) return;
103
+ if (Array.isArray(row.repeat)) {
104
+ const sources = row.repeat.map((source) => Array.isArray(source) ? source : []);
105
+ const count = repeatLength(sources, row.minRows);
106
+ for (let line = 0; line < count; line += 1) {
107
+ body.push(
108
+ /* @__PURE__ */ jsx("tr", { children: renderCells(
109
+ cells,
110
+ sources.map((source) => source[line] ?? null),
111
+ `rep-${rowIndex}-${line}`
112
+ ) }, `rep-${rowIndex}-${line}`)
113
+ );
114
+ }
115
+ return;
116
+ }
117
+ body.push(/* @__PURE__ */ jsx("tr", { children: renderCells(cells, null, `row-${rowIndex}`) }, `row-${rowIndex}`));
118
+ });
119
+ return /* @__PURE__ */ jsxs("div", { className: "erp-recsheet__scroll", children: [
120
+ /* @__PURE__ */ jsx(RecordSheetStyles, {}),
121
+ /* @__PURE__ */ jsxs("table", { className: "erp-recsheet", children: [
122
+ /* @__PURE__ */ jsx("colgroup", { children: Array.from({ length: width }, (_, index) => /* @__PURE__ */ jsx("col", { style: { width: `${100 / width}%` } }, index)) }),
123
+ /* @__PURE__ */ jsxs("tbody", { children: [
124
+ title ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { className: "erp-recsheet__title", colSpan: width, children: title }) }) : null,
125
+ body
126
+ ] })
127
+ ] }),
128
+ note ? /* @__PURE__ */ jsx("p", { className: "erp-recsheet__note", children: note }) : null
129
+ ] });
130
+ }
131
+ var RecordSheet = boxed(RecordSheetImpl, "RecordSheet");
132
+
133
+ export { RecordSheet };
package/dist/meta.d.ts CHANGED
@@ -442,6 +442,7 @@ declare const OrgChartMeta: SduiComponentMeta;
442
442
  declare const SummaryTableMeta: SduiComponentMeta;
443
443
  declare const TreeViewMeta: SduiComponentMeta;
444
444
  declare const PrintSheetMeta: SduiComponentMeta;
445
+ declare const RecordSheetMeta: SduiComponentMeta;
445
446
  declare const SecureScreenMeta: SduiComponentMeta;
446
447
  declare const StripMeta: SduiComponentMeta;
447
448
  /**
@@ -467,6 +468,7 @@ declare const widgetComponentMeta: {
467
468
  OrgChart: SduiComponentMeta;
468
469
  PeriodFilter: SduiComponentMeta;
469
470
  PrintSheet: SduiComponentMeta;
471
+ RecordSheet: SduiComponentMeta;
470
472
  SearchableMultiPicker: SduiComponentMeta;
471
473
  SecureScreen: SduiComponentMeta;
472
474
  StackedMeter: SduiComponentMeta;
@@ -557,11 +559,11 @@ declare const SDUI_CATEGORIES: ReadonlyArray<{
557
559
  label: string;
558
560
  }>;
559
561
  /**
560
- * 라이브러리가 아는 어휘 전체 — 기본 41 + rich 2 + 위젯 21 + DS 6 + 렌더러 내장 2 = 72종.
562
+ * 라이브러리가 아는 어휘 전체 — 기본 42 + rich 2 + 위젯 22 + DS 6 + 렌더러 내장 2 = 74종.
561
563
  * 편집기처럼 어휘 전부를 다뤄야 하는 쪽에서 쓴다.
562
564
  *
563
565
  * **레지스트리와 일대일이 아니다.** `defaultRegistry`에 없는 것도 들어 있다 —
564
- * rich 2종, 위젯 21종, DS 6종은 소비자가 `createRegistry`로 직접 얹는 어휘라서
566
+ * rich 2종, 위젯 22종, DS 6종은 소비자가 `createRegistry`로 직접 얹는 어휘라서
565
567
  * 여기 있다고 곧바로 렌더되지는 않는다. 이 목록은 "빌더가 프롭을 그릴 줄 아는 이름"이지
566
568
  * "지금 렌더할 수 있는 이름"이 아니다.
567
569
  *
@@ -586,4 +588,4 @@ declare function paletteGroups(catalog?: Record<string, SduiComponentMeta>): Arr
586
588
  items: SduiComponentMeta[];
587
589
  }>;
588
590
 
589
- export { ActionsMeta, AlertMeta, AutocompleteFieldMeta, AvatarMeta, BadgeMeta, BreadcrumbMeta, ButtonMeta, CanMeta, CardMeta, ChartMeta, CheckboxMeta, ColMeta, ColumnBoardMeta, DatePickerMeta, DateRangePickerMeta, DialogMeta, DiffViewMeta, DisclosureMeta, DividerMeta, EmptyStateMeta, EventCalendarMeta, FieldMeta, ForEachMeta, FormMeta, FragmentMeta, GridMeta, IconButtonMeta, IconMeta, ImageLightboxMeta, InlineEditMeta, InputMeta, JsonFieldMeta, KeyValueListMeta, LiveClockMeta, MapPreviewMeta, OrgChartMeta, PageHeadMeta, PaginationMeta, PeriodFilterMeta, PrintSheetMeta, ProgressBarMeta, RadioMeta, RemoteSearchResultsMeta, RowMeta, SDUI_CATEGORIES, SELF_AXIS_PROPS, type SduiCategory, type SduiChildrenMeta, type SduiComponentMeta, type SduiDomMeta, type SduiEnumOption, type SduiPropGroup, type SduiPropKind, type SduiPropMeta, type SduiResizeMeta, type SduiSlotMeta, SearchResultsMeta, SearchableMultiPickerMeta, SectionMeta, SecureScreenMeta, SegmentedControlMeta, SelectMeta, ShowMeta, SidebarNavMeta, SortHandleMeta, SortableListMeta, SpacerMeta, SpinnerMeta, StackedMeterMeta, StatCardMeta, StripMeta, SummaryTableMeta, SwitchMeta, TableMeta, TabsMeta, TagMeta, TagMultiSelectMeta, TextMeta, TextareaMeta, TimePickerMeta, TimelineMeta, ToastMeta, TooltipMeta, TreePickerMeta, TreeViewMeta, allComponentMeta, builtinComponentMeta, coreComponentMeta, dsComponentMeta, getComponentMeta, paletteGroups, richComponentMeta, slotNamesOf, widgetComponentMeta, withSelfAxis, withSelfAxisAll };
591
+ export { ActionsMeta, AlertMeta, AutocompleteFieldMeta, AvatarMeta, BadgeMeta, BreadcrumbMeta, ButtonMeta, CanMeta, CardMeta, ChartMeta, CheckboxMeta, ColMeta, ColumnBoardMeta, DatePickerMeta, DateRangePickerMeta, DialogMeta, DiffViewMeta, DisclosureMeta, DividerMeta, EmptyStateMeta, EventCalendarMeta, FieldMeta, ForEachMeta, FormMeta, FragmentMeta, GridMeta, IconButtonMeta, IconMeta, ImageLightboxMeta, InlineEditMeta, InputMeta, JsonFieldMeta, KeyValueListMeta, LiveClockMeta, MapPreviewMeta, OrgChartMeta, PageHeadMeta, PaginationMeta, PeriodFilterMeta, PrintSheetMeta, ProgressBarMeta, RadioMeta, RecordSheetMeta, RemoteSearchResultsMeta, RowMeta, SDUI_CATEGORIES, SELF_AXIS_PROPS, type SduiCategory, type SduiChildrenMeta, type SduiComponentMeta, type SduiDomMeta, type SduiEnumOption, type SduiPropGroup, type SduiPropKind, type SduiPropMeta, type SduiResizeMeta, type SduiSlotMeta, SearchResultsMeta, SearchableMultiPickerMeta, SectionMeta, SecureScreenMeta, SegmentedControlMeta, SelectMeta, ShowMeta, SidebarNavMeta, SortHandleMeta, SortableListMeta, SpacerMeta, SpinnerMeta, StackedMeterMeta, StatCardMeta, StripMeta, SummaryTableMeta, SwitchMeta, TableMeta, TabsMeta, TagMeta, TagMultiSelectMeta, TextMeta, TextareaMeta, TimePickerMeta, TimelineMeta, ToastMeta, TooltipMeta, TreePickerMeta, TreeViewMeta, allComponentMeta, builtinComponentMeta, coreComponentMeta, dsComponentMeta, getComponentMeta, paletteGroups, richComponentMeta, slotNamesOf, widgetComponentMeta, withSelfAxis, withSelfAxisAll };
package/dist/meta.js CHANGED
@@ -4478,6 +4478,146 @@ var PrintSheetMeta = {
4478
4478
  },
4479
4479
  resize: { kind: "none" }
4480
4480
  };
4481
+ var RecordSheetMeta = {
4482
+ name: "RecordSheet",
4483
+ label: "\uC591\uC2DD \uD45C",
4484
+ category: "data",
4485
+ icon: "layout-grid",
4486
+ description: "\uCE78\uC744 \uBCD1\uD569\uD574 \uC4F0\uB294 \uC885\uC774 \uC11C\uC2DD\uC6A9 \uD45C(\uC778\uC0AC\uAE30\uB85D\uCE74\uB4DC \uB4F1). \uACA9\uC790 \uC5F4 \uC218\uB97C \uC815\uD558\uACE0 \uCE78\uB9C8\uB2E4 \uBA87 \uCE78\uC744 \uCC28\uC9C0\uD560\uC9C0 \uC801\uB294\uB2E4 \u2014 \uAD6C\uD68D\uC774 \uB2EC\uB77C\uB3C4 \uC138\uB85C\uC120\uC774 \uD558\uB098\uB85C \uC774\uC5B4\uC9C4\uB2E4.",
4487
+ props: [
4488
+ {
4489
+ name: "columns",
4490
+ kind: "number",
4491
+ label: "\uACA9\uC790 \uC5F4 \uC218",
4492
+ default: 24,
4493
+ description: "\uBAA8\uB4E0 \uCE78 \uBCD1\uD569(span)\uC758 \uAE30\uC900. 24\uBA74 2\xB73\xB74\xB76\xB78\xB712 \uB4F1\uBD84\uC774 \uB531 \uB5A8\uC5B4\uC9C4\uB2E4.",
4494
+ group: "layout"
4495
+ },
4496
+ { name: "title", kind: "string", label: "\uD45C \uC81C\uBAA9 \uC904", bindable: true, group: "content" },
4497
+ {
4498
+ name: "rows",
4499
+ kind: "array",
4500
+ label: "\uC904",
4501
+ required: true,
4502
+ group: "data",
4503
+ description: "\uC704\uC5D0\uC11C \uC544\uB798\uB85C \uADF8\uB9B4 \uC904 \uBAA9\uB85D. \uAC01 \uC904\uC740 \uCE78 \uBAA9\uB85D\uC774\uAC70\uB098, \uBC30\uC5F4\uC744 \uB418\uD480\uC774\uD558\uB294 \uC904\uC774\uB2E4.",
4504
+ item: [
4505
+ {
4506
+ name: "gap",
4507
+ kind: "boolean",
4508
+ label: "\uBE48 \uC904",
4509
+ description: "\uD14C\uB450\uB9AC \uC5C6\uB294 \uC5EC\uBC31 \uC904 \u2014 \uAD6C\uD68D \uC0AC\uC774\uB97C \uB744\uC6B4\uB2E4. \uCF1C\uBA74 \uB098\uBA38\uC9C0\uB294 \uBB34\uC2DC\uB41C\uB2E4."
4510
+ },
4511
+ {
4512
+ name: "repeat",
4513
+ kind: "binding",
4514
+ label: "\uB418\uD480\uC774\uD560 \uBC30\uC5F4\uB4E4",
4515
+ bindable: true,
4516
+ description: "\uBC30\uC5F4\uC758 \uBC30\uC5F4. \uC5EC\uB7FF \uC8FC\uBA74 \uB098\uB780\uD788 \uB193\uACE0 \uAC00\uC7A5 \uAE34 \uAC83\uC5D0 \uB9DE\uCD98\uB2E4 \u2014 \uC67C\uCABD \uD559\uB825\xB7\uC624\uB978\uCABD \uC790\uACA9\uCC98\uB7FC \uAE38\uC774\uAC00 \uB2E4\uB978 \uBAA9\uB85D\uC744 \uD55C \uACA9\uC790\uC5D0 \uB2F4\uB294\uB2E4."
4517
+ },
4518
+ {
4519
+ name: "minRows",
4520
+ kind: "number",
4521
+ label: "\uCD5C\uC18C \uC904 \uC218",
4522
+ description: "\uAC12\uC774 \uBAA8\uC790\uB77C\uBA74 \uBE48 \uC904\uB85C \uCC44\uC6CC \uC591\uC2DD \uB192\uC774\uB97C \uC9C0\uD0A8\uB2E4."
4523
+ },
4524
+ {
4525
+ name: "cells",
4526
+ kind: "array",
4527
+ label: "\uCE78",
4528
+ item: [
4529
+ { name: "span", kind: "number", label: "\uC5F4 \uBCD1\uD569", default: 1 },
4530
+ { name: "rowSpan", kind: "number", label: "\uD589 \uBCD1\uD569", default: 1 },
4531
+ {
4532
+ name: "kind",
4533
+ kind: "enum",
4534
+ label: "\uCE78 \uC885\uB958",
4535
+ default: "value",
4536
+ options: [
4537
+ { value: "value", label: "\uAC12" },
4538
+ { value: "label", label: "\uBA38\uB9AC\uCE78", description: "\uD68C\uC0C9 \uBC30\uACBD + \uAC00\uC6B4\uB370 \uC815\uB82C" },
4539
+ { value: "section", label: "\uAD6C\uD68D \uC81C\uBAA9", description: "\uAD6C\uD68D \uC704\uC5D0 \uAD75\uC740 \uC120\uC774 \uBD99\uB294\uB2E4" },
4540
+ { value: "photo", label: "\uC0AC\uC9C4", description: "src\uC758 \uC0AC\uC9C4\uC744 \uCC44\uC6B4\uB2E4. \uC5C6\uC73C\uBA74 \uC790\uB9AC \uC0C1\uC790." }
4541
+ ]
4542
+ },
4543
+ { name: "text", kind: "node", label: "\uACE0\uC815 \uAC12", bindable: true },
4544
+ { name: "source", kind: "number", label: "\uBC30\uC5F4 \uBC88\uD638", default: 0, description: "\uB418\uD480\uC774 \uC904\uC5D0\uC11C \uBA87 \uBC88\uC9F8 \uBC30\uC5F4\uC744 \uBCFC\uC9C0." },
4545
+ { name: "field", kind: "string", label: "\uD56D\uBAA9 \uD544\uB4DC" },
4546
+ {
4547
+ name: "fields",
4548
+ kind: "array",
4549
+ label: "\uC774\uC5B4 \uBD99\uC77C \uD544\uB4DC\uB4E4",
4550
+ item: [],
4551
+ itemKind: "string",
4552
+ description: "\uAE30\uAC04 \uCE78(\uC2DC\uC791 ~ \uC885\uB8CC)\uCC98\uB7FC \uB450 \uD544\uB4DC\uB97C \uD55C \uCE78\uC5D0 \uB2F4\uC744 \uB54C."
4553
+ },
4554
+ { name: "separator", kind: "string", label: "\uC774\uC74C\uB9D0", default: " ~ " },
4555
+ {
4556
+ name: "align",
4557
+ kind: "enum",
4558
+ label: "\uC815\uB82C",
4559
+ options: [
4560
+ { value: "left", label: "\uC67C\uCABD" },
4561
+ { value: "center", label: "\uAC00\uC6B4\uB370" },
4562
+ { value: "right", label: "\uC624\uB978\uCABD" }
4563
+ ]
4564
+ },
4565
+ { name: "mono", kind: "boolean", label: "\uACE0\uC815\uD3ED \uAE00\uAF34" },
4566
+ { name: "placeholder", kind: "string", label: "\uBE48 \uAC12 \uD45C\uC2DC", default: "-" },
4567
+ { name: "src", kind: "string", label: "\uC0AC\uC9C4 \uC8FC\uC18C", bindable: true },
4568
+ { name: "alt", kind: "string", label: "\uC0AC\uC9C4 \uB300\uCCB4 \uAE00\uC790", default: "\uC0AC\uC9C4" }
4569
+ ]
4570
+ }
4571
+ ]
4572
+ },
4573
+ {
4574
+ name: "note",
4575
+ kind: "string",
4576
+ label: "\uD45C \uC544\uB798 \uC8FC\uC11D",
4577
+ bindable: true,
4578
+ group: "content",
4579
+ description: "\uC624\uB978\uCABD \uC544\uB798\uC5D0 \uC791\uAC8C \uBD99\uB294 \uD55C \uC904(\uCD9C\uB825\uC77C \uB4F1)."
4580
+ }
4581
+ ],
4582
+ children: { accepts: false },
4583
+ dom: { element: "div" },
4584
+ preset: {
4585
+ component: "RecordSheet",
4586
+ props: {
4587
+ columns: 12,
4588
+ title: "\uC0AC\uC6D0 \uC778\uC0AC\uAE30\uB85D\uCE74\uB4DC",
4589
+ rows: [
4590
+ {
4591
+ cells: [
4592
+ { kind: "label", span: 2, text: "\uC131\uBA85" },
4593
+ { span: 4, text: "\uD64D\uAE38\uB3D9" },
4594
+ { kind: "label", span: 2, text: "\uC0AC\uBC88" },
4595
+ { span: 4, text: "140", mono: true }
4596
+ ]
4597
+ },
4598
+ { gap: true },
4599
+ { cells: [{ kind: "section", span: 12, text: "1) \uD559\uC704 \uBC0F \uD559\uB825\uC0AC\uD56D" }] },
4600
+ {
4601
+ cells: [
4602
+ { kind: "label", span: 5, text: "\uD559\uAD50\uBA85" },
4603
+ { kind: "label", span: 3, text: "\uD559\uC704" },
4604
+ { kind: "label", span: 4, text: "\uC878\uC5C5\uC77C" }
4605
+ ]
4606
+ },
4607
+ {
4608
+ repeat: [[{ institution: "\uC704\uD504\uCF54\uB300\uD559\uAD50", degree: "\uD559\uC0AC", end_date: "2018-02-09" }]],
4609
+ minRows: 2,
4610
+ cells: [
4611
+ { span: 5, field: "institution" },
4612
+ { span: 3, field: "degree", align: "center" },
4613
+ { span: 4, field: "end_date", align: "center", mono: true }
4614
+ ]
4615
+ }
4616
+ ]
4617
+ }
4618
+ },
4619
+ resize: { kind: "none" }
4620
+ };
4481
4621
  var SecureScreenMeta = {
4482
4622
  name: "SecureScreen",
4483
4623
  label: "\uD654\uBA74 \uBCF4\uD638",
@@ -4576,6 +4716,7 @@ var widgetComponentMeta = {
4576
4716
  OrgChart: OrgChartMeta,
4577
4717
  PeriodFilter: PeriodFilterMeta,
4578
4718
  PrintSheet: PrintSheetMeta,
4719
+ RecordSheet: RecordSheetMeta,
4579
4720
  SearchableMultiPicker: SearchableMultiPickerMeta,
4580
4721
  SecureScreen: SecureScreenMeta,
4581
4722
  StackedMeter: StackedMeterMeta,
@@ -4620,4 +4761,4 @@ function paletteGroups(catalog = allComponentMeta) {
4620
4761
  })).filter((group) => group.items.length > 0);
4621
4762
  }
4622
4763
 
4623
- export { ActionsMeta, AlertMeta, AutocompleteFieldMeta, AvatarMeta, BadgeMeta, BreadcrumbMeta, ButtonMeta, CanMeta, CardMeta, ChartMeta, CheckboxMeta, ColMeta, ColumnBoardMeta, DatePickerMeta, DateRangePickerMeta, DialogMeta, DiffViewMeta, DisclosureMeta, DividerMeta, EmptyStateMeta, EventCalendarMeta, FieldMeta, ForEachMeta, FormMeta, FragmentMeta, GridMeta, IconButtonMeta, IconMeta, ImageLightboxMeta, InlineEditMeta, InputMeta, JsonFieldMeta, KeyValueListMeta, LiveClockMeta, MapPreviewMeta, OrgChartMeta, PageHeadMeta, PaginationMeta, PeriodFilterMeta, PrintSheetMeta, ProgressBarMeta, RadioMeta, RemoteSearchResultsMeta, RowMeta, SDUI_CATEGORIES, SELF_AXIS_PROPS, SearchResultsMeta, SearchableMultiPickerMeta, SectionMeta, SecureScreenMeta, SegmentedControlMeta, SelectMeta, ShowMeta, SidebarNavMeta, SortHandleMeta, SortableListMeta, SpacerMeta, SpinnerMeta, StackedMeterMeta, StatCardMeta, StripMeta, SummaryTableMeta, SwitchMeta, TableMeta, TabsMeta, TagMeta, TagMultiSelectMeta, TextMeta, TextareaMeta, TimePickerMeta, TimelineMeta, ToastMeta, TooltipMeta, TreePickerMeta, TreeViewMeta, allComponentMeta, builtinComponentMeta, coreComponentMeta, dsComponentMeta, getComponentMeta, paletteGroups, richComponentMeta, slotNamesOf, widgetComponentMeta, withSelfAxis, withSelfAxisAll };
4764
+ export { ActionsMeta, AlertMeta, AutocompleteFieldMeta, AvatarMeta, BadgeMeta, BreadcrumbMeta, ButtonMeta, CanMeta, CardMeta, ChartMeta, CheckboxMeta, ColMeta, ColumnBoardMeta, DatePickerMeta, DateRangePickerMeta, DialogMeta, DiffViewMeta, DisclosureMeta, DividerMeta, EmptyStateMeta, EventCalendarMeta, FieldMeta, ForEachMeta, FormMeta, FragmentMeta, GridMeta, IconButtonMeta, IconMeta, ImageLightboxMeta, InlineEditMeta, InputMeta, JsonFieldMeta, KeyValueListMeta, LiveClockMeta, MapPreviewMeta, OrgChartMeta, PageHeadMeta, PaginationMeta, PeriodFilterMeta, PrintSheetMeta, ProgressBarMeta, RadioMeta, RecordSheetMeta, RemoteSearchResultsMeta, RowMeta, SDUI_CATEGORIES, SELF_AXIS_PROPS, SearchResultsMeta, SearchableMultiPickerMeta, SectionMeta, SecureScreenMeta, SegmentedControlMeta, SelectMeta, ShowMeta, SidebarNavMeta, SortHandleMeta, SortableListMeta, SpacerMeta, SpinnerMeta, StackedMeterMeta, StatCardMeta, StripMeta, SummaryTableMeta, SwitchMeta, TableMeta, TabsMeta, TagMeta, TagMultiSelectMeta, TextMeta, TextareaMeta, TimePickerMeta, TimelineMeta, ToastMeta, TooltipMeta, TreePickerMeta, TreeViewMeta, allComponentMeta, builtinComponentMeta, coreComponentMeta, dsComponentMeta, getComponentMeta, paletteGroups, richComponentMeta, slotNamesOf, widgetComponentMeta, withSelfAxis, withSelfAxisAll };
@@ -0,0 +1,59 @@
1
+ import { S as SduiBoxProps } from '../layout-B1QrIBm6.js';
2
+ import React__default from 'react';
3
+
4
+ /** 칸의 생김새 — 값칸(기본)·머리칸·구획 제목·사진칸 */
5
+ type RecordSheetCellKind = 'value' | 'label' | 'section' | 'photo';
6
+ interface RecordSheetCell {
7
+ /** 격자에서 차지할 열 수. 기본 1 */
8
+ span?: number;
9
+ /** 아래로 병합할 줄 수(사진 칸 등). 기본 1 */
10
+ rowSpan?: number;
11
+ kind?: RecordSheetCellKind;
12
+ /** 고정 칸의 값. 되풀이 줄에서는 `field`/`fields`가 우선한다. */
13
+ text?: React__default.ReactNode;
14
+ /** 되풀이 줄에서 볼 배열 번호(`repeat`의 인덱스). 기본 0 */
15
+ source?: number;
16
+ /** 되풀이 항목에서 꺼낼 필드 */
17
+ field?: string;
18
+ /** 여러 필드를 이어 붙인다 — 기간 칸(시작 ~ 종료) 등. `field`보다 우선한다. */
19
+ fields?: string[];
20
+ /** `fields` 사이에 넣을 글자. 기본 ' ~ ' */
21
+ separator?: string;
22
+ align?: 'left' | 'center' | 'right';
23
+ /** 고정폭 글꼴 — 날짜·번호 칸 */
24
+ mono?: boolean;
25
+ /** 값이 비었을 때 대신 쓸 글자. 기본 '-'. 되풀이의 **빈 줄**은 언제나 빈칸이다. */
26
+ placeholder?: string;
27
+ /** 사진 칸(kind:'photo')의 이미지 주소 */
28
+ src?: string;
29
+ /** 사진이 없거나 못 불러올 때 상자에 쓸 글자. 기본 '사진' */
30
+ alt?: string;
31
+ }
32
+ interface RecordSheetRow {
33
+ /** 테두리 없는 빈 줄 — 구획 사이를 띄운다. 주면 나머지는 무시된다. */
34
+ gap?: boolean;
35
+ /**
36
+ * 이 줄을 배열만큼 되풀이한다. 배열을 여럿 주면 나란히 놓고 가장 긴 것에 맞춘다.
37
+ * 칸은 `source`로 몇 번째 배열을 볼지 고른다.
38
+ */
39
+ repeat?: Array<unknown>;
40
+ /** 되풀이의 최소 줄 수 — 모자라면 빈 줄로 채운다 */
41
+ minRows?: number;
42
+ cells?: RecordSheetCell[];
43
+ }
44
+ interface RecordSheetProps {
45
+ /** 격자 열 수 — 모든 `span`의 기준. 기본 24 */
46
+ columns?: number;
47
+ /** 표 맨 위 제목 줄(반전 배경). 없으면 그리지 않는다. */
48
+ title?: string;
49
+ rows: RecordSheetRow[];
50
+ /** 표 아래 오른쪽에 붙는 주석 한 줄(예: 출력일) */
51
+ note?: string;
52
+ }
53
+ /**
54
+ * 바깥에서 온 `style`·`className`을 뿌리에 얹어 내보낸다 — 자식 축(`grow`·`width` …)이
55
+ * 이 컴포넌트에서도 동작하게 하는 유일한 통로다. 까닭은 {@link ../boxed.tsx}에 있다.
56
+ */
57
+ declare const RecordSheet: React__default.FC<RecordSheetProps & SduiBoxProps>;
58
+
59
+ export { RecordSheet, type RecordSheetCell, type RecordSheetCellKind, type RecordSheetProps, type RecordSheetRow };
@@ -0,0 +1,2 @@
1
+ export { RecordSheet } from '../chunk-K3JBSWFI.js';
2
+ import '../chunk-SAN4IX6N.js';
@@ -16,6 +16,8 @@ import { SecureScreenProps } from './SecureScreen.js';
16
16
  export { SecureScreen } from './SecureScreen.js';
17
17
  import { SearchableMultiPickerProps } from './SearchableMultiPicker.js';
18
18
  export { MultiPickerOption, SearchableMultiPicker } from './SearchableMultiPicker.js';
19
+ import { RecordSheetProps } from './RecordSheet.js';
20
+ export { RecordSheet, RecordSheetCell, RecordSheetCellKind, RecordSheetRow } from './RecordSheet.js';
19
21
  import { PrintSheetProps } from './PrintSheet.js';
20
22
  export { PrintSheet } from './PrintSheet.js';
21
23
  import { PeriodFilterProps } from './PeriodFilter.js';
@@ -61,6 +63,7 @@ declare const widgetComponents: {
61
63
  OrgChart: React.FC<OrgChartProps & SduiBoxProps>;
62
64
  PeriodFilter: React.FC<PeriodFilterProps & SduiBoxProps>;
63
65
  PrintSheet: React.FC<PrintSheetProps & SduiBoxProps>;
66
+ RecordSheet: React.FC<RecordSheetProps & SduiBoxProps>;
64
67
  SearchableMultiPicker: React.FC<SearchableMultiPickerProps & SduiBoxProps>;
65
68
  SecureScreen: React.FC<SecureScreenProps & SduiBoxProps>;
66
69
  StackedMeter: React.FC<StackedMeterProps & SduiBoxProps>;
@@ -74,4 +77,4 @@ declare const widgetComponents: {
74
77
  /** 위젯 어휘의 컴포넌트 이름 union — 메타데이터 대조에 쓴다(`@wipco/sdui/meta`). */
75
78
  type SduiWidgetComponentName = keyof typeof widgetComponents;
76
79
 
77
- export { ColumnBoardProps, DiffViewProps, DisclosureProps, EventCalendarProps, ImageLightboxProps, InlineEditProps, JsonFieldProps, LiveClockProps, OrgChartProps, PeriodFilterProps, PrintSheetProps, type SduiWidgetComponentName, SearchableMultiPickerProps, SecureScreenProps, StackedMeterProps, StripProps, SummaryTableProps, TagMultiSelectProps, TimelineProps, TreePickerProps, TreeViewProps, widgetComponents };
80
+ export { ColumnBoardProps, DiffViewProps, DisclosureProps, EventCalendarProps, ImageLightboxProps, InlineEditProps, JsonFieldProps, LiveClockProps, OrgChartProps, PeriodFilterProps, PrintSheetProps, RecordSheetProps, type SduiWidgetComponentName, SearchableMultiPickerProps, SecureScreenProps, StackedMeterProps, StripProps, SummaryTableProps, TagMultiSelectProps, TimelineProps, TreePickerProps, TreeViewProps, widgetComponents };
@@ -1,3 +1,9 @@
1
+ import { TreePicker } from '../chunk-EQW24SJC.js';
2
+ export { TreePicker } from '../chunk-EQW24SJC.js';
3
+ import { TreeView } from '../chunk-IDUN2ESE.js';
4
+ export { TreeView, buildTreeNodes } from '../chunk-IDUN2ESE.js';
5
+ import { RecordSheet } from '../chunk-K3JBSWFI.js';
6
+ export { RecordSheet } from '../chunk-K3JBSWFI.js';
1
7
  import { SearchableMultiPicker } from '../chunk-N5IATDUF.js';
2
8
  export { SearchableMultiPicker } from '../chunk-N5IATDUF.js';
3
9
  import { SecureScreen } from '../chunk-IIRENCDS.js';
@@ -12,10 +18,6 @@ import { TagMultiSelect } from '../chunk-QDEZXA34.js';
12
18
  export { TagMultiSelect } from '../chunk-QDEZXA34.js';
13
19
  import { Timeline } from '../chunk-EFYEOT47.js';
14
20
  export { Timeline } from '../chunk-EFYEOT47.js';
15
- import { TreePicker } from '../chunk-EQW24SJC.js';
16
- export { TreePicker } from '../chunk-EQW24SJC.js';
17
- import { TreeView } from '../chunk-IDUN2ESE.js';
18
- export { TreeView, buildTreeNodes } from '../chunk-IDUN2ESE.js';
19
21
  import { EventCalendar } from '../chunk-C3JY6GA3.js';
20
22
  export { EventCalendar } from '../chunk-C3JY6GA3.js';
21
23
  import { ImageLightbox } from '../chunk-XPBZMECW.js';
@@ -58,6 +60,7 @@ var widgetComponents = {
58
60
  OrgChart,
59
61
  PeriodFilter,
60
62
  PrintSheet,
63
+ RecordSheet,
61
64
  SearchableMultiPicker,
62
65
  SecureScreen,
63
66
  StackedMeter,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipco/sdui",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "WIPCO 서버 주도 UI(SDUI) 렌더러 — JSON 페이지 스펙을 React 컴포넌트로 렌더링",
5
5
  "keywords": [
6
6
  "sdui",
@@ -84,6 +84,10 @@
84
84
  "types": "./dist/widgets/PrintSheet.d.ts",
85
85
  "default": "./dist/widgets/PrintSheet.js"
86
86
  },
87
+ "./widgets/RecordSheet": {
88
+ "types": "./dist/widgets/RecordSheet.d.ts",
89
+ "default": "./dist/widgets/RecordSheet.js"
90
+ },
87
91
  "./widgets/SearchableMultiPicker": {
88
92
  "types": "./dist/widgets/SearchableMultiPicker.d.ts",
89
93
  "default": "./dist/widgets/SearchableMultiPicker.js"