@wipco/sdui 0.26.0 → 0.27.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,599 @@
1
+ import { includesLooseSearch } from './chunk-BD75U73S.js';
2
+ import { useSduiAdapter, hostFetchOf, defaultAdapter } from './chunk-DVOPZFQS.js';
3
+ import { Icon, Badge, IconButton, Field, Select, Input, Tag, Spinner, Button } from './chunk-WIDDHR7L.js';
4
+ import { boxed } from './chunk-SAN4IX6N.js';
5
+ import React, { useState, useId, useRef, useEffect } from 'react';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
+
8
+ var TYPE_OPTIONS = [
9
+ { value: "team_leader", label: "\uD300\uC7A5" },
10
+ { value: "division_head", label: "\uBCF8\uBD80\uC7A5/\uC2E4\uC7A5" },
11
+ { value: "custom", label: "\uC0AC\uC6A9\uC790 \uC9C0\uC815" }
12
+ ];
13
+ var stepTypeIcon = (type) => {
14
+ switch (type) {
15
+ case "team_leader":
16
+ return "users";
17
+ case "division_head":
18
+ return "building-2";
19
+ default:
20
+ return "user";
21
+ }
22
+ };
23
+ var stepTypeTone = (type) => {
24
+ switch (type) {
25
+ case "team_leader":
26
+ return "brand";
27
+ case "division_head":
28
+ return "info";
29
+ default:
30
+ return "neutral";
31
+ }
32
+ };
33
+ var stepLabel = (step) => {
34
+ const clip = (text) => text.length > 30 ? `${text.substring(0, 30)}\u2026` : text;
35
+ const name = step.name?.trim();
36
+ if (name) return clip(name);
37
+ switch (step.type ?? "custom") {
38
+ case "team_leader":
39
+ return "\uD300\uC7A5";
40
+ case "division_head":
41
+ return "\uBCF8\uBD80\uC7A5/\uC2E4\uC7A5";
42
+ default: {
43
+ const approvers = step.customApprovers ?? [];
44
+ if (approvers.length > 0) return clip(approvers.map((approver) => approver.name).join(", "));
45
+ return "\uC0AC\uC6A9\uC790 \uC9C0\uC815";
46
+ }
47
+ }
48
+ };
49
+ var renumber = (steps) => steps.map((step, index) => ({ ...step, order: index + 1 }));
50
+ var uidCounter = 0;
51
+ var uid = (prefix) => `${prefix}-${Date.now()}-${++uidCounter}`;
52
+ function isRecord(value) {
53
+ return typeof value === "object" && value !== null && !Array.isArray(value);
54
+ }
55
+ function toSearchResults(payload) {
56
+ let rows = [];
57
+ if (Array.isArray(payload)) rows = payload;
58
+ else if (isRecord(payload)) {
59
+ for (const key of ["items", "data", "results", "rows"]) {
60
+ const inner = payload[key];
61
+ if (Array.isArray(inner)) {
62
+ rows = inner;
63
+ break;
64
+ }
65
+ }
66
+ }
67
+ return rows.filter(isRecord).flatMap((row) => {
68
+ const id = row.id;
69
+ const name = row.name ?? row.label;
70
+ if (id === null || id === void 0 || name === null || name === void 0) return [];
71
+ const subRaw = row.sub ?? row.email ?? row.workEmail ?? row.department;
72
+ const sub = isRecord(subRaw) ? subRaw.name : subRaw;
73
+ return [
74
+ {
75
+ id: String(id),
76
+ name: String(name),
77
+ type: row.type === "group" ? "group" : "user",
78
+ sub: sub === null || sub === void 0 ? void 0 : String(sub)
79
+ }
80
+ ];
81
+ });
82
+ }
83
+ var ellipsisStyle = {
84
+ display: "block",
85
+ overflow: "hidden",
86
+ textOverflow: "ellipsis",
87
+ whiteSpace: "nowrap"
88
+ };
89
+ var orderCircleStyle = {
90
+ display: "inline-flex",
91
+ alignItems: "center",
92
+ justifyContent: "center",
93
+ width: 28,
94
+ height: 28,
95
+ flex: "none",
96
+ borderRadius: "var(--wp-radius-pill)",
97
+ background: "var(--wp-surface-brand-tint)",
98
+ color: "var(--wp-text-brand)"
99
+ };
100
+ var dashedEmptyStyle = {
101
+ border: "var(--wp-border-w) dashed var(--wp-border-default)",
102
+ borderRadius: "var(--wp-radius-lg)",
103
+ padding: "var(--wp-space-4)",
104
+ textAlign: "center",
105
+ color: "var(--wp-text-muted)"
106
+ };
107
+ function ApprovalLineEditorImpl({
108
+ value,
109
+ onChange,
110
+ searchEndpoint,
111
+ groupSearchEndpoint,
112
+ options,
113
+ disabled = false
114
+ }) {
115
+ const steps = [...value ?? []].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
116
+ const [newStepType, setNewStepType] = useState("team_leader");
117
+ const [newStepName, setNewStepName] = useState("");
118
+ const [selectedApprovers, setSelectedApprovers] = useState([]);
119
+ const listId = useId();
120
+ const adapter = useSduiAdapter();
121
+ const api = hostFetchOf(adapter) ?? defaultAdapter.fetch;
122
+ const searchHostRef = useRef(null);
123
+ const seqRef = useRef(0);
124
+ const optionsRef = useRef(options);
125
+ optionsRef.current = options;
126
+ const [query, setQuery] = useState("");
127
+ const [searchOpen, setSearchOpen] = useState(false);
128
+ const [searchStatus, setSearchStatus] = useState("idle");
129
+ const [results, setResults] = useState([]);
130
+ const [activeIndex, setActiveIndex] = useState(0);
131
+ const searchListRef = useRef(null);
132
+ useEffect(() => {
133
+ if (!searchOpen) return;
134
+ const box = searchListRef.current;
135
+ const active = box?.querySelector(`#${CSS.escape(`${listId}-opt-${activeIndex}`)}`);
136
+ if (!box || !active) return;
137
+ const top = active.offsetTop;
138
+ const bottom = top + active.offsetHeight;
139
+ if (top < box.scrollTop) box.scrollTop = top;
140
+ else if (bottom > box.scrollTop + box.clientHeight) box.scrollTop = bottom - box.clientHeight;
141
+ }, [searchOpen, activeIndex, listId, results]);
142
+ const [draggedIndex, setDraggedIndex] = useState(null);
143
+ const [dragOverIndex, setDragOverIndex] = useState(null);
144
+ const emit = (next) => onChange?.(renumber(next));
145
+ useEffect(() => {
146
+ if (disabled || newStepType !== "custom") return;
147
+ const keyword = query.trim();
148
+ if (!keyword) {
149
+ seqRef.current += 1;
150
+ setSearchStatus("idle");
151
+ setResults([]);
152
+ setSearchOpen(false);
153
+ return;
154
+ }
155
+ setSearchStatus("loading");
156
+ setSearchOpen(true);
157
+ const seq = ++seqRef.current;
158
+ const timer = setTimeout(() => {
159
+ if (searchEndpoint) {
160
+ const withQ = (endpoint) => `${endpoint}${endpoint.includes("?") ? "&" : "?"}q=${encodeURIComponent(keyword)}`;
161
+ const requests = [
162
+ api(withQ(searchEndpoint), { method: "GET" }).then(
163
+ (payload) => ({ rows: toSearchResults(payload) }),
164
+ (error) => ({ rows: [], error })
165
+ )
166
+ ];
167
+ if (groupSearchEndpoint) {
168
+ requests.push(
169
+ api(withQ(groupSearchEndpoint), { method: "GET" }).then(
170
+ (payload) => ({
171
+ rows: toSearchResults(payload).map((row) => ({ ...row, type: "group" }))
172
+ }),
173
+ (error) => ({ rows: [], error })
174
+ )
175
+ );
176
+ }
177
+ void Promise.all(requests).then((settled) => {
178
+ if (seqRef.current !== seq) return;
179
+ const errors = settled.filter((r) => r.error !== void 0);
180
+ if (errors.length === settled.length) {
181
+ setResults([]);
182
+ setSearchStatus(
183
+ errors.some((r) => r.error?.status === 503) ? "offline" : "error"
184
+ );
185
+ return;
186
+ }
187
+ setResults(settled.flatMap((r) => r.rows));
188
+ setActiveIndex(0);
189
+ setSearchStatus("ready");
190
+ });
191
+ return;
192
+ }
193
+ const filtered = (optionsRef.current ?? []).filter(
194
+ (option) => includesLooseSearch(option.name, keyword)
195
+ );
196
+ if (seqRef.current !== seq) return;
197
+ setResults(filtered);
198
+ setActiveIndex(0);
199
+ setSearchStatus("ready");
200
+ }, 300);
201
+ return () => clearTimeout(timer);
202
+ }, [query, searchEndpoint, groupSearchEndpoint, newStepType, disabled]);
203
+ useEffect(() => {
204
+ if (!searchOpen) return;
205
+ const closeOnOutsideClick = (event) => {
206
+ if (event.target instanceof Node && searchHostRef.current?.contains(event.target)) return;
207
+ setSearchOpen(false);
208
+ };
209
+ const closeOnEscape = (event) => {
210
+ if (event.key === "Escape") setSearchOpen(false);
211
+ };
212
+ document.addEventListener("pointerdown", closeOnOutsideClick);
213
+ document.addEventListener("keydown", closeOnEscape);
214
+ return () => {
215
+ document.removeEventListener("pointerdown", closeOnOutsideClick);
216
+ document.removeEventListener("keydown", closeOnEscape);
217
+ };
218
+ }, [searchOpen]);
219
+ const addApprover = (result) => {
220
+ setSelectedApprovers(
221
+ (current) => current.some((approver) => approver.id === result.id) ? current : [...current, { id: result.id, name: result.name, type: result.type }]
222
+ );
223
+ setQuery("");
224
+ setResults([]);
225
+ setSearchOpen(false);
226
+ setSearchStatus("idle");
227
+ };
228
+ const removeApprover = (id) => {
229
+ setSelectedApprovers((current) => current.filter((approver) => approver.id !== id));
230
+ };
231
+ const handleSearchKeyDown = (event) => {
232
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") {
233
+ event.preventDefault();
234
+ if (!searchOpen || results.length === 0) return;
235
+ setActiveIndex((index) => {
236
+ const delta = event.key === "ArrowDown" ? 1 : -1;
237
+ return (index + delta + results.length) % results.length;
238
+ });
239
+ return;
240
+ }
241
+ if (event.key === "Enter") {
242
+ event.preventDefault();
243
+ if (searchOpen && searchStatus === "ready") {
244
+ const active = results[activeIndex];
245
+ if (active) addApprover(active);
246
+ }
247
+ return;
248
+ }
249
+ if (event.key === "Escape") setSearchOpen(false);
250
+ };
251
+ const customWithoutApprovers = newStepType === "custom" && selectedApprovers.length === 0;
252
+ const addStep = () => {
253
+ if (disabled || customWithoutApprovers) return;
254
+ const newStep = {
255
+ id: uid("step"),
256
+ type: newStepType,
257
+ // 이름은 선택 — 넣으면 결재 화면의 단계 표시명으로 그대로 쓰인다.
258
+ name: newStepName.trim() || void 0,
259
+ customApprovers: newStepType === "custom" ? selectedApprovers : void 0,
260
+ order: steps.length + 1
261
+ };
262
+ emit([...steps, newStep]);
263
+ setNewStepType("team_leader");
264
+ setNewStepName("");
265
+ setSelectedApprovers([]);
266
+ setQuery("");
267
+ setResults([]);
268
+ setSearchOpen(false);
269
+ setSearchStatus("idle");
270
+ };
271
+ const removeStep = (id) => {
272
+ emit(steps.filter((step) => step.id !== id));
273
+ };
274
+ const moveStep = (index, direction) => {
275
+ const target = index + direction;
276
+ if (target < 0 || target >= steps.length) return;
277
+ const next = [...steps];
278
+ [next[index], next[target]] = [next[target], next[index]];
279
+ emit(next);
280
+ };
281
+ const handleDrop = (event, dropIndex) => {
282
+ event.preventDefault();
283
+ setDragOverIndex(null);
284
+ if (draggedIndex === null || draggedIndex === dropIndex) {
285
+ setDraggedIndex(null);
286
+ return;
287
+ }
288
+ const next = [...steps];
289
+ const [dragged] = next.splice(draggedIndex, 1);
290
+ next.splice(dropIndex, 0, dragged);
291
+ emit(next);
292
+ setDraggedIndex(null);
293
+ };
294
+ return /* @__PURE__ */ jsxs("div", { className: "wp-col", style: { gap: "var(--wp-space-4)" }, children: [
295
+ /* @__PURE__ */ jsxs("div", { className: "wp-col", style: { gap: "var(--wp-space-2)" }, children: [
296
+ /* @__PURE__ */ jsx("span", { className: "wp-label", children: "\uD604\uC7AC \uACB0\uC7AC\uC120" }),
297
+ steps.length === 0 ? /* @__PURE__ */ jsx("div", { className: "wp-body-sm", style: dashedEmptyStyle, children: "\uC124\uC815\uB41C \uACB0\uC7AC \uB2E8\uACC4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 \uC774\uB300\uB85C \uC800\uC7A5\uD558\uBA74 \uC790\uB3D9 \uC2B9\uC778\uB429\uB2C8\uB2E4." }) : steps.map((step, index) => /* @__PURE__ */ jsxs(
298
+ "div",
299
+ {
300
+ className: "wp-row",
301
+ onDragOver: (event) => {
302
+ event.preventDefault();
303
+ event.dataTransfer.dropEffect = "move";
304
+ },
305
+ onDragEnter: (event) => {
306
+ event.preventDefault();
307
+ if (draggedIndex !== null && draggedIndex !== index) setDragOverIndex(index);
308
+ },
309
+ onDragLeave: (event) => {
310
+ if (!event.currentTarget.contains(event.relatedTarget)) {
311
+ setDragOverIndex(null);
312
+ }
313
+ },
314
+ onDrop: (event) => handleDrop(event, index),
315
+ style: {
316
+ border: `var(--wp-border-w) solid ${dragOverIndex === index ? "var(--wp-border-brand)" : "var(--wp-border-subtle)"}`,
317
+ borderRadius: "var(--wp-radius-lg)",
318
+ background: dragOverIndex === index ? "var(--wp-surface-selected)" : "var(--wp-surface-card)",
319
+ padding: "var(--wp-space-2) var(--wp-space-3)",
320
+ opacity: draggedIndex === index ? 0.5 : void 0
321
+ },
322
+ children: [
323
+ /* @__PURE__ */ jsx(
324
+ "span",
325
+ {
326
+ draggable: !disabled,
327
+ title: disabled ? "\uBE44\uD65C\uC131\uD654\uB428" : "\uB4DC\uB798\uADF8\uD558\uC5EC \uC21C\uC11C \uBCC0\uACBD",
328
+ onDragStart: (event) => {
329
+ setDraggedIndex(index);
330
+ event.dataTransfer.effectAllowed = "move";
331
+ event.dataTransfer.setData("text/plain", String(index));
332
+ },
333
+ onDragEnd: () => {
334
+ setDraggedIndex(null);
335
+ setDragOverIndex(null);
336
+ },
337
+ style: {
338
+ display: "inline-flex",
339
+ flex: "none",
340
+ color: "var(--wp-text-muted)",
341
+ cursor: disabled ? "not-allowed" : "grab"
342
+ },
343
+ children: /* @__PURE__ */ jsx(Icon, { name: "move", size: 16 })
344
+ }
345
+ ),
346
+ /* @__PURE__ */ jsx("span", { className: "wp-body-sm", style: orderCircleStyle, children: index + 1 }),
347
+ /* @__PURE__ */ jsx(
348
+ Icon,
349
+ {
350
+ name: stepTypeIcon(step.type),
351
+ size: 16,
352
+ style: { color: "var(--wp-text-muted)", flex: "none" }
353
+ }
354
+ ),
355
+ /* @__PURE__ */ jsx("div", { className: "wp-row", style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx(Badge, { tone: stepTypeTone(step.type), children: stepLabel(step) }) }),
356
+ /* @__PURE__ */ jsxs("div", { className: "wp-row", style: { flex: "none", gap: "var(--wp-space-1)" }, children: [
357
+ /* @__PURE__ */ jsx(
358
+ IconButton,
359
+ {
360
+ type: "button",
361
+ icon: "chevron-up",
362
+ label: "\uC704\uB85C \uC774\uB3D9",
363
+ size: "sm",
364
+ disabled: disabled || index === 0,
365
+ onClick: () => moveStep(index, -1)
366
+ }
367
+ ),
368
+ /* @__PURE__ */ jsx(
369
+ IconButton,
370
+ {
371
+ type: "button",
372
+ icon: "chevron-down",
373
+ label: "\uC544\uB798\uB85C \uC774\uB3D9",
374
+ size: "sm",
375
+ disabled: disabled || index === steps.length - 1,
376
+ onClick: () => moveStep(index, 1)
377
+ }
378
+ ),
379
+ /* @__PURE__ */ jsx(
380
+ IconButton,
381
+ {
382
+ type: "button",
383
+ icon: "trash-2",
384
+ label: "\uB2E8\uACC4 \uC0AD\uC81C",
385
+ variant: "danger",
386
+ size: "sm",
387
+ disabled,
388
+ onClick: () => removeStep(step.id)
389
+ }
390
+ )
391
+ ] })
392
+ ]
393
+ },
394
+ step.id
395
+ ))
396
+ ] }),
397
+ /* @__PURE__ */ jsxs("div", { className: "wp-col", style: { gap: "var(--wp-space-2)" }, children: [
398
+ /* @__PURE__ */ jsx("span", { className: "wp-label", children: "\uACB0\uC7AC \uB2E8\uACC4 \uCD94\uAC00" }),
399
+ /* @__PURE__ */ jsxs("div", { className: "wp-row", style: { alignItems: "flex-start", flexWrap: "wrap" }, children: [
400
+ /* @__PURE__ */ jsx("div", { style: { width: 180 }, children: /* @__PURE__ */ jsx(Field, { label: "\uACB0\uC7AC\uC790 \uC720\uD615", children: /* @__PURE__ */ jsx(
401
+ Select,
402
+ {
403
+ options: TYPE_OPTIONS,
404
+ value: newStepType,
405
+ disabled,
406
+ onChange: (event) => {
407
+ const nextType = event.target.value;
408
+ setNewStepType(nextType);
409
+ if (nextType !== "custom") {
410
+ setSelectedApprovers([]);
411
+ setQuery("");
412
+ setResults([]);
413
+ setSearchOpen(false);
414
+ setSearchStatus("idle");
415
+ }
416
+ }
417
+ }
418
+ ) }) }),
419
+ /* @__PURE__ */ jsx("div", { style: { flex: 1, minWidth: 220 }, children: /* @__PURE__ */ jsx(Field, { label: "\uB2E8\uACC4 \uC774\uB984 (\uC120\uD0DD)", hint: "\uBE44\uC6CC \uB450\uBA74 \uACB0\uC7AC\uC790 \uC720\uD615 \uC774\uB984\uC774 \uD45C\uC2DC\uB429\uB2C8\uB2E4.", children: /* @__PURE__ */ jsx(
420
+ Input,
421
+ {
422
+ value: newStepName,
423
+ disabled,
424
+ placeholder: "\uC608: \uC778\uC0AC \uB2F4\uB2F9\uC790 \uACB0\uC7AC",
425
+ onKeyDown: (event) => {
426
+ if (event.key === "Enter") event.preventDefault();
427
+ },
428
+ onChange: (event) => setNewStepName(event.target.value)
429
+ }
430
+ ) }) })
431
+ ] }),
432
+ newStepType === "custom" ? /* @__PURE__ */ jsxs("div", { className: "wp-col", style: { gap: "var(--wp-space-2)" }, children: [
433
+ /* @__PURE__ */ jsx("span", { className: "wp-caption", children: "\uACB0\uC7AC\uC790\uB97C \uAC80\uC0C9\uD558\uC5EC \uC120\uD0DD\uD558\uC138\uC694 (\uC5EC\uB7EC \uBA85 \uC120\uD0DD \uAC00\uB2A5)" }),
434
+ selectedApprovers.length > 0 ? /* @__PURE__ */ jsx(
435
+ "div",
436
+ {
437
+ className: "wp-row",
438
+ style: {
439
+ flexWrap: "wrap",
440
+ gap: "var(--wp-space-1)",
441
+ border: "var(--wp-border-w) solid var(--wp-border-subtle)",
442
+ borderRadius: "var(--wp-radius-control)",
443
+ background: "var(--wp-surface-sunken)",
444
+ padding: "var(--wp-space-2)"
445
+ },
446
+ children: selectedApprovers.map((approver) => /* @__PURE__ */ jsxs(
447
+ Tag,
448
+ {
449
+ onRemove: disabled ? void 0 : () => removeApprover(approver.id),
450
+ children: [
451
+ /* @__PURE__ */ jsx(
452
+ Icon,
453
+ {
454
+ name: approver.type === "user" ? "user" : "users",
455
+ size: 12,
456
+ style: { marginRight: "var(--wp-space-1)" }
457
+ }
458
+ ),
459
+ approver.name
460
+ ]
461
+ },
462
+ approver.id
463
+ ))
464
+ }
465
+ ) : null,
466
+ /* @__PURE__ */ jsxs("div", { ref: searchHostRef, className: "erp-popover-host", style: { maxWidth: 420 }, children: [
467
+ /* @__PURE__ */ jsx(
468
+ Input,
469
+ {
470
+ role: "combobox",
471
+ "aria-expanded": searchOpen,
472
+ "aria-controls": listId,
473
+ "aria-autocomplete": "list",
474
+ "aria-activedescendant": searchOpen && searchStatus === "ready" && results.length > 0 ? `${listId}-opt-${activeIndex}` : void 0,
475
+ icon: "search",
476
+ placeholder: "\uC0AC\uC6A9\uC790 \uB610\uB294 \uADF8\uB8F9 \uAC80\uC0C9",
477
+ disabled,
478
+ value: query,
479
+ onChange: (event) => setQuery(event.target.value),
480
+ onFocus: () => {
481
+ if (query.trim()) setSearchOpen(true);
482
+ },
483
+ onKeyDown: handleSearchKeyDown
484
+ }
485
+ ),
486
+ searchOpen ? /* @__PURE__ */ jsx("div", { className: "erp-popover erp-popover--left", style: { width: "100%" }, children: /* @__PURE__ */ jsx(
487
+ "div",
488
+ {
489
+ id: listId,
490
+ role: "listbox",
491
+ ref: searchListRef,
492
+ className: "erp-popover__body",
493
+ style: {
494
+ maxHeight: 260,
495
+ overflowY: "auto",
496
+ overscrollBehavior: "contain",
497
+ padding: "var(--wp-space-1)"
498
+ },
499
+ children: searchStatus === "loading" ? /* @__PURE__ */ jsx("div", { className: "wp-row", style: { padding: "var(--wp-space-2) var(--wp-space-3)" }, children: /* @__PURE__ */ jsx(Spinner, { size: "sm", label: "\uAC80\uC0C9 \uC911\u2026" }) }) : searchStatus === "offline" ? /* @__PURE__ */ jsxs("div", { className: "wp-row", style: { padding: "var(--wp-space-2) var(--wp-space-3)" }, children: [
500
+ /* @__PURE__ */ jsx(Icon, { name: "unplug", size: 16, style: { color: "var(--wp-text-muted)", flex: "none" } }),
501
+ /* @__PURE__ */ jsx("span", { className: "wp-caption", children: "\uBC31\uC5D4\uB4DC \uBBF8\uC5F0\uB3D9 \u2014 \uAC80\uC0C9 \uACB0\uACFC\uB97C \uBD88\uB7EC\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4" })
502
+ ] }) : searchStatus === "error" ? /* @__PURE__ */ jsxs("div", { className: "wp-row", style: { padding: "var(--wp-space-2) var(--wp-space-3)" }, children: [
503
+ /* @__PURE__ */ jsx(Icon, { name: "circle-alert", size: 16, style: { color: "var(--wp-text-danger)", flex: "none" } }),
504
+ /* @__PURE__ */ jsx("span", { className: "wp-caption", children: "\uAC80\uC0C9 \uC2E4\uD328 \u2014 \uC7A0\uC2DC \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574 \uC8FC\uC138\uC694" })
505
+ ] }) : results.length === 0 ? /* @__PURE__ */ jsx("div", { className: "wp-caption", style: { padding: "var(--wp-space-2) var(--wp-space-3)" }, children: "\uACB0\uACFC \uC5C6\uC74C" }) : results.map((result, index) => /* @__PURE__ */ jsxs(
506
+ "button",
507
+ {
508
+ id: `${listId}-opt-${index}`,
509
+ type: "button",
510
+ role: "option",
511
+ "aria-selected": index === activeIndex,
512
+ onClick: () => addApprover(result),
513
+ onPointerEnter: () => setActiveIndex(index),
514
+ className: "wp-row",
515
+ style: {
516
+ width: "100%",
517
+ textAlign: "left",
518
+ padding: "var(--wp-space-2) var(--wp-space-3)",
519
+ border: 0,
520
+ borderRadius: "var(--wp-radius-sm)",
521
+ background: index === activeIndex ? "var(--wp-surface-hover)" : "transparent",
522
+ color: "var(--wp-text-default)",
523
+ font: "inherit",
524
+ cursor: "pointer"
525
+ },
526
+ children: [
527
+ /* @__PURE__ */ jsx(
528
+ Icon,
529
+ {
530
+ name: result.type === "user" ? "user" : "users",
531
+ size: 16,
532
+ style: { color: "var(--wp-text-muted)", flex: "none" }
533
+ }
534
+ ),
535
+ /* @__PURE__ */ jsxs("span", { style: { flex: 1, minWidth: 0 }, children: [
536
+ /* @__PURE__ */ jsx("span", { className: "wp-body-sm", style: ellipsisStyle, children: result.name }),
537
+ result.sub ? /* @__PURE__ */ jsx("span", { className: "wp-caption", style: ellipsisStyle, children: result.sub }) : null
538
+ ] }),
539
+ /* @__PURE__ */ jsx(Badge, { tone: result.type === "user" ? "neutral" : "info", children: result.type === "user" ? "\uC0AC\uC6A9\uC790" : "\uADF8\uB8F9" })
540
+ ]
541
+ },
542
+ `${result.type}-${result.id}`
543
+ ))
544
+ }
545
+ ) }) : null
546
+ ] })
547
+ ] }) : null,
548
+ /* @__PURE__ */ jsx("div", { className: "wp-row", children: /* @__PURE__ */ jsx(
549
+ Button,
550
+ {
551
+ type: "button",
552
+ variant: "secondary",
553
+ icon: "plus",
554
+ disabled: disabled || customWithoutApprovers,
555
+ title: disabled ? "\uBE44\uD65C\uC131\uD654\uB428" : customWithoutApprovers ? "\uACB0\uC7AC\uC790\uB97C \uD55C \uBA85 \uC774\uC0C1 \uC120\uD0DD\uD574\uC57C \uCD94\uAC00\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4" : void 0,
556
+ onClick: addStep,
557
+ children: "\uCD94\uAC00"
558
+ }
559
+ ) })
560
+ ] }),
561
+ /* @__PURE__ */ jsxs("div", { className: "wp-col", style: { gap: "var(--wp-space-2)" }, children: [
562
+ /* @__PURE__ */ jsx("span", { className: "wp-label", children: "\uACB0\uC7AC \uC21C\uC11C \uBBF8\uB9AC\uBCF4\uAE30" }),
563
+ /* @__PURE__ */ jsx(
564
+ "div",
565
+ {
566
+ style: {
567
+ background: "var(--wp-surface-sunken)",
568
+ borderRadius: "var(--wp-radius-lg)",
569
+ padding: "var(--wp-space-3)"
570
+ },
571
+ children: steps.length === 0 ? /* @__PURE__ */ jsx("span", { className: "wp-caption", children: "\uACB0\uC7AC\uC120\uC774 \uC5EC\uAE30\uC5D0 \uD45C\uC2DC\uB429\uB2C8\uB2E4." }) : /* @__PURE__ */ jsx("div", { className: "wp-row", style: { flexWrap: "wrap", gap: "var(--wp-space-1)" }, children: steps.map((step, index) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
572
+ /* @__PURE__ */ jsxs(Tag, { children: [
573
+ /* @__PURE__ */ jsx(
574
+ Icon,
575
+ {
576
+ name: stepTypeIcon(step.type),
577
+ size: 12,
578
+ style: { marginRight: "var(--wp-space-1)" }
579
+ }
580
+ ),
581
+ stepLabel(step)
582
+ ] }),
583
+ index < steps.length - 1 ? /* @__PURE__ */ jsx(
584
+ Icon,
585
+ {
586
+ name: "arrow-right",
587
+ size: 14,
588
+ style: { color: "var(--wp-text-muted)", flex: "none" }
589
+ }
590
+ ) : null
591
+ ] }, step.id)) })
592
+ }
593
+ )
594
+ ] })
595
+ ] });
596
+ }
597
+ var ApprovalLineEditor = boxed(ApprovalLineEditorImpl, "ApprovalLineEditor");
598
+
599
+ export { ApprovalLineEditor, stepLabel, stepTypeIcon };