web-mojo 2.3.2 → 2.3.5

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 (120) hide show
  1. package/CHANGELOG.md +192 -5
  2. package/dist/admin-models.cjs.js +1 -1
  3. package/dist/admin-models.es.js +1 -1
  4. package/dist/admin.cjs.js +1 -1
  5. package/dist/admin.es.js +1 -1
  6. package/dist/auth.cjs.js +1 -1
  7. package/dist/auth.es.js +1 -1
  8. package/dist/charts.cjs.js +1 -1
  9. package/dist/charts.es.js +1 -1
  10. package/dist/chunks/{AssistantPanelView-D-0f5hZS.js → AssistantPanelView-CvjzGGS8.js} +2 -2
  11. package/dist/chunks/{AssistantPanelView-D-0f5hZS.js.map → AssistantPanelView-CvjzGGS8.js.map} +1 -1
  12. package/dist/chunks/{AssistantPanelView-72i9d6rq.js → AssistantPanelView-D3WCWj5q.js} +2 -2
  13. package/dist/chunks/{AssistantPanelView-72i9d6rq.js.map → AssistantPanelView-D3WCWj5q.js.map} +1 -1
  14. package/dist/chunks/{ChatView-ys5MIiBf.js → ChatView-B-2JVhM3.js} +2 -2
  15. package/dist/chunks/{ChatView-ys5MIiBf.js.map → ChatView-B-2JVhM3.js.map} +1 -1
  16. package/dist/chunks/{ChatView-CXykdAV1.js → ChatView-oZ9FggEo.js} +2 -2
  17. package/dist/chunks/{ChatView-CXykdAV1.js.map → ChatView-oZ9FggEo.js.map} +1 -1
  18. package/dist/chunks/{Collection-CY6BblFn.js → Collection-BtSHP_BV.js} +2 -2
  19. package/dist/chunks/{Collection-CY6BblFn.js.map → Collection-BtSHP_BV.js.map} +1 -1
  20. package/dist/chunks/{Collection-BpUmNuDZ.js → Collection-CtSGTegm.js} +2 -2
  21. package/dist/chunks/{Collection-BpUmNuDZ.js.map → Collection-CtSGTegm.js.map} +1 -1
  22. package/dist/chunks/{ContextMenu-XQVFU0mL.js → ContextMenu-0KtfqyQm.js} +2 -2
  23. package/dist/chunks/{ContextMenu-XQVFU0mL.js.map → ContextMenu-0KtfqyQm.js.map} +1 -1
  24. package/dist/chunks/{ContextMenu-PtN50qH2.js → ContextMenu-DvQTJA49.js} +2 -2
  25. package/dist/chunks/{ContextMenu-PtN50qH2.js.map → ContextMenu-DvQTJA49.js.map} +1 -1
  26. package/dist/chunks/{DataView-BTi_BZHx.js → DataView-DJMOmlKN.js} +2 -2
  27. package/dist/chunks/{DataView-BTi_BZHx.js.map → DataView-DJMOmlKN.js.map} +1 -1
  28. package/dist/chunks/{DataView-WHRh1o6E.js → DataView-jHxX-6Gh.js} +2 -2
  29. package/dist/chunks/{DataView-WHRh1o6E.js.map → DataView-jHxX-6Gh.js.map} +1 -1
  30. package/dist/chunks/{FormView-DTD-Zy22.js → FormView-C_7xQuI4.js} +3 -3
  31. package/dist/chunks/{FormView-DTD-Zy22.js.map → FormView-C_7xQuI4.js.map} +1 -1
  32. package/dist/chunks/{FormView-BzaGMf5_.js → FormView-D8YrH2V4.js} +3 -3
  33. package/dist/chunks/{FormView-BzaGMf5_.js.map → FormView-D8YrH2V4.js.map} +1 -1
  34. package/dist/chunks/{ListView-BsnnTcmC.js → ListView-CjJ-4gD7.js} +2 -2
  35. package/dist/chunks/{ListView-BsnnTcmC.js.map → ListView-CjJ-4gD7.js.map} +1 -1
  36. package/dist/chunks/{ListView-Xf7kO6Me.js → ListView-mr1Kmuj-.js} +2 -2
  37. package/dist/chunks/{ListView-Xf7kO6Me.js.map → ListView-mr1Kmuj-.js.map} +1 -1
  38. package/dist/chunks/{MetricsCountryMapView-BzGOi1d2.js → MetricsCountryMapView-BIsfmvE0.js} +2 -2
  39. package/dist/chunks/{MetricsCountryMapView-BzGOi1d2.js.map → MetricsCountryMapView-BIsfmvE0.js.map} +1 -1
  40. package/dist/chunks/{MetricsCountryMapView-C-S00Wiw.js → MetricsCountryMapView-D9J4Gwdi.js} +2 -2
  41. package/dist/chunks/{MetricsCountryMapView-C-S00Wiw.js.map → MetricsCountryMapView-D9J4Gwdi.js.map} +1 -1
  42. package/dist/chunks/Modal-DF98u_sN.js +3 -0
  43. package/dist/chunks/Modal-DF98u_sN.js.map +1 -0
  44. package/dist/chunks/Modal-DYJadSN8.js +3 -0
  45. package/dist/chunks/Modal-DYJadSN8.js.map +1 -0
  46. package/dist/chunks/Passkeys-8ko7Rg8G.js +2 -0
  47. package/dist/chunks/Passkeys-8ko7Rg8G.js.map +1 -0
  48. package/dist/chunks/Passkeys-CD8RKUl8.js +2 -0
  49. package/dist/chunks/Passkeys-CD8RKUl8.js.map +1 -0
  50. package/dist/chunks/TokenManager-B-xR8zPl.js +2 -0
  51. package/dist/chunks/TokenManager-B-xR8zPl.js.map +1 -0
  52. package/dist/chunks/TokenManager-CZTL4OqZ.js +2 -0
  53. package/dist/chunks/TokenManager-CZTL4OqZ.js.map +1 -0
  54. package/dist/chunks/{User-KTBU_5cr.js → User-C6Tbn6vZ.js} +2 -2
  55. package/dist/chunks/User-C6Tbn6vZ.js.map +1 -0
  56. package/dist/chunks/{User-B_Urf7U7.js → User-DRbw-wOB.js} +2 -2
  57. package/dist/chunks/User-DRbw-wOB.js.map +1 -0
  58. package/dist/chunks/{UserProfileView-BmduMJ86.js → UserProfileView-DC70hRer.js} +2 -2
  59. package/dist/chunks/{UserProfileView-COxSyPB0.js.map → UserProfileView-DC70hRer.js.map} +1 -1
  60. package/dist/chunks/{UserProfileView-COxSyPB0.js → UserProfileView-TQ9BqUE2.js} +2 -2
  61. package/dist/chunks/{UserProfileView-BmduMJ86.js.map → UserProfileView-TQ9BqUE2.js.map} +1 -1
  62. package/dist/chunks/{View-C8UWvaSM.js → View-BWOE7WJm.js} +2 -2
  63. package/dist/chunks/{View-C8UWvaSM.js.map → View-BWOE7WJm.js.map} +1 -1
  64. package/dist/chunks/{View-Cvs2TY7b.js → View-D6Ug7M6k.js} +2 -2
  65. package/dist/chunks/{View-Cvs2TY7b.js.map → View-D6Ug7M6k.js.map} +1 -1
  66. package/dist/chunks/{WebApp-kbRq7dM_.js → WebApp-By80XfTK.js} +2 -2
  67. package/dist/chunks/{WebApp-kbRq7dM_.js.map → WebApp-By80XfTK.js.map} +1 -1
  68. package/dist/chunks/{WebApp-DuwanN2O.js → WebApp-CLTFSbto.js} +2 -2
  69. package/dist/chunks/{WebApp-DuwanN2O.js.map → WebApp-CLTFSbto.js.map} +1 -1
  70. package/dist/chunks/{admin-BcJ_hgzn.js → admin-CXA-Vkhf.js} +2 -2
  71. package/dist/chunks/{admin-BcJ_hgzn.js.map → admin-CXA-Vkhf.js.map} +1 -1
  72. package/dist/chunks/{admin-DtjMWe6R.js → admin-DcLy2QC2.js} +2 -2
  73. package/dist/chunks/{admin-DtjMWe6R.js.map → admin-DcLy2QC2.js.map} +1 -1
  74. package/dist/chunks/{exportChart-Dn2pioNl.js → exportChart-BQXkqsxe.js} +2 -2
  75. package/dist/chunks/{exportChart-Dn2pioNl.js.map → exportChart-BQXkqsxe.js.map} +1 -1
  76. package/dist/chunks/{exportChart-Bkxr7mCe.js → exportChart-UQ5nq_mR.js} +2 -2
  77. package/dist/chunks/{exportChart-Bkxr7mCe.js.map → exportChart-UQ5nq_mR.js.map} +1 -1
  78. package/dist/chunks/{index-CJeTVskY.js → index-C9wf7N-j.js} +2 -2
  79. package/dist/chunks/{index-CJeTVskY.js.map → index-C9wf7N-j.js.map} +1 -1
  80. package/dist/chunks/{index-BCWkcyOy.js → index-TqW1pAMX.js} +2 -2
  81. package/dist/chunks/{index-BCWkcyOy.js.map → index-TqW1pAMX.js.map} +1 -1
  82. package/dist/chunks/{version-DkxW4rIi.js → version-Bdrq2emC.js} +2 -2
  83. package/dist/chunks/{version-DkxW4rIi.js.map → version-Bdrq2emC.js.map} +1 -1
  84. package/dist/chunks/{version-CB0Ssm9c.js → version-xpJSWoyH.js} +2 -2
  85. package/dist/chunks/{version-CB0Ssm9c.js.map → version-xpJSWoyH.js.map} +1 -1
  86. package/dist/core.css +68 -209
  87. package/dist/css/web-mojo.css +1 -1
  88. package/dist/docit.cjs.js +1 -1
  89. package/dist/docit.es.js +1 -1
  90. package/dist/index.cjs.js +1 -1
  91. package/dist/index.cjs.js.map +1 -1
  92. package/dist/index.es.js +1 -1
  93. package/dist/index.es.js.map +1 -1
  94. package/dist/lightbox.cjs.js +1 -1
  95. package/dist/lightbox.es.js +1 -1
  96. package/dist/map.cjs.js +1 -1
  97. package/dist/map.es.js +1 -1
  98. package/dist/timeline.cjs.js +1 -1
  99. package/dist/timeline.es.js +1 -1
  100. package/dist/user-profile.cjs.js +1 -1
  101. package/dist/user-profile.es.js +1 -1
  102. package/dist/web-mojo.lite.iife.js +95 -168
  103. package/dist/web-mojo.lite.iife.js.map +1 -1
  104. package/dist/web-mojo.lite.iife.min.js +98 -98
  105. package/dist/web-mojo.lite.iife.min.js.map +1 -1
  106. package/package.json +3 -1
  107. package/dist/chunks/Modal-GWjyfcz5.js +0 -3
  108. package/dist/chunks/Modal-GWjyfcz5.js.map +0 -1
  109. package/dist/chunks/Modal-wrfWfQhv.js +0 -3
  110. package/dist/chunks/Modal-wrfWfQhv.js.map +0 -1
  111. package/dist/chunks/Passkeys-BviQX3_5.js +0 -2
  112. package/dist/chunks/Passkeys-BviQX3_5.js.map +0 -1
  113. package/dist/chunks/Passkeys-gXR1Rc6C.js +0 -2
  114. package/dist/chunks/Passkeys-gXR1Rc6C.js.map +0 -1
  115. package/dist/chunks/TokenManager-C6aXkRaI.js +0 -2
  116. package/dist/chunks/TokenManager-C6aXkRaI.js.map +0 -1
  117. package/dist/chunks/TokenManager-DgvhhTqN.js +0 -2
  118. package/dist/chunks/TokenManager-DgvhhTqN.js.map +0 -1
  119. package/dist/chunks/User-B_Urf7U7.js.map +0 -1
  120. package/dist/chunks/User-KTBU_5cr.js.map +0 -1
