@wipco/sdui 1.4.2 → 1.6.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 (143) hide show
  1. package/dist/{DatePicker-C_TT_SOw.d.ts → DatePicker-DX9juElE.d.ts} +10 -1
  2. package/dist/{chunk-GZBY7I4Y.js → chunk-2KQL6DYG.js} +3 -3
  3. package/dist/{chunk-RYBBPFI7.js → chunk-2QXA52DG.js} +4 -4
  4. package/dist/{chunk-DMLDKW7K.js → chunk-37BNG4DT.js} +1 -1
  5. package/dist/{chunk-5WW4MBRO.js → chunk-3JTBOABA.js} +6 -2
  6. package/dist/{chunk-UV6HHFEW.js → chunk-4OABUPIU.js} +129 -68
  7. package/dist/{chunk-ZORQPB6B.js → chunk-53KS4E5N.js} +318 -359
  8. package/dist/{chunk-I5SD7XRA.js → chunk-6TI4WF5Y.js} +3 -3
  9. package/dist/{chunk-44TDRCKR.js → chunk-6XI2VF2O.js} +5 -5
  10. package/dist/{chunk-HBIIEYKW.js → chunk-7C54CKFZ.js} +4 -4
  11. package/dist/{chunk-IZ3JA2BR.js → chunk-7JP52QQO.js} +3 -3
  12. package/dist/{chunk-I45EUZC6.js → chunk-AY4GM6KQ.js} +4 -2
  13. package/dist/{chunk-SAPBDJJQ.js → chunk-AZSLSAJB.js} +2 -2
  14. package/dist/chunk-BITS7UJY.js +333 -0
  15. package/dist/{chunk-RNOUXUBO.js → chunk-BLFJMMBW.js} +306 -57
  16. package/dist/{chunk-YOZN35HD.js → chunk-CEVZAFPO.js} +3 -3
  17. package/dist/chunk-CI5OZ2QT.js +106 -0
  18. package/dist/{chunk-FNMS7OB7.js → chunk-CSE3PZOZ.js} +5 -5
  19. package/dist/chunk-CSZCWBOE.js +256 -0
  20. package/dist/{chunk-JIV4YHCZ.js → chunk-EJIWOD7W.js} +1 -1
  21. package/dist/{chunk-JZXU22PE.js → chunk-FEKKOBPX.js} +208 -117
  22. package/dist/chunk-GSM664TX.js +38 -0
  23. package/dist/{chunk-JYAR7D5U.js → chunk-HRHKQOOF.js} +2 -2
  24. package/dist/{chunk-CXW6KT6X.js → chunk-HXLQSO66.js} +3 -3
  25. package/dist/{chunk-O4IISNE7.js → chunk-IB2ZPUTF.js} +51 -12
  26. package/dist/{chunk-MPT7WJG2.js → chunk-IQXLNICY.js} +5 -5
  27. package/dist/{chunk-OQ52XMGG.js → chunk-K6RE23XX.js} +4 -4
  28. package/dist/{chunk-VY7MVBSE.js → chunk-KZ6U6FKB.js} +2 -2
  29. package/dist/{chunk-WPSK2CB5.js → chunk-LIZTK3HO.js} +16 -5
  30. package/dist/{chunk-Q4SWUINA.js → chunk-LKQJJSVJ.js} +1 -1
  31. package/dist/{chunk-E6ISNQK3.js → chunk-M6H3SHIS.js} +31 -8
  32. package/dist/chunk-MN4RZ2WP.js +380 -0
  33. package/dist/{chunk-GTGS2QRL.js → chunk-NA232CBX.js} +3 -3
  34. package/dist/{chunk-ZFNFPXPR.js → chunk-NAIWQQPW.js} +2 -2
  35. package/dist/{chunk-YVTV4ZV6.js → chunk-NWYYNE3Q.js} +1 -1
  36. package/dist/{chunk-DKVSM5HX.js → chunk-OUEJWC2Z.js} +6 -6
  37. package/dist/{chunk-DOL57OOP.js → chunk-OYDJHQNZ.js} +3 -3
  38. package/dist/{chunk-YWUDBLO6.js → chunk-QVS6K4FP.js} +2 -2
  39. package/dist/{chunk-N5RKM6IC.js → chunk-RU5U2YMT.js} +4 -4
  40. package/dist/{chunk-A6LAIGUS.js → chunk-V7BWMOHO.js} +7 -4
  41. package/dist/{chunk-2HLXCKK7.js → chunk-VPOOIEKT.js} +2 -2
  42. package/dist/{chunk-2YP5N4VV.js → chunk-VZOQRQAR.js} +1 -1
  43. package/dist/{chunk-GNA6SX2H.js → chunk-W4VA76QO.js} +2 -2
  44. package/dist/{chunk-BEM2YS7U.js → chunk-WEG3V7ZB.js} +3 -3
  45. package/dist/{chunk-XGFDY43I.js → chunk-WTIYILY3.js} +88 -18
  46. package/dist/{chunk-RWSH2MBU.js → chunk-X2NIRVLN.js} +73 -19
  47. package/dist/{chunk-AXGF4M57.js → chunk-XAXROQKB.js} +1 -1
  48. package/dist/{chunk-NIJUVTEW.js → chunk-XG22XKKD.js} +3 -3
  49. package/dist/{chunk-A5XQOEVH.js → chunk-YN7X7BEO.js} +4 -4
  50. package/dist/{chunk-KO6OEY3G.js → chunk-YNEEJCSZ.js} +3 -13
  51. package/dist/{chunk-7P7N43JV.js → chunk-YZTTFEL4.js} +2 -2
  52. package/dist/index.d.ts +494 -89
  53. package/dist/index.js +1098 -124
  54. package/dist/{layout-C3nRXMwb.d.ts → layout-DmRikwZb.d.ts} +5 -4
  55. package/dist/meta.d.ts +1 -1
  56. package/dist/meta.js +286 -22
  57. package/dist/rich/ExcelUploadCard.d.ts +1 -1
  58. package/dist/rich/ExcelUploadCard.js +5 -4
  59. package/dist/rich.d.ts +21 -3
  60. package/dist/rich.js +277 -35
  61. package/dist/styles.css +102 -4
  62. package/dist/{types-COjGKgmd.d.ts → types-CYfIthux.d.ts} +57 -1
  63. package/dist/widgets/ApprovalLineEditor.d.ts +1 -1
  64. package/dist/widgets/ApprovalLineEditor.js +9 -8
  65. package/dist/widgets/ApprovalOverridesEditor.d.ts +1 -1
  66. package/dist/widgets/ApprovalOverridesEditor.js +11 -10
  67. package/dist/widgets/ApprovalStepper.d.ts +29 -4
  68. package/dist/widgets/ApprovalStepper.js +3 -3
  69. package/dist/widgets/AutocompleteField.d.ts +1 -1
  70. package/dist/widgets/AutocompleteField.js +9 -8
  71. package/dist/widgets/ColumnBoard.d.ts +1 -1
  72. package/dist/widgets/ColumnBoard.js +3 -3
  73. package/dist/widgets/DiffView.d.ts +1 -1
  74. package/dist/widgets/DiffView.js +3 -3
  75. package/dist/widgets/Disclosure.d.ts +1 -1
  76. package/dist/widgets/Disclosure.js +3 -3
  77. package/dist/widgets/EventCalendar.d.ts +5 -1
  78. package/dist/widgets/EventCalendar.js +5 -3
  79. package/dist/widgets/FileDropzone.d.ts +1 -1
  80. package/dist/widgets/FileDropzone.js +9 -7
  81. package/dist/widgets/ImageLightbox.d.ts +1 -1
  82. package/dist/widgets/ImageLightbox.js +7 -5
  83. package/dist/widgets/InlineEdit.d.ts +1 -1
  84. package/dist/widgets/InlineEdit.js +3 -3
  85. package/dist/widgets/JsonField.d.ts +1 -1
  86. package/dist/widgets/JsonField.js +3 -3
  87. package/dist/widgets/LiveClock.d.ts +1 -1
  88. package/dist/widgets/LiveClock.js +2 -2
  89. package/dist/widgets/OptionSchemaEditor.d.ts +1 -1
  90. package/dist/widgets/OptionSchemaEditor.js +4 -4
  91. package/dist/widgets/OptionValueFields.d.ts +1 -1
  92. package/dist/widgets/OptionValueFields.js +4 -4
  93. package/dist/widgets/OrgChart.d.ts +1 -1
  94. package/dist/widgets/OrgChart.js +4 -4
  95. package/dist/widgets/OrgChartBoard.d.ts +15 -33
  96. package/dist/widgets/OrgChartBoard.js +10 -8
  97. package/dist/widgets/PeriodFilter.d.ts +1 -1
  98. package/dist/widgets/PeriodFilter.js +6 -5
  99. package/dist/widgets/PermissionMatrixEditor.d.ts +34 -2
  100. package/dist/widgets/PermissionMatrixEditor.js +6 -4
  101. package/dist/widgets/PositionSelect.d.ts +1 -1
  102. package/dist/widgets/PositionSelect.js +5 -4
  103. package/dist/widgets/PrintSheet.d.ts +15 -2
  104. package/dist/widgets/PrintSheet.js +3 -3
  105. package/dist/widgets/ProfileEditDiffCard.d.ts +1 -1
  106. package/dist/widgets/ProfileEditDiffCard.js +5 -4
  107. package/dist/widgets/QRDisplay.d.ts +1 -1
  108. package/dist/widgets/QRDisplay.js +5 -4
  109. package/dist/widgets/RankBoard.d.ts +1 -1
  110. package/dist/widgets/RankBoard.js +8 -6
  111. package/dist/widgets/RecordSheet.d.ts +1 -1
  112. package/dist/widgets/RecordSheet.js +2 -2
  113. package/dist/widgets/RoleMemberPicker.d.ts +1 -1
  114. package/dist/widgets/RoleMemberPicker.js +6 -5
  115. package/dist/widgets/SearchableMultiPicker.d.ts +1 -1
  116. package/dist/widgets/SearchableMultiPicker.js +7 -6
  117. package/dist/widgets/SecureScreen.d.ts +1 -1
  118. package/dist/widgets/SecureScreen.js +3 -3
  119. package/dist/widgets/StackedMeter.d.ts +1 -1
  120. package/dist/widgets/StackedMeter.js +2 -2
  121. package/dist/widgets/StagePeriodEditor.d.ts +1 -1
  122. package/dist/widgets/StagePeriodEditor.js +6 -5
  123. package/dist/widgets/Strip.d.ts +1 -1
  124. package/dist/widgets/Strip.js +2 -2
  125. package/dist/widgets/SummaryTable.d.ts +1 -1
  126. package/dist/widgets/SummaryTable.js +2 -2
  127. package/dist/widgets/TagInput.d.ts +1 -1
  128. package/dist/widgets/TagInput.js +3 -3
  129. package/dist/widgets/TagMultiSelect.d.ts +1 -1
  130. package/dist/widgets/TagMultiSelect.js +5 -4
  131. package/dist/widgets/Timeline.d.ts +1 -1
  132. package/dist/widgets/Timeline.js +4 -4
  133. package/dist/widgets/TreePicker.d.ts +1 -1
  134. package/dist/widgets/TreePicker.js +8 -7
  135. package/dist/widgets/TreeView.d.ts +1 -1
  136. package/dist/widgets/TreeView.js +7 -6
  137. package/dist/widgets/index.d.ts +3 -3
  138. package/dist/widgets/index.js +84 -83
  139. package/package.json +1 -1
  140. package/dist/chunk-LFEJLOFN.js +0 -352
  141. package/dist/chunk-MMIGOPO5.js +0 -111
  142. package/dist/chunk-TFGNKFL2.js +0 -39
  143. package/dist/chunk-XQPTSEJC.js +0 -135
@@ -1,352 +0,0 @@
1
- import { useSduiAdapter, hostFetchOf, defaultAdapter } from './chunk-KO6OEY3G.js';
2
- import { Icon, Badge, Checkbox, Select, Button } from './chunk-RNOUXUBO.js';
3
- import { boxed } from './chunk-5WW4MBRO.js';
4
- import { useRef, useEffect, useMemo, useState } from 'react';
5
- import { jsx, jsxs } from 'react/jsx-runtime';
6
-
7
- var OPERATIONS = [
8
- { key: "read", label: "\uC870\uD68C" },
9
- { key: "create", label: "\uC0DD\uC131" },
10
- { key: "update", label: "\uC218\uC815" },
11
- { key: "delete", label: "\uC0AD\uC81C" }
12
- ];
13
- var SCOPE_OPTIONS = [
14
- { value: "team", label: "\uD300" },
15
- { value: "headquarter", label: "\uBCF8\uBD80" },
16
- { value: "all", label: "\uC804\uCCB4" }
17
- ];
18
- var CATEGORY_LABELS = {
19
- fi: "\uC7AC\uBB34",
20
- asset: "\uC790\uC0B0",
21
- hr: "\uC778\uC0AC",
22
- core: "\uACF5\uD1B5",
23
- rbac: "\uAD8C\uD55C"
24
- };
25
- var CATEGORY_ORDER = ["fi", "asset", "hr", "core", "rbac"];
26
- var entityOf = (code) => {
27
- const i = code.lastIndexOf(".");
28
- return i > 0 ? code.slice(0, i) : code;
29
- };
30
- var operationOf = (code) => {
31
- const i = code.lastIndexOf(".");
32
- const op = i > 0 ? code.slice(i + 1) : "";
33
- return OPERATIONS.some((o) => o.key === op) ? op : null;
34
- };
35
- function groupCatalog(catalog, categoryLabels, categoryOrder) {
36
- const categories = /* @__PURE__ */ new Map();
37
- for (const entry of catalog) {
38
- if (!entry || typeof entry.code !== "string") continue;
39
- const category = entry.category?.trim() || "\uAE30\uD0C0";
40
- const entity = entityOf(entry.code);
41
- const byEntity = categories.get(category) ?? /* @__PURE__ */ new Map();
42
- categories.set(category, byEntity);
43
- const row = byEntity.get(entity) ?? { entity, label: "", cells: {}, extras: [] };
44
- byEntity.set(entity, row);
45
- const op = operationOf(entry.code);
46
- if (op) {
47
- row.cells[op] = entry;
48
- if (!row.label) row.label = entry.name.replace(/\s*(조회|생성|수정|삭제)\s*$/, "") || entity;
49
- } else {
50
- row.extras.push(entry);
51
- if (!row.label) row.label = entry.name;
52
- }
53
- }
54
- const order = (c) => {
55
- const i = categoryOrder.indexOf(c);
56
- return i < 0 ? categoryOrder.length : i;
57
- };
58
- return [...categories.entries()].sort((a, b) => order(a[0]) - order(b[0]) || a[0].localeCompare(b[0])).map(([category, byEntity]) => ({
59
- category,
60
- label: categoryLabels[category] ?? category,
61
- rows: [...byEntity.values()].sort((a, b) => a.entity.localeCompare(b.entity))
62
- }));
63
- }
64
- function PermissionMatrixEditorImpl({
65
- permissions,
66
- value,
67
- onChange,
68
- sourceEndpoint,
69
- disabled = false,
70
- scopeOptions = SCOPE_OPTIONS,
71
- defaultScope = "all",
72
- categoryLabels = CATEGORY_LABELS,
73
- categoryOrder = CATEGORY_ORDER,
74
- emptyText = "\uAD8C\uD55C \uCE74\uD0C8\uB85C\uADF8\uAC00 \uBE44\uC5B4 \uC788\uC2B5\uB2C8\uB2E4 \u2014 \uD398\uC774\uC9C0\uC758 data \uC120\uC5B8(/permissions?limit=1000)\uC744 \uD655\uC778\uD558\uC138\uC694."
75
- }) {
76
- const adapter = useSduiAdapter();
77
- const api = hostFetchOf(adapter) ?? defaultAdapter.fetch;
78
- const onChangeRef = useRef(onChange);
79
- onChangeRef.current = onChange;
80
- const seededFor = useRef(null);
81
- useEffect(() => {
82
- if (!sourceEndpoint || seededFor.current === sourceEndpoint) return;
83
- seededFor.current = sourceEndpoint;
84
- api(sourceEndpoint, { method: "GET" }).then((response) => {
85
- if (seededFor.current !== sourceEndpoint) return;
86
- const body = response;
87
- const rows = Array.isArray(body?.permissions) ? body.permissions : [];
88
- onChangeRef.current?.(
89
- rows.flatMap((row) => {
90
- if (typeof row !== "object" || row === null) return [];
91
- const { code, scope } = row;
92
- if (typeof code !== "string" || !code) return [];
93
- return [{ code, scope: typeof scope === "string" ? scope : defaultScope }];
94
- })
95
- );
96
- }).catch(() => {
97
- });
98
- }, [sourceEndpoint, defaultScope]);
99
- const grants = useMemo(() => Array.isArray(value) ? value : [], [value]);
100
- const catalog = useMemo(
101
- () => Array.isArray(permissions) ? permissions : [],
102
- [permissions]
103
- );
104
- const labelsKey = JSON.stringify(categoryLabels);
105
- const orderKey = JSON.stringify(categoryOrder);
106
- const groups = useMemo(
107
- () => groupCatalog(catalog, categoryLabels, categoryOrder),
108
- [catalog, labelsKey, orderKey]
109
- );
110
- const granted = useMemo(() => new Set(grants.map((g) => g.code)), [grants]);
111
- const scopeOf = useMemo(() => {
112
- const map = /* @__PURE__ */ new Map();
113
- for (const g of grants) {
114
- const e = entityOf(g.code);
115
- if (!map.has(e) && g.scope) map.set(e, g.scope);
116
- }
117
- return map;
118
- }, [grants]);
119
- const [closed, setClosed] = useState(/* @__PURE__ */ new Set());
120
- const toggleCategory = (c) => setClosed((prev) => {
121
- const next = new Set(prev);
122
- if (next.has(c)) next.delete(c);
123
- else next.add(c);
124
- return next;
125
- });
126
- const emit = (nextGranted, nextScopes) => {
127
- onChange?.(
128
- [...nextGranted].sort().map((code) => ({
129
- code,
130
- scope: nextScopes.get(entityOf(code)) ?? defaultScope
131
- }))
132
- );
133
- };
134
- const toggleCode = (code, on) => {
135
- const next = new Set(granted);
136
- if (on) next.add(code);
137
- else next.delete(code);
138
- emit(next, scopeOf);
139
- };
140
- const setEntityScope = (entity, scope) => {
141
- const next = new Map(scopeOf);
142
- next.set(entity, scope);
143
- emit(granted, next);
144
- };
145
- const toggleRow = (row, on) => {
146
- const next = new Set(granted);
147
- for (const op of OPERATIONS) {
148
- const cell = row.cells[op.key];
149
- if (!cell) continue;
150
- if (on) next.add(cell.code);
151
- else next.delete(cell.code);
152
- }
153
- for (const extra of row.extras) {
154
- if (on) next.add(extra.code);
155
- else next.delete(extra.code);
156
- }
157
- emit(next, scopeOf);
158
- };
159
- if (catalog.length === 0) {
160
- return /* @__PURE__ */ jsx(
161
- "div",
162
- {
163
- className: "wp-body-sm",
164
- style: {
165
- border: "var(--wp-border-w) dashed var(--wp-border-default)",
166
- borderRadius: "var(--wp-radius-lg)",
167
- padding: "var(--wp-space-4)",
168
- textAlign: "center",
169
- color: "var(--wp-text-muted)"
170
- },
171
- children: emptyText
172
- }
173
- );
174
- }
175
- return /* @__PURE__ */ jsxs("div", { className: "wp-col", style: { gap: "var(--wp-space-2)" }, children: [
176
- /* @__PURE__ */ jsxs("span", { className: "wp-caption", children: [
177
- "\uAD8C\uD55C ",
178
- catalog.length,
179
- "\uC885 \uC911 ",
180
- granted.size,
181
- "\uAC1C \uBD80\uC5EC\uB428 \xB7 \uBC94\uC704\uB294 \uC5D4\uD2F0\uD2F0 \uB2E8\uC704\uB85C \uC801\uC6A9\uB429\uB2C8\uB2E4 (",
182
- scopeOptions.map((option) => option.label).join(" < "),
183
- ")"
184
- ] }),
185
- /* @__PURE__ */ jsx(
186
- "div",
187
- {
188
- style: {
189
- position: "relative",
190
- border: "var(--wp-border-w) solid var(--wp-border-default)",
191
- borderRadius: "var(--wp-radius-lg)",
192
- overflowY: "auto",
193
- maxHeight: "min(46vh, 400px)",
194
- minHeight: 160
195
- },
196
- children: groups.map((group) => {
197
- const total = group.rows.reduce(
198
- (a, r) => a + Object.keys(r.cells).length + r.extras.length,
199
- 0
200
- );
201
- const on = group.rows.reduce(
202
- (a, r) => a + OPERATIONS.filter((o) => r.cells[o.key] && granted.has(r.cells[o.key].code)).length + r.extras.filter((x) => granted.has(x.code)).length,
203
- 0
204
- );
205
- const isClosed = closed.has(group.category);
206
- return /* @__PURE__ */ jsxs("div", { children: [
207
- /* @__PURE__ */ jsxs(
208
- "button",
209
- {
210
- type: "button",
211
- className: "wp-row",
212
- onClick: () => toggleCategory(group.category),
213
- style: {
214
- position: "sticky",
215
- top: 0,
216
- zIndex: 1,
217
- width: "100%",
218
- alignItems: "center",
219
- padding: "var(--wp-space-2) var(--wp-space-3)",
220
- background: "var(--wp-surface-sunken)",
221
- border: "none",
222
- borderTop: "var(--wp-border-w) solid var(--wp-border-default)",
223
- cursor: "pointer",
224
- textAlign: "left"
225
- },
226
- "aria-expanded": !isClosed,
227
- children: [
228
- /* @__PURE__ */ jsx(Icon, { name: isClosed ? "chevron-right" : "chevron-down", size: 14 }),
229
- /* @__PURE__ */ jsx("span", { className: "wp-label", style: { flex: 1 }, children: group.label }),
230
- /* @__PURE__ */ jsxs(Badge, { tone: on > 0 ? "brand" : "neutral", children: [
231
- on,
232
- "/",
233
- total
234
- ] })
235
- ]
236
- }
237
- ),
238
- isClosed ? null : /* @__PURE__ */ jsxs("div", { className: "wp-col", style: { gap: 0 }, children: [
239
- /* @__PURE__ */ jsxs(
240
- "div",
241
- {
242
- className: "wp-row wp-caption",
243
- style: {
244
- alignItems: "center",
245
- padding: "var(--wp-space-1) var(--wp-space-3)",
246
- borderTop: "var(--wp-border-w) solid var(--wp-divider)",
247
- color: "var(--wp-text-muted)"
248
- },
249
- children: [
250
- /* @__PURE__ */ jsx("span", { style: { flex: 1.6 }, children: "\uC5D4\uD2F0\uD2F0" }),
251
- OPERATIONS.map((op) => /* @__PURE__ */ jsx("span", { style: { flex: "none", width: 52, textAlign: "center" }, children: op.label }, op.key)),
252
- /* @__PURE__ */ jsx("span", { style: { flex: "none", width: 96, textAlign: "center" }, children: "\uBC94\uC704" }),
253
- /* @__PURE__ */ jsx("span", { style: { flex: "none", width: 60 } })
254
- ]
255
- }
256
- ),
257
- group.rows.map((row) => {
258
- const rowCodes = [
259
- ...OPERATIONS.flatMap(
260
- (o) => row.cells[o.key] ? [row.cells[o.key].code] : []
261
- ),
262
- ...row.extras.map((x) => x.code)
263
- ];
264
- const allOn = rowCodes.length > 0 && rowCodes.every((c) => granted.has(c));
265
- const anyOn = rowCodes.some((c) => granted.has(c));
266
- return /* @__PURE__ */ jsxs(
267
- "div",
268
- {
269
- className: "wp-row",
270
- style: {
271
- alignItems: "center",
272
- padding: "var(--wp-space-1) var(--wp-space-3)",
273
- borderTop: "var(--wp-border-w) solid var(--wp-divider)"
274
- },
275
- children: [
276
- /* @__PURE__ */ jsxs("span", { className: "wp-body-sm", style: { flex: 1.6, minWidth: 0 }, children: [
277
- row.label || row.entity,
278
- /* @__PURE__ */ jsx(
279
- "span",
280
- {
281
- className: "wp-caption",
282
- style: {
283
- marginLeft: "var(--wp-space-2)",
284
- color: "var(--wp-text-muted)"
285
- },
286
- children: row.entity
287
- }
288
- )
289
- ] }),
290
- OPERATIONS.map((op) => {
291
- const cell = row.cells[op.key];
292
- return /* @__PURE__ */ jsx(
293
- "span",
294
- {
295
- style: {
296
- flex: "none",
297
- width: 52,
298
- display: "inline-flex",
299
- justifyContent: "center"
300
- },
301
- children: cell ? /* @__PURE__ */ jsx(
302
- Checkbox,
303
- {
304
- "aria-label": `${row.label || row.entity} ${op.label}`,
305
- checked: granted.has(cell.code),
306
- disabled,
307
- onChange: (event) => toggleCode(cell.code, event.target.checked)
308
- }
309
- ) : /* @__PURE__ */ jsx("span", { className: "wp-caption", style: { color: "var(--wp-text-muted)" }, children: "\u2013" })
310
- },
311
- op.key
312
- );
313
- }),
314
- /* @__PURE__ */ jsx("span", { style: { flex: "none", width: 96 }, children: /* @__PURE__ */ jsx(
315
- Select,
316
- {
317
- "aria-label": `${row.label || row.entity} \uBC94\uC704`,
318
- value: scopeOf.get(row.entity) ?? defaultScope,
319
- options: scopeOptions,
320
- disabled: disabled || !anyOn,
321
- onChange: (event) => setEntityScope(row.entity, event.target.value)
322
- }
323
- ) }),
324
- /* @__PURE__ */ jsx("span", { style: { flex: "none", width: 60, textAlign: "right" }, children: /* @__PURE__ */ jsx(
325
- Button,
326
- {
327
- type: "button",
328
- size: "sm",
329
- variant: "ghost",
330
- disabled,
331
- onClick: () => toggleRow(row, !allOn),
332
- children: allOn ? "\uD574\uC81C" : "\uC804\uCCB4"
333
- }
334
- ) })
335
- ]
336
- },
337
- row.entity
338
- );
339
- })
340
- ] })
341
- ] }, group.category);
342
- })
343
- }
344
- )
345
- ] });
346
- }
347
- var PermissionMatrixEditor = boxed(
348
- PermissionMatrixEditorImpl,
349
- "PermissionMatrixEditor"
350
- );
351
-
352
- export { PermissionMatrixEditor };
@@ -1,111 +0,0 @@
1
- import { useRef, useState, useEffect, useCallback } from 'react';
2
-
3
- // src/widgets/usePanZoomCanvas.ts
4
- var MIN_ZOOM = 0.35;
5
- var MAX_ZOOM = 1.8;
6
- var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
7
- function applyZoom(current, nextScale, focal) {
8
- const scale = clamp(nextScale, MIN_ZOOM, MAX_ZOOM);
9
- return {
10
- scale,
11
- x: focal.x - (focal.x - current.x) / current.scale * scale,
12
- y: focal.y - (focal.y - current.y) / current.scale * scale
13
- };
14
- }
15
- function usePanZoomCanvas(options) {
16
- const { stopSelector, initialView } = options;
17
- const viewportRef = useRef(null);
18
- const dragRef = useRef(null);
19
- const [view, setView] = useState(initialView);
20
- const [dragging, setDragging] = useState(false);
21
- const [isFullscreen, setIsFullscreen] = useState(false);
22
- useEffect(() => {
23
- const handleFullscreenChange = () => {
24
- setIsFullscreen(document.fullscreenElement === viewportRef.current);
25
- };
26
- document.addEventListener("fullscreenchange", handleFullscreenChange);
27
- return () => document.removeEventListener("fullscreenchange", handleFullscreenChange);
28
- }, []);
29
- useEffect(() => {
30
- const viewport = viewportRef.current;
31
- if (!viewport) return;
32
- const onWheel = (event) => {
33
- event.preventDefault();
34
- const rect = viewport.getBoundingClientRect();
35
- const focal = { x: event.clientX - rect.left, y: event.clientY - rect.top };
36
- setView(
37
- (current) => applyZoom(current, current.scale * (event.deltaY > 0 ? 0.9 : 1.1), focal)
38
- );
39
- };
40
- viewport.addEventListener("wheel", onWheel, { passive: false });
41
- return () => viewport.removeEventListener("wheel", onWheel);
42
- }, []);
43
- const viewportCenter = useCallback(() => {
44
- const rect = viewportRef.current?.getBoundingClientRect();
45
- if (!rect) return { x: 0, y: 0 };
46
- return { x: rect.width / 2, y: rect.height / 2 };
47
- }, []);
48
- const zoomAt = useCallback((nextScale, focal) => {
49
- setView((current) => applyZoom(current, nextScale, focal));
50
- }, []);
51
- const handlePointerDown = (event) => {
52
- if (event.target.closest(stopSelector)) return;
53
- dragRef.current = {
54
- pointerId: event.pointerId,
55
- startX: event.clientX,
56
- startY: event.clientY,
57
- originX: view.x,
58
- originY: view.y
59
- };
60
- setDragging(true);
61
- event.currentTarget.setPointerCapture(event.pointerId);
62
- };
63
- const handlePointerMove = (event) => {
64
- const drag = dragRef.current;
65
- if (!drag || drag.pointerId !== event.pointerId) return;
66
- setView((current) => ({
67
- ...current,
68
- x: drag.originX + event.clientX - drag.startX,
69
- y: drag.originY + event.clientY - drag.startY
70
- }));
71
- };
72
- const handlePointerUp = (event) => {
73
- if (dragRef.current?.pointerId !== event.pointerId) return;
74
- dragRef.current = null;
75
- setDragging(false);
76
- if (event.currentTarget.hasPointerCapture(event.pointerId)) {
77
- event.currentTarget.releasePointerCapture(event.pointerId);
78
- }
79
- };
80
- const toggleFullscreen = async () => {
81
- const viewport = viewportRef.current;
82
- if (!viewport) return;
83
- try {
84
- if (document.fullscreenElement === viewport) {
85
- await document.exitFullscreen();
86
- return;
87
- }
88
- await viewport.requestFullscreen();
89
- } catch {
90
- }
91
- };
92
- return {
93
- viewportRef,
94
- view,
95
- setView,
96
- dragging,
97
- isFullscreen,
98
- viewportCenter,
99
- zoomAt,
100
- toggleFullscreen,
101
- /** 뷰포트 div에 그대로 spread — 패닝 4종 핸들러. */
102
- pointerHandlers: {
103
- onPointerDown: handlePointerDown,
104
- onPointerMove: handlePointerMove,
105
- onPointerUp: handlePointerUp,
106
- onPointerCancel: handlePointerUp
107
- }
108
- };
109
- }
110
-
111
- export { MAX_ZOOM, MIN_ZOOM, usePanZoomCanvas };
@@ -1,39 +0,0 @@
1
- import { OverlayLayer } from './chunk-XQPTSEJC.js';
2
- import { Dialog, warnOnce } from './chunk-RNOUXUBO.js';
3
- import { createContext, useContext, useMemo } from 'react';
4
- import { jsx } from 'react/jsx-runtime';
5
-
6
- var SduiDispatchContext = createContext(null);
7
- function useSduiDispatch() {
8
- const dispatch = useContext(SduiDispatchContext);
9
- if (!dispatch) {
10
- throw new Error("useSduiDispatch\uB294 SduiRenderer \uB0B4\uBD80\uC5D0\uC11C\uB9CC \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.");
11
- }
12
- return dispatch;
13
- }
14
- var ALLOW_ALL = () => true;
15
- var DENY_ALL = () => false;
16
- var MISSING = () => {
17
- warnOnce(
18
- "permission:missing",
19
- '[sdui] \uAD8C\uD55C \uD310\uC815(can)\uC774 \uC8FC\uC785\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4 \u2014 <Can>\uC774 \uC804\uBD80 \uD1B5\uACFC\uD569\uB2C8\uB2E4. SduiRenderer\uC5D0 can \uCF5C\uBC31\uC744 \uB118\uAE30\uAC70\uB098, \uC138\uC158\uC774 \uC5C6\uB294 \uBBF8\uB9AC\uBCF4\uAE30\uB77C\uBA74 can="allow-all"\uC744 \uBA85\uC2DC\uD558\uC138\uC694.'
20
- );
21
- return true;
22
- };
23
- var SduiPermissionContext = createContext(null);
24
- function SduiPermissionProvider({ can, children }) {
25
- const value = useMemo(() => {
26
- if (can === "allow-all") return ALLOW_ALL;
27
- if (can === "deny-all") return DENY_ALL;
28
- return typeof can === "function" ? can : null;
29
- }, [can]);
30
- return /* @__PURE__ */ jsx(SduiPermissionContext.Provider, { value, children });
31
- }
32
- function useSduiCan() {
33
- return useContext(SduiPermissionContext) ?? MISSING;
34
- }
35
- function SduiDialog(props) {
36
- return /* @__PURE__ */ jsx(OverlayLayer, { onClose: props.onClose, children: /* @__PURE__ */ jsx(Dialog, { ...props }) });
37
- }
38
-
39
- export { SduiDialog, SduiDispatchContext, SduiPermissionProvider, useSduiCan, useSduiDispatch };
@@ -1,135 +0,0 @@
1
- import React, { useRef, useEffect, useSyncExternalStore } from 'react';
2
- import { createPortal } from 'react-dom';
3
- import { jsx } from 'react/jsx-runtime';
4
-
5
- // src/overlay.tsx
6
- var OVERLAY_ROOT_ID = "wp-overlay-root";
7
- var DOCUMENT_POSITION_FOLLOWING = 4;
8
- function getOverlayRoot() {
9
- if (typeof document === "undefined") return null;
10
- const existing = document.getElementById(OVERLAY_ROOT_ID);
11
- if (existing) return existing;
12
- const created = document.createElement("div");
13
- created.id = OVERLAY_ROOT_ID;
14
- document.body.appendChild(created);
15
- return created;
16
- }
17
- var layers = [];
18
- var nextId = 0;
19
- var subscribers = /* @__PURE__ */ new Set();
20
- var keyListenerBound = false;
21
- function emit() {
22
- layers = layers.slice();
23
- subscribers.forEach((fn) => fn());
24
- }
25
- function topLayer(list) {
26
- let best;
27
- let bestNode = null;
28
- for (const layer of list) {
29
- const node = layer.node();
30
- if (!best) {
31
- best = layer;
32
- bestNode = node;
33
- continue;
34
- }
35
- if (!node) continue;
36
- if (!bestNode) {
37
- best = layer;
38
- bestNode = node;
39
- continue;
40
- }
41
- if (bestNode.compareDocumentPosition(node) & DOCUMENT_POSITION_FOLLOWING) {
42
- best = layer;
43
- bestNode = node;
44
- }
45
- }
46
- return best;
47
- }
48
- function layerHoldsTop(list, id) {
49
- const top = topLayer(list);
50
- if (!top) return false;
51
- if (top.id === id) return true;
52
- const mine = list.find((l) => l.id === id)?.node();
53
- const topNode = top.node();
54
- return !!mine && !!topNode && mine.contains(topNode);
55
- }
56
- function escapeTopmost() {
57
- topLayer(layers)?.onEscape();
58
- }
59
- function handleKeyDown(event) {
60
- if (event.key !== "Escape") return;
61
- escapeTopmost();
62
- }
63
- function push(layer) {
64
- layers.push(layer);
65
- if (!keyListenerBound && typeof document !== "undefined") {
66
- document.addEventListener("keydown", handleKeyDown);
67
- keyListenerBound = true;
68
- }
69
- emit();
70
- }
71
- function remove(id) {
72
- layers = layers.filter((l) => l.id !== id);
73
- emit();
74
- }
75
- function subscribe(fn) {
76
- subscribers.add(fn);
77
- return () => {
78
- subscribers.delete(fn);
79
- };
80
- }
81
- var snapshot = () => layers;
82
- var serverSnapshot = () => [];
83
- function useOverlayLayer(active, onEscape, nodeRef) {
84
- const idRef = useRef(0);
85
- if (idRef.current === 0) idRef.current = ++nextId;
86
- const escapeRef = useRef(onEscape);
87
- escapeRef.current = onEscape;
88
- const nodeRefRef = useRef(nodeRef);
89
- nodeRefRef.current = nodeRef;
90
- useEffect(() => {
91
- if (!active) return;
92
- const id2 = idRef.current;
93
- push({
94
- id: id2,
95
- onEscape: () => escapeRef.current?.(),
96
- node: () => nodeRefRef.current?.current ?? null
97
- });
98
- return () => remove(id2);
99
- }, [active]);
100
- const current = useSyncExternalStore(subscribe, snapshot, serverSnapshot);
101
- const id = idRef.current;
102
- return {
103
- isTop: active && topLayer(current)?.id === id,
104
- holdsTop: active && layerHoldsTop(current, id)
105
- };
106
- }
107
- var OverlayContainerContext = React.createContext(null);
108
- function OverlayLayer({
109
- onClose,
110
- children
111
- }) {
112
- const ref = useRef(null);
113
- const container = React.useContext(OverlayContainerContext);
114
- const { holdsTop } = useOverlayLayer(true, onClose, ref);
115
- useEffect(() => {
116
- ref.current?.toggleAttribute("inert", !holdsTop);
117
- }, [holdsTop]);
118
- const layer = /* @__PURE__ */ jsx(
119
- "div",
120
- {
121
- ref,
122
- className: "wp-overlay-layer",
123
- onClick: (event) => {
124
- if (onClose && event.target instanceof HTMLElement && event.target.classList.contains("wp-overlay")) {
125
- onClose();
126
- }
127
- },
128
- children
129
- }
130
- );
131
- const root = container ?? getOverlayRoot();
132
- return root ? createPortal(layer, root) : layer;
133
- }
134
-
135
- export { OverlayContainerContext, OverlayLayer, getOverlayRoot, useOverlayLayer };