@yuneta/gobj-ui 2.4.0 → 2.5.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/gobj-ui.cjs.js +50 -45
- package/dist/gobj-ui.es.js +50 -45
- package/package.json +1 -1
- package/src/c_yui_main.css +78 -0
- package/src/c_yui_main.js +66 -39
- package/src/yui_icons.css +15 -0
package/dist/gobj-ui.cjs.js
CHANGED
|
@@ -1562,7 +1562,7 @@ function yui_toolbar(attrs = {}, items = []) {
|
|
|
1562
1562
|
* The tabs in a content-layer to manage sub-containers can be managed by yui_tabs.js
|
|
1563
1563
|
* or be integrated in each gobj.
|
|
1564
1564
|
*
|
|
1565
|
-
* Copyright (c) 2025, ArtGins.
|
|
1565
|
+
* Copyright (c) 2025-2026, ArtGins.
|
|
1566
1566
|
* All Rights Reserved.
|
|
1567
1567
|
***********************************************************************/
|
|
1568
1568
|
/***************************************************************
|
|
@@ -2153,9 +2153,19 @@ console.log("GLOBAL callback");
|
|
|
2153
2153
|
************************************************************/
|
|
2154
2154
|
function display_volatil_modal({ title, msg, callback, type, x_close, buttons }) {
|
|
2155
2155
|
const callback_ = callback;
|
|
2156
|
+
let type_ = (type || "info").toLowerCase();
|
|
2157
|
+
if (type_ === "danger") type_ = "error";
|
|
2158
|
+
const TYPE_ICONS = {
|
|
2159
|
+
"info": "yi-circle-info",
|
|
2160
|
+
"question": "yi-question",
|
|
2161
|
+
"success": "yi-square-check",
|
|
2162
|
+
"warning": "yi-triangle-exclamation",
|
|
2163
|
+
"error": "yi-circle-exclamation"
|
|
2164
|
+
};
|
|
2165
|
+
let icon = TYPE_ICONS[type_] || TYPE_ICONS["info"];
|
|
2156
2166
|
let $element = (0, _yuneta_gobj_js.createElement2)([
|
|
2157
2167
|
"div",
|
|
2158
|
-
{ class:
|
|
2168
|
+
{ class: `modal yui-volatil is-${type_}` },
|
|
2159
2169
|
[[
|
|
2160
2170
|
"div",
|
|
2161
2171
|
{ class: "modal-background" },
|
|
@@ -2167,44 +2177,39 @@ function display_volatil_modal({ title, msg, callback, type, x_close, buttons })
|
|
|
2167
2177
|
]]
|
|
2168
2178
|
]);
|
|
2169
2179
|
const destroyModal = () => {
|
|
2180
|
+
document.removeEventListener("keydown", on_keydown, true);
|
|
2170
2181
|
$element.classList.remove("is-active");
|
|
2171
2182
|
$element.parentNode.removeChild($element);
|
|
2172
2183
|
};
|
|
2184
|
+
const on_keydown = (evt) => {
|
|
2185
|
+
if (evt.key !== "Escape") return;
|
|
2186
|
+
let $modals = document.querySelectorAll(".modal.is-active");
|
|
2187
|
+
if ($modals.length && $modals[$modals.length - 1] !== $element) return;
|
|
2188
|
+
evt.stopPropagation();
|
|
2189
|
+
evt.preventDefault();
|
|
2190
|
+
let $cancel = $element.querySelector(".cancelButton, .delete");
|
|
2191
|
+
if ($cancel) $cancel.click();
|
|
2192
|
+
else destroyModal();
|
|
2193
|
+
};
|
|
2194
|
+
document.addEventListener("keydown", on_keydown, true);
|
|
2173
2195
|
let $modal_card = $element.querySelector(".modal-card");
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
}
|
|
2192
|
-
let title_ = !title ? [] : [
|
|
2193
|
-
"p",
|
|
2194
|
-
{ class: "modal-card-title has-text-centered" },
|
|
2195
|
-
title
|
|
2196
|
-
];
|
|
2197
|
-
let x_close_ = !x_close ? [] : ["button", {
|
|
2198
|
-
class: "delete is-large",
|
|
2199
|
-
"aria-label": "close"
|
|
2200
|
-
}];
|
|
2201
|
-
let $header = (0, _yuneta_gobj_js.createElement2)([
|
|
2202
|
-
"header",
|
|
2203
|
-
{ class: `modal-card-head ${background_color} p-3` },
|
|
2204
|
-
[title_, x_close_]
|
|
2205
|
-
]);
|
|
2206
|
-
$modal_card.appendChild($header);
|
|
2207
|
-
}
|
|
2196
|
+
$modal_card.appendChild((0, _yuneta_gobj_js.createElement2)([
|
|
2197
|
+
"div",
|
|
2198
|
+
{ class: "yui-volatil-icon" },
|
|
2199
|
+
[["i", {
|
|
2200
|
+
class: icon,
|
|
2201
|
+
"aria-hidden": "true"
|
|
2202
|
+
}]]
|
|
2203
|
+
]));
|
|
2204
|
+
if (title) $modal_card.appendChild((0, _yuneta_gobj_js.createElement2)([
|
|
2205
|
+
"p",
|
|
2206
|
+
{ class: "yui-volatil-title has-text-centered" },
|
|
2207
|
+
title
|
|
2208
|
+
]));
|
|
2209
|
+
if (x_close) $modal_card.appendChild((0, _yuneta_gobj_js.createElement2)(["button", {
|
|
2210
|
+
class: "delete yui-volatil-x",
|
|
2211
|
+
"aria-label": "close"
|
|
2212
|
+
}]));
|
|
2208
2213
|
let $section = (0, _yuneta_gobj_js.createElement2)([
|
|
2209
2214
|
"section",
|
|
2210
2215
|
{ class: "modal-card-body has-text-centered" },
|
|
@@ -2265,7 +2270,7 @@ function display_info_message(title, msg, callback) {
|
|
|
2265
2270
|
msg,
|
|
2266
2271
|
callback,
|
|
2267
2272
|
type: "info",
|
|
2268
|
-
buttons: [{ content: `<button class="button is-
|
|
2273
|
+
buttons: [{ content: `<button class="button is-info px-6 with-focus">${(0, i18next.t)("accept")}</button>` }]
|
|
2269
2274
|
});
|
|
2270
2275
|
}
|
|
2271
2276
|
/************************************************************
|
|
@@ -2278,7 +2283,7 @@ function display_warning_message(title, msg, callback) {
|
|
|
2278
2283
|
msg,
|
|
2279
2284
|
callback,
|
|
2280
2285
|
type: "warning",
|
|
2281
|
-
buttons: [{ content: `<button class="button is-
|
|
2286
|
+
buttons: [{ content: `<button class="button is-warning px-6 with-focus">${(0, i18next.t)("accept")}</button>` }]
|
|
2282
2287
|
});
|
|
2283
2288
|
}
|
|
2284
2289
|
/************************************************************
|
|
@@ -2291,7 +2296,7 @@ function display_error_message(title, msg, callback, without_buttons) {
|
|
|
2291
2296
|
msg,
|
|
2292
2297
|
callback,
|
|
2293
2298
|
type: "error",
|
|
2294
|
-
buttons: without_buttons ? [] : [{ content: `<button class="button is-
|
|
2299
|
+
buttons: without_buttons ? [] : [{ content: `<button class="button is-danger px-6 with-focus">${(0, i18next.t)("accept")}</button>` }]
|
|
2295
2300
|
});
|
|
2296
2301
|
}
|
|
2297
2302
|
/************************************************************
|
|
@@ -2299,7 +2304,7 @@ function display_error_message(title, msg, callback, without_buttons) {
|
|
|
2299
2304
|
************************************************************/
|
|
2300
2305
|
function get_yesnocancel(msg, callback) {
|
|
2301
2306
|
let content = `<div class="">
|
|
2302
|
-
<p class="
|
|
2307
|
+
<p class="yui-volatil-msg">${(0, i18next.t)(msg)}</p>
|
|
2303
2308
|
<div class="buttons is-centered">
|
|
2304
2309
|
<button class="button to-close is-success px-6 with-focus yesButton">${(0, i18next.t)("yes")}</button>
|
|
2305
2310
|
<button class="button to-close is-danger px-6 noButton">${(0, i18next.t)("no")}</button>
|
|
@@ -2315,7 +2320,7 @@ function get_yesnocancel(msg, callback) {
|
|
|
2315
2320
|
title: null,
|
|
2316
2321
|
msg: content,
|
|
2317
2322
|
callback: callback_,
|
|
2318
|
-
type: "
|
|
2323
|
+
type: "question"
|
|
2319
2324
|
});
|
|
2320
2325
|
}
|
|
2321
2326
|
/************************************************************
|
|
@@ -2323,7 +2328,7 @@ function get_yesnocancel(msg, callback) {
|
|
|
2323
2328
|
************************************************************/
|
|
2324
2329
|
function get_yesno(msg, callback) {
|
|
2325
2330
|
let content = `<div class="">
|
|
2326
|
-
<p class="
|
|
2331
|
+
<p class="yui-volatil-msg">${msg}</p>
|
|
2327
2332
|
<div class="buttons is-centered">
|
|
2328
2333
|
<button class="button to-close is-success px-6 with-focus yesButton">${(0, i18next.t)("yes")}</button>
|
|
2329
2334
|
<button class="button to-close is-danger px-6 noButton">${(0, i18next.t)("no")}</button>
|
|
@@ -2338,7 +2343,7 @@ function get_yesno(msg, callback) {
|
|
|
2338
2343
|
title: null,
|
|
2339
2344
|
msg: content,
|
|
2340
2345
|
callback: callback_,
|
|
2341
|
-
type: "
|
|
2346
|
+
type: "question"
|
|
2342
2347
|
});
|
|
2343
2348
|
}
|
|
2344
2349
|
/************************************************************
|
|
@@ -2346,7 +2351,7 @@ function get_yesno(msg, callback) {
|
|
|
2346
2351
|
************************************************************/
|
|
2347
2352
|
function get_ok(msg, callback) {
|
|
2348
2353
|
let content = `<div class="">
|
|
2349
|
-
<p class="
|
|
2354
|
+
<p class="yui-volatil-msg">${msg}</p>
|
|
2350
2355
|
<div class="buttons is-centered">
|
|
2351
2356
|
<button class="button to-close is-success px-6 with-focus yesButton">${(0, i18next.t)("accept")}</button>
|
|
2352
2357
|
</div>
|
|
@@ -2360,7 +2365,7 @@ function get_ok(msg, callback) {
|
|
|
2360
2365
|
title: null,
|
|
2361
2366
|
msg: content,
|
|
2362
2367
|
callback: callback_,
|
|
2363
|
-
type: "
|
|
2368
|
+
type: "success"
|
|
2364
2369
|
});
|
|
2365
2370
|
}
|
|
2366
2371
|
/************************************************************
|
package/dist/gobj-ui.es.js
CHANGED
|
@@ -1557,7 +1557,7 @@ function yui_toolbar(attrs = {}, items = []) {
|
|
|
1557
1557
|
* The tabs in a content-layer to manage sub-containers can be managed by yui_tabs.js
|
|
1558
1558
|
* or be integrated in each gobj.
|
|
1559
1559
|
*
|
|
1560
|
-
* Copyright (c) 2025, ArtGins.
|
|
1560
|
+
* Copyright (c) 2025-2026, ArtGins.
|
|
1561
1561
|
* All Rights Reserved.
|
|
1562
1562
|
***********************************************************************/
|
|
1563
1563
|
/***************************************************************
|
|
@@ -2148,9 +2148,19 @@ console.log("GLOBAL callback");
|
|
|
2148
2148
|
************************************************************/
|
|
2149
2149
|
function display_volatil_modal({ title, msg, callback, type, x_close, buttons }) {
|
|
2150
2150
|
const callback_ = callback;
|
|
2151
|
+
let type_ = (type || "info").toLowerCase();
|
|
2152
|
+
if (type_ === "danger") type_ = "error";
|
|
2153
|
+
const TYPE_ICONS = {
|
|
2154
|
+
"info": "yi-circle-info",
|
|
2155
|
+
"question": "yi-question",
|
|
2156
|
+
"success": "yi-square-check",
|
|
2157
|
+
"warning": "yi-triangle-exclamation",
|
|
2158
|
+
"error": "yi-circle-exclamation"
|
|
2159
|
+
};
|
|
2160
|
+
let icon = TYPE_ICONS[type_] || TYPE_ICONS["info"];
|
|
2151
2161
|
let $element = createElement2([
|
|
2152
2162
|
"div",
|
|
2153
|
-
{ class:
|
|
2163
|
+
{ class: `modal yui-volatil is-${type_}` },
|
|
2154
2164
|
[[
|
|
2155
2165
|
"div",
|
|
2156
2166
|
{ class: "modal-background" },
|
|
@@ -2162,44 +2172,39 @@ function display_volatil_modal({ title, msg, callback, type, x_close, buttons })
|
|
|
2162
2172
|
]]
|
|
2163
2173
|
]);
|
|
2164
2174
|
const destroyModal = () => {
|
|
2175
|
+
document.removeEventListener("keydown", on_keydown, true);
|
|
2165
2176
|
$element.classList.remove("is-active");
|
|
2166
2177
|
$element.parentNode.removeChild($element);
|
|
2167
2178
|
};
|
|
2179
|
+
const on_keydown = (evt) => {
|
|
2180
|
+
if (evt.key !== "Escape") return;
|
|
2181
|
+
let $modals = document.querySelectorAll(".modal.is-active");
|
|
2182
|
+
if ($modals.length && $modals[$modals.length - 1] !== $element) return;
|
|
2183
|
+
evt.stopPropagation();
|
|
2184
|
+
evt.preventDefault();
|
|
2185
|
+
let $cancel = $element.querySelector(".cancelButton, .delete");
|
|
2186
|
+
if ($cancel) $cancel.click();
|
|
2187
|
+
else destroyModal();
|
|
2188
|
+
};
|
|
2189
|
+
document.addEventListener("keydown", on_keydown, true);
|
|
2168
2190
|
let $modal_card = $element.querySelector(".modal-card");
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
}
|
|
2187
|
-
let title_ = !title ? [] : [
|
|
2188
|
-
"p",
|
|
2189
|
-
{ class: "modal-card-title has-text-centered" },
|
|
2190
|
-
title
|
|
2191
|
-
];
|
|
2192
|
-
let x_close_ = !x_close ? [] : ["button", {
|
|
2193
|
-
class: "delete is-large",
|
|
2194
|
-
"aria-label": "close"
|
|
2195
|
-
}];
|
|
2196
|
-
let $header = createElement2([
|
|
2197
|
-
"header",
|
|
2198
|
-
{ class: `modal-card-head ${background_color} p-3` },
|
|
2199
|
-
[title_, x_close_]
|
|
2200
|
-
]);
|
|
2201
|
-
$modal_card.appendChild($header);
|
|
2202
|
-
}
|
|
2191
|
+
$modal_card.appendChild(createElement2([
|
|
2192
|
+
"div",
|
|
2193
|
+
{ class: "yui-volatil-icon" },
|
|
2194
|
+
[["i", {
|
|
2195
|
+
class: icon,
|
|
2196
|
+
"aria-hidden": "true"
|
|
2197
|
+
}]]
|
|
2198
|
+
]));
|
|
2199
|
+
if (title) $modal_card.appendChild(createElement2([
|
|
2200
|
+
"p",
|
|
2201
|
+
{ class: "yui-volatil-title has-text-centered" },
|
|
2202
|
+
title
|
|
2203
|
+
]));
|
|
2204
|
+
if (x_close) $modal_card.appendChild(createElement2(["button", {
|
|
2205
|
+
class: "delete yui-volatil-x",
|
|
2206
|
+
"aria-label": "close"
|
|
2207
|
+
}]));
|
|
2203
2208
|
let $section = createElement2([
|
|
2204
2209
|
"section",
|
|
2205
2210
|
{ class: "modal-card-body has-text-centered" },
|
|
@@ -2260,7 +2265,7 @@ function display_info_message(title, msg, callback) {
|
|
|
2260
2265
|
msg,
|
|
2261
2266
|
callback,
|
|
2262
2267
|
type: "info",
|
|
2263
|
-
buttons: [{ content: `<button class="button is-
|
|
2268
|
+
buttons: [{ content: `<button class="button is-info px-6 with-focus">${t("accept")}</button>` }]
|
|
2264
2269
|
});
|
|
2265
2270
|
}
|
|
2266
2271
|
/************************************************************
|
|
@@ -2273,7 +2278,7 @@ function display_warning_message(title, msg, callback) {
|
|
|
2273
2278
|
msg,
|
|
2274
2279
|
callback,
|
|
2275
2280
|
type: "warning",
|
|
2276
|
-
buttons: [{ content: `<button class="button is-
|
|
2281
|
+
buttons: [{ content: `<button class="button is-warning px-6 with-focus">${t("accept")}</button>` }]
|
|
2277
2282
|
});
|
|
2278
2283
|
}
|
|
2279
2284
|
/************************************************************
|
|
@@ -2286,7 +2291,7 @@ function display_error_message(title, msg, callback, without_buttons) {
|
|
|
2286
2291
|
msg,
|
|
2287
2292
|
callback,
|
|
2288
2293
|
type: "error",
|
|
2289
|
-
buttons: without_buttons ? [] : [{ content: `<button class="button is-
|
|
2294
|
+
buttons: without_buttons ? [] : [{ content: `<button class="button is-danger px-6 with-focus">${t("accept")}</button>` }]
|
|
2290
2295
|
});
|
|
2291
2296
|
}
|
|
2292
2297
|
/************************************************************
|
|
@@ -2294,7 +2299,7 @@ function display_error_message(title, msg, callback, without_buttons) {
|
|
|
2294
2299
|
************************************************************/
|
|
2295
2300
|
function get_yesnocancel(msg, callback) {
|
|
2296
2301
|
let content = `<div class="">
|
|
2297
|
-
<p class="
|
|
2302
|
+
<p class="yui-volatil-msg">${t(msg)}</p>
|
|
2298
2303
|
<div class="buttons is-centered">
|
|
2299
2304
|
<button class="button to-close is-success px-6 with-focus yesButton">${t("yes")}</button>
|
|
2300
2305
|
<button class="button to-close is-danger px-6 noButton">${t("no")}</button>
|
|
@@ -2310,7 +2315,7 @@ function get_yesnocancel(msg, callback) {
|
|
|
2310
2315
|
title: null,
|
|
2311
2316
|
msg: content,
|
|
2312
2317
|
callback: callback_,
|
|
2313
|
-
type: "
|
|
2318
|
+
type: "question"
|
|
2314
2319
|
});
|
|
2315
2320
|
}
|
|
2316
2321
|
/************************************************************
|
|
@@ -2318,7 +2323,7 @@ function get_yesnocancel(msg, callback) {
|
|
|
2318
2323
|
************************************************************/
|
|
2319
2324
|
function get_yesno(msg, callback) {
|
|
2320
2325
|
let content = `<div class="">
|
|
2321
|
-
<p class="
|
|
2326
|
+
<p class="yui-volatil-msg">${msg}</p>
|
|
2322
2327
|
<div class="buttons is-centered">
|
|
2323
2328
|
<button class="button to-close is-success px-6 with-focus yesButton">${t("yes")}</button>
|
|
2324
2329
|
<button class="button to-close is-danger px-6 noButton">${t("no")}</button>
|
|
@@ -2333,7 +2338,7 @@ function get_yesno(msg, callback) {
|
|
|
2333
2338
|
title: null,
|
|
2334
2339
|
msg: content,
|
|
2335
2340
|
callback: callback_,
|
|
2336
|
-
type: "
|
|
2341
|
+
type: "question"
|
|
2337
2342
|
});
|
|
2338
2343
|
}
|
|
2339
2344
|
/************************************************************
|
|
@@ -2341,7 +2346,7 @@ function get_yesno(msg, callback) {
|
|
|
2341
2346
|
************************************************************/
|
|
2342
2347
|
function get_ok(msg, callback) {
|
|
2343
2348
|
let content = `<div class="">
|
|
2344
|
-
<p class="
|
|
2349
|
+
<p class="yui-volatil-msg">${msg}</p>
|
|
2345
2350
|
<div class="buttons is-centered">
|
|
2346
2351
|
<button class="button to-close is-success px-6 with-focus yesButton">${t("accept")}</button>
|
|
2347
2352
|
</div>
|
|
@@ -2355,7 +2360,7 @@ function get_ok(msg, callback) {
|
|
|
2355
2360
|
title: null,
|
|
2356
2361
|
msg: content,
|
|
2357
2362
|
callback: callback_,
|
|
2358
|
-
type: "
|
|
2363
|
+
type: "success"
|
|
2359
2364
|
});
|
|
2360
2365
|
}
|
|
2361
2366
|
/************************************************************
|
package/package.json
CHANGED
package/src/c_yui_main.css
CHANGED
|
@@ -421,3 +421,81 @@ a.flex-horizontal-section { /* To make flex any <a> */
|
|
|
421
421
|
color: var(--bulma-link-invert);
|
|
422
422
|
}
|
|
423
423
|
}
|
|
424
|
+
|
|
425
|
+
/*============================================================
|
|
426
|
+
* Volatil modals (display_volatil_modal):
|
|
427
|
+
* get_yesnocancel / get_yesno / get_ok and the typed
|
|
428
|
+
* info/warning/error messages. Icon-centric layout: a
|
|
429
|
+
* narrow rounded card with a tinted round icon of the
|
|
430
|
+
* type; everything maps to Bulma vars so one rule set
|
|
431
|
+
* follows light and dark.
|
|
432
|
+
*============================================================*/
|
|
433
|
+
.modal.yui-volatil .modal-background {
|
|
434
|
+
background-color: color-mix(in srgb, var(--bulma-scheme-invert, #000) 45%, transparent);
|
|
435
|
+
}
|
|
436
|
+
.modal.yui-volatil .modal-card {
|
|
437
|
+
position: relative;
|
|
438
|
+
width: min(26rem, calc(100vw - 2rem));
|
|
439
|
+
border-radius: 0.75rem;
|
|
440
|
+
background: var(--bulma-scheme-main, #fff);
|
|
441
|
+
box-shadow: 0 12px 40px color-mix(in srgb, var(--bulma-scheme-invert, #000) 30%, transparent);
|
|
442
|
+
padding: 1.5rem 1.5rem 1.25rem;
|
|
443
|
+
}
|
|
444
|
+
.modal.yui-volatil .modal-card-body {
|
|
445
|
+
background: transparent;
|
|
446
|
+
padding: 0;
|
|
447
|
+
}
|
|
448
|
+
.modal.yui-volatil .modal-card-foot {
|
|
449
|
+
background: transparent;
|
|
450
|
+
border-top: none;
|
|
451
|
+
padding: 1rem 0 0;
|
|
452
|
+
}
|
|
453
|
+
.yui-volatil-icon {
|
|
454
|
+
width: 3.25rem;
|
|
455
|
+
height: 3.25rem;
|
|
456
|
+
border-radius: 9999px;
|
|
457
|
+
display: flex;
|
|
458
|
+
align-items: center;
|
|
459
|
+
justify-content: center;
|
|
460
|
+
margin: 0 auto 0.75rem;
|
|
461
|
+
font-size: 1.5rem;
|
|
462
|
+
background: color-mix(in srgb, var(--yui-volatil-base, var(--bulma-info, #3e8ed0)) 15%, transparent);
|
|
463
|
+
color: var(--yui-volatil-ink, var(--bulma-info, #3e8ed0));
|
|
464
|
+
}
|
|
465
|
+
.modal.yui-volatil.is-info,
|
|
466
|
+
.modal.yui-volatil.is-question {
|
|
467
|
+
--yui-volatil-base: var(--bulma-info, #3e8ed0);
|
|
468
|
+
--yui-volatil-ink: var(--bulma-info-on-scheme, #3e8ed0);
|
|
469
|
+
}
|
|
470
|
+
.modal.yui-volatil.is-success {
|
|
471
|
+
--yui-volatil-base: var(--bulma-success, #48c78e);
|
|
472
|
+
--yui-volatil-ink: var(--bulma-success-on-scheme, #257953);
|
|
473
|
+
}
|
|
474
|
+
.modal.yui-volatil.is-warning {
|
|
475
|
+
--yui-volatil-base: var(--bulma-warning, #ffe08a);
|
|
476
|
+
--yui-volatil-ink: var(--bulma-warning-on-scheme, #946c00);
|
|
477
|
+
}
|
|
478
|
+
.modal.yui-volatil.is-error {
|
|
479
|
+
--yui-volatil-base: var(--bulma-danger, #f14668);
|
|
480
|
+
--yui-volatil-ink: var(--bulma-danger-on-scheme, #cc0f35);
|
|
481
|
+
}
|
|
482
|
+
.yui-volatil-title {
|
|
483
|
+
font-size: 1.15rem;
|
|
484
|
+
font-weight: 600;
|
|
485
|
+
text-transform: capitalize;
|
|
486
|
+
margin-bottom: 0.25rem;
|
|
487
|
+
color: var(--bulma-text-strong, inherit);
|
|
488
|
+
}
|
|
489
|
+
.yui-volatil-x {
|
|
490
|
+
position: absolute;
|
|
491
|
+
top: 0.75rem;
|
|
492
|
+
right: 0.75rem;
|
|
493
|
+
}
|
|
494
|
+
.yui-volatil-msg {
|
|
495
|
+
font-size: 1.05rem;
|
|
496
|
+
color: var(--bulma-text, inherit);
|
|
497
|
+
}
|
|
498
|
+
.modal.yui-volatil .modal-card-body .buttons {
|
|
499
|
+
margin-top: 1.25rem;
|
|
500
|
+
margin-bottom: 0;
|
|
501
|
+
}
|
package/src/c_yui_main.js
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* The tabs in a content-layer to manage sub-containers can be managed by yui_tabs.js
|
|
28
28
|
* or be integrated in each gobj.
|
|
29
29
|
*
|
|
30
|
-
* Copyright (c) 2025, ArtGins.
|
|
30
|
+
* Copyright (c) 2025-2026, ArtGins.
|
|
31
31
|
* All Rights Reserved.
|
|
32
32
|
***********************************************************************/
|
|
33
33
|
/* global ResizeObserver, window, document */
|
|
@@ -879,50 +879,77 @@ function display_volatil_modal(
|
|
|
879
879
|
{title, msg, callback, type, x_close, buttons}
|
|
880
880
|
) {
|
|
881
881
|
const callback_ = callback; // ✅ Assign to a constant
|
|
882
|
+
|
|
883
|
+
/* Normalize the type: it picks the tinted icon and the accent
|
|
884
|
+
* color (see the .yui-volatil rules in c_yui_main.css). */
|
|
885
|
+
let type_ = (type || "info").toLowerCase();
|
|
886
|
+
if(type_ === "danger") {
|
|
887
|
+
type_ = "error";
|
|
888
|
+
}
|
|
889
|
+
const TYPE_ICONS = {
|
|
890
|
+
"info": "yi-circle-info",
|
|
891
|
+
"question": "yi-question",
|
|
892
|
+
"success": "yi-square-check",
|
|
893
|
+
"warning": "yi-triangle-exclamation",
|
|
894
|
+
"error": "yi-circle-exclamation",
|
|
895
|
+
};
|
|
896
|
+
let icon = TYPE_ICONS[type_] || TYPE_ICONS["info"];
|
|
897
|
+
|
|
882
898
|
let $element = createElement2([
|
|
883
|
-
'div', {class:
|
|
899
|
+
'div', {class: `modal yui-volatil is-${type_}`}, [
|
|
884
900
|
['div', {class: 'modal-background'}, ''],
|
|
885
901
|
['div', {class: 'modal-card'}, []]
|
|
886
902
|
]
|
|
887
903
|
]);
|
|
888
904
|
|
|
889
905
|
const destroyModal = ()=> {
|
|
906
|
+
document.removeEventListener('keydown', on_keydown, true);
|
|
890
907
|
$element.classList.remove('is-active');
|
|
891
908
|
$element.parentNode.removeChild($element);
|
|
892
909
|
};
|
|
893
910
|
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
911
|
+
/* Escape = cancel. Capture phase on document, so Escape handlers
|
|
912
|
+
* beneath the modal (e.g. the treedb edit dialog's own) don't also
|
|
913
|
+
* fire and stack a second confirm. Only the top-most open modal
|
|
914
|
+
* reacts; the cancel/x click path carries the callback semantics,
|
|
915
|
+
* a buttonless modal just dismisses. */
|
|
916
|
+
const on_keydown = (evt)=> {
|
|
917
|
+
if(evt.key !== "Escape") {
|
|
918
|
+
return;
|
|
919
|
+
}
|
|
920
|
+
let $modals = document.querySelectorAll('.modal.is-active');
|
|
921
|
+
if($modals.length && $modals[$modals.length - 1] !== $element) {
|
|
922
|
+
return;
|
|
898
923
|
}
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
break;
|
|
907
|
-
case "warning":
|
|
908
|
-
background_color = 'has-background-warning';
|
|
909
|
-
break;
|
|
910
|
-
case "error":
|
|
911
|
-
case "danger":
|
|
912
|
-
background_color = 'has-background-danger';
|
|
913
|
-
break;
|
|
924
|
+
evt.stopPropagation();
|
|
925
|
+
evt.preventDefault();
|
|
926
|
+
let $cancel = $element.querySelector('.cancelButton, .delete');
|
|
927
|
+
if($cancel) {
|
|
928
|
+
$cancel.click();
|
|
929
|
+
} else {
|
|
930
|
+
destroyModal();
|
|
914
931
|
}
|
|
932
|
+
};
|
|
933
|
+
document.addEventListener('keydown', on_keydown, true);
|
|
915
934
|
|
|
916
|
-
|
|
917
|
-
let x_close_ = !x_close ? [] : ['button', {class: 'delete is-large', 'aria-label': 'close'}];
|
|
935
|
+
let $modal_card = $element.querySelector('.modal-card');
|
|
918
936
|
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
]
|
|
924
|
-
|
|
925
|
-
|
|
937
|
+
/* Icon-centric layout (no colored header bar): a tinted round
|
|
938
|
+
* icon of the type, an optional title, an optional top-right x. */
|
|
939
|
+
$modal_card.appendChild(createElement2(
|
|
940
|
+
['div', {class: 'yui-volatil-icon'}, [
|
|
941
|
+
['i', {class: icon, 'aria-hidden': 'true'}]
|
|
942
|
+
]]
|
|
943
|
+
));
|
|
944
|
+
if(title) {
|
|
945
|
+
$modal_card.appendChild(createElement2(
|
|
946
|
+
['p', {class: 'yui-volatil-title has-text-centered'}, title]
|
|
947
|
+
));
|
|
948
|
+
}
|
|
949
|
+
if(x_close) {
|
|
950
|
+
$modal_card.appendChild(createElement2(
|
|
951
|
+
['button', {class: 'delete yui-volatil-x', 'aria-label': 'close'}]
|
|
952
|
+
));
|
|
926
953
|
}
|
|
927
954
|
|
|
928
955
|
let $section = createElement2(
|
|
@@ -1017,7 +1044,7 @@ function display_info_message(title, msg, callback)
|
|
|
1017
1044
|
type: 'info',
|
|
1018
1045
|
buttons: [{
|
|
1019
1046
|
content:
|
|
1020
|
-
`<button class="button is-
|
|
1047
|
+
`<button class="button is-info px-6 with-focus">${t('accept')}</button>`,
|
|
1021
1048
|
}]
|
|
1022
1049
|
});
|
|
1023
1050
|
}
|
|
@@ -1037,7 +1064,7 @@ function display_warning_message(title, msg, callback)
|
|
|
1037
1064
|
type: 'warning',
|
|
1038
1065
|
buttons: [{
|
|
1039
1066
|
content:
|
|
1040
|
-
`<button class="button is-
|
|
1067
|
+
`<button class="button is-warning px-6 with-focus">${t('accept')}</button>`,
|
|
1041
1068
|
}]
|
|
1042
1069
|
});
|
|
1043
1070
|
}
|
|
@@ -1057,7 +1084,7 @@ function display_error_message(title, msg, callback, without_buttons)
|
|
|
1057
1084
|
type: 'error',
|
|
1058
1085
|
buttons: without_buttons? []: [{
|
|
1059
1086
|
content:
|
|
1060
|
-
`<button class="button is-
|
|
1087
|
+
`<button class="button is-danger px-6 with-focus">${t('accept')}</button>`,
|
|
1061
1088
|
}]
|
|
1062
1089
|
});
|
|
1063
1090
|
}
|
|
@@ -1069,7 +1096,7 @@ function get_yesnocancel(msg, callback)
|
|
|
1069
1096
|
{
|
|
1070
1097
|
let content =
|
|
1071
1098
|
`<div class="">
|
|
1072
|
-
<p class="
|
|
1099
|
+
<p class="yui-volatil-msg">${t(msg)}</p>
|
|
1073
1100
|
<div class="buttons is-centered">
|
|
1074
1101
|
<button class="button to-close is-success px-6 with-focus yesButton">${t('yes')}</button>
|
|
1075
1102
|
<button class="button to-close is-danger px-6 noButton">${t('no')}</button>
|
|
@@ -1091,7 +1118,7 @@ function get_yesnocancel(msg, callback)
|
|
|
1091
1118
|
title: null,
|
|
1092
1119
|
msg: content,
|
|
1093
1120
|
callback: callback_,
|
|
1094
|
-
type: '
|
|
1121
|
+
type: 'question'
|
|
1095
1122
|
});
|
|
1096
1123
|
}
|
|
1097
1124
|
|
|
@@ -1102,7 +1129,7 @@ function get_yesno(msg, callback)
|
|
|
1102
1129
|
{
|
|
1103
1130
|
let content =
|
|
1104
1131
|
`<div class="">
|
|
1105
|
-
<p class="
|
|
1132
|
+
<p class="yui-volatil-msg">${msg}</p>
|
|
1106
1133
|
<div class="buttons is-centered">
|
|
1107
1134
|
<button class="button to-close is-success px-6 with-focus yesButton">${t('yes')}</button>
|
|
1108
1135
|
<button class="button to-close is-danger px-6 noButton">${t('no')}</button>
|
|
@@ -1123,7 +1150,7 @@ function get_yesno(msg, callback)
|
|
|
1123
1150
|
title: null,
|
|
1124
1151
|
msg: content,
|
|
1125
1152
|
callback: callback_,
|
|
1126
|
-
type: '
|
|
1153
|
+
type: 'question'
|
|
1127
1154
|
});
|
|
1128
1155
|
}
|
|
1129
1156
|
|
|
@@ -1134,7 +1161,7 @@ function get_ok(msg, callback)
|
|
|
1134
1161
|
{
|
|
1135
1162
|
let content =
|
|
1136
1163
|
`<div class="">
|
|
1137
|
-
<p class="
|
|
1164
|
+
<p class="yui-volatil-msg">${msg}</p>
|
|
1138
1165
|
<div class="buttons is-centered">
|
|
1139
1166
|
<button class="button to-close is-success px-6 with-focus yesButton">${t('accept')}</button>
|
|
1140
1167
|
</div>
|
|
@@ -1154,7 +1181,7 @@ function get_ok(msg, callback)
|
|
|
1154
1181
|
title: null,
|
|
1155
1182
|
msg: content,
|
|
1156
1183
|
callback: callback_,
|
|
1157
|
-
type: '
|
|
1184
|
+
type: 'success'
|
|
1158
1185
|
});
|
|
1159
1186
|
}
|
|
1160
1187
|
|
package/src/yui_icons.css
CHANGED
|
@@ -239,3 +239,18 @@
|
|
|
239
239
|
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E%3Cpath d='M438.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L338.7 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l306.7 0L233.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l160-160z'/%3E%3C/svg%3E");
|
|
240
240
|
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E%3Cpath d='M438.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L338.7 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l306.7 0L233.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l160-160z'/%3E%3C/svg%3E");
|
|
241
241
|
}
|
|
242
|
+
|
|
243
|
+
.yi-circle-info::before {
|
|
244
|
+
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336l24 0 0-64-24 0c-13.3 0-24-10.7-24-24s10.7-24 24-24l48 0c13.3 0 24 10.7 24 24l0 88 8 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-80 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-208a32 32 0 1 1 0 64 32 32 0 1 1 0-64z'/%3E%3C/svg%3E");
|
|
245
|
+
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336l24 0 0-64-24 0c-13.3 0-24-10.7-24-24s10.7-24 24-24l48 0c13.3 0 24 10.7 24 24l0 88 8 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-80 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-208a32 32 0 1 1 0 64 32 32 0 1 1 0-64z'/%3E%3C/svg%3E");
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.yi-triangle-exclamation::before {
|
|
249
|
+
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M256 32c14.2 0 27.3 7.5 34.5 19.8l216 368c7.3 12.4 7.3 27.7 .2 40.1S486.3 480 472 480L40 480c-14.3 0-27.6-7.7-34.7-20.1s-7-27.8 .2-40.1l216-368C228.7 39.5 241.8 32 256 32zm0 128c-13.3 0-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z'/%3E%3C/svg%3E");
|
|
250
|
+
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M256 32c14.2 0 27.3 7.5 34.5 19.8l216 368c7.3 12.4 7.3 27.7 .2 40.1S486.3 480 472 480L40 480c-14.3 0-27.6-7.7-34.7-20.1s-7-27.8 .2-40.1l216-368C228.7 39.5 241.8 32 256 32zm0 128c-13.3 0-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z'/%3E%3C/svg%3E");
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.yi-circle-exclamation::before {
|
|
254
|
+
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-384c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zm32 224a32 32 0 1 1 -64 0 32 32 0 1 1 64 0z'/%3E%3C/svg%3E");
|
|
255
|
+
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-384c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zm32 224a32 32 0 1 1 -64 0 32 32 0 1 1 64 0z'/%3E%3C/svg%3E");
|
|
256
|
+
}
|