@@ -5379,23 +5379,11 @@ var MOJO = (function(exports) {
5379
5379
  }
5380
5380
  constructor(options = {}) {
5381
5381
  const modalId = options.id || `modal-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
5382
- options.header === false || options.header === null;
5383
- options.headerContent !== void 0 && options.headerContent !== null;
5384
- let resolvedStyle = options.style;
5385
- let bandlessClass = "";
5386
- if (options.eyebrow === false || options.eyebrow === null) {
5387
- bandlessClass = "modal-bandless";
5388
- } else if (options.eyebrow) {
5389
- const safe = String(options.eyebrow).replace(/['"\\]/g, "");
5390
- const styleVar = `--mojo-eyebrow: '${safe}'`;
5391
- resolvedStyle = [resolvedStyle, styleVar].filter(Boolean).join("; ");
5392
- }
5393
5382
  super({
5394
5383
  ...options,
5395
5384
  id: modalId,
5396
5385
  tagName: "div",
5397
- className: `modal ${options.fade !== false ? "fade" : ""} ${bandlessClass} ${options.className || ""}`.trim().replace(/\s+/g, " "),
5398
- style: resolvedStyle,
5386
+ className: `modal ${options.fade !== false ? "fade" : ""} ${options.className || ""}`.trim().replace(/\s+/g, " "),
5399
5387
  attributes: {
5400
5388
  tabindex: "-1",
5401
5389
  "aria-hidden": "true",
@@ -8499,48 +8487,91 @@ var MOJO = (function(exports) {
8499
8487
  metrics: ["view_metrics", "manage_metrics", "write_metrics"],
8500
8488
  files: ["view_fileman", "manage_files", "view_vault", "manage_vault"]
8501
8489
  };
8502
- User.GRANULAR_TO_CATEGORY = {};
8503
- for (const [category, perms] of Object.entries(User.CATEGORY_GRANULAR_MAP)) {
8504
- for (const perm of perms) {
8505
- User.GRANULAR_TO_CATEGORY[perm] = category;
8506
- }
8507
- }
8508
8490
  User.APP_CATEGORY_PERMISSIONS = [];
8509
8491
  User.APP_GRANULAR_PERMISSIONS = [];
8510
- User.PERMISSIONS = [
8511
- ...User.CATEGORY_PERMISSIONS,
8512
- ...User.GRANULAR_PERMISSION_TABS.flatMap((tab) => tab.permissions),
8513
- ...User.APP_CATEGORY_PERMISSIONS,
8514
- ...User.APP_GRANULAR_PERMISSIONS
8515
- ];
8516
- User.PERMISSION_FIELDS = [
8517
- ...User.PERMISSIONS.map((permission) => ({
8518
- name: `permissions.${permission.name}`,
8492
+ User._permSwitch = function(p) {
8493
+ return {
8494
+ name: `permissions.${p.name}`,
8519
8495
  type: "switch",
8520
- label: permission.label,
8521
- columns: 6
8522
- }))
8523
- ];
8524
- const _permSwitch = (p) => ({ name: `permissions.${p.name}`, type: "switch", label: p.label, columns: 6, ...p.tooltip ? { tooltip: p.tooltip } : {} });
8525
- User.CATEGORY_PERMISSION_FIELDS = (() => {
8526
- const tabs = [
8527
- { label: "System", fields: User.CATEGORY_PERMISSIONS.map(_permSwitch) }
8496
+ label: p.label,
8497
+ columns: 6,
8498
+ ...p.tooltip ? { tooltip: p.tooltip } : {}
8499
+ };
8500
+ };
8501
+ User.PERMISSIONS = [];
8502
+ User.PERMISSION_FIELDS = [];
8503
+ User.CATEGORY_PERMISSION_FIELDS = [];
8504
+ User.GRANULAR_PERMISSION_FIELDS = [];
8505
+ User.GRANULAR_TO_CATEGORY = {};
8506
+ User.rebuildPermissions = function() {
8507
+ const _ps = User._permSwitch;
8508
+ User.PERMISSIONS.length = 0;
8509
+ User.PERMISSIONS.push(
8510
+ ...User.CATEGORY_PERMISSIONS,
8511
+ ...User.GRANULAR_PERMISSION_TABS.flatMap((tab) => tab.permissions),
8512
+ ...User.APP_CATEGORY_PERMISSIONS,
8513
+ ...User.APP_GRANULAR_PERMISSIONS
8514
+ );
8515
+ User.PERMISSION_FIELDS.length = 0;
8516
+ User.PERMISSION_FIELDS.push(...User.PERMISSIONS.map(_ps));
8517
+ const categoryTabs = [
8518
+ { label: "System", fields: User.CATEGORY_PERMISSIONS.map(_ps) }
8528
8519
  ];
8529
8520
  if (User.APP_CATEGORY_PERMISSIONS.length > 0) {
8530
- tabs.push({ label: "App", fields: User.APP_CATEGORY_PERMISSIONS.map(_permSwitch) });
8521
+ categoryTabs.push({ label: "App", fields: User.APP_CATEGORY_PERMISSIONS.map(_ps) });
8531
8522
  }
8532
- return [{ type: "tabset", tabs }];
8533
- })();
8534
- User.GRANULAR_PERMISSION_FIELDS = (() => {
8535
- const tabs = User.GRANULAR_PERMISSION_TABS.map((tab) => ({
8523
+ User.CATEGORY_PERMISSION_FIELDS.length = 0;
8524
+ User.CATEGORY_PERMISSION_FIELDS.push({ type: "tabset", tabs: categoryTabs });
8525
+ const granularTabs = User.GRANULAR_PERMISSION_TABS.map((tab) => ({
8536
8526
  label: tab.label,
8537
- fields: tab.permissions.map(_permSwitch)
8527
+ fields: tab.permissions.map(_ps)
8538
8528
  }));
8539
8529
  if (User.APP_GRANULAR_PERMISSIONS.length > 0) {
8540
- tabs.push({ label: "App", fields: User.APP_GRANULAR_PERMISSIONS.map(_permSwitch) });
8530
+ granularTabs.push({ label: "App", fields: User.APP_GRANULAR_PERMISSIONS.map(_ps) });
8531
+ }
8532
+ User.GRANULAR_PERMISSION_FIELDS.length = 0;
8533
+ User.GRANULAR_PERMISSION_FIELDS.push({ type: "tabset", tabs: granularTabs });
8534
+ for (const k of Object.keys(User.GRANULAR_TO_CATEGORY)) {
8535
+ delete User.GRANULAR_TO_CATEGORY[k];
8536
+ }
8537
+ for (const [category, perms] of Object.entries(User.CATEGORY_GRANULAR_MAP)) {
8538
+ for (const perm of perms) {
8539
+ User.GRANULAR_TO_CATEGORY[perm] = category;
8540
+ }
8541
+ }
8542
+ };
8543
+ User.registerCategoryMap = function(map) {
8544
+ if (!map) return;
8545
+ let touched = false;
8546
+ for (const [category, perms] of Object.entries(map)) {
8547
+ if (!Array.isArray(perms)) continue;
8548
+ const existing = User.CATEGORY_GRANULAR_MAP[category] || [];
8549
+ User.CATEGORY_GRANULAR_MAP[category] = Array.from(/* @__PURE__ */ new Set([...existing, ...perms]));
8550
+ touched = true;
8551
+ }
8552
+ if (touched) User.rebuildPermissions();
8553
+ };
8554
+ User.registerPermissions = function(spec) {
8555
+ if (!spec) return;
8556
+ if (Array.isArray(spec.categories)) {
8557
+ User.APP_CATEGORY_PERMISSIONS.push(...spec.categories);
8558
+ }
8559
+ if (Array.isArray(spec.granularPermissions)) {
8560
+ User.APP_GRANULAR_PERMISSIONS.push(...spec.granularPermissions);
8561
+ }
8562
+ if (Array.isArray(spec.granularTabs)) {
8563
+ User.GRANULAR_PERMISSION_TABS.push(...spec.granularTabs);
8541
8564
  }
8542
- return [{ type: "tabset", tabs }];
8543
- })();
8565
+ if (spec.categoryGranularMap) {
8566
+ for (const [category, perms] of Object.entries(spec.categoryGranularMap)) {
8567
+ if (!Array.isArray(perms)) continue;
8568
+ const existing = User.CATEGORY_GRANULAR_MAP[category] || [];
8569
+ User.CATEGORY_GRANULAR_MAP[category] = Array.from(/* @__PURE__ */ new Set([...existing, ...perms]));
8570
+ }
8571
+ }
8572
+ User.rebuildPermissions();
8573
+ };
8574
+ User.rebuildPermissions();
8544
8575
  const UserForms = {
8545
8576
  create: {
8546
8577
  title: "Create User",
@@ -8824,25 +8855,6 @@ var MOJO = (function(exports) {
8824
8855
  }
8825
8856
  };
8826
8857
  class Modal {
8827
- // ── Global eyebrow toggle ──────────────────────────────────
8828
- //
8829
- // The eyebrow band can be disabled app-wide by setting the
8830
- // `mojo-no-eyebrow` class on <html>. These helpers just wrap that so
8831
- // callers don't have to touch the DOM directly.
8832
- //
8833
- // Modal.setEyebrowEnabled(false); // turn the band off everywhere
8834
- // Modal.setEyebrowEnabled(true); // turn it back on
8835
- // if (Modal.isEyebrowEnabled()) ...
8836
- /** Enable or disable the eyebrow band on every modal in the app. */
8837
- static setEyebrowEnabled(enabled) {
8838
- if (typeof document === "undefined") return;
8839
- document.documentElement.classList.toggle("mojo-no-eyebrow", !enabled);
8840
- }
8841
- /** True when the eyebrow band is enabled (the default). */
8842
- static isEyebrowEnabled() {
8843
- if (typeof document === "undefined") return true;
8844
- return !document.documentElement.classList.contains("mojo-no-eyebrow");
8845
- }
8846
8858
  // ── Internal: shared render → show → resolve helper ────────
8847
8859
  //
8848
8860
  // Most static helpers want the same lifecycle: render the modal into
@@ -8968,49 +8980,6 @@ var MOJO = (function(exports) {
8968
8980
  * `value` (or its `action` / index when `value` is omitted), or
8969
8981
  * `null` on dismiss.
8970
8982
  */
8971
- /**
8972
- * Build a CSS `style` string with the `--mojo-eyebrow` custom property
8973
- * set so the hero band's `content` picks it up. View applies the
8974
- * returned string to `element.style.cssText` on the modal root.
8975
- *
8976
- * Caller's `eyebrow` option (string | null | '' | false | undefined)
8977
- * always wins over the helper's default. `null`, `''`, and `false`
8978
- * all clear the band content. `undefined` falls back to the default.
8979
- *
8980
- * @param {string} defaultEyebrow - the helper's default eyebrow text
8981
- * @param {string|null|false|undefined} callerEyebrow - user override
8982
- * @param {string} [callerStyle] - any other style string from the caller
8983
- * @returns {string} merged style string suitable for opts.style
8984
- */
8985
- /**
8986
- * Resolve the eyebrow text a helper will end up showing.
8987
- * Pure function — no formatting, just the value.
8988
- */
8989
- static _resolveEyebrow(defaultEyebrow, callerEyebrow) {
8990
- if (callerEyebrow === null || callerEyebrow === false || callerEyebrow === "") return "";
8991
- if (typeof callerEyebrow === "string") return callerEyebrow;
8992
- return defaultEyebrow || "";
8993
- }
8994
- /**
8995
- * If the modal-header title would just duplicate the band's eyebrow
8996
- * (case-insensitive), suppress the header title — the band already
8997
- * carries it and is the always-on system anchor.
8998
- */
8999
- static _suppressDuplicateTitle(title, eyebrowText) {
9000
- if (!eyebrowText || !title) return title;
9001
- const t = String(title).trim().toUpperCase();
9002
- const e = String(eyebrowText).trim().toUpperCase();
9003
- return t === e ? "" : title;
9004
- }
9005
- static _eyebrowStyle(defaultEyebrow, callerEyebrow, callerStyle) {
9006
- if (callerEyebrow === void 0 && typeof callerStyle === "string" && callerStyle.includes("--mojo-eyebrow")) {
9007
- return callerStyle;
9008
- }
9009
- const finalText = Modal._resolveEyebrow(defaultEyebrow, callerEyebrow);
9010
- const safe = String(finalText).replace(/['"\\]/g, "");
9011
- const styleVar = `--mojo-eyebrow: '${safe}'`;
9012
- return [callerStyle, styleVar].filter(Boolean).join("; ");
9013
- }
9014
8983
  static async dialog(options = {}) {
9015
8984
  if (typeof options === "string") {
9016
8985
  const message2 = arguments[0];
@@ -9028,21 +8997,15 @@ var MOJO = (function(exports) {
9028
8997
  centered = true,
9029
8998
  buttons = [{ text: "OK", class: "btn-primary", value: true }],
9030
8999
  rejectOnDismiss = false,
9031
- eyebrow,
9032
- style: callerStyle,
9033
9000
  ...rest2
9034
9001
  } = options;
9035
9002
  const resolvedBody = body ?? view ?? message ?? content ?? "";
9036
- const eyebrowText = Modal._resolveEyebrow("", eyebrow);
9037
- const finalTitle = Modal._suppressDuplicateTitle(title, eyebrowText);
9038
- const style = Modal._eyebrowStyle("", eyebrow, callerStyle);
9039
9003
  const modal = new ModalView({
9040
- title: finalTitle,
9004
+ title,
9041
9005
  body: resolvedBody,
9042
9006
  size,
9043
9007
  centered,
9044
9008
  buttons,
9045
- style,
9046
9009
  ...rest2
9047
9010
  });
9048
9011
  return Modal._renderAndAwait(modal, { buttons, rejectOnDismiss });
@@ -9111,10 +9074,6 @@ var MOJO = (function(exports) {
9111
9074
  body: composedBody,
9112
9075
  size,
9113
9076
  centered: false,
9114
- // The drawer header replaces the modal's hero band entirely —
9115
- // suppress the band so the caller's eyebrow/title/meta block
9116
- // owns the top of the card cleanly.
9117
- className: `modal-bandless ${rest2.className || ""}`.trim(),
9118
9077
  buttons: [{ text: "Close", class: "btn-secondary", dismiss: true }],
9119
9078
  ...rest2
9120
9079
  });
@@ -9130,7 +9089,6 @@ var MOJO = (function(exports) {
9130
9089
  * (views typically have their own headers). Size defaults to `lg`.
9131
9090
  */
9132
9091
  static async show(view, options = {}) {
9133
- const { eyebrow, style: callerStyle, ...rest2 } = options;
9134
9092
  return Modal.dialog({
9135
9093
  header: options.title !== void 0 ? !!options.title : false,
9136
9094
  title: options.title || void 0,
@@ -9138,8 +9096,7 @@ var MOJO = (function(exports) {
9138
9096
  size: "lg",
9139
9097
  centered: false,
9140
9098
  buttons: [{ text: "Close", class: "btn-secondary", dismiss: true }],
9141
- style: Modal._eyebrowStyle("DETAILS", eyebrow, callerStyle),
9142
- ...rest2
9099
+ ...options
9143
9100
  });
9144
9101
  }
9145
9102
  /**
@@ -9185,14 +9142,12 @@ var MOJO = (function(exports) {
9185
9142
  );
9186
9143
  }
9187
9144
  const viewInstance = new ViewClass({ model });
9188
- const { eyebrow, style: callerStyle, ...rest2 } = options;
9189
9145
  return Modal.dialog({
9190
9146
  header: false,
9191
9147
  body: viewInstance,
9192
9148
  size: "lg",
9193
9149
  centered: false,
9194
- style: Modal._eyebrowStyle("DETAILS", eyebrow, callerStyle),
9195
- ...rest2
9150
+ ...options
9196
9151
  });
9197
9152
  }
9198
9153
  // ── alert / confirm / prompt / showError ──────────────────
@@ -9216,32 +9171,28 @@ var MOJO = (function(exports) {
9216
9171
  message = "",
9217
9172
  title: resolvedTitle = "Alert",
9218
9173
  type = "info",
9219
- eyebrow: callerEyebrow,
9174
+ icon: callerIcon,
9220
9175
  className: callerClassName,
9221
- style: callerStyle,
9222
9176
  ...rest2
9223
9177
  } = opts;
9224
9178
  const typeKey = type === "danger" ? "error" : type;
9225
9179
  const typeClass = `modal-alert modal-alert-${typeKey}`;
9226
9180
  const className = [typeClass, callerClassName].filter(Boolean).join(" ");
9227
- const defaultEyebrowMap = {
9228
- info: "INFORMATION",
9229
- success: "SUCCESS",
9230
- warning: "WARNING",
9231
- error: "ERROR"
9181
+ const defaultIcons = {
9182
+ info: "bi-info-circle",
9183
+ success: "bi-check-circle",
9184
+ warning: "bi-exclamation-triangle",
9185
+ error: "bi-x-circle"
9232
9186
  };
9233
- const defaultEyebrow = defaultEyebrowMap[typeKey] ?? defaultEyebrowMap.info;
9234
- const eyebrowText = Modal._resolveEyebrow(defaultEyebrow, callerEyebrow);
9235
- const finalTitle = Modal._suppressDuplicateTitle(resolvedTitle, eyebrowText);
9236
- const style = Modal._eyebrowStyle(defaultEyebrow, callerEyebrow, callerStyle);
9237
- const titleHtml = finalTitle ? `<span class="modal-alert-headline">${finalTitle}</span>` : "";
9187
+ const iconClass = callerIcon !== void 0 ? callerIcon : defaultIcons[typeKey];
9188
+ const iconHtml = iconClass ? `<i class="bi ${iconClass} modal-alert-icon"></i>` : "";
9189
+ const headlineHtml = `<span class="modal-alert-headline">${resolvedTitle}</span>`;
9238
9190
  return Modal.dialog({
9239
- title: titleHtml,
9191
+ title: `${iconHtml}${headlineHtml}`,
9240
9192
  body: `<p class="modal-alert-message">${message}</p>`,
9241
9193
  size: "sm",
9242
9194
  centered: true,
9243
9195
  className,
9244
- style,
9245
9196
  buttons: [{ text: "OK", class: "btn-primary", value: true }],
9246
9197
  ...rest2
9247
9198
  });
@@ -9263,19 +9214,14 @@ var MOJO = (function(exports) {
9263
9214
  { text: options.cancelText || "Cancel", class: "btn-secondary", dismiss: true, action: "cancel" },
9264
9215
  { text: options.confirmText || "Confirm", class: options.confirmClass || "btn-primary", action: "confirm" }
9265
9216
  ];
9266
- const { eyebrow, style: callerStyle, ...rest2 } = options;
9267
- const eyebrowText = Modal._resolveEyebrow("CONFIRM", eyebrow);
9268
- const finalTitle = Modal._suppressDuplicateTitle(title, eyebrowText);
9269
- const style = Modal._eyebrowStyle("CONFIRM", eyebrow, callerStyle);
9270
9217
  const modal = new ModalView({
9271
- title: finalTitle,
9218
+ title,
9272
9219
  body: `<p>${message}</p>`,
9273
9220
  size: options.size || "sm",
9274
9221
  centered: true,
9275
9222
  backdrop: "static",
9276
9223
  buttons,
9277
- style,
9278
- ...rest2
9224
+ ...options
9279
9225
  });
9280
9226
  const result = await Modal._renderAndAwait(modal, { buttons });
9281
9227
  return result === "confirm";
@@ -9293,12 +9239,8 @@ var MOJO = (function(exports) {
9293
9239
  { text: "Cancel", class: "btn-secondary", dismiss: true },
9294
9240
  { text: "OK", class: "btn-primary", action: "ok" }
9295
9241
  ];
9296
- const { eyebrow, style: callerStyle, ...rest2 } = options;
9297
- const eyebrowText = Modal._resolveEyebrow("INPUT", eyebrow);
9298
- const finalTitle = Modal._suppressDuplicateTitle(title, eyebrowText);
9299
- const style = Modal._eyebrowStyle("INPUT", eyebrow, callerStyle);
9300
9242
  const modal = new ModalView({
9301
- title: finalTitle,
9243
+ title,
9302
9244
  body: `
9303
9245
  <p>${message}</p>
9304
9246
  <input type="${inputType}"
@@ -9311,8 +9253,7 @@ var MOJO = (function(exports) {
9311
9253
  centered: true,
9312
9254
  backdrop: "static",
9313
9255
  buttons,
9314
- style,
9315
- ...rest2
9256
+ ...options
9316
9257
  });
9317
9258
  modal.on("shown", () => {
9318
9259
  const input = modal.element.querySelector(`#${inputId}`);
@@ -9348,8 +9289,6 @@ var MOJO = (function(exports) {
9348
9289
  centered = true,
9349
9290
  submitText = "Submit",
9350
9291
  cancelText = "Cancel",
9351
- eyebrow,
9352
- style: callerStyle,
9353
9292
  ...rest2
9354
9293
  } = options;
9355
9294
  const FormView2 = (await Promise.resolve().then(() => FormView$1)).default;
@@ -9369,17 +9308,12 @@ var MOJO = (function(exports) {
9369
9308
  { text: cancelText, class: "btn-secondary", action: "cancel" },
9370
9309
  { text: submitText, class: "btn-primary", action: "submit" }
9371
9310
  ];
9372
- const defaultEyebrow = String(title || "FORM").toUpperCase();
9373
- const eyebrowText = Modal._resolveEyebrow(defaultEyebrow, eyebrow);
9374
- const finalTitle = Modal._suppressDuplicateTitle(title, eyebrowText);
9375
- const style = Modal._eyebrowStyle(defaultEyebrow, eyebrow, callerStyle);
9376
9311
  const modal = new ModalView({
9377
- title: finalTitle,
9312
+ title,
9378
9313
  body: formView,
9379
9314
  size,
9380
9315
  centered,
9381
9316
  buttons,
9382
- style,
9383
9317
  ...rest2
9384
9318
  });
9385
9319
  return Modal._renderAndAwait(modal, {
@@ -9436,8 +9370,6 @@ var MOJO = (function(exports) {
9436
9370
  cancelText = "Cancel",
9437
9371
  model,
9438
9372
  fields,
9439
- eyebrow,
9440
- style: callerStyle,
9441
9373
  ...rest2
9442
9374
  } = options;
9443
9375
  if (!model) {
@@ -9460,17 +9392,12 @@ var MOJO = (function(exports) {
9460
9392
  { text: cancelText, class: "btn-secondary", action: "cancel" },
9461
9393
  { text: submitText, class: "btn-primary", action: "submit" }
9462
9394
  ];
9463
- const defaultEyebrow = String(title || "EDIT").toUpperCase();
9464
- const eyebrowText = Modal._resolveEyebrow(defaultEyebrow, eyebrow);
9465
- const finalTitle = Modal._suppressDuplicateTitle(title, eyebrowText);
9466
- const style = Modal._eyebrowStyle(defaultEyebrow, eyebrow, callerStyle);
9467
9395
  const modal = new ModalView({
9468
- title: finalTitle,
9396
+ title,
9469
9397
  body: formView,
9470
9398
  size,
9471
9399
  centered,
9472
9400
  buttons,
9473
- style,
9474
9401
  ...rest2
9475
9402
  });
9476
9403
  return Modal._renderAndAwait(modal, {