@windwalker-io/unicorn-next 0.1.15 → 0.1.17
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/chunks/grid.js +70 -8
- package/dist/chunks/grid.js.map +1 -1
- package/dist/chunks/show-on.js +1 -1
- package/dist/chunks/show-on.js.map +1 -1
- package/dist/chunks/unicorn.js +299 -60
- package/dist/chunks/unicorn.js.map +1 -1
- package/dist/chunks/validation.js +17 -2
- package/dist/chunks/validation.js.map +1 -1
- package/dist/index.d.ts +84 -19
- package/dist/unicorn.js +32 -31
- package/package.json +1 -1
- package/src/composable/index.ts +1 -0
- package/src/composable/useBsModalAlert.ts +299 -0
- package/src/composable/useForm.ts +45 -11
- package/src/composable/useHttp.ts +50 -3
- package/src/composable/useUIBootstrap5.ts +2 -0
- package/src/module/grid.ts +105 -13
- package/src/module/show-on.ts +1 -1
- package/src/module/validation.ts +29 -6
- package/src/service/dom.ts +1 -1
- package/src/service/ui.ts +2 -0
package/dist/chunks/unicorn.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Modal } from "bootstrap";
|
|
1
2
|
const copyProps = (dest, src, exclude = []) => {
|
|
2
3
|
const props = Object.getOwnPropertyDescriptors(src);
|
|
3
4
|
for (let prop of exclude)
|
|
@@ -1155,6 +1156,212 @@ async function resolveSource(src) {
|
|
|
1155
1156
|
}
|
|
1156
1157
|
return src;
|
|
1157
1158
|
}
|
|
1159
|
+
async function useUIBootstrap5(install = false, pushToGlobal = false) {
|
|
1160
|
+
const { UIBootstrap5 } = await import("./ui-bootstrap5.js");
|
|
1161
|
+
const theme = UIBootstrap5.get();
|
|
1162
|
+
if (install) {
|
|
1163
|
+
useUITheme(theme);
|
|
1164
|
+
if (pushToGlobal) {
|
|
1165
|
+
theme.pushBootstrapToGlobal();
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
return theme;
|
|
1169
|
+
}
|
|
1170
|
+
async function useBs5Tooltip(selector = '[data-bs-toggle="tooltip"]', config = {}) {
|
|
1171
|
+
const bs5 = await useUIBootstrap5();
|
|
1172
|
+
return bs5.tooltip(selector, config);
|
|
1173
|
+
}
|
|
1174
|
+
const useBs5KeepTab = async (selector, options = {}) => {
|
|
1175
|
+
const bs5 = await useUIBootstrap5();
|
|
1176
|
+
return bs5.keepTab(selector, options);
|
|
1177
|
+
};
|
|
1178
|
+
const useBs5ButtonRadio = async (selector, options = {}) => {
|
|
1179
|
+
const bs5 = await useUIBootstrap5();
|
|
1180
|
+
return bs5.buttonRadio(selector, options);
|
|
1181
|
+
};
|
|
1182
|
+
const defaultOptions = {
|
|
1183
|
+
buttons: [
|
|
1184
|
+
"OK"
|
|
1185
|
+
]
|
|
1186
|
+
};
|
|
1187
|
+
async function useBsModalAlert(id, options) {
|
|
1188
|
+
await useUIBootstrap5();
|
|
1189
|
+
let modalElement = void 0;
|
|
1190
|
+
if (typeof id !== "string" && !(id instanceof HTMLElement)) {
|
|
1191
|
+
options = id;
|
|
1192
|
+
id = "uni-modal-alert";
|
|
1193
|
+
modalElement = document.getElementById(id);
|
|
1194
|
+
} else {
|
|
1195
|
+
modalElement = typeof id === "string" ? document.getElementById(id) : id;
|
|
1196
|
+
}
|
|
1197
|
+
if (!modalElement) {
|
|
1198
|
+
modalElement = html(`<div id="${id}" class="uni-modal-alert modal fade" tabindex="-1" role="dialog">
|
|
1199
|
+
<div class="modal-dialog" role="document">
|
|
1200
|
+
<div class="modal-content">
|
|
1201
|
+
<div class="modal-body text-center p-4"></div>
|
|
1202
|
+
<div class="modal-footer"></div>
|
|
1203
|
+
</div>
|
|
1204
|
+
</div>
|
|
1205
|
+
</div>`);
|
|
1206
|
+
document.body.appendChild(modalElement);
|
|
1207
|
+
}
|
|
1208
|
+
const modal = Modal.getOrCreateInstance(modalElement, options);
|
|
1209
|
+
return {
|
|
1210
|
+
show: (title, text, icon, options2) => {
|
|
1211
|
+
if (typeof title === "string") {
|
|
1212
|
+
options2 = options2 || {};
|
|
1213
|
+
options2.title = title;
|
|
1214
|
+
options2.text = text;
|
|
1215
|
+
options2.icon = icon;
|
|
1216
|
+
} else {
|
|
1217
|
+
options2 = title;
|
|
1218
|
+
}
|
|
1219
|
+
return new Promise((resolve) => {
|
|
1220
|
+
prepareModalElement(modalElement, resolve, options2);
|
|
1221
|
+
modal.show(options2?.relatedTarget);
|
|
1222
|
+
});
|
|
1223
|
+
},
|
|
1224
|
+
hide: () => {
|
|
1225
|
+
modal.hide();
|
|
1226
|
+
},
|
|
1227
|
+
dispose: () => {
|
|
1228
|
+
modal.dispose();
|
|
1229
|
+
},
|
|
1230
|
+
toggle: (relatedTarget) => {
|
|
1231
|
+
modal.toggle(relatedTarget);
|
|
1232
|
+
},
|
|
1233
|
+
destroy: () => {
|
|
1234
|
+
modal.dispose();
|
|
1235
|
+
modalElement.remove();
|
|
1236
|
+
},
|
|
1237
|
+
instance: modal,
|
|
1238
|
+
el: modalElement
|
|
1239
|
+
};
|
|
1240
|
+
}
|
|
1241
|
+
async function prepareModalElement(modalElement, handler, options) {
|
|
1242
|
+
options = Object.assign({}, defaultOptions, options || {});
|
|
1243
|
+
let header = options.header;
|
|
1244
|
+
const content = options.content;
|
|
1245
|
+
modalElement.querySelector(".modal-header")?.remove();
|
|
1246
|
+
modalElement.querySelector(".modal-body").innerHTML = "";
|
|
1247
|
+
modalElement.querySelector(".modal-footer").innerHTML = "";
|
|
1248
|
+
const dialog = modalElement.querySelector(".modal-dialog");
|
|
1249
|
+
dialog?.classList.remove("modal-sm", "modal-lg", "modal-xl", "modal-xxl");
|
|
1250
|
+
if (header) {
|
|
1251
|
+
if (typeof header === "string") {
|
|
1252
|
+
header = `<div class="modal-header">
|
|
1253
|
+
<h5 class="modal-title">${header}</h5>
|
|
1254
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
1255
|
+
</div>`;
|
|
1256
|
+
}
|
|
1257
|
+
header = await anyToElement(header);
|
|
1258
|
+
modalElement.querySelector(".modal-content").insertAdjacentElement("afterbegin", header);
|
|
1259
|
+
}
|
|
1260
|
+
if (content) {
|
|
1261
|
+
let contentElement = await anyToElement(content);
|
|
1262
|
+
modalElement.querySelector(".modal-body").appendChild(contentElement);
|
|
1263
|
+
} else {
|
|
1264
|
+
const title = options.title;
|
|
1265
|
+
const text = options.text;
|
|
1266
|
+
let icon = options.icon;
|
|
1267
|
+
if (icon) {
|
|
1268
|
+
if (typeof icon === "string") {
|
|
1269
|
+
icon = `<div class="uni-modal-alert__icon text-center mb-4"><span class="${icon}" style="font-size: 48px;"></span></div>`;
|
|
1270
|
+
}
|
|
1271
|
+
icon = await anyToElement(icon);
|
|
1272
|
+
modalElement.querySelector(".modal-body").appendChild(icon);
|
|
1273
|
+
}
|
|
1274
|
+
if (title) {
|
|
1275
|
+
const titleEl = html(`<h4 class="uni-modal-alert__title">${title}</h4>`);
|
|
1276
|
+
modalElement.querySelector(".modal-body").appendChild(titleEl);
|
|
1277
|
+
}
|
|
1278
|
+
if (text) {
|
|
1279
|
+
const textEl = html(`<div class="uni-modal-alert__text">${text}</div>`);
|
|
1280
|
+
modalElement.querySelector(".modal-body").appendChild(textEl);
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
const buttons = options.buttons;
|
|
1284
|
+
for (const i in buttons) {
|
|
1285
|
+
const button = buttons[i];
|
|
1286
|
+
const isConfirm = buttons.length === 1 || buttons.length === 2 && Number(i) === 1;
|
|
1287
|
+
const buttonElement = createButton(
|
|
1288
|
+
button,
|
|
1289
|
+
handler,
|
|
1290
|
+
isConfirm
|
|
1291
|
+
);
|
|
1292
|
+
modalElement.querySelector(".modal-footer").appendChild(await buttonElement);
|
|
1293
|
+
}
|
|
1294
|
+
if (options.size) {
|
|
1295
|
+
modalElement.querySelector(".modal-dialog").classList.add(`modal-${options.size}`);
|
|
1296
|
+
}
|
|
1297
|
+
return modalElement;
|
|
1298
|
+
}
|
|
1299
|
+
async function anyToElement(content) {
|
|
1300
|
+
if (typeof content === "function") {
|
|
1301
|
+
return content();
|
|
1302
|
+
}
|
|
1303
|
+
return typeof content === "string" ? html(content) : content;
|
|
1304
|
+
}
|
|
1305
|
+
async function createButton(buttonOption, handler, isConfirm) {
|
|
1306
|
+
if (typeof buttonOption === "function") {
|
|
1307
|
+
return await buttonOption();
|
|
1308
|
+
}
|
|
1309
|
+
if (typeof buttonOption === "string") {
|
|
1310
|
+
buttonOption = {
|
|
1311
|
+
text: buttonOption,
|
|
1312
|
+
value: isConfirm ?? false,
|
|
1313
|
+
class: isConfirm ? "btn btn-primary is-confirm" : "btn btn-outline-secondary",
|
|
1314
|
+
styles: isConfirm ? { width: "150px" } : {},
|
|
1315
|
+
dismiss: true
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
let button;
|
|
1319
|
+
if (buttonOption instanceof HTMLElement) {
|
|
1320
|
+
button = buttonOption;
|
|
1321
|
+
} else {
|
|
1322
|
+
const {
|
|
1323
|
+
text,
|
|
1324
|
+
class: className = "btn btn-secondary",
|
|
1325
|
+
attrs = {},
|
|
1326
|
+
styles = {},
|
|
1327
|
+
dismiss = true,
|
|
1328
|
+
value,
|
|
1329
|
+
href,
|
|
1330
|
+
target,
|
|
1331
|
+
onClick
|
|
1332
|
+
} = buttonOption;
|
|
1333
|
+
const tag = href ? "a" : "button";
|
|
1334
|
+
const el = document.createElement(tag);
|
|
1335
|
+
if (el instanceof HTMLAnchorElement) {
|
|
1336
|
+
el.href = href;
|
|
1337
|
+
el.target = target || "_self";
|
|
1338
|
+
}
|
|
1339
|
+
if (el instanceof HTMLButtonElement) {
|
|
1340
|
+
el.type = "button";
|
|
1341
|
+
}
|
|
1342
|
+
el.setAttribute("class", className);
|
|
1343
|
+
for (let attr in attrs) {
|
|
1344
|
+
el.setAttribute(attr, attrs[attr]);
|
|
1345
|
+
}
|
|
1346
|
+
for (let style in styles) {
|
|
1347
|
+
el.style[style] = styles[style];
|
|
1348
|
+
}
|
|
1349
|
+
if (dismiss) {
|
|
1350
|
+
el.setAttribute("data-bs-dismiss", "modal");
|
|
1351
|
+
}
|
|
1352
|
+
if (typeof text === "string") {
|
|
1353
|
+
el.textContent = text;
|
|
1354
|
+
} else if (typeof text === "function") {
|
|
1355
|
+
text(el);
|
|
1356
|
+
}
|
|
1357
|
+
el.addEventListener("click", (e) => {
|
|
1358
|
+
onClick?.(value, e);
|
|
1359
|
+
handler(value);
|
|
1360
|
+
});
|
|
1361
|
+
button = el;
|
|
1362
|
+
}
|
|
1363
|
+
return button;
|
|
1364
|
+
}
|
|
1158
1365
|
async function useCheckboxesMultiSelect(selector, options = {}) {
|
|
1159
1366
|
const m = await import("./checkboxes-multi-select.js");
|
|
1160
1367
|
if (selector) {
|
|
@@ -1192,10 +1399,29 @@ async function useFieldSingleImageDrag() {
|
|
|
1192
1399
|
return module;
|
|
1193
1400
|
}
|
|
1194
1401
|
let formElement;
|
|
1195
|
-
|
|
1196
|
-
const
|
|
1197
|
-
|
|
1198
|
-
|
|
1402
|
+
function useFormAsync(ele, options = {}) {
|
|
1403
|
+
const promise = import("./form.js").then(({ UnicornFormElement }) => {
|
|
1404
|
+
formElement ??= UnicornFormElement;
|
|
1405
|
+
return useForm(ele, options);
|
|
1406
|
+
});
|
|
1407
|
+
const proxy = new Proxy({}, {
|
|
1408
|
+
get(target, prop) {
|
|
1409
|
+
return (...args) => {
|
|
1410
|
+
return promise.then((form) => {
|
|
1411
|
+
const func = form[prop];
|
|
1412
|
+
if (typeof func === "function") {
|
|
1413
|
+
return func.apply(form, args);
|
|
1414
|
+
}
|
|
1415
|
+
throw new Error(`Method ${String(prop)} does not exist on form.`);
|
|
1416
|
+
});
|
|
1417
|
+
};
|
|
1418
|
+
}
|
|
1419
|
+
});
|
|
1420
|
+
Object.assign(proxy, {
|
|
1421
|
+
then: promise.then.bind(promise),
|
|
1422
|
+
catch: promise.catch.bind(promise)
|
|
1423
|
+
});
|
|
1424
|
+
return proxy;
|
|
1199
1425
|
}
|
|
1200
1426
|
function useForm(ele, options = {}) {
|
|
1201
1427
|
if (!formElement) {
|
|
@@ -1262,9 +1488,42 @@ async function useGridComponent(ele, options = {}) {
|
|
|
1262
1488
|
await grid?.initComponent();
|
|
1263
1489
|
return grid;
|
|
1264
1490
|
}
|
|
1265
|
-
|
|
1266
|
-
const
|
|
1267
|
-
|
|
1491
|
+
function useHttpClient(config) {
|
|
1492
|
+
const promise = import("./http-client.js").then(({ createHttpClient }) => {
|
|
1493
|
+
return createHttpClient(config);
|
|
1494
|
+
});
|
|
1495
|
+
const data2 = {
|
|
1496
|
+
request: (options) => {
|
|
1497
|
+
return promise.then((client) => client.request(options));
|
|
1498
|
+
},
|
|
1499
|
+
get: (url, options) => {
|
|
1500
|
+
return promise.then((client) => client.get(url, options));
|
|
1501
|
+
},
|
|
1502
|
+
post: (url, data22, options) => {
|
|
1503
|
+
return promise.then((client) => client.post(url, data22, options));
|
|
1504
|
+
},
|
|
1505
|
+
put: (url, data22, options) => {
|
|
1506
|
+
return promise.then((client) => client.put(url, data22, options));
|
|
1507
|
+
},
|
|
1508
|
+
patch: (url, data22, options) => {
|
|
1509
|
+
return promise.then((client) => client.patch(url, data22, options));
|
|
1510
|
+
},
|
|
1511
|
+
delete: (url, data22, options) => {
|
|
1512
|
+
return promise.then((client) => client.delete(url, data22, options));
|
|
1513
|
+
},
|
|
1514
|
+
head: (url, options) => {
|
|
1515
|
+
return promise.then((client) => client.head(url, options));
|
|
1516
|
+
},
|
|
1517
|
+
options: (url, options) => {
|
|
1518
|
+
return promise.then((client) => client.options(url, options));
|
|
1519
|
+
},
|
|
1520
|
+
http: promise
|
|
1521
|
+
};
|
|
1522
|
+
Object.assign(data2, {
|
|
1523
|
+
then: promise.then.bind(promise),
|
|
1524
|
+
catch: promise.catch.bind(promise)
|
|
1525
|
+
});
|
|
1526
|
+
return data2;
|
|
1268
1527
|
}
|
|
1269
1528
|
async function useIframeModal() {
|
|
1270
1529
|
const module = await import("./iframe-modal.js");
|
|
@@ -1372,29 +1631,6 @@ async function useTinymceHook(handler) {
|
|
|
1372
1631
|
const { addHook } = await import("./tinymce.js");
|
|
1373
1632
|
return addHook(handler);
|
|
1374
1633
|
}
|
|
1375
|
-
async function useUIBootstrap5(install = false, pushToGlobal = false) {
|
|
1376
|
-
const { UIBootstrap5 } = await import("./ui-bootstrap5.js");
|
|
1377
|
-
const theme = UIBootstrap5.get();
|
|
1378
|
-
if (install) {
|
|
1379
|
-
useUITheme(theme);
|
|
1380
|
-
if (pushToGlobal) {
|
|
1381
|
-
theme.pushBootstrapToGlobal();
|
|
1382
|
-
}
|
|
1383
|
-
}
|
|
1384
|
-
return theme;
|
|
1385
|
-
}
|
|
1386
|
-
async function useBs5Tooltip(selector = '[data-bs-toggle="tooltip"]', config = {}) {
|
|
1387
|
-
const bs5 = await useUIBootstrap5();
|
|
1388
|
-
return bs5.tooltip(selector, config);
|
|
1389
|
-
}
|
|
1390
|
-
const useBs5KeepTab = async (selector, options = {}) => {
|
|
1391
|
-
const bs5 = await useUIBootstrap5();
|
|
1392
|
-
return bs5.keepTab(selector, options);
|
|
1393
|
-
};
|
|
1394
|
-
const useBs5ButtonRadio = async (selector, options = {}) => {
|
|
1395
|
-
const bs5 = await useUIBootstrap5();
|
|
1396
|
-
return bs5.buttonRadio(selector, options);
|
|
1397
|
-
};
|
|
1398
1634
|
let instances = {};
|
|
1399
1635
|
async function useWebDirective(name = "unicorn", options = {}) {
|
|
1400
1636
|
if (options === false) {
|
|
@@ -1698,6 +1934,7 @@ function useDisableOnSubmit(formSelector = "#admin-form", buttonSelector = "", o
|
|
|
1698
1934
|
].join(",");
|
|
1699
1935
|
const event = options.event || "submit";
|
|
1700
1936
|
const spinnerClass = options.spinnerClass || "spinner-border spinner-border-sm";
|
|
1937
|
+
const loadingClass = options.loadingCass || "is-loading";
|
|
1701
1938
|
selectAll(buttonSelector, (button) => {
|
|
1702
1939
|
button.addEventListener("click", (e) => {
|
|
1703
1940
|
button.dataset.clicked = "1";
|
|
@@ -1718,6 +1955,7 @@ function useDisableOnSubmit(formSelector = "#admin-form", buttonSelector = "", o
|
|
|
1718
1955
|
button.classList.add("disabled");
|
|
1719
1956
|
if (button.dataset.clicked) {
|
|
1720
1957
|
let icon = button.querySelector(iconSelector);
|
|
1958
|
+
button.classList.add(loadingClass);
|
|
1721
1959
|
if (icon) {
|
|
1722
1960
|
const i = html("<i></i>");
|
|
1723
1961
|
icon.parentNode.replaceChild(i, icon);
|
|
@@ -2238,7 +2476,7 @@ export {
|
|
|
2238
2476
|
useKeepAlive as Z,
|
|
2239
2477
|
__ as _,
|
|
2240
2478
|
useUniDirective as a,
|
|
2241
|
-
|
|
2479
|
+
useS3MultipartUploader as a$,
|
|
2242
2480
|
useBs5ButtonRadio as a0,
|
|
2243
2481
|
useBs5Tooltip as a1,
|
|
2244
2482
|
useFormAsync as a2,
|
|
@@ -2258,24 +2496,24 @@ export {
|
|
|
2258
2496
|
removeBoundedInstance as aG,
|
|
2259
2497
|
removeData as aH,
|
|
2260
2498
|
useAlertAdapter as aI,
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2499
|
+
useBsModalAlert as aJ,
|
|
2500
|
+
useCssIncludes as aK,
|
|
2501
|
+
useFieldCascadeSelect as aL,
|
|
2502
|
+
useFieldFileDrag as aM,
|
|
2503
|
+
useFieldFlatpickr as aN,
|
|
2504
|
+
useFieldModalSelect as aO,
|
|
2505
|
+
useFieldModalTree as aP,
|
|
2506
|
+
useFieldRepeatable as aQ,
|
|
2507
|
+
useFieldSingleImageDrag as aR,
|
|
2508
|
+
useFormComponent as aS,
|
|
2509
|
+
useFormSubmit as aT,
|
|
2510
|
+
useGridComponent as aU,
|
|
2511
|
+
useIframeModal as aV,
|
|
2512
|
+
useInject as aW,
|
|
2513
|
+
useLang as aX,
|
|
2514
|
+
useLegacy as aY,
|
|
2515
|
+
useListDependent as aZ,
|
|
2516
|
+
useMacro as a_,
|
|
2279
2517
|
watchAttributes as aa,
|
|
2280
2518
|
injectCssToDocument as ab,
|
|
2281
2519
|
useImport as ac,
|
|
@@ -2303,17 +2541,18 @@ export {
|
|
|
2303
2541
|
doImport as ay,
|
|
2304
2542
|
hasRoute as az,
|
|
2305
2543
|
animateTo as b,
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2544
|
+
useS3Uploader as b0,
|
|
2545
|
+
useSeriesImport as b1,
|
|
2546
|
+
useShowOn as b2,
|
|
2547
|
+
useTinymce as b3,
|
|
2548
|
+
useTinymceHook as b4,
|
|
2549
|
+
useUI as b5,
|
|
2550
|
+
useUIBootstrap5 as b6,
|
|
2551
|
+
useUnicorn as b7,
|
|
2552
|
+
useUnicornPhpAdapter as b8,
|
|
2553
|
+
useVueComponentField as b9,
|
|
2554
|
+
useWebDirective as ba,
|
|
2555
|
+
wait as bb,
|
|
2317
2556
|
renderMessage as c,
|
|
2318
2557
|
clearMessages as d,
|
|
2319
2558
|
clearNotifies as e,
|