@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.
- package/dist/{DatePicker-C_TT_SOw.d.ts → DatePicker-DX9juElE.d.ts} +10 -1
- package/dist/{chunk-GZBY7I4Y.js → chunk-2KQL6DYG.js} +3 -3
- package/dist/{chunk-RYBBPFI7.js → chunk-2QXA52DG.js} +4 -4
- package/dist/{chunk-DMLDKW7K.js → chunk-37BNG4DT.js} +1 -1
- package/dist/{chunk-5WW4MBRO.js → chunk-3JTBOABA.js} +6 -2
- package/dist/{chunk-UV6HHFEW.js → chunk-4OABUPIU.js} +129 -68
- package/dist/{chunk-ZORQPB6B.js → chunk-53KS4E5N.js} +318 -359
- package/dist/{chunk-I5SD7XRA.js → chunk-6TI4WF5Y.js} +3 -3
- package/dist/{chunk-44TDRCKR.js → chunk-6XI2VF2O.js} +5 -5
- package/dist/{chunk-HBIIEYKW.js → chunk-7C54CKFZ.js} +4 -4
- package/dist/{chunk-IZ3JA2BR.js → chunk-7JP52QQO.js} +3 -3
- package/dist/{chunk-I45EUZC6.js → chunk-AY4GM6KQ.js} +4 -2
- package/dist/{chunk-SAPBDJJQ.js → chunk-AZSLSAJB.js} +2 -2
- package/dist/chunk-BITS7UJY.js +333 -0
- package/dist/{chunk-RNOUXUBO.js → chunk-BLFJMMBW.js} +306 -57
- package/dist/{chunk-YOZN35HD.js → chunk-CEVZAFPO.js} +3 -3
- package/dist/chunk-CI5OZ2QT.js +106 -0
- package/dist/{chunk-FNMS7OB7.js → chunk-CSE3PZOZ.js} +5 -5
- package/dist/chunk-CSZCWBOE.js +256 -0
- package/dist/{chunk-JIV4YHCZ.js → chunk-EJIWOD7W.js} +1 -1
- package/dist/{chunk-JZXU22PE.js → chunk-FEKKOBPX.js} +208 -117
- package/dist/chunk-GSM664TX.js +38 -0
- package/dist/{chunk-JYAR7D5U.js → chunk-HRHKQOOF.js} +2 -2
- package/dist/{chunk-CXW6KT6X.js → chunk-HXLQSO66.js} +3 -3
- package/dist/{chunk-O4IISNE7.js → chunk-IB2ZPUTF.js} +51 -12
- package/dist/{chunk-MPT7WJG2.js → chunk-IQXLNICY.js} +5 -5
- package/dist/{chunk-OQ52XMGG.js → chunk-K6RE23XX.js} +4 -4
- package/dist/{chunk-VY7MVBSE.js → chunk-KZ6U6FKB.js} +2 -2
- package/dist/{chunk-WPSK2CB5.js → chunk-LIZTK3HO.js} +16 -5
- package/dist/{chunk-Q4SWUINA.js → chunk-LKQJJSVJ.js} +1 -1
- package/dist/{chunk-E6ISNQK3.js → chunk-M6H3SHIS.js} +31 -8
- package/dist/chunk-MN4RZ2WP.js +380 -0
- package/dist/{chunk-GTGS2QRL.js → chunk-NA232CBX.js} +3 -3
- package/dist/{chunk-ZFNFPXPR.js → chunk-NAIWQQPW.js} +2 -2
- package/dist/{chunk-YVTV4ZV6.js → chunk-NWYYNE3Q.js} +1 -1
- package/dist/{chunk-DKVSM5HX.js → chunk-OUEJWC2Z.js} +6 -6
- package/dist/{chunk-DOL57OOP.js → chunk-OYDJHQNZ.js} +3 -3
- package/dist/{chunk-YWUDBLO6.js → chunk-QVS6K4FP.js} +2 -2
- package/dist/{chunk-N5RKM6IC.js → chunk-RU5U2YMT.js} +4 -4
- package/dist/{chunk-A6LAIGUS.js → chunk-V7BWMOHO.js} +7 -4
- package/dist/{chunk-2HLXCKK7.js → chunk-VPOOIEKT.js} +2 -2
- package/dist/{chunk-2YP5N4VV.js → chunk-VZOQRQAR.js} +1 -1
- package/dist/{chunk-GNA6SX2H.js → chunk-W4VA76QO.js} +2 -2
- package/dist/{chunk-BEM2YS7U.js → chunk-WEG3V7ZB.js} +3 -3
- package/dist/{chunk-XGFDY43I.js → chunk-WTIYILY3.js} +88 -18
- package/dist/{chunk-RWSH2MBU.js → chunk-X2NIRVLN.js} +73 -19
- package/dist/{chunk-AXGF4M57.js → chunk-XAXROQKB.js} +1 -1
- package/dist/{chunk-NIJUVTEW.js → chunk-XG22XKKD.js} +3 -3
- package/dist/{chunk-A5XQOEVH.js → chunk-YN7X7BEO.js} +4 -4
- package/dist/{chunk-KO6OEY3G.js → chunk-YNEEJCSZ.js} +3 -13
- package/dist/{chunk-7P7N43JV.js → chunk-YZTTFEL4.js} +2 -2
- package/dist/index.d.ts +494 -89
- package/dist/index.js +1098 -124
- package/dist/{layout-C3nRXMwb.d.ts → layout-DmRikwZb.d.ts} +5 -4
- package/dist/meta.d.ts +1 -1
- package/dist/meta.js +286 -22
- package/dist/rich/ExcelUploadCard.d.ts +1 -1
- package/dist/rich/ExcelUploadCard.js +5 -4
- package/dist/rich.d.ts +21 -3
- package/dist/rich.js +277 -35
- package/dist/styles.css +102 -4
- package/dist/{types-COjGKgmd.d.ts → types-CYfIthux.d.ts} +57 -1
- package/dist/widgets/ApprovalLineEditor.d.ts +1 -1
- package/dist/widgets/ApprovalLineEditor.js +9 -8
- package/dist/widgets/ApprovalOverridesEditor.d.ts +1 -1
- package/dist/widgets/ApprovalOverridesEditor.js +11 -10
- package/dist/widgets/ApprovalStepper.d.ts +29 -4
- package/dist/widgets/ApprovalStepper.js +3 -3
- package/dist/widgets/AutocompleteField.d.ts +1 -1
- package/dist/widgets/AutocompleteField.js +9 -8
- package/dist/widgets/ColumnBoard.d.ts +1 -1
- package/dist/widgets/ColumnBoard.js +3 -3
- package/dist/widgets/DiffView.d.ts +1 -1
- package/dist/widgets/DiffView.js +3 -3
- package/dist/widgets/Disclosure.d.ts +1 -1
- package/dist/widgets/Disclosure.js +3 -3
- package/dist/widgets/EventCalendar.d.ts +5 -1
- package/dist/widgets/EventCalendar.js +5 -3
- package/dist/widgets/FileDropzone.d.ts +1 -1
- package/dist/widgets/FileDropzone.js +9 -7
- package/dist/widgets/ImageLightbox.d.ts +1 -1
- package/dist/widgets/ImageLightbox.js +7 -5
- package/dist/widgets/InlineEdit.d.ts +1 -1
- package/dist/widgets/InlineEdit.js +3 -3
- package/dist/widgets/JsonField.d.ts +1 -1
- package/dist/widgets/JsonField.js +3 -3
- package/dist/widgets/LiveClock.d.ts +1 -1
- package/dist/widgets/LiveClock.js +2 -2
- package/dist/widgets/OptionSchemaEditor.d.ts +1 -1
- package/dist/widgets/OptionSchemaEditor.js +4 -4
- package/dist/widgets/OptionValueFields.d.ts +1 -1
- package/dist/widgets/OptionValueFields.js +4 -4
- package/dist/widgets/OrgChart.d.ts +1 -1
- package/dist/widgets/OrgChart.js +4 -4
- package/dist/widgets/OrgChartBoard.d.ts +15 -33
- package/dist/widgets/OrgChartBoard.js +10 -8
- package/dist/widgets/PeriodFilter.d.ts +1 -1
- package/dist/widgets/PeriodFilter.js +6 -5
- package/dist/widgets/PermissionMatrixEditor.d.ts +34 -2
- package/dist/widgets/PermissionMatrixEditor.js +6 -4
- package/dist/widgets/PositionSelect.d.ts +1 -1
- package/dist/widgets/PositionSelect.js +5 -4
- package/dist/widgets/PrintSheet.d.ts +15 -2
- package/dist/widgets/PrintSheet.js +3 -3
- package/dist/widgets/ProfileEditDiffCard.d.ts +1 -1
- package/dist/widgets/ProfileEditDiffCard.js +5 -4
- package/dist/widgets/QRDisplay.d.ts +1 -1
- package/dist/widgets/QRDisplay.js +5 -4
- package/dist/widgets/RankBoard.d.ts +1 -1
- package/dist/widgets/RankBoard.js +8 -6
- package/dist/widgets/RecordSheet.d.ts +1 -1
- package/dist/widgets/RecordSheet.js +2 -2
- package/dist/widgets/RoleMemberPicker.d.ts +1 -1
- package/dist/widgets/RoleMemberPicker.js +6 -5
- package/dist/widgets/SearchableMultiPicker.d.ts +1 -1
- package/dist/widgets/SearchableMultiPicker.js +7 -6
- package/dist/widgets/SecureScreen.d.ts +1 -1
- package/dist/widgets/SecureScreen.js +3 -3
- package/dist/widgets/StackedMeter.d.ts +1 -1
- package/dist/widgets/StackedMeter.js +2 -2
- package/dist/widgets/StagePeriodEditor.d.ts +1 -1
- package/dist/widgets/StagePeriodEditor.js +6 -5
- package/dist/widgets/Strip.d.ts +1 -1
- package/dist/widgets/Strip.js +2 -2
- package/dist/widgets/SummaryTable.d.ts +1 -1
- package/dist/widgets/SummaryTable.js +2 -2
- package/dist/widgets/TagInput.d.ts +1 -1
- package/dist/widgets/TagInput.js +3 -3
- package/dist/widgets/TagMultiSelect.d.ts +1 -1
- package/dist/widgets/TagMultiSelect.js +5 -4
- package/dist/widgets/Timeline.d.ts +1 -1
- package/dist/widgets/Timeline.js +4 -4
- package/dist/widgets/TreePicker.d.ts +1 -1
- package/dist/widgets/TreePicker.js +8 -7
- package/dist/widgets/TreeView.d.ts +1 -1
- package/dist/widgets/TreeView.js +7 -6
- package/dist/widgets/index.d.ts +3 -3
- package/dist/widgets/index.js +84 -83
- package/package.json +1 -1
- package/dist/chunk-LFEJLOFN.js +0 -352
- package/dist/chunk-MMIGOPO5.js +0 -111
- package/dist/chunk-TFGNKFL2.js +0 -39
- package/dist/chunk-XQPTSEJC.js +0 -135
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mergeStyle, containerLayoutStyle, joinClass } from './chunk-
|
|
1
|
+
import { mergeStyle, containerLayoutStyle, joinClass } from './chunk-3JTBOABA.js';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
|
|
@@ -183,8 +183,135 @@ var CALC_OPS = /* @__PURE__ */ new Set([
|
|
|
183
183
|
"join",
|
|
184
184
|
"split",
|
|
185
185
|
"sortBy",
|
|
186
|
-
"map"
|
|
186
|
+
"map",
|
|
187
|
+
// 서식 (신규) — 원시 ISO 일시·금액을 Text 로 찍던 자리를 사람이 읽는 글자로
|
|
188
|
+
"formatDate",
|
|
189
|
+
"formatNumber",
|
|
190
|
+
// 지금 — 인쇄 양식의 "출력일"처럼 스펙이 오늘 날짜를 박아 두던 자리(고정값 2026-08-03 실측)
|
|
191
|
+
"today"
|
|
187
192
|
]);
|
|
193
|
+
var KST_OFFSET_MINUTES = 9 * 60;
|
|
194
|
+
var ISO_DATE_RE = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
195
|
+
var ISO_DATETIME_RE = /^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2})(?::(\d{2})(?:[.,]\d+)?)?(Z|[+-]\d{2}(?::?\d{2})?)?$/i;
|
|
196
|
+
var pad2 = (n) => String(n).padStart(2, "0");
|
|
197
|
+
function isRealDate(year, month, day) {
|
|
198
|
+
if (month < 1 || month > 12 || day < 1) return false;
|
|
199
|
+
const probe = new Date(Date.UTC(year, month - 1, day));
|
|
200
|
+
return probe.getUTCFullYear() === year && probe.getUTCMonth() === month - 1 && probe.getUTCDate() === day;
|
|
201
|
+
}
|
|
202
|
+
function offsetMinutes(zone) {
|
|
203
|
+
if (zone === "Z" || zone === "z") return 0;
|
|
204
|
+
const match = /^([+-])(\d{2}):?(\d{2})?$/.exec(zone);
|
|
205
|
+
if (!match) return null;
|
|
206
|
+
const hours = Number(match[2]);
|
|
207
|
+
const minutes = Number(match[3] ?? "0");
|
|
208
|
+
if (hours > 23 || minutes > 59) return null;
|
|
209
|
+
const total = hours * 60 + minutes;
|
|
210
|
+
return match[1] === "-" ? -total : total;
|
|
211
|
+
}
|
|
212
|
+
function kstClockOf(utcMs) {
|
|
213
|
+
const shifted = new Date(utcMs + KST_OFFSET_MINUTES * 6e4);
|
|
214
|
+
return {
|
|
215
|
+
year: shifted.getUTCFullYear(),
|
|
216
|
+
month: shifted.getUTCMonth() + 1,
|
|
217
|
+
day: shifted.getUTCDate(),
|
|
218
|
+
hour: shifted.getUTCHours(),
|
|
219
|
+
minute: shifted.getUTCMinutes(),
|
|
220
|
+
hasTime: true
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
function wallClockOf(text) {
|
|
224
|
+
const trimmed = text.trim();
|
|
225
|
+
const dateOnly = ISO_DATE_RE.exec(trimmed);
|
|
226
|
+
if (dateOnly) {
|
|
227
|
+
const [year2, month2, day2] = [Number(dateOnly[1]), Number(dateOnly[2]), Number(dateOnly[3])];
|
|
228
|
+
if (!isRealDate(year2, month2, day2)) return null;
|
|
229
|
+
return { year: year2, month: month2, day: day2, hour: 0, minute: 0, hasTime: false };
|
|
230
|
+
}
|
|
231
|
+
const match = ISO_DATETIME_RE.exec(trimmed);
|
|
232
|
+
if (!match) return null;
|
|
233
|
+
const year = Number(match[1]);
|
|
234
|
+
const month = Number(match[2]);
|
|
235
|
+
const day = Number(match[3]);
|
|
236
|
+
const hour = Number(match[4]);
|
|
237
|
+
const minute = Number(match[5]);
|
|
238
|
+
const second = match[6] === void 0 ? 0 : Number(match[6]);
|
|
239
|
+
if (!isRealDate(year, month, day) || hour > 23 || minute > 59 || second > 60) return null;
|
|
240
|
+
const zone = match[7];
|
|
241
|
+
if (zone === void 0) return { year, month, day, hour, minute, hasTime: true };
|
|
242
|
+
const offset = offsetMinutes(zone);
|
|
243
|
+
if (offset === null) return null;
|
|
244
|
+
return kstClockOf(Date.UTC(year, month - 1, day, hour, minute, second) - offset * 6e4);
|
|
245
|
+
}
|
|
246
|
+
function isZonedIsoDateTime(value) {
|
|
247
|
+
if (typeof value !== "string") return false;
|
|
248
|
+
const match = ISO_DATETIME_RE.exec(value.trim());
|
|
249
|
+
return match !== null && match[7] !== void 0 && wallClockOf(value) !== null;
|
|
250
|
+
}
|
|
251
|
+
function formatDateValue(value, format = "datetime") {
|
|
252
|
+
if (value === null || value === void 0 || value === "") return "";
|
|
253
|
+
let clock;
|
|
254
|
+
if (value instanceof Date) {
|
|
255
|
+
clock = Number.isNaN(value.getTime()) ? null : kstClockOf(value.getTime());
|
|
256
|
+
} else if (typeof value === "string") {
|
|
257
|
+
clock = wallClockOf(value);
|
|
258
|
+
} else {
|
|
259
|
+
return String(value);
|
|
260
|
+
}
|
|
261
|
+
if (!clock) return typeof value === "string" ? value : "";
|
|
262
|
+
const ymd = `${String(clock.year).padStart(4, "0")}-${pad2(clock.month)}-${pad2(clock.day)}`;
|
|
263
|
+
if (!clock.hasTime) return ymd;
|
|
264
|
+
const hm = `${pad2(clock.hour)}:${pad2(clock.minute)}`;
|
|
265
|
+
if (format === "date") return ymd;
|
|
266
|
+
if (format === "time") return hm;
|
|
267
|
+
return `${ymd} ${hm}`;
|
|
268
|
+
}
|
|
269
|
+
function parseNumeric(value) {
|
|
270
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : null;
|
|
271
|
+
if (typeof value !== "string") return null;
|
|
272
|
+
const plain = value.replace(/,/g, "").trim();
|
|
273
|
+
if (!/^[+-]?(\d+(\.\d*)?|\.\d+)$/.test(plain)) return null;
|
|
274
|
+
const parsed = Number(plain);
|
|
275
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
276
|
+
}
|
|
277
|
+
function groupThousands(value) {
|
|
278
|
+
const text = String(value);
|
|
279
|
+
if (!/^-?\d+(\.\d+)?$/.test(text)) return text;
|
|
280
|
+
const negative = text.startsWith("-");
|
|
281
|
+
const [integer, fraction] = (negative ? text.slice(1) : text).split(".");
|
|
282
|
+
const grouped = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
283
|
+
return `${negative ? "-" : ""}${grouped}${fraction === void 0 ? "" : `.${fraction}`}`;
|
|
284
|
+
}
|
|
285
|
+
function formatNumberValue(value, digits) {
|
|
286
|
+
if (value === null || value === void 0 || value === "") return "";
|
|
287
|
+
const numeric = parseNumeric(value);
|
|
288
|
+
if (numeric === null) return typeof value === "string" ? value : String(value);
|
|
289
|
+
const wanted = digits === null || digits === void 0 || digits === "" ? NaN : Number(digits);
|
|
290
|
+
if (!Number.isFinite(wanted)) return groupThousands(numeric);
|
|
291
|
+
const fixed = Math.max(0, Math.min(6, Math.trunc(wanted)));
|
|
292
|
+
return new Intl.NumberFormat("ko-KR", {
|
|
293
|
+
minimumFractionDigits: fixed,
|
|
294
|
+
maximumFractionDigits: fixed
|
|
295
|
+
}).format(numeric);
|
|
296
|
+
}
|
|
297
|
+
var DISPLAY_FORMATS = /* @__PURE__ */ new Set(["date", "datetime", "time", "number", "currency"]);
|
|
298
|
+
function formatDisplayValue(value, format) {
|
|
299
|
+
if (typeof value !== "string" && typeof value !== "number") return value;
|
|
300
|
+
if (value === "") return value;
|
|
301
|
+
const chosen = typeof format === "string" && DISPLAY_FORMATS.has(format) ? format : void 0;
|
|
302
|
+
switch (chosen) {
|
|
303
|
+
case "date":
|
|
304
|
+
case "datetime":
|
|
305
|
+
case "time":
|
|
306
|
+
return typeof value === "string" ? formatDateValue(value, chosen) : value;
|
|
307
|
+
case "number":
|
|
308
|
+
return formatNumberValue(value);
|
|
309
|
+
case "currency":
|
|
310
|
+
return parseNumeric(value) === null ? value : `${formatNumberValue(value, 0)}\uC6D0`;
|
|
311
|
+
default:
|
|
312
|
+
return isZonedIsoDateTime(value) ? formatDateValue(value, "datetime") : value;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
188
315
|
function isFieldRef(value) {
|
|
189
316
|
return isPlainObject(value) && "$field" in value;
|
|
190
317
|
}
|
|
@@ -395,6 +522,17 @@ function evaluateCalc(calc, resolved, resolve) {
|
|
|
395
522
|
return desc ? -order : order;
|
|
396
523
|
});
|
|
397
524
|
}
|
|
525
|
+
/* ── 서식 ── */
|
|
526
|
+
case "formatDate": {
|
|
527
|
+
const format = resolved[1];
|
|
528
|
+
return formatDateValue(first, format === "date" || format === "time" ? format : "datetime");
|
|
529
|
+
}
|
|
530
|
+
case "formatNumber":
|
|
531
|
+
return formatNumberValue(first, resolved[1]);
|
|
532
|
+
case "today": {
|
|
533
|
+
const format = first === "datetime" || first === "time" ? first : "date";
|
|
534
|
+
return formatDateValue(/* @__PURE__ */ new Date(), format);
|
|
535
|
+
}
|
|
398
536
|
default:
|
|
399
537
|
return null;
|
|
400
538
|
}
|
|
@@ -1219,6 +1357,48 @@ function pickOptionText(option, key) {
|
|
|
1219
1357
|
if (raw === null || raw === void 0) return void 0;
|
|
1220
1358
|
return String(raw);
|
|
1221
1359
|
}
|
|
1360
|
+
var SELECT_BOX_STYLE_KEYS = /* @__PURE__ */ new Set([
|
|
1361
|
+
"width",
|
|
1362
|
+
"minWidth",
|
|
1363
|
+
"maxWidth",
|
|
1364
|
+
"flex",
|
|
1365
|
+
"flexGrow",
|
|
1366
|
+
"flexShrink",
|
|
1367
|
+
"flexBasis",
|
|
1368
|
+
"alignSelf",
|
|
1369
|
+
"justifySelf",
|
|
1370
|
+
"order",
|
|
1371
|
+
"gridColumn",
|
|
1372
|
+
"gridColumnStart",
|
|
1373
|
+
"gridColumnEnd",
|
|
1374
|
+
"gridRow",
|
|
1375
|
+
"gridRowStart",
|
|
1376
|
+
"gridRowEnd",
|
|
1377
|
+
"gridArea",
|
|
1378
|
+
"margin",
|
|
1379
|
+
"marginTop",
|
|
1380
|
+
"marginBottom",
|
|
1381
|
+
"marginLeft",
|
|
1382
|
+
"marginRight",
|
|
1383
|
+
"marginInline",
|
|
1384
|
+
"marginInlineStart",
|
|
1385
|
+
"marginInlineEnd",
|
|
1386
|
+
"marginBlock",
|
|
1387
|
+
"marginBlockStart",
|
|
1388
|
+
"marginBlockEnd"
|
|
1389
|
+
]);
|
|
1390
|
+
function splitSelectStyle(style) {
|
|
1391
|
+
if (!style) return {};
|
|
1392
|
+
const box = {};
|
|
1393
|
+
const control = {};
|
|
1394
|
+
for (const [key, value] of Object.entries(style)) {
|
|
1395
|
+
(SELECT_BOX_STYLE_KEYS.has(key) ? box : control)[key] = value;
|
|
1396
|
+
}
|
|
1397
|
+
return {
|
|
1398
|
+
box: Object.keys(box).length > 0 ? box : void 0,
|
|
1399
|
+
control: Object.keys(control).length > 0 ? control : void 0
|
|
1400
|
+
};
|
|
1401
|
+
}
|
|
1222
1402
|
function Select({
|
|
1223
1403
|
options,
|
|
1224
1404
|
valueKey = "value",
|
|
@@ -1227,15 +1407,17 @@ function Select({
|
|
|
1227
1407
|
invalid = false,
|
|
1228
1408
|
placeholder,
|
|
1229
1409
|
className = "",
|
|
1410
|
+
style,
|
|
1230
1411
|
...rest
|
|
1231
1412
|
}) {
|
|
1413
|
+
const { box: boxStyle, control: controlStyle } = splitSelectStyle(style);
|
|
1232
1414
|
const classes = ["wp-select"];
|
|
1233
1415
|
if (size !== "md") classes.push(`wp-select--${size}`);
|
|
1234
1416
|
if (invalid) classes.push("wp-select--invalid");
|
|
1235
1417
|
if (className) classes.push(className);
|
|
1236
1418
|
const list = Array.isArray(options) ? options : [];
|
|
1237
|
-
return /* @__PURE__ */ jsxs("div", { className: "wp-selectwrap", children: [
|
|
1238
|
-
/* @__PURE__ */ jsxs("select", { className: classes.join(" "), "aria-invalid": invalid || void 0, ...rest, children: [
|
|
1419
|
+
return /* @__PURE__ */ jsxs("div", { className: "wp-selectwrap", style: boxStyle, children: [
|
|
1420
|
+
/* @__PURE__ */ jsxs("select", { className: classes.join(" "), "aria-invalid": invalid || void 0, style: controlStyle, ...rest, children: [
|
|
1239
1421
|
placeholder ? /* @__PURE__ */ jsx("option", { value: "", children: placeholder }) : null,
|
|
1240
1422
|
list.map((option, index) => {
|
|
1241
1423
|
const value = pickOptionText(option, valueKey);
|
|
@@ -1262,12 +1444,12 @@ function Select({
|
|
|
1262
1444
|
/* @__PURE__ */ jsx("span", { className: "wp-selectwrap__caret", children: /* @__PURE__ */ jsx(Icon, { name: "chevron-down", size: 15 }) })
|
|
1263
1445
|
] });
|
|
1264
1446
|
}
|
|
1265
|
-
function Checkbox({ label, description, indeterminate = false, disabled = false, className = "", ...rest }) {
|
|
1447
|
+
function Checkbox({ label, description, indeterminate = false, disabled = false, className = "", style, ...rest }) {
|
|
1266
1448
|
const ref = React.useRef(null);
|
|
1267
1449
|
React.useEffect(() => {
|
|
1268
1450
|
if (ref.current) ref.current.indeterminate = indeterminate;
|
|
1269
1451
|
}, [indeterminate]);
|
|
1270
|
-
return /* @__PURE__ */ jsxs("label", { className: joinClass("wp-check", disabled && "wp-check--disabled", className), children: [
|
|
1452
|
+
return /* @__PURE__ */ jsxs("label", { className: joinClass("wp-check", disabled && "wp-check--disabled", className), style, children: [
|
|
1271
1453
|
/* @__PURE__ */ jsx("input", { ref, type: "checkbox", disabled, ...rest }),
|
|
1272
1454
|
/* @__PURE__ */ jsx("span", { className: "wp-check__box", children: /* @__PURE__ */ jsx(Icon, { name: indeterminate ? "minus" : "check", size: 12, strokeWidth: 2.5 }) }),
|
|
1273
1455
|
label || description ? /* @__PURE__ */ jsxs("span", { className: "wp-check__text", children: [
|
|
@@ -1276,8 +1458,8 @@ function Checkbox({ label, description, indeterminate = false, disabled = false,
|
|
|
1276
1458
|
] }) : null
|
|
1277
1459
|
] });
|
|
1278
1460
|
}
|
|
1279
|
-
function Switch({ label, size = "md", disabled = false, className = "", ...rest }) {
|
|
1280
|
-
return /* @__PURE__ */ jsxs("label", { className: joinClass("wp-switch", size === "sm" && "wp-switch--sm", className), children: [
|
|
1461
|
+
function Switch({ label, size = "md", disabled = false, className = "", style, ...rest }) {
|
|
1462
|
+
return /* @__PURE__ */ jsxs("label", { className: joinClass("wp-switch", size === "sm" && "wp-switch--sm", className), style, children: [
|
|
1281
1463
|
/* @__PURE__ */ jsx("input", { type: "checkbox", role: "switch", disabled, ...rest }),
|
|
1282
1464
|
/* @__PURE__ */ jsx("span", { className: "wp-switch__track" }),
|
|
1283
1465
|
label ? /* @__PURE__ */ jsx("span", { children: label }) : null
|
|
@@ -1318,18 +1500,39 @@ function Card({
|
|
|
1318
1500
|
if (selected) classes.push("wp-card--selected");
|
|
1319
1501
|
if (className) classes.push(className);
|
|
1320
1502
|
const bodyClass = padding === "tight" ? "wp-card__body wp-card__body--tight" : "wp-card__body";
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1503
|
+
const { onClick, onKeyDown, role, tabIndex, ...divRest } = rest;
|
|
1504
|
+
const pressable = interactive && typeof onClick === "function";
|
|
1505
|
+
const handleKeyDown = pressable ? (event) => {
|
|
1506
|
+
onKeyDown?.(event);
|
|
1507
|
+
if (event.defaultPrevented || event.target !== event.currentTarget) return;
|
|
1508
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
1509
|
+
event.preventDefault();
|
|
1510
|
+
if (event.repeat) return;
|
|
1511
|
+
event.currentTarget.click();
|
|
1512
|
+
} : onKeyDown;
|
|
1513
|
+
return /* @__PURE__ */ jsxs(
|
|
1514
|
+
"div",
|
|
1515
|
+
{
|
|
1516
|
+
className: classes.join(" "),
|
|
1517
|
+
...divRest,
|
|
1518
|
+
onClick,
|
|
1519
|
+
onKeyDown: handleKeyDown,
|
|
1520
|
+
role: role ?? (pressable ? "button" : void 0),
|
|
1521
|
+
tabIndex: tabIndex ?? (pressable ? 0 : void 0),
|
|
1522
|
+
children: [
|
|
1523
|
+
cover ? /* @__PURE__ */ jsx("div", { className: "wp-card__cover", children: cover }) : null,
|
|
1524
|
+
title || actions ? /* @__PURE__ */ jsxs("div", { className: "wp-card__head", children: [
|
|
1525
|
+
/* @__PURE__ */ jsxs("div", { style: { minWidth: 0 }, children: [
|
|
1526
|
+
/* @__PURE__ */ jsx("div", { className: "wp-card__title", children: title }),
|
|
1527
|
+
subtitle ? /* @__PURE__ */ jsx("div", { className: "wp-card__sub", children: subtitle }) : null
|
|
1528
|
+
] }),
|
|
1529
|
+
actions ? /* @__PURE__ */ jsx("div", { className: "wp-row", style: { gap: 6, flex: "none" }, children: actions }) : null
|
|
1530
|
+
] }) : null,
|
|
1531
|
+
padding === "none" ? children : /* @__PURE__ */ jsx("div", { className: bodyClass, children }),
|
|
1532
|
+
footer ? /* @__PURE__ */ jsx("div", { className: "wp-card__foot", children: footer }) : null
|
|
1533
|
+
]
|
|
1534
|
+
}
|
|
1535
|
+
);
|
|
1333
1536
|
}
|
|
1334
1537
|
function Badge({ tone = "neutral", dot = false, size = "md", children, className = "", ...rest }) {
|
|
1335
1538
|
return /* @__PURE__ */ jsx(
|
|
@@ -1385,14 +1588,33 @@ function Toast({ tone = "info", title, children, action, onClose, className = ""
|
|
|
1385
1588
|
onClose ? /* @__PURE__ */ jsx("button", { type: "button", className: "wp-toast__x", "aria-label": "\uB2EB\uAE30", onClick: onClose, children: /* @__PURE__ */ jsx(Icon, { name: "x", size: 13 }) }) : null
|
|
1386
1589
|
] });
|
|
1387
1590
|
}
|
|
1591
|
+
function revealSelectedTab(list) {
|
|
1592
|
+
if (!list || list.scrollWidth <= list.clientWidth + 1) return;
|
|
1593
|
+
const tab = list.querySelector('[role="tab"][aria-selected="true"]');
|
|
1594
|
+
if (!tab) return;
|
|
1595
|
+
const listBox = list.getBoundingClientRect();
|
|
1596
|
+
const tabBox = tab.getBoundingClientRect();
|
|
1597
|
+
const margin = 24;
|
|
1598
|
+
if (tabBox.left < listBox.left) {
|
|
1599
|
+
list.scrollLeft -= listBox.left - tabBox.left + margin;
|
|
1600
|
+
} else if (tabBox.right > listBox.right) {
|
|
1601
|
+
list.scrollLeft += tabBox.right - listBox.right + margin;
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1388
1604
|
function Tabs({ items = [], value, onChange, size = "md", onChrome = false, className = "", ...rest }) {
|
|
1605
|
+
const listRef = React.useRef(null);
|
|
1606
|
+
const itemList = asArray(items);
|
|
1607
|
+
React.useEffect(() => {
|
|
1608
|
+
revealSelectedTab(listRef.current);
|
|
1609
|
+
}, [value, itemList.length]);
|
|
1389
1610
|
return /* @__PURE__ */ jsx(
|
|
1390
1611
|
"div",
|
|
1391
1612
|
{
|
|
1392
1613
|
className: joinClass("wp-tabs", size === "lg" && "wp-tabs--lg", onChrome && "wp-tabs--onchrome", className),
|
|
1393
1614
|
role: "tablist",
|
|
1394
1615
|
...rest,
|
|
1395
|
-
|
|
1616
|
+
ref: listRef,
|
|
1617
|
+
children: itemList.map((item) => /* @__PURE__ */ jsxs(
|
|
1396
1618
|
"button",
|
|
1397
1619
|
{
|
|
1398
1620
|
type: "button",
|
|
@@ -1423,19 +1645,25 @@ function Table({
|
|
|
1423
1645
|
rowKey = "id",
|
|
1424
1646
|
onRowClick,
|
|
1425
1647
|
empty,
|
|
1648
|
+
emptyText,
|
|
1649
|
+
stackable: stackableProp,
|
|
1426
1650
|
className = "",
|
|
1651
|
+
style,
|
|
1427
1652
|
...rest
|
|
1428
1653
|
}) {
|
|
1654
|
+
const stackable = stackableProp ?? !sticky;
|
|
1655
|
+
const wrapped = !sticky;
|
|
1429
1656
|
const classes = ["wp-table"];
|
|
1430
1657
|
if (dense) classes.push("wp-table--dense");
|
|
1431
1658
|
if (hover) classes.push("wp-table--hover");
|
|
1432
1659
|
if (sticky) classes.push("wp-table--sticky");
|
|
1433
|
-
if (
|
|
1660
|
+
if (stackable) classes.push("wp-table--stackable");
|
|
1661
|
+
if (!wrapped && className) classes.push(className);
|
|
1434
1662
|
const columnList = asArray(columns);
|
|
1435
1663
|
const rowList = asArray(rows);
|
|
1436
1664
|
const selectedList = asArray(selectedIds);
|
|
1437
1665
|
if (!rowList.length && empty) return /* @__PURE__ */ jsx(Fragment, { children: empty });
|
|
1438
|
-
|
|
1666
|
+
const table = /* @__PURE__ */ jsxs("table", { className: classes.join(" "), style: wrapped ? void 0 : style, ...rest, children: [
|
|
1439
1667
|
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: columnList.map((column) => /* @__PURE__ */ jsx("th", { style: { width: column.width, textAlign: column.align === "right" ? "right" : void 0 }, children: column.sortable && onSort ? /* @__PURE__ */ jsxs("button", { type: "button", className: "wp-table__sort", onClick: () => onSort(column.key), children: [
|
|
1440
1668
|
column.header,
|
|
1441
1669
|
/* @__PURE__ */ jsx(
|
|
@@ -1446,34 +1674,53 @@ function Table({
|
|
|
1446
1674
|
}
|
|
1447
1675
|
)
|
|
1448
1676
|
] }) : column.header }, column.key)) }) }),
|
|
1449
|
-
/* @__PURE__ */
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
const
|
|
1467
|
-
content
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1677
|
+
/* @__PURE__ */ jsxs("tbody", { children: [
|
|
1678
|
+
rowList.length === 0 ? (
|
|
1679
|
+
// 머리글은 남겨 "무슨 표인지"는 보이게 하고, 비었다는 사실은 한 줄로 말한다.
|
|
1680
|
+
// data-label="" — 행 카드 모드에서 라벨 없이 문구만 서게(선택 칸과 같은 규칙).
|
|
1681
|
+
/* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { className: "wp-table__empty", colSpan: Math.max(1, columnList.length), "data-label": "", children: emptyText || "\uD45C\uC2DC\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4" }) })
|
|
1682
|
+
) : null,
|
|
1683
|
+
rowList.map((row, index) => /* @__PURE__ */ jsx(
|
|
1684
|
+
"tr",
|
|
1685
|
+
{
|
|
1686
|
+
"aria-selected": selectedList.indexOf(row?.[rowKey]) > -1 || void 0,
|
|
1687
|
+
onClick: onRowClick ? () => onRowClick(row) : void 0,
|
|
1688
|
+
style: onRowClick ? { cursor: "pointer" } : void 0,
|
|
1689
|
+
children: columnList.map((column) => {
|
|
1690
|
+
const cls = [];
|
|
1691
|
+
if (column.align === "right") cls.push("wp-table__num");
|
|
1692
|
+
if (column.mono) cls.push("wp-table__mono");
|
|
1693
|
+
if (column.strong) cls.push("wp-table__strong");
|
|
1694
|
+
const raw = column.key ? fieldOf(row, column.key) : void 0;
|
|
1695
|
+
let content;
|
|
1696
|
+
if (column.render) {
|
|
1697
|
+
content = column.render(row, index);
|
|
1698
|
+
} else if (column.badge) {
|
|
1699
|
+
const key = raw == null ? "" : String(raw);
|
|
1700
|
+
const tone = column.badge.toneMap?.[key] ?? "neutral";
|
|
1701
|
+
content = /* @__PURE__ */ jsx(Badge, { tone, children: column.badge.labelMap?.[key] ?? key });
|
|
1702
|
+
} else {
|
|
1703
|
+
content = formatDisplayValue(raw, column.format);
|
|
1704
|
+
}
|
|
1705
|
+
return /* @__PURE__ */ jsx(
|
|
1706
|
+
"td",
|
|
1707
|
+
{
|
|
1708
|
+
className: cls.join(" ") || void 0,
|
|
1709
|
+
"data-label": stackable ? typeof column.header === "string" ? column.header : "" : void 0,
|
|
1710
|
+
children: content
|
|
1711
|
+
},
|
|
1712
|
+
column.key
|
|
1713
|
+
);
|
|
1714
|
+
})
|
|
1715
|
+
},
|
|
1716
|
+
row?.[rowKey] != null ? String(row[rowKey]) : index
|
|
1717
|
+
))
|
|
1718
|
+
] })
|
|
1476
1719
|
] });
|
|
1720
|
+
if (!wrapped) return table;
|
|
1721
|
+
const boxClasses = ["wp-table-scroll", "wp-table-scroll--plain"];
|
|
1722
|
+
if (className) boxClasses.push(className);
|
|
1723
|
+
return /* @__PURE__ */ jsx("div", { className: boxClasses.join(" "), style, children: table });
|
|
1477
1724
|
}
|
|
1478
1725
|
function StatCard({ label, value, unit, delta, trend = "flat", icon, footer, size = "md", className = "", ...rest }) {
|
|
1479
1726
|
const arrow = trend === "up" ? "arrow-up-right" : trend === "down" ? "arrow-down" : "minus";
|
|
@@ -1483,7 +1730,7 @@ function StatCard({ label, value, unit, delta, trend = "flat", icon, footer, siz
|
|
|
1483
1730
|
label
|
|
1484
1731
|
] }),
|
|
1485
1732
|
/* @__PURE__ */ jsxs("div", { className: "wp-stat__value", children: [
|
|
1486
|
-
value,
|
|
1733
|
+
typeof value === "number" ? formatNumberValue(value) : value,
|
|
1487
1734
|
unit ? /* @__PURE__ */ jsx("span", { className: "wp-stat__unit", children: unit }) : null
|
|
1488
1735
|
] }),
|
|
1489
1736
|
delta ? /* @__PURE__ */ jsxs("div", { className: `wp-stat__delta wp-stat__delta--${trend}`, children: [
|
|
@@ -1501,18 +1748,20 @@ function EmptyState({ icon = "square-dashed", title, children, actions, tight =
|
|
|
1501
1748
|
actions ? /* @__PURE__ */ jsx("div", { className: "wp-empty__actions", children: actions }) : null
|
|
1502
1749
|
] });
|
|
1503
1750
|
}
|
|
1504
|
-
function Spinner({ size = "md", inverse = false, label, className = "", ...rest }) {
|
|
1751
|
+
function Spinner({ size = "md", inverse = false, label, className = "", style, ...rest }) {
|
|
1752
|
+
const labeled = Boolean(label);
|
|
1505
1753
|
const el = /* @__PURE__ */ jsx(
|
|
1506
1754
|
"span",
|
|
1507
1755
|
{
|
|
1508
|
-
className: joinClass("wp-spinner", size !== "md" && `wp-spinner--${size}`, inverse && "wp-spinner--inverse", className),
|
|
1756
|
+
className: joinClass("wp-spinner", size !== "md" && `wp-spinner--${size}`, inverse && "wp-spinner--inverse", !labeled && className),
|
|
1757
|
+
style: labeled ? void 0 : style,
|
|
1509
1758
|
role: "status",
|
|
1510
1759
|
"aria-label": label || "\uB85C\uB529 \uC911",
|
|
1511
1760
|
...rest
|
|
1512
1761
|
}
|
|
1513
1762
|
);
|
|
1514
|
-
if (!
|
|
1515
|
-
return /* @__PURE__ */ jsxs("span", { className: "wp-row", style: { gap: 8 }, children: [
|
|
1763
|
+
if (!labeled) return el;
|
|
1764
|
+
return /* @__PURE__ */ jsxs("span", { className: joinClass("wp-row", className), style: { gap: 8, ...style }, children: [
|
|
1516
1765
|
el,
|
|
1517
1766
|
/* @__PURE__ */ jsx("span", { className: "wp-caption", children: label })
|
|
1518
1767
|
] });
|
|
@@ -1583,7 +1832,7 @@ function Pagination({ page = 1, pageCount = 1, total, pageSize, onChange, classN
|
|
|
1583
1832
|
const from = total != null && pageSize ? (page - 1) * pageSize + 1 : null;
|
|
1584
1833
|
const to = total != null && pageSize ? Math.min(total, page * pageSize) : null;
|
|
1585
1834
|
return /* @__PURE__ */ jsxs("div", { className: joinClass("wp-pager", className), ...rest, children: [
|
|
1586
|
-
from != null ? /* @__PURE__ */ jsxs("span", { className: "wp-num", children: [
|
|
1835
|
+
from != null && total === 0 ? /* @__PURE__ */ jsx("span", { className: "wp-num", children: "0\uAC74" }) : from != null ? /* @__PURE__ */ jsxs("span", { className: "wp-num", children: [
|
|
1587
1836
|
from,
|
|
1588
1837
|
"\u2013",
|
|
1589
1838
|
to,
|
|
@@ -1730,4 +1979,4 @@ function Tooltip({ label, shortcut, placement = "top", wrap = false, children, c
|
|
|
1730
1979
|
);
|
|
1731
1980
|
}
|
|
1732
1981
|
|
|
1733
|
-
export { Alert, Avatar, Badge, Breadcrumb, Button, CALC_OPS, Card, Checkbox, Dialog, EmptyState, Field, ICON_NODES, Icon, IconButton, Input, Pagination, ProgressBar, Radio, SegmentedControl, Select, SidebarNav, Spinner, StatCard, Switch, Table, Tabs, Tag, Textarea, Toast, Tooltip, evaluateCalc, fieldOf, isPlainObject, toNumber, warnOnce };
|
|
1982
|
+
export { Alert, Avatar, Badge, Breadcrumb, Button, CALC_OPS, Card, Checkbox, Dialog, EmptyState, Field, ICON_NODES, Icon, IconButton, Input, Pagination, ProgressBar, Radio, SegmentedControl, Select, SidebarNav, Spinner, StatCard, Switch, Table, Tabs, Tag, Textarea, Toast, Tooltip, evaluateCalc, fieldOf, formatDateValue, formatDisplayValue, formatNumberValue, isPlainObject, isZonedIsoDateTime, parseNumeric, toNumber, warnOnce };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useSduiAdapter, hostFetchOf, defaultAdapter } from './chunk-
|
|
2
|
-
import { Spinner, Badge, Icon } from './chunk-
|
|
3
|
-
import { boxed } from './chunk-
|
|
1
|
+
import { useSduiAdapter, hostFetchOf, defaultAdapter } from './chunk-YNEEJCSZ.js';
|
|
2
|
+
import { Spinner, Badge, Icon } from './chunk-BLFJMMBW.js';
|
|
3
|
+
import { boxed } from './chunk-3JTBOABA.js';
|
|
4
4
|
import { useState, useEffect } from 'react';
|
|
5
5
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
6
|
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { OverlayLayer } from './chunk-BITS7UJY.js';
|
|
2
|
+
import { Dialog, Button, warnOnce } from './chunk-BLFJMMBW.js';
|
|
3
|
+
import { createContext, useContext, useMemo, useRef, useCallback, useState } from 'react';
|
|
4
|
+
import { jsx, jsxs, Fragment } 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
|
+
var SduiRuntimeContext = createContext(null);
|
|
36
|
+
function useSduiRuntime() {
|
|
37
|
+
const runtime = useContext(SduiRuntimeContext);
|
|
38
|
+
if (!runtime) throw new Error("useSduiRuntime\uC740 SduiRenderer \uB0B4\uBD80\uC5D0\uC11C\uB9CC \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.");
|
|
39
|
+
return runtime;
|
|
40
|
+
}
|
|
41
|
+
var SduiFormScopeContext = createContext(null);
|
|
42
|
+
var SduiDirtyRegistryContext = createContext(null);
|
|
43
|
+
var SduiLeaveRegistryContext = createContext(null);
|
|
44
|
+
var DEFAULT_CONFIRM_MESSAGE = "\uC9C0\uAE08 \uB2EB\uC73C\uBA74 \uC785\uB825\uD55C \uB0B4\uC6A9\uC774 \uC800\uC7A5\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.";
|
|
45
|
+
function isInsideBody(target) {
|
|
46
|
+
return target instanceof Element && target.closest(".wp-dialog__body, .wp-anchored-pop") !== null;
|
|
47
|
+
}
|
|
48
|
+
function SduiDialog({ confirmClose, ...props }) {
|
|
49
|
+
const { onClose } = props;
|
|
50
|
+
const dirtyChecks = useRef(/* @__PURE__ */ new Set());
|
|
51
|
+
const registry = useMemo(
|
|
52
|
+
() => ({
|
|
53
|
+
register: (isDirty) => {
|
|
54
|
+
dirtyChecks.current.add(isDirty);
|
|
55
|
+
return () => {
|
|
56
|
+
dirtyChecks.current.delete(isDirty);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}),
|
|
60
|
+
[]
|
|
61
|
+
);
|
|
62
|
+
const touched = useRef(false);
|
|
63
|
+
const markTouched = useCallback((event) => {
|
|
64
|
+
if (isInsideBody(event.target)) touched.current = true;
|
|
65
|
+
}, []);
|
|
66
|
+
const [asking, setAsking] = useState(false);
|
|
67
|
+
const explicit = confirmClose === true || typeof confirmClose === "string" && confirmClose !== "";
|
|
68
|
+
const needsConfirm = () => {
|
|
69
|
+
if (confirmClose === false) return false;
|
|
70
|
+
if (explicit) return true;
|
|
71
|
+
if (!touched.current) return false;
|
|
72
|
+
for (const isDirty of dirtyChecks.current) if (isDirty()) return true;
|
|
73
|
+
return false;
|
|
74
|
+
};
|
|
75
|
+
const guardedClose = () => {
|
|
76
|
+
if (!onClose || asking) return;
|
|
77
|
+
if (needsConfirm()) setAsking(true);
|
|
78
|
+
else onClose();
|
|
79
|
+
};
|
|
80
|
+
const message = typeof confirmClose === "string" && confirmClose !== "" ? confirmClose : DEFAULT_CONFIRM_MESSAGE;
|
|
81
|
+
const keep = () => setAsking(false);
|
|
82
|
+
const discard = () => {
|
|
83
|
+
setAsking(false);
|
|
84
|
+
onClose?.();
|
|
85
|
+
};
|
|
86
|
+
return /* @__PURE__ */ jsxs(SduiDirtyRegistryContext.Provider, { value: registry, children: [
|
|
87
|
+
/* @__PURE__ */ jsx(OverlayLayer, { onClose: onClose ? guardedClose : void 0, children: /* @__PURE__ */ jsx(Dialog, { ...props, onInputCapture: markTouched, onChangeCapture: markTouched, onPointerDownCapture: markTouched }) }),
|
|
88
|
+
asking ? /* @__PURE__ */ jsx(OverlayLayer, { onClose: keep, children: /* @__PURE__ */ jsx(
|
|
89
|
+
Dialog,
|
|
90
|
+
{
|
|
91
|
+
size: "sm",
|
|
92
|
+
icon: "triangle-alert",
|
|
93
|
+
tone: "danger",
|
|
94
|
+
title: "\uC791\uC131 \uC911\uC778 \uB0B4\uC6A9\uC744 \uBC84\uB9B4\uAE4C\uC694?",
|
|
95
|
+
onClose: keep,
|
|
96
|
+
footer: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
97
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", "data-autofocus": "", onClick: keep, children: "\uACC4\uC18D \uC791\uC131" }),
|
|
98
|
+
/* @__PURE__ */ jsx(Button, { variant: "danger", onClick: discard, children: "\uBC84\uB9AC\uACE0 \uB2EB\uAE30" })
|
|
99
|
+
] }),
|
|
100
|
+
children: message
|
|
101
|
+
}
|
|
102
|
+
) }) : null
|
|
103
|
+
] });
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export { SduiDialog, SduiDirtyRegistryContext, SduiDispatchContext, SduiFormScopeContext, SduiLeaveRegistryContext, SduiPermissionProvider, SduiRuntimeContext, useSduiCan, useSduiDispatch, useSduiRuntime };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ellipsisStyle, unwrapRows } from './chunk-
|
|
2
|
-
import { includesLooseSearch } from './chunk-
|
|
3
|
-
import { useSduiAdapter, hostFetchOf } from './chunk-
|
|
4
|
-
import { Icon, Button, Input, Spinner } from './chunk-
|
|
5
|
-
import { boxed } from './chunk-
|
|
1
|
+
import { ellipsisStyle, unwrapRows } from './chunk-LKQJJSVJ.js';
|
|
2
|
+
import { includesLooseSearch } from './chunk-4OABUPIU.js';
|
|
3
|
+
import { useSduiAdapter, hostFetchOf } from './chunk-YNEEJCSZ.js';
|
|
4
|
+
import { Icon, Button, Input, Spinner } from './chunk-BLFJMMBW.js';
|
|
5
|
+
import { boxed } from './chunk-3JTBOABA.js';
|
|
6
6
|
import { useId, useRef, useMemo, useState, useEffect } from 'react';
|
|
7
7
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
8
8
|
|