@wipco/sdui 1.3.0 → 1.4.1

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 (36) hide show
  1. package/dist/{chunk-HBBTENSV.js → chunk-44TDRCKR.js} +1 -1
  2. package/dist/{chunk-7FZTUI6U.js → chunk-BEM2YS7U.js} +1 -1
  3. package/dist/{chunk-B6WMC2AN.js → chunk-CXW6KT6X.js} +1 -1
  4. package/dist/{chunk-GE6BYNQJ.js → chunk-DKVSM5HX.js} +1 -1
  5. package/dist/{chunk-N25YP7ID.js → chunk-FNMS7OB7.js} +1 -1
  6. package/dist/chunk-GNA6SX2H.js +253 -0
  7. package/dist/{chunk-C37U3GCC.js → chunk-GZBY7I4Y.js} +1 -1
  8. package/dist/{chunk-AC5TI3BE.js → chunk-HBIIEYKW.js} +1 -1
  9. package/dist/{chunk-FLAN7CV3.js → chunk-MPT7WJG2.js} +1 -1
  10. package/dist/{chunk-5XPZ3RSA.js → chunk-NIJUVTEW.js} +1 -1
  11. package/dist/{chunk-7BGDSSAN.js → chunk-OQ52XMGG.js} +1 -1
  12. package/dist/chunk-RIZRM7OO.js +8 -0
  13. package/dist/{chunk-WSLT32Q4.js → chunk-RWSH2MBU.js} +3 -5
  14. package/dist/{chunk-WOYMEEPH.js → chunk-UV6HHFEW.js} +1 -1
  15. package/dist/{chunk-37SFFW37.js → chunk-WPSK2CB5.js} +11 -1
  16. package/dist/index.d.ts +11 -0
  17. package/dist/index.js +26 -15
  18. package/dist/meta.d.ts +4 -2
  19. package/dist/meta.js +87 -2
  20. package/dist/rich.js +2 -2
  21. package/dist/styles.css +1 -0
  22. package/dist/widgets/ApprovalLineEditor.js +4 -3
  23. package/dist/widgets/ApprovalOverridesEditor.js +5 -4
  24. package/dist/widgets/AutocompleteField.js +4 -3
  25. package/dist/widgets/OptionSchemaEditor.js +2 -2
  26. package/dist/widgets/OptionValueFields.js +2 -2
  27. package/dist/widgets/PeriodFilter.js +3 -2
  28. package/dist/widgets/SearchableMultiPicker.js +4 -3
  29. package/dist/widgets/StagePeriodEditor.js +3 -2
  30. package/dist/widgets/TagInput.d.ts +49 -0
  31. package/dist/widgets/TagInput.js +4 -0
  32. package/dist/widgets/TreePicker.js +5 -4
  33. package/dist/widgets/TreeView.js +4 -3
  34. package/dist/widgets/index.d.ts +4 -1
  35. package/dist/widgets/index.js +26 -22
  36. package/package.json +5 -1
@@ -1,4 +1,4 @@
1
- import { DateRangePicker } from './chunk-WSLT32Q4.js';
1
+ import { DateRangePicker } from './chunk-RWSH2MBU.js';
2
2
  import { SegmentedControl, Select } from './chunk-RNOUXUBO.js';
3
3
  import { boxed } from './chunk-5WW4MBRO.js';
4
4
  import { useState, useMemo } from 'react';
@@ -1,4 +1,4 @@
1
- import { Text } from './chunk-37SFFW37.js';
1
+ import { Text } from './chunk-WPSK2CB5.js';
2
2
  import { Switch, Field, Select, Input } from './chunk-RNOUXUBO.js';
3
3
  import { boxed } from './chunk-5WW4MBRO.js';
4
4
  import React, { useMemo } from 'react';
@@ -1,4 +1,4 @@
1
- import { Text } from './chunk-37SFFW37.js';
1
+ import { Text } from './chunk-WPSK2CB5.js';
2
2
  import { Field, Input, Select, IconButton, Button } from './chunk-RNOUXUBO.js';
3
3
  import { boxed } from './chunk-5WW4MBRO.js';
4
4
  import { useMemo } from 'react';
@@ -1,5 +1,5 @@
1
1
  import { TagMultiSelect } from './chunk-I5SD7XRA.js';
2
- import { ApprovalLineEditor, stepTypeIcon, stepLabel } from './chunk-FLAN7CV3.js';
2
+ import { ApprovalLineEditor, stepTypeIcon, stepLabel } from './chunk-MPT7WJG2.js';
3
3
  import { orderCircleStyle, unwrapRows, uid } from './chunk-Q4SWUINA.js';
4
4
  import { useSduiAdapter, hostFetchOf, defaultAdapter } from './chunk-KO6OEY3G.js';
5
5
  import { Card, Icon, Input, IconButton, Field, Button, Badge } from './chunk-RNOUXUBO.js';
@@ -1,5 +1,5 @@
1
1
  import { ellipsisStyle, unwrapRows } from './chunk-Q4SWUINA.js';
2
- import { includesLooseSearch } from './chunk-WOYMEEPH.js';
2
+ import { includesLooseSearch } from './chunk-UV6HHFEW.js';
3
3
  import { useSduiAdapter, hostFetchOf } from './chunk-KO6OEY3G.js';
4
4
  import { Icon, Button, Input, Spinner } from './chunk-RNOUXUBO.js';
5
5
  import { boxed } from './chunk-5WW4MBRO.js';
@@ -0,0 +1,253 @@
1
+ import { HoistedStyle } from './chunk-RIZRM7OO.js';
2
+ import { Tag } from './chunk-RNOUXUBO.js';
3
+ import { boxed } from './chunk-5WW4MBRO.js';
4
+ import { useState, useMemo, useRef, useEffect } from 'react';
5
+ import { jsxs, jsx } from 'react/jsx-runtime';
6
+
7
+ var TAG_INPUT_CSS = `
8
+ .wp-taginput{position:relative;display:flex;flex-wrap:wrap;align-items:center;gap:4px;min-height:32px;width:100%;padding:3px 8px;font-size:13px;color:var(--wp-text-default);background:var(--wp-surface-card);border:1px solid var(--wp-border-default);border-radius:var(--wp-radius-md);cursor:text;transition:border-color .12s,box-shadow .12s;box-sizing:border-box}
9
+ .wp-taginput:focus-within{border-color:var(--wp-border-focus);box-shadow:0 0 0 3px rgba(10,115,201,.15)}
10
+ .wp-taginput--disabled{background:var(--wp-surface-disabled);color:var(--wp-text-disabled);cursor:not-allowed}
11
+ .wp-taginput__input{flex:1 1 80px;min-width:80px;height:24px;border:0;outline:0;background:transparent;font:inherit;color:inherit;padding:0 2px}
12
+ .wp-taginput__input::placeholder{color:var(--wp-text-subtle)}
13
+ .wp-taginput__input:disabled{cursor:not-allowed}
14
+ .wp-taginput__menu{position:absolute;left:-1px;right:-1px;top:calc(100% + 4px);z-index:30;margin:0;padding:4px;list-style:none;max-height:220px;overflow:auto;background:var(--wp-surface-card);border:1px solid var(--wp-border-default);border-radius:var(--wp-radius-md);box-shadow:var(--wp-shadow-md,0 6px 20px rgba(0,0,0,.12))}
15
+ .wp-taginput__option{display:flex;align-items:center;justify-content:space-between;gap:var(--wp-space-2);padding:5px 8px;border-radius:var(--wp-radius-sm);font-size:13px;cursor:pointer}
16
+ .wp-taginput__option:hover,.wp-taginput__option--active{background:var(--wp-surface-hover,var(--wp-slate-100))}
17
+ .wp-taginput__count{font-size:11.5px;color:var(--wp-text-subtle);font-family:var(--wp-font-mono)}
18
+ `;
19
+ function normalizeKeyword(raw, maxLength = 50) {
20
+ if (raw === null || raw === void 0) return null;
21
+ const text = String(raw).replace(/^[\s#]+/, "").replace(/\s+/g, " ").trim();
22
+ if (!text) return null;
23
+ return text.length > maxLength ? text.slice(0, maxLength) : text;
24
+ }
25
+ function normalizeKeywords(list, options = {}) {
26
+ const source = Array.isArray(list) ? list : [];
27
+ const seen = /* @__PURE__ */ new Set();
28
+ const out = [];
29
+ for (const raw of source) {
30
+ const word = normalizeKeyword(raw, options.maxLength);
31
+ if (!word) continue;
32
+ const key = word.toLowerCase();
33
+ if (seen.has(key)) continue;
34
+ seen.add(key);
35
+ out.push(word);
36
+ if (options.maxItems !== void 0 && out.length >= options.maxItems) break;
37
+ }
38
+ return out;
39
+ }
40
+ function splitKeywordText(text) {
41
+ return text.split(/[,\n\t]|\s+(?=#)/).map((part) => part.trim()).filter((part) => part.length > 0);
42
+ }
43
+ function foldSuggestions(raw, key = "keyword") {
44
+ if (!Array.isArray(raw)) return [];
45
+ const out = [];
46
+ for (const item of raw) {
47
+ if (typeof item === "string" || typeof item === "number") {
48
+ const word2 = normalizeKeyword(item);
49
+ if (word2) out.push({ keyword: word2 });
50
+ continue;
51
+ }
52
+ if (item === null || typeof item !== "object") continue;
53
+ const row = item;
54
+ const word = normalizeKeyword(row[key] ?? row.value ?? row.label);
55
+ if (!word) continue;
56
+ const count = typeof row.count === "number" ? row.count : void 0;
57
+ out.push(count === void 0 ? { keyword: word } : { keyword: word, count });
58
+ }
59
+ return out;
60
+ }
61
+ function TagInputImpl({
62
+ value,
63
+ onChange,
64
+ placeholder = "\uD0A4\uC6CC\uB4DC \uC785\uB825 \uD6C4 Enter",
65
+ disabled = false,
66
+ suggestions,
67
+ suggestionKey = "keyword",
68
+ maxItems,
69
+ maxLength = 50,
70
+ hash = true,
71
+ maxSuggestions = 8
72
+ }) {
73
+ const isControlled = value !== void 0 && typeof onChange === "function";
74
+ const [internal, setInternal] = useState(() => normalizeKeywords(value));
75
+ const current = useMemo(
76
+ () => normalizeKeywords(isControlled ? value : internal, { maxLength }),
77
+ [isControlled, value, internal, maxLength]
78
+ );
79
+ const [draft, setDraft] = useState("");
80
+ const [focused, setFocused] = useState(false);
81
+ const [active, setActive] = useState(-1);
82
+ const inputRef = useRef(null);
83
+ const onChangeRef = useRef(onChange);
84
+ onChangeRef.current = onChange;
85
+ const commit = (next) => {
86
+ const normalized = normalizeKeywords(next, { maxItems, maxLength });
87
+ setInternal(normalized);
88
+ onChangeRef.current?.(normalized);
89
+ };
90
+ const folded = useMemo(() => foldSuggestions(suggestions, suggestionKey), [suggestions, suggestionKey]);
91
+ const visible = useMemo(() => {
92
+ if (folded.length === 0) return [];
93
+ const taken = new Set(current.map((word) => word.toLowerCase()));
94
+ const needle = normalizeKeyword(draft)?.toLowerCase() ?? "";
95
+ const seen = /* @__PURE__ */ new Set();
96
+ const out = [];
97
+ for (const item of folded) {
98
+ const key = item.keyword.toLowerCase();
99
+ if (taken.has(key) || seen.has(key)) continue;
100
+ if (needle && !key.includes(needle)) continue;
101
+ seen.add(key);
102
+ out.push(item);
103
+ if (out.length >= maxSuggestions) break;
104
+ }
105
+ return out;
106
+ }, [folded, current, draft, maxSuggestions]);
107
+ useEffect(() => {
108
+ if (active >= visible.length) setActive(visible.length - 1);
109
+ }, [visible.length, active]);
110
+ const full = maxItems !== void 0 && current.length >= maxItems;
111
+ const menuOpen = focused && !disabled && !full && visible.length > 0;
112
+ const addWords = (words) => {
113
+ if (disabled) return;
114
+ const cleaned = words.map((word) => normalizeKeyword(word, maxLength)).filter((w) => !!w);
115
+ if (cleaned.length === 0) return;
116
+ commit([...current, ...cleaned]);
117
+ setDraft("");
118
+ setActive(-1);
119
+ };
120
+ const removeAt = (index) => {
121
+ if (disabled) return;
122
+ commit(current.filter((_, i) => i !== index));
123
+ inputRef.current?.focus();
124
+ };
125
+ const commitDraft = () => {
126
+ const words = splitKeywordText(draft);
127
+ if (words.length > 0) addWords(words);
128
+ else if (draft) setDraft("");
129
+ };
130
+ const onKeyDown = (event) => {
131
+ if (disabled) return;
132
+ switch (event.key) {
133
+ case "Enter": {
134
+ event.preventDefault();
135
+ if (menuOpen && active >= 0 && active < visible.length) {
136
+ addWords([visible[active].keyword]);
137
+ } else {
138
+ commitDraft();
139
+ }
140
+ return;
141
+ }
142
+ case ",": {
143
+ event.preventDefault();
144
+ commitDraft();
145
+ return;
146
+ }
147
+ case "Tab": {
148
+ if (draft.trim()) {
149
+ event.preventDefault();
150
+ commitDraft();
151
+ }
152
+ return;
153
+ }
154
+ case "Backspace": {
155
+ if (draft === "" && current.length > 0) {
156
+ event.preventDefault();
157
+ removeAt(current.length - 1);
158
+ }
159
+ return;
160
+ }
161
+ case "ArrowDown": {
162
+ if (!menuOpen) return;
163
+ event.preventDefault();
164
+ setActive((index) => (index + 1) % visible.length);
165
+ return;
166
+ }
167
+ case "ArrowUp": {
168
+ if (!menuOpen) return;
169
+ event.preventDefault();
170
+ setActive((index) => index <= 0 ? visible.length - 1 : index - 1);
171
+ return;
172
+ }
173
+ case "Escape": {
174
+ if (menuOpen || draft) {
175
+ event.preventDefault();
176
+ event.stopPropagation();
177
+ setActive(-1);
178
+ setDraft("");
179
+ }
180
+ return;
181
+ }
182
+ default:
183
+ return;
184
+ }
185
+ };
186
+ const onPaste = (event) => {
187
+ const text = event.clipboardData.getData("text");
188
+ if (!/[,\n\t#]/.test(text)) return;
189
+ event.preventDefault();
190
+ addWords(splitKeywordText(`${draft}${text}`));
191
+ };
192
+ return /* @__PURE__ */ jsxs(
193
+ "div",
194
+ {
195
+ className: ["wp-taginput", disabled && "wp-taginput--disabled"].filter(Boolean).join(" "),
196
+ onMouseDown: (event) => {
197
+ if (event.target === event.currentTarget) {
198
+ event.preventDefault();
199
+ inputRef.current?.focus();
200
+ }
201
+ },
202
+ children: [
203
+ /* @__PURE__ */ jsx(HoistedStyle, { id: "wp-taginput", css: TAG_INPUT_CSS }),
204
+ current.map((word, index) => /* @__PURE__ */ jsx(Tag, { onRemove: disabled ? void 0 : () => removeAt(index), children: hash ? `#${word}` : word }, `${word}-${index}`)),
205
+ /* @__PURE__ */ jsx(
206
+ "input",
207
+ {
208
+ ref: inputRef,
209
+ className: "wp-taginput__input",
210
+ type: "text",
211
+ role: "combobox",
212
+ "aria-expanded": menuOpen,
213
+ "aria-autocomplete": "list",
214
+ value: draft,
215
+ disabled: disabled || full,
216
+ placeholder: current.length === 0 ? placeholder : full ? "" : void 0,
217
+ onChange: (event) => {
218
+ setDraft(event.target.value);
219
+ setActive(-1);
220
+ },
221
+ onKeyDown,
222
+ onPaste,
223
+ onFocus: () => setFocused(true),
224
+ onBlur: () => {
225
+ setFocused(false);
226
+ commitDraft();
227
+ }
228
+ }
229
+ ),
230
+ menuOpen ? /* @__PURE__ */ jsx("ul", { className: "wp-taginput__menu", role: "listbox", children: visible.map((item, index) => /* @__PURE__ */ jsxs(
231
+ "li",
232
+ {
233
+ role: "option",
234
+ "aria-selected": index === active,
235
+ className: ["wp-taginput__option", index === active && "wp-taginput__option--active"].filter(Boolean).join(" "),
236
+ onMouseDown: (event) => {
237
+ event.preventDefault();
238
+ addWords([item.keyword]);
239
+ },
240
+ children: [
241
+ /* @__PURE__ */ jsx("span", { children: hash ? `#${item.keyword}` : item.keyword }),
242
+ item.count !== void 0 ? /* @__PURE__ */ jsx("span", { className: "wp-taginput__count", children: item.count }) : null
243
+ ]
244
+ },
245
+ item.keyword
246
+ )) }) : null
247
+ ]
248
+ }
249
+ );
250
+ }
251
+ var TagInput = boxed(TagInputImpl, "TagInput");
252
+
253
+ export { TagInput, foldSuggestions, normalizeKeyword, normalizeKeywords, splitKeywordText };
@@ -1,4 +1,4 @@
1
- import { buildCascadingTree } from './chunk-WOYMEEPH.js';
1
+ import { buildCascadingTree } from './chunk-UV6HHFEW.js';
2
2
  import { Input, IconButton, EmptyState, Icon, Badge } from './chunk-RNOUXUBO.js';
3
3
  import { boxed } from './chunk-5WW4MBRO.js';
4
4
  import React, { useMemo, useState, useRef, useEffect } from 'react';
@@ -1,4 +1,4 @@
1
- import { includesLooseSearch } from './chunk-WOYMEEPH.js';
1
+ import { includesLooseSearch } from './chunk-UV6HHFEW.js';
2
2
  import { OverlayLayer } from './chunk-XQPTSEJC.js';
3
3
  import { Button, Dialog, Input, Tag, Checkbox } from './chunk-RNOUXUBO.js';
4
4
  import { boxed } from './chunk-5WW4MBRO.js';
@@ -1,5 +1,5 @@
1
1
  import { orderCircleStyle, ellipsisStyle, unwrapRows, uid } from './chunk-Q4SWUINA.js';
2
- import { includesLooseSearch } from './chunk-WOYMEEPH.js';
2
+ import { includesLooseSearch } from './chunk-UV6HHFEW.js';
3
3
  import { useSduiAdapter, hostFetchOf, defaultAdapter } from './chunk-KO6OEY3G.js';
4
4
  import { Icon, Badge, IconButton, Field, Select, Input, Tag, Spinner, Button, isPlainObject } from './chunk-RNOUXUBO.js';
5
5
  import { boxed } from './chunk-5WW4MBRO.js';
@@ -1,4 +1,4 @@
1
- import { DatePicker, TimePicker } from './chunk-WSLT32Q4.js';
1
+ import { DatePicker, TimePicker } from './chunk-RWSH2MBU.js';
2
2
  import { Field } from './chunk-RNOUXUBO.js';
3
3
  import { boxed } from './chunk-5WW4MBRO.js';
4
4
  import { useState, useRef, useEffect, useMemo } from 'react';
@@ -1,4 +1,4 @@
1
- import { resolveTreeNodes, TreeView } from './chunk-C37U3GCC.js';
1
+ import { resolveTreeNodes, TreeView } from './chunk-GZBY7I4Y.js';
2
2
  import { OverlayLayer } from './chunk-XQPTSEJC.js';
3
3
  import { Field, Dialog, Icon, Button, Input } from './chunk-RNOUXUBO.js';
4
4
  import { boxed } from './chunk-5WW4MBRO.js';
@@ -0,0 +1,8 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+
3
+ // src/hoisted-style.tsx
4
+ function HoistedStyle({ id, css }) {
5
+ return /* @__PURE__ */ jsx("style", { href: id, precedence: "medium", children: css });
6
+ }
7
+
8
+ export { HoistedStyle };
@@ -1,13 +1,11 @@
1
+ import { HoistedStyle } from './chunk-RIZRM7OO.js';
1
2
  import { useOverlayLayer, OverlayContainerContext, getOverlayRoot } from './chunk-XQPTSEJC.js';
2
3
  import { Icon } from './chunk-RNOUXUBO.js';
3
4
  import { boxed } from './chunk-5WW4MBRO.js';
4
5
  import React, { useState, useRef, useEffect, useMemo, useCallback, useLayoutEffect } from 'react';
5
- import { jsxs, jsx } from 'react/jsx-runtime';
6
6
  import { createPortal } from 'react-dom';
7
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
8
 
8
- function HoistedStyle({ id, css }) {
9
- return /* @__PURE__ */ jsx("style", { href: id, precedence: "medium", children: css });
10
- }
11
9
  var ANCHOR_GAP = 8;
12
10
  var VIEWPORT_EDGE = 8;
13
11
  function anchorTo(host, height) {
@@ -993,4 +991,4 @@ var DP_CSS = `
993
991
  var DatePicker = boxed(DatePickerImpl, "DatePicker");
994
992
  var DateRangePicker = boxed(DateRangePickerImpl, "DateRangePicker");
995
993
 
996
- export { DatePicker, DateRangePicker, HoistedStyle, TimePicker, YMD_RE, parseYmd };
994
+ export { DatePicker, DateRangePicker, TimePicker, YMD_RE, parseYmd };
@@ -1,4 +1,4 @@
1
- import { DateRangePicker } from './chunk-WSLT32Q4.js';
1
+ import { DateRangePicker } from './chunk-RWSH2MBU.js';
2
2
  import { useOverlayLayer } from './chunk-XQPTSEJC.js';
3
3
  import { Input, Button, IconButton, Tag, Field, Checkbox } from './chunk-RNOUXUBO.js';
4
4
  import { useRef, useEffect, useState, useMemo } from 'react';
@@ -138,7 +138,17 @@ function Text({
138
138
  function KeyValueList({ source, items, className, style }) {
139
139
  return /* @__PURE__ */ jsx("div", { className: joinClass("wp-kv", className), style, children: (items ?? []).map((item, index) => {
140
140
  const raw = item.key ? source?.[item.key] : item.value;
141
- const content = raw === null || raw === void 0 || raw === "" ? "\u2014" : raw;
141
+ const scalarList = Array.isArray(raw) && raw.every((entry) => typeof entry === "string" || typeof entry === "number");
142
+ let content;
143
+ if (scalarList) {
144
+ const words = raw.map(String).filter((word) => word !== "");
145
+ content = words.length === 0 ? "\u2014" : /* @__PURE__ */ jsx("span", { className: "wp-kv__tags", children: words.map((word, wordIndex) => /* @__PURE__ */ jsxs("span", { className: "wp-tag", children: [
146
+ item.prefix ?? "",
147
+ word
148
+ ] }, `${word}-${wordIndex}`)) });
149
+ } else {
150
+ content = raw === null || raw === void 0 || raw === "" ? "\u2014" : raw;
151
+ }
142
152
  return /* @__PURE__ */ jsxs(React.Fragment, { children: [
143
153
  /* @__PURE__ */ jsx("span", { className: "wp-kv__k", children: item.label }),
144
154
  /* @__PURE__ */ jsx("span", { className: joinClass("wp-kv__v", item.mono && "wp-mono"), children: content })
package/dist/index.d.ts CHANGED
@@ -1004,6 +1004,11 @@ interface SduiTagCell {
1004
1004
  type: 'tag';
1005
1005
  colorMap?: Record<string, string>;
1006
1006
  filled?: boolean;
1007
+ /**
1008
+ * 각 태그 앞에 붙일 글자(예: `#`). 값이 **배열**이면 원소마다 태그 하나씩 그린다 —
1009
+ * 키워드 열(text[])이 그 자리다. 톤 조회 키는 접두어 없는 원래 값이다.
1010
+ */
1011
+ prefix?: string;
1007
1012
  }
1008
1013
  /**
1009
1014
  * 값을 링크로. `to`는 `/assets/{id}` 처럼 행의 필드를 `{키}`로 끼워 넣는 경로 템플릿이고,
@@ -1433,6 +1438,12 @@ interface KeyValueItem {
1433
1438
  key?: string;
1434
1439
  value?: React__default.ReactNode;
1435
1440
  mono?: boolean;
1441
+ /**
1442
+ * 값이 **문자열·숫자 배열**이면 태그(.wp-tag)로 그린다 — 키워드(text[]) 열이 그 자리다.
1443
+ * 그때 각 태그 앞에 붙일 글자(예: `#`). 배열이 비면 다른 빈 값처럼 `—`.
1444
+ * 배열을 그냥 노드로 흘리면 React 가 원소를 구분자 없이 이어 붙여 "ab" 처럼 보인다.
1445
+ */
1446
+ prefix?: string;
1436
1447
  }
1437
1448
  interface KeyValueListProps {
1438
1449
  /** 값의 원천 객체 — 보통 상태 바인딩({ "$state": "selectedOrder" })을 넣는다 */
package/dist/index.js CHANGED
@@ -1,14 +1,15 @@
1
1
  export { loadOptionalModule } from './chunk-YVTV4ZV6.js';
2
2
  import { useSduiDispatch, SduiDialog, useSduiCan, SduiDispatchContext, SduiPermissionProvider } from './chunk-TFGNKFL2.js';
3
3
  export { SduiDialog, SduiPermissionProvider, useSduiCan, useSduiDispatch } from './chunk-TFGNKFL2.js';
4
- import { Text, Spacer, Show, Section, Row, PageHead, KeyValueList, Grid, Divider, Col, Actions } from './chunk-37SFFW37.js';
5
- export { Actions, Col, Divider, Grid, KeyValueList, PageHead, Row, Section, Show, Spacer, Text } from './chunk-37SFFW37.js';
4
+ import { Text, Spacer, Show, Section, Row, PageHead, KeyValueList, Grid, Divider, Col, Actions } from './chunk-WPSK2CB5.js';
5
+ export { Actions, Col, Divider, Grid, KeyValueList, PageHead, Row, Section, Show, Spacer, Text } from './chunk-WPSK2CB5.js';
6
6
  import { ImageViewer } from './chunk-SAPBDJJQ.js';
7
7
  export { ImageViewer } from './chunk-SAPBDJJQ.js';
8
- import { normalizeSearchFields, searchValuesFromParams, splitMultiValue, includesLooseSearch, cascadingValuePaths, SearchToolbar, searchFieldKeys, Popover } from './chunk-WOYMEEPH.js';
9
- export { SearchToolbar, cascadingValuePaths, cleanSearchValues, includesLooseSearch, joinMultiValue, normalizeSearchText, searchFieldKeys, searchValuesFromParams, splitMultiValue } from './chunk-WOYMEEPH.js';
10
- import { HoistedStyle, parseYmd, YMD_RE, TimePicker, DateRangePicker, DatePicker } from './chunk-WSLT32Q4.js';
11
- export { DatePicker, DateRangePicker, TimePicker } from './chunk-WSLT32Q4.js';
8
+ import { normalizeSearchFields, searchValuesFromParams, splitMultiValue, includesLooseSearch, cascadingValuePaths, SearchToolbar, searchFieldKeys, Popover } from './chunk-UV6HHFEW.js';
9
+ export { SearchToolbar, cascadingValuePaths, cleanSearchValues, includesLooseSearch, joinMultiValue, normalizeSearchText, searchFieldKeys, searchValuesFromParams, splitMultiValue } from './chunk-UV6HHFEW.js';
10
+ import { parseYmd, YMD_RE, TimePicker, DateRangePicker, DatePicker } from './chunk-RWSH2MBU.js';
11
+ export { DatePicker, DateRangePicker, TimePicker } from './chunk-RWSH2MBU.js';
12
+ import { HoistedStyle } from './chunk-RIZRM7OO.js';
12
13
  export { OverlayContainerContext, OverlayLayer, getOverlayRoot, useOverlayLayer } from './chunk-XQPTSEJC.js';
13
14
  import { DEV, isSafeNavigationTarget, useSduiAdapter, hostFetchOf, useSduiSandbox, resolveAdapter, assetResolverOf, SduiAdapterContext } from './chunk-KO6OEY3G.js';
14
15
  export { defaultAdapter, useSduiAssetResolver, useSduiSandbox } from './chunk-KO6OEY3G.js';
@@ -273,9 +274,20 @@ function cellRenderer(cell, key, dispatch) {
273
274
  };
274
275
  case "tag":
275
276
  return (row) => {
276
- const value = String(fieldOf(row, key) ?? "");
277
- if (!value) return null;
278
- return /* @__PURE__ */ jsx(Tag, { color: cell.colorMap?.[value], filled: cell.filled, children: value });
277
+ const raw = fieldOf(row, key);
278
+ const values = (Array.isArray(raw) ? raw : [raw]).filter((item) => item !== null && item !== void 0 && item !== "").map(String);
279
+ if (values.length === 0) return null;
280
+ const prefix = cell.prefix ?? "";
281
+ if (values.length === 1 && !Array.isArray(raw)) {
282
+ return /* @__PURE__ */ jsxs(Tag, { color: cell.colorMap?.[values[0]], filled: cell.filled, children: [
283
+ prefix,
284
+ values[0]
285
+ ] });
286
+ }
287
+ return /* @__PURE__ */ jsx("span", { className: "wp-cell-tags", children: values.map((value, index) => /* @__PURE__ */ jsxs(Tag, { color: cell.colorMap?.[value], filled: cell.filled, children: [
288
+ prefix,
289
+ value
290
+ ] }, `${value}-${index}`)) });
279
291
  };
280
292
  case "link":
281
293
  return (row) => {
@@ -584,6 +596,10 @@ function resolveViewItems(views, disableGrid, disableList) {
584
596
  }
585
597
  return items.length > 0 ? items : [DEFAULT_VIEWS[0]];
586
598
  }
599
+ function localSearchText(row) {
600
+ const scalar = (v) => typeof v === "string" || typeof v === "number";
601
+ return Object.values(row ?? {}).flatMap((v) => Array.isArray(v) ? v.filter(scalar) : scalar(v) ? [v] : []).join(" ");
602
+ }
587
603
  function SearchResults({
588
604
  item,
589
605
  columns,
@@ -660,12 +676,7 @@ function SearchResults({
660
676
  let rows = item.data;
661
677
  if (hasAllRows) {
662
678
  if (appliedSearch) {
663
- rows = rows.filter(
664
- (row) => includesLooseSearch(
665
- Object.values(row).filter((v) => typeof v === "string" || typeof v === "number").join(" "),
666
- appliedSearch
667
- )
668
- );
679
+ rows = rows.filter((row) => includesLooseSearch(localSearchText(row), appliedSearch));
669
680
  }
670
681
  for (const { key, values } of activeFilters) {
671
682
  rows = rows.filter((row) => values.includes(String(cell(row, key))));
package/dist/meta.d.ts CHANGED
@@ -399,7 +399,7 @@ declare const richComponentMeta: {
399
399
  };
400
400
 
401
401
  /**
402
- * `@wipco/sdui/widgets` 어휘 37종의 빌더 메타데이터.
402
+ * `@wipco/sdui/widgets` 어휘 38종의 빌더 메타데이터.
403
403
  *
404
404
  * core와 파일을 나눈 이유는 `rich.ts`와 같다 — 위젯을 얹지 않은 소비자가 이 데이터를
405
405
  * 받지 않게 하려는 것이다. 여기도 값 import는 없다(`import type`만).
@@ -443,6 +443,7 @@ declare const InlineEditMeta: SduiComponentMeta;
443
443
  declare const JsonFieldMeta: SduiComponentMeta;
444
444
  declare const PeriodFilterMeta: SduiComponentMeta;
445
445
  declare const SearchableMultiPickerMeta: SduiComponentMeta;
446
+ declare const TagInputMeta: SduiComponentMeta;
446
447
  declare const TagMultiSelectMeta: SduiComponentMeta;
447
448
  declare const TreePickerMeta: SduiComponentMeta;
448
449
  declare const DisclosureMeta: SduiComponentMeta;
@@ -505,6 +506,7 @@ declare const widgetComponentMeta: {
505
506
  StackedMeter: SduiComponentMeta;
506
507
  Strip: SduiComponentMeta;
507
508
  SummaryTable: SduiComponentMeta;
509
+ TagInput: SduiComponentMeta;
508
510
  TagMultiSelect: SduiComponentMeta;
509
511
  Timeline: SduiComponentMeta;
510
512
  TreePicker: SduiComponentMeta;
@@ -633,4 +635,4 @@ declare function paletteGroups(catalog?: Record<string, SduiComponentMeta>): Arr
633
635
  items: SduiComponentMeta[];
634
636
  }>;
635
637
 
636
- export { ActionsMeta, AlertMeta, ApprovalLineEditorMeta, ApprovalOverridesEditorMeta, ApprovalStepperMeta, AutocompleteFieldMeta, AvatarMeta, BadgeMeta, BreadcrumbMeta, ButtonMeta, CanMeta, CardMeta, ChartMeta, CheckboxMeta, ColMeta, ColumnBoardMeta, DatePickerMeta, DateRangePickerMeta, DialogMeta, DiffViewMeta, DisclosureMeta, DividerMeta, EmptyStateMeta, EventCalendarMeta, ExcelUploadCardMeta, FieldMeta, FileDropzoneMeta, ForEachMeta, FormMeta, FragmentMeta, GridMeta, IconButtonMeta, IconMeta, ImageLightboxMeta, InlineEditMeta, InputMeta, JsonFieldMeta, KeyValueListMeta, LiveClockMeta, MapPreviewMeta, OptionSchemaEditorMeta, OptionValueFieldsMeta, OrgChartBoardMeta, OrgChartMeta, PageHeadMeta, PaginationMeta, PeriodFilterMeta, PermissionMatrixEditorMeta, PositionSelectMeta, PrintSheetMeta, ProfileEditDiffCardMeta, ProgressBarMeta, QRDisplayMeta, RadioMeta, RankBoardMeta, RecordSheetMeta, RemoteSearchResultsMeta, RoleMemberPickerMeta, 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, StagePeriodEditorMeta, StatCardMeta, StripMeta, SummaryTableMeta, SwitchMeta, TableMeta, TabsMeta, TagMeta, TagMultiSelectMeta, TextMeta, TextareaMeta, TimePickerMeta, TimelineMeta, ToastMeta, TooltipMeta, TreePickerMeta, TreeViewMeta, allComponentMeta, builtinComponentMeta, coreComponentMeta, dsComponentMeta, getComponentMeta, metaSlotNames, paletteGroups, richComponentMeta, slotNamesOf, widgetComponentMeta, withSelfAxis, withSelfAxisAll };
638
+ export { ActionsMeta, AlertMeta, ApprovalLineEditorMeta, ApprovalOverridesEditorMeta, ApprovalStepperMeta, AutocompleteFieldMeta, AvatarMeta, BadgeMeta, BreadcrumbMeta, ButtonMeta, CanMeta, CardMeta, ChartMeta, CheckboxMeta, ColMeta, ColumnBoardMeta, DatePickerMeta, DateRangePickerMeta, DialogMeta, DiffViewMeta, DisclosureMeta, DividerMeta, EmptyStateMeta, EventCalendarMeta, ExcelUploadCardMeta, FieldMeta, FileDropzoneMeta, ForEachMeta, FormMeta, FragmentMeta, GridMeta, IconButtonMeta, IconMeta, ImageLightboxMeta, InlineEditMeta, InputMeta, JsonFieldMeta, KeyValueListMeta, LiveClockMeta, MapPreviewMeta, OptionSchemaEditorMeta, OptionValueFieldsMeta, OrgChartBoardMeta, OrgChartMeta, PageHeadMeta, PaginationMeta, PeriodFilterMeta, PermissionMatrixEditorMeta, PositionSelectMeta, PrintSheetMeta, ProfileEditDiffCardMeta, ProgressBarMeta, QRDisplayMeta, RadioMeta, RankBoardMeta, RecordSheetMeta, RemoteSearchResultsMeta, RoleMemberPickerMeta, 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, StagePeriodEditorMeta, StatCardMeta, StripMeta, SummaryTableMeta, SwitchMeta, TableMeta, TabsMeta, TagInputMeta, TagMeta, TagMultiSelectMeta, TextMeta, TextareaMeta, TimePickerMeta, TimelineMeta, ToastMeta, TooltipMeta, TreePickerMeta, TreeViewMeta, allComponentMeta, builtinComponentMeta, coreComponentMeta, dsComponentMeta, getComponentMeta, metaSlotNames, paletteGroups, richComponentMeta, slotNamesOf, widgetComponentMeta, withSelfAxis, withSelfAxisAll };
package/dist/meta.js CHANGED
@@ -1654,7 +1654,13 @@ var KeyValueListMeta = {
1654
1654
  { name: "label", kind: "node", label: "\uB77C\uBCA8", required: true },
1655
1655
  { name: "key", kind: "string", label: "source\uC758 \uD544\uB4DC", description: "\uC0DD\uB7B5\uD558\uBA74 value\uB97C \uADF8\uB300\uB85C \uC4F4\uB2E4." },
1656
1656
  { name: "value", kind: "node", label: "\uAC12", bindable: true },
1657
- { name: "mono", kind: "boolean", label: "\uACE0\uC815\uD3ED \uAE00\uAF34" }
1657
+ { name: "mono", kind: "boolean", label: "\uACE0\uC815\uD3ED \uAE00\uAF34" },
1658
+ {
1659
+ name: "prefix",
1660
+ kind: "string",
1661
+ label: "\uD0DC\uADF8 \uC811\uB450\uC5B4",
1662
+ description: "\uAC12\uC774 \uBB38\uC790\uC5F4 \uBC30\uC5F4\uC774\uBA74 \uD0DC\uADF8\uB85C \uADF8\uB9B0\uB2E4 \u2014 \uADF8\uB54C \uAC01 \uC55E\uC5D0 \uBD99\uC77C \uAE00\uC790(\uC608: #). \uBE48 \uBC30\uC5F4\uC740 \u2014."
1663
+ }
1658
1664
  ]
1659
1665
  },
1660
1666
  styleProp,
@@ -1995,6 +2001,12 @@ var searchCellFields = [
1995
2001
  { value: "image", label: "\uC0AC\uC9C4" }
1996
2002
  ]
1997
2003
  },
2004
+ {
2005
+ name: "prefix",
2006
+ kind: "string",
2007
+ label: "\uD0DC\uADF8 \uC811\uB450\uC5B4",
2008
+ description: "type=tag \u2014 \uAC01 \uD0DC\uADF8 \uC55E\uC5D0 \uBD99\uC77C \uAE00\uC790(\uC608: #). \uAC12\uC774 \uBC30\uC5F4\uC774\uBA74 \uC6D0\uC18C\uB9C8\uB2E4 \uD0DC\uADF8 \uD558\uB098\uC529 \uADF8\uB9B0\uB2E4(\uD0A4\uC6CC\uB4DC \uC5F4)."
2009
+ },
1998
2010
  { name: "width", kind: "number", label: "\uC0AC\uC9C4 \uAC00\uB85C(px)", description: "type=image (\uAE30\uBCF8 72)" },
1999
2011
  { name: "height", kind: "number", label: "\uC0AC\uC9C4 \uC138\uB85C(px)", description: "type=image (\uAE30\uBCF8 52)" },
2000
2012
  {
@@ -4813,6 +4825,78 @@ var SearchableMultiPickerMeta = {
4813
4825
  },
4814
4826
  resize: { kind: "none" }
4815
4827
  };
4828
+ var TagInputMeta = {
4829
+ name: "TagInput",
4830
+ label: "\uD0A4\uC6CC\uB4DC \uC785\uB825",
4831
+ category: "input",
4832
+ icon: "tag",
4833
+ description: "\uB0B1\uB9D0\uC744 \uC9C1\uC811 \uC801\uC5B4 \uCE69(#\uD0A4\uC6CC\uB4DC)\uC73C\uB85C \uC313\uB294 \uC790\uC720 \uC785\uB825. Enter\xB7\uC27C\uD45C\uAC00 \uD655\uC815\uD558\uACE0, \uCD94\uCC9C \uBAA9\uB85D\uC744 \uC8FC\uBA74 \uC774\uBBF8 \uC4F0\uB294 \uD0A4\uC6CC\uB4DC\uB85C \uD45C\uAE30\uAC00 \uBAA8\uC778\uB2E4.",
4834
+ props: [
4835
+ {
4836
+ name: "value",
4837
+ kind: "array",
4838
+ label: "\uD0A4\uC6CC\uB4DC",
4839
+ required: true,
4840
+ bindable: true,
4841
+ description: '\uBB38\uC790\uC5F4 \uBC30\uC5F4. \uBCF4\uD1B5 { "$state": "form.keywords" }\uB97C \uAC74\uB2E4. \uAC12\uC5D0\uB294 # \uC744 \uB123\uC9C0 \uC54A\uB294\uB2E4(\uC55E\uC758 # \uC740 \uBC97\uAE34\uB2E4).',
4842
+ group: "data",
4843
+ item: [],
4844
+ itemKind: "string"
4845
+ },
4846
+ { name: "onChange", kind: "action", label: "\uBCC0\uACBD", eventArg: "\uD0A4\uC6CC\uB4DC \uBB38\uC790\uC5F4 \uBC30\uC5F4", group: "behavior" },
4847
+ { name: "placeholder", kind: "string", label: "\uC548\uB0B4 \uBB38\uAD6C", default: "\uD0A4\uC6CC\uB4DC \uC785\uB825 \uD6C4 Enter", group: "content" },
4848
+ {
4849
+ name: "suggestions",
4850
+ kind: "array",
4851
+ label: "\uCD94\uCC9C \uD0A4\uC6CC\uB4DC",
4852
+ bindable: true,
4853
+ description: "\uC785\uB825 \uC911\uC5D0 \uC544\uB798\uB85C \uD3BC\uCE60 \uD6C4\uBCF4. \uBB38\uC790\uC5F4 \uBC30\uC5F4\uC774\uAC70\uB098 {keyword, count} \uAC1D\uCCB4 \uBC30\uC5F4(page.data \uB85C /finance/keywords \uAC19\uC740 \uC9D1\uACC4\uB97C \uBB3C\uB9B0\uB2E4). \uC774\uBBF8 \uB2E8 \uAC83\uC740 \uBE7C\uACE0 \uBCF4\uC5EC \uC900\uB2E4.",
4854
+ group: "data",
4855
+ item: [],
4856
+ itemKind: "string"
4857
+ },
4858
+ {
4859
+ name: "suggestionKey",
4860
+ kind: "string",
4861
+ label: "\uCD94\uCC9C \uB0B1\uB9D0 \uD0A4",
4862
+ default: "keyword",
4863
+ description: "\uCD94\uCC9C\uC774 \uAC1D\uCCB4 \uBC30\uC5F4\uC77C \uB54C \uB0B1\uB9D0\uC744 \uC77D\uC744 \uD0A4. \uC5C6\uC73C\uBA74 value \u2192 label \uC21C\uC73C\uB85C \uBCF8\uB2E4.",
4864
+ group: "data",
4865
+ advanced: true
4866
+ },
4867
+ { name: "maxItems", kind: "number", label: "\uCD5C\uB300 \uAC1C\uC218", description: "\uB118\uC73C\uBA74 \uB354 \uBC1B\uC9C0 \uC54A\uB294\uB2E4.", group: "behavior" },
4868
+ {
4869
+ name: "maxLength",
4870
+ kind: "number",
4871
+ label: "\uB0B1\uB9D0 \uCD5C\uB300 \uAE00\uC790",
4872
+ default: 50,
4873
+ description: "\uB118\uB294 \uAE00\uC790\uB294 \uC798\uB77C \uB2F4\uB294\uB2E4.",
4874
+ group: "behavior",
4875
+ advanced: true
4876
+ },
4877
+ { name: "hash", kind: "boolean", label: "# \uD45C\uAE30", default: true, description: "\uCE69 \uC55E\uC5D0 # \uC744 \uADF8\uB9B0\uB2E4. \uAC12 \uC790\uCCB4\uC5D0\uB294 \uB123\uC9C0 \uC54A\uB294\uB2E4.", group: "content" },
4878
+ {
4879
+ name: "maxSuggestions",
4880
+ kind: "number",
4881
+ label: "\uCD94\uCC9C \uCD5C\uB300 \uC904 \uC218",
4882
+ default: 8,
4883
+ group: "behavior",
4884
+ advanced: true
4885
+ },
4886
+ { name: "disabled", kind: "boolean", label: "\uBE44\uD65C\uC131", default: false, bindable: true, group: "behavior" }
4887
+ ],
4888
+ children: { accepts: false },
4889
+ dom: { element: "div" },
4890
+ preset: {
4891
+ component: "TagInput",
4892
+ props: {
4893
+ value: { $state: "keywords", default: [] },
4894
+ onChange: { action: "setState", key: "keywords", fromEvent: true },
4895
+ placeholder: "\uD0A4\uC6CC\uB4DC \uC785\uB825 \uD6C4 Enter"
4896
+ }
4897
+ },
4898
+ resize: { kind: "none" }
4899
+ };
4816
4900
  var TagMultiSelectMeta = {
4817
4901
  name: "TagMultiSelect",
4818
4902
  label: "\uD0DC\uADF8 \uB2E4\uC911 \uC120\uD0DD",
@@ -5968,6 +6052,7 @@ var widgetComponentMeta = {
5968
6052
  StackedMeter: StackedMeterMeta,
5969
6053
  Strip: StripMeta,
5970
6054
  SummaryTable: SummaryTableMeta,
6055
+ TagInput: TagInputMeta,
5971
6056
  TagMultiSelect: TagMultiSelectMeta,
5972
6057
  Timeline: TimelineMeta,
5973
6058
  TreePicker: TreePickerMeta,
@@ -6018,4 +6103,4 @@ function paletteGroups(catalog = allComponentMeta) {
6018
6103
  })).filter((group) => group.items.length > 0);
6019
6104
  }
6020
6105
 
6021
- export { ActionsMeta, AlertMeta, ApprovalLineEditorMeta, ApprovalOverridesEditorMeta, ApprovalStepperMeta, AutocompleteFieldMeta, AvatarMeta, BadgeMeta, BreadcrumbMeta, ButtonMeta, CanMeta, CardMeta, ChartMeta, CheckboxMeta, ColMeta, ColumnBoardMeta, DatePickerMeta, DateRangePickerMeta, DialogMeta, DiffViewMeta, DisclosureMeta, DividerMeta, EmptyStateMeta, EventCalendarMeta, ExcelUploadCardMeta, FieldMeta, FileDropzoneMeta, ForEachMeta, FormMeta, FragmentMeta, GridMeta, IconButtonMeta, IconMeta, ImageLightboxMeta, InlineEditMeta, InputMeta, JsonFieldMeta, KeyValueListMeta, LiveClockMeta, MapPreviewMeta, OptionSchemaEditorMeta, OptionValueFieldsMeta, OrgChartBoardMeta, OrgChartMeta, PageHeadMeta, PaginationMeta, PeriodFilterMeta, PermissionMatrixEditorMeta, PositionSelectMeta, PrintSheetMeta, ProfileEditDiffCardMeta, ProgressBarMeta, QRDisplayMeta, RadioMeta, RankBoardMeta, RecordSheetMeta, RemoteSearchResultsMeta, RoleMemberPickerMeta, RowMeta, SDUI_CATEGORIES, SELF_AXIS_PROPS, SearchResultsMeta, SearchableMultiPickerMeta, SectionMeta, SecureScreenMeta, SegmentedControlMeta, SelectMeta, ShowMeta, SidebarNavMeta, SortHandleMeta, SortableListMeta, SpacerMeta, SpinnerMeta, StackedMeterMeta, StagePeriodEditorMeta, StatCardMeta, StripMeta, SummaryTableMeta, SwitchMeta, TableMeta, TabsMeta, TagMeta, TagMultiSelectMeta, TextMeta, TextareaMeta, TimePickerMeta, TimelineMeta, ToastMeta, TooltipMeta, TreePickerMeta, TreeViewMeta, allComponentMeta, builtinComponentMeta, coreComponentMeta, dsComponentMeta, getComponentMeta, metaSlotNames, paletteGroups, richComponentMeta, slotNamesOf, widgetComponentMeta, withSelfAxis, withSelfAxisAll };
6106
+ export { ActionsMeta, AlertMeta, ApprovalLineEditorMeta, ApprovalOverridesEditorMeta, ApprovalStepperMeta, AutocompleteFieldMeta, AvatarMeta, BadgeMeta, BreadcrumbMeta, ButtonMeta, CanMeta, CardMeta, ChartMeta, CheckboxMeta, ColMeta, ColumnBoardMeta, DatePickerMeta, DateRangePickerMeta, DialogMeta, DiffViewMeta, DisclosureMeta, DividerMeta, EmptyStateMeta, EventCalendarMeta, ExcelUploadCardMeta, FieldMeta, FileDropzoneMeta, ForEachMeta, FormMeta, FragmentMeta, GridMeta, IconButtonMeta, IconMeta, ImageLightboxMeta, InlineEditMeta, InputMeta, JsonFieldMeta, KeyValueListMeta, LiveClockMeta, MapPreviewMeta, OptionSchemaEditorMeta, OptionValueFieldsMeta, OrgChartBoardMeta, OrgChartMeta, PageHeadMeta, PaginationMeta, PeriodFilterMeta, PermissionMatrixEditorMeta, PositionSelectMeta, PrintSheetMeta, ProfileEditDiffCardMeta, ProgressBarMeta, QRDisplayMeta, RadioMeta, RankBoardMeta, RecordSheetMeta, RemoteSearchResultsMeta, RoleMemberPickerMeta, RowMeta, SDUI_CATEGORIES, SELF_AXIS_PROPS, SearchResultsMeta, SearchableMultiPickerMeta, SectionMeta, SecureScreenMeta, SegmentedControlMeta, SelectMeta, ShowMeta, SidebarNavMeta, SortHandleMeta, SortableListMeta, SpacerMeta, SpinnerMeta, StackedMeterMeta, StagePeriodEditorMeta, StatCardMeta, StripMeta, SummaryTableMeta, SwitchMeta, TableMeta, TabsMeta, TagInputMeta, TagMeta, TagMultiSelectMeta, TextMeta, TextareaMeta, TimePickerMeta, TimelineMeta, ToastMeta, TooltipMeta, TreePickerMeta, TreeViewMeta, allComponentMeta, builtinComponentMeta, coreComponentMeta, dsComponentMeta, getComponentMeta, metaSlotNames, paletteGroups, richComponentMeta, slotNamesOf, widgetComponentMeta, withSelfAxis, withSelfAxisAll };
package/dist/rich.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { useOptionalModule, DependencyPlaceholder } from './chunk-YVTV4ZV6.js';
2
- import { HoistedStyle } from './chunk-WSLT32Q4.js';
3
- export { DatePicker, DateRangePicker, TimePicker } from './chunk-WSLT32Q4.js';
2
+ export { DatePicker, DateRangePicker, TimePicker } from './chunk-RWSH2MBU.js';
3
+ import { HoistedStyle } from './chunk-RIZRM7OO.js';
4
4
  import './chunk-XQPTSEJC.js';
5
5
  import { useSduiAssetResolver } from './chunk-KO6OEY3G.js';
6
6
  import { Spinner, EmptyState } from './chunk-RNOUXUBO.js';
package/dist/styles.css CHANGED
@@ -361,6 +361,7 @@
361
361
  .wp-kv { display: grid; grid-template-columns: minmax(96px, auto) 1fr; gap: 7px var(--wp-space-4); align-items: baseline; }
362
362
  .wp-kv__k { font-size: 12px; font-weight: 600; color: var(--wp-text-muted); }
363
363
  .wp-kv__v { font-size: 13px; color: var(--wp-text-default); min-width: 0; overflow-wrap: anywhere; }
364
+ .wp-kv__tags, .wp-cell-tags { display: inline-flex; flex-wrap: wrap; gap: 4px; vertical-align: middle; }
364
365
 
365
366
  /* ---------- 버튼 ---------- */
366
367
  .wp-btn {
@@ -1,7 +1,8 @@
1
- export { ApprovalLineEditor, stepLabel, stepTypeIcon } from '../chunk-FLAN7CV3.js';
1
+ export { ApprovalLineEditor, stepLabel, stepTypeIcon } from '../chunk-MPT7WJG2.js';
2
2
  import '../chunk-Q4SWUINA.js';
3
- import '../chunk-WOYMEEPH.js';
4
- import '../chunk-WSLT32Q4.js';
3
+ import '../chunk-UV6HHFEW.js';
4
+ import '../chunk-RWSH2MBU.js';
5
+ import '../chunk-RIZRM7OO.js';
5
6
  import '../chunk-XQPTSEJC.js';
6
7
  import '../chunk-KO6OEY3G.js';
7
8
  import '../chunk-RNOUXUBO.js';
@@ -1,9 +1,10 @@
1
- export { ApprovalOverridesEditor, facetsFrom } from '../chunk-GE6BYNQJ.js';
1
+ export { ApprovalOverridesEditor, facetsFrom } from '../chunk-DKVSM5HX.js';
2
2
  import '../chunk-I5SD7XRA.js';
3
- import '../chunk-FLAN7CV3.js';
3
+ import '../chunk-MPT7WJG2.js';
4
4
  import '../chunk-Q4SWUINA.js';
5
- import '../chunk-WOYMEEPH.js';
6
- import '../chunk-WSLT32Q4.js';
5
+ import '../chunk-UV6HHFEW.js';
6
+ import '../chunk-RWSH2MBU.js';
7
+ import '../chunk-RIZRM7OO.js';
7
8
  import '../chunk-XQPTSEJC.js';
8
9
  import '../chunk-KO6OEY3G.js';
9
10
  import '../chunk-RNOUXUBO.js';
@@ -1,7 +1,8 @@
1
- export { AutocompleteField, endpointSearchFn, toAutocompleteOptions } from '../chunk-N25YP7ID.js';
1
+ export { AutocompleteField, endpointSearchFn, toAutocompleteOptions } from '../chunk-FNMS7OB7.js';
2
2
  import '../chunk-Q4SWUINA.js';
3
- import '../chunk-WOYMEEPH.js';
4
- import '../chunk-WSLT32Q4.js';
3
+ import '../chunk-UV6HHFEW.js';
4
+ import '../chunk-RWSH2MBU.js';
5
+ import '../chunk-RIZRM7OO.js';
5
6
  import '../chunk-XQPTSEJC.js';
6
7
  import '../chunk-KO6OEY3G.js';
7
8
  import '../chunk-RNOUXUBO.js';
@@ -1,4 +1,4 @@
1
- export { OPTION_TYPES, OptionSchemaEditor } from '../chunk-B6WMC2AN.js';
2
- import '../chunk-37SFFW37.js';
1
+ export { OPTION_TYPES, OptionSchemaEditor } from '../chunk-CXW6KT6X.js';
2
+ import '../chunk-WPSK2CB5.js';
3
3
  import '../chunk-RNOUXUBO.js';
4
4
  import '../chunk-5WW4MBRO.js';
@@ -1,4 +1,4 @@
1
- export { OptionValueFields } from '../chunk-7FZTUI6U.js';
2
- import '../chunk-37SFFW37.js';
1
+ export { OptionValueFields } from '../chunk-BEM2YS7U.js';
2
+ import '../chunk-WPSK2CB5.js';
3
3
  import '../chunk-RNOUXUBO.js';
4
4
  import '../chunk-5WW4MBRO.js';
@@ -1,5 +1,6 @@
1
- export { PeriodFilter } from '../chunk-HBBTENSV.js';
2
- import '../chunk-WSLT32Q4.js';
1
+ export { PeriodFilter } from '../chunk-44TDRCKR.js';
2
+ import '../chunk-RWSH2MBU.js';
3
+ import '../chunk-RIZRM7OO.js';
3
4
  import '../chunk-XQPTSEJC.js';
4
5
  import '../chunk-RNOUXUBO.js';
5
6
  import '../chunk-5WW4MBRO.js';
@@ -1,6 +1,7 @@
1
- export { SearchableMultiPicker } from '../chunk-AC5TI3BE.js';
2
- import '../chunk-WOYMEEPH.js';
3
- import '../chunk-WSLT32Q4.js';
1
+ export { SearchableMultiPicker } from '../chunk-HBIIEYKW.js';
2
+ import '../chunk-UV6HHFEW.js';
3
+ import '../chunk-RWSH2MBU.js';
4
+ import '../chunk-RIZRM7OO.js';
4
5
  import '../chunk-XQPTSEJC.js';
5
6
  import '../chunk-RNOUXUBO.js';
6
7
  import '../chunk-5WW4MBRO.js';
@@ -1,5 +1,6 @@
1
- export { StagePeriodEditor } from '../chunk-5XPZ3RSA.js';
2
- import '../chunk-WSLT32Q4.js';
1
+ export { StagePeriodEditor } from '../chunk-NIJUVTEW.js';
2
+ import '../chunk-RWSH2MBU.js';
3
+ import '../chunk-RIZRM7OO.js';
3
4
  import '../chunk-XQPTSEJC.js';
4
5
  import '../chunk-RNOUXUBO.js';
5
6
  import '../chunk-5WW4MBRO.js';
@@ -0,0 +1,49 @@
1
+ import { S as SduiBoxProps } from '../layout-C3nRXMwb.js';
2
+ import React__default from 'react';
3
+
4
+ interface TagInputProps {
5
+ /** 현재 키워드 목록. 보통 `{ "$state": "form.keywords" }` 를 건다. */
6
+ value: string[];
7
+ onChange: (values: string[]) => void;
8
+ placeholder?: string;
9
+ disabled?: boolean;
10
+ /**
11
+ * 추천 키워드. 문자열 배열이거나 객체 배열 — 객체는 `suggestionKey`(기본 'keyword',
12
+ * 없으면 value → label 순)로 낱말을 읽고 `count` 가 있으면 옆에 건수를 적는다.
13
+ */
14
+ suggestions?: Array<string | number | Record<string, unknown>>;
15
+ /** 추천 객체에서 낱말을 읽을 키. 기본 'keyword'. */
16
+ suggestionKey?: string;
17
+ /** 최대 개수. 넘으면 더 받지 않는다. */
18
+ maxItems?: number;
19
+ /** 낱말 하나의 최대 글자 수(기본 50). 넘는 글자는 잘라 담는다. */
20
+ maxLength?: number;
21
+ /** 칩 앞에 `#` 을 그린다(기본 켜짐). 값 자체에는 넣지 않는다. */
22
+ hash?: boolean;
23
+ /** 포커스 없이도 보이는 추천 최대 줄 수(기본 8). */
24
+ maxSuggestions?: number;
25
+ }
26
+ interface TagInputSuggestion {
27
+ keyword: string;
28
+ count?: number;
29
+ }
30
+ /** 낱말 하나를 다듬는다 — 앞 `#` 제거·공백 정리·길이 제한. 비면 null. */
31
+ declare function normalizeKeyword(raw: unknown, maxLength?: number): string | null;
32
+ /**
33
+ * 목록을 다듬고 대소문자 무시 중복을 접는다(먼저 온 표기가 남는다).
34
+ * `maxItems` 가 있으면 그 개수에서 자른다.
35
+ */
36
+ declare function normalizeKeywords(list: unknown, options?: {
37
+ maxItems?: number;
38
+ maxLength?: number;
39
+ }): string[];
40
+ /**
41
+ * 입력·붙여넣기 문자열을 낱말 목록으로 가른다 — 쉼표·줄바꿈·탭, 그리고 `#` 앞의 공백.
42
+ * 낱말 안의 공백은 살린다("공공 입찰" 은 하나다). `#a #b` 는 둘이다.
43
+ */
44
+ declare function splitKeywordText(text: string): string[];
45
+ /** 추천 원소를 `{keyword, count}` 로 접는다. */
46
+ declare function foldSuggestions(raw: unknown, key?: string): TagInputSuggestion[];
47
+ declare const TagInput: React__default.FC<TagInputProps & SduiBoxProps>;
48
+
49
+ export { TagInput, type TagInputProps, type TagInputSuggestion, foldSuggestions, normalizeKeyword, normalizeKeywords, splitKeywordText };
@@ -0,0 +1,4 @@
1
+ export { TagInput, foldSuggestions, normalizeKeyword, normalizeKeywords, splitKeywordText } from '../chunk-GNA6SX2H.js';
2
+ import '../chunk-RIZRM7OO.js';
3
+ import '../chunk-RNOUXUBO.js';
4
+ import '../chunk-5WW4MBRO.js';
@@ -1,7 +1,8 @@
1
- export { TreePicker } from '../chunk-7BGDSSAN.js';
2
- import '../chunk-C37U3GCC.js';
3
- import '../chunk-WOYMEEPH.js';
4
- import '../chunk-WSLT32Q4.js';
1
+ export { TreePicker } from '../chunk-OQ52XMGG.js';
2
+ import '../chunk-GZBY7I4Y.js';
3
+ import '../chunk-UV6HHFEW.js';
4
+ import '../chunk-RWSH2MBU.js';
5
+ import '../chunk-RIZRM7OO.js';
5
6
  import '../chunk-XQPTSEJC.js';
6
7
  import '../chunk-RNOUXUBO.js';
7
8
  import '../chunk-5WW4MBRO.js';
@@ -1,6 +1,7 @@
1
- export { TreeView, buildTreeNodes, pruneExcluded, resolveTreeNodes } from '../chunk-C37U3GCC.js';
2
- import '../chunk-WOYMEEPH.js';
3
- import '../chunk-WSLT32Q4.js';
1
+ export { TreeView, buildTreeNodes, pruneExcluded, resolveTreeNodes } from '../chunk-GZBY7I4Y.js';
2
+ import '../chunk-UV6HHFEW.js';
3
+ import '../chunk-RWSH2MBU.js';
4
+ import '../chunk-RIZRM7OO.js';
4
5
  import '../chunk-XQPTSEJC.js';
5
6
  import '../chunk-RNOUXUBO.js';
6
7
  import '../chunk-5WW4MBRO.js';
@@ -6,6 +6,8 @@ import { TimelineProps } from './Timeline.js';
6
6
  export { Timeline, TimelineItem } from './Timeline.js';
7
7
  import { TagMultiSelectProps } from './TagMultiSelect.js';
8
8
  export { TagMultiSelect, TagMultiSelectOption, pickSeedValues } from './TagMultiSelect.js';
9
+ import { TagInputProps } from './TagInput.js';
10
+ export { TagInput, TagInputSuggestion, foldSuggestions, normalizeKeyword, normalizeKeywords, splitKeywordText } from './TagInput.js';
9
11
  import { SummaryTableProps } from './SummaryTable.js';
10
12
  export { SummaryTable, SummaryTableColumn } from './SummaryTable.js';
11
13
  import { StripProps } from './Strip.js';
@@ -109,6 +111,7 @@ declare const widgetComponents: {
109
111
  StagePeriodEditor: React.FC<StagePeriodEditorProps & SduiBoxProps>;
110
112
  Strip: React.FC<StripProps & SduiBoxProps>;
111
113
  SummaryTable: React.FC<SummaryTableProps & SduiBoxProps>;
114
+ TagInput: React.FC<TagInputProps & SduiBoxProps>;
112
115
  TagMultiSelect: React.FC<TagMultiSelectProps & SduiBoxProps>;
113
116
  Timeline: React.FC<TimelineProps & SduiBoxProps>;
114
117
  TreePicker: React.FC<TreePickerProps & SduiBoxProps>;
@@ -117,4 +120,4 @@ declare const widgetComponents: {
117
120
  /** 위젯 어휘의 컴포넌트 이름 union — 메타데이터 대조에 쓴다(`@wipco/sdui/meta`). */
118
121
  type SduiWidgetComponentName = keyof typeof widgetComponents;
119
122
 
120
- export { ApprovalLineEditorProps, ApprovalOverridesEditorProps, ApprovalStepperProps, ColumnBoardProps, DiffViewProps, DisclosureProps, EventCalendarProps, ImageLightboxProps, InlineEditProps, JsonFieldProps, LiveClockProps, OptionSchemaEditorProps, OptionValueFieldsProps, OrgChartBoardProps, OrgChartProps, PeriodFilterProps, PermissionMatrixEditorProps, PositionSelectProps, PrintSheetProps, ProfileEditDiffCardProps, QRDisplayProps, RankBoardProps, RecordSheetProps, RoleMemberPickerProps, type SduiWidgetComponentName, SearchableMultiPickerProps, SecureScreenProps, StackedMeterProps, StagePeriodEditorProps, StripProps, SummaryTableProps, TagMultiSelectProps, TimelineProps, TreePickerProps, TreeViewProps, widgetComponents };
123
+ export { ApprovalLineEditorProps, ApprovalOverridesEditorProps, ApprovalStepperProps, ColumnBoardProps, DiffViewProps, DisclosureProps, EventCalendarProps, ImageLightboxProps, InlineEditProps, JsonFieldProps, LiveClockProps, OptionSchemaEditorProps, OptionValueFieldsProps, OrgChartBoardProps, OrgChartProps, PeriodFilterProps, PermissionMatrixEditorProps, PositionSelectProps, PrintSheetProps, ProfileEditDiffCardProps, QRDisplayProps, RankBoardProps, RecordSheetProps, RoleMemberPickerProps, type SduiWidgetComponentName, SearchableMultiPickerProps, SecureScreenProps, StackedMeterProps, StagePeriodEditorProps, StripProps, SummaryTableProps, TagInputProps, TagMultiSelectProps, TimelineProps, TreePickerProps, TreeViewProps, widgetComponents };
@@ -1,19 +1,21 @@
1
+ import { TreePicker } from '../chunk-OQ52XMGG.js';
2
+ export { TreePicker } from '../chunk-OQ52XMGG.js';
3
+ import { TreeView } from '../chunk-GZBY7I4Y.js';
4
+ export { TreeView, buildTreeNodes } from '../chunk-GZBY7I4Y.js';
1
5
  import { SecureScreen } from '../chunk-I45EUZC6.js';
2
6
  export { SecureScreen } from '../chunk-I45EUZC6.js';
3
7
  import { StackedMeter } from '../chunk-JIV4YHCZ.js';
4
8
  export { StackedMeter } from '../chunk-JIV4YHCZ.js';
5
- import { StagePeriodEditor } from '../chunk-5XPZ3RSA.js';
6
- export { StagePeriodEditor } from '../chunk-5XPZ3RSA.js';
9
+ import { StagePeriodEditor } from '../chunk-NIJUVTEW.js';
10
+ export { StagePeriodEditor } from '../chunk-NIJUVTEW.js';
7
11
  import { Strip } from '../chunk-AXGF4M57.js';
8
12
  export { Strip } from '../chunk-AXGF4M57.js';
9
13
  import { SummaryTable } from '../chunk-2YP5N4VV.js';
10
14
  export { SummaryTable } from '../chunk-2YP5N4VV.js';
15
+ import { TagInput } from '../chunk-GNA6SX2H.js';
16
+ export { TagInput, foldSuggestions, normalizeKeyword, normalizeKeywords, splitKeywordText } from '../chunk-GNA6SX2H.js';
11
17
  import { Timeline } from '../chunk-GTGS2QRL.js';
12
18
  export { Timeline } from '../chunk-GTGS2QRL.js';
13
- import { TreePicker } from '../chunk-7BGDSSAN.js';
14
- export { TreePicker } from '../chunk-7BGDSSAN.js';
15
- import { TreeView } from '../chunk-C37U3GCC.js';
16
- export { TreeView, buildTreeNodes } from '../chunk-C37U3GCC.js';
17
19
  import { PositionSelect } from '../chunk-DOL57OOP.js';
18
20
  export { PositionSelect } from '../chunk-DOL57OOP.js';
19
21
  import { PrintSheet } from '../chunk-E6ISNQK3.js';
@@ -28,16 +30,16 @@ import { RecordSheet } from '../chunk-O4IISNE7.js';
28
30
  export { RecordSheet } from '../chunk-O4IISNE7.js';
29
31
  import { RoleMemberPicker } from '../chunk-A5XQOEVH.js';
30
32
  export { RoleMemberPicker } from '../chunk-A5XQOEVH.js';
31
- import { SearchableMultiPicker } from '../chunk-AC5TI3BE.js';
32
- export { SearchableMultiPicker } from '../chunk-AC5TI3BE.js';
33
+ import { SearchableMultiPicker } from '../chunk-HBIIEYKW.js';
34
+ export { SearchableMultiPicker } from '../chunk-HBIIEYKW.js';
33
35
  import { JsonField } from '../chunk-ZFNFPXPR.js';
34
36
  export { JsonField } from '../chunk-ZFNFPXPR.js';
35
37
  import { LiveClock } from '../chunk-DMLDKW7K.js';
36
38
  export { LiveClock } from '../chunk-DMLDKW7K.js';
37
- import { OptionSchemaEditor } from '../chunk-B6WMC2AN.js';
38
- export { OPTION_TYPES, OptionSchemaEditor } from '../chunk-B6WMC2AN.js';
39
- import { OptionValueFields } from '../chunk-7FZTUI6U.js';
40
- export { OptionValueFields } from '../chunk-7FZTUI6U.js';
39
+ import { OptionSchemaEditor } from '../chunk-CXW6KT6X.js';
40
+ export { OPTION_TYPES, OptionSchemaEditor } from '../chunk-CXW6KT6X.js';
41
+ import { OptionValueFields } from '../chunk-BEM2YS7U.js';
42
+ export { OptionValueFields } from '../chunk-BEM2YS7U.js';
41
43
  import { OrgChart } from '../chunk-A6LAIGUS.js';
42
44
  export { OrgChart } from '../chunk-A6LAIGUS.js';
43
45
  import { OrgChartBoard } from '../chunk-JZXU22PE.js';
@@ -46,9 +48,9 @@ import '../chunk-XRHR452N.js';
46
48
  import '../chunk-MMIGOPO5.js';
47
49
  import { PermissionMatrixEditor } from '../chunk-LFEJLOFN.js';
48
50
  export { PermissionMatrixEditor } from '../chunk-LFEJLOFN.js';
49
- import { PeriodFilter } from '../chunk-HBBTENSV.js';
50
- export { PeriodFilter } from '../chunk-HBBTENSV.js';
51
- export { AutocompleteField, endpointSearchFn, toAutocompleteOptions } from '../chunk-N25YP7ID.js';
51
+ import { PeriodFilter } from '../chunk-44TDRCKR.js';
52
+ export { PeriodFilter } from '../chunk-44TDRCKR.js';
53
+ export { AutocompleteField, endpointSearchFn, toAutocompleteOptions } from '../chunk-FNMS7OB7.js';
52
54
  import { ColumnBoard } from '../chunk-YWUDBLO6.js';
53
55
  export { ColumnBoard } from '../chunk-YWUDBLO6.js';
54
56
  import { DiffView } from '../chunk-JYAR7D5U.js';
@@ -63,17 +65,18 @@ export { ImageLightbox } from '../chunk-VY7MVBSE.js';
63
65
  import { InlineEdit } from '../chunk-7P7N43JV.js';
64
66
  export { InlineEdit } from '../chunk-7P7N43JV.js';
65
67
  import '../chunk-TFGNKFL2.js';
66
- import '../chunk-37SFFW37.js';
68
+ import '../chunk-WPSK2CB5.js';
67
69
  import '../chunk-SAPBDJJQ.js';
68
- import { ApprovalOverridesEditor } from '../chunk-GE6BYNQJ.js';
69
- export { ApprovalOverridesEditor } from '../chunk-GE6BYNQJ.js';
70
+ import { ApprovalOverridesEditor } from '../chunk-DKVSM5HX.js';
71
+ export { ApprovalOverridesEditor } from '../chunk-DKVSM5HX.js';
70
72
  import { TagMultiSelect } from '../chunk-I5SD7XRA.js';
71
73
  export { TagMultiSelect, pickSeedValues } from '../chunk-I5SD7XRA.js';
72
- import { ApprovalLineEditor } from '../chunk-FLAN7CV3.js';
73
- export { ApprovalLineEditor } from '../chunk-FLAN7CV3.js';
74
+ import { ApprovalLineEditor } from '../chunk-MPT7WJG2.js';
75
+ export { ApprovalLineEditor } from '../chunk-MPT7WJG2.js';
74
76
  import '../chunk-Q4SWUINA.js';
75
- import '../chunk-WOYMEEPH.js';
76
- import '../chunk-WSLT32Q4.js';
77
+ import '../chunk-UV6HHFEW.js';
78
+ import '../chunk-RWSH2MBU.js';
79
+ import '../chunk-RIZRM7OO.js';
77
80
  import '../chunk-XQPTSEJC.js';
78
81
  import '../chunk-KO6OEY3G.js';
79
82
  import { ApprovalStepper } from '../chunk-XGFDY43I.js';
@@ -113,6 +116,7 @@ var widgetComponents = {
113
116
  StagePeriodEditor,
114
117
  Strip,
115
118
  SummaryTable,
119
+ TagInput,
116
120
  TagMultiSelect,
117
121
  Timeline,
118
122
  TreePicker,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipco/sdui",
3
- "version": "1.3.0",
3
+ "version": "1.4.1",
4
4
  "description": "WIPCO 서버 주도 UI(SDUI) 렌더러 — JSON 페이지 스펙을 React 컴포넌트로 렌더링",
5
5
  "keywords": [
6
6
  "sdui",
@@ -168,6 +168,10 @@
168
168
  "types": "./dist/widgets/SummaryTable.d.ts",
169
169
  "default": "./dist/widgets/SummaryTable.js"
170
170
  },
171
+ "./widgets/TagInput": {
172
+ "types": "./dist/widgets/TagInput.d.ts",
173
+ "default": "./dist/widgets/TagInput.js"
174
+ },
171
175
  "./widgets/TagMultiSelect": {
172
176
  "types": "./dist/widgets/TagMultiSelect.d.ts",
173
177
  "default": "./dist/widgets/TagMultiSelect.js"