@wipco/sdui 0.1.0 → 0.3.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.
Files changed (78) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +27 -0
  3. package/dist/chunk-4SU2KYPU.js +59 -0
  4. package/dist/chunk-56KKWLNI.js +186 -0
  5. package/dist/chunk-7Y4J7EOK.js +115 -0
  6. package/dist/chunk-APCXOCAO.js +110 -0
  7. package/dist/chunk-AROOQ5W6.js +119 -0
  8. package/dist/chunk-DGPRX4MU.js +251 -0
  9. package/dist/chunk-IL2KS4WS.js +25 -0
  10. package/dist/chunk-KADFN76X.js +541 -0
  11. package/dist/chunk-KBHI3IUR.js +40 -0
  12. package/dist/chunk-LZJTKVMO.js +767 -0
  13. package/dist/chunk-MOIU7MUA.js +282 -0
  14. package/dist/chunk-MSAV4J4I.js +77 -0
  15. package/dist/chunk-OOHHW4K4.js +159 -0
  16. package/dist/chunk-Q6SBH63R.js +190 -0
  17. package/dist/chunk-QZQDHSMD.js +78 -0
  18. package/dist/chunk-RH7ESUE6.js +309 -0
  19. package/dist/chunk-SEBPBUZR.js +260 -0
  20. package/dist/chunk-USKRM22W.js +39 -0
  21. package/dist/chunk-WNYWTFGW.js +61 -0
  22. package/dist/chunk-WVRCIVAD.js +72 -0
  23. package/dist/chunk-YJMD6MOE.js +404 -0
  24. package/dist/chunk-ZNITJ4KK.js +433 -0
  25. package/dist/chunk-ZQR3ULVH.js +193 -0
  26. package/dist/chunk-ZUCI34QY.js +1290 -0
  27. package/dist/index.d.ts +391 -79
  28. package/dist/index.js +277 -758
  29. package/dist/meta.d.ts +10 -2
  30. package/dist/meta.js +268 -27
  31. package/dist/rich.js +3 -2
  32. package/dist/styles.css +334 -13
  33. package/dist/widgets/AutocompleteField.d.ts +96 -0
  34. package/dist/widgets/AutocompleteField.js +3 -0
  35. package/dist/widgets/ColumnBoard.d.ts +47 -0
  36. package/dist/widgets/ColumnBoard.js +2 -0
  37. package/dist/widgets/DiffView.d.ts +30 -0
  38. package/dist/widgets/DiffView.js +2 -0
  39. package/dist/widgets/Disclosure.d.ts +20 -0
  40. package/dist/widgets/Disclosure.js +2 -0
  41. package/dist/widgets/EventCalendar.d.ts +59 -0
  42. package/dist/widgets/EventCalendar.js +2 -0
  43. package/dist/widgets/ImageLightbox.d.ts +25 -0
  44. package/dist/widgets/ImageLightbox.js +2 -0
  45. package/dist/widgets/InlineEdit.d.ts +23 -0
  46. package/dist/widgets/InlineEdit.js +2 -0
  47. package/dist/widgets/JsonField.d.ts +24 -0
  48. package/dist/widgets/JsonField.js +2 -0
  49. package/dist/widgets/LiveClock.d.ts +21 -0
  50. package/dist/widgets/LiveClock.js +1 -0
  51. package/dist/widgets/OrgChart.d.ts +32 -0
  52. package/dist/widgets/OrgChart.js +2 -0
  53. package/dist/widgets/PeriodFilter.d.ts +48 -0
  54. package/dist/widgets/PeriodFilter.js +2 -0
  55. package/dist/widgets/PrintSheet.d.ts +23 -0
  56. package/dist/widgets/PrintSheet.js +2 -0
  57. package/dist/widgets/SearchableMultiPicker.d.ts +29 -0
  58. package/dist/widgets/SearchableMultiPicker.js +3 -0
  59. package/dist/widgets/SecureScreen.d.ts +25 -0
  60. package/dist/widgets/SecureScreen.js +2 -0
  61. package/dist/widgets/StackedMeter.d.ts +26 -0
  62. package/dist/widgets/StackedMeter.js +1 -0
  63. package/dist/widgets/Strip.d.ts +20 -0
  64. package/dist/widgets/Strip.js +1 -0
  65. package/dist/widgets/SummaryTable.d.ts +31 -0
  66. package/dist/widgets/SummaryTable.js +1 -0
  67. package/dist/widgets/TagMultiSelect.d.ts +25 -0
  68. package/dist/widgets/TagMultiSelect.js +2 -0
  69. package/dist/widgets/Timeline.d.ts +30 -0
  70. package/dist/widgets/Timeline.js +3 -0
  71. package/dist/widgets/TreePicker.d.ts +21 -0
  72. package/dist/widgets/TreePicker.js +3 -0
  73. package/dist/widgets/TreeView.d.ts +26 -0
  74. package/dist/widgets/TreeView.js +2 -0
  75. package/dist/widgets/index.d.ts +76 -0
  76. package/dist/widgets/index.js +69 -0
  77. package/package.json +93 -3
  78. package/dist/chunk-AR2JYE75.js +0 -889
@@ -0,0 +1,260 @@
1
+ import { Input, IconButton, EmptyState, Icon, Badge } from './chunk-ZUCI34QY.js';
2
+ import React, { useState, useMemo } from 'react';
3
+ import { jsxs, jsx } from 'react/jsx-runtime';
4
+
5
+ var INDENT = 24;
6
+ var ROW_PAD = 8;
7
+ var TREE_CSS = `
8
+ .erp-treeview__row{transition:background var(--wp-duration-fast) var(--wp-ease-out);}
9
+ .erp-treeview__row:hover{background:var(--wp-surface-hover);}
10
+ .erp-treeview__row:focus-visible{outline:none;box-shadow:var(--wp-ring-focus);}
11
+ .erp-treeview__row[aria-current='true'],
12
+ .erp-treeview__row[aria-current='true']:hover{background:var(--wp-surface-selected);}
13
+ `;
14
+ function pruneExcluded(nodes, excluded) {
15
+ if (excluded.size === 0) return nodes;
16
+ const out = [];
17
+ for (const node of nodes) {
18
+ if (excluded.has(node.id)) continue;
19
+ if (!node.children || node.children.length === 0) {
20
+ out.push(node);
21
+ continue;
22
+ }
23
+ const children = pruneExcluded(node.children, excluded);
24
+ out.push(children.length > 0 ? { ...node, children } : { ...node, children: void 0 });
25
+ }
26
+ return out;
27
+ }
28
+ function filterTree(nodes, lowerQuery) {
29
+ const out = [];
30
+ for (const node of nodes) {
31
+ const selfMatch = node.label.toLowerCase().includes(lowerQuery) || (node.meta ? node.meta.toLowerCase().includes(lowerQuery) : false);
32
+ if (selfMatch) {
33
+ out.push(node);
34
+ continue;
35
+ }
36
+ if (node.children && node.children.length > 0) {
37
+ const children = filterTree(node.children, lowerQuery);
38
+ if (children.length > 0) out.push({ ...node, children });
39
+ }
40
+ }
41
+ return out;
42
+ }
43
+ function collectExpandedIds(nodes, maxDepth, depth = 0, acc = /* @__PURE__ */ new Set()) {
44
+ if (depth >= maxDepth) return acc;
45
+ for (const node of nodes) {
46
+ if (node.children && node.children.length > 0) {
47
+ acc.add(node.id);
48
+ collectExpandedIds(node.children, maxDepth, depth + 1, acc);
49
+ }
50
+ }
51
+ return acc;
52
+ }
53
+ function toggled(prev, id) {
54
+ const next = new Set(prev);
55
+ if (next.has(id)) next.delete(id);
56
+ else next.add(id);
57
+ return next;
58
+ }
59
+ function TreeView({
60
+ nodes,
61
+ selectedId,
62
+ onSelect,
63
+ searchable = false,
64
+ defaultExpandedDepth = 1,
65
+ excludeIds,
66
+ maxHeight
67
+ }) {
68
+ const [expanded, setExpanded] = useState(() => collectExpandedIds(nodes, defaultExpandedDepth));
69
+ const [searchCollapsed, setSearchCollapsed] = useState(() => /* @__PURE__ */ new Set());
70
+ const [query, setQuery] = useState("");
71
+ const [innerSelected, setInnerSelected] = useState(null);
72
+ const isControlled = selectedId !== void 0;
73
+ const currentSelected = isControlled ? selectedId : innerSelected;
74
+ const trimmedQuery = query.trim().toLowerCase();
75
+ const searching = trimmedQuery.length > 0;
76
+ const visibleNodes = useMemo(() => {
77
+ const pruned = pruneExcluded(nodes, new Set(excludeIds ?? []));
78
+ return searching ? filterTree(pruned, trimmedQuery) : pruned;
79
+ }, [nodes, excludeIds, searching, trimmedQuery]);
80
+ const isOpen = (id) => searching ? !searchCollapsed.has(id) : expanded.has(id);
81
+ const toggleNode = (id) => {
82
+ if (searching) setSearchCollapsed((prev) => toggled(prev, id));
83
+ else setExpanded((prev) => toggled(prev, id));
84
+ };
85
+ const handleSelect = (node) => {
86
+ if (!isControlled) setInnerSelected(node.id);
87
+ onSelect?.(node.id, node);
88
+ };
89
+ const renderNode = (node, depth) => {
90
+ const children = node.children ?? [];
91
+ const hasChildren = children.length > 0;
92
+ const open = hasChildren && isOpen(node.id);
93
+ const isSelected = currentSelected != null && currentSelected === node.id;
94
+ const guides = [];
95
+ for (let i = 0; i < depth; i += 1) {
96
+ guides.push(
97
+ /* @__PURE__ */ jsx(
98
+ "span",
99
+ {
100
+ "aria-hidden": true,
101
+ style: {
102
+ position: "absolute",
103
+ top: 0,
104
+ bottom: 0,
105
+ left: ROW_PAD + i * INDENT + 11,
106
+ width: 1,
107
+ background: "var(--wp-border-subtle)"
108
+ }
109
+ },
110
+ i
111
+ )
112
+ );
113
+ }
114
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
115
+ /* @__PURE__ */ jsxs(
116
+ "div",
117
+ {
118
+ role: "treeitem",
119
+ "aria-level": depth + 1,
120
+ "aria-expanded": hasChildren ? open : void 0,
121
+ "aria-selected": isSelected,
122
+ "aria-current": isSelected ? "true" : void 0,
123
+ tabIndex: 0,
124
+ className: "erp-treeview__row",
125
+ style: {
126
+ position: "relative",
127
+ display: "flex",
128
+ alignItems: "center",
129
+ gap: "var(--wp-space-2)",
130
+ minHeight: "var(--wp-row-h-dense)",
131
+ paddingLeft: ROW_PAD + depth * INDENT,
132
+ paddingRight: "var(--wp-space-2)",
133
+ borderRadius: "var(--wp-radius-sm)",
134
+ cursor: "pointer",
135
+ userSelect: "none",
136
+ minWidth: 0
137
+ },
138
+ onClick: () => handleSelect(node),
139
+ onKeyDown: (event) => {
140
+ if (event.key === "Enter" || event.key === " ") {
141
+ event.preventDefault();
142
+ handleSelect(node);
143
+ } else if (event.key === "ArrowRight" && hasChildren && !open) {
144
+ event.preventDefault();
145
+ toggleNode(node.id);
146
+ } else if (event.key === "ArrowLeft" && open) {
147
+ event.preventDefault();
148
+ toggleNode(node.id);
149
+ }
150
+ },
151
+ children: [
152
+ guides,
153
+ hasChildren ? /* @__PURE__ */ jsx(
154
+ IconButton,
155
+ {
156
+ icon: open ? "chevron-down" : "chevron-right",
157
+ label: open ? "\uC811\uAE30" : "\uD3BC\uCE58\uAE30",
158
+ variant: "ghost",
159
+ size: "xs",
160
+ style: { flexShrink: 0 },
161
+ tabIndex: -1,
162
+ onClick: (event) => {
163
+ event.stopPropagation();
164
+ toggleNode(node.id);
165
+ }
166
+ }
167
+ ) : /* @__PURE__ */ jsx("span", { "aria-hidden": true, style: { width: 24, flexShrink: 0 } }),
168
+ /* @__PURE__ */ jsx(
169
+ Icon,
170
+ {
171
+ name: hasChildren ? open ? "folder-open" : "folder" : "circle-dot",
172
+ size: 16,
173
+ style: { flexShrink: 0, color: isSelected ? "var(--wp-text-brand)" : "var(--wp-text-muted)" }
174
+ }
175
+ ),
176
+ /* @__PURE__ */ jsx(
177
+ "span",
178
+ {
179
+ className: "wp-body-sm",
180
+ style: {
181
+ overflow: "hidden",
182
+ textOverflow: "ellipsis",
183
+ whiteSpace: "nowrap",
184
+ color: isSelected ? "var(--wp-text-strong)" : "var(--wp-text-default)",
185
+ fontWeight: isSelected ? "var(--wp-weight-medium)" : void 0
186
+ },
187
+ children: node.label
188
+ }
189
+ ),
190
+ node.meta ? /* @__PURE__ */ jsx(
191
+ "span",
192
+ {
193
+ className: "wp-caption",
194
+ style: {
195
+ overflow: "hidden",
196
+ textOverflow: "ellipsis",
197
+ whiteSpace: "nowrap",
198
+ color: "var(--wp-text-muted)",
199
+ flexShrink: 1
200
+ },
201
+ children: node.meta
202
+ }
203
+ ) : null,
204
+ hasChildren ? /* @__PURE__ */ jsx(Badge, { tone: isSelected ? "brand" : "neutral", className: "erp-treeview__count", children: children.length }) : null
205
+ ]
206
+ }
207
+ ),
208
+ hasChildren && open ? /* @__PURE__ */ jsx("div", { role: "group", children: children.map((child) => renderNode(child, depth + 1)) }) : null
209
+ ] }, node.id);
210
+ };
211
+ return /* @__PURE__ */ jsxs(
212
+ "div",
213
+ {
214
+ className: "erp-treeview",
215
+ style: { display: "flex", flexDirection: "column", gap: "var(--wp-space-2)", minWidth: 0 },
216
+ children: [
217
+ /* @__PURE__ */ jsx("style", { children: TREE_CSS }),
218
+ searchable ? /* @__PURE__ */ jsx(
219
+ Input,
220
+ {
221
+ size: "sm",
222
+ icon: "search",
223
+ placeholder: "\uC774\uB984\uC73C\uB85C \uAC80\uC0C9",
224
+ value: query,
225
+ "aria-label": "\uD2B8\uB9AC \uAC80\uC0C9",
226
+ onChange: (event) => {
227
+ setQuery(event.target.value);
228
+ setSearchCollapsed(/* @__PURE__ */ new Set());
229
+ },
230
+ trailing: searching ? /* @__PURE__ */ jsx(
231
+ IconButton,
232
+ {
233
+ icon: "x",
234
+ label: "\uAC80\uC0C9\uC5B4 \uC9C0\uC6B0\uAE30",
235
+ variant: "ghost",
236
+ size: "xs",
237
+ style: { pointerEvents: "auto" },
238
+ onClick: () => {
239
+ setQuery("");
240
+ setSearchCollapsed(/* @__PURE__ */ new Set());
241
+ }
242
+ }
243
+ ) : void 0
244
+ }
245
+ ) : null,
246
+ /* @__PURE__ */ jsx(
247
+ "div",
248
+ {
249
+ role: "tree",
250
+ className: "wp-scroll",
251
+ style: { overflowY: "auto", ...maxHeight ? { maxHeight } : null },
252
+ children: visibleNodes.length === 0 ? searching ? /* @__PURE__ */ jsx(EmptyState, { tight: true, icon: "search", title: "\uAC80\uC0C9 \uACB0\uACFC \uC5C6\uC74C", children: "\uB2E4\uB978 \uAC80\uC0C9\uC5B4\uB85C \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694." }) : /* @__PURE__ */ jsx(EmptyState, { tight: true, title: "\uD56D\uBAA9 \uC5C6\uC74C", children: "\uD45C\uC2DC\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4." }) : visibleNodes.map((node) => renderNode(node, 0))
253
+ }
254
+ )
255
+ ]
256
+ }
257
+ );
258
+ }
259
+
260
+ export { TreeView };
@@ -0,0 +1,39 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+
3
+ // src/widgets/SummaryTable.tsx
4
+ var SUMMARY_TABLE_CSS = `
5
+ .erp-sumtable tfoot td{height:var(--wp-row-h);padding:0 12px;background:var(--wp-surface-sunken);border-top:var(--wp-border-w) solid var(--wp-border-strong);color:var(--wp-text-strong);font-weight:var(--wp-weight-semibold);vertical-align:middle}
6
+ .erp-sumtable.wp-table--dense tfoot td{height:var(--wp-row-h-dense)}
7
+ .erp-sumtable__scroll{overflow-x:auto;min-width:0}
8
+ .erp-sumtable__empty{text-align:center;color:var(--wp-text-muted)}
9
+ `;
10
+ function SummaryTableStyles() {
11
+ return /* @__PURE__ */ jsx("style", { href: "erp-sumtable", precedence: "medium", children: SUMMARY_TABLE_CSS });
12
+ }
13
+ function cellClass(column) {
14
+ const classes = [];
15
+ if (column.align === "right") classes.push("wp-table__num");
16
+ if (column.mono) classes.push("wp-table__mono");
17
+ if (column.strong) classes.push("wp-table__strong");
18
+ return classes.length > 0 ? classes.join(" ") : void 0;
19
+ }
20
+ function SummaryTable({ columns, rows, footer, dense = false }) {
21
+ const tableClass = dense ? "wp-table wp-table--dense erp-sumtable" : "wp-table erp-sumtable";
22
+ return /* @__PURE__ */ jsxs("div", { className: "erp-sumtable__scroll", children: [
23
+ /* @__PURE__ */ jsx(SummaryTableStyles, {}),
24
+ /* @__PURE__ */ jsxs("table", { className: tableClass, children: [
25
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: columns.map((column) => /* @__PURE__ */ jsx(
26
+ "th",
27
+ {
28
+ style: column.align === "right" ? { textAlign: "right" } : void 0,
29
+ children: column.header
30
+ },
31
+ column.key
32
+ )) }) }),
33
+ /* @__PURE__ */ jsx("tbody", { children: rows.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { className: "erp-sumtable__empty", colSpan: Math.max(columns.length, 1), children: "\uD45C\uC2DC\uD560 \uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4." }) }) : rows.map((row, rowIndex) => /* @__PURE__ */ jsx("tr", { children: columns.map((column) => /* @__PURE__ */ jsx("td", { className: cellClass(column), children: row[column.key] }, column.key)) }, rowIndex)) }),
34
+ footer !== void 0 ? /* @__PURE__ */ jsx("tfoot", { children: /* @__PURE__ */ jsx("tr", { children: columns.map((column) => /* @__PURE__ */ jsx("td", { className: cellClass(column), children: footer[column.key] }, column.key)) }) }) : null
35
+ ] })
36
+ ] });
37
+ }
38
+
39
+ export { SummaryTable };
@@ -0,0 +1,61 @@
1
+ import { Icon } from './chunk-ZUCI34QY.js';
2
+ import { useState, useId, useCallback } from 'react';
3
+ import { jsxs, jsx } from 'react/jsx-runtime';
4
+
5
+ var DISCLOSURE_CSS = `
6
+ .erp-disclosure{min-width:0}
7
+ .erp-disclosure__btn{display:flex;align-items:center;gap:var(--wp-space-2);width:100%;margin:0;padding:var(--wp-space-1) var(--wp-space-2);border:none;background:transparent;border-radius:var(--wp-radius-sm);font:inherit;font-size:var(--wp-size-sm);font-weight:var(--wp-weight-medium);color:var(--wp-text-default);text-align:left;cursor:pointer;transition:var(--wp-transition-control)}
8
+ .erp-disclosure__btn:hover{background:var(--wp-surface-hover);color:var(--wp-text-strong)}
9
+ .erp-disclosure__btn:focus-visible{outline:none;box-shadow:var(--wp-ring-focus)}
10
+ .erp-disclosure__chevron{display:inline-flex;flex:none;color:var(--wp-text-muted);transition:var(--wp-transition-transform)}
11
+ .erp-disclosure__chevron--open{transform:rotate(90deg)}
12
+ .erp-disclosure__summary{flex:1 1 auto;min-width:0}
13
+ .erp-disclosure__content{min-width:0;padding:var(--wp-space-1) var(--wp-space-2) var(--wp-space-2) calc(var(--wp-space-2) + 16px + var(--wp-space-2))}
14
+ `;
15
+ function DisclosureStyles() {
16
+ return /* @__PURE__ */ jsx("style", { href: "erp-disclosure", precedence: "medium", children: DISCLOSURE_CSS });
17
+ }
18
+ function Disclosure({
19
+ summary,
20
+ children,
21
+ defaultOpen = false,
22
+ open,
23
+ onOpenChange
24
+ }) {
25
+ const [internalOpen, setInternalOpen] = useState(defaultOpen);
26
+ const isOpen = open !== void 0 ? open : internalOpen;
27
+ const contentId = useId();
28
+ const hasContent = children !== void 0 && children !== null;
29
+ const toggle = useCallback(() => {
30
+ const next = !isOpen;
31
+ if (open === void 0) setInternalOpen(next);
32
+ onOpenChange?.(next);
33
+ }, [isOpen, open, onOpenChange]);
34
+ return /* @__PURE__ */ jsxs("div", { className: "erp-disclosure", children: [
35
+ /* @__PURE__ */ jsx(DisclosureStyles, {}),
36
+ /* @__PURE__ */ jsxs(
37
+ "button",
38
+ {
39
+ type: "button",
40
+ className: "erp-disclosure__btn",
41
+ "aria-expanded": isOpen,
42
+ "aria-controls": hasContent ? contentId : void 0,
43
+ onClick: toggle,
44
+ children: [
45
+ /* @__PURE__ */ jsx(
46
+ "span",
47
+ {
48
+ className: isOpen ? "erp-disclosure__chevron erp-disclosure__chevron--open" : "erp-disclosure__chevron",
49
+ "aria-hidden": "true",
50
+ children: /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: 16 })
51
+ }
52
+ ),
53
+ /* @__PURE__ */ jsx("span", { className: "erp-disclosure__summary", children: summary })
54
+ ]
55
+ }
56
+ ),
57
+ hasContent ? /* @__PURE__ */ jsx("div", { id: contentId, className: "erp-disclosure__content", hidden: !isOpen, children }) : null
58
+ ] });
59
+ }
60
+
61
+ export { Disclosure };
@@ -0,0 +1,72 @@
1
+ import { Icon, Badge } from './chunk-ZUCI34QY.js';
2
+ import React from 'react';
3
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
+
5
+ var DIFF_CSS = `
6
+ .erp-diff{display:flex;flex-direction:column;gap:var(--wp-space-4);min-width:0;font-size:var(--wp-size-sm)}
7
+ .erp-diff__grid{display:grid;grid-template-columns:minmax(72px,auto) 1fr auto 1fr;gap:var(--wp-space-2) var(--wp-space-3);align-items:center;min-width:0}
8
+ .erp-diff__grid--lists{grid-template-columns:minmax(72px,auto) 1fr;align-items:start}
9
+ .erp-diff__label{color:var(--wp-text-subtle);white-space:nowrap}
10
+ .erp-diff__before{min-width:0;color:var(--wp-text-subtle);text-decoration:line-through;overflow-wrap:anywhere}
11
+ .erp-diff__after{justify-self:start;min-width:0;padding:1px 6px;background:var(--wp-status-success-bg);border-radius:var(--wp-radius-sm);color:var(--wp-text-strong);font-weight:var(--wp-weight-medium);overflow-wrap:anywhere}
12
+ .erp-diff__empty{color:var(--wp-text-subtle);text-decoration:none;background:transparent;padding:0;font-weight:var(--wp-weight-regular)}
13
+ .erp-diff__arrow{display:inline-flex;color:var(--wp-text-subtle)}
14
+ .erp-diff__badges{display:flex;flex-wrap:wrap;gap:var(--wp-space-1);min-width:0;padding-top:1px}
15
+ `;
16
+ function DiffStyles() {
17
+ return /* @__PURE__ */ jsx("style", { href: "erp-diffview", precedence: "medium", children: DIFF_CSS });
18
+ }
19
+ function DiffView({ fields, lists }) {
20
+ const hasFields = fields !== void 0 && fields.length > 0;
21
+ const hasLists = lists !== void 0 && lists.length > 0;
22
+ if (!hasFields && !hasLists) {
23
+ return /* @__PURE__ */ jsx("p", { className: "wp-caption", style: { margin: 0 }, children: "\uBCC0\uACBD \uC0AC\uD56D\uC774 \uC5C6\uC2B5\uB2C8\uB2E4." });
24
+ }
25
+ return /* @__PURE__ */ jsxs("div", { className: "erp-diff", children: [
26
+ /* @__PURE__ */ jsx(DiffStyles, {}),
27
+ hasFields ? /* @__PURE__ */ jsx("div", { className: "erp-diff__grid", children: fields.map((field, index) => {
28
+ const hasBefore = field.before !== void 0 && field.before !== null;
29
+ const hasAfter = field.after !== void 0 && field.after !== null;
30
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
31
+ /* @__PURE__ */ jsx("span", { className: "erp-diff__label", children: field.label }),
32
+ /* @__PURE__ */ jsx(
33
+ "span",
34
+ {
35
+ className: hasBefore ? "erp-diff__before" : "erp-diff__before erp-diff__empty",
36
+ children: hasBefore ? field.before : "\u2014"
37
+ }
38
+ ),
39
+ /* @__PURE__ */ jsx("span", { className: "erp-diff__arrow", "aria-hidden": "true", children: /* @__PURE__ */ jsx(Icon, { name: "arrow-right", size: 14 }) }),
40
+ /* @__PURE__ */ jsx(
41
+ "span",
42
+ {
43
+ className: hasAfter ? "erp-diff__after" : "erp-diff__after erp-diff__empty",
44
+ children: hasAfter ? field.after : "\u2014"
45
+ }
46
+ )
47
+ ] }, `${field.label}-${index}`);
48
+ }) }) : null,
49
+ hasLists ? /* @__PURE__ */ jsx("div", { className: "erp-diff__grid erp-diff__grid--lists", children: lists.map((list, index) => {
50
+ const added = list.added ?? [];
51
+ const removed = list.removed ?? [];
52
+ const kept = list.kept ?? [];
53
+ const isEmpty = added.length === 0 && removed.length === 0 && kept.length === 0;
54
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
55
+ /* @__PURE__ */ jsx("span", { className: "erp-diff__label", children: list.label }),
56
+ /* @__PURE__ */ jsx("span", { className: "erp-diff__badges", children: isEmpty ? /* @__PURE__ */ jsx("span", { className: "wp-caption", children: "\uBCC0\uACBD \uC5C6\uC74C" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
57
+ added.map((value, i) => /* @__PURE__ */ jsxs(Badge, { tone: "success", children: [
58
+ "+ ",
59
+ value
60
+ ] }, `a-${value}-${i}`)),
61
+ removed.map((value, i) => /* @__PURE__ */ jsxs(Badge, { tone: "danger", children: [
62
+ "\u2212 ",
63
+ value
64
+ ] }, `r-${value}-${i}`)),
65
+ kept.map((value, i) => /* @__PURE__ */ jsx(Badge, { tone: "neutral", children: value }, `k-${value}-${i}`))
66
+ ] }) })
67
+ ] }, `${list.label}-${index}`);
68
+ }) }) : null
69
+ ] });
70
+ }
71
+
72
+ export { DiffView